From nobody Mon Jul 24 10:25:07 2006 From: Aharon Robbins Subject: gawk 3.1.5, patch for multibyte locales To: bug-gnu-utils@gnu.org Date: Sun, 23 Jul 2006 22:30:56 +0300 Greetings all. The problem with gawk and multibyte locales has come up enough that it's time to post a patch. This is extracted from my current code base. It is untested but should do the trick. At least now it'll be in the mailing list archives. Arnold ------------------------------- Fri Mar 10 06:28:23 2006 Arnold D. Robbins * awk.h (free_wstr): New declaration if MBS_SUPPORT, empty macro otherwise. * node.c (free_wstr): New function, inside MBS_SUPPORT. Frees the wide string part of a node. Provided so that it can be used consistently everywhere. (format_val, r_dupnode, mk_number, make_str_node, unref): Use it. * builtin.c (sub_common): Call `free_wstr' instead of doing it manually. * eval.c (r_tree_eval): Same in Node_assign_concat case. * field.c (set_field, rebuild_record, set_record): Add calls to `free_wstr'. Mon Feb 13 22:45:34 2006 Arnold D. Robbins * eval.c (r_tree_eval): Node_assign_concat. Release any wide string value and reset the WSTRCUR flag. Based on bug report by Karal Zak. diff -u ../gawk-3.1.5/awk.h ./awk.h --- ../gawk-3.1.5/awk.h 2005-07-26 21:07:43.000000000 +0300 +++ ./awk.h 2006-03-10 06:35:14.000000000 +0200 @@ -1166,6 +1166,9 @@ #define force_wstring(n) str2wstr(n, NULL) extern const wchar_t *wstrstr P((const wchar_t *haystack, size_t hs_len, const wchar_t *needle, size_t needle_len)); extern const wchar_t *wcasestrstr P((const wchar_t *haystack, size_t hs_len, const wchar_t *needle, size_t needle_len)); +extern void free_wstr P((NODE *n)); +#else +#define free_wstr(NODE) /* empty */ #endif /* re.c */ extern Regexp *make_regexp P((const char *s, size_t len, int ignorecase, int dfa)); diff -u ../gawk-3.1.5/builtin.c ./builtin.c --- ../gawk-3.1.5/builtin.c 2005-07-26 21:07:43.000000000 +0300 +++ ./builtin.c 2006-03-10 06:55:00.000000000 +0200 @@ -2462,6 +2462,7 @@ free(t->stptr); t->stptr = buf; t->stlen = textlen; + free_wstr(t); free_temp(s); if (matches > 0 && lhs) { diff -u ../gawk-3.1.5/eval.c ./eval.c --- ../gawk-3.1.5/eval.c 2005-07-26 21:07:43.000000000 +0300 +++ ./eval.c 2006-07-04 22:41:25.000000000 +0300 @@ -1176,6 +1176,7 @@ memcpy(l->stptr + l->stlen, r->stptr, r->stlen); l->stlen += r->stlen; l->stptr[l->stlen] = '\0'; + free_wstr(l); } else { char *nval; size_t nlen = l->stlen + r->stlen + 2; diff -u ../gawk-3.1.5/field.c ./field.c --- ../gawk-3.1.5/field.c 2005-05-11 18:28:15.000000000 +0300 +++ ./field.c 2006-03-10 06:48:22.000000000 +0200 @@ -129,6 +129,7 @@ n->stptr = str; n->stlen = len; n->flags = (STRCUR|STRING|MAYBE_NUM|FIELD); + free_wstr(n); } /* rebuild_record --- Someone assigned a value to $(something). @@ -210,6 +211,7 @@ } n->stptr = cops; + free_wstr(n); unref(fields_arr[i]); fields_arr[i] = n; } @@ -273,6 +275,7 @@ n->type = Node_val; n->stfmt = -1; n->flags = (STRING|STRCUR|MAYBE_NUM|FIELD); + free_wstr(n); fields_arr[0] = n; #undef INITIAL_SIZE diff -u ../gawk-3.1.5/node.c ./node.c --- ../gawk-3.1.5/node.c 2005-07-26 21:07:43.000000000 +0300 +++ ./node.c 2006-03-10 07:04:25.000000000 +0200 @@ -216,15 +218,7 @@ no_malloc: s->stref = 1; s->flags |= STRCUR; -#if defined MBS_SUPPORT - if ((s->flags & WSTRCUR) != 0) { - assert(s->wstptr != NULL); - free(s->wstptr); - s->wstptr = NULL; - s->wstlen = 0; - s->flags &= ~WSTRCUR; - } -#endif + free_wstr(s); return s; } @@ -287,7 +281,12 @@ *r = *n; r->flags &= ~(PERM|TEMP|FIELD); r->flags |= MALLOC; -#if defined MBS_SUPPORT +#ifdef MBS_SUPPORT + /* + * DON'T call free_wstr(r) here! + * r->wstptr still points at n->wstptr's value, and we + * don't want to free it! + */ r->wstptr = NULL; #endif /* defined MBS_SUPPORT */ if (n->type == Node_val && (n->flags & STRCUR) != 0) { @@ -344,11 +343,7 @@ r->stref = 1; r->stptr = NULL; r->stlen = 0; -#if defined MBS_SUPPORT - r->wstptr = NULL; - r->wstlen = 0; - r->flags &= ~WSTRCUR; -#endif /* MBS_SUPPORT */ + free_wsptr(r); #endif /* GAWKDEBUG */ return r; } @@ -363,10 +358,7 @@ getnode(r); r->type = Node_val; r->flags = (STRING|STRCUR|MALLOC); -#if defined MBS_SUPPORT - r->wstptr = NULL; - r->wstlen = 0; -#endif + free_wstr(r); if (flags & ALREADY_MALLOCED) r->stptr = s; else { @@ -510,15 +502,7 @@ return; } free(tmp->stptr); -#if defined MBS_SUPPORT - if (tmp->wstptr != NULL) { - assert((tmp->flags & WSTRCUR) != 0); - free(tmp->wstptr); - } - tmp->flags &= ~WSTRCUR; - tmp->wstptr = NULL; - tmp->wstlen = 0; -#endif + free_wstr(tmp); } freenode(tmp); return; @@ -775,6 +759,21 @@ return n; } +/* free_wstr --- release the wide string part of a node */ + +void +free_wstr(NODE *n) +{ + + if ((n->flags & WSTRCUR) != 0) { + assert(n->wstptr != NULL); + free(n->wstptr); + } + n->wstptr = NULL; + n->wstlen = 0; + n->flags &= ~WSTRCUR; +} + #if 0 static void dump_wstr(FILE *fp, const wchar_t *str, size_t len) _______________________________________________ bug-gnu-utils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-gnu-utils