aboutsummaryrefslogtreecommitdiffstats
path: root/src/mds-kbdc/make-tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mds-kbdc/make-tree.c')
-rw-r--r--src/mds-kbdc/make-tree.c1705
1 files changed, 829 insertions, 876 deletions
diff --git a/src/mds-kbdc/make-tree.c b/src/mds-kbdc/make-tree.c
index 1b5e8a5..f5bdf55 100644
--- a/src/mds-kbdc/make-tree.c
+++ b/src/mds-kbdc/make-tree.c
@@ -31,7 +31,7 @@
#ifndef DEBUG
# define DEBUG_PROC(statements)
#else
-# define DEBUG_PROC(statements) statements
+# define DEBUG_PROC(statements) statements
#endif
@@ -40,16 +40,14 @@
* as a compiler debugging feature and should be used from
* inside `DEBUG_PROC`
*/
-#define PRINT_STACK \
- do \
- { \
- size_t i = stack_ptr; \
- fprintf(stderr, "stack {\n"); \
- while (i--) \
- fprintf(stderr, " %s\n", keyword_stack[i]); \
- fprintf(stderr, "}\n"); \
- } \
- while (0)
+#define PRINT_STACK\
+ do {\
+ size_t i = stack_ptr;\
+ fprintf(stderr, "stack {\n");\
+ while (i--)\
+ fprintf(stderr, " %s\n", keyword_stack[i]);\
+ fprintf(stderr, "}\n");\
+ } while (0)
/**
@@ -60,8 +58,8 @@
* @param UPPER:¿T? The upper bound, inclusive
* @return :int 1 if `LOWER` ≤ `VALUE` ≤ `UPPER`, otherwise 0
*/
-#define in_range(LOWER, VALUE, UPPER) \
- (((LOWER) <= (VALUE)) && ((VALUE) <= (UPPER)))
+#define in_range(LOWER, VALUE, UPPER)\
+ ((LOWER) <= (VALUE) && (VALUE) <= (UPPER))
/**
@@ -70,23 +68,23 @@
* @param C:char The character
* @return :int Zero if `C` is a valid callable name character or a forward slash, otherwise 0
*/
-#define is_name_char(C) \
- (in_range('a', C, 'z') || in_range('A', C, 'Z') || strchr("0123456789_/", C))
+#define is_name_char(C)\
+ (in_range('a', C, 'z') || in_range('A', C, 'Z') || strchr("0123456789_/", C))
/**
* Pointer to the beginning of the current line
*/
-#define LINE \
- (result->source_code->lines[line_i])
+#define LINE\
+ (result->source_code->lines[line_i])
/**
* Update the tip of the stack to point to the address
* of the current stack's tip's `next`-member
*/
-#define NEXT \
- tree_stack[stack_ptr] = &(tree_stack[stack_ptr][0]->next)
+#define NEXT\
+ tree_stack[stack_ptr] = &(tree_stack[stack_ptr][0]->next)
/**
@@ -97,9 +95,9 @@
* @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, ...) \
- NEW_ERROR_(result, SEVERITY, ERROR_IS_IN_FILE, line_i, \
- (size_t)(line - LINE), (size_t)(end - LINE), 1, __VA_ARGS__)
+#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__)
/**
@@ -108,13 +106,13 @@
* @param LOWERCASE:identifier The keyword, for the node type, in lower case
* @param UPPERCASE:identifier The keyword, for the node type, in upper case
*/
-#define NEW_NODE(LOWERCASE, UPPERCASE) \
- mds_kbdc_tree_##LOWERCASE##_t* node; \
- fail_if (xcalloc(node, 1, mds_kbdc_tree_##LOWERCASE##_t)); \
- node->type = MDS_KBDC_TREE_TYPE_##UPPERCASE; \
- node->loc_line = line_i; \
- node->loc_start = (size_t)(line - LINE); \
- node->loc_end = (size_t)(end - LINE)
+#define NEW_NODE(LOWERCASE, UPPERCASE)\
+ mds_kbdc_tree_##LOWERCASE##_t *node;\
+ fail_if (xcalloc(node, 1, mds_kbdc_tree_##LOWERCASE##_t));\
+ node->type = MDS_KBDC_TREE_TYPE_##UPPERCASE;\
+ node->loc_line = line_i;\
+ node->loc_start = (size_t)(line - LINE);\
+ node->loc_end = (size_t)(end - LINE)
/**
@@ -123,13 +121,13 @@
* @param LOWERCASE:identifier The keyword, for the node type, in lower case
* @param UPPERCASE:identifier The keyword, for the node type, in upper case
*/
-#define NEW_SUBNODE(LOWERCASE, UPPERCASE) \
- mds_kbdc_tree_##LOWERCASE##_t* subnode; \
- fail_if (xcalloc(subnode, 1, mds_kbdc_tree_##LOWERCASE##_t)); \
- subnode->type = MDS_KBDC_TREE_TYPE_##UPPERCASE; \
- subnode->loc_line = line_i; \
- subnode->loc_start = (size_t)(line - LINE); \
- subnode->loc_end = (size_t)(end - LINE)
+#define NEW_SUBNODE(LOWERCASE, UPPERCASE)\
+ mds_kbdc_tree_##LOWERCASE##_t *subnode;\
+ fail_if (xcalloc(subnode, 1, mds_kbdc_tree_##LOWERCASE##_t));\
+ subnode->type = MDS_KBDC_TREE_TYPE_##UPPERCASE;\
+ subnode->loc_line = line_i;\
+ subnode->loc_start = (size_t)(line - LINE);\
+ subnode->loc_end = (size_t)(end - LINE)
/**
@@ -142,10 +140,10 @@
*
* @param KEYWORD:const char* The keyword for the current node's type
*/
-#define BRANCH(KEYWORD) \
- (*(tree_stack[stack_ptr]) = (mds_kbdc_tree_t*)node, \
- tree_stack[stack_ptr + 1] = &(node->inner), \
- keyword_stack[stack_ptr++] = KEYWORD)
+#define BRANCH(KEYWORD)\
+ (*(tree_stack[stack_ptr]) = (mds_kbdc_tree_t *)node,\
+ tree_stack[stack_ptr + 1] = &(node->inner),\
+ keyword_stack[stack_ptr++] = KEYWORD)
/**
@@ -156,9 +154,9 @@
* This is what should be done when a leaf node has been
* created and should be added to the result tree
*/
-#define LEAF \
- (*(tree_stack[stack_ptr]) = (mds_kbdc_tree_t*)node, \
- NEXT)
+#define LEAF\
+ (*(tree_stack[stack_ptr]) = (mds_kbdc_tree_t*)node,\
+ NEXT)
/**
@@ -166,9 +164,9 @@
*
* @param var:const char* The variable
*/
-#define SKIP_SPACES(var) \
- while (*var && (*var == ' ')) \
- var++
+#define SKIP_SPACES(var)\
+ while (*var && *var == ' ')\
+ var++
/**
@@ -176,8 +174,8 @@
*
* @param KEYWORD:const char* The keyword
*/
-#define NO_PARAMETERS(KEYWORD) \
- fail_if (no_parameters(KEYWORD))
+#define NO_PARAMETERS(KEYWORD)\
+ fail_if (no_parameters(KEYWORD))
/**
@@ -187,18 +185,18 @@
* @param var:identifier The name of the member variable, for the current
* node, where the parameter should be stored
*/
-#define NAMES_1(var) \
- fail_if (names_1(&(node->var)))
+#define NAMES_1(var)\
+ fail_if (names_1(&node->var))
/**
* Suppress the next `line = STREND(line)`
*/
-#define NO_JUMP \
- (*end = prev_end_char, \
- end = line, \
- prev_end_char = *end, \
- *end = '\0')
+#define NO_JUMP\
+ (*end = prev_end_char,\
+ end = line,\
+ prev_end_char = *end,\
+ *end = '\0')
/**
@@ -206,8 +204,8 @@
*
* @param c:char The character
*/
-#define IS_END(c) \
- strchr(" >}])", c)
+#define IS_END(c)\
+ strchr(" >}])", c)
/**
@@ -217,31 +215,28 @@
* @param var:identifier The name of the member variable, for the current
* node, where the parameter should be stored
*/
-#define CHARS(var) \
- fail_if (chars(&(node->var)))
+#define CHARS(var)\
+ fail_if (chars(&node->var))
/**
* Test that there are no more parameters
*/
-#define END \
- do \
- { \
- SKIP_SPACES(line); \
- if (*line) \
- { \
- NEW_ERROR(1, ERROR, "too many parameters"); \
- error->end = strlen(LINE); \
- } \
- } \
- while (0)
+#define END\
+ do {\
+ SKIP_SPACES(line);\
+ if (*line) {\
+ NEW_ERROR(1, ERROR, "too many parameters");\
+ error->end = strlen(LINE);\
+ }\
+ } while (0)
/**
* Test that the next parameter is in quotes
*/
-#define QUOTES \
- fail_if (quotes())
+#define QUOTES\
+ fail_if (quotes())
/**
@@ -251,14 +246,12 @@
* @param var:identifier The name of the member variable, for the current
* node, where the parameter should be stored
*/
-#define QUOTES_1(var) \
- do \
- { \
- QUOTES; \
- CHARS(var); \
- END; \
- } \
- while (0)
+#define QUOTES_1(var)\
+ do {\
+ QUOTES;\
+ CHARS(var);\
+ END;\
+ } while (0)
/**
@@ -266,8 +259,8 @@
*
* @param KEYWORD:const char* The keyword
*/
-#define TEST_FOR_KEYWORD(KEYWORD) \
- fail_if (test_for_keyword(KEYWORD))
+#define TEST_FOR_KEYWORD(KEYWORD)\
+ fail_if (test_for_keyword(KEYWORD))
/**
@@ -277,8 +270,8 @@
* @param var:identifier The name of the member variable, for the current
* node, where the parameter should be stored
*/
-#define KEYS(var) \
- fail_if (keys(&(node->var)))
+#define KEYS(var)\
+ fail_if (keys(&node->var))
/**
@@ -288,8 +281,8 @@
* @param var:identifier The name of the member variable, for the current
* node, where the parameter should be stored
*/
-#define PURE_KEYS(var) \
- fail_if (pure_keys(&(node->var)))
+#define PURE_KEYS(var)\
+ fail_if (pure_keys(&node->var))
@@ -299,23 +292,21 @@
* @param mapseq:int Whether this is a mapping sequence, otherwise
* it is treated as macro call arguments
*/
-#define SEQUENCE(mapseq) \
- do /* for(;;) */ \
- { \
- *end = prev_end_char; \
- SKIP_SPACES(line); \
- if ((*line == '\0') || (*line == (mapseq ? ':' : ')'))) \
- break; \
- fail_if (sequence(mapseq, stack_orig)); \
- } \
- while (1)
+#define SEQUENCE(mapseq)\
+ do /* for(;;) */ {\
+ *end = prev_end_char;\
+ SKIP_SPACES(line);\
+ if (!*line || *line == (mapseq ? ':' : ')'))\
+ break;\
+ fail_if (sequence(mapseq, stack_orig));\
+ } while (1)
/**
* Check that the scopes created in `SEQUENCE` has all been popped
*/
-#define SEQUENCE_FULLY_POPPED \
- fail_if (sequence_fully_popped(stack_orig))
+#define SEQUENCE_FULLY_POPPED\
+ fail_if (sequence_fully_popped(stack_orig))
/**
@@ -325,14 +316,12 @@
* @param UPPERCASE:identifier The keyword, for the node type, in upper case
* @param PARSE:expression Statement, without final semicolon, to retrieve members
*/
-#define MAKE_LEAF(LOWERCASE, UPPERCASE, PARSE) \
- do \
- { \
- NEW_NODE(LOWERCASE, UPPERCASE); \
- PARSE; \
- LEAF; \
- } \
- while (0)
+#define MAKE_LEAF(LOWERCASE, UPPERCASE, PARSE)\
+ do {\
+ NEW_NODE(LOWERCASE, UPPERCASE);\
+ PARSE;\
+ LEAF;\
+ } while (0)
/**
@@ -342,26 +331,24 @@
* @param UPPERCASE:identifier The keyword, for the node type, in upper case
* @param PARSE:expression Statement, without final semicolon, to retrieve members
*/
-#define MAKE_BRANCH(LOWERCASE, UPPERCASE, PARSE) \
- do \
- { \
- NEW_NODE(LOWERCASE, UPPERCASE); \
- PARSE; \
- BRANCH(#LOWERCASE); \
- } \
- while (0)
+#define MAKE_BRANCH(LOWERCASE, UPPERCASE, PARSE)\
+ do {\
+ NEW_NODE(LOWERCASE, UPPERCASE);\
+ PARSE;\
+ BRANCH(#LOWERCASE);\
+ } while (0)
/**
* Variable whether the latest created error is stored
*/
-static mds_kbdc_parse_error_t* error;
+static mds_kbdc_parse_error_t *error;
/**
* Output parameter for the parsing result
*/
-static mds_kbdc_parsed_t* restrict result;
+static mds_kbdc_parsed_t *restrict result;
/**
* The head of the parsing-stack
@@ -371,12 +358,12 @@ static size_t stack_ptr;
/**
* The keyword portion of the parsing-stack
*/
-static const char** restrict keyword_stack;
+static const char **restrict keyword_stack;
/**
* The tree portion of the parsing-stack
*/
-static mds_kbdc_tree_t*** restrict tree_stack;
+static mds_kbdc_tree_t ***restrict tree_stack;
/**
* The index of the currently parsed line
@@ -392,12 +379,12 @@ static int in_array;
* The beginning of what has not get been parsed
* on the current line
*/
-static char* line = NULL;
+static char *line = NULL;
/**
* The end of what has been parsed on the current line
*/
-static char* end = NULL;
+static char *end = NULL;
/**
* The previous value of `*end`
@@ -408,7 +395,7 @@ static char prev_end_char;
* Pointer to the first non-whitespace character
* on the current line
*/
-static char* original;
+static char *original;
/**
* Whether it has been identified that the
@@ -427,40 +414,39 @@ static int too_few;
* @param filename The filename of the parsed file
* @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)
+static int
+get_pathname(const char *restrict filename)
{
- char* cwd = NULL;
- int saved_errno;
-
- /* 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. */
- result->pathname = abspath(filename);
- if (result->pathname == NULL)
- {
- fail_if (errno != ENOENT);
- saved_errno = errno;
- fail_if (cwd = curpath(), cwd == NULL);
- fail_if (xstrdup(result->pathname, filename));
- NEW_ERROR_(result, ERROR, 0, 0, 0, 0, 1, "no such file or directory in ‘%s’", cwd);
- free(cwd);
- return 0;
- }
-
- /* Check that the file exists and can be read. */
- if (access(result->pathname, R_OK) < 0)
- {
- saved_errno = errno;
- NEW_ERROR_(result, ERROR, 0, 0, 0, 0, 0, NULL);
- fail_if (xstrdup(error->description, strerror(saved_errno)));
- return 0;
- }
-
- return 1;
- fail:
- saved_errno = errno;
- free(cwd);
- return errno = saved_errno, -1;
+ char *cwd = NULL;
+ int saved_errno;
+
+ /* 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. */
+ result->pathname = abspath(filename);
+ if (!result->pathname) {
+ fail_if (errno != ENOENT);
+ saved_errno = errno;
+ fail_if (!(cwd = curpath()));
+ fail_if (xstrdup(result->pathname, filename));
+ NEW_ERROR_(result, ERROR, 0, 0, 0, 0, 1, "no such file or directory in ‘%s’", cwd);
+ free(cwd);
+ return 0;
+ }
+
+ /* Check that the file exists and can be read. */
+ if (access(result->pathname, R_OK) < 0) {
+ saved_errno = errno;
+ NEW_ERROR_(result, ERROR, 0, 0, 0, 0, 0, NULL);
+ fail_if (xstrdup(error->description, strerror(saved_errno)));
+ return 0;
+ }
+
+ return 1;
+fail:
+ saved_errno = errno;
+ free(cwd);
+ return errno = saved_errno, -1;
}
@@ -469,25 +455,25 @@ static int get_pathname(const char* restrict filename)
*
* @return Zero on success, -1 on error
*/
-static int allocate_stacks(void)
+static int
+allocate_stacks(void)
{
- size_t max_line_length = 0, cur_line_length, line_n;
-
- /* The maximum line-length is needed because lines can have there own stacking,
- * like sequence mapping lines, additionally, let statements can have one array. */
- 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, line_n + max_line_length, const char*));
- fail_if (xmalloc(tree_stack, line_n + max_line_length + 1, mds_kbdc_tree_t**));
-
- return 0;
- fail:
- return -1;
+ size_t max_line_length = 0, cur_line_length, line_n;
+
+ /* The maximum line-length is needed because lines can have there own stacking,
+ * like sequence mapping lines, additionally, let statements can have one array. */
+ 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, line_n + max_line_length, const char*));
+ fail_if (xmalloc(tree_stack, line_n + max_line_length + 1, mds_kbdc_tree_t**));
+
+ return 0;
+fail:
+ return -1;
}
@@ -496,14 +482,15 @@ static int allocate_stacks(void)
*
* @return Zero on success, -1 on error
*/
-static int read_source_code(void)
+static int
+read_source_code(void)
{
- /* Read the file and simplify it a bit. */
- fail_if (read_source_lines(result->pathname, result->source_code) < 0);
-
- return 0;
- fail:
- return -1;
+ /* Read the file and simplify it a bit. */
+ fail_if (read_source_lines(result->pathname, result->source_code) < 0);
+
+ return 0;
+fail:
+ return -1;
}
@@ -517,34 +504,32 @@ static int read_source_code(void)
*
* @return Zero on success, -1 on error
*/
-static int check_for_premature_end_of_file(void)
+static int
+check_for_premature_end_of_file(void)
{
- /* Check that all scopes have been popped. */
- if (stack_ptr)
- {
- while (stack_ptr && keyword_stack[stack_ptr - 1] == NULL)
- stack_ptr--;
- if (stack_ptr)
- {
- NEW_ERROR(0, ERROR, "premature end of file");
- while (stack_ptr--)
- {
- if (keyword_stack[stack_ptr] == NULL)
- continue;
- line_i = tree_stack[stack_ptr][0]->loc_line;
- line = LINE + tree_stack[stack_ptr][0]->loc_start;
- end = LINE + tree_stack[stack_ptr][0]->loc_end;
- if (!strcmp(keyword_stack[stack_ptr], "}"))
- NEW_ERROR(1, NOTE, "missing associated ‘%s’", keyword_stack[stack_ptr]);
- else
- NEW_ERROR(1, NOTE, "missing associated ‘end %s’", keyword_stack[stack_ptr]);
- }
+ /* Check that all scopes have been popped. */
+ if (stack_ptr) {
+ while (stack_ptr && !keyword_stack[stack_ptr - 1])
+ stack_ptr--;
+ if (stack_ptr) {
+ NEW_ERROR(0, ERROR, "premature end of file");
+ while (stack_ptr--) {
+ if (!keyword_stack[stack_ptr])
+ continue;
+ line_i = tree_stack[stack_ptr][0]->loc_line;
+ line = LINE + tree_stack[stack_ptr][0]->loc_start;
+ end = LINE + tree_stack[stack_ptr][0]->loc_end;
+ if (!strcmp(keyword_stack[stack_ptr], "}"))
+ NEW_ERROR(1, NOTE, "missing associated ‘%s’", keyword_stack[stack_ptr]);
+ else
+ NEW_ERROR(1, NOTE, "missing associated ‘end %s’", keyword_stack[stack_ptr]);
+ }
+ }
}
- }
-
- return 0;
- fail:
- return -1;
+
+ return 0;
+fail:
+ return -1;
}
@@ -555,16 +540,16 @@ static int check_for_premature_end_of_file(void)
*
* @return Zero on success, -1 on error
*/
-static int check_whether_file_is_empty(void)
+static int
+check_whether_file_is_empty(void)
{
- /* Warn about empty files. */
- if (result->tree == NULL)
- if (result->errors_ptr == 0)
- NEW_ERROR(0, WARNING, "file is empty");
-
- return 0;
- fail:
- return -1;
+ /* Warn about empty files. */
+ if (!result->tree && !result->errors_ptr)
+ NEW_ERROR(0, WARNING, "file is empty");
+
+ return 0;
+fail:
+ return -1;
}
@@ -578,20 +563,20 @@ static int check_whether_file_is_empty(void)
* @param keyword The keyword
* @return Zero on success, -1 on error
*/
-static int no_parameters(const char* restrict keyword)
+static int
+no_parameters(const char *restrict keyword)
{
- line = STREND(line);
- *end = prev_end_char, prev_end_char = '\0';
- SKIP_SPACES(line);
- if (*line)
- {
- end = STREND(line);
- NEW_ERROR(1, ERROR, "extra token after ‘%s’", keyword);
- }
-
- return 0;
- fail:
- return -1;
+ line = STREND(line);
+ *end = prev_end_char, prev_end_char = '\0';
+ SKIP_SPACES(line);
+ if (*line) {
+ end = STREND(line);
+ NEW_ERROR(1, ERROR, "extra token after ‘%s’", keyword);
+ }
+
+ return 0;
+fail:
+ return -1;
}
@@ -604,55 +589,51 @@ static int no_parameters(const char* restrict keyword)
* node, where the parameter should be stored
* @return Zero on success, -1 on error
*/
-static int names_1(char** restrict var)
+static int
+names_1(char **restrict var)
{
- char* name_end;
- char* test;
- int stray_char = 0;
- char* end_end;
-
- line = STREND(line);
- *end = prev_end_char, prev_end_char = '\0';
- SKIP_SPACES(line);
- if (*line == '\0')
- {
- line = original, end = STREND(line);
- NEW_ERROR(1, ERROR, "a name is expected");
- }
- else
- {
- name_end = line;
- while (*name_end && is_name_char(*name_end))
- name_end++;
- if (*name_end && (*name_end != ' '))
- {
- end_end = name_end + 1;
- while ((*end_end & 0xC0) == 0x80)
- end_end++;
- prev_end_char = *end_end, *end_end = '\0';
- NEW_ERROR(1, ERROR, "stray ‘%s’ character", name_end);
- error->start = (size_t)(name_end - LINE);
- error->end = (size_t)(end_end - LINE);
- *end_end = prev_end_char;
- stray_char = 1;
+ char *name_end;
+ char *test;
+ int stray_char = 0;
+ char *end_end;
+
+ line = STREND(line);
+ *end = prev_end_char, prev_end_char = '\0';
+ SKIP_SPACES(line);
+ if (!*line) {
+ line = original, end = STREND(line);
+ NEW_ERROR(1, ERROR, "a name is expected");
+ } else {
+ name_end = line;
+ while (*name_end && is_name_char(*name_end))
+ name_end++;
+ if (*name_end && (*name_end != ' ')) {
+ end_end = name_end + 1;
+ while ((*end_end & 0xC0) == 0x80)
+ end_end++;
+ prev_end_char = *end_end, *end_end = '\0';
+ NEW_ERROR(1, ERROR, "stray ‘%s’ character", name_end);
+ error->start = (size_t)(name_end - LINE);
+ error->end = (size_t)(end_end - LINE);
+ *end_end = prev_end_char;
+ stray_char = 1;
+ }
+ test = name_end;
+ SKIP_SPACES(test);
+ if (*test && !stray_char) {
+ NEW_ERROR(1, ERROR, "too many parameters");
+ error->start = (size_t)(test - LINE);
+ error->end = strlen(LINE);
+ }
+ end = name_end;
+ prev_end_char = *end;
+ *end = '\0';
+ fail_if (xstrdup(*var, line));
}
- test = name_end;
- SKIP_SPACES(test);
- if (*test && !stray_char)
- {
- NEW_ERROR(1, ERROR, "too many parameters");
- error->start = (size_t)(test - LINE);
- error->end = strlen(LINE);
- }
- end = name_end;
- prev_end_char = *end;
- *end = '\0';
- fail_if (xstrdup(*var, line));
- }
-
- return 0;
- fail:
- return -1;
+
+ return 0;
+fail:
+ return -1;
}
@@ -664,46 +645,49 @@ static int names_1(char** restrict var)
* node, where the parameter should be stored
* @return Zero on success, -1 on error
*/
-static int chars(char** restrict var)
+static int
+chars(char **restrict var)
{
- if (too_few)
- return 0;
- line = STREND(line);
- *end = prev_end_char, prev_end_char = '\0';
- SKIP_SPACES(line);
- if (*line == '\0')
- {
- line = original, end = STREND(line);
- NEW_ERROR(1, ERROR, "too few parameters");
- line = end, too_few = 1;
- }
- else
- {
- char* arg_end = line;
- char* call_end = arg_end;
- int escape = 0, quote = 0;
- while (*arg_end)
- {
- char c = *arg_end++;
- if (escape) escape = 0;
- else if (arg_end <= call_end) ;
- else if (c == '\\')
- {
- escape = 1;
- call_end = arg_end + get_end_of_call(arg_end, 0, strlen(arg_end));
- }
- else if (quote) quote = (c != '"');
- else if (IS_END(c)) { arg_end--; break; }
- else quote = (c == '"');
+ char *arg_end, *call_end, c;
+ int escape, quote;
+ if (too_few)
+ return 0;
+ line = STREND(line);
+ *end = prev_end_char, prev_end_char = '\0';
+ SKIP_SPACES(line);
+ if (!*line) {
+ line = original, end = STREND(line);
+ NEW_ERROR(1, ERROR, "too few parameters");
+ line = end, too_few = 1;
+ } else {
+ arg_end = line;
+ call_end = arg_end;
+ escape = quote = 0;
+ while (*arg_end) {
+ c = *arg_end++;
+ if (escape) {
+ escape = 0;
+ } else if (arg_end <= call_end) { ;
+ } else if (c == '\\') {
+ escape = 1;
+ call_end = arg_end + get_end_of_call(arg_end, 0, strlen(arg_end));
+ } else if (quote) {
+ quote = c != '"';
+ } else if (IS_END(c)) {
+ arg_end--;
+ break;
+ } else {
+ quote = c == '"';
+ }
+ }
+ prev_end_char = *arg_end, *arg_end = '\0', end = arg_end;
+ fail_if (xstrdup(*var, line));
+ line = end;
}
- prev_end_char = *arg_end, *arg_end = '\0', end = arg_end;
- fail_if (xstrdup(*var, line));
- line = end;
- }
-
- return 0;
- fail:
- return -1;
+
+ return 0;
+fail:
+ return -1;
}
@@ -712,25 +696,25 @@ static int chars(char** restrict var)
*
* @return Zero on success, -1 on error
*/
-static int quotes(void)
+static int
+quotes(void)
{
- char* line_ = line;
- line = STREND(line);
- *end = prev_end_char;
- SKIP_SPACES(line);
- if (*line && (*line != '"'))
- {
- char* arg_end = line;
- SKIP_SPACES(arg_end);
- NEW_ERROR(1, ERROR, "parameter must be in quotes");
- error->end = (size_t)(arg_end - LINE);
- }
- *end = '\0';
- line = line_;
-
- return 0;
- fail:
- return -1;
+ char *line_ = line, *arg_end;
+ line = STREND(line);
+ *end = prev_end_char;
+ SKIP_SPACES(line);
+ if (*line && *line != '"') {
+ arg_end = line;
+ SKIP_SPACES(arg_end);
+ NEW_ERROR(1, ERROR, "parameter must be in quotes");
+ error->end = (size_t)(arg_end - LINE);
+ }
+ *end = '\0';
+ line = line_;
+
+ return 0;
+fail:
+ return -1;
}
@@ -739,23 +723,23 @@ static int quotes(void)
*
* @return Whether the currently line has unparsed parameters, -1 on error
*/
-static int have_more_parameters(void)
+static int
+have_more_parameters(void)
{
- if (too_few)
- return 0;
- line = STREND(line);
- *end = prev_end_char, prev_end_char = '\0';
- SKIP_SPACES(line);
- if (*line == '\0')
- {
- line = original, end = STREND(line);
- NEW_ERROR(1, ERROR, "too few parameters");
- line = end, too_few = 1;
- return 0;
- }
- return 1;
- fail:
- return -1;
+ if (too_few)
+ return 0;
+ line = STREND(line);
+ *end = prev_end_char, prev_end_char = '\0';
+ SKIP_SPACES(line);
+ if (!*line) {
+ line = original, end = STREND(line);
+ NEW_ERROR(1, ERROR, "too few parameters");
+ line = end, too_few = 1;
+ return 0;
+ }
+ return 1;
+fail:
+ return -1;
}
@@ -765,32 +749,33 @@ static int have_more_parameters(void)
* @param keyword The keyword
* @return Zero on success, -1 on error
*/
-static int test_for_keyword(const char* restrict keyword)
+static int
+test_for_keyword(const char *restrict keyword)
{
- int ok, r = have_more_parameters();
- fail_if (r < 0);
- if (r == 0)
- return 0;
-
- ok = (strstr(line, keyword) == line);
- line += strlen(keyword);
- ok = ok && ((*line == '\0') || (*line == ' '));
- if (ok)
- {
- end = line;
- prev_end_char = *end, *end = '\0';
- return 0;
- }
- line -= strlen(keyword);
- end = line;
- SKIP_SPACES(end);
- prev_end_char = *end, *end = '\0';
- NEW_ERROR(1, ERROR, "expecting keyword ‘%s’", keyword);
- error->end = error->start + 1;
-
- return 0;
- fail:
- return -1;
+ int ok, r = have_more_parameters();
+ fail_if (r < 0);
+ if (!r)
+ return 0;
+
+ ok = (strstr(line, keyword) == line);
+ line += strlen(keyword);
+ ok = ok && (!*line || *line == ' ');
+ if (ok) {
+ end = line;
+ prev_end_char = *end;
+ *end = '\0';
+ return 0;
+ }
+ line -= strlen(keyword);
+ end = line;
+ SKIP_SPACES(end);
+ prev_end_char = *end, *end = '\0';
+ NEW_ERROR(1, ERROR, "expecting keyword ‘%s’", keyword);
+ error->end = error->start + 1;
+
+ return 0;
+fail:
+ return -1;
}
@@ -802,52 +787,53 @@ static int test_for_keyword(const char* restrict keyword)
* node, where the parameter should be stored
* @return Zero on success, -1 on error
*/
-static int keys(mds_kbdc_tree_t** restrict var)
+static int
+keys(mds_kbdc_tree_t **restrict var)
{
- char* arg_end;
- char* call_end;
- int r, escape = 0, quote = 0, triangle;
- r = have_more_parameters();
- fail_if (r < 0);
- if (r == 0)
- return 0;
-
- arg_end = line;
- call_end = arg_end;
- triangle = (*arg_end == '<');
- while (*arg_end)
- {
- char c = *arg_end++ ;
- if (escape) escape = 0;
- else if (arg_end <= call_end) ;
- else if (c == '\\')
- {
- escape = 1;
- call_end = arg_end + get_end_of_call(arg_end, 0, strlen(arg_end));
+ char *arg_end, *call_end, c;
+ int r, escape = 0, quote = 0, triangle;
+ r = have_more_parameters();
+ fail_if (r < 0);
+ if (!r)
+ return 0;
+
+ arg_end = line;
+ call_end = arg_end;
+ triangle = *arg_end == '<';
+ while (*arg_end) {
+ c = *arg_end++;
+ if (escape) {
+ escape = 0;
+ } else if (arg_end <= call_end) { ;
+ } else if (c == '\\') {
+ escape = 1;
+ call_end = arg_end + get_end_of_call(arg_end, 0, strlen(arg_end));
+ } else if (quote) {
+ quote = c != '"';
+ } else if (c == '\"') {
+ quote = 1;
+ } else if (c == '>') {
+ triangle = 0;
+ } else if (IS_END(c) && !triangle) {
+ arg_end--;
+ break;
+ }
}
- else if (quote) quote = (c != '"');
- else if (c == '\"') quote = 1;
- else if (c == '>') triangle = 0;
- else if (IS_END(c) && !triangle) { arg_end--; break; }
- }
- prev_end_char = *arg_end, *arg_end = '\0', end = arg_end;
- if (*line == '<')
- {
- NEW_SUBNODE(keys, KEYS);
- *var = (mds_kbdc_tree_t*)subnode;
- fail_if (xstrdup(subnode->keys, line));
- }
- else
- {
- NEW_SUBNODE(string, STRING);
- *var = (mds_kbdc_tree_t*)subnode;
- fail_if (xstrdup(subnode->string, line));
- }
- line = end;
-
- return 0;
- fail:
- return -1;
+ prev_end_char = *arg_end, *arg_end = '\0', end = arg_end;
+ if (*line == '<') {
+ NEW_SUBNODE(keys, KEYS);
+ *var = (mds_kbdc_tree_t *)subnode;
+ fail_if (xstrdup(subnode->keys, line));
+ } else {
+ NEW_SUBNODE(string, STRING);
+ *var = (mds_kbdc_tree_t *)subnode;
+ fail_if (xstrdup(subnode->string, line));
+ }
+ line = end;
+
+ return 0;
+fail:
+ return -1;
}
@@ -860,41 +846,45 @@ static int keys(mds_kbdc_tree_t** restrict var)
* node, where the parameter should be stored
* @return Zero on success, -1 on error
*/
-static int pure_keys(char** restrict var)
+static int
+pure_keys(char **restrict var)
{
- char* arg_end;
- char* call_end;
- int r, escape = 0, quote = 0, triangle;
- r = have_more_parameters();
- fail_if (r < 0);
- if (r == 0)
- return 0;
-
- arg_end = line;
- call_end = arg_end;
- triangle = (*arg_end == '<');
- while (*arg_end)
- {
- char c = *arg_end++ ;
- if (escape) escape = 0;
- else if (arg_end <= call_end) ;
- else if (c == '\\')
- {
- escape = 1;
- call_end = arg_end + get_end_of_call(arg_end, 0, strlen(arg_end));
+ char *arg_end, *call_end, c;
+ int r, escape = 0, quote = 0, triangle;
+ r = have_more_parameters();
+ fail_if (r < 0);
+ if (!r)
+ return 0;
+
+ arg_end = line;
+ call_end = arg_end;
+ triangle = *arg_end == '<';
+ while (*arg_end) {
+ c = *arg_end++;
+ if (escape) {
+ escape = 0;
+ } else if (arg_end <= call_end) { ;
+ } else if (c == '\\') {
+ escape = 1;
+ call_end = arg_end + get_end_of_call(arg_end, 0, strlen(arg_end));
+ } else if (quote) {
+ quote = c != '"';
+ } else if (c == '\"') {
+ quote = 1;
+ } else if (c == '>') {
+ triangle = 0;
+ } else if (IS_END(c) && !triangle) {
+ arg_end--;
+ break;
+ }
}
- else if (quote) quote = (c != '"');
- else if (c == '\"') quote = 1;
- else if (c == '>') triangle = 0;
- else if (IS_END(c) && !triangle) { arg_end--; break; }
- }
- prev_end_char = *arg_end, *arg_end = '\0';
- fail_if (xstrdup(*var, line));
- end = arg_end, line = end;
-
- return 0;
- fail:
- return -1;
+ prev_end_char = *arg_end, *arg_end = '\0';
+ fail_if (xstrdup(*var, line));
+ end = arg_end, line = end;
+
+ return 0;
+fail:
+ return -1;
}
@@ -906,65 +896,54 @@ static int pure_keys(char** restrict var)
* @param stack_orig The size of the stack when `SEQUENCE` was called
* @return Zero on success, -1 on error
*/
-static int sequence(int mapseq, size_t stack_orig)
+static int
+sequence(int mapseq, size_t stack_orig)
{
- if (mapseq && (*line == '('))
- {
- NEW_NODE(unordered, UNORDERED);
- node->loc_end = node->loc_start + 1;
- BRANCH(")");
- line++;
- }
- else if (*line == '[')
- {
- NEW_NODE(alternation, ALTERNATION);
- node->loc_end = node->loc_start + 1;
- BRANCH("]");
- line++;
- }
- else if (*line == '.')
- {
- NEW_NODE(nothing, NOTHING);
- node->loc_end = node->loc_start + 1;
- LEAF;
- line++;
- }
- else if (strchr("])", *line))
- {
- end = line + 1;
- prev_end_char = *end, *end = '\0';
- if (stack_ptr == stack_orig)
- NEW_ERROR(1, ERROR, "runaway ‘%s’", line);
- else
- {
- stack_ptr--;
- if (strcmp(line, keyword_stack[stack_ptr]))
- NEW_ERROR(1, ERROR, "expected ‘%s’ but got ‘%s’", keyword_stack[stack_ptr], line);
- NEXT;
+ if (mapseq && *line == '(') {
+ NEW_NODE(unordered, UNORDERED);
+ node->loc_end = node->loc_start + 1;
+ BRANCH(")");
+ line++;
+ } else if (*line == '[') {
+ NEW_NODE(alternation, ALTERNATION);
+ node->loc_end = node->loc_start + 1;
+ BRANCH("]");
+ line++;
+ } else if (*line == '.') {
+ NEW_NODE(nothing, NOTHING);
+ node->loc_end = node->loc_start + 1;
+ LEAF;
+ line++;
+ } else if (strchr("])", *line)) {
+ end = line + 1;
+ prev_end_char = *end, *end = '\0';
+ if (stack_ptr == stack_orig) {
+ NEW_ERROR(1, ERROR, "runaway ‘%s’", line);
+ } else {
+ stack_ptr--;
+ if (strcmp(line, keyword_stack[stack_ptr]))
+ NEW_ERROR(1, ERROR, "expected ‘%s’ but got ‘%s’", keyword_stack[stack_ptr], line);
+ NEXT;
+ }
+ *end = prev_end_char;
+ line++;
+ } else if (*line == '<') {
+ NEW_NODE(keys, KEYS);
+ NO_JUMP;
+ PURE_KEYS(keys);
+ LEAF;
+ node->loc_end = (size_t)(line - LINE);
+ } else {
+ NEW_NODE(string, STRING);
+ NO_JUMP;
+ CHARS(string);
+ LEAF;
+ node->loc_end = (size_t)(line - LINE);
}
- *end = prev_end_char;
- line++;
- }
- else if (*line == '<')
- {
- NEW_NODE(keys, KEYS);
- NO_JUMP;
- PURE_KEYS(keys);
- LEAF;
- node->loc_end = (size_t)(line - LINE);
- }
- else
- {
- NEW_NODE(string, STRING);
- NO_JUMP;
- CHARS(string);
- LEAF;
- node->loc_end = (size_t)(line - LINE);
- }
-
- return 0;
+
+ return 0;
fail:
- return -1;
+ return -1;
}
@@ -973,23 +952,23 @@ static int sequence(int mapseq, size_t stack_orig)
*
* @param stack_orig The size of the stack when `SEQUENCE` was called
*/
-static int sequence_fully_popped(size_t stack_orig)
+static int
+sequence_fully_popped(size_t stack_orig)
{
- if (stack_ptr == stack_orig)
- return 0;
- end = line + 1;
- NEW_ERROR(1, ERROR, "premature end of sequence");
- while (stack_ptr > stack_orig)
- {
- stack_ptr--;
- NEW_ERROR(1, NOTE, "missing associated ‘%s’", keyword_stack[stack_ptr]);
- error->start = tree_stack[stack_ptr][0]->loc_start;
- error->end = tree_stack[stack_ptr][0]->loc_end;
- }
-
- return 0;
- fail:
- return -1;
+ if (stack_ptr == stack_orig)
+ return 0;
+ end = line + 1;
+ NEW_ERROR(1, ERROR, "premature end of sequence");
+ while (stack_ptr > stack_orig) {
+ stack_ptr--;
+ NEW_ERROR(1, NOTE, "missing associated ‘%s’", keyword_stack[stack_ptr]);
+ error->start = tree_stack[stack_ptr][0]->loc_start;
+ error->end = tree_stack[stack_ptr][0]->loc_end;
+ }
+
+ return 0;
+fail:
+ return -1;
}
@@ -1002,62 +981,54 @@ static int sequence_fully_popped(size_t stack_orig)
*
* @return Zero on success, -1 on error, 1 if the caller should go to `redo`
*/
-static int parse_else(void)
+static int
+parse_else(void)
{
- size_t i;
- if (stack_ptr == 0)
- {
- NEW_ERROR(1, ERROR, "runaway ‘else’ statement");
- return 0;
- }
- line = STREND(line);
- *end = prev_end_char, prev_end_char = '\0';
- end = STREND(line);
- SKIP_SPACES(line);
- i = stack_ptr - 1;
- while (keyword_stack[i] == NULL)
- i--;
- if (strcmp(keyword_stack[i], "if"))
- {
- stack_ptr--;
- line = original, end = STREND(line);
- NEW_ERROR(1, ERROR, "runaway ‘else’ statement");
- }
- else if (*line == '\0')
- {
- /* else */
- mds_kbdc_tree_if_t* supernode = &(tree_stack[stack_ptr - 1][0]->if_);
- if (supernode->otherwise)
- {
- line = strstr(LINE, "else");
- end = line + 4, prev_end_char = *end;
- NEW_ERROR(1, ERROR, "multiple ‘else’ statements");
- mds_kbdc_tree_free(supernode->otherwise);
- supernode->otherwise = NULL;
+ size_t i;
+ if (!stack_ptr) {
+ NEW_ERROR(1, ERROR, "runaway ‘else’ statement");
+ return 0;
}
- tree_stack[stack_ptr] = &(supernode->otherwise);
- }
- else if ((strstr(line, "if") == line) && ((line[2] == ' ') || (line[2] == '\0')))
- {
- /* else if */
- mds_kbdc_tree_if_t* supernode = &(tree_stack[stack_ptr - 1][0]->if_);
- NEW_NODE(if, IF);
- node->loc_end = node->loc_start + 2;
- end = line += 2, prev_end_char = *end, *end = '\0';
- CHARS(condition);
- END;
- tree_stack[stack_ptr] = &(supernode->otherwise);
- BRANCH(NULL);
- }
- else
- {
- NEW_ERROR(1, ERROR, "expecting nothing or ‘if’");
- stack_ptr--;
- }
-
- return 0;
- fail:
- return -1;
+ line = STREND(line);
+ *end = prev_end_char, prev_end_char = '\0';
+ end = STREND(line);
+ SKIP_SPACES(line);
+ i = stack_ptr - 1;
+ while (!keyword_stack[i])
+ i--;
+ if (strcmp(keyword_stack[i], "if")) {
+ stack_ptr--;
+ line = original, end = STREND(line);
+ NEW_ERROR(1, ERROR, "runaway ‘else’ statement");
+ } else if (!*line) {
+ /* else */
+ mds_kbdc_tree_if_t *supernode = &tree_stack[stack_ptr - 1][0]->if_;
+ if (supernode->otherwise) {
+ line = strstr(LINE, "else");
+ end = line + 4, prev_end_char = *end;
+ NEW_ERROR(1, ERROR, "multiple ‘else’ statements");
+ mds_kbdc_tree_free(supernode->otherwise);
+ supernode->otherwise = NULL;
+ }
+ tree_stack[stack_ptr] = &supernode->otherwise;
+ } else if (strstr(line, "if") == line && (line[2] == ' ' || !line[2])) {
+ /* else if */
+ mds_kbdc_tree_if_t *supernode = &tree_stack[stack_ptr - 1][0]->if_;
+ NEW_NODE(if, IF);
+ node->loc_end = node->loc_start + 2;
+ end = line += 2, prev_end_char = *end, *end = '\0';
+ CHARS(condition);
+ END;
+ tree_stack[stack_ptr] = &(supernode->otherwise);
+ BRANCH(NULL);
+ } else {
+ NEW_ERROR(1, ERROR, "expecting nothing or ‘if’");
+ stack_ptr--;
+ }
+
+ return 0;
+fail:
+ return -1;
}
@@ -1066,20 +1037,21 @@ static int parse_else(void)
*
* @return Zero on success, -1 on error, 1 if the caller should go to `redo`
*/
-static int parse_for(void)
+static int
+parse_for(void)
{
- NEW_NODE(for, FOR);
- CHARS(first);
- TEST_FOR_KEYWORD("to");
- CHARS(last);
- TEST_FOR_KEYWORD("as");
- CHARS(variable);
- END;
- BRANCH("for");
-
- return 0;
- fail:
- return -1;
+ NEW_NODE(for, FOR);
+ CHARS(first);
+ TEST_FOR_KEYWORD("to");
+ CHARS(last);
+ TEST_FOR_KEYWORD("as");
+ CHARS(variable);
+ END;
+ BRANCH("for");
+
+ return 0;
+fail:
+ return -1;
}
@@ -1088,52 +1060,48 @@ static int parse_for(void)
*
* @return Zero on success, -1 on error, 1 if the caller should go to `redo`
*/
-static int parse_let(void)
+static int
+parse_let(void)
{
- NEW_NODE(let, LET);
- CHARS(variable);
- TEST_FOR_KEYWORD(":");
- *end = prev_end_char;
- SKIP_SPACES(line);
- if (*line == '{')
+ NEW_NODE(let, LET);
+ CHARS(variable);
+ TEST_FOR_KEYWORD(":");
+ *end = prev_end_char;
+ SKIP_SPACES(line);
+ if (*line == '{')
#define inner value
- BRANCH(NULL);
+ BRANCH(NULL);
#undef inner
- else
- LEAF;
- if (*line == '\0')
- {
- line = original, end = STREND(line), prev_end_char = '\0';
- NEW_ERROR(1, ERROR, "too few parameters");
- }
- else if (*line != '{')
- {
+ else
+ LEAF;
+ if (!*line) {
+ line = original, end = STREND(line), prev_end_char = '\0';
+ NEW_ERROR(1, ERROR, "too few parameters");
+ } else if (*line != '{') {
#define node subnode
- NEW_NODE(string, STRING);
- NO_JUMP;
- CHARS(string);
- node->loc_end = (size_t)(end - LINE);
+ NEW_NODE(string, STRING);
+ NO_JUMP;
+ CHARS(string);
+ node->loc_end = (size_t)(end - LINE);
#undef node
- node->value = (mds_kbdc_tree_t*)subnode;
- END;
- }
- else
- {
+ node->value = (mds_kbdc_tree_t*)subnode;
+ END;
+ } else {
#define node subnode
#define inner elements
- NEW_NODE(array, ARRAY);
- BRANCH("}");
- node->loc_end = node->loc_start + 1;
+ NEW_NODE(array, ARRAY);
+ BRANCH("}");
+ node->loc_end = node->loc_start + 1;
#undef inner
#undef node
- in_array = 1;
- line++;
- return 1;
- }
-
- return 0;
- fail:
- return -1;
+ in_array = 1;
+ line++;
+ return 1;
+ }
+
+ return 0;
+fail:
+ return -1;
}
@@ -1142,29 +1110,28 @@ static int parse_let(void)
*
* @return Zero on success, -1 on error, 1 if the caller should go to `redo`
*/
-static int parse_end(void)
+static int
+parse_end(void)
{
- if (stack_ptr == 0)
- {
- NEW_ERROR(1, ERROR, "runaway ‘end’ statement");
- return 0;
- }
- line = STREND(line);
- *end = prev_end_char, prev_end_char = '\0';
- SKIP_SPACES(line);
- while (keyword_stack[--stack_ptr] == NULL);
- if (*line == '\0')
- {
- line = original, end = STREND(line);
- NEW_ERROR(1, ERROR, "expecting a keyword after ‘end’");
- }
- else if (strcmp(line, keyword_stack[stack_ptr]))
- NEW_ERROR(1, ERROR, "expected ‘%s’ but got ‘%s’", keyword_stack[stack_ptr], line);
- NEXT;
-
- return 0;
- fail:
- return -1;
+ if (!stack_ptr) {
+ NEW_ERROR(1, ERROR, "runaway ‘end’ statement");
+ return 0;
+ }
+ line = STREND(line);
+ *end = prev_end_char, prev_end_char = '\0';
+ SKIP_SPACES(line);
+ while (!keyword_stack[--stack_ptr]);
+ if (!*line) {
+ line = original, end = STREND(line);
+ NEW_ERROR(1, ERROR, "expecting a keyword after ‘end’");
+ } else if (strcmp(line, keyword_stack[stack_ptr])) {
+ NEW_ERROR(1, ERROR, "expected ‘%s’ but got ‘%s’", keyword_stack[stack_ptr], line);
+ }
+ NEXT;
+
+ return 0;
+fail:
+ return -1;
}
@@ -1173,57 +1140,56 @@ static int parse_end(void)
*
* @return Zero on success, -1 on error, 1 if the caller should go to `redo`
*/
-static int parse_map(void)
+static int
+parse_map(void)
{
- size_t stack_orig = stack_ptr + 1;
- char* colon;
+ size_t stack_orig = stack_ptr + 1;
+ char *colon;
#define node supernode
#define inner sequence
- NEW_NODE(map, MAP);
- node->loc_end = node->loc_start;
- BRANCH(":");
+ NEW_NODE(map, MAP);
+ node->loc_end = node->loc_start;
+ BRANCH(":");
#undef inner
#undef node
- SEQUENCE(1);
- SEQUENCE_FULLY_POPPED;
+ SEQUENCE(1);
+ SEQUENCE_FULLY_POPPED;
#define node supernode
#define inner result
- stack_ptr--;
- *end = prev_end_char;
- supernode->loc_end = (size_t)(end - LINE);
- SKIP_SPACES(line);
- if (colon = line, *line++ != ':')
- {
- LEAF;
- prev_end_char = *end;
- return 0; /* Not an error in functions, or if \set is access, even indirectly. */
- }
- BRANCH(":");
+ stack_ptr--;
+ *end = prev_end_char;
+ supernode->loc_end = (size_t)(end - LINE);
+ SKIP_SPACES(line);
+ if (colon = line, *line++ != ':') {
+ LEAF;
+ prev_end_char = *end;
+ return 0; /* Not an error in functions, or if \set is access, even indirectly. */
+ }
+ BRANCH(":");
#undef inner
#undef node
- SEQUENCE(1);
- SEQUENCE_FULLY_POPPED;
- stack_ptr--;
- *end = prev_end_char;
- supernode->loc_end = (size_t)(end - LINE);
- SKIP_SPACES(line);
+ SEQUENCE(1);
+ SEQUENCE_FULLY_POPPED;
+ stack_ptr--;
+ *end = prev_end_char;
+ supernode->loc_end = (size_t)(end - LINE);
+ SKIP_SPACES(line);
#define node supernode
- LEAF;
+ LEAF;
#undef node
- if (supernode->result == NULL)
- {
- NEW_ERROR(1, ERROR, "output missing");
- error->start = (size_t)(colon - LINE);
- error->end = error->start + 1;
- }
- if (*line == '\0')
- return prev_end_char = *end, 0;
- end = STREND(line), prev_end_char = *end;
- NEW_ERROR(1, ERROR, "too many parameters");
-
- return 0;
- fail:
- return -1;
+ if (!supernode->result) {
+ NEW_ERROR(1, ERROR, "output missing");
+ error->start = (size_t)(colon - LINE);
+ error->end = error->start + 1;
+ }
+ if (!*line)
+ return prev_end_char = *end, 0;
+ end = STREND(line), prev_end_char = *end;
+ NEW_ERROR(1, ERROR, "too many parameters");
+
+ return 0;
+fail:
+ return -1;
}
@@ -1232,63 +1198,59 @@ static int parse_map(void)
*
* @return Zero on success, -1 on error, 1 if the caller should go to `redo`
*/
-static int parse_macro_call(void)
+static int
+parse_macro_call(void)
{
- char* old_end = end;
- char old_prev_end_char = prev_end_char;
- size_t stack_orig = stack_ptr + 1;
- *end = prev_end_char;
- end = strchrnul(line, '(');
- prev_end_char = *end, *end = '\0';
- if (prev_end_char)
- {
+ char *old_end = end;
+ char old_prev_end_char = prev_end_char;
+ size_t stack_orig = stack_ptr + 1;
+ *end = prev_end_char;
+ end = strchrnul(line, '(');
+ prev_end_char = *end, *end = '\0';
+ if (prev_end_char) {
#define node supernode
#define inner arguments
- NEW_NODE(macro_call, MACRO_CALL);
- old_end = end, old_prev_end_char = prev_end_char;
- NO_JUMP;
- *old_end = '\0';
- CHARS(name);
- BRANCH(NULL);
- end = old_end, prev_end_char = old_prev_end_char;
- line++;
+ NEW_NODE(macro_call, MACRO_CALL);
+ old_end = end, old_prev_end_char = prev_end_char;
+ NO_JUMP;
+ *old_end = '\0';
+ CHARS(name);
+ BRANCH(NULL);
+ end = old_end, prev_end_char = old_prev_end_char;
+ line++;
#undef inner
#undef node
- SEQUENCE(0);
- SEQUENCE_FULLY_POPPED;
+ SEQUENCE(0);
+ SEQUENCE_FULLY_POPPED;
#define node supernode
- if (*line == ')')
- {
- line++;
- SKIP_SPACES(line);
- if (*line)
- {
- NEW_ERROR(1, ERROR, "extra token after macro call");
- error->end = strlen(LINE);
- }
- }
- else
- {
- NEW_ERROR(1, ERROR, "missing ‘)’");
- error->start = (size_t)(strchr(LINE, '(') - LINE);
- error->end = error->start + 1;
- }
- stack_ptr--;
- NEXT;
- return 0;
+ if (*line == ')') {
+ line++;
+ SKIP_SPACES(line);
+ if (*line) {
+ NEW_ERROR(1, ERROR, "extra token after macro call");
+ error->end = strlen(LINE);
+ }
+ } else {
+ NEW_ERROR(1, ERROR, "missing ‘)’");
+ error->start = (size_t)(strchr(LINE, '(') - LINE);
+ error->end = error->start + 1;
+ }
+ stack_ptr--;
+ NEXT;
+ return 0;
#undef node
- }
- *old_end = '\0';
- end = old_end;
- prev_end_char = old_prev_end_char;
- if (strchr("}", *line))
- NEW_ERROR(1, ERROR, "runaway ‘%c’", *line);
- else
- NEW_ERROR(1, ERROR, "invalid syntax ‘%s’", line);
-
- return 0;
- fail:
- return -1;
+ }
+ *old_end = '\0';
+ end = old_end;
+ prev_end_char = old_prev_end_char;
+ if (strchr("}", *line))
+ NEW_ERROR(1, ERROR, "runaway ‘%c’", *line);
+ else
+ NEW_ERROR(1, ERROR, "invalid syntax ‘%s’", line);
+
+ return 0;
+fail:
+ return -1;
}
@@ -1297,48 +1259,44 @@ static int parse_macro_call(void)
*
* @return Zero on success, -1 on error, 1 if the caller should go to `redo`
*/
-static int parse_array_elements(void)
+static int
+parse_array_elements(void)
{
- for (;;)
- {
- SKIP_SPACES(line);
- if (*line == '\0')
- return 0;
- else if (*line == '}')
- {
- line++;
- end = STREND(line);
- END;
- line = end, prev_end_char = '\0';
- goto done;
+ for (;;) {
+ SKIP_SPACES(line);
+ if (!*line) {
+ return 0;
+ } else if (*line == '}') {
+ line++;
+ end = STREND(line);
+ END;
+ line = end, prev_end_char = '\0';
+ goto done;
+ } else {
+ NEW_NODE(string, STRING);
+ if (strchr("[]()<>{}", *line)) {
+ mds_kbdc_tree_free((mds_kbdc_tree_t*)node);
+ NEW_ERROR(1, ERROR, "x-stray ‘%c’", *line);
+ error->end = error->start + 1;
+ goto done;
+ }
+ NO_JUMP;
+ CHARS(string);
+ LEAF;
+ node->loc_end = (size_t)(end - LINE);
+ *end = prev_end_char;
+ line = end;
+ }
}
- else
- {
- NEW_NODE(string, STRING);
- if (strchr("[]()<>{}", *line))
- {
- mds_kbdc_tree_free((mds_kbdc_tree_t*)node);
- NEW_ERROR(1, ERROR, "x-stray ‘%c’", *line);
- error->end = error->start + 1;
- goto done;
- }
- NO_JUMP;
- CHARS(string);
- LEAF;
- node->loc_end = (size_t)(end - LINE);
- *end = prev_end_char;
- line = end;
- }
- }
-
- fail:
- return -1;
-
- done:
- in_array = 0;
- stack_ptr -= 2;
- NEXT;
- return 0;
+
+fail:
+ return -1;
+
+done:
+ in_array = 0;
+ stack_ptr -= 2;
+ NEXT;
+ return 0;
}
@@ -1347,50 +1305,47 @@ static int parse_array_elements(void)
*
* @return Zero on success, -1 on error
*/
-static int parse_line(void)
+static int
+parse_line(void)
{
-#define p(function) \
- do \
- { \
- fail_if (r = function(), r < 0); \
- if (r > 0) \
- goto redo; \
- } \
- while (0)
-
- int r;
-
- redo:
- if (in_array) p (parse_array_elements);
- else if (!strcmp(line, "have_chars"))
- MAKE_LEAF(assumption_have_chars, ASSUMPTION_HAVE_CHARS, QUOTES_1(chars));
- else if (!strcmp(line, "have_range"))
- MAKE_LEAF(assumption_have_range, ASSUMPTION_HAVE_RANGE, CHARS(first); CHARS(last); END);
- else if (!strcmp(line, "have")) MAKE_LEAF(assumption_have, ASSUMPTION_HAVE, KEYS(data); END);
- else if (!strcmp(line, "information")) MAKE_BRANCH(information, INFORMATION, NO_PARAMETERS("information"));
- else if (!strcmp(line, "assumption")) MAKE_BRANCH(assumption, ASSUMPTION, NO_PARAMETERS("assumption"));
- else if (!strcmp(line, "return")) MAKE_LEAF(return, RETURN, NO_PARAMETERS("return"));
- else if (!strcmp(line, "continue")) MAKE_LEAF(continue, CONTINUE, NO_PARAMETERS("continue"));
- else if (!strcmp(line, "break")) MAKE_LEAF(break, BREAK, NO_PARAMETERS("break"));
- else if (!strcmp(line, "language")) MAKE_LEAF(information_language, INFORMATION_LANGUAGE, QUOTES_1(data));
- else if (!strcmp(line, "country")) MAKE_LEAF(information_country, INFORMATION_COUNTRY, QUOTES_1(data));
- else if (!strcmp(line, "variant")) MAKE_LEAF(information_variant, INFORMATION_VARIANT, QUOTES_1(data));
- else if (!strcmp(line, "include")) MAKE_LEAF(include, INCLUDE, QUOTES_1(filename));
- else if (!strcmp(line, "function")) MAKE_BRANCH(function, FUNCTION, NAMES_1(name));
- else if (!strcmp(line, "macro")) MAKE_BRANCH(macro, MACRO, NAMES_1(name));
- else if (!strcmp(line, "if")) MAKE_BRANCH(if, IF, CHARS(condition); END);
- else if (!strcmp(line, "else")) p (parse_else);
- else if (!strcmp(line, "for")) p (parse_for);
- else if (!strcmp(line, "let")) p (parse_let);
- else if (!strcmp(line, "end")) p (parse_end);
- else if (strchr("\\\"<([0123456789", *line)) p (parse_map);
- else p (parse_macro_call);
-
- *end = prev_end_char;
-
- return 0;
- fail:
- return -1;
+#define p(function)\
+ do {\
+ fail_if ((r = function()) < 0);\
+ if (r > 0)\
+ goto redo;\
+ } while (0)
+
+ int r;
+
+redo:
+ if (in_array) p (parse_array_elements);
+ else if (!strcmp(line, "have_chars")) MAKE_LEAF(assumption_have_chars, ASSUMPTION_HAVE_CHARS, QUOTES_1(chars));
+ else if (!strcmp(line, "have_range")) MAKE_LEAF(assumption_have_range, ASSUMPTION_HAVE_RANGE, CHARS(first); CHARS(last); END);
+ else if (!strcmp(line, "have")) MAKE_LEAF(assumption_have, ASSUMPTION_HAVE, KEYS(data); END);
+ else if (!strcmp(line, "information")) MAKE_BRANCH(information, INFORMATION, NO_PARAMETERS("information"));
+ else if (!strcmp(line, "assumption")) MAKE_BRANCH(assumption, ASSUMPTION, NO_PARAMETERS("assumption"));
+ else if (!strcmp(line, "return")) MAKE_LEAF(return, RETURN, NO_PARAMETERS("return"));
+ else if (!strcmp(line, "continue")) MAKE_LEAF(continue, CONTINUE, NO_PARAMETERS("continue"));
+ else if (!strcmp(line, "break")) MAKE_LEAF(break, BREAK, NO_PARAMETERS("break"));
+ else if (!strcmp(line, "language")) MAKE_LEAF(information_language, INFORMATION_LANGUAGE, QUOTES_1(data));
+ else if (!strcmp(line, "country")) MAKE_LEAF(information_country, INFORMATION_COUNTRY, QUOTES_1(data));
+ else if (!strcmp(line, "variant")) MAKE_LEAF(information_variant, INFORMATION_VARIANT, QUOTES_1(data));
+ else if (!strcmp(line, "include")) MAKE_LEAF(include, INCLUDE, QUOTES_1(filename));
+ else if (!strcmp(line, "function")) MAKE_BRANCH(function, FUNCTION, NAMES_1(name));
+ else if (!strcmp(line, "macro")) MAKE_BRANCH(macro, MACRO, NAMES_1(name));
+ else if (!strcmp(line, "if")) MAKE_BRANCH(if, IF, CHARS(condition); END);
+ else if (!strcmp(line, "else")) p (parse_else);
+ else if (!strcmp(line, "for")) p (parse_for);
+ else if (!strcmp(line, "let")) p (parse_let);
+ else if (!strcmp(line, "end")) p (parse_end);
+ else if (strchr("\\\"<([0123456789", *line)) p (parse_map);
+ else p (parse_macro_call);
+
+ *end = prev_end_char;
+
+ return 0;
+fail:
+ return -1;
#undef p
}
@@ -1406,63 +1361,62 @@ static int parse_line(void)
* @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_parsed_t* restrict result_)
+int
+parse_to_tree(const char *restrict filename, mds_kbdc_parsed_t *restrict result_)
{
- size_t line_n;
- int r, saved_errno;
-
-
- /* Prepare parsing. */
- result = result_;
- stack_ptr = 0;
- keyword_stack = NULL;
- tree_stack = NULL;
- in_array = 0;
-
- fail_if (xmalloc(result->source_code, 1, mds_kbdc_source_code_t));
- mds_kbdc_source_code_initialise(result->source_code);
-
- r = get_pathname(filename);
- fail_if (r < 0);
- if (r == 0)
- return 0;
-
- fail_if (read_source_code());
- fail_if (allocate_stacks());
-
-
- /* Create a node-slot for the tree root. */
- *tree_stack = &(result->tree);
-
- /* Parse the file. */
- for (line_i = 0, line_n = result->source_code->line_count; line_i < line_n; line_i++)
- {
- line = LINE;
- SKIP_SPACES(line);
- if (end = strchrnul(line, ' '), end == line)
- continue;
- prev_end_char = *end, *end = '\0';
- original = line;
- too_few = 0;
-
- parse_line();
- }
-
-
- /* Check parsing state. */
- fail_if (check_for_premature_end_of_file());
- fail_if (check_whether_file_is_empty());
-
- /* Clean up. */
- free(keyword_stack);
- free(tree_stack);
- return 0;
-
- fail:
- saved_errno = errno;
- free(keyword_stack);
- free(tree_stack);
- return errno = saved_errno, -1;
+ size_t line_n;
+ int r, saved_errno;
+
+
+ /* Prepare parsing. */
+ result = result_;
+ stack_ptr = 0;
+ keyword_stack = NULL;
+ tree_stack = NULL;
+ in_array = 0;
+
+ fail_if (xmalloc(result->source_code, 1, mds_kbdc_source_code_t));
+ mds_kbdc_source_code_initialise(result->source_code);
+
+ fail_if ((r = get_pathname(filename)) < 0);
+ if (!r)
+ return 0;
+
+ fail_if (read_source_code());
+ fail_if (allocate_stacks());
+
+
+ /* Create a node-slot for the tree root. */
+ *tree_stack = &(result->tree);
+
+ /* Parse the file. */
+ for (line_i = 0, line_n = result->source_code->line_count; line_i < line_n; line_i++) {
+ line = LINE;
+ SKIP_SPACES(line);
+ if ((end = strchrnul(line, ' ')) == line)
+ continue;
+ prev_end_char = *end, *end = '\0';
+ original = line;
+ too_few = 0;
+
+ parse_line();
+ }
+
+
+ /* Check parsing state. */
+ fail_if (check_for_premature_end_of_file());
+ fail_if (check_whether_file_is_empty());
+
+ /* Clean up. */
+ free(keyword_stack);
+ free(tree_stack);
+ return 0;
+
+fail:
+ saved_errno = errno;
+ free(keyword_stack);
+ free(tree_stack);
+ return errno = saved_errno, -1;
}
@@ -1493,4 +1447,3 @@ int parse_to_tree(const char* restrict filename, mds_kbdc_parsed_t* restrict res
#undef in_range
#undef PRINT_STACK
#undef DEBUG_PROC
-