# #
#############################################################################*/
-%parse-param {PakfireParser parser}
+%parse-param {Pakfire pakfire} {PakfireParser* result}
// Generate verbose error messages
%define parse.error verbose
%{
+
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
extern int yyparse();
extern int num_lines;
-static void yyerror(PakfireParser parser, const char* s);
+static void yyerror(Pakfire pakfire, PakfireParser* result, const char* s);
#define ABORT do { YYABORT; } while (0);
OP_EQUALS = 0,
};
-static PakfireParser make_if_stmt(PakfireParser parser, const enum operator op,
+static PakfireParser make_if_stmt(Pakfire pakfire, PakfireParser* parser, const enum operator op,
const char* val1, const char* val2, PakfireParser if_block, PakfireParser else_block);
static PakfireParser make_child(PakfireParser parent, const char* namespace);
+static inline int pakfire_parser_new_declaration(
+ struct pakfire_parser_declaration** declaration, const char* name, const char* value) {
+ if (!name)
+ return EINVAL;
+
+ struct pakfire_parser_declaration* d = malloc(sizeof(*d));
+ if (!d)
+ return ENOMEM;
+
+ // Copy name
+ d->name = strdup(name);
+
+ // Copy value
+ if (value)
+ d->value = strdup(value);
+ else
+ d->value = NULL;
+
+ *declaration = d;
+
+ return 0;
+}
+
+static void pakfire_parser_free_declaration(struct pakfire_parser_declaration* declaration) {
+ free(declaration->name);
+
+ if (declaration->value)
+ free(declaration->value);
+
+ free(declaration);
+}
+
%}
%token T_INDENT
%type <string> key
%type <string> value
+%type <declaration> declaration
%type <string> lines
%type <string> line
%union {
PakfireParser parser;
char* string;
+ struct pakfire_parser_declaration* declaration;
}
+%destructor { pakfire_parser_unref($$); } <parser>
+%destructor { pakfire_parser_free_declaration($$); } <declaration>
+
%start grammar
%%
grammar : %empty
{
- $$ = make_child(parser, NULL);
+ $$ = pakfire_parser_create(pakfire, NULL, NULL);
+ if (!$$)
+ ABORT;
+
+ if (!*result)
+ *result = $$;
}
| grammar declaration
+ {
+ int r = pakfire_parser_apply_declaration($1, $2);
+ if (r)
+ ABORT;
+
+ $$ = pakfire_parser_ref($1);
+ }
| grammar subparser
{
- if ($2) {
- $$ = pakfire_parser_merge($1, $2);
- //pakfire_parser_unref($2);
- }
+ pakfire_parser_merge($1, $2);
+ $$ = pakfire_parser_ref($1);
}
| grammar if_stmt
{
- if ($2) {
- $$ = pakfire_parser_merge($1, $2);
- //pakfire_parser_unref($2);
- }
+ pakfire_parser_merge($1, $2);
+ $$ = pakfire_parser_ref($1);
}
| grammar empty
{
- $$ = $1;
+ $$ = pakfire_parser_ref($1);
}
;
subgrammar : T_INDENT grammar T_OUTDENT
{
- $$ = $2;
+ $$ = pakfire_parser_ref($2);
}
;
declaration : key T_ASSIGN value T_EOL
{
- int r = pakfire_parser_set(parser, $1, $3);
+ int r = pakfire_parser_new_declaration(&$$, $1, $3);
if (r)
ABORT;
}
| key T_APPEND value T_EOL
{
- int r = pakfire_parser_append(parser, $1, $3);
+ // XXX HANDLE APPEND PROPERLY
+ int r = pakfire_parser_new_declaration(&$$, $1, $3);
if (r)
ABORT;
}
| key T_EOL T_INDENT lines T_OUTDENT T_END T_EOL
{
- int r = pakfire_parser_set(parser, $1, $4);
+ int r = pakfire_parser_new_declaration(&$$, $1, $4);
if (r)
ABORT;
}
}
;
-subparser : subparser_open T_INDENT grammar T_OUTDENT subparser_close
+subparser : T_SUBPARSER T_EOL subgrammar T_END T_EOL
{
- // Move back to the parent parser
- parser = pakfire_parser_get_parent(parser);
-
- // Merge block into the parent parser
- $$ = pakfire_parser_merge(parser, $3);
-
- // Free block parser
- pakfire_parser_unref($3);
+ // XXX HANDLE NAMESPACE
+ $$ = pakfire_parser_ref($3);
}
;
-subparser_open : T_SUBPARSER T_EOL
+if_stmt : T_IF T_STRING T_EQUALS T_STRING T_EOL subgrammar else_stmt T_END T_EOL
{
- // Create a new sub-parser which opens a new namespace
- parser = make_child(parser, $1);
+ $$ = make_if_stmt(pakfire, result, OP_EQUALS, $2, $4, $6, $7);
}
;
-subparser_close : T_END T_EOL;
-
-if : T_IF
- {
- // Open a new block
- parser = make_child(parser, NULL);
- };
-
-else : T_ELSE T_EOL
+else_stmt : T_ELSE T_EOL subgrammar
{
- // Close the if block
- parser = pakfire_parser_get_parent(parser);
-
- // Open a new else block
- parser = make_child(parser, NULL);
- };
-
-if_stmt : if T_STRING T_EQUALS T_STRING T_EOL subgrammar else_stmt T_END T_EOL
- {
- $$ = make_if_stmt(parser, OP_EQUALS, $2, $4, $6, $7);
-
- //pakfire_parser_unref($6);
- //pakfire_parser_unref($7);
- }
- ;
-
-else_stmt : else subgrammar
- {
- $$ = $2;
+ $$ = pakfire_parser_ref($3);
}
| %empty
{
#endif
// Create a new sub-parser
- PakfireParser parser = pakfire_parser_create(pakfire, parent, NULL);
+ PakfireParser parser = NULL;
num_lines = 1;
YY_BUFFER_STATE buffer = yy_scan_bytes(data, len);
- int r = yyparse(parser);
+ int r = yyparse(pakfire, &parser);
yy_delete_buffer(buffer);
// If everything was parsed successfully, we merge the sub-parser into
return r;
}
-void yyerror(PakfireParser parser, const char* s) {
- Pakfire pakfire = pakfire_parser_get_pakfire(parser);
-
+void yyerror(Pakfire pakfire, PakfireParser* result, const char* s) {
ERROR(pakfire, "Error (line %d): %s\n", num_lines, s);
-
- pakfire_unref(pakfire);
}
-static PakfireParser make_if_stmt(PakfireParser parser, const enum operator op,
+static PakfireParser make_if_stmt(Pakfire pakfire, PakfireParser* parser, const enum operator op,
const char* val1, const char* val2, PakfireParser if_block, PakfireParser else_block) {
- Pakfire pakfire = pakfire_parser_get_pakfire(parser);
-
switch (op) {
case OP_EQUALS:
DEBUG(pakfire, "Evaluating if statement: %s == %s?\n", val1, val2);
break;
}
- DEBUG(pakfire, " parser = %p, if = %p, else = %p\n", parser, if_block, else_block);
+ DEBUG(pakfire, " parser = %p, if = %p, else = %p\n", *parser, if_block, else_block);
// Expand values
- char* v1 = pakfire_parser_expand(parser, val1);
- char* v2 = pakfire_parser_expand(parser, val2);
+ char* v1 = pakfire_parser_expand(*parser, val1);
+ char* v2 = pakfire_parser_expand(*parser, val2);
PakfireParser result = NULL;
break;
}
- pakfire_unref(pakfire);
free(v1);
free(v2);