fix text header chasing
This commit is contained in:
111
source/quickjs.c
111
source/quickjs.c
@@ -21907,32 +21907,18 @@ static JSValue js_cell_text_trim (JSContext *ctx, JSValue this_val, int argc, JS
|
||||
if (argc < 1) return JS_NULL;
|
||||
if (!JS_IsText (argv[0])) return JS_NULL;
|
||||
|
||||
JSGCRef str_ref;
|
||||
JS_PushGCRef (ctx, &str_ref);
|
||||
str_ref.val = JS_ToString (ctx, argv[0]);
|
||||
if (JS_IsException (str_ref.val)) {
|
||||
JS_PopGCRef (ctx, &str_ref);
|
||||
return str_ref.val;
|
||||
}
|
||||
|
||||
JSText *p = JS_VALUE_GET_STRING (str_ref.val);
|
||||
JSValue str = argv[0];
|
||||
int start = 0;
|
||||
int end = (int)JSText_len (p);
|
||||
int end = js_string_value_len (str);
|
||||
|
||||
if (argc > 1 && !JS_IsNull (argv[1])) {
|
||||
/* Custom trim with reject characters */
|
||||
const char *reject = JS_ToCString (ctx, argv[1]);
|
||||
if (!reject) {
|
||||
JS_PopGCRef (ctx, &str_ref);
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
if (!reject) return JS_EXCEPTION;
|
||||
size_t reject_len = strlen (reject);
|
||||
|
||||
/* Re-chase p after JS_ToCString which can trigger GC */
|
||||
p = JS_VALUE_GET_STRING (str_ref.val);
|
||||
|
||||
while (start < end) {
|
||||
uint32_t c = string_get (p, start);
|
||||
uint32_t c = js_string_value_get (str, start);
|
||||
int found = 0;
|
||||
for (size_t i = 0; i < reject_len; i++) {
|
||||
if (c == (uint8_t)reject[i]) {
|
||||
@@ -21944,7 +21930,7 @@ static JSValue js_cell_text_trim (JSContext *ctx, JSValue this_val, int argc, JS
|
||||
start++;
|
||||
}
|
||||
while (end > start) {
|
||||
uint32_t c = string_get (p, end - 1);
|
||||
uint32_t c = js_string_value_get (str, end - 1);
|
||||
int found = 0;
|
||||
for (size_t i = 0; i < reject_len; i++) {
|
||||
if (c == (uint8_t)reject[i]) {
|
||||
@@ -21958,17 +21944,13 @@ static JSValue js_cell_text_trim (JSContext *ctx, JSValue this_val, int argc, JS
|
||||
JS_FreeCString (ctx, reject);
|
||||
} else {
|
||||
/* Default: trim whitespace */
|
||||
while (start < end && lre_is_space (string_get (p, start)))
|
||||
while (start < end && lre_is_space (js_string_value_get (str, start)))
|
||||
start++;
|
||||
while (end > start && lre_is_space (string_get (p, end - 1)))
|
||||
while (end > start && lre_is_space (js_string_value_get (str, end - 1)))
|
||||
end--;
|
||||
}
|
||||
|
||||
/* Re-chase before js_sub_string */
|
||||
p = JS_VALUE_GET_STRING (str_ref.val);
|
||||
JSValue result = js_sub_string (ctx, p, start, end);
|
||||
JS_PopGCRef (ctx, &str_ref);
|
||||
return result;
|
||||
return js_sub_string_val (ctx, str, start, end);
|
||||
}
|
||||
|
||||
/* text.codepoint(str) - get first codepoint */
|
||||
@@ -22386,9 +22368,7 @@ static JSValue js_cell_text_search (JSContext *ctx, JSValue this_val, int argc,
|
||||
if (JS_SetPropertyStr (ctx, rx, "lastIndex", JS_NewInt32 (ctx, 0)) < 0)
|
||||
goto fail_rx_search;
|
||||
|
||||
/* Re-chase p before js_sub_string */
|
||||
JSText *p = JS_VALUE_GET_STRING (str);
|
||||
JSValue sub_str = js_sub_string (ctx, p, from, len);
|
||||
JSValue sub_str = js_sub_string_val (ctx, str, from, len);
|
||||
if (JS_IsException (sub_str)) goto fail_rx_search;
|
||||
|
||||
JSValue exec_res = JS_Invoke (ctx, rx, JS_KEY_exec, 1, (JSValue *)&sub_str);
|
||||
@@ -22499,9 +22479,7 @@ static JSValue js_cell_text_extract (JSContext *ctx, JSValue this_val, int argc,
|
||||
if (from == 0 && to == len) {
|
||||
sub_str = str;
|
||||
} else {
|
||||
/* Re-chase p before js_sub_string */
|
||||
JSText *p = JS_VALUE_GET_STRING (str);
|
||||
sub_str = js_sub_string (ctx, p, from, to);
|
||||
sub_str = js_sub_string_val (ctx, str, from, to);
|
||||
if (JS_IsException (sub_str)) goto fail_rx;
|
||||
}
|
||||
|
||||
@@ -22566,28 +22544,35 @@ static JSValue js_cell_text_extract (JSContext *ctx, JSValue this_val, int argc,
|
||||
JSValue needle_val = JS_ToString (ctx, argv[1]);
|
||||
if (JS_IsException (needle_val)) return JS_EXCEPTION;
|
||||
|
||||
int needle_len = (int)JSText_len (JS_VALUE_GET_STRING (needle_val));
|
||||
int needle_len = js_string_value_len (needle_val);
|
||||
|
||||
/* Re-chase both p and needle right before js_str_find_range */
|
||||
JSText *p = JS_VALUE_GET_STRING (str);
|
||||
JSText *needle = JS_VALUE_GET_STRING (needle_val);
|
||||
int pos = js_str_find_range (p, from, to, needle);
|
||||
/* Find needle in str[from..to) */
|
||||
int pos = -1;
|
||||
if (needle_len == 0) {
|
||||
pos = from;
|
||||
} else if (needle_len <= (to - from)) {
|
||||
int limit = to - needle_len;
|
||||
for (int i = from; i <= limit; i++) {
|
||||
int j = 0;
|
||||
for (; j < needle_len; j++) {
|
||||
if (js_string_value_get (str, i + j) != js_string_value_get (needle_val, j))
|
||||
break;
|
||||
}
|
||||
if (j == needle_len) { pos = i; break; }
|
||||
}
|
||||
}
|
||||
|
||||
if (pos < 0) return JS_NULL;
|
||||
|
||||
JSValue arr = JS_NewArrayLen (ctx, 1);
|
||||
if (JS_IsException (arr)) return JS_EXCEPTION;
|
||||
|
||||
/* Re-chase p before js_sub_string */
|
||||
p = JS_VALUE_GET_STRING (str);
|
||||
JSValue match = js_sub_string (ctx, p, pos, pos + needle_len);
|
||||
if (JS_IsException (match)) {
|
||||
JSValue match = js_sub_string_val (ctx, str, pos, pos + needle_len);
|
||||
if (JS_IsException (match))
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
if (JS_SetPropertyUint32 (ctx, arr, 0, match) < 0) {
|
||||
if (JS_SetPropertyUint32 (ctx, arr, 0, match) < 0)
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
@@ -22609,20 +22594,17 @@ static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc,
|
||||
int is_record = JS_IsRecord (collection);
|
||||
if (!is_array && !is_record) return JS_NULL;
|
||||
|
||||
int len = (int)JSText_len (JS_VALUE_GET_STRING (text_val));
|
||||
int len = js_string_value_len (text_val);
|
||||
|
||||
JSText *result = pretext_init (ctx, len);
|
||||
if (!result) return JS_EXCEPTION;
|
||||
|
||||
int pos = 0;
|
||||
while (pos < len) {
|
||||
/* Re-chase sp at the start of each loop iteration */
|
||||
JSText *sp = JS_VALUE_GET_STRING (text_val);
|
||||
|
||||
/* Find next '{' */
|
||||
int brace_start = -1;
|
||||
for (int i = pos; i < len; i++) {
|
||||
if (string_get (sp, i) == '{') {
|
||||
if (js_string_value_get (text_val, i) == '{') {
|
||||
brace_start = i;
|
||||
break;
|
||||
}
|
||||
@@ -22630,8 +22612,7 @@ static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc,
|
||||
|
||||
if (brace_start < 0) {
|
||||
/* No more braces, copy rest of string */
|
||||
sp = JS_VALUE_GET_STRING (text_val); /* Re-chase before js_sub_string */
|
||||
JSValue tail = js_sub_string (ctx, sp, pos, len);
|
||||
JSValue tail = js_sub_string_val (ctx, text_val, pos, len);
|
||||
if (JS_IsException (tail)) return JS_EXCEPTION;
|
||||
result = pretext_concat_value (ctx, result, tail);
|
||||
break;
|
||||
@@ -22639,20 +22620,16 @@ static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc,
|
||||
|
||||
/* Copy text before brace */
|
||||
if (brace_start > pos) {
|
||||
sp = JS_VALUE_GET_STRING (text_val); /* Re-chase before js_sub_string */
|
||||
JSValue prefix = js_sub_string (ctx, sp, pos, brace_start);
|
||||
JSValue prefix = js_sub_string_val (ctx, text_val, pos, brace_start);
|
||||
if (JS_IsException (prefix)) return JS_EXCEPTION;
|
||||
result = pretext_concat_value (ctx, result, prefix);
|
||||
if (!result) return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
/* Re-chase sp before searching for closing brace */
|
||||
sp = JS_VALUE_GET_STRING (text_val);
|
||||
|
||||
/* Find closing '}' */
|
||||
int brace_end = -1;
|
||||
for (int i = brace_start + 1; i < len; i++) {
|
||||
if (string_get (sp, i) == '}') {
|
||||
if (js_string_value_get (text_val, i) == '}') {
|
||||
brace_end = i;
|
||||
break;
|
||||
}
|
||||
@@ -22660,8 +22637,7 @@ static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc,
|
||||
|
||||
if (brace_end < 0) {
|
||||
/* No closing brace, copy '{' and continue */
|
||||
sp = JS_VALUE_GET_STRING (text_val); /* Re-chase before js_sub_string */
|
||||
JSValue ch = js_sub_string (ctx, sp, brace_start, brace_start + 1);
|
||||
JSValue ch = js_sub_string_val (ctx, text_val, brace_start, brace_start + 1);
|
||||
if (JS_IsException (ch)) return JS_EXCEPTION;
|
||||
result = pretext_concat_value (ctx, result, ch);
|
||||
if (!result) return JS_EXCEPTION;
|
||||
@@ -22670,17 +22646,15 @@ static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc,
|
||||
}
|
||||
|
||||
/* Extract content between braces */
|
||||
sp = JS_VALUE_GET_STRING (text_val); /* Re-chase before js_sub_string */
|
||||
JSValue middle = js_sub_string (ctx, sp, brace_start + 1, brace_end);
|
||||
JSValue middle = js_sub_string_val (ctx, text_val, brace_start + 1, brace_end);
|
||||
if (JS_IsException (middle)) return JS_EXCEPTION;
|
||||
|
||||
/* Split on ':' to get name and format_spec */
|
||||
JSText *middle_str = JS_VALUE_GET_STRING (middle);
|
||||
int middle_len = (int)JSText_len (middle_str);
|
||||
int middle_len = js_string_value_len (middle);
|
||||
|
||||
int colon_pos = -1;
|
||||
for (int i = 0; i < middle_len; i++) {
|
||||
if (string_get (middle_str, i) == ':') {
|
||||
if (js_string_value_get (middle, i) == ':') {
|
||||
colon_pos = i;
|
||||
break;
|
||||
}
|
||||
@@ -22688,10 +22662,8 @@ static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc,
|
||||
|
||||
JSValue name_val, format_spec;
|
||||
if (colon_pos >= 0) {
|
||||
middle_str = JS_VALUE_GET_STRING (middle); /* Re-chase before js_sub_string */
|
||||
name_val = js_sub_string (ctx, middle_str, 0, colon_pos);
|
||||
middle_str = JS_VALUE_GET_STRING (middle); /* Re-chase before js_sub_string */
|
||||
format_spec = js_sub_string (ctx, middle_str, colon_pos + 1, middle_len);
|
||||
name_val = js_sub_string_val (ctx, middle, 0, colon_pos);
|
||||
format_spec = js_sub_string_val (ctx, middle, colon_pos + 1, middle_len);
|
||||
} else {
|
||||
name_val = middle;
|
||||
format_spec = JS_KEY_empty;
|
||||
@@ -22763,8 +22735,7 @@ static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc,
|
||||
if (!result) return JS_EXCEPTION;
|
||||
} else {
|
||||
/* No substitution, keep original {name} or {name:format} */
|
||||
sp = JS_VALUE_GET_STRING (text_val); /* Re-chase before js_sub_string */
|
||||
JSValue orig = js_sub_string (ctx, sp, brace_start, brace_end + 1);
|
||||
JSValue orig = js_sub_string_val (ctx, text_val, brace_start, brace_end + 1);
|
||||
if (JS_IsException (orig)) return JS_EXCEPTION;
|
||||
result = pretext_concat_value (ctx, result, orig);
|
||||
if (!result) return JS_EXCEPTION;
|
||||
|
||||
Reference in New Issue
Block a user