Skip to content

Commit

Permalink
Merge pull request #74 from ErwannLesech/fix_space_doubleq
Browse files Browse the repository at this point in the history
Fix space words in double quote
  • Loading branch information
ErwannLesech authored Jan 20, 2024
2 parents 5e2fb46 + 70e20b6 commit f8bed40
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 10 deletions.
7 changes: 7 additions & 0 deletions src/ast/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ struct ast_node *ast_node_word(char *value)
return node;
}

struct ast_node *ast_node_word_double_quote(char *value)
{
struct ast_node *node = ast_node_new(AST_WORD_DOUBLE_QUOTE);
node->value = value;
return node;
}

void ast_append(struct ast_node *parent, struct ast_node *child)
{
if (parent->children == NULL)
Expand Down
10 changes: 9 additions & 1 deletion src/ast/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ enum ast_type
AST_OR,
AST_COMMAND,
AST_WORD_ASSIGNMENT,
AST_VARIABLE
AST_VARIABLE,
AST_WORD_DOUBLE_QUOTE
};

/**
Expand Down Expand Up @@ -79,6 +80,13 @@ void ast_free(struct ast_node *node);
*/
struct ast_node *ast_node_word(char *value);

/**
* \brief Create a new AST node of type AST_WORD_DOUBLE_QUOTE.
* \param value The value of the node.
* \return The new node.
*/
struct ast_node *ast_node_word_double_quote(char *value);

/**
* \brief Convert an AST type to a string.
* \param type The type to convert.
Expand Down
2 changes: 1 addition & 1 deletion src/execute/utils/ast_variable.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ int ast_eval_assignment(struct ast_node *node)
*/
char *handle_word(struct ast_node *node)
{
if (node->type == AST_WORD)
if (node->type == AST_WORD || node->type == AST_WORD_DOUBLE_QUOTE)
{
return node->value;
}
Expand Down
2 changes: 1 addition & 1 deletion src/execute/utils/builtin.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ void print_echo(struct ast_node *node, int enable_escapes, int j)
}
}
if (i != node->children_count - 1
&& node->children[i]->type != AST_VARIABLE)
&& node->children[i]->type != AST_VARIABLE && node->children[i]->type != AST_WORD_DOUBLE_QUOTE)
putchar(' ');
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/lexer/lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,8 @@ struct token parse_input_for_tok(struct lexer *lexer)
lexer->curr_tok.type = TOKEN_EOL;
}
// Else it's a word
token.type = TOKEN_WORD;
token.type = lexer->curr_tok.type == TOKEN_DOUBLE_QUOTE ? TOKEN_WORD_DOUBLE_QUOTE
: TOKEN_WORD;
token.data = word;
return token;
}
Expand Down
67 changes: 64 additions & 3 deletions src/lexer/tests/lexer2_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -928,7 +928,7 @@ Test(lexer2, variable_distinction_access_double_quote_with_string)
token_free(tok);

tok = lexer_pop(lexer);
cr_assert_eq(tok.type, TOKEN_WORD, "got %d", tok.type);
cr_assert_eq(tok.type, TOKEN_WORD_DOUBLE_QUOTE, "got %d", tok.type);
cr_assert_str_eq(tok.data, "variable:");
token_free(tok);

Expand Down Expand Up @@ -1099,9 +1099,70 @@ Test(lexer2, personalized_variable2)
token_free(tok);

tok = lexer_pop(lexer);
cr_assert_eq(tok.type, TOKEN_VARIABLE);
cr_assert_str_eq(tok.data, "$a");
cr_assert_eq(tok.type, TOKEN_VARIABLE, "got %d", tok.type);
cr_assert_str_eq(tok.data, "$a", "got %s", tok.data);
token_free(tok);

lexer_free(lexer);
}

