Skip to content

Commit

Permalink
Merge pull request #81 from ErwannLesech/dev
Browse files Browse the repository at this point in the history
Step2.2 - Add tests and last fixes
  • Loading branch information
ErwannLesech authored Jan 20, 2024
2 parents c68a0e6 + d951c23 commit d103f4e
Show file tree
Hide file tree
Showing 44 changed files with 261 additions and 45 deletions.
2 changes: 1 addition & 1 deletion src/lexer/Makefile.am
Original file line number Diff line number Diff line change
@@ -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
20 changes: 16 additions & 4 deletions src/lexer/lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand All @@ -198,6 +198,16 @@ 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);
if (lexer->data[lexer->index] == '$')
{
break;
}
}

// Handle the double quote
word = handle_double_quote(lexer, is_diactivated, word,
Expand All @@ -207,8 +217,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
Expand Down
25 changes: 25 additions & 0 deletions src/lexer/lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -121,6 +127,25 @@ 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.
* \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.
Expand Down
28 changes: 5 additions & 23 deletions src/lexer/lexer_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
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;
}
Expand Down Expand Up @@ -149,7 +150,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;
}
Expand Down Expand Up @@ -204,6 +205,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)
{
Expand Down Expand Up @@ -241,27 +243,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
{
Expand Down
123 changes: 123 additions & 0 deletions src/lexer/lexer_utils2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#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]);
}

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;
}

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;
}
7 changes: 1 addition & 6 deletions src/lexer/tests/lexer2_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
7 changes: 7 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,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);
print_token(lexer->curr_tok);
printf("value: %s\n", token.data);
}*/

int val = parser_loop(lexer, pretty_print_enabled);
if (val == 2)
Expand Down
1 change: 1 addition & 0 deletions tests/quote/double_quote/double_quote10.test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a=1;echo "$a\"$a"
1 change: 1 addition & 0 deletions tests/quote/double_quote/double_quote11.test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
echo "Special characters: !@#%$^&*()"
1 change: 1 addition & 0 deletions tests/quote/double_quote/double_quote12.test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bb=1; echo "$ddd\""
1 change: 1 addition & 0 deletions tests/quote/double_quote/double_quote5.test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a=1;echo "$a\""
1 change: 1 addition & 0 deletions tests/quote/double_quote/double_quote6.test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a=1;echo "idiej$a:jodejoj" "$a" "dikefok"'
1 change: 1 addition & 0 deletions tests/quote/double_quote/double_quote7.test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a=1;echo "lpikopo"pojo^é$
4 changes: 4 additions & 0 deletions tests/quote/double_quote/double_quote8.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
a=1;echo "lpikopo\


"
1 change: 1 addition & 0 deletions tests/quote/double_quote/double_quote9.test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a=1;echo "lpikopo\$$\$$\\$\$\*\\*\\\*\*\\***\ "
10 changes: 9 additions & 1 deletion tests/quote/double_quote/testsuite.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
run_test double_quote1.test
run_test double_quote2.test
run_test double_quote3.test
run_test double_quote4.test
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
1 change: 1 addition & 0 deletions tests/quote/double_quote_error/double_quote_error1.test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bb=1; echo "$bb
1 change: 1 addition & 0 deletions tests/quote/double_quote_error/double_quote_error2.test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bb=1; echo "$ddd\"
1 change: 1 addition & 0 deletions tests/quote/double_quote_error/double_quote_error3.test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tata=1; echo "${tata}
1 change: 1 addition & 0 deletions tests/quote/double_quote_error/double_quote_error4.test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tata=1; echo "${tata}\"
1 change: 1 addition & 0 deletions tests/quote/double_quote_error/double_quote_error5.test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tata=1; echo "${tata"
1 change: 1 addition & 0 deletions tests/quote/double_quote_error/double_quote_error6.test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tata=1; echo "$
1 change: 1 addition & 0 deletions tests/quote/double_quote_error/double_quote_error7.test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tata=1; echo "$lff
1 change: 1 addition & 0 deletions tests/quote/double_quote_error/double_quote_error8.test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tata=1; echo \"${tata}"
8 changes: 8 additions & 0 deletions tests/quote/double_quote_error/testsuite.sh
Original file line number Diff line number Diff line change
@@ -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
4 changes: 2 additions & 2 deletions tests/quote/single_quote_error/testsuite.sh
Original file line number Diff line number Diff line change
@@ -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
run_test single_quoteMouli1.test
run_test single_quoteMouli2.test
5 changes: 5 additions & 0 deletions tests/redirections/redir_&input/complex1.test
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit d103f4e

Please sign in to comment.