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