]> Creatis software - gdcm.git/blob - src/gdcmArgMgr.cxx
UserDefinedFileIdentifier is now more human readable
[gdcm.git] / src / gdcmArgMgr.cxx
1 /*=========================================================================
2   
3   Program:   gdcm
4   Module:    $RCSfile: gdcmArgMgr.cxx,v $
5   Language:  C++
6   Date:      $Date: 2007/05/23 14:18:07 $
7   Version:   $Revision: 1.24 $
8   
9   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10   l'Image). All rights reserved. See Doc/License.txt or
11   http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
12   
13      This software is distributed WITHOUT ANY WARRANTY; without even
14      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15      PURPOSE.  See the above copyright notices for more information.
16   
17 =========================================================================*/
18
19 #include <stdio.h>
20 #include <iostream>
21 #include <ctype.h>
22 #include <string.h>  // For strlen
23
24 // No strcasecmp in WIN32 world, but stricmp
25 // http://www.opengroup.org/onlinepubs/007908799/xsh/strcasecmp.html
26 #ifdef _WIN32
27 #define strcasecmp stricmp
28 #endif
29
30 #include <string.h>  // For strtok and strlen
31 #include <stdlib.h>  // For strtol and strtod
32
33 #include "gdcmArgMgr.h"
34
35 namespace GDCM_NAME_SPACE 
36 {
37 //-------------------------------------------------------------------------
38 // Constructor / Destructor
39
40 /**
41  * \brief   constructor
42  * @param argc arguments count, as passed to main()
43  * @param argv  pointers array on the arguments passed to main()  
44  */
45  ArgMgr::ArgMgr(int argc, char **argv)
46  {
47    int i;
48    int nblettre;
49    ArgUsed = NULL;
50    Appel   = NULL;
51   
52    /* Read the parameters of the command line *************************/
53    for ( ArgCount=0, nblettre=1 , i=0; i<argc; i++) 
54    {
55       if ( FiltreLong(argv[i]) ) 
56       { 
57           std::cout << "Argument too long ( > "
58                     << ARG_LONG_MAX << ")" << std::endl;
59           return;
60       }
61       if ( argv[i][0] == '@' )
62       {                       
63          nblettre  += ArgLoadFromFile ( &argv[i][1] );   
64       }
65       else
66       {                                         
67          ArgLab [ArgCount] = strcpy ( (char *)malloc(strlen(argv[i])+1), argv[i] ) ;
68          nblettre  += 1 + strlen(ArgLab[ArgCount]);     
69          ArgCount++;                               
70       }
71       if (ArgCount >= ARGMAXCOUNT )      
72       {
73           std::cout << "Too many Arguments ( more than "
74                     << ARGMAXCOUNT << ")" << std::endl; 
75           return;
76       }
77    }
78
79    /* Fills an array with the already used parameters ****/
80    ArgUsed = (char *)calloc (1, ArgCount );
81
82    /* Builds the full string with all the parameters  **************/
83    Appel = (char *) calloc (1, nblettre );
84
85    for ( *Appel = '\0', i=0; i<ArgCount; i++)
86    {
87       strcat ( Appel, ArgLab [i] ) ;
88       strcat ( Appel, " " ) ;
89    }
90
91    /* Splitting label from label value *************************************/
92    for ( i=0; i<ArgCount; i++) 
93    {
94       char * egaloufin = ArgLab[i] ;
95       while ( (*egaloufin != '\0') && (*egaloufin != '=') ) 
96          egaloufin ++ ;
97       if ( *egaloufin ) *(egaloufin++) = '\0';
98       ArgStr[i]= egaloufin;
99    }
100
101    /* Set labels to upper-case (labels are not case sensitive ) *********/
102    //char *secu;
103    for ( i=0; i<ArgCount; i++)
104    {
105       //secu = ArgLab[i];
106       ArgLab[i] = Majuscule ( ArgLab[i] ) ;
107       //free (secu); //we still need it in the caller pgm.
108    }
109
110   /* Standard arguments are managed by ArgStdArgs **********************/
111    ArgStdArgs(); 
112  }
113
114 /**
115  * \brief  canonical destructor
116  */
117 ArgMgr::~ArgMgr()
118 {
119    for(int i=0;i<ArgCount;i++)
120       if ( ArgLab[i] )
121          free(ArgLab[i]);
122    if ( ArgUsed )
123       free(ArgUsed);
124    if ( Appel )
125       free(Appel);
126 }
127  
128 /**
129  * \brief  checks if a parameter exists in the command line
130  * @param param  label name
131  * @return   0 if label is not found
132  *           else, returns the number of the spot it was found last time.
133  */
134 int ArgMgr::ArgMgrDefined( const char *param )
135 {
136   int i;
137   bool trouve;
138   char *temp;
139   temp = Majuscule ( param ) ;
140   for ( i = ArgCount-1; i>0; i-- )
141   { 
142     trouve = ( strcmp( ArgLab[i], temp )==0 ) ;
143     if ( trouve )
144     {
145       free (temp);
146       ArgUsed[i] = true ;           
147       for ( int j=1; j<i; j++)
148       {                     
149          if ( (!ArgUsed[j])&&(!strcmp(ArgLab[i],ArgLab[j])) )
150             ArgUsed[j] = i ;
151       }
152       return i ;
153     }   
154   }
155   free (temp);
156   return 0 ;
157 }
158
159 /**
160  * \brief  Gets the parameter value, read on the command line
161  * @param param   name of the searched parameter label
162  * @return   Value, as a char array, of the parameter
163  *            whose label is given.
164  */
165 char *ArgMgr::ArgMgrValue ( const char *param )
166 {
167    int trouve ;
168    if ( (trouve = ArgMgrDefined ( param )) != false )
169       return ArgStr[trouve] ;
170    else
171       return NULL ;
172 }
173
174 /**
175  * \brief  Search for the first not yet used label
176  * @return Pointer to the char array holding the first non used label
177  */
178 const char *ArgMgr::ArgMgrUnused ( )
179 {
180    int i ;
181    for ( i=ArgCount-1; i>0; i-- )
182    {
183       if ( ! ArgUsed[i] )
184       {
185          ArgMgrDefined(ArgLab[i]);
186          return ArgLab[i] ;
187       }
188   }
189   return NULL ;
190 }
191
192 /**
193  * \brief  Prints unused labels, if any
194  * @return number of unused labels
195  */
196 int ArgMgr::ArgMgrPrintUnusedLabels ()
197 {
198    const char *label;
199    int i=0;
200    while ( (label=ArgMgrUnused())!=0 )
201    {
202       if (i==0)
203          std::cout << "\n Unused Labels:" << std::endl
204                    << "=============="    << std::endl;
205       std::cout << "Label : " << label << " = " 
206                 << ArgMgrValue(label) << std::endl;
207       i++;
208    }
209    return i;
210 }
211
212 /**
213  * \brief  Prints program usage
214  * @param usage  array of pointers to the documentation lines of the program.
215  * @return exception code
216  */
217 int ArgMgr::ArgMgrUsage(const char **usage )
218 {
219    while ( *usage ) 
220       std::cout << std::endl << *(usage++);
221    std::cout << std::endl; 
222    return (0);
223 }
224
225 /**
226  * \brief Forget it, right now ... 
227  * Saves a char. array in a parameter file
228  *         whose name is given on command line by : PARAMOUT=???
229  *         or, as a default, by ARG_DEFAULT_PARAMOUT
230  * @param param  char. array that defines the parameter
231  * @return   Entier correspondant au rang dans la liste de labels
232  */
233 int ArgMgr::ArgMgrSave ( const char *param )
234 {
235    static int   deja = 0;
236    FILE         *fd;
237    if ( *ArgParamOut == '\0' )
238       return 0;
239    if ( deja ) 
240    {
241       fd = fopen ( ArgParamOut, "a+" );
242    }
243    else
244    {
245       deja = 1;
246       fd = fopen ( ArgParamOut, "w" );
247    } 
248    if ( !fd ) 
249       return 0;
250    fprintf ( fd, "%s\n", param );
251    fclose  ( fd );
252    return 1;
253 }
254
255 /**
256  * \brief  Gets an int value passed as an argument to a program
257  *         (use default value if not found)
258  *         EXAMPLE:     int dimx = ArgMgrGetInt ( "DIMX", 256 );
259  * @param label   label name 
260  * @param defaultVal default value
261  * @return parameter value
262  */
263 int ArgMgr::ArgMgrGetInt(const char *label, int defaultVal)
264 {
265    return ( (ArgMgrDefined(label))
266             ? (atoi(ArgMgrValue(label)))
267             : (defaultVal) );
268 }
269
270 /**
271  * \brief  Gets a float value passed as an argument to a program
272  *         (use default value if not found)
273  *         EXAMPLE:     float scale = ArgMgrGetFloat ( "SCALE", 0.33 );
274  * @param param   label name 
275  * @param defaultVal default value
276  * @return parameter value
277  */
278 float ArgMgr::ArgMgrGetFloat(const char *param, float defaultVal)
279 {
280    return     ( (ArgMgrDefined(param))
281                ? ((float)atof(ArgMgrValue(param)))
282                : (defaultVal) );
283 }
284
285 /**
286  * \brief  Gets a 'string' value passed as an argument to a program
287  *         (use default value if not found)
288  *         EXAMPLE :  char *imageName = ArgMgrGetString( "NAME", "test.dcm" );
289  * @param param   label name 
290  * @param defaultVal default value
291  * @return parameter value
292  */
293 const char *ArgMgr::ArgMgrGetString(const char *param, const char *defaultVal)
294 {
295    return    ( (ArgMgrDefined(param)) 
296               ? (ArgMgrValue(param))
297               : (defaultVal) );
298 }
299
300 /**
301  * \brief  Gets a value amongst a set of values
302  *         (use default value if not found) 
303  *         EXAMPLE:     int nlab = ArgMgrGetLabel("CONFIRM","NO\\YES", 0); 
304  * @param param   label name 
305  * @param liste  character Chain describing the various values.
306  *               Value are separated by '\\'.
307  *               Not case sensitive.
308  * @param val  number of default value
309  * @return   int : range of value amongst the values list
310  */
311 int ArgMgr::ArgMgrGetLabel (const char *param, const char *liste, int val )
312 {
313   char *lab;
314   const char *vallab;
315   int i = 1;
316   char *tmp;
317   tmp = (char *) malloc(strlen(liste)+1);
318   strcpy(tmp,liste);
319
320   if ( (vallab = ArgMgrGetString(param,(const char *)NULL)) != 0 ) 
321   { 
322      for ( lab = strtok (tmp,"\\"); 
323            lab != 0; 
324            lab = strtok(0L,"\\"), i++ )
325      { 
326         // strcmp ignoring case
327         if( strcasecmp(lab, vallab) == 0)
328            return i;
329      } 
330      val=0;
331    }
332    free(tmp);
333    return val;
334 }
335
336 /**
337  * \brief  Demands a value amongst a set of values (abort if not found)
338  *         EXaMPLE:     int nlab = ArgMgrWantLabel("CONFIRM","NO\\YES", usage); 
339  * @param param   label name 
340  * @param liste  character Chain describing the various values.
341  *               Labels are separated by  '\\'.
342  *               No case sensitive.
343  *               WARNING this will be changed (not const)
344  * @param usage Usage program (displayed if label not found)
345  * @return   int : range of value amongst the values list
346  */
347 int ArgMgr::ArgMgrWantLabel (const char *param, char *liste, const char **usage )
348 {
349    char *lab;
350    const char *vallab;
351    int i = 1;
352    if ( (vallab = ArgMgrGetString(param,0)) != 0 ) 
353    {
354       for ( lab = strtok (liste,"\\"); lab != 0; lab = strtok(0L,"\\"), i++ )
355         if ( strcasecmp(lab,vallab)==0) 
356            return i;
357       return 0;
358    }
359    ArgMgrUsage(usage);
360    return 0;
361 }
362
363 /**
364  * \brief  Demands an int value passed as an argument to a program
365  *         If not found usage is displayed and the prog aborted
366  *  EXAMPLE:     int dimx = ArgMgrWantInt ( "DIMX", usage );
367  * @param label   label name 
368  * @param usage Usage program (displayed if label not found)
369  * @return parameter value
370  */
371 int ArgMgr::ArgMgrWantInt (const char *label, const char **usage)
372 {
373    return        ( (ArgMgrDefined(label) ) 
374                  ? (atoi(ArgMgrValue(label) ) ) 
375                  : (ArgMgrUsage(usage),1) );
376 }
377
378 /**
379  * \brief  Demands a float value passed as an argument to a program
380  *         If not found usage is displayed and the prog aborted
381  *  EXAMPLE:     float scale = ArgMgrWantFloat ( "SCALE", usage );
382  * @param label   label name 
383  * @param usage Usage program (displayed if label not found)
384  * @return parameter value
385  */
386 float ArgMgr::ArgMgrWantFloat (const char *label, const char **usage)
387 {
388    return       ( (ArgMgrDefined(label) ) 
389                 ? ((float)atof(ArgMgrValue(label) ) ) 
390                 : (ArgMgrUsage(usage),(float)1.0) );
391 }
392
393 /**
394  * \brief  Demands a 'string' value passed as an argument to a program
395  *         If not found usage is displayed and the prog aborted
396  *  EXAMPLE:     char *code = ArgMgrWantString ( "CODE", usage );
397  * @param label   Parameter label
398  * @param usage Usage program (displayed if label not found)
399  * @return parameter value
400  */
401 char *ArgMgr::ArgMgrWantString(const char *label, const char **usage)
402 {
403    return      ( (ArgMgrDefined(label) ) 
404                ? (ArgMgrValue(label) ) 
405                : (ArgMgrUsage(usage),(char*)0) );
406 }
407
408 /**
409  * \brief  decodes and returns an array of 'STRING'
410  *  EXAMPLE:     char **codes = ArgMgrGetListOfString ( "CODES", &nbOfCodes ); 
411  * @param label   label name 
412  * @param number  nb of found 'STRINGs'
413  * @return   Pointer to the 'STRING' array; NULL if error
414  */
415 char **ArgMgr::ArgMgrGetListOfString ( const char *label, int *number )
416 {
417   int taille;
418   char  *value = ArgMgrValue(label);
419   char **liste;
420   char **elem;
421   char  *chainecur; 
422   if (!value)
423   {
424      *number = 0;
425      return 0;
426   }
427   *number = IdStrCountChar(value,',')+1; /* nb Elements = nb Commas +1 */
428   taille = *number;
429   liste = (char **) malloc (sizeof(char*) * taille + strlen(value)+1);
430   if ( !liste )
431      return 0;
432   value = strcpy( ((char*)liste)+sizeof(char*) * taille, value );
433   for ( elem = liste, chainecur = strtok(value,", ");
434         taille>0;
435         taille--, chainecur = (chainecur) ? strtok ( 0, ", " ) : 0 )
436   {
437     *(elem++) = chainecur;
438   }
439   return liste;
440 }
441
442 /**
443  * \brief  decodes and returns an array of 'INT'
444  *  EXAMPLE:     int *points = ArgMgrGetListOfInt ( "POINTS", &nbOfPoints );  
445  * @param label   label name 
446  * @param number  nb of found INT
447  * @return   Pointer to the INT array; NULL if error
448  */
449 int *ArgMgr::ArgMgrGetListOfInt ( const char *label, int *number )
450 {
451   char *value = ArgMgrValue(label);
452   int *liste;
453   int *elem;
454   int taille;
455   if (!value)
456   {
457      *number = 0;
458      return 0;
459   }          
460   *number = IdStrCountChar(value,',')+1; /* nb Elements = nb Commas +1 */ 
461   taille= *number;
462   liste = (int *) calloc (1,sizeof(int)*taille );
463   if ( !liste )
464      return 0;
465   elem = liste;
466   //*number = 1;
467
468   while ( taille>0 ) 
469   {
470     *(elem++) = (int) strtol ( value, &value, 10 );      
471     if ( *value == '\0' )
472        return liste;
473     if ( *(value++) != ',' ) 
474     {
475       free (liste);
476       return 0;
477     }
478     taille --;
479   }
480 return liste;
481 }
482
483 /**
484  * \brief  decodes and returns an array of 'FLOAT'
485  * @param label   label name 
486  * @param number  number of found FLOATs
487  * @return   Pointer to the FLOAT array; NULL if error
488  */
489 float *ArgMgr::ArgMgrGetListOfFloat ( const char *label, int *number )
490 {
491   char *value = ArgMgrValue(label);
492   float *liste;
493   float *elem;
494   int taille;
495   if (!value)
496     return 0;
497   *number = IdStrCountChar(value,',')+1; /* nb Elements = nb Commas +1 */
498   taille= *number;
499   liste = (float *) calloc (1,sizeof(float)*taille );
500   if ( !liste )
501   {
502      *number = 0;
503      return 0;
504   }
505   elem = liste;
506   //*number = 1;
507
508   while ( taille>0 ) 
509   {
510     *(elem++) = (float) strtod ( value, &value );      
511     if ( *value == '\0' )
512        return liste;
513     if ( *(value++) != ',' )
514     {
515       free (liste);
516       return 0;
517     }
518     taille --;
519   }
520 return liste;
521 }
522
523 /**
524  * \brief  decodes and returns an array of 'INT pairs', passed in decimal
525  * @param param   label name 
526  * @param number   nb of found pairs
527  * @return        pointer to the array of 'INT pairs'; NULL if fail
528  */
529 int *ArgMgr::ArgMgrGetIntEnum ( const char *param, int *number )
530 {
531    char *value = ArgMgrValue(param);
532    int *liste;
533    if (!value) 
534    {
535       *number = 0; 
536       return 0;
537    }
538    liste = IdStrIntEnum(value, number);
539    return liste;
540 }
541
542 /**
543  * \brief  decodes and returns an array of 'INT16 pairs', passed in hexadecimal
544  * @param param   label name 
545  * @param number   nb of found pairs
546  * @return        pointer to the array of 'INT16 pairs'; NULL if fail
547  */
548 uint16_t *ArgMgr::ArgMgrGetXInt16Enum ( const char *param, int *number )
549 {
550    char *value = ArgMgrValue(param);
551    uint16_t *liste;
552    if (!value) 
553    {
554       *number = 0; 
555       return 0;
556    }
557    liste = IdStrXInt16Enum(value, number);
558    return liste;
559 }
560 /**
561  * \brief  decodes and returns an array of 'FLOAT pairs'
562  * @param param   label name 
563  * @param number   nb of found pairs
564  * @return        pointer to the array of 'FLOAT pairs'; NULL if fail
565
566  */
567 float *ArgMgr::ArgMgrGetFloatEnum ( const char *param, int *number )
568 {
569    char  *value = ArgMgrValue(param);
570    float *liste;
571    if (!value) 
572    {
573       *number = 0; 
574       return 0;
575    }
576    liste = IdStrFloatEnum(value, number);
577    return liste;
578 }
579
580 // ------------------------ Those are 'service functions' ---------------------
581 // ------------------------       internal use only       ---------------------
582
583 /**
584  * \brief     Counts the nb of occurrences of a given charact within a 'string' 
585  * @param chaine     Pointer to the 'string'
586  * @param caract     charact to count
587  * @return       occurence number
588  */
589 int ArgMgr::IdStrCountChar (char *chaine, int caract)
590 {
591   int i=0;
592   char *ptr;
593   for ( ptr = chaine ; *ptr!='\0' ; ptr ++ ) 
594      if (*ptr==caract) 
595         i++;  
596   return i;
597 }
598
599 /**
600  * \brief     returns an array of 'INT pairs'
601  * @param value  char array decribing a set of 'INT pairs' (f1-l1, f2-l2, ...)
602  * @param number nb of found INT pairs
603  * @return       pointer to the array of 'INT pairs'
604  */
605 int *ArgMgr::IdStrIntEnum ( char* value, int *number)
606 {
607    int* liste;
608    int taille;
609    int i;
610
611    *number = IdStrCountChar(value,',')+1; /* nb Elements = nb Commas +1 */
612    taille= *number;
613    liste = (int *) calloc (1,sizeof(int)*2*taille );
614    if ( !liste )
615    {
616       return 0;
617    }
618    i=0;
619    while ( taille>0 ) 
620    {
621       liste[i] = (int) strtol ( value, &value, 10 );
622       if ( *value == '\0' ) 
623       {
624          liste[i+1]=liste[i];
625          return liste;
626       }
627       if ( *(value++) != '-' ) 
628       {
629          liste[i+1]=liste[i];
630          value--;
631        }
632        else
633        {
634           liste[i+1] = (int) strtol ( value, &value, 10 );
635        }
636        if ( *value == '\0' )
637           return liste;
638        if ( *(value++) != ',' )
639        {
640           free (liste);
641           return 0;
642        }
643        taille --; i+=2;
644    }
645    return liste;
646 }
647
648 /**
649  * \brief     returns an array of set of 'INT16 pairs', passed in Hexadecimal
650  * @param value  char array decribing a set of 'INT16 pairs' (f1-l1, f2-l2, ...)
651  *               coded in hexadecimal e.g. 0x0008,0x00ac
652  * @param number nb of found pairs
653  * @return        array of set of 'INT16 pairs'
654  */
655 uint16_t *ArgMgr::IdStrXInt16Enum ( char *value, int *number)
656 {
657    uint16_t *liste;
658    int taille;
659    int i;
660
661    *number = IdStrCountChar(value,',')+1; /* nb Elements = nb Commas +1 */
662    taille= *number;
663    liste = (uint16_t *) calloc (1,sizeof(uint16_t)*2*taille );
664    if ( !liste )
665    {
666       return 0;
667    }
668    i=0;
669    while ( taille>0 ) 
670    {
671       liste[i] = (uint16_t) strtol ( value, &value, 16 );
672       if ( *value == '\0' ) 
673       {
674          liste[i+1]=liste[i];
675          return liste;
676       }
677       if ( *(value++) != '-' ) 
678       {
679          liste[i+1]=liste[i];
680          value--;
681        }
682        else
683        {
684           liste[i+1] = (uint16_t) strtol ( value, &value, 16 );
685        }
686        if ( *value == '\0' )
687           return liste;
688        if ( *(value++) != ',' )
689        {
690           free (liste);
691           return 0;
692        }
693        taille --; i+=2;
694    }
695    return liste;
696
697 /**
698  * \brief     returns an array of 'FLOAT pairs'
699  * @param value  char array decribing a set of 'FLOAT pairs' (f1-l1, f2-l2, ...)
700  * @param number nb of found pairs
701  * @return       pointer to the array of 'FLOAT pairs'; NULL if fail
702  */
703 float *ArgMgr::IdStrFloatEnum (char *value, int *number)
704 {
705    float *liste;
706    int taille;
707    int i;
708    *number = IdStrCountChar(value,',')+1; /* nb Elements = nb Commas +1 */
709    taille= *number;
710    liste = (float *) calloc (1,sizeof(float)*2*taille );
711    if ( !liste )
712       return 0;
713    i=0;
714    while ( taille>0 ) 
715    {
716       liste[i] = (float) strtod ( value, &value );      
717       if ( *value == '\0' ) 
718       {
719          liste[i+1]=liste[i];
720          return liste;
721       }
722       if ( *(value++) != '-' ) 
723       {
724          liste[i+1]=liste[i];
725          value--;
726       }
727       else
728       {
729           liste[i+1] = (float) strtod ( value, &value );
730       }
731       if ( *value == '\0' ) 
732          return liste;
733       if ( *(value++) != ',' )
734       {
735          free (liste);
736          return 0;
737       }
738       taille --; i+=2;
739    }
740    return liste;
741 }
742
743 //-----------------------------------------------------------------------------
744 // Protected
745
746 //-----------------------------------------------------------------------------
747 // Private
748
749 /**************************************************************************
750 *                                                                         *
751 * Nom de la fonction : Majuscule                                          *
752 * Role ............. : Creates a new Upper case char array.               *
753 * parameters ....... : Pointer to the initial char array.                 *                           *
754 * Valeur retournee . : Pointer to the new Upper case char array.          *
755 *                                                                         *
756 **************************************************************************/
757 char *ArgMgr::Majuscule (const char *chaine )
758 {
759   char *ptr, *ptr2, *ptr3;
760   ptr2 = (char *)malloc(strlen(chaine)*sizeof(char)+1);
761   ptr3=ptr2;
762   for ( ptr = (char *)chaine ; *ptr!='\0' ; ptr ++ ) 
763    {  
764        *ptr3 = toupper ( * ptr ); ptr3++; 
765    }
766   *ptr3='\0'; 
767   return ptr2;
768 }
769
770 /**************************************************************************
771 *                                                                         *
772 * Nom de la fonction : FiltreLong                                         *
773 * Role ............. : Stops the program if argument is too long.         *
774 *                      ARG_LONG_MAX defines max length.                   *
775 * parameters ....... : Pointer to the argument.                           *
776 * Valeur retournee . : false if OK.                                       *
777 *                      true if KO.                                        *
778 **************************************************************************/
779 int ArgMgr::FiltreLong ( const char *arg  )
780 {
781   int  n = 0 ;
782   while ( (n++<ARG_LONG_MAX) && (*(arg++) != '\0') ) ;
783   return (n>=ARG_LONG_MAX) ;
784 }
785
786 /*------------------------------------------------------------------------
787  | Role       : Reads a parameter from a file
788  | Return     : Type   : char *
789  |              Role   : pointer to the label
790  | parameters : param  : char *
791  |              Role   : one where the parameter will be stored
792  |              fd     : FILE *
793  |              Role   : File description (assumed to be open)
794  +------------------------------------------------------------------------*/
795 const char *ArgMgr::LoadedParam ( const char *param, FILE *fd )
796 {
797   int    carlu;
798   char  *car = (char *)param;
799   int    quote = false;
800   int    nbcar = 0;
801
802   /* remove spaces at the beginning****/
803   while ( isspace(carlu=fgetc (fd)) );
804   if (carlu==EOF)
805      return 0;
806   /* Search for a " */
807   if ( carlu=='\"' ) 
808   {
809     carlu=fgetc(fd);
810     quote=true;
811   /* Read all the characters */
812   }
813   while (  (carlu!=EOF)
814         && (  ( (!quote)&&(!isspace(carlu)) )
815          ||( (quote)&& !(carlu=='\"')   ) ) ) 
816   {
817      *(car++) = (char) carlu;
818      nbcar ++;
819   /* sans depasser la taille max*/
820      if ( nbcar >= ARG_LONG_MAX ) 
821      {
822         std::cout << "\nError: Argument too long ( > "
823                   << ARG_LONG_MAX << ")in parameter file."
824                   << std::endl;
825         break;
826      }
827      carlu = fgetc(fd);
828   }
829   *car = '\0';
830   return param;
831 }
832
833 /*------------------------------------------------------------------------
834  | Role       : Reading of arguments in a parameter file
835  |              (this function is recursive).
836  | Return     : Type   : int
837  |              Role   : length needed to store all the parameters
838  | parameters : filename : char *
839  |              Role     : parameter File name
840  |
841  +------------------------------------------------------------------------*/
842 int ArgMgr::ArgLoadFromFile ( const char *filename )
843 {
844   int   nbl = 0;
845   char  param[ARG_LONG_MAX+1];
846   FILE  *fch;
847
848   fch = fopen ( filename, ID_RFILE_TEXT );
849   while ( LoadedParam (param, fch ) )
850   {
851     int n = strlen(param);
852     if ( param[0]=='@' )
853     {
854       nbl  += ArgLoadFromFile ( &param[1] );
855     }
856     else
857     {
858       ArgLab [ArgCount] = strcpy ((char *) malloc(n+1), param ) ;
859       nbl += n + 1 ;
860       ArgCount++;
861       if ( ArgCount >= ARGMAXCOUNT ) 
862          break;
863     }
864   }
865   fclose ( fch );
866   return nbl;
867 }
868
869 /*------------------------------------------------------------------------
870  | Role       : Standard parameters management (on command line)
871  | Return     : Type   : void
872  | parameters : none
873  +------------------------------------------------------------------------*/
874 void ArgMgr::ArgStdArgs()
875 {
876   char *logfile;
877   FILE *fd;
878
879   if ( (ArgParamOut=ArgMgrValue((char*)ARG_LABEL_PARAMOUT))==0 )
880     ArgParamOut = ARG_DEFAULT_PARAMOUT;
881   if ( (logfile = ArgMgrValue((char*)ARG_LABEL_LOGFILE))!=0) 
882   {
883     if ( *logfile == '\0' )
884        logfile = (char *)ARG_DEFAULT_LOGFILE;
885     fd = fopen ( logfile, "a+" );
886     if ( fd ) 
887     {
888       fprintf ( fd, "%s\n", Appel );
889       fclose  ( fd );
890     }
891   }
892 }
893
894 /*------------------------------------------------------------------------
895  | Role       : Sets in Upper Case.
896  | Return     : Type   : char *
897  | parameters : char *
898  +------------------------------------------------------------------------*/
899 char *ArgMgr::maj ( char *a )
900 {
901    char *b = a;
902    while ( *b !=0 ) 
903    {
904       if ( *b<='z' && *b>='a' ) *b = *b+'A'-'a';
905       b++;
906    }
907    return a;
908 }
909 //-----------------------------------------------------------------------------
910 // Print
911
912 //-----------------------------------------------------------------------------
913 } // end namespace gdcm