Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Step2.2 - Add tests and last fixes #81

Merged
merged 7 commits into from
Jan 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading