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