if (!PyArg_ParseTuple(args, "s", &data))
return NULL;
- int r = pakfire_parser_parse(self->parser, data, strlen(data));
+ int r = pakfire_parser_parse(self->parser, data, strlen(data), NULL);
if (r) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
return NULL;
}
- int r = pakfire_parser_read(self->parser, f);
+ int r = pakfire_parser_read(self->parser, f, NULL);
fclose(f);
if (r) {
return r;
// Parse metadata file
- r = pakfire_parser_parse_data(archive->parser, (const char*)data, data_size);
+ r = pakfire_parser_parse_data(archive->parser, (const char*)data, data_size, NULL);
free(data);
return r;
#include <pakfire/types.h>
+struct pakfire_parser_error;
+
PakfireParser pakfire_parser_create(Pakfire pakfire, PakfireParser parser,
const char* namespace);
PakfireParser pakfire_parser_create_child(PakfireParser parser,
PakfireParser pakfire_parser_merge(PakfireParser parser1, PakfireParser parser2);
-int pakfire_parser_read(PakfireParser parser, FILE* f);
-int pakfire_parser_read_file(PakfireParser parser, const char* path);
-int pakfire_parser_parse(PakfireParser parser, const char* data, size_t size);
+int pakfire_parser_read(PakfireParser parser, FILE* f, struct pakfire_parser_error** error);
+int pakfire_parser_read_file(PakfireParser parser, const char* path,
+ struct pakfire_parser_error** error);
+int pakfire_parser_parse(PakfireParser parser, const char* data, size_t size,
+ struct pakfire_parser_error** error);
char* pakfire_parser_dump(PakfireParser parser);
const char* pakfire_parser_get_namespace(PakfireParser parser);
int pakfire_parser_set_namespace(PakfireParser parser, const char* namespace);
+// Errors
+int pakfire_parser_error_create(struct pakfire_parser_error** error,
+ PakfireParser parser, const char* filename, int line, const char* message);
+struct pakfire_parser_error* pakfire_parser_error_ref(struct pakfire_parser_error* error);
+struct pakfire_parser_error* pakfire_parser_error_unref(struct pakfire_parser_error* error);
+
+const char* pakfire_parser_error_get_filename(struct pakfire_parser_error* error);
+int pakfire_parser_error_get_line(struct pakfire_parser_error* error);
+const char* pakfire_parser_error_get_message(struct pakfire_parser_error* error);
+
#ifdef PAKFIRE_PRIVATE
Pakfire pakfire_parser_get_pakfire(PakfireParser parser);
int pakfire_parser_apply_declaration(
PakfireParser parser, struct pakfire_parser_declaration* declaration);
-int pakfire_parser_parse_data(PakfireParser parser, const char* data, size_t len);
+int pakfire_parser_parse_data(PakfireParser parent, const char* data, size_t len,
+ struct pakfire_parser_error** error);
#endif /* PAKFIRE_PRIVATE */
pakfire_parser_set_namespace;
pakfire_parser_unref;
+ # parser error
+ pakfire_parser_error_create;
+ pakfire_parser_error_get_filename;
+ pakfire_parser_error_get_line;
+ pakfire_parser_error_get_message;
+ pakfire_parser_error_ref;
+ pakfire_parser_error_unref;
+
# problem
pakfire_problem_append;
pakfire_problem_create;
return parser1;
}
-PAKFIRE_EXPORT int pakfire_parser_read(PakfireParser parser, FILE* f) {
+PAKFIRE_EXPORT int pakfire_parser_read(PakfireParser parser, FILE* f,
+ struct pakfire_parser_error** error) {
char* data;
size_t len;
if (r)
return r;
- r = pakfire_parser_parse_data(parser, data, len);
+ r = pakfire_parser_parse_data(parser, data, len, error);
if (data)
free(data);
return r;
}
-PAKFIRE_EXPORT int pakfire_parser_read_file(PakfireParser parser, const char* path) {
+PAKFIRE_EXPORT int pakfire_parser_read_file(PakfireParser parser, const char* path,
+ struct pakfire_parser_error** error) {
FILE* f = fopen(path, "r");
if (!f)
return 1;
- int r = pakfire_parser_read(parser, f);
+ int r = pakfire_parser_read(parser, f, error);
fclose(f);
return r;
}
-PAKFIRE_EXPORT int pakfire_parser_parse(PakfireParser parser, const char* data, size_t size) {
- return pakfire_parser_parse_data(parser, data, size);
+PAKFIRE_EXPORT int pakfire_parser_parse(PakfireParser parser,
+ const char* data, size_t size, struct pakfire_parser_error** error) {
+ return pakfire_parser_parse_data(parser, data, size, error);
}
PAKFIRE_EXPORT char* pakfire_parser_dump(PakfireParser parser) {
return 0;
}
+
+// Error
+
+struct pakfire_parser_error {
+ PakfireParser parser;
+ int nrefs;
+
+ char* filename;
+ int line;
+ char* message;
+};
+
+PAKFIRE_EXPORT int pakfire_parser_error_create(struct pakfire_parser_error** error,
+ PakfireParser parser, const char* filename, int line, const char* message) {
+ struct pakfire_parser_error* e = calloc(1, sizeof(*e));
+ if (!e)
+ return ENOMEM;
+
+ // Initialize reference counter
+ e->nrefs = 1;
+
+ e->parser = pakfire_parser_ref(parser);
+
+ // Copy all input values
+ if (filename)
+ e->filename = strdup(filename);
+
+ e->line = line;
+
+ if (message)
+ e->message = strdup(message);
+
+ *error = e;
+
+ return 0;
+}
+
+PAKFIRE_EXPORT struct pakfire_parser_error* pakfire_parser_error_ref(
+ struct pakfire_parser_error* error) {
+ ++error->nrefs;
+
+ return error;
+}
+
+static void pakfire_parser_error_free(struct pakfire_parser_error* error) {
+ pakfire_parser_unref(error->parser);
+
+ if (error->filename)
+ free(error->filename);
+
+ if (error->message)
+ free(error->message);
+
+ free(error);
+}
+
+PAKFIRE_EXPORT struct pakfire_parser_error* pakfire_parser_error_unref(
+ struct pakfire_parser_error* error) {
+ if (--error->nrefs > 0)
+ return error;
+
+ pakfire_parser_error_free(error);
+
+ return NULL;
+}
+
+PAKFIRE_EXPORT const char* pakfire_parser_error_get_filename(
+ struct pakfire_parser_error* error) {
+ return error->filename;
+}
+
+PAKFIRE_EXPORT int pakfire_parser_error_get_line(struct pakfire_parser_error* error) {
+ return error->line;
+}
+
+PAKFIRE_EXPORT const char* pakfire_parser_error_get_message(
+ struct pakfire_parser_error* error) {
+ return error->message;
+}
# #
#############################################################################*/
-%parse-param {Pakfire pakfire} {PakfireParser* result}
+%parse-param {Pakfire pakfire} {PakfireParser* result} {struct pakfire_parser_error** error}
// Generate verbose error messages
%define parse.error verbose
extern int yyparse();
extern int num_lines;
-static void yyerror(Pakfire pakfire, PakfireParser* result, const char* s);
#define ABORT do { YYABORT; } while (0);
OP_EQUALS = 0,
};
+static void yyerror(Pakfire pakfire, PakfireParser* result,
+ struct pakfire_parser_error** error, const char* s) {
+ ERROR(pakfire, "Error (line %d): %s\n", num_lines, s);
+
+ // Create a new error object
+ if (error) {
+ int r = pakfire_parser_error_create(error, *result, NULL, num_lines, s);
+ if (r) {
+ ERROR(pakfire, "Could not create error object: %s\n", strerror(errno));
+ }
+ }
+}
+
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);
%%
-int pakfire_parser_parse_data(PakfireParser parent, const char* data, size_t len) {
+int pakfire_parser_parse_data(PakfireParser parent, const char* data, size_t len,
+ struct pakfire_parser_error** error) {
Pakfire pakfire = pakfire_parser_get_pakfire(parent);
#ifdef ENABLE_DEBUG
num_lines = 1;
YY_BUFFER_STATE buffer = yy_scan_bytes(data, len);
- int r = yyparse(pakfire, &parser);
+ int r = yyparse(pakfire, &parser, error);
yy_delete_buffer(buffer);
// If everything was parsed successfully, we merge the sub-parser into
return r;
}
-void yyerror(Pakfire pakfire, PakfireParser* result, const char* s) {
- ERROR(pakfire, "Error (line %d): %s\n", num_lines, s);
-}
-
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) {
switch (op) {
PakfireParser parser = pakfire_parser_create(t->pakfire, NULL, NULL);
- int r = pakfire_parser_read(parser, f);
+ int r = pakfire_parser_read(parser, f, NULL);
ASSERT(r == 0);
pakfire_parser_unref(parser);
ASSERT(parser);
for (unsigned int i = 0; i < buffer.gl_pathc; i++) {
- r = pakfire_parser_read_file(parser, buffer.gl_pathv[i]);
+ r = pakfire_parser_read_file(parser, buffer.gl_pathv[i], NULL);
ASSERT(r == 0);
}
FILE* f = fopen(path, "r");
ASSERT(f);
- int r = pakfire_parser_read(parser, f);
+ int r = pakfire_parser_read(parser, f, NULL);
if (r) {
fprintf(stderr, "Could not parse %s\n", path);
return EXIT_FAILURE;