]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Interpreter/Args.cpp
Vendor import of lldb trunk r256945:
[FreeBSD/FreeBSD.git] / source / Interpreter / Args.cpp
1 //===-- 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 <cstdlib>
12 // C++ Includes
13 // Other libraries and framework includes
14 // Project includes
15 #include "lldb/Interpreter/Args.h"
16 #include "lldb/Core/Stream.h"
17 #include "lldb/Core/StreamFile.h"
18 #include "lldb/Core/StreamString.h"
19 #include "lldb/DataFormatters/FormatManager.h"
20 #include "lldb/Host/StringConvert.h"
21 #include "lldb/Interpreter/Options.h"
22 #include "lldb/Interpreter/CommandInterpreter.h"
23 #include "lldb/Interpreter/CommandReturnObject.h"
24 #include "lldb/Target/Process.h"
25 #include "lldb/Target/StackFrame.h"
26 #include "lldb/Target/Target.h"
27
28 using namespace lldb;
29 using namespace lldb_private;
30
31 //----------------------------------------------------------------------
32 // Args constructor
33 //----------------------------------------------------------------------
34 Args::Args (llvm::StringRef command) :
35     m_args(),
36     m_argv(),
37     m_args_quote_char()
38 {
39     SetCommandString (command);
40 }
41
42
43 //----------------------------------------------------------------------
44 // We have to be very careful on the copy constructor of this class
45 // to make sure we copy all of the string values, but we can't copy the
46 // rhs.m_argv into m_argv since it will point to the "const char *" c 
47 // strings in rhs.m_args. We need to copy the string list and update our
48 // own m_argv appropriately. 
49 //----------------------------------------------------------------------
50 Args::Args (const Args &rhs) :
51     m_args (rhs.m_args),
52     m_argv (),
53     m_args_quote_char(rhs.m_args_quote_char)
54 {
55     UpdateArgvFromArgs();
56 }
57
58 //----------------------------------------------------------------------
59 // We have to be very careful on the copy constructor of this class
60 // to make sure we copy all of the string values, but we can't copy the
61 // rhs.m_argv into m_argv since it will point to the "const char *" c 
62 // strings in rhs.m_args. We need to copy the string list and update our
63 // own m_argv appropriately. 
64 //----------------------------------------------------------------------
65 const Args &
66 Args::operator= (const Args &rhs)
67 {
68     // Make sure we aren't assigning to self
69     if (this != &rhs)
70     {
71         m_args = rhs.m_args;
72         m_args_quote_char = rhs.m_args_quote_char;
73         UpdateArgvFromArgs();
74     }
75     return *this;
76 }
77
78 //----------------------------------------------------------------------
79 // Destructor
80 //----------------------------------------------------------------------
81 Args::~Args ()
82 {
83 }
84
85 void
86 Args::Dump (Stream *s)
87 {
88     const size_t argc = m_argv.size();
89     for (size_t i=0; i<argc; ++i)
90     {
91         s->Indent();
92         const char *arg_cstr = m_argv[i];
93         if (arg_cstr)
94             s->Printf("argv[%zi]=\"%s\"\n", i, arg_cstr);
95         else
96             s->Printf("argv[%zi]=NULL\n", i);
97     }
98     s->EOL();
99 }
100
101 bool
102 Args::GetCommandString (std::string &command) const
103 {
104     command.clear();
105     const size_t argc = GetArgumentCount();
106     for (size_t i=0; i<argc; ++i)
107     {
108         if (i > 0)
109             command += ' ';
110         command += m_argv[i];
111     }
112     return argc > 0;
113 }
114
115 bool
116 Args::GetQuotedCommandString (std::string &command) const
117 {
118     command.clear ();
119     const size_t argc = GetArgumentCount();
120     for (size_t i = 0; i < argc; ++i)
121     {
122         if (i > 0)
123             command.append (1, ' ');
124         char quote_char = GetArgumentQuoteCharAtIndex(i);
125         if (quote_char)
126         {
127             command.append (1, quote_char);
128             command.append (m_argv[i]);
129             command.append (1, quote_char);
130         }
131         else
132             command.append (m_argv[i]);
133     }
134     return argc > 0;
135 }
136
137 // A helper function for argument parsing.
138 // Parses the initial part of the first argument using normal double quote rules:
139 // backslash escapes the double quote and itself. The parsed string is appended to the second
140 // argument. The function returns the unparsed portion of the string, starting at the closing
141 // quote.
142 static llvm::StringRef
143 ParseDoubleQuotes(llvm::StringRef quoted, std::string &result)
144 {
145     // Inside double quotes, '\' and '"' are special.
146     static const char *k_escapable_characters = "\"\\";
147     while (true)
148     {
149         // Skip over over regular characters and append them.
150         size_t regular = quoted.find_first_of(k_escapable_characters);
151         result += quoted.substr(0, regular);
152         quoted = quoted.substr(regular);
153
154         // If we have reached the end of string or the closing quote, we're done.
155         if (quoted.empty() || quoted.front() == '"')
156             break;
157
158         // We have found a backslash.
159         quoted = quoted.drop_front();
160
161         if (quoted.empty())
162         {
163             // A lone backslash at the end of string, let's just append it.
164             result += '\\';
165             break;
166         }
167
168         // If the character after the backslash is not a whitelisted escapable character, we
169         // leave the character sequence untouched.
170         if (strchr(k_escapable_characters, quoted.front()) == nullptr)
171             result += '\\';
172
173         result += quoted.front();
174         quoted = quoted.drop_front();
175     }
176
177     return quoted;
178 }
179
180 // A helper function for SetCommandString.
181 // Parses a single argument from the command string, processing quotes and backslashes in a
182 // shell-like manner. The parsed argument is appended to the m_args array. The function returns
183 // the unparsed portion of the string, starting at the first unqouted, unescaped whitespace
184 // character.
185 llvm::StringRef
186 Args::ParseSingleArgument(llvm::StringRef command)
187 {
188     // Argument can be split into multiple discontiguous pieces,
189     // for example:
190     //  "Hello ""World"
191     // this would result in a single argument "Hello World" (without/
192     // the quotes) since the quotes would be removed and there is
193     // not space between the strings.
194
195     std::string arg;
196
197     // Since we can have multiple quotes that form a single command
198     // in a command like: "Hello "world'!' (which will make a single
199     // argument "Hello world!") we remember the first quote character
200     // we encounter and use that for the quote character.
201     char first_quote_char = '\0';
202
203     bool arg_complete = false;
204     do
205     {
206         // Skip over over regular characters and append them.
207         size_t regular = command.find_first_of(" \t\"'`\\");
208         arg += command.substr(0, regular);
209         command = command.substr(regular);
210
211         if (command.empty())
212             break;
213
214         char special = command.front();
215         command = command.drop_front();
216         switch (special)
217         {
218         case '\\':
219             if (command.empty())
220             {
221                 arg += '\\';
222                 break;
223             }
224
225             // If the character after the backslash is not a whitelisted escapable character, we
226             // leave the character sequence untouched.
227             if (strchr(" \t\\'\"`", command.front()) == nullptr)
228                 arg += '\\';
229
230             arg += command.front();
231             command = command.drop_front();
232
233             break;
234
235         case ' ':
236         case '\t':
237             // We are not inside any quotes, we just found a space after an
238             // argument. We are done.
239             arg_complete = true;
240             break;
241
242         case '"':
243         case '\'':
244         case '`':
245             // We found the start of a quote scope.
246             if (first_quote_char == '\0')
247                 first_quote_char = special;
248
249             if (special == '"')
250                 command = ParseDoubleQuotes(command, arg);
251             else
252             {
253                 // For single quotes, we simply skip ahead to the matching quote character
254                 // (or the end of the string).
255                 size_t quoted = command.find(special);
256                 arg += command.substr(0, quoted);
257                 command = command.substr(quoted);
258             }
259
260             // If we found a closing quote, skip it.
261             if (! command.empty())
262                 command = command.drop_front();
263
264             break;
265         }
266     } while (!arg_complete);
267
268     m_args.push_back(arg);
269     m_args_quote_char.push_back (first_quote_char);
270     return command;
271 }
272
273 void
274 Args::SetCommandString (llvm::StringRef command)
275 {
276     m_args.clear();
277     m_argv.clear();
278     m_args_quote_char.clear();
279
280     static const char *k_space_separators = " \t";
281     command = command.ltrim(k_space_separators);
282     while (!command.empty())
283     {
284         command = ParseSingleArgument(command);
285         command = command.ltrim(k_space_separators);
286     }
287
288     UpdateArgvFromArgs();
289 }
290
291 void
292 Args::UpdateArgsAfterOptionParsing()
293 {
294     // Now m_argv might be out of date with m_args, so we need to fix that
295     arg_cstr_collection::const_iterator argv_pos, argv_end = m_argv.end();
296     arg_sstr_collection::iterator args_pos;
297     arg_quote_char_collection::iterator quotes_pos;
298
299     for (argv_pos = m_argv.begin(), args_pos = m_args.begin(), quotes_pos = m_args_quote_char.begin();
300          argv_pos != argv_end && args_pos != m_args.end();
301          ++argv_pos)
302     {
303         const char *argv_cstr = *argv_pos;
304         if (argv_cstr == nullptr)
305             break;
306
307         while (args_pos != m_args.end())
308         {
309             const char *args_cstr = args_pos->c_str();
310             if (args_cstr == argv_cstr)
311             {
312                 // We found the argument that matches the C string in the
313                 // vector, so we can now look for the next one
314                 ++args_pos;
315                 ++quotes_pos;
316                 break;
317             }
318             else
319             {
320                 quotes_pos = m_args_quote_char.erase (quotes_pos);
321                 args_pos = m_args.erase (args_pos);
322             }
323         }
324     }
325
326     if (args_pos != m_args.end())
327         m_args.erase (args_pos, m_args.end());
328
329     if (quotes_pos != m_args_quote_char.end())
330         m_args_quote_char.erase (quotes_pos, m_args_quote_char.end());
331 }
332
333 void
334 Args::UpdateArgvFromArgs()
335 {
336     m_argv.clear();
337     arg_sstr_collection::const_iterator pos, end = m_args.end();
338     for (pos = m_args.begin(); pos != end; ++pos)
339         m_argv.push_back(pos->c_str());
340     m_argv.push_back(nullptr);
341     // Make sure we have enough arg quote chars in the array
342     if (m_args_quote_char.size() < m_args.size())
343         m_args_quote_char.resize (m_argv.size());
344 }
345
346 size_t
347 Args::GetArgumentCount() const
348 {
349     if (m_argv.empty())
350         return 0;
351     return m_argv.size() - 1;
352 }
353
354 const char *
355 Args::GetArgumentAtIndex (size_t idx) const
356 {
357     if (idx < m_argv.size())
358         return m_argv[idx];
359     return nullptr;
360 }
361
362 char
363 Args::GetArgumentQuoteCharAtIndex (size_t idx) const
364 {
365     if (idx < m_args_quote_char.size())
366         return m_args_quote_char[idx];
367     return '\0';
368 }
369
370 char **
371 Args::GetArgumentVector()
372 {
373     if (!m_argv.empty())
374         return const_cast<char **>(&m_argv[0]);
375     return nullptr;
376 }
377
378 const char **
379 Args::GetConstArgumentVector() const
380 {
381     if (!m_argv.empty())
382         return const_cast<const char **>(&m_argv[0]);
383     return nullptr;
384 }
385
386 void
387 Args::Shift ()
388 {
389     // Don't pop the last NULL terminator from the argv array
390     if (m_argv.size() > 1)
391     {
392         m_argv.erase(m_argv.begin());
393         m_args.pop_front();
394         if (!m_args_quote_char.empty())
395             m_args_quote_char.erase(m_args_quote_char.begin());
396     }
397 }
398
399 const char *
400 Args::Unshift (const char *arg_cstr, char quote_char)
401 {
402     m_args.push_front(arg_cstr);
403     m_argv.insert(m_argv.begin(), m_args.front().c_str());
404     m_args_quote_char.insert(m_args_quote_char.begin(), quote_char);
405     return GetArgumentAtIndex (0);
406 }
407
408 void
409 Args::AppendArguments (const Args &rhs)
410 {
411     const size_t rhs_argc = rhs.GetArgumentCount();
412     for (size_t i=0; i<rhs_argc; ++i)
413         AppendArgument(rhs.GetArgumentAtIndex(i),
414                        rhs.GetArgumentQuoteCharAtIndex(i));
415 }
416
417 void
418 Args::AppendArguments (const char **argv)
419 {
420     if (argv)
421     {
422         for (uint32_t i=0; argv[i]; ++i)
423             AppendArgument(argv[i]);
424     }
425 }
426
427 const char *
428 Args::AppendArgument (const char *arg_cstr, char quote_char)
429 {
430     return InsertArgumentAtIndex (GetArgumentCount(), arg_cstr, quote_char);
431 }
432
433 const char *
434 Args::InsertArgumentAtIndex (size_t idx, const char *arg_cstr, char quote_char)
435 {
436     // Since we are using a std::list to hold onto the copied C string and
437     // we don't have direct access to the elements, we have to iterate to
438     // find the value.
439     arg_sstr_collection::iterator pos, end = m_args.end();
440     size_t i = idx;
441     for (pos = m_args.begin(); i > 0 && pos != end; ++pos)
442         --i;
443
444     pos = m_args.insert(pos, arg_cstr);
445     
446     if (idx >= m_args_quote_char.size())
447     {
448         m_args_quote_char.resize(idx + 1);
449         m_args_quote_char[idx] = quote_char;
450     }
451     else
452         m_args_quote_char.insert(m_args_quote_char.begin() + idx, quote_char);
453     
454     UpdateArgvFromArgs();
455     return GetArgumentAtIndex(idx);
456 }
457
458 const char *
459 Args::ReplaceArgumentAtIndex (size_t idx, const char *arg_cstr, char quote_char)
460 {
461     // Since we are using a std::list to hold onto the copied C string and
462     // we don't have direct access to the elements, we have to iterate to
463     // find the value.
464     arg_sstr_collection::iterator pos, end = m_args.end();
465     size_t i = idx;
466     for (pos = m_args.begin(); i > 0 && pos != end; ++pos)
467         --i;
468
469     if (pos != end)
470     {
471         pos->assign(arg_cstr);
472         assert(idx < m_argv.size() - 1);
473         m_argv[idx] = pos->c_str();
474         if (idx >= m_args_quote_char.size())
475             m_args_quote_char.resize(idx + 1);
476         m_args_quote_char[idx] = quote_char;
477         return GetArgumentAtIndex(idx);
478     }
479     return nullptr;
480 }
481
482 void
483 Args::DeleteArgumentAtIndex (size_t idx)
484 {
485     // Since we are using a std::list to hold onto the copied C string and
486     // we don't have direct access to the elements, we have to iterate to
487     // find the value.
488     arg_sstr_collection::iterator pos, end = m_args.end();
489     size_t i = idx;
490     for (pos = m_args.begin(); i > 0 && pos != end; ++pos)
491         --i;
492
493     if (pos != end)
494     {
495         m_args.erase (pos);
496         assert(idx < m_argv.size() - 1);
497         m_argv.erase(m_argv.begin() + idx);
498         if (idx < m_args_quote_char.size())
499             m_args_quote_char.erase(m_args_quote_char.begin() + idx);
500     }
501 }
502
503 void
504 Args::SetArguments (size_t argc, const char **argv)
505 {
506     // m_argv will be rebuilt in UpdateArgvFromArgs() below, so there is
507     // no need to clear it here.
508     m_args.clear();
509     m_args_quote_char.clear();
510
511     // First copy each string
512     for (size_t i=0; i<argc; ++i)
513     {
514         m_args.push_back (argv[i]);
515         if ((argv[i][0] == '\'') || (argv[i][0] == '"') || (argv[i][0] == '`'))
516             m_args_quote_char.push_back (argv[i][0]);
517         else
518             m_args_quote_char.push_back ('\0');
519     }
520
521     UpdateArgvFromArgs();
522 }
523
524 void
525 Args::SetArguments (const char **argv)
526 {
527     // m_argv will be rebuilt in UpdateArgvFromArgs() below, so there is
528     // no need to clear it here.
529     m_args.clear();
530     m_args_quote_char.clear();
531     
532     if (argv)
533     {
534         // First copy each string
535         for (size_t i=0; argv[i]; ++i)
536         {
537             m_args.push_back (argv[i]);
538             if ((argv[i][0] == '\'') || (argv[i][0] == '"') || (argv[i][0] == '`'))
539                 m_args_quote_char.push_back (argv[i][0]);
540             else
541                 m_args_quote_char.push_back ('\0');
542         }
543     }
544     
545     UpdateArgvFromArgs();
546 }
547
548
549 Error
550 Args::ParseOptions (Options &options)
551 {
552     StreamString sstr;
553     Error error;
554     Option *long_options = options.GetLongOptions();
555     if (long_options == nullptr)
556     {
557         error.SetErrorStringWithFormat("invalid long options");
558         return error;
559     }
560
561     for (int i=0; long_options[i].definition != nullptr; ++i)
562     {
563         if (long_options[i].flag == nullptr)
564         {
565             if (isprint8(long_options[i].val))
566             {
567                 sstr << (char)long_options[i].val;
568                 switch (long_options[i].definition->option_has_arg)
569                 {
570                 default:
571                 case OptionParser::eNoArgument:                       break;
572                 case OptionParser::eRequiredArgument: sstr << ':';    break;
573                 case OptionParser::eOptionalArgument: sstr << "::";   break;
574                 }
575             }
576         }
577     }
578     Mutex::Locker options_locker(NULL);
579     OptionParser::Prepare(options_locker);
580     int val;
581     while (1)
582     {
583         int long_options_index = -1;
584         val = OptionParser::Parse(GetArgumentCount(),
585                                  GetArgumentVector(),
586                                  sstr.GetData(),
587                                  long_options,
588                                  &long_options_index);
589         if (val == -1)
590             break;
591
592         // Did we get an error?
593         if (val == '?')
594         {
595             error.SetErrorStringWithFormat("unknown or ambiguous option");
596             break;
597         }
598         // The option auto-set itself
599         if (val == 0)
600             continue;
601
602         ((Options *) &options)->OptionSeen (val);
603
604         // Lookup the long option index
605         if (long_options_index == -1)
606         {
607             for (int i=0;
608                  long_options[i].definition || long_options[i].flag || long_options[i].val;
609                  ++i)
610             {
611                 if (long_options[i].val == val)
612                 {
613                     long_options_index = i;
614                     break;
615                 }
616             }
617         }
618         // Call the callback with the option
619         if (long_options_index >= 0 && long_options[long_options_index].definition)
620         {
621             const OptionDefinition *def = long_options[long_options_index].definition;
622             CommandInterpreter &interpreter = options.GetInterpreter();
623             OptionValidator *validator = def->validator;
624             if (validator && !validator->IsValid(*interpreter.GetPlatform(true), interpreter.GetExecutionContext()))
625             {
626                 error.SetErrorStringWithFormat("Option \"%s\" invalid.  %s", def->long_option, def->validator->LongConditionString());
627             }
628             else
629             {
630                 error = options.SetOptionValue(long_options_index,
631                                                (def->option_has_arg == OptionParser::eNoArgument) ? nullptr : OptionParser::GetOptionArgument());
632             }
633         }
634         else
635         {
636             error.SetErrorStringWithFormat("invalid option with value '%i'", val);
637         }
638         if (error.Fail())
639             break;
640     }
641
642     // Update our ARGV now that get options has consumed all the options
643     m_argv.erase(m_argv.begin(), m_argv.begin() + OptionParser::GetOptionIndex());
644     UpdateArgsAfterOptionParsing ();
645     return error;
646 }
647
648 void
649 Args::Clear ()
650 {
651     m_args.clear ();
652     m_argv.clear ();
653     m_args_quote_char.clear();
654 }
655
656 lldb::addr_t
657 Args::StringToAddress (const ExecutionContext *exe_ctx, const char *s, lldb::addr_t fail_value, Error *error_ptr)
658 {
659     bool error_set = false;
660     if (s && s[0])
661     {
662         char *end = nullptr;
663         lldb::addr_t addr = ::strtoull (s, &end, 0);
664         if (*end == '\0')
665         {
666             if (error_ptr)
667                 error_ptr->Clear();
668             return addr; // All characters were used, return the result
669         }
670         // Try base 16 with no prefix...
671         addr = ::strtoull (s, &end, 16);
672         if (*end == '\0')
673         {
674             if (error_ptr)
675                 error_ptr->Clear();
676             return addr; // All characters were used, return the result
677         }
678         
679         if (exe_ctx)
680         {
681             Target *target = exe_ctx->GetTargetPtr();
682             if (target)
683             {
684                 lldb::ValueObjectSP valobj_sp;
685                 EvaluateExpressionOptions options;
686                 options.SetCoerceToId(false);
687                 options.SetUnwindOnError(true);
688                 options.SetKeepInMemory(false);
689                 options.SetTryAllThreads(true);
690                 
691                 ExpressionResults expr_result = target->EvaluateExpression(s,
692                                                                            exe_ctx->GetFramePtr(),
693                                                                            valobj_sp,
694                                                                            options);
695
696                 bool success = false;
697                 if (expr_result == eExpressionCompleted)
698                 {
699                     if (valobj_sp)
700                         valobj_sp = valobj_sp->GetQualifiedRepresentationIfAvailable(valobj_sp->GetDynamicValueType(), true);
701                     // Get the address to watch.
702                     if (valobj_sp)
703                         addr = valobj_sp->GetValueAsUnsigned(fail_value, &success);
704                     if (success)
705                     {
706                         if (error_ptr)
707                             error_ptr->Clear();
708                         return addr;
709                     }
710                     else
711                     {
712                         if (error_ptr)
713                         {
714                             error_set = true;
715                             error_ptr->SetErrorStringWithFormat("address expression \"%s\" resulted in a value whose type can't be converted to an address: %s", s, valobj_sp->GetTypeName().GetCString());
716                         }
717                     }
718                     
719                 }
720                 else
721                 {
722                     // Since the compiler can't handle things like "main + 12" we should
723                     // try to do this for now. The compiler doesn't like adding offsets
724                     // to function pointer types.
725                     static RegularExpression g_symbol_plus_offset_regex("^(.*)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*$");
726                     RegularExpression::Match regex_match(3);
727                     if (g_symbol_plus_offset_regex.Execute(s, &regex_match))
728                     {
729                         uint64_t offset = 0;
730                         bool add = true;
731                         std::string name;
732                         std::string str;
733                         if (regex_match.GetMatchAtIndex(s, 1, name))
734                         {
735                             if (regex_match.GetMatchAtIndex(s, 2, str))
736                             {
737                                 add = str[0] == '+';
738                                 
739                                 if (regex_match.GetMatchAtIndex(s, 3, str))
740                                 {
741                                     offset = StringConvert::ToUInt64(str.c_str(), 0, 0, &success);
742                                     
743                                     if (success)
744                                     {
745                                         Error error;
746                                         addr = StringToAddress (exe_ctx, name.c_str(), LLDB_INVALID_ADDRESS, &error);
747                                         if (addr != LLDB_INVALID_ADDRESS)
748                                         {
749                                             if (add)
750                                                 return addr + offset;
751                                             else
752                                                 return addr - offset;
753                                         }
754                                     }
755                                 }
756                             }
757                         }
758                     }
759                     
760                     if (error_ptr)
761                     {
762                         error_set = true;
763                         error_ptr->SetErrorStringWithFormat("address expression \"%s\" evaluation failed", s);
764                     }
765                 }
766             }
767         }
768     }
769     if (error_ptr)
770     {
771         if (!error_set)
772             error_ptr->SetErrorStringWithFormat("invalid address expression \"%s\"", s);
773     }
774     return fail_value;
775 }
776
777 const char *
778 Args::StripSpaces (std::string &s, bool leading, bool trailing, bool return_null_if_empty)
779 {
780     static const char *k_white_space = " \t\v";
781     if (!s.empty())
782     {
783         if (leading)
784         {
785             size_t pos = s.find_first_not_of (k_white_space);
786             if (pos == std::string::npos)
787                 s.clear();
788             else if (pos > 0)
789                 s.erase(0, pos);
790         }
791         
792         if (trailing)
793         {
794             size_t rpos = s.find_last_not_of(k_white_space);
795             if (rpos != std::string::npos && rpos + 1 < s.size())
796                 s.erase(rpos + 1);
797         }
798     }
799     if (return_null_if_empty && s.empty())
800         return nullptr;
801     return s.c_str();
802 }
803
804 bool
805 Args::StringToBoolean (const char *s, bool fail_value, bool *success_ptr)
806 {
807     llvm::StringRef ref = llvm::StringRef(s).trim();
808     if (ref.equals_lower("false") ||
809         ref.equals_lower("off") ||
810         ref.equals_lower("no") ||
811         ref.equals_lower("0"))
812     {
813         if (success_ptr)
814             *success_ptr = true;
815         return false;
816     }
817     else
818     if (ref.equals_lower("true") ||
819         ref.equals_lower("on") ||
820         ref.equals_lower("yes") ||
821         ref.equals_lower("1"))
822     {
823         if (success_ptr) *success_ptr = true;
824         return true;
825     }
826     if (success_ptr) *success_ptr = false;
827     return fail_value;
828 }
829
830 char
831 Args::StringToChar(const char *s, char fail_value, bool *success_ptr)
832 {
833     bool success = false;
834     char result = fail_value;
835
836     if (s)
837     {
838         size_t length = strlen(s);
839         if (length == 1)
840         {
841             success = true;
842             result = s[0];
843         }
844     }
845     if (success_ptr)
846         *success_ptr = success;
847     return result;
848 }
849
850 const char *
851 Args::StringToVersion (const char *s, uint32_t &major, uint32_t &minor, uint32_t &update)
852 {
853     major = UINT32_MAX;
854     minor = UINT32_MAX;
855     update = UINT32_MAX;
856
857     if (s && s[0])
858     {
859         char *pos = nullptr;
860         unsigned long uval32 = ::strtoul (s, &pos, 0);
861         if (pos == s)
862             return s;
863         major = uval32;
864         if (*pos == '\0')
865         {
866             return pos;   // Decoded major and got end of string
867         }
868         else if (*pos == '.')
869         {
870             const char *minor_cstr = pos + 1;
871             uval32 = ::strtoul (minor_cstr, &pos, 0);
872             if (pos == minor_cstr)
873                 return pos; // Didn't get any digits for the minor version...
874             minor = uval32;
875             if (*pos == '.')
876             {
877                 const char *update_cstr = pos + 1;
878                 uval32 = ::strtoul (update_cstr, &pos, 0);
879                 if (pos == update_cstr)
880                     return pos;
881                 update = uval32;
882             }
883             return pos;
884         }
885     }
886     return nullptr;
887 }
888
889 const char *
890 Args::GetShellSafeArgument (const char *unsafe_arg, std::string &safe_arg)
891 {
892     safe_arg.assign (unsafe_arg);
893     size_t prev_pos = 0;
894     while (prev_pos < safe_arg.size())
895     {
896         // Escape spaces and quotes
897         size_t pos = safe_arg.find_first_of(" '\"", prev_pos);
898         if (pos != std::string::npos)
899         {
900             safe_arg.insert (pos, 1, '\\');
901             prev_pos = pos + 2;
902         }
903         else
904             break;
905     }
906     return safe_arg.c_str();
907 }
908
909
910 int64_t
911 Args::StringToOptionEnum (const char *s, OptionEnumValueElement *enum_values, int32_t fail_value, Error &error)
912 {    
913     if (enum_values)
914     {
915         if (s && s[0])
916         {
917             for (int i = 0; enum_values[i].string_value != nullptr ; i++)
918             {
919                 if (strstr(enum_values[i].string_value, s) == enum_values[i].string_value)
920                 {
921                     error.Clear();
922                     return enum_values[i].value;
923                 }
924             }
925         }
926
927         StreamString strm;
928         strm.PutCString ("invalid enumeration value, valid values are: ");
929         for (int i = 0; enum_values[i].string_value != nullptr; i++)
930         {
931             strm.Printf ("%s\"%s\"", 
932                          i > 0 ? ", " : "",
933                          enum_values[i].string_value);
934         }
935         error.SetErrorString(strm.GetData());
936     }
937     else
938     {
939         error.SetErrorString ("invalid enumeration argument");
940     }
941     return fail_value;
942 }
943
944 ScriptLanguage
945 Args::StringToScriptLanguage (const char *s, ScriptLanguage fail_value, bool *success_ptr)
946 {
947     if (s && s[0])
948     {
949         if ((::strcasecmp (s, "python") == 0) ||
950             (::strcasecmp (s, "default") == 0 && eScriptLanguagePython == eScriptLanguageDefault))
951         {
952             if (success_ptr) *success_ptr = true;
953             return eScriptLanguagePython;
954         }
955         if (::strcasecmp (s, "none"))
956         {
957             if (success_ptr) *success_ptr = true;
958             return eScriptLanguageNone;
959         }
960     }
961     if (success_ptr) *success_ptr = false;
962     return fail_value;
963 }
964
965 Error
966 Args::StringToFormat
967 (
968     const char *s,
969     lldb::Format &format,
970     size_t *byte_size_ptr
971 )
972 {
973     format = eFormatInvalid;
974     Error error;
975
976     if (s && s[0])
977     {
978         if (byte_size_ptr)
979         {
980             if (isdigit (s[0]))
981             {
982                 char *format_char = nullptr;
983                 unsigned long byte_size = ::strtoul (s, &format_char, 0);
984                 if (byte_size != ULONG_MAX)
985                     *byte_size_ptr = byte_size;
986                 s = format_char;
987             }
988             else
989                 *byte_size_ptr = 0;
990         }
991
992         const bool partial_match_ok = true;
993         if (!FormatManager::GetFormatFromCString (s, partial_match_ok, format))
994         {
995             StreamString error_strm;
996             error_strm.Printf ("Invalid format character or name '%s'. Valid values are:\n", s);
997             for (Format f = eFormatDefault; f < kNumFormats; f = Format(f+1))
998             {
999                 char format_char = FormatManager::GetFormatAsFormatChar(f);
1000                 if (format_char)
1001                     error_strm.Printf ("'%c' or ", format_char);
1002             
1003                 error_strm.Printf ("\"%s\"", FormatManager::GetFormatAsCString(f));
1004                 error_strm.EOL();
1005             }
1006             
1007             if (byte_size_ptr)
1008                 error_strm.PutCString ("An optional byte size can precede the format character.\n");
1009             error.SetErrorString(error_strm.GetString().c_str());
1010         }
1011
1012         if (error.Fail())
1013             return error;
1014     }
1015     else
1016     {
1017         error.SetErrorStringWithFormat("%s option string", s ? "empty" : "invalid");
1018     }
1019     return error;
1020 }
1021
1022 lldb::Encoding
1023 Args::StringToEncoding (const char *s, lldb::Encoding fail_value)
1024 {
1025     if (s && s[0])
1026     {
1027         if (strcmp(s, "uint") == 0)
1028             return eEncodingUint;
1029         else if (strcmp(s, "sint") == 0)
1030             return eEncodingSint;
1031         else if (strcmp(s, "ieee754") == 0)
1032             return eEncodingIEEE754;
1033         else if (strcmp(s, "vector") == 0)
1034             return eEncodingVector;
1035     }
1036     return fail_value;
1037 }
1038
1039 uint32_t
1040 Args::StringToGenericRegister (const char *s)
1041 {
1042     if (s && s[0])
1043     {
1044         if (strcmp(s, "pc") == 0)
1045             return LLDB_REGNUM_GENERIC_PC;
1046         else if (strcmp(s, "sp") == 0)
1047             return LLDB_REGNUM_GENERIC_SP;
1048         else if (strcmp(s, "fp") == 0)
1049             return LLDB_REGNUM_GENERIC_FP;
1050         else if (strcmp(s, "ra") == 0 || strcmp(s, "lr") == 0)
1051             return LLDB_REGNUM_GENERIC_RA;
1052         else if (strcmp(s, "flags") == 0)
1053             return LLDB_REGNUM_GENERIC_FLAGS;
1054         else if (strncmp(s, "arg", 3) == 0)
1055         {
1056             if (s[3] && s[4] == '\0')
1057             {
1058                 switch (s[3])
1059                 {
1060                     case '1': return LLDB_REGNUM_GENERIC_ARG1;
1061                     case '2': return LLDB_REGNUM_GENERIC_ARG2;
1062                     case '3': return LLDB_REGNUM_GENERIC_ARG3;
1063                     case '4': return LLDB_REGNUM_GENERIC_ARG4;
1064                     case '5': return LLDB_REGNUM_GENERIC_ARG5;
1065                     case '6': return LLDB_REGNUM_GENERIC_ARG6;
1066                     case '7': return LLDB_REGNUM_GENERIC_ARG7;
1067                     case '8': return LLDB_REGNUM_GENERIC_ARG8;
1068                 }
1069             }
1070         }
1071     }
1072     return LLDB_INVALID_REGNUM;
1073 }
1074
1075
1076 void
1077 Args::LongestCommonPrefix (std::string &common_prefix)
1078 {
1079     arg_sstr_collection::iterator pos, end = m_args.end();
1080     pos = m_args.begin();
1081     if (pos == end)
1082         common_prefix.clear();
1083     else
1084         common_prefix = (*pos);
1085
1086     for (++pos; pos != end; ++pos)
1087     {
1088         size_t new_size = (*pos).size();
1089
1090         // First trim common_prefix if it is longer than the current element:
1091         if (common_prefix.size() > new_size)
1092             common_prefix.erase (new_size);
1093
1094         // Then trim it at the first disparity:
1095
1096         for (size_t i = 0; i < common_prefix.size(); i++)
1097         {
1098             if ((*pos)[i]  != common_prefix[i])
1099             {
1100                 common_prefix.erase(i);
1101                 break;
1102             }
1103         }
1104
1105         // If we've emptied the common prefix, we're done.
1106         if (common_prefix.empty())
1107             break;
1108     }
1109 }
1110
1111 size_t
1112 Args::FindArgumentIndexForOption (Option *long_options, int long_options_index)
1113 {
1114     char short_buffer[3];
1115     char long_buffer[255];
1116     ::snprintf (short_buffer, sizeof (short_buffer), "-%c", long_options[long_options_index].val);
1117     ::snprintf (long_buffer, sizeof (long_buffer),  "--%s", long_options[long_options_index].definition->long_option);
1118     size_t end = GetArgumentCount ();
1119     size_t idx = 0;
1120     while (idx < end)
1121     {   
1122         if ((::strncmp (GetArgumentAtIndex (idx), short_buffer, strlen (short_buffer)) == 0)
1123             || (::strncmp (GetArgumentAtIndex (idx), long_buffer, strlen (long_buffer)) == 0))
1124             {
1125                 return idx;
1126             }
1127         ++idx;
1128     }
1129
1130     return end;
1131 }
1132
1133 bool
1134 Args::IsPositionalArgument (const char *arg)
1135 {
1136     if (arg == nullptr)
1137         return false;
1138         
1139     bool is_positional = true;
1140     const char *cptr = arg;
1141     
1142     if (cptr[0] == '%')
1143     {
1144         ++cptr;
1145         while (isdigit (cptr[0]))
1146             ++cptr;
1147         if (cptr[0] != '\0')
1148             is_positional = false;
1149     }
1150     else
1151         is_positional = false;
1152
1153     return is_positional;
1154 }
1155
1156 void
1157 Args::ParseAliasOptions (Options &options,
1158                          CommandReturnObject &result,
1159                          OptionArgVector *option_arg_vector,
1160                          std::string &raw_input_string)
1161 {
1162     StreamString sstr;
1163     int i;
1164     Option *long_options = options.GetLongOptions();
1165
1166     if (long_options == nullptr)
1167     {
1168         result.AppendError ("invalid long options");
1169         result.SetStatus (eReturnStatusFailed);
1170         return;
1171     }
1172
1173     for (i = 0; long_options[i].definition != nullptr; ++i)
1174     {
1175         if (long_options[i].flag == nullptr)
1176         {
1177             sstr << (char) long_options[i].val;
1178             switch (long_options[i].definition->option_has_arg)
1179             {
1180                 default:
1181                 case OptionParser::eNoArgument:
1182                     break;
1183                 case OptionParser::eRequiredArgument:
1184                     sstr << ":";
1185                     break;
1186                 case OptionParser::eOptionalArgument:
1187                     sstr << "::";
1188                     break;
1189             }
1190         }
1191     }
1192
1193     Mutex::Locker options_locker(NULL);
1194     OptionParser::Prepare(options_locker);
1195     int val;
1196     while (1)
1197     {
1198         int long_options_index = -1;
1199         val = OptionParser::Parse (GetArgumentCount(),
1200                                   GetArgumentVector(),
1201                                   sstr.GetData(),
1202                                   long_options,
1203                                   &long_options_index);
1204
1205         if (val == -1)
1206             break;
1207
1208         if (val == '?')
1209         {
1210             result.AppendError ("unknown or ambiguous option");
1211             result.SetStatus (eReturnStatusFailed);
1212             break;
1213         }
1214
1215         if (val == 0)
1216             continue;
1217
1218         options.OptionSeen (val);
1219
1220         // Look up the long option index
1221         if (long_options_index == -1)
1222         {
1223             for (int j = 0;
1224                  long_options[j].definition || long_options[j].flag || long_options[j].val;
1225                  ++j)
1226             {
1227                 if (long_options[j].val == val)
1228                 {
1229                     long_options_index = j;
1230                     break;
1231                 }
1232             }
1233         }
1234
1235         // See if the option takes an argument, and see if one was supplied.
1236         if (long_options_index >= 0)
1237         {
1238             StreamString option_str;
1239             option_str.Printf ("-%c", val);
1240             const OptionDefinition *def = long_options[long_options_index].definition;
1241             int has_arg = (def == nullptr) ? OptionParser::eNoArgument : def->option_has_arg;
1242
1243             switch (has_arg)
1244             {
1245             case OptionParser::eNoArgument:
1246                 option_arg_vector->push_back (OptionArgPair (std::string (option_str.GetData()), 
1247                                                              OptionArgValue (OptionParser::eNoArgument, "<no-argument>")));
1248                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1249                 break;
1250             case OptionParser::eRequiredArgument:
1251                 if (OptionParser::GetOptionArgument() != nullptr)
1252                 {
1253                     option_arg_vector->push_back (OptionArgPair (std::string (option_str.GetData()),
1254                                                                  OptionArgValue (OptionParser::eRequiredArgument,
1255                                                                                  std::string (OptionParser::GetOptionArgument()))));
1256                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1257                 }
1258                 else
1259                 {
1260                     result.AppendErrorWithFormat ("Option '%s' is missing argument specifier.\n",
1261                                                  option_str.GetData());
1262                     result.SetStatus (eReturnStatusFailed);
1263                 }
1264                 break;
1265             case OptionParser::eOptionalArgument:
1266                 if (OptionParser::GetOptionArgument() != nullptr)
1267                 {
1268                     option_arg_vector->push_back (OptionArgPair (std::string (option_str.GetData()),
1269                                                                  OptionArgValue (OptionParser::eOptionalArgument,
1270                                                                                  std::string (OptionParser::GetOptionArgument()))));
1271                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1272                 }
1273                 else
1274                 {
1275                     option_arg_vector->push_back (OptionArgPair (std::string (option_str.GetData()),
1276                                                                  OptionArgValue (OptionParser::eOptionalArgument, "<no-argument>")));
1277                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1278                 }
1279                 break;
1280             default:
1281                 result.AppendErrorWithFormat ("error with options table; invalid value in has_arg field for option '%c'.\n", val);
1282                 result.SetStatus (eReturnStatusFailed);
1283                 break;
1284             }
1285         }
1286         else
1287         {
1288             result.AppendErrorWithFormat ("Invalid option with value '%c'.\n", val);
1289             result.SetStatus (eReturnStatusFailed);
1290         }
1291
1292         if (long_options_index >= 0)
1293         {
1294             // Find option in the argument list; also see if it was supposed to take an argument and if one was
1295             // supplied.  Remove option (and argument, if given) from the argument list.  Also remove them from
1296             // the raw_input_string, if one was passed in.
1297             size_t idx = FindArgumentIndexForOption (long_options, long_options_index);
1298             if (idx < GetArgumentCount())
1299             {
1300                 if (raw_input_string.size() > 0)
1301                 {
1302                     const char *tmp_arg = GetArgumentAtIndex (idx);
1303                     size_t pos = raw_input_string.find (tmp_arg);
1304                     if (pos != std::string::npos)
1305                         raw_input_string.erase (pos, strlen (tmp_arg));
1306                 }
1307                 ReplaceArgumentAtIndex (idx, "");
1308                 if ((long_options[long_options_index].definition->option_has_arg != OptionParser::eNoArgument)
1309                     && (OptionParser::GetOptionArgument() != nullptr)
1310                     && (idx+1 < GetArgumentCount())
1311                     && (strcmp (OptionParser::GetOptionArgument(), GetArgumentAtIndex(idx+1)) == 0))
1312                 {
1313                     if (raw_input_string.size() > 0)
1314                     {
1315                         const char *tmp_arg = GetArgumentAtIndex (idx+1);
1316                         size_t pos = raw_input_string.find (tmp_arg);
1317                         if (pos != std::string::npos)
1318                             raw_input_string.erase (pos, strlen (tmp_arg));
1319                     }
1320                     ReplaceArgumentAtIndex (idx+1, "");
1321                 }
1322             }
1323         }
1324
1325         if (!result.Succeeded())
1326             break;
1327     }
1328 }
1329
1330 void
1331 Args::ParseArgsForCompletion
1332 (
1333     Options &options,
1334     OptionElementVector &option_element_vector,
1335     uint32_t cursor_index
1336 )
1337 {
1338     StreamString sstr;
1339     Option *long_options = options.GetLongOptions();
1340     option_element_vector.clear();
1341
1342     if (long_options == nullptr)
1343     {
1344         return;
1345     }
1346
1347     // Leading : tells getopt to return a : for a missing option argument AND
1348     // to suppress error messages.
1349
1350     sstr << ":";
1351     for (int i = 0; long_options[i].definition != nullptr; ++i)
1352     {
1353         if (long_options[i].flag == nullptr)
1354         {
1355             sstr << (char) long_options[i].val;
1356             switch (long_options[i].definition->option_has_arg)
1357             {
1358                 default:
1359                 case OptionParser::eNoArgument:
1360                     break;
1361                 case OptionParser::eRequiredArgument:
1362                     sstr << ":";
1363                     break;
1364                 case OptionParser::eOptionalArgument:
1365                     sstr << "::";
1366                     break;
1367             }
1368         }
1369     }
1370
1371     Mutex::Locker options_locker(NULL);
1372     OptionParser::Prepare(options_locker);
1373     OptionParser::EnableError(false);
1374
1375     int val;
1376     const OptionDefinition *opt_defs = options.GetDefinitions();
1377
1378     // Fooey... OptionParser::Parse permutes the GetArgumentVector to move the options to the front.
1379     // So we have to build another Arg and pass that to OptionParser::Parse so it doesn't
1380     // change the one we have.
1381
1382     std::vector<const char *> dummy_vec (GetArgumentVector(), GetArgumentVector() + GetArgumentCount() + 1);
1383
1384     bool failed_once = false;
1385     uint32_t dash_dash_pos = -1;
1386         
1387     while (1)
1388     {
1389         bool missing_argument = false;
1390         int long_options_index = -1;
1391         
1392         val = OptionParser::Parse (dummy_vec.size() - 1,
1393                                   const_cast<char *const *>(&dummy_vec.front()),
1394                                   sstr.GetData(),
1395                                   long_options,
1396                                   &long_options_index);
1397
1398         if (val == -1)
1399         {
1400             // When we're completing a "--" which is the last option on line, 
1401             if (failed_once)
1402                 break;
1403                 
1404             failed_once = true;
1405             
1406             // If this is a bare  "--" we mark it as such so we can complete it successfully later.
1407             // Handling the "--" is a little tricky, since that may mean end of options or arguments, or the
1408             // user might want to complete options by long name.  I make this work by checking whether the
1409             // cursor is in the "--" argument, and if so I assume we're completing the long option, otherwise
1410             // I let it pass to OptionParser::Parse which will terminate the option parsing.
1411             // Note, in either case we continue parsing the line so we can figure out what other options
1412             // were passed.  This will be useful when we come to restricting completions based on what other
1413             // options we've seen on the line.
1414
1415             if (static_cast<size_t>(OptionParser::GetOptionIndex()) < dummy_vec.size() - 1
1416                 && (strcmp (dummy_vec[OptionParser::GetOptionIndex()-1], "--") == 0))
1417             {
1418                 dash_dash_pos = OptionParser::GetOptionIndex() - 1;
1419                 if (static_cast<size_t>(OptionParser::GetOptionIndex() - 1) == cursor_index)
1420                 {
1421                     option_element_vector.push_back (OptionArgElement (OptionArgElement::eBareDoubleDash, OptionParser::GetOptionIndex() - 1,
1422                                                                    OptionArgElement::eBareDoubleDash));
1423                     continue;
1424                 }
1425                 else
1426                     break;
1427             }
1428             else
1429                 break;
1430         }
1431         else if (val == '?')
1432         {
1433             option_element_vector.push_back (OptionArgElement (OptionArgElement::eUnrecognizedArg, OptionParser::GetOptionIndex() - 1,
1434                                                                OptionArgElement::eUnrecognizedArg));
1435             continue;
1436         }
1437         else if (val == 0)
1438         {
1439             continue;
1440         }
1441         else if (val == ':')
1442         {
1443             // This is a missing argument.
1444             val = OptionParser::GetOptionErrorCause();
1445             missing_argument = true;
1446         }
1447
1448         ((Options *) &options)->OptionSeen (val);
1449
1450         // Look up the long option index
1451         if (long_options_index == -1)
1452         {
1453             for (int j = 0;
1454                  long_options[j].definition || long_options[j].flag || long_options[j].val;
1455                  ++j)
1456             {
1457                 if (long_options[j].val == val)
1458                 {
1459                     long_options_index = j;
1460                     break;
1461                 }
1462             }
1463         }
1464
1465         // See if the option takes an argument, and see if one was supplied.
1466         if (long_options_index >= 0)
1467         {
1468             int opt_defs_index = -1;
1469             for (int i = 0; ; i++)
1470             {
1471                 if (opt_defs[i].short_option == 0)
1472                     break;
1473                 else if (opt_defs[i].short_option == val)
1474                 {
1475                     opt_defs_index = i;
1476                     break;
1477                 }
1478             }
1479
1480             const OptionDefinition *def = long_options[long_options_index].definition;
1481             int has_arg = (def == nullptr) ? OptionParser::eNoArgument : def->option_has_arg;
1482             switch (has_arg)
1483             {
1484             case OptionParser::eNoArgument:
1485                 option_element_vector.push_back (OptionArgElement (opt_defs_index, OptionParser::GetOptionIndex() - 1, 0));
1486                 break;
1487             case OptionParser::eRequiredArgument:
1488                 if (OptionParser::GetOptionArgument() != nullptr)
1489                 {
1490                     int arg_index;
1491                     if (missing_argument)
1492                         arg_index = -1;
1493                     else
1494                         arg_index = OptionParser::GetOptionIndex() - 1;
1495
1496                     option_element_vector.push_back (OptionArgElement (opt_defs_index, OptionParser::GetOptionIndex() - 2, arg_index));
1497                 }
1498                 else
1499                 {
1500                     option_element_vector.push_back (OptionArgElement (opt_defs_index, OptionParser::GetOptionIndex() - 1, -1));
1501                 }
1502                 break;
1503             case OptionParser::eOptionalArgument:
1504                 if (OptionParser::GetOptionArgument() != nullptr)
1505                 {
1506                     option_element_vector.push_back (OptionArgElement (opt_defs_index, OptionParser::GetOptionIndex() - 2, OptionParser::GetOptionIndex() - 1));
1507                 }
1508                 else
1509                 {
1510                     option_element_vector.push_back (OptionArgElement (opt_defs_index, OptionParser::GetOptionIndex() - 2, OptionParser::GetOptionIndex() - 1));
1511                 }
1512                 break;
1513             default:
1514                 // The options table is messed up.  Here we'll just continue
1515                 option_element_vector.push_back (OptionArgElement (OptionArgElement::eUnrecognizedArg, OptionParser::GetOptionIndex() - 1,
1516                                                                    OptionArgElement::eUnrecognizedArg));
1517                 break;
1518             }
1519         }
1520         else
1521         {
1522             option_element_vector.push_back (OptionArgElement (OptionArgElement::eUnrecognizedArg, OptionParser::GetOptionIndex() - 1,
1523                                                                OptionArgElement::eUnrecognizedArg));
1524         }
1525     }
1526     
1527     // Finally we have to handle the case where the cursor index points at a single "-".  We want to mark that in
1528     // the option_element_vector, but only if it is not after the "--".  But it turns out that OptionParser::Parse just ignores
1529     // an isolated "-".  So we have to look it up by hand here.  We only care if it is AT the cursor position.
1530     // Note, a single quoted dash is not the same as a single dash...
1531     
1532     if ((static_cast<int32_t>(dash_dash_pos) == -1 || cursor_index < dash_dash_pos)
1533          && m_args_quote_char[cursor_index] == '\0'
1534          && strcmp (GetArgumentAtIndex(cursor_index), "-") == 0)
1535     {
1536         option_element_vector.push_back (OptionArgElement (OptionArgElement::eBareDash, cursor_index, 
1537                                                            OptionArgElement::eBareDash));
1538         
1539     }
1540 }
1541
1542 void
1543 Args::EncodeEscapeSequences (const char *src, std::string &dst)
1544 {
1545     dst.clear();
1546     if (src)
1547     {
1548         for (const char *p = src; *p != '\0'; ++p)
1549         {
1550             size_t non_special_chars = ::strcspn (p, "\\");
1551             if (non_special_chars > 0)
1552             {
1553                 dst.append(p, non_special_chars);
1554                 p += non_special_chars;
1555                 if (*p == '\0')
1556                     break;
1557             }
1558             
1559             if (*p == '\\')
1560             {
1561                 ++p; // skip the slash
1562                 switch (*p)
1563                 {
1564                     case 'a' : dst.append(1, '\a'); break;
1565                     case 'b' : dst.append(1, '\b'); break;
1566                     case 'f' : dst.append(1, '\f'); break;
1567                     case 'n' : dst.append(1, '\n'); break;
1568                     case 'r' : dst.append(1, '\r'); break;
1569                     case 't' : dst.append(1, '\t'); break;
1570                     case 'v' : dst.append(1, '\v'); break;
1571                     case '\\': dst.append(1, '\\'); break;
1572                     case '\'': dst.append(1, '\''); break;
1573                     case '"' : dst.append(1, '"'); break;
1574                     case '0' :
1575                         // 1 to 3 octal chars
1576                     {
1577                         // Make a string that can hold onto the initial zero char,
1578                         // up to 3 octal digits, and a terminating NULL.
1579                         char oct_str[5] = { '\0', '\0', '\0', '\0', '\0' };
1580                         
1581                         int i;
1582                         for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
1583                             oct_str[i] = p[i];
1584                         
1585                         // We don't want to consume the last octal character since
1586                         // the main for loop will do this for us, so we advance p by
1587                         // one less than i (even if i is zero)
1588                         p += i - 1;
1589                         unsigned long octal_value = ::strtoul (oct_str, nullptr, 8);
1590                         if (octal_value <= UINT8_MAX)
1591                         {
1592                             dst.append(1, (char)octal_value);
1593                         }
1594                     }
1595                         break;
1596                         
1597                     case 'x':
1598                         // hex number in the format
1599                         if (isxdigit(p[1]))
1600                         {
1601                             ++p;    // Skip the 'x'
1602                             
1603                             // Make a string that can hold onto two hex chars plus a
1604                             // NULL terminator
1605                             char hex_str[3] = { *p, '\0', '\0' };
1606                             if (isxdigit(p[1]))
1607                             {
1608                                 ++p; // Skip the first of the two hex chars
1609                                 hex_str[1] = *p;
1610                             }
1611                             
1612                             unsigned long hex_value = strtoul (hex_str, nullptr, 16);
1613                             if (hex_value <= UINT8_MAX)
1614                                 dst.append (1, (char)hex_value);
1615                         }
1616                         else
1617                         {
1618                             dst.append(1, 'x');
1619                         }
1620                         break;
1621                         
1622                     default:
1623                         // Just desensitize any other character by just printing what
1624                         // came after the '\'
1625                         dst.append(1, *p);
1626                         break;
1627                         
1628                 }
1629             }
1630         }
1631     }
1632 }
1633
1634
1635 void
1636 Args::ExpandEscapedCharacters (const char *src, std::string &dst)
1637 {
1638     dst.clear();
1639     if (src)
1640     {
1641         for (const char *p = src; *p != '\0'; ++p)
1642         {
1643             if (isprint8(*p))
1644                 dst.append(1, *p);
1645             else
1646             {
1647                 switch (*p)
1648                 {
1649                     case '\a': dst.append("\\a"); break;
1650                     case '\b': dst.append("\\b"); break;
1651                     case '\f': dst.append("\\f"); break;
1652                     case '\n': dst.append("\\n"); break;
1653                     case '\r': dst.append("\\r"); break;
1654                     case '\t': dst.append("\\t"); break;
1655                     case '\v': dst.append("\\v"); break;
1656                     case '\'': dst.append("\\'"); break;
1657                     case '"': dst.append("\\\""); break;
1658                     case '\\': dst.append("\\\\"); break;
1659                     default:
1660                         {
1661                             // Just encode as octal
1662                             dst.append("\\0");
1663                             char octal_str[32];
1664                             snprintf(octal_str, sizeof(octal_str), "%o", *p);
1665                             dst.append(octal_str);
1666                         }
1667                         break;
1668                 }
1669             }
1670         }
1671     }
1672 }
1673
1674 std::string
1675 Args::EscapeLLDBCommandArgument (const std::string& arg, char quote_char)
1676 {
1677     const char* chars_to_escape = nullptr;
1678     switch (quote_char)
1679     {
1680         case '\0':
1681             chars_to_escape = " \t\\'\"`";
1682             break;
1683         case '\'':
1684             chars_to_escape = "";
1685             break;
1686         case '"':
1687             chars_to_escape = "$\"`\\";
1688             break;
1689         default:
1690             assert(false && "Unhandled quote character");
1691     }
1692
1693     std::string res;
1694     res.reserve(arg.size());
1695     for (char c : arg)
1696     {
1697         if (::strchr(chars_to_escape, c))
1698             res.push_back('\\');
1699         res.push_back(c);
1700     }
1701     return res;
1702 }
1703