aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMattias Andrée <maandree@operamail.com>2014-11-17 21:28:28 +0100
committerMattias Andrée <maandree@operamail.com>2014-11-17 21:28:28 +0100
commita7fbfe615ac12b9258f57bf38bc35d81a1c24321 (patch)
treeda7920c854f754fedff98709a443ac1a27bf2a94 /src
parentwhitespace (diff)
downloadmds-a7fbfe615ac12b9258f57bf38bc35d81a1c24321.tar.gz
mds-a7fbfe615ac12b9258f57bf38bc35d81a1c24321.tar.bz2
mds-a7fbfe615ac12b9258f57bf38bc35d81a1c24321.tar.xz
mds-kbdc: support alternations and dots in macro_calls
Signed-off-by: Mattias Andrée <maandree@operamail.com>
Diffstat (limited to 'src')
-rw-r--r--src/mds-kbdc/make-tree.c63
1 files changed, 28 insertions, 35 deletions
diff --git a/src/mds-kbdc/make-tree.c b/src/mds-kbdc/make-tree.c
index a16bda7..4ed3017 100644
--- a/src/mds-kbdc/make-tree.c
+++ b/src/mds-kbdc/make-tree.c
@@ -554,15 +554,18 @@
/**
* Parse a sequence in a mapping
+ *
+ * @param mapseq:int Whether this is a mapping sequence, otherwise
+ * it is treated as macro call arguments
*/
-#define SEQUENCE \
+#define SEQUENCE(mapseq) \
do /* for(;;) */ \
{ \
*end = prev_end_char; \
SKIP_SPACES(line); \
- if ((*line == '\0') || (*line == ':')) \
+ if ((*line == '\0') || (*line == (mapseq ? ':' : ')'))) \
break; \
- if (*line == '(') \
+ if (mapseq && (*line == '(')) \
{ \
NEW_NODE(unordered, UNORDERED); \
node->loc_end = node->loc_start + 1; \
@@ -958,7 +961,7 @@ int parse_to_tree(const char* restrict filename, mds_kbdc_tree_t** restrict resu
BRANCH(":");
#undef inner
#undef node
- SEQUENCE;
+ SEQUENCE(1);
SEQUENCE_FULLY_POPPED(stack_orig);
#define node supernode
#define inner result
@@ -973,7 +976,7 @@ int parse_to_tree(const char* restrict filename, mds_kbdc_tree_t** restrict resu
BRANCH(":");
#undef inner
#undef node
- SEQUENCE;
+ SEQUENCE(1);
SEQUENCE_FULLY_POPPED(stack_orig);
stack_ptr--;
*end = prev_end_char;
@@ -990,57 +993,47 @@ int parse_to_tree(const char* restrict filename, mds_kbdc_tree_t** restrict resu
{
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);
-#define inner arguments
BRANCH(NULL);
-#undef inner
end = old_end, prev_end_char = old_prev_end_char;
line++;
- for (;;)
+#undef inner
+#undef node
+ SEQUENCE(0);
+ SEQUENCE_FULLY_POPPED(stack_orig);
+#define node supernode
+ if (*line == ')')
{
- *end = prev_end_char;
+ line++;
SKIP_SPACES(line);
- if (*line == '\0')
+ if (*line)
{
- NEW_ERROR(1, ERROR, "missing ‘)’");
- error->start = (size_t)(strchr(LINE, '(') - LINE);
- error->end = error->start + 1;
- break;
- }
- else if (*line == ')')
- {
- line++;
- SKIP_SPACES(line);
- if (*line)
- {
- NEW_ERROR(1, ERROR, "extra token after macro call");
- error->end = strlen(LINE);
- }
- break;
- }
- else
- {
-#define node subnode
- NEW_NODE(string, STRING);
- NO_JUMP;
- CHARS(string);
- LEAF;
- node->loc_end = (size_t)(line - LINE);
-#undef node
+ 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;
goto next;
+#undef node
}
*old_end = '\0';
end = old_end;