📄 jsstr.c
字号:
/* Mismatch: ensure our caller advances i past end of string. */ sep->length = 1; return length; } i = (jsint)index; *sep = cx->regExpStatics.lastMatch; if (sep->length == 0) { /* * Empty string match: never split on an empty match at the start * of a find_split cycle. Same rule as for an empty global match * in match_or_replace. */ if (i == *ip) { /* * "Bump-along" to avoid sticking at an empty match, but don't * bump past end of string -- our caller must do that by adding * sep->length to our return value. */ if ((size_t)i == length) { if (cx->version == JSVERSION_1_2) { sep->length = 1; return i; } return -1; } i++; goto again; } } JS_ASSERT((size_t)i >= sep->length); return i - sep->length; }#endif /* JS_HAS_REGEXPS */ /* * Deviate from ECMA by never splitting an empty string by any separator * string into a non-empty array (an array of length 1 that contains the * empty string). */ if (!JSVERSION_IS_ECMA(cx->version) && length == 0) return -1; /* * Special case: if sep is the empty string, split str into one character * substrings. Let our caller worry about whether to split once at end of * string into an empty substring. * * For 1.2 compatibility, at the end of the string, we return the length as * the result, and set the separator length to 1 -- this allows the caller * to include an additional null string at the end of the substring list. */ if (sep->length == 0) { if (cx->version == JSVERSION_1_2) { if ((size_t)i == length) { sep->length = 1; return i; } return i + 1; } return ((size_t)i == length) ? -1 : i + 1; } /* * Now that we know sep is non-empty, search starting at i in str for an * occurrence of all of sep's chars. If we find them, return the index of * the first separator char. Otherwise, return length. */ j = 0; while ((size_t)(k = i + j) < length) { if (chars[k] == sep->chars[j]) { if ((size_t)++j == sep->length) return i; } else { i++; j = 0; } } return k;}static JSBoolstr_split(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSString *str, *sub; JSObject *arrayobj; jsval v; JSBool ok, limited; JSRegExp *re; JSSubString *sep, tmp = { 0 }; jsdouble d; jsint i, j; uint32 len, limit; str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); if (!str) return JS_FALSE; argv[-1] = STRING_TO_JSVAL(str); arrayobj = js_ConstructObject(cx, &js_ArrayClass, NULL, NULL, 0, NULL); if (!arrayobj) return JS_FALSE; *rval = OBJECT_TO_JSVAL(arrayobj); if (argc == 0) { v = STRING_TO_JSVAL(str); ok = JS_SetElement(cx, arrayobj, 0, &v); } else {#if JS_HAS_REGEXPS if (JSVAL_IS_REGEXP(cx, argv[0])) { re = (JSRegExp *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(argv[0])); sep = &tmp; /* Set a magic value so we can detect a successful re match. */ sep->chars = NULL; } else#endif { JSString *str2 = js_ValueToString(cx, argv[0]); if (!str2) return JS_FALSE; argv[0] = STRING_TO_JSVAL(str2); /* * Point sep at a local copy of str2's header because find_split * will modify sep->length. */ tmp.length = JSSTRING_LENGTH(str2); tmp.chars = JSSTRING_CHARS(str2); sep = &tmp; re = NULL; } /* Use the second argument as the split limit, if given. */ limited = (argc > 1) && !JSVAL_IS_VOID(argv[1]); limit = 0; /* Avoid warning. */ if (limited) { if (!js_ValueToNumber(cx, argv[1], &d)) return JS_FALSE; /* Clamp limit between 0 and 1 + string length. */ if (!js_DoubleToECMAUint32(cx, d, &limit)) return JS_FALSE; if (limit > JSSTRING_LENGTH(str)) limit = 1 + JSSTRING_LENGTH(str); } len = i = 0; while ((j = find_split(cx, str, re, &i, sep)) >= 0) { if (limited && len >= limit) break; sub = js_NewDependentString(cx, str, i, (size_t)(j - i), 0); if (!sub) return JS_FALSE; v = STRING_TO_JSVAL(sub); if (!JS_SetElement(cx, arrayobj, len, &v)) return JS_FALSE; len++;#if JS_HAS_REGEXPS /* * Imitate perl's feature of including parenthesized substrings * that matched part of the delimiter in the new array, after the * split substring that was delimited. */ if (re && sep->chars) { uintN num; JSSubString *parsub; for (num = 0; num < cx->regExpStatics.parenCount; num++) { if (limited && len >= limit) break; parsub = REGEXP_PAREN_SUBSTRING(&cx->regExpStatics, num); sub = js_NewStringCopyN(cx, parsub->chars, parsub->length, 0); if (!sub) return JS_FALSE; v = STRING_TO_JSVAL(sub); if (!JS_SetElement(cx, arrayobj, len, &v)) return JS_FALSE; len++; } sep->chars = NULL; }#endif i = j + sep->length; if (!JSVERSION_IS_ECMA(cx->version)) { /* * Deviate from ECMA to imitate Perl, which omits a final * split unless a limit argument is given and big enough. */ if (!limited && (size_t)i == JSSTRING_LENGTH(str)) break; } } ok = (j != -2); } return ok;}#if JS_HAS_PERL_SUBSTRstatic JSBoolstr_substr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSString *str; jsdouble d; jsdouble length, begin, end; str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); if (!str) return JS_FALSE; if (argc != 0) { if (!js_ValueToNumber(cx, argv[0], &d)) return JS_FALSE; length = JSSTRING_LENGTH(str); begin = js_DoubleToInteger(d); if (begin < 0) { begin += length; if (begin < 0) begin = 0; } else if (begin > length) { begin = length; } if (argc == 1) { end = length; } else { if (!js_ValueToNumber(cx, argv[1], &d)) return JS_FALSE; end = js_DoubleToInteger(d); if (end < 0) end = 0; end += begin; if (end > length) end = length; } str = js_NewDependentString(cx, str, (size_t)begin, (size_t)(end - begin), 0); if (!str) return JS_FALSE; } *rval = STRING_TO_JSVAL(str); return JS_TRUE;}#endif /* JS_HAS_PERL_SUBSTR */#if JS_HAS_SEQUENCE_OPS/* * Python-esque sequence operations. */static JSBoolstr_concat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSString *str, *str2; uintN i; str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); if (!str) return JS_FALSE; argv[-1] = STRING_TO_JSVAL(str); for (i = 0; i < argc; i++) { str2 = js_ValueToString(cx, argv[i]); if (!str2) return JS_FALSE; argv[i] = STRING_TO_JSVAL(str2); str = js_ConcatStrings(cx, str, str2); if (!str) return JS_FALSE; } *rval = STRING_TO_JSVAL(str); return JS_TRUE;}static JSBoolstr_slice(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSString *str; jsdouble d; jsdouble length, begin, end; str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); if (!str) return JS_FALSE; argv[-1] = STRING_TO_JSVAL(str); if (argc != 0) { if (!js_ValueToNumber(cx, argv[0], &d)) return JS_FALSE; length = JSSTRING_LENGTH(str); begin = js_DoubleToInteger(d); if (begin < 0) { begin += length; if (begin < 0) begin = 0; } else if (begin > length) { begin = length; } if (argc == 1) { end = length; } else { if (!js_ValueToNumber(cx, argv[1], &d)) return JS_FALSE; end = js_DoubleToInteger(d); if (end < 0) { end += length; if (end < 0) end = 0; } else if (end > length) { end = length; } if (end < begin) end = begin; } str = js_NewDependentString(cx, str, (size_t)begin, (size_t)(end - begin), 0); if (!str) return JS_FALSE; } *rval = STRING_TO_JSVAL(str); return JS_TRUE;}#endif /* JS_HAS_SEQUENCE_OPS */#if JS_HAS_STR_HTML_HELPERS/* * HTML composition aids. */static JSBooltagify(JSContext *cx, JSObject *obj, jsval *argv, const char *begin, const jschar *param, const char *end, jsval *rval){ JSString *str; jschar *tagbuf; size_t beglen, endlen, parlen, taglen; size_t i, j; str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); if (!str) return JS_FALSE; argv[-1] = STRING_TO_JSVAL(str); if (!end) end = begin; beglen = strlen(begin); taglen = 1 + beglen + 1; /* '<begin' + '>' */ parlen = 0; /* Avoid warning. */ if (param) { parlen = js_strlen(param); taglen += 2 + parlen + 1; /* '="param"' */ } endlen = strlen(end); taglen += JSSTRING_LENGTH(str) + 2 + endlen + 1; /* 'str</end>' */ tagbuf = (jschar *) JS_malloc(cx, (taglen + 1) * sizeof(jschar)); if (!tagbuf) return JS_FALSE; j = 0; tagbuf[j++] = '<'; for (i = 0; i < beglen; i++) tagbuf[j++] = (jschar)begin[i]; if (param) { tagbuf[j++] = '='; tagbuf[j++] = '"'; js_strncpy(&tagbuf[j], param, parlen); j += parlen; tagbuf[j++] = '"'; } tagbuf[j++] = '>'; js_strncpy(&tagbuf[j], JSSTRING_CHARS(str), JSSTRING_LENGTH(str)); j += JSSTRING_LENGTH(str); tagbuf[j++] = '<'; tagbuf[j++] = '/'; for (i = 0; i < endlen; i++) tagbuf[j++] = (jschar)end[i]; tagbuf[j++] = '>'; JS_ASSERT(j == taglen); tagbuf[j] = 0; str = js_NewString(cx, tagbuf, taglen, 0); if (!str) { free((char *)tagbuf); return JS_FALSE; } *rval = STRING_TO_JSVAL(str); return JS_TRUE;}static JSBooltagify_value(JSContext *cx, JSObject *obj, jsval *argv, const char *begin, const char *end, jsval *rval){ JSString *param; param = js_ValueToString(cx, argv[0]); if (!param) return JS_FALSE; argv[0] = STRING_TO_JSVAL(param); return tagify(cx, obj, argv, begin, JSSTRING_CHARS(param), end, rval);}static JSBoolstr_bold(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ return tagify(cx, obj, argv, "b", NULL, NULL, rval);}static JSBoolstr_italics(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ return tagify(cx, obj, argv, "i", NULL, NULL, rval);}static JSBoolstr_fixed(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ return tagify(cx, obj, argv, "tt", NULL, NULL, rval);}static JSBoolstr_fontsize(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ return tagify_value(cx, obj, argv, "font size", "font", rval);}static JSBool
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -