1 /*
2  * Defines for a generic argv and argc processor...
3  *
4  * Copyright 2000 by Gray Watson
5  *
6  * This file is part of the argv library.
7  *
8  * Permission to use, copy, modify, and distribute this software for
9  * any purpose and without fee is hereby granted, provided that the
10  * above copyright notice and this permission notice appear in all
11  * copies, and that the name of Gray Watson not be used in advertising
12  * or publicity pertaining to distribution of the document or software
13  * without specific, written prior permission.
14  *
15  * Gray Watson makes no representations about the suitability of the
16  * software described herein for any purpose.  It is provided "as is"
17  * without express or implied warranty.
18  *
19  * The author may be contacted via http://256.com/gray/
20  *
21  * $Id: argv.h.1,v 1.22 2010/02/15 13:59:37 gray Exp $
22  */
23 
24 #ifndef __ARGV_H__
25 #define __ARGV_H__
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #if 0
30 }
31 #endif
32 #endif
33 
34 /*
35  * Version string for the library
36  *
37  * NOTE to gray: whenever this is changed, corresponding Changlog and
38  * NEWS entries *must* be entered and argv.texi updated.
39  *
40  * ARGV LIBRARY VERSION -- 2.7.0
41  */
42 
43 /* argv version defines */
44 #define ARGV_VERSION_MAJOR	2	/* X.0.0 */
45 #define ARGV_VERSION_MINOR	7	/* 0.X.0 */
46 #define ARGV_VERSION_PATCH	0	/* 0.0.X */
47 
48 /* produced by configure, inserted into argv.h */
49 /* used to handle the const operator */
50 /* const is available */
51 
52 /* NOTE: start of $Id: argv.h.3,v 1.33 2007/01/08 20:32:57 gray Exp $ */
53 
54 /*
55  * Generic and standardized argument processor.  You describe the arguments
56  * that you are looking for along with their types and these routines do the
57  * work to convert them into values.
58  *
59  * These routines also provide standardized error and usage messages as well
60  * as good usage documentation and long and short options.
61  */
62 
63 #include <stdio.h>			/* have to for FILE * below */
64 
65 /* this defines what type the standard void memory-pointer is */
66 #if (defined(__STDC__) && __STDC__ == 1) || defined(__cplusplus)
67 #define ARGV_PNT	void *
68 #else
69 #define ARGV_PNT	char *
70 #endif
71 
72 /*
73  * argument information structure.  this specifies the allowable options
74  * and some information about each one.
75  *
76  * { 'O',  "optimize",  ARGV_BOOL,  &optimize,  NULL,  "turn on optimization" }
77  * { 'c',  "config",  ARGV_CHAR_P,  &config,  "file",  "configuration file" }
78  */
79 typedef struct {
80   char		ar_short_arg;		/* short argument, 'd' if '-d' */
81   const char	*ar_long_arg;		/* long version of arg, '--delete' */
82   unsigned int	ar_type;		/* type of option, see values below */
83   ARGV_PNT	ar_variable;		/* address of associated variable */
84   const char	*ar_var_label;		/* label for variable description */
85   const char	*ar_comment;		/* comment for usage message */
86 } argv_t;
87 
88 /*
89  * Argument array type.  when ARGV_FLAG_ARRAY is |'d with the ar_type
90  * in the above structure then multiple instances of the option are
91  * allowed and each instance is stored into the following structure
92  * that MUST be in ar_variable in the above arg_t structure.
93  *
94  * NOTE: after the arguments have been processed, if aa_entryn is > 0
95  * then aa_entries needs to be free'd by user. argv_cleanup() can be
96  * used for this
97  */
98 typedef struct {
99   int		aa_entry_n;		/* number of elements in aa_entrees */
100   ARGV_PNT	aa_entries;		/* entry list specified */
101 } argv_array_t;
102 
103 /*  extract the count of the elements from an argv ARRAY */
104 #define ARGV_ARRAY_COUNT(array)		((array).aa_entry_n)
105 
106 /* extract WHICH entry of TYPE from an argv ARRAY */
107 #define ARGV_ARRAY_ENTRY(array, type, which)	\
108 	(((type *)(array).aa_entries)[which])
109 
110 /* extract a pointer to WHICH entry of TYPE from an argv ARRAY */
111 #define ARGV_ARRAY_ENTRY_P(array, type, which)	\
112 	(((type *)(array).aa_entries) + which)
113 
114 /* special ar_short_arg value to mark the last entry in the argument array */
115 #define ARGV_LAST	((char)255)
116 
117 /*
118  * special ar_short_arg value to mark mandatory arguments (i.e. arguments that
119  * *must* be specified.  for arguments that are not optional like [-b].
120  * to have a variable number of mandatory args then make the last MAND
121  * entry be a ARG_ARRAY type.
122  */
123 #define ARGV_MAND	((char)254)
124 
125 /*
126  * special ar_short_arg value to mark that there is the possibility of
127  * a mandatory argument here if one is specified.
128  */
129 #define ARGV_MAYBE	((char)253)
130 
131 /*
132  * special ar_short_arg value to say that the previous and next arguments in
133  * the list should not be used together.
134  * {'a'...}, {ARG_OR}, {'b'...}, {ARG_OR}, {'c'...} means
135  * the user should only specific -a or -b or -c but not 2 or more.
136  */
137 #define ARGV_OR		((char)252)
138 
139 /*
140  * special ar_short_arg value that is the same as ARGV_OR but one of the args
141  * must be used.
142  * {'a'...}, {ARG_ONE_OF}, {'b'...}, {ARG_ONE_OF}, {'c'...} means
143  * the user must specify one of -a or -b or -c but not 2 or more.
144  * ARGV_XOR is there for compatibility with older versions.
145  */
146 #define ARGV_ONE_OF	((char)251)
147 #define ARGV_XOR	((char)251)
148 
149 /*
150  * ar_type values of arg_t
151  * NOTE: if this list is changed, some defines in argv_loc need to be changed
152  */
153 #define ARGV_BOOL	1		/* boolean type, sets to ARGV_TRUE */
154 #define ARGV_BOOL_NEG	2		/* like bool but sets to ARGV_FALSE */
155 #define ARGV_BOOL_ARG	3		/* like bool but takes a yes/no arg */
156 #define ARGV_CHAR	4		/* single character */
157 #define ARGV_CHAR_P	5		/* same as STRING */
158 #define ARGV_SHORT	6		/* short integer number */
159 #define ARGV_U_SHORT	7		/* unsigned short integer number */
160 #define ARGV_INT	8		/* integer number */
161 #define ARGV_U_INT	9		/* unsigned integer number */
162 #define ARGV_LONG	10		/* long integer number */
163 #define ARGV_U_LONG	11		/* unsinged long integer number */
164 #define ARGV_FLOAT	12		/* floating pointer number */
165 #define ARGV_DOUBLE	13		/* double floating pointer number */
166 #define ARGV_BIN	14		/* binary number (0s and 1s) */
167 #define ARGV_OCT	15		/* octal number, (base 8) */
168 #define ARGV_HEX	16		/* hexadecimal number, (base 16) */
169 #define ARGV_INCR	17		/* int arg which gets ++ each time */
170 #define ARGV_SIZE	18		/* long arg which knows mMbBkKgG */
171 #define ARGV_U_SIZE	19		/* u_long arg which knows mMbBkKgG */
172 #define ARGV_BOOL_INT	20		/* like bool but takes an integer var*/
173 #define ARGV_BOOL_INT_NEG 21		/* like bool-neg but with an integer */
174 #define ARGV_BOOL_INT_ARG 22		/* like bool-arg but with an integer */
175 
176 #define ARGV_TYPE(t)	((t) & 0x3F)	/* strip off all but the var type */
177 #define ARGV_FLAG_ARRAY	(1 << 14)	/* OR with type to indicate array */
178 #define ARGV_FLAG_MAND	(1 << 13)	/* OR with type to mark mandatory */
179 /* NOTE: other internal flags defined in argv_loc.h */
180 
181 /* argv_usage which argument values */
182 #define ARGV_USAGE_NONE		0	/* no usage messages -- special */
183 #define ARGV_USAGE_SHORT	1	/* print short usage messages */
184 #define ARGV_USAGE_LONG		2	/* print long-format usage messages */
185 #define ARGV_USAGE_DEFAULT	3	/* default usage messages */
186 #define ARGV_USAGE_SEE		4	/* say see --usage for more info */
187 #define ARGV_USAGE_SHORT_REM	5	/* short + reminder how to get long */
188 #define ARGV_USAGE_ALL		6	/* all usage information */
189 
190 /* boolean type settings */
191 #define ARGV_FALSE		0
192 #define ARGV_TRUE		1
193 
194 /*<<<<<<<<<<  The below prototypes are auto-generated by fillproto */
195 
196 /* This is a processed version of argv[0], pre-path removed: /bin/ls -> ls */
197 extern
198 char	argv_program[/* PROGRAM_NAME + 1 */];
199 
200 /* A global value of argv from main after argv_process has been called */
201 extern
202 char	**argv_argv;
203 
204 /* A global value of argc from main after argv_process has been called */
205 extern
206 int	argv_argc;
207 
208 /* This should be set externally to provide general program help to user */
209 extern
210 char	*argv_help_string;
211 
212 /* This should be set externally to provide version information to the user */
213 extern
214 char	*argv_version_string;
215 
216 /*
217  * Are we running interactively?  This will exit on errors.  Set to
218  * false to return error codes instead.
219  */
220 extern
221 int 	argv_interactive;
222 
223 /*
224  * The FILE stream that argv out_puts all its errors.  Set to NULL to
225  * not dump any error messages.  Default is stderr.
226  */
227 extern
228 FILE 	*argv_error_stream;
229 
230 /*
231  * This is the error code to exit with when we have a usage error and
232  * we are in interactive mode.
233  */
234 extern
235 int	argv_error_code;
236 
237 /*
238  * Set to 1 (the default) to enable the handling of -l=foo or
239  * --logfile=foo type of arguments.  Set to 0 to disable.  This allows
240  * you to specifically assign a value to an argument.
241  */
242 extern
243 int	argv_close_enable_b;
244 
245 /*
246  * If the library sees a "--" argument, it will turn off further
247  * argument process.  Set to 1 to enable the ability of specifying
248  * additional "--" arguments to reenable (basically toggle on then
249  * off) argument processing.  Set to 0 (the default) to disable this
250  * behavior.
251  */
252 extern
253 int	argv_last_toggle_b;
254 
255 /*
256  * Set to 1 (the default) to have the library accept multiple usage of
257  * the same argument.  Set to 0 to have the library generate an error
258  * if you use an argument twice.
259  */
260 extern
261 int	argv_multi_accept_b;
262 
263 /*
264  * Set to one of the ARGV_USAGE_ defines in the argv.h file.  This
265  * tell the library what usage information to display when --usage is
266  * specified by the user.  Default is ARGV_USAGE_LONG.
267  */
268 extern
269 int	argv_usage_type;
270 
271 /*
272  * Set to one of the ARGV_USAGE_ defines in the argv.h file.  This
273  * tell the library what usage information to display when an error is
274  * encountered.  The usage information accompanies the error message.
275  * Default is ARGV_USAGE_SEE.
276  */
277 extern
278 int	argv_error_type;
279 
280 /*
281  * Set to 1 (the default) if you want the library look for associated
282  * arguments from the associated program's environmental variable.  If
283  * set the 0 then no environmental variable will be used.  If you are
284  * running program foo then the library will look for the
285  * environmental variable ARGV_foo and will add those to the argument
286  * list specified on the command line.  By default they will be
287  * inserted in front of those on the command line unless the
288  * argv_env_after_b is set to 1.
289  *
290  * NOTE: this is set by argv_process automatically.  If you do not
291  * want this behavior, you should use argv_process_no_env.
292  */
293 extern
294 int	argv_process_env_b;
295 
296 /*
297  * Set to 1 if you want the library to append the arguments from the
298  * program's environmental variable after those specified on the
299  * command line.  If set the 0 (the default) then they will be
300  * inserted before those specified on the command line.  See
301  * argv_process_env_b for more information.
302  */
303 extern
304 int	argv_env_after_b;
305 
306 /*
307  * int argv_process_no_env
308  *
309  * DESCRIPTION:
310  *
311  * Process the user arguments with an argv_t structure array.  Like
312  * argv_process_args but without the processing of the argv
313  * environmental variables.
314  *
315  * RETURNS:
316  *
317  * Success - 0
318  *
319  * Failure - -1
320  *
321  * ARGUMENTS:
322  *
323  * args - Array of argv_t structures.
324  *
325  * arg_c - Number of arguments in the argv array.
326  *
327  * argv - Array of character pointers terminated by 0L.
328  */
329 extern
330 int	argv_process_no_env(argv_t *args, const int arg_c, char **argv);
331 
332 /*
333  * int argv_process
334  *
335  * DESCRIPTION:
336  *
337  * Processes a number of arguments depending on the argument array.
338  * This routine will not modify the argv array in any way.
339  *
340  * NOTE: it will modify the args array by setting various flags in the
341  * type field.  returns 0 if no error else -1.
342  *
343  * ARGUMENTS:
344  *
345  * args - Array of argv_t structures that we are using to process the
346  * user argument array.  If null then an empty array is used.
347  *
348  * argc - Number of arguments in the argv argument array.
349  *
350  * argv - Array of character pointer arguments terminated by a 0L.
351  */
352 extern
353 int	argv_process(argv_t *args, const int argc, char **argv);
354 
355 /*
356  * int argv_usage
357  *
358  * DESCRIPTION:
359  *
360  * Print the standard usage messages for our argument array.  You can
361  * specify whether you want to see a short or long usage messages.
362  *
363  * NOTE: if this is called before argv_process then the program name
364  * may be invalid.
365  *
366  * RETURNS:
367  *
368  * Success - 0
369  *
370  * Failure - -1
371  *
372  * ARGUMENTS:
373  *
374  * args - Our argument array to print the usage messages about.  If
375  * null then an empty array is used.
376  *
377  * which - Either ARGV_USAGE_SHORT (for short usage messages),
378  * ARGV_USAGE_LONG (for long usage messages), or ARGV_USAGE_DEFAULT
379  * (the user's default either long or short).
380  */
381 extern
382 int	argv_usage(const argv_t *args, const int which);
383 
384 /*
385  * int argv_was_used
386  *
387  * DESCRIPTION:
388  *
389  * See if an argument was used in a previous call to argv_process.
390  *
391  * RETURNS:
392  *
393  * 1 if yes it was used, else 0 if not.
394  *
395  * ARGUMENTS:
396  *
397  * args - Argument list to search.
398  *
399  * short_arg - Short argument to see if it was used.
400  */
401 extern
402 int	argv_was_used(const argv_t *args, const char short_arg);
403 
404 /*
405  * int argv_long_was_used
406  *
407  * DESCRIPTION:
408  *
409  * See if a long argument was used in a previous call to argv_process.
410  *
411  * RETURNS:
412  *
413  * 1 if yes it was used, else 0 if not.
414  *
415  * ARGUMENTS:
416  *
417  * args - Argument list to search.
418  *
419  * long_arg - Long argument to see if it was used.
420  */
421 extern
422 int	argv_long_was_used(const argv_t *args, const char *long_arg);
423 
424 /*
425  * int argv_entry_was_used
426  *
427  * DESCRIPTION:
428  *
429  * See if an entry in the argument array was used in a previous call
430  * to argv_process.
431  *
432  * RETURNS:
433  *
434  * 1 if yes it was used, else 0 if not.
435  *
436  * ARGUMENTS:
437  *
438  * argv_entry_p - Pointer to an entry in a argv_t list.
439  */
440 extern
441 int	argv_entry_was_used(const argv_t *argv_entry_p);
442 
443 /*
444  * void argv_cleanup
445  *
446  * DESCRIPTION:
447  *
448  * Frees up any allocations associated with the argument array during
449  * argv_process.  This should be done at the end of the program or
450  * after all the arguments have been referenced.
451  *
452  * RETURNS:
453  *
454  * None.
455  *
456  * ARGUMENTS:
457  *
458  * args - Argument array we are cleaning up.
459  */
460 extern
461 void	argv_cleanup(const argv_t *args);
462 
463 /*
464  * int argv_copy_args
465  *
466  * DESCRIPTION:
467  *
468  * Copy all the arguements (not including the 0th) one after the other
469  * into the user specified buffer.
470  *
471  * NOTE: you can get the 0th argument from argv_argv[0] or
472  * argv_program.
473  *
474  * RETURNS:
475  *
476  * Success - 0
477  *
478  * Failure - -1
479  *
480  * ARGUMENTS:
481  *
482  * buf - Buffer to copy all of the user arguments into.
483  *
484  * buf_size - Size of the buffer.
485  */
486 extern
487 int	argv_copy_args(char *buf, const int buf_size);
488 
489 /*
490  * int argv_value_string
491  *
492  * DESCRIPTION:
493  *
494  * Convert the value of a RC entry to its string equivalent in the
495  * buffer provided.
496  *
497  * RETURNS:
498  *
499  * Length of bytes copied into the buffer.
500  *
501  * ARGUMENTS:
502  *
503  * argv_entry_p - Pointer to an entry in a argv_t list.
504  *
505  * buf - Buffer to convert the value into.
506  *
507  * buf_size - Size of the buffer.
508  */
509 extern
510 int	argv_value_string(const argv_t *argv_entry_p, char *buf,
511 			  const int buf_size);
512 
513 /*
514  * int argv_type_info
515  *
516  * DESCRIPTION:
517  *
518  * Get internal information about the type of the argument.
519  *
520  * RETURNS:
521  *
522  * The name of the type.
523  *
524  * ARGUMENTS:
525  *
526  * type - Number of argument type.
527  *
528  * size_p - Pointer to an unsigned integer which, if not NULL, will be
529  * set with the size of the type.
530  *
531  * desc_p - Pointer to a constant character pointer which, if not
532  * NULL, will be pointed to a description of the type.
533  */
534 extern
535 const char	*argv_type_info(const unsigned int type, unsigned int *size_p,
536 				const char **desc_p);
537 
538 /*<<<<<<<<<<   This is end of the auto-generated output from fillproto. */
539 
540 #ifdef __cplusplus
541 #if 0
542 {
543 #endif
544 }
545 #endif
546 
547 #endif /* ! __ARGV_H__ */
548