More API function tests...
[oweals/gnunet.git] / src / util / getopt_helpers.c
1 /*
2      This file is part of GNUnet
3      Copyright (C) 2006, 2011 GNUnet e.V.
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
19 */
20
21 /**
22  * @file src/util/getopt_helpers.c
23  * @brief implements command line that sets option
24  * @author Christian Grothoff
25  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28
29 #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
30
31
32 /**
33  * Print out program version (implements --version).
34  *
35  * @param ctx command line processing context
36  * @param scls additional closure (points to version string)
37  * @param option name of the option
38  * @param value not used (NULL)
39  * @return #GNUNET_NO (do not continue, not an error)
40  */
41 int
42 GNUNET_GETOPT_print_version_ (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
43                               void *scls,
44                               const char *option,
45                               const char *value)
46 {
47   const char *version = scls;
48
49   printf ("%s v%s\n",
50           ctx->binaryName,
51           version);
52   return GNUNET_NO;
53 }
54
55
56 /**
57  * At what offset does the help text start?
58  */
59 #define BORDER 29
60
61 /**
62  * Print out details on command line options (implements --help).
63  *
64  * @param ctx command line processing context
65  * @param scls additional closure (points to about text)
66  * @param option name of the option
67  * @param value not used (NULL)
68  * @return #GNUNET_NO (do not continue, not an error)
69  */
70 int
71 GNUNET_GETOPT_format_help_ (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
72                             void *scls,
73                             const char *option,
74                             const char *value)
75 {
76   const char *about = scls;
77   size_t slen;
78   unsigned int i;
79   int j;
80   size_t ml;
81   size_t p;
82   char *scp;
83   const char *trans;
84   const struct GNUNET_GETOPT_CommandLineOption *opt;
85   const struct GNUNET_OS_ProjectData *pd;
86
87   if (NULL != about)
88   {
89     printf ("%s\n%s\n", ctx->binaryOptions, gettext (about));
90     printf (_
91             ("Arguments mandatory for long options are also mandatory for short options.\n"));
92   }
93   i = 0;
94   opt = ctx->allOptions;
95   while (opt[i].description != NULL)
96   {
97     if (opt[i].shortName == '\0')
98       printf ("      ");
99     else
100       printf ("  -%c, ", opt[i].shortName);
101     printf ("--%s", opt[i].name);
102     slen = 8 + strlen (opt[i].name);
103     if (opt[i].argumentHelp != NULL)
104     {
105       printf ("=%s", opt[i].argumentHelp);
106       slen += 1 + strlen (opt[i].argumentHelp);
107     }
108     if (slen > BORDER)
109     {
110       printf ("\n%*s", BORDER, "");
111       slen = BORDER;
112     }
113     if (slen < BORDER)
114     {
115       printf ("%*s", (int) (BORDER - slen), "");
116       slen = BORDER;
117     }
118     if (0 < strlen (opt[i].description))
119       trans = gettext (opt[i].description);
120     else
121       trans = "";
122     ml = strlen (trans);
123     p = 0;
124 OUTER:
125     while (ml - p > 78 - slen)
126     {
127       for (j = p + 78 - slen; j > p; j--)
128       {
129         if (isspace ((unsigned char) trans[j]))
130         {
131           scp = GNUNET_malloc (j - p + 1);
132           GNUNET_memcpy (scp, &trans[p], j - p);
133           scp[j - p] = '\0';
134           printf ("%s\n%*s", scp, BORDER + 2, "");
135           GNUNET_free (scp);
136           p = j + 1;
137           slen = BORDER + 2;
138           goto OUTER;
139         }
140       }
141       /* could not find space to break line */
142       scp = GNUNET_malloc (78 - slen + 1);
143       GNUNET_memcpy (scp, &trans[p], 78 - slen);
144       scp[78 - slen] = '\0';
145       printf ("%s\n%*s", scp, BORDER + 2, "");
146       GNUNET_free (scp);
147       slen = BORDER + 2;
148       p = p + 78 - slen;
149     }
150     /* print rest */
151     if (p < ml)
152       printf ("%s\n", &trans[p]);
153     if (strlen (trans) == 0)
154       printf ("\n");
155     i++;
156   }
157   pd = GNUNET_OS_project_data_get ();
158   printf ("Report bugs to %s.\n"
159           "GNUnet home page: %s\n"
160           "General help using GNU software: http://www.gnu.org/gethelp/\n",
161           pd->bug_email,
162           pd->homepage);
163   return GNUNET_NO;
164 }
165
166
167 /**
168  * Set an option of type 'unsigned int' from the command line. Each
169  * time the option flag is given, the value is incremented by one.
170  * A pointer to this function should be passed as part of the
171  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
172  * of this type.  It should be followed by a pointer to a value of
173  * type 'int'.
174  *
175  * @param ctx command line processing context
176  * @param scls additional closure (will point to the 'int')
177  * @param option name of the option
178  * @param value not used (NULL)
179  * @return #GNUNET_OK
180  */
181 int
182 GNUNET_GETOPT_increment_value (struct GNUNET_GETOPT_CommandLineProcessorContext
183                                *ctx, void *scls, const char *option,
184                                const char *value)
185 {
186   int *val = scls;
187
188   (*val)++;
189   return GNUNET_OK;
190 }
191
192
193 /**
194  * Set an option of type 'int' from the command line to 1 if the
195  * given option is present.
196  * A pointer to this function should be passed as part of the
197  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
198  * of this type.  It should be followed by a pointer to a value of
199  * type 'int'.
200  *
201  * @param ctx command line processing context
202  * @param scls additional closure (will point to the 'int')
203  * @param option name of the option
204  * @param value not used (NULL)
205  * @return #GNUNET_OK
206  */
207 int
208 GNUNET_GETOPT_set_one (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
209                        void *scls, const char *option, const char *value)
210 {
211   int *val = scls;
212
213   *val = 1;
214   return GNUNET_OK;
215 }
216
217
218 /**
219  * Set an option of type 'char *' from the command line.
220  * A pointer to this function should be passed as part of the
221  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
222  * of this type.  It should be followed by a pointer to a value of
223  * type 'char *', which will be allocated with the requested string.
224  *
225  * @param ctx command line processing context
226  * @param scls additional closure (will point to the 'char *',
227  *             which will be allocated)
228  * @param option name of the option
229  * @param value actual value of the option (a string)
230  * @return #GNUNET_OK
231  */
232 int
233 GNUNET_GETOPT_set_string (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
234                           void *scls, const char *option, const char *value)
235 {
236   char **val = scls;
237
238   GNUNET_assert (value != NULL);
239   GNUNET_free_non_null (*val);
240   *val = GNUNET_strdup (value);
241   return GNUNET_OK;
242 }
243
244
245 int
246 GNUNET_GETOPT_set_filename (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
247                             void *scls, const char *option, const char *value)
248 {
249   char **val = scls;
250
251   GNUNET_assert (value != NULL);
252   GNUNET_free_non_null (*val);
253   *val = GNUNET_STRINGS_filename_expand (value);
254   return GNUNET_OK;
255 }
256
257 /**
258  * Set an option of type 'unsigned long long' from the command line.
259  * A pointer to this function should be passed as part of the
260  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
261  * of this type.  It should be followed by a pointer to a value of
262  * type 'unsigned long long'.
263  *
264  * @param ctx command line processing context
265  * @param scls additional closure (will point to the 'unsigned long long')
266  * @param option name of the option
267  * @param value actual value of the option as a string.
268  * @return #GNUNET_OK if parsing the value worked
269  */
270 int
271 GNUNET_GETOPT_set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
272                          void *scls, const char *option, const char *value)
273 {
274   unsigned long long *val = scls;
275
276   if (1 != SSCANF (value, "%llu", val))
277   {
278     FPRINTF (stderr, _("You must pass a number to the `%s' option.\n"), option);
279     return GNUNET_SYSERR;
280   }
281   return GNUNET_OK;
282 }
283
284
285 /**
286  * Set an option of type 'struct GNUNET_TIME_Relative' from the command line.
287  * A pointer to this function should be passed as part of the
288  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
289  * of this type.  It should be followed by a pointer to a value of
290  * type 'struct GNUNET_TIME_Relative'.
291  *
292  * @param ctx command line processing context
293  * @param scls additional closure (will point to the 'struct GNUNET_TIME_Relative')
294  * @param option name of the option
295  * @param value actual value of the option as a string.
296  * @return #GNUNET_OK if parsing the value worked
297  */
298 int
299 GNUNET_GETOPT_set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
300                                  void *scls, const char *option, const char *value)
301 {
302   struct GNUNET_TIME_Relative *val = scls;
303
304   if (GNUNET_OK !=
305       GNUNET_STRINGS_fancy_time_to_relative (value,
306                                              val))
307   {
308     FPRINTF (stderr, _("You must pass relative time to the `%s' option.\n"), option);
309     return GNUNET_SYSERR;
310   }
311   return GNUNET_OK;
312 }
313
314
315 /**
316  * Set an option of type 'unsigned int' from the command line.
317  * A pointer to this function should be passed as part of the
318  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
319  * of this type.  It should be followed by a pointer to a value of
320  * type 'unsigned int'.
321  *
322  * @param ctx command line processing context
323  * @param scls additional closure (will point to the 'unsigned int')
324  * @param option name of the option
325  * @param value actual value of the option as a string.
326  * @return #GNUNET_OK if parsing the value worked
327  */
328 int
329 GNUNET_GETOPT_set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
330                         void *scls, const char *option, const char *value)
331 {
332   unsigned int *val = scls;
333
334   if (1 != SSCANF (value, "%u", val))
335   {
336     FPRINTF (stderr, _("You must pass a number to the `%s' option.\n"), option);
337     return GNUNET_SYSERR;
338   }
339   return GNUNET_OK;
340 }
341
342
343 /* end of getopt_helpers.c */