le_args.h

Go to the documentation of this file.
1 /**
2  * @page c_args Command Line Arguments API
3  *
4  * @ref le_args.h "API Reference"
5  *
6  * <HR>
7  *
8  * When a program starts, arguments may be passed from the command line.
9  *
10  * @verbatim
11 $ foo bar baz
12 @endverbatim
13  *
14  * In a traditional C/C++ program, these arguments are received as parameters to @c main().
15  * The Legato framework makes these available to component via function calls instead.
16  *
17  * @section c_args_by_index Argument Access By Index
18  *
19  * The arguments can be fetched by index using @c le_arg_GetArg(). The first argument has index 0,
20  * the second argument has index 1, etc. In the above example, <b>bar</b> has index 0 and
21  * <b>baz</b> has index 1.
22  *
23  * The number of available arguments is obtained using @c le_arg_NumArgs().
24  *
25  * The name of the program is obtained using @c le_arg_GetProgramName().
26  *
27  * The program name and all arguments are assumed to be Null-terminated UTF-8 strings. For more
28  * information about UTF-8 strings see @ref c_utf8.
29  *
30  * @section c_args_options Options
31  *
32  * Options are arguments that start with a "-" or "--".
33  *
34  * To search for a specific option, the following functions are provided:
35  * - le_arg_GetFlagOption() - Searches for a given flag (flags don't have values).
36  * - le_arg_GetIntOption() - Searches for a given option with an integer value.
37  * - le_arg_GetStringOption() - Searches for a given option with a string value.
38  *
39  * @note A "-" or "--" by itself is not considered an option. These are treated as positional
40  * arguments.
41  *
42  * @section c_args_positional Positional Arguments
43  *
44  * Positional arguments are arguments that <b>do not</b> start with a "-" or "--"; except for
45  * "-" or "--" by itself (these are positional arguments).
46  *
47  * For example, the following command line has four positional arguments ("foo", "bar", "-",
48  * and "--"). A flag option ("-x"), and two string options ("-f ./infile" and
49  * "--output=/tmp/output file") are intermixed with the positional arguments.
50  *
51  * @code
52  * $ myExe -x foo -f ./infile - "--output=/tmp/output file" bar --
53  * @endcode
54  *
55  * In this example, "foo" is the first positional argument, "-" is the
56  * second, "bar" is the third, and "--" is the fourth.
57  *
58  * Positional arguments are retrieved using the @ref c_args_scanner and
59  * le_arg_AddPositionalCallback().
60  *
61  * @section c_args_scanner Argument Scanner
62  *
63  * If you're building a command-line application with a complex argument list, you may want to
64  * use the Legato framework's argument scanner feature. It supports many options commonly seen
65  * in command-line tools and performs a lot of the error checking and reporting for you.
66  *
67  * For example, the @c commandLine sample application implements a tool called @c fileInfo that
68  * prints information about files or directories. It is flexible about the order of appearance
69  * of options on the command-line. For example, the following are equivalent:
70  *
71  * @verbatim
72 # fileInfo -x -mc 20 permissions *
73 @endverbatim
74  *
75  * @verbatim
76 # fileInfo permissions --max-count=20 * -x
77 @endverbatim
78  *
79  * Note that
80  * - "-mc 20" and "--max-count=20" are different ways of specifying the same option;
81  * - the order of appearance of the options can change;
82  * - options (which start with '-' or '--') and other arguments can be intermixed.
83  *
84  * @subsection c_args_scanner_usage Usage
85  *
86  * A program (typically inside a @c COMPONENT_INIT) can call functions to register variables
87  * to be set or call-back functions to be called when certain arguments are passed to the program.
88  *
89  * After registering the variables and call-back functions, le_arg_Scan() is called to parse
90  * the argument list.
91  *
92  * The following functions can be called before le_arg_Scan() is called to register variables
93  * to be set or call-back functions to be called by le_arg_Scan():
94  *
95  * - le_arg_SetFlagVar()
96  * - le_arg_SetIntVar()
97  * - le_arg_SetStringVar()
98  * - le_arg_SetFlagCallback()
99  * - le_arg_SetIntCallback()
100  * - le_arg_SetStringCallback()
101  * - le_arg_AddPositionalCallback()
102  *
103  * There are essentially 3 forms of function:
104  *
105  * - le_arg_SetXxxVar() - Registers a variable to be set by le_arg_Scan() when it sees a
106  * certain argument starting with '-' or '--'.
107  *
108  * - le_arg_SetXxxCallback() - Registers a call-back function to be called by le_arg_Scan() when
109  * it sees a certain argument starting with '-' or '--'.
110  *
111  * - le_arg_AddPositionalCallback() - Registers a call-back function to be called by le_arg_Scan()
112  * when it sees an argument that does not start with either
113  * '-' or '--'.
114  *
115  * le_arg_AddPositionalCallback() can be called multiple times. This constructs a list of
116  * call-back functions, where the first function in that list will be called for the first
117  * positional argument, the second function in the list will be called for the second positional
118  * argument, etc.
119  *
120  * Normally, an error will be generated if there are not the same number of positional arguments
121  * as there are positional callbacks in the list. However, this behaviour can be changed:
122  *
123  * - If le_arg_AllowMorePositionalArgsThanCallbacks() is called, then the last callback in the
124  * list will be called for each of the extra positional arguments on the command-line.
125  *
126  * - If le_arg_AllowLessPositionalArgsThanCallbacks() will allow shorter argument lists, which
127  * will result in one or more of the last callbacks in the list not being called.
128  *
129  * le_utf8_ParseInt() can be used by a positional callback to convert the string value it receives
130  * into an integer value, if needed.
131  *
132  * @subsection c_args_parser_example Example
133  *
134  * @code
135  *
136  * // Set IsExtreme to true if the -x or --extreme appears on the command-line.
137  * le_arg_SetFlagVar(&IsExtreme, "x", "extreme");
138  *
139  * // Set Count to the value N given by "-mc N" or "--max-count=N".
140  * le_arg_SetIntVar(&MaxCount, "mc", "max-count");
141  *
142  * // Register a function to be called if -h or --help appears on the command-line.
143  * le_arg_SetFlagCallback(PrintHelp, "h", "help");
144  *
145  * // The first argument that doesn't start with '-' or '--' should be a command.
146  * le_arg_AddPositionalCallback(SetCommand);
147  *
148  * // All other arguments that don't start with '-' or '--' should be file paths.
149  * le_arg_AddPositionalCallback(SetFilePath);
150  * le_arg_AllowMorePositionalArgsThanCallbacks();
151  *
152  * // Perform command-line argument processing.
153  * le_arg_Scan();
154  *
155  * @endcode
156  *
157  * @subsection c_args_parser_errorHandling Error Handling
158  *
159  * If a program wishes to try to recover from errors on the command-line or to generate its own
160  * special form of error message, it can use le_arg_SetErrorHandler() to register a callback
161  * function to be called to handle errors.
162  *
163  * If no error handler is set, the default handler will print an error message
164  * to the standard error stream and terminate the process with an exit code
165  * of EXIT_FAILURE.
166  *
167  * Error conditions that can be reported to the error handler are described in the documentation
168  * for @ref le_arg_ErrorHandlerFunc_t.
169  *
170  * @code
171  *
172  * // Set Count to the value N given by "-mc N" or "--max-count=N".
173  * le_arg_SetIntVar(&MaxCount, "mc", "max-count");
174  *
175  * // Register my own error handler.
176  * le_arg_SetErrorHandler(HandleArgError);
177  *
178  * // Perform command-line argument processing.
179  * le_arg_Scan();
180  *
181  * @endcode
182  *
183  * @section c_args_writingYourOwnMain Writing Your Own main()?
184  *
185  * If you are not using a main() function that is auto-generated by the Legato application
186  * framework's build tools (@c mksys, @c mkapp, or @c mkexe ), then you must call le_arg_SetArgs()
187  * to pass @c argc and @c argv to the argument parsing system before using any other @c le_arg
188  * functions.
189  *
190  * <HR>
191  *
192  * Copyright (C) Sierra Wireless Inc.
193  */
194 
195 //--------------------------------------------------------------------------------------------------
196 /** @file le_args.h
197  *
198  * Legato @ref c_args include file.
199  *
200  * Copyright (C) Sierra Wireless Inc.
201  */
202 
203 #ifndef LEGATO_ARGS_INCLUDE_GUARD
204 #define LEGATO_ARGS_INCLUDE_GUARD
205 
206 
207 //--------------------------------------------------------------------------------------------------
208 /**
209  * Gets the program name.
210  *
211  * @return Pointer to the null-terminated program name string.
212  */
213 //--------------------------------------------------------------------------------------------------
214 const char* le_arg_GetProgramName
215 (
216  void
217 );
218 
219 
220 //--------------------------------------------------------------------------------------------------
221 /**
222  * Gets the number of command line arguments available not including the program name.
223  *
224  * @return
225  * Number of command line arguments available.
226  */
227 //--------------------------------------------------------------------------------------------------
228 size_t le_arg_NumArgs
229 (
230  void
231 );
232 
233 
234 //--------------------------------------------------------------------------------------------------
235 /**
236  * Gets a command line argument by index.
237  *
238  * @return Pointer to the argument string (null-terminated), or NULL if the index is out of range.
239  */
240 //--------------------------------------------------------------------------------------------------
241 const char* le_arg_GetArg
242 (
243  size_t argIndex ///< [IN] Index of the argument (0 = first argument after the program name).
244 );
245 
246 
247 //--------------------------------------------------------------------------------------------------
248 /**
249  * Searches the argument list for a flag option. Can search for a short name (e.g., <c>-f</c>)
250  * or a long name (e.g., <c>--flag</c>) for the same flag at the same time.
251  *
252  * @return
253  * - LE_OK if found,
254  * - LE_NOT_FOUND if not found,
255  * - LE_FORMAT_ERROR if found but has a value (e.g., <c>--flag=foo</c>).
256  *
257  * @note If both shortName and longName are NULL, LE_NOT_FOUND will be returned.
258  **/
259 //--------------------------------------------------------------------------------------------------
261 (
262  const char* shortName, ///< [IN] Name that appears after a single '-' (can be NULL).
263  const char* longName ///< [IN] Name that appears afer a "--" (can be NULL).
264 );
265 
266 
267 //--------------------------------------------------------------------------------------------------
268 /**
269  * Searches the argument list for an option with an integer value. Can search for a short name
270  * (e.g., <c>-c 1234</c>) or a long name (e.g., <c>--count=1234</c>) form of the same option at the
271  * same time.
272  *
273  * @return
274  * - LE_OK if found and successfully converted to an integer.
275  * - LE_NOT_FOUND if not found.
276  * - LE_FORMAT_ERROR if the option wasn't provided with an integer value.
277  * - LE_OUT_OF_RANGE - Magnitude of integer value too big to be stored in an int.
278  *
279  * @note If both shortName and longName are NULL, LE_NOT_FOUND will be returned.
280  **/
281 //--------------------------------------------------------------------------------------------------
283 (
284  int* varPtr, ///< [OUT] Variable into which the value will be stored if found.
285  const char* shortName, ///< [IN] Name that appears after a single '-' (can be NULL).
286  const char* longName ///< [IN] Name that appears afer a "--" (can be NULL).
287 );
288 
289 
290 //--------------------------------------------------------------------------------------------------
291 /**
292  * Searches the argument list for an option with a string value. Can search for a short name
293  * (e.g., <c>-f foo</c>) or a long name (e.g., <c>--file=foo</c>) form of the same option at the
294  * same time.
295  *
296  * @note <c>--file=</c> is a valid string option with an empty string ("") value. The equivalent
297  * short name version of that option would be something like <c>-f ""</c>.
298  *
299  * @return
300  * - LE_OK if found.
301  * - LE_NOT_FOUND if not found.
302  * - LE_FORMAT_ERROR if the option wasn't provided with a value.
303  *
304  * @note If both shortName and longName are NULL, LE_NOT_FOUND will be returned.
305  **/
306 //--------------------------------------------------------------------------------------------------
308 (
309  const char** varPtr, ///< [OUT] Variable into which to store a pointer to the value if found.
310  const char* shortName, ///< [IN] Name that appears after a single '-' (can be NULL).
311  const char* longName ///< [IN] Name that appears afer a "--" (can be NULL).
312 );
313 
314 
315 //--------------------------------------------------------------------------------------------------
316 /**
317  * Register a boolean variable to be set if a given flag option appears on the argument list.
318  *
319  * No value is expected after the option name.
320  *
321  * One or the other of shortName or longName may be NULL.
322  * If not NULL, these MUST be pointers to strings that are never deallocated or changed.
323  **/
324 //--------------------------------------------------------------------------------------------------
326 (
327  bool* varPtr, ///< Ptr to the variable to be set true if the flag option is found.
328  const char* shortName, ///< Short form of option name (e.g., "h" will match "-h").
329  const char* longName ///< Long form of option name (e.g., "help" will match "--help").
330 );
331 
332 
333 //--------------------------------------------------------------------------------------------------
334 /**
335  * Register an integer variable to be set if a given option appears on the argument list.
336  *
337  * An integer value is expected after the option name.
338  *
339  * One or the other of shortName or longName may be NULL.
340  * If not NULL, these MUST be pointers to strings that are never deallocated or changed.
341  **/
342 //--------------------------------------------------------------------------------------------------
343 void le_arg_SetIntVar
344 (
345  int* varPtr, ///< Ptr to the variable to be set if the option is found.
346  const char* shortName, ///< Short form of option name (e.g., "n" will match "-n 1234").
347  const char* longName ///< Long form of name ("max-count" matches "--max-count=1234").
348 );
349 
350 
351 //--------------------------------------------------------------------------------------------------
352 /**
353  * Register a string variable to be set if a given option appears on the argument list.
354  *
355  * A value is expected after the option name.
356  *
357  * @code
358  * const char* namePtr = "default";
359  * le_arg_SetStringVar(&namePtr, "n", "name");
360  * @endcode
361  *
362  * One or the other of shortName or longName may be NULL.
363  * If not NULL, these MUST be pointers to strings that are never deallocated or changed.
364  **/
365 //--------------------------------------------------------------------------------------------------
367 (
368  const char** varPtr, ///< Ptr to the variable to be set if the option is found.
369  const char* shortName, ///< Short form of option name (e.g., "n" will match "-n foo").
370  const char* longName ///< Long form of name ("name" matches "--name=foo").
371 );
372 
373 
374 //--------------------------------------------------------------------------------------------------
375 /**
376  * Flag argument callback functions registered using le_arg_SetFlagCallback() must conform to this
377  * prototype.
378  *
379  * If the flag appears N times on the command line, the callback will be called N times.
380  **/
381 //--------------------------------------------------------------------------------------------------
382 typedef void (*le_arg_FlagCallbackFunc_t)(void);
383 
384 //--------------------------------------------------------------------------------------------------
385 /**
386  * Register a callback function to be called if a given flag option appears on the argument list.
387  *
388  * No value is expected after the option name.
389  *
390  * One or the other of shortName or longName may be NULL.
391  * If not NULL, these MUST be pointers to strings that are never deallocated or changed.
392  **/
393 //--------------------------------------------------------------------------------------------------
395 (
396  le_arg_FlagCallbackFunc_t func, ///< The callback function address.
397  const char* shortName, ///< Short form of option name (e.g., "h" will match "-h").
398  const char* longName ///< Long form of option name (e.g., "help" will match "--help").
399 );
400 
401 
402 //--------------------------------------------------------------------------------------------------
403 /**
404  * Integer argument callback functions registered using le_arg_SetIntCallback() must conform to
405  * this prototype.
406  *
407  * If the option appears N times on the command line, the callback will be called N times.
408  *
409  * @param value The value of the integer option.
410  **/
411 //--------------------------------------------------------------------------------------------------
412 typedef void (*le_arg_IntCallbackFunc_t)
413 (
414  int value ///< see above.
415 );
416 
417 //--------------------------------------------------------------------------------------------------
418 /**
419  * Register a callback function to be called if a given integer value option appears on the
420  * argument list.
421  *
422  * An integer value is expected after the option name.
423  *
424  * One or the other of shortName or longName may be NULL.
425  * If not NULL, these MUST be pointers to strings that are never deallocated or changed.
426  **/
427 //--------------------------------------------------------------------------------------------------
429 (
430  le_arg_IntCallbackFunc_t func, ///< The callback function address.
431  const char* shortName, ///< Short form of option name (e.g., "n" will match "-n 1234").
432  const char* longName ///< Long form of name ("max-count" matches "--max-count=1234").
433 );
434 
435 
436 //--------------------------------------------------------------------------------------------------
437 /**
438  * String argument callback functions registered using le_arg_SetStringCallback() or
439  * le_arg_AddPositionalCallback() must conform to this prototype.
440  *
441  * If the option appears N times on the command line, the callback will be called N times.
442  *
443  * @param value Pointer to the value of the string option.
444  **/
445 //--------------------------------------------------------------------------------------------------
446 typedef void (*le_arg_StringCallbackFunc_t)
447 (
448  const char* value ///< see above.
449 );
450 
451 //--------------------------------------------------------------------------------------------------
452 /**
453  * Register a callback function to be called if a given string option appears on the argument list.
454  *
455  * A string value is expected after the option name.
456  *
457  * One or the other of shortName or longName may be NULL.
458  * If not NULL, these MUST be pointers to strings that are never deallocated or changed.
459  **/
460 //--------------------------------------------------------------------------------------------------
462 (
463  le_arg_StringCallbackFunc_t func,///< The callback function address.
464  const char* shortName, ///< Short form of option name (e.g., "n" will match "-n foo").
465  const char* longName ///< Long form of name ("name" matches "--name=foo").
466 );
467 
468 
469 //--------------------------------------------------------------------------------------------------
470 /**
471  * Register a callback function to be called if an argument appears outside of any options.
472  * For example, in the following command-line, "foo" and "bar" are positional arguments (while "-l"
473  * is a flag option and "ls" is the program name):
474  *
475  * @code
476  * $ ls -l foo bar
477  * @endcode
478  *
479  * Each callback function registered using this method is added to the positional callback list.
480  * When the first positional argument is encountered, the first positional callback function is
481  * called. When the Nth positional argument is encountered, the Nth positional callback
482  * is called. If there are N positional arguments and M positional callbacks, and N > M, then
483  * the last positional callback will be called once for each positional argument from M through N,
484  * inclusive.
485  **/
486 //--------------------------------------------------------------------------------------------------
488 (
489  le_arg_StringCallbackFunc_t func ///< The callback function address.
490 );
491 
492 
493 //--------------------------------------------------------------------------------------------------
494 /**
495  * Tell the argument parser to allow more positional arguments than positional callbacks.
496  *
497  * If more positional arguments are encountered than the number of positional callbacks when this
498  * is allowed, le_arg_Scan() will call the last positional callback again for each extra positional
499  * argument it finds. If this is not allowed, le_arg_Scan() will print an error message to the
500  * standard error stream and exit the process with EXIT_FAILURE if there are more positional
501  * arguments than there are positional callbacks.
502  **/
503 //--------------------------------------------------------------------------------------------------
505 (
506  void
507 );
508 
509 
510 //--------------------------------------------------------------------------------------------------
511 /**
512  * Tell the argument parser to allow less positional arguments than positional callbacks.
513  *
514  * If less positional arguments are encountered than the number of positional callbacks when this
515  * is allowed, any positional callbacks that don't have arguments won't be called. If this is not
516  * allowed, le_arg_Scan() will print an error message to the standard error stream and exit the
517  * process with EXIT_FAILURE if there are less positional arguments than there are positional
518  * callbacks.
519  **/
520 //--------------------------------------------------------------------------------------------------
522 (
523  void
524 );
525 
526 
527 //--------------------------------------------------------------------------------------------------
528 /**
529  * Error handler function prototype. All argument error handler functions (passed into
530  * le_arg_SetErrorHandler() ) must conform to this prototype.
531  *
532  * Errors that can be reported to this function are:
533  * - LE_BAD_PARAMETER - The argument is not expected.
534  * - LE_NOT_FOUND - The argument should have a value, but no value was given.
535  * - LE_FORMAT_ERROR - The argument should have a numerical value, but was given something else.
536  * - LE_OUT_OF_RANGE - Magnitude of numerical argument too big to be stored in chosen data type.
537  * - LE_OVERFLOW - Too many positional arguments found on command line.
538  * - LE_UNDERFLOW - Too few positional arguments found on command line.
539  * - LE_UNSUPPORTED - The argument should not have a value but was given one.
540  *
541  * @return The number of arguments to skip before resuming argument scanning.
542  * 0 = resume scanning at argIndex + 1; 1 = resume at argIndex + 2; etc.
543  *
544  * @param argIndex Index of argument that is bad (0 = first arg after program name).
545  *
546  * @param errorCode Code indicating the type of error that was encountered.
547  **/
548 //--------------------------------------------------------------------------------------------------
549 typedef size_t (*le_arg_ErrorHandlerFunc_t)
550 (
551  size_t argIndex, ///< see above.
552  le_result_t errorCode ///< see above.
553 );
554 
555 
556 //--------------------------------------------------------------------------------------------------
557 /**
558  * Register an error handler function to be called by le_arg_Scan() whenever an unexpected argument
559  * is encountered or an option's value cannot be converted to the correct data type.
560  **/
561 //--------------------------------------------------------------------------------------------------
563 (
564  le_arg_ErrorHandlerFunc_t errorHandlerFunc ///< [IN] The error handler function.
565 );
566 
567 
568 //--------------------------------------------------------------------------------------------------
569 /**
570  * Scans the argument list, setting variables and calling callbacks registered using the
571  * le_arg_SetXxxVar(), le_arg_SetXxxCallback(), and le_arg_AddPositionalParameters() functions.
572  **/
573 //--------------------------------------------------------------------------------------------------
574 void le_arg_Scan
575 (
576  void
577 );
578 
579 
580 //--------------------------------------------------------------------------------------------------
581 /**
582  * Passes argc and argv to the argument parser for later use by le_arg_Scan().
583  *
584  * @note This function is normally called by main(). If the Legato application framework is
585  * automatically generating main() for you, then you can just ignore this function.
586  */
587 //--------------------------------------------------------------------------------------------------
588 void le_arg_SetArgs
589 (
590  const size_t argc, ///< [IN] argc from main().
591  char** argv ///< [IN] argv from main().
592 );
593 
594 
595 #endif // LEGATO_ARGS_INCLUDE_GUARD
size_t le_arg_NumArgs(void)
le_result_t
Definition: le_basics.h:35
le_result_t le_arg_GetIntOption(int *varPtr, const char *shortName, const char *longName)
void le_arg_SetStringCallback(le_arg_StringCallbackFunc_t func, const char *shortName, const char *longName)
void le_arg_SetStringVar(const char **varPtr, const char *shortName, const char *longName)
void le_arg_AllowMorePositionalArgsThanCallbacks(void)
void(* le_arg_FlagCallbackFunc_t)(void)
Definition: le_args.h:382
void le_arg_SetIntVar(int *varPtr, const char *shortName, const char *longName)
const char * le_arg_GetProgramName(void)
void le_arg_SetFlagCallback(le_arg_FlagCallbackFunc_t func, const char *shortName, const char *longName)
void le_arg_Scan(void)
void le_arg_SetFlagVar(bool *varPtr, const char *shortName, const char *longName)
const char * le_arg_GetArg(size_t argIndex)
void le_arg_AddPositionalCallback(le_arg_StringCallbackFunc_t func)
void(* le_arg_IntCallbackFunc_t)(int value)
Definition: le_args.h:413
void le_arg_AllowLessPositionalArgsThanCallbacks(void)
void le_arg_SetErrorHandler(le_arg_ErrorHandlerFunc_t errorHandlerFunc)
size_t(* le_arg_ErrorHandlerFunc_t)(size_t argIndex, le_result_t errorCode)
Definition: le_args.h:550
void(* le_arg_StringCallbackFunc_t)(const char *value)
Definition: le_args.h:447
void le_arg_SetArgs(const size_t argc, char **argv)
le_result_t le_arg_GetFlagOption(const char *shortName, const char *longName)
void le_arg_SetIntCallback(le_arg_IntCallbackFunc_t func, const char *shortName, const char *longName)
le_result_t le_arg_GetStringOption(const char **varPtr, const char *shortName, const char *longName)