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 (argc < 1) return JS_NULL;
|
||||||
if (!JS_IsText (argv[0])) return JS_NULL;
|
if (!JS_IsText (argv[0])) return JS_NULL;
|
||||||
|
|
||||||
JSGCRef str_ref;
|
JSValue str = argv[0];
|
||||||
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);
|
|
||||||
int start = 0;
|
int start = 0;
|
||||||
int end = (int)JSText_len (p);
|
int end = js_string_value_len (str);
|
||||||
|
|
||||||
if (argc > 1 && !JS_IsNull (argv[1])) {
|
if (argc > 1 && !JS_IsNull (argv[1])) {
|
||||||
/* Custom trim with reject characters */
|
/* Custom trim with reject characters */
|
||||||
const char *reject = JS_ToCString (ctx, argv[1]);
|
const char *reject = JS_ToCString (ctx, argv[1]);
|
||||||
if (!reject) {
|
if (!reject) return JS_EXCEPTION;
|
||||||
JS_PopGCRef (ctx, &str_ref);
|
|
||||||
return JS_EXCEPTION;
|
|
||||||
}
|
|
||||||
size_t reject_len = strlen (reject);
|
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) {
|
while (start < end) {
|
||||||
uint32_t c = string_get (p, start);
|
uint32_t c = js_string_value_get (str, start);
|
||||||
int found = 0;
|
int found = 0;
|
||||||
for (size_t i = 0; i < reject_len; i++) {
|
for (size_t i = 0; i < reject_len; i++) {
|
||||||
if (c == (uint8_t)reject[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++;
|
start++;
|
||||||
}
|
}
|
||||||
while (end > 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;
|
int found = 0;
|
||||||
for (size_t i = 0; i < reject_len; i++) {
|
for (size_t i = 0; i < reject_len; i++) {
|
||||||
if (c == (uint8_t)reject[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);
|
JS_FreeCString (ctx, reject);
|
||||||
} else {
|
} else {
|
||||||
/* Default: trim whitespace */
|
/* 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++;
|
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--;
|
end--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Re-chase before js_sub_string */
|
return js_sub_string_val (ctx, str, start, end);
|
||||||
p = JS_VALUE_GET_STRING (str_ref.val);
|
|
||||||
JSValue result = js_sub_string (ctx, p, start, end);
|
|
||||||
JS_PopGCRef (ctx, &str_ref);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* text.codepoint(str) - get first codepoint */
|
/* 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)
|
if (JS_SetPropertyStr (ctx, rx, "lastIndex", JS_NewInt32 (ctx, 0)) < 0)
|
||||||
goto fail_rx_search;
|
goto fail_rx_search;
|
||||||
|
|
||||||
/* Re-chase p before js_sub_string */
|
JSValue sub_str = js_sub_string_val (ctx, str, from, len);
|
||||||
JSText *p = JS_VALUE_GET_STRING (str);
|
|
||||||
JSValue sub_str = js_sub_string (ctx, p, from, len);
|
|
||||||
if (JS_IsException (sub_str)) goto fail_rx_search;
|
if (JS_IsException (sub_str)) goto fail_rx_search;
|
||||||
|
|
||||||
JSValue exec_res = JS_Invoke (ctx, rx, JS_KEY_exec, 1, (JSValue *)&sub_str);
|
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) {
|
if (from == 0 && to == len) {
|
||||||
sub_str = str;
|
sub_str = str;
|
||||||
} else {
|
} else {
|
||||||
/* Re-chase p before js_sub_string */
|
sub_str = js_sub_string_val (ctx, str, from, to);
|
||||||
JSText *p = JS_VALUE_GET_STRING (str);
|
|
||||||
sub_str = js_sub_string (ctx, p, from, to);
|
|
||||||
if (JS_IsException (sub_str)) goto fail_rx;
|
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]);
|
JSValue needle_val = JS_ToString (ctx, argv[1]);
|
||||||
if (JS_IsException (needle_val)) return JS_EXCEPTION;
|
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 */
|
/* Find needle in str[from..to) */
|
||||||
JSText *p = JS_VALUE_GET_STRING (str);
|
int pos = -1;
|
||||||
JSText *needle = JS_VALUE_GET_STRING (needle_val);
|
if (needle_len == 0) {
|
||||||
int pos = js_str_find_range (p, from, to, needle);
|
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;
|
if (pos < 0) return JS_NULL;
|
||||||
|
|
||||||
JSValue arr = JS_NewArrayLen (ctx, 1);
|
JSValue arr = JS_NewArrayLen (ctx, 1);
|
||||||
if (JS_IsException (arr)) return JS_EXCEPTION;
|
if (JS_IsException (arr)) return JS_EXCEPTION;
|
||||||
|
|
||||||
/* Re-chase p before js_sub_string */
|
JSValue match = js_sub_string_val (ctx, str, pos, pos + needle_len);
|
||||||
p = JS_VALUE_GET_STRING (str);
|
if (JS_IsException (match))
|
||||||
JSValue match = js_sub_string (ctx, p, pos, pos + needle_len);
|
|
||||||
if (JS_IsException (match)) {
|
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
}
|
|
||||||
|
|
||||||
if (JS_SetPropertyUint32 (ctx, arr, 0, match) < 0) {
|
if (JS_SetPropertyUint32 (ctx, arr, 0, match) < 0)
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
}
|
|
||||||
|
|
||||||
return arr;
|
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);
|
int is_record = JS_IsRecord (collection);
|
||||||
if (!is_array && !is_record) return JS_NULL;
|
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);
|
JSText *result = pretext_init (ctx, len);
|
||||||
if (!result) return JS_EXCEPTION;
|
if (!result) return JS_EXCEPTION;
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
while (pos < len) {
|
while (pos < len) {
|
||||||
/* Re-chase sp at the start of each loop iteration */
|
|
||||||
JSText *sp = JS_VALUE_GET_STRING (text_val);
|
|
||||||
|
|
||||||
/* Find next '{' */
|
/* Find next '{' */
|
||||||
int brace_start = -1;
|
int brace_start = -1;
|
||||||
for (int i = pos; i < len; i++) {
|
for (int i = pos; i < len; i++) {
|
||||||
if (string_get (sp, i) == '{') {
|
if (js_string_value_get (text_val, i) == '{') {
|
||||||
brace_start = i;
|
brace_start = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -22630,8 +22612,7 @@ static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc,
|
|||||||
|
|
||||||
if (brace_start < 0) {
|
if (brace_start < 0) {
|
||||||
/* No more braces, copy rest of string */
|
/* 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_val (ctx, text_val, pos, len);
|
||||||
JSValue tail = js_sub_string (ctx, sp, pos, len);
|
|
||||||
if (JS_IsException (tail)) return JS_EXCEPTION;
|
if (JS_IsException (tail)) return JS_EXCEPTION;
|
||||||
result = pretext_concat_value (ctx, result, tail);
|
result = pretext_concat_value (ctx, result, tail);
|
||||||
break;
|
break;
|
||||||
@@ -22639,20 +22620,16 @@ static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc,
|
|||||||
|
|
||||||
/* Copy text before brace */
|
/* Copy text before brace */
|
||||||
if (brace_start > pos) {
|
if (brace_start > pos) {
|
||||||
sp = JS_VALUE_GET_STRING (text_val); /* Re-chase before js_sub_string */
|
JSValue prefix = js_sub_string_val (ctx, text_val, pos, brace_start);
|
||||||
JSValue prefix = js_sub_string (ctx, sp, pos, brace_start);
|
|
||||||
if (JS_IsException (prefix)) return JS_EXCEPTION;
|
if (JS_IsException (prefix)) return JS_EXCEPTION;
|
||||||
result = pretext_concat_value (ctx, result, prefix);
|
result = pretext_concat_value (ctx, result, prefix);
|
||||||
if (!result) return JS_EXCEPTION;
|
if (!result) return JS_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Re-chase sp before searching for closing brace */
|
|
||||||
sp = JS_VALUE_GET_STRING (text_val);
|
|
||||||
|
|
||||||
/* Find closing '}' */
|
/* Find closing '}' */
|
||||||
int brace_end = -1;
|
int brace_end = -1;
|
||||||
for (int i = brace_start + 1; i < len; i++) {
|
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;
|
brace_end = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -22660,8 +22637,7 @@ static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc,
|
|||||||
|
|
||||||
if (brace_end < 0) {
|
if (brace_end < 0) {
|
||||||
/* No closing brace, copy '{' and continue */
|
/* No closing brace, copy '{' and continue */
|
||||||
sp = JS_VALUE_GET_STRING (text_val); /* Re-chase before js_sub_string */
|
JSValue ch = js_sub_string_val (ctx, text_val, brace_start, brace_start + 1);
|
||||||
JSValue ch = js_sub_string (ctx, sp, brace_start, brace_start + 1);
|
|
||||||
if (JS_IsException (ch)) return JS_EXCEPTION;
|
if (JS_IsException (ch)) return JS_EXCEPTION;
|
||||||
result = pretext_concat_value (ctx, result, ch);
|
result = pretext_concat_value (ctx, result, ch);
|
||||||
if (!result) return JS_EXCEPTION;
|
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 */
|
/* Extract content between braces */
|
||||||
sp = JS_VALUE_GET_STRING (text_val); /* Re-chase before js_sub_string */
|
JSValue middle = js_sub_string_val (ctx, text_val, brace_start + 1, brace_end);
|
||||||
JSValue middle = js_sub_string (ctx, sp, brace_start + 1, brace_end);
|
|
||||||
if (JS_IsException (middle)) return JS_EXCEPTION;
|
if (JS_IsException (middle)) return JS_EXCEPTION;
|
||||||
|
|
||||||
/* Split on ':' to get name and format_spec */
|
/* Split on ':' to get name and format_spec */
|
||||||
JSText *middle_str = JS_VALUE_GET_STRING (middle);
|
int middle_len = js_string_value_len (middle);
|
||||||
int middle_len = (int)JSText_len (middle_str);
|
|
||||||
|
|
||||||
int colon_pos = -1;
|
int colon_pos = -1;
|
||||||
for (int i = 0; i < middle_len; i++) {
|
for (int i = 0; i < middle_len; i++) {
|
||||||
if (string_get (middle_str, i) == ':') {
|
if (js_string_value_get (middle, i) == ':') {
|
||||||
colon_pos = i;
|
colon_pos = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -22688,10 +22662,8 @@ static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc,
|
|||||||
|
|
||||||
JSValue name_val, format_spec;
|
JSValue name_val, format_spec;
|
||||||
if (colon_pos >= 0) {
|
if (colon_pos >= 0) {
|
||||||
middle_str = JS_VALUE_GET_STRING (middle); /* Re-chase before js_sub_string */
|
name_val = js_sub_string_val (ctx, middle, 0, colon_pos);
|
||||||
name_val = js_sub_string (ctx, middle_str, 0, colon_pos);
|
format_spec = js_sub_string_val (ctx, middle, colon_pos + 1, middle_len);
|
||||||
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);
|
|
||||||
} else {
|
} else {
|
||||||
name_val = middle;
|
name_val = middle;
|
||||||
format_spec = JS_KEY_empty;
|
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;
|
if (!result) return JS_EXCEPTION;
|
||||||
} else {
|
} else {
|
||||||
/* No substitution, keep original {name} or {name:format} */
|
/* 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_val (ctx, text_val, brace_start, brace_end + 1);
|
||||||
JSValue orig = js_sub_string (ctx, sp, brace_start, brace_end + 1);
|
|
||||||
if (JS_IsException (orig)) return JS_EXCEPTION;
|
if (JS_IsException (orig)) return JS_EXCEPTION;
|
||||||
result = pretext_concat_value (ctx, result, orig);
|
result = pretext_concat_value (ctx, result, orig);
|
||||||
if (!result) return JS_EXCEPTION;
|
if (!result) return JS_EXCEPTION;
|
||||||
|
|||||||
Reference in New Issue
Block a user