From d91b495ff43b8c705cd018d771cc49a3226a0d16 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Tue, 1 Aug 2023 18:48:40 +0000 Subject: [PATCH] parser: Remove any global variables Signed-off-by: Michael Tremer --- src/libpakfire/include/pakfire/parser.h | 11 ++++++ src/libpakfire/parser/grammar.y | 25 +++++++++----- src/libpakfire/parser/scanner.l | 45 +++++++++++-------------- 3 files changed, 47 insertions(+), 34 deletions(-) diff --git a/src/libpakfire/include/pakfire/parser.h b/src/libpakfire/include/pakfire/parser.h index 5caa1f125..a306a516e 100644 --- a/src/libpakfire/include/pakfire/parser.h +++ b/src/libpakfire/include/pakfire/parser.h @@ -87,6 +87,17 @@ const char* pakfire_parser_error_get_message(struct pakfire_parser_error* error) struct pakfire* pakfire_parser_get_pakfire(struct pakfire_parser* parser); +struct pakfire_parser_state { + unsigned int lineno; + + // Indentation level + unsigned int indent_level; + + // Remember current indentation + unsigned int current_indent; + unsigned int readline_indent; +}; + struct pakfire_parser_declaration { char namespace[NAME_MAX]; char name[NAME_MAX]; diff --git a/src/libpakfire/parser/grammar.y b/src/libpakfire/parser/grammar.y index 60a195e4a..5cbb0abbb 100644 --- a/src/libpakfire/parser/grammar.y +++ b/src/libpakfire/parser/grammar.y @@ -56,19 +56,20 @@ #endif typedef void* yyscan_t; -extern int yylex_init(yyscan_t* scanner); +extern int yylex_init_extra(struct pakfire_parser_state* state, yyscan_t* scanner); int yylex_destroy(yyscan_t scanner); typedef struct yy_buffer_state* YY_BUFFER_STATE; extern YY_BUFFER_STATE yy_scan_bytes(const char* buffer, int len, yyscan_t scanner); extern void yy_delete_buffer(YY_BUFFER_STATE buffer, yyscan_t scanner); +#define YY_EXTRA_TYPE struct pakfire_parser_state* +YY_EXTRA_TYPE yyget_extra(yyscan_t scanner); + #include "grammar.h" extern int yylex (YYSTYPE* yylval_param, yyscan_t yyscanner); -extern int num_lines; - #define ABORT do { YYABORT; } while (0); enum operator { @@ -77,11 +78,13 @@ enum operator { static void yyerror(yyscan_t* scanner, struct pakfire* pakfire, struct pakfire_parser** parser, struct pakfire_parser* parent, struct pakfire_parser_error** error, const char* s) { - ERROR(pakfire, "Error (line %d): %s\n", num_lines, s); + const struct pakfire_parser_state* state = yyget_extra(scanner); + + ERROR(pakfire, "Error (line %d): %s\n", state->lineno, s); // Create a new error object if (error) { - int r = pakfire_parser_error_create(error, *parser, NULL, num_lines, s); + int r = pakfire_parser_error_create(error, *parser, NULL, state->lineno, s); if (r) { ERROR(pakfire, "Could not create error object: %s\n", strerror(errno)); } @@ -400,6 +403,14 @@ int pakfire_parser_parse_data(struct pakfire_parser* parent, const char* data, s struct pakfire* pakfire = pakfire_parser_get_pakfire(parent); yyscan_t scanner; + // Initialize the parser's state + struct pakfire_parser_state state = { + .lineno = 1, + .indent_level = 0, + .current_indent = 0, + .readline_indent = 0, + }; + #ifdef ENABLE_DEBUG DEBUG(pakfire, "Parsing the following data (%zu):\n%.*s\n", len, (int)len, data); @@ -409,13 +420,11 @@ int pakfire_parser_parse_data(struct pakfire_parser* parent, const char* data, s #endif // Initialise scanner - yylex_init(&scanner); + yylex_init_extra(&state, &scanner); // Create a new sub-parser struct pakfire_parser* parser = NULL; - num_lines = 1; - YY_BUFFER_STATE buffer = yy_scan_bytes(data, len, scanner); int r = yyparse(scanner, pakfire, &parser, parent, error); yy_delete_buffer(buffer, scanner); diff --git a/src/libpakfire/parser/scanner.l b/src/libpakfire/parser/scanner.l index e8ca4fe7f..6bf90a21e 100644 --- a/src/libpakfire/parser/scanner.l +++ b/src/libpakfire/parser/scanner.l @@ -24,6 +24,7 @@ %option reentrant %option stack noyy_top_state %option warn +%option extra-type="struct pakfire_parser_state*" /* Enable to debug the scanner */ /* %option debug */ @@ -31,8 +32,6 @@ %{ #define YY_DECL int yylex (YYSTYPE* yylval_param, yyscan_t yyscanner) -int num_lines; - #include #include #include @@ -43,13 +42,6 @@ int num_lines; #include "grammar.h" -// Indentation level -unsigned int indent_level = 0; - -// Remember current indentation -unsigned int current_indent = 0; -unsigned int readline_indent = 0; - static char* unquote(const char* input) { size_t length = strlen(input); @@ -157,7 +149,7 @@ scriptlet script(let)? <*>\n { // Handles line numbers without consuming the newline character - num_lines++; REJECT; + yyextra->lineno++; REJECT; } #.*$ { @@ -166,7 +158,7 @@ scriptlet script(let)? \n { // Jump back into indentation processing after a newline - current_indent = 0; + yyextra->current_indent = 0; yy_push_state(INDENT, yyscanner); @@ -279,14 +271,15 @@ scriptlet script(let)? } \t { - if (readline_indent && current_indent >= readline_indent) + if (yyextra->readline_indent && + yyextra->current_indent >= yyextra->readline_indent) REJECT; - current_indent++; + yyextra->current_indent++; } \n { // Jump back into indentation processing after a newline - current_indent = 0; + yyextra->current_indent = 0; return T_EOL; } @@ -294,11 +287,11 @@ scriptlet script(let)? yyless(0); // This is the first line - if (!readline_indent) { + if (!yyextra->readline_indent) { // If indentation is above indent level, // we are good to continue - if (current_indent > indent_level) { - readline_indent = current_indent; + if (yyextra->current_indent > yyextra->indent_level) { + yyextra->readline_indent = yyextra->current_indent; return T_INDENT; // If we found the same or less indentation we go back @@ -309,8 +302,8 @@ scriptlet script(let)? } // <-- ? - else if (current_indent < readline_indent) { - readline_indent = 0; + else if (yyextra->current_indent < yyextra->readline_indent) { + yyextra->readline_indent = 0; yy_pop_state(yyscanner); return T_OUTDENT; @@ -320,26 +313,26 @@ scriptlet script(let)? } } -\t { current_indent++; } -\n { current_indent = 0; } +\t { yyextra->current_indent++; } +\n { yyextra->current_indent = 0; } . { // Put the read character back for the next round yyless(0); // Mark beginning of line to match ^ - if (current_indent == 0) + if (yyextra->current_indent == 0) yy_set_bol(1); // --> - More indentation? - if (current_indent > indent_level) { - indent_level++; + if (yyextra->current_indent > yyextra->indent_level) { + yyextra->indent_level++; yy_pop_state(yyscanner); return T_INDENT; // <-- - If indentation has become less - } else if (current_indent < indent_level) { - indent_level--; + } else if (yyextra->current_indent < yyextra->indent_level) { + yyextra->indent_level--; yy_pop_state(yyscanner); return T_OUTDENT; -- 2.39.5