parse: lex: improve scanning of more complex redirection expressions
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
#include "../token.h"
|
||||
#include "lex-internal.h"
|
||||
|
||||
static bool char_can_continue_word(struct lex_ctx *ctx, fx_wchar c)
|
||||
@@ -34,6 +35,8 @@ static enum bshell_status command_symbol(struct lex_ctx *ctx)
|
||||
|
||||
struct lex_token *tok = NULL;
|
||||
switch (sym->id) {
|
||||
case SYM_DQUOTE:
|
||||
return BSHELL_SUCCESS;
|
||||
case SYM_SQUOTE:
|
||||
status = read_literal_string(ctx, &tok);
|
||||
if (status != BSHELL_SUCCESS) {
|
||||
@@ -85,6 +88,39 @@ static enum bshell_status command_symbol(struct lex_ctx *ctx)
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
static bool string_is_redirection(const char *s)
|
||||
{
|
||||
if (!*s) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!strcmp(s, ">") || !strcmp(s, ">>")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
long nr_angles = 0;
|
||||
for (size_t i = 0; s[i];) {
|
||||
fx_wchar c = fx_wchar_utf8_codepoint_decode(s);
|
||||
if (fx_wchar_is_number(c)) {
|
||||
if (nr_angles) {
|
||||
return false;
|
||||
}
|
||||
} else if (c == '>') {
|
||||
nr_angles++;
|
||||
|
||||
if (nr_angles > 2) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
s += fx_wchar_utf8_codepoint_stride(s);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static enum bshell_status command_word(struct lex_ctx *ctx)
|
||||
{
|
||||
struct lex_token *word = NULL;
|
||||
@@ -97,6 +133,7 @@ static enum bshell_status command_word(struct lex_ctx *ctx)
|
||||
bool continue_word = false;
|
||||
|
||||
fx_wchar c = peek_char(ctx);
|
||||
const char *s = word->tok_str;
|
||||
if (char_can_begin_symbol_in_state(ctx, c, LEX_STATE_WORD)) {
|
||||
continue_word = true;
|
||||
}
|
||||
@@ -105,6 +142,10 @@ static enum bshell_status command_word(struct lex_ctx *ctx)
|
||||
continue_word = false;
|
||||
}
|
||||
|
||||
if (string_is_redirection(s)) {
|
||||
continue_word = false;
|
||||
}
|
||||
|
||||
if (continue_word) {
|
||||
lex_state_push(ctx, LEX_STATE_WORD, 0);
|
||||
}
|
||||
@@ -171,6 +212,8 @@ static const unsigned int symbols[] = {
|
||||
SYM_PIPE,
|
||||
SYM_SEMICOLON,
|
||||
SYM_RIGHT_PAREN,
|
||||
SYM_LEFT_PAREN,
|
||||
SYM_LEFT_BRACE,
|
||||
SYM_RIGHT_BRACE,
|
||||
SYM_NONE,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user