Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37044828
en ru br
Репозитории 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
www.altlinux.org/Changes

Группа :: Работа с текстами
Пакет: 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;
 }
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin