1 /*#############################################################################
3 # Pakfire - The IPFire package management system #
4 # Copyright (C) 2019 Pakfire development team #
6 # This program is free software: you can redistribute it and/or modify #
7 # it under the terms of the GNU General Public License as published by #
8 # the Free Software Foundation, either version 3 of the License, or #
9 # (at your option) any later version. #
11 # This program is distributed in the hope that it will be useful, #
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14 # GNU General Public License for more details. #
16 # You should have received a copy of the GNU General Public License #
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
19 #############################################################################*/
24 #include <pakfire/logging.h>
25 #include <pakfire/parser.h>
26 #include <pakfire/types.h>
27 #include <pakfire/util.h>
29 #define YYERROR_VERBOSE 1
31 typedef struct yy_buffer_state* YY_BUFFER_STATE;
32 extern YY_BUFFER_STATE yy_scan_bytes(const char* buffer, size_t len);
33 extern void yy_delete_buffer(YY_BUFFER_STATE buffer);
39 static Pakfire pakfire;
40 static void yyerror(const char* s);
42 static void cleanup(void);
43 #define ABORT do { cleanup(); YYABORT; } while (0);
45 #define NUM_DECLARATIONS 128
46 static int pakfire_parser_add_declaration(const char* name, const char* value);
47 static struct pakfire_parser_declaration* declarations[NUM_DECLARATIONS];
49 char* current_block = NULL;
63 %type <string> variable;
81 empty : WHITESPACE NEWLINE
85 // Optional whitespace
86 whitespace : WHITESPACE
108 | words WHITESPACE WORD
110 int r = asprintf(&$$, "%s %s", $1, $3);
112 ERROR(pakfire, "Could not allocate memory");
117 line : whitespace words NEWLINE
119 // Only forward words
122 | whitespace NEWLINE {
128 int r = asprintf(&$$, "%s\n%s", $1, $2);
130 ERROR(pakfire, "Could not allocate memory");
140 block_opening : variable NEWLINE
142 current_block = pakfire_strdup($1);
145 block_closing : END NEWLINE
147 pakfire_free(current_block);
148 current_block = NULL;
151 block : block_opening assignments block_closing;
153 assignments : assignments assignment
158 assignment : whitespace variable whitespace ASSIGN whitespace value whitespace NEWLINE
160 int r = pakfire_parser_add_declaration($2, $6);
164 | whitespace DEFINE WHITESPACE variable NEWLINE text whitespace END NEWLINE
166 int r = pakfire_parser_add_declaration($4, $6);
173 static void cleanup(void) {
174 // Reset Pakfire pointer
177 // Free all declarations
178 for (unsigned int i = 0; i < NUM_DECLARATIONS; i++) {
179 pakfire_free(declarations[i]);
182 // Reset current_block
184 pakfire_free(current_block);
185 current_block = NULL;
189 static int pakfire_parser_add_declaration(const char* name, const char* value) {
190 struct pakfire_parser_declaration* d;
193 while (i++ < NUM_DECLARATIONS && declarations[i])
196 if (i == NUM_DECLARATIONS) {
197 ERROR(pakfire, "No free declarations left\n");
201 // Allocate a new declaration
202 declarations[i] = d = pakfire_calloc(1, sizeof(*d));
208 int r = asprintf(&d->name, "%s.%s", current_block, name);
212 d->name = pakfire_strdup(name);
216 d->value = pakfire_strdup(value);
218 DEBUG(pakfire, "New declaration: %s = %s\n", d->name, d->value);
223 int pakfire_parser_parse_metadata(Pakfire _pakfire, const char* data, size_t len) {
226 DEBUG(pakfire, "Parsing the following data:\n%s\n", data);
230 YY_BUFFER_STATE buffer = yy_scan_bytes(data, len);
232 yy_delete_buffer(buffer);
237 void yyerror(const char* s) {
238 ERROR(pakfire, "Error (line %d): %s\n", num_lines, s);