00001 /* 00002 * Copyright 1999-2006 University of Chicago 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00022 #ifndef GLOBUS_ARGS_H 00023 #define GLOBUS_ARGS_H 00024 00025 #include "globus_module.h" 00026 #include "globus_list.h" 00027 00028 #ifdef __cplusplus 00029 extern "C" { 00030 #endif 00031 00032 #define GLOBUS_ARGS_HELP -2 /* for -help and -usage */ 00033 #define GLOBUS_ARGS_VERSION -3 /* for -version and -versions */ 00034 00035 00036 /* globus_args.h : a Globus-style argument option parser 00037 00038 The API implements the following behavior: 00039 00040 (1) Valid flags are detected as one '-' followed by any character that is 00041 not '-'. 00042 00043 (2) A flag may have zero or more predicates (values) associated with it, 00044 but for any given flag the number of those (the arity) is fixed. 00045 00046 (3) If a flag has arity of k>0, then the k arguments following the flag 00047 are taken verbatim as the predicates associated with the flag, 00048 including leading '-', if any. 00049 00050 (4) Flagged arguments must not be combined (i.e., "-fg" is never the same 00051 as "-f -g". 00052 00053 (5) The end of flagged arguments will be detected either implicitly (with 00054 the first unrecognized or non-flagged argument) or explicitly (when 00055 "--" is detected when scanning for the next argument flag). 00056 00057 (6) When scanning for the next argument flag, an error is detected if the 00058 detected argument begins with "--*", where '*' is any character. 00059 00060 (7) The argument flags "-help", "-usage", "-version", and "-versions" are 00061 reserved, and if they are detected the library will create an 00062 appropriate message and signal an error. 00063 00064 (8) If an error is detected, then the library will create an error message. 00065 00066 (9) A created error message will be written to stderr, unless dictated 00067 otherwise by the user (in which case the error message will be passed 00068 back to the user). 00069 */ 00070 00071 00072 /* prototype definition of the predicate test function */ 00073 00074 typedef int (*globus_args_valid_predicate_t) (char * arg_value, 00075 void * validation_value, 00076 char ** error_msg); 00077 00078 00079 /* option specification datatype 00080 00081 An option can have several names: "-foo" or "-f" for short, etc. 00082 The parsing library therefore identifies an option trough its 00083 id_number. The user must ensure that the id_number is unique for 00084 each descriptor_t. 00085 00086 The arity of an option is defined as its number of predicates 00087 (following arguments): "-debug" has arity 0, "-foo xyz 123" 00088 has arity 2, etc. 00089 00090 The array of predicate test functions, "tests", may be or contain 00091 GLOBUS_NULL. Any non-null entry in the tests array must have a 00092 non-null entry in the "test_parms" array. 00093 */ 00094 00095 typedef struct globus_args_option_descriptor_s 00096 { 00097 int id_number; /* unique integer */ 00098 char ** names; /* null-terminated array */ 00099 int arity; /* number of arguments */ 00100 globus_args_valid_predicate_t * tests; /* array of size "arity" */ 00101 void ** test_parms; /* test function parms */ 00102 } globus_args_option_descriptor_t; 00103 00104 00105 /* option instance datatype 00106 00107 when a correctly specified argument option is found, an instance of it 00108 is recorded and returned on the format specified in this struct. The 00109 'arity' is provided for user-level consistency checks. 00110 00111 'value' is an array of pointers to the option's predicates: these are 00112 pointers to entries in argv[], and should therefore be treated as 00113 read-only, to conform with POSIX standard. 00114 */ 00115 00116 typedef struct globus_args_option_instance_s 00117 { 00118 int id_number; 00119 int arity; 00120 char ** values; 00121 } globus_args_option_instance_t; 00122 00123 00124 00125 /* globus_args_scan() -- the parsing function 00126 00127 This function scans the argument list 'argv', validates the 00128 arguments as appropriate, and builds an ordered list with the 00129 successfully validated argument options. 00130 00131 An option is successfully validated if it is found in the 00132 'options' array, and the predicate values associated with it 00133 passes the predicate test functions associated with the same 00134 option. 00135 00136 If 'error_msg' is null, messages will be written to 00137 stderr. Otherwise, it will be pointed to an allocated buffer which 00138 must be freed by the user, containing the error message. 00139 00140 A 'reserved option' is one of the 0-arity options "-help", 00141 "-usage", "-version", or "-versions". When detected, a message is created 00142 (and written to stderr if error_msg is null), containing the 00143 appropriate information. A reserved option will terminate the 00144 argument scanning and return. 00145 00146 The successfully validated options are removed from the 'argv' list 00147 unless an error is detected. 'argc' is updated accordingly. The 00148 argc/argv convention with argv[0] being the name of the executable 00149 is maintained. 00150 00151 Returns: 00152 -> The number of successfully identified and validated options. 00153 -> -1 if an error was detected 00154 -> GLOBUS_ARGS_HELP or GLOBUS_ARGS_VERSION 00155 if the corresponding reserved option was detected 00156 (all < 0) 00157 00158 */ 00159 00160 int 00161 globus_args_scan( int * argc, 00162 char *** argv, 00163 int option_count, 00164 globus_args_option_descriptor_t * options, 00165 const char * name, 00166 const globus_version_t * version, 00167 const char * oneline_usage, 00168 const char * long_usage, 00169 globus_list_t ** options_found, 00170 char ** error_msg ); 00171 00172 00173 /* globus_args_destroy_option_instance_list() 00174 00175 globus_args_destroy_option_instance_list() correctly destroys the 00176 list of globus_args_option_instance_t, created by 00177 globus_args_scan(). It takes into account the dynamically allocated 00178 elements in the struct : just calling globus_list_destroy() will 00179 cause memory leaks. 00180 00181 */ 00182 00183 void 00184 globus_args_option_instance_list_free( globus_list_t ** list ); 00185 00186 00187 /* provided predicate functions */ 00188 00189 00190 int 00191 globus_validate_int( char * value, 00192 void * parms, 00193 char ** error_msg ); 00194 00195 /* globus_args_validate_int() verifies that value is a valid integer (in 00196 octal, decimal, or hexadecimal format) and does further validation based 00197 on the values in *parms, which is of the following range check type */ 00198 00199 #define GLOBUS_VALIDATE_INT_NOCHECK 0x00 00200 #define GLOBUS_VALIDATE_INT_MIN 0x01 00201 #define GLOBUS_VALIDATE_INT_MAX 0x02 00202 #define GLOBUS_VALIDATE_INT_MINMAX 0x03 /* 3 == (min | max) */ 00203 00204 typedef struct globus_validate_int_parms_s 00205 { 00206 int range_type; /* one of GLOBUS_VALIDATE_INT_* */ 00207 int range_min; /* inclusive min value */ 00208 int range_max; /* inclusive max value */ 00209 } globus_validate_int_parms_t; 00210 00211 00212 00213 /* globus_validate_filename() verifies that value is a valid file (and 00214 path), based on *parms, which is an int with one or several values of 00215 the standard O_RDONLY, O_RDWR, O_CREAT, O_WRONLY, O_APPEND. 00216 00217 NOTE: the validation is done by actually trying to open the file in 00218 the mode described by *parms. */ 00219 00220 int 00221 globus_validate_filename( char * value, 00222 void * parms, 00223 char ** error_msg ); 00224 00225 00226 /* ---------------------------------------------------------------------------- 00227 globus_bytestr_to_num() 00228 00229 converts a string such as 40M, 256K, 2G to an equivalent off_t. 00230 Valid multipliers are G,g, M,m, K,k, B,b. 00231 00232 Returns 0 on success, nonzero on error. 00233 00234 */ 00235 int 00236 globus_args_bytestr_to_num( 00237 const char * str, 00238 globus_off_t * out); 00239 00240 #ifdef __cplusplus 00241 } 00242 #endif 00243 00244 #endif /* ifndef GLOBUS_ARGS_H */