aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mds-kbdc/make-tree.c98
-rw-r--r--src/mds-kbdc/make-tree.h11
-rw-r--r--src/mds-kbdc/mds-kbdc.c30
-rw-r--r--src/mds-kbdc/parsed.c22
-rw-r--r--src/mds-kbdc/parsed.h24
-rw-r--r--src/mds-kbdc/simplify-tree.c112
-rw-r--r--src/mds-kbdc/simplify-tree.h12
7 files changed, 93 insertions, 216 deletions
diff --git a/src/mds-kbdc/make-tree.c b/src/mds-kbdc/make-tree.c
index 2e3668c..1d91a57 100644
--- a/src/mds-kbdc/make-tree.c
+++ b/src/mds-kbdc/make-tree.c
@@ -17,10 +17,6 @@
*/
#include "make-tree.h"
-#include "raw-data.h"
-
-#include <libmdsserver/macros.h>
-
#include <limits.h>
#include <stdlib.h>
#include <libgen.h>
@@ -80,7 +76,7 @@
* Pointer to the beginning of the current line
*/
#define LINE \
- (source_code.lines[line_i])
+ (result->source_code->lines[line_i])
/**
@@ -94,33 +90,14 @@
/**
* 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 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
+ * @scope error:mds_kbdc_parse_error_t* Variable where the new error will be stored
*/
-#define NEW_ERROR(ERROR_IS_IN_FILE, SEVERITY, ...) \
- do \
- { \
- if (errors_ptr + 1 >= errors_size) \
- { \
- errors_size = errors_size ? (errors_size << 1) : 2; \
- fail_if (xxrealloc(old_errors, *errors, errors_size, mds_kbdc_parse_error_t*)); \
- } \
- fail_if (xcalloc(error, 1, mds_kbdc_parse_error_t)); \
- (*errors)[errors_ptr + 0] = error; \
- (*errors)[errors_ptr + 1] = NULL; \
- errors_ptr++; \
- error->line = line_i; \
- 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); \
- 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 (xasprintf(error->description, __VA_ARGS__)); \
- } \
- while (0)
+#define NEW_ERROR(ERROR_IS_IN_FILE, SEVERITY, ...) \
+ NEW_ERROR_(result, SEVERITY, ERROR_IS_IN_FILE, line_i, \
+ (size_t)(line - LINE), (size_t)(end - LINE), 1, __VA_ARGS__)
/**
@@ -674,57 +651,39 @@
* Parse a file into a syntax tree
*
* @param filename The filename of the file to parse
- * @param result Output parameter for the root of the tree, `NULL` if -1 is returned
- * @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 result Output parameter for the parsing result
+ * @return -1 if an error occursed that cannot be stored in `result`, zero otherwise
*/
-int parse_to_tree(const char* restrict filename, mds_kbdc_tree_t** restrict result,
- mds_kbdc_parse_error_t*** restrict errors)
+int parse_to_tree(const char* restrict filename, mds_kbdc_parsed_t* restrict result)
{
mds_kbdc_parse_error_t* error;
- mds_kbdc_parse_error_t** old_errors = NULL;
- char* pathname;
- mds_kbdc_source_code_t source_code;
- size_t errors_size = 0;
- size_t errors_ptr = 0;
size_t line_i, line_n;
const char** keyword_stack = NULL;
mds_kbdc_tree_t*** tree_stack = NULL;
size_t stack_ptr = 0;
int saved_errno, in_array = 0;
- *result = NULL;
- *errors = NULL;
- mds_kbdc_source_code_initialise(&source_code);
+ fail_if (xmalloc(result->source_code, 1, mds_kbdc_source_code_t));
+ mds_kbdc_source_code_initialise(result->source_code);
/* Get a non-relative pathname for the file, relative filenames
* can be misleading as the program can have changed working
* directory to be able to resolve filenames. */
- pathname = realpath(filename, NULL);
- fail_if (pathname == NULL);
+ result->pathname = realpath(filename, NULL);
+ fail_if (result->pathname == NULL);
/* Check that the file exists and can be read. */
- if (access(pathname, R_OK) < 0)
+ if (access(result->pathname, R_OK) < 0)
{
saved_errno = errno;
- fail_if (xmalloc(*errors, 2, mds_kbdc_parse_error_t*));
- fail_if (xmalloc(**errors, 1, mds_kbdc_parse_error_t));
- (*errors)[1] = NULL;
-
- (**errors)->severity = MDS_KBDC_PARSE_ERROR_ERROR;
- (**errors)->error_is_in_file = 0;
- (**errors)->pathname = pathname, pathname = NULL;
- (**errors)->line = 0;
- (**errors)->start = 0;
- (**errors)->end = 0;
- (**errors)->code = NULL;
- (**errors)->description = strdup(strerror(saved_errno));
- fail_if ((**errors)->description == NULL);
+ NEW_ERROR_(result, ERROR, 0, 0, 0, 0, 0, NULL);
+ error->description = strdup(strerror(saved_errno));
+ fail_if (error->description == NULL);
return 0;
}
/* Read the file and simplify it a bit. */
- fail_if (read_source_lines(pathname, &source_code) < 0);
+ fail_if (read_source_lines(result->pathname, result->source_code) < 0);
/* TODO '\t':s should be expanded into ' ':s. */
/* Allocate stacks needed to parse the tree. */
@@ -732,20 +691,20 @@ int parse_to_tree(const char* restrict filename, mds_kbdc_tree_t** restrict resu
/* The maxium line-length is needed because lines can have there own stacking,
* like sequence mapping lines, additionally, let statements can have one array. */
size_t max_line_length = 0, cur_line_length;
- for (line_i = 0, line_n = source_code.line_count; line_i < line_n; line_i++)
+ for (line_i = 0, line_n = result->source_code->line_count; line_i < line_n; line_i++)
{
cur_line_length = strlen(LINE);
if (max_line_length < cur_line_length)
max_line_length = cur_line_length;
}
- fail_if (xmalloc(keyword_stack, source_code.line_count + max_line_length, const char*));
- fail_if (xmalloc(tree_stack, source_code.line_count + max_line_length + 1, mds_kbdc_tree_t**));
+ fail_if (xmalloc(keyword_stack, result->source_code->line_count + max_line_length, const char*));
+ fail_if (xmalloc(tree_stack, result->source_code->line_count + max_line_length + 1, mds_kbdc_tree_t**));
}
/* Create a node-slot for the tree root. */
- *tree_stack = result;
+ *tree_stack = &(result->tree);
- for (line_i = 0, line_n = source_code.line_count; line_i < line_n; line_i++)
+ for (line_i = 0, line_n = result->source_code->line_count; line_i < line_n; line_i++)
{
char* line = LINE;
char* end;
@@ -1059,21 +1018,14 @@ int parse_to_tree(const char* restrict filename, mds_kbdc_tree_t** restrict resu
}
}
- free(pathname);
free(keyword_stack);
free(tree_stack);
- mds_kbdc_source_code_destroy(&source_code);
return 0;
pfail:
saved_errno = errno;
- free(pathname);
free(keyword_stack);
free(tree_stack);
- 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;
return errno = saved_errno, -1;
}
diff --git a/src/mds-kbdc/make-tree.h b/src/mds-kbdc/make-tree.h
index 6c02a8f..e854dad 100644
--- a/src/mds-kbdc/make-tree.h
+++ b/src/mds-kbdc/make-tree.h
@@ -19,20 +19,17 @@
#define MDS_MDS_KBDC_MAKE_TREE_H
-#include "tree.h"
-#include "parse-error.h"
+#include "parsed.h"
/**
* Parse a file into a syntax tree
*
* @param filename The filename of the file to parse
- * @param result Output parameter for the root of the tree, `NULL` if -1 is returned
- * @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 result Output parameter for the parsing result
+ * @return -1 if an error occursed that cannot be stored in `result`, zero otherwise
*/
-int parse_to_tree(const char* restrict filename, mds_kbdc_tree_t** restrict result,
- mds_kbdc_parse_error_t*** restrict errors);
+int parse_to_tree(const char* restrict filename, mds_kbdc_parsed_t* restrict result);
#endif
diff --git a/src/mds-kbdc/mds-kbdc.c b/src/mds-kbdc/mds-kbdc.c
index dc3327f..f7bfb06 100644
--- a/src/mds-kbdc/mds-kbdc.c
+++ b/src/mds-kbdc/mds-kbdc.c
@@ -38,33 +38,23 @@
*/
int main(int argc_, char** argv_)
{
- mds_kbdc_parse_error_t** parse_errors;
- mds_kbdc_tree_t* tree;
+ mds_kbdc_parsed_t result;
+ int fatal;
argc = argc_;
argv = argv_;
- fail_if (parse_to_tree(argv[1], &tree, &parse_errors) < 0);
- mds_kbdc_tree_print(tree, stderr);
- if (parse_errors != NULL)
- {
- mds_kbdc_parse_error_t** errors = parse_errors;
- int fatal = 0;
- while (*errors)
- {
- if ((*errors)->severity >= MDS_KBDC_PARSE_ERROR_ERROR)
- fatal = 1;
- mds_kbdc_parse_error_print(*errors++, stderr);
- }
- mds_kbdc_parse_error_free_all(parse_errors);
- if (fatal)
- return mds_kbdc_tree_free(tree), 1;
- }
- mds_kbdc_tree_free(tree);
- return 0;
+ mds_kbdc_parsed_initialise(&result);
+ fail_if (parse_to_tree(argv[1], &result) < 0);
+ fatal = mds_kbdc_parsed_is_fatal(&result);
+ mds_kbdc_tree_print(result.tree, stderr);
+ mds_kbdc_parsed_print_errors(&result, stderr);
+ mds_kbdc_parsed_destroy(&result);
+ return fatal;
pfail:
xperror(*argv);
+ mds_kbdc_parsed_destroy(&result);
return 1;
}
diff --git a/src/mds-kbdc/parsed.c b/src/mds-kbdc/parsed.c
index e7d821b..6b4160f 100644
--- a/src/mds-kbdc/parsed.c
+++ b/src/mds-kbdc/parsed.c
@@ -49,6 +49,18 @@ void mds_kbdc_parsed_destroy(mds_kbdc_parsed_t* restrict this)
/**
+ * Check whether a fatal errors has occurred
+ *
+ * @param this The parsing result
+ * @return Whether a fatal errors has occurred
+ */
+int mds_kbdc_parsed_is_fatal(mds_kbdc_parsed_t* restrict this)
+{
+ return this->severest_error_level >= MDS_KBDC_PARSE_ERROR_ERROR;
+}
+
+
+/**
* Print all encountered errors
*
* @param this The parsing result
@@ -57,8 +69,9 @@ void mds_kbdc_parsed_destroy(mds_kbdc_parsed_t* restrict this)
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);
+ if (errors)
+ while (*errors)
+ mds_kbdc_parse_error_print(*errors++, output);
}
@@ -77,7 +90,8 @@ mds_kbdc_parse_error_t* mds_kbdc_parsed_new_error(mds_kbdc_parsed_t* restrict th
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;
+ size_t old_errors_ptr = this->errors_ptr;
+ int saved_errno;
if (this->errors_ptr + 1 >= this->errors_size)
{
@@ -105,7 +119,7 @@ mds_kbdc_parse_error_t* mds_kbdc_parsed_new_error(mds_kbdc_parsed_t* restrict th
error->line = line;
error->start = start;
error->end = end;
- error->code = strdup(this->source_code.real_lines[line]);
+ error->code = strdup(this->source_code->real_lines[line]);
fail_if (error->code == NULL);
}
diff --git a/src/mds-kbdc/parsed.h b/src/mds-kbdc/parsed.h
index f2a847e..567168c 100644
--- a/src/mds-kbdc/parsed.h
+++ b/src/mds-kbdc/parsed.h
@@ -37,16 +37,18 @@
* @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 WITH_DESCRIPTION:int Whether a description should be stored
* @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__)); \
- } \
+#define NEW_ERROR_(RESULT, SEVERITY, ERROR_IS_IN_FILE, LINE, START, END, WITH_DESCRIPTION, ...) \
+ do \
+ { \
+ error = mds_kbdc_parsed_new_error(RESULT, MDS_KBDC_PARSE_ERROR_##SEVERITY, \
+ ERROR_IS_IN_FILE, LINE, START, END); \
+ fail_if (error == NULL); \
+ fail_if (WITH_DESCRIPTION && xasprintf(error->description, __VA_ARGS__)); \
+ } \
while (0)
@@ -117,6 +119,14 @@ void mds_kbdc_parsed_initialise(mds_kbdc_parsed_t* restrict this);
void mds_kbdc_parsed_destroy(mds_kbdc_parsed_t* restrict this);
/**
+ * Check whether a fatal errors has occurred
+ *
+ * @param this The parsing result
+ * @return Whether a fatal errors has occurred
+ */
+int mds_kbdc_parsed_is_fatal(mds_kbdc_parsed_t* restrict this) __attribute__((pure));
+
+/**
* Print all encountered errors
*
* @param this The parsing result
diff --git a/src/mds-kbdc/simplify-tree.c b/src/mds-kbdc/simplify-tree.c
index 8b8bf1d..87dd891 100644
--- a/src/mds-kbdc/simplify-tree.c
+++ b/src/mds-kbdc/simplify-tree.c
@@ -17,91 +17,34 @@
*/
#include "simplify-tree.h"
-#include <libmdsserver/macros.h>
-
#include <stdlib.h>
#include <string.h>
-/**
- * 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)
-
/**
* Add an error the to error list
*
- * @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
+ * @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
+ * @scope error:mds_kbdc_parse_error_t* Variable where the new error will be stored
*/
-#define NEW_ERROR(NODE, SEVERITY, ...) \
- do \
- { \
- if (errors_ptr + 1 >= errors_size) \
- { \
- errors_size = errors_size ? (errors_size << 1) : 2; \
- fail_if (xxrealloc(old_errors, *errors, errors_size, mds_kbdc_parse_error_t*)); \
- old_errors = NULL; \
- } \
- fail_if (xcalloc(error, 1, mds_kbdc_parse_error_t)); \
- (*errors)[errors_ptr + 0] = error; \
- (*errors)[errors_ptr + 1] = NULL; \
- errors_ptr++; \
- error->line = (NODE)->loc_line; \
- error->severity = MDS_KBDC_PARSE_ERROR_##SEVERITY; \
- error->error_is_in_file = 1; \
- error->start = (NODE)->loc_start; \
- error->end = (NODE)->loc_end; \
- fail_if ((error->pathname = strdup(pathname)) == NULL); \
- fail_if ((error->code = strdup(source_code.real_lines[error->line])) == NULL); \
- fail_if (xasprintf(error->description, __VA_ARGS__)); \
- } \
- while (0)
+#define NEW_ERROR(NODE, SEVERITY, ...) \
+ NEW_ERROR_(result, SEVERITY, 1, (NODE)->loc_line, \
+ (NODE)->loc_start, (NODE)->loc_end, 1, __VA_ARGS__)
/**
- * Temporary storage variable for the new error,
- * it is made available so that it is easy to
- * make adjustments to the error after calling
- * `NEW_ERROR`
+ * Variable whether the latest created error is stored
*/
static mds_kbdc_parse_error_t* error;
/**
- * The number of elements allocated for `*errors`
- */
-static size_t errors_size;
-
-/**
- * The number of elements stored in `*errors`
+ * The parameter of `simplify_tree`
*/
-static size_t errors_ptr;
-
-/**
- * Pointer to the list of errors
- */
-static mds_kbdc_parse_error_t*** errors;
-
-/**
- * The old `*errors` used temporary when reallocating `*errors`
- */
-static mds_kbdc_parse_error_t** old_errors;
-
-/**
- * The pathname of the file that have been parsed
- */
-static char* pathname;
+static mds_kbdc_parsed_t* restrict result;
@@ -202,41 +145,16 @@ static int simplify(mds_kbdc_tree_t* restrict tree)
/**
* Simplify a tree and generate related warnings in the process
*
- * @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
+ * @param result_ `result` from `parse_to_tree`, same sematics, will be updated
+ * @return -1 if an error occursed that cannot be stored in `result`, zero otherwise
*/
-int simplify_tree(const char* restrict filename, mds_kbdc_tree_t* restrict tree,
- mds_kbdc_parse_error_t*** restrict errors_)
+int simplify_tree(mds_kbdc_parsed_t* restrict result_)
{
- 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;
- return r;
+ result = result_;
+ return simplify(result_->tree);
}
#undef NEW_ERROR
-#undef xasprintf
diff --git a/src/mds-kbdc/simplify-tree.h b/src/mds-kbdc/simplify-tree.h
index 94e4f94..9db62ef 100644
--- a/src/mds-kbdc/simplify-tree.h
+++ b/src/mds-kbdc/simplify-tree.h
@@ -19,20 +19,16 @@
#define MDS_MDS_KBDC_SIMPLIFY_TREE_H
-#include "tree.h"
-#include "parse-error.h"
+#include "parsed.h"
/**
* Simplify a tree and generate related warnings in the process
*
- * @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
+ * @param result `result` from `parse_to_tree`, same sematics, will be updated
+ * @return -1 if an error occursed that cannot be stored in `result`, zero otherwise
*/
-int simplify_tree(const char* restrict filename, mds_kbdc_tree_t* restrict tree,
- mds_kbdc_parse_error_t*** restrict errors);
+int simplify_tree(mds_kbdc_parsed_t* restrict result);
#endif