/* static void scIntegerValueOf(const CFunctionsScopePtr &c, void *) { string str = c->getArgument("str")->toString(); int val = 0; if (str.length()==1) val = str.operator[](0); c->setReturnVar(c->newScriptVar(val)); } */ static void scJSONStringify(const CFunctionsScopePtr &c, void *) { uint32_t UniqueID = c->getContext()->allocUniqueID(); bool hasRecursion=false; c->setReturnVar(c->newScriptVar(c->getArgument("obj")->getParsableString("", " ", UniqueID, hasRecursion))); c->getContext()->freeUniqueID(); if(hasRecursion) c->throwError(TypeError, "cyclic object value"); }
static void scStringReplace(const CFunctionsScopePtr &c, void *) { const string str = this2string(c); CScriptVarPtr newsubstrVar = c->getArgument("newsubstr"); string substr, ret_str; bool global, ignoreCase, sticky; bool isRegExp = getRegExpData(c, "substr", false, "flags", substr, global, ignoreCase, sticky); if(isRegExp && !newsubstrVar->isFunction()) { #ifndef NO_REGEXP regex::flag_type flags = regex_constants::ECMAScript; if(ignoreCase) flags |= regex_constants::icase; regex_constants::match_flag_type mflags = regex_constants::match_default; if(!global) mflags |= regex_constants::format_first_only; if(sticky) mflags |= regex_constants::match_continuous; ret_str = regex_replace(str, regex(substr, flags), newsubstrVar->toString(), mflags); #endif /* NO_REGEXP */ } else { bool (*search)(const string &, const string::const_iterator &, const string &, bool, bool, string::const_iterator &, string::const_iterator &); #ifndef NO_REGEXP if(isRegExp) search = regex_search; else #endif /* NO_REGEXP */ search = string_search; string newsubstr; vector<CScriptVarPtr> arguments; if(!newsubstrVar->isFunction()) newsubstr = newsubstrVar->toString(); global = global && substr.length(); string::const_iterator search_begin=str.begin(), match_begin, match_end; if(search(str, search_begin, substr, ignoreCase, sticky, match_begin, match_end)) { do { ret_str.append(search_begin, match_begin); if(newsubstrVar->isFunction()) { arguments.push_back(c->newScriptVar(string(match_begin, match_end))); newsubstr = c->getContext()->callFunction(newsubstrVar, arguments)->toString(); arguments.pop_back(); } ret_str.append(newsubstr); #if 1 /* Fix from "vcmpeq" (see Issue 14) currently untested */ if (match_begin == match_end) { if (search_begin != str.end()) ++search_begin; else break; } else { search_begin = match_end; } #else search_begin = match_end; #endif } while(global && search(str, search_begin, substr, ignoreCase, sticky, match_begin, match_end)); } ret_str.append(search_begin, str.end()); } c->setReturnVar(c->newScriptVar(ret_str)); }
static void scStringSplit(const CFunctionsScopePtr &c, void *) { string str = c->getArgument("this")->getString(); CScriptVarPtr sep_var = c->getArgument("separator"); CScriptVarPtr limit_var = c->getArgument("limit"); int limit = limit_var->isUndefined() ? 0x7fffffff : limit_var->getInt(); CScriptVarPtr result(newScriptVar(c->getContext(), Array)); c->setReturnVar(result); if(limit == 0 || !str.size()) return; else if(sep_var->isUndefined()) { result->setArrayIndex(0, c->newScriptVar(str)); return; } string sep = sep_var->getString(); if(sep.size() == 0) { for(int i=0; i<min((int)sep.size(), limit); ++i) result->setArrayIndex(i, c->newScriptVar(str.substr(i,1))); return; } int length = 0; string::size_type pos = 0, last_pos=0; do { pos = str.find(sep, last_pos); result->setArrayIndex(length++, c->newScriptVar(str.substr(last_pos ,pos-last_pos))); if(length == limit || pos == string::npos) break; last_pos = pos+sep.size(); } while (last_pos < str.size()); }
static void scStringMatch(const CFunctionsScopePtr &c, void *) { string str = this2string(c); string flags="flags", substr, newsubstr, match; bool global, ignoreCase, sticky; CScriptVarRegExpPtr RegExp = getRegExpData(c, "regexp", true, "flags", substr, global, ignoreCase, sticky); if(!global) { if(!RegExp) RegExp = ::newScriptVar(c->getContext(), substr, flags); if(RegExp) { try { c->setReturnVar(RegExp->exec(str)); } catch(regex_error e) { c->throwError(SyntaxError, string(e.what())+" - "+CScriptVarRegExp::ErrorStr(e.code())); } } } else { try { CScriptVarArrayPtr retVar = c->newScriptVar(Array); int idx=0; string::size_type offset=0; global = global && substr.length(); string::const_iterator search_begin=str.begin(), match_begin, match_end; if(regex_search(str, search_begin, substr, ignoreCase, sticky, match_begin, match_end)) { do { offset = match_begin-str.begin(); retVar->addChild(int2string(idx++), c->newScriptVar(string(match_begin, match_end))); #if 1 /* Fix from "vcmpeq" (see Issue 14) currently untested */ if (match_begin == match_end) { if (search_begin != str.end()) ++search_begin; else break; } else { search_begin = match_end; } #else search_begin = match_end; #endif } while(global && regex_search(str, search_begin, substr, ignoreCase, sticky, match_begin, match_end)); } if(idx) { retVar->addChild("input", c->newScriptVar(str)); retVar->addChild("index", c->newScriptVar((int)offset)); c->setReturnVar(retVar); } else c->setReturnVar(c->constScriptVar(Null)); } catch(regex_error e) { c->throwError(SyntaxError, string(e.what())+" - "+CScriptVarRegExp::ErrorStr(e.code())); } } }
void js_dump(const CFunctionsScopePtr &v, void *) { v->getContext()->getRoot()->trace("> "); }