summaryrefslogtreecommitdiffstats
path: root/pacman-c++/server/anyoption.cpp
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2011-05-05 00:57:07 +0200
committermanuel <manuel@mausz.at>2011-05-05 00:57:07 +0200
commitce48af53646cd9e7ec762fc1ac176b3aa620b11d (patch)
treef8fbf2cae8c7d0cbac2696a8f4cf94410bfb4928 /pacman-c++/server/anyoption.cpp
parente54ccad07e256ba877bd41d70bd358bd0085bd1e (diff)
downloadfoop-ce48af53646cd9e7ec762fc1ac176b3aa620b11d.tar.gz
foop-ce48af53646cd9e7ec762fc1ac176b3aa620b11d.tar.bz2
foop-ce48af53646cd9e7ec762fc1ac176b3aa620b11d.zip
- refactorized the whole project and made a few subprojects
- replaced tcp with enet - added connect dialog - some smaller bugfixes
Diffstat (limited to 'pacman-c++/server/anyoption.cpp')
-rw-r--r--pacman-c++/server/anyoption.cpp1175
1 files changed, 1175 insertions, 0 deletions
diff --git a/pacman-c++/server/anyoption.cpp b/pacman-c++/server/anyoption.cpp
new file mode 100644
index 0000000..4e3828e
--- /dev/null
+++ b/pacman-c++/server/anyoption.cpp
@@ -0,0 +1,1175 @@
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
65AnyOption::AnyOption()
66{
67 init();
68}
69
70AnyOption::AnyOption(int maxopt)
71{
72 init( maxopt , maxopt );
73}
74
75AnyOption::AnyOption(int maxopt, int maxcharopt)
76{
77 init( maxopt , maxcharopt );
78}
79
80AnyOption::~AnyOption()
81{
82 if( mem_allocated )
83 cleanup();
84}
85
86void
87AnyOption::init()
88{
89 init( DEFAULT_MAXOPTS , DEFAULT_MAXOPTS );
90}
91
92void
93AnyOption::init(int maxopt, int maxcharopt )
94{
95
96 max_options = maxopt;
97 max_char_options = maxcharopt;
98 max_usage_lines = DEFAULT_MAXUSAGE;
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
142bool
143AnyOption::alloc()
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
193bool
194AnyOption::doubleOptStorage()
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
214bool
215AnyOption::doubleCharStorage()
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
237bool
238AnyOption::doubleUsageStorage()
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
252void
253AnyOption::cleanup()
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
268void
269AnyOption::setCommandPrefixChar( char _prefix )
270{
271 opt_prefix_char = _prefix;
272}
273
274void
275AnyOption::setCommandLongPrefix( char *_prefix )
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
284void
285AnyOption::setFileCommentChar( char _comment )
286{
287 file_delimiter_char = _comment;
288}
289
290
291void
292AnyOption::setFileDelimiterChar( char _delimiter )
293{
294 file_comment_char = _delimiter ;
295}
296
297bool
298AnyOption::CommandSet()
299{
300 return( command_set );
301}
302
303bool
304AnyOption::FileSet()
305{
306 return( file_set );
307}
308
309void
310AnyOption::noPOSIX()
311{
312 posix_style = false;
313}
314
315bool
316AnyOption::POSIX()
317{
318 return posix_style;
319}
320
321
322void
323AnyOption::setVerbose()
324{
325 verbose = true ;
326}
327
328void
329AnyOption::printVerbose()
330{
331 if( verbose )
332 cout << endl ;
333}
334void
335AnyOption::printVerbose( const char *msg )
336{
337 if( verbose )
338 cout << msg ;
339}
340
341void
342AnyOption::printVerbose( char *msg )
343{
344 if( verbose )
345 cout << msg ;
346}
347
348void
349AnyOption::printVerbose( char ch )
350{
351 if( verbose )
352 cout << ch ;
353}
354
355bool
356AnyOption::hasOptions()
357{
358 return hasoptions;
359}
360
361void
362AnyOption::autoUsagePrint(bool _autousage)
363{
364 autousage = _autousage;
365}
366
367void
368AnyOption::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
377void
378AnyOption::useFiileName( const char *_filename )
379{
380 filename = _filename;
381 file_set = true;
382}
383
384/*
385 * set methods for options
386 */
387
388void
389AnyOption::setCommandOption( const char *opt )
390{
391 addOption( opt , COMMAND_OPT );
392 g_value_counter++;
393}
394
395void
396AnyOption::setCommandOption( char opt )
397{
398 addOption( opt , COMMAND_OPT );
399 g_value_counter++;
400}
401
402void
403AnyOption::setCommandOption( const char *opt , char optchar )
404{
405 addOption( opt , COMMAND_OPT );
406 addOption( optchar , COMMAND_OPT );
407 g_value_counter++;
408}
409
410void
411AnyOption::setCommandFlag( const char *opt )
412{
413 addOption( opt , COMMAND_FLAG );
414 g_value_counter++;
415}
416
417void
418AnyOption::setCommandFlag( char opt )
419{
420 addOption( opt , COMMAND_FLAG );
421 g_value_counter++;
422}
423
424void
425AnyOption::setCommandFlag( const char *opt , char optchar )
426{
427 addOption( opt , COMMAND_FLAG );
428 addOption( optchar , COMMAND_FLAG );
429 g_value_counter++;
430}
431
432void
433AnyOption::setFileOption( const char *opt )
434{
435 addOption( opt , FILE_OPT );
436 g_value_counter++;
437}
438
439void
440AnyOption::setFileOption( char opt )
441{
442 addOption( opt , FILE_OPT );
443 g_value_counter++;
444}
445
446void
447AnyOption::setFileOption( const char *opt , char optchar )
448{
449 addOption( opt , FILE_OPT );
450 addOption( optchar, FILE_OPT );
451 g_value_counter++;
452}
453
454void
455AnyOption::setFileFlag( const char *opt )
456{
457 addOption( opt , FILE_FLAG );
458 g_value_counter++;
459}
460
461void
462AnyOption::setFileFlag( char opt )
463{
464 addOption( opt , FILE_FLAG );
465 g_value_counter++;
466}
467
468void
469AnyOption::setFileFlag( const char *opt , char optchar )
470{
471 addOption( opt , FILE_FLAG );
472 addOption( optchar , FILE_FLAG );
473 g_value_counter++;
474}
475
476void
477AnyOption::setOption( const char *opt )
478{
479 addOption( opt , COMMON_OPT );
480 g_value_counter++;
481}
482
483void
484AnyOption::setOption( char opt )
485{
486 addOption( opt , COMMON_OPT );
487 g_value_counter++;
488}
489
490void
491AnyOption::setOption( const char *opt , char optchar )
492{
493 addOption( opt , COMMON_OPT );
494 addOption( optchar , COMMON_OPT );
495 g_value_counter++;
496}
497
498void
499AnyOption::setFlag( const char *opt )
500{
501 addOption( opt , COMMON_FLAG );
502 g_value_counter++;
503}
504
505void
506AnyOption::setFlag( const char opt )
507{
508 addOption( opt , COMMON_FLAG );
509 g_value_counter++;
510}
511
512void
513AnyOption::setFlag( const char *opt , char optchar )
514{
515 addOption( opt , COMMON_FLAG );
516 addOption( optchar , COMMON_FLAG );
517 g_value_counter++;
518}
519
520void
521AnyOption::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 ;
531 optionindex[ option_counter ] = g_value_counter;
532 option_counter++;
533}
534
535void
536AnyOption::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
547 if( optchar_counter >= max_char_options ){
548 if( doubleCharStorage() == false ){
549 addOptionError( opt );
550 return;
551 }
552 }
553 optionchars[ optchar_counter ] = opt ;
554 optchartype[ optchar_counter ] = type ;
555 optcharindex[ optchar_counter ] = g_value_counter;
556 optchar_counter++;
557}
558
559void
560AnyOption::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
570void
571AnyOption::addOptionError( char opt )
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
581void
582AnyOption::processOptions()
583{
584 if( ! valueStoreOK() )
585 return;
586}
587
588void
589AnyOption::processCommandArgs(int max_args)
590{
591 max_legal_args = max_args;
592 processCommandArgs();
593}
594
595void
596AnyOption::processCommandArgs( int _argc, char **_argv, int max_args )
597{
598 max_legal_args = max_args;
599 processCommandArgs( _argc, _argv );
600}
601
602void
603AnyOption::processCommandArgs( int _argc, char **_argv )
604{
605 useCommandArgs( _argc, _argv );
606 processCommandArgs();
607}
608
609void
610AnyOption::processCommandArgs()
611{
612 if( ! ( valueStoreOK() && CommandSet() ) )
613 return;
614
615 if( max_legal_args == 0 )
616 max_legal_args = argc;
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
652char
653AnyOption::parsePOSIX( char* arg )
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
679int
680AnyOption::parseGNU( char *arg )
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
714int
715AnyOption::matchOpt( char *opt )
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}
737bool
738AnyOption::matchChar( char c )
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 true;
750 }
751 }
752 }
753 //printVerbose( "Unknown command argument option : " );
754 //printVerbose( c ) ;
755 //printVerbose( );
756 printAutoUsage();
757 return false;
758}
759
760bool
761AnyOption::valueStoreOK( )
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 */
779char*
780AnyOption::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
792bool
793AnyOption::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
804char*
805AnyOption::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
816bool
817AnyOption::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
828bool
829AnyOption::findFlag( char* val )
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 */
843bool
844AnyOption::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
858bool
859AnyOption::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
873bool
874AnyOption::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
888bool
889AnyOption::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
904int
905AnyOption::getArgc( )
906{
907 return new_argc;
908}
909
910char*
911AnyOption::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
921bool
922AnyOption::processFile()
923{
924 if( ! (valueStoreOK() && FileSet()) )
925 return false;
926 return ( consumeFile(readFile()) );
927}
928
929bool
930AnyOption::processFile( const char *filename )
931{
932 useFiileName(filename );
933 return ( processFile() );
934}
935
936char*
937AnyOption::readFile()
938{
939 return ( readFile(filename) );
940}
941
942/*
943 * read the file contents to a character buffer
944 */
945
946char*
947AnyOption::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 */
970bool
971AnyOption::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
1022void
1023AnyOption::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 */
1052char*
1053AnyOption::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
1064void
1065AnyOption::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
1095void
1096AnyOption::justValue( char *type )
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
1132void
1133AnyOption::printAutoUsage()
1134{
1135 if( autousage ) printUsage();
1136}
1137
1138void
1139AnyOption::printUsage()
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
1152void
1153AnyOption::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
1165void
1166AnyOption::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}