rm index and indexof

This commit is contained in:
2026-01-17 16:21:02 -06:00
parent 97ece8e5cb
commit a7a323a74e
19 changed files with 86 additions and 303 deletions

View File

@@ -595,7 +595,7 @@ Total benchmarks: ${total_benches}
} }
} }
var json_path = `${report_dir}/${pkg_res.package.replace(/\//g, '_')}.json` var json_path = `${report_dir}/${replace(pkg_res.package, /\//, '_')}.json`
fd.slurpwrite(json_path, stone(blob(json.encode(pkg_benches)))) fd.slurpwrite(json_path, stone(blob(json.encode(pkg_benches))))
} }
} }

View File

@@ -17,30 +17,7 @@ var writepath = "."
function normalize_path(path) { function normalize_path(path) {
if (!path) return "" if (!path) return ""
// Remove leading/trailing slashes and normalize // Remove leading/trailing slashes and normalize
return path.replace(/^\/+|\/+$/g, "") return replace(path, /^\/+|\/+$/, "")
}
// Helper to get directory from path
function dirname(path) {
var idx = path.lastIndexOf("/")
if (idx == -1) return ""
return text(path, 0, idx)
}
// Helper to get basename from path
function basename(path) {
var idx = path.lastIndexOf("/")
if (idx == -1) return path
return text(path, idx + 1)
}
// Helper to join paths
function join_paths(base, rel) {
base = base.replace(/\/+$/, "")
rel = rel.replace(/^\/+/, "")
if (!base) return rel
if (!rel) return base
return base + "/" + rel
} }
// Check if a file exists in a specific mount // Check if a file exists in a specific mount
@@ -59,7 +36,7 @@ function mount_exists(mount, path) {
return false return false
} }
} else { // fs } else { // fs
var full_path = join_paths(mount.source, path) var full_path = fd.join_paths(mount.source, path)
try { try {
var st = fd.stat(full_path) var st = fd.stat(full_path)
return st.isFile || st.isDirectory return st.isFile || st.isDirectory
@@ -86,7 +63,7 @@ function is_directory(path) {
return false; return false;
} }
} else { // fs } else { // fs
var full_path = join_paths(mount.source, path) var full_path = fd.join_paths(mount.source, path)
try { try {
var st = fd.stat(full_path) var st = fd.stat(full_path)
return st.isDirectory return st.isDirectory
@@ -103,11 +80,11 @@ function resolve(path, must_exist) {
// Check for named mount // Check for named mount
if (starts_with(path, "@")) { if (starts_with(path, "@")) {
var idx = path.indexOf("/") var idx = search(path, "/")
var mount_name = "" var mount_name = ""
var rel_path = "" var rel_path = ""
if (idx == -1) { if (idx == null) {
mount_name = text(path, 1) mount_name = text(path, 1)
rel_path = "" rel_path = ""
} else { } else {
@@ -212,7 +189,7 @@ function slurp(path) {
if (!data) throw Error("File not found in qop: " + path) if (!data) throw Error("File not found in qop: " + path)
return data return data
} else { } else {
var full_path = join_paths(res.mount.source, res.path) var full_path = fd.join_paths(res.mount.source, res.path)
return fd.slurp(full_path) return fd.slurp(full_path)
} }
} }
@@ -256,7 +233,7 @@ function stat(path) {
isDirectory: s.isDirectory isDirectory: s.isDirectory
} }
} else { } else {
var full_path = join_paths(res.mount.source, res.path) var full_path = fd.join_paths(res.mount.source, res.path)
var s = fd.stat(full_path) var s = fd.stat(full_path)
return { return {
filesize: s.size, filesize: s.size,
@@ -298,14 +275,14 @@ function rm(path) {
var res = resolve(path, true) var res = resolve(path, true)
if (res.mount.type != 'fs') throw Error("Cannot delete from non-fs mount") if (res.mount.type != 'fs') throw Error("Cannot delete from non-fs mount")
var full_path = join_paths(res.mount.source, res.path) var full_path = fd.join_paths(res.mount.source, res.path)
var st = fd.stat(full_path) var st = fd.stat(full_path)
if (st.isDirectory) fd.rmdir(full_path) if (st.isDirectory) fd.rmdir(full_path)
else fd.unlink(full_path) else fd.unlink(full_path)
} }
function mkdir(path) { function mkdir(path) {
var full = join_paths(writepath, path) var full = fd.join_paths(writepath, path)
fd.mkdir(full) fd.mkdir(full)
} }
@@ -324,7 +301,7 @@ function prefdir(org, app) {
function realdir(path) { function realdir(path) {
var res = resolve(path, false) var res = resolve(path, false)
if (!res) return null if (!res) return null
return join_paths(res.mount.source, res.path) return fd.join_paths(res.mount.source, res.path)
} }
function enumerate(path, recurse) { function enumerate(path, recurse) {
@@ -342,16 +319,16 @@ function enumerate(path, recurse) {
results.push(item_rel) results.push(item_rel)
if (recurse) { if (recurse) {
var st = fd.stat(join_paths(curr_full, item)) var st = fd.stat(fd.join_paths(curr_full, item))
if (st.isDirectory) { if (st.isDirectory) {
visit(join_paths(curr_full, item), item_rel) visit(fd.join_paths(curr_full, item), item_rel)
} }
} }
} }
} }
if (res.mount.type == 'fs') { if (res.mount.type == 'fs') {
var full = join_paths(res.mount.source, res.path) var full = fd.join_paths(res.mount.source, res.path)
var st = fd.stat(full) var st = fd.stat(full)
if (st && st.isDirectory) { if (st && st.isDirectory) {
visit(full, "") visit(full, "")
@@ -370,8 +347,8 @@ function enumerate(path, recurse) {
if (rel.length == 0) continue if (rel.length == 0) continue
if (!recurse) { if (!recurse) {
var slash = rel.indexOf('/') var slash = search(rel, '/')
if (slash != -1) { if (slash != null) {
rel = text(rel, 0, slash) rel = text(rel, 0, slash)
} }
} }
@@ -415,7 +392,7 @@ function globfs(globs, dir) {
for (var item of list) { for (var item of list) {
var item_rel = rel_prefix ? rel_prefix + "/" + item : item var item_rel = rel_prefix ? rel_prefix + "/" + item : item
var child_full = join_paths(curr_full, item) var child_full = fd.join_paths(curr_full, item)
var st = fd.stat(child_full) var st = fd.stat(child_full)
if (st.isDirectory) { if (st.isDirectory) {
@@ -431,7 +408,7 @@ function globfs(globs, dir) {
} }
if (res.mount.type == 'fs') { if (res.mount.type == 'fs') {
var full = join_paths(res.mount.source, res.path) var full = fd.join_paths(res.mount.source, res.path)
var st = fd.stat(full) var st = fd.stat(full)
if (st && st.isDirectory) { if (st && st.isDirectory) {
visit(full, "") visit(full, "")

View File

@@ -111,7 +111,7 @@ if (is_shop_scope) {
// Gather files to clean // Gather files to clean
var lib_dir = shop.get_lib_dir() var lib_dir = shop.get_lib_dir()
var build_dir = shop.get_build_dir() var build_dir = shop.get_build_dir()
var packages_dir = shop.get_package_dir('').replace(/\/$/, '') // Get base packages dir var packages_dir = replace(shop.get_package_dir(''), /\/$/, '') // Get base packages dir
if (clean_build) { if (clean_build) {
if (is_shop_scope) { if (is_shop_scope) {

View File

@@ -31,7 +31,7 @@ if (target_path == '.' || starts_with(target_path, './') || starts_with(target_p
target_path = cwd + text(target_path, 1) target_path = cwd + text(target_path, 1)
} else if (starts_with(target_path, '../')) { } else if (starts_with(target_path, '../')) {
// Go up one directory from cwd // Go up one directory from cwd
var parent = text(cwd, 0, cwd.lastIndexOf('/')) var parent = fd.dirname(cwd)
target_path = parent + text(target_path, 2) target_path = parent + text(target_path, 2)
} }
} }
@@ -99,7 +99,7 @@ try {
parts.shift() parts.shift()
var rel_path = text(parts, '/') var rel_path = text(parts, '/')
var full_path = target_path + '/' + rel_path var full_path = target_path + '/' + rel_path
var dir_path = text(full_path, 0, full_path.lastIndexOf('/')) var dir_path = fd.dirname(full_path)
// Ensure directory exists // Ensure directory exists
if (!fd.is_dir(dir_path)) { if (!fd.is_dir(dir_path)) {

View File

@@ -64,7 +64,7 @@ function parse_value(str) {
if (str == 'false') return false if (str == 'false') return false
// Number (including underscores) // Number (including underscores)
var num_str = str.replace(/_/g, '') var num_str = replace(str, /_/g, '')
if (/^-?\d+$/.test(num_str)) return parseInt(num_str) if (/^-?\d+$/.test(num_str)) return parseInt(num_str)
if (/^-?\d*\.\d+$/.test(num_str)) return parseFloat(num_str) if (/^-?\d*\.\d+$/.test(num_str)) return parseFloat(num_str)
@@ -77,7 +77,7 @@ function format_value(val) {
if (is_text(val)) return '"' + val + '"' if (is_text(val)) return '"' + val + '"'
if (is_number(val) && val >= 1000) { if (is_number(val) && val >= 1000) {
// Add underscores to large numbers // Add underscores to large numbers
return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '_') return replace(val.toString(), /\B(?=(\d{3})+(?!\d))/g, '_')
} }
return text(val) return text(val)
} }

View File

@@ -270,7 +270,7 @@ Cell supports regex patterns in string functions, but not standalone regex objec
```javascript ```javascript
text.search("hello world", /world/) text.search("hello world", /world/)
text.replace("hello", /l/g, "L") replace("hello", /l/g, "L")
``` ```
## Error Handling ## Error Handling

View File

@@ -70,18 +70,18 @@ text.search("hello world", "xyz") // null
text.search("hello hello", "hello", 1) // 6 text.search("hello hello", "hello", 1) // 6
``` ```
### text.replace(text, target, replacement, limit) ### text.replace(text, target, replacement, cap)
Replace occurrences of `target` with `replacement`. Replace occurrences of `target` with `replacement`. If `cap` is not specified, replaces all occurrences.
```javascript ```javascript
text.replace("hello", "l", "L") // "heLLo" text.replace("hello", "l", "L") // "heLLo" (replaces all)
text.replace("hello", "l", "L", 1) // "heLlo" text.replace("hello", "l", "L", 1) // "heLlo" (replaces first only)
// With function // With function
text.replace("hello", "l", function(match, pos) { text.replace("hello", "l", function(match, pos) {
return pos == 2 ? "L" : match return pos == 2 ? "L" : match
}) // "heLlo" }) // "heLLo" (replaces all by default)
``` ```
### text.format(text, collection, transformer) ### text.format(text, collection, transformer)

32
fd.cm
View File

@@ -1,15 +1,43 @@
var fd = this var fd = this
var wildstar = use('wildstar') var wildstar = use('wildstar')
function last_pos(str, sep) {
var last = null
replace(str, sep, function(m, pos) {
last = pos
return m
})
return last
}
// Helper to join paths // Helper to join paths
function join_paths(base, rel) { function join_paths(base, rel) {
base = base.replace(/\/+$/, "") base = replace(base, /\/+$/, "")
rel = rel.replace(/^\/+/, "") rel = replace(rel, /^\/+/, "")
if (!base) return rel if (!base) return rel
if (!rel) return base if (!rel) return base
return base + "/" + rel return base + "/" + rel
} }
fd.join_paths = join_paths
fd.basename = function basename(path) {
var last = last_pos(path, '/')
if (last == null) return path
return text(path, last+1)
}
fd.dirname = function dirname(path) {
var last = last_pos(path, '/')
if (last == null) return ""
return text(path,0,last)
}
fd.stem = function stem(path) {
var last = last_pos(path, '.')
if (last == null) return path
return text(path,0,last)
}
fd.globfs = function(globs, dir) { fd.globfs = function(globs, dir) {
if (dir == null) dir = "." if (dir == null) dir = "."
var results = [] var results = []

View File

@@ -202,7 +202,7 @@ if (format == 'tree') {
if (node.local) attrs += ', color=blue' if (node.local) attrs += ', color=blue'
// Safe node ID for dot // Safe node ID for dot
var safe_id = id.replaceAll(/[^a-zA-Z0-9]/g, '_') var safe_id = replace(id, /[^a-zA-Z0-9]/g, '_')
log.console(' ' + safe_id + ' [' + attrs + '];') log.console(' ' + safe_id + ' [' + attrs + '];')
} }
@@ -210,8 +210,8 @@ if (format == 'tree') {
// Edges // Edges
for (var e of edges) { for (var e of edges) {
var from_id = e.from.replaceAll(/[^a-zA-Z0-9]/g, '_') var from_id = replace(e.from, /[^a-zA-Z0-9]/g, '_')
var to_id = e.to.replaceAll(/[^a-zA-Z0-9]/g, '_') var to_id = replace(e.to, /[^a-zA-Z0-9]/g, '_')
var label = e.alias != e.to ? 'label="' + e.alias + '"' : '' var label = e.alias != e.to ? 'label="' + e.alias + '"' : ''
log.console(' ' + from_id + ' -> ' + to_id + (label ? ' [' + label + ']' : '') + ';') log.console(' ' + from_id + ' -> ' + to_id + (label ? ' [' + label + ']' : '') + ';')
} }

View File

@@ -1106,7 +1106,7 @@ function install_zip(zip_blob, target_dir) {
parts.shift() parts.shift()
var rel_path = text(parts, '/') var rel_path = text(parts, '/')
var full_path = target_dir + '/' + rel_path var full_path = target_dir + '/' + rel_path
var dir_path = text(full_path, 0, full_path.lastIndexOf('/')) var dir_path = fd.dirname(full_path)
if (!created_dirs[dir_path]) { if (!created_dirs[dir_path]) {
ensure_dir(dir_path) ensure_dir(dir_path)
@@ -1251,7 +1251,7 @@ Shop.get_package_dir = function(pkg) {
// -> 'js_gitea_pockle_world_john_prosperon_sprite_use' // -> 'js_gitea_pockle_world_john_prosperon_sprite_use'
Shop.c_symbol_for_file = function(pkg, file) { Shop.c_symbol_for_file = function(pkg, file) {
var pkg_safe = replace(replace(replace(pkg, '/', '_'), '.', '_'), '-', '_') var pkg_safe = replace(replace(replace(pkg, '/', '_'), '.', '_'), '-', '_')
var file_safe = replace(replace(text(file, 0, file.lastIndexOf('.')), '/', '_'), '.', '_') var file_safe = replace(replace(fd.stem(file), '/', '_'), '.', '_')
return 'js_' + pkg_safe + '_' + file_safe + '_use' return 'js_' + pkg_safe + '_' + file_safe + '_use'
} }

View File

@@ -184,7 +184,7 @@ Link.sync_one = function(canonical, target, shop) {
var link_target = resolve_link_target(target) var link_target = resolve_link_target(target)
// Ensure parent directories exist // Ensure parent directories exist
var parent = text(target_dir, 0, target_dir.lastIndexOf('/')) var parent = fd.dirname(target_dir)
ensure_dir(parent) ensure_dir(parent)
// Check current state // Check current state

View File

@@ -120,19 +120,15 @@ package.find_package_dir = function(file)
var absolute = fd.realpath(file) var absolute = fd.realpath(file)
var dir = absolute var dir = absolute
if (fd.is_file(dir)) { if (fd.is_file(dir))
var last_slash = dir.lastIndexOf('/') dir = fd.dirname(dir)
if (last_slash > 0) dir = text(dir, 0, last_slash)
}
while (dir && dir.length > 0) { while (dir && dir.length > 0) {
var toml_path = dir + '/cell.toml' var toml_path = dir + '/cell.toml'
if (fd.is_file(toml_path)) { if (fd.is_file(toml_path)) {
return dir return dir
} }
var last_slash = dir.lastIndexOf('/') dir = fd.dirname(dir)
if (last_slash <= 0) break
dir = text(dir, 0, last_slash)
} }
return null return null
@@ -291,12 +287,7 @@ package.get_c_files = function(name, target, exclude_main) {
var ext = ends_with(file, '.cpp') ? '.cpp' : '.c' var ext = ends_with(file, '.cpp') ? '.cpp' : '.c'
var base = text(file, 0, -ext.length) var base = text(file, 0, -ext.length)
var dir = '' var dir = ''
var name_part = base var name_part = fd.basename(base)
var slash = base.lastIndexOf('/')
if (slash >= 0) {
dir = text(base, 0, slash + 1)
name_part = text(base, slash + 1)
}
// Check for target suffix // Check for target suffix
var is_variant = false var is_variant = false
@@ -341,9 +332,7 @@ package.get_c_files = function(name, target, exclude_main) {
if (selected) { if (selected) {
// Skip main.c if requested // Skip main.c if requested
if (exclude_main) { if (exclude_main) {
var basename = selected var basename = fd.basename(selected)
var s = selected.lastIndexOf('/')
if (s >= 0) basename = text(selected, s + 1)
if (basename == 'main.c' || starts_with(basename, 'main_')) continue if (basename == 'main.c' || starts_with(basename, 'main_')) continue
} }
result.push(selected) result.push(selected)

View File

@@ -52,7 +52,7 @@ function unpack(archive_path) {
var data = archive.read(f) var data = archive.read(f)
if (data) { if (data) {
// Ensure directory exists // Ensure directory exists
var dir = text(f, 0, f.lastIndexOf('/')) var dir = fd.dirname(f)
if (dir) { if (dir) {
// recursive mkdir // recursive mkdir
var parts = array(dir, '/') var parts = array(dir, '/')

View File

@@ -30302,103 +30302,9 @@ static int js_string_find_invalid_codepoint(JSString *p)
return -1; return -1;
} }
static JSValue js_string_indexOf(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv, int lastIndexOf)
{
JSValue str, v;
int i, len, v_len, pos, start, stop, ret, inc;
JSString *p;
JSString *p1;
str = JS_ToStringCheckObject(ctx, this_val);
if (JS_IsException(str))
return str;
v = JS_ToString(ctx, argv[0]);
if (JS_IsException(v))
goto fail;
p = JS_VALUE_GET_STRING(str);
p1 = JS_VALUE_GET_STRING(v);
len = p->len;
v_len = p1->len;
if (lastIndexOf) {
pos = len - v_len;
if (argc > 1) {
double d;
if (JS_ToFloat64(ctx, &d, argv[1]))
goto fail;
if (!isnan(d)) {
if (d <= 0)
pos = 0;
else if (d < pos)
pos = d;
}
}
start = pos;
stop = 0;
inc = -1;
} else {
pos = 0;
if (argc > 1) {
if (JS_ToInt32Clamp(ctx, &pos, argv[1], 0, len, 0))
goto fail;
}
start = pos;
stop = len - v_len;
inc = 1;
}
ret = -1;
if (len >= v_len && inc * (stop - start) >= 0) {
for (i = start;; i += inc) {
if (!string_cmp(p, p1, i, 0, v_len)) {
ret = i;
break;
}
if (i == stop)
break;
}
}
JS_FreeValue(ctx, str);
JS_FreeValue(ctx, v);
return JS_NewInt32(ctx, ret);
fail:
JS_FreeValue(ctx, str);
JS_FreeValue(ctx, v);
return JS_EXCEPTION;
}
/* return < 0 if exception or TRUE/FALSE */ /* return < 0 if exception or TRUE/FALSE */
static int js_is_regexp(JSContext *ctx, JSValueConst obj); static int js_is_regexp(JSContext *ctx, JSValueConst obj);
static int check_regexp_g_flag(JSContext *ctx, JSValueConst regexp)
{
int ret;
JSValue flags;
ret = js_is_regexp(ctx, regexp);
if (ret < 0)
return -1;
if (ret) {
flags = JS_GetProperty(ctx, regexp, JS_ATOM_flags);
if (JS_IsException(flags))
return -1;
if (JS_IsNull(flags) || JS_IsNull(flags)) {
JS_ThrowTypeError(ctx, "cannot convert to object");
return -1;
}
flags = JS_ToStringFree(ctx, flags);
if (JS_IsException(flags))
return -1;
ret = string_indexof_char(JS_VALUE_GET_STRING(flags), 'g', 0);
JS_FreeValue(ctx, flags);
if (ret < 0) {
JS_ThrowTypeError(ctx, "regexp must have the 'g' flag");
return -1;
}
}
return 0;
}
static JSValue js_string___GetSubstitution(JSContext *ctx, JSValueConst this_val, static JSValue js_string___GetSubstitution(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv) int argc, JSValueConst *argv)
{ {
@@ -30507,119 +30413,6 @@ exception:
return JS_EXCEPTION; return JS_EXCEPTION;
} }
static JSValue js_string_replace(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv,
int is_replaceAll)
{
// replace(rx, rep)
JSValueConst O = this_val, searchValue = argv[0], replaceValue = argv[1];
JSValueConst args[6];
JSValue str, search_str, replaceValue_str, repl_str;
JSString *sp, *searchp;
StringBuffer b_s, *b = &b_s;
int pos, functionalReplace, endOfLastMatch;
BOOL is_first;
if (JS_IsNull(O) || JS_IsNull(O))
return JS_ThrowTypeError(ctx, "cannot convert to object");
search_str = JS_NULL;
replaceValue_str = JS_NULL;
repl_str = JS_NULL;
if (!JS_IsNull(searchValue) && !JS_IsNull(searchValue)) {
JSValue replacer;
if (is_replaceAll) {
if (check_regexp_g_flag(ctx, searchValue) < 0)
return JS_EXCEPTION;
}
replacer = JS_GetProperty(ctx, searchValue, JS_ATOM_Symbol_replace);
if (JS_IsException(replacer))
return JS_EXCEPTION;
if (!JS_IsNull(replacer) && !JS_IsNull(replacer)) {
args[0] = O;
args[1] = replaceValue;
return JS_CallFree(ctx, replacer, searchValue, 2, args);
}
}
string_buffer_init(ctx, b, 0);
str = JS_ToString(ctx, O);
if (JS_IsException(str))
goto exception;
search_str = JS_ToString(ctx, searchValue);
if (JS_IsException(search_str))
goto exception;
functionalReplace = JS_IsFunction(ctx, replaceValue);
if (!functionalReplace) {
replaceValue_str = JS_ToString(ctx, replaceValue);
if (JS_IsException(replaceValue_str))
goto exception;
}
sp = JS_VALUE_GET_STRING(str);
searchp = JS_VALUE_GET_STRING(search_str);
endOfLastMatch = 0;
is_first = TRUE;
for(;;) {
if (unlikely(searchp->len == 0)) {
if (is_first)
pos = 0;
else if (endOfLastMatch >= sp->len)
pos = -1;
else
pos = endOfLastMatch + 1;
} else {
pos = string_indexof(sp, searchp, endOfLastMatch);
}
if (pos < 0) {
if (is_first) {
string_buffer_free(b);
JS_FreeValue(ctx, search_str);
JS_FreeValue(ctx, replaceValue_str);
return str;
} else {
break;
}
}
if (functionalReplace) {
args[0] = search_str;
args[1] = JS_NewInt32(ctx, pos);
args[2] = str;
repl_str = JS_ToStringFree(ctx, JS_Call(ctx, replaceValue, JS_NULL, 3, args));
} else {
args[0] = search_str;
args[1] = str;
args[2] = JS_NewInt32(ctx, pos);
args[3] = JS_NULL;
args[4] = JS_NULL;
args[5] = replaceValue_str;
repl_str = js_string___GetSubstitution(ctx, JS_NULL, 6, args);
}
if (JS_IsException(repl_str))
goto exception;
string_buffer_concat(b, sp, endOfLastMatch, pos);
string_buffer_concat_value_free(b, repl_str);
endOfLastMatch = pos + searchp->len;
is_first = FALSE;
if (!is_replaceAll)
break;
}
string_buffer_concat(b, sp, endOfLastMatch, sp->len);
JS_FreeValue(ctx, search_str);
JS_FreeValue(ctx, replaceValue_str);
JS_FreeValue(ctx, str);
return string_buffer_end(b);
exception:
string_buffer_free(b);
JS_FreeValue(ctx, search_str);
JS_FreeValue(ctx, replaceValue_str);
JS_FreeValue(ctx, str);
return JS_EXCEPTION;
}
/* also used for String.prototype.valueOf */ /* also used for String.prototype.valueOf */
static JSValue js_string_toString(JSContext *ctx, JSValueConst this_val, static JSValue js_string_toString(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv) int argc, JSValueConst *argv)
@@ -30686,10 +30479,6 @@ static JSValue js_string_concat(JSContext *ctx, JSValueConst this_val,
static const JSCFunctionListEntry js_string_proto_funcs[] = { static const JSCFunctionListEntry js_string_proto_funcs[] = {
JS_PROP_INT32_DEF("length", 0, JS_PROP_CONFIGURABLE ), JS_PROP_INT32_DEF("length", 0, JS_PROP_CONFIGURABLE ),
JS_CFUNC_DEF("concat", 1, js_string_concat), JS_CFUNC_DEF("concat", 1, js_string_concat),
JS_CFUNC_MAGIC_DEF("indexOf", 1, js_string_indexOf, 0 ),
JS_CFUNC_MAGIC_DEF("lastIndexOf", 1, js_string_indexOf, 1 ),
JS_CFUNC_MAGIC_DEF("replace", 2, js_string_replace, 0 ),
JS_CFUNC_MAGIC_DEF("replaceAll", 2, js_string_replace, 1 ),
JS_CFUNC_DEF("toString", 0, js_string_toString ), JS_CFUNC_DEF("toString", 0, js_string_toString ),
JS_CFUNC_DEF("valueOf", 0, js_string_toString ), JS_CFUNC_DEF("valueOf", 0, js_string_toString ),
JS_CFUNC_MAGIC_DEF("[Symbol.iterator]", 0, js_create_array_iterator, JS_ITERATOR_KIND_VALUE | 4 ), JS_CFUNC_MAGIC_DEF("[Symbol.iterator]", 0, js_create_array_iterator, JS_ITERATOR_KIND_VALUE | 4 ),

View File

@@ -644,7 +644,7 @@ Total: ${totals.total}, Passed: ${totals.passed}, Failed: ${totals.failed}
} }
} }
var json_path = `${report_dir}/${pkg_res.package.replace(/\//g, '_')}.json` var json_path = `${report_dir}/${replace(pkg_res.package, /\//, '_')}.json`
fd.slurpwrite(json_path, stone(blob(json.encode(pkg_tests)))) fd.slurpwrite(json_path, stone(blob(json.encode(pkg_tests))))
} }
} }

View File

@@ -1566,13 +1566,13 @@ return {
test_string_indexOf: function() { test_string_indexOf: function() {
var str = "hello world" var str = "hello world"
if (str.indexOf("world") != 6) throw "string indexOf failed" if (search(str, "world") != 6) throw "string search failed"
if (str.indexOf("xyz") != -1) throw "string indexOf not found failed" if (search(str, "xyz") != null) throw "string search not found failed"
}, },
test_string_lastIndexOf: function() { test_string_lastIndexOf: function() {
var str = "hello hello" var str = "hello hello"
if (str.lastIndexOf("hello") != 6) throw "string lastIndexOf failed" if (search(str, "hello", 0, true) != 6) throw "string lastSearch failed"
}, },
test_string_toLowerCase: function() { test_string_toLowerCase: function() {
@@ -1949,8 +1949,8 @@ return {
test_text_returns_function_source: function() { test_text_returns_function_source: function() {
var fn = function(x) { return x * 2 } var fn = function(x) { return x * 2 }
var src = text(fn) var src = text(fn)
if (src.indexOf("function") == -1) throw "text(fn) should contain 'function'" if (search(src, "function") == null) throw "text(fn) should contain 'function'"
if (src.indexOf("return") == -1) throw "text(fn) should contain function body" if (search(src, "return") == null) throw "text(fn) should contain function body"
}, },
test_call_invokes_function: function() { test_call_invokes_function: function() {
@@ -2057,7 +2057,7 @@ return {
proxy.nonexistent() proxy.nonexistent()
} catch (e) { } catch (e) {
caught = true caught = true
if (e.indexOf("no such method") == -1) throw "wrong error message" if (search(e, "no such method") == null) throw "wrong error message"
} }
if (!caught) throw "proxy should throw for unknown method" if (!caught) throw "proxy should throw for unknown method"
}, },
@@ -2892,7 +2892,7 @@ return {
test_text_number_float: function() { test_text_number_float: function() {
var result = text(3.14) var result = text(3.14)
if (result.indexOf("3.14") != 0) throw "text number float failed" if (search(result, "3.14") != 0) throw "text number float failed"
}, },
test_text_array_join: function() { test_text_array_join: function() {

View File

@@ -236,12 +236,12 @@ return {
test_tiny_number: function() { test_tiny_number: function() {
var tiny = 0.0000001 var tiny = 0.0000001
var result = text(tiny, "n") var result = text(tiny, "n")
if (result.indexOf('e') == -1) throw "Tiny number format failed" if (search(result, 'e', 0) == null) throw "Tiny number format failed"
}, },
test_huge_number: function() { test_huge_number: function() {
var huge = 1e22 var huge = 1e22
var result = text(huge, "n") var result = text(huge, "n")
if (result.indexOf('e') == -1) throw "Huge number format failed" if (search(result, 'e', 0) == null) throw "Huge number format failed"
} }
} }

View File

@@ -190,9 +190,9 @@ function time_text(num = now(),
fmt = replace(fmt, "s", rec.second); fmt = replace(fmt, "s", rec.second);
fmt = replace(fmt, "x", dst ? "DST" : ""); /* new */ fmt = replace(fmt, "x", dst ? "DST" : ""); /* new */
fmt = replace(fmt, "z", (full_offset >= 0 ? "+" : "") + text(full_offset)); fmt = replace(fmt, "z", (full_offset >= 0 ? "+" : "") + text(full_offset));
fmt = fmt.replaceAll(/mm[^bB]/g, rec.month + 1); fmt = replace(fmt, /mm[^bB]/g, rec.month + 1);
fmt = fmt.replaceAll(/m[^bB]/g, rec.month + 1); fmt = replace(fmt, /m[^bB]/g, rec.month + 1);
fmt = fmt.replaceAll(/v[^bB]/g, rec.weekday); fmt = replace(fmt, /v[^bB]/g, rec.weekday);
fmt = replace(fmt, "mb", text(time.monthstr[rec.month], 0, 3)); fmt = replace(fmt, "mb", text(time.monthstr[rec.month], 0, 3));
fmt = replace(fmt, "mB", time.monthstr[rec.month]); fmt = replace(fmt, "mB", time.monthstr[rec.month]);
fmt = replace(fmt, "vB", time.weekdays[rec.weekday]); fmt = replace(fmt, "vB", time.weekdays[rec.weekday]);

View File

@@ -63,8 +63,8 @@ function parse_toml(toml_text) {
} }
// Key-value pair // Key-value pair
var eq_index = line.indexOf('=') var eq_index = search(line, '=')
if (eq_index > 0) { if (eq_index != null && eq_index > 0) {
var key_part = trim(text(line, 0, eq_index)) var key_part = trim(text(line, 0, eq_index))
var value = trim(text(line, eq_index + 1)) var value = trim(text(line, eq_index + 1))
if (key_part == null) key_part = trim(text(line, 0, eq_index)) if (key_part == null) key_part = trim(text(line, 0, eq_index))