1 /** \file popt/popt.h
2  * \ingroup popt
3  */
4 
5 /* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
6    file accompanying popt source distributions, available from
7    ftp://ftp.rpm.org/pub/rpm/dist. */
8 
9 #ifndef H_POPT
10 #define H_POPT
11 
12 #include <stdio.h>			/* for FILE * */
13 
14 #define POPT_OPTION_DEPTH	10
15 
16 /** \ingroup popt
17  * \name Arg type identifiers
18  */
19 /*@{*/
20 #define POPT_ARG_NONE		 0U	/*!< no arg */
21 #define POPT_ARG_STRING		 1U	/*!< arg will be saved as string */
22 #define POPT_ARG_INT		 2U	/*!< arg ==> int */
23 #define POPT_ARG_LONG		 3U	/*!< arg ==> long */
24 #define POPT_ARG_INCLUDE_TABLE	 4U	/*!< arg points to table */
25 #define POPT_ARG_CALLBACK	 5U	/*!< table-wide callback... must be
26 					   set first in table; arg points
27 					   to callback, descrip points to
28 					   callback data to pass */
29 #define POPT_ARG_INTL_DOMAIN     6U	/*!< set the translation domain
30 					   for this table and any
31 					   included tables; arg points
32 					   to the domain string */
33 #define POPT_ARG_VAL		 7U	/*!< arg should take value val */
34 #define	POPT_ARG_FLOAT		 8U	/*!< arg ==> float */
35 #define	POPT_ARG_DOUBLE		 9U	/*!< arg ==> double */
36 #define	POPT_ARG_LONGLONG	 10U	/*!< arg ==> long long */
37 
38 #define POPT_ARG_MAINCALL	(16U+11U)	/*!< EXPERIMENTAL: return (*arg) (argc, argv) */
39 #define	POPT_ARG_ARGV		12U	/*!< dupe'd arg appended to realloc'd argv array. */
40 #define	POPT_ARG_SHORT		13U	/*!< arg ==> short */
41 #define	POPT_ARG_BITSET		(16U+14U)	/*!< arg ==> bit set */
42 
43 #define POPT_ARG_MASK		0x000000FFU
44 #define POPT_GROUP_MASK		0x0000FF00U
45 
46 /*@}*/
47 
48 /** \ingroup popt
49  * \name Arg modifiers
50  */
51 /*@{*/
52 #define POPT_ARGFLAG_ONEDASH	0x80000000U  /*!< allow -longoption */
53 #define POPT_ARGFLAG_DOC_HIDDEN 0x40000000U  /*!< don't show in help/usage */
54 #define POPT_ARGFLAG_STRIP	0x20000000U  /*!< strip this arg from argv(only applies to long args) */
55 #define	POPT_ARGFLAG_OPTIONAL	0x10000000U  /*!< arg may be missing */
56 
57 #define	POPT_ARGFLAG_OR		0x08000000U  /*!< arg will be or'ed */
58 #define	POPT_ARGFLAG_NOR	0x09000000U  /*!< arg will be nor'ed */
59 #define	POPT_ARGFLAG_AND	0x04000000U  /*!< arg will be and'ed */
60 #define	POPT_ARGFLAG_NAND	0x05000000U  /*!< arg will be nand'ed */
61 #define	POPT_ARGFLAG_XOR	0x02000000U  /*!< arg will be xor'ed */
62 #define	POPT_ARGFLAG_NOT	0x01000000U  /*!< arg will be negated */
63 #define POPT_ARGFLAG_LOGICALOPS \
64         (POPT_ARGFLAG_OR|POPT_ARGFLAG_AND|POPT_ARGFLAG_XOR)
65 
66 #define	POPT_BIT_SET	(POPT_ARG_VAL|POPT_ARGFLAG_OR)
67 					/*!< set arg bit(s) */
68 #define	POPT_BIT_CLR	(POPT_ARG_VAL|POPT_ARGFLAG_NAND)
69 					/*!< clear arg bit(s) */
70 
71 #define	POPT_ARGFLAG_SHOW_DEFAULT 0x00800000U /*!< show default value in --help */
72 #define	POPT_ARGFLAG_RANDOM	0x00400000U  /*!< random value in [1,arg] */
73 #define	POPT_ARGFLAG_TOGGLE	0x00200000U  /*!< permit --[no]opt prefix toggle */
74 
75 /*@}*/
76 
77 /** \ingroup popt
78  * \name Callback modifiers
79  */
80 /*@{*/
81 #define POPT_CBFLAG_PRE		0x80000000U  /*!< call the callback before parse */
82 #define POPT_CBFLAG_POST	0x40000000U  /*!< call the callback after parse */
83 #define POPT_CBFLAG_INC_DATA	0x20000000U  /*!< use data from the include line,
84 					       not the subtable */
85 #define POPT_CBFLAG_SKIPOPTION	0x10000000U  /*!< don't callback with option */
86 #define POPT_CBFLAG_CONTINUE	0x08000000U  /*!< continue callbacks with option */
87 /*@}*/
88 
89 /** \ingroup popt
90  * \name Error return values
91  */
92 /*@{*/
93 #define POPT_ERROR_NOARG	-10	/*!< missing argument */
94 #define POPT_ERROR_BADOPT	-11	/*!< unknown option */
95 #define POPT_ERROR_OPTSTOODEEP	-13	/*!< aliases nested too deeply */
96 #define POPT_ERROR_BADQUOTE	-15	/*!< error in paramter quoting */
97 #define POPT_ERROR_ERRNO	-16	/*!< errno set, use strerror(errno) */
98 #define POPT_ERROR_BADNUMBER	-17	/*!< invalid numeric value */
99 #define POPT_ERROR_OVERFLOW	-18	/*!< number too large or too small */
100 #define	POPT_ERROR_BADOPERATION	-19	/*!< mutually exclusive logical operations requested */
101 #define	POPT_ERROR_NULLARG	-20	/*!< opt->arg should not be NULL */
102 #define	POPT_ERROR_MALLOC	-21	/*!< memory allocation failed */
103 #define	POPT_ERROR_BADCONFIG	-22	/*!< config file failed sanity test */
104 /*@}*/
105 
106 /** \ingroup popt
107  * \name poptBadOption() flags
108  */
109 /*@{*/
110 #define POPT_BADOPTION_NOALIAS  (1U << 0)  /*!< don't go into an alias */
111 /*@}*/
112 
113 /** \ingroup popt
114  * \name poptGetContext() flags
115  */
116 /*@{*/
117 #define POPT_CONTEXT_NO_EXEC	(1U << 0)  /*!< ignore exec expansions */
118 #define POPT_CONTEXT_KEEP_FIRST	(1U << 1)  /*!< pay attention to argv[0] */
119 #define POPT_CONTEXT_POSIXMEHARDER (1U << 2) /*!< options can't follow args */
120 #define POPT_CONTEXT_ARG_OPTS	(1U << 4) /*!< return args as options with value 0 */
121 /*@}*/
122 
123 /** \ingroup popt
124  */
125 struct poptOption {
126     const char * longName;	/*!< may be NULL */
127     char shortName;		/*!< may be NUL */
128     unsigned int argInfo;
129     void * arg;			/*!< depends on argInfo */
130     int val;			/*!< 0 means don't return, just update flag */
131     const char * descrip;	/*!< description for autohelp -- may be NULL */
132     const char * argDescrip;	/*!< argument description for autohelp */
133 };
134 
135 /** \ingroup popt
136  * A popt alias argument for poptAddAlias().
137  */
138 struct poptAlias {
139     const char * longName;	/*!< may be NULL */
140     char shortName;		/*!< may be NUL */
141     int argc;
142     const char ** argv;		/*!< must be free()able */
143 };
144 
145 /** \ingroup popt
146  * A popt alias or exec argument for poptAddItem().
147  */
148 typedef struct poptItem_s {
149     struct poptOption option;	/*!< alias/exec name(s) and description. */
150     int argc;			/*!< (alias) no. of args. */
151     const char ** argv;		/*!< (alias) args, must be free()able. */
152 } * poptItem;
153 
154 /** \ingroup popt
155  * \name Auto-generated help/usage
156  */
157 /*@{*/
158 
159 /**
160  * Empty table marker to enable displaying popt alias/exec options.
161  */
162 extern struct poptOption poptAliasOptions[];
163 #define POPT_AUTOALIAS { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptAliasOptions, \
164 			0, "Options implemented via popt alias/exec:", NULL },
165 
166 /**
167  * Auto help table options.
168  */
169 extern struct poptOption poptHelpOptions[];
170 
171 extern struct poptOption * poptHelpOptionsI18N;
172 
173 #define POPT_AUTOHELP { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptHelpOptions, \
174 			0, "Help options:", NULL },
175 
176 #define POPT_TABLEEND { NULL, '\0', 0, NULL, 0, NULL, NULL }
177 /*@}*/
178 
179 /** \ingroup popt
180  */
181 typedef struct poptContext_s * poptContext;
182 
183 /** \ingroup popt
184  */
185 #ifndef __cplusplus
186 typedef struct poptOption * poptOption;
187 #endif
188 
189 /** \ingroup popt
190  */
191 enum poptCallbackReason {
192     POPT_CALLBACK_REASON_PRE	= 0,
193     POPT_CALLBACK_REASON_POST	= 1,
194     POPT_CALLBACK_REASON_OPTION = 2
195 };
196 
197 #ifdef __cplusplus
198 extern "C" {
199 #endif
200 
201 /** \ingroup popt
202  * Table callback prototype.
203  * @param con		context
204  * @param reason	reason for callback
205  * @param opt		option that triggered callback
206  * @param arg		@todo Document.
207  * @param data		@todo Document.
208  */
209 typedef void (*poptCallbackType) (poptContext con,
210 		enum poptCallbackReason reason,
211 		const struct poptOption * opt,
212 		const char * arg,
213 		const void * data);
214 
215 /** \ingroup popt
216  * Destroy context.
217  * @param con		context
218  * @return		NULL always
219  */
220 poptContext poptFreeContext( poptContext con);
221 
222 /** \ingroup popt
223  * Initialize popt context.
224  * @param name		context name (usually argv[0] program name)
225  * @param argc		no. of arguments
226  * @param argv		argument array
227  * @param options	address of popt option table
228  * @param flags		or'd POPT_CONTEXT_* bits
229  * @return		initialized popt context
230  */
231 poptContext poptGetContext(
232 		const char * name,
233 		int argc, const char ** argv,
234 		const struct poptOption * options,
235 		unsigned int flags);
236 
237 /** \ingroup popt
238  * Destroy context (alternative implementation).
239  * @param con		context
240  * @return		NULL always
241  */
242 poptContext poptFini( poptContext con);
243 
244 /** \ingroup popt
245  * Initialize popt context (alternative implementation).
246  * This routine does poptGetContext() and then poptReadConfigFiles().
247  * @param argc		no. of arguments
248  * @param argv		argument array
249  * @param options	address of popt option table
250  * @param configPaths	colon separated file path(s) to read.
251  * @return		initialized popt context (NULL on error).
252  */
253 poptContext poptInit(int argc, const char ** argv,
254 		const struct poptOption * options,
255 		const char * configPaths);
256 
257 /** \ingroup popt
258  * Reinitialize popt context.
259  * @param con		context
260  */
261 void poptResetContext(poptContext con);
262 
263 /** \ingroup popt
264  * Return value of next option found.
265  * @param con		context
266  * @return		next option val, -1 on last item, POPT_ERROR_* on error
267  */
268 int poptGetNextOpt(poptContext con);
269 
270 /** \ingroup popt
271  * Return next option argument (if any).
272  * @param con		context
273  * @return		option argument, NULL if no argument is available
274  */
275 char * poptGetOptArg(poptContext con);
276 
277 /** \ingroup popt
278  * Return next argument.
279  * @param con		context
280  * @return		next argument, NULL if no argument is available
281  */
282 const char * poptGetArg(poptContext con);
283 
284 /** \ingroup popt
285  * Peek at current argument.
286  * @param con		context
287  * @return		current argument, NULL if no argument is available
288  */
289 const char * poptPeekArg(poptContext con)
290 	/*@*/;
291 
292 /** \ingroup popt
293  * Return remaining arguments.
294  * @param con		context
295  * @return		argument array, NULL terminated
296  */
297 const char ** poptGetArgs(poptContext con);
298 
299 /** \ingroup popt
300  * Return the option which caused the most recent error.
301  * @param con		context
302  * @param flags
303  * @return		offending option
304  */
305 const char * poptBadOption(poptContext con, unsigned int flags)
306 	/*@*/;
307 
308 /** \ingroup popt
309  * Add arguments to context.
310  * @param con		context
311  * @param argv		argument array, NULL terminated
312  * @return		0 on success, POPT_ERROR_OPTSTOODEEP on failure
313  */
314 int poptStuffArgs(poptContext con, const char ** argv);
315 
316 /** \ingroup popt
317  * Add alias to context.
318  * @todo Pass alias by reference, not value.
319  * @deprecated Use poptAddItem instead.
320  * @param con		context
321  * @param alias		alias to add
322  * @param flags		(unused)
323  * @return		0 on success
324  */
325 int poptAddAlias(poptContext con, struct poptAlias alias, int flags);
326 
327 /** \ingroup popt
328  * Add alias/exec item to context.
329  * @param con		context
330  * @param newItem	alias/exec item to add
331  * @param flags		0 for alias, 1 for exec
332  * @return		0 on success
333  */
334 int poptAddItem(poptContext con, poptItem newItem, int flags);
335 
336 /** \ingroup popt
337  * Test path/file for config file sanity (regular file, permissions etc)
338  * @param fn		file name
339  * @return		1 on OK, 0 on NOTOK.
340  */
341 int poptSaneFile(const char * fn);
342 
343 /**
344  * Read a file into a buffer.
345  * @param fn		file name
346  * @retval *bp		buffer (malloc'd) (or NULL)
347  * @retval *nbp		no. of bytes in buffer (including final NUL) (or NULL)
348  * @param flags		1 to trim escaped newlines
349  * return		0 on success
350  */
351 int poptReadFile(const char * fn, char ** bp,
352 		size_t * nbp, int flags);
353 #define	POPT_READFILE_TRIMNEWLINES	1
354 
355 /** \ingroup popt
356  * Read configuration file.
357  * @param con		context
358  * @param fn		file name to read
359  * @return		0 on success, POPT_ERROR_ERRNO on failure
360  */
361 int poptReadConfigFile(poptContext con, const char * fn);
362 
363 /** \ingroup popt
364  * Read configuration file(s).
365  * Colon separated files to read, looping over poptReadConfigFile().
366  * Note that an '@' character preceeding a path in the list will
367  * also perform additional sanity checks on the file before reading.
368  * @param con		context
369  * @param paths		colon separated file name(s) to read
370  * @return		0 on success, POPT_ERROR_BADCONFIG on failure
371  */
372 int poptReadConfigFiles(poptContext con, const char * paths);
373 
374 /** \ingroup popt
375  * Read default configuration from /etc/popt and $HOME/.popt.
376  * @param con		context
377  * @param useEnv	(unused)
378  * @return		0 on success, POPT_ERROR_ERRNO on failure
379  */
380 int poptReadDefaultConfig(poptContext con, int useEnv);
381 
382 /** \ingroup popt
383  * Duplicate an argument array.
384  * @note: The argument array is malloc'd as a single area, so only argv must
385  * be free'd.
386  *
387  * @param argc		no. of arguments
388  * @param argv		argument array
389  * @retval argcPtr	address of returned no. of arguments
390  * @retval argvPtr	address of returned argument array
391  * @return		0 on success, POPT_ERROR_NOARG on failure
392  */
393 int poptDupArgv(int argc, const char **argv,
394 		int * argcPtr,
395 		const char *** argvPtr);
396 
397 /** \ingroup popt
398  * Parse a string into an argument array.
399  * The parse allows ', ", and \ quoting, but ' is treated the same as " and
400  * both may include \ quotes.
401  * @note: The argument array is malloc'd as a single area, so only argv must
402  * be free'd.
403  *
404  * @param s		string to parse
405  * @retval argcPtr	address of returned no. of arguments
406  * @retval argvPtr	address of returned argument array
407  */
408 int poptParseArgvString(const char * s,
409 		int * argcPtr, const char *** argvPtr);
410 
411 /** \ingroup popt
412  * Parses an input configuration file and returns an string that is a
413  * command line.  For use with popt.  You must free the return value when done.
414  *
415  * Given the file:
416 \verbatim
417 # this line is ignored
418     #   this one too
419 aaa
420   bbb
421     ccc
422 bla=bla
423 
424 this_is   =   fdsafdas
425      bad_line=
426   reall bad line
427   reall bad line  = again
428 5555=   55555
429   test = with lots of spaces
430 \endverbatim
431 *
432 * The result is:
433 \verbatim
434 --aaa --bbb --ccc --bla="bla" --this_is="fdsafdas" --5555="55555" --test="with lots of spaces"
435 \endverbatim
436 *
437 * Passing this to poptParseArgvString() yields an argv of:
438 \verbatim
439 '--aaa'
440 '--bbb'
441 '--ccc'
442 '--bla=bla'
443 '--this_is=fdsafdas'
444 '--5555=55555'
445 '--test=with lots of spaces'
446 \endverbatim
447  *
448  * @bug NULL is returned if file line is too long.
449  * @bug Silently ignores invalid lines.
450  *
451  * @param fp		file handle to read
452  * @param *argstrp	return string of options (malloc'd)
453  * @param flags		unused
454  * @return		0 on success
455  * @see			poptParseArgvString
456  */
457 int poptConfigFileToString(FILE *fp, char ** argstrp, int flags);
458 
459 /** \ingroup popt
460  * Return formatted error string for popt failure.
461  * @param error		popt error
462  * @return		error string
463  */
464 const char * poptStrerror(const int error);
465 
466 /** \ingroup popt
467  * Limit search for executables.
468  * @param con		context
469  * @param path		single path to search for executables
470  * @param allowAbsolute	absolute paths only?
471  */
472 void poptSetExecPath(poptContext con, const char * path, int allowAbsolute);
473 
474 /** \ingroup popt
475  * Print detailed description of options.
476  * @param con		context
477  * @param fp		ouput file handle
478  * @param flags		(unused)
479  */
480 void poptPrintHelp(poptContext con, FILE * fp, int flags);
481 
482 /** \ingroup popt
483  * Print terse description of options.
484  * @param con		context
485  * @param fp		ouput file handle
486  * @param flags		(unused)
487  */
488 void poptPrintUsage(poptContext con, FILE * fp, int flags);
489 
490 /** \ingroup popt
491  * Provide text to replace default "[OPTION...]" in help/usage output.
492  * @param con		context
493  * @param text		replacement text
494  */
495 void poptSetOtherOptionHelp(poptContext con, const char * text);
496 
497 /** \ingroup popt
498  * Return argv[0] from context.
499  * @param con		context
500  * @return		argv[0]
501  */
502 const char * poptGetInvocationName(poptContext con)
503 	/*@*/;
504 
505 /** \ingroup popt
506  * Shuffle argv pointers to remove stripped args, returns new argc.
507  * @param con		context
508  * @param argc		no. of args
509  * @param argv		arg vector
510  * @return		new argc
511  */
512 int poptStrippedArgv(poptContext con, int argc, char ** argv);
513 
514 /**
515  * Add a string to an argv array.
516  * @retval *argvp	argv array
517  * @param argInfo	(unused)
518  * @param val		string arg to add (using strdup)
519  * @return		0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION
520  */
521 int poptSaveString(const char *** argvp, unsigned int argInfo,
522 		const char * val);
523 
524 /**
525  * Save a long long, performing logical operation with value.
526  * @warning Alignment check may be too strict on certain platorms.
527  * @param arg		integer pointer, aligned on int boundary.
528  * @param argInfo	logical operation (see POPT_ARGFLAG_*)
529  * @param aLongLong	value to use
530  * @return		0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION
531  */
532 int poptSaveLongLong(long long * arg, unsigned int argInfo,
533 		long long aLongLong);
534 
535 /**
536  * Save a long, performing logical operation with value.
537  * @warning Alignment check may be too strict on certain platorms.
538  * @param arg		integer pointer, aligned on int boundary.
539  * @param argInfo	logical operation (see POPT_ARGFLAG_*)
540  * @param aLong		value to use
541  * @return		0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION
542  */
543 int poptSaveLong(long * arg, unsigned int argInfo, long aLong);
544 
545 /**
546  * Save a short integer, performing logical operation with value.
547  * @warning Alignment check may be too strict on certain platorms.
548  * @param arg		short pointer, aligned on short boundary.
549  * @param argInfo	logical operation (see POPT_ARGFLAG_*)
550  * @param aLong		value to use
551  * @return		0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION
552  */
553 int poptSaveShort(short * arg, unsigned int argInfo, long aLong);
554 
555 /**
556  * Save an integer, performing logical operation with value.
557  * @warning Alignment check may be too strict on certain platorms.
558  * @param arg		integer pointer, aligned on int boundary.
559  * @param argInfo	logical operation (see POPT_ARGFLAG_*)
560  * @param aLong		value to use
561  * @return		0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION
562  */
563 int poptSaveInt(int * arg, unsigned int argInfo, long aLong);
564 
565 /* The bit set typedef. */
566 typedef struct poptBits_s {
567     unsigned int bits[1];
568 } * poptBits;
569 
570 #define _POPT_BITS_N    1024U    /* estimated population */
571 #define _POPT_BITS_M    ((3U * _POPT_BITS_N) / 2U)
572 #define _POPT_BITS_K    16U      /* no. of linear hash combinations */
573 
574 extern unsigned int _poptBitsN;
575 extern  unsigned int _poptBitsM;
576 extern  unsigned int _poptBitsK;
577 
578 int poptBitsAdd(poptBits bits, const char * s);
579 int poptBitsChk(poptBits bits, const char * s);
580 int poptBitsClr(poptBits bits);
581 int poptBitsDel(poptBits bits, const char * s);
582 int poptBitsIntersect(poptBits * ap, const poptBits b);
583 int poptBitsUnion(poptBits * ap, const poptBits b);
584 int poptBitsArgs(poptContext con, poptBits * ap);
585 
586 /**
587  * Save a string into a bit set (experimental).
588  * @retval *bits	bit set (lazily malloc'd if NULL)
589  * @param argInfo	logical operation (see POPT_ARGFLAG_*)
590  * @param s		string to add to bit set
591  * @return		0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION
592  */
593 int poptSaveBits(poptBits * bitsp, unsigned int argInfo,
594 		const char * s);
595 
596 
597 #ifdef  __cplusplus
598 }
599 #endif
600 
601 #endif
602