Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

gdcmArgMgr.cxx

Go to the documentation of this file.
00001 /*=========================================================================
00002   
00003   Program:   gdcm
00004   Module:    $RCSfile: gdcmArgMgr.cxx,v $
00005   Language:  C++
00006   Date:      $Date: 2005/12/22 14:46:06 $
00007   Version:   $Revision: 1.16 $
00008   
00009   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
00010   l'Image). All rights reserved. See Doc/License.txt or
00011   http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
00012   
00013      This software is distributed WITHOUT ANY WARRANTY; without even
00014      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00015      PURPOSE.  See the above copyright notices for more information.
00016   
00017 =========================================================================*/
00018 
00019 #include <stdio.h>
00020 #include <iostream>
00021 #include <ctype.h>
00022 #include <string.h>  // For strlen
00023 
00024 #include <string.h>  // For strtok and strlen
00025 #include <stdlib.h>  // For strtol and strtod
00026 
00027 #include "gdcmArgMgr.h"
00028 
00029 namespace gdcm 
00030 {
00031 //-------------------------------------------------------------------------
00032 // Constructor / Destructor
00033 
00039  ArgMgr::ArgMgr(int argc, char **argv)
00040  {
00041    int i;
00042    int nblettre;
00043    ArgUsed = NULL;
00044    Appel   = NULL;
00045   
00046    /* Read the parameters of the command line *************************/
00047    for ( ArgCount=0, nblettre=1 , i=0; i<argc; i++) 
00048    {
00049       if ( FiltreLong(argv[i]) ) 
00050       { 
00051           std::cout << "Argument too long ( > "
00052                     << ARG_LONG_MAX << ")" << std::endl;
00053           return;
00054       }
00055       if ( argv[i][0] == '@' )
00056       {                       
00057          nblettre  += ArgLoadFromFile ( &argv[i][1] );   
00058       }
00059       else
00060       {                                         
00061          ArgLab [ArgCount] = strcpy ( (char *)malloc(strlen(argv[i])+1), argv[i] ) ;
00062          nblettre  += 1 + strlen(ArgLab[ArgCount]);     
00063          ArgCount++;                               
00064       }
00065       if (ArgCount >= ARGMAXCOUNT )      
00066       {
00067           std::cout << "Too many Arguments ( more than "
00068                     << ARGMAXCOUNT << ")" << std::endl; 
00069           return;
00070       }
00071    }
00072 
00073    /* Fills an array with the already used parameters ****/
00074    ArgUsed = (char *)calloc (1, ArgCount );
00075 
00076    /* Builds the full string with all the parameters  **************/
00077    Appel = (char *) calloc (1, nblettre );
00078 
00079    for ( *Appel = '\0', i=0; i<ArgCount; i++)
00080    {
00081       strcat ( Appel, ArgLab [i] ) ;
00082       strcat ( Appel, " " ) ;
00083    }
00084 
00085    /* Splitting label from label value *************************************/
00086    for ( i=0; i<ArgCount; i++) 
00087    {
00088       char * egaloufin = ArgLab[i] ;
00089       while ( (*egaloufin != '\0') && (*egaloufin != '=') ) 
00090          egaloufin ++ ;
00091       if ( *egaloufin ) *(egaloufin++) = '\0';
00092       ArgStr[i]= egaloufin;
00093    }
00094 
00095    /* Set labels to upper-case (labels are not case sensitive ) *********/
00096    for ( i=0; i<ArgCount; i++)
00097       ArgLab[i] = Majuscule ( ArgLab[i] ) ;
00098 
00099   /* Standard arguments are managed by ArgStdArgs **********************/
00100    ArgStdArgs(); 
00101  }
00102 
00106 ArgMgr::~ArgMgr()
00107 {
00108    for(int i=0;i<ArgCount;i++)
00109       if ( ArgLab[i] )
00110          free(ArgLab[i]);
00111    if ( ArgUsed )
00112       free(ArgUsed);
00113    if ( Appel )
00114       free(Appel);
00115 }
00116  
00123 int ArgMgr::ArgMgrDefined( const char *param )
00124 {
00125   int i;
00126   bool trouve;
00127   char *temp;
00128   temp = Majuscule ( param ) ;
00129   for ( i = ArgCount-1; i>0; i-- )
00130   { 
00131     trouve = ( strcmp( ArgLab[i], temp )==0 ) ;
00132     if ( trouve )
00133     {
00134       ArgUsed[i] = true ;           
00135       for ( int j=1; j<i; j++)
00136       {                     
00137          if ( (!ArgUsed[j])&&(!strcmp(ArgLab[i],ArgLab[j])) )
00138             ArgUsed[j] = i ;
00139       }
00140       return i ;
00141     }
00142   }
00143   return 0 ;
00144 }
00145 
00152 char *ArgMgr::ArgMgrValue ( const char *param )
00153 {
00154    int trouve ;
00155    if ( (trouve = ArgMgrDefined ( param )) != false )
00156       return ArgStr[trouve] ;
00157    else
00158       return NULL ;
00159 }
00160 
00165 char *ArgMgr::ArgMgrUnused ( )
00166 {
00167    int i ;
00168    for ( i=ArgCount-1; i>0; i-- )
00169    {
00170       if ( ! ArgUsed[i] )
00171       {
00172          ArgMgrDefined(ArgLab[i]);
00173          return ArgLab[i] ;
00174       }
00175   }
00176   return NULL ;
00177 }
00178 
00183 int ArgMgr::ArgMgrPrintUnusedLabels ()
00184 {
00185    char *label;
00186    int i=0;
00187    while ( (label=ArgMgrUnused())!=0 )
00188    {
00189       if (i==0)
00190          std::cout << "\n Unused Labels:" << std::endl
00191                    << "=============="    << std::endl;
00192       std::cout << "Label : " << label << " = " 
00193                 << ArgMgrValue(label) << std::endl;
00194       i++;
00195    }
00196    return i;
00197 }
00198 
00204 int ArgMgr::ArgMgrUsage(const char **usage )
00205 {
00206    while ( *usage ) 
00207       std::cout << std::endl << *(usage++);
00208    std::cout << std::endl; 
00209    return (0);
00210 }
00211 
00220 int ArgMgr::ArgMgrSave ( char *param )
00221 {
00222    static int   deja = 0;
00223    FILE         *fd;
00224    if ( *ArgParamOut == '\0' )
00225       return 0;
00226    if ( deja ) 
00227    {
00228       fd = fopen ( ArgParamOut, "a+" );
00229    }
00230    else
00231    {
00232       deja = 1;
00233       fd = fopen ( ArgParamOut, "w" );
00234    } 
00235    if ( !fd ) 
00236       return 0;
00237    fprintf ( fd, "%s\n", param );
00238    fclose  ( fd );
00239    return 1;
00240 }
00241 
00250 int ArgMgr::ArgMgrGetInt(const char *label, int defaultVal)
00251 {
00252    return ( (ArgMgrDefined(label))
00253             ? (atoi(ArgMgrValue(label)))
00254             : (defaultVal) );
00255 }
00256 
00265 float ArgMgr::ArgMgrGetFloat(const char *param, float defaultVal)
00266 {
00267    return     ( (ArgMgrDefined(param))
00268                ? ((float)atof(ArgMgrValue(param)))
00269                : (defaultVal) );
00270 }
00271 
00280 char *ArgMgr::ArgMgrGetString(const char *param, char *defaultVal)
00281 {
00282    return    ( (ArgMgrDefined(param)) 
00283               ? (ArgMgrValue(param))
00284               : (defaultVal) );
00285 }
00286 
00298 int ArgMgr::ArgMgrGetLabel (const char *param, char *liste, int val )
00299 {
00300   char *lab;
00301   char *vallab;
00302   int i = 1;
00303   char *tmp;
00304   tmp = (char *) malloc(strlen(liste)+1);
00305   strcpy(tmp,liste);
00306 
00307   if ( (vallab = ArgMgrGetString(param,(char *)NULL)) != 0 ) 
00308   { 
00309      for ( lab = strtok (tmp,"\\"); 
00310            lab != 0; 
00311            lab = strtok(0L,"\\"), i++ )
00312      { 
00313         if ( strcmp(maj(lab),maj(vallab))==0)
00314            return i;
00315      } 
00316      val=0;
00317    }
00318    free(tmp);
00319    return val;
00320 }
00321 
00332 int ArgMgr::ArgMgrWantLabel (const char *param, char *liste, const char **usage )
00333 {
00334    char *lab;
00335    char *vallab;
00336    int i = 1;
00337    if ( (vallab = ArgMgrGetString(param,0)) != 0 ) 
00338    {
00339       for ( lab = strtok (liste,"\\"); lab != 0; lab = strtok(0L,"\\"), i++ )
00340         if ( strcmp(maj(lab),maj(vallab))==0) 
00341            return i;
00342       return 0;
00343    }
00344    ArgMgrUsage(usage);
00345    return 0;
00346 }
00347 
00356 int ArgMgr::ArgMgrWantInt (const char *label, const char **usage)
00357 {
00358    return        ( (ArgMgrDefined(label) ) 
00359                  ? (atoi(ArgMgrValue(label) ) ) 
00360                  : (ArgMgrUsage(usage),1) );
00361 }
00362 
00371 float ArgMgr::ArgMgrWantFloat (const char *label, const char **usage)
00372 {
00373    return       ( (ArgMgrDefined(label) ) 
00374                 ? ((float)atof(ArgMgrValue(label) ) ) 
00375                 : (ArgMgrUsage(usage),(float)1.0) );
00376 }
00377 
00386 char *ArgMgr::ArgMgrWantString(const char *label, const char **usage)
00387 {
00388    return      ( (ArgMgrDefined(label) ) 
00389                ? (ArgMgrValue(label) ) 
00390                : (ArgMgrUsage(usage),(char*)0) );
00391 }
00392 
00400 char **ArgMgr::ArgMgrGetListOfString ( const char *label, int *number )
00401 {
00402   int taille;
00403   char  *value = ArgMgrValue(label);
00404   char **liste;
00405   char **elem;
00406   char  *chainecur; 
00407   if (!value)
00408   {
00409      *number = 0;
00410      return 0;
00411   }
00412   *number = IdStrCountChar(value,',')+1; /* nb Elements = nb Commas +1 */
00413   taille = *number;
00414   liste = (char **) malloc (sizeof(char*) * taille + strlen(value)+1);
00415   if ( !liste )
00416      return 0;
00417   value = strcpy( ((char*)liste)+sizeof(char*) * taille, value );
00418   for ( elem = liste, chainecur = strtok(value,", ");
00419         taille>0;
00420         taille--, chainecur = (chainecur) ? strtok ( 0, ", " ) : 0 )
00421   {
00422     *(elem++) = chainecur;
00423   }
00424   return liste;
00425 }
00426 
00434 int *ArgMgr::ArgMgrGetListOfInt ( const char *label, int *number )
00435 {
00436   char *value = ArgMgrValue(label);
00437   int *liste;
00438   int *elem;
00439   int taille;
00440   if (!value)
00441   {
00442      *number = 0;
00443      return 0;
00444   }          
00445   *number = IdStrCountChar(value,',')+1; /* nb Elements = nb Commas +1 */ 
00446   taille= *number;
00447   liste = (int *) calloc (1,sizeof(int)*taille );
00448   if ( !liste )
00449      return 0;
00450   elem = liste;
00451   //*number = 1;
00452 
00453   while ( taille>0 ) 
00454   {
00455     *(elem++) = (int) strtol ( value, &value, 10 );      
00456     if ( *value == '\0' )
00457        return liste;
00458     if ( *(value++) != ',' ) 
00459     {
00460       free (liste);
00461       return 0;
00462     }
00463     taille --;
00464   }
00465 return liste;
00466 }
00467 
00474 float *ArgMgr::ArgMgrGetListOfFloat ( const char *label, int *number )
00475 {
00476   char *value = ArgMgrValue(label);
00477   float *liste;
00478   float *elem;
00479   int taille;
00480   if (!value)
00481     return 0;
00482   *number = IdStrCountChar(value,',')+1; /* nb Elements = nb Commas +1 */
00483   taille= *number;
00484   liste = (float *) calloc (1,sizeof(float)*taille );
00485   if ( !liste )
00486   {
00487      *number = 0;
00488      return 0;
00489   }
00490   elem = liste;
00491   //*number = 1;
00492 
00493   while ( taille>0 ) 
00494   {
00495     *(elem++) = (float) strtod ( value, &value );      
00496     if ( *value == '\0' )
00497        return liste;
00498     if ( *(value++) != ',' )
00499     {
00500       free (liste);
00501       return 0;
00502     }
00503     taille --;
00504   }
00505 return liste;
00506 }
00507 
00514 int *ArgMgr::ArgMgrGetIntEnum ( const char *param, int *number )
00515 {
00516    char *value = ArgMgrValue(param);
00517    int *liste;
00518    if (!value) 
00519    {
00520       *number = 0; 
00521       return 0;
00522    }
00523    liste = IdStrIntEnum(value, number);
00524    return liste;
00525 }
00526 
00533 uint16_t *ArgMgr::ArgMgrGetXInt16Enum ( const char *param, int *number )
00534 {
00535    char *value = ArgMgrValue(param);
00536    uint16_t *liste;
00537    if (!value) 
00538    {
00539       *number = 0; 
00540       return 0;
00541    }
00542    liste = IdStrXInt16Enum(value, number);
00543    return liste;
00544 }
00552 float *ArgMgr::ArgMgrGetFloatEnum ( const char *param, int *number )
00553 {
00554    char  *value = ArgMgrValue(param);
00555    float *liste;
00556    if (!value) 
00557    {
00558       *number = 0; 
00559       return 0;
00560    }
00561    liste = IdStrFloatEnum(value, number);
00562    return liste;
00563 }
00564 
00565 // ------------------------ Those are 'service functions' ---------------------
00566 // ------------------------       internal use only       ---------------------
00567 
00574 int ArgMgr::IdStrCountChar (char *chaine, int caract)
00575 {
00576   int i=0;
00577   char *ptr;
00578   for ( ptr = chaine ; *ptr!='\0' ; ptr ++ ) 
00579      if (*ptr==caract) 
00580         i++;  
00581   return i;
00582 }
00583 
00590 int *ArgMgr::IdStrIntEnum ( char* value, int *number)
00591 {
00592    int* liste;
00593    int taille;
00594    int i;
00595 
00596    *number = IdStrCountChar(value,',')+1; /* nb Elements = nb Commas +1 */
00597    taille= *number;
00598    liste = (int *) calloc (1,sizeof(int)*2*taille );
00599    if ( !liste )
00600    {
00601       return 0;
00602    }
00603    i=0;
00604    while ( taille>0 ) 
00605    {
00606       liste[i] = (int) strtol ( value, &value, 10 );
00607       if ( *value == '\0' ) 
00608       {
00609          liste[i+1]=liste[i];
00610          return liste;
00611       }
00612       if ( *(value++) != '-' ) 
00613       {
00614          liste[i+1]=liste[i];
00615          value--;
00616        }
00617        else
00618        {
00619           liste[i+1] = (int) strtol ( value, &value, 10 );
00620        }
00621        if ( *value == '\0' )
00622           return liste;
00623        if ( *(value++) != ',' )
00624        {
00625           free (liste);
00626           return 0;
00627        }
00628        taille --; i+=2;
00629    }
00630    return liste;
00631 }
00632 
00640 uint16_t *ArgMgr::IdStrXInt16Enum ( char *value, int *number)
00641 {
00642    uint16_t *liste;
00643    int taille;
00644    int i;
00645 
00646    *number = IdStrCountChar(value,',')+1; /* nb Elements = nb Commas +1 */
00647    taille= *number;
00648    liste = (uint16_t *) calloc (1,sizeof(uint16_t)*2*taille );
00649    if ( !liste )
00650    {
00651       return 0;
00652    }
00653    i=0;
00654    while ( taille>0 ) 
00655    {
00656       liste[i] = (uint16_t) strtol ( value, &value, 16 );
00657       if ( *value == '\0' ) 
00658       {
00659          liste[i+1]=liste[i];
00660          return liste;
00661       }
00662       if ( *(value++) != '-' ) 
00663       {
00664          liste[i+1]=liste[i];
00665          value--;
00666        }
00667        else
00668        {
00669           liste[i+1] = (uint16_t) strtol ( value, &value, 16 );
00670        }
00671        if ( *value == '\0' )
00672           return liste;
00673        if ( *(value++) != ',' )
00674        {
00675           free (liste);
00676           return 0;
00677        }
00678        taille --; i+=2;
00679    }
00680    return liste;
00681 } 
00688 float *ArgMgr::IdStrFloatEnum (char *value, int *number)
00689 {
00690    float *liste;
00691    int taille;
00692    int i;
00693    *number = IdStrCountChar(value,',')+1; /* nb Elements = nb Commas +1 */
00694    taille= *number;
00695    liste = (float *) calloc (1,sizeof(float)*2*taille );
00696    if ( !liste )
00697       return 0;
00698    i=0;
00699    while ( taille>0 ) 
00700    {
00701       liste[i] = (float) strtod ( value, &value );      
00702       if ( *value == '\0' ) 
00703       {
00704          liste[i+1]=liste[i];
00705          return liste;
00706       }
00707       if ( *(value++) != '-' ) 
00708       {
00709          liste[i+1]=liste[i];
00710          value--;
00711       }
00712       else
00713       {
00714           liste[i+1] = (float) strtod ( value, &value );
00715       }
00716       if ( *value == '\0' ) 
00717          return liste;
00718       if ( *(value++) != ',' )
00719       {
00720          free (liste);
00721          return 0;
00722       }
00723       taille --; i+=2;
00724    }
00725    return liste;
00726 }
00727 
00728 //-----------------------------------------------------------------------------
00729 // Protected
00730 
00731 //-----------------------------------------------------------------------------
00732 // Private
00733 
00734 /**************************************************************************
00735 *                                                                         *
00736 * Nom de la fonction : Majuscule                                          *
00737 * Role ............. : Creates a new Upper case char array.               *
00738 * parameters ....... : Pointer to the initial char array.                 *                           *
00739 * Valeur retournee . : Pointer to the new Upper case char array.          *
00740 *                                                                         *
00741 **************************************************************************/
00742 char *ArgMgr::Majuscule (const char *chaine )
00743 {
00744   char *ptr, *ptr2, *ptr3;
00745   ptr2 = (char *)malloc(strlen(chaine)*sizeof(char)+1);
00746   ptr3=ptr2;
00747   for ( ptr = (char *)chaine ; *ptr!='\0' ; ptr ++ ) 
00748    {  
00749        *ptr3 = toupper ( * ptr ); ptr3++; 
00750    }
00751   *ptr3='\0'; 
00752   return ptr2;
00753 }
00754 
00755 /**************************************************************************
00756 *                                                                         *
00757 * Nom de la fonction : FiltreLong                                         *
00758 * Role ............. : Stops the program if argument is too long.         *
00759 *                      ARG_LONG_MAX defines max length.                   *
00760 * parameters ....... : Pointer to the argument.                           *
00761 * Valeur retournee . : false if OK.                                       *
00762 *                      true if KO.                                        *
00763 **************************************************************************/
00764 int ArgMgr::FiltreLong ( char *arg  )
00765 {
00766   int  n = 0 ;
00767   while ( (n++<ARG_LONG_MAX) && (*(arg++) != '\0') ) ;
00768   return (n>=ARG_LONG_MAX) ;
00769 }
00770 
00771 /*------------------------------------------------------------------------
00772  | Role       : Reads a parameter from a file
00773  | Return     : Type   : char *
00774  |              Role   : pointer to the label
00775  | parameters : param  : char *
00776  |              Role   : one where the parameter will be stored
00777  |              fd     : FILE *
00778  |              Role   : File description (assumed to be open)
00779  +------------------------------------------------------------------------*/
00780 const char *ArgMgr::LoadedParam ( const char *param, FILE *fd )
00781 {
00782   int    carlu;
00783   char  *car = (char *)param;
00784   int    quote = false;
00785   int    nbcar = 0;
00786 
00787   /* remove spaces at the beginning****/
00788   while ( isspace(carlu=fgetc (fd)) );
00789   if (carlu==EOF)
00790      return 0;
00791   /* Search for a " */
00792   if ( carlu=='\"' ) 
00793   {
00794     carlu=fgetc(fd);
00795     quote=true;
00796   /* Read all the characters */
00797   }
00798   while (  (carlu!=EOF)
00799         && (  ( (!quote)&&(!isspace(carlu)) )
00800          ||( (quote)&& !(carlu=='\"')   ) ) ) 
00801   {
00802      *(car++) = (char) carlu;
00803      nbcar ++;
00804   /* sans depasser la taille max*/
00805      if ( nbcar >= ARG_LONG_MAX ) 
00806      {
00807         std::cout << "\nError: Argument too long ( > "
00808                   << ARG_LONG_MAX << ")in parameter file."
00809                   << std::endl;
00810         break;
00811      }
00812      carlu = fgetc(fd);
00813   }
00814   *car = '\0';
00815   return param;
00816 }
00817 
00818 /*------------------------------------------------------------------------
00819  | Role       : Reading of arguments in a parameter file
00820  |              (this function is recursive).
00821  | Return     : Type   : int
00822  |              Role   : length needed to store all the parameters
00823  | parameters : filename : char *
00824  |              Role     : parameter File name
00825  |
00826  +------------------------------------------------------------------------*/
00827 int ArgMgr::ArgLoadFromFile ( char *filename )
00828 {
00829   int   nbl = 0;
00830   char  param[ARG_LONG_MAX+1];
00831   FILE  *fch;
00832 
00833   fch = fopen ( filename, ID_RFILE_TEXT );
00834   while ( LoadedParam (param, fch ) )
00835   {
00836     int n = strlen(param);
00837     if ( param[0]=='@' )
00838     {
00839       nbl  += ArgLoadFromFile ( &param[1] );
00840     }
00841     else
00842     {
00843       ArgLab [ArgCount] = strcpy ((char *) malloc(n+1), param ) ;
00844       nbl += n + 1 ;
00845       ArgCount++;
00846       if ( ArgCount >= ARGMAXCOUNT ) 
00847          break;
00848     }
00849   }
00850   fclose ( fch );
00851   return nbl;
00852 }
00853 
00854 /*------------------------------------------------------------------------
00855  | Role       : Standard parameters management (on command line)
00856  | Return     : Type   : void
00857  | parameters : none
00858  +------------------------------------------------------------------------*/
00859 void ArgMgr::ArgStdArgs()
00860 {
00861   char *logfile;
00862   FILE *fd;
00863 
00864   if ( (ArgParamOut=ArgMgrValue((char*)ARG_LABEL_PARAMOUT))==0 )
00865     ArgParamOut = ARG_DEFAULT_PARAMOUT;
00866   if ( (logfile = ArgMgrValue((char*)ARG_LABEL_LOGFILE))!=0) 
00867   {
00868     if ( *logfile == '\0' )
00869        logfile = (char *)ARG_DEFAULT_LOGFILE;
00870     fd = fopen ( logfile, "a+" );
00871     if ( fd ) 
00872     {
00873       fprintf ( fd, "%s\n", Appel );
00874       fclose  ( fd );
00875     }
00876   }
00877 }
00878 
00879 /*------------------------------------------------------------------------
00880  | Role       : Sets in Upper Case.
00881  | Return     : Type   : char *
00882  | parameters : char *
00883  +------------------------------------------------------------------------*/
00884 char *ArgMgr::maj ( char *a )
00885 {
00886    char *b = a;
00887    while ( *b !=0 ) 
00888    {
00889       if ( *b<='z' && *b>='a' ) *b = *b+'A'-'a';
00890       b++;
00891    }
00892    return a;
00893 }
00894 //-----------------------------------------------------------------------------
00895 // Print
00896 
00897 //-----------------------------------------------------------------------------
00898 } // end namespace gdcm

Generated on Fri Jan 20 10:14:23 2006 for gdcm by  doxygen 1.4.4