_info 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #include "config.h"
  2. #include <stdio.h>
  3. #include <string.h>
  4. /**
  5. * autodata - stash pointers in your binary for automatic registration
  6. *
  7. * This code allows declarations in your source which you can gather
  8. * together at runtime to form tables. This is often used in place of
  9. * having a central registration function or table.
  10. *
  11. * Note that this technique does not work in general for shared libaries,
  12. * only for code compiled into a binary.
  13. *
  14. * License: BSD-MIT
  15. *
  16. * Example:
  17. * // Distributed commandline option registration (note: ccan/opt is better!)
  18. * #include <ccan/autodata/autodata.h>
  19. * #include <stdio.h>
  20. * #include <unistd.h>
  21. * #include <stdbool.h>
  22. * #include <err.h>
  23. *
  24. * static bool verbose = false;
  25. *
  26. * // This would normally be in a header, so any C file can use it.
  27. * struct option {
  28. * char c;
  29. * bool takes_arg;
  30. * bool (*cb)(char *optarg);
  31. * };
  32. * AUTODATA_TYPE(options, struct option);
  33. * #define REGISTER_OPTION(optstruct) \
  34. * AUTODATA(options, (optstruct))
  35. *
  36. * // Now a few examples (could be anywhere in source)
  37. * static bool verbose_cb(char *unused)
  38. * {
  39. * verbose = true;
  40. * return true;
  41. * }
  42. * static struct option dash_v = { 'v', false, verbose_cb };
  43. * REGISTER_OPTION(&dash_v);
  44. *
  45. * static bool chdir_cb(char *dir)
  46. * {
  47. * if (verbose)
  48. * printf("chdir to %s. ", dir);
  49. * if (chdir(dir) != 0)
  50. * return false;
  51. * return true;
  52. * }
  53. * static struct option dash_C = { 'C', true, chdir_cb };
  54. * REGISTER_OPTION(&dash_C);
  55. *
  56. * int main(int argc, char *argv[])
  57. * {
  58. * struct option **opts;
  59. * size_t i, num;
  60. * int o;
  61. * char *optstring, *p;
  62. *
  63. * // Gather together all the registered options.
  64. * opts = autodata_get(options, &num);
  65. *
  66. * // Make pretty string for getopt().
  67. * p = optstring = malloc(num * 2 + 1);
  68. * for (i = 0; i < num; i++) {
  69. * *(p++) = opts[i]->c;
  70. * if (opts[i]->takes_arg)
  71. * *(p++) = ':';
  72. * }
  73. * *p = '\0';
  74. *
  75. * while ((o = getopt(argc, argv, optstring)) != -1) {
  76. * if (o == '?')
  77. * exit(1);
  78. * // Call callback in matching option.
  79. * for (i = 0; i < num; i++) {
  80. * if (opts[i]->c == o) {
  81. * if (!opts[i]->cb(optarg))
  82. * err(1, "parsing -%c", o);
  83. * break;
  84. * }
  85. * }
  86. * }
  87. * // free up gathered option table.
  88. * autodata_free(opts);
  89. *
  90. * if (verbose)
  91. * printf("verbose mode on\n");
  92. * return 0;
  93. * }
  94. * // Given -v outputs 'verbose mode on'
  95. * // Given -v -C / outputs 'chdir to /. verbose mode on'
  96. */
  97. int main(int argc, char *argv[])
  98. {
  99. /* Expect exactly one argument */
  100. if (argc != 2)
  101. return 1;
  102. if (strcmp(argv[1], "depends") == 0) {
  103. printf("ccan/compiler\n");
  104. printf("ccan/ptr_valid\n");
  105. return 0;
  106. }
  107. return 1;
  108. }