00001
00002
00003
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 #ifndef _CHOMP_SYSTEM_ARG_H_
00076 #define _CHOMP_SYSTEM_ARG_H_
00077
00078 #include "chomp/system/config.h"
00079
00080 #include <iostream>
00081 #include <iomanip>
00082 #include <cstring>
00083 #include <sstream>
00084 #include <cctype>
00085
00086 namespace chomp {
00087 namespace homology {
00088
00089
00090 class arguments;
00091
00092
00093
00094
00095
00096
00100 class argflags
00101 {
00102 public:
00104 enum names {obligatory = 0x01, hasdefault = 0x02,
00105 filled = 0x04, breakinterpreting = 0x08,
00106 toomany = 0x10, missingvalue = 0x20,
00107 readerror = 0x40, ignorevalue = 0x80};
00108
00110 argflags (): n (0) {}
00111
00113 ~argflags () {}
00114
00116 void set (int flag) {n |= flag;}
00117
00119 void unset (int flag) {n &= ~flag;}
00120
00122 bool get (int flag) const {return !!(n & flag);}
00123
00124 private:
00126 int n;
00127
00128 };
00129
00130
00131
00132
00133
00134
00137 class argelement
00138 {
00139 public:
00141 argelement (const char *_name);
00142
00144 virtual ~argelement ();
00145
00147 const char *getname () const;
00148
00151 char *getvalue (char *str);
00152
00156 virtual int setvalue (char *str, char *next) = 0;
00157
00159 virtual void restore () = 0;
00160
00162 virtual void show (std::ostream &out) const = 0;
00163
00165 void resetflags ();
00166
00168 void set (int flag);
00169
00171 void unset (int flag);
00172
00174 bool get (int flag) const;
00175
00176 private:
00179 char *name;
00180
00182 argflags flags;
00183
00184 };
00185
00186 inline argelement::argelement (const char *_name): flags ()
00187 {
00188 if (!_name || !*_name)
00189 name = NULL;
00190 else
00191 {
00192 name = new char [strlen (_name) + 1];
00193 strcpy (name, _name);
00194 }
00195 return;
00196 }
00197
00198 inline argelement::~argelement ()
00199 {
00200 if (name)
00201 delete [] name;
00202 return;
00203 }
00204
00205 inline const char *argelement::getname () const
00206 {
00207 return name;
00208 }
00209
00210 inline void argelement::resetflags ()
00211 {
00212 flags. unset (argflags::filled);
00213 flags. unset (argflags::readerror);
00214 flags. unset (argflags::toomany);
00215 flags. unset (argflags::missingvalue);
00216 return;
00217 }
00218
00219 inline void argelement::set (int flag)
00220 {
00221 flags. set (flag);
00222 return;
00223 }
00224
00225 inline void argelement::unset (int flag)
00226 {
00227 flags. unset (flag);
00228 return;
00229 }
00230
00231 inline bool argelement::get (int flag) const
00232 {
00233 return flags. get (flag);
00234 }
00235
00236 inline std::ostream &operator << (std::ostream &out, const argelement &p)
00237 {
00238 p. show (out);
00239 return out;
00240 }
00241
00242
00243
00244
00245
00246
00252 template <class type>
00253 class argunit: public argelement
00254 {
00255 public:
00258 argunit (const char *_name, type &_value);
00259
00263 argunit (const char *_name, type &_value, type defaultvalue);
00264
00267 argunit (const char *_name, type *_value, int &_count,
00268 int _size);
00269
00272 argunit (const char *_name, type *_value, int &_count,
00273 int _size, type defaultvalue);
00274
00276 int setvalue (char *str, char *next);
00277
00279 void restore ();
00280
00282 void show (std::ostream &out) const;
00283
00284 private:
00287 type &value;
00288
00290 type defaultvalue;
00291
00294 type previousvalue;
00295
00297 type *table;
00298
00301 int *count;
00302
00304 int previouscount;
00305
00307 int size;
00308
00309 };
00310
00311 template <class type>
00312 inline argunit<type>::argunit (const char *_name, type &_value):
00313 argelement (_name), value (_value), previousvalue (_value),
00314 table (NULL)
00315 {
00316 return;
00317 }
00318
00319 template <class type>
00320 inline argunit<type>::argunit (const char *_name, type &_value,
00321 type _defaultvalue):
00322 argelement (_name), value (_value), defaultvalue (_defaultvalue),
00323 previousvalue (_value), table (NULL)
00324 {
00325 set (argflags::hasdefault);
00326 return;
00327 }
00328
00329 template <class type>
00330 inline argunit<type>::argunit (const char *_name, type *_value,
00331 int &_count, int _size):
00332 argelement (_name), value (*_value), previousvalue (*_value),
00333 table (_value), count (&_count), previouscount (_count),
00334 size (_size)
00335 {
00336 return;
00337 }
00338
00339 template <class type>
00340 inline argunit<type>::argunit (const char *_name, type *_value,
00341 int &_count, int _size, type _defaultvalue):
00342 argelement (_name), value (*_value), defaultvalue (_defaultvalue),
00343 previousvalue (*_value), table (_value),
00344 count (&_count), previouscount (_count), size (_size)
00345
00346 {
00347 set (argflags::hasdefault);
00348 return;
00349 }
00350
00353 template <class type>
00354 inline int readfromstring (char *str, type &t)
00355 {
00356 std::istringstream s (str);
00357 try
00358 {
00359 s >> t;
00360 if (!s)
00361 return -1;
00362 }
00363 catch (...)
00364 {
00365 return -1;
00366 }
00367 return 0;
00368 }
00369
00372 inline int readfromstring (char *str, char *&t)
00373 {
00374 t = str;
00375 return 0;
00376 }
00377
00380
00381
00382 inline int readfromstring (char *str, const char *&t)
00383 {
00384 t = str;
00385 return 0;
00386 }
00387
00389 inline int readfromstring (char *str, bool &t)
00390 {
00391 switch (*str)
00392 {
00393 case 'T':
00394 case 't':
00395 case 'Y':
00396 case 'y':
00397 case '1':
00398 t = true;
00399 return 0;
00400 case 'F':
00401 case 'f':
00402 case 'N':
00403 case 'n':
00404 case '0':
00405 t = false;
00406 return 0;
00407 default:
00408 return -1;
00409 }
00410 }
00411
00412 template <class type>
00413 inline int argunit<type>::setvalue (char *str, char *next)
00414 {
00415
00416 int usenext = 0;
00417 char *s;
00418 if (str && *str)
00419 s = str;
00420 else
00421 {
00422 if (next && *next && ((*next != '-') ||
00423 std::isdigit (next [1])))
00424 {
00425 s = next;
00426 usenext = 1;
00427 }
00428 else
00429 s = NULL;
00430 }
00431
00432
00433 int result = -1;
00434 type element;
00435 if (s)
00436 result = readfromstring (s, element);
00437
00438
00439 if (result < 0)
00440 {
00441 if (get (argflags::hasdefault))
00442 {
00443 element = defaultvalue;
00444 usenext = 0;
00445 }
00446 else
00447 {
00448 if (s)
00449 set (argflags::readerror);
00450 else
00451 set (argflags::missingvalue);
00452 return 0;
00453 }
00454 }
00455
00456
00457 if (table)
00458
00459 if (*count < size)
00460 table [(*count) ++] = element;
00461
00462 else
00463 {
00464 set (argflags::toomany);
00465 set (argflags::filled);
00466 }
00467 else
00468 {
00469 value = element;
00470 set (argflags::filled);
00471 }
00472
00473 return usenext;
00474 }
00475
00476 template <class type>
00477 void argunit<type>::restore ()
00478 {
00479 if (!table)
00480 value = previousvalue;
00481 else
00482 *count = previouscount;
00483 resetflags ();
00484 return;
00485 }
00486
00487 template <class type>
00488 void argunit<type>::show (std::ostream &out) const
00489 {
00490 if (get (argflags::obligatory))
00491 out << "Oblig. ";
00492 if (getname () && *getname ())
00493 {
00494 if (get (argflags::ignorevalue))
00495 out << "Switch";
00496 else
00497 out << "Param.";
00498 out << " '-" << getname () << "'";
00499 }
00500 else
00501 out << "Word";
00502 if (!table && get (argflags::filled))
00503 out << " set to '" << value << "'";
00504 else if (table && *count)
00505 {
00506 for (int i = 0; i < *count; ++ i)
00507 out << (i ? ", " : " set to '") << table [i];
00508 out << "'";
00509 if (get (argflags::toomany))
00510 out << " [too many!]";
00511 }
00512 else
00513 out << " not found";
00514 if (get (argflags::hasdefault))
00515 out << " (default: '" << defaultvalue << "')";
00516 else
00517 out << " (no default value)";
00518 out << "." << std::endl;
00519 return;
00520 }
00521
00522
00523
00524
00525
00526
00534 class arguments
00535 {
00536 public:
00538 arguments ();
00539
00541 ~arguments ();
00542
00544 void add (argelement *p);
00545
00548 int remove (char *name);
00549
00556 int analyze (int argc, char *argv [],
00557 std::ostream &out = std::cerr);
00558
00561 void reset ();
00562
00564 friend std::ostream &operator << (std::ostream &out,
00565 arguments &p);
00566
00567 private:
00569 int n;
00570
00572 int length;
00573
00575 argelement **tab;
00576
00578 void inctable ();
00579
00580 };
00581
00582 inline arguments::arguments ()
00583 {
00584 n = 0;
00585 length = 0;
00586 tab = NULL;
00587 return;
00588 }
00589
00590 inline void arguments::add (argelement *p)
00591 {
00592 inctable ();
00593 tab [n ++] = p;
00594 return;
00595 }
00596
00597
00598
00604 template <class type>
00605 inline void arg (arguments &a, const char *name, type &value)
00606 {
00607 argunit<type> *p = new argunit<type> (name, value);
00608 a. add (p);
00609 return;
00610 }
00611
00615 template <class type>
00616 inline void arg (arguments &a, const char *name, type &value,
00617 type defaultvalue)
00618 {
00619 argunit<type> *p = new argunit<type> (name, value, defaultvalue);
00620 a. add (p);
00621 return;
00622 }
00623
00625 inline void arg (arguments &a, const char *name, char *&value,
00626 const char *defaultvalue)
00627 {
00628 argunit<char *> *p =
00629 new argunit<char *> (name, value,
00630 const_cast<char *> (defaultvalue));
00631 a. add (p);
00632 return;
00633 }
00634
00639 template <class type>
00640 inline void arg (arguments &a, const char *name, type *value,
00641 int &count, int size)
00642 {
00643 argunit<type> *p = new argunit<type> (name, value, count, size);
00644 a. add (p);
00645 return;
00646 }
00647
00649 template <class type>
00650 inline void arg (arguments &a, const char *name, type *value,
00651 int &count, int size, type defaultvalue)
00652 {
00653 argunit<type> *p = new argunit<type> (name, value, count, size,
00654 defaultvalue);
00655 a. add (p);
00656 return;
00657 }
00658
00662 template <class type>
00663 inline void argoblig (arguments &arg, const char *name, type &value)
00664 {
00665 argunit<type> *p = new argunit<type> (name, value);
00666 p -> set (argflags::obligatory);
00667 arg. add (p);
00668 return;
00669 }
00670
00672 template <class type>
00673 inline void argoblig (arguments &arg, const char *name, type &value,
00674 type defaultvalue)
00675 {
00676 argunit<type> *p = new argunit<type> (name, value, defaultvalue);
00677 p -> set (argflags::obligatory);
00678 arg. add (p);
00679 return;
00680 }
00681
00683 inline void argoblig (arguments &arg, const char *name, char *&value,
00684 const char *defaultvalue)
00685 {
00686 argunit<char *> *p =
00687 new argunit<char *> (name, value, (char *) defaultvalue);
00688 p -> set (argflags::obligatory);
00689 arg. add (p);
00690 return;
00691 }
00692
00697 template <class type>
00698 inline void argbreak (arguments &arg, const char *name, type &value)
00699 {
00700 argunit<type> *p = new argunit<type> (name, value);
00701 p -> set (argflags::breakinterpreting);
00702 p -> set (argflags::ignorevalue);
00703 arg. add (p);
00704 return;
00705 }
00706
00708 template <class type>
00709 inline void argbreak (arguments &arg, const char *name, type &value,
00710 type defaultvalue)
00711 {
00712 argunit<type> *p = new argunit<type> (name, value, defaultvalue);
00713 p -> set (argflags::breakinterpreting);
00714 p -> set (argflags::ignorevalue);
00715 arg. add (p);
00716 return;
00717 }
00718
00720 inline void argbreak (arguments &arg, const char *name, char *&value,
00721 const char *defaultvalue)
00722 {
00723 argunit<char *> *p =
00724 new argunit<char *> (name, value, (char *) defaultvalue);
00725 p -> set (argflags::breakinterpreting);
00726 p -> set (argflags::ignorevalue);
00727 arg. add (p);
00728 return;
00729 }
00730
00732 inline void argbreak (arguments &arg, const char *name)
00733 {
00734 char *dummystring = NULL;
00735 argunit<char *> *p = new argunit<char *> (name, dummystring);
00736 p -> set (argflags::breakinterpreting);
00737 p -> set (argflags::ignorevalue);
00738 arg. add (p);
00739 return;
00740 }
00741
00745 template <class type>
00746 inline void argswitch (arguments &arg, const char *name, type &value,
00747 const type &defaultvalue)
00748 {
00749 argunit<type> *p = new argunit<type> (name, value, defaultvalue);
00750 p -> set (argflags::ignorevalue);
00751 arg. add (p);
00752 return;
00753 }
00754
00756 inline void argswitch (arguments &arg, const char *name, char *&value,
00757 const char *defaultvalue)
00758 {
00759 argunit<char *> *p =
00760 new argunit<char *> (name, value, (char *) defaultvalue);
00761 p -> set (argflags::ignorevalue);
00762 arg. add (p);
00763 return;
00764 }
00765
00767 inline void argswitch (arguments &arg, const char *name)
00768 {
00769 char *dummystring = NULL;
00770 argunit<char *> *p = new argunit<char *> (name, dummystring);
00771 p -> set (argflags::ignorevalue);
00772 arg. add (p);
00773 return;
00774 }
00775
00779 inline void arghelp (arguments &a)
00780 {
00781 argbreak (a, "?");
00782 argbreak (a, "h");
00783 argbreak (a, "H");
00784 argbreak (a, "-help");
00785 return;
00786 }
00787
00788
00789
00790 #ifdef OUTPUTSTREAM
00791
00794 inline void argstreams (arguments &a, char *&logfilename, char *&seqfilename,
00795 bool &quiet, bool &debug)
00796 {
00797 arg (a, "-log", logfilename);
00798 arg (a, "-seq", seqfilename);
00799 argswitch (a, "-quiet", quiet, true);
00800 argswitch (a, "-debug", debug, true);
00801 return;
00802 }
00803
00807 inline void setstreams (const char *logfilename, char *seqfilename,
00808 bool quiet, bool debug)
00809 {
00810 if (debug)
00811 sbug. show = true;
00812 if (quiet)
00813 {
00814 sout. show = false;
00815 scon. show = false;
00816 sbug. show = false;
00817 }
00818 if (logfilename)
00819 {
00820 slog. logfile (logfilename);
00821 slog. keepforever ();
00822 sout. logfile (slog);
00823 serr. logfile (slog);
00824 if (debug)
00825 sbug. logfile (slog);
00826 }
00827 if (seqfilename)
00828 sseq. logfile (seqfilename);
00829 #ifdef TIMEUSED
00830 program_time = sout;
00831 #endif
00832 return;
00833 }
00834
00835 #ifndef algstreamprepare
00836
00837
00838
00839 #define argstreamprepare(a) \
00840 char *arg_logfilename = NULL; \
00841 char *arg_seqfilename = NULL; \
00842 char *arg_computername = NULL; \
00843 bool arg_quiet = false; \
00844 bool arg_debug = false; \
00845 arg (a, "-comp", arg_computername); \
00846 argstreams (a, arg_logfilename, arg_seqfilename, arg_quiet, arg_debug);
00847 #endif
00848
00849 #ifndef argstreamset
00850
00851
00852
00853 #define argstreamset() \
00854 setstreams (arg_logfilename, arg_seqfilename, arg_quiet, arg_debug); \
00855 slog << commandline (argc, argv) << "\n\n"; \
00856 if (arg_computername) slog << "Running on " << arg_computername << ". "; \
00857 slog << "Start time: " << currenttime () << '\n';
00858 #endif
00859
00860 #endif
00861
00862
00863
00864 }
00865 }
00866
00867 #endif // _CHOMP_SYSTEM_ARG_H_
00868
00870