From 0534b88bad0393f2531fb9da3309f798a9313857 Mon Sep 17 00:00:00 2001 From: Ugo Majer Date: Sat, 20 Jan 2024 18:37:22 +0100 Subject: [PATCH 1/5] test: new tests on double quote and variable This commit add several tests on double quote, variable and redirection. One test named redirections/redir_&output/simple4.test break the moulinette :) so I didnt add him to testsuite.sh --- src/main.c | 2 +- tests/quote/double_quote/double_quote10.test | 1 + tests/quote/double_quote/double_quote11.test | 1 + tests/quote/double_quote/double_quote12.test | 1 + tests/quote/double_quote/double_quote5.test | 1 + tests/quote/double_quote/double_quote6.test | 1 + tests/quote/double_quote/double_quote7.test | 1 + tests/quote/double_quote/double_quote8.test | 4 ++++ tests/quote/double_quote/double_quote9.test | 1 + tests/quote/double_quote/testsuite.sh | 10 +++++++++- .../quote/double_quote_error/double_quote_error1.test | 1 + .../quote/double_quote_error/double_quote_error2.test | 1 + .../quote/double_quote_error/double_quote_error3.test | 1 + .../quote/double_quote_error/double_quote_error4.test | 1 + .../quote/double_quote_error/double_quote_error5.test | 1 + .../quote/double_quote_error/double_quote_error6.test | 1 + .../quote/double_quote_error/double_quote_error7.test | 1 + .../quote/double_quote_error/double_quote_error8.test | 1 + tests/quote/double_quote_error/testsuite.sh | 8 ++++++++ tests/quote/single_quote_error/testsuite.sh | 4 ++-- tests/redirections/redir_&input/complex1.test | 5 +++++ tests/redirections/redir_&input/testsuite.sh | 3 ++- tests/redirections/redir_&output/error1.test | 3 +++ tests/redirections/redir_&output/input.txt | 5 +++++ tests/redirections/redir_&output/simple2.test | 6 +++--- tests/redirections/redir_&output/simple4.test | 8 ++++++++ tests/redirections/redir_&output/testsuite.sh | 3 ++- tests/redirections/redir_input/file.txt | 1 + tests/redirections/redir_input/simple1.test | 4 +++- tests/redirections/redir_output/double_redir.test | 4 ++++ tests/redirections/redir_output/simple2.test | 1 + tests/redirections/redir_output/testsuite.sh | 3 ++- tests/variable/variable/condition_variable2.test | 1 + .../{simple_variable4.tet => simple_variable4.test} | 0 tests/variable/variable/testsuite.sh | 1 + .../variable_error/condition_variable_error1.test | 1 + .../variable_error/simple_error_variable3.test | 1 + tests/variable/variable_error/testsuite.sh | 4 +++- 38 files changed, 85 insertions(+), 12 deletions(-) create mode 100644 tests/quote/double_quote/double_quote10.test create mode 100644 tests/quote/double_quote/double_quote11.test create mode 100644 tests/quote/double_quote/double_quote12.test create mode 100644 tests/quote/double_quote/double_quote5.test create mode 100644 tests/quote/double_quote/double_quote6.test create mode 100644 tests/quote/double_quote/double_quote7.test create mode 100644 tests/quote/double_quote/double_quote8.test create mode 100644 tests/quote/double_quote/double_quote9.test create mode 100644 tests/quote/double_quote_error/double_quote_error1.test create mode 100644 tests/quote/double_quote_error/double_quote_error2.test create mode 100644 tests/quote/double_quote_error/double_quote_error3.test create mode 100644 tests/quote/double_quote_error/double_quote_error4.test create mode 100644 tests/quote/double_quote_error/double_quote_error5.test create mode 100644 tests/quote/double_quote_error/double_quote_error6.test create mode 100644 tests/quote/double_quote_error/double_quote_error7.test create mode 100644 tests/quote/double_quote_error/double_quote_error8.test create mode 100644 tests/quote/double_quote_error/testsuite.sh create mode 100644 tests/redirections/redir_&input/complex1.test create mode 100644 tests/redirections/redir_&output/error1.test create mode 100644 tests/redirections/redir_&output/input.txt create mode 100644 tests/redirections/redir_&output/simple4.test create mode 100644 tests/redirections/redir_output/double_redir.test create mode 100644 tests/variable/variable/condition_variable2.test rename tests/variable/variable/{simple_variable4.tet => simple_variable4.test} (100%) create mode 100644 tests/variable/variable_error/condition_variable_error1.test create mode 100644 tests/variable/variable_error/simple_error_variable3.test diff --git a/src/main.c b/src/main.c index 33562618..f1057971 100644 --- a/src/main.c +++ b/src/main.c @@ -39,7 +39,7 @@ int main(int argc, char **argv) { errx(1, "Error while creating lexer"); } - + int val = parser_loop(lexer, pretty_print_enabled); if (val == 2) { diff --git a/tests/quote/double_quote/double_quote10.test b/tests/quote/double_quote/double_quote10.test new file mode 100644 index 00000000..dbcc50e8 --- /dev/null +++ b/tests/quote/double_quote/double_quote10.test @@ -0,0 +1 @@ +a=1;echo "$a\"$a" \ No newline at end of file diff --git a/tests/quote/double_quote/double_quote11.test b/tests/quote/double_quote/double_quote11.test new file mode 100644 index 00000000..02ebdd8a --- /dev/null +++ b/tests/quote/double_quote/double_quote11.test @@ -0,0 +1 @@ +echo "Special characters: !@#%$^&*()" \ No newline at end of file diff --git a/tests/quote/double_quote/double_quote12.test b/tests/quote/double_quote/double_quote12.test new file mode 100644 index 00000000..bb7178ea --- /dev/null +++ b/tests/quote/double_quote/double_quote12.test @@ -0,0 +1 @@ +bb=1; echo "$ddd\"" \ No newline at end of file diff --git a/tests/quote/double_quote/double_quote5.test b/tests/quote/double_quote/double_quote5.test new file mode 100644 index 00000000..addeff31 --- /dev/null +++ b/tests/quote/double_quote/double_quote5.test @@ -0,0 +1 @@ +a=1;echo "$a\"" \ No newline at end of file diff --git a/tests/quote/double_quote/double_quote6.test b/tests/quote/double_quote/double_quote6.test new file mode 100644 index 00000000..f5c6502a --- /dev/null +++ b/tests/quote/double_quote/double_quote6.test @@ -0,0 +1 @@ +a=1;echo "idiej$a:jodejoj" "$a" "dikefok"' \ No newline at end of file diff --git a/tests/quote/double_quote/double_quote7.test b/tests/quote/double_quote/double_quote7.test new file mode 100644 index 00000000..bbd38d37 --- /dev/null +++ b/tests/quote/double_quote/double_quote7.test @@ -0,0 +1 @@ +a=1;echo "lpikopo"pojo^é$ \ No newline at end of file diff --git a/tests/quote/double_quote/double_quote8.test b/tests/quote/double_quote/double_quote8.test new file mode 100644 index 00000000..79747dfa --- /dev/null +++ b/tests/quote/double_quote/double_quote8.test @@ -0,0 +1,4 @@ +a=1;echo "lpikopo\ + + +" \ No newline at end of file diff --git a/tests/quote/double_quote/double_quote9.test b/tests/quote/double_quote/double_quote9.test new file mode 100644 index 00000000..9e4fda48 --- /dev/null +++ b/tests/quote/double_quote/double_quote9.test @@ -0,0 +1 @@ +a=1;echo "lpikopo\$$\$$\\$\$\*\\*\\\*\*\\***\ " \ No newline at end of file diff --git a/tests/quote/double_quote/testsuite.sh b/tests/quote/double_quote/testsuite.sh index 31a008fb..b2a7e20a 100644 --- a/tests/quote/double_quote/testsuite.sh +++ b/tests/quote/double_quote/testsuite.sh @@ -1,4 +1,12 @@ run_test double_quote1.test run_test double_quote2.test run_test double_quote3.test -run_test double_quote4.test \ No newline at end of file +run_test double_quote4.test +run_test double_quote5.test +run_test double_quote6.test +run_test double_quote7.test +run_test double_quote8.test +run_test double_quote9.test +run_test double_quote10.test +run_test double_quote11.test +run_test double_quote12.test \ No newline at end of file diff --git a/tests/quote/double_quote_error/double_quote_error1.test b/tests/quote/double_quote_error/double_quote_error1.test new file mode 100644 index 00000000..58c5313d --- /dev/null +++ b/tests/quote/double_quote_error/double_quote_error1.test @@ -0,0 +1 @@ +bb=1; echo "$bb \ No newline at end of file diff --git a/tests/quote/double_quote_error/double_quote_error2.test b/tests/quote/double_quote_error/double_quote_error2.test new file mode 100644 index 00000000..a17274b9 --- /dev/null +++ b/tests/quote/double_quote_error/double_quote_error2.test @@ -0,0 +1 @@ +bb=1; echo "$ddd\" \ No newline at end of file diff --git a/tests/quote/double_quote_error/double_quote_error3.test b/tests/quote/double_quote_error/double_quote_error3.test new file mode 100644 index 00000000..74034281 --- /dev/null +++ b/tests/quote/double_quote_error/double_quote_error3.test @@ -0,0 +1 @@ +tata=1; echo "${tata} \ No newline at end of file diff --git a/tests/quote/double_quote_error/double_quote_error4.test b/tests/quote/double_quote_error/double_quote_error4.test new file mode 100644 index 00000000..a2a9f7a5 --- /dev/null +++ b/tests/quote/double_quote_error/double_quote_error4.test @@ -0,0 +1 @@ +tata=1; echo "${tata}\" \ No newline at end of file diff --git a/tests/quote/double_quote_error/double_quote_error5.test b/tests/quote/double_quote_error/double_quote_error5.test new file mode 100644 index 00000000..6efb40a9 --- /dev/null +++ b/tests/quote/double_quote_error/double_quote_error5.test @@ -0,0 +1 @@ +tata=1; echo "${tata" \ No newline at end of file diff --git a/tests/quote/double_quote_error/double_quote_error6.test b/tests/quote/double_quote_error/double_quote_error6.test new file mode 100644 index 00000000..1d3311c7 --- /dev/null +++ b/tests/quote/double_quote_error/double_quote_error6.test @@ -0,0 +1 @@ +tata=1; echo "$ \ No newline at end of file diff --git a/tests/quote/double_quote_error/double_quote_error7.test b/tests/quote/double_quote_error/double_quote_error7.test new file mode 100644 index 00000000..33dc7b55 --- /dev/null +++ b/tests/quote/double_quote_error/double_quote_error7.test @@ -0,0 +1 @@ +tata=1; echo "$lff \ No newline at end of file diff --git a/tests/quote/double_quote_error/double_quote_error8.test b/tests/quote/double_quote_error/double_quote_error8.test new file mode 100644 index 00000000..24abd685 --- /dev/null +++ b/tests/quote/double_quote_error/double_quote_error8.test @@ -0,0 +1 @@ +tata=1; echo \"${tata}" \ No newline at end of file diff --git a/tests/quote/double_quote_error/testsuite.sh b/tests/quote/double_quote_error/testsuite.sh new file mode 100644 index 00000000..3e0ecf65 --- /dev/null +++ b/tests/quote/double_quote_error/testsuite.sh @@ -0,0 +1,8 @@ +run_test double_quote_error1.test +run_test double_quote_error2.test +run_test double_quote_error3.test +run_test double_quote_error4.test +run_test double_quote_error5.test +run_test double_quote_error6.test +run_test double_quote_error7.test +run_test double_quote_error8.test \ No newline at end of file diff --git a/tests/quote/single_quote_error/testsuite.sh b/tests/quote/single_quote_error/testsuite.sh index db5c2be1..e6726832 100644 --- a/tests/quote/single_quote_error/testsuite.sh +++ b/tests/quote/single_quote_error/testsuite.sh @@ -1,5 +1,5 @@ run_test single_quote_error1.test run_test single_quote_error2.test run_test single_quote_error3.test -run_test single_quote_errorMouli1.test -run_test single_quote_errorMouli2.test \ No newline at end of file +run_test single_quoteMouli1.test +run_test single_quoteMouli2.test \ No newline at end of file diff --git a/tests/redirections/redir_&input/complex1.test b/tests/redirections/redir_&input/complex1.test new file mode 100644 index 00000000..7a7125d5 --- /dev/null +++ b/tests/redirections/redir_&input/complex1.test @@ -0,0 +1,5 @@ +echo 'hello' > input.txt +ls > output.txt 2<&1 < input.txt +cat output.txt +cat input.txt +rm input.txt output.txt \ No newline at end of file diff --git a/tests/redirections/redir_&input/testsuite.sh b/tests/redirections/redir_&input/testsuite.sh index 0a7672ab..4370aa69 100644 --- a/tests/redirections/redir_&input/testsuite.sh +++ b/tests/redirections/redir_&input/testsuite.sh @@ -1 +1,2 @@ -run_test simple1.test \ No newline at end of file +run_test simple1.test +run_test complex1.test \ No newline at end of file diff --git a/tests/redirections/redir_&output/error1.test b/tests/redirections/redir_&output/error1.test new file mode 100644 index 00000000..ce85a5e4 --- /dev/null +++ b/tests/redirections/redir_&output/error1.test @@ -0,0 +1,3 @@ +t 2>& file; +cat file +rm file \ No newline at end of file diff --git a/tests/redirections/redir_&output/input.txt b/tests/redirections/redir_&output/input.txt new file mode 100644 index 00000000..9adc6a3b --- /dev/null +++ b/tests/redirections/redir_&output/input.txt @@ -0,0 +1,5 @@ +1 +3 +2 +7 +0 diff --git a/tests/redirections/redir_&output/simple2.test b/tests/redirections/redir_&output/simple2.test index ce85a5e4..5bc16279 100644 --- a/tests/redirections/redir_&output/simple2.test +++ b/tests/redirections/redir_&output/simple2.test @@ -1,3 +1,3 @@ -t 2>& file; -cat file -rm file \ No newline at end of file +ls -l non_existent_directory >& output_and_error.txt +if [ -s output_and_error.txt ]; then echo tata; fi +rm -f output_and_error.txt \ No newline at end of file diff --git a/tests/redirections/redir_&output/simple4.test b/tests/redirections/redir_&output/simple4.test new file mode 100644 index 00000000..45715188 --- /dev/null +++ b/tests/redirections/redir_&output/simple4.test @@ -0,0 +1,8 @@ +echo '1 +3 +2 +7 +0' > input.txt +sort < input.txt >& sorted_output.txt +cat sorted_output.txt +rm input.txt sorted_output.txt \ No newline at end of file diff --git a/tests/redirections/redir_&output/testsuite.sh b/tests/redirections/redir_&output/testsuite.sh index 673d84a4..d5b41e22 100644 --- a/tests/redirections/redir_&output/testsuite.sh +++ b/tests/redirections/redir_&output/testsuite.sh @@ -1,3 +1,4 @@ run_test simple1.test run_test simple2.test -run_test simple3.test \ No newline at end of file +run_test simple3.test +run_test error1.test \ No newline at end of file diff --git a/tests/redirections/redir_input/file.txt b/tests/redirections/redir_input/file.txt index e69de29b..5ab2f8a4 100644 --- a/tests/redirections/redir_input/file.txt +++ b/tests/redirections/redir_input/file.txt @@ -0,0 +1 @@ +Hello \ No newline at end of file diff --git a/tests/redirections/redir_input/simple1.test b/tests/redirections/redir_input/simple1.test index d85f007f..f7e91bcc 100644 --- a/tests/redirections/redir_input/simple1.test +++ b/tests/redirections/redir_input/simple1.test @@ -1 +1,3 @@ -ls < file.txt \ No newline at end of file +echo 'hello' > file.txt +ls < file.txt +rm file.txt diff --git a/tests/redirections/redir_output/double_redir.test b/tests/redirections/redir_output/double_redir.test new file mode 100644 index 00000000..e30978a8 --- /dev/null +++ b/tests/redirections/redir_output/double_redir.test @@ -0,0 +1,4 @@ +ls -l non_existent_directory 1> success.txt 2> error.txt; echo tata +cat success.txt +if [ -s error.txt ]; then echo tata;fi +rm success.txt error.txt \ No newline at end of file diff --git a/tests/redirections/redir_output/simple2.test b/tests/redirections/redir_output/simple2.test index c59d8c28..898bf83d 100644 --- a/tests/redirections/redir_output/simple2.test +++ b/tests/redirections/redir_output/simple2.test @@ -1,3 +1,4 @@ wrong_command 2>file +if [ -s error.txt ]; then echo tata;fi # cat file --> working but not the same stderr message rm file \ No newline at end of file diff --git a/tests/redirections/redir_output/testsuite.sh b/tests/redirections/redir_output/testsuite.sh index bf61e093..73a786ec 100644 --- a/tests/redirections/redir_output/testsuite.sh +++ b/tests/redirections/redir_output/testsuite.sh @@ -1,2 +1,3 @@ run_test simple1.test -run_test simple2.test \ No newline at end of file +run_test simple2.test +run_test double_redir.test \ No newline at end of file diff --git a/tests/variable/variable/condition_variable2.test b/tests/variable/variable/condition_variable2.test new file mode 100644 index 00000000..b549e93f --- /dev/null +++ b/tests/variable/variable/condition_variable2.test @@ -0,0 +1 @@ +a=true; if $a; then echo atat;fi \ No newline at end of file diff --git a/tests/variable/variable/simple_variable4.tet b/tests/variable/variable/simple_variable4.test similarity index 100% rename from tests/variable/variable/simple_variable4.tet rename to tests/variable/variable/simple_variable4.test diff --git a/tests/variable/variable/testsuite.sh b/tests/variable/variable/testsuite.sh index 2cfb2a1c..66574b2c 100644 --- a/tests/variable/variable/testsuite.sh +++ b/tests/variable/variable/testsuite.sh @@ -7,4 +7,5 @@ run_test simple_variable6.test run_test simple_variable7.test run_test simple_variable8.test run_test condition_variable1.test +run_test condition_variable2.test run_test environment_variable.test \ No newline at end of file diff --git a/tests/variable/variable_error/condition_variable_error1.test b/tests/variable/variable_error/condition_variable_error1.test new file mode 100644 index 00000000..0050be05 --- /dev/null +++ b/tests/variable/variable_error/condition_variable_error1.test @@ -0,0 +1 @@ +a=1; if $a; then echo atat;fi \ No newline at end of file diff --git a/tests/variable/variable_error/simple_error_variable3.test b/tests/variable/variable_error/simple_error_variable3.test new file mode 100644 index 00000000..662ef107 --- /dev/null +++ b/tests/variable/variable_error/simple_error_variable3.test @@ -0,0 +1 @@ +$1 ${a} ${b} b=2; b=1; echo ${b} \ No newline at end of file diff --git a/tests/variable/variable_error/testsuite.sh b/tests/variable/variable_error/testsuite.sh index 54ac8cf2..ac40b50a 100644 --- a/tests/variable/variable_error/testsuite.sh +++ b/tests/variable/variable_error/testsuite.sh @@ -1,3 +1,5 @@ run_test while_variable_error1.test run_test simple_error_variable1.test -run_test simple_error_variable2.test \ No newline at end of file +run_test simple_error_variable2.test +run_test simple_error_variable3.test +run_test conditional_variable_error1.test \ No newline at end of file From 7bcd3287654326d050332721b3e7e98cd8db5bbd Mon Sep 17 00:00:00 2001 From: Ugo Majer Date: Sat, 20 Jan 2024 19:29:51 +0100 Subject: [PATCH 2/5] fix: fix the backslash at the begining of a string in double quote This commit fix the backslash at the begining of a word in double quote and adding a pretty print for token --- src/lexer/Makefile.am | 2 +- src/lexer/lexer.c | 5 +++ src/lexer/lexer.h | 17 +++++++++ src/lexer/lexer_utils.c | 49 ++++++++++++++----------- src/lexer/lexer_utils2.c | 35 ++++++++++++++++++ src/main.c | 7 ++++ tests/redirections/redir_input/file.txt | 1 - 7 files changed, 93 insertions(+), 23 deletions(-) create mode 100644 src/lexer/lexer_utils2.c delete mode 100644 tests/redirections/redir_input/file.txt diff --git a/src/lexer/Makefile.am b/src/lexer/Makefile.am index 1b1fcc5c..1cdec2f4 100644 --- a/src/lexer/Makefile.am +++ b/src/lexer/Makefile.am @@ -1,5 +1,5 @@ lib_LIBRARIES = liblexer.a -liblexer_a_SOURCES = lexer.c lexer_utils.c lexer.h token.h +liblexer_a_SOURCES = lexer.c lexer_utils.c lexer_utils2.c lexer.h token.h liblexer_a_CFLAGS = -Wall -Wextra -Werror -Wvla -pedantic -std=c99 liblexer_a_CPPFLAGS = -I$(top_srcdir)/src diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c index f40f2f08..07db69e7 100644 --- a/src/lexer/lexer.c +++ b/src/lexer/lexer.c @@ -198,6 +198,11 @@ char *get_word(struct lexer *lexer, bool *is_diactivated) word_index -= 1; lexer->curr_tok.type = TOKEN_DOUBLE_QUOTE; } + else if (word_index > 0 && lexer->data[lexer->index -1] == '\\') + { + word_index -= 1; + handle_back_slash_in_double_quote(lexer, word, &word_index); + } // Handle the double quote word = handle_double_quote(lexer, is_diactivated, word, diff --git a/src/lexer/lexer.h b/src/lexer/lexer.h index cece3695..5c4169d9 100644 --- a/src/lexer/lexer.h +++ b/src/lexer/lexer.h @@ -55,6 +55,12 @@ void lexer_free(struct lexer *lexer); */ void token_free(struct token token); +/** + * \brief Print the given token. + * \param token The token to print. +*/ +void print_token(struct token token); + /** * \brief Get the next token from the lexer. * \param lexer The lexer. @@ -121,6 +127,17 @@ bool check_variable_assignement(char *word); bool check_variable_name(struct lexer *lexer, char **word, unsigned *word_index, bool *is_in_braces); +/** + * \brief Handle the backslash character in a double quote. + * \param lexer The lexer. + * \param word The word. + * \param word_index The index of the word. +*/ + + +void handle_back_slash_in_double_quote(struct lexer *lexer, char *word, + unsigned *word_index); + /** * \brief Handle the dollar character. * \param lexer The lexer. diff --git a/src/lexer/lexer_utils.c b/src/lexer/lexer_utils.c index 79df6065..b7da4191 100644 --- a/src/lexer/lexer_utils.c +++ b/src/lexer/lexer_utils.c @@ -190,6 +190,32 @@ bool check_variable_name(struct lexer *lexer, char **word, unsigned *word_index, return true; } +void handle_back_slash_in_double_quote(struct lexer *lexer, char *word, + unsigned *word_index) +{ + if (lexer->data[lexer->index] == '\"' + || lexer->data[lexer->index] == '$' + || lexer->data[lexer->index] == '\\' + || lexer->data[lexer->index] == '\n' + || lexer->data[lexer->index] == '`') + { + if (lexer->data[lexer->index] != '\n') + { + word[*word_index] = lexer->data[lexer->index]; + } + else + { + *word_index -= 1; + } + lexer->index += 1; + } + else + { + word[*word_index] = '\\'; + } + *word_index += 1; +} + bool handle_dollar(struct lexer *lexer, char **word, unsigned *word_index, bool *is_in_braces) { @@ -204,6 +230,7 @@ bool handle_dollar(struct lexer *lexer, char **word, unsigned *word_index, // Check if the name of the variable is correct return check_variable_name(lexer, word, word_index, is_in_braces); } + char *handle_double_quote(struct lexer *lexer, bool *is_diactivated, char *word, unsigned *word_index) { @@ -241,27 +268,7 @@ char *handle_double_quote(struct lexer *lexer, bool *is_diactivated, char *word, { lexer->index += 1; word = realloc(word, sizeof(char) * (*word_index + 1)); - if (lexer->data[lexer->index] == '\"' - || lexer->data[lexer->index] == '$' - || lexer->data[lexer->index] == '\\' - || lexer->data[lexer->index] == '\n' - || lexer->data[lexer->index] == '`') - { - if (lexer->data[lexer->index] != '\n') - { - word[*word_index] = lexer->data[lexer->index]; - } - else - { - *word_index -= 1; - } - lexer->index += 1; - } - else - { - word[*word_index] = '\\'; - } - *word_index += 1; + handle_back_slash_in_double_quote(lexer, word, word_index); } else { diff --git a/src/lexer/lexer_utils2.c b/src/lexer/lexer_utils2.c new file mode 100644 index 00000000..e9ae194f --- /dev/null +++ b/src/lexer/lexer_utils2.c @@ -0,0 +1,35 @@ +#include "lexer.h" + +void print_token(struct token token) +{ + char *tokens[] = { + // Step1 + [TOKEN_IF] = "TOKEN_IF", + [TOKEN_THEN] = "TOKEN_THEN", + [TOKEN_ELIF] = "TOKEN_ELIF", + [TOKEN_ELSE] = "TOKEN_ELSE", + [TOKEN_FI] = "TOKEN_FI", + [TOKEN_SEMICOLON] = "TOKEN_SEMICOLON", + [TOKEN_WORD] = "TOKEN_WORD", + [TOKEN_EOL] = "TOKEN_EOL", + [TOKEN_EOF] = "TOKEN_EOF", + [TOKEN_ERROR] = "TOKEN_ERROR", + // Step 2 + [TOKEN_DONE] = "TOKEN_DONE", + [TOKEN_AND] = "TOKEN_AND", + [TOKEN_OR] = "TOKEN_OR", + [TOKEN_PIPE] = "TOKEN_PIPE", + [TOKEN_NEGATE] = "TOKEN_NEGATE", + [TOKEN_IONUMBER] = "TOKEN_IONUMBER", + [TOKEN_REDIR] = "TOKEN_REDIR", + [TOKEN_DOUBLE_QUOTE] = "TOKEN_DOUBLE_QUOTE", + [TOKEN_WORD_DOUBLE_QUOTE] = "TOKEN_WORD_DOUBLE_QUOTE", + [TOKEN_WORD_ASSIGNMENT] = "TOKEN_WORD_ASSIGNMENT", + [TOKEN_VARIABLE] = "TOKEN_VARIABLE", + + // Internal values for lexer + [TOKEN_VARIABLE_VALUE] = "TOKEN_VARIABLE_VALUE", + [TOKEN_VARIABLE_AND_DOUBLE_QUOTE] = "TOKEN_VARIABLE_AND_DOUBLE_QUOTE" + }; + printf("Token: %s\n", tokens[token.type]); +} \ No newline at end of file diff --git a/src/main.c b/src/main.c index f1057971..e07f5d83 100644 --- a/src/main.c +++ b/src/main.c @@ -40,6 +40,13 @@ int main(int argc, char **argv) errx(1, "Error while creating lexer"); } + /*while (lexer_peek(lexer).type != TOKEN_EOF) + { + struct token token = lexer_pop(lexer); + print_token(token); + printf("value: %s\n", token.data); + }*/ + int val = parser_loop(lexer, pretty_print_enabled); if (val == 2) { diff --git a/tests/redirections/redir_input/file.txt b/tests/redirections/redir_input/file.txt deleted file mode 100644 index 5ab2f8a4..00000000 --- a/tests/redirections/redir_input/file.txt +++ /dev/null @@ -1 +0,0 @@ -Hello \ No newline at end of file From 33f2fc63b5eb841cd746c5313a4cbe960e4cef6b Mon Sep 17 00:00:00 2001 From: erwann lesech Date: Sat, 20 Jan 2024 20:26:44 +0100 Subject: [PATCH 3/5] fix enable continue word after double quote closure and include variable if wrong variable name --- src/lexer/lexer.c | 10 +++-- src/lexer/lexer.h | 9 +++++ src/lexer/lexer_utils2.c | 71 ++++++++++++++++++++++++++++++++++ src/lexer/tests/lexer2_tests.c | 7 +--- 4 files changed, 87 insertions(+), 10 deletions(-) diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c index 07db69e7..98b5180c 100644 --- a/src/lexer/lexer.c +++ b/src/lexer/lexer.c @@ -149,7 +149,8 @@ char *get_word(struct lexer *lexer, bool *is_diactivated) // Handle the variable if (lexer->data[lexer->index] == '$') { - if (word_index != 0) + if (word_index != 0 && check_variable_name_simulated(lexer->data, + lexer->index)) { break; } @@ -181,7 +182,6 @@ char *get_word(struct lexer *lexer, bool *is_diactivated) { lexer->index += 1; } - // Take next char and put it in the word word[word_index] = lexer->data[lexer->index]; ++word_index; @@ -212,8 +212,10 @@ char *get_word(struct lexer *lexer, bool *is_diactivated) { return NULL; } - word[word_index] = '\0'; - return word; + if (lexer->curr_tok.type == TOKEN_VARIABLE_AND_DOUBLE_QUOTE) + { + return word; + } } // Handle backslash diff --git a/src/lexer/lexer.h b/src/lexer/lexer.h index 5c4169d9..92852d07 100644 --- a/src/lexer/lexer.h +++ b/src/lexer/lexer.h @@ -127,6 +127,15 @@ bool check_variable_assignement(char *word); bool check_variable_name(struct lexer *lexer, char **word, unsigned *word_index, bool *is_in_braces); +/** + * \brief Check if the current word is a valid variable name (simulated mode) + * meaning that pointers to the lexer and the word won't be modified. + * \param data The word to check + * \param index The index of the data to check + * \return true if it's a valid variable name, false otherwise +*/ +bool check_variable_name_simulated(const char *data, int index); + /** * \brief Handle the backslash character in a double quote. * \param lexer The lexer. diff --git a/src/lexer/lexer_utils2.c b/src/lexer/lexer_utils2.c index e9ae194f..04c9c427 100644 --- a/src/lexer/lexer_utils2.c +++ b/src/lexer/lexer_utils2.c @@ -32,4 +32,75 @@ void print_token(struct token token) [TOKEN_VARIABLE_AND_DOUBLE_QUOTE] = "TOKEN_VARIABLE_AND_DOUBLE_QUOTE" }; printf("Token: %s\n", tokens[token.type]); +} + +bool check_variable_name_simulated(const char *data, int index) +{ + bool is_in_braces = false; + + index += 1; + + // Check if it's a special variable (like $?, $*, $@, $# or $$) + if (data[index] == '?' || data[index] == '*' + || data[index] == '@' || data[index] == '#' + || data[index] == '$') + { + return true; + } + + // Chech if it's a special variable (like $n) + else if (data[index] >= '0' + && data[index] <= '9') + { + return true; + } + + else if (data[index] == '{') + { + index += 1; + is_in_braces = true; + } + + // Classic variable name + else if (data[index] == '_' + || data[index] == '-' + || (data[index] >= 'a' + && data[index] <= 'z') + || (data[index] >= 'A' + && data[index] <= 'Z')) + { + index += 1; + } + // Not a valid variable name + else + { + return false; + } + + // Check the rest of the variable name break + while (data[index] == '_' || data[index] == '-' + || (data[index] >= 'a' + && data[index] <= 'z') + || (data[index] >= 'A' + && data[index] <= 'Z') + || (data[index] >= '0' + && data[index] <= '9')) + { + index += 1; + } + + if (is_in_braces) + { + if (data[index] == '}') + { + index += 1; + return true; + } + else + { + return false; + } + } + + return true; } \ No newline at end of file diff --git a/src/lexer/tests/lexer2_tests.c b/src/lexer/tests/lexer2_tests.c index 466d8470..75691709 100644 --- a/src/lexer/tests/lexer2_tests.c +++ b/src/lexer/tests/lexer2_tests.c @@ -997,12 +997,7 @@ Test(lexer2, variable_distinction_access_deactivate_brace) tok = lexer_pop(lexer); cr_assert_eq(tok.type, TOKEN_WORD, "got %d", tok.type); - cr_assert_str_eq(tok.data, "variable:"); - token_free(tok); - - tok = lexer_pop(lexer); - cr_assert_eq(tok.type, TOKEN_WORD); - cr_assert_str_eq(tok.data, "${a_123as}"); + cr_assert_str_eq(tok.data, "variable:${a_123as}"); token_free(tok); tok = lexer_pop(lexer); From 916e7fa8e78c9e84defdf8e8c87f7434027bb10f Mon Sep 17 00:00:00 2001 From: Ugo Majer Date: Sat, 20 Jan 2024 20:45:43 +0100 Subject: [PATCH 4/5] fix: fix double quote test 10 --- src/lexer/lexer.c | 4 ++++ src/lexer/lexer_utils.c | 30 ++---------------------------- src/lexer/lexer_utils2.c | 28 +++++++++++++++++++++++++++- src/main.c | 4 ++-- 4 files changed, 35 insertions(+), 31 deletions(-) diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c index 98b5180c..d03bf023 100644 --- a/src/lexer/lexer.c +++ b/src/lexer/lexer.c @@ -202,6 +202,10 @@ char *get_word(struct lexer *lexer, bool *is_diactivated) { word_index -= 1; handle_back_slash_in_double_quote(lexer, word, &word_index); + if (lexer->data[lexer->index] == '$') + { + break; + } } // Handle the double quote diff --git a/src/lexer/lexer_utils.c b/src/lexer/lexer_utils.c index b7da4191..a3443bf2 100644 --- a/src/lexer/lexer_utils.c +++ b/src/lexer/lexer_utils.c @@ -98,7 +98,7 @@ bool check_variable_name(struct lexer *lexer, char **word, unsigned *word_index, char *curr_word = *word; *is_in_braces = false; // Handle variable in double quote - if (lexer->curr_tok.type == TOKEN_DOUBLE_QUOTE) + if (lexer->curr_tok.type == TOKEN_DOUBLE_QUOTE || lexer->curr_tok.type == TOKEN_VARIABLE_AND_DOUBLE_QUOTE) { lexer->curr_tok.type = TOKEN_VARIABLE_AND_DOUBLE_QUOTE; } @@ -149,7 +149,7 @@ bool check_variable_name(struct lexer *lexer, char **word, unsigned *word_index, // Not a valid variable name else { - if (lexer->curr_tok.type != TOKEN_DOUBLE_QUOTE) + if (lexer->curr_tok.type != TOKEN_VARIABLE_AND_DOUBLE_QUOTE) { lexer->curr_tok.type = TOKEN_WORD; } @@ -190,32 +190,6 @@ bool check_variable_name(struct lexer *lexer, char **word, unsigned *word_index, return true; } -void handle_back_slash_in_double_quote(struct lexer *lexer, char *word, - unsigned *word_index) -{ - if (lexer->data[lexer->index] == '\"' - || lexer->data[lexer->index] == '$' - || lexer->data[lexer->index] == '\\' - || lexer->data[lexer->index] == '\n' - || lexer->data[lexer->index] == '`') - { - if (lexer->data[lexer->index] != '\n') - { - word[*word_index] = lexer->data[lexer->index]; - } - else - { - *word_index -= 1; - } - lexer->index += 1; - } - else - { - word[*word_index] = '\\'; - } - *word_index += 1; -} - bool handle_dollar(struct lexer *lexer, char **word, unsigned *word_index, bool *is_in_braces) { diff --git a/src/lexer/lexer_utils2.c b/src/lexer/lexer_utils2.c index 04c9c427..e9f66b70 100644 --- a/src/lexer/lexer_utils2.c +++ b/src/lexer/lexer_utils2.c @@ -103,4 +103,30 @@ bool check_variable_name_simulated(const char *data, int index) } return true; -} \ No newline at end of file +} + +void handle_back_slash_in_double_quote(struct lexer *lexer, char *word, + unsigned *word_index) +{ + if (lexer->data[lexer->index] == '\"' + || lexer->data[lexer->index] == '$' + || lexer->data[lexer->index] == '\\' + || lexer->data[lexer->index] == '\n' + || lexer->data[lexer->index] == '`') + { + if (lexer->data[lexer->index] != '\n') + { + word[*word_index] = lexer->data[lexer->index]; + } + else + { + *word_index -= 1; + } + lexer->index += 1; + } + else + { + word[*word_index] = '\\'; + } + *word_index += 1; +} diff --git a/src/main.c b/src/main.c index e07f5d83..138cabc5 100644 --- a/src/main.c +++ b/src/main.c @@ -39,11 +39,11 @@ int main(int argc, char **argv) { errx(1, "Error while creating lexer"); } - - /*while (lexer_peek(lexer).type != TOKEN_EOF) + /* while (lexer_peek(lexer).type != TOKEN_EOF) { struct token token = lexer_pop(lexer); print_token(token); + print_token(lexer->curr_tok); printf("value: %s\n", token.data); }*/ From d951c230f869d252ee438d54004095d17a8de5ec Mon Sep 17 00:00:00 2001 From: erwann lesech Date: Sat, 20 Jan 2024 20:58:19 +0100 Subject: [PATCH 5/5] style: clang the code --- src/lexer/lexer.c | 7 ++-- src/lexer/lexer.h | 9 ++--- src/lexer/lexer_utils.c | 3 +- src/lexer/lexer_utils2.c | 87 ++++++++++++++++++---------------------- 4 files changed, 49 insertions(+), 57 deletions(-) diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c index d03bf023..3b8925c3 100644 --- a/src/lexer/lexer.c +++ b/src/lexer/lexer.c @@ -149,8 +149,8 @@ char *get_word(struct lexer *lexer, bool *is_diactivated) // Handle the variable if (lexer->data[lexer->index] == '$') { - if (word_index != 0 && check_variable_name_simulated(lexer->data, - lexer->index)) + if (word_index != 0 + && check_variable_name_simulated(lexer->data, lexer->index)) { break; } @@ -198,7 +198,8 @@ char *get_word(struct lexer *lexer, bool *is_diactivated) word_index -= 1; lexer->curr_tok.type = TOKEN_DOUBLE_QUOTE; } - else if (word_index > 0 && lexer->data[lexer->index -1] == '\\') + else if (word_index > 0 + && lexer->data[lexer->index - 1] == '\\') { word_index -= 1; handle_back_slash_in_double_quote(lexer, word, &word_index); diff --git a/src/lexer/lexer.h b/src/lexer/lexer.h index 92852d07..905df2ff 100644 --- a/src/lexer/lexer.h +++ b/src/lexer/lexer.h @@ -58,7 +58,7 @@ void token_free(struct token token); /** * \brief Print the given token. * \param token The token to print. -*/ + */ void print_token(struct token token); /** @@ -133,7 +133,7 @@ bool check_variable_name(struct lexer *lexer, char **word, unsigned *word_index, * \param data The word to check * \param index The index of the data to check * \return true if it's a valid variable name, false otherwise -*/ + */ bool check_variable_name_simulated(const char *data, int index); /** @@ -141,11 +141,10 @@ bool check_variable_name_simulated(const char *data, int index); * \param lexer The lexer. * \param word The word. * \param word_index The index of the word. -*/ - + */ void handle_back_slash_in_double_quote(struct lexer *lexer, char *word, - unsigned *word_index); + unsigned *word_index); /** * \brief Handle the dollar character. diff --git a/src/lexer/lexer_utils.c b/src/lexer/lexer_utils.c index a3443bf2..c7a6d5d6 100644 --- a/src/lexer/lexer_utils.c +++ b/src/lexer/lexer_utils.c @@ -98,7 +98,8 @@ bool check_variable_name(struct lexer *lexer, char **word, unsigned *word_index, char *curr_word = *word; *is_in_braces = false; // Handle variable in double quote - if (lexer->curr_tok.type == TOKEN_DOUBLE_QUOTE || lexer->curr_tok.type == TOKEN_VARIABLE_AND_DOUBLE_QUOTE) + if (lexer->curr_tok.type == TOKEN_DOUBLE_QUOTE + || lexer->curr_tok.type == TOKEN_VARIABLE_AND_DOUBLE_QUOTE) { lexer->curr_tok.type = TOKEN_VARIABLE_AND_DOUBLE_QUOTE; } diff --git a/src/lexer/lexer_utils2.c b/src/lexer/lexer_utils2.c index e9f66b70..5a47a31c 100644 --- a/src/lexer/lexer_utils2.c +++ b/src/lexer/lexer_utils2.c @@ -2,34 +2,34 @@ void print_token(struct token token) { - char *tokens[] = { - // Step1 - [TOKEN_IF] = "TOKEN_IF", - [TOKEN_THEN] = "TOKEN_THEN", - [TOKEN_ELIF] = "TOKEN_ELIF", - [TOKEN_ELSE] = "TOKEN_ELSE", - [TOKEN_FI] = "TOKEN_FI", - [TOKEN_SEMICOLON] = "TOKEN_SEMICOLON", - [TOKEN_WORD] = "TOKEN_WORD", - [TOKEN_EOL] = "TOKEN_EOL", - [TOKEN_EOF] = "TOKEN_EOF", - [TOKEN_ERROR] = "TOKEN_ERROR", - // Step 2 - [TOKEN_DONE] = "TOKEN_DONE", - [TOKEN_AND] = "TOKEN_AND", - [TOKEN_OR] = "TOKEN_OR", - [TOKEN_PIPE] = "TOKEN_PIPE", - [TOKEN_NEGATE] = "TOKEN_NEGATE", - [TOKEN_IONUMBER] = "TOKEN_IONUMBER", - [TOKEN_REDIR] = "TOKEN_REDIR", - [TOKEN_DOUBLE_QUOTE] = "TOKEN_DOUBLE_QUOTE", - [TOKEN_WORD_DOUBLE_QUOTE] = "TOKEN_WORD_DOUBLE_QUOTE", - [TOKEN_WORD_ASSIGNMENT] = "TOKEN_WORD_ASSIGNMENT", - [TOKEN_VARIABLE] = "TOKEN_VARIABLE", + char *tokens[] = { // Step1 + [TOKEN_IF] = "TOKEN_IF", + [TOKEN_THEN] = "TOKEN_THEN", + [TOKEN_ELIF] = "TOKEN_ELIF", + [TOKEN_ELSE] = "TOKEN_ELSE", + [TOKEN_FI] = "TOKEN_FI", + [TOKEN_SEMICOLON] = "TOKEN_SEMICOLON", + [TOKEN_WORD] = "TOKEN_WORD", + [TOKEN_EOL] = "TOKEN_EOL", + [TOKEN_EOF] = "TOKEN_EOF", + [TOKEN_ERROR] = "TOKEN_ERROR", + // Step 2 + [TOKEN_DONE] = "TOKEN_DONE", + [TOKEN_AND] = "TOKEN_AND", + [TOKEN_OR] = "TOKEN_OR", + [TOKEN_PIPE] = "TOKEN_PIPE", + [TOKEN_NEGATE] = "TOKEN_NEGATE", + [TOKEN_IONUMBER] = "TOKEN_IONUMBER", + [TOKEN_REDIR] = "TOKEN_REDIR", + [TOKEN_DOUBLE_QUOTE] = "TOKEN_DOUBLE_QUOTE", + [TOKEN_WORD_DOUBLE_QUOTE] = "TOKEN_WORD_DOUBLE_QUOTE", + [TOKEN_WORD_ASSIGNMENT] = "TOKEN_WORD_ASSIGNMENT", + [TOKEN_VARIABLE] = "TOKEN_VARIABLE", - // Internal values for lexer - [TOKEN_VARIABLE_VALUE] = "TOKEN_VARIABLE_VALUE", - [TOKEN_VARIABLE_AND_DOUBLE_QUOTE] = "TOKEN_VARIABLE_AND_DOUBLE_QUOTE" + // Internal values for lexer + [TOKEN_VARIABLE_VALUE] = "TOKEN_VARIABLE_VALUE", + [TOKEN_VARIABLE_AND_DOUBLE_QUOTE] = + "TOKEN_VARIABLE_AND_DOUBLE_QUOTE" }; printf("Token: %s\n", tokens[token.type]); } @@ -41,16 +41,14 @@ bool check_variable_name_simulated(const char *data, int index) index += 1; // Check if it's a special variable (like $?, $*, $@, $# or $$) - if (data[index] == '?' || data[index] == '*' - || data[index] == '@' || data[index] == '#' - || data[index] == '$') + if (data[index] == '?' || data[index] == '*' || data[index] == '@' + || data[index] == '#' || data[index] == '$') { return true; } // Chech if it's a special variable (like $n) - else if (data[index] >= '0' - && data[index] <= '9') + else if (data[index] >= '0' && data[index] <= '9') { return true; } @@ -62,12 +60,9 @@ bool check_variable_name_simulated(const char *data, int index) } // Classic variable name - else if (data[index] == '_' - || data[index] == '-' - || (data[index] >= 'a' - && data[index] <= 'z') - || (data[index] >= 'A' - && data[index] <= 'Z')) + else if (data[index] == '_' || data[index] == '-' + || (data[index] >= 'a' && data[index] <= 'z') + || (data[index] >= 'A' && data[index] <= 'Z')) { index += 1; } @@ -79,15 +74,12 @@ bool check_variable_name_simulated(const char *data, int index) // Check the rest of the variable name break while (data[index] == '_' || data[index] == '-' - || (data[index] >= 'a' - && data[index] <= 'z') - || (data[index] >= 'A' - && data[index] <= 'Z') - || (data[index] >= '0' - && data[index] <= '9')) + || (data[index] >= 'a' && data[index] <= 'z') + || (data[index] >= 'A' && data[index] <= 'Z') + || (data[index] >= '0' && data[index] <= '9')) { index += 1; - } + } if (is_in_braces) { @@ -106,10 +98,9 @@ bool check_variable_name_simulated(const char *data, int index) } void handle_back_slash_in_double_quote(struct lexer *lexer, char *word, - unsigned *word_index) + unsigned *word_index) { - if (lexer->data[lexer->index] == '\"' - || lexer->data[lexer->index] == '$' + if (lexer->data[lexer->index] == '\"' || lexer->data[lexer->index] == '$' || lexer->data[lexer->index] == '\\' || lexer->data[lexer->index] == '\n' || lexer->data[lexer->index] == '`')