CommandParser.cc

00001 // ----------------------------------------------------------------------^
00002 // Copyright (C) 2004, 2005, 2006, 2007, 2008 Giorgio Calderone
00003 // (mailto: <gcalderone@ifc.inaf.it>)
00004 // 
00005 // This file is part of MCS.
00006 // 
00007 // MCS is free software; you can redistribute it and/or modify
00008 // it under the terms of the GNU General Public License as published by
00009 // the Free Software Foundation; either version 2 of the License, or
00010 // (at your option) any later version.
00011 // 
00012 // MCS is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 // 
00017 // You should have received a copy of the GNU General Public License
00018 // along with MCS; if not, write to the Free Software
00019 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 // 
00021 // ----------------------------------------------------------------------$
00022 
00023 #include "mcs.hh"
00024 using namespace mcs;
00025 
00026 
00027 //--------------------------------------------------------
00028 mcs::CommandParser::CommandParser()
00029 {
00030     MCS_DEBUG_SETUP(0, "CommandParser");
00031 
00032     int i;
00033     for (i=0; i<MCS_CMD_MAX_TOKENS; i++) {
00034     md_args[i] = NULL;
00035     md_optargs[i] = NULL;
00036     }
00037 }
00038 
00039 mcs::CommandParser::~CommandParser()
00040 {
00041     clearArgs();
00042     MCS_DEBUG_LEAVE(NOARGS);
00043 }
00044 
00045 
00046 string mcs::CommandParser::clean(string c)
00047 {
00048 
00049     c = subst(c, "\t+|\n+|\r+", " ");
00050     c = subst(c, ";.*", "", MCS_SUBST_TRAILING);
00051     c = trim(c);
00052     return c;
00053 }
00054 
00055 void mcs::CommandParser::clearArgs()
00056 {
00057     MCS_DEBUG_ENTER(NOARGS);
00058     int i;
00059     for (i=0; i<MCS_CMD_MAX_TOKENS; i++) {
00060     if (md_args[i]) delete md_args[i];
00061     if (md_optargs[i]) delete md_optargs[i];
00062     md_args[i] = NULL;
00063     md_optargs[i] = NULL;
00064     }
00065     args.clear();
00066     opts.clear();
00067     optargs.clear();
00068     tokens.clear();
00069     rest.clear();
00070     MCS_DEBUG_LEAVE(NOARGS);
00071 }
00072 
00073 
00074 string mcs::CommandParser::cline()
00075 {
00076     return origcmdline;
00077 }
00078 
00079 
00080 string mcs::CommandParser::cmd()
00081 {
00082     return lcmd;
00083 }
00084 
00085 string mcs::CommandParser::allargs()
00086 {
00087     unsigned int i;
00088     string s;
00089     for (i=0; i<args.size(); i++) {
00090     if (i > 0) s+= " ";
00091     s += args[i];
00092     }
00093     return s;
00094 }
00095 
00096 int mcs::CommandParser::argc()
00097 {
00098     return args.size();
00099 }
00100 
00101 
00102 int mcs::CommandParser::tokenc()
00103 {
00104     return tokens.size();
00105 }
00106 
00107 
00108 string mcs::CommandParser::token(int i)
00109 {
00110     unsigned int ui = i;
00111 
00112     if (i < 0)
00113     throw MCS_ERROR(MSG_INDEX_LT_ZERO, i);
00114 
00115     if (ui >= tokens.size())
00116     throw MCS_ERROR(MSG_INDEX_OUT_RANGE, ui, tokens.size());
00117 
00118     return tokens[ui];
00119 }
00120 
00121 
00122 string mcs::CommandParser::line_afterToken(int i)
00123 {
00124     unsigned int ui = i;
00125 
00126     if (i < 0)
00127     throw MCS_ERROR(MSG_INDEX_LT_ZERO, i);
00128 
00129     if (ui >= rest.size())
00130     throw MCS_ERROR(MSG_INDEX_OUT_RANGE, ui, rest.size());
00131 
00132     return rest[ui];
00133 }
00134 
00135 
00136 Data& mcs::CommandParser::arg(int i)
00137 {
00138     unsigned int ui = i;
00139 
00140     if (i < 0)
00141     throw MCS_ERROR(MSG_INDEX_LT_ZERO, i);
00142 
00143     if (ui >= args.size())
00144     throw MCS_ERROR(MSG_INDEX_OUT_RANGE, ui, args.size());
00145 
00146     return *md_args[ui];
00147 }
00148 
00149 
00150 string mcs::CommandParser::sarg(int i)
00151 {
00152     return arg(i).sval();
00153 }
00154 
00155 
00156 string mcs::CommandParser::opt(int i)
00157 {
00158     unsigned int ui = i;
00159 
00160     if (i < 0)
00161     throw MCS_ERROR(MSG_INDEX_LT_ZERO, i);
00162 
00163     if (ui >= opts.size())
00164     throw MCS_ERROR(MSG_INDEX_OUT_RANGE, ui, opts.size());
00165 
00166     return opts[ui];
00167 }
00168 
00169 
00170 int mcs::CommandParser::optc()
00171 {
00172     return opts.size();
00173 }
00174 
00175 
00176 Data& mcs::CommandParser::optarg(int i)
00177 {
00178     unsigned int ui = i;
00179 
00180     if (i < 0)
00181     throw MCS_ERROR(MSG_INDEX_LT_ZERO, i);
00182 
00183     if (ui >= opts.size())
00184     throw MCS_ERROR(MSG_INDEX_OUT_RANGE, ui, opts.size());
00185 
00186     return *md_optargs[ui];
00187 }
00188 
00189 
00190 bool mcs::CommandParser::cmpCmd(string cmd)
00191 {
00192     cmd = clean(cmd);
00193     if (cmd.length() != lcmd.length())
00194       return false;
00195     else
00196       return (! strncasecmp(cmd.c_str(),
00197                 lcmd.c_str(),
00198                 lcmd.length()));
00199 }
00200 
00201 
00202 bool mcs::CommandParser::givenOpt(string opt, int& i)
00203 {
00204     unsigned int ui;
00205 
00206     opt = clean(opt);
00207     for (ui=0; ui< opts.size(); ui++)
00208     if (opts[ui] == opt) {
00209         i = ui;
00210         return true;
00211     }
00212     return false;
00213 }
00214 
00215 bool mcs::CommandParser::givenOpt(string opt)
00216 {
00217     int i;
00218     return givenOpt(opt, i);
00219 }
00220 
00221 
00222 void mcs::CommandParser::parseCmd(int argc, char* argv[])
00223 {
00224   string cmd;
00225   int i;
00226 
00227   for (i=0; i<argc; i++)
00228     cmd += argv[i] + string(" ");
00229 
00230   parseCmd(cmd);
00231 }
00232 
00233 void mcs::CommandParser::parseCmd(string c)
00234 {
00235   unsigned int ui;
00236   string opt, s;
00237   vector<string> lpar;
00238   const char* p;
00239   bool quoted = false;
00240   bool escape = false;
00241 
00242   clearArgs();
00243   origcmdline = clean(c);
00244   c = origcmdline;
00245   lcmd = "";
00246 
00247   p = c.c_str();
00248   s = "";
00249   while (*p) {
00250       if ((! escape)   &&   (*p == '\\'))
00251       escape = true;
00252       else {
00253       if ((! escape)   &&   (*p == '"'))
00254           quoted = ! quoted;
00255       else if ((! quoted)   &&   (*p == ' ')) {
00256           s = trim(s);
00257           if (! s.empty()) {
00258           args.push_back(s);
00259           tokens.push_back(s);
00260           rest.push_back(string(p));
00261           }
00262           s = "";
00263       }
00264       else
00265           s += *p;
00266 
00267       escape = false;
00268       }
00269       p++;
00270   }
00271   s = trim(s);
00272   if (! s.empty()) {
00273       args.push_back(s);
00274       tokens.push_back(s);
00275       rest.push_back("");
00276   }
00277 
00278   if (args.size() >= 1) {
00279       lcmd = args[0];
00280       args.erase(args.begin());
00281   }
00282 
00283   pcrecpp::RE reopt("^-(\\w+)");
00284   pcrecpp::RE reoptwarg("^-(\\w+)=(.+)");
00285   ui = 0;
00286   while (ui < args.size()) {
00287       s = "";
00288       if (reopt.FullMatch(args[ui], &opt)          ||
00289       reoptwarg.FullMatch(args[ui], &opt, &s) )  {
00290       opts.push_back(opt);
00291       optargs.push_back(s);
00292       md_optargs[opts.size()-1] = new Data(s);
00293       args.erase(args.begin() + ui);
00294       }
00295       else {
00296       md_args[ui] = new Data(args[ui]);
00297       ui++;
00298       }
00299   }
00300 
00301   /* //DEBUG
00302   int i;
00303   cout << endl << __LINE__ << " " << cmd() << "|" << endl << endl;
00304   cout << "Arguments: " << argc() << endl;
00305   for (i=0; i<argc(); i++)
00306       cout << i << " " << arg(i).sval() << "|" << endl;
00307 
00308   cout << endl << "Options: " << optc() << endl;
00309   for (i=0; i<optc(); i++)
00310       cout << i << " "
00311        << this->opt(i) << " "
00312        << optarg(i).sval() << "|" << endl;
00313   */
00314 }
00315 
00316 
00317 
00318 vector<string> mcs::CommandParser::replPars_onFile(string fn)
00319 {
00320     vector<string> v;
00321     ifstream fin;
00322     string s, line;
00323 
00324     fin.open(fn.csz);
00325     if (!(fin.is_open()))
00326     throw MCS_ERROR(MSG_CANT_OPEN_FILE, fn.csz);
00327     else {
00328     line = "";
00329     while(getline(fin, s)) {
00330         s = replPars(s);
00331         if (! s.empty()) {
00332         if (! line.empty()) line += " " ;
00333         line += s;
00334         if (s[s.length()-1] == ';') {  //the line is complete
00335             line = line.substr(0, line.length()-1); //removes ";"
00336             v.push_back(trim(line));
00337             line = "";
00338         }
00339         }
00340     }
00341     }
00342 
00343     fin.close();
00344     return v;
00345 }
00346 
00347 //Used to parse external script
00348 //Must be used one line at a time
00349 string mcs::CommandParser::replPars(string s)
00350 {
00351   char expr[10];
00352   unsigned int i;
00353   string r;
00354 
00355   s = trim(s);
00356   if (! s.empty()) {
00357       s = subst(s, "\n+"   , "", MCS_SUBST_TRAILING);  //Trailing newlines
00358       s = subst(s, "#.*$"  , "" );                 //Comments   --> null
00359       s = subst(s, "\t+"   , " ");                 //tabs       --> space
00360       s = subst(s, ";\\s*$", ";");                 //";" spaces --> ";"
00361 
00362       if (! s.empty()) {
00363       for (i=0; i<args.size(); i++) {   //Arguments
00364           sprintf(expr, "\\$%d", i);
00365           r = md_args[i]->sval();
00366           s = subst(s, expr, r, MCS_SUBST_QUOTE_WITH);
00367       }
00368       s = trim(s);
00369       }
00370   }
00371 
00372   return s;
00373 }

mcslogo

MCS (My Customizable Server) ver. 0.3.3-alpha3
Documentation generated on Thu Mar 22 13:22:23 UTC 2012