getopt_helpers.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895
  1. /*
  2. This file is part of GNUnet
  3. Copyright (C) 2006, 2011 GNUnet e.V.
  4. GNUnet is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; either version 3, or (at your
  7. option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNUnet; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  15. Boston, MA 02110-1301, USA.
  16. */
  17. /**
  18. * @file src/util/getopt_helpers.c
  19. * @brief implements command line that sets option
  20. * @author Christian Grothoff
  21. */
  22. #include "platform.h"
  23. #include "gnunet_util_lib.h"
  24. #define LOG(kind,...) GNUNET_log_from (kind, "util-getopt", __VA_ARGS__)
  25. /**
  26. * Print out program version (implements --version).
  27. *
  28. * @param ctx command line processing context
  29. * @param scls additional closure (points to version string)
  30. * @param option name of the option
  31. * @param value not used (NULL)
  32. * @return #GNUNET_NO (do not continue, not an error)
  33. */
  34. static int
  35. print_version (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
  36. void *scls,
  37. const char *option,
  38. const char *value)
  39. {
  40. const char *version = scls;
  41. printf ("%s v%s\n",
  42. ctx->binaryName,
  43. version);
  44. return GNUNET_NO;
  45. }
  46. /**
  47. * Define the option to print the version of
  48. * the application (-v option)
  49. *
  50. * @param version string with the version number
  51. */
  52. struct GNUNET_GETOPT_CommandLineOption
  53. GNUNET_GETOPT_option_version (const char *version)
  54. {
  55. struct GNUNET_GETOPT_CommandLineOption clo = {
  56. .shortName = 'v',
  57. .name = "version",
  58. .description = gettext_noop("print the version number"),
  59. .processor = &print_version,
  60. .scls = (void *) version
  61. };
  62. return clo;
  63. }
  64. /**
  65. * At what offset does the help text start?
  66. */
  67. #define BORDER 29
  68. /**
  69. * Print out details on command line options (implements --help).
  70. *
  71. * @param ctx command line processing context
  72. * @param scls additional closure (points to about text)
  73. * @param option name of the option
  74. * @param value not used (NULL)
  75. * @return #GNUNET_NO (do not continue, not an error)
  76. */
  77. static int
  78. format_help (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
  79. void *scls,
  80. const char *option,
  81. const char *value)
  82. {
  83. const char *about = scls;
  84. size_t slen;
  85. unsigned int i;
  86. int j;
  87. size_t ml;
  88. size_t p;
  89. char *scp;
  90. const char *trans;
  91. const struct GNUNET_GETOPT_CommandLineOption *opt;
  92. const struct GNUNET_OS_ProjectData *pd;
  93. if (NULL != about)
  94. {
  95. printf ("%s\n%s\n", ctx->binaryOptions, gettext (about));
  96. printf (_
  97. ("Arguments mandatory for long options are also mandatory for short options.\n"));
  98. }
  99. i = 0;
  100. opt = ctx->allOptions;
  101. while (opt[i].description != NULL)
  102. {
  103. if (opt[i].shortName == '\0')
  104. printf (" ");
  105. else
  106. printf (" -%c, ", opt[i].shortName);
  107. printf ("--%s", opt[i].name);
  108. slen = 8 + strlen (opt[i].name);
  109. if (opt[i].argumentHelp != NULL)
  110. {
  111. printf ("=%s", opt[i].argumentHelp);
  112. slen += 1 + strlen (opt[i].argumentHelp);
  113. }
  114. if (slen > BORDER)
  115. {
  116. printf ("\n%*s", BORDER, "");
  117. slen = BORDER;
  118. }
  119. if (slen < BORDER)
  120. {
  121. printf ("%*s", (int) (BORDER - slen), "");
  122. slen = BORDER;
  123. }
  124. if (0 < strlen (opt[i].description))
  125. trans = gettext (opt[i].description);
  126. else
  127. trans = "";
  128. ml = strlen (trans);
  129. p = 0;
  130. OUTER:
  131. while (ml - p > 78 - slen)
  132. {
  133. for (j = p + 78 - slen; j > p; j--)
  134. {
  135. if (isspace ((unsigned char) trans[j]))
  136. {
  137. scp = GNUNET_malloc (j - p + 1);
  138. GNUNET_memcpy (scp, &trans[p], j - p);
  139. scp[j - p] = '\0';
  140. printf ("%s\n%*s", scp, BORDER + 2, "");
  141. GNUNET_free (scp);
  142. p = j + 1;
  143. slen = BORDER + 2;
  144. goto OUTER;
  145. }
  146. }
  147. /* could not find space to break line */
  148. scp = GNUNET_malloc (78 - slen + 1);
  149. GNUNET_memcpy (scp, &trans[p], 78 - slen);
  150. scp[78 - slen] = '\0';
  151. printf ("%s\n%*s", scp, BORDER + 2, "");
  152. GNUNET_free (scp);
  153. slen = BORDER + 2;
  154. p = p + 78 - slen;
  155. }
  156. /* print rest */
  157. if (p < ml)
  158. printf ("%s\n", &trans[p]);
  159. if (strlen (trans) == 0)
  160. printf ("\n");
  161. i++;
  162. }
  163. pd = GNUNET_OS_project_data_get ();
  164. printf ("Report bugs to %s.\n"
  165. "GNUnet home page: %s\n"
  166. "General help using GNU software: http://www.gnu.org/gethelp/\n",
  167. pd->bug_email,
  168. pd->homepage);
  169. return GNUNET_NO;
  170. }
  171. /**
  172. * Defining the option to print the command line
  173. * help text (-h option).
  174. *
  175. * @param about string with brief description of the application
  176. */
  177. struct GNUNET_GETOPT_CommandLineOption
  178. GNUNET_GETOPT_option_help (const char *about)
  179. {
  180. struct GNUNET_GETOPT_CommandLineOption clo = {
  181. .shortName = 'h',
  182. .name = "help",
  183. .description = gettext_noop("print this help"),
  184. .processor = format_help,
  185. .scls = (void *) about
  186. };
  187. return clo;
  188. }
  189. /**
  190. * Set an option of type 'unsigned int' from the command line. Each
  191. * time the option flag is given, the value is incremented by one.
  192. * A pointer to this function should be passed as part of the
  193. * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
  194. * of this type. It should be followed by a pointer to a value of
  195. * type 'int'.
  196. *
  197. * @param ctx command line processing context
  198. * @param scls additional closure (will point to the 'unsigned int')
  199. * @param option name of the option
  200. * @param value not used (NULL)
  201. * @return #GNUNET_OK
  202. */
  203. static int
  204. increment_value (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
  205. void *scls,
  206. const char *option,
  207. const char *value)
  208. {
  209. unsigned int *val = scls;
  210. (*val)++;
  211. return GNUNET_OK;
  212. }
  213. /**
  214. * Increment @a val each time the option flag is given by one.
  215. *
  216. * @param shortName short name of the option
  217. * @param name long name of the option
  218. * @param argumentHelp help text for the option argument
  219. * @param description long help text for the option
  220. * @param[out] val increment by 1 each time the option is present
  221. */
  222. struct GNUNET_GETOPT_CommandLineOption
  223. GNUNET_GETOPT_option_increment_uint (char shortName,
  224. const char *name,
  225. const char *description,
  226. unsigned int *val)
  227. {
  228. struct GNUNET_GETOPT_CommandLineOption clo = {
  229. .shortName = shortName,
  230. .name = name,
  231. .description = description,
  232. .processor = &increment_value,
  233. .scls = (void *) val
  234. };
  235. return clo;
  236. }
  237. /**
  238. * Define the '-V' verbosity option. Using the option more
  239. * than once increments @a level each time.
  240. *
  241. * @param[out] level set to the verbosity level
  242. */
  243. struct GNUNET_GETOPT_CommandLineOption
  244. GNUNET_GETOPT_option_verbose (unsigned int *level)
  245. {
  246. struct GNUNET_GETOPT_CommandLineOption clo = {
  247. .shortName = 'V',
  248. .name = "verbose",
  249. .description = gettext_noop("be verbose"),
  250. .processor = &increment_value,
  251. .scls = (void *) level
  252. };
  253. return clo;
  254. }
  255. /**
  256. * Set an option of type 'int' from the command line to 1 if the
  257. * given option is present.
  258. * A pointer to this function should be passed as part of the
  259. * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
  260. * of this type. It should be followed by a pointer to a value of
  261. * type 'int'.
  262. *
  263. * @param ctx command line processing context
  264. * @param scls additional closure (will point to the 'int')
  265. * @param option name of the option
  266. * @param value not used (NULL)
  267. * @return #GNUNET_OK
  268. */
  269. static int
  270. set_one (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
  271. void *scls,
  272. const char *option,
  273. const char *value)
  274. {
  275. int *val = scls;
  276. *val = 1;
  277. return GNUNET_OK;
  278. }
  279. /**
  280. * Allow user to specify a flag (which internally means setting
  281. * an integer to 1/#GNUNET_YES/#GNUNET_OK.
  282. *
  283. * @param shortName short name of the option
  284. * @param name long name of the option
  285. * @param argumentHelp help text for the option argument
  286. * @param description long help text for the option
  287. * @param[out] val set to 1 if the option is present
  288. */
  289. struct GNUNET_GETOPT_CommandLineOption
  290. GNUNET_GETOPT_option_flag (char shortName,
  291. const char *name,
  292. const char *description,
  293. int *val)
  294. {
  295. struct GNUNET_GETOPT_CommandLineOption clo = {
  296. .shortName = shortName,
  297. .name = name,
  298. .description = description,
  299. .processor = &set_one,
  300. .scls = (void *) val
  301. };
  302. return clo;
  303. }
  304. /**
  305. * Set an option of type 'char *' from the command line.
  306. * A pointer to this function should be passed as part of the
  307. * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
  308. * of this type. It should be followed by a pointer to a value of
  309. * type 'char *', which will be allocated with the requested string.
  310. *
  311. * @param ctx command line processing context
  312. * @param scls additional closure (will point to the 'char *',
  313. * which will be allocated)
  314. * @param option name of the option
  315. * @param value actual value of the option (a string)
  316. * @return #GNUNET_OK
  317. */
  318. static int
  319. set_string (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
  320. void *scls,
  321. const char *option,
  322. const char *value)
  323. {
  324. char **val = scls;
  325. GNUNET_assert (NULL != value);
  326. GNUNET_free_non_null (*val);
  327. *val = GNUNET_strdup (value);
  328. return GNUNET_OK;
  329. }
  330. /**
  331. * Allow user to specify a string.
  332. *
  333. * @param shortName short name of the option
  334. * @param name long name of the option
  335. * @param argumentHelp help text for the option argument
  336. * @param description long help text for the option
  337. * @param[out] str set to the string
  338. */
  339. struct GNUNET_GETOPT_CommandLineOption
  340. GNUNET_GETOPT_option_string (char shortName,
  341. const char *name,
  342. const char *argumentHelp,
  343. const char *description,
  344. char **str)
  345. {
  346. struct GNUNET_GETOPT_CommandLineOption clo = {
  347. .shortName = shortName,
  348. .name = name,
  349. .argumentHelp = argumentHelp,
  350. .description = description,
  351. .require_argument = 1,
  352. .processor = &set_string,
  353. .scls = (void *) str
  354. };
  355. return clo;
  356. }
  357. /**
  358. * Define the '-L' log level option. Note that we do not check
  359. * that the log level is valid here.
  360. *
  361. * @param[out] level set to the log level
  362. */
  363. struct GNUNET_GETOPT_CommandLineOption
  364. GNUNET_GETOPT_option_loglevel (char **level)
  365. {
  366. struct GNUNET_GETOPT_CommandLineOption clo = {
  367. .shortName = 'L',
  368. .name = "log",
  369. .argumentHelp = "LOGLEVEL",
  370. .description = gettext_noop("configure logging to use LOGLEVEL"),
  371. .require_argument = 1,
  372. .processor = &set_string,
  373. .scls = (void *) level
  374. };
  375. return clo;
  376. }
  377. /**
  378. * Set an option of type 'char *' from the command line with
  379. * filename expansion a la #GNUNET_STRINGS_filename_expand().
  380. *
  381. * @param ctx command line processing context
  382. * @param scls additional closure (will point to the `char *`,
  383. * which will be allocated)
  384. * @param option name of the option
  385. * @param value actual value of the option (a string)
  386. * @return #GNUNET_OK
  387. */
  388. static int
  389. set_filename (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
  390. void *scls,
  391. const char *option,
  392. const char *value)
  393. {
  394. char **val = scls;
  395. GNUNET_assert (NULL != value);
  396. GNUNET_free_non_null (*val);
  397. *val = GNUNET_STRINGS_filename_expand (value);
  398. return GNUNET_OK;
  399. }
  400. /**
  401. * Allow user to specify a filename (automatically path expanded).
  402. *
  403. * @param shortName short name of the option
  404. * @param name long name of the option
  405. * @param argumentHelp help text for the option argument
  406. * @param description long help text for the option
  407. * @param[out] str set to the string
  408. */
  409. struct GNUNET_GETOPT_CommandLineOption
  410. GNUNET_GETOPT_option_filename (char shortName,
  411. const char *name,
  412. const char *argumentHelp,
  413. const char *description,
  414. char **str)
  415. {
  416. struct GNUNET_GETOPT_CommandLineOption clo = {
  417. .shortName = shortName,
  418. .name = name,
  419. .argumentHelp = argumentHelp,
  420. .description = description,
  421. .require_argument = 1,
  422. .processor = &set_filename,
  423. .scls = (void *) str
  424. };
  425. return clo;
  426. }
  427. /**
  428. * Allow user to specify log file name (-l option)
  429. *
  430. * @param[out] logfn set to the name of the logfile
  431. */
  432. struct GNUNET_GETOPT_CommandLineOption
  433. GNUNET_GETOPT_option_logfile (char **logfn)
  434. {
  435. struct GNUNET_GETOPT_CommandLineOption clo = {
  436. .shortName = 'l',
  437. .name = "logfile",
  438. .argumentHelp = "FILENAME",
  439. .description = gettext_noop ("configure logging to write logs to FILENAME"),
  440. .require_argument = 1,
  441. .processor = &set_filename,
  442. .scls = (void *) logfn
  443. };
  444. return clo;
  445. }
  446. /**
  447. * Allow user to specify configuration file name (-c option)
  448. *
  449. * @param[out] fn set to the name of the configuration file
  450. */
  451. struct GNUNET_GETOPT_CommandLineOption
  452. GNUNET_GETOPT_option_cfgfile (char **fn)
  453. {
  454. struct GNUNET_GETOPT_CommandLineOption clo = {
  455. .shortName = 'c',
  456. .name = "config",
  457. .argumentHelp = "FILENAME",
  458. .description = gettext_noop("use configuration file FILENAME"),
  459. .require_argument = 1,
  460. .processor = &set_filename,
  461. .scls = (void *) fn
  462. };
  463. return clo;
  464. }
  465. /**
  466. * Set an option of type 'unsigned long long' from the command line.
  467. * A pointer to this function should be passed as part of the
  468. * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
  469. * of this type. It should be followed by a pointer to a value of
  470. * type 'unsigned long long'.
  471. *
  472. * @param ctx command line processing context
  473. * @param scls additional closure (will point to the 'unsigned long long')
  474. * @param option name of the option
  475. * @param value actual value of the option as a string.
  476. * @return #GNUNET_OK if parsing the value worked
  477. */
  478. static int
  479. set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
  480. void *scls,
  481. const char *option,
  482. const char *value)
  483. {
  484. unsigned long long *val = scls;
  485. if (1 != SSCANF (value,
  486. "%llu",
  487. val))
  488. {
  489. FPRINTF (stderr,
  490. _("You must pass a number to the `%s' option.\n"),
  491. option);
  492. return GNUNET_SYSERR;
  493. }
  494. return GNUNET_OK;
  495. }
  496. /**
  497. * Allow user to specify an `unsigned long long`
  498. *
  499. * @param shortName short name of the option
  500. * @param name long name of the option
  501. * @param argumentHelp help text for the option argument
  502. * @param description long help text for the option
  503. * @param[out] val set to the value specified at the command line
  504. */
  505. struct GNUNET_GETOPT_CommandLineOption
  506. GNUNET_GETOPT_option_ulong (char shortName,
  507. const char *name,
  508. const char *argumentHelp,
  509. const char *description,
  510. unsigned long long *val)
  511. {
  512. struct GNUNET_GETOPT_CommandLineOption clo = {
  513. .shortName = shortName,
  514. .name = name,
  515. .argumentHelp = argumentHelp,
  516. .description = description,
  517. .require_argument = 1,
  518. .processor = &set_ulong,
  519. .scls = (void *) val
  520. };
  521. return clo;
  522. }
  523. /**
  524. * Set an option of type 'struct GNUNET_TIME_Relative' from the command line.
  525. * A pointer to this function should be passed as part of the
  526. * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
  527. * of this type. It should be followed by a pointer to a value of
  528. * type 'struct GNUNET_TIME_Relative'.
  529. *
  530. * @param ctx command line processing context
  531. * @param scls additional closure (will point to the 'struct GNUNET_TIME_Relative')
  532. * @param option name of the option
  533. * @param value actual value of the option as a string.
  534. * @return #GNUNET_OK if parsing the value worked
  535. */
  536. static int
  537. set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
  538. void *scls,
  539. const char *option,
  540. const char *value)
  541. {
  542. struct GNUNET_TIME_Relative *val = scls;
  543. if (GNUNET_OK !=
  544. GNUNET_STRINGS_fancy_time_to_relative (value,
  545. val))
  546. {
  547. FPRINTF (stderr,
  548. _("You must pass relative time to the `%s' option.\n"),
  549. option);
  550. return GNUNET_SYSERR;
  551. }
  552. return GNUNET_OK;
  553. }
  554. /**
  555. * Allow user to specify a `struct GNUNET_TIME_Relative`
  556. * (using human-readable "fancy" time).
  557. *
  558. * @param shortName short name of the option
  559. * @param name long name of the option
  560. * @param argumentHelp help text for the option argument
  561. * @param description long help text for the option
  562. * @param[out] val set to the time specified at the command line
  563. */
  564. struct GNUNET_GETOPT_CommandLineOption
  565. GNUNET_GETOPT_option_relative_time (char shortName,
  566. const char *name,
  567. const char *argumentHelp,
  568. const char *description,
  569. struct GNUNET_TIME_Relative *val)
  570. {
  571. struct GNUNET_GETOPT_CommandLineOption clo = {
  572. .shortName = shortName,
  573. .name = name,
  574. .argumentHelp = argumentHelp,
  575. .description = description,
  576. .require_argument = 1,
  577. .processor = &set_relative_time,
  578. .scls = (void *) val
  579. };
  580. return clo;
  581. }
  582. /**
  583. * Set an option of type 'struct GNUNET_TIME_Absolute' from the command line.
  584. * A pointer to this function should be passed as part of the
  585. * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
  586. * of this type. It should be followed by a pointer to a value of
  587. * type 'struct GNUNET_TIME_Absolute'.
  588. *
  589. * @param ctx command line processing context
  590. * @param scls additional closure (will point to the `struct GNUNET_TIME_Absolute`)
  591. * @param option name of the option
  592. * @param value actual value of the option as a string.
  593. * @return #GNUNET_OK if parsing the value worked
  594. */
  595. static int
  596. set_absolute_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
  597. void *scls,
  598. const char *option,
  599. const char *value)
  600. {
  601. struct GNUNET_TIME_Absolute *val = scls;
  602. if (GNUNET_OK !=
  603. GNUNET_STRINGS_fancy_time_to_absolute (value,
  604. val))
  605. {
  606. FPRINTF (stderr,
  607. _("You must pass absolute time to the `%s' option.\n"),
  608. option);
  609. return GNUNET_SYSERR;
  610. }
  611. return GNUNET_OK;
  612. }
  613. /**
  614. * Allow user to specify a `struct GNUNET_TIME_Absolute`
  615. * (using human-readable "fancy" time).
  616. *
  617. * @param shortName short name of the option
  618. * @param name long name of the option
  619. * @param argumentHelp help text for the option argument
  620. * @param description long help text for the option
  621. * @param[out] val set to the time specified at the command line
  622. */
  623. struct GNUNET_GETOPT_CommandLineOption
  624. GNUNET_GETOPT_option_absolute_time (char shortName,
  625. const char *name,
  626. const char *argumentHelp,
  627. const char *description,
  628. struct GNUNET_TIME_Absolute *val)
  629. {
  630. struct GNUNET_GETOPT_CommandLineOption clo = {
  631. .shortName = shortName,
  632. .name = name,
  633. .argumentHelp = argumentHelp,
  634. .description = description,
  635. .require_argument = 1,
  636. .processor = &set_absolute_time,
  637. .scls = (void *) val
  638. };
  639. return clo;
  640. }
  641. /**
  642. * Set an option of type 'unsigned int' from the command line.
  643. * A pointer to this function should be passed as part of the
  644. * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
  645. * of this type. It should be followed by a pointer to a value of
  646. * type 'unsigned int'.
  647. *
  648. * @param ctx command line processing context
  649. * @param scls additional closure (will point to the 'unsigned int')
  650. * @param option name of the option
  651. * @param value actual value of the option as a string.
  652. * @return #GNUNET_OK if parsing the value worked
  653. */
  654. static int
  655. set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
  656. void *scls,
  657. const char *option,
  658. const char *value)
  659. {
  660. unsigned int *val = scls;
  661. if (1 != SSCANF (value,
  662. "%u",
  663. val))
  664. {
  665. FPRINTF (stderr,
  666. _("You must pass a number to the `%s' option.\n"),
  667. option);
  668. return GNUNET_SYSERR;
  669. }
  670. return GNUNET_OK;
  671. }
  672. /**
  673. * Allow user to specify an unsigned integer.
  674. *
  675. * @param shortName short name of the option
  676. * @param name long name of the option
  677. * @param argumentHelp help text for the option argument
  678. * @param description long help text for the option
  679. * @param[out] val set to the value specified at the command line
  680. */
  681. struct GNUNET_GETOPT_CommandLineOption
  682. GNUNET_GETOPT_option_uint (char shortName,
  683. const char *name,
  684. const char *argumentHelp,
  685. const char *description,
  686. unsigned int *val)
  687. {
  688. struct GNUNET_GETOPT_CommandLineOption clo = {
  689. .shortName = shortName,
  690. .name = name,
  691. .argumentHelp = argumentHelp,
  692. .description = description,
  693. .require_argument = 1,
  694. .processor = &set_uint,
  695. .scls = (void *) val
  696. };
  697. return clo;
  698. }
  699. /**
  700. * Closure for #set_base32().
  701. */
  702. struct Base32Context
  703. {
  704. /**
  705. * Value to initialize (already allocated)
  706. */
  707. void *val;
  708. /**
  709. * Number of bytes expected for @e val.
  710. */
  711. size_t val_size;
  712. };
  713. /**
  714. * Set an option of type 'unsigned int' from the command line.
  715. * A pointer to this function should be passed as part of the
  716. * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
  717. * of this type. It should be followed by a pointer to a value of
  718. * type 'unsigned int'.
  719. *
  720. * @param ctx command line processing context
  721. * @param scls additional closure (will point to the 'unsigned int')
  722. * @param option name of the option
  723. * @param value actual value of the option as a string.
  724. * @return #GNUNET_OK if parsing the value worked
  725. */
  726. static int
  727. set_base32 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
  728. void *scls,
  729. const char *option,
  730. const char *value)
  731. {
  732. struct Base32Context *bc = scls;
  733. if (GNUNET_OK !=
  734. GNUNET_STRINGS_string_to_data (value,
  735. strlen (value),
  736. bc->val,
  737. bc->val_size))
  738. {
  739. fprintf (stderr,
  740. _("Argument `%s' malformed. Expected base32 (Crockford) encoded value.\n"),
  741. option);
  742. return GNUNET_SYSERR;
  743. }
  744. return GNUNET_OK;
  745. }
  746. /**
  747. * Helper function to clean up after
  748. * #GNUNET_GETOPT_option_base32_fixed_size.
  749. *
  750. * @param cls value to GNUNET_free()
  751. */
  752. static void
  753. free_bc (void *cls)
  754. {
  755. GNUNET_free (cls);
  756. }
  757. /**
  758. * Allow user to specify a binary value using Crockford
  759. * Base32 encoding.
  760. *
  761. * @param shortName short name of the option
  762. * @param name long name of the option
  763. * @param argumentHelp help text for the option argument
  764. * @param description long help text for the option
  765. * @param[out] val binary value decoded from Crockford Base32-encoded argument
  766. * @param val_size size of @a val in bytes
  767. */
  768. struct GNUNET_GETOPT_CommandLineOption
  769. GNUNET_GETOPT_option_base32_fixed_size (char shortName,
  770. const char *name,
  771. const char *argumentHelp,
  772. const char *description,
  773. void *val,
  774. size_t val_size)
  775. {
  776. struct Base32Context *bc = GNUNET_new (struct Base32Context);
  777. struct GNUNET_GETOPT_CommandLineOption clo = {
  778. .shortName = shortName,
  779. .name = name,
  780. .argumentHelp = argumentHelp,
  781. .description = description,
  782. .require_argument = 1,
  783. .processor = &set_base32,
  784. .cleaner = &free_bc,
  785. .scls = (void *) bc
  786. };
  787. bc->val = val;
  788. bc->val_size = val_size;
  789. return clo;
  790. }
  791. /**
  792. * Make the given option mandatory.
  793. *
  794. * @param opt option to modify
  795. * @return @a opt with the mandatory flag set.
  796. */
  797. struct GNUNET_GETOPT_CommandLineOption
  798. GNUNET_GETOPT_option_mandatory (struct GNUNET_GETOPT_CommandLineOption opt)
  799. {
  800. opt.option_mandatory = 1;
  801. return opt;
  802. }
  803. /* end of getopt_helpers.c */