00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "optarg.h"
00021 #include "helper.h"
00022 #include <string.h>
00023 #include <math.h>
00024 #include <stdlib.h>
00025
00028 void optarglist_print( OptArgList *list, FILE *out ){
00029 int i;
00030 fprintf( out, "OptArgList '%p' with %i items:\n", list, list->nargs );
00031 for( i=0; i<list->nargs; i++ ){
00032 fprintf( out, " %i: %s(%s) is %s: ", i+1, list->args[i].key, list->args[i].type,
00033 list->args[i].scalar?"scalar":"pointer");
00034 if( list->args[i].scalar ){
00035 fprintf( out, "%f\n", list->args[i].data_scalar );
00036 } else {
00037 fprintf( out, "%p\n", list->args[i].data_ptr );
00038 }
00039 }
00040 }
00041
00045 OptArgList* optarglist_hidden( char *format, va_list ap ){
00046 char *key, *type;
00047 char *tmp;
00048 char *fmt;
00049 int nargs, i;
00050 OptArgList *L;
00051
00052 nargs=0;
00053 tmp=format;
00054
00055
00056 while( (tmp=strchr( tmp, '=' ))!=NULL ){
00057 tmp++;
00058 nargs++;
00059 }
00060
00061 if( sizeof(char*)!=sizeof(void*) ||
00062 sizeof(double*)!=sizeof(void*) ){
00063 errprintf("System Error! For this function to work, all pointers must be of the same size!\n");
00064 return NULL;
00065 }
00066
00067 L = (OptArgList*)malloc( sizeof( OptArgList ) );
00068 L->nargs=nargs;
00069 L->args=(OptArg*)malloc( nargs*sizeof( OptArg ) );
00070 dprintf("Found %i args\n", nargs );
00071
00072
00073 fmt = (char*)malloc( (strlen( format )+1)*sizeof(char) );
00074 strcpy( fmt, format );
00075 key=fmt;
00076 type=fmt;
00077 for( i=0; i<nargs; i++ ){
00078 if( (tmp=strchr( key, '=' )) ){
00079 *tmp='\0';
00080 }
00081 dprintf("key=%s\n", key);
00082 strcpy( L->args[i].key, key );
00083 string_strip_blanks( L->args[i].key );
00084
00085 type=tmp+1;
00086 if( (tmp=strchr( type, ',' ) ) ){
00087 *tmp='\0';
00088 key = tmp+1;
00089 }
00090
00091 dprintf("type=%s\n", type );
00092 strcpy( L->args[i].type, type );
00093 string_strip_blanks( L->args[i].type );
00094 }
00095 dprintf("Parsing done\n");
00096
00097 for (i = 0; i < nargs; i++){
00098 if( !strchr( L->args[i].type, '*' ) ){
00099 L->args[i].scalar=TRUE;
00100 if( !strcmp( L->args[i].type, "char" ) ){
00101 L->args[i].data_scalar = (double) va_arg (ap, int );
00102 } else if( !strcmp( L->args[i].type, "short" ) ){
00103 L->args[i].data_scalar = (double) va_arg (ap, int );
00104 } else if( !strcmp( L->args[i].type, "int" ) ){
00105 L->args[i].data_scalar = (double)va_arg (ap, int );
00106 } else if( !strcmp( L->args[i].type, "long" ) ){
00107 L->args[i].data_scalar = (double) va_arg (ap, long );
00108 } else if( !strcmp( L->args[i].type, "float" ) ){
00109 L->args[i].data_scalar = (double) va_arg (ap, double );
00110 } else if( !strcmp( L->args[i].type, "double" ) ){
00111 L->args[i].data_scalar = (double) va_arg (ap, double );
00112 } else {
00113 errprintf("Sorry, do not know scalar data type '%s'\n"
00114 "This function is probably going to break because of this.\n"
00115 "Please correct the error and restart.\n",
00116 L->args[i].type );
00117 break;
00118 }
00119 } else {
00120 dprintf("There is a pointer in the %i'th argument\n", i+1 );
00121 L->args[i].scalar=FALSE;
00122 L->args[i].data_ptr = (void*)va_arg(ap, void *);
00123 dprintf("got a pointer: %p\n", L->args[i].data_ptr );
00124 }
00125 }
00126
00127
00128 free( fmt );
00129 return L;
00130 }
00131
00167 OptArgList* optarglisttmp( char *format, ... ){
00168 va_list ap;
00169 va_start (ap, format );
00170 OptArgList *o=optarglist_hidden( format, ap );
00171 va_end(ap);
00172
00173 OptArg f;
00174 sprintf(f.key, "optarglist_free");
00175 f.scalar=TRUE;
00176 sprintf(f.type, "int");
00177 f.data_ptr=NULL;
00178 f.data_scalar=1.0;
00179 OptArgList *no=optarglist_append_arg( o, &f );
00180 optarglist_free( o );
00181
00182 return no;
00183 }
00184
00218 OptArgList* optarglist( char *format, ... ){
00219 va_list ap;
00220 va_start (ap, format );
00221 OptArgList *o=optarglist_hidden( format, ap );
00222 va_end(ap);
00223
00224 return o;
00225 }
00226
00231 void optarglist_free( OptArgList *list ){
00232 free( list->args );
00233 free( list );
00234 }
00235
00236
00242 double optarglist_scalar_by_key( OptArgList *list, const char *key ){
00243 OptArg *arg;
00244 arg = optarglist_optarg_by_key( list, key );
00245 if( !arg ){
00246 errprintf("There is no key: '%s'\n", key );
00247 return NAN;
00248 }
00249 if( !arg->scalar ){
00250 errprintf("You requested a scalar from a pointer argument\nYou get NaN instead :-)\n");
00251 return NAN;
00252 }
00253 dprintf("arg->data_scalar=%f\n", arg->data_scalar );
00254 return arg->data_scalar;
00255 }
00256
00262 void* optarglist_ptr_by_key ( OptArgList *list, const char *key ){
00263 OptArg *arg;
00264 arg = optarglist_optarg_by_key( list, key );
00265 if( !arg ) return NULL;
00266 if( arg->scalar ){
00267 errprintf("You requested a data-pointer from a scalar argument\nYou get NULL instead :-)\n");
00268 return NULL;
00269 }
00270 return arg->data_ptr;
00271 }
00272
00278 OptArg* optarglist_optarg_by_key( OptArgList *list, const char *key ){
00279 int i;
00280 if( !list ) return NULL;
00281 for( i=0; i<list->nargs; i++ ){
00282 if( !strcmp( list->args[i].key, key ) )
00283 return &(list->args[i]);
00284 }
00285 return NULL;
00286 }
00287
00290 bool optarglist_has_key( OptArgList *list, const char *key ){
00291 int i;
00292 if( !list ) return FALSE;
00293 for( i=0; i<list->nargs; i++ ){
00294 if( !strcmp( list->args[i].key, key ) )
00295 return TRUE;
00296 }
00297 return FALSE;
00298 }
00299
00307 OptArgList* optarglist_append_arg ( OptArgList *list, OptArg *arg ){
00308 OptArgList *new;
00309
00310 new = (OptArgList*)malloc( sizeof( OptArgList ) );
00311 new->nargs=list->nargs+1;
00312 new->args=(OptArg*)malloc( new->nargs*sizeof( OptArg ) );
00313 memcpy( new->args, list->args, list->nargs * sizeof( OptArg ) );
00314 memcpy( &(new->args[new->nargs-1]), arg, sizeof( OptArg ) );
00315 return new;
00316 }
00317
00330 OptArgList* optarglist_delete_arg ( OptArgList *list, OptArg *arg ){
00331 int idx=-1;
00332 int i,j;
00333 for( i=0; i<list->nargs; i++ ){
00334 if( &(list->args[i])==arg ){
00335 idx=i;
00336 }
00337 }
00338 if( idx<0 ){
00339 warnprintf("list did not contain the optional argument\n");
00340 return;
00341 }
00342
00343 OptArgList *L = (OptArgList*)malloc( sizeof( OptArgList ) );
00344 L->nargs=list->nargs-1;
00345 L->args=(OptArg*)malloc( L->nargs*sizeof( OptArg ) );
00346 for( i=0,j=0; i<list->nargs; i++ ){
00347 if( i==idx ) continue;
00348 memcpy( &(L->args[i]), &(list->args[i]), sizeof(OptArg) );
00349 j++;
00350 }
00351
00352 return L;
00353 }
00386 OptArgList* optarglist_remove_freeflag( OptArgList *list, bool *removedflag ){
00387 OptArg *freearg;
00388 OptArgList *nlist=list;
00389 *removedflag=FALSE;
00390 if( optarglist_has_key( list, "optarglist_free" ) ){
00391 freearg=optarglist_optarg_by_key( list, "optarglist_free" );
00392 nlist=optarglist_delete_arg( list, freearg );
00393 optarglist_free( list );
00394 *removedflag=TRUE;
00395 }
00396
00397 return nlist;
00398 }
00399
00402 OptArg* optarg_scalar( const char *key, double scalar ){
00403 OptArg *p = (OptArg*)malloc(sizeof(OptArg) );
00404 strncpy( p->key, key, MAX_LABEL_LENGTH );
00405 p->scalar = TRUE;
00406 p->data_scalar = scalar;
00407 sprintf( p->type, "double" );
00408 p->data_ptr = NULL;
00409 return p;
00410 }
00411
00414 OptArg* optarg_ptr ( const char *key, void *ptr ){
00415 OptArg *p = (OptArg*)malloc(sizeof(OptArg) );
00416 strncpy( p->key, key, MAX_LABEL_LENGTH );
00417 p->scalar = FALSE;
00418 p->data_ptr = ptr;
00419 sprintf( p->type, "void*" );
00420 p->data_scalar = 0.0/0.0;
00421 return p;
00422 }