00001 /* LIBDGL -- a Directed Graph Library implementation 00002 * Copyright (C) 2002 Roberto Micarelli 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 */ 00018 00019 /* best view tabstop=4 00020 */ 00021 00022 /*@********************************************************************* 00023 * @pack: GNO_PACK 00024 * @descr: Command line options utility. 00025 * 00026 * @notes: Support to easily parse command line options. Some concepts 00027 * were taken from the posix getopt() family functions, while 00028 * our specific experience in C programming suggested us a 00029 * proprietary implementation to make source code more readable 00030 * at life easier (I hope). 00031 * Option format: 00032 * 00033 * syntax name 00034 * ---------------------------------------------- 00035 * --option=value long-parametric 00036 * --option long-boolean 00037 * -option value short-parametric 00038 * -option short-boolean 00039 * 00040 * C sample: 00041 * ---------------------------------------------- 00042 * #include <stdio.h> 00043 * #include <opt.h> 00044 * 00045 * int main( int argc , char ** argv ) 00046 * { 00047 * Boolean fHelp; 00048 * Boolean fTcp; 00049 * Boolean fUdp; 00050 * char * pszProtocol; 00051 * char * pszInterface; 00052 * int i; 00053 * 00054 * GNO_BEGIN 00055 * GNO_SWITCH( "h", "help", False , & fHelp , "Print this help." ) 00056 * GNO_SWITCH( "t", "tcp", False , & fTcp , NULL ) 00057 * GNO_SWITCH( "u", "udp", False , & fUdp , NULL ) 00058 * GNO_OPTION( "p", "protocol", "tcp" , & pszProtocol , NULL ) 00059 * GNO_OPTION( "i", "interface", "eth0" , & pszInterface , NULL ) 00060 * GNO_END 00061 * 00062 * 00063 * if ( GNO_PARSE( argc , argv ) < 0 ) 00064 * { 00065 * return 1; 00066 * } 00067 * 00068 * if ( fHelp == True ) 00069 * { 00070 * GNO_HELP( "t_opt usage" ); 00071 * return 0; 00072 * } 00073 * 00074 * printf ( "t/tcp = %s\n", (fTcp == True) ? "True" : "False" ); 00075 * printf ( "u/udp = %s\n", (fUdp == True) ? "True" : "False" ); 00076 * printf ( "p/protocol = <%s>\n", pszProtocol ); 00077 * printf ( "i/interface = <%s>\n", pszInterface ); 00078 * 00079 * GNO_FREE(); 00080 * 00081 * printf( "orphan options:\n" ); 00082 * 00083 * for ( i = 0 ; i < argc ; i ++ ) 00084 * { 00085 * if ( argv[ i ] ) 00086 * { 00087 * printf( "arg %d: %s\n", i, argv[i ] ); 00088 * } 00089 * else 00090 * { 00091 * printf( "arg %d: --\n", i ); 00092 * } 00093 * } 00094 * return 0; 00095 * } 00096 * 00097 **********************************************************************/ 00098 00099 #ifndef _GNOPT_H_ 00100 #define _GNOPT_H_ 00101 00102 #ifdef __cplusplus 00103 extern "C" { 00104 #endif 00105 00106 /*********************************************************************** 00107 * DEFINES 00108 **********************************************************************/ 00109 /*@*-------------------------------------------------------------------- 00110 * @defs: GNO_FLG 00111 * @descr: flags used to set the nFlg field in the GnoOption_s 00112 * SWITCH = boolean option required 00113 * 00114 * @see: GnoOption_s 00115 * 00116 *--------------------------------------------------------------------*/ 00117 00118 #define GNO_FLG_SWITCH 0x01 00119 00120 /*@*-------------------------------------------------------------------- 00121 * @defs: True/False 00122 * @descr: one more useful (?) true/false definition 00123 * 00124 *--------------------------------------------------------------------*/ 00125 #define True 1 00126 #define False 0 00127 00128 /*********************************************************************** 00129 * STRUCTS/UNIONS/TYPES/FUNCDEFS 00130 **********************************************************************/ 00131 /*@*-------------------------------------------------------------------- 00132 * @type: Boolean 00133 * @descr: wasn't it better to use 'int'? 00134 *--------------------------------------------------------------------*/ 00135 typedef int Boolean; 00136 00137 /*@*-------------------------------------------------------------------- 00138 * @type: GnoOption_s 00139 * @descr: This structure describes an option. We intend to use an array 00140 * of GnoOption_s, terminated by a 'NULL' entry (one containing 00141 * all binary-zero fields), and to pass it to GnoParse() together 00142 * with the typical argc,argv couple of main() args. The array's 00143 * entries are looked-up and filled with coherent argc,argv 00144 * values. Some fields are statically filled by user while other 00145 * are returned by the GnoParse() function. 00146 * Fields set by the user: 00147 * 00148 * nFlg = So far the only supported flag is GNO_FLG_SWITCH 00149 * to address a boolean option type. 00150 * fDef = The default value for a boolean option. 00151 * pszDef = The default value for a parametric option. 00152 * pszShort = The short name of the option. 00153 * pszLong = The long name of the option. 00154 * pfValue = Pointer to a boolean option return value. 00155 * ppszValue = Pointer to a parametric option return value. 00156 * pszDescr = A brief option description 00157 * 00158 * Fields set by GnoParse(): 00159 * 00160 * iArg = argv option index 00161 * *ppszValue = pointer to parametric option value 00162 * *pfValue = True/False 00163 * 00164 * User supplied fields are mandatory only within specific 00165 * conditions: 00166 * 00167 * - at least one of pszShort/pszLong must be specified 00168 * - fDef and pfValue apply to a boolean option only 00169 * - pszDef and ppszValue apply to a parametric option only 00170 * - pszDescr is optional 00171 * 00172 * @see: GnoParse(), GNO_FLG 00173 * 00174 *--------------------------------------------------------------------*/ 00175 00176 typedef struct GnoOption 00177 { 00178 int iArg; /* returned argv option index */ 00179 int nFlg; /* flags describing the option */ 00180 Boolean fDef; /* default returned value for a boolean option */ 00181 char * pszDef; /* default returned value for a parametric option */ 00182 char * pszShort; /* short-option recogniser */ 00183 char * pszLong; /* long-option recogniser */ 00184 Boolean * pfValue; /* address to return a boolean option */ 00185 char ** ppszValue; /* address to return a parametric option */ 00186 char * pszDescr; /* a brief option description */ 00187 00188 } GnoOption_s; 00189 00190 00191 /*********************************************************************** 00192 * MACROS 00193 **********************************************************************/ 00194 /*@*-------------------------------------------------------------------- 00195 * 00196 * @macro: GNO_BEGIN 00197 * @descr: Begin an option array declaration 00198 * 00199 * @notes: The best use is to start option declaration immediately after 00200 * the automatic-variable declaration in the main() function. 00201 * 00202 *--------------------------------------------------------------------*/ 00203 #define GNO_BEGIN GnoOption_s _aopt[] = { 00204 00205 /*@*-------------------------------------------------------------------- 00206 * 00207 * @macro: GNO_OPTION 00208 * @descr: Declare a parametric option 00209 * 00210 * 00211 * @args: I: chsopt = short option character 00212 * I: pszlopt -> long option psz 00213 * I: pszdef -> default-returned psz 00214 * I: ppszv -> user-addressed return variable pointer 00215 * 00216 *--------------------------------------------------------------------*/ 00217 #define GNO_OPTION(pszsopt,pszlopt,pszdef,ppszv,pszdescr) \ 00218 { 0, 0, 0, pszdef, pszsopt, pszlopt, NULL, ppszv, pszdescr }, 00219 00220 /*@*-------------------------------------------------------------------- 00221 * 00222 * @macro: GNO_SWITCH 00223 * @descr: Declare a boolean option 00224 * 00225 * @args: I: chsopt = short option character 00226 * I: pszlopt -> long option psz 00227 * I: fdef = default-returned Boolean 00228 * I: pfv -> user-addressed return variable pointer 00229 * 00230 *--------------------------------------------------------------------*/ 00231 #define GNO_SWITCH(pszsopt,pszlopt,fdef,pfv,pszdescr) \ 00232 { \ 00233 0, \ 00234 GNO_FLG_SWITCH, \ 00235 fdef, NULL, \ 00236 pszsopt, pszlopt, \ 00237 pfv, NULL, \ 00238 pszdescr \ 00239 }, 00240 00241 /*@*-------------------------------------------------------------------- 00242 * 00243 * @macro: GNO_PARSE 00244 * @descr: Parse a GnoOption_s array declaration 00245 * 00246 * @args: I: argc = count of argv entries 00247 * I: argv -> array of sz pointers 00248 * 00249 *--------------------------------------------------------------------*/ 00250 #define GNO_PARSE(argc,argv) GnoParse( (argc), (argv), _aopt ) 00251 00252 /*@*-------------------------------------------------------------------- 00253 * 00254 * @macro: GNO_END 00255 * @descr: Terminate an option array declaration 00256 * 00257 *--------------------------------------------------------------------*/ 00258 #define GNO_END { 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } }; 00259 00260 /*@*-------------------------------------------------------------------- 00261 * 00262 * @macro: GNO_HELP 00263 * 00264 * @descr: Print a brief option's help on the standard error 00265 * 00266 * @args: I: pszhead -> help header string 00267 * 00268 *--------------------------------------------------------------------*/ 00269 #define GNO_HELP(pszhead) GnoHelp( pszhead , _aopt ) 00270 00271 /*@*-------------------------------------------------------------------- 00272 * 00273 * @macro: GNO_FREE 00274 * 00275 * @descr: Free resources created by a previously parsed array 00276 * 00277 * 00278 *--------------------------------------------------------------------*/ 00279 #define GNO_FREE() GnoFree( _aopt ) 00280 00281 00282 /*********************************************************************** 00283 * FUNCTION PROTOTYPES 00284 **********************************************************************/ 00285 00286 extern int GnoParse( int argc , char ** argv , GnoOption_s * pOpt ); 00287 00288 extern void GnoFree( GnoOption_s * pOpt ); 00289 00290 extern void GnoHelp( char *pszHead, GnoOption_s * pOpt ); 00291 00292 00293 #ifdef __cplusplus 00294 } 00295 #endif 00296 00297 #endif /* top of file */ 00298 00299 /***************************** END OF FILE ****************************/