diff options
author | Mattias Andrée <maandree@operamail.com> | 2014-12-05 16:09:26 +0100 |
---|---|---|
committer | Mattias Andrée <maandree@operamail.com> | 2014-12-05 16:09:26 +0100 |
commit | a738f7ec92c2c101d1ca56c29761a9e318663031 (patch) | |
tree | 4c5a5086a6250094902e333a46097f88fcc7fe5a /src/mds-kbdc | |
parent | mds-kbdc: m (diff) | |
download | mds-a738f7ec92c2c101d1ca56c29761a9e318663031.tar.gz mds-a738f7ec92c2c101d1ca56c29761a9e318663031.tar.bz2 mds-a738f7ec92c2c101d1ca56c29761a9e318663031.tar.xz |
mds-kbdc: create compiled versions of C(KEYS) and C(STRING) so we do not have to convert back and forth between UTF-8 and UTF-16
Signed-off-by: Mattias Andrée <maandree@operamail.com>
Diffstat (limited to 'src/mds-kbdc')
-rw-r--r-- | src/mds-kbdc/compile-layout.c | 19 | ||||
-rw-r--r-- | src/mds-kbdc/string.c | 44 | ||||
-rw-r--r-- | src/mds-kbdc/string.h | 28 | ||||
-rw-r--r-- | src/mds-kbdc/tree.c | 56 | ||||
-rw-r--r-- | src/mds-kbdc/tree.h | 75 |
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; |