00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include <ctype.h>
00005 #include "hash_table.h"
00006 #include "parse_params.h"
00007 #include "xmem.h"
00008
00009 #define PARAMBUFLEN (256*4096)
00010 static char param_buffer[PARAMBUFLEN];
00011 static Hash_Table_t ParamHash;
00012
00013
00014 float strtof(const char *nptr, char **endptr);
00015
00016
00017 static unsigned int hash(const void *v);
00018 static int equal(const void *a, const void *b);
00019 static void print(const void *key, const void *value);
00020 static int parse_line(char *inbuf, char **outbuf, char **pname, char **pvalue);
00021 static int parse_file(FILE *stream, Hash_Table_t *h, char **bufstart, char *bufend);
00022
00023
00024 static unsigned int hash(const void *v)
00025 {
00026 char *c = (char *) v;
00027 unsigned int sum = 0;
00028
00029 while ( *c )
00030 sum += (unsigned int) *c++ + 31*sum;
00031 return sum;
00032 }
00033
00034 static int equal(const void *a, const void *b)
00035 {
00036 return strncmp((char *)a, (char *)b, LINEMAX);
00037 }
00038
00039 static void print(const void *key, const void *value)
00040 {
00041 printf("%s = %s\n",(char *) key, (char *) value);
00042 }
00043
00044
00045
00046
00047
00048 static int parse_line(char *inbuf, char **outbuf, char **pname, char **pvalue)
00049 {
00050
00051
00052
00053
00054
00055
00056
00057
00058 char *instart, *name, *value;
00059
00060 instart = inbuf;
00061 *pname = NULL; *pvalue = NULL;
00062 name = *outbuf; *name = '\0';
00063 while(isspace(*inbuf)) ++inbuf;
00064 if (*inbuf == '\0')
00065 return 0;
00066 while(isgraph(*inbuf) && *inbuf != '=' && *inbuf != '#' )
00067 *name++ = (char) toupper((int)(*inbuf++));
00068 if (*inbuf == '#')
00069 return 0;
00070 *name++ = '\0';
00071 *pname = *outbuf; *pvalue = name;
00072 *name++ = '\0';
00073 *outbuf = name;
00074 while(isspace(*inbuf)) ++inbuf;
00075 if (*inbuf != '=')
00076 {
00077 fprintf(stderr,"'%s': Unexpected parameter string format: Expected '='.\n",instart);
00078 return 1;
00079 }
00080 ++inbuf;
00081 while(isspace(*inbuf)) ++inbuf;
00082 if (*inbuf == '#')
00083 return 1;
00084 if ( *inbuf == '"' )
00085 {
00086
00087 ++inbuf;
00088 value = name;
00089 *pvalue = value;
00090 while(isprint(*inbuf) && *inbuf != '#' && *inbuf != '"' )
00091 *value++ = *inbuf++;
00092 if ( *inbuf != '"' )
00093 fprintf(stderr,"'%s': Unterminated string missing '\"'.\n",instart);
00094 }
00095 else
00096 {
00097 value = name;
00098 *pvalue = value;
00099 while(isgraph(*inbuf) && *inbuf != '#' )
00100 *value++ = *inbuf++;
00101 }
00102 *value++ = '\0';
00103 *outbuf = value;
00104
00105 return 2;
00106 }
00107
00108 static int parse_file(FILE *stream, Hash_Table_t *h, char **bufstart, char *bufend)
00109 {
00110 int count, status;
00111 char linebuf[LINEMAX], *name, *value;
00112
00113 count = 0;
00114 while(fgets(linebuf, LINEMAX, stream)) {
00115 if ((int)(bufend - *bufstart) < LINEMAX) {
00116 fprintf(stderr,"Parameter buffer depleted.\n");
00117 exit(1);
00118 }
00119 status = parse_line(linebuf, bufstart, &name, &value);
00120
00121 if (status) {
00122 hash_insert(h,name,value);
00123 ++count;
00124 }
00125 }
00126 return count;
00127 }
00128
00129 int XXX_params_parse_arguments(int argc, char *argv[])
00130 {
00131 int count;
00132 int i, status;
00133 char *bufstart = param_buffer, *bufend = ¶m_buffer[PARAMBUFLEN-1];
00134 char *name, *value;
00135 FILE *stream;
00136
00137 count = 0;
00138 hash_init(&ParamHash,503,1,equal,hash);
00139 for (i=1; i<argc; i++)
00140 {
00141 if (argv[i][0] == '-') {
00142 status = parse_line(&argv[i][1], &bufstart, &name, &value);
00143 if (status)
00144 {
00145 hash_insert(&ParamHash,name,value);
00146 ++count;
00147 }
00148 }
00149 else
00150 {
00151 if ((stream = fopen(argv[i],"r")))
00152 {
00153 count += parse_file(stream, &ParamHash,&bufstart,bufend);
00154 fclose(stream);
00155 }
00156 else
00157 fprintf(stderr,"parse_params: Couldn't open file '%s'.\n",argv[i]);
00158 }
00159 }
00160 return count;
00161 }
00162
00163
00164 void XXX_params_free(void)
00165
00166
00167 {
00168 hash_free(&ParamHash);
00169 }
00170
00171
00172
00173 void params_print(void)
00174 {
00175 hash_map(&ParamHash,print);
00176 }
00177
00178 void XXX_params_stat(void)
00179 {
00180 hash_stat(&ParamHash);
00181 }
00182
00183
00184
00185 int XXX_params_isdef( const char *name )
00186 {
00187 int i;
00188 char buf[LINEMAX], *p=buf;
00189
00190 for (i=0; i<LINEMAX-1 && *name!='\0'; i++)
00191 *p++ = toupper(*name++);
00192 *p = '\0';
00193 return hash_member(&ParamHash, buf);
00194 }
00195
00196 int XXX_params_get_int( const char *name)
00197 {
00198 int i;
00199 const char *value;
00200 char *endptr;
00201 long int val;
00202 char buf[LINEMAX], *p=buf;
00203
00204 for (i=0; i<LINEMAX-1 && *name!='\0'; i++)
00205 *p++ = toupper(*name++);
00206 *p = '\0';
00207 if((value = hash_lookup(&ParamHash,buf)))
00208 {
00209 val = strtol(value,&endptr,10);
00210 if (value[0]=='\0' || *endptr!='\0' )
00211 fprintf(stderr,"GetArgInt: The value of '%s' = '%s' is not an int.\n",name, value);
00212 else
00213 return (int) val;
00214 }
00215 else
00216 fprintf(stderr,"Unknown parameter '%s'.\n",name);
00217 exit(1);
00218 }
00219
00220 float XXX_params_get_float( const char *name)
00221 {
00222 int i;
00223 const char *value;
00224 char *endptr;
00225 float val;
00226 char buf[LINEMAX], *p=buf;
00227
00228 for (i=0; i<LINEMAX-1 && *name!='\0'; i++)
00229 *p++ = toupper(*name++);
00230 *p = '\0';
00231 if((value = hash_lookup(&ParamHash,buf)))
00232 {
00233 val = strtof(value,&endptr);
00234 if (val==0 && endptr==value )
00235 fprintf(stderr,"GetArgFloat: The value of '%s' = '%s' is not a float.\n",name, value);
00236 else
00237 return val;
00238 }
00239 else
00240 fprintf(stderr,"Unknown parameter '%s'.\n",name);
00241 exit(1);
00242 }
00243
00244 float XXX_params_get_double( const char *name)
00245 {
00246 int i;
00247 const char *value;
00248 char *endptr;
00249 double val;
00250 char buf[LINEMAX], *p=buf;
00251
00252 for (i=0; i<LINEMAX-1 && *name!='\0'; i++)
00253 *p++ = toupper(*name++);
00254 *p = '\0';
00255 if((value = hash_lookup(&ParamHash,buf)))
00256 {
00257 val = strtod(value,&endptr);
00258 if (val==0 && endptr==value )
00259 fprintf(stderr,"GetArgDouble: The value of '%s' = '%s' is not a double.\n",name,
00260 value);
00261 else
00262 return val;
00263 }
00264 else
00265 fprintf(stderr,"Unknown parameter '%s'.\n",name);
00266 exit(1);
00267 }
00268
00269 const char *XXX_params_get_string( const char *name)
00270 {
00271 int i;
00272 const char *value;
00273 char buf[LINEMAX], *p=buf;
00274
00275 for (i=0; i<LINEMAX-1 && *name!='\0'; i++)
00276 *p++ = toupper(*name++);
00277 *p = '\0';
00278 if((value = hash_lookup(&ParamHash,buf)))
00279 return value;
00280 else
00281 fprintf(stderr,"Unknown parameter '%s'.\n",name);
00282 exit(1);
00283 }
00284
00285 char XXX_params_get_char( const char *name)
00286 {
00287 int i;
00288 const char *value;
00289 char buf[LINEMAX], *p=buf;
00290
00291 for (i=0; i<LINEMAX-1 && *name!='\0'; i++)
00292 *p++ = toupper(*name++);
00293 *p = '\0';
00294 if((value = hash_lookup(&ParamHash,buf))) {
00295 if (strlen(value)>1)
00296 fprintf(stderr,"GetArgChar: The value of '%s' = '%s' is not a char.\n",name, value);
00297 return value[0];
00298 }
00299 else
00300 fprintf(stderr,"Unknown parameter '%s'.\n",name);
00301 exit(1);
00302 }