201 lines
5.2 KiB
Diff
201 lines
5.2 KiB
Diff
From nobody Mon Jul 24 10:25:07 2006
|
|
From: Aharon Robbins <arnold@skeeve.com>
|
|
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 <arnold@skeeve.com>
|
|
|
|
* 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 <arnold@skeeve.com>
|
|
|
|
* 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
|
|
|