1 /* LIBDGL -- a Directed Graph Library implementation
2  * Copyright (C) 2002 Roberto Micarelli
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 /* best view tabstop=4
20  */
21 
22 /*@*********************************************************************
23  * @pack:       GNO_PACK
24  * @descr:      Command line options utility.
25  *
26  * @notes:      Support to easily parse command line options. Some concepts
27  *                      were taken from the posix getopt() family functions, while
28  *                      our specific experience in C programming suggested us a
29  *                      proprietary implementation to make source code more readable
30  *                      at life easier (I hope).
31  *                      Option format:
32  *
33  *                      syntax                          name
34  *                      ----------------------------------------------
35  *                      --option=value          long-parametric
36  *                      --option                        long-boolean
37  *                      -option value           short-parametric
38  *                      -option                         short-boolean
39  *
40  *              C sample:
41  *              ----------------------------------------------
42  *              #include <stdio.h>
43  *              #include <opt.h>
44  *
45  *              int main( int argc , char ** argv )
46  *              {
47  *                      Boolean         fHelp;
48  *                      Boolean         fTcp;
49  *                      Boolean         fUdp;
50  *                      char    *       pszProtocol;
51  *                      char    *       pszInterface;
52  *                      int                     i;
53  *
54  *                      GNO_BEGIN
55  *                      GNO_SWITCH( "h", "help", False , & fHelp , "Print this help." )
56  *                      GNO_SWITCH( "t", "tcp", False , & fTcp , NULL )
57  *                      GNO_SWITCH( "u", "udp", False , & fUdp , NULL )
58  *                      GNO_OPTION( "p", "protocol", "tcp" , & pszProtocol , NULL )
59  *                      GNO_OPTION( "i", "interface", "eth0" , & pszInterface , NULL )
60  *                      GNO_END
61  *
62  *
63  *                      if ( GNO_PARSE( argc , argv ) < 0 )
64  *                      {
65  *                              return 1;
66  *                      }
67  *
68  *                      if ( fHelp == True )
69  *                      {
70  *                              GNO_HELP( "t_opt usage" );
71  *                              return 0;
72  *                      }
73  *
74  *                      printf ( "t/tcp  = %s\n", (fTcp  == True) ? "True" : "False" );
75  *                      printf ( "u/udp  = %s\n", (fUdp  == True) ? "True" : "False" );
76  *                      printf ( "p/protocol  = <%s>\n", pszProtocol );
77  *                      printf ( "i/interface = <%s>\n", pszInterface );
78  *
79  *                      GNO_FREE();
80  *
81  *                      printf( "orphan options:\n" );
82  *
83  *                      for ( i = 0 ; i < argc ; i ++ )
84  *                      {
85  *                              if ( argv[ i ] )
86  *                              {
87  *                                      printf( "arg %d: %s\n", i, argv[i ] );
88  *                              }
89  *                              else
90  *                              {
91  *                                      printf( "arg %d: --\n", i );
92  *                              }
93  *                      }
94  *                      return 0;
95  *              }
96  *
97  **********************************************************************/
98 
99 #ifndef _GNOPT_H_
100 #define _GNOPT_H_
101 
102 #ifdef __cplusplus
103 extern "C"
104 {
105 #endif
106 
107 /***********************************************************************
108  *				DEFINES
109  **********************************************************************/
110     /*@*--------------------------------------------------------------------
111      * @defs:       GNO_FLG
112      * @descr:      flags used to set the nFlg field in the GnoOption_s
113      *                      SWITCH    = boolean option required
114      *
115      * @see:        GnoOption_s
116      *
117      *--------------------------------------------------------------------*/
118 
119 #define GNO_FLG_SWITCH		0x01
120 
121     /*@*--------------------------------------------------------------------
122      * @defs:       True/False
123      * @descr:      one more useful (?) true/false definition
124      *
125      *--------------------------------------------------------------------*/
126 #define True  1
127 #define False 0
128 
129 /***********************************************************************
130  *				STRUCTS/UNIONS/TYPES/FUNCDEFS
131  **********************************************************************/
132     /*@*--------------------------------------------------------------------
133      * @type:       Boolean
134      * @descr:      wasn't it better to use 'int'?
135      *--------------------------------------------------------------------*/
136     typedef int Boolean;
137 
138     /*@*--------------------------------------------------------------------
139      * @type:       GnoOption_s
140      * @descr:      This structure describes an option. We intend to use an array
141      *          of GnoOption_s, terminated by a 'NULL' entry (one containing
142      *                      all binary-zero fields), and to pass it to GnoParse() together
143      *                      with the typical argc,argv couple of main() args. The array's
144      *                      entries are looked-up and filled with coherent argc,argv
145      *                      values. Some fields are statically filled by user while other
146      *                      are returned by the GnoParse() function.
147      *                      Fields set by the user:
148      *
149      *                      nFlg      = So far the only supported flag is GNO_FLG_SWITCH
150      *                                  to address a boolean option type.
151      *                      fDef      = The default value for a boolean option.
152      *                      pszDef    = The default value for a parametric option.
153      *                      pszShort  = The short name of the option.
154      *                      pszLong   = The long name of the option.
155      *                      pfValue   = Pointer to a boolean option return value.
156      *                      ppszValue = Pointer to a parametric option return value.
157      *                      pszDescr  = A brief option description
158      *
159      *                      Fields set by GnoParse():
160      *
161      *                      iArg       = argv option index
162      *                      *ppszValue = pointer to parametric option value
163      *                      *pfValue   = True/False
164      *
165      *                      User supplied fields are mandatory only within specific
166      *                      conditions:
167      *
168      *                      - at least one of pszShort/pszLong must be specified
169      *                      - fDef and pfValue apply to a boolean option only
170      *                      - pszDef and ppszValue apply to a parametric option only
171      *                      - pszDescr is optional
172      *
173      * @see:        GnoParse(), GNO_FLG
174      *
175      *--------------------------------------------------------------------*/
176 
177     typedef struct GnoOption
178     {
179 	int iArg;		/* returned argv option index */
180 	int nFlg;		/* flags describing the option */
181 	Boolean fDef;		/* default returned value for a boolean option */
182 	char *pszDef;		/* default returned value for a parametric option */
183 	char *pszShort;		/* short-option recogniser */
184 	char *pszLong;		/* long-option recogniser */
185 	Boolean *pfValue;	/* address to return a boolean option */
186 	char **ppszValue;	/* address to return a parametric option */
187 	char *pszDescr;		/* a brief option description */
188 
189     } GnoOption_s;
190 
191 
192 /***********************************************************************
193  *				MACROS
194  **********************************************************************/
195     /*@*--------------------------------------------------------------------
196      *
197      * @macro:      GNO_BEGIN
198      * @descr:      Begin an option array declaration
199      *
200      * @notes:      The best use is to start option declaration immediately after
201      *                      the automatic-variable declaration in the main() function.
202      *
203      *--------------------------------------------------------------------*/
204 #define GNO_BEGIN GnoOption_s _aopt[] = {
205 
206     /*@*--------------------------------------------------------------------
207      *
208      * @macro:      GNO_OPTION
209      * @descr:      Declare a parametric option
210      *
211      *
212      * @args:       I:      chsopt  =       short option character
213      *                      I:      pszlopt ->      long option psz
214      *                      I:      pszdef  ->      default-returned psz
215      *                      I:      ppszv   ->      user-addressed return variable pointer
216      *
217      *--------------------------------------------------------------------*/
218 #define GNO_OPTION(pszsopt,pszlopt,pszdef,ppszv,pszdescr) \
219 			{ 0, 0, 0, pszdef, pszsopt, pszlopt, NULL, ppszv, pszdescr },
220 
221     /*@*--------------------------------------------------------------------
222      *
223      * @macro:      GNO_SWITCH
224      * @descr:      Declare a boolean option
225      *
226      * @args:       I:      chsopt  =       short option character
227      *                      I:      pszlopt ->      long option psz
228      *                      I:      fdef    =       default-returned Boolean
229      *                      I:      pfv             ->      user-addressed return variable pointer
230      *
231      *--------------------------------------------------------------------*/
232 #define GNO_SWITCH(pszsopt,pszlopt,fdef,pfv,pszdescr) \
233 			{	\
234 				0, \
235 				GNO_FLG_SWITCH, \
236 				fdef, NULL, \
237 				pszsopt, pszlopt, \
238 				pfv, NULL, \
239 				pszdescr \
240 			},
241 
242     /*@*--------------------------------------------------------------------
243      *
244      * @macro:      GNO_PARSE
245      * @descr:      Parse a GnoOption_s array declaration
246      *
247      * @args:       I:      argc    =       count of argv entries
248      *                      I:      argv    ->      array of sz pointers
249      *
250      *--------------------------------------------------------------------*/
251 #define GNO_PARSE(argc,argv) GnoParse( (argc), (argv), _aopt )
252 
253     /*@*--------------------------------------------------------------------
254      *
255      * @macro:      GNO_END
256      * @descr:      Terminate an option array declaration
257      *
258      *--------------------------------------------------------------------*/
259 #define GNO_END	{ 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } };
260 
261     /*@*--------------------------------------------------------------------
262      *
263      * @macro:      GNO_HELP
264      *
265      * @descr:      Print a brief option's help on the standard error
266      *
267      * @args:       I:      pszhead ->      help header string
268      *
269      *--------------------------------------------------------------------*/
270 #define GNO_HELP(pszhead) GnoHelp( pszhead , _aopt )
271 
272     /*@*--------------------------------------------------------------------
273      *
274      * @macro:      GNO_FREE
275      *
276      * @descr:      Free resources created by a previously parsed array
277      *
278      *
279      *--------------------------------------------------------------------*/
280 #define GNO_FREE() GnoFree( _aopt )
281 
282 
283 /***********************************************************************
284  *				FUNCTION PROTOTYPES
285  **********************************************************************/
286 
287     extern int GnoParse(int argc, char **argv, GnoOption_s * pOpt);
288 
289     extern void GnoFree(GnoOption_s * pOpt);
290 
291     extern void GnoHelp(char *pszHead, GnoOption_s * pOpt);
292 
293 
294 #ifdef __cplusplus
295 }
296 #endif
297 
298 #endif				/* top of file */
299 
300 /***************************** END OF FILE ****************************/
301