[v5 PATCH 13/13] builtin: Process multi-byte characters in read(1)

Herbert Xu <[email protected]>
Newsgroups org.kernel.vger.dash
Message-ID <73254ee7731cd2f0b5877159920dcf159beba1b3.1717291579.git.herbert@gondor.apana.org.au>
Add support for multi-byte characters in read(1) by using getmbc
from the parser.

Signed-off-by: Herbert Xu <[email protected]>
---
 src/miscbltin.c | 19 +++++++++++++------
 src/parser.c    |  2 +-
 src/parser.h    |  1 +
 3 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/src/miscbltin.c b/src/miscbltin.c
index 10d256e..5aa2b24 100644
--- a/src/miscbltin.c
+++ b/src/miscbltin.c
@@ -36,15 +36,16 @@
  * Miscelaneous builtins.
  */
 
+#include <ctype.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdlib.h>
 #include <sys/types.h>		/* quad_t */
 #include <sys/param.h>		/* BSD4_4 */
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <unistd.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <inttypes.h>
 
 #include "error.h"
 #include "expand.h"
@@ -151,8 +152,10 @@ readcmd(int argc, char **argv)
 	goto start;
 
 	for (;;) {
+		unsigned ml;
 		int c;
 
+		CHECKSTRSPACE((MB_LEN_MAX > 16 ? MB_LEN_MAX : 16) + 4, p);
 		c = pgetc();
 		if (c == PEOF) {
 			status = 1;
@@ -160,9 +163,14 @@ readcmd(int argc, char **argv)
 		}
 		if (c == '\0')
 			continue;
+		ml = getmbc(c, p, 0);
+		if (ml) {
+			p += ml;
+			goto record;
+		}
 		if (newloc >= startloc) {
 			if (c == '\n')
-				goto resetbs;
+				goto record;
 			goto put;
 		}
 		if (!rflag && c == '\\') {
@@ -172,13 +180,12 @@ readcmd(int argc, char **argv)
 		if (c == '\n')
 			break;
 put:
-		CHECKSTRSPACE(2, p);
 		if (strchr(qchars, c))
 			USTPUTC(CTLESC, p);
 		USTPUTC(c, p);
 
+record:
 		if (newloc >= startloc) {
-resetbs:
 			recordregion(startloc, newloc, 0);
 start:
 			startloc = p - (char *)stackblock();
diff --git a/src/parser.c b/src/parser.c
index 1a2f5df..a4d3291 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -883,7 +883,7 @@ static void synstack_pop(struct synstack **stack)
 	*stack = (*stack)->next;
 }
 
-static unsigned getmbc(int c, char *out, int mode)
+unsigned getmbc(int c, char *out, int mode)
 {
 	char *const start = out;
 	mbstate_t mbst = {};
diff --git a/src/parser.h b/src/parser.h
index 14bfc4f..7a9605b 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -95,6 +95,7 @@ const char *getprompt(void *);
 const char *const *findkwd(const char *);
 char *endofname(const char *);
 const char *expandstr(const char *);
+unsigned getmbc(int c, char *out, int mode);
 
 static inline int
 goodname(const char *p)
-- 
2.39.2
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.