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