various: add LICENSE comments.
[ccan] / ccan / typesafe_cb / _info
index 5e35eb7652ece2a30b2d64118de5e9a790cb8c57..a3cdeab584bc346b9a629b796fdf6724521e4901 100644 (file)
@@ -5,7 +5,7 @@
 /**
  * typesafe_cb - macros for safe callbacks.
  *
- * The basis of the typesafe_cb header is cast_if_type(): a
+ * The basis of the typesafe_cb header is typesafe_cb_cast(): a
  * conditional cast macro.   If an expression exactly matches a given
  * type, it is cast to the target type, otherwise it is left alone.
  *
  * the exactly correct function type to match the argument, or a
  * function which takes a void *.
  *
- * This is where typesafe_cb() comes in: it uses cast_if_type() to
+ * This is where typesafe_cb() comes in: it uses typesafe_cb_cast() to
  * cast the callback function if it matches the argument type:
  *
  *     void _register_callback(void (*cb)(void *arg), void *arg);
  *     #define register_callback(cb, arg)                              \
- *             _register_callback(typesafe_cb(void, (cb), (arg)), (arg))
+ *             _register_callback(typesafe_cb(void, void *, (cb), (arg)), \
+ *                                (arg))
  *
  * On compilers which don't support the extensions required
- * cast_if_type() and friend become an unconditional cast, so your
+ * typesafe_cb_cast() and friend become an unconditional cast, so your
  * code will compile but you won't get type checking.
  *
- * Licence: LGPL (2 or any later version)
+ * Example:
+ *     #include <ccan/typesafe_cb/typesafe_cb.h>
+ *     #include <stdlib.h>
+ *     #include <stdio.h>
+ *
+ *     // Generic callback infrastructure.
+ *     struct callback {
+ *             struct callback *next;
+ *             int value;
+ *             int (*callback)(int value, void *arg);
+ *             void *arg;
+ *     };
+ *     static struct callback *callbacks;
+ *     
+ *     static void _register_callback(int value, int (*cb)(int, void *),
+ *                                    void *arg)
+ *     {
+ *             struct callback *new = malloc(sizeof(*new));
+ *             new->next = callbacks;
+ *             new->value = value;
+ *             new->callback = cb;
+ *             new->arg = arg;
+ *             callbacks = new;
+ *     }
+ *     #define register_callback(value, cb, arg)                       \
+ *             _register_callback(value,                               \
+ *                                typesafe_cb_preargs(int, void *,     \
+ *                                                    (cb), (arg), int),\
+ *                                (arg))
+ *     
+ *     static struct callback *find_callback(int value)
+ *     {
+ *             struct callback *i;
+ *     
+ *             for (i = callbacks; i; i = i->next)
+ *                     if (i->value == value)
+ *                             return i;
+ *             return NULL;
+ *     }   
+ *
+ *     // Define several silly callbacks.  Note they don't use void *!
+ *     #define DEF_CALLBACK(name, op)                  \
+ *             static int name(int val, int *arg)      \
+ *             {                                       \
+ *                     printf("%s", #op);              \
+ *                     return val op *arg;             \
+ *             }
+ *     DEF_CALLBACK(multiply, *);
+ *     DEF_CALLBACK(add, +);
+ *     DEF_CALLBACK(divide, /);
+ *     DEF_CALLBACK(sub, -);
+ *     DEF_CALLBACK(or, |);
+ *     DEF_CALLBACK(and, &);
+ *     DEF_CALLBACK(xor, ^);
+ *     DEF_CALLBACK(assign, =);
+ *
+ *     // Silly game to find the longest chain of values.
+ *     int main(int argc, char *argv[])
+ *     {
+ *             int i, run = 1, num = argv[1] ? atoi(argv[1]) : 0;
+ *     
+ *             for (i = 1; i < 1024;) {
+ *                     // Since run is an int, compiler checks "add" does too.
+ *                     register_callback(i++, add, &run);
+ *                     register_callback(i++, divide, &run);
+ *                     register_callback(i++, sub, &run);
+ *                     register_callback(i++, multiply, &run);
+ *                     register_callback(i++, or, &run);
+ *                     register_callback(i++, and, &run);
+ *                     register_callback(i++, xor, &run);
+ *                     register_callback(i++, assign, &run);
+ *             }
+ *     
+ *             printf("%i ", num);
+ *             while (run < 56) {
+ *                     struct callback *cb = find_callback(num % i);
+ *                     if (!cb) {
+ *                             printf("-> STOP\n");
+ *                             return 1;
+ *                     }
+ *                     num = cb->callback(num, cb->arg);
+ *                     printf("->%i ", num);
+ *                     run++;
+ *             }
+ *             printf("-> Winner!\n");
+ *             return 0;
+ *     }
+ *
+ * License: LGPL (v2.1 or any later version)
+ * Author: Rusty Russell <rusty@rustcorp.com.au>
  */
 int main(int argc, char *argv[])
 {