]> git.ipfire.org Git - pakfire.git/commitdiff
parser: Remove any global variables
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 1 Aug 2023 18:48:40 +0000 (18:48 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 1 Aug 2023 18:49:13 +0000 (18:49 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/include/pakfire/parser.h
src/libpakfire/parser/grammar.y
src/libpakfire/parser/scanner.l

index 5caa1f125cb1dbdc44a2f7c00a7a1740592b5912..a306a516ed84c5cc369f5bf28bd00f8419531fad 100644 (file)
@@ -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];
index 60a195e4add3a9bf1005c2c338c0ca78e38f862f..5cbb0abbbc76f78a1a106697e235e5c791857cd6 100644 (file)
 #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);
index e8ca4fe7f2d1ba5c88f5d6b437efc97606e29143..6bf90a21ea4d25373d296d1b3ef1a2ccb8aea721 100644 (file)
@@ -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 <ctype.h>
 #include <stdint.h>
 #include <stdlib.h>
@@ -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)?
                                                }
 
 <READLINES>\t                  {
-                                                       if (readline_indent && current_indent >= readline_indent)
+                                                       if (yyextra->readline_indent &&
+                                                                       yyextra->current_indent >= yyextra->readline_indent)
                                                                REJECT;
 
-                                                       current_indent++;
+                                                       yyextra->current_indent++;
                                                }
 <READLINES>\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)?
                                                        }
                                                }
 
-<INDENT>\t                             { current_indent++; }
-<INDENT>\n                             { current_indent = 0; }
+<INDENT>\t                             { yyextra->current_indent++; }
+<INDENT>\n                             { yyextra->current_indent = 0; }
 <INDENT>.                              {
                                                        // 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;