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

Herbert Xu
2024-05-05T09:15:30Z

Add support for multi-byte characters in read(1) by using getmbc
from the parser.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---
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 71d61f3..d368adc 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