00001
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <string.h>
00015 #include <ctype.h>
00016
00017 #include "CTB.hxx"
00018 #include "CTB_Trace.hxx"
00019 #include "CTBargv.hxx"
00020
00029
00031
00032 CTBargv::CTBargv()
00033 : mi_argc(0),
00034 mc_args(0),
00035 m_argv(0),
00036 mi_curarg(-1)
00037 {
00038 CTB_Trace("CTBargv()");
00039 }
00040
00041
00043
00044 CTBargv::CTBargv(int argc, char* argv[])
00045 : mi_argc(argc),
00046 mc_args(0),
00047 m_argv(0),
00048 mi_curarg(-1)
00049 {
00050 CTB_Trace("CTBargv(int,char*[])");
00051 int i_totlen = 0;
00052 char* c_cur;
00053
00054 if (argc <= 0) return;
00055
00056 m_argv = new argdsc[argc];
00057
00058 for (int i = 0; i < argc; i++) {
00059 int i_nchar = strlen(argv[i]);
00060 m_argv[i].mi_nchar = i_nchar;
00061 i_totlen += 1 + i_nchar;
00062 }
00063
00064 mc_args = new char[i_totlen];
00065
00066 c_cur = mc_args;
00067 for (int i = 0; i < argc; i++) {
00068 m_argv[i].mc_arg = c_cur;
00069 strcpy(c_cur,argv[i]);
00070 c_cur += 1 + m_argv[i].mi_nchar;
00071 }
00072
00073 m_argv[0].mb_used = true;
00074 }
00075
00076
00078
00079 CTBargv::~CTBargv()
00080 {
00081 CTB_Trace("~CTBargv()");
00082
00083 delete mc_args;
00084 delete [] m_argv;
00085 }
00086
00087
00089
00094 bool CTBargv::Locate(const char* c_opt, int i_npar)
00095 {
00096 CTB_Trace("CTBargv::Locate(const char*,int)");
00097
00098 mi_curarg = -1;
00099
00100 for (int i = 1; i < mi_argc; i++) {
00101 if (!m_argv[i].mb_used && strcmp(c_opt,m_argv[i].mc_arg) == 0) {
00102 m_argv[i].mb_used = true;
00103 mi_curarg = i;
00104 break;
00105 }
00106 }
00107
00108 if (mi_curarg >= 0) {
00109 int i_lastarg = mi_curarg + i_npar;
00110 bool b_error_npar = false;
00111
00112 if (i_lastarg >= mi_argc) {
00113 b_error_npar = true;
00114 i_lastarg = mi_argc - 1;
00115 }
00116
00117 for (int i = mi_curarg+1; i <= i_lastarg; i++) {
00118 if (m_argv[i].mb_used) b_error_npar = true;
00119 }
00120
00121 if (b_error_npar) {
00122 for (int i = mi_curarg; i <= i_lastarg; i++) {
00123 m_argv[i].mb_used = true;
00124 m_argv[i].mi_errorflags = mi_error_npar;
00125 }
00126 mi_curarg = -1;
00127 }
00128 }
00129
00130
00131 return mi_curarg >= 0;
00132 }
00133
00134
00136
00137 const char* CTBargv::NextArg()
00138 {
00139 CTB_Trace("CTBargv::NextArg()");
00140
00141 if (mi_curarg < 0 || mi_curarg >= mi_argc-1) {
00142 mi_curarg = -1;
00143 return 0;
00144 }
00145
00146 mi_curarg += 1;
00147 m_argv[mi_curarg].mb_used = true;
00148 return m_argv[mi_curarg].mc_arg;
00149 }
00150
00151
00153
00154 void CTBargv::CheckUnused()
00155 {
00156 CTB_Trace("CTBargv::CheckUnused()");
00157
00158 for (int i = 0; i < mi_argc; i++) {
00159 if (!m_argv[i].mb_used) {
00160 m_argv[i].mb_used = true;
00161 m_argv[i].mi_errorflags = mi_error_unused;
00162 }
00163 }
00164 return;
00165 }
00166
00167
00168
00170
00171 bool CTBargv::CheckErrors()
00172 {
00173 CTB_Trace("CTBargv::CheckErrors()");
00174
00175 for (int i = 0; i < mi_argc; i++) {
00176 if (m_argv[i].mi_errorflags != 0) return true;
00177 }
00178 return false;
00179 }
00180
00181
00183
00184 bool CTBargv::CheckErrors(ostream& os)
00185 {
00186 CTB_Trace("CTBargv::CheckErrors(ostream&)");
00187
00188 if (!CheckErrors()) return false;
00189 for (int i = 0; i < mi_argc; i++) {
00190 int i_errorflags = m_argv[i].mi_errorflags;
00191 if ((i_errorflags & mi_error_unused) != 0) {
00192 os << "%CTBargv-E unused argument \"" <<
00193 m_argv[i].mc_arg << "\"" << endl;
00194 }
00195 if ((i_errorflags & mi_error_conv) != 0) {
00196 os << "%CTBargv-E conversion error in \"" <<
00197 m_argv[i].mc_arg << "\"" << endl;
00198 }
00199 if ((i_errorflags & mi_error_npar) != 0) {
00200 os << "%CTBargv-E insufficient option arguments for \"" <<
00201 m_argv[i].mc_arg << "\"" << endl;
00202 }
00203 }
00204 return true;
00205 }
00206
00207
00209
00210 void CTBargv::SetupStream(istrstream& istr)
00211 {
00212 CTB_Trace("CTBargv::SetupStrea(istrstream&)");
00213
00214 istr.clear();
00215 return;
00216 }
00217
00218
00220
00221 void CTBargv::CheckStream(istrstream& istr)
00222 {
00223 CTB_Trace("CTBargv::CheckStream(istrstream&)");
00224
00225 bool b_nonwhite = false;
00226 int i_ncharleft = 0;
00227 char c;
00228
00229 istr.clear();
00230
00231 while(istr.get(c)) {
00232 i_ncharleft += 1;
00233 if (!isspace(c)) b_nonwhite = true;
00234 }
00235
00236 if (b_nonwhite && mi_curarg >= 0) {
00237 m_argv[mi_curarg].mi_errorflags = mi_error_conv;
00238 m_argv[mi_curarg].mi_ncharleft = i_ncharleft;
00239 }
00240
00241 return;
00242 }
00243
00244
00246
00247 void CTBargv::ToStream(ostream& os) const
00248 {
00249 CTB_Trace("CTBargv::ToStream(ostream&)");
00250
00251 os << "Number of arguments: " << mi_argc << endl;
00252 for (int i = 0; i < mi_argc; i++){
00253 os << setw(3) << i << ": ";
00254 os << ((!m_argv[i].mb_used) ? "u" : " ");
00255 os << ((m_argv[i].mi_errorflags) ? "e" : " ");
00256 os << " \"";
00257 os << m_argv[i].mc_arg;
00258 os << "\"";
00259 if (m_argv[i].mi_errorflags) {
00260 int i_ncharleft = m_argv[i].mi_ncharleft;
00261 int i_nchar = m_argv[i].mi_nchar;
00262 if (i_ncharleft > 0 && i_ncharleft <= i_nchar) {
00263 os << endl;
00264 os << " ";
00265 for (int iz = 0; iz < i_nchar-i_ncharleft; iz++) os << " ";
00266 os << "^";
00267 }
00268 }
00269
00270 os << endl;
00271 }
00272 return;
00273 }
00274
00275
00276 CTBargv::argdsc::argdsc()
00277 : mc_arg(0),
00278 mi_nchar(0),
00279 mi_ncharleft(0),
00280 mb_used(false),
00281 mi_errorflags(0)
00282 {}
00283
00284
00285
00286 #if (defined(CTB__OutLine) || defined(CTBargv__OutLine))
00287 #define inline
00288 #include "CTBargv.icc"
00289 #undef inline
00290 #endif