/************************************************************************* * vlc_parse_cmdline: Command line parsing into elements. * * The command line is composed of space/tab separated arguments. * Quotes can be used as argument delimiters and a backslash can be used to * escape a quote. *************************************************************************/ static void find_end_quote( char **s, char **ppsz_parser, int i_quote ) { int i_bcount = 0; while( **s ) { if( **s == '\\' ) { **ppsz_parser = **s; (*ppsz_parser)++; (*s)++; i_bcount++; } else if( **s == '"' || **s == '\'' ) { /* Preceeded by a number of '\' which we erase. */ *ppsz_parser -= i_bcount / 2; if( i_bcount & 1 ) { /* '\\' followed by a '"' or '\'' */ *ppsz_parser -= 1; **ppsz_parser = **s; (*ppsz_parser)++; (*s)++; i_bcount = 0; continue; } if( **s == i_quote ) { /* End */ return; } else { /* Different quoting */ int i_quote = **s; **ppsz_parser = **s; (*ppsz_parser)++; (*s)++; find_end_quote( s, ppsz_parser, i_quote ); **ppsz_parser = **s; (*ppsz_parser)++; (*s)++; } i_bcount = 0; } else { /* A regular character */ **ppsz_parser = **s; (*ppsz_parser)++; (*s)++; i_bcount = 0; } } }
static gdb::unique_xmalloc_ptr<char> explicit_location_lex_one (const char **inp, const struct language_defn *language, explicit_completion_info *completion_info) { const char *start = *inp; if (*start == '\0') return NULL; /* If quoted, skip to the ending quote. */ if (strchr (get_gdb_linespec_parser_quote_characters (), *start)) { if (completion_info != NULL) completion_info->quoted_arg_start = start; const char *end = find_end_quote (start + 1, *start); if (end == NULL) { if (completion_info == NULL) error (_("Unmatched quote, %s."), start); end = start + strlen (start); *inp = end; return gdb::unique_xmalloc_ptr<char> (savestring (start + 1, *inp - start - 1)); } if (completion_info != NULL) completion_info->quoted_arg_end = end; *inp = end + 1; return gdb::unique_xmalloc_ptr<char> (savestring (start + 1, *inp - start - 2)); } /* If the input starts with '-' or '+', the string ends with the next whitespace or comma. */ if (*start == '-' || *start == '+') { while (*inp[0] != '\0' && *inp[0] != ',' && !isspace (*inp[0])) ++(*inp); } else { /* Handle numbers first, stopping at the next whitespace or ','. */ while (isdigit (*inp[0])) ++(*inp); if (*inp[0] == '\0' || isspace (*inp[0]) || *inp[0] == ',') return gdb::unique_xmalloc_ptr<char> (savestring (start, *inp - start)); /* Otherwise stop at the next occurrence of whitespace, '\0', keyword, or ','. */ *inp = start; while ((*inp)[0] && (*inp)[0] != ',' && !(isspace ((*inp)[0]) || linespec_lexer_lex_keyword (&(*inp)[1]))) { /* Special case: C++ operator,. */ if (language->la_language == language_cplus && startswith (*inp, CP_OPERATOR_STR)) (*inp) += CP_OPERATOR_LEN; ++(*inp); } } if (*inp - start > 0) return gdb::unique_xmalloc_ptr<char> (savestring (start, *inp - start)); return NULL; }