Репозитории ALT
S: | 5.1.0.0.213.d04f-alt1 |
5.1: | 3.1.6-alt3 |
4.1: | 3.1.5-alt3 |
4.0: | 3.1.5-alt3 |
3.0: | 3.1.4-alt2 |
Группа :: Работа с текстами
Пакет: gawk
Главная Изменения Спек Патчи Sources Загрузить Gear Bugs and FR Repocop
Патч: gawk-3.1.4-rh-uplow.patch
Скачать
Скачать
--- gawk-3.1.4/builtin.c.uplow 2004-11-09 15:53:03.357118488 +0100
+++ gawk-3.1.4/builtin.c 2004-11-09 15:55:25.455516248 +0100
@@ -1652,51 +1652,116 @@
fflush(rp->fp);
}
+/* wide_tolower_toupper --- lower- or uppercase a multibute string */
+
+typedef int (*isw_func)(wint_t);
+typedef wint_t (*tow_func)(wint_t);
+
+static NODE *
+wide_tolower_toupper(NODE *t1, isw_func iswu, tow_func towl)
+{
+#ifdef MBS_SUPPORT
+ register unsigned char *cp, *cpe;
+ register unsigned char *cp2;
+ size_t mbclen;
+ mbstate_t mbs, prev_mbs;
+ wchar_t wc;
+ NODE *t2;
+ /*
+ * Since the lowercase char and its uppercase equivalent may occupy
+ * different number of bytes (Turkish `i'), we cannot say the length
+ * of the output string.
+ * This approach is adapted from format_tree().
+ */
+ unsigned char *obuf;
+ size_t osiz, ofre;
+
+ /*
+ * Better 2 spare bytes than 1, consistently with make_str_node().
+ * And we need gawk_mb_cur_max free bytes before we convert the last
+ * char, so we add (gawk_mb_cur_max - 1).
+ */
+ osiz = t1->stlen + 2 + (gawk_mb_cur_max - 1);
+ ofre = osiz - 2;
+ emalloc(obuf, char *, osiz, "wide_tolower_toupper");
+
+ memset(&mbs, 0, sizeof(mbstate_t));
+ cp = (unsigned char *)t1->stptr;
+ cpe = (unsigned char *)(t1->stptr + t1->stlen);
+ cp2 = obuf;
+ while (cp < cpe) {
+ if (ofre < gawk_mb_cur_max) {
+ size_t olen = cp2 - obuf;
+ ofre += osiz;
+ osiz *= 2;
+ erealloc(obuf, char *, osiz, "wide_tolower_toupper");
+ cp2 = obuf + olen;
+ }
+ prev_mbs = mbs;
+ mbclen = (size_t) mbrtowc(&wc, (char *) cp, cpe - cp,
+ &mbs);
+ if (mbclen == 0 || mbclen == (size_t) -1 || mbclen == (size_t) -2) {
+ /* Null wide char, or a problem appeared. */
+ *cp2++ = *cp++;
+ ofre--;
+ continue;
+ }
+
+ /* If the character doesn't need change, copy it. */
+ if (!(*iswu)(wc)) {
+ ofre -= mbclen;
+ while (mbclen--)
+ *cp2++ = *cp++;
+ continue;
+ }
+
+ /* Increment the input pointer. */
+ cp += mbclen;
+
+ /* Write the modified wide character. */
+ mbclen = wcrtomb((char *) cp2, (*towl)(wc), &prev_mbs);
+
+ if (mbclen > 0 && mbclen < (size_t) -2) {
+ /* Increment the output pointer. */
+ cp2 += mbclen;
+ ofre -= mbclen;
+ } else {
+ /* A problem appeared. */
+ cp2++;
+ ofre--;
+ }
+ }
+ t2 = make_str_node(obuf, cp2 - obuf, ALREADY_MALLOCED);
+ t2->flags |= TEMP;
+ return t2;
+#else
+ cant_happen();
+ return NULL;
+#endif
+}
+
/* do_tolower --- lower case a string */
NODE *
do_tolower(NODE *tree)
{
NODE *t1, *t2;
- register unsigned char *cp, *cp2;
-#ifdef MBS_SUPPORT
- size_t mbclen = 0;
- mbstate_t mbs, prev_mbs;
- if (gawk_mb_cur_max > 1)
- memset(&mbs, 0, sizeof(mbstate_t));
-#endif
t1 = tree_eval(tree->lnode);
if (do_lint && (t1->flags & (STRING|STRCUR)) == 0)
lintwarn(_("tolower: received non-string argument"));
t1 = force_string(t1);
- t2 = tmp_string(t1->stptr, t1->stlen);
- for (cp = (unsigned char *)t2->stptr,
- cp2 = (unsigned char *)(t2->stptr + t2->stlen); cp < cp2; cp++)
-#ifdef MBS_SUPPORT
- if (gawk_mb_cur_max > 1) {
- wchar_t wc;
- prev_mbs = mbs;
- mbclen = (size_t) mbrtowc(&wc, (char *) cp, cp2 - cp,
- &mbs);
- if ((mbclen != 1) && (mbclen != (size_t) -1) &&
- (mbclen != (size_t) -2) && (mbclen != 0)) {
- /* a multibyte character. */
- if (iswupper(wc)) {
- wc = towlower(wc);
- wcrtomb((char *) cp, wc, &prev_mbs);
- }
- /* Adjust the pointer. */
- cp += mbclen - 1;
- } else {
- /* Otherwise we treat it as a singlebyte character. */
- if (ISUPPER(*cp))
- *cp = tolower(*cp);
- }
- } else
-#endif
- if (ISUPPER(*cp))
- *cp = TOLOWER(*cp);
+
+ if (gawk_mb_cur_max > 1)
+ t2 = wide_tolower_toupper(t1, &iswupper, &towlower);
+ else {
+ register unsigned char *cp, *cpe;
+ t2 = tmp_string(t1->stptr, t1->stlen);
+ for (cp = (unsigned char *)t2->stptr,
+ cpe = (unsigned char *)(t2->stptr + t2->stlen); cp < cpe; cp++)
+ if (ISUPPER(*cp))
+ *cp = TOLOWER(*cp);
+ }
free_temp(t1);
return t2;
}
@@ -1707,45 +1772,22 @@
do_toupper(NODE *tree)
{
NODE *t1, *t2;
- register unsigned char *cp, *cp2;
-#ifdef MBS_SUPPORT
- size_t mbclen = 0;
- mbstate_t mbs, prev_mbs;
- if (gawk_mb_cur_max > 1)
- memset(&mbs, 0, sizeof(mbstate_t));
-#endif
t1 = tree_eval(tree->lnode);
if (do_lint && (t1->flags & (STRING|STRCUR)) == 0)
lintwarn(_("toupper: received non-string argument"));
t1 = force_string(t1);
- t2 = tmp_string(t1->stptr, t1->stlen);
- for (cp = (unsigned char *)t2->stptr,
- cp2 = (unsigned char *)(t2->stptr + t2->stlen); cp < cp2; cp++)
-#ifdef MBS_SUPPORT
- if (gawk_mb_cur_max > 1) {
- wchar_t wc;
- prev_mbs = mbs;
- mbclen = (size_t) mbrtowc(&wc, (char *) cp, cp2 - cp,
- &mbs);
- if ((mbclen != 1) && (mbclen != (size_t) -1) &&
- (mbclen != (size_t) -2) && (mbclen != 0)) {
- /* a multibyte character. */
- if (iswlower(wc)) {
- wc = towupper(wc);
- wcrtomb((char *) cp, wc, &prev_mbs);
- }
- /* Adjust the pointer. */
- cp += mbclen - 1;
- } else {
- /* Otherwise we treat it as a singlebyte character. */
- if (ISLOWER(*cp))
- *cp = toupper(*cp);
- }
- } else
-#endif
- if (ISLOWER(*cp))
- *cp = TOUPPER(*cp);
+
+ if (gawk_mb_cur_max > 1)
+ t2 = wide_tolower_toupper(t1, &iswlower, &towupper);
+ else {
+ register unsigned char *cp, *cpe;
+ t2 = tmp_string(t1->stptr, t1->stlen);
+ for (cp = (unsigned char *)t2->stptr,
+ cpe = (unsigned char *)(t2->stptr + t2->stlen); cp < cpe; cp++)
+ if (ISLOWER(*cp))
+ *cp = TOUPPER(*cp);
+ }
free_temp(t1);
return t2;
}