X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Fautodata%2F_info;h=a101276d7720ae1988664f20acc3fd31a26769d0;hp=b804bcdd329c2eba9a49a7b6a95837124b6e9f62;hb=291237b4fed863be74051274ac5ad9920cb33cc3;hpb=446eaa5f66db385d89357ba43aa5886f8b906ff0 diff --git a/ccan/autodata/_info b/ccan/autodata/_info index b804bcdd..a101276d 100644 --- a/ccan/autodata/_info +++ b/ccan/autodata/_info @@ -1,15 +1,99 @@ -#include #include "config.h" +#include +#include /** * autodata - stash pointers in your binary for automatic registration * * This code allows declarations in your source which you can gather * together at runtime to form tables. This is often used in place of - * having to patch a registration function call out, or a central - * table. + * having a central registration function or table. + * + * Note that this technique does not work in general for shared libaries, + * only for code compiled into a binary. * * License: BSD-MIT + * + * Example: + * // Distributed commandline option registration (note: ccan/opt is better!) + * #include + * #include + * #include + * #include + * #include + * + * static bool verbose = false; + * + * // This would normally be in a header, so any C file can use it. + * struct option { + * char c; + * bool takes_arg; + * bool (*cb)(char *optarg); + * }; + * AUTODATA_TYPE(options, struct option); + * #define REGISTER_OPTION(optstruct) \ + * AUTODATA(options, (optstruct)) + * + * // Now a few examples (could be anywhere in source) + * static bool verbose_cb(char *unused) + * { + * verbose = true; + * return true; + * } + * static struct option dash_v = { 'v', false, verbose_cb }; + * REGISTER_OPTION(&dash_v); + * + * static bool chdir_cb(char *dir) + * { + * if (verbose) + * printf("chdir to %s. ", dir); + * if (chdir(dir) != 0) + * return false; + * return true; + * } + * static struct option dash_C = { 'C', true, chdir_cb }; + * REGISTER_OPTION(&dash_C); + * + * int main(int argc, char *argv[]) + * { + * struct option **opts; + * size_t i, num; + * int o; + * char *optstring, *p; + * + * // Gather together all the registered options. + * opts = autodata_get(options, &num); + * + * // Make pretty string for getopt(). + * p = optstring = malloc(num * 2 + 1); + * for (i = 0; i < num; i++) { + * *(p++) = opts[i]->c; + * if (opts[i]->takes_arg) + * *(p++) = ':'; + * } + * *p = '\0'; + * + * while ((o = getopt(argc, argv, optstring)) != -1) { + * if (o == '?') + * exit(1); + * // Call callback in matching option. + * for (i = 0; i < num; i++) { + * if (opts[i]->c == o) { + * if (!opts[i]->cb(optarg)) + * err(1, "parsing -%c", o); + * break; + * } + * } + * } + * // free up gathered option table. + * autodata_free(opts); + * + * if (verbose) + * printf("verbose mode on\n"); + * return 0; + * } + * // Given -v outputs 'verbose mode on' + * // Given -v -C / outputs 'chdir to /. verbose mode on' */ int main(int argc, char *argv[]) {