The Original CHomP Software
arg.h
Go to the documentation of this file.
1
3
53
54// Copyright (C) 1997-2020 by Pawel Pilarczyk.
55//
56// This file is part of my research software package. This is free software:
57// you can redistribute it and/or modify it under the terms of the GNU
58// General Public License as published by the Free Software Foundation,
59// either version 3 of the License, or (at your option) any later version.
60//
61// This software is distributed in the hope that it will be useful,
62// but WITHOUT ANY WARRANTY; without even the implied warranty of
63// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
64// GNU General Public License for more details.
65//
66// You should have received a copy of the GNU General Public License
67// along with this software; see the file "license.txt". If not,
68// please, see <https://www.gnu.org/licenses/>.
69
70// You may want to include "textfile.h" and "timeused.h" before this file.
71// Started on March 3, 2002. Last revision: March 9, 2007.
72
73
74#ifndef _CHOMP_SYSTEM_ARG_H_
75#define _CHOMP_SYSTEM_ARG_H_
76
77#include "chomp/system/config.h"
78
79#include <iostream>
80#include <iomanip>
81#include <cstring>
82#include <sstream>
83#include <cctype>
84
85namespace chomp {
86namespace homology {
87
88// the main front-end class defined in this file
89class arguments;
90
91
92// --------------------------------------------------
93// -------------------- argflags --------------------
94// --------------------------------------------------
95
100{
101public:
103 enum names {obligatory = 0x01, hasdefault = 0x02,
104 filled = 0x04, breakinterpreting = 0x08,
105 toomany = 0x10, missingvalue = 0x20,
106 readerror = 0x40, ignorevalue = 0x80};
107
109 argflags (): n (0) {}
110
113
115 void set (int flag) {n |= flag;}
116
118 void unset (int flag) {n &= ~flag;}
119
121 bool get (int flag) const {return !!(n & flag);}
122
123private:
125 int n;
126
127}; /* argflags */
128
129
130// --------------------------------------------------
131// ------------------- argelement -------------------
132// --------------------------------------------------
133
137{
138public:
140 argelement (const char *_name);
141
143 virtual ~argelement ();
144
146 const char *getname () const;
147
150 char *getvalue (char *str);
151
155 virtual int setvalue (char *str, char *next) = 0;
156
158 virtual void restore () = 0;
159
161 virtual void show (std::ostream &out) const = 0;
162
164 void resetflags ();
165
167 void set (int flag);
168
170 void unset (int flag);
171
173 bool get (int flag) const;
174
175private:
178 char *name;
179
182
183}; /* class argelement */
184
185inline argelement::argelement (const char *_name): flags ()
186{
187 if (!_name || !*_name)
188 name = NULL;
189 else
190 {
191 name = new char [strlen (_name) + 1];
192 strcpy (name, _name);
193 }
194 return;
195} /* argelement::argelement */
196
198{
199 if (name)
200 delete [] name;
201 return;
202} /* argelement::~argelement */
203
204inline const char *argelement::getname () const
205{
206 return name;
207} /* argelement::getname */
208
210{
215 return;
216} /* argelement::resetflags */
217
218inline void argelement::set (int flag)
219{
220 flags. set (flag);
221 return;
222} /* argelement::set */
223
224inline void argelement::unset (int flag)
225{
226 flags. unset (flag);
227 return;
228} /* argelement::unset */
229
230inline bool argelement::get (int flag) const
231{
232 return flags. get (flag);
233} /* argelement::get */
234
235inline std::ostream &operator << (std::ostream &out, const argelement &p)
236{
237 p. show (out);
238 return out;
239} /* operator << */
240
241
242// --------------------------------------------------
243// -------------------- argunit ---------------------
244// --------------------------------------------------
245
251template <class type>
252class argunit: public argelement
253{
254public:
257 argunit (const char *_name, type &_value);
258
262 argunit (const char *_name, type &_value, type defaultvalue);
263
266 argunit (const char *_name, type *_value, int &_count,
267 int _size);
268
271 argunit (const char *_name, type *_value, int &_count,
272 int _size, type defaultvalue);
273
275 int setvalue (char *str, char *next);
276
278 void restore ();
279
281 void show (std::ostream &out) const;
282
283private:
286 type &value;
287
290
294
296 type *table;
297
300 int *count;
301
304
306 int size;
307
308}; /* class argunit */
309
310template <class type>
311inline argunit<type>::argunit (const char *_name, type &_value):
312 argelement (_name), value (_value), previousvalue (_value),
313 table (NULL)
314{
315 return;
316} /* argunit<type>::argunit */
317
318template <class type>
319inline argunit<type>::argunit (const char *_name, type &_value,
320 type _defaultvalue):
321 argelement (_name), value (_value), defaultvalue (_defaultvalue),
322 previousvalue (_value), table (NULL)
323{
325 return;
326} /* argunit<type>::argunit */
327
328template <class type>
329inline argunit<type>::argunit (const char *_name, type *_value,
330 int &_count, int _size):
331 argelement (_name), value (*_value), previousvalue (*_value),
332 table (_value), count (&_count), previouscount (_count),
333 size (_size)
334{
335 return;
336} /* argunit<type>::argunit */
337
338template <class type>
339inline argunit<type>::argunit (const char *_name, type *_value,
340 int &_count, int _size, type _defaultvalue):
341 argelement (_name), value (*_value), defaultvalue (_defaultvalue),
342 previousvalue (*_value), table (_value),
343 count (&_count), previouscount (_count), size (_size)
344
345{
347 return;
348} /* argunit<type>::argunit */
349
352template <class type>
353inline int readfromstring (char *str, type &t)
354{
355 std::istringstream s (str);
356 try
357 {
358 s >> t;
359 if (!s)
360 return -1;
361 }
362 catch (...)
363 {
364 return -1;
365 }
366 return 0;
367} /* readfromstring */
368
371inline int readfromstring (char *str, char *&t)
372{
373 t = str;
374 return 0;
375} /* readfromstring */
376
379// This function was added by Tomek Kapela. His remark
380// justifying this addition: "e.g to replace default constant C strings".
381inline int readfromstring (char *str, const char *&t)
382{
383 t = str;
384 return 0;
385} /* readfromstring */
386
388inline int readfromstring (char *str, bool &t)
389{
390 switch (*str)
391 {
392 case 'T':
393 case 't':
394 case 'Y':
395 case 'y':
396 case '1':
397 t = true;
398 return 0;
399 case 'F':
400 case 'f':
401 case 'N':
402 case 'n':
403 case '0':
404 t = false;
405 return 0;
406 default:
407 return -1;
408 }
409} /* readfromstring */
410
411template <class type>
412inline int argunit<type>::setvalue (char *str, char *next)
413{
414 // determine the string from which the value should be read
415 int usenext = 0;
416 char *s;
417 if (str && *str)
418 s = str;
419 else
420 {
421 if (next && *next && ((*next != '-') ||
422 std::isdigit (next [1])))
423 {
424 s = next;
425 usenext = 1;
426 }
427 else
428 s = NULL;
429 }
430
431 // read the element from the string if available
432 int result = -1;
433 type element;
434 if (s)
435 result = readfromstring (s, element);
436
437 // if could not read the string, try the default value
438 if (result < 0)
439 {
440 if (get (argflags::hasdefault))
441 {
442 element = defaultvalue;
443 usenext = 0;
444 }
445 else
446 {
447 if (s)
449 else
451 return 0;
452 }
453 }
454
455 // put the element to its place
456 if (table)
457 // if there is still room in the table, put the element there
458 if (*count < size)
459 table [(*count) ++] = element;
460 // if the table is full, indicate it
461 else
462 {
463 set (argflags::toomany);
464 set (argflags::filled);
465 }
466 else
467 {
468 value = element;
469 set (argflags::filled);
470 }
471
472 return usenext;
473} /* argunit<type>::setvalue */
474
475template <class type>
477{
478 if (!table)
479 value = previousvalue;
480 else
481 *count = previouscount;
482 resetflags ();
483 return;
484} /* argunit<type>::restore */
485
486template <class type>
487void argunit<type>::show (std::ostream &out) const
488{
489 if (get (argflags::obligatory))
490 out << "Oblig. ";
491 if (getname () && *getname ())
492 {
493 if (get (argflags::ignorevalue))
494 out << "Switch";
495 else
496 out << "Param.";
497 out << " '-" << getname () << "'";
498 }
499 else
500 out << "Word";
501 if (!table && get (argflags::filled))
502 out << " set to '" << value << "'";
503 else if (table && *count)
504 {
505 for (int i = 0; i < *count; ++ i)
506 out << (i ? ", " : " set to '") << table [i];
507 out << "'";
508 if (get (argflags::toomany))
509 out << " [too many!]";
510 }
511 else
512 out << " not found";
513 if (get (argflags::hasdefault))
514 out << " (default: '" << defaultvalue << "')";
515 else
516 out << " (no default value)";
517 out << "." << std::endl;
518 return;
519} /* argunit<type>::show */
520
521
522// --------------------------------------------------
523// ------------------- arguments --------------------
524// --------------------------------------------------
525
534{
535public:
537 arguments ();
538
541
543 void add (argelement *p);
544
547 int remove (char *name);
548
555 int analyze (int argc, char *argv [],
556 std::ostream &out = std::cerr);
557
560 void reset ();
561
563 friend std::ostream &operator << (std::ostream &out,
564 arguments &p);
565
566private:
568 int n;
569
572
575
577 void inctable ();
578
579}; /* class arguments */
580
582{
583 n = 0;
584 length = 0;
585 tab = NULL;
586 return;
587} /* arguments::arguments */
588
590{
591 inctable ();
592 tab [n ++] = p;
593 return;
594} /* arguments::add */
595
596// --------------------------------------------------
597
603template <class type>
604inline void arg (arguments &a, const char *name, type &value)
605{
606 argunit<type> *p = new argunit<type> (name, value);
607 a. add (p);
608 return;
609} /* arg */
610
614template <class type>
615inline void arg (arguments &a, const char *name, type &value,
616 type defaultvalue)
617{
618 argunit<type> *p = new argunit<type> (name, value, defaultvalue);
619 a. add (p);
620 return;
621} /* arg */
622
624inline void arg (arguments &a, const char *name, char *&value,
625 const char *defaultvalue)
626{
627 argunit<char *> *p =
628 new argunit<char *> (name, value,
629 const_cast<char *> (defaultvalue));
630 a. add (p);
631 return;
632} /* arg */
633
638template <class type>
639inline void arg (arguments &a, const char *name, type *value,
640 int &count, int size)
641{
642 argunit<type> *p = new argunit<type> (name, value, count, size);
643 a. add (p);
644 return;
645} /* arg */
646
648template <class type>
649inline void arg (arguments &a, const char *name, type *value,
650 int &count, int size, type defaultvalue)
651{
652 argunit<type> *p = new argunit<type> (name, value, count, size,
653 defaultvalue);
654 a. add (p);
655 return;
656} /* argoblig */
657
661template <class type>
662inline void argoblig (arguments &arg, const char *name, type &value)
663{
664 argunit<type> *p = new argunit<type> (name, value);
665 p -> set (argflags::obligatory);
666 arg. add (p);
667 return;
668} /* argoblig */
669
671template <class type>
672inline void argoblig (arguments &arg, const char *name, type &value,
673 type defaultvalue)
674{
675 argunit<type> *p = new argunit<type> (name, value, defaultvalue);
676 p -> set (argflags::obligatory);
677 arg. add (p);
678 return;
679} /* argoblig */
680
682inline void argoblig (arguments &arg, const char *name, char *&value,
683 const char *defaultvalue)
684{
685 argunit<char *> *p =
686 new argunit<char *> (name, value, (char *) defaultvalue);
687 p -> set (argflags::obligatory);
688 arg. add (p);
689 return;
690} /* argoblig */
691
696template <class type>
697inline void argbreak (arguments &arg, const char *name, type &value)
698{
699 argunit<type> *p = new argunit<type> (name, value);
701 p -> set (argflags::ignorevalue);
702 arg. add (p);
703 return;
704} /* argbreak */
705
707template <class type>
708inline void argbreak (arguments &arg, const char *name, type &value,
709 type defaultvalue)
710{
711 argunit<type> *p = new argunit<type> (name, value, defaultvalue);
713 p -> set (argflags::ignorevalue);
714 arg. add (p);
715 return;
716} /* argbreak */
717
719inline void argbreak (arguments &arg, const char *name, char *&value,
720 const char *defaultvalue)
721{
722 argunit<char *> *p =
723 new argunit<char *> (name, value, (char *) defaultvalue);
725 p -> set (argflags::ignorevalue);
726 arg. add (p);
727 return;
728} /* argbreak */
729
731inline void argbreak (arguments &arg, const char *name)
732{
733 char *dummystring = NULL;
734 argunit<char *> *p = new argunit<char *> (name, dummystring);
736 p -> set (argflags::ignorevalue);
737 arg. add (p);
738 return;
739} /* argbreak */
740
744template <class type>
745inline void argswitch (arguments &arg, const char *name, type &value,
746 const type &defaultvalue)
747{
748 argunit<type> *p = new argunit<type> (name, value, defaultvalue);
749 p -> set (argflags::ignorevalue);
750 arg. add (p);
751 return;
752} /* argswitch */
753
755inline void argswitch (arguments &arg, const char *name, char *&value,
756 const char *defaultvalue)
757{
758 argunit<char *> *p =
759 new argunit<char *> (name, value, (char *) defaultvalue);
760 p -> set (argflags::ignorevalue);
761 arg. add (p);
762 return;
763} /* argswitch */
764
766inline void argswitch (arguments &arg, const char *name)
767{
768 char *dummystring = NULL;
769 argunit<char *> *p = new argunit<char *> (name, dummystring);
770 p -> set (argflags::ignorevalue);
771 arg. add (p);
772 return;
773} /* argswitch */
774
778inline void arghelp (arguments &a)
779{
780 argbreak (a, "?");
781 argbreak (a, "h");
782 argbreak (a, "H");
783 argbreak (a, "-help");
784 return;
785} /* arghelp */
786
787// --------------------------------------------------
788
789#ifdef OUTPUTSTREAM
790
793inline void argstreams (arguments &a, char *&logfilename, char *&seqfilename,
794 bool &quiet, bool &debug)
795{
796 arg (a, "-log", logfilename);
797 arg (a, "-seq", seqfilename);
798 argswitch (a, "-quiet", quiet, true);
799 argswitch (a, "-debug", debug, true);
800 return;
801} /* argstreams */
802
806inline void setstreams (const char *logfilename, char *seqfilename,
807 bool quiet, bool debug)
808{
809 if (debug)
810 sbug. show = true;
811 if (quiet)
812 {
813 sout. show = false;
814 scon. show = false;
815 sbug. show = false;
816 }
817 if (logfilename)
818 {
819 slog. logfile (logfilename);
820 slog. keepforever ();
821 sout. logfile (slog);
822 serr. logfile (slog);
823 if (debug)
824 sbug. logfile (slog);
825 }
826 if (seqfilename)
827 sseq. logfile (seqfilename);
828#ifdef TIMEUSED
830#endif
831 return;
832} /* setstreams */
833
834#ifndef algstreamprepare
838#define argstreamprepare(a) \
839char *arg_logfilename = NULL; \
840char *arg_seqfilename = NULL; \
841char *arg_computername = NULL; \
842bool arg_quiet = false; \
843bool arg_debug = false; \
844arg (a, "-comp", arg_computername); \
845argstreams (a, arg_logfilename, arg_seqfilename, arg_quiet, arg_debug);
846#endif
847
848#ifndef argstreamset
852#define argstreamset() \
853setstreams (arg_logfilename, arg_seqfilename, arg_quiet, arg_debug); \
854slog << commandline (argc, argv) << "\n\n"; \
855if (arg_computername) slog << "Running on " << arg_computername << ". "; \
856slog << "Start time: " << currenttime () << '\n';
857#endif
858
859#endif
860/* */
861
862
863} // namespace homology
864} // namespace chomp
865
866#endif // _CHOMP_SYSTEM_ARG_H_
867
869
This is a helper class which defines common properties of a command-line argument bound with any type...
Definition: arg.h:137
bool get(int flag) const
Returns the value of the given flag.
Definition: arg.h:230
virtual int setvalue(char *str, char *next)=0
Sets the value of this argument according to the string.
const char * getname() const
Returns the name of the command-line argument.
Definition: arg.h:204
void unset(int flag)
Unsets (clears) the given flag.
Definition: arg.h:224
void set(int flag)
Sets the given flag.
Definition: arg.h:218
virtual void show(std::ostream &out) const =0
Outputs the argument element to the output stream.
void resetflags()
Resets the flags.
Definition: arg.h:209
argelement(const char *_name)
The constructor.
Definition: arg.h:185
char * getvalue(char *str)
Returns the argument's value string from the argument string or returns 0 if it is not this argument.
virtual ~argelement()
The destructor.
Definition: arg.h:197
virtual void restore()=0
Restores the previous argument value (except for tables).
argflags flags
The flags associated with this argument.
Definition: arg.h:181
char * name
The argument name (without '-').
Definition: arg.h:178
This is a helper class which defines specific flags indicating various types of command-line argument...
Definition: arg.h:100
argflags()
The constructor. All flags are initially cleared (unset).
Definition: arg.h:109
void unset(int flag)
Unsets (clears) the given flag.
Definition: arg.h:118
names
A list of specific names for the flags.
Definition: arg.h:103
~argflags()
The destructor.
Definition: arg.h:112
int n
The interger variable that stores the flags.
Definition: arg.h:125
bool get(int flag) const
Returns true if any of the given flags is set or false otherwise.
Definition: arg.h:121
void set(int flag)
Sets the given flag.
Definition: arg.h:115
The objects of this class gather the expected command-line arguments and decode them.
Definition: arg.h:534
int remove(char *name)
Removes all the arguments with this name from the list and return the number of removed items.
int analyze(int argc, char *argv[], std::ostream &out=std::cerr)
Analyzes the arguments from the command line strings.
~arguments()
The destructor.
void reset()
Resets the flags and returns previous argument values (except for tables).
int n
The number of arguments in the table.
Definition: arg.h:568
void inctable()
Increases the tables if necessary.
friend std::ostream & operator<<(std::ostream &out, arguments &p)
Displays the arguments actually decoded (for debugging purpose).
arguments()
The default constructor.
Definition: arg.h:581
int length
The allocated length of the table of arguments.
Definition: arg.h:571
argelement ** tab
The table of pointers to specific arguments.
Definition: arg.h:574
void add(argelement *p)
Adds an argument to the end of the list.
Definition: arg.h:589
This is a helper class which defines one command-line argument which is bound with some specific vari...
Definition: arg.h:253
type defaultvalue
The default value of the variable if any.
Definition: arg.h:289
int previouscount
The initial value of the number of elements in the array.
Definition: arg.h:303
type & value
A reference to the variable which is bound to this command line argument.
Definition: arg.h:286
int setvalue(char *str, char *next)
Sets the argument value from the text string.
Definition: arg.h:412
int size
The size of the array if any.
Definition: arg.h:306
argunit(const char *_name, type &_value)
The constructor of a command line argument bound with one variable.
Definition: arg.h:311
type * table
A pointer to the array bound with the variable.
Definition: arg.h:296
type previousvalue
The original value of the variable (before reading the command line).
Definition: arg.h:293
void restore()
Restores the previous argument value (except for tables).
Definition: arg.h:476
int * count
A pointer to the number of elements currently present in the array.
Definition: arg.h:300
void show(std::ostream &out) const
Displays the value and some information.
Definition: arg.h:487
This file contains some precompiler definitions which indicate the operating system and/or compiler u...
outputstream sseq
An auxiliary stream which captures sequences of processed data.
void setstreams(const char *logfilename, char *seqfilename, bool quiet, bool debug)
Sets the parameters of the output streams depending on the file names acquired from the command line.
Definition: arg.h:806
void argstreams(arguments &a, char *&logfilename, char *&seqfilename, bool &quiet, bool &debug)
Adds typical command line arguments for manipulating output streams.
Definition: arg.h:793
outputstream sout
A replacement for standard output stream, with optional logging and other features provided by the cl...
outputstream serr
A wrapper for the standard error stream.
std::ostream & operator<<(std::ostream &out, const bincube< Dim, twoPower > &b)
Definition: bincube.h:907
void arg(arguments &a, const char *name, type &value)
Adds a command line argument.
Definition: arg.h:604
outputstream sbug
An output stream for writing additional debug messages.
timeused program_time
The external variable which measures the time used by the program from its start.
void argoblig(arguments &arg, const char *name, type &value)
Defines an obligatory command line argument.
Definition: arg.h:662
void argbreak(arguments &arg, const char *name, type &value)
Adds an argument whose appearence interrupts the analysis of the command line and makes the analyzing...
Definition: arg.h:697
outputstream scon
The console output stream to which one should put all the junk that spoils the log file,...
void argswitch(arguments &arg, const char *name, type &value, const type &defaultvalue)
Defines a command line argument which is a switch, that is, there is no value given for it in the com...
Definition: arg.h:745
int readfromstring(char *str, type &t)
A template for reading a variable from a string.
Definition: arg.h:353
outputstream slog
The output stream to which one can send messages for logging only.
void arghelp(arguments &a)
Adds the typical arguments which should make the program display help information.
Definition: arg.h:778
This namespace contains the entire CHomP library interface.
Definition: bitmaps.h:51