Command.cpp
Go to the documentation of this file.
1 #include <swarmio/tool/Command.h>
2 #include <swarmio/Exception.h>
3 #include <regex>
4 
5 using namespace swarmio;
6 using namespace swarmio::tool;
7 
8 void Command::HighlighterCallback(const std::string& input, replxx::Replxx::colors_t& colors, void* unused)
9 {
10  // Workaround for a known bug with UTF-8 special characters
11  colors.resize(input.size());
12 
13  // Verbs are MAGENTA, so we start with that
14  size_t location = 0;
15  auto currentColor = replxx::Replxx::Color::BRIGHTMAGENTA;
16 
17  // Skip whitespace
18  for (; location < input.size() && input[location] == ' '; ++location)
19  {
20  colors[location] = replxx::Replxx::Color::DEFAULT;
21  }
22 
23  // Process verb
24  for (; location < input.size(); ++location)
25  {
26  if (input[location] != ' ')
27  {
28  colors[location] = replxx::Replxx::Color::BRIGHTMAGENTA;
29  }
30  else
31  {
32  break;
33  }
34  }
35 
36  // Process the rest of the components
37  bool first = true;
38  while (location < input.size())
39  {
40  // Look ahead
41  size_t nextSpace = input.find(' ', location);
42  size_t nextAssignment = input.find('=', location);
43  if (nextSpace == location)
44  {
45  // Skip leading space
46  colors[location] = replxx::Replxx::Color::DEFAULT;
47  ++location;
48  }
49  else
50  {
51  // Determine color
52  auto color = replxx::Replxx::Color::WHITE;
53  if (nextAssignment == location)
54  {
55  // Error, starts with =
56  color = replxx::Replxx::Color::BRIGHTRED;
57  }
58  else
59  {
60  if (nextAssignment == std::string::npos)
61  {
62  if (first)
63  {
64  // Path
65  color = replxx::Replxx::Color::BRIGHTCYAN;
66  }
67  else
68  {
69  // Error, invalid location for path
70  color = replxx::Replxx::Color::BRIGHTRED;
71  }
72  }
73  else
74  {
75  // Parameter
76  if (nextAssignment < nextSpace || nextSpace == std::string::npos)
77  {
78  color = replxx::Replxx::Color::WHITE;
79  }
80  else
81  {
82  if (first)
83  {
84  // Path
85  color = replxx::Replxx::Color::BRIGHTCYAN;
86  }
87  else
88  {
89  // Error, invalid location for path
90  color = replxx::Replxx::Color::BRIGHTRED;
91  }
92  }
93  }
94  }
95 
96  // Apply color
97  for (; location < input.size() && input[location] != ' '; ++location)
98  {
99  colors[location] = color;
100  }
101 
102  // Mark as not first
103  first = false;
104  }
105  }
106 }
107 
109 {
110  for (;;)
111  {
112  size_t location = input.find(' ');
113  if (input.empty())
114  {
115  throw Exception("Syntax error: empty command");
116  }
117  else if (location == std::string::npos)
118  {
119  // Verb only command
120  return Command(input);
121  }
122  else if (location == 0)
123  {
124  // Remove leading space
125  input = input.substr(1);
126 
127  // Start over
128  continue;
129  }
130  else
131  {
132  // Create command with verb
133  Command command(input.substr(0, location));
134 
135  // Strip verb
136  input = input.substr(location + 1);
137 
138  // Process the rest
139  bool first = true;
140  while (!input.empty())
141  {
142  // Find next space and assignment operator
143  size_t nextSpace = input.find(' ');
144  size_t nextAssignment = input.find('=');
145 
146  // Determine type of parameter
147  if (nextSpace == 0)
148  {
149  // Skip extra space
150  input = input.substr(1);
151  }
152  else if (nextAssignment == 0)
153  {
154  throw Exception("Syntax error: empty key for parameter");
155  }
156  else if (nextSpace == std::string::npos)
157  {
158  if (nextAssignment == std::string::npos)
159  {
160  // Parse as path
161  if (first)
162  {
163  command._path = input;
164  }
165  else
166  {
167  throw Exception("Syntax error: stray name or path");
168  }
169  }
170  else
171  {
172  // Parse as parameter
173  std::string key = input.substr(0, nextAssignment);
174  if (command._parameters.find(key) == command._parameters.end())
175  {
176  command._parameters[key] = input.substr(nextAssignment + 1);
177  }
178  else
179  {
180  throw Exception("Syntax error: duplicate parameter");
181  }
182  }
183 
184  // No more
185  break;
186  }
187  else
188  {
189  if (nextAssignment > nextSpace)
190  {
191  // Parse as path
192  if (first)
193  {
194  command._path = input.substr(0, nextSpace);
195  }
196  else
197  {
198  throw Exception("Syntax error: stray name or path");
199  }
200  }
201  else
202  {
203  // Parse as parameter
204  std::string key = input.substr(0, nextAssignment);
205  if (command._parameters.find(key) == command._parameters.end())
206  {
207  command._parameters[key] = input.substr(nextAssignment + 1, nextSpace - nextAssignment - 1);
208  }
209  else
210  {
211  throw Exception("Syntax error: duplicate parameter");
212  }
213  }
214 
215  // Strip component
216  input = input.substr(nextSpace + 1);
217 
218  // Mark as not first
219  first = false;
220  }
221  }
222 
223  // Return command
224  return command;
225  }
226  }
227 }
228 
229 bool Command::Is(const char* pattern) const
230 {
231  // Build expression
232  std::regex matcher(pattern, std::regex_constants::icase);
233 
234  // Match
235  return std::regex_match(_verb, matcher);
236 }
static void HighlighterCallback(const std::string &input, replxx::Replxx::colors_t &colors, void *unused)
Highlighter callback for commands.
Definition: Command.cpp:8
Exception class thrown by all library classes.
std::string _verb
Verb.
Definition: Command.h:23
static Command Parse(std::string command)
Parse a string as a command.
Definition: Command.cpp:108
Command(const std::string &verb)
Construct a new Command object.
Definition: Command.h:42
ROSLIB_DECL std::string command(const std::string &cmd)
Parser for commands of the default form.
Definition: Command.h:15
bool Is(const char *pattern) const
Do a case insensitive regex match on the verb.
Definition: Command.cpp:229


swarmros
Author(s):
autogenerated on Fri Apr 3 2020 03:42:47