shithub: femtolisp

Download patch

ref: acc691da05c16e097220430143ea7cab2cc3465e
parent: f001b95402211734a1a6ac053e73fb4183ee7958
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Fri Oct 25 21:42:18 EDT 2024

string.sub: make indexes point to runes, doing so with bytes is kinda useless

--- a/string.c
+++ b/string.c
@@ -184,22 +184,24 @@
 	if(nargs != 2)
 		argcount(nargs, 3);
 	char *s = tostring(args[0]);
-	size_t len = cv_len((cvalue_t*)ptr(args[0]));
-	size_t i1, i2;
-	i1 = toulong(args[1]);
-	if(i1 > len)
+	size_t lenbytes = cv_len((cvalue_t*)ptr(args[0]));
+	size_t startbytes, n, startchar = toulong(args[1]);
+	for(startbytes = n = 0; n < startchar && startbytes < lenbytes; n++)
+		startbytes += u8_seqlen(s+startbytes);
+	if(n != startchar)
 		bounds_error(args[0], args[1]);
+	size_t endbytes = lenbytes;
 	if(nargs == 3){
-		i2 = toulong(args[2]);
-		if(i2 > len)
+		size_t endchar = toulong(args[2]);
+		for(endbytes = startbytes; n < endchar && endbytes < lenbytes; n++)
+			endbytes += u8_seqlen(s+endbytes);
+		if(n != endchar)
 			bounds_error(args[0], args[2]);
-	}else{
-		i2 = len;
 	}
-	if(i2 <= i1)
-		return cvalue_string(0);
-	value_t ns = cvalue_string(i2-i1);
-	memmove(cv_data((cvalue_t*)ptr(ns)), &s[i1], i2-i1);
+	if(endbytes == startbytes)
+		return symbol_value(emptystringsym);
+	value_t ns = cvalue_string(endbytes-startbytes);
+	memmove(cv_data(ptr(ns)), s+startbytes, endbytes-startbytes);
 	return ns;
 }