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