aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mds-kbdc/compile-layout.c19
-rw-r--r--src/mds-kbdc/string.c44
-rw-r--r--src/mds-kbdc/string.h28
-rw-r--r--src/mds-kbdc/tree.c56
-rw-r--r--src/mds-kbdc/tree.h75
5 files changed, 167 insertions, 55 deletions
diff --git a/src/mds-kbdc/compile-layout.c b/src/mds-kbdc/compile-layout.c
index ea6f43e..cdf8df6 100644
--- a/src/mds-kbdc/compile-layout.c
+++ b/src/mds-kbdc/compile-layout.c
@@ -1108,9 +1108,8 @@ static int evaluate_element(mds_kbdc_tree_t* restrict node)
if (node->type == C(KEYS))
fail_if ((data = parse_keys(node, node->keys.keys, node->loc_start), data == NULL));
free(node->string.string);
- node->string.string = string_encode(data);
- free(data);
- fail_if (node->string.string == NULL);
+ node->type = (node->type == C(STRING)) ? C(COMPILED_STRING) : C(COMPILED_KEYS);
+ node->compiled_string.string = data;
bad |= (node->processed == PROCESS_LEVEL);
}
@@ -1171,14 +1170,14 @@ static int compile_array(mds_kbdc_tree_array_t* restrict tree)
*/
static int check_nonnul(mds_kbdc_tree_t* restrict tree)
{
- const char* restrict string;
+ const char32_t* restrict string;
int rc = 0;
again:
if (tree == NULL)
return rc;
- for (string = tree->string.string; *string; string++)
- if ((string[0] == (char)0xC0) && (string[1] == (char)0x80))
+ for (string = tree->compiled_string.string; *string != -1; string++)
+ if (*string == 0)
{
NEW_ERROR(tree, ERROR, "NULL characters are not allowed in mappings");
tree->processed = PROCESS_LEVEL;
@@ -1208,7 +1207,6 @@ static int compile_map(mds_kbdc_tree_map_t* restrict tree)
mds_kbdc_tree_t* old_seq = tree->sequence;
mds_kbdc_tree_t* old_res = tree->result;
mds_kbdc_tree_map_t* dup_map = NULL;
- char32_t* data = NULL;
int r, saved_errno;
mds_kbdc_tree_t* previous_last_value_statement = last_value_statement;
@@ -1268,10 +1266,8 @@ static int compile_map(mds_kbdc_tree_map_t* restrict tree)
last_value_statement = (mds_kbdc_tree_t*)tree;
/* Add the value statement */
- data = string_decode(seq->string.string);
- fail_if (data == NULL);
- fail_if ((r = set_return_value(data), r < 0));
- data = NULL;
+ fail_if ((r = set_return_value(seq->compiled_string.string), r < 0));
+ seq->compiled_string.string = NULL;
/* Check that the value-statement is inside a function call, or has
side-effects by directly or indirectly calling ‘\set/3’ on an
@@ -1298,7 +1294,6 @@ static int compile_map(mds_kbdc_tree_map_t* restrict tree)
mds_kbdc_tree_free(res);
return 0;
FAIL_BEGIN;
- free(data);
mds_kbdc_include_stack_free(include_stack);
mds_kbdc_tree_free((mds_kbdc_tree_t*)dup_map);
mds_kbdc_tree_free(seq);
diff --git a/src/mds-kbdc/string.c b/src/mds-kbdc/string.c
index ac3ef4b..69f8f25 100644
--- a/src/mds-kbdc/string.c
+++ b/src/mds-kbdc/string.c
@@ -20,29 +20,30 @@
#include <libmdsserver/macros.h>
#include <stdlib.h>
+#include <string.h>
/**
- * Get the length of a string.
+ * Get the length of a string
*
- * @param string The string.
- * @return The length of the string.
+ * @param string The string
+ * @return The length of the string
*/
size_t string_length(const char32_t* restrict string)
{
size_t i = 0;
- while (string[i] >= 0)
+ while (string[i] > -1)
i++;
return i;
}
/**
- * Convert a NUL-terminated UTF-8 string to a -1-terminated UTF-32 string.
+ * Convert a NUL-terminated UTF-8 string to a -1-terminated UTF-32 string
*
- * @param string The UTF-8 string.
- * @return The string in UTF-32, `NULL` on error.
+ * @param string The UTF-8 string
+ * @return The string in UTF-32, `NULL` on error
*/
char32_t* string_decode(const char* restrict string)
{
@@ -84,10 +85,12 @@ char32_t* string_decode(const char* restrict string)
/**
- * Convert a -1-terminated UTF-32 string to a NUL-terminated Modified UTF-8 string.
+ * Convert a -1-terminated UTF-32 string to a NUL-terminated Modified UTF-8 string
*
- * @param string The UTF-32 string.
- * @return The string in UTF-8, `NULL` on error.
+ * Negative values apart from -1 are converted to 0x00
+ *
+ * @param string The UTF-32 string
+ * @return The string in UTF-8, `NULL` on error
*/
char* string_encode(const char32_t* restrict string)
{
@@ -119,3 +122,24 @@ char* string_encode(const char32_t* restrict string)
return rc[j] = '\0', rc;
}
+
+/**
+ * Create duplicate of a string
+ *
+ * @param string The string
+ * @return A duplicate of the strnig, `NULL` on error or if `string` is `NULL`
+ */
+char32_t* string_dup(const char32_t* restrict string)
+{
+ size_t n;
+ char32_t* rc;
+ if (string == NULL)
+ return NULL;
+ n = string_length(string) + 1;
+ rc = malloc(n * sizeof(char32_t));
+ if (rc == NULL)
+ return NULL;
+ memcpy(rc, string, n * sizeof(char32_t));
+ return rc;
+}
+
diff --git a/src/mds-kbdc/string.h b/src/mds-kbdc/string.h
index 92051af..905c6a3 100644
--- a/src/mds-kbdc/string.h
+++ b/src/mds-kbdc/string.h
@@ -24,35 +24,43 @@
/**
- * Data type for a character in a decoded string.
+ * Data type for a character in a decoded string
*/
typedef int32_t char32_t;
/**
- * Get the length of a string.
+ * Get the length of a string
*
- * @param string The string.
- * @return The length of the string.
+ * @param string The string
+ * @return The length of the string
*/
size_t string_length(const char32_t* restrict string) __attribute__((pure, nonnull));
/**
- * Convert a NUL-terminated UTF-8 string to a -1-terminated UTF-32 string.
+ * Convert a NUL-terminated UTF-8 string to a -1-terminated UTF-32 string
*
- * @param string The UTF-8 string.
- * @return The string in UTF-32, `NULL` on error.
+ * @param string The UTF-8 string
+ * @return The string in UTF-32, `NULL` on error
*/
char32_t* string_decode(const char* restrict string) __attribute__((nonnull));
/**
- * Convert a -1-terminated UTF-32 string to a NUL-terminated Modified UTF-8 string.
+ * Convert a -1-terminated UTF-32 string to a NUL-terminated Modified UTF-8 string
*
- * @param string The UTF-32 string.
- * @return The string in UTF-8, `NULL` on error.
+ * @param string The UTF-32 string
+ * @return The string in UTF-8, `NULL` on error
*/
char* string_encode(const char32_t* restrict string) __attribute__((nonnull));
+/**
+ * Create duplicate of a string
+ *
+ * @param string The string
+ * @return A duplicate of the strnig, `NULL` on error or if `string` is `NULL`
+ */
+char32_t* string_dup(const char32_t* restrict string);
+
#endif
diff --git a/src/mds-kbdc/tree.c b/src/mds-kbdc/tree.c
index 27265d3..7493ceb 100644
--- a/src/mds-kbdc/tree.c
+++ b/src/mds-kbdc/tree.c
@@ -156,11 +156,11 @@ static void mds_kbdc_tree_destroy_(mds_kbdc_tree_t* restrict this, int recursive
break;
case C(KEYS):
- xfree(mds_kbdc_tree_keys_t*, keys);
- break;
-
case C(STRING):
- xfree(mds_kbdc_tree_string_t*, string);
+ case C(COMPILED_KEYS):
+ case C(COMPILED_STRING):
+ xfree(mds_kbdc_tree_keys_t*, keys);
+ /* We are abusing the similaries of the structures. */
break;
case C(MACRO_CALL):
@@ -245,8 +245,7 @@ void mds_kbdc_tree_free(mds_kbdc_tree_t* restrict this)
*
* @param member:identifer The member in the tree to duplicate
*/
-#define T(member) \
- fail_if (t->member && (n->member = mds_kbdc_tree_dup(t->member), n->member == NULL))
+#define T(member) fail_if (t->member && (n->member = mds_kbdc_tree_dup(t->member), n->member == NULL))
/**
@@ -254,8 +253,15 @@ void mds_kbdc_tree_free(mds_kbdc_tree_t* restrict this)
*
* @param member:identifer The member in the tree to duplicate
*/
-#define S(member) \
- fail_if (t->member && (n->member = strdup(t->member), n->member == NULL))
+#define S(member) fail_if (t->member && (n->member = strdup(t->member), n->member == NULL))
+
+
+/**
+ * Duplicate an UTF-32-string and goto `fail` on failure
+ *
+ * @param member:identifer The member in the tree to duplicate
+ */
+#define Z(member) fail_if (t->member && (n->member = string_dup(t->member), n->member == NULL))
/**
@@ -263,8 +269,7 @@ void mds_kbdc_tree_free(mds_kbdc_tree_t* restrict this)
*
* @param member:identifer The member in the tree to copied
*/
-#define R(member) \
- fail_if (t->member && (n->member = mds_kbdc_source_code_dup(t->member), n->member == NULL))
+#define R(member) fail_if (t->member && (n->member = mds_kbdc_source_code_dup(t->member), n->member == NULL))
/**
@@ -318,6 +323,8 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(mds_kbdc_tree_t* restrict this)
case C(ASSUMPTION_HAVE_CHARS): { NODE(assumption_have_chars); S(chars); } break;
case C(KEYS): { NODE(keys); S(keys); } break;
case C(STRING): { NODE(string); S(string); } break;
+ case C(COMPILED_KEYS): { NODE(compiled_keys); Z(keys); } break;
+ case C(COMPILED_STRING): { NODE(compiled_string); Z(string); } break;
case C(ASSUMPTION_HAVE_RANGE): { NODE(assumption_have_range); S(first);S(last); } break;
case C(FOR): { NODE(for); S(first);S(last);S(variable);T(inner); } break;
case C(IF): { NODE(if); S(condition);T(inner);T(otherwise); } break;
@@ -336,6 +343,7 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(mds_kbdc_tree_t* restrict this)
#undef NODE
#undef R
+#undef Z
#undef S
#undef T
@@ -397,9 +405,9 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(mds_kbdc_tree_t* restrict this)
*
* @param MEMBER:identifier The tree structure's member
*/
-#define SIMPLE(MEMBER) \
- STRING(MEMBER); \
- fprintf(output, ")\n", node->MEMBER)
+#define SIMPLE(MEMBER) \
+ STRING(MEMBER); \
+ fprintf(output, ")\n")
/**
@@ -527,6 +535,28 @@ static void mds_kbdc_tree_print_indented(mds_kbdc_tree_t* restrict this, FILE* o
case C(BREAK): NOTHING("break");
case C(CONTINUE): NOTHING("continue");
+ case C(COMPILED_KEYS):
+ {
+ NODE(compiled_keys, "compiled_keys");
+ if (node->keys)
+ fprintf(output, " ‘\033[32m%s\033[00m’", string_encode(node->keys));
+ else
+ fprintf(output, " \033[35mnil\033[00m");
+ fprintf(output, ")\n");
+ }
+ break;
+
+ case C(COMPILED_STRING):
+ {
+ NODE(compiled_string, "compiled_string");
+ if (node->string)
+ fprintf(output, " ‘\033[32m%s\033[00m’", string_encode(node->string));
+ else
+ fprintf(output, " \033[35mnil\033[00m");
+ fprintf(output, ")\n");
+ }
+ break;
+
case C(FOR):
{
NODE(for, "for");
diff --git a/src/mds-kbdc/tree.h b/src/mds-kbdc/tree.h
index a3304a6..1c5d8d3 100644
--- a/src/mds-kbdc/tree.h
+++ b/src/mds-kbdc/tree.h
@@ -20,6 +20,7 @@
#include "raw-data.h"
+#include "string.h"
#include <stddef.h>
#include <stdio.h>
@@ -118,44 +119,54 @@
#define MDS_KBDC_TREE_TYPE_STRING 17
/**
+ * Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_compiled_keys_t`
+ */
+#define MDS_KBDC_TREE_TYPE_COMPILED_KEYS 18
+
+/**
+ * Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_compiled_string_t`
+ */
+#define MDS_KBDC_TREE_TYPE_COMPILED_STRING 19
+
+/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_nothing_t`
*/
-#define MDS_KBDC_TREE_TYPE_NOTHING 18
+#define MDS_KBDC_TREE_TYPE_NOTHING 20
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_alternation_t`
*/
-#define MDS_KBDC_TREE_TYPE_ALTERNATION 19
+#define MDS_KBDC_TREE_TYPE_ALTERNATION 21
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_unordered_t`
*/
-#define MDS_KBDC_TREE_TYPE_UNORDERED 20
+#define MDS_KBDC_TREE_TYPE_UNORDERED 22
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_ordered_t`
*/
-#define MDS_KBDC_TREE_TYPE_ORDERED 21
+#define MDS_KBDC_TREE_TYPE_ORDERED 23
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_macro_call_t`
*/
-#define MDS_KBDC_TREE_TYPE_MACRO_CALL 22
+#define MDS_KBDC_TREE_TYPE_MACRO_CALL 24
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_return_t`
*/
-#define MDS_KBDC_TREE_TYPE_RETURN 23
+#define MDS_KBDC_TREE_TYPE_RETURN 25
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_break_t`
*/
-#define MDS_KBDC_TREE_TYPE_BREAK 24
+#define MDS_KBDC_TREE_TYPE_BREAK 26
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_continue_t`
*/
-#define MDS_KBDC_TREE_TYPE_CONTINUE 25
+#define MDS_KBDC_TREE_TYPE_CONTINUE 27
@@ -553,14 +564,14 @@ typedef struct mds_kbdc_tree_array
/**
- * Leaf structure for a key combination
+ * Leaf structure for a key-combination
*/
typedef struct mds_kbdc_tree_keys
{
MDS_KBDC_TREE_COMMON;
/**
- * The key combination
+ * The key-combination
*/
char* keys;
@@ -593,6 +604,48 @@ typedef struct mds_kbdc_tree_string
/**
+ * Leaf structure for a compiled key-combination
+ */
+typedef struct mds_kbdc_tree_compiled_keys
+{
+ MDS_KBDC_TREE_COMMON;
+
+ /**
+ * The key-combination
+ *
+ * Strictly terminated by -1
+ */
+ char32_t* keys;
+
+ MDS_KBDC_TREE_PADDING(1);
+
+} mds_kbdc_tree_compiled_keys_t;
+
+
+/**
+ * Leaf structure for a compiled string
+ */
+typedef struct mds_kbdc_tree_compiled_string
+{
+ MDS_KBDC_TREE_COMMON;
+
+ /**
+ * The string
+ */
+ char32_t* string;
+
+ /*
+ * `evaluate_element` in "compile-layout.c" utilises
+ * that `mds_kbdc_tree_string.compiled_string` has the
+ * same offset as `mds_kbdc_tree_keys.compiled_keys`.
+ */
+
+ MDS_KBDC_TREE_PADDING(1);
+
+} mds_kbdc_tree_compiled_string_t;
+
+
+/**
* Leaf structure for nothing (a dot in the layout code)
*
* Other leaf structures without any content may `typedef`
@@ -703,6 +756,8 @@ union mds_kbdc_tree
mds_kbdc_tree_array_t array;
mds_kbdc_tree_keys_t keys;
mds_kbdc_tree_string_t string;
+ mds_kbdc_tree_compiled_keys_t compiled_keys;
+ mds_kbdc_tree_compiled_string_t compiled_string;
mds_kbdc_tree_nothing_t nothing;
mds_kbdc_tree_alternation_t alternation;
mds_kbdc_tree_unordered_t unordered;