Add && and || support to tokenizer

This commit is contained in:
ridiculousfish 2018-03-01 12:56:15 -08:00
parent a5dd96558f
commit 8ded041352
5 changed files with 56 additions and 45 deletions

View file

@ -535,10 +535,14 @@ static void test_tokenizer() {
const wchar_t *str = const wchar_t *str =
L"string <redirection 2>&1 'nested \"quoted\" '(string containing subshells " L"string <redirection 2>&1 'nested \"quoted\" '(string containing subshells "
L"){and,brackets}$as[$well (as variable arrays)] not_a_redirect^ ^ ^^is_a_redirect " L"){and,brackets}$as[$well (as variable arrays)] not_a_redirect^ ^ ^^is_a_redirect "
L"&&& ||| "
L"&& || & |"
L"Compress_Newlines\n \n\t\n \nInto_Just_One"; L"Compress_Newlines\n \n\t\n \nInto_Just_One";
const int types[] = {TOK_STRING, TOK_REDIRECT, TOK_STRING, TOK_REDIRECT, TOK_STRING, const int types[] = {TOK_STRING, TOK_REDIRECT, TOK_STRING, TOK_REDIRECT, TOK_STRING,
TOK_STRING, TOK_STRING, TOK_REDIRECT, TOK_REDIRECT, TOK_STRING, TOK_STRING, TOK_STRING, TOK_REDIRECT, TOK_REDIRECT, TOK_STRING,
TOK_STRING, TOK_END, TOK_STRING}; TOK_ANDAND, TOK_BACKGROUND, TOK_OROR, TOK_PIPE, TOK_ANDAND,
TOK_OROR, TOK_BACKGROUND, TOK_PIPE, TOK_STRING, TOK_END,
TOK_STRING};
say(L"Test correct tokenization"); say(L"Test correct tokenization");

View file

@ -1773,6 +1773,10 @@ static bool should_import_bash_history_line(const std::string &line) {
if (line.find("((") != std::string::npos) return false; if (line.find("((") != std::string::npos) return false;
if (line.find("))") != std::string::npos) return false; if (line.find("))") != std::string::npos) return false;
// Temporarily skip lines with && and ||
if (line.find("&&") != std::string::npos) return false;
if (line.find("||") != std::string::npos) return false;
// Skip lines that end with a backslash. We do not handle multiline commands from bash history. // Skip lines that end with a backslash. We do not handle multiline commands from bash history.
if (line.back() == '\\') return false; if (line.back() == '\\') return false;

View file

@ -213,43 +213,32 @@ wcstring parse_token_t::user_presentable_description() const {
/// Convert from tokenizer_t's token type to a parse_token_t type. /// Convert from tokenizer_t's token type to a parse_token_t type.
static inline parse_token_type_t parse_token_type_from_tokenizer_token( static inline parse_token_type_t parse_token_type_from_tokenizer_token(
enum token_type tokenizer_token_type) { enum token_type tokenizer_token_type) {
parse_token_type_t result = token_type_invalid;
switch (tokenizer_token_type) { switch (tokenizer_token_type) {
case TOK_STRING: { case TOK_NONE:
result = parse_token_type_string; DIE("TOK_NONE passed to parse_token_type_from_tokenizer_token");
break; return token_type_invalid;
} case TOK_STRING:
case TOK_PIPE: { return parse_token_type_string;
result = parse_token_type_pipe; case TOK_PIPE:
break; return parse_token_type_pipe;
} case TOK_ANDAND:
case TOK_END: { case TOK_OROR:
result = parse_token_type_end; // Temporary while && and || support is brought up.
break; return parse_special_type_comment;
} case TOK_END:
case TOK_BACKGROUND: { return parse_token_type_end;
result = parse_token_type_background; case TOK_BACKGROUND:
break; return parse_token_type_background;
} case TOK_REDIRECT:
case TOK_REDIRECT: { return parse_token_type_redirection;
result = parse_token_type_redirection; case TOK_ERROR:
break; return parse_special_type_tokenizer_error;
} case TOK_COMMENT:
case TOK_ERROR: { return parse_special_type_comment;
result = parse_special_type_tokenizer_error;
break;
}
case TOK_COMMENT: {
result = parse_special_type_comment;
break;
}
default: {
debug(0, "Bad token type %d passed to %s", (int)tokenizer_token_type, __FUNCTION__);
DIE("bad token type");
break;
}
} }
return result; debug(0, "Bad token type %d passed to %s", (int)tokenizer_token_type, __FUNCTION__);
DIE("bad token type");
return token_type_invalid;
} }
/// Helper function for parse_dump_tree(). /// Helper function for parse_dump_tree().

View file

@ -528,16 +528,28 @@ maybe_t<tok_t> tokenizer_t::tok_next() {
break; break;
} }
case L'&': { case L'&': {
result.type = TOK_BACKGROUND; if (this->buff[1] == L'&') {
result.length = 1; result.type = TOK_ANDAND;
this->buff++; result.length = 2;
this->buff += 2;
} else {
result.type = TOK_BACKGROUND;
result.length = 1;
this->buff++;
}
break; break;
} }
case L'|': { case L'|': {
result.type = TOK_PIPE; if (this->buff[1] == L'|') {
result.redirected_fd = 1; result.type = TOK_OROR;
result.length = 1; result.length = 2;
this->buff++; this->buff += 2;
} else {
result.type = TOK_PIPE;
result.redirected_fd = 1;
result.length = 1;
this->buff++;
}
break; break;
} }
case L'>': case L'>':

View file

@ -14,6 +14,8 @@ enum token_type {
TOK_ERROR, /// Error reading token TOK_ERROR, /// Error reading token
TOK_STRING, /// String token TOK_STRING, /// String token
TOK_PIPE, /// Pipe token TOK_PIPE, /// Pipe token
TOK_ANDAND, /// && token
TOK_OROR, /// || token
TOK_END, /// End token (semicolon or newline, not literal end) TOK_END, /// End token (semicolon or newline, not literal end)
TOK_REDIRECT, /// redirection token TOK_REDIRECT, /// redirection token
TOK_BACKGROUND, /// send job to bg token TOK_BACKGROUND, /// send job to bg token