Tanl Linguistic Pipeline |
00001 /* 00002 ** IXE C++ Library 00003 ** Common/OptionStream.h 00004 ** ---------------------------------------------------------------------- 00005 ** Copyright (c) 2000 Giuseppe Attardi (attardi@di.unipi.it). 00006 ** ---------------------------------------------------------------------- 00007 ** 00008 ** This file is part of IXE. 00009 ** 00010 ** IXE is free software; you can redistribute it and/or modify it 00011 ** under the terms of the GNU General Public License, version 3, 00012 ** as published by the Free Software Foundation. 00013 ** 00014 ** IXE is distributed in the hope that it will be useful, 00015 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 ** GNU General Public License for more details. 00018 ** 00019 ** You should have received a copy of the GNU General Public License 00020 ** along with this program. If not, see <http://www.gnu.org/licenses/>. 00021 ** ---------------------------------------------------------------------- 00022 */ 00023 00024 #ifndef IXE_OptionStream_H 00025 #define IXE_OptionStream_H 00026 00027 // Settings 00028 #include "platform.h" 00029 00030 // standard 00031 #include <iostream> 00032 00033 namespace IXE { 00034 00035 using namespace std; 00036 00041 struct Options 00042 { 00043 enum { 00044 no_arg = 0, 00045 req_arg = 1, 00046 opt_arg = 2 00047 }; 00048 00049 struct spec { 00050 // 00051 // A spec gives a specification for an option: its long name, 00052 // its argument type, and it's short option equivalent. A 00053 // null-terminated array of specs is given to the OptionStream 00054 // constructor. 00055 // 00056 // The arg_type takes on one of the above enum values, but is 00057 // not declared as an enum to allow the integer values to be 00058 // used as a shorthand. 00059 // 00060 // Regardless of whether the user enters a long or a short 00061 // option, it is the short option character that is returned to 00062 // the caller in order to be able to use a simple switch 00063 // statement to do different things depending on the option. 00064 // 00065 // If, for a given long option there is to be no short option 00066 // equivalent, then the caller has to make up bogus ones that 00067 // the user will never type. Either the ASCII control or high 00068 // characters can be user for this. The null character may not 00069 // be used. 00070 // 00071 00072 char const* long_name; 00073 short arg_type; 00074 unsigned char c; 00075 char const* use_msg; 00076 }; 00077 00078 static ostream& usage(spec const options[], ostream& err); 00079 }; 00080 00091 class OptionStream 00092 { 00093 public: 00094 OptionStream(int argc, char* argv[], Options::spec const[], 00095 std::ostream& = std::cerr); 00096 00097 int shift() const { return index; } 00098 operator bool() const { return !end; } 00099 00100 class Option { 00101 // 00102 // An option is what is extracted from an OptionStream. Its 00103 // operator char() gives which option it is and arg() gives its 00104 // argument, if any. For options that do not have an argument, 00105 // arg() returns the null pointer. 00106 // 00107 // An option may be copied in which case it has a private copy 00108 // of its argument. 00109 // 00110 public: 00111 Option(char c = '\0', char* a = 0) : 00112 c(c), _arg(a), am_copy(false) { } 00113 Option(Option const& o) { 00114 if (&o != this) copy(o); 00115 } 00116 ~Option() { 00117 if (am_copy) delete[] _arg; 00118 } 00119 Option& operator =(Option const &o) { 00120 if (&o != this) { 00121 if (am_copy) delete[] _arg; 00122 copy(o); 00123 } 00124 return *this; 00125 } 00126 00127 char* arg() const { return _arg; } 00128 operator char() const { return c; } 00129 00130 friend OptionStream& operator >>(OptionStream&, Option&); 00131 private: 00132 char c; 00133 char* _arg; 00134 bool am_copy; 00135 void copy(Option const&); 00136 }; 00137 00138 friend OptionStream& operator >>(OptionStream&, Option&); 00139 private: 00140 int argc; 00141 char** argv; 00142 Options::spec const* specs; 00143 std::ostream& err; 00144 int index; 00145 char* next_c; 00146 bool end; 00147 }; 00148 00149 } // namespace IXE 00150 00151 #endif /* IXE_OptionStream_H */