ref: 996c021140362c19d87dd0ab8f9e6280b0bc37e8
parent: 7c72a3b4dd1ca191c8799069306e2d94233c1a23
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Tue Dec 31 23:25:30 EST 2024
print_string: fix mixed ascii+non-ascii runes clobbered printout Fixes: https://todo.sr.ht/~ft/femtolisp/34
--- a/print.c
+++ b/print.c
@@ -506,14 +506,14 @@
static void
print_string(ios_t *f, const char *str, size_t sz)
{
- char buf[512];
- size_t i = 0;
+ char buf[64];
uint8_t c;
- static char hexdig[] = "0123456789abcdef";
+ static const char hexdig[] = "0123456789abcdef";
+ size_t i = 0;
if(!u8_isvalid(str, sz)){
// alternate print algorithm that preserves data if it's not UTF-8
- for(i = 0; i < sz; i++){
+ for(; i < sz; i++){
c = str[i];
if(c == '\\')
outsn(f, "\\\\", 2);
@@ -529,7 +529,7 @@
}
}else{
while(i < sz){
- size_t n = u8_escape(buf, sizeof(buf), str, &i, sz, 1, 0);
+ size_t n = u8_escape(buf, sizeof(buf), str, &i, sz, true, false);
outsn(f, buf, n-1);
}
}
@@ -759,11 +759,12 @@
}
return;
}else if(eltype == FL_runesym){
- char buf[UTFmax];
+ char buf[UTFmax+1];
if(!FL(print_princ))
outc(f, '"');
for(i = 0; i < cnt; i++, data = (char*)data + elsize){
int n = runetochar(buf, (Rune*)data);
+ buf[n] = 0;
if(FL(print_princ))
ios_write(f, buf, n);
else
--- a/utf8.c
+++ b/utf8.c
@@ -16,8 +16,8 @@
#include "flisp.h"
static const uint32_t offsetsFromUTF8[6] = {
- 0x00000000UL, 0x00003080UL, 0x000E2080UL,
- 0x03C82080UL, 0xFA082080UL, 0x82082080UL
+ 0x00000000U, 0x00003080U, 0x000E2080U,
+ 0x03C82080U, 0xFA082080U, 0x82082080U
};
static const char trailingBytesForUTF8[256] = {
@@ -46,7 +46,7 @@
size_t
u8_seqlen(const char *s)
{
- return trailingBytesForUTF8[(unsigned int)(uint8_t)s[0]] + 1;
+ return trailingBytesForUTF8[(uint8_t)s[0]] + 1;
}
/* byte offset => charnum */
@@ -80,14 +80,12 @@
Rune
u8_nextmemchar(const char *s, size_t *i)
{
+ size_t sz = u8_seqlen(&s[*i]);
Rune ch = 0;
- size_t sz = 0;
-
- do{
+ for(size_t j = 0; j < sz; j++){
ch <<= 6;
ch += (uint8_t)s[(*i)++];
- sz++;
- }while(!isutf(s[*i]));
+ };
return ch - offsetsFromUTF8[sz-1];
}
@@ -94,7 +92,7 @@
int
octal_digit(char c)
{
- return (c >= '0' && c <= '7');
+ return c >= '0' && c <= '7';
}
int
@@ -156,7 +154,7 @@
}
size_t
-u8_escape(char *buf, size_t sz, const char *src, size_t *pi, size_t end, int escape_quotes, int ascii)
+u8_escape(char *buf, size_t sz, const char *src, size_t *pi, size_t end, bool escape_quotes, bool ascii)
{
size_t i = *pi, i0;
Rune ch;
@@ -187,7 +185,7 @@
}
*buf++ = '\0';
*pi = i;
- return (buf-start);
+ return buf - start;
}
char *
--- a/utf8.h
+++ b/utf8.h
@@ -37,7 +37,7 @@
returns number of bytes placed in buf, including a NUL terminator.
*/
size_t u8_escape(char *buf, size_t sz, const char *src, size_t *pi, size_t end,
- int escape_quotes, int ascii);
+ bool escape_quotes, bool ascii);
/* utility predicates used by the above */
int octal_digit(char c);