Test (lexer2, double_quote_space)
{
struct lexer *lexer = lexer_new("h=\"Hello\"; w=\"World\"; echo \"$h, ${w}!\"");
struct token tok = lexer_pop(lexer);
cr_assert_eq(tok.type, TOKEN_WORD_ASSIGNMENT);
cr_assert_str_eq(tok.data, "h");
token_free(tok);

tok = lexer_pop(lexer);
cr_assert_eq(tok.type, TOKEN_WORD);
cr_assert_str_eq(tok.data, "Hello");
token_free(tok);

tok = lexer_pop(lexer);
cr_assert_eq(tok.type, TOKEN_SEMICOLON);
cr_assert_str_eq(tok.data, ";");
token_free(tok);

tok = lexer_pop(lexer);
cr_assert_eq(tok.type, TOKEN_WORD_ASSIGNMENT);
cr_assert_str_eq(tok.data, "w");
token_free(tok);

tok = lexer_pop(lexer);
cr_assert_eq(tok.type, TOKEN_WORD);
cr_assert_str_eq(tok.data, "World");
token_free(tok);

tok = lexer_pop(lexer);
cr_assert_eq(tok.type, TOKEN_SEMICOLON);
cr_assert_str_eq(tok.data, ";");
token_free(tok);

tok = lexer_pop(lexer);
cr_assert_eq(tok.type, TOKEN_WORD);
cr_assert_str_eq(tok.data, "echo");
token_free(tok);

tok = lexer_pop(lexer);
cr_assert_eq(tok.type, TOKEN_VARIABLE);
cr_assert_str_eq(tok.data, "$h");
token_free(tok);

tok = lexer_pop(lexer);
cr_assert_eq(tok.type, TOKEN_WORD_DOUBLE_QUOTE);
cr_assert_str_eq(tok.data, ", ");
token_free(tok);

tok = lexer_pop(lexer);
cr_assert_eq(tok.type, TOKEN_VARIABLE);
cr_assert_str_eq(tok.data, "$w");
token_free(tok);

tok = lexer_pop(lexer);
cr_assert_eq(tok.type, TOKEN_WORD);
cr_assert_str_eq(tok.data, "!");
token_free(tok);

lexer_free(lexer);
}
1 change: 1 addition & 0 deletions src/lexer/token.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ enum token_type
TOKEN_IONUMBER, // [0-9]+
TOKEN_REDIR, // >, <, >>, >&, <&, >|, <>
TOKEN_DOUBLE_QUOTE, // "
TOKEN_WORD_DOUBLE_QUOTE, // "[a-zA-Z0-9_ ]*"
TOKEN_WORD_ASSIGNMENT, // variable=
TOKEN_VARIABLE, // $variable

Expand Down
11 changes: 8 additions & 3 deletions src/parser/parser_element.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,12 +159,12 @@ struct ast_node *simple_command(struct lexer *lexer)
child2 = prefix(lexer);
}
}
if (parser_peek(lexer) != TOKEN_WORD)
if (parser_peek(lexer) != TOKEN_WORD && parser_peek(lexer) != TOKEN_WORD_DOUBLE_QUOTE)
{
return current;
}
}
if (parser_peek(lexer) == TOKEN_WORD)
if (parser_peek(lexer) == TOKEN_WORD || parser_peek(lexer) == TOKEN_WORD_DOUBLE_QUOTE)
{
char *value = lexer_peek(lexer).data;
if (strcmp(value, "while") == 0 || strcmp(value, "until") == 0
Expand Down Expand Up @@ -209,11 +209,16 @@ struct ast_node *element(struct lexer *lexer)
|| parser_peek(lexer) == TOKEN_WORD_ASSIGNMENT
|| parser_peek(lexer) == TOKEN_NEGATE)
{
// printf("value=%s\n", lexer_peek(lexer).data);
struct ast_node *curr = ast_node_word(lexer_peek(lexer).data);
parser_pop(lexer);
return curr;
}
else if (parser_peek(lexer) == TOKEN_WORD_DOUBLE_QUOTE)
{
struct ast_node *curr = ast_node_word_double_quote(lexer_peek(lexer).data);
parser_pop(lexer);
return curr;
}

// printf("Error: element\n");
ast_free(current);
Expand Down
9 changes: 9 additions & 0 deletions src/parser/tests/parser_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,3 +236,12 @@ Test(parser, error4)
lexer_free(lexer);
ast_free(node);
}

Test(parser, custom_double_quote)
{
struct lexer *lexer = lexer_new("echo \"variable= $a\"");
struct ast_node *node = parse(lexer);

lexer_free(lexer);
ast_free(node);
}

0 comments on commit f8bed40

Please sign in to comment.