run-set_alloc.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. #include <ccan/tap/tap.h>
  2. #include <stdlib.h>
  3. /* Make sure we override these! */
  4. static void *no_malloc(size_t size)
  5. {
  6. abort();
  7. }
  8. static void *no_realloc(void *p, size_t size)
  9. {
  10. abort();
  11. }
  12. static void no_free(void *p)
  13. {
  14. abort();
  15. }
  16. #define malloc no_malloc
  17. #define realloc no_realloc
  18. #define free no_free
  19. #include <ccan/opt/opt.c>
  20. #include <ccan/opt/usage.c>
  21. #include <ccan/opt/helpers.c>
  22. #include <ccan/opt/parse.c>
  23. #include "utils.h"
  24. #undef malloc
  25. #undef realloc
  26. #undef free
  27. static unsigned int alloc_count, realloc_count, free_count;
  28. static void *ptrs[100];
  29. static void **find_ptr(void *p)
  30. {
  31. unsigned int i;
  32. for (i = 0; i < 100; i++)
  33. if (ptrs[i] == p)
  34. return ptrs + i;
  35. return NULL;
  36. }
  37. static void *allocfn(size_t size)
  38. {
  39. alloc_count++;
  40. return *find_ptr(NULL) = malloc(size);
  41. }
  42. static void *reallocfn(void *ptr, size_t size)
  43. {
  44. realloc_count++;
  45. if (!ptr)
  46. alloc_count++;
  47. return *find_ptr(ptr) = realloc(ptr, size);
  48. }
  49. static void freefn(void *ptr)
  50. {
  51. free_count++;
  52. free(ptr);
  53. *find_ptr(ptr) = NULL;
  54. }
  55. int main(int argc, char *argv[])
  56. {
  57. const char *myname = argv[0];
  58. plan_tests(220);
  59. opt_set_alloc(allocfn, reallocfn, freefn);
  60. /* Simple short arg.*/
  61. opt_register_noarg("-a", test_noarg, NULL, "All");
  62. ok1(parse_args(&argc, &argv, "-a", NULL));
  63. ok1(argc == 1);
  64. ok1(argv[0] == myname);
  65. ok1(argv[1] == NULL);
  66. ok1(test_cb_called == 1);
  67. /* Simple long arg. */
  68. opt_register_noarg("--aaa", test_noarg, NULL, "AAAAll");
  69. ok1(parse_args(&argc, &argv, "--aaa", NULL));
  70. ok1(argc == 1);
  71. ok1(argv[0] == myname);
  72. ok1(argv[1] == NULL);
  73. ok1(test_cb_called == 2);
  74. /* Both long and short args. */
  75. opt_register_noarg("--aaa|-a", test_noarg, NULL, "AAAAAAll");
  76. ok1(parse_args(&argc, &argv, "--aaa", "-a", NULL));
  77. ok1(argc == 1);
  78. ok1(argv[0] == myname);
  79. ok1(argv[1] == NULL);
  80. ok1(test_cb_called == 4);
  81. /* Extra arguments preserved. */
  82. ok1(parse_args(&argc, &argv, "--aaa", "-a", "extra", "args", NULL));
  83. ok1(argc == 3);
  84. ok1(argv[0] == myname);
  85. ok1(strcmp(argv[1], "extra") == 0);
  86. ok1(strcmp(argv[2], "args") == 0);
  87. ok1(test_cb_called == 6);
  88. /* Malformed versions. */
  89. ok1(!parse_args(&argc, &argv, "--aaa=arg", NULL));
  90. ok1(strstr(err_output, ": --aaa: doesn't allow an argument"));
  91. ok1(!parse_args(&argc, &argv, "--aa", NULL));
  92. ok1(strstr(err_output, ": --aa: unrecognized option"));
  93. ok1(!parse_args(&argc, &argv, "--aaargh", NULL));
  94. ok1(strstr(err_output, ": --aaargh: unrecognized option"));
  95. /* Argument variants. */
  96. reset_options();
  97. test_cb_called = 0;
  98. opt_register_arg("-a|--aaa", test_arg, NULL, "aaa", "AAAAAAll");
  99. ok1(parse_args(&argc, &argv, "--aaa", "aaa", NULL));
  100. ok1(argc == 1);
  101. ok1(argv[0] == myname);
  102. ok1(test_cb_called == 1);
  103. ok1(parse_args(&argc, &argv, "--aaa=aaa", NULL));
  104. ok1(argc == 1);
  105. ok1(argv[0] == myname);
  106. ok1(test_cb_called == 2);
  107. ok1(parse_args(&argc, &argv, "-a", "aaa", NULL));
  108. ok1(argc == 1);
  109. ok1(argv[0] == myname);
  110. ok1(test_cb_called == 3);
  111. /* Malformed versions. */
  112. ok1(!parse_args(&argc, &argv, "-a", NULL));
  113. ok1(strstr(err_output, ": -a: requires an argument"));
  114. ok1(!parse_args(&argc, &argv, "--aaa", NULL));
  115. ok1(strstr(err_output, ": --aaa: requires an argument"));
  116. ok1(!parse_args(&argc, &argv, "--aa", NULL));
  117. ok1(strstr(err_output, ": --aa: unrecognized option"));
  118. ok1(!parse_args(&argc, &argv, "--aaargh", NULL));
  119. ok1(strstr(err_output, ": --aaargh: unrecognized option"));
  120. /* Now, tables. */
  121. /* Short table: */
  122. reset_options();
  123. test_cb_called = 0;
  124. opt_register_table(short_table, NULL);
  125. ok1(parse_args(&argc, &argv, "-a", NULL));
  126. ok1(argc == 1);
  127. ok1(argv[0] == myname);
  128. ok1(argv[1] == NULL);
  129. ok1(test_cb_called == 1);
  130. /* This one needs an arg. */
  131. ok1(parse_args(&argc, &argv, "-b", NULL) == false);
  132. ok1(test_cb_called == 1);
  133. ok1(parse_args(&argc, &argv, "-b", "b", NULL));
  134. ok1(argc == 1);
  135. ok1(argv[0] == myname);
  136. ok1(argv[1] == NULL);
  137. ok1(test_cb_called == 2);
  138. /* Long table: */
  139. reset_options();
  140. test_cb_called = 0;
  141. opt_register_table(long_table, NULL);
  142. ok1(parse_args(&argc, &argv, "--ddd", NULL));
  143. ok1(argc == 1);
  144. ok1(argv[0] == myname);
  145. ok1(argv[1] == NULL);
  146. ok1(test_cb_called == 1);
  147. /* This one needs an arg. */
  148. ok1(parse_args(&argc, &argv, "--eee", NULL) == false);
  149. ok1(test_cb_called == 1);
  150. ok1(parse_args(&argc, &argv, "--eee", "eee", NULL));
  151. ok1(argc == 1);
  152. ok1(argv[0] == myname);
  153. ok1(argv[1] == NULL);
  154. ok1(test_cb_called == 2);
  155. /* Short and long, both. */
  156. reset_options();
  157. test_cb_called = 0;
  158. opt_register_table(long_and_short_table, NULL);
  159. ok1(parse_args(&argc, &argv, "-g", NULL));
  160. ok1(argc == 1);
  161. ok1(argv[0] == myname);
  162. ok1(argv[1] == NULL);
  163. ok1(test_cb_called == 1);
  164. ok1(parse_args(&argc, &argv, "--ggg", NULL));
  165. ok1(argc == 1);
  166. ok1(argv[0] == myname);
  167. ok1(argv[1] == NULL);
  168. ok1(test_cb_called == 2);
  169. /* This one needs an arg. */
  170. ok1(parse_args(&argc, &argv, "-h", NULL) == false);
  171. ok1(test_cb_called == 2);
  172. ok1(parse_args(&argc, &argv, "-h", "hhh", NULL));
  173. ok1(argc == 1);
  174. ok1(argv[0] == myname);
  175. ok1(argv[1] == NULL);
  176. ok1(test_cb_called == 3);
  177. ok1(parse_args(&argc, &argv, "--hhh", NULL) == false);
  178. ok1(test_cb_called == 3);
  179. ok1(parse_args(&argc, &argv, "--hhh", "hhh", NULL));
  180. ok1(argc == 1);
  181. ok1(argv[0] == myname);
  182. ok1(argv[1] == NULL);
  183. ok1(test_cb_called == 4);
  184. /* Those will all work as tables. */
  185. test_cb_called = 0;
  186. reset_options();
  187. opt_register_table(subtables, NULL);
  188. ok1(parse_args(&argc, &argv, "-a", NULL));
  189. ok1(argc == 1);
  190. ok1(argv[0] == myname);
  191. ok1(argv[1] == NULL);
  192. ok1(test_cb_called == 1);
  193. /* This one needs an arg. */
  194. ok1(parse_args(&argc, &argv, "-b", NULL) == false);
  195. ok1(test_cb_called == 1);
  196. ok1(parse_args(&argc, &argv, "-b", "b", NULL));
  197. ok1(argc == 1);
  198. ok1(argv[0] == myname);
  199. ok1(argv[1] == NULL);
  200. ok1(test_cb_called == 2);
  201. ok1(parse_args(&argc, &argv, "--ddd", NULL));
  202. ok1(argc == 1);
  203. ok1(argv[0] == myname);
  204. ok1(argv[1] == NULL);
  205. ok1(test_cb_called == 3);
  206. /* This one needs an arg. */
  207. ok1(parse_args(&argc, &argv, "--eee", NULL) == false);
  208. ok1(test_cb_called == 3);
  209. ok1(parse_args(&argc, &argv, "--eee", "eee", NULL));
  210. ok1(argc == 1);
  211. ok1(argv[0] == myname);
  212. ok1(argv[1] == NULL);
  213. ok1(test_cb_called == 4);
  214. /* Short and long, both. */
  215. ok1(parse_args(&argc, &argv, "-g", NULL));
  216. ok1(argc == 1);
  217. ok1(argv[0] == myname);
  218. ok1(argv[1] == NULL);
  219. ok1(test_cb_called == 5);
  220. ok1(parse_args(&argc, &argv, "--ggg", NULL));
  221. ok1(argc == 1);
  222. ok1(argv[0] == myname);
  223. ok1(argv[1] == NULL);
  224. ok1(test_cb_called == 6);
  225. /* This one needs an arg. */
  226. ok1(parse_args(&argc, &argv, "-h", NULL) == false);
  227. ok1(test_cb_called == 6);
  228. ok1(parse_args(&argc, &argv, "-h", "hhh", NULL));
  229. ok1(argc == 1);
  230. ok1(argv[0] == myname);
  231. ok1(argv[1] == NULL);
  232. ok1(test_cb_called == 7);
  233. ok1(parse_args(&argc, &argv, "--hhh", NULL) == false);
  234. ok1(test_cb_called == 7);
  235. ok1(parse_args(&argc, &argv, "--hhh", "hhh", NULL));
  236. ok1(argc == 1);
  237. ok1(argv[0] == myname);
  238. ok1(argv[1] == NULL);
  239. ok1(test_cb_called == 8);
  240. /* Now the tricky one: -? must not be confused with an unknown option */
  241. test_cb_called = 0;
  242. reset_options();
  243. /* glibc's getopt does not handle ? with arguments. */
  244. opt_register_noarg("-?", test_noarg, NULL, "Help");
  245. ok1(parse_args(&argc, &argv, "-?", NULL));
  246. ok1(test_cb_called == 1);
  247. ok1(parse_args(&argc, &argv, "-a", NULL) == false);
  248. ok1(test_cb_called == 1);
  249. ok1(strstr(err_output, ": -a: unrecognized option"));
  250. ok1(parse_args(&argc, &argv, "--aaaa", NULL) == false);
  251. ok1(test_cb_called == 1);
  252. ok1(strstr(err_output, ": --aaaa: unrecognized option"));
  253. test_cb_called = 0;
  254. reset_options();
  255. /* Corner cases involving short arg parsing weirdness. */
  256. opt_register_noarg("-a|--aaa", test_noarg, NULL, "a");
  257. opt_register_arg("-b|--bbb", test_arg, NULL, "bbb", "b");
  258. opt_register_arg("-c|--ccc", test_arg, NULL, "aaa", "c");
  259. /* -aa == -a -a */
  260. ok1(parse_args(&argc, &argv, "-aa", NULL));
  261. ok1(test_cb_called == 2);
  262. ok1(parse_args(&argc, &argv, "-aab", NULL) == false);
  263. ok1(test_cb_called == 4);
  264. ok1(strstr(err_output, ": -b: requires an argument"));
  265. ok1(parse_args(&argc, &argv, "-bbbb", NULL));
  266. ok1(test_cb_called == 5);
  267. ok1(parse_args(&argc, &argv, "-aabbbb", NULL));
  268. ok1(test_cb_called == 8);
  269. ok1(parse_args(&argc, &argv, "-aabbbb", "-b", "bbb", NULL));
  270. ok1(test_cb_called == 12);
  271. ok1(parse_args(&argc, &argv, "-aabbbb", "--bbb", "bbb", NULL));
  272. ok1(test_cb_called == 16);
  273. ok1(parse_args(&argc, &argv, "-aabbbb", "--bbb=bbb", NULL));
  274. ok1(test_cb_called == 20);
  275. ok1(parse_args(&argc, &argv, "-aacaaa", NULL));
  276. ok1(test_cb_called == 23);
  277. ok1(parse_args(&argc, &argv, "-aacaaa", "-a", NULL));
  278. ok1(test_cb_called == 27);
  279. ok1(parse_args(&argc, &argv, "-aacaaa", "--bbb", "bbb", "-aacaaa",
  280. NULL));
  281. ok1(test_cb_called == 34);
  282. test_cb_called = 0;
  283. reset_options();
  284. /* -- and POSIXLY_CORRECT */
  285. opt_register_noarg("-a|--aaa", test_noarg, NULL, "a");
  286. ok1(parse_args(&argc, &argv, "-a", "--", "-a", NULL));
  287. ok1(test_cb_called == 1);
  288. ok1(argc == 2);
  289. ok1(strcmp(argv[1], "-a") == 0);
  290. ok1(!argv[2]);
  291. unsetenv("POSIXLY_CORRECT");
  292. ok1(parse_args(&argc, &argv, "-a", "somearg", "-a", "--", "-a", NULL));
  293. ok1(test_cb_called == 3);
  294. ok1(argc == 3);
  295. ok1(strcmp(argv[1], "somearg") == 0);
  296. ok1(strcmp(argv[2], "-a") == 0);
  297. ok1(!argv[3]);
  298. setenv("POSIXLY_CORRECT", "1", 1);
  299. ok1(parse_args(&argc, &argv, "-a", "somearg", "-a", "--", "-a", NULL));
  300. ok1(test_cb_called == 4);
  301. ok1(argc == 5);
  302. ok1(strcmp(argv[1], "somearg") == 0);
  303. ok1(strcmp(argv[2], "-a") == 0);
  304. ok1(strcmp(argv[3], "--") == 0);
  305. ok1(strcmp(argv[4], "-a") == 0);
  306. ok1(!argv[5]);
  307. /* We should have tested each one at least once! */
  308. ok1(realloc_count);
  309. ok1(alloc_count);
  310. ok1(free_count);
  311. ok1(free_count < alloc_count);
  312. reset_options();
  313. ok1(free_count == alloc_count);
  314. /* parse_args allocates argv */
  315. free(argv);
  316. return exit_status();
  317. }