From ce342a04922797cb53557178c54d32c4efafda16 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Wed, 6 Jul 2016 21:31:22 -0400 Subject: Document string termination in header files and remove no-longer-needed string termination logic in various places. --- gawkapi.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'gawkapi.c') diff --git a/gawkapi.c b/gawkapi.c index df69012b..afefa4f6 100644 --- a/gawkapi.c +++ b/gawkapi.c @@ -440,6 +440,7 @@ node_to_awk_value(NODE *node, awk_value_t *val, awk_valtype_t wanted) (void) force_string(node); val->str_value.str = node->stptr; val->str_value.len = node->stlen; + assert(val->str_value.str[val->str_value.len] == '\0'); ret = awk_true; break; @@ -468,6 +469,7 @@ node_to_awk_value(NODE *node, awk_value_t *val, awk_valtype_t wanted) val->val_type = AWK_STRING; val->str_value.str = node->stptr; val->str_value.len = node->stlen; + assert(val->str_value.str[val->str_value.len] == '\0'); ret = awk_true; } else val->val_type = AWK_UNDEFINED; -- cgit v1.2.3 From c86137f472fdf876c2c223c8d99f673f477b7554 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Fri, 8 Jul 2016 15:26:00 -0400 Subject: Optimization: support unterminated field strings inside gawk, but make terminated copies for the API. --- gawkapi.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 9 deletions(-) (limited to 'gawkapi.c') diff --git a/gawkapi.c b/gawkapi.c index afefa4f6..97825a30 100644 --- a/gawkapi.c +++ b/gawkapi.c @@ -391,6 +391,52 @@ api_awk_atexit(awk_ext_id_t id, list_head = p; } +static struct { + char **strings; + size_t i, size; +} scopy; + +void +free_api_string_copies() +{ + size_t i; + + for (i = 0; i < scopy.i; i++) + free(scopy.strings[i]); + scopy.i = 0; +} + +/* return a node string with nul termination */ + +static inline void +assign_string(NODE *node, awk_value_t *val) +{ + val->val_type = AWK_STRING; + if (node->stptr[node->stlen] != '\0') { + /* + * This is an unterminated field string, so make a copy. + * This should happen only for $n where n > 0 and n < NF. + */ + char *s; + assert((node->flags & MALLOC) == 0); + if (scopy.i == scopy.size) { + /* expand list */ + if (scopy.size == 0) + scopy.size = 8; /* initial size */ + else + scopy.size *= 2; + erealloc(scopy.strings, char **, scopy.size * sizeof(char *), "assign_string"); + } + emalloc(s, char *, node->stlen + 1, "assign_string"); + memcpy(s, node->stptr, node->stlen); + s[node->stlen] = '\0'; + val->str_value.str = scopy.strings[scopy.i++] = s; + } + else + val->str_value.str = node->stptr; + val->str_value.len = node->stlen; +} + /* node_to_awk_value --- convert a node into a value for an extension */ static awk_bool_t @@ -435,12 +481,8 @@ node_to_awk_value(NODE *node, awk_value_t *val, awk_valtype_t wanted) break; case AWK_STRING: - val->val_type = AWK_STRING; - (void) force_string(node); - val->str_value.str = node->stptr; - val->str_value.len = node->stlen; - assert(val->str_value.str[val->str_value.len] == '\0'); + assign_string(node, val); ret = awk_true; break; @@ -466,10 +508,7 @@ node_to_awk_value(NODE *node, awk_value_t *val, awk_valtype_t wanted) val->num_value = get_number_d(node); ret = awk_true; } else if ((node->flags & STRING) != 0) { - val->val_type = AWK_STRING; - val->str_value.str = node->stptr; - val->str_value.len = node->stlen; - assert(val->str_value.str[val->str_value.len] == '\0'); + assign_string(node, val); ret = awk_true; } else val->val_type = AWK_UNDEFINED; -- cgit v1.2.3 From cc04afb329cea035d0d9b67cd3b677e06b2f3996 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sat, 12 Nov 2016 19:12:13 +0200 Subject: Further code improvements and doc changes as diff until merge. --- gawkapi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'gawkapi.c') diff --git a/gawkapi.c b/gawkapi.c index 7bba07f6..958c3c16 100644 --- a/gawkapi.c +++ b/gawkapi.c @@ -396,6 +396,8 @@ static struct { size_t i, size; } scopy; +/* free_api_string_copies --- release memory used by string copies */ + void free_api_string_copies() { @@ -406,7 +408,7 @@ free_api_string_copies() scopy.i = 0; } -/* return a node string with nul termination */ +/* assign_string --- return a string node with NUL termination */ static inline void assign_string(NODE *node, awk_value_t *val) @@ -418,6 +420,7 @@ assign_string(NODE *node, awk_value_t *val) * This should happen only for $n where n > 0 and n < NF. */ char *s; + assert((node->flags & MALLOC) == 0); if (scopy.i == scopy.size) { /* expand list */ -- cgit v1.2.3