aboutsummaryrefslogtreecommitdiffstats
path: root/src/mds-kbdc
diff options
context:
space:
mode:
Diffstat (limited to 'src/mds-kbdc')
-rw-r--r--src/mds-kbdc/builtin-functions.c99
-rw-r--r--src/mds-kbdc/compile-layout.c90
-rw-r--r--src/mds-kbdc/eliminate-dead-code.c22
-rw-r--r--src/mds-kbdc/include-stack.c13
-rw-r--r--src/mds-kbdc/make-tree.c27
-rw-r--r--src/mds-kbdc/paths.c5
-rw-r--r--src/mds-kbdc/process-includes.c10
-rw-r--r--src/mds-kbdc/raw-data.c8
-rw-r--r--src/mds-kbdc/simplify-tree.c40
-rw-r--r--src/mds-kbdc/string.c15
-rw-r--r--src/mds-kbdc/tree.c7
-rw-r--r--src/mds-kbdc/validate-tree.c41
-rw-r--r--src/mds-kbdc/variables.c11
13 files changed, 241 insertions, 147 deletions
diff --git a/src/mds-kbdc/builtin-functions.c b/src/mds-kbdc/builtin-functions.c
index fca6496..4ccc31f 100644
--- a/src/mds-kbdc/builtin-functions.c
+++ b/src/mds-kbdc/builtin-functions.c
@@ -19,6 +19,8 @@
#include "variables.h"
+#include <libmdsserver/macros.h>
+
#include <stdlib.h>
#include <string.h>
@@ -34,8 +36,7 @@
size_t bn = string_length(b); \
size_t i, n = an > bn ? an : bn; \
char32_t* restrict rc = malloc((n + 1) * sizeof(char32_t)); \
- if (rc == NULL) \
- return NULL; \
+ fail_if (rc == NULL); \
rc[n] = -1
/**
@@ -45,10 +46,19 @@
const char32_t* restrict a = *args++; \
size_t i, n = string_length(a); \
char32_t* restrict rc = malloc((n + 1) * sizeof(char32_t)); \
- if (rc == NULL) \
- return NULL; \
+ fail_if (rc == NULL); \
rc[n] = -1
+/**
+ * Return a value, or if there was a failure somewhere, return `NULL`
+ *
+ * @param v:void* The value to return on success
+ */
+#define return(v) \
+ return v; \
+ fail: \
+ return NULL;
+
/**
* Definition of the built-in function add/2
@@ -61,7 +71,7 @@ static char32_t* builtin_function_add_2(const char32_t** restrict args)
define_2;
for (i = 0; i < n; i++)
rc[i] = a[i % an] + b[i % bn];
- return rc;
+ return(rc);
}
@@ -76,7 +86,7 @@ static char32_t* builtin_function_sub_2(const char32_t** restrict args)
define_2;
for (i = 0; i < n; i++)
rc[i] = a[i % an] - b[i % bn];
- return rc;
+ return(rc);
}
@@ -91,7 +101,7 @@ static char32_t* builtin_function_mul_2(const char32_t** restrict args)
define_2;
for (i = 0; i < n; i++)
rc[i] = a[i % an] * b[i % bn];
- return rc;
+ return(rc);
}
@@ -106,7 +116,7 @@ static char32_t* builtin_function_div_2(const char32_t** restrict args)
define_2;
for (i = 0; i < n; i++)
rc[i] = a[i % an] / b[i % bn];
- return rc;
+ return(rc);
}
@@ -121,7 +131,7 @@ static char32_t* builtin_function_mod_2(const char32_t** restrict args)
define_2;
for (i = 0; i < n; i++)
rc[i] = a[i % an] % b[i % bn];
- return rc;
+ return(rc);
}
@@ -136,7 +146,7 @@ static char32_t* builtin_function_rsh_2(const char32_t** restrict args)
define_2;
for (i = 0; i < n; i++)
rc[i] = a[i % an] << b[i % bn];
- return rc;
+ return(rc);
}
@@ -151,7 +161,7 @@ static char32_t* builtin_function_lsh_2(const char32_t** restrict args)
define_2;
for (i = 0; i < n; i++)
rc[i] = a[i % an] >> b[i % bn];
- return rc;
+ return(rc);
}
@@ -166,7 +176,7 @@ static char32_t* builtin_function_or_2(const char32_t** restrict args)
define_2;
for (i = 0; i < n; i++)
rc[i] = a[i % an] | b[i % bn];
- return rc;
+ return(rc);
}
@@ -181,7 +191,7 @@ static char32_t* builtin_function_and_2(const char32_t** restrict args)
define_2;
for (i = 0; i < n; i++)
rc[i] = a[i % an] & b[i % bn];
- return rc;
+ return(rc);
}
@@ -196,7 +206,7 @@ static char32_t* builtin_function_xor_2(const char32_t** restrict args)
define_2;
for (i = 0; i < n; i++)
rc[i] = a[i % an] ^ b[i % bn];
- return rc;
+ return(rc);
}
@@ -211,7 +221,7 @@ static char32_t* builtin_function_not_1(const char32_t** restrict args)
define_1;
for (i = 0; i < n; i++)
rc[i] = !a[i];
- return rc;
+ return(rc);
}
@@ -226,7 +236,7 @@ static char32_t* builtin_function_equals_2(const char32_t** restrict args)
define_2;
for (i = 0; i < n; i++)
rc[i] = a[i % an] == b[i % bn];
- return rc;
+ return(rc);
}
@@ -241,7 +251,7 @@ static char32_t* builtin_function_greater_2(const char32_t** restrict args)
define_2;
for (i = 0; i < n; i++)
rc[i] = a[i % an] > b[i % bn];
- return rc;
+ return(rc);
}
@@ -256,7 +266,7 @@ static char32_t* builtin_function_less_2(const char32_t** restrict args)
define_2;
for (i = 0; i < n; i++)
rc[i] = a[i % an] < b[i % bn];
- return rc;
+ return(rc);
}
@@ -270,11 +280,13 @@ static char32_t* builtin_function_get_2(const char32_t** restrict args)
{
const char32_t* restrict a = *args++;
const char32_t* restrict b = *args++;
+ char32_t* restrict rc;
size_t n = (size_t)*b;
mds_kbdc_tree_t* value = variables_get((size_t)*a);
while (n--)
value = value->next;
- return string_dup(value->compiled_string.string);
+ fail_if (rc = string_dup(value->compiled_string.string), rc == NULL);
+ return(rc);
}
@@ -289,20 +301,22 @@ static char32_t* builtin_function_set_3(const char32_t** restrict args)
const char32_t* restrict a = *args++;
const char32_t* restrict b = *args++;
const char32_t* restrict c = *args++;
+ char32_t* restrict rc;
size_t n = (size_t)*b;
mds_kbdc_tree_t* value = variables_get((size_t)*a);
while (n--)
value = value->next;
free(value->compiled_string.string);
value->compiled_string.string = string_dup(c);
- if (value->compiled_string.string == NULL)
- return NULL;
- return string_dup(c);
+ fail_if (value->compiled_string.string == NULL);
+ fail_if (rc = string_dup(c), rc == NULL);
+ return(rc);
}
#undef define_1
#undef define_2
+#undef return
/**
@@ -350,32 +364,33 @@ int builtin_function_defined(const char* restrict name, size_t arg_count)
*/
char32_t* builtin_function_invoke(const char* restrict name, size_t arg_count, const char32_t** restrict args)
{
- if (arg_count == 3)
- if (!strcmp(name, "set"))
- return builtin_function_set_3(args);
+#define t(f) do { fail_if (rc = builtin_function_##f(args), rc == NULL); return rc; } while (0)
+ char32_t* rc;
- if (arg_count == 1)
- if (!strcmp(name, "not"))
- return builtin_function_not_1(args);
+ if ((arg_count == 3) && !strcmp(name, "set")) t (set_3);
+ if ((arg_count == 1) && !strcmp(name, "not")) t (not_1);
if (arg_count != 2)
abort();
- if (!strcmp(name, "add")) return builtin_function_add_2(args);
- if (!strcmp(name, "sub")) return builtin_function_sub_2(args);
- if (!strcmp(name, "mul")) return builtin_function_mul_2(args);
- if (!strcmp(name, "div")) return builtin_function_div_2(args);
- if (!strcmp(name, "mod")) return builtin_function_mod_2(args);
- if (!strcmp(name, "rsh")) return builtin_function_rsh_2(args);
- if (!strcmp(name, "lsh")) return builtin_function_lsh_2(args);
- if (!strcmp(name, "or")) return builtin_function_or_2(args);
- if (!strcmp(name, "and")) return builtin_function_and_2(args);
- if (!strcmp(name, "xor")) return builtin_function_xor_2(args);
- if (!strcmp(name, "equals")) return builtin_function_equals_2(args);
- if (!strcmp(name, "greater")) return builtin_function_greater_2(args);
- if (!strcmp(name, "less")) return builtin_function_less_2(args);
- if (!strcmp(name, "get")) return builtin_function_get_2(args);
+ if (!strcmp(name, "add")) t (add_2);
+ if (!strcmp(name, "sub")) t (sub_2);
+ if (!strcmp(name, "mul")) t (mul_2);
+ if (!strcmp(name, "div")) t (div_2);
+ if (!strcmp(name, "mod")) t (mod_2);
+ if (!strcmp(name, "rsh")) t (rsh_2);
+ if (!strcmp(name, "lsh")) t (lsh_2);
+ if (!strcmp(name, "or")) t (or_2);
+ if (!strcmp(name, "and")) t (and_2);
+ if (!strcmp(name, "xor")) t (xor_2);
+ if (!strcmp(name, "equals")) t (equals_2);
+ if (!strcmp(name, "greater")) t (greater_2);
+ if (!strcmp(name, "less")) t (less_2);
+ if (!strcmp(name, "get")) t (get_2);
abort();
+ fail:
+ return NULL;
+#undef t
}
diff --git a/src/mds-kbdc/compile-layout.c b/src/mds-kbdc/compile-layout.c
index ccf647c..539ade3 100644
--- a/src/mds-kbdc/compile-layout.c
+++ b/src/mds-kbdc/compile-layout.c
@@ -604,6 +604,8 @@ static int check_function_calls_in_literal(const mds_kbdc_tree_t* restrict tree,
{
int rc = 0;
(void) check_function_calls_in_literal_(tree, raw, lineoff, &raw, &rc);
+ fail_if (rc < 0);
+ fail:
return rc;
}
@@ -669,7 +671,10 @@ static char32_t* parse_escape(mds_kbdc_tree_t* restrict tree, const char* restri
/* Read escape. */
if (*escape == 100)
/* Function call. */
- return parse_function_call(tree, raw_, lineoff, escape, end);
+ {
+ fail_if (rc = parse_function_call(tree, raw_, lineoff, escape, end), rc == NULL);
+ return rc;
+ }
/* Octal or hexadecimal representation, or variable dereference. */
for (; (c = *raw); have = 1, raw++)
if (CR( 8, '0', '7')) numbuf = 8 * numbuf + (c & 15);
@@ -909,7 +914,11 @@ static char32_t* parse_string(mds_kbdc_tree_t* restrict tree, const char* restri
{
mds_kbdc_tree_t* old_last_value_statement = last_value_statement;
char32_t* rc = (strchr("\"\\", *raw) ? parse_quoted_string : parse_unquoted_string)(tree, raw, lineoff);
- return last_value_statement = old_last_value_statement, rc;
+ last_value_statement = old_last_value_statement;
+ fail_if (rc == NULL);
+ return rc;
+ fail:
+ return NULL;
}
@@ -1077,7 +1086,7 @@ static size_t parse_variable(mds_kbdc_tree_t* restrict tree, const char* restric
memcpy(dotless, raw_, n * sizeof(char)), dotless[n] = '\0';
var = (size_t)atoll(dotless + 1);
if (strlen(dotless + 1) != (size_t)snprintf(NULL, 0, "%zu", var))
- return errno = ERANGE, (size_t)0;
+ fail_if ((errno = ERANGE));
return var;
fail:
return 0;
@@ -1172,7 +1181,10 @@ static int parse_function_argument(mds_kbdc_tree_t* restrict tree, const char* r
static int set_macro(mds_kbdc_tree_macro_t* restrict macro,
mds_kbdc_include_stack_t* macro_include_stack)
{
- return callables_set(macro->name, 0, (mds_kbdc_tree_t*)macro, macro_include_stack);
+ fail_if (callables_set(macro->name, 0, (mds_kbdc_tree_t*)macro, macro_include_stack));
+ return 0;
+ fail:
+ return -1;
}
@@ -1246,7 +1258,10 @@ static int set_function(mds_kbdc_tree_function_t* restrict function,
*suffix_start = '\0';
r = callables_set(suffixless, arg_count, (mds_kbdc_tree_t*)function, function_include_stack);
- return *suffix_start = '/', r;
+ fail_if (*suffix_start = '/', r);
+ return 0;
+ fail:
+ return -1;
}
@@ -1304,8 +1319,7 @@ static int compile_include(mds_kbdc_tree_include_t* restrict tree)
{
void* data;
int r;
- if (mds_kbdc_include_stack_push(tree, &data))
- return -1;
+ fail_if (mds_kbdc_include_stack_push(tree, &data));
r = compile_subtree(tree->inner);
mds_kbdc_include_stack_pop(data);
@@ -1314,7 +1328,10 @@ static int compile_include(mds_kbdc_tree_include_t* restrict tree)
* include-stack as its overriding statement. */
last_value_statement = NULL;
- return r;
+ fail_if (r);
+ return 0;
+ fail:
+ return -1;
}
@@ -1650,7 +1667,7 @@ static int compile_have_range(mds_kbdc_tree_assumption_have_range_t* restrict tr
*/
static int check_marco_calls(mds_kbdc_tree_t* restrict tree)
{
-#define t(...) if (rc |= r = (__VA_ARGS__), r < 0) return r
+#define t(...) fail_if (rc |= r = (__VA_ARGS__), r < 0)
mds_kbdc_tree_macro_t* _macro;
mds_kbdc_include_stack_t* _macro_include_stack;
void* data;
@@ -1685,6 +1702,8 @@ static int check_marco_calls(mds_kbdc_tree_t* restrict tree)
tree = tree->next;
goto again;
+ fail:
+ return -1;
(void) _macro;
(void) _macro_include_stack;
#undef t
@@ -1699,7 +1718,7 @@ static int check_marco_calls(mds_kbdc_tree_t* restrict tree)
*/
static int check_function_calls_in_for(const mds_kbdc_tree_for_t* restrict tree)
{
-#define t(...) if (rc |= r = check_function_calls_in_literal(__VA_ARGS__), r < 0) return r
+#define t(...) fail_if (rc |= r = check_function_calls_in_literal(__VA_ARGS__), r < 0)
size_t lineoff_first;
size_t lineoff_last;
char* restrict code = result->source_code->real_lines[tree->loc_line];
@@ -1713,6 +1732,8 @@ static int check_function_calls_in_for(const mds_kbdc_tree_for_t* restrict tree)
t ((const mds_kbdc_tree_t*)tree, tree->last, lineoff_last);
return rc;
+ fail:
+ return -1;
#undef t
}
@@ -1727,9 +1748,13 @@ static int check_function_calls_in_if(const mds_kbdc_tree_if_t* restrict tree)
{
size_t lineoff;
char* restrict code = result->source_code->real_lines[tree->loc_line];
+ int r;
for (lineoff = tree->loc_end; code[lineoff] == ' '; lineoff++);
- return check_function_calls_in_literal((const mds_kbdc_tree_t*)tree, tree->condition, lineoff);
+ r = check_function_calls_in_literal((const mds_kbdc_tree_t*)tree, tree->condition, lineoff);
+ fail_if (r < 0);
+ fail:
+ return r;
}
@@ -1741,7 +1766,11 @@ static int check_function_calls_in_if(const mds_kbdc_tree_if_t* restrict tree)
*/
static int check_function_calls_in_keys(const mds_kbdc_tree_keys_t* restrict tree)
{
- return check_function_calls_in_literal((const mds_kbdc_tree_t*)tree, tree->keys, tree->loc_start);
+ int r;
+ r = check_function_calls_in_literal((const mds_kbdc_tree_t*)tree, tree->keys, tree->loc_start);
+ fail_if (r < 0);
+ fail:
+ return r;
}
@@ -1753,7 +1782,11 @@ static int check_function_calls_in_keys(const mds_kbdc_tree_keys_t* restrict tre
*/
static int check_function_calls_in_string(const mds_kbdc_tree_string_t* restrict tree)
{
- return check_function_calls_in_literal((const mds_kbdc_tree_t*)tree, tree->string, tree->loc_start);
+ int r;
+ r = check_function_calls_in_literal((const mds_kbdc_tree_t*)tree, tree->string, tree->loc_start);
+ fail_if (r < 0);
+ fail:
+ return r;
}
@@ -1765,7 +1798,7 @@ static int check_function_calls_in_string(const mds_kbdc_tree_string_t* restrict
*/
static int check_function_calls(const mds_kbdc_tree_t* restrict tree)
{
-#define t(...) if (rc |= r = (__VA_ARGS__), r < 0) return r
+#define t(...) fail_if (rc |= r = (__VA_ARGS__), r < 0)
void* data;
int r, rc = 0;
again:
@@ -1801,6 +1834,8 @@ static int check_function_calls(const mds_kbdc_tree_t* restrict tree)
tree = tree->next;
goto again;
+ fail:
+ return -1;
#undef t
}
@@ -2103,12 +2138,13 @@ static int compile_if(mds_kbdc_tree_if_t* restrict tree)
/* Evaluate whether the evaluted value is true. */
for (ok = 1, i = 0; data[i] >= 0; i++)
ok &= !!(data[i]);
- free(data);
+ free(data), data = NULL;;
/* Compile the appropriate clause. */
ok = compile_subtree(ok ? tree->inner : tree->otherwise);
last_value_statement = NULL;
- return ok;
+ fail_if (ok < 0);
+ return 0;
FAIL_BEGIN;
free(data);
FAIL_END;
@@ -2200,7 +2236,10 @@ static int evaluate_element(mds_kbdc_tree_t* restrict node)
*/
static int compile_keys(mds_kbdc_tree_keys_t* restrict tree)
{
- return evaluate_element((mds_kbdc_tree_t*)tree) < 0 ? -1 : 0;
+ fail_if (evaluate_element((mds_kbdc_tree_t*)tree));
+ return 0;
+ fail:
+ return -1;
}
@@ -2212,7 +2251,10 @@ static int compile_keys(mds_kbdc_tree_keys_t* restrict tree)
*/
static int compile_string(mds_kbdc_tree_string_t* restrict tree)
{
- return evaluate_element((mds_kbdc_tree_t*)tree) < 0 ? -1 : 0;
+ fail_if (evaluate_element((mds_kbdc_tree_t*)tree));
+ return 0;
+ fail:
+ return -1;
}
@@ -2225,11 +2267,12 @@ static int compile_string(mds_kbdc_tree_string_t* restrict tree)
static int compile_array(mds_kbdc_tree_array_t* restrict tree)
{
int r = evaluate_element(tree->elements);
- if (r < 0)
- return -1;
+ fail_if (r < 0);
if (r)
tree->processed = PROCESS_LEVEL;
return 0;
+ fail:
+ return -1;
}
@@ -2261,7 +2304,7 @@ static int check_nonnul(mds_kbdc_tree_t* restrict tree)
tree = tree->next;
goto again;
fail:
- return -1;
+ return -1;
}
@@ -2533,7 +2576,10 @@ int compile_layout(mds_kbdc_parsed_t* restrict result_)
variables_terminate();
callables_terminate();
errno = saved_errno;
- return r;
+ fail_if (r);
+ return 0;
+ fail:
+ return -1;
}
diff --git a/src/mds-kbdc/eliminate-dead-code.c b/src/mds-kbdc/eliminate-dead-code.c
index 4916fa4..5628a91 100644
--- a/src/mds-kbdc/eliminate-dead-code.c
+++ b/src/mds-kbdc/eliminate-dead-code.c
@@ -82,11 +82,13 @@ static int eliminate_include(mds_kbdc_tree_include_t* restrict tree)
{
void* data;
int r;
- if (mds_kbdc_include_stack_push(tree, &data))
- return -1;
+ fail_if (mds_kbdc_include_stack_push(tree, &data));
r = eliminate_subtree(tree->inner);
mds_kbdc_include_stack_pop(data);
- return r;
+ fail_if (r);
+ return 0;
+ fail:
+ return -1;
}
@@ -118,9 +120,8 @@ static int eliminate_if(mds_kbdc_tree_if_t* restrict tree)
*/
static int eliminate_subtree(mds_kbdc_tree_t* restrict tree)
{
-#define e(type) if ((r = eliminate_##type(&(tree->type)))) return r
-#define E(type) if ((r = eliminate_##type(&(tree->type##_)))) return r
- int r;
+#define e(type) fail_if (eliminate_##type(&(tree->type)))
+#define E(type) fail_if (eliminate_##type(&(tree->type##_)))
again:
if (tree == NULL)
return 0;
@@ -134,8 +135,7 @@ static int eliminate_subtree(mds_kbdc_tree_t* restrict tree)
case C(MACRO):
case C(ASSUMPTION):
case C(FOR):
- if ((r = eliminate_subtree(tree->information.inner)))
- return r;
+ fail_if (eliminate_subtree(tree->information.inner));
if ((tree->type == C(FUNCTION)) || (tree->type == C(MACRO))) elimination_level = 0;
else if ((tree->type == C(FOR)) && (elimination_level == 1)) elimination_level = 0;
break;
@@ -174,7 +174,11 @@ int eliminate_dead_code(mds_kbdc_parsed_t* restrict result_)
int r;
mds_kbdc_include_stack_begin(result = result_);
r = eliminate_subtree(result_->tree);
- return mds_kbdc_include_stack_end(), r;
+ mds_kbdc_include_stack_end();
+ fail_if (r);
+ return 0;
+ fail:
+ return -1;
}
diff --git a/src/mds-kbdc/include-stack.c b/src/mds-kbdc/include-stack.c
index bec1425..d8c4547 100644
--- a/src/mds-kbdc/include-stack.c
+++ b/src/mds-kbdc/include-stack.c
@@ -190,9 +190,7 @@ mds_kbdc_include_stack_t* mds_kbdc_include_stack_save(void)
return latest_save;
}
- latest_save = malloc(sizeof(mds_kbdc_include_stack_t));
- if (latest_save == NULL)
- return NULL;
+ fail_if (xmalloc(latest_save, 1, mds_kbdc_include_stack_t));
latest_save->stack = NULL;
latest_save->ptr = includes_ptr;
@@ -207,8 +205,8 @@ mds_kbdc_include_stack_t* mds_kbdc_include_stack_save(void)
return latest_save;
fail:
saved_errno = errno;
- free(latest_save->stack);
- latest_save = NULL;
+ if (latest_save)
+ free(latest_save->stack), latest_save = NULL;
errno = saved_errno;
return NULL;
}
@@ -229,8 +227,7 @@ int mds_kbdc_include_stack_restore(mds_kbdc_include_stack_t* restrict stack)
if (stack->ptr > includes_size)
{
new = realloc(includes, stack->ptr * sizeof(const mds_kbdc_tree_include_t*));
- if (new == NULL)
- return -1;
+ fail_if (new == NULL);
includes = new;
includes_size = stack->ptr;
}
@@ -238,6 +235,8 @@ int mds_kbdc_include_stack_restore(mds_kbdc_include_stack_t* restrict stack)
memcpy(includes, stack->stack, stack->ptr * sizeof(const mds_kbdc_tree_include_t*));
includes_ptr = stack->ptr;
return 0;
+ fail:
+ return -1;
}
diff --git a/src/mds-kbdc/make-tree.c b/src/mds-kbdc/make-tree.c
index 8a7bb1e..77155b2 100644
--- a/src/mds-kbdc/make-tree.c
+++ b/src/mds-kbdc/make-tree.c
@@ -425,7 +425,7 @@ static int too_few;
* Get the pathname name of the parsed file
*
* @param filename The filename of the parsed file
- * @return The value the caller should return, or 1 if the caller should not return
+ * @return The value the caller should return, or 1 if the caller should not return, -1 on error
*/
static int get_pathname(const char* restrict filename)
{
@@ -769,9 +769,10 @@ static int have_more_parameters(void)
*/
static int test_for_keyword(const char* restrict keyword)
{
- int r, ok;
- if (r = have_more_parameters(), r <= 0)
- return r;
+ int ok, r = have_more_parameters();
+ fail_if (r < 0);
+ if (r == 0)
+ return 0;
ok = (strstr(line, keyword) == line);
line += strlen(keyword);
@@ -807,8 +808,10 @@ static int keys(mds_kbdc_tree_t** restrict var)
char* arg_end;
char* call_end;
int r, escape = 0, quote = 0, triangle;
- if (r = have_more_parameters(), r <= 0)
- return r;
+ r = have_more_parameters();
+ fail_if (r < 0);
+ if (r == 0)
+ return 0;
arg_end = line;
call_end = arg_end;
@@ -863,8 +866,10 @@ static int pure_keys(char** restrict var)
char* arg_end;
char* call_end;
int r, escape = 0, quote = 0, triangle;
- if (r = have_more_parameters(), r <= 0)
- return r;
+ r = have_more_parameters();
+ fail_if (r < 0);
+ if (r == 0)
+ return 0;
arg_end = line;
call_end = arg_end;
@@ -1408,8 +1413,10 @@ int parse_to_tree(const char* restrict filename, mds_kbdc_parsed_t* restrict res
fail_if (xmalloc(result->source_code, 1, mds_kbdc_source_code_t));
mds_kbdc_source_code_initialise(result->source_code);
- if (r = get_pathname(filename), r <= 0)
- return r;
+ r = get_pathname(filename);
+ fail_if (r < 0);
+ if (r == 0)
+ return 0;
fail_if (read_source_code());
fail_if (allocate_stacks());
diff --git a/src/mds-kbdc/paths.c b/src/mds-kbdc/paths.c
index a14681e..e294020 100644
--- a/src/mds-kbdc/paths.c
+++ b/src/mds-kbdc/paths.c
@@ -73,7 +73,10 @@ char* abspath(const char* path)
size_t size, p;
if (*path == '/')
- return strdup(path);
+ {
+ fail_if (buf = strdup(path), buf == NULL);
+ return buf;
+ }
fail_if (cwd = curpath(), cwd == NULL);
size = (p = strlen(cwd)) + strlen(path) + 2;
diff --git a/src/mds-kbdc/process-includes.c b/src/mds-kbdc/process-includes.c
index 57e0502..2faaf3f 100644
--- a/src/mds-kbdc/process-includes.c
+++ b/src/mds-kbdc/process-includes.c
@@ -242,8 +242,7 @@ static int process_include(mds_kbdc_tree_include_t* restrict tree)
*/
static int process_includes_in_tree(mds_kbdc_tree_t* restrict tree)
{
-#define p(expr) if ((r = process_includes_in_tree(tree->expr))) return r
- int r;
+#define p(expr) fail_if (process_includes_in_tree(tree->expr))
again:
if (tree == NULL)
return 0;
@@ -257,8 +256,7 @@ static int process_includes_in_tree(mds_kbdc_tree_t* restrict tree)
case C(FOR): p (for_.inner); break;
case C(IF): p (if_.inner); p (if_.otherwise); break;
case C(INCLUDE):
- if ((r = process_include(&(tree->include))))
- return r;
+ fail_if (process_include(&(tree->include)));
break;
default:
break;
@@ -266,6 +264,8 @@ static int process_includes_in_tree(mds_kbdc_tree_t* restrict tree)
tree = tree->next;
goto again;
+ fail:
+ return -1;
#undef p
}
@@ -290,7 +290,7 @@ int process_includes(mds_kbdc_parsed_t* restrict result_)
{
struct stat* old;
if (xxrealloc(old, included, included_size += 4, struct stat))
- return included = old, -1;
+ fail_if (included = old, 1);
}
for (i = 0; i < included_ptr; i++)
diff --git a/src/mds-kbdc/raw-data.c b/src/mds-kbdc/raw-data.c
index 359abe8..83e8b48 100644
--- a/src/mds-kbdc/raw-data.c
+++ b/src/mds-kbdc/raw-data.c
@@ -456,14 +456,15 @@ static char* encode_utf8(char* buffer, char32_t character)
text[0] = character;
text[1] = -1;
- if (str_ = str = string_encode(text), str == NULL)
- return NULL;
+ fail_if (str_ = str = string_encode(text), str == NULL);
while (*str)
*buffer++ = *str++;
free(str_);
return buffer;
+ fail:
+ return NULL;
}
@@ -489,8 +490,7 @@ char* parse_raw_string(const char* restrict string)
* is not code point whose UTF-8 encoding is longer than its
* hexadecimal representation. */
p = rc = malloc(strlen(string) * sizeof(char));
- if (rc == NULL)
- return NULL;
+ fail_if (rc == NULL);
while ((c = *string++))
if (r(escape == 8, '0', '7')) buf = (buf << 3) | (c & 15);
diff --git a/src/mds-kbdc/simplify-tree.c b/src/mds-kbdc/simplify-tree.c
index c46649e..d24569d 100644
--- a/src/mds-kbdc/simplify-tree.c
+++ b/src/mds-kbdc/simplify-tree.c
@@ -161,6 +161,7 @@ static int eliminate_alternation(mds_kbdc_tree_t* tree, mds_kbdc_tree_t* argumen
mds_kbdc_tree_t* next_alternative;
mds_kbdc_tree_t* new_argument;
size_t i;
+ int saved_errno;
/* Detach next statement, we do not want to duplicate all following statements. */
next_statement = tree->next, tree->next = NULL;
@@ -171,13 +172,7 @@ static int eliminate_alternation(mds_kbdc_tree_t* tree, mds_kbdc_tree_t* argumen
for (first = last = NULL; alternative; alternative = next_alternative)
{
/* Duplicate statement. */
- if (new_tree = mds_kbdc_tree_dup(tree), new_tree == NULL)
- {
- int saved_errno = errno;
- argument->alternation.inner = alternative;
- tree->next = next_statement;
- return errno = saved_errno, -1;
- }
+ fail_if (new_tree = mds_kbdc_tree_dup(tree), new_tree == NULL);
/* Join trees. */
if (last)
last->next = new_tree;
@@ -204,6 +199,11 @@ static int eliminate_alternation(mds_kbdc_tree_t* tree, mds_kbdc_tree_t* argumen
/* Reattach the statement that followed to the last generated statement. */
last->next = next_statement;
return 0;
+ fail:
+ saved_errno = errno;
+ argument->alternation.inner = alternative;
+ tree->next = next_statement;
+ return errno = saved_errno, -1;
}
@@ -567,7 +567,8 @@ static int simplify_alternation(mds_kbdc_tree_alternation_t* restrict tree)
NEW_ERROR(tree, WARNING, "singleton alternation");
memcpy(tree, temp, sizeof(mds_kbdc_tree_t));
free(temp);
- return simplify((mds_kbdc_tree_t*)tree);
+ fail_if (simplify((mds_kbdc_tree_t*)tree));
+ return 0;
}
/* Simplify. */
@@ -625,11 +626,10 @@ static mds_kbdc_tree_t* create_permutations(mds_kbdc_tree_t* elements)
mds_kbdc_tree_t* subperms = NULL;
mds_kbdc_tree_t* perm;
mds_kbdc_tree_t ordered;
- int saved_errno, no_perms;
+ int saved_errno, no_perms, stage = 0;
/* Error case. */
- if (elements == NULL)
- return NULL;
+ fail_if (elements == NULL);
/* Base case. */
if (elements->next == NULL)
@@ -639,6 +639,7 @@ static mds_kbdc_tree_t* create_permutations(mds_kbdc_tree_t* elements)
return first;
}
+ stage++;
for (previous_next = &elements; (argument = *previous_next); previous_next = &((*previous_next)->next))
{
/* Created ordered alternative for a permutation prototype. */
@@ -682,7 +683,8 @@ static mds_kbdc_tree_t* create_permutations(mds_kbdc_tree_t* elements)
saved_errno = errno;
mds_kbdc_tree_free(first);
mds_kbdc_tree_free(subperms);
- mds_kbdc_tree_destroy(&ordered);
+ if (stage > 0)
+ mds_kbdc_tree_destroy(&ordered);
errno = saved_errno;
return NULL;
}
@@ -730,7 +732,8 @@ static int simplify_unordered(mds_kbdc_tree_unordered_t* restrict tree)
NEW_ERROR(tree, WARNING, "singleton unordered subsequence");
memcpy(tree, temp, sizeof(mds_kbdc_tree_t));
free(temp);
- return simplify((mds_kbdc_tree_t*)tree);
+ fail_if (simplify((mds_kbdc_tree_t*)tree));
+ return -1;
}
/* Remove ‘.’:s. */
@@ -783,9 +786,9 @@ static int simplify_unordered(mds_kbdc_tree_unordered_t* restrict tree)
* if it does not list any permutations. */
NEW_ERROR_(result, INTERNAL_ERROR, 0, 0, 0, 0, 1,
"Fail to create permutations of an unordered sequence");
- errno = 0;
+ return 0;
}
- return tree->inner = arguments, -1;
+ fail_if (tree->inner = arguments, 1);
}
mds_kbdc_tree_free(arguments);
@@ -803,9 +806,8 @@ static int simplify_unordered(mds_kbdc_tree_unordered_t* restrict tree)
*/
static int simplify(mds_kbdc_tree_t* restrict tree)
{
-#define s(expr) if ((r = simplify(tree->expr))) return r
-#define S(type) if ((r = simplify_##type(&(tree->type)))) return r
- int r;
+#define s(expr) fail_if (simplify(tree->expr))
+#define S(type) fail_if (simplify_##type(&(tree->type)))
again:
if (tree == NULL)
return 0;
@@ -828,6 +830,8 @@ static int simplify(mds_kbdc_tree_t* restrict tree)
tree = tree->next;
goto again;
+ fail:
+ return -1;
#undef s
#undef S
}
diff --git a/src/mds-kbdc/string.c b/src/mds-kbdc/string.c
index 062aed3..6ecf757 100644
--- a/src/mds-kbdc/string.c
+++ b/src/mds-kbdc/string.c
@@ -56,8 +56,7 @@ char32_t* string_decode(const char* restrict string)
length++;
/* Allocated UTF-32 string. */
- if (xmalloc(rc, length + 1, char32_t))
- return NULL;
+ fail_if (xmalloc(rc, length + 1, char32_t));
/* Convert to UTF-32. */
for (i = j = n = 0; string[i]; i++)
@@ -81,6 +80,8 @@ char32_t* string_decode(const char* restrict string)
/* -1-terminate and return. */
return rc[length] = -1, rc;
+ fail:
+ return NULL;
}
@@ -98,8 +99,7 @@ char* string_encode(const char32_t* restrict string)
char* restrict rc;
/* Allocated Modified UTF-8 string. */
- if (xmalloc(rc, 7 * n + 1, char))
- return NULL;
+ fail_if (xmalloc(rc, 7 * n + 1, char));
/* Convert to Modified UTF-8. */
for (i = j = 0; i < n; i++)
@@ -127,6 +127,8 @@ char* string_encode(const char32_t* restrict string)
/* NUL-terminate and return. */
return rc[j] = '\0', rc;
+ fail:
+ return NULL;
}
@@ -143,9 +145,10 @@ char32_t* string_dup(const char32_t* restrict string)
if (string == NULL)
return NULL;
n = string_length(string) + 1;
- if (xmalloc(rc, n, char32_t))
- return NULL;
+ fail_if (xmalloc(rc, n, char32_t));
memcpy(rc, string, n * sizeof(char32_t));
return rc;
+ fail:
+ return NULL;
}
diff --git a/src/mds-kbdc/tree.c b/src/mds-kbdc/tree.c
index ac9de2b..b32c503 100644
--- a/src/mds-kbdc/tree.c
+++ b/src/mds-kbdc/tree.c
@@ -60,11 +60,12 @@ void mds_kbdc_tree_initialise(mds_kbdc_tree_t* restrict this, int type)
*/
mds_kbdc_tree_t* mds_kbdc_tree_create(int type)
{
- mds_kbdc_tree_t* this = malloc(sizeof(mds_kbdc_tree_t));
- if (this == NULL)
- return NULL;
+ mds_kbdc_tree_t* this;
+ fail_if (xmalloc(this, 1, mds_kbdc_tree_t));
mds_kbdc_tree_initialise(this, type);
return this;
+ fail:
+ return NULL;
}
diff --git a/src/mds-kbdc/validate-tree.c b/src/mds-kbdc/validate-tree.c
index eeb5735..466f138 100644
--- a/src/mds-kbdc/validate-tree.c
+++ b/src/mds-kbdc/validate-tree.c
@@ -106,11 +106,13 @@ static int validate_include(mds_kbdc_tree_include_t* restrict tree)
{
void* data;
int r;
- if (mds_kbdc_include_stack_push(tree, &data))
- return -1;
+ fail_if (mds_kbdc_include_stack_push(tree, &data));
r = validate_subtree(tree->inner);
mds_kbdc_include_stack_pop(data);
- return r;
+ fail_if (r);
+ return 0;
+ fail:
+ return -1;
}
@@ -339,9 +341,11 @@ static int validate_macro_call(mds_kbdc_tree_macro_call_t* restrict tree)
static int validate_for(mds_kbdc_tree_for_t* restrict tree)
{
int r;
- fors++;
- r = validate_subtree(tree->inner);
- return fors--, r;
+ fors++, r = validate_subtree(tree->inner), fors--;
+ fail_if (r);
+ return 0;
+ fail:
+ return -1;
}
@@ -353,8 +357,10 @@ static int validate_for(mds_kbdc_tree_for_t* restrict tree)
*/
static int validate_if(mds_kbdc_tree_if_t* restrict tree)
{
- return -(validate_subtree(tree->inner) ||
- validate_subtree(tree->otherwise));
+ fail_if ((validate_subtree(tree->inner) || validate_subtree(tree->otherwise)));
+ return 0;
+ fail:
+ return -1;
}
@@ -446,9 +452,8 @@ static int validate_information_data(mds_kbdc_tree_t* restrict tree)
*/
static int validate_subtree(mds_kbdc_tree_t* restrict tree)
{
-#define v(type) if ((r = validate_##type(&(tree->type)))) return r
-#define V(type) if ((r = validate_##type(&(tree->type##_)))) return r
- int r;
+#define v(type) fail_if (validate_##type(&(tree->type)))
+#define V(type) fail_if (validate_##type(&(tree->type##_)))
again:
if (tree == NULL)
return 0;
@@ -470,14 +475,12 @@ static int validate_subtree(mds_kbdc_tree_t* restrict tree)
case C(INFORMATION_LANGUAGE):
case C(INFORMATION_COUNTRY):
case C(INFORMATION_VARIANT):
- if ((r = validate_information_data(tree)))
- return r;
+ fail_if (validate_information_data(tree));
break;
case C(ASSUMPTION_HAVE):
case C(ASSUMPTION_HAVE_CHARS):
case C(ASSUMPTION_HAVE_RANGE):
- if ((r = validate_assumption_data(tree)))
- return r;
+ fail_if (validate_assumption_data(tree));
break;
default:
break;
@@ -485,6 +488,8 @@ static int validate_subtree(mds_kbdc_tree_t* restrict tree)
tree = tree->next;
goto again;
+ fail:
+ return -1;
#undef V
#undef v
}
@@ -502,7 +507,11 @@ int validate_tree(mds_kbdc_parsed_t* restrict result_)
mds_kbdc_include_stack_begin(result = result_);
r = validate_subtree(result_->tree);
fors = 0;
- return mds_kbdc_include_stack_end(), r;
+ mds_kbdc_include_stack_end();
+ fail_if (r);
+ return 0;
+ fail:
+ return -1;
}
diff --git a/src/mds-kbdc/variables.c b/src/mds-kbdc/variables.c
index 55bae76..7431767 100644
--- a/src/mds-kbdc/variables.c
+++ b/src/mds-kbdc/variables.c
@@ -17,6 +17,8 @@
*/
#include "variables.h"
+#include <libmdsserver/macros.h>
+
#include <stdlib.h>
#include <string.h>
@@ -149,9 +151,8 @@ int variables_let(size_t variable, mds_kbdc_tree_t* restrict value)
/* Grow the table if necessary to fit the variable. */
if (variable >= variable_count)
{
- new = realloc(variables, (variable + 1) * sizeof(variable_t*));
- if (new == NULL)
- return -1;
+ new = variables;
+ fail_if (xrealloc(new, variable + 1, variable_t*));
variables = new;
memset(variables + variable_count, 0, (variable + 1 - variable_count) * sizeof(variable_t*));
variable_count = variable + 1;
@@ -169,13 +170,15 @@ int variables_let(size_t variable, mds_kbdc_tree_t* restrict value)
previous = variables[variable];
variables[variable] = malloc(sizeof(variable_t));
if (variables[variable] == NULL)
- return variables[variable] = previous, -1;
+ fail_if (variables[variable] = previous, 1);
variables[variable]->value = value;
variables[variable]->previous = previous;
variables[variable]->scope = current_scope;
}
return 0;
+ fail:
+ return -1;
}