]> Creatis software - gdcm.git/blob - src/gdcmArgMgr.cxx
class ArgMgr (for Arguments Manager) is designed for
[gdcm.git] / src / gdcmArgMgr.cxx
1 /*=========================================================================
2   
3   Program:   gdcm
4   Module:    $RCSfile: gdcmArgMgr.cxx,v $
5   Language:  C++
6   Date:      $Date: 2005/06/06 12:37:58 $
7   Version:   $Revision: 1.1 $
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  name of the searched parameter label
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
206  *               of the program.
207  * @return exception code
208  */
209 int ArgMgr::ArgMgrUsage(char **usage_text )
210 {
211    while ( *usage_text ) 
212       std::cout << std::endl << *(usage_text++);
213    std::cout << std::endl; 
214    return (0);
215 }
216
217
218 /**
219  * \brief Forget it, right now ... 
220  * sauvegarde une chaine de caract. dans un fichier de parameters
221  *         Le nom du fichier est celui specifie sur la ligne
222  *         d'appel par : PARAMOUT=???
223  *         ou, par defaut, celui donne par ARG_DEFAULT_PARAMOUT
224  * @param param  Chaine de caractere definissant le parameter:
225  * @return   Entier correspondant au rang dans la liste de labels
226  */
227 int ArgMgr::ArgMgrSave ( char *param )
228 {
229    static int   deja = 0;
230    FILE         *fd;
231    if ( *ArgParamOut == '\0' )
232       return 0;
233    if(deja) 
234    {
235       fd = fopen ( ArgParamOut, "a+" );
236    }
237    else
238    {
239       deja = 1;
240       fd = fopen ( ArgParamOut, "w" );
241    } 
242    if ( !fd ) 
243       return 0;
244    fprintf ( fd, "%s\n", param );
245    fclose  ( fd );
246    return 1;
247 }
248
249 /**
250  * \brief  Gets an int value passed as an argument to a program
251  *         (use default value if not found)
252  *  EXEMPLE:     int dimx = ArgMgrGetInt ( "DIMX", 256 );
253  * @param label   parameter label
254  * @param defaultVal default value
255  * @return parameter value
256  */
257 int ArgMgr::ArgMgrGetInt(char *label, int defaultVal)
258 {
259    return ( (ArgMgrDefined(label))
260             ? (atoi(ArgMgrValue(label)))
261             : (defaultVal) );
262 }
263
264 /**
265  * \brief  Gets a float value passed as an argument to a program
266  *         (use default value if not found)
267  *  EXEMPLE:     float scale = ArgMgrGetFloat ( "SCALE", 0.33 );
268  * @param label   parameter label
269  * @param defaultVal default value
270  * @return parameter value
271  */
272 float ArgMgr::ArgMgrGetFloat(char *label, float defaultVal)
273 {
274    return     ( (ArgMgrDefined(label))
275                ? (atof(ArgMgrValue(label)))
276                : (defaultVal) );
277 }
278
279 /**
280  * \brief  Gets a 'string' value passed as an argument to a program
281  *         (use default value if not found)
282  * @param label   parameter label
283  * @param defaultVal default value
284  * @return parameter value
285  */
286 char *ArgMgr::ArgMgrGetString(char *label, char *defaultVal)
287 {
288    return    ( (ArgMgrDefined(label)) 
289               ? (ArgMgrValue(label))
290               : (defaultVal) );
291 }
292
293 /**
294  * \brief  Gets a value amongst a set od values
295  *         (use default value if not found) 
296  *         EXEMPLE:     int nlab = ArgMgrGetLabel("CONFIRM","NO\\YES", 0); 
297  * @param label   parameter label
298  * @param liste  character Chain describing the varous 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 (char *label, char *liste, int val )
305 {
306   char *lab;
307   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(label,(char *)NULL)) != 0 ) 
314   { 
315      for ( lab = strtok (tmp,"\\"); 
316            lab != 0; 
317            lab = strtok(0L,"\\"), i++ )
318      { 
319         if ( strcmp(maj(lab),maj(vallab))==0)
320            return i;
321      } 
322      val=0;
323    }
324    free(tmp);
325    return val;
326 }
327
328 /**
329  * \brief  Lecture d'un arg.de type label parmi un ensemble de labels
330  *         EXEMPLE:     int nlab = ArgMgrWantLabel("CONFIRM","NO\\YES", usage); 
331  * @param label   Parameter label
332  * @param liste Chaine de caracteres decrivant les differents labels.
333  *               Chaque label est separe par un '\\'.
334  *               Aucune difference n'est faite entre maj./min.
335  * @param usage Usage program (displayed if label not found)
336  * @return   Entier correspondant au rang dans la liste de labels
337  */
338 int ArgMgr::ArgMgrWantLabel (char *label, char *liste, char *usage[] )
339 {
340    char *lab;
341    char *vallab;
342    int i = 1;
343    if ( (vallab = ArgMgrGetString(label,0)) != 0 ) 
344    {
345       for ( lab = strtok (liste,"\\"); lab != 0; lab = strtok(0L,"\\"), i++ )
346         if ( strcmp(maj(lab),maj(vallab))==0) 
347            return i;
348       return 0;
349    }
350    ArgMgrUsage(usage);
351    return 0;
352 }
353
354 /**
355  * \brief  Demands an int value passed as an argument to a program
356  *         If not found usage is displayed and the prog aborted
357  *  EXEMPLE:     int dimx = ArgMgrWantInt ( "DIMX", usage );
358  * @param label   Parameter label
359  * @param usage Usage program (displayed if label not found)
360  * @return parameter value
361  */
362 int ArgMgr::ArgMgrWantInt (char *label, char **usage)
363 {
364    return        ( (ArgMgrDefined(label) ) 
365                  ? (atoi(ArgMgrValue(label) ) ) 
366                  : (ArgMgrUsage(usage),1) );
367 }
368
369 /**
370  * \brief  Demands a float value passed as an argument to a program
371  *         If not found usage is displayed and the prog aborted
372  *  EXEMPLE:     float scale = ArgMgrWantFloat ( "SCALE", usage );
373  * @param label   Parameter label
374  * @param usage Usage program (displayed if label not found)
375  * @return parameter value
376  */
377 float ArgMgr::ArgMgrWantFloat (char *label, char **usage)
378 {
379    return       ( (ArgMgrDefined(label) ) 
380                 ? (atof(ArgMgrValue(label) ) ) 
381                 : (ArgMgrUsage(usage),1.0) );
382 }
383
384 /**
385  * \brief  Demands a 'string' value passed as an argument to a program
386  *         If not found usage is displayed and the prog aborted
387  *  EXEMPLE:     char *code = ArgMgrWantString ( "CODE", usage );
388  * @param label   Parameter label
389  * @param usage Usage program (displayed if label not found)
390  * @return parameter value
391  */
392 char *ArgMgr::ArgMgrWantString(char *label, char **usage)
393 {
394    return      ( (ArgMgrDefined(label) ) 
395                ? (ArgMgrValue(label) ) 
396                : (ArgMgrUsage(usage),(char*)0) );
397 }
398
399 /**
400  * \brief  decodage des elements d'un argument 'liste de STRING' de lgr qcq
401  * @param label   pointer vers le label de la liste
402  * @param number  taille de la liste  trouvee
403  * @return   Pointer vers le tableau de lgr 'taille'
404  *     Pointer NULL si erreur
405  */
406 char **ArgMgr::ArgMgrGetListOfString ( char *label, int *nbElem )
407 {
408   int taille;
409   char  *value = ArgMgrValue(label);
410   char **liste;
411   char **elem;
412   char  *chainecur; 
413   if (!value)
414      return 0;
415   *nbElem = IdStrCountChar(value,',')+1; /* nb Elements = nb Commas +1 */
416   taille = *nbElem;
417   liste = (char **) malloc (sizeof(char*) * taille + strlen(value)+1);
418   if ( !liste )
419      return 0;
420   value = strcpy( ((char*)liste)+sizeof(char*) * taille, value );
421   for ( elem = liste, chainecur = strtok(value,", ");
422         taille>0;
423         taille--, chainecur = (chainecur) ? strtok ( 0, ", " ) : 0 )
424   {
425     *(elem++) = chainecur;
426   }
427   return liste;
428 }
429
430 /**
431  * \brief  decodage des elements d'un argument 'liste diINTEGER' de lgr quelconque
432  * @param label   pointer vers le label de la liste
433  * @param number  taille de la liste  trouvee
434  * @return   Pointer vers le tableau de lgr 'taille'
435  *     Pointer NULL si erreur
436  */
437 int *ArgMgr::ArgMgrGetListOfInt ( char *label, int *number )
438 {
439   char *value = ArgMgrValue(label);
440   int *liste;
441   int *elem;
442   int taille;
443   if (!value)
444      return 0;
445   *number = IdStrCountChar(value,',')+1; /* nb Elements = nb Commas +1 */
446   taille= *number;
447   liste = (int *) calloc (1,sizeof(int)*taille );
448   if ( !liste )
449      return 0;
450   elem = liste;
451   *number = 1;
452
453   while ( taille>0 ) 
454   {
455     *(elem++) = (int) strtol ( value, &value, 10 );      
456     if ( *value == '\0' )
457        return liste;
458     if ( *(value++) != ',' ) 
459     {
460       free (liste);
461       return 0;
462     }
463     taille --;
464   }
465 return liste;
466 }
467
468 /**
469  * \brief  decodage des elements d'un argument 'liste de FLOAT' de lgr qcq
470  * @param label   pointer vers le label de la liste
471  * @param number  taille de la liste  trouvee
472  * @return   Pointer vers le tableau de lgr 'taille'
473  *     NULL if error
474  */
475 float *ArgMgr::ArgMgrGetListOfFloat ( char *label, int *number )
476 {
477   char *value = ArgMgrValue(label);
478   float *liste;
479   float *elem;
480   int taille;
481   if (!value)
482     return 0;
483   *number = IdStrCountChar(value,',')+1; /* nb Elements = nb Commas +1 */
484   taille= *number;
485   liste = (float *) calloc (1,sizeof(float)*taille );
486   if ( !liste )
487      return 0;
488   elem = liste;
489   *number = 1;
490
491   while ( taille>0 ) 
492   {
493     *(elem++) = (float) strtod ( value, &value );      
494     if ( *value == '\0' )
495        return liste;
496     if ( *(value++) != ',' )
497     {
498       free (liste);
499       return 0;
500     }
501     taille --;
502   }
503 return liste;
504 }
505
506 /**
507  * \brief     Counts the nb of occurrences of a given charact within a 'string' 
508  * @param chaine     Pointer to the 'string'
509  * @param caract     charact to count
510  * @return       occurence number
511  */
512 int ArgMgr::IdStrCountChar (char *chaine, int caract)
513 {
514   int i=0;
515   char *ptr;
516   for ( ptr = chaine ; *ptr!='\0' ; ptr ++ ) 
517      if (*ptr==caract) 
518         i++;  
519   return i;
520 }
521
522 /**
523  * \brief     renvoie 1 tableau contenant une liste d'intervalles entiers
524  * @param value     pointer vers la zone allouee contenant les
525  *    intervalles (deb1,fin1, deb2,fin2, ...)
526  * @param number     Pointer vers le nb d'interv trouves
527  * @return        1 tableau contenant une liste d'intervalles entiers
528  */
529 int *ArgMgr::IdStrIntEnum ( char* value, int *number)
530 {
531    int* liste;
532    int taille;
533    int i;
534
535    *number = IdStrCountChar(value,',')+1; /* nb Elements = nb Virgules +1 */
536    taille= *number;
537    liste = (int *) calloc (1,sizeof(int)*2*taille );
538    if ( !liste )
539    {
540       return 0;
541    }
542    i=0;
543    while ( taille>0 ) 
544    {
545       liste[i] = (int) strtol ( value, &value, 10 );
546       if ( *value == '\0' ) 
547       {
548          liste[i+1]=liste[i];
549          return liste;
550       }
551       if ( *(value++) != '-' ) 
552       {
553          liste[i+1]=liste[i];
554          value--;
555        }
556        else
557        {
558           liste[i+1] = (int) strtol ( value, &value, 10 );
559        }
560        if ( *value == '\0' )
561           return liste;
562        if ( *(value++) != ',' )
563        {
564           free (liste);
565           return 0;
566        }
567        taille --; i+=2;
568    }
569    return liste;
570 }
571
572 /**
573  * \brief     renvoie 1 tableau contenant une liste d'intervalles FLOAT
574  * @param value     pointer vers la zone allouee contenant les
575  *     intervalles (deb1,fin1, deb2,fin2, ...)
576  * @param number     Pointer vers le nb d'interv trouves
577  * @return        1 tableau contenant une liste d'intervalles FLOAT
578  */
579 float *ArgMgr::IdStrFloatEnum (char *value, int *number)
580 {
581    float *liste;
582    int taille;
583    int i;
584    *number = IdStrCountChar(value,',')+1; /* nb Elements = nb Virgules +1 */
585    taille= *number;
586    liste = (float *) calloc (1,sizeof(float)*2*taille );
587    if ( !liste )
588       return 0;
589    i=0;
590    while ( taille>0 ) 
591    {
592       liste[i] = (float) strtod ( value, &value );      
593       if ( *value == '\0' ) 
594       {
595          liste[i+1]=liste[i];
596          return liste;
597       }
598       if ( *(value++) != '-' ) 
599       {
600          liste[i+1]=liste[i];
601          value--;
602       }
603       else
604       {
605           liste[i+1] = (float) strtod ( value, &value );
606       }
607       if ( *value == '\0' ) 
608          return liste;
609       if ( *(value++) != ',' )
610       {
611          free (liste);
612          return 0;
613       }
614       taille --; i+=2;
615    }
616    return liste;
617 }
618
619 /**
620  * \brief  decodage des elements d'un argument 'intervalles d'int' de lgr quelconque
621  * @param label   pointer vers le label de la liste
622  * @param number  taille de la liste d'intervalles trouvee
623  * @return   Pointer vers le tableau de taille '2*nbElem'
624  *     Pointer NULL si erreur
625  */
626 int *ArgMgr::ArgMgrGetIntEnum ( char *label, int *number )
627 {
628    char *value = ArgMgrValue(label);
629    int *liste;
630    if (!value) 
631       return 0;
632    liste = IdStrIntEnum(value, number);
633    return liste;
634 }
635
636 /**
637  * \brief  decodage des elements d'un argument 'intervalles d'int' de lgr quelconque
638  * @param label   pointer vers le label de la liste
639  * @param number  taille de la liste d'intervalles trouvee
640  * @return   Pointer vers le tableau de taille '2*nbElem'
641  *     Pointer NULL si erreur
642  */
643 float *ArgMgr::ArgMgrGetFloatEnum ( char *label, int *number )
644 {
645    char  *value = ArgMgrValue(label);
646    float *liste;
647    if (!value) 
648       return 0;
649    liste = IdStrFloatEnum(value, number);
650    return liste;
651 }
652
653 //-----------------------------------------------------------------------------
654 // Protected
655
656 //-----------------------------------------------------------------------------
657 // Private
658
659 /**************************************************************************
660 *                                                                         *
661 * Nom de la fonction : Majuscule                                          *
662 * Role ............. : Met une chaine de caracteres en majuscules.        *
663 * parameters ....... : Pointer vers la chaine.                           *
664 * Valeur retournee . : pointer vers cette meme chaine en majuscule.      *
665 *                                                                         *
666 **************************************************************************/
667 char *ArgMgr::Majuscule (char *chaine )
668 {
669   char *ptr, *ptr2, *ptr3;
670   ptr2 = (char *)malloc(strlen(chaine)*sizeof(char)+1);
671   ptr3=ptr2;
672   for ( ptr = chaine ; *ptr!='\0' ; ptr ++ ) 
673    {  
674        *ptr3 = toupper ( * ptr ); ptr3++; 
675    }
676   *ptr3='\0'; 
677   return ptr2;
678 }
679
680 /**************************************************************************
681 *                                                                         *
682 * Nom de la fonction : FiltreLong                                         *
683 * Role ............. : Arrete le programme si l'argument est trop long.   *
684 *                      ARG_LONG_MAX definit cette longueur.               *
685 * parameters ....... : Pointer vers l'argument.                          *
686 * Valeur retournee . : Faux s'il n'y a pas d'erreur.                      *
687 *                      Vrai s'il y a une erreur.                          *
688 **************************************************************************/
689 int ArgMgr::FiltreLong ( char *arg  )
690 {
691   int  n = 0 ;
692   while ( (n++<ARG_LONG_MAX) && (*(arg++) != '\0') ) ;
693   return (n>=ARG_LONG_MAX) ;
694 }
695
696 /*------------------------------------------------------------------------
697  | Role       : Lit un parameter depuis un fichier
698  | Retour     : Type   : char *
699  |              Role   : pointer vers le label
700  | parameters : param  : char *
701  |              Role   : one ou il faut stocker le parameter
702  |              fd     : FILE *
703  |              Role   : descripteur du fichier (suppose ouvert)
704  +------------------------------------------------------------------------*/
705 char *ArgMgr::LoadedParam ( char *param, FILE *fd )
706 {
707   int    carlu;
708   char * car = param;
709   int    quote = false;
710   int    nbcar = 0;
711
712   /* On supprime les espaces ****/
713   /* du debut de chaine *********/
714   while ( isspace(carlu=fgetc (fd)) );
715   if (carlu==EOF)
716      return 0;
717   /* On cherche une " eventuelle */
718   if ( carlu=='\"' ) 
719   {
720     carlu=fgetc(fd);
721     quote=true;
722   /* On lit tous les caracteres */
723   }
724   while (  (carlu!=EOF)
725         && (  ( (!quote)&&(!isspace(carlu)) )
726          ||( (quote)&& !(carlu=='\"')   ) ) ) 
727   {
728      *(car++) = (char) carlu;
729      nbcar ++;
730   /* sans depasser la taille max*/
731      if ( nbcar >= ARG_LONG_MAX ) 
732      {
733         std::cout << "\nError: Argument too long ( > "
734                   << ARG_LONG_MAX << ")in parameter file."
735                   << std::endl;
736         break;
737      }
738      carlu = fgetc(fd);
739   }
740   *car = '\0';
741   return param;
742 }
743
744 /*------------------------------------------------------------------------
745  | Role       : Lecture d'arguments dans un fichier de parameters
746  |              (cette fonction est recursive).
747  | Retour     : Type   : int
748  |              Role   : retourne le nombre de lettres necessaires
749  |                       pour stocker en memoire tous les parameters
750  | parameters : filename : char *
751  |              Role     : nom du fichier de parameter
752  |
753  +------------------------------------------------------------------------*/
754 int ArgMgr::ArgLoadFromFile ( char *filename )
755 {
756   int   nbl = 0;
757   char  param[ARG_LONG_MAX+1];
758   FILE  *fch;
759
760   fch = fopen ( filename, ID_RFILE_TEXT );
761   while ( LoadedParam (param, fch ) )
762   {
763     int n = strlen(param);
764     if ( param[0]=='@' )
765     {
766       nbl  += ArgLoadFromFile ( &param[1] );
767     }
768     else
769     {
770       ArgLab [ArgCount] = strcpy ((char *) malloc(n+1), param ) ;
771       nbl += n + 1 ;
772       ArgCount++;
773       if ( ArgCount >= ARGMAXCOUNT ) 
774          break;
775     }
776   }
777   fclose ( fch );
778   return nbl;
779 }
780
781 /*------------------------------------------------------------------------
782  | Role       : Gestion des parameters standard de la ligne d'argument.
783  | Retour     : Type   : void
784  | parameters : aucun
785  +------------------------------------------------------------------------*/
786 void ArgMgr::ArgStdArgs()
787 {
788   char *logfile;
789   FILE *fd;
790
791   if ( (ArgParamOut=ArgMgrValue(ARG_LABEL_PARAMOUT))==0 )
792     ArgParamOut = ARG_DEFAULT_PARAMOUT;
793   if ( (logfile = ArgMgrValue(ARG_LABEL_LOGFILE))!=0) 
794   {
795     if ( *logfile == '\0' )
796        logfile = ARG_DEFAULT_LOGFILE;
797     fd = fopen ( logfile, "a+" );
798     if ( fd ) 
799     {
800       fprintf ( fd, "%s\n", Appel );
801       fclose  ( fd );
802     }
803   }
804 }
805
806 /*------------------------------------------------------------------------
807  | Role       : met en majuscule 'sur place'.
808  | Retour     : Type   : char *
809  | parameters : char *
810  +------------------------------------------------------------------------*/
811 char *ArgMgr::maj ( char *a )
812 {
813    char *b = a;
814    while ( *b !=0 ) 
815    {
816       if ( *b<='z' && *b>='a' ) *b = *b+'A'-'a';
817       b++;
818    }
819    return a;
820 }
821 //-----------------------------------------------------------------------------
822 // Print
823
824 //-----------------------------------------------------------------------------
825 } // end namespace gdcm