fix
[oweals/gnunet.git] / src / util / getopt_helpers.c
1 /*
2      This file is part of GNUnet
3      (C) 2006, 2011 Christian Grothoff (and other contributing authors)
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 2, 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., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, 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
27 #include "platform.h"
28 #include "gnunet_common.h"
29 #include "gnunet_getopt_lib.h"
30
31 #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
32
33
34 /**
35  * Print out program version (implements --version).
36  *
37  * @param ctx command line processing context
38  * @param scls additional closure (points to version string)
39  * @param option name of the option
40  * @param value not used (NULL)
41  * @return GNUNET_SYSERR (do not continue)
42  */
43 int
44 GNUNET_GETOPT_print_version_ (struct GNUNET_GETOPT_CommandLineProcessorContext
45                               *ctx, void *scls, const char *option,
46                               const char *value)
47 {
48   const char *version = scls;
49
50   printf ("%s v%s\n", ctx->binaryName, version);
51   return GNUNET_SYSERR;
52 }
53
54
55
56 #define BORDER 29
57
58 /**
59  * Print out details on command line options (implements --help).
60  *
61  * @param ctx command line processing context
62  * @param scls additional closure (points to about text)
63  * @param option name of the option
64  * @param value not used (NULL)
65  * @return GNUNET_SYSERR (do not continue)
66  */
67 int
68 GNUNET_GETOPT_format_help_ (struct GNUNET_GETOPT_CommandLineProcessorContext
69                             *ctx, void *scls, const char *option,
70                             const char *value)
71 {
72   const char *about = scls;
73   size_t slen;
74   unsigned int i;
75   int j;
76   size_t ml;
77   size_t p;
78   char *scp;
79   const char *trans;
80   const struct GNUNET_GETOPT_CommandLineOption *opt;
81
82   printf ("%s\n%s\n", ctx->binaryOptions, gettext (about));
83   printf (_
84           ("Arguments mandatory for long options are also mandatory for short options.\n"));
85   i = 0;
86   opt = ctx->allOptions;
87   while (opt[i].description != NULL)
88     {
89       if (opt[i].shortName == '\0')
90         printf ("      ");
91       else
92         printf ("  -%c, ", opt[i].shortName);
93       printf ("--%s", opt[i].name);
94       slen = 8 + strlen (opt[i].name);
95       if (opt[i].argumentHelp != NULL)
96         {
97           printf ("=%s", opt[i].argumentHelp);
98           slen += 1 + strlen (opt[i].argumentHelp);
99         }
100       if (slen > BORDER)
101         {
102           printf ("\n%*s", BORDER, "");
103           slen = BORDER;
104         }
105       if (slen < BORDER)
106         {
107           printf ("%*s", (int) (BORDER - slen), "");
108           slen = BORDER;
109         }
110       if (0 < strlen (opt[i].description))
111         trans = gettext (opt[i].description);
112       else
113         trans = "";
114       ml = strlen (trans);
115       p = 0;
116     OUTER:
117       while (ml - p > 78 - slen)
118         {
119           for (j = p + 78 - slen; j > p; j--)
120             {
121               if (isspace ((unsigned char) trans[j]))
122                 {
123                   scp = GNUNET_malloc (j - p + 1);
124                   memcpy (scp, &trans[p], j - p);
125                   scp[j - p] = '\0';
126                   printf ("%s\n%*s", scp, BORDER + 2, "");
127                   GNUNET_free (scp);
128                   p = j + 1;
129                   slen = BORDER + 2;
130                   goto OUTER;
131                 }
132             }
133           /* could not find space to break line */
134           scp = GNUNET_malloc (78 - slen + 1);
135           memcpy (scp, &trans[p], 78 - slen);
136           scp[78 - slen] = '\0';
137           printf ("%s\n%*s", scp, BORDER + 2, "");
138           GNUNET_free (scp);
139           slen = BORDER + 2;
140           p = p + 78 - slen;
141         }
142       /* print rest */
143       if (p < ml)
144         printf ("%s\n", &trans[p]);
145       if (strlen (trans) == 0)
146         printf ("\n");
147       i++;
148     }
149   printf ("Report bugs to gnunet-developers@gnu.org.\n"
150           "GNUnet home page: http://www.gnu.org/software/gnunet/\n"
151           "General help using GNU software: http://www.gnu.org/gethelp/\n");
152   return GNUNET_SYSERR;
153 }
154
155
156 /**
157  * Set an option of type 'unsigned int' from the command line. Each
158  * time the option flag is given, the value is incremented by one.
159  * A pointer to this function should be passed as part of the
160  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
161  * of this type.  It should be followed by a pointer to a value of
162  * type 'int'.
163  *
164  * @param ctx command line processing context
165  * @param scls additional closure (will point to the 'int')
166  * @param option name of the option
167  * @param value not used (NULL)
168  * @return GNUNET_OK
169  */
170 int
171 GNUNET_GETOPT_increment_value (struct
172                                GNUNET_GETOPT_CommandLineProcessorContext *ctx,
173                                void *scls, const char *option,
174                                const char *value)
175 {
176   int *val = scls;
177
178   (*val)++;
179   return GNUNET_OK;
180 }
181
182
183 /**
184  * Set an option of type 'int' from the command line to 1 if the
185  * given option is present.
186  * A pointer to this function should be passed as part of the
187  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
188  * of this type.  It should be followed by a pointer to a value of
189  * type 'int'.
190  *
191  * @param ctx command line processing context
192  * @param scls additional closure (will point to the 'int')
193  * @param option name of the option
194  * @param value not used (NULL)
195  * @return GNUNET_OK
196  */
197 int
198 GNUNET_GETOPT_set_one (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
199                        void *scls, const char *option, const char *value)
200 {
201   int *val = scls;
202
203   *val = 1;
204   return GNUNET_OK;
205 }
206
207
208 /**
209  * Set an option of type 'char *' from the command line.
210  * A pointer to this function should be passed as part of the
211  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
212  * of this type.  It should be followed by a pointer to a value of
213  * type 'char *'.
214  *
215  * @param ctx command line processing context
216  * @param scls additional closure (will point to the 'char *',
217  *             which will be allocated)
218  * @param option name of the option
219  * @param value actual value of the option (a string)
220  * @return GNUNET_OK
221  */
222 int
223 GNUNET_GETOPT_set_string (struct GNUNET_GETOPT_CommandLineProcessorContext
224                           *ctx, void *scls, const char *option,
225                           const char *value)
226 {
227   char **val = scls;
228
229   GNUNET_assert (value != NULL);
230   GNUNET_free_non_null (*val);
231   *val = GNUNET_strdup (value);
232   return GNUNET_OK;
233 }
234
235
236 /**
237  * Set an option of type 'unsigned long long' from the command line.
238  * A pointer to this function should be passed as part of the
239  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
240  * of this type.  It should be followed by a pointer to a value of
241  * type 'unsigned long long'.
242  *
243  * @param ctx command line processing context
244  * @param scls additional closure (will point to the 'unsigned long long')
245  * @param option name of the option
246  * @param value actual value of the option as a string.
247  * @return GNUNET_OK if parsing the value worked
248  */
249 int
250 GNUNET_GETOPT_set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext
251                          *ctx, void *scls, const char *option,
252                          const char *value)
253 {
254   unsigned long long *val = scls;
255
256   if (1 != SSCANF (value, "%llu", val))
257     {
258       fprintf (stderr, _("You must pass a number to the `%s' option.\n"),
259                option);
260       return GNUNET_SYSERR;
261     }
262   return GNUNET_OK;
263 }
264
265
266 /**
267  * Set an option of type 'unsigned long long' from the command line.
268  * A pointer to this function should be passed as part of the
269  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
270  * of this type.  It should be followed by a pointer to a value of
271  * type 'unsigned int'.
272  *
273  * @param ctx command line processing context
274  * @param scls additional closure (will point to the 'unsigned int')
275  * @param option name of the option
276  * @param value actual value of the option as a string.
277  * @return GNUNET_OK if parsing the value worked
278  */
279 int
280 GNUNET_GETOPT_set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
281                         void *scls, const char *option, const char *value)
282 {
283   unsigned int *val = scls;
284
285   if (1 != SSCANF (value, "%u", val))
286     {
287       fprintf (stderr, _("You must pass a number to the `%s' option.\n"),
288                option);
289       return GNUNET_SYSERR;
290     }
291   return GNUNET_OK;
292 }
293
294
295 /* end of getopt_helpers.c */