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