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: 2007/05/23 14:18:07 $
00007   Version:   $Revision: 1.24 $
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 // No strcasecmp in WIN32 world, but stricmp
00025 // http://www.opengroup.org/onlinepubs/007908799/xsh/strcasecmp.html
00026 #ifdef _WIN32
00027 #define strcasecmp stricmp
00028 #endif
00029 
00030 #include <string.h>  // For strtok and strlen
00031 #include <stdlib.h>  // For strtol and strtod
00032 
00033 #include "gdcmArgMgr.h"
00034 
00035 namespace GDCM_NAME_SPACE 
00036 {
00037 //-------------------------------------------------------------------------
00038 // Constructor / Destructor
00039 
00045  ArgMgr::ArgMgr(int argc, char **argv)
00046  {
00047    int i;
00048    int nblettre;
00049    ArgUsed = NULL;
00050    Appel   = NULL;
00051   
00052    /* Read the parameters of the command line *************************/
00053    for ( ArgCount=0, nblettre=1 , i=0; i<argc; i++) 
00054    {
00055       if ( FiltreLong(argv[i]) ) 
00056       { 
00057           std::cout << "Argument too long ( > "
00058                     << ARG_LONG_MAX << ")" << std::endl;
00059           return;
00060       }
00061       if ( argv[i][0] == '@' )
00062       {                       
00063          nblettre  += ArgLoadFromFile ( &argv[i][1] );   
00064       }
00065       else
00066       {                                         
00067          ArgLab [ArgCount] = strcpy ( (char *)malloc(strlen(argv[i])+1), argv[i] ) ;
00068          nblettre  += 1 + strlen(ArgLab[ArgCount]);     
00069          ArgCount++;                               
00070       }
00071       if (ArgCount >= ARGMAXCOUNT )      
00072       {
00073           std::cout << "Too many Arguments ( more than "
00074                     << ARGMAXCOUNT << ")" << std::endl; 
00075           return;
00076       }
00077    }
00078 
00079    /* Fills an array with the already used parameters ****/
00080    ArgUsed = (char *)calloc (1, ArgCount );
00081 
00082    /* Builds the full string with all the parameters  **************/
00083    Appel = (char *) calloc (1, nblettre );
00084 
00085    for ( *Appel = '\0', i=0; i<ArgCount; i++)
00086    {
00087       strcat ( Appel, ArgLab [i] ) ;
00088       strcat ( Appel, " " ) ;
00089    }
00090 
00091    /* Splitting label from label value *************************************/
00092    for ( i=0; i<ArgCount; i++) 
00093    {
00094       char * egaloufin = ArgLab[i] ;
00095       while ( (*egaloufin != '\0') && (*egaloufin != '=') ) 
00096          egaloufin ++ ;
00097       if ( *egaloufin ) *(egaloufin++) = '\0';
00098       ArgStr[i]= egaloufin;
00099    }
00100 
00101    /* Set labels to upper-case (labels are not case sensitive ) *********/
00102    //char *secu;
00103    for ( i=0; i<ArgCount; i++)
00104    {
00105       //secu = ArgLab[i];
00106       ArgLab[i] = Majuscule ( ArgLab[i] ) ;
00107       //free (secu); //we still need it in the caller pgm.
00108    }
00109 
00110   /* Standard arguments are managed by ArgStdArgs **********************/
00111    ArgStdArgs(); 
00112  }
00113 
00117 ArgMgr::~ArgMgr()
00118 {
00119    for(int i=0;i<ArgCount;i++)
00120       if ( ArgLab[i] )
00121          free(ArgLab[i]);
00122    if ( ArgUsed )
00123       free(ArgUsed);
00124    if ( Appel )
00125       free(Appel);
00126 }
00127  
00134 int ArgMgr::ArgMgrDefined( const char *param )
00135 {
00136   int i;
00137   bool trouve;
00138   char *temp;
00139   temp = Majuscule ( param ) ;
00140   for ( i = ArgCount-1; i>0; i-- )
00141   { 
00142     trouve = ( strcmp( ArgLab[i], temp )==0 ) ;
00143     if ( trouve )
00144     {
00145       free (temp);
00146       ArgUsed[i] = true ;           
00147       for ( int j=1; j<i; j++)
00148       {                     
00149          if ( (!ArgUsed[j])&&(!strcmp(ArgLab[i],ArgLab[j])) )
00150             ArgUsed[j] = i ;
00151       }
00152       return i ;
00153     }   
00154   }
00155   free (temp);
00156   return 0 ;
00157 }
00158 
00165 char *ArgMgr::ArgMgrValue ( const char *param )
00166 {
00167    int trouve ;
00168    if ( (trouve = ArgMgrDefined ( param )) != false )
00169       return ArgStr[trouve] ;
00170    else
00171       return NULL ;
00172 }
00173 
00178 const char *ArgMgr::ArgMgrUnused ( )
00179 {
00180    int i ;
00181    for ( i=ArgCount-1; i>0; i-- )
00182    {
00183       if ( ! ArgUsed[i] )
00184       {
00185          ArgMgrDefined(ArgLab[i]);
00186          return ArgLab[i] ;
00187       }
00188   }
00189   return NULL ;
00190 }
00191 
00196 int ArgMgr::ArgMgrPrintUnusedLabels ()
00197 {
00198    const char *label;
00199    int i=0;
00200    while ( (label=ArgMgrUnused())!=0 )
00201    {
00202       if (i==0)
00203          std::cout << "\n Unused Labels:" << std::endl
00204                    << "=============="    << std::endl;
00205       std::cout << "Label : " << label << " = " 
00206                 << ArgMgrValue(label) << std::endl;
00207       i++;
00208    }
00209    return i;
00210 }
00211 
00217 int ArgMgr::ArgMgrUsage(const char **usage )
00218 {
00219    while ( *usage ) 
00220       std::cout << std::endl << *(usage++);
00221    std::cout << std::endl; 
00222    return (0);
00223 }
00224 
00233 int ArgMgr::ArgMgrSave ( const char *param )
00234 {
00235    static int   deja = 0;
00236    FILE         *fd;
00237    if ( *ArgParamOut == '\0' )
00238       return 0;
00239    if ( deja ) 
00240    {
00241       fd = fopen ( ArgParamOut, "a+" );
00242    }
00243    else
00244    {
00245       deja = 1;
00246       fd = fopen ( ArgParamOut, "w" );
00247    } 
00248    if ( !fd ) 
00249       return 0;
00250    fprintf ( fd, "%s\n", param );
00251    fclose  ( fd );
00252    return 1;
00253 }
00254 
00263 int ArgMgr::ArgMgrGetInt(const char *label, int defaultVal)
00264 {
00265    return ( (ArgMgrDefined(label))
00266             ? (atoi(ArgMgrValue(label)))
00267             : (defaultVal) );
00268 }
00269 
00278 float ArgMgr::ArgMgrGetFloat(const char *param, float defaultVal)
00279 {
00280    return     ( (ArgMgrDefined(param))
00281                ? ((float)atof(ArgMgrValue(param)))
00282                : (defaultVal) );
00283 }
00284 
00293 const char *ArgMgr::ArgMgrGetString(const char *param, const char *defaultVal)
00294 {
00295    return    ( (ArgMgrDefined(param)) 
00296               ? (ArgMgrValue(param))
00297               : (defaultVal) );
00298 }
00299 
00311 int ArgMgr::ArgMgrGetLabel (const char *param, const char *liste, int val )
00312 {
00313   char *lab;
00314   const char *vallab;
00315   int i = 1;
00316   char *tmp;
00317   tmp = (char *) malloc(strlen(liste)+1);
00318   strcpy(tmp,liste);
00319 
00320   if ( (vallab = ArgMgrGetString(param,(const char *)NULL)) != 0 ) 
00321   { 
00322      for ( lab = strtok (tmp,"\\"); 
00323            lab != 0; 
00324            lab = strtok(0L,"\\"), i++ )
00325      { 
00326         // strcmp ignoring case
00327         if( strcasecmp(lab, vallab) == 0)
00328            return i;
00329      } 
00330      val=0;
00331    }
00332    free(tmp);
00333    return val;
00334 }
00335 
00347 int ArgMgr::ArgMgrWantLabel (const char *param, char *liste, const char **usage )
00348 {
00349    char *lab;
00350    const char *vallab;
00351    int i = 1;
00352    if ( (vallab = ArgMgrGetString(param,0)) != 0 ) 
00353    {
00354       for ( lab = strtok (liste,"\\"); lab != 0; lab = strtok(0L,"\\"), i++ )
00355         if ( strcasecmp(lab,vallab)==0) 
00356            return i;
00357       return 0;
00358    }
00359    ArgMgrUsage(usage);
00360    return 0;
00361 }
00362 
00371 int ArgMgr::ArgMgrWantInt (const char *label, const char **usage)
00372 {
00373    return        ( (ArgMgrDefined(label) ) 
00374                  ? (atoi(ArgMgrValue(label) ) ) 
00375                  : (ArgMgrUsage(usage),1) );
00376 }
00377 
00386 float ArgMgr::ArgMgrWantFloat (const char *label, const char **usage)
00387 {
00388    return       ( (ArgMgrDefined(label) ) 
00389                 ? ((float)atof(ArgMgrValue(label) ) ) 
00390                 : (ArgMgrUsage(usage),(float)1.0) );
00391 }
00392 
00401 char *ArgMgr::ArgMgrWantString(const char *label, const char **usage)
00402 {
00403    return      ( (ArgMgrDefined(label) ) 
00404                ? (ArgMgrValue(label) ) 
00405                : (ArgMgrUsage(usage),(char*)0) );
00406 }
00407 
00415 char **ArgMgr::ArgMgrGetListOfString ( const char *label, int *number )
00416 {
00417   int taille;
00418   char  *value = ArgMgrValue(label);
00419   char **liste;
00420   char **elem;
00421   char  *chainecur; 
00422   if (!value)
00423   {
00424      *number = 0;
00425      return 0;
00426   }
00427   *number = IdStrCountChar(value,',')+1; /* nb Elements = nb Commas +1 */
00428   taille = *number;
00429   liste = (char **) malloc (sizeof(char*) * taille + strlen(value)+1);
00430   if ( !liste )
00431      return 0;
00432   value = strcpy( ((char*)liste)+sizeof(char*) * taille, value );
00433   for ( elem = liste, chainecur = strtok(value,", ");
00434         taille>0;
00435         taille--, chainecur = (chainecur) ? strtok ( 0, ", " ) : 0 )
00436   {
00437     *(elem++) = chainecur;
00438   }
00439   return liste;
00440 }
00441 
00449 int *ArgMgr::ArgMgrGetListOfInt ( const char *label, int *number )
00450 {
00451   char *value = ArgMgrValue(label);
00452   int *liste;
00453   int *elem;
00454   int taille;
00455   if (!value)
00456   {
00457      *number = 0;
00458      return 0;
00459   }          
00460   *number = IdStrCountChar(value,',')+1; /* nb Elements = nb Commas +1 */ 
00461   taille= *number;
00462   liste = (int *) calloc (1,sizeof(int)*taille );
00463   if ( !liste )
00464      return 0;
00465   elem = liste;
00466   //*number = 1;
00467 
00468   while ( taille>0 ) 
00469   {
00470     *(elem++) = (int) strtol ( value, &value, 10 );      
00471     if ( *value == '\0' )
00472        return liste;
00473     if ( *(value++) != ',' ) 
00474     {
00475       free (liste);
00476       return 0;
00477     }
00478     taille --;
00479   }
00480 return liste;
00481 }
00482 
00489 float *ArgMgr::ArgMgrGetListOfFloat ( const char *label, int *number )
00490 {
00491   char *value = ArgMgrValue(label);
00492   float *liste;
00493   float *elem;
00494   int taille;
00495   if (!value)
00496     return 0;
00497   *number = IdStrCountChar(value,',')+1; /* nb Elements = nb Commas +1 */
00498   taille= *number;
00499   liste = (float *) calloc (1,sizeof(float)*taille );
00500   if ( !liste )
00501   {
00502      *number = 0;
00503      return 0;
00504   }
00505   elem = liste;
00506   //*number = 1;
00507 
00508   while ( taille>0 ) 
00509   {
00510     *(elem++) = (float) strtod ( value, &value );      
00511     if ( *value == '\0' )
00512        return liste;
00513     if ( *(value++) != ',' )
00514     {
00515       free (liste);
00516       return 0;
00517     }
00518     taille --;
00519   }
00520 return liste;
00521 }
00522 
00529 int *ArgMgr::ArgMgrGetIntEnum ( const char *param, int *number )
00530 {
00531    char *value = ArgMgrValue(param);
00532    int *liste;
00533    if (!value) 
00534    {
00535       *number = 0; 
00536       return 0;
00537    }
00538    liste = IdStrIntEnum(value, number);
00539    return liste;
00540 }
00541 
00548 uint16_t *ArgMgr::ArgMgrGetXInt16Enum ( const char *param, int *number )
00549 {
00550    char *value = ArgMgrValue(param);
00551    uint16_t *liste;
00552    if (!value) 
00553    {
00554       *number = 0; 
00555       return 0;
00556    }
00557    liste = IdStrXInt16Enum(value, number);
00558    return liste;
00559 }
00567 float *ArgMgr::ArgMgrGetFloatEnum ( const char *param, int *number )
00568 {
00569    char  *value = ArgMgrValue(param);
00570    float *liste;
00571    if (!value) 
00572    {
00573       *number = 0; 
00574       return 0;
00575    }
00576    liste = IdStrFloatEnum(value, number);
00577    return liste;
00578 }
00579 
00580 // ------------------------ Those are 'service functions' ---------------------
00581 // ------------------------       internal use only       ---------------------
00582 
00589 int ArgMgr::IdStrCountChar (char *chaine, int caract)
00590 {
00591   int i=0;
00592   char *ptr;
00593   for ( ptr = chaine ; *ptr!='\0' ; ptr ++ ) 
00594      if (*ptr==caract) 
00595         i++;  
00596   return i;
00597 }
00598 
00605 int *ArgMgr::IdStrIntEnum ( char* value, int *number)
00606 {
00607    int* liste;
00608    int taille;
00609    int i;
00610 
00611    *number = IdStrCountChar(value,',')+1; /* nb Elements = nb Commas +1 */
00612    taille= *number;
00613    liste = (int *) calloc (1,sizeof(int)*2*taille );
00614    if ( !liste )
00615    {
00616       return 0;
00617    }
00618    i=0;
00619    while ( taille>0 ) 
00620    {
00621       liste[i] = (int) strtol ( value, &value, 10 );
00622       if ( *value == '\0' ) 
00623       {
00624          liste[i+1]=liste[i];
00625          return liste;
00626       }
00627       if ( *(value++) != '-' ) 
00628       {
00629          liste[i+1]=liste[i];
00630          value--;
00631        }
00632        else
00633        {
00634           liste[i+1] = (int) strtol ( value, &value, 10 );
00635        }
00636        if ( *value == '\0' )
00637           return liste;
00638        if ( *(value++) != ',' )
00639        {
00640           free (liste);
00641           return 0;
00642        }
00643        taille --; i+=2;
00644    }
00645    return liste;
00646 }
00647 
00655 uint16_t *ArgMgr::IdStrXInt16Enum ( char *value, int *number)
00656 {
00657    uint16_t *liste;
00658    int taille;
00659    int i;
00660 
00661    *number = IdStrCountChar(value,',')+1; /* nb Elements = nb Commas +1 */
00662    taille= *number;
00663    liste = (uint16_t *) calloc (1,sizeof(uint16_t)*2*taille );
00664    if ( !liste )
00665    {
00666       return 0;
00667    }
00668    i=0;
00669    while ( taille>0 ) 
00670    {
00671       liste[i] = (uint16_t) strtol ( value, &value, 16 );
00672       if ( *value == '\0' ) 
00673       {
00674          liste[i+1]=liste[i];
00675          return liste;
00676       }
00677       if ( *(value++) != '-' ) 
00678       {
00679          liste[i+1]=liste[i];
00680          value--;
00681        }
00682        else
00683        {
00684           liste[i+1] = (uint16_t) strtol ( value, &value, 16 );
00685        }
00686        if ( *value == '\0' )
00687           return liste;
00688        if ( *(value++) != ',' )
00689        {
00690           free (liste);
00691           return 0;
00692        }
00693        taille --; i+=2;
00694    }
00695    return liste;
00696 } 
00703 float *ArgMgr::IdStrFloatEnum (char *value, int *number)
00704 {
00705    float *liste;
00706    int taille;
00707    int i;
00708    *number = IdStrCountChar(value,',')+1; /* nb Elements = nb Commas +1 */
00709    taille= *number;
00710    liste = (float *) calloc (1,sizeof(float)*2*taille );
00711    if ( !liste )
00712       return 0;
00713    i=0;
00714    while ( taille>0 ) 
00715    {
00716       liste[i] = (float) strtod ( value, &value );      
00717       if ( *value == '\0' ) 
00718       {
00719          liste[i+1]=liste[i];
00720          return liste;
00721       }
00722       if ( *(value++) != '-' ) 
00723       {
00724          liste[i+1]=liste[i];
00725          value--;
00726       }
00727       else
00728       {
00729           liste[i+1] = (float) strtod ( value, &value );
00730       }
00731       if ( *value == '\0' ) 
00732          return liste;
00733       if ( *(value++) != ',' )
00734       {
00735          free (liste);
00736          return 0;
00737       }
00738       taille --; i+=2;
00739    }
00740    return liste;
00741 }
00742 
00743 //-----------------------------------------------------------------------------
00744 // Protected
00745 
00746 //-----------------------------------------------------------------------------
00747 // Private
00748 
00749 /**************************************************************************
00750 *                                                                         *
00751 * Nom de la fonction : Majuscule                                          *
00752 * Role ............. : Creates a new Upper case char array.               *
00753 * parameters ....... : Pointer to the initial char array.                 *                           *
00754 * Valeur retournee . : Pointer to the new Upper case char array.          *
00755 *                                                                         *
00756 **************************************************************************/
00757 char *ArgMgr::Majuscule (const char *chaine )
00758 {
00759   char *ptr, *ptr2, *ptr3;
00760   ptr2 = (char *)malloc(strlen(chaine)*sizeof(char)+1);
00761   ptr3=ptr2;
00762   for ( ptr = (char *)chaine ; *ptr!='\0' ; ptr ++ ) 
00763    {  
00764        *ptr3 = toupper ( * ptr ); ptr3++; 
00765    }
00766   *ptr3='\0'; 
00767   return ptr2;
00768 }
00769 
00770 /**************************************************************************
00771 *                                                                         *
00772 * Nom de la fonction : FiltreLong                                         *
00773 * Role ............. : Stops the program if argument is too long.         *
00774 *                      ARG_LONG_MAX defines max length.                   *
00775 * parameters ....... : Pointer to the argument.                           *
00776 * Valeur retournee . : false if OK.                                       *
00777 *                      true if KO.                                        *
00778 **************************************************************************/
00779 int ArgMgr::FiltreLong ( const char *arg  )
00780 {
00781   int  n = 0 ;
00782   while ( (n++<ARG_LONG_MAX) && (*(arg++) != '\0') ) ;
00783   return (n>=ARG_LONG_MAX) ;
00784 }
00785 
00786 /*------------------------------------------------------------------------
00787  | Role       : Reads a parameter from a file
00788  | Return     : Type   : char *
00789  |              Role   : pointer to the label
00790  | parameters : param  : char *
00791  |              Role   : one where the parameter will be stored
00792  |              fd     : FILE *
00793  |              Role   : File description (assumed to be open)
00794  +------------------------------------------------------------------------*/
00795 const char *ArgMgr::LoadedParam ( const char *param, FILE *fd )
00796 {
00797   int    carlu;
00798   char  *car = (char *)param;
00799   int    quote = false;
00800   int    nbcar = 0;
00801 
00802   /* remove spaces at the beginning****/
00803   while ( isspace(carlu=fgetc (fd)) );
00804   if (carlu==EOF)
00805      return 0;
00806   /* Search for a " */
00807   if ( carlu=='\"' ) 
00808   {
00809     carlu=fgetc(fd);
00810     quote=true;
00811   /* Read all the characters */
00812   }
00813   while (  (carlu!=EOF)
00814         && (  ( (!quote)&&(!isspace(carlu)) )
00815          ||( (quote)&& !(carlu=='\"')   ) ) ) 
00816   {
00817      *(car++) = (char) carlu;
00818      nbcar ++;
00819   /* sans depasser la taille max*/
00820      if ( nbcar >= ARG_LONG_MAX ) 
00821      {
00822         std::cout << "\nError: Argument too long ( > "
00823                   << ARG_LONG_MAX << ")in parameter file."
00824                   << std::endl;
00825         break;
00826      }
00827      carlu = fgetc(fd);
00828   }
00829   *car = '\0';
00830   return param;
00831 }
00832 
00833 /*------------------------------------------------------------------------
00834  | Role       : Reading of arguments in a parameter file
00835  |              (this function is recursive).
00836  | Return     : Type   : int
00837  |              Role   : length needed to store all the parameters
00838  | parameters : filename : char *
00839  |              Role     : parameter File name
00840  |
00841  +------------------------------------------------------------------------*/
00842 int ArgMgr::ArgLoadFromFile ( const char *filename )
00843 {
00844   int   nbl = 0;
00845   char  param[ARG_LONG_MAX+1];
00846   FILE  *fch;
00847 
00848   fch = fopen ( filename, ID_RFILE_TEXT );
00849   while ( LoadedParam (param, fch ) )
00850   {
00851     int n = strlen(param);
00852     if ( param[0]=='@' )
00853     {
00854       nbl  += ArgLoadFromFile ( &param[1] );
00855     }
00856     else
00857     {
00858       ArgLab [ArgCount] = strcpy ((char *) malloc(n+1), param ) ;
00859       nbl += n + 1 ;
00860       ArgCount++;
00861       if ( ArgCount >= ARGMAXCOUNT ) 
00862          break;
00863     }
00864   }
00865   fclose ( fch );
00866   return nbl;
00867 }
00868 
00869 /*------------------------------------------------------------------------
00870  | Role       : Standard parameters management (on command line)
00871  | Return     : Type   : void
00872  | parameters : none
00873  +------------------------------------------------------------------------*/
00874 void ArgMgr::ArgStdArgs()
00875 {
00876   char *logfile;
00877   FILE *fd;
00878 
00879   if ( (ArgParamOut=ArgMgrValue((char*)ARG_LABEL_PARAMOUT))==0 )
00880     ArgParamOut = ARG_DEFAULT_PARAMOUT;
00881   if ( (logfile = ArgMgrValue((char*)ARG_LABEL_LOGFILE))!=0) 
00882   {
00883     if ( *logfile == '\0' )
00884        logfile = (char *)ARG_DEFAULT_LOGFILE;
00885     fd = fopen ( logfile, "a+" );
00886     if ( fd ) 
00887     {
00888       fprintf ( fd, "%s\n", Appel );
00889       fclose  ( fd );
00890     }
00891   }
00892 }
00893 
00894 /*------------------------------------------------------------------------
00895  | Role       : Sets in Upper Case.
00896  | Return     : Type   : char *
00897  | parameters : char *
00898  +------------------------------------------------------------------------*/
00899 char *ArgMgr::maj ( char *a )
00900 {
00901    char *b = a;
00902    while ( *b !=0 ) 
00903    {
00904       if ( *b<='z' && *b>='a' ) *b = *b+'A'-'a';
00905       b++;
00906    }
00907    return a;
00908 }
00909 //-----------------------------------------------------------------------------
00910 // Print
00911 
00912 //-----------------------------------------------------------------------------
00913 } // end namespace gdcm

Generated on Fri Aug 24 12:59:28 2007 for gdcm by  doxygen 1.4.6