1 /* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* ====================================================================
3  * Copyright (c) 1999-2004 Carnegie Mellon University.  All rights
4  * reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  *
18  * This work was supported in part by funding from the Defense Advanced
19  * Research Projects Agency and the National Science Foundation of the
20  * United States of America, and the CMU Sphinx Speech Consortium.
21  *
22  * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
23  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
26  * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  * ====================================================================
35  *
36  */
37 /*
38  * cmd_ln.h -- Command line argument parsing.
39  *
40  * **********************************************
41  * CMU ARPA Speech Project
42  *
43  * Copyright (c) 1999 Carnegie Mellon University.
44  * ALL RIGHTS RESERVED.
45  * **********************************************
46  *
47  * HISTORY
48  *
49  * 15-Jul-1997	M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
50  * 		Added required arguments types.
51  *
52  * 07-Dec-96	M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
53  * 		Created, based on Eric's implementation.  Basically, combined several
54  *		functions into one, eliminated validation, and simplified the interface.
55  */
56 
57 
58 #ifndef _LIBUTIL_CMD_LN_H_
59 #define _LIBUTIL_CMD_LN_H_
60 
61 #include <stdio.h>
62 #include <stdarg.h>
63 
64 /* Win32/WinCE DLL gunk */
65 #include <sphinxbase/sphinxbase_export.h>
66 #include <sphinxbase/prim_type.h>
67 
68 /**
69  * @file cmd_ln.h
70  * @brief Command-line and other configurationparsing and handling.
71  *
72  * Configuration parameters, optionally parsed from the command line.
73  */
74 
75 
76 #ifdef __cplusplus
77 extern "C" {
78 #endif
79 #if 0
80 /* Fool Emacs. */
81 }
82 #endif
83 
84 /**
85  * @struct arg_t
86  * Argument definition structure.
87  */
88 typedef struct arg_s {
89 	char const *name;   /**< Name of the command line switch */
90 	int type;           /**< Type of the argument in question */
91 	char const *deflt;  /**< Default value (as a character string), or NULL if none */
92 	char const *doc;    /**< Documentation/description string */
93 } arg_t;
94 
95 /**
96  * @name Values for arg_t::type
97  */
98 /* @{ */
99 /**
100  * Bit indicating a required argument.
101  */
102 #define ARG_REQUIRED (1<<0)
103 /**
104  * Integer argument (optional).
105  */
106 #define ARG_INTEGER  (1<<1)
107 /**
108  * Floating point argument (optional).
109  */
110 #define ARG_FLOATING (1<<2)
111 /**
112  * String argument (optional).
113  */
114 #define ARG_STRING   (1<<3)
115 /**
116  * Boolean (true/false) argument (optional).
117  */
118 #define ARG_BOOLEAN  (1<<4)
119 /**
120  * Boolean (true/false) argument (optional).
121  */
122 #define ARG_STRING_LIST  (1<<5)
123 
124 /**
125  * Required integer argument.
126  */
127 #define REQARG_INTEGER (ARG_INTEGER | ARG_REQUIRED)
128 /**
129  * Required floating point argument.
130  */
131 #define REQARG_FLOATING (ARG_FLOATING | ARG_REQUIRED)
132 /**
133  * Required string argument.
134  */
135 #define REQARG_STRING (ARG_STRING | ARG_REQUIRED)
136 /**
137  * Required boolean argument.
138  */
139 #define REQARG_BOOLEAN (ARG_BOOLEAN | ARG_REQUIRED)
140 
141 /**
142  * @deprecated Use ARG_INTEGER instead.
143  */
144 #define ARG_INT32   ARG_INTEGER
145 /**
146  * @deprecated Use ARG_FLOATING instead.
147  */
148 #define ARG_FLOAT32 ARG_FLOATING
149 /**
150  * @deprecated Use ARG_FLOATING instead.
151  */
152 #define ARG_FLOAT64 ARG_FLOATING
153 /**
154  * @deprecated Use REQARG_INTEGER instead.
155  */
156 #define REQARG_INT32 (ARG_INT32 | ARG_REQUIRED)
157 /**
158  * @deprecated Use REQARG_FLOATING instead.
159  */
160 #define REQARG_FLOAT32 (ARG_FLOAT32 | ARG_REQUIRED)
161 /**
162  * @deprecated Use REQARG_FLOATING instead.
163  */
164 #define REQARG_FLOAT64 (ARG_FLOAT64 | ARG_REQUIRED)
165 /* @} */
166 
167 
168 /**
169  * Helper macro to stringify enums and other non-string values for
170  * default arguments.
171  **/
172 #define ARG_STRINGIFY(s) ARG_STRINGIFY1(s)
173 #define ARG_STRINGIFY1(s) #s
174 
175 /**
176  * @struct cmd_ln_t
177  * Opaque structure used to hold the results of command-line parsing.
178  */
179 typedef struct cmd_ln_s cmd_ln_t;
180 
181 /**
182  * Create a cmd_ln_t from NULL-terminated list of arguments.
183  *
184  * This function creates a cmd_ln_t from a NULL-terminated list of
185  * argument strings.  For example, to create the equivalent of passing
186  * "-hmm foodir -dsratio 2 -lm bar.lm" on the command-line:
187  *
188  *  config = cmd_ln_init(NULL, defs, TRUE, "-hmm", "foodir", "-dsratio", "2",
189  *                       "-lm", "bar.lm", NULL);
190  *
191  * Note that for simplicity, <strong>all</strong> arguments are passed
192  * as strings, regardless of the actual underlying type.
193  *
194  * @param inout_cmdln Previous command-line to update, or NULL to create a new one.
195  * @param defn Array of argument name definitions, or NULL to allow any arguments.
196  * @param strict Whether to fail on duplicate or unknown arguments.
197  * @return A cmd_ln_t* containing the results of command line parsing, or NULL on failure.
198  */
199 SPHINXBASE_EXPORT
200 cmd_ln_t *cmd_ln_init(cmd_ln_t *inout_cmdln, arg_t const *defn, int32 strict, ...);
201 
202 /**
203  * Retain ownership of a command-line argument set.
204  *
205  * @return pointer to retained command-line argument set.
206  */
207 SPHINXBASE_EXPORT
208 cmd_ln_t *cmd_ln_retain(cmd_ln_t *cmdln);
209 
210 /**
211  * Release a command-line argument set and all associated strings.
212  *
213  * @return new reference count (0 if freed completely)
214  */
215 SPHINXBASE_EXPORT
216 int cmd_ln_free_r(cmd_ln_t *cmdln);
217 
218 /**
219  * Parse a list of strings into argumetns.
220  *
221  * Parse the given list of arguments (name-value pairs) according to
222  * the given definitions.  Argument values can be retrieved in future
223  * using cmd_ln_access().  argv[0] is assumed to be the program name
224  * and skipped.  Any unknown argument name causes a fatal error.  The
225  * routine also prints the prevailing argument values (to stderr)
226  * after parsing.
227  *
228  * @note It is currently assumed that the strings in argv are
229  *       allocated statically, or at least that they will be valid as
230  *       long as the cmd_ln_t returned from this function.
231  *       Unpredictable behaviour will result if they are freed or
232  *       otherwise become invalidated.
233  *
234  * @return A cmd_ln_t containing the results of command line parsing,
235  *         or NULL on failure.
236  **/
237 SPHINXBASE_EXPORT
238 cmd_ln_t *cmd_ln_parse_r(cmd_ln_t *inout_cmdln, /**< In/Out: Previous command-line to update,
239                                                      or NULL to create a new one. */
240                          arg_t const *defn,	/**< In: Array of argument name definitions */
241                          int32 argc,		/**< In: Number of actual arguments */
242                          char *argv[],		/**< In: Actual arguments */
243                          int32 strict           /**< In: Fail on duplicate or unknown
244                                                    arguments, or no arguments? */
245     );
246 
247 /**
248  * Parse an arguments file by deliminating on " \r\t\n" and putting each tokens
249  * into an argv[] for cmd_ln_parse().
250  *
251  * @return A cmd_ln_t containing the results of command line parsing, or NULL on failure.
252  */
253 SPHINXBASE_EXPORT
254 cmd_ln_t *cmd_ln_parse_file_r(cmd_ln_t *inout_cmdln, /**< In/Out: Previous command-line to update,
255                                                      or NULL to create a new one. */
256                               arg_t const *defn,   /**< In: Array of argument name definitions*/
257                               char const *filename,/**< In: A file that contains all
258                                                      the arguments */
259                               int32 strict         /**< In: Fail on duplicate or unknown
260                                                      arguments, or no arguments? */
261     );
262 
263 /**
264  * Access the generic type union for a command line argument.
265  */
266 SPHINXBASE_EXPORT
267 anytype_t *cmd_ln_access_r(cmd_ln_t *cmdln, char const *name);
268 
269 /**
270  * Retrieve a string from a command-line object.
271  *
272  * The command-line object retains ownership of this string, so you
273  * should not attempt to free it manually.
274  *
275  * @param cmdln Command-line object.
276  * @param name the command-line flag to retrieve.
277  * @return the string value associated with <tt>name</tt>, or NULL if
278  *         <tt>name</tt> does not exist.  You must use
279  *         cmd_ln_exists_r() to distinguish between cases where a
280  *         value is legitimately NULL and where the corresponding flag
281  *         is unknown.
282  */
283 SPHINXBASE_EXPORT
284 char const *cmd_ln_str_r(cmd_ln_t *cmdln, char const *name);
285 
286 /**
287  * Retrieve an array of strings from a command-line object.
288  *
289  * The command-line object retains ownership of this array, so you
290  * should not attempt to free it manually.
291  *
292  * @param cmdln Command-line object.
293  * @param name the command-line flag to retrieve.
294  * @return the array of strings associated with <tt>name</tt>, or NULL if
295  *         <tt>name</tt> does not exist.  You must use
296  *         cmd_ln_exists_r() to distinguish between cases where a
297  *         value is legitimately NULL and where the corresponding flag
298  *         is unknown.
299  */
300 SPHINXBASE_EXPORT
301 char const **cmd_ln_str_list_r(cmd_ln_t *cmdln, char const *name);
302 
303 /**
304  * Retrieve an integer from a command-line object.
305  *
306  * @param cmdln Command-line object.
307  * @param name the command-line flag to retrieve.
308  * @return the integer value associated with <tt>name</tt>, or 0 if
309  *         <tt>name</tt> does not exist.  You must use
310  *         cmd_ln_exists_r() to distinguish between cases where a
311  *         value is legitimately zero and where the corresponding flag
312  *         is unknown.
313  */
314 SPHINXBASE_EXPORT
315 long cmd_ln_int_r(cmd_ln_t *cmdln, char const *name);
316 
317 /**
318  * Retrieve a floating-point number from a command-line object.
319  *
320  * @param cmdln Command-line object.
321  * @param name the command-line flag to retrieve.
322  * @return the float value associated with <tt>name</tt>, or 0.0 if
323  *         <tt>name</tt> does not exist.  You must use
324  *         cmd_ln_exists_r() to distinguish between cases where a
325  *         value is legitimately zero and where the corresponding flag
326  *         is unknown.
327  */
328 SPHINXBASE_EXPORT
329 double cmd_ln_float_r(cmd_ln_t *cmdln, char const *name);
330 
331 /**
332  * Retrieve a boolean value from a command-line object.
333  */
334 #define cmd_ln_boolean_r(c,n) (cmd_ln_int_r(c,n) != 0)
335 
336 /**
337  * Set a string in a command-line object.
338  *
339  * @param cmdln Command-line object.
340  * @param name The command-line flag to set.
341  * @param str String value to set.  The command-line object does not
342  *            retain ownership of this pointer.
343  */
344 SPHINXBASE_EXPORT
345 void cmd_ln_set_str_r(cmd_ln_t *cmdln, char const *name, char const *str);
346 
347 /**
348  * Set an integer in a command-line object.
349  *
350  * @param cmdln Command-line object.
351  * @param name The command-line flag to set.
352  * @param iv Integer value to set.
353  */
354 SPHINXBASE_EXPORT
355 void cmd_ln_set_int_r(cmd_ln_t *cmdln, char const *name, long iv);
356 
357 /**
358  * Set a floating-point number in a command-line object.
359  *
360  * @param cmdln Command-line object.
361  * @param name The command-line flag to set.
362  * @param fv Integer value to set.
363  */
364 SPHINXBASE_EXPORT
365 void cmd_ln_set_float_r(cmd_ln_t *cmdln, char const *name, double fv);
366 
367 /**
368  * Set a boolean value in a command-line object.
369  */
370 #define cmd_ln_set_boolean_r(c,n,b) (cmd_ln_set_int_r(c,n,(b)!=0))
371 
372 /*
373  * Compatibility macros
374  */
375 #define cmd_ln_int32_r(c,n)	(int32)cmd_ln_int_r(c,n)
376 #define cmd_ln_float32_r(c,n)	(float32)cmd_ln_float_r(c,n)
377 #define cmd_ln_float64_r(c,n)	(float64)cmd_ln_float_r(c,n)
378 #define cmd_ln_set_int32_r(c,n,i)   cmd_ln_set_int_r(c,n,i)
379 #define cmd_ln_set_float32_r(c,n,f) cmd_ln_set_float_r(c,n,(double)f)
380 #define cmd_ln_set_float64_r(c,n,f) cmd_ln_set_float_r(c,n,(double)f)
381 
382 /**
383  * Re-entrant version of cmd_ln_exists().
384  *
385  * @return True if the command line argument exists (i.e. it
386  * was one of the arguments defined in the call to cmd_ln_parse_r().
387  */
388 SPHINXBASE_EXPORT
389 int cmd_ln_exists_r(cmd_ln_t *cmdln, char const *name);
390 
391 /**
392  * Print a help message listing the valid argument names, and the associated
393  * attributes as given in defn.
394  */
395 SPHINXBASE_EXPORT
396 void cmd_ln_print_help_r (cmd_ln_t *cmdln,
397                           FILE *fp,	   /**< In: File to which to print */
398 			  const arg_t *defn /**< In: Array of argument name definitions */
399 	);
400 
401 /**
402  * Non-reentrant version of cmd_ln_parse().
403  *
404  * @deprecated This is deprecated in favor of the re-entrant API
405  * function cmd_ln_parse_r().
406  * @return 0 if successful, <0 if error.
407  */
408 SPHINXBASE_EXPORT
409 int32 cmd_ln_parse(const arg_t *defn,  /**< In: Array of argument name definitions */
410                    int32 argc,	       /**< In: Number of actual arguments */
411                    char *argv[],       /**< In: Actual arguments */
412                    int32 strict        /**< In: Fail on duplicate or unknown
413                                           arguments, or no arguments? */
414 	);
415 
416 /**
417  * Parse an arguments file by deliminating on " \r\t\n" and putting each tokens
418  * into an argv[] for cmd_ln_parse().
419  *
420  * @deprecated This is deprecated in favor of the re-entrant API
421  * function cmd_ln_parse_file_r().
422  *
423  * @return 0 if successful, <0 on error.
424  */
425 SPHINXBASE_EXPORT
426 int32 cmd_ln_parse_file(const arg_t *defn,   /**< In: Array of argument name definitions*/
427 			char const *filename,/**< In: A file that contains all the arguments */
428                         int32 strict         /**< In: Fail on duplicate or unknown
429                                                 arguments, or no arguments? */
430 	);
431 
432 /**
433  * Old application initialization routine for Sphinx3 code.
434  *
435  * @deprecated This is deprecated in favor of the re-entrant API.
436  */
437 SPHINXBASE_EXPORT
438 void cmd_ln_appl_enter(int argc,   /**< In: Number of actual arguments */
439 		       char *argv[], /**< In: Number of actual arguments */
440 		       char const* default_argfn, /**< In: default argument file name*/
441 		       const arg_t *defn /**< Command-line argument definition */
442 	);
443 
444 
445 /**
446  * Finalization routine corresponding to cmd_ln_appl_enter().
447  *
448  * @deprecated This is deprecated in favor of the re-entrant API.
449  */
450 
451 SPHINXBASE_EXPORT
452 void cmd_ln_appl_exit(void);
453 
454 /**
455  * Retrieve the global cmd_ln_t object used by non-re-entrant functions.
456  *
457  * @deprecated This is deprecated in favor of the re-entrant API.
458  * @return global cmd_ln_t object.
459  */
460 SPHINXBASE_EXPORT
461 cmd_ln_t *cmd_ln_get(void);
462 
463 /**
464  * Test the existence of a command-line argument in the global set of
465  * definitions.
466  *
467  * @deprecated This is deprecated in favor of the re-entrant API
468  * function cmd_ln_exists_r().
469  *
470  * @return True if the command line argument exists (i.e. it
471  * was one of the arguments defined in the call to cmd_ln_parse().
472  */
473 #define cmd_ln_exists(name)	cmd_ln_exists_r(cmd_ln_get(), name)
474 
475 /**
476  * Return a pointer to the previously parsed value for the given argument name.
477  *
478  * @deprecated This is deprecated in favor of the re-entrant API
479  * function cmd_ln_access_r().
480  */
481 #define cmd_ln_access(name)	cmd_ln_access_r(cmd_ln_get(), name)
482 
483 /**
484  * Retrieve a string from the global command line.
485  *
486  * @deprecated This is deprecated in favor of the re-entrant API
487  * function cmd_ln_str_r().
488  */
489 #define cmd_ln_str(name)	cmd_ln_str_r(cmd_ln_get(), name)
490 
491 /**
492  * Retrieve an array of strings in the global command line.
493  *
494  * @deprecated This is deprecated in favor of the re-entrant API
495  * function cmd_ln_str_list_r().
496  */
497 #define cmd_ln_str_list(name)	cmd_ln_str_list_r(cmd_ln_get(), name)
498 
499 /**
500  * Retrieve a 32-bit integer from the global command line.
501  *
502  * @deprecated This is deprecated in favor of the re-entrant API
503  * function cmd_ln_int_r().
504  */
505 #define cmd_ln_int32(name)	(int32)cmd_ln_int_r(cmd_ln_get(), name)
506 /**
507  * Retrieve a 32-bit float from the global command line.
508  *
509  * @deprecated This is deprecated in favor of the re-entrant API
510  * function cmd_ln_float_r().
511  */
512 #define cmd_ln_float32(name)	(float32)cmd_ln_float_r(cmd_ln_get(), name)
513 /**
514  * Retrieve a 64-bit float from the global command line.
515  *
516  * @deprecated This is deprecated in favor of the re-entrant API
517  * function cmd_ln_float_r().
518  */
519 #define cmd_ln_float64(name)	(float64)cmd_ln_float_r(cmd_ln_get(), name)
520 /**
521  * Retrieve a boolean from the global command line.
522  *
523  * @deprecated This is deprecated in favor of the re-entrant API
524  * function cmd_ln_boolean_r().
525  */
526 #define cmd_ln_boolean(name)	cmd_ln_boolean_r(cmd_ln_get(), name)
527 
528 /**
529  * Set a string in the global command line.
530  *
531  * @deprecated This is deprecated in favor of the re-entrant API
532  * function cmd_ln_set_str_r().
533  */
534 #define cmd_ln_set_str(n,s)     cmd_ln_set_str_r(cmd_ln_get(),n,s)
535 /**
536  * Set a 32-bit integer value in the global command line.
537  *
538  * @deprecated This is deprecated in favor of the re-entrant API
539  * function cmd_ln_set_int_r().
540  */
541 #define cmd_ln_set_int32(n,i)   cmd_ln_set_int_r(cmd_ln_get(),n,i)
542 /**
543  * Set a 32-bit float in the global command line.
544  *
545  * @deprecated This is deprecated in favor of the re-entrant API
546  * function cmd_ln_set_float_r().
547  */
548 #define cmd_ln_set_float32(n,f) cmd_ln_set_float_r(cmd_ln_get(),n,f)
549 /**
550  * Set a 64-bit float in the global command line.
551  *
552  * @deprecated This is deprecated in favor of the re-entrant API
553  * function cmd_ln_set_float_r().
554  */
555 #define cmd_ln_set_float64(n,f) cmd_ln_set_float_r(cmd_ln_get(),n,f)
556 /**
557  * Set a boolean value in the global command line.
558  *
559  * @deprecated This is deprecated in favor of the re-entrant API
560  * function cmd_ln_set_boolean_r().
561  */
562 #define cmd_ln_set_boolean(n,b) cmd_ln_set_boolean_r(cmd_ln_get(),n,b)
563 
564 /**
565  * Print a help message listing the valid argument names, and the associated
566  * attributes as given in defn.
567  *
568  * @deprecated This is deprecated in favor of the re-entrant API
569  * function cmd_ln_print_help_r().
570  */
571 #define cmd_ln_print_help(f,d) cmd_ln_print_help_r(cmd_ln_get(),f,d)
572 
573 /**
574  * Free the global command line, if any exists.
575  * @deprecated Use the re-entrant API instead.
576  */
577 SPHINXBASE_EXPORT
578 void cmd_ln_free (void);
579 
580 
581 #ifdef __cplusplus
582 }
583 #endif
584 
585 #endif
586 
587 
588