aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--Makefile2
-rw-r--r--src/libmdsserver/macros.h13
-rw-r--r--src/mds-kbdc/make-tree.c25
-rw-r--r--src/mds-kbdc/mds-kbdc.c1
-rw-r--r--src/mds-kbdc/parsed.c121
-rw-r--r--src/mds-kbdc/parsed.h144
-rw-r--r--src/mds-kbdc/raw-data.c20
-rw-r--r--src/mds-kbdc/raw-data.h24
-rw-r--r--src/mds-kbdc/simplify-tree.c109
-rw-r--r--src/mds-kbdc/simplify-tree.h10
10 files changed, 395 insertions, 74 deletions
diff --git a/Makefile b/Makefile
index 2e77f50..76bf89f 100644
--- a/Makefile
+++ b/Makefile
@@ -31,7 +31,7 @@ OBJ_mds-registry_ = mds-registry util globals reexec registry signals \
slave
OBJ_mds-kbdc_ = mds-kbdc globals raw-data functions string tree \
- make-tree parse-error simplify-tree
+ make-tree parse-error simplify-tree parsed
OBJ_mds-server = $(foreach O,$(OBJ_mds-server_),obj/mds-server/$(O).o)
OBJ_mds-registry = $(foreach O,$(OBJ_mds-registry_),obj/mds-registry/$(O).o)
diff --git a/src/libmdsserver/macros.h b/src/libmdsserver/macros.h
index 79d427f..e7cfad5 100644
--- a/src/libmdsserver/macros.h
+++ b/src/libmdsserver/macros.h
@@ -38,6 +38,19 @@
/**
+ * Wrapper around `asprintf` that makes sure that first
+ * argument gets set to `NULL` on error and that zero is
+ * returned on success rather than the number of printed
+ * characters
+ *
+ * @param VAR:char** The output parameter for the string
+ * @param ...:const char*, ... The format string and arguments
+ * @return :int Zero on success, -1 on error
+ */
+#define xasprintf(VAR, ...) \
+ (asprintf(&(VAR), __VA_ARGS__) < 0 ? (VAR = NULL, -1) : 0)
+
+/**
* Wrapper for `snprintf` that allows you to forget about the buffer size
*
* @param buffer:char[] The buffer, must be of the type `char[]` and not `char*`
diff --git a/src/mds-kbdc/make-tree.c b/src/mds-kbdc/make-tree.c
index 72a50df..2e3668c 100644
--- a/src/mds-kbdc/make-tree.c
+++ b/src/mds-kbdc/make-tree.c
@@ -55,20 +55,6 @@
/**
- * Wrapper around `asprintf` that makes sure that first
- * argument gets set to `NULL` on error and that zero is
- * returned on success rather than the number of printed
- * characters
- *
- * @param VAR:char** The output parameter for the string
- * @param ...:const char*, ... The format string and arguments
- * @return :int Zero on success, -1 on error
- */
-#define xasprintf(VAR, ...) \
- (asprintf(&(VAR), __VA_ARGS__) < 0 ? (VAR = NULL, -1) : 0)
-
-
-/**
* Check whether a value is inside a closed range
*
* @param LOWER:¿T? The lower bound, inclusive
@@ -698,7 +684,7 @@ int parse_to_tree(const char* restrict filename, mds_kbdc_tree_t** restrict resu
mds_kbdc_parse_error_t* error;
mds_kbdc_parse_error_t** old_errors = NULL;
char* pathname;
- source_code_t source_code;
+ mds_kbdc_source_code_t source_code;
size_t errors_size = 0;
size_t errors_ptr = 0;
size_t line_i, line_n;
@@ -709,11 +695,11 @@ int parse_to_tree(const char* restrict filename, mds_kbdc_tree_t** restrict resu
*result = NULL;
*errors = NULL;
- source_code_initialise(&source_code);
+ mds_kbdc_source_code_initialise(&source_code);
/* Get a non-relative pathname for the file, relative filenames
* can be misleading as the program can have changed working
- * directroy to be able to resolve filenames. */
+ * directory to be able to resolve filenames. */
pathname = realpath(filename, NULL);
fail_if (pathname == NULL);
@@ -1076,7 +1062,7 @@ int parse_to_tree(const char* restrict filename, mds_kbdc_tree_t** restrict resu
free(pathname);
free(keyword_stack);
free(tree_stack);
- source_code_destroy(&source_code);
+ mds_kbdc_source_code_destroy(&source_code);
return 0;
pfail:
@@ -1084,7 +1070,7 @@ int parse_to_tree(const char* restrict filename, mds_kbdc_tree_t** restrict resu
free(pathname);
free(keyword_stack);
free(tree_stack);
- source_code_destroy(&source_code);
+ mds_kbdc_source_code_destroy(&source_code);
mds_kbdc_parse_error_free_all(old_errors);
mds_kbdc_parse_error_free_all(*errors), *errors = NULL;
mds_kbdc_tree_free(*result), *result = NULL;
@@ -1117,7 +1103,6 @@ int parse_to_tree(const char* restrict filename, mds_kbdc_tree_t** restrict resu
#undef LINE
#undef is_name_char
#undef in_range
-#undef xasprintf
#undef PRINT_STACK
#undef DEBUG_PROC
diff --git a/src/mds-kbdc/mds-kbdc.c b/src/mds-kbdc/mds-kbdc.c
index 34b2002..dc3327f 100644
--- a/src/mds-kbdc/mds-kbdc.c
+++ b/src/mds-kbdc/mds-kbdc.c
@@ -55,7 +55,6 @@ int main(int argc_, char** argv_)
if ((*errors)->severity >= MDS_KBDC_PARSE_ERROR_ERROR)
fatal = 1;
mds_kbdc_parse_error_print(*errors++, stderr);
- errors++;
}
mds_kbdc_parse_error_free_all(parse_errors);
if (fatal)
diff --git a/src/mds-kbdc/parsed.c b/src/mds-kbdc/parsed.c
new file mode 100644
index 0000000..e7d821b
--- /dev/null
+++ b/src/mds-kbdc/parsed.c
@@ -0,0 +1,121 @@
+/**
+ * mds — A micro-display server
+ * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "parsed.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+
+
+/**
+ * Initialise a `mds_kbdc_parsed_t*`
+ *
+ * @param this The `mds_kbdc_parsed_t*`
+ */
+void mds_kbdc_parsed_initialise(mds_kbdc_parsed_t* restrict this)
+{
+ memset(this, 0, sizeof(mds_kbdc_parsed_t));
+}
+
+
+/**
+ * Release all resources allocated in a `mds_kbdc_parsed_t*`
+ *
+ * @param this The `mds_kbdc_parsed_t*`
+ */
+void mds_kbdc_parsed_destroy(mds_kbdc_parsed_t* restrict this)
+{
+ mds_kbdc_tree_free(this->tree);
+ mds_kbdc_source_code_destroy(this->source_code);
+ free(this->pathname);
+ mds_kbdc_parse_error_free_all(this->errors);
+ memset(this, 0, sizeof(mds_kbdc_parsed_t));
+}
+
+
+/**
+ * Print all encountered errors
+ *
+ * @param this The parsing result
+ * @param output The output file
+ */
+void mds_kbdc_parsed_print_errors(mds_kbdc_parsed_t* restrict this, FILE* output)
+{
+ mds_kbdc_parse_error_t** errors = this->errors;
+ while (*errors)
+ mds_kbdc_parse_error_print(*errors++, output);
+}
+
+
+/**
+ * Add a new error to the list
+ *
+ * @param this The parsing result
+ * @param severity A `MDS_KBDC_PARSE_ERROR_*` to indicate severity
+ * @param error_is_in_file Whether the error is in the layout code
+ * @param line The line where the error occurred, zero-based
+ * @param start The byte where the error started, on the line, inclusive, zero-based
+ * @param end The byte where the error ended, on the line, exclusive, zero-based
+ * @return The new error on success, `NULL` on error
+ */
+mds_kbdc_parse_error_t* mds_kbdc_parsed_new_error(mds_kbdc_parsed_t* restrict this, int severity,
+ int error_is_in_file, size_t line, size_t start, size_t end)
+{
+ mds_kbdc_parse_error_t* error = NULL;
+ int saved_errno, old_errors_ptr = this->errors_ptr;
+
+ if (this->errors_ptr + 1 >= this->errors_size)
+ {
+ size_t new_errors_size = this->errors_size ? (this->errors_size << 1) : 2;
+ mds_kbdc_parse_error_t** new_errors = this->errors;
+
+ fail_if (xrealloc(new_errors, new_errors_size, mds_kbdc_parse_error_t*));
+ this->errors = new_errors;
+ this->errors_size = new_errors_size;
+ }
+
+ fail_if (xcalloc(error, 1, mds_kbdc_parse_error_t));
+ this->errors[this->errors_ptr + 0] = error;
+ this->errors[this->errors_ptr + 1] = NULL;
+ this->errors_ptr++;
+
+ error->severity = severity;
+ if (this->severest_error_level < severity)
+ this->severest_error_level = severity;
+
+ fail_if ((error->pathname = strdup(this->pathname)) == NULL);
+
+ if ((error->error_is_in_file = error_is_in_file))
+ {
+ error->line = line;
+ error->start = start;
+ error->end = end;
+ error->code = strdup(this->source_code.real_lines[line]);
+ fail_if (error->code == NULL);
+ }
+
+ return error;
+ pfail:
+ saved_errno = errno;
+ free(error);
+ this->errors_ptr = old_errors_ptr;
+ this->errors[this->errors_ptr] = NULL;
+ errno = saved_errno;
+ return NULL;
+}
+
diff --git a/src/mds-kbdc/parsed.h b/src/mds-kbdc/parsed.h
new file mode 100644
index 0000000..d16af62
--- /dev/null
+++ b/src/mds-kbdc/parsed.h
@@ -0,0 +1,144 @@
+/**
+ * mds — A micro-display server
+ * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef MDS_MDS_KBDC_PARSED_H
+#define MDS_MDS_KBDC_PARSED_H
+
+
+#include "tree.h"
+#include "raw-data.h"
+#include "parse-error.h"
+
+#include <libmdsserver/macros.h>
+
+#include <stddef.h>
+#include <stdio.h>
+
+
+
+
+/**
+ * @param RESULT:mds_kbdc_parsed_t* The parsing result
+ * @param SEVERITY:int * in `MDS_KBDC_PARSE_ERROR_*` to indicate severity
+ * @param ERROR_IS_IN_FILE:int Whether the error is in the layout code
+ * @param LINE:size_t The line where the error occurred, zero-based
+ * @param START:size_t The byte where the error started, on the line, inclusive, zero-based
+ * @param END:size_t The byte where the error ended, on the line, exclusive, zero-based
+ * @param ...:const char*, ... Error description format string and arguments
+ * @scope error:mds_kbdc_parse_error_t* Variable where the new error will be stored
+ */
+#define NEW_ERROR_(RESULT, SEVERITY, ERROR_IS_IN_FILE, LINE, START, END, ...) \
+ do \
+ { \
+ error = mds_kbdc_parsed_new_error(RESULT, SEVERITY, ERROR_IS_IN_FILE, LINE, START, END); \
+ fail_if (error == NULL); \
+ fail_if (xasprintf(error->description, __VA_ARGS__)); \
+ } \
+ while (0)
+
+
+
+/**
+ * Structure with parsed tree, error list
+ * source code and the file's pathname
+ */
+typedef struct mds_kbdc_parsed
+{
+ /**
+ * The parsed tree
+ */
+ mds_kbdc_tree_t* tree;
+
+ /**
+ * The source code of the parsed file
+ */
+ mds_kbdc_source_code_t* source_code;
+
+ /**
+ * A non-relative pathname to the parsed file.
+ * Relative filenames can be misleading as the
+ * program can have changed working directory
+ * to be able to resolve filenames.
+ */
+ char* pathname;
+
+ /**
+ * `NULL`-terminated list of found errors
+ * `NULL` if no errors that could be listed
+ * were found
+ */
+ mds_kbdc_parse_error_t** errors;
+
+ /**
+ * The number of elements allocated to `errors`
+ */
+ size_t errors_size;
+
+ /**
+ * The number of elements stored in `errors`
+ */
+ size_t errors_ptr;
+
+ /**
+ * The level of the severest countered error,
+ * 0 if none has been encountered.
+ */
+ int severest_error_level;
+
+} mds_kbdc_parsed_t;
+
+
+
+/**
+ * Initialise a `mds_kbdc_parsed_t*`
+ *
+ * @param this The `mds_kbdc_parsed_t*`
+ */
+void mds_kbdc_parsed_initialise(mds_kbdc_parsed_t* restrict this);
+
+/**
+ * Release all resources allocated in a `mds_kbdc_parsed_t*`
+ *
+ * @param this The `mds_kbdc_parsed_t*`
+ */
+void mds_kbdc_parsed_destroy(mds_kbdc_parsed_t* restrict this);
+
+/**
+ * Print all encountered errors
+ *
+ * @param this The parsing result
+ * @param output The output file
+ */
+void mds_kbdc_parsed_print_errors(mds_kbdc_parsed_t* restrict this, FILE* output);
+
+/**
+ * Add a new error to the list
+ *
+ * @param this The parsing result
+ * @param severity A `MDS_KBDC_PARSE_ERROR_*` to indicate severity
+ * @param error_is_in_file Whether the error is in the layout code
+ * @param line The line where the error occurred, zero-based
+ * @param start The byte where the error started, on the line, inclusive, zero-based
+ * @param end The byte where the error ended, on the line, exclusive, zero-based
+ * @return The new error on success, `NULL` on error
+ */
+mds_kbdc_parse_error_t* mds_kbdc_parsed_new_error(mds_kbdc_parsed_t* restrict this, int severity,
+ int error_is_in_file, size_t line, size_t start, size_t end);
+
+
+#endif
+
diff --git a/src/mds-kbdc/raw-data.c b/src/mds-kbdc/raw-data.c
index 60c3e17..a1f8ec3 100644
--- a/src/mds-kbdc/raw-data.c
+++ b/src/mds-kbdc/raw-data.c
@@ -33,11 +33,11 @@
/**
- * Initialise a `source_code_t*`
+ * Initialise a `mds_kbdc_source_code_t*`
*
- * @param this The `source_code_t*`
+ * @param this The `mds_kbdc_source_code_t*`
*/
-void source_code_initialise(source_code_t* restrict this)
+void mds_kbdc_source_code_initialise(mds_kbdc_source_code_t* restrict this)
{
this->lines = NULL;
this->real_lines = NULL;
@@ -48,11 +48,11 @@ void source_code_initialise(source_code_t* restrict this)
/**
- * Release all data in a `source_code_t*`
+ * Release all data in a `mds_kbdc_source_code_t*`
*
- * @param this The `source_code_t*`
+ * @param this The `mds_kbdc_source_code_t*`
*/
-void source_code_destroy(source_code_t* restrict this)
+void mds_kbdc_source_code_destroy(mds_kbdc_source_code_t* restrict this)
{
free(this->lines), this->lines = NULL;
free(this->real_lines), this->real_lines = NULL;
@@ -62,11 +62,11 @@ void source_code_destroy(source_code_t* restrict this)
/**
- * Release all data in a `source_code_t*`, and free it
+ * Release all data in a `mds_kbdc_source_code_t*`, and free it
*
- * @param this The `source_code_t*`
+ * @param this The `mds_kbdc_source_code_t*`
*/
-void source_code_free(source_code_t* restrict this)
+void mds_kbdc_source_code_free(mds_kbdc_source_code_t* restrict this)
{
free(this->lines);
free(this->real_lines);
@@ -316,7 +316,7 @@ static char** line_split(char* content, size_t length)
* @param source_code Output parameter for read data
* @return Zero on success, -1 on error
*/
-int read_source_lines(const char* restrict pathname, source_code_t* restrict source_code)
+int read_source_lines(const char* restrict pathname, mds_kbdc_source_code_t* restrict source_code)
{
char* content = NULL;
char* real_content = NULL;
diff --git a/src/mds-kbdc/raw-data.h b/src/mds-kbdc/raw-data.h
index 335afc6..4bc7355 100644
--- a/src/mds-kbdc/raw-data.h
+++ b/src/mds-kbdc/raw-data.h
@@ -25,7 +25,7 @@
/**
* Source code by lines, with and without comments
*/
-typedef struct source_code
+typedef struct mds_kbdc_source_code
{
/**
* Source code by lines without comments,
@@ -55,29 +55,29 @@ typedef struct source_code
*/
size_t line_count;
-} source_code_t;
+} mds_kbdc_source_code_t;
/**
- * Initialise a `source_code_t*`
+ * Initialise a `mds_kbdc_source_code_t*`
*
- * @param this The `source_code_t*`
+ * @param this The `mds_kbdc_source_code_t*`
*/
-void source_code_initialise(source_code_t* restrict this);
+void mds_kbdc_source_code_initialise(mds_kbdc_source_code_t* restrict this);
/**
- * Release all data in a `source_code_t*`
+ * Release all data in a `mds_kbdc_source_code_t*`
*
- * @param this The `source_code_t*`
+ * @param this The `mds_kbdc_source_code_t*`
*/
-void source_code_destroy(source_code_t* restrict this);
+void mds_kbdc_source_code_destroy(mds_kbdc_source_code_t* restrict this);
/**
- * Release all data in a `source_code_t*`, and free it
+ * Release all data in a `mds_kbdc_source_code_t*`, and free it
*
- * @param this The `source_code_t*`
+ * @param this The `mds_kbdc_source_code_t*`
*/
-void source_code_free(source_code_t* restrict this);
+void mds_kbdc_source_code_free(mds_kbdc_source_code_t* restrict this);
/**
@@ -101,7 +101,7 @@ size_t get_end_of_call(char* restrict content, size_t offset, size_t size) __att
* @param source_code Output parameter for read data
* @return Zero on success, -1 on error
*/
-int read_source_lines(const char* restrict pathname, source_code_t* restrict source_code);
+int read_source_lines(const char* restrict pathname, mds_kbdc_source_code_t* restrict source_code);
#endif
diff --git a/src/mds-kbdc/simplify-tree.c b/src/mds-kbdc/simplify-tree.c
index 83eb013..8b8bf1d 100644
--- a/src/mds-kbdc/simplify-tree.c
+++ b/src/mds-kbdc/simplify-tree.c
@@ -19,6 +19,9 @@
#include <libmdsserver/macros.h>
+#include <stdlib.h>
+#include <string.h>
+
/**
* Wrapper around `asprintf` that makes sure that first
@@ -35,20 +38,13 @@
/**
- * Pointer to the beginning of the current line
- */
-#define LINE \
- (source_code.lines[line_i])
-
-
-/**
* Add an error the to error list
*
- * @param ERROR_IS_IN_FILE:int Whether the error is in the layout code
- * @param SEVERITY:identifier * in `MDS_KBDC_PARSE_ERROR_*` to indicate severity
- * @param ...:const char*, ... Error description format string and arguments
+ * @param NODE:const mds_kbdc_tree_t* The node the triggered the error
+ * @param SEVERITY:identifier * in `MDS_KBDC_PARSE_ERROR_*` to indicate severity
+ * @param ...:const char*, ... Error description format string and arguments
*/
-#define NEW_ERROR(ERROR_IS_IN_FILE, SEVERITY, ...) \
+#define NEW_ERROR(NODE, SEVERITY, ...) \
do \
{ \
if (errors_ptr + 1 >= errors_size) \
@@ -61,14 +57,13 @@
(*errors)[errors_ptr + 0] = error; \
(*errors)[errors_ptr + 1] = NULL; \
errors_ptr++; \
- error->line = line_i; \
+ error->line = (NODE)->loc_line; \
error->severity = MDS_KBDC_PARSE_ERROR_##SEVERITY; \
- error->error_is_in_file = ERROR_IS_IN_FILE; \
- error->start = (size_t)(line - LINE); \
- error->end = (size_t)(end - LINE); \
+ error->error_is_in_file = 1; \
+ error->start = (NODE)->loc_start; \
+ error->end = (NODE)->loc_end; \
fail_if ((error->pathname = strdup(pathname)) == NULL); \
- if (ERROR_IS_IN_FILE) \
- fail_if ((error->code = strdup(source_code.real_lines[line_i])) == NULL); \
+ fail_if ((error->code = strdup(source_code.real_lines[error->line])) == NULL); \
fail_if (xasprintf(error->description, __VA_ARGS__)); \
} \
while (0)
@@ -81,17 +76,17 @@
* make adjustments to the error after calling
* `NEW_ERROR`
*/
-static mds_kbdc_parse_error_t* error = NULL;
+static mds_kbdc_parse_error_t* error;
/**
* The number of elements allocated for `*errors`
*/
-static size_t errors_size = 0;
+static size_t errors_size;
/**
* The number of elements stored in `*errors`
*/
-static size_t errors_ptr = 0;
+static size_t errors_ptr;
/**
* Pointer to the list of errors
@@ -101,8 +96,54 @@ static mds_kbdc_parse_error_t*** errors;
/**
* The old `*errors` used temporary when reallocating `*errors`
*/
-static mds_kbdc_parse_error_t** old_errors = NULL;
+static mds_kbdc_parse_error_t** old_errors;
+
+/**
+ * The pathname of the file that have been parsed
+ */
+static char* pathname;
+
+
+
+/**
+ * Simplify a subtree
+ *
+ * @param tree The tree
+ * @return Zero on success, -1 on error
+ */
+static int simplify(mds_kbdc_tree_t* restrict tree);
+
+/**
+ * Simplify a macro call-subtree
+ *
+ * @param tree The macro call-subtree
+ * @return Zero on success, -1 on error
+ */
+static int simplify_macro_call(mds_kbdc_tree_macro_call_t* restrict tree)
+{
+ mds_kbdc_tree_t* argument = tree->arguments;
+ mds_kbdc_tree_t** here;
+
+ /* Simplify arguments. */
+ for (argument = tree->arguments; argument; argument = argument->next)
+ simplify(argument);
+
+ /* Remove ‘.’:s. */
+ for (here = &(tree->arguments); *here; here = &((*here)->next))
+ while (*here && (*here)->type == MDS_KBDC_TREE_TYPE_NOTHING)
+ {
+ mds_kbdc_tree_t* temp = (*here)->next;
+ (*here)->next = NULL;
+ NEW_ERROR(*here, WARNING, "‘.’ outside alternation has no effect");
+ mds_kbdc_tree_free(*here);
+ *here = temp;
+ }
+
+ return 0;
+ pfail:
+ return -1;
+}
/**
@@ -132,15 +173,20 @@ static int simplify(mds_kbdc_tree_t* restrict tree)
break;
case MDS_KBDC_TREE_TYPE_MAP:
+ /* TODO */
break;
case MDS_KBDC_TREE_TYPE_ALTERNATION:
+ /* TODO find alternations inside alternations */
break;
case MDS_KBDC_TREE_TYPE_UNORDERED:
+ /* TODO find unordered and nothing inside unordered */
break;
case MDS_KBDC_TREE_TYPE_MACRO_CALL:
+ if ((r = simplify_macro_call(&(tree->macro_call))))
+ return r;
break;
default:
@@ -156,21 +202,33 @@ static int simplify(mds_kbdc_tree_t* restrict tree)
/**
* Simplify a tree and generate related warnings in the process
*
- * @param tree The tree, it may be modified
- * @param errors_ `NULL`-terminated list of found error, `NULL` if no errors were found or if -1 is returned
- * @return -1 if an error occursed that cannot be stored in `*errors`, zero otherwise
+ * @param filename The filename of the tree that have been parsed
+ * @param tree The tree, it may be modified
+ * @param errors_ `NULL`-terminated list of found error, `NULL` if no errors were found or if -1 is returned
+ * @return -1 if an error occursed that cannot be stored in `*errors`, zero otherwise
*/
-int simplify_tree(mds_kbdc_tree_t* restrict tree, mds_kbdc_parse_error_t*** restrict errors_)
+int simplify_tree(const char* restrict filename, mds_kbdc_tree_t* restrict tree,
+ mds_kbdc_parse_error_t*** restrict errors_)
{
int r, saved_errno;
+ error = NULL;
+ errors_size = errors_ptr = 0;
errors = errors_;
*errors = NULL;
+ old_errors = NULL;
+
+ /* Get a non-relative pathname for the file, relative filenames
+ * can be misleading as the program can have changed working
+ * directroy to be able to resolve filenames. */
+ fail_if ((pathname = realpath(filename, NULL), pathname == NULL));
if (r = simplify(tree), !r)
return 0;
+ pfail:
saved_errno = errno;
+ free(pathname);
mds_kbdc_parse_error_free_all(old_errors);
mds_kbdc_parse_error_free_all(*errors), *errors = NULL;
errno = saved_errno;
@@ -180,6 +238,5 @@ int simplify_tree(mds_kbdc_tree_t* restrict tree, mds_kbdc_parse_error_t*** rest
#undef NEW_ERROR
-#undef LINE
#undef xasprintf
diff --git a/src/mds-kbdc/simplify-tree.h b/src/mds-kbdc/simplify-tree.h
index c45f1de..94e4f94 100644
--- a/src/mds-kbdc/simplify-tree.h
+++ b/src/mds-kbdc/simplify-tree.h
@@ -26,11 +26,13 @@
/**
* Simplify a tree and generate related warnings in the process
*
- * @param tree The tree, it may be modified
- * @param errors `NULL`-terminated list of found error, `NULL` if no errors were found or if -1 is returned
- * @return -1 if an error occursed that cannot be stored in `*errors`, zero otherwise
+ * @param filename The filename of the tree that have been parsed
+ * @param tree The tree, it may be modified
+ * @param errors `NULL`-terminated list of found error, `NULL` if no errors were found or if -1 is returned
+ * @return -1 if an error occursed that cannot be stored in `*errors`, zero otherwise
*/
-int simplify_tree(mds_kbdc_tree_t* restrict tree, mds_kbdc_parse_error_t*** restrict errors);
+int simplify_tree(const char* restrict filename, mds_kbdc_tree_t* restrict tree,
+ mds_kbdc_parse_error_t*** restrict errors);
#endif