-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 GNUNET_GETOPT_CommandLineProcessorContext
172                                *ctx, void *scls, const char *option,
173                                const char *value)
174 {
175   int *val = scls;
176
177   (*val)++;
178   return GNUNET_OK;
179 }
180
181
182 /**
183  * Set an option of type 'int' from the command line to 1 if the
184  * given option is present.
185  * A pointer to this function should be passed as part of the
186  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
187  * of this type.  It should be followed by a pointer to a value of
188  * type 'int'.
189  *
190  * @param ctx command line processing context
191  * @param scls additional closure (will point to the 'int')
192  * @param option name of the option
193  * @param value not used (NULL)
194  * @return GNUNET_OK
195  */
196 int
197 GNUNET_GETOPT_set_one (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
198                        void *scls, const char *option, const char *value)
199 {
200   int *val = scls;
201
202   *val = 1;
203   return GNUNET_OK;
204 }
205
206
207 /**
208  * Set an option of type 'char *' from the command line.
209  * A pointer to this function should be passed as part of the
210  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
211  * of this type.  It should be followed by a pointer to a value of
212  * type 'char *'.
213  *
214  * @param ctx command line processing context
215  * @param scls additional closure (will point to the 'char *',
216  *             which will be allocated)
217  * @param option name of the option
218  * @param value actual value of the option (a string)
219  * @return GNUNET_OK
220  */
221 int
222 GNUNET_GETOPT_set_string (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
223                           void *scls, const char *option, const char *value)
224 {
225   char **val = scls;
226
227   GNUNET_assert (value != NULL);
228   GNUNET_free_non_null (*val);
229   *val = GNUNET_strdup (value);
230   return GNUNET_OK;
231 }
232
233
234 /**
235  * Set an option of type 'unsigned long long' from the command line.
236  * A pointer to this function should be passed as part of the
237  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
238  * of this type.  It should be followed by a pointer to a value of
239  * type 'unsigned long long'.
240  *
241  * @param ctx command line processing context
242  * @param scls additional closure (will point to the 'unsigned long long')
243  * @param option name of the option
244  * @param value actual value of the option as a string.
245  * @return GNUNET_OK if parsing the value worked
246  */
247 int
248 GNUNET_GETOPT_set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
249                          void *scls, const char *option, const char *value)
250 {
251   unsigned long long *val = scls;
252
253   if (1 != SSCANF (value, "%llu", val))
254   {
255     FPRINTF (stderr, _("You must pass a number to the `%s' option.\n"), option);
256     return GNUNET_SYSERR;
257   }
258   return GNUNET_OK;
259 }
260
261
262 /**
263  * Set an option of type 'unsigned int' from the command line.
264  * A pointer to this function should be passed as part of the
265  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
266  * of this type.  It should be followed by a pointer to a value of
267  * type 'unsigned int'.
268  *
269  * @param ctx command line processing context
270  * @param scls additional closure (will point to the 'unsigned int')
271  * @param option name of the option
272  * @param value actual value of the option as a string.
273  * @return GNUNET_OK if parsing the value worked
274  */
275 int
276 GNUNET_GETOPT_set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
277                         void *scls, const char *option, const char *value)
278 {
279   unsigned int *val = scls;
280
281   if (1 != SSCANF (value, "%u", val))
282   {
283     FPRINTF (stderr, _("You must pass a number to the `%s' option.\n"), option);
284     return GNUNET_SYSERR;
285   }
286   return GNUNET_OK;
287 }
288
289
290 /* end of getopt_helpers.c */