FFSM++  1.1.0
French Forest Sector Model ++
anyoption.cpp
Go to the documentation of this file.
1 /*
2  * AnyOption 1.3
3  *
4  * kishan at hackorama dot com www.hackorama.com JULY 2001
5  *
6  * + Acts as a common facade class for reading
7  * commandline options as well as options from
8  * an optionfile with delimited type value pairs
9  *
10  * + Handles the POSIX style single character options ( -w )
11  * as well as the newer GNU long options ( --width )
12  *
13  * + The option file assumes the traditional format of
14  * first character based comment lines and type value
15  * pairs with a delimiter , and flags which are not pairs
16  *
17  * # this is a coment
18  * # next line is an option value pair
19  * width : 100
20  * # next line is a flag
21  * noimages
22  *
23  * + Supports printing out Help and Usage
24  *
25  * + Why not just use getopt() ?
26  *
27  * getopt() Its a POSIX standard not part of ANSI-C.
28  * So it may not be available on platforms like Windows.
29  *
30  * + Why it is so long ?
31  *
32  * The actual code which does command line parsing
33  * and option file parsing are done in few methods.
34  * Most of the extra code are for providing a flexible
35  * common public interface to both a resourcefile and
36  * and command line supporting POSIX style and
37  * GNU long option as well as mixing of both.
38  *
39  * + Please see "anyoption.h" for public method descriptions
40  *
41  */
42 
43 /* Updated Auguest 2004
44  * Fix from Michael D Peters (mpeters at sandia.gov)
45  * to remove static local variables, allowing multiple instantiations
46  * of the reader (for using multiple configuration files). There is
47  * an error in the destructor when using multiple instances, so you
48  * cannot delete your objects (it will crash), but not calling the
49  * destructor only introduces a small memory leak, so I
50  * have not bothered tracking it down.
51  *
52  * Also updated to use modern C++ style headers, rather than
53  * depricated iostream.h (it was causing my compiler problems)
54 */
55 
56 /*
57  * Updated September 2006
58  * Fix from Boyan Asenov for a bug in mixing up option indexes
59  * leading to exception when mixing different options types
60  */
61 
62 #include "anyoption.h"
63 #include <cstring>
64 
66 {
67  init();
68 }
69 
71 {
72  init( maxopt , maxopt );
73 }
74 
75 AnyOption::AnyOption(int maxopt, int maxcharopt)
76 {
77  init( maxopt , maxcharopt );
78 }
79 
81 {
82  if( mem_allocated )
83  cleanup();
84 }
85 
86 void
88 {
90 }
91 
92 void
93 AnyOption::init(int maxopt, int maxcharopt )
94 {
95 
96  max_options = maxopt;
97  max_char_options = maxcharopt;
99  usage_lines = 0 ;
100  argc = 0;
101  argv = NULL;
102  posix_style = true;
103  verbose = false;
104  filename = NULL;
105  appname = NULL;
106  option_counter = 0;
107  optchar_counter = 0;
108  new_argv = NULL;
109  new_argc = 0 ;
110  max_legal_args = 0 ;
111  command_set = false;
112  file_set = false;
113  values = NULL;
114  g_value_counter = 0;
115  mem_allocated = false;
116  command_set = false;
117  file_set = false;
118  opt_prefix_char = '-';
119  file_delimiter_char = ':';
120  file_comment_char = '#';
121  equalsign = '=';
122  comment = '#' ;
123  delimiter = ':' ;
124  endofline = '\n';
125  whitespace = ' ' ;
126  nullterminate = '\0';
127  set = false;
128  once = true;
129  hasoptions = false;
130  autousage = false;
131 
132  strcpy( long_opt_prefix , "--" );
133 
134  if( alloc() == false ){
135  cout << endl << "OPTIONS ERROR : Failed allocating memory" ;
136  cout << endl ;
137  cout << "Exiting." << endl ;
138  exit (0);
139  }
140 }
141 
142 bool
144 {
145  int i = 0 ;
146  int size = 0 ;
147 
148  if( mem_allocated )
149  return true;
150 
151  size = (max_options+1) * sizeof(const char*);
152  options = (const char**)malloc( size );
153  optiontype = (int*) malloc( (max_options+1)*sizeof(int) );
154  optionindex = (int*) malloc( (max_options+1)*sizeof(int) );
155  if( options == NULL || optiontype == NULL || optionindex == NULL )
156  return false;
157  else
158  mem_allocated = true;
159  for( i = 0 ; i < max_options ; i++ ){
160  options[i] = NULL;
161  optiontype[i] = 0 ;
162  optionindex[i] = -1 ;
163  }
164  optionchars = (char*) malloc( (max_char_options+1)*sizeof(char) );
165  optchartype = (int*) malloc( (max_char_options+1)*sizeof(int) );
166  optcharindex = (int*) malloc( (max_char_options+1)*sizeof(int) );
167  if( optionchars == NULL ||
168  optchartype == NULL ||
169  optcharindex == NULL )
170  {
171  mem_allocated = false;
172  return false;
173  }
174  for( i = 0 ; i < max_char_options ; i++ ){
175  optionchars[i] = '0';
176  optchartype[i] = 0 ;
177  optcharindex[i] = -1 ;
178  }
179 
180  size = (max_usage_lines+1) * sizeof(const char*) ;
181  usage = (const char**) malloc( size );
182 
183  if( usage == NULL ){
184  mem_allocated = false;
185  return false;
186  }
187  for( i = 0 ; i < max_usage_lines ; i++ )
188  usage[i] = NULL;
189 
190  return true;
191 }
192 
193 bool
195 {
196  options = (const char**)realloc( options,
197  ((2*max_options)+1) * sizeof( const char*) );
198  optiontype = (int*) realloc( optiontype ,
199  ((2 * max_options)+1)* sizeof(int) );
200  optionindex = (int*) realloc( optionindex,
201  ((2 * max_options)+1) * sizeof(int) );
202  if( options == NULL || optiontype == NULL || optionindex == NULL )
203  return false;
204  /* init new storage */
205  for( int i = max_options ; i < 2*max_options ; i++ ){
206  options[i] = NULL;
207  optiontype[i] = 0 ;
208  optionindex[i] = -1 ;
209  }
210  max_options = 2 * max_options ;
211  return true;
212 }
213 
214 bool
216 {
217  optionchars = (char*) realloc( optionchars,
218  ((2*max_char_options)+1)*sizeof(char) );
219  optchartype = (int*) realloc( optchartype,
220  ((2*max_char_options)+1)*sizeof(int) );
221  optcharindex = (int*) realloc( optcharindex,
222  ((2*max_char_options)+1)*sizeof(int) );
223  if( optionchars == NULL ||
224  optchartype == NULL ||
225  optcharindex == NULL )
226  return false;
227  /* init new storage */
228  for( int i = max_char_options ; i < 2*max_char_options ; i++ ){
229  optionchars[i] = '0';
230  optchartype[i] = 0 ;
231  optcharindex[i] = -1 ;
232  }
233  max_char_options = 2 * max_char_options;
234  return true;
235 }
236 
237 bool
239 {
240  usage = (const char**)realloc( usage,
241  ((2*max_usage_lines)+1) * sizeof( const char*) );
242  if ( usage == NULL )
243  return false;
244  for( int i = max_usage_lines ; i < 2*max_usage_lines ; i++ )
245  usage[i] = NULL;
246  max_usage_lines = 2 * max_usage_lines ;
247  return true;
248 
249 }
250 
251 
252 void
254 {
255  free (options);
256  free (optiontype);
257  free (optionindex);
258  free (optionchars);
259  free (optchartype);
260  free (optcharindex);
261  free (usage);
262  if( values != NULL )
263  free (values);
264  if( new_argv != NULL )
265  free (new_argv);
266 }
267 
268 void
270 {
271  opt_prefix_char = _prefix;
272 }
273 
274 void
276 {
277  if( strlen( _prefix ) > MAX_LONG_PREFIX_LENGTH ){
278  *( _prefix + MAX_LONG_PREFIX_LENGTH ) = '\0';
279  }
280 
281  strcpy (long_opt_prefix, _prefix);
282 }
283 
284 void
286 {
287  file_delimiter_char = _comment;
288 }
289 
290 
291 void
293 {
294  file_comment_char = _delimiter ;
295 }
296 
297 bool
299 {
300  return( command_set );
301 }
302 
303 bool
305 {
306  return( file_set );
307 }
308 
309 void
311 {
312  posix_style = false;
313 }
314 
315 bool
317 {
318  return posix_style;
319 }
320 
321 
322 void
324 {
325  verbose = true ;
326 }
327 
328 void
330 {
331  if( verbose )
332  cout << endl ;
333 }
334 void
335 AnyOption::printVerbose( const char *msg )
336 {
337  if( verbose )
338  cout << msg ;
339 }
340 
341 void
343 {
344  if( verbose )
345  cout << msg ;
346 }
347 
348 void
350 {
351  if( verbose )
352  cout << ch ;
353 }
354 
355 bool
357 {
358  return hasoptions;
359 }
360 
361 void
363 {
364  autousage = _autousage;
365 }
366 
367 void
368 AnyOption::useCommandArgs( int _argc, char **_argv )
369 {
370  argc = _argc;
371  argv = _argv;
372  command_set = true;
373  appname = argv[0];
374  if(argc > 1) hasoptions = true;
375 }
376 
377 void
378 AnyOption::useFiileName( const char *_filename )
379 {
380  filename = _filename;
381  file_set = true;
382 }
383 
384 /*
385  * set methods for options
386  */
387 
388 void
389 AnyOption::setCommandOption( const char *opt )
390 {
391  addOption( opt , COMMAND_OPT );
392  g_value_counter++;
393 }
394 
395 void
397 {
398  addOption( opt , COMMAND_OPT );
399  g_value_counter++;
400 }
401 
402 void
403 AnyOption::setCommandOption( const char *opt , char optchar )
404 {
405  addOption( opt , COMMAND_OPT );
406  addOption( optchar , COMMAND_OPT );
407  g_value_counter++;
408 }
409 
410 void
411 AnyOption::setCommandFlag( const char *opt )
412 {
413  addOption( opt , COMMAND_FLAG );
414  g_value_counter++;
415 }
416 
417 void
419 {
420  addOption( opt , COMMAND_FLAG );
421  g_value_counter++;
422 }
423 
424 void
425 AnyOption::setCommandFlag( const char *opt , char optchar )
426 {
427  addOption( opt , COMMAND_FLAG );
428  addOption( optchar , COMMAND_FLAG );
429  g_value_counter++;
430 }
431 
432 void
433 AnyOption::setFileOption( const char *opt )
434 {
435  addOption( opt , FILE_OPT );
436  g_value_counter++;
437 }
438 
439 void
441 {
442  addOption( opt , FILE_OPT );
443  g_value_counter++;
444 }
445 
446 void
447 AnyOption::setFileOption( const char *opt , char optchar )
448 {
449  addOption( opt , FILE_OPT );
450  addOption( optchar, FILE_OPT );
451  g_value_counter++;
452 }
453 
454 void
455 AnyOption::setFileFlag( const char *opt )
456 {
457  addOption( opt , FILE_FLAG );
458  g_value_counter++;
459 }
460 
461 void
463 {
464  addOption( opt , FILE_FLAG );
465  g_value_counter++;
466 }
467 
468 void
469 AnyOption::setFileFlag( const char *opt , char optchar )
470 {
471  addOption( opt , FILE_FLAG );
472  addOption( optchar , FILE_FLAG );
473  g_value_counter++;
474 }
475 
476 void
477 AnyOption::setOption( const char *opt )
478 {
479  addOption( opt , COMMON_OPT );
480  g_value_counter++;
481 }
482 
483 void
485 {
486  addOption( opt , COMMON_OPT );
487  g_value_counter++;
488 }
489 
490 void
491 AnyOption::setOption( const char *opt , char optchar )
492 {
493  addOption( opt , COMMON_OPT );
494  addOption( optchar , COMMON_OPT );
495  g_value_counter++;
496 }
497 
498 void
499 AnyOption::setFlag( const char *opt )
500 {
501  addOption( opt , COMMON_FLAG );
502  g_value_counter++;
503 }
504 
505 void
506 AnyOption::setFlag( const char opt )
507 {
508  addOption( opt , COMMON_FLAG );
509  g_value_counter++;
510 }
511 
512 void
513 AnyOption::setFlag( const char *opt , char optchar )
514 {
515  addOption( opt , COMMON_FLAG );
516  addOption( optchar , COMMON_FLAG );
517  g_value_counter++;
518 }
519 
520 void
521 AnyOption::addOption( const char *opt, int type )
522 {
523  if( option_counter >= max_options ){
524  if( doubleOptStorage() == false ){
525  addOptionError( opt );
526  return;
527  }
528  }
529  options[ option_counter ] = opt ;
530  optiontype[ option_counter ] = type ;
532  option_counter++;
533 }
534 
535 void
536 AnyOption::addOption( char opt, int type )
537 {
538  if( !POSIX() ){
539  printVerbose("Ignoring the option character \"");
540  printVerbose( opt );
541  printVerbose( "\" ( POSIX options are turned off )" );
542  printVerbose();
543  return;
544  }
545 
546 
548  if( doubleCharStorage() == false ){
549  addOptionError( opt );
550  return;
551  }
552  }
553  optionchars[ optchar_counter ] = opt ;
554  optchartype[ optchar_counter ] = type ;
556  optchar_counter++;
557 }
558 
559 void
560 AnyOption::addOptionError( const char *opt )
561 {
562  cout << endl ;
563  cout << "OPTIONS ERROR : Failed allocating extra memory " << endl ;
564  cout << "While adding the option : \""<< opt << "\"" << endl;
565  cout << "Exiting." << endl ;
566  cout << endl ;
567  exit(0);
568 }
569 
570 void
572 {
573  cout << endl ;
574  cout << "OPTIONS ERROR : Failed allocating extra memory " << endl ;
575  cout << "While adding the option: \""<< opt << "\"" << endl;
576  cout << "Exiting." << endl ;
577  cout << endl ;
578  exit(0);
579 }
580 
581 void
583 {
584  if( ! valueStoreOK() )
585  return;
586 }
587 
588 void
590 {
591  max_legal_args = max_args;
593 }
594 
595 void
596 AnyOption::processCommandArgs( int _argc, char **_argv, int max_args )
597 {
598  max_legal_args = max_args;
599  processCommandArgs( _argc, _argv );
600 }
601 
602 void
603 AnyOption::processCommandArgs( int _argc, char **_argv )
604 {
605  useCommandArgs( _argc, _argv );
607 }
608 
609 void
611 {
612  if( ! ( valueStoreOK() && CommandSet() ) )
613  return;
614 
615  if( max_legal_args == 0 )
617  new_argv = (int*) malloc( (max_legal_args+1) * sizeof(int) );
618  for( int i = 1 ; i < argc ; i++ ){/* ignore first argv */
619  if( argv[i][0] == long_opt_prefix[0] &&
620  argv[i][1] == long_opt_prefix[1] ) { /* long GNU option */
621  int match_at = parseGNU( argv[i]+2 ); /* skip -- */
622  if( match_at >= 0 && i < argc-1 ) /* found match */
623  setValue( options[match_at] , argv[++i] );
624  }else if( argv[i][0] == opt_prefix_char ) { /* POSIX char */
625  if( POSIX() ){
626  char ch = parsePOSIX( argv[i]+1 );/* skip - */
627  if( ch != '0' && i < argc-1 ) /* matching char */
628  setValue( ch , argv[++i] );
629  } else { /* treat it as GNU option with a - */
630  int match_at = parseGNU( argv[i]+1 ); /* skip - */
631  if( match_at >= 0 && i < argc-1 ) /* found match */
632  setValue( options[match_at] , argv[++i] );
633  }
634  }else { /* not option but an argument keep index */
635  if( new_argc < max_legal_args ){
636  new_argv[ new_argc ] = i ;
637  new_argc++;
638  }else{ /* ignore extra arguments */
639  printVerbose( "Ignoring extra argument: " );
640  printVerbose( argv[i] );
641  printVerbose( );
642  printAutoUsage();
643  }
644  printVerbose( "Unknown command argument option : " );
645  printVerbose( argv[i] );
646  printVerbose( );
647  printAutoUsage();
648  }
649  }
650 }
651 
652 char
654 {
655 
656  for( unsigned int i = 0 ; i < strlen(arg) ; i++ ){
657  char ch = arg[i] ;
658  if( matchChar(ch) ) { /* keep matching flags till an option */
659  /*if last char argv[++i] is the value */
660  if( i == strlen(arg)-1 ){
661  return ch;
662  }else{/* else the rest of arg is the value */
663  i++; /* skip any '=' and ' ' */
664  while( arg[i] == whitespace
665  || arg[i] == equalsign )
666  i++;
667  setValue( ch , arg+i );
668  return '0';
669  }
670  }
671  }
672  printVerbose( "Unknown command argument option : " );
673  printVerbose( arg );
674  printVerbose( );
675  printAutoUsage();
676  return '0';
677 }
678 
679 int
681 {
682  int split_at = 0;
683  /* if has a '=' sign get value */
684  for( unsigned int i = 0 ; i < strlen(arg) ; i++ ){
685  if(arg[i] == equalsign ){
686  split_at = i ; /* store index */
687  i = strlen(arg); /* get out of loop */
688  }
689  }
690  if( split_at > 0 ){ /* it is an option value pair */
691  char* tmp = (char*) malloc( (split_at+1)*sizeof(char) );
692  for( int i = 0 ; i < split_at ; i++ )
693  tmp[i] = arg[i];
694  tmp[split_at] = '\0';
695 
696  if ( matchOpt( tmp ) >= 0 ){
697  setValue( options[matchOpt(tmp)] , arg+split_at+1 );
698  free (tmp);
699  }else{
700  printVerbose( "Unknown command argument option : " );
701  printVerbose( arg );
702  printVerbose( );
703  printAutoUsage();
704  free (tmp);
705  return -1;
706  }
707  }else{ /* regular options with no '=' sign */
708  return matchOpt(arg);
709  }
710  return -1;
711 }
712 
713 
714 int
716 {
717  for( int i = 0 ; i < option_counter ; i++ ){
718  if( strcmp( options[i], opt ) == 0 ){
719  if( optiontype[i] == COMMON_OPT ||
720  optiontype[i] == COMMAND_OPT )
721  { /* found option return index */
722  return i;
723  }else if( optiontype[i] == COMMON_FLAG ||
724  optiontype[i] == COMMAND_FLAG )
725  { /* found flag, set it */
726  setFlagOn( opt );
727  return -1;
728  }
729  }
730  }
731  printVerbose( "Unknown command argument option : " );
732  printVerbose( opt ) ;
733  printVerbose( );
734  printAutoUsage();
735  return -1;
736 }
737 bool
739 {
740  for( int i = 0 ; i < optchar_counter ; i++ ){
741  if( optionchars[i] == c ) { /* found match */
742  if(optchartype[i] == COMMON_OPT ||
743  optchartype[i] == COMMAND_OPT )
744  { /* an option store and stop scanning */
745  return true;
746  }else if( optchartype[i] == COMMON_FLAG ||
747  optchartype[i] == COMMAND_FLAG ) { /* a flag store and keep scanning */
748  setFlagOn( c );
749  return false;
750  }
751  }
752  }
753  printVerbose( "Unknown command argument option : " );
754  printVerbose( c ) ;
755  printVerbose( );
756  printAutoUsage();
757  return false;
758 }
759 
760 bool
762 {
763  int size= 0;
764  if( !set ){
765  if( g_value_counter > 0 ){
766  size = g_value_counter * sizeof(char*);
767  values = (char**)malloc( size );
768  for( int i = 0 ; i < g_value_counter ; i++)
769  values[i] = NULL;
770  set = true;
771  }
772  }
773  return set;
774 }
775 
776 /*
777  * public get methods
778  */
779 char*
780 AnyOption::getValue( const char *option )
781 {
782  if( !valueStoreOK() )
783  return NULL;
784 
785  for( int i = 0 ; i < option_counter ; i++ ){
786  if( strcmp( options[i], option ) == 0 )
787  return values[ optionindex[i] ];
788  }
789  return NULL;
790 }
791 
792 bool
793 AnyOption::getFlag( const char *option )
794 {
795  if( !valueStoreOK() )
796  return false;
797  for( int i = 0 ; i < option_counter ; i++ ){
798  if( strcmp( options[i], option ) == 0 )
799  return findFlag( values[ optionindex[i] ] );
800  }
801  return false;
802 }
803 
804 char*
805 AnyOption::getValue( char option )
806 {
807  if( !valueStoreOK() )
808  return NULL;
809  for( int i = 0 ; i < optchar_counter ; i++ ){
810  if( optionchars[i] == option )
811  return values[ optcharindex[i] ];
812  }
813  return NULL;
814 }
815 
816 bool
817 AnyOption::getFlag( char option )
818 {
819  if( !valueStoreOK() )
820  return false;
821  for( int i = 0 ; i < optchar_counter ; i++ ){
822  if( optionchars[i] == option )
823  return findFlag( values[ optcharindex[i] ] ) ;
824  }
825  return false;
826 }
827 
828 bool
830 {
831  if( val == NULL )
832  return false;
833 
834  if( strcmp( TRUE_FLAG , val ) == 0 )
835  return true;
836 
837  return false;
838 }
839 
840 /*
841  * private set methods
842  */
843 bool
844 AnyOption::setValue( const char *option , char *value )
845 {
846  if( !valueStoreOK() )
847  return false;
848  for( int i = 0 ; i < option_counter ; i++ ){
849  if( strcmp( options[i], option ) == 0 ){
850  values[ optionindex[i] ] = (char*) malloc((strlen(value)+1)*sizeof(char));
851  strcpy( values[ optionindex[i] ], value );
852  return true;
853  }
854  }
855  return false;
856 }
857 
858 bool
859 AnyOption::setFlagOn( const char *option )
860 {
861  if( !valueStoreOK() )
862  return false;
863  for( int i = 0 ; i < option_counter ; i++ ){
864  if( strcmp( options[i], option ) == 0 ){
865  values[ optionindex[i] ] = (char*) malloc((strlen(TRUE_FLAG)+1)*sizeof(char));
866  strcpy( values[ optionindex[i] ] , TRUE_FLAG );
867  return true;
868  }
869  }
870  return false;
871 }
872 
873 bool
874 AnyOption::setValue( char option , char *value )
875 {
876  if( !valueStoreOK() )
877  return false;
878  for( int i = 0 ; i < optchar_counter ; i++ ){
879  if( optionchars[i] == option ){
880  values[ optcharindex[i] ] = (char*) malloc((strlen(value)+1)*sizeof(char));
881  strcpy( values[ optcharindex[i] ], value );
882  return true;
883  }
884  }
885  return false;
886 }
887 
888 bool
889 AnyOption::setFlagOn( char option )
890 {
891  if( !valueStoreOK() )
892  return false;
893  for( int i = 0 ; i < optchar_counter ; i++ ){
894  if( optionchars[i] == option ){
895  values[ optcharindex[i] ] = (char*) malloc((strlen(TRUE_FLAG)+1)*sizeof(char));
896  strcpy( values[ optcharindex[i] ] , TRUE_FLAG );
897  return true;
898  }
899  }
900  return false;
901 }
902 
903 
904 int
906 {
907  return new_argc;
908 }
909 
910 char*
911 AnyOption::getArgv( int index )
912 {
913  if( index < new_argc ){
914  return ( argv[ new_argv[ index ] ] );
915  }
916  return NULL;
917 }
918 
919 /* dotfile sub routines */
920 
921 bool
923 {
924  if( ! (valueStoreOK() && FileSet()) )
925  return false;
926  return ( consumeFile(readFile()) );
927 }
928 
929 bool
931 {
932  useFiileName(filename );
933  return ( processFile() );
934 }
935 
936 char*
938 {
939  return ( readFile(filename) );
940 }
941 
942 /*
943  * read the file contents to a character buffer
944  */
945 
946 char*
947 AnyOption::readFile( const char* fname )
948 {
949  int length;
950  char *buffer;
951  ifstream is;
952  is.open ( fname , ifstream::in );
953  if( ! is.good() ){
954  is.close();
955  return NULL;
956  }
957  is.seekg (0, ios::end);
958  length = is.tellg();
959  is.seekg (0, ios::beg);
960  buffer = (char*) malloc(length*sizeof(char));
961  is.read (buffer,length);
962  is.close();
963  return buffer;
964 }
965 
966 /*
967  * scans a char* buffer for lines that does not
968  * start with the specified comment character.
969  */
970 bool
971 AnyOption::consumeFile( char *buffer )
972 {
973 
974  if( buffer == NULL )
975  return false;
976 
977  char *cursor = buffer;/* preserve the ptr */
978  char *pline = NULL ;
979  int linelength = 0;
980  bool newline = true;
981  for( unsigned int i = 0 ; i < strlen( buffer ) ; i++ ){
982  if( *cursor == endofline ) { /* end of line */
983  if( pline != NULL ) /* valid line */
984  processLine( pline, linelength );
985  pline = NULL;
986  newline = true;
987  }else if( newline ){ /* start of line */
988  newline = false;
989  if( (*cursor != comment ) ){ /* not a comment */
990  pline = cursor ;
991  linelength = 0 ;
992  }
993  }
994  cursor++; /* keep moving */
995  linelength++;
996  }
997  free (buffer);
998  return true;
999 }
1000 
1001 
1002 /*
1003  * find a valid type value pair separated by a delimiter
1004  * character and pass it to valuePairs()
1005  * any line which is not valid will be considered a value
1006  * and will get passed on to justValue()
1007  *
1008  * assuming delimiter is ':' the behaviour will be,
1009  *
1010  * width:10 - valid pair valuePairs( width, 10 );
1011  * width : 10 - valid pair valuepairs( width, 10 );
1012  *
1013  * :::: - not valid
1014  * width - not valid
1015  * :10 - not valid
1016  * width: - not valid
1017  * :: - not valid
1018  * : - not valid
1019  *
1020  */
1021 
1022 void
1023 AnyOption::processLine( char *theline, int length )
1024 {
1025  bool found = false;
1026  char *pline = (char*) malloc( (length+1)*sizeof(char) );
1027  for( int i = 0 ; i < length ; i ++ )
1028  pline[i]= *(theline++);
1029  pline[length] = nullterminate;
1030  char *cursor = pline ; /* preserve the ptr */
1031  if( *cursor == delimiter || *(cursor+length-1) == delimiter ){
1032  justValue( pline );/* line with start/end delimiter */
1033  }else{
1034  for( int i = 1 ; i < length-1 && !found ; i++){/* delimiter */
1035  if( *cursor == delimiter ){
1036  *(cursor-1) = nullterminate; /* two strings */
1037  found = true;
1038  valuePairs( pline , cursor+1 );
1039  }
1040  cursor++;
1041  }
1042  cursor++;
1043  if( !found ) /* not a pair */
1044  justValue( pline );
1045  }
1046  free (pline);
1047 }
1048 
1049 /*
1050  * removes trailing and preceeding whitespaces from a string
1051  */
1052 char*
1053 AnyOption::chomp( char *str )
1054 {
1055  while( *str == whitespace )
1056  str++;
1057  char *end = str+strlen(str)-1;
1058  while( *end == whitespace )
1059  end--;
1060  *(end+1) = nullterminate;
1061  return str;
1062 }
1063 
1064 void
1065 AnyOption::valuePairs( char *type, char *value )
1066 {
1067  if ( strlen(chomp(type)) == 1 ){ /* this is a char option */
1068  for( int i = 0 ; i < optchar_counter ; i++ ){
1069  if( optionchars[i] == type[0] ){ /* match */
1070  if( optchartype[i] == COMMON_OPT ||
1071  optchartype[i] == FILE_OPT )
1072  {
1073  setValue( type[0] , chomp(value) );
1074  return;
1075  }
1076  }
1077  }
1078  }
1079  /* if no char options matched */
1080  for( int i = 0 ; i < option_counter ; i++ ){
1081  if( strcmp( options[i], type ) == 0 ){ /* match */
1082  if( optiontype[i] == COMMON_OPT ||
1083  optiontype[i] == FILE_OPT )
1084  {
1085  setValue( type , chomp(value) );
1086  return;
1087  }
1088  }
1089  }
1090  printVerbose( "Unknown option in resourcefile : " );
1091  printVerbose( type );
1092  printVerbose( );
1093 }
1094 
1095 void
1097 {
1098 
1099  if ( strlen(chomp(type)) == 1 ){ /* this is a char option */
1100  for( int i = 0 ; i < optchar_counter ; i++ ){
1101  if( optionchars[i] == type[0] ){ /* match */
1102  if( optchartype[i] == COMMON_FLAG ||
1103  optchartype[i] == FILE_FLAG )
1104  {
1105  setFlagOn( type[0] );
1106  return;
1107  }
1108  }
1109  }
1110  }
1111  /* if no char options matched */
1112  for( int i = 0 ; i < option_counter ; i++ ){
1113  if( strcmp( options[i], type ) == 0 ){ /* match */
1114  if( optiontype[i] == COMMON_FLAG ||
1115  optiontype[i] == FILE_FLAG )
1116  {
1117  setFlagOn( type );
1118  return;
1119  }
1120  }
1121  }
1122  printVerbose( "Unknown option in resourcefile : " );
1123  printVerbose( type );
1124  printVerbose( );
1125 }
1126 
1127 /*
1128  * usage and help
1129  */
1130 
1131 
1132 void
1134 {
1135  if( autousage ) printUsage();
1136 }
1137 
1138 void
1140 {
1141 
1142  if( once ) {
1143  once = false ;
1144  cout << endl ;
1145  for( int i = 0 ; i < usage_lines ; i++ )
1146  cout << usage[i] << endl ;
1147  cout << endl ;
1148  }
1149 }
1150 
1151 
1152 void
1153 AnyOption::addUsage( const char *line )
1154 {
1155  if( usage_lines >= max_usage_lines ){
1156  if( doubleUsageStorage() == false ){
1157  addUsageError( line );
1158  exit(1);
1159  }
1160  }
1161  usage[ usage_lines ] = line ;
1162  usage_lines++;
1163 }
1164 
1165 void
1166 AnyOption::addUsageError( const char *line )
1167 {
1168  cout << endl ;
1169  cout << "OPTIONS ERROR : Failed allocating extra memory " << endl ;
1170  cout << "While adding the usage/help : \""<< line << "\"" << endl;
1171  cout << "Exiting." << endl ;
1172  cout << endl ;
1173  exit(0);
1174 
1175 }
bool hasoptions
Definition: anyoption.h:218
void setFileDelimiterChar(char _delimiter)
Definition: anyoption.cpp:292
void setVerbose()
Definition: anyoption.cpp:323
char * chomp(char *str)
Definition: anyoption.cpp:1053
bool alloc()
Definition: anyoption.cpp:143
int * optcharindex
Definition: anyoption.h:184
#define MAX_LONG_PREFIX_LENGTH
Definition: anyoption.h:23
void useCommandArgs(int _argc, char **_argv)
Definition: anyoption.cpp:368
int * optiontype
Definition: anyoption.h:176
bool consumeFile(char *buffer)
Definition: anyoption.cpp:971
char opt_prefix_char
Definition: anyoption.h:204
#define DEFAULT_MAXUSAGE
Definition: anyoption.h:25
char * getArgv(int index)
Definition: anyoption.cpp:911
bool setFlagOn(const char *option)
Definition: anyoption.cpp:859
int new_argc
Definition: anyoption.h:169
char delimiter
Definition: anyoption.h:210
char ** argv
Definition: anyoption.h:164
const char ** usage
Definition: anyoption.h:192
char whitespace
Definition: anyoption.h:212
void useFiileName(const char *_filename)
Definition: anyoption.cpp:378
int matchOpt(char *opt)
Definition: anyoption.cpp:715
bool doubleUsageStorage()
Definition: anyoption.cpp:238
void setFlag(const char *opt_string)
Definition: anyoption.cpp:499
void printAutoUsage()
Definition: anyoption.cpp:1133
bool valueStoreOK()
Definition: anyoption.cpp:761
void processLine(char *theline, int length)
Definition: anyoption.cpp:1023
char parsePOSIX(char *arg)
Definition: anyoption.cpp:653
char file_delimiter_char
Definition: anyoption.h:206
void noPOSIX()
Definition: anyoption.cpp:310
#define COMMON_OPT
Definition: anyoption.h:9
int optchar_counter
Definition: anyoption.h:185
bool command_set
Definition: anyoption.h:196
int option_counter
Definition: anyoption.h:178
bool findFlag(char *value)
Definition: anyoption.cpp:829
char equalsign
Definition: anyoption.h:208
void autoUsagePrint(bool flag)
Definition: anyoption.cpp:362
void printVerbose()
Definition: anyoption.cpp:329
char nullterminate
Definition: anyoption.h:213
void setFileCommentChar(char _comment)
Definition: anyoption.cpp:285
void setCommandPrefixChar(char _prefix)
Definition: anyoption.cpp:269
bool once
Definition: anyoption.h:216
void setCommandOption(const char *opt_string)
Definition: anyoption.cpp:389
char file_comment_char
Definition: anyoption.h:207
int max_char_options
Definition: anyoption.h:181
bool autousage
Definition: anyoption.h:219
int g_value_counter
Definition: anyoption.h:189
int max_legal_args
Definition: anyoption.h:170
const char * filename
Definition: anyoption.h:165
char endofline
Definition: anyoption.h:211
#define DEFAULT_MAXOPTS
Definition: anyoption.h:22
int * new_argv
Definition: anyoption.h:168
bool hasOptions()
Definition: anyoption.cpp:356
bool FileSet()
Definition: anyoption.cpp:304
#define TRUE_FLAG
Definition: anyoption.h:28
bool verbose
Definition: anyoption.h:200
bool getFlag(const char *_option)
Definition: anyoption.cpp:793
void processCommandArgs()
Definition: anyoption.cpp:610
#define COMMAND_FLAG
Definition: anyoption.h:13
void setFileOption(const char *opt_string)
Definition: anyoption.cpp:433
void init()
Definition: anyoption.cpp:87
bool posix_style
Definition: anyoption.h:199
bool file_set
Definition: anyoption.h:197
int argc
Definition: anyoption.h:163
bool matchChar(char c)
Definition: anyoption.cpp:738
char * getValue(const char *_option)
Definition: anyoption.cpp:780
const char ** options
Definition: anyoption.h:175
void addUsageError(const char *line)
Definition: anyoption.cpp:1166
void printUsage()
Definition: anyoption.cpp:1139
bool processFile()
Definition: anyoption.cpp:922
void justValue(char *value)
Definition: anyoption.cpp:1096
#define FILE_FLAG
Definition: anyoption.h:14
void setCommandFlag(const char *opt_string)
Definition: anyoption.cpp:411
bool mem_allocated
Definition: anyoption.h:198
int usage_lines
Definition: anyoption.h:194
void processOptions()
Definition: anyoption.cpp:582
char ** values
Definition: anyoption.h:188
#define COMMON_FLAG
Definition: anyoption.h:12
void addUsage(const char *line)
Definition: anyoption.cpp:1153
int * optchartype
Definition: anyoption.h:183
bool doubleOptStorage()
Definition: anyoption.cpp:194
int max_options
Definition: anyoption.h:174
bool setValue(const char *option, char *value)
Definition: anyoption.cpp:844
void setCommandLongPrefix(char *_prefix)
Definition: anyoption.cpp:275
int getArgc()
Definition: anyoption.cpp:905
char * optionchars
Definition: anyoption.h:182
void setOption(const char *opt_string)
Definition: anyoption.cpp:477
bool doubleCharStorage()
Definition: anyoption.cpp:215
char comment
Definition: anyoption.h:209
int parseGNU(char *arg)
Definition: anyoption.cpp:680
void valuePairs(char *type, char *value)
Definition: anyoption.cpp:1065
int max_usage_lines
Definition: anyoption.h:193
#define COMMAND_OPT
Definition: anyoption.h:10
void addOption(const char *option, int type)
Definition: anyoption.cpp:521
void cleanup()
Definition: anyoption.cpp:253
bool CommandSet()
Definition: anyoption.cpp:298
char * appname
Definition: anyoption.h:166
char long_opt_prefix[MAX_LONG_PREFIX_LENGTH+1]
Definition: anyoption.h:205
#define FILE_OPT
Definition: anyoption.h:11
int * optionindex
Definition: anyoption.h:177
void addOptionError(const char *opt)
Definition: anyoption.cpp:560
bool POSIX()
Definition: anyoption.cpp:316
char * readFile()
Definition: anyoption.cpp:937
void setFileFlag(const char *opt_string)
Definition: anyoption.cpp:455