MCS  0.3.3-alpha7
CommandParser.cc
1 // ----------------------------------------------------------------------^
2 // Copyright (C) 2004, 2005, 2006, 2007, 2008 Giorgio Calderone
3 // (mailto: <gcalderone@ifc.inaf.it>)
4 //
5 // This file is part of MCS.
6 //
7 // MCS is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // MCS is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with MCS; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 //
21 // ----------------------------------------------------------------------$
22 
23 #include "mcs.hh"
24 using namespace mcs;
25 
26 
27 //--------------------------------------------------------
29 {
30  MCS_DEBUG_SETUP(0, "CommandParser");
31 
32  int i;
33  for (i=0; i<MCS_CMD_MAX_TOKENS; i++) {
34  md_args[i] = NULL;
35  md_optargs[i] = NULL;
36  }
37 }
38 
40 {
41  clearArgs();
42  MCS_DEBUG_LEAVE(NOARGS);
43 }
44 
45 
46 string mcs::CommandParser::clean(string c)
47 {
48 
49  c = subst(c, "\t+|\n+|\r+", " ");
50  c = subst(c, ";.*", "", MCS_SUBST_TRAILING);
51  c = trim(c);
52  return c;
53 }
54 
56 {
57  MCS_DEBUG_ENTER(NOARGS);
58  int i;
59  for (i=0; i<MCS_CMD_MAX_TOKENS; i++) {
60  if (md_args[i]) delete md_args[i];
61  if (md_optargs[i]) delete md_optargs[i];
62  md_args[i] = NULL;
63  md_optargs[i] = NULL;
64  }
65  args.clear();
66  opts.clear();
67  optargs.clear();
68  tokens.clear();
69  rest.clear();
70  MCS_DEBUG_LEAVE(NOARGS);
71 }
72 
73 
75 {
76  return origcmdline;
77 }
78 
79 
81 {
82  return lcmd;
83 }
84 
86 {
87  unsigned int i;
88  string s;
89  for (i=0; i<args.size(); i++) {
90  if (i > 0) s+= " ";
91  s += args[i];
92  }
93  return s;
94 }
95 
97 {
98  return args.size();
99 }
100 
101 
103 {
104  return tokens.size();
105 }
106 
107 
109 {
110  unsigned int ui = i;
111 
112  if (i < 0)
113  throw MCS_ERROR(MSG_INDEX_LT_ZERO, i);
114 
115  if (ui >= tokens.size())
116  throw MCS_ERROR(MSG_INDEX_OUT_RANGE, ui, tokens.size());
117 
118  return tokens[ui];
119 }
120 
121 
123 {
124  unsigned int ui = i;
125 
126  if (i < 0)
127  throw MCS_ERROR(MSG_INDEX_LT_ZERO, i);
128 
129  if (ui >= rest.size())
130  throw MCS_ERROR(MSG_INDEX_OUT_RANGE, ui, rest.size());
131 
132  return rest[ui];
133 }
134 
135 
137 {
138  unsigned int ui = i;
139 
140  if (i < 0)
141  throw MCS_ERROR(MSG_INDEX_LT_ZERO, i);
142 
143  if (ui >= args.size())
144  throw MCS_ERROR(MSG_INDEX_OUT_RANGE, ui, args.size());
145 
146  return *md_args[ui];
147 }
148 
149 
151 {
152  return arg(i).sval();
153 }
154 
155 
157 {
158  unsigned int ui = i;
159 
160  if (i < 0)
161  throw MCS_ERROR(MSG_INDEX_LT_ZERO, i);
162 
163  if (ui >= opts.size())
164  throw MCS_ERROR(MSG_INDEX_OUT_RANGE, ui, opts.size());
165 
166  return opts[ui];
167 }
168 
169 
171 {
172  return opts.size();
173 }
174 
175 
177 {
178  unsigned int ui = i;
179 
180  if (i < 0)
181  throw MCS_ERROR(MSG_INDEX_LT_ZERO, i);
182 
183  if (ui >= opts.size())
184  throw MCS_ERROR(MSG_INDEX_OUT_RANGE, ui, opts.size());
185 
186  return *md_optargs[ui];
187 }
188 
189 
191 {
192  cmd = clean(cmd);
193  if (cmd.length() != lcmd.length())
194  return false;
195  else
196  return (! strncasecmp(cmd.c_str(),
197  lcmd.c_str(),
198  lcmd.length()));
199 }
200 
201 
202 bool mcs::CommandParser::givenOpt(string opt, int& i)
203 {
204  unsigned int ui;
205 
206  opt = clean(opt);
207  for (ui=0; ui< opts.size(); ui++)
208  if (opts[ui] == opt) {
209  i = ui;
210  return true;
211  }
212  return false;
213 }
214 
216 {
217  int i;
218  return givenOpt(opt, i);
219 }
220 
221 
222 void mcs::CommandParser::parseCmd(int argc, char* argv[])
223 {
224  string cmd;
225  int i;
226 
227  for (i=0; i<argc; i++)
228  cmd += argv[i] + string(" ");
229 
230  parseCmd(cmd);
231 }
232 
234 {
235  unsigned int ui;
236  string opt, s;
237  vector<string> lpar;
238  const char* p;
239  bool quoted = false;
240  bool escape = false;
241 
242  clearArgs();
243  origcmdline = clean(c);
244  c = origcmdline;
245  lcmd = "";
246 
247  p = c.c_str();
248  s = "";
249  while (*p) {
250  if ((! escape) && (*p == '\\'))
251  escape = true;
252  else {
253  if ((! escape) && (*p == '"'))
254  quoted = ! quoted;
255  else if ((! quoted) && (*p == ' ')) {
256  s = trim(s);
257  if (! s.empty()) {
258  args.push_back(s);
259  tokens.push_back(s);
260  rest.push_back(string(p));
261  }
262  s = "";
263  }
264  else
265  s += *p;
266 
267  escape = false;
268  }
269  p++;
270  }
271  s = trim(s);
272  if (! s.empty()) {
273  args.push_back(s);
274  tokens.push_back(s);
275  rest.push_back("");
276  }
277 
278  if (args.size() >= 1) {
279  lcmd = args[0];
280  args.erase(args.begin());
281  }
282 
283  pcrecpp::RE reopt("^-(\\w+)");
284  pcrecpp::RE reoptwarg("^-(\\w+)=(.+)");
285  ui = 0;
286  while (ui < args.size()) {
287  s = "";
288  if (reopt.FullMatch(args[ui], &opt) ||
289  reoptwarg.FullMatch(args[ui], &opt, &s) ) {
290  opts.push_back(opt);
291  optargs.push_back(s);
292  md_optargs[opts.size()-1] = new Data(s);
293  args.erase(args.begin() + ui);
294  }
295  else {
296  md_args[ui] = new Data(args[ui]);
297  ui++;
298  }
299  }
300 
301  /* //DEBUG
302  int i;
303  cout << endl << __LINE__ << " " << cmd() << "|" << endl << endl;
304  cout << "Arguments: " << argc() << endl;
305  for (i=0; i<argc(); i++)
306  cout << i << " " << arg(i).sval() << "|" << endl;
307 
308  cout << endl << "Options: " << optc() << endl;
309  for (i=0; i<optc(); i++)
310  cout << i << " "
311  << this->opt(i) << " "
312  << optarg(i).sval() << "|" << endl;
313  */
314 }
315 
316 
317 
318 vector<string> mcs::CommandParser::replPars_onFile(string fn)
319 {
320  vector<string> v;
321  ifstream fin;
322  string s, line;
323 
324  fin.open(fn.csz);
325  if (!(fin.is_open()))
326  throw MCS_ERROR(MSG_CANT_OPEN_FILE, fn.csz);
327  else {
328  line = "";
329  while(getline(fin, s)) {
330  s = replPars(s);
331  if (! s.empty()) {
332  if (! line.empty()) line += " " ;
333  line += s;
334  if (s[s.length()-1] == ';') { //the line is complete
335  line = line.substr(0, line.length()-1); //removes ";"
336  v.push_back(trim(line));
337  line = "";
338  }
339  }
340  }
341  }
342 
343  fin.close();
344  return v;
345 }
346 
347 //Used to parse external script
348 //Must be used one line at a time
350 {
351  char expr[10];
352  unsigned int i;
353  string r;
354 
355  s = trim(s);
356  if (! s.empty()) {
357  s = subst(s, "\n+" , "", MCS_SUBST_TRAILING); //Trailing newlines
358  s = subst(s, "#.*$" , "" ); //Comments --> null
359  s = subst(s, "\t+" , " "); //tabs --> space
360  s = subst(s, ";\\s*$", ";"); //";" spaces --> ";"
361 
362  if (! s.empty()) {
363  for (i=0; i<args.size(); i++) { //Arguments
364  sprintf(expr, "\\$%d", i);
365  r = md_args[i]->sval();
366  s = subst(s, expr, r, MCS_SUBST_QUOTE_WITH);
367  }
368  s = trim(s);
369  }
370  }
371 
372  return s;
373 }
string opt(int i)
Return option at i-th position.
int optc()
Return number of options.
string cline()
Returns the entire command line.
string sarg(int i)
Return argument at i-th position as a string, see arg(int).
string allargs()
Returns all arguments (not tokens!) as a string.
#define MCS_CMD_MAX_TOKENS
Max number of tokens for a command line.
Definition: mcs.hh:5117
void parseCmd(string c)
Parse a command line into tokens, arguments and options.
vector< string > replPars_onFile(string fn)
Parse a MCS script.
Data & optarg(int i)
Return argument to option at i-th position.
#define MCS_SUBST_TRAILING
To be used with subst(), substitute only if "what" is at the end. See subst().
Definition: mcs.hh:505
CommandParser()
Constructor.
string line_afterToken(int i)
Return the "rest" relative to token at i-th position.
#define MCS_ERROR(A, rest...)
Facility to easily pass all necessary parameter to an Event constructor.
Definition: mcs.hh:964
~CommandParser()
Destructor, this destroy all Data objects containing arguments.
int argc()
Return number of arguments.
static string clean(string c)
Cleans a string.
bool givenOpt(string opt)
Check if a certain option has been given.
Main include file for all MCS based applications.
bool cmpCmd(string cmd)
Check if the string in the parameter is the same as the command (case insensitive).
A general purpose data type.
Definition: mcs.hh:3092
string subst(string s, string what, string with, int op=0)
Perform substitutions on a string.
Definition: Utils.cc:135
string trim(string s)
Remove any leading or trailing blanks.
Definition: Utils.cc:160
string cmd()
Returns the first token, that is the command.
string token(int i)
Return token at i-th position.
Data & arg(int i)
Return argument at i-th position.
string replPars(string str)
Perform parameter substitutions.
int tokenc()
Return number of tokens.
#define MCS_SUBST_QUOTE_WITH
To be used with subst(), doubles each backslash in "with". See subst().
Definition: mcs.hh:499
Namespace for MCS library.
void clearArgs()
Destroy all Data objects containing arguments.

mcslogo

MCS (My Customizable Server) ver. 0.3.3-alpha7
Documentation generated on Mon May 28 07:39:41 UTC 2018