From a7a323a74e758a0ccca099d3734d66b577d859ed Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Sat, 17 Jan 2026 16:21:02 -0600 Subject: [PATCH] rm index and indexof --- bench.ce | 2 +- cellfs.cm | 57 ++++-------- clean.ce | 2 +- clone.ce | 4 +- config.ce | 4 +- docs/cellscript.md | 2 +- docs/library/text.md | 10 +- fd.cm | 32 ++++++- graph.ce | 6 +- internal/shop.cm | 4 +- link.cm | 2 +- package.cm | 21 +---- qopconv.ce | 2 +- source/quickjs.c | 211 ------------------------------------------- test.ce | 2 +- tests/suite.cm | 14 +-- tests/text.cm | 4 +- time.cm | 6 +- toml.cm | 4 +- 19 files changed, 86 insertions(+), 303 deletions(-) diff --git a/bench.ce b/bench.ce index c3abb810..b53ea61d 100644 --- a/bench.ce +++ b/bench.ce @@ -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)))) } } diff --git a/cellfs.cm b/cellfs.cm index 5cfd20af..dc0bef50 100644 --- a/cellfs.cm +++ b/cellfs.cm @@ -17,30 +17,7 @@ var writepath = "." function normalize_path(path) { if (!path) return "" // Remove leading/trailing slashes and normalize - return path.replace(/^\/+|\/+$/g, "") -} - -// 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 + return replace(path, /^\/+|\/+$/, "") } // Check if a file exists in a specific mount @@ -59,7 +36,7 @@ function mount_exists(mount, path) { return false } } else { // fs - var full_path = join_paths(mount.source, path) + var full_path = fd.join_paths(mount.source, path) try { var st = fd.stat(full_path) return st.isFile || st.isDirectory @@ -86,7 +63,7 @@ function is_directory(path) { return false; } } else { // fs - var full_path = join_paths(mount.source, path) + var full_path = fd.join_paths(mount.source, path) try { var st = fd.stat(full_path) return st.isDirectory @@ -103,11 +80,11 @@ function resolve(path, must_exist) { // Check for named mount if (starts_with(path, "@")) { - var idx = path.indexOf("/") + var idx = search(path, "/") var mount_name = "" var rel_path = "" - if (idx == -1) { + if (idx == null) { mount_name = text(path, 1) rel_path = "" } else { @@ -212,7 +189,7 @@ function slurp(path) { if (!data) throw Error("File not found in qop: " + path) return data } 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) } } @@ -256,7 +233,7 @@ function stat(path) { isDirectory: s.isDirectory } } 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) return { filesize: s.size, @@ -298,14 +275,14 @@ function rm(path) { var res = resolve(path, true) 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) if (st.isDirectory) fd.rmdir(full_path) else fd.unlink(full_path) } function mkdir(path) { - var full = join_paths(writepath, path) + var full = fd.join_paths(writepath, path) fd.mkdir(full) } @@ -324,7 +301,7 @@ function prefdir(org, app) { function realdir(path) { var res = resolve(path, false) 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) { @@ -342,16 +319,16 @@ function enumerate(path, recurse) { results.push(item_rel) if (recurse) { - var st = fd.stat(join_paths(curr_full, item)) + var st = fd.stat(fd.join_paths(curr_full, item)) 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') { - var full = join_paths(res.mount.source, res.path) + var full = fd.join_paths(res.mount.source, res.path) var st = fd.stat(full) if (st && st.isDirectory) { visit(full, "") @@ -370,8 +347,8 @@ function enumerate(path, recurse) { if (rel.length == 0) continue if (!recurse) { - var slash = rel.indexOf('/') - if (slash != -1) { + var slash = search(rel, '/') + if (slash != null) { rel = text(rel, 0, slash) } } @@ -415,7 +392,7 @@ function globfs(globs, dir) { for (var item of list) { 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) if (st.isDirectory) { @@ -431,7 +408,7 @@ function globfs(globs, dir) { } 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) if (st && st.isDirectory) { visit(full, "") diff --git a/clean.ce b/clean.ce index 5b7ca73e..c2841b88 100644 --- a/clean.ce +++ b/clean.ce @@ -111,7 +111,7 @@ if (is_shop_scope) { // Gather files to clean var lib_dir = shop.get_lib_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 (is_shop_scope) { diff --git a/clone.ce b/clone.ce index e153f9b4..2ee39903 100644 --- a/clone.ce +++ b/clone.ce @@ -31,7 +31,7 @@ if (target_path == '.' || starts_with(target_path, './') || starts_with(target_p target_path = cwd + text(target_path, 1) } else if (starts_with(target_path, '../')) { // 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) } } @@ -99,7 +99,7 @@ try { parts.shift() var rel_path = text(parts, '/') 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 if (!fd.is_dir(dir_path)) { diff --git a/config.ce b/config.ce index 45c0da47..a0896237 100644 --- a/config.ce +++ b/config.ce @@ -64,7 +64,7 @@ function parse_value(str) { if (str == 'false') return false // 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*\.\d+$/.test(num_str)) return parseFloat(num_str) @@ -77,7 +77,7 @@ function format_value(val) { if (is_text(val)) return '"' + val + '"' if (is_number(val) && val >= 1000) { // 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) } diff --git a/docs/cellscript.md b/docs/cellscript.md index 0db62e19..1b102428 100644 --- a/docs/cellscript.md +++ b/docs/cellscript.md @@ -270,7 +270,7 @@ Cell supports regex patterns in string functions, but not standalone regex objec ```javascript text.search("hello world", /world/) -text.replace("hello", /l/g, "L") +replace("hello", /l/g, "L") ``` ## Error Handling diff --git a/docs/library/text.md b/docs/library/text.md index 912378a7..aab23cab 100644 --- a/docs/library/text.md +++ b/docs/library/text.md @@ -70,18 +70,18 @@ text.search("hello world", "xyz") // null 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 -text.replace("hello", "l", "L") // "heLLo" -text.replace("hello", "l", "L", 1) // "heLlo" +text.replace("hello", "l", "L") // "heLLo" (replaces all) +text.replace("hello", "l", "L", 1) // "heLlo" (replaces first only) // With function text.replace("hello", "l", function(match, pos) { return pos == 2 ? "L" : match -}) // "heLlo" +}) // "heLLo" (replaces all by default) ``` ### text.format(text, collection, transformer) diff --git a/fd.cm b/fd.cm index f4f4af35..b4612c8b 100644 --- a/fd.cm +++ b/fd.cm @@ -1,15 +1,43 @@ var fd = this 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 function join_paths(base, rel) { - base = base.replace(/\/+$/, "") - rel = rel.replace(/^\/+/, "") + base = replace(base, /\/+$/, "") + rel = replace(rel, /^\/+/, "") if (!base) return rel if (!rel) return base 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) { if (dir == null) dir = "." var results = [] diff --git a/graph.ce b/graph.ce index 0d291fc6..ac36b754 100644 --- a/graph.ce +++ b/graph.ce @@ -202,7 +202,7 @@ if (format == 'tree') { if (node.local) attrs += ', color=blue' // 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 + '];') } @@ -210,8 +210,8 @@ if (format == 'tree') { // Edges for (var e of edges) { - var from_id = e.from.replaceAll(/[^a-zA-Z0-9]/g, '_') - var to_id = e.to.replaceAll(/[^a-zA-Z0-9]/g, '_') + var from_id = replace(e.from, /[^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 + '"' : '' log.console(' ' + from_id + ' -> ' + to_id + (label ? ' [' + label + ']' : '') + ';') } diff --git a/internal/shop.cm b/internal/shop.cm index 40e4a864..6f1e5f1e 100644 --- a/internal/shop.cm +++ b/internal/shop.cm @@ -1106,7 +1106,7 @@ function install_zip(zip_blob, target_dir) { parts.shift() var rel_path = text(parts, '/') 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]) { ensure_dir(dir_path) @@ -1251,7 +1251,7 @@ Shop.get_package_dir = function(pkg) { // -> 'js_gitea_pockle_world_john_prosperon_sprite_use' Shop.c_symbol_for_file = function(pkg, file) { 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' } diff --git a/link.cm b/link.cm index c6a4cce9..ab9fa4f8 100644 --- a/link.cm +++ b/link.cm @@ -184,7 +184,7 @@ Link.sync_one = function(canonical, target, shop) { var link_target = resolve_link_target(target) // Ensure parent directories exist - var parent = text(target_dir, 0, target_dir.lastIndexOf('/')) + var parent = fd.dirname(target_dir) ensure_dir(parent) // Check current state diff --git a/package.cm b/package.cm index 1b22989d..efeb7a61 100644 --- a/package.cm +++ b/package.cm @@ -120,19 +120,15 @@ package.find_package_dir = function(file) var absolute = fd.realpath(file) var dir = absolute - if (fd.is_file(dir)) { - var last_slash = dir.lastIndexOf('/') - if (last_slash > 0) dir = text(dir, 0, last_slash) - } + if (fd.is_file(dir)) + dir = fd.dirname(dir) while (dir && dir.length > 0) { var toml_path = dir + '/cell.toml' if (fd.is_file(toml_path)) { return dir } - var last_slash = dir.lastIndexOf('/') - if (last_slash <= 0) break - dir = text(dir, 0, last_slash) + dir = fd.dirname(dir) } return null @@ -291,12 +287,7 @@ package.get_c_files = function(name, target, exclude_main) { var ext = ends_with(file, '.cpp') ? '.cpp' : '.c' var base = text(file, 0, -ext.length) var dir = '' - var name_part = base - var slash = base.lastIndexOf('/') - if (slash >= 0) { - dir = text(base, 0, slash + 1) - name_part = text(base, slash + 1) - } + var name_part = fd.basename(base) // Check for target suffix var is_variant = false @@ -341,9 +332,7 @@ package.get_c_files = function(name, target, exclude_main) { if (selected) { // Skip main.c if requested if (exclude_main) { - var basename = selected - var s = selected.lastIndexOf('/') - if (s >= 0) basename = text(selected, s + 1) + var basename = fd.basename(selected) if (basename == 'main.c' || starts_with(basename, 'main_')) continue } result.push(selected) diff --git a/qopconv.ce b/qopconv.ce index 748bfa72..500f8fcc 100644 --- a/qopconv.ce +++ b/qopconv.ce @@ -52,7 +52,7 @@ function unpack(archive_path) { var data = archive.read(f) if (data) { // Ensure directory exists - var dir = text(f, 0, f.lastIndexOf('/')) + var dir = fd.dirname(f) if (dir) { // recursive mkdir var parts = array(dir, '/') diff --git a/source/quickjs.c b/source/quickjs.c index a3715618..18b7ba07 100644 --- a/source/quickjs.c +++ b/source/quickjs.c @@ -30302,103 +30302,9 @@ static int js_string_find_invalid_codepoint(JSString *p) 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 */ 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, int argc, JSValueConst *argv) { @@ -30507,119 +30413,6 @@ 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 */ static JSValue js_string_toString(JSContext *ctx, JSValueConst this_val, 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[] = { JS_PROP_INT32_DEF("length", 0, JS_PROP_CONFIGURABLE ), 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("valueOf", 0, js_string_toString ), JS_CFUNC_MAGIC_DEF("[Symbol.iterator]", 0, js_create_array_iterator, JS_ITERATOR_KIND_VALUE | 4 ), diff --git a/test.ce b/test.ce index 6d7d73b7..2dedbada 100644 --- a/test.ce +++ b/test.ce @@ -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)))) } } diff --git a/tests/suite.cm b/tests/suite.cm index dbdf9101..527d42ea 100644 --- a/tests/suite.cm +++ b/tests/suite.cm @@ -1566,13 +1566,13 @@ return { test_string_indexOf: function() { var str = "hello world" - if (str.indexOf("world") != 6) throw "string indexOf failed" - if (str.indexOf("xyz") != -1) throw "string indexOf not found failed" + if (search(str, "world") != 6) throw "string search failed" + if (search(str, "xyz") != null) throw "string search not found failed" }, test_string_lastIndexOf: function() { 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() { @@ -1949,8 +1949,8 @@ return { test_text_returns_function_source: function() { var fn = function(x) { return x * 2 } var src = text(fn) - if (src.indexOf("function") == -1) throw "text(fn) should contain 'function'" - if (src.indexOf("return") == -1) throw "text(fn) should contain function body" + if (search(src, "function") == null) throw "text(fn) should contain 'function'" + if (search(src, "return") == null) throw "text(fn) should contain function body" }, test_call_invokes_function: function() { @@ -2057,7 +2057,7 @@ return { proxy.nonexistent() } catch (e) { 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" }, @@ -2892,7 +2892,7 @@ return { test_text_number_float: function() { 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() { diff --git a/tests/text.cm b/tests/text.cm index 94b9d10c..a0b04ce2 100644 --- a/tests/text.cm +++ b/tests/text.cm @@ -236,12 +236,12 @@ return { test_tiny_number: function() { var tiny = 0.0000001 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() { var huge = 1e22 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" } } diff --git a/time.cm b/time.cm index bf7d72e1..770a33c1 100644 --- a/time.cm +++ b/time.cm @@ -190,9 +190,9 @@ function time_text(num = now(), fmt = replace(fmt, "s", rec.second); fmt = replace(fmt, "x", dst ? "DST" : ""); /* new */ fmt = replace(fmt, "z", (full_offset >= 0 ? "+" : "") + text(full_offset)); - fmt = fmt.replaceAll(/mm[^bB]/g, rec.month + 1); - fmt = fmt.replaceAll(/m[^bB]/g, rec.month + 1); - fmt = fmt.replaceAll(/v[^bB]/g, rec.weekday); + fmt = replace(fmt, /mm[^bB]/g, rec.month + 1); + fmt = replace(fmt, /m[^bB]/g, rec.month + 1); + fmt = replace(fmt, /v[^bB]/g, rec.weekday); fmt = replace(fmt, "mb", text(time.monthstr[rec.month], 0, 3)); fmt = replace(fmt, "mB", time.monthstr[rec.month]); fmt = replace(fmt, "vB", time.weekdays[rec.weekday]); diff --git a/toml.cm b/toml.cm index e7f1531c..559350ad 100644 --- a/toml.cm +++ b/toml.cm @@ -63,8 +63,8 @@ function parse_toml(toml_text) { } // Key-value pair - var eq_index = line.indexOf('=') - if (eq_index > 0) { + var eq_index = search(line, '=') + if (eq_index != null && eq_index > 0) { var key_part = trim(text(line, 0, eq_index)) var value = trim(text(line, eq_index + 1)) if (key_part == null) key_part = trim(text(line, 0, eq_index))