• API Main Page
  • Documentation
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

src/optarg.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2008-2010 by Matthias Ihrke   *
00003  *   mihrke@uni-goettingen.de   *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
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   /* count '=' */
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   /* parse key=type information from format */
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, '*' ) ){ /* it's scalar */
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 );         /* Initialize the argument list. */
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 );         /* Initialize the argument list. */
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 }

Generated on Fri Jun 25 2010 14:10:20 for libeegtools by  doxygen 1.7.0