blob: affa644cd4b70d6a575023e479f2eb079f98357e [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:241//===-- Args.cpp ------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// C Includes
11#include <getopt.h>
Eli Friedman5661f922010-06-09 10:59:2312#include <cstdlib>
Chris Lattner30fdc8d2010-06-08 16:52:2413// C++ Includes
14// Other libraries and framework includes
15// Project includes
Jim Ingham40af72e2010-06-15 19:49:2716#include "lldb/Interpreter/Args.h"
Chris Lattner30fdc8d2010-06-08 16:52:2417#include "lldb/Core/Stream.h"
18#include "lldb/Core/StreamFile.h"
19#include "lldb/Core/StreamString.h"
Jim Ingham40af72e2010-06-15 19:49:2720#include "lldb/Interpreter/Options.h"
Chris Lattner30fdc8d2010-06-08 16:52:2421#include "lldb/Interpreter/CommandReturnObject.h"
22
Chris Lattner30fdc8d2010-06-08 16:52:2423using namespace lldb;
24using namespace lldb_private;
25
Chris Lattner30fdc8d2010-06-08 16:52:2426//----------------------------------------------------------------------
27// Args constructor
28//----------------------------------------------------------------------
29Args::Args (const char *command) :
30 m_args(),
31 m_argv()
32{
Greg Clayton6ad07dd2010-12-19 03:41:2433 if (command)
34 SetCommandString (command);
Chris Lattner30fdc8d2010-06-08 16:52:2435}
36
37
38Args::Args (const char *command, size_t len) :
39 m_args(),
40 m_argv()
41{
Greg Clayton6ad07dd2010-12-19 03:41:2442 if (command && len)
43 SetCommandString (command, len);
Chris Lattner30fdc8d2010-06-08 16:52:2444}
45
Chris Lattner30fdc8d2010-06-08 16:52:2446//----------------------------------------------------------------------
47// Destructor
48//----------------------------------------------------------------------
49Args::~Args ()
50{
51}
52
53void
54Args::Dump (Stream *s)
55{
56// int argc = GetArgumentCount();
57//
58// arg_sstr_collection::const_iterator pos, begin = m_args.begin(), end = m_args.end();
59// for (pos = m_args.begin(); pos != end; ++pos)
60// {
61// s->Indent();
62// s->Printf("args[%zu]=%s\n", std::distance(begin, pos), pos->c_str());
63// }
64// s->EOL();
65 const int argc = m_argv.size();
66 for (int i=0; i<argc; ++i)
67 {
68 s->Indent();
69 const char *arg_cstr = m_argv[i];
70 if (arg_cstr)
71 s->Printf("argv[%i]=\"%s\"\n", i, arg_cstr);
72 else
73 s->Printf("argv[%i]=NULL\n", i);
74 }
75 s->EOL();
76}
77
78bool
79Args::GetCommandString (std::string &command)
80{
81 command.clear();
82 int argc = GetArgumentCount();
83 for (int i=0; i<argc; ++i)
84 {
85 if (i > 0)
86 command += ' ';
87 command += m_argv[i];
88 }
89 return argc > 0;
90}
91
Caroline Tice2d5289d62010-12-10 00:26:5492bool
93Args::GetQuotedCommandString (std::string &command)
94{
95 command.clear ();
Greg Clayton6ad07dd2010-12-19 03:41:2496 size_t argc = GetArgumentCount ();
97 for (size_t i = 0; i < argc; ++i)
Caroline Tice2d5289d62010-12-10 00:26:5498 {
99 if (i > 0)
Greg Clayton6ad07dd2010-12-19 03:41:24100 command.append (1, ' ');
101 char quote_char = GetArgumentQuoteCharAtIndex(i);
102 if (quote_char)
Caroline Tice2d5289d62010-12-10 00:26:54103 {
Greg Clayton6ad07dd2010-12-19 03:41:24104 command.append (1, quote_char);
105 command.append (m_argv[i]);
106 command.append (1, quote_char);
Caroline Tice2d5289d62010-12-10 00:26:54107 }
108 else
Greg Clayton6ad07dd2010-12-19 03:41:24109 command.append (m_argv[i]);
Caroline Tice2d5289d62010-12-10 00:26:54110 }
111 return argc > 0;
112}
113
Chris Lattner30fdc8d2010-06-08 16:52:24114void
115Args::SetCommandString (const char *command, size_t len)
116{
117 // Use std::string to make sure we get a NULL terminated string we can use
118 // as "command" could point to a string within a large string....
119 std::string null_terminated_command(command, len);
120 SetCommandString(null_terminated_command.c_str());
121}
122
123void
124Args::SetCommandString (const char *command)
125{
Greg Clayton6ad07dd2010-12-19 03:41:24126 StreamFile s(stdout);
127 s.Printf("\nCOMMAND: %s\n", command);
Chris Lattner30fdc8d2010-06-08 16:52:24128 m_args.clear();
129 m_argv.clear();
Greg Clayton6ad07dd2010-12-19 03:41:24130 m_args_quote_char.clear();
131
Chris Lattner30fdc8d2010-06-08 16:52:24132 if (command && command[0])
133 {
Greg Clayton6ad07dd2010-12-19 03:41:24134 static const char *k_space_separators = " \t";
135 static const char *k_space_separators_with_slash_and_quotes = " \t \\'\"`";
136 const char *arg_end = NULL;
137 const char *arg_pos;
138 for (arg_pos = command;
139 arg_pos && arg_pos[0];
140 arg_pos = arg_end)
Chris Lattner30fdc8d2010-06-08 16:52:24141 {
Greg Clayton6ad07dd2010-12-19 03:41:24142 // Skip any leading space separators
143 const char *arg_start = ::strspn (arg_pos, k_space_separators) + arg_pos;
144
145 // If there were only space separators to the end of the line, then
Chris Lattner30fdc8d2010-06-08 16:52:24146 // we're done.
147 if (*arg_start == '\0')
148 break;
149
Greg Clayton6ad07dd2010-12-19 03:41:24150 // Arguments can be split into multiple discongituous pieces,
151 // for example:
152 // "Hello ""World"
153 // this would result in a single argument "Hello World" (without/
154 // the quotes) since the quotes would be removed and there is
155 // not space between the strings. So we need to keep track of the
156 // current start of each argument piece in "arg_piece_start"
157 const char *arg_piece_start = arg_start;
158 arg_pos = arg_piece_start;
159
Chris Lattner30fdc8d2010-06-08 16:52:24160 std::string arg;
Greg Clayton6ad07dd2010-12-19 03:41:24161 // Since we can have multiple quotes that form a single command
162 // in a command like: "Hello "world'!' (which will make a single
163 // argument "Hello world!") we remember the first quote character
164 // we encounter and use that for the quote character.
165 char first_quote_char = '\0';
166 char quote_char = '\0';
167 bool arg_complete = false;
Chris Lattner30fdc8d2010-06-08 16:52:24168
Greg Clayton6ad07dd2010-12-19 03:41:24169 do
Chris Lattner30fdc8d2010-06-08 16:52:24170 {
Greg Clayton6ad07dd2010-12-19 03:41:24171 arg_end = ::strcspn (arg_pos, k_space_separators_with_slash_and_quotes) + arg_pos;
172
173 switch (arg_end[0])
Chris Lattner30fdc8d2010-06-08 16:52:24174 {
Greg Clayton6ad07dd2010-12-19 03:41:24175 default:
176 assert (!"Unhandled case statement, we must handle this...");
177 break;
Chris Lattner30fdc8d2010-06-08 16:52:24178
Greg Clayton6ad07dd2010-12-19 03:41:24179 case '\0':
180 // End of C string
181 if (arg_piece_start && arg_piece_start[0])
182 arg.append (arg_piece_start);
183 arg_complete = true;
184 break;
185
186 case '\\':
187 // Backslash character
188 switch (arg_end[1])
Chris Lattner30fdc8d2010-06-08 16:52:24189 {
Greg Clayton6ad07dd2010-12-19 03:41:24190 case '\0':
191 arg.append (arg_piece_start);
192 arg_complete = true;
Chris Lattner30fdc8d2010-06-08 16:52:24193 break;
Chris Lattner30fdc8d2010-06-08 16:52:24194
Greg Clayton6ad07dd2010-12-19 03:41:24195 default:
196 arg_pos = arg_end + 2;
197 break;
198 }
199 break;
200
201 case '"':
202 case '\'':
203 case '`':
204 // Quote characters
205 if (quote_char)
206 {
207 // We found a quote character while inside a quoted
208 // character argument. If it matches our current quote
209 // character, this ends the effect of the quotes. If it
210 // doesn't we ignore it.
211 if (quote_char == arg_end[0])
Chris Lattner30fdc8d2010-06-08 16:52:24212 {
Greg Clayton6ad07dd2010-12-19 03:41:24213 arg.append (arg_piece_start, arg_end - arg_piece_start);
214 // Clear the quote character and let parsing
215 // continue (we need to watch for things like:
216 // "Hello ""World"
217 // "Hello "World
218 // "Hello "'World'
219 // All of which will result in a single argument "Hello World"
220 quote_char = '\0'; // Note that we are no longer inside quotes
221 arg_pos = arg_end + 1; // Skip the quote character
222 arg_piece_start = arg_pos; // Note we are starting from later in the string
223 }
224 else
225 {
226 // different quote, skip it and keep going
227 arg_pos = arg_end + 1;
228 }
229 }
230 else
231 {
232 // We found the start of a quote scope.
233 // Make sure there isn't a string that predeces
234 // the start of a quote scope like:
235 // Hello" World"
236 // If so, then add the "Hello" to the arg
237 if (arg_end > arg_piece_start)
238 arg.append (arg_piece_start, arg_end - arg_piece_start);
239
240 // Enter into a quote scope
241 quote_char = arg_end[0];
242
243 if (first_quote_char == '\0')
244 first_quote_char = quote_char;
245
246 arg_pos = arg_end;
247
248 if (quote_char != '`')
249 ++arg_pos; // Skip the quote character if it is not a backtick
250
251 arg_piece_start = arg_pos; // Note we are starting from later in the string
252
253 // Skip till the next quote character
254 const char *end_quote = ::strchr (arg_piece_start, quote_char);
255 while (end_quote && end_quote[-1] == '\\')
256 {
257 // Don't skip the quote character if it is
258 // preceded by a '\' character
259 end_quote = ::strchr (end_quote + 1, quote_char);
260 }
261
262 if (end_quote)
263 {
264 if (end_quote > arg_piece_start)
Chris Lattner30fdc8d2010-06-08 16:52:24265 {
Greg Clayton6ad07dd2010-12-19 03:41:24266 // Keep the backtick quote on commands
267 if (quote_char == '`')
268 arg.append (arg_piece_start, end_quote + 1 - arg_piece_start);
269 else
270 arg.append (arg_piece_start, end_quote - arg_piece_start);
271 }
272
273 // If the next character is a space or the end of
274 // string, this argument is complete...
275 if (end_quote[1] == ' ' || end_quote[1] == '\t' || end_quote[1] == '\0')
276 {
277 arg_complete = true;
278 arg_end = end_quote + 1;
Chris Lattner30fdc8d2010-06-08 16:52:24279 }
280 else
281 {
Greg Clayton6ad07dd2010-12-19 03:41:24282 arg_pos = end_quote + 1;
283 arg_piece_start = arg_pos;
Chris Lattner30fdc8d2010-06-08 16:52:24284 }
Greg Clayton6ad07dd2010-12-19 03:41:24285 quote_char = '\0';
Chris Lattner30fdc8d2010-06-08 16:52:24286 }
287 }
Greg Clayton6ad07dd2010-12-19 03:41:24288 break;
Chris Lattner30fdc8d2010-06-08 16:52:24289
Greg Clayton6ad07dd2010-12-19 03:41:24290 case ' ':
291 case '\t':
292 if (quote_char)
Chris Lattner30fdc8d2010-06-08 16:52:24293 {
Greg Clayton6ad07dd2010-12-19 03:41:24294 // We are currently processing a quoted character and found
295 // a space character, skip any spaces and keep trying to find
296 // the end of the argument.
297 arg_pos = ::strspn (arg_end, k_space_separators) + arg_end;
Chris Lattner30fdc8d2010-06-08 16:52:24298 }
Greg Clayton6ad07dd2010-12-19 03:41:24299 else
Chris Lattner30fdc8d2010-06-08 16:52:24300 {
Greg Clayton6ad07dd2010-12-19 03:41:24301 // We are not inside any quotes, we just found a space after an
302 // argument
303 if (arg_end > arg_piece_start)
304 arg.append (arg_piece_start, arg_end - arg_piece_start);
305 arg_complete = true;
Chris Lattner30fdc8d2010-06-08 16:52:24306 }
Greg Clayton6ad07dd2010-12-19 03:41:24307 break;
Chris Lattner30fdc8d2010-06-08 16:52:24308 }
Greg Clayton6ad07dd2010-12-19 03:41:24309 } while (!arg_complete);
Chris Lattner30fdc8d2010-06-08 16:52:24310
311 m_args.push_back(arg);
Greg Clayton6ad07dd2010-12-19 03:41:24312 m_args_quote_char.push_back (first_quote_char);
Chris Lattner30fdc8d2010-06-08 16:52:24313 }
Greg Clayton6ad07dd2010-12-19 03:41:24314 UpdateArgvFromArgs();
Chris Lattner30fdc8d2010-06-08 16:52:24315 }
Greg Clayton6ad07dd2010-12-19 03:41:24316 Dump (&s);
Chris Lattner30fdc8d2010-06-08 16:52:24317}
318
319void
320Args::UpdateArgsAfterOptionParsing()
321{
322 // Now m_argv might be out of date with m_args, so we need to fix that
323 arg_cstr_collection::const_iterator argv_pos, argv_end = m_argv.end();
324 arg_sstr_collection::iterator args_pos;
325 arg_quote_char_collection::iterator quotes_pos;
326
327 for (argv_pos = m_argv.begin(), args_pos = m_args.begin(), quotes_pos = m_args_quote_char.begin();
328 argv_pos != argv_end && args_pos != m_args.end();
329 ++argv_pos)
330 {
331 const char *argv_cstr = *argv_pos;
332 if (argv_cstr == NULL)
333 break;
334
335 while (args_pos != m_args.end())
336 {
337 const char *args_cstr = args_pos->c_str();
338 if (args_cstr == argv_cstr)
339 {
340 // We found the argument that matches the C string in the
341 // vector, so we can now look for the next one
342 ++args_pos;
343 ++quotes_pos;
344 break;
345 }
346 else
347 {
348 quotes_pos = m_args_quote_char.erase (quotes_pos);
349 args_pos = m_args.erase (args_pos);
350 }
351 }
352 }
353
354 if (args_pos != m_args.end())
355 m_args.erase (args_pos, m_args.end());
356
357 if (quotes_pos != m_args_quote_char.end())
358 m_args_quote_char.erase (quotes_pos, m_args_quote_char.end());
359}
360
361void
362Args::UpdateArgvFromArgs()
363{
364 m_argv.clear();
365 arg_sstr_collection::const_iterator pos, end = m_args.end();
366 for (pos = m_args.begin(); pos != end; ++pos)
367 m_argv.push_back(pos->c_str());
368 m_argv.push_back(NULL);
Greg Clayton6ad07dd2010-12-19 03:41:24369 // Make sure we have enough arg quote chars in the array
370 if (m_args_quote_char.size() < m_args.size())
371 m_args_quote_char.resize (m_argv.size());
Chris Lattner30fdc8d2010-06-08 16:52:24372}
373
374size_t
375Args::GetArgumentCount() const
376{
377 if (m_argv.empty())
378 return 0;
379 return m_argv.size() - 1;
380}
381
382const char *
383Args::GetArgumentAtIndex (size_t idx) const
384{
385 if (idx < m_argv.size())
386 return m_argv[idx];
387 return NULL;
388}
389
390char
391Args::GetArgumentQuoteCharAtIndex (size_t idx) const
392{
393 if (idx < m_args_quote_char.size())
394 return m_args_quote_char[idx];
395 return '\0';
396}
397
398char **
399Args::GetArgumentVector()
400{
401 if (!m_argv.empty())
402 return (char **)&m_argv[0];
403 return NULL;
404}
405
406const char **
407Args::GetConstArgumentVector() const
408{
409 if (!m_argv.empty())
410 return (const char **)&m_argv[0];
411 return NULL;
412}
413
414void
415Args::Shift ()
416{
417 // Don't pop the last NULL terminator from the argv array
418 if (m_argv.size() > 1)
419 {
420 m_argv.erase(m_argv.begin());
421 m_args.pop_front();
Greg Clayton6ad07dd2010-12-19 03:41:24422 if (!m_args_quote_char.empty())
423 m_args_quote_char.erase(m_args_quote_char.begin());
Chris Lattner30fdc8d2010-06-08 16:52:24424 }
425}
426
427const char *
428Args::Unshift (const char *arg_cstr, char quote_char)
429{
430 m_args.push_front(arg_cstr);
431 m_argv.insert(m_argv.begin(), m_args.front().c_str());
432 m_args_quote_char.insert(m_args_quote_char.begin(), quote_char);
433 return GetArgumentAtIndex (0);
434}
435
436void
437Args::AppendArguments (const Args &rhs)
438{
439 const size_t rhs_argc = rhs.GetArgumentCount();
440 for (size_t i=0; i<rhs_argc; ++i)
441 AppendArgument(rhs.GetArgumentAtIndex(i));
442}
443
444const char *
445Args::AppendArgument (const char *arg_cstr, char quote_char)
446{
447 return InsertArgumentAtIndex (GetArgumentCount(), arg_cstr, quote_char);
448}
449
450const char *
451Args::InsertArgumentAtIndex (size_t idx, const char *arg_cstr, char quote_char)
452{
453 // Since we are using a std::list to hold onto the copied C string and
454 // we don't have direct access to the elements, we have to iterate to
455 // find the value.
456 arg_sstr_collection::iterator pos, end = m_args.end();
457 size_t i = idx;
458 for (pos = m_args.begin(); i > 0 && pos != end; ++pos)
459 --i;
460
461 pos = m_args.insert(pos, arg_cstr);
462
Greg Clayton6ad07dd2010-12-19 03:41:24463 if (idx >= m_args_quote_char.size())
464 {
465 m_args_quote_char.resize(idx + 1);
466 m_args_quote_char[idx] = quote_char;
467 }
468 else
469 m_args_quote_char.insert(m_args_quote_char.begin() + idx, quote_char);
Chris Lattner30fdc8d2010-06-08 16:52:24470
471 UpdateArgvFromArgs();
472 return GetArgumentAtIndex(idx);
473}
474
475const char *
476Args::ReplaceArgumentAtIndex (size_t idx, const char *arg_cstr, char quote_char)
477{
478 // Since we are using a std::list to hold onto the copied C string and
479 // we don't have direct access to the elements, we have to iterate to
480 // find the value.
481 arg_sstr_collection::iterator pos, end = m_args.end();
482 size_t i = idx;
483 for (pos = m_args.begin(); i > 0 && pos != end; ++pos)
484 --i;
485
486 if (pos != end)
487 {
488 pos->assign(arg_cstr);
489 assert(idx < m_argv.size() - 1);
490 m_argv[idx] = pos->c_str();
Greg Clayton6ad07dd2010-12-19 03:41:24491 if (idx >= m_args_quote_char.size())
492 m_args_quote_char.resize(idx + 1);
Chris Lattner30fdc8d2010-06-08 16:52:24493 m_args_quote_char[idx] = quote_char;
494 return GetArgumentAtIndex(idx);
495 }
496 return NULL;
497}
498
499void
500Args::DeleteArgumentAtIndex (size_t idx)
501{
502 // Since we are using a std::list to hold onto the copied C string and
503 // we don't have direct access to the elements, we have to iterate to
504 // find the value.
505 arg_sstr_collection::iterator pos, end = m_args.end();
506 size_t i = idx;
507 for (pos = m_args.begin(); i > 0 && pos != end; ++pos)
508 --i;
509
510 if (pos != end)
511 {
512 m_args.erase (pos);
513 assert(idx < m_argv.size() - 1);
514 m_argv.erase(m_argv.begin() + idx);
Greg Clayton6ad07dd2010-12-19 03:41:24515 if (idx < m_args_quote_char.size())
516 m_args_quote_char.erase(m_args_quote_char.begin() + idx);
Chris Lattner30fdc8d2010-06-08 16:52:24517 }
518}
519
520void
521Args::SetArguments (int argc, const char **argv)
522{
523 // m_argv will be rebuilt in UpdateArgvFromArgs() below, so there is
524 // no need to clear it here.
525 m_args.clear();
526 m_args_quote_char.clear();
527
528 // Make a copy of the arguments in our internal buffer
529 size_t i;
530 // First copy each string
531 for (i=0; i<argc; ++i)
532 {
533 m_args.push_back (argv[i]);
Greg Clayton6ad07dd2010-12-19 03:41:24534 if ((argv[i][0] == '\'') || (argv[i][0] == '"') || (argv[i][0] == '`'))
Chris Lattner30fdc8d2010-06-08 16:52:24535 m_args_quote_char.push_back (argv[i][0]);
536 else
537 m_args_quote_char.push_back ('\0');
538 }
539
540 UpdateArgvFromArgs();
541}
542
543
544Error
545Args::ParseOptions (Options &options)
546{
547 StreamString sstr;
Chris Lattner30fdc8d2010-06-08 16:52:24548 Error error;
549 struct option *long_options = options.GetLongOptions();
550 if (long_options == NULL)
551 {
552 error.SetErrorStringWithFormat("Invalid long options.\n");
553 return error;
554 }
555
Greg Claytonb1320972010-07-14 00:18:15556 for (int i=0; long_options[i].name != NULL; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24557 {
558 if (long_options[i].flag == NULL)
559 {
560 sstr << (char)long_options[i].val;
561 switch (long_options[i].has_arg)
562 {
563 default:
564 case no_argument: break;
565 case required_argument: sstr << ':'; break;
566 case optional_argument: sstr << "::"; break;
567 }
568 }
569 }
Eli Friedmanadb35022010-06-13 19:18:49570#ifdef __GLIBC__
571 optind = 0;
572#else
Chris Lattner30fdc8d2010-06-08 16:52:24573 optreset = 1;
574 optind = 1;
Eli Friedmanadb35022010-06-13 19:18:49575#endif
Chris Lattner30fdc8d2010-06-08 16:52:24576 int val;
577 while (1)
578 {
579 int long_options_index = -1;
580 val = ::getopt_long(GetArgumentCount(), GetArgumentVector(), sstr.GetData(), long_options,
581 &long_options_index);
582 if (val == -1)
583 break;
584
585 // Did we get an error?
586 if (val == '?')
587 {
588 error.SetErrorStringWithFormat("Unknown or ambiguous option.\n");
589 break;
590 }
591 // The option auto-set itself
592 if (val == 0)
593 continue;
594
595 ((Options *) &options)->OptionSeen (val);
596
597 // Lookup the long option index
598 if (long_options_index == -1)
599 {
600 for (int i=0;
601 long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val;
602 ++i)
603 {
604 if (long_options[i].val == val)
605 {
606 long_options_index = i;
607 break;
608 }
609 }
610 }
611 // Call the callback with the option
612 if (long_options_index >= 0)
613 {
614 error = options.SetOptionValue(long_options_index,
615 long_options[long_options_index].has_arg == no_argument ? NULL : optarg);
616 }
617 else
618 {
619 error.SetErrorStringWithFormat("Invalid option with value '%i'.\n", val);
620 }
621 if (error.Fail())
622 break;
623 }
624
625 // Update our ARGV now that get options has consumed all the options
626 m_argv.erase(m_argv.begin(), m_argv.begin() + optind);
627 UpdateArgsAfterOptionParsing ();
628 return error;
629}
630
631void
632Args::Clear ()
633{
634 m_args.clear ();
635 m_argv.clear ();
636 m_args_quote_char.clear();
637}
638
639int32_t
640Args::StringToSInt32 (const char *s, int32_t fail_value, int base, bool *success_ptr)
641{
642 if (s && s[0])
643 {
644 char *end = NULL;
645 int32_t uval = ::strtol (s, &end, base);
646 if (*end == '\0')
647 {
648 if (success_ptr) *success_ptr = true;
649 return uval; // All characters were used, return the result
650 }
651 }
652 if (success_ptr) *success_ptr = false;
653 return fail_value;
654}
655
656uint32_t
657Args::StringToUInt32 (const char *s, uint32_t fail_value, int base, bool *success_ptr)
658{
659 if (s && s[0])
660 {
661 char *end = NULL;
662 uint32_t uval = ::strtoul (s, &end, base);
663 if (*end == '\0')
664 {
665 if (success_ptr) *success_ptr = true;
666 return uval; // All characters were used, return the result
667 }
668 }
669 if (success_ptr) *success_ptr = false;
670 return fail_value;
671}
672
673
674int64_t
675Args::StringToSInt64 (const char *s, int64_t fail_value, int base, bool *success_ptr)
676{
677 if (s && s[0])
678 {
679 char *end = NULL;
680 int64_t uval = ::strtoll (s, &end, base);
681 if (*end == '\0')
682 {
683 if (success_ptr) *success_ptr = true;
684 return uval; // All characters were used, return the result
685 }
686 }
687 if (success_ptr) *success_ptr = false;
688 return fail_value;
689}
690
691uint64_t
692Args::StringToUInt64 (const char *s, uint64_t fail_value, int base, bool *success_ptr)
693{
694 if (s && s[0])
695 {
696 char *end = NULL;
697 uint64_t uval = ::strtoull (s, &end, base);
698 if (*end == '\0')
699 {
700 if (success_ptr) *success_ptr = true;
701 return uval; // All characters were used, return the result
702 }
703 }
704 if (success_ptr) *success_ptr = false;
705 return fail_value;
706}
707
708lldb::addr_t
709Args::StringToAddress (const char *s, lldb::addr_t fail_value, bool *success_ptr)
710{
711 if (s && s[0])
712 {
713 char *end = NULL;
714 lldb::addr_t addr = ::strtoull (s, &end, 0);
715 if (*end == '\0')
716 {
717 if (success_ptr) *success_ptr = true;
718 return addr; // All characters were used, return the result
719 }
720 // Try base 16 with no prefix...
721 addr = ::strtoull (s, &end, 16);
722 if (*end == '\0')
723 {
724 if (success_ptr) *success_ptr = true;
725 return addr; // All characters were used, return the result
726 }
727 }
728 if (success_ptr) *success_ptr = false;
729 return fail_value;
730}
731
732bool
733Args::StringToBoolean (const char *s, bool fail_value, bool *success_ptr)
734{
735 if (s && s[0])
736 {
737 if (::strcasecmp (s, "false") == 0 ||
738 ::strcasecmp (s, "off") == 0 ||
739 ::strcasecmp (s, "no") == 0 ||
740 ::strcmp (s, "0") == 0)
741 {
742 if (success_ptr)
743 *success_ptr = true;
744 return false;
745 }
746 else
747 if (::strcasecmp (s, "true") == 0 ||
748 ::strcasecmp (s, "on") == 0 ||
749 ::strcasecmp (s, "yes") == 0 ||
750 ::strcmp (s, "1") == 0)
751 {
752 if (success_ptr) *success_ptr = true;
753 return true;
754 }
755 }
756 if (success_ptr) *success_ptr = false;
757 return fail_value;
758}
759
760int32_t
761Args::StringToOptionEnum (const char *s, lldb::OptionEnumValueElement *enum_values, int32_t fail_value, bool *success_ptr)
762{
763 if (enum_values && s && s[0])
764 {
765 for (int i = 0; enum_values[i].string_value != NULL ; i++)
766 {
767 if (strstr(enum_values[i].string_value, s) == enum_values[i].string_value)
768 {
769 if (success_ptr) *success_ptr = true;
770 return enum_values[i].value;
771 }
772 }
773 }
774 if (success_ptr) *success_ptr = false;
775
776 return fail_value;
777}
778
779ScriptLanguage
780Args::StringToScriptLanguage (const char *s, ScriptLanguage fail_value, bool *success_ptr)
781{
782 if (s && s[0])
783 {
784 if ((::strcasecmp (s, "python") == 0) ||
785 (::strcasecmp (s, "default") == 0 && eScriptLanguagePython == eScriptLanguageDefault))
786 {
787 if (success_ptr) *success_ptr = true;
788 return eScriptLanguagePython;
789 }
790 if (::strcasecmp (s, "none"))
791 {
792 if (success_ptr) *success_ptr = true;
793 return eScriptLanguageNone;
794 }
795 }
796 if (success_ptr) *success_ptr = false;
797 return fail_value;
798}
799
800Error
801Args::StringToFormat
802(
803 const char *s,
804 lldb::Format &format
805)
806{
807 format = eFormatInvalid;
808 Error error;
809
810 if (s && s[0])
811 {
812 switch (s[0])
813 {
814 case 'y': format = eFormatBytes; break;
815 case 'Y': format = eFormatBytesWithASCII; break;
816 case 'b': format = eFormatBinary; break;
817 case 'B': format = eFormatBoolean; break;
818 case 'c': format = eFormatChar; break;
819 case 'C': format = eFormatCharPrintable; break;
820 case 'o': format = eFormatOctal; break;
821 case 'i':
822 case 'd': format = eFormatDecimal; break;
823 case 'u': format = eFormatUnsigned; break;
824 case 'x': format = eFormatHex; break;
825 case 'f':
826 case 'e':
827 case 'g': format = eFormatFloat; break;
828 case 'p': format = eFormatPointer; break;
829 case 's': format = eFormatCString; break;
830 default:
831 error.SetErrorStringWithFormat("Invalid format character '%c'. Valid values are:\n"
832 " b - binary\n"
833 " B - boolean\n"
834 " c - char\n"
835 " C - printable char\n"
836 " d - signed decimal\n"
837 " e - float\n"
838 " f - float\n"
839 " g - float\n"
840 " i - signed decimal\n"
841 " o - octal\n"
842 " s - c-string\n"
843 " u - unsigned decimal\n"
844 " x - hex\n"
845 " y - bytes\n"
846 " Y - bytes with ASCII\n", s[0]);
847 break;
848 }
849
850 if (error.Fail())
851 return error;
852 }
853 else
854 {
855 error.SetErrorStringWithFormat("%s option string.\n", s ? "empty" : "invalid");
856 }
857 return error;
858}
859
860void
861Args::LongestCommonPrefix (std::string &common_prefix)
862{
863 arg_sstr_collection::iterator pos, end = m_args.end();
864 pos = m_args.begin();
865 if (pos == end)
866 common_prefix.clear();
867 else
868 common_prefix = (*pos);
869
870 for (++pos; pos != end; ++pos)
871 {
Greg Claytonc982c762010-07-09 20:39:50872 size_t new_size = (*pos).size();
Chris Lattner30fdc8d2010-06-08 16:52:24873
874 // First trim common_prefix if it is longer than the current element:
875 if (common_prefix.size() > new_size)
876 common_prefix.erase (new_size);
877
878 // Then trim it at the first disparity:
879
Greg Claytonc982c762010-07-09 20:39:50880 for (size_t i = 0; i < common_prefix.size(); i++)
Chris Lattner30fdc8d2010-06-08 16:52:24881 {
882 if ((*pos)[i] != common_prefix[i])
883 {
884 common_prefix.erase(i);
885 break;
886 }
887 }
888
889 // If we've emptied the common prefix, we're done.
890 if (common_prefix.empty())
891 break;
892 }
893}
894
Caroline Ticed9d63362010-12-07 19:58:26895size_t
896Args::FindArgumentIndexForOption (struct option *long_options, int long_options_index)
897{
898 char short_buffer[3];
899 char long_buffer[255];
900 ::snprintf (short_buffer, sizeof (short_buffer), "-%c", (char) long_options[long_options_index].val);
901 ::snprintf (long_buffer, sizeof (long_buffer), "--%s", long_options[long_options_index].name);
902 size_t end = GetArgumentCount ();
903 size_t idx = 0;
904 while (idx < end)
905 {
906 if ((::strncmp (GetArgumentAtIndex (idx), short_buffer, strlen (short_buffer)) == 0)
907 || (::strncmp (GetArgumentAtIndex (idx), long_buffer, strlen (long_buffer)) == 0))
908 {
909 return idx;
910 }
911 ++idx;
912 }
913
914 return end;
915}
916
917bool
918Args::IsPositionalArgument (const char *arg)
919{
920 if (arg == NULL)
921 return false;
922
923 bool is_positional = true;
924 char *cptr = (char *) arg;
925
926 if (cptr[0] == '%')
927 {
928 ++cptr;
929 while (isdigit (cptr[0]))
930 ++cptr;
931 if (cptr[0] != '\0')
932 is_positional = false;
933 }
934 else
935 is_positional = false;
936
937 return is_positional;
938}
939
Chris Lattner30fdc8d2010-06-08 16:52:24940void
Caroline Tice636d6ed2010-10-12 17:45:19941Args::ParseAliasOptions (Options &options,
942 CommandReturnObject &result,
Caroline Tice844d23032010-12-09 22:52:49943 OptionArgVector *option_arg_vector,
944 std::string &raw_input_string)
Chris Lattner30fdc8d2010-06-08 16:52:24945{
946 StreamString sstr;
947 int i;
948 struct option *long_options = options.GetLongOptions();
949
950 if (long_options == NULL)
951 {
952 result.AppendError ("invalid long options");
953 result.SetStatus (eReturnStatusFailed);
954 return;
955 }
956
957 for (i = 0; long_options[i].name != NULL; ++i)
958 {
959 if (long_options[i].flag == NULL)
960 {
961 sstr << (char) long_options[i].val;
962 switch (long_options[i].has_arg)
963 {
964 default:
965 case no_argument:
966 break;
967 case required_argument:
968 sstr << ":";
969 break;
970 case optional_argument:
971 sstr << "::";
972 break;
973 }
974 }
975 }
976
Eli Friedmanadb35022010-06-13 19:18:49977#ifdef __GLIBC__
978 optind = 0;
979#else
Chris Lattner30fdc8d2010-06-08 16:52:24980 optreset = 1;
981 optind = 1;
Eli Friedmanadb35022010-06-13 19:18:49982#endif
Chris Lattner30fdc8d2010-06-08 16:52:24983 int val;
984 while (1)
985 {
986 int long_options_index = -1;
987 val = ::getopt_long (GetArgumentCount(), GetArgumentVector(), sstr.GetData(), long_options,
988 &long_options_index);
989
990 if (val == -1)
991 break;
992
993 if (val == '?')
994 {
995 result.AppendError ("unknown or ambiguous option");
996 result.SetStatus (eReturnStatusFailed);
997 break;
998 }
999
1000 if (val == 0)
1001 continue;
1002
1003 ((Options *) &options)->OptionSeen (val);
1004
1005 // Look up the long option index
1006 if (long_options_index == -1)
1007 {
1008 for (int j = 0;
1009 long_options[j].name || long_options[j].has_arg || long_options[j].flag || long_options[j].val;
1010 ++j)
1011 {
1012 if (long_options[j].val == val)
1013 {
1014 long_options_index = j;
1015 break;
1016 }
1017 }
1018 }
1019
1020 // See if the option takes an argument, and see if one was supplied.
1021 if (long_options_index >= 0)
1022 {
1023 StreamString option_str;
1024 option_str.Printf ("-%c", (char) val);
1025
1026 switch (long_options[long_options_index].has_arg)
1027 {
1028 case no_argument:
Caroline Ticed9d63362010-12-07 19:58:261029 option_arg_vector->push_back (OptionArgPair (std::string (option_str.GetData()),
1030 OptionArgValue (no_argument, "<no-argument>")));
Caroline Tice5172e6c2010-09-12 04:48:451031 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:241032 break;
1033 case required_argument:
1034 if (optarg != NULL)
1035 {
1036 option_arg_vector->push_back (OptionArgPair (std::string (option_str.GetData()),
Caroline Ticed9d63362010-12-07 19:58:261037 OptionArgValue (required_argument,
1038 std::string (optarg))));
Chris Lattner30fdc8d2010-06-08 16:52:241039 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1040 }
1041 else
1042 {
1043 result.AppendErrorWithFormat ("Option '%s' is missing argument specifier.\n",
1044 option_str.GetData());
1045 result.SetStatus (eReturnStatusFailed);
1046 }
1047 break;
1048 case optional_argument:
1049 if (optarg != NULL)
1050 {
1051 option_arg_vector->push_back (OptionArgPair (std::string (option_str.GetData()),
Caroline Ticed9d63362010-12-07 19:58:261052 OptionArgValue (optional_argument,
1053 std::string (optarg))));
Chris Lattner30fdc8d2010-06-08 16:52:241054 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1055 }
1056 else
1057 {
1058 option_arg_vector->push_back (OptionArgPair (std::string (option_str.GetData()),
Caroline Ticed9d63362010-12-07 19:58:261059 OptionArgValue (optional_argument, "<no-argument>")));
Chris Lattner30fdc8d2010-06-08 16:52:241060 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1061 }
1062 break;
1063 default:
1064 result.AppendErrorWithFormat
1065 ("error with options table; invalid value in has_arg field for option '%c'.\n",
1066 (char) val);
1067 result.SetStatus (eReturnStatusFailed);
1068 break;
1069 }
1070 }
1071 else
1072 {
1073 result.AppendErrorWithFormat ("Invalid option with value '%c'.\n", (char) val);
1074 result.SetStatus (eReturnStatusFailed);
1075 }
Caroline Tice636d6ed2010-10-12 17:45:191076
1077 if (long_options_index >= 0)
1078 {
1079 // Find option in the argument list; also see if it was supposed to take an argument and if one was
Caroline Tice844d23032010-12-09 22:52:491080 // supplied. Remove option (and argument, if given) from the argument list. Also remove them from
1081 // the raw_input_string, if one was passed in.
Caroline Ticed9d63362010-12-07 19:58:261082 size_t idx = FindArgumentIndexForOption (long_options, long_options_index);
1083 if (idx < GetArgumentCount())
1084 {
Caroline Tice844d23032010-12-09 22:52:491085 if (raw_input_string.size() > 0)
1086 {
1087 const char *tmp_arg = GetArgumentAtIndex (idx);
1088 size_t pos = raw_input_string.find (tmp_arg);
1089 if (pos != std::string::npos)
1090 raw_input_string.erase (pos, strlen (tmp_arg));
1091 }
Caroline Ticed9d63362010-12-07 19:58:261092 ReplaceArgumentAtIndex (idx, "");
1093 if ((long_options[long_options_index].has_arg != no_argument)
1094 && (optarg != NULL)
1095 && (idx+1 < GetArgumentCount())
1096 && (strcmp (optarg, GetArgumentAtIndex(idx+1)) == 0))
Caroline Tice844d23032010-12-09 22:52:491097 {
1098 if (raw_input_string.size() > 0)
1099 {
1100 const char *tmp_arg = GetArgumentAtIndex (idx+1);
1101 size_t pos = raw_input_string.find (tmp_arg);
1102 if (pos != std::string::npos)
1103 raw_input_string.erase (pos, strlen (tmp_arg));
1104 }
Caroline Ticed9d63362010-12-07 19:58:261105 ReplaceArgumentAtIndex (idx+1, "");
Caroline Tice844d23032010-12-09 22:52:491106 }
Caroline Ticed9d63362010-12-07 19:58:261107 }
Caroline Tice636d6ed2010-10-12 17:45:191108 }
1109
Chris Lattner30fdc8d2010-06-08 16:52:241110 if (!result.Succeeded())
1111 break;
1112 }
1113}
1114
1115void
1116Args::ParseArgsForCompletion
1117(
1118 Options &options,
Jim Inghamd43e0092010-06-24 20:31:041119 OptionElementVector &option_element_vector,
1120 uint32_t cursor_index
Chris Lattner30fdc8d2010-06-08 16:52:241121)
1122{
1123 StreamString sstr;
Chris Lattner30fdc8d2010-06-08 16:52:241124 struct option *long_options = options.GetLongOptions();
1125 option_element_vector.clear();
1126
1127 if (long_options == NULL)
1128 {
1129 return;
1130 }
1131
1132 // Leading : tells getopt to return a : for a missing option argument AND
1133 // to suppress error messages.
1134
1135 sstr << ":";
Greg Claytonb1320972010-07-14 00:18:151136 for (int i = 0; long_options[i].name != NULL; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:241137 {
1138 if (long_options[i].flag == NULL)
1139 {
1140 sstr << (char) long_options[i].val;
1141 switch (long_options[i].has_arg)
1142 {
1143 default:
1144 case no_argument:
1145 break;
1146 case required_argument:
1147 sstr << ":";
1148 break;
1149 case optional_argument:
1150 sstr << "::";
1151 break;
1152 }
1153 }
1154 }
1155
Eli Friedmanadb35022010-06-13 19:18:491156#ifdef __GLIBC__
1157 optind = 0;
1158#else
Chris Lattner30fdc8d2010-06-08 16:52:241159 optreset = 1;
1160 optind = 1;
Eli Friedmanadb35022010-06-13 19:18:491161#endif
Chris Lattner30fdc8d2010-06-08 16:52:241162 opterr = 0;
1163
1164 int val;
1165 const OptionDefinition *opt_defs = options.GetDefinitions();
1166
Jim Inghamd43e0092010-06-24 20:31:041167 // Fooey... getopt_long permutes the GetArgumentVector to move the options to the front.
Chris Lattner30fdc8d2010-06-08 16:52:241168 // So we have to build another Arg and pass that to getopt_long so it doesn't
Jim Inghamd43e0092010-06-24 20:31:041169 // change the one we have.
Chris Lattner30fdc8d2010-06-08 16:52:241170
Greg Claytonc982c762010-07-09 20:39:501171 std::vector<const char *> dummy_vec (GetArgumentVector(), GetArgumentVector() + GetArgumentCount() + 1);
Chris Lattner30fdc8d2010-06-08 16:52:241172
Jim Inghamd43e0092010-06-24 20:31:041173 bool failed_once = false;
1174 uint32_t dash_dash_pos = -1;
1175
Chris Lattner30fdc8d2010-06-08 16:52:241176 while (1)
1177 {
1178 bool missing_argument = false;
1179 int parse_start = optind;
1180 int long_options_index = -1;
Jim Inghamd43e0092010-06-24 20:31:041181
Greg Claytonc982c762010-07-09 20:39:501182 val = ::getopt_long (dummy_vec.size() - 1,
Greg Clayton471b31c2010-07-20 22:52:081183 (char *const *) &dummy_vec.front(),
Greg Claytonc982c762010-07-09 20:39:501184 sstr.GetData(),
1185 long_options,
Chris Lattner30fdc8d2010-06-08 16:52:241186 &long_options_index);
1187
1188 if (val == -1)
Jim Inghamd43e0092010-06-24 20:31:041189 {
1190 // When we're completing a "--" which is the last option on line,
1191 if (failed_once)
1192 break;
1193
1194 failed_once = true;
1195
1196 // If this is a bare "--" we mark it as such so we can complete it successfully later.
1197 // Handling the "--" is a little tricky, since that may mean end of options or arguments, or the
1198 // user might want to complete options by long name. I make this work by checking whether the
1199 // cursor is in the "--" argument, and if so I assume we're completing the long option, otherwise
1200 // I let it pass to getopt_long which will terminate the option parsing.
1201 // Note, in either case we continue parsing the line so we can figure out what other options
1202 // were passed. This will be useful when we come to restricting completions based on what other
1203 // options we've seen on the line.
Chris Lattner30fdc8d2010-06-08 16:52:241204
Jim Inghamd43e0092010-06-24 20:31:041205 if (optind < dummy_vec.size() - 1
1206 && (strcmp (dummy_vec[optind-1], "--") == 0))
1207 {
1208 dash_dash_pos = optind - 1;
1209 if (optind - 1 == cursor_index)
1210 {
1211 option_element_vector.push_back (OptionArgElement (OptionArgElement::eBareDoubleDash, optind - 1,
1212 OptionArgElement::eBareDoubleDash));
1213 continue;
1214 }
1215 else
1216 break;
1217 }
1218 else
1219 break;
1220 }
Chris Lattner30fdc8d2010-06-08 16:52:241221 else if (val == '?')
1222 {
Jim Inghamd43e0092010-06-24 20:31:041223 option_element_vector.push_back (OptionArgElement (OptionArgElement::eUnrecognizedArg, optind - 1,
1224 OptionArgElement::eUnrecognizedArg));
Chris Lattner30fdc8d2010-06-08 16:52:241225 continue;
1226 }
1227 else if (val == 0)
1228 {
1229 continue;
1230 }
1231 else if (val == ':')
1232 {
1233 // This is a missing argument.
1234 val = optopt;
1235 missing_argument = true;
1236 }
1237
1238 ((Options *) &options)->OptionSeen (val);
1239
1240 // Look up the long option index
1241 if (long_options_index == -1)
1242 {
1243 for (int j = 0;
1244 long_options[j].name || long_options[j].has_arg || long_options[j].flag || long_options[j].val;
1245 ++j)
1246 {
1247 if (long_options[j].val == val)
1248 {
1249 long_options_index = j;
1250 break;
1251 }
1252 }
1253 }
1254
1255 // See if the option takes an argument, and see if one was supplied.
1256 if (long_options_index >= 0)
1257 {
1258 int opt_defs_index = -1;
1259 for (int i = 0; ; i++)
1260 {
1261 if (opt_defs[i].short_option == 0)
1262 break;
1263 else if (opt_defs[i].short_option == val)
1264 {
1265 opt_defs_index = i;
1266 break;
1267 }
1268 }
1269
1270 switch (long_options[long_options_index].has_arg)
1271 {
1272 case no_argument:
1273 option_element_vector.push_back (OptionArgElement (opt_defs_index, parse_start, 0));
1274 break;
1275 case required_argument:
1276 if (optarg != NULL)
1277 {
1278 int arg_index;
1279 if (missing_argument)
1280 arg_index = -1;
1281 else
Jim Inghamd43e0092010-06-24 20:31:041282 arg_index = optind - 1;
Chris Lattner30fdc8d2010-06-08 16:52:241283
Jim Inghamd43e0092010-06-24 20:31:041284 option_element_vector.push_back (OptionArgElement (opt_defs_index, optind - 2, arg_index));
Chris Lattner30fdc8d2010-06-08 16:52:241285 }
1286 else
1287 {
Jim Inghamd43e0092010-06-24 20:31:041288 option_element_vector.push_back (OptionArgElement (opt_defs_index, optind - 1, -1));
Chris Lattner30fdc8d2010-06-08 16:52:241289 }
1290 break;
1291 case optional_argument:
1292 if (optarg != NULL)
1293 {
Jim Inghamd43e0092010-06-24 20:31:041294 option_element_vector.push_back (OptionArgElement (opt_defs_index, optind - 2, optind - 1));
Chris Lattner30fdc8d2010-06-08 16:52:241295 }
1296 else
1297 {
Jim Inghamd43e0092010-06-24 20:31:041298 option_element_vector.push_back (OptionArgElement (opt_defs_index, optind - 2, optind - 1));
Chris Lattner30fdc8d2010-06-08 16:52:241299 }
1300 break;
1301 default:
1302 // The options table is messed up. Here we'll just continue
Jim Inghamd43e0092010-06-24 20:31:041303 option_element_vector.push_back (OptionArgElement (OptionArgElement::eUnrecognizedArg, optind - 1,
1304 OptionArgElement::eUnrecognizedArg));
Chris Lattner30fdc8d2010-06-08 16:52:241305 break;
1306 }
1307 }
1308 else
1309 {
Jim Inghamd43e0092010-06-24 20:31:041310 option_element_vector.push_back (OptionArgElement (OptionArgElement::eUnrecognizedArg, optind - 1,
1311 OptionArgElement::eUnrecognizedArg));
Chris Lattner30fdc8d2010-06-08 16:52:241312 }
1313 }
Jim Inghamd43e0092010-06-24 20:31:041314
1315 // Finally we have to handle the case where the cursor index points at a single "-". We want to mark that in
1316 // the option_element_vector, but only if it is not after the "--". But it turns out that getopt_long just ignores
1317 // an isolated "-". So we have to look it up by hand here. We only care if it is AT the cursor position.
1318
1319 if ((dash_dash_pos == -1 || cursor_index < dash_dash_pos)
1320 && strcmp (GetArgumentAtIndex(cursor_index), "-") == 0)
1321 {
1322 option_element_vector.push_back (OptionArgElement (OptionArgElement::eBareDash, cursor_index,
1323 OptionArgElement::eBareDash));
1324
1325 }
Chris Lattner30fdc8d2010-06-08 16:52:241326}