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