ref: 76a7c66de3702ff0486900f7d4fa626407b953c3
parent: c1b99838564a31cba20b227c1f4a9ffa51d5c74e
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Mon Nov 18 20:30:17 EST 2024
read_string: use read context buffer (increase its size) to avoid allocations
--- a/read.c
+++ b/read.c
@@ -15,7 +15,7 @@
struct Rctx {
uint32_t toktype;
value_t tokval;
- char buf[256];
+ char buf[1024];
};
static value_t do_read_sexpr(Rctx *ctx, value_t label);
@@ -415,22 +415,28 @@
}
static value_t
-read_string(void)
+read_string(Rctx *ctx)
{
char *buf, *temp;
char eseq[10];
- size_t i = 0, j, sz = 64, ndig;
+ size_t i = 0, j, sz, ndig;
int c;
value_t s;
Rune r = 0;
- buf = MEM_ALLOC(sz);
+ sz = sizeof(ctx->buf);
+ buf = ctx->buf;
while(1){
if(i >= sz-UTFmax){ // -UTFmax: leaves room for longest utf8 sequence
sz *= 2;
- temp = MEM_REALLOC(buf, sz);
+ if(buf == ctx->buf){
+ if((temp = MEM_ALLOC(sz)) != nil)
+ memcpy(temp, ctx->buf, i);
+ }else
+ temp = MEM_REALLOC(buf, sz);
if(temp == nil){
- MEM_FREE(buf);
+ if(buf == ctx->buf)
+ MEM_FREE(buf);
parse_error("out of memory reading string");
}
buf = temp;
@@ -437,7 +443,8 @@
}
c = ios_getc(RS);
if(c == IOS_EOF){
- MEM_FREE(buf);
+ if(buf != ctx->buf)
+ MEM_FREE(buf);
parse_error("unexpected end of input in string");
}
if(c == '"')
@@ -445,7 +452,8 @@
else if(c == '\\'){
c = ios_getc(RS);
if(c == IOS_EOF){
- MEM_FREE(buf);
+ if(buf != ctx->buf)
+ MEM_FREE(buf);
parse_error("end of input in escape sequence");
}
j = 0;
@@ -473,7 +481,8 @@
if(j)
r = strtol(eseq, nil, 16);
if(!j || r > Runemax){
- MEM_FREE(buf);
+ if(buf != ctx->buf)
+ MEM_FREE(buf);
parse_error("invalid escape sequence");
}
if(ndig == 2)
@@ -485,7 +494,8 @@
}else{
char esc = read_escape_control_char((char)c);
if(esc == (char)c && !strchr("\\'\"`", esc)){
- MEM_FREE(buf);
+ if(buf != ctx->buf)
+ MEM_FREE(buf);
parse_error("invalid escape sequence: \\%c", (char)c);
}
buf[i++] = esc;
@@ -496,7 +506,8 @@
}
s = cvalue_string(i);
memcpy(cvalue_data(s), buf, i);
- MEM_FREE(buf);
+ if(buf != ctx->buf)
+ MEM_FREE(buf);
return s;
}
@@ -671,7 +682,7 @@
*pv = gensym();
return *pv;
case TOK_DOUBLEQUOTE:
- return read_string();
+ return read_string(ctx);
}
return FL(unspecified);
}