//************************************ // Method: getRegExpData // FullName: getRegExpData // Access: public static // Returns: bool true if regexp-param=RegExp-Object / other false // Qualifier: // Parameter: const CFunctionsScopePtr & c // Parameter: const string & regexp - parameter name of the regexp // Parameter: bool noUndefined - true an undefined regexp aims in "" else in "undefined" // Parameter: const string & flags - parameter name of the flags // Parameter: string & substr - rgexp.source // Parameter: bool & global // Parameter: bool & ignoreCase // Parameter: bool & sticky //************************************ static CScriptVarPtr getRegExpData(const CFunctionsScopePtr &c, const string ®exp, bool noUndefined, const char *flags_argument, string &substr, bool &global, bool &ignoreCase, bool &sticky) { CScriptVarPtr regexpVar = c->getArgument(regexp); if(regexpVar->isRegExp()) { #ifndef NO_REGEXP CScriptVarRegExpPtr RegExp(regexpVar); substr = RegExp->Regexp(); ignoreCase = RegExp->IgnoreCase(); global = RegExp->Global(); sticky = RegExp->Sticky(); return RegExp; #endif /* NO_REGEXP */ } else { substr.clear(); if(!noUndefined || !regexpVar->isUndefined()) substr = regexpVar->toString(); CScriptVarPtr flagVar; if(flags_argument && (flagVar = c->getArgument(flags_argument)) && !flagVar->isUndefined()) { string flags = flagVar->toString(); string::size_type pos = flags.find_first_not_of("gimy"); if(pos != string::npos) { c->throwError(SyntaxError, string("invalid regular expression flag ")+flags[pos]); } global = flags.find_first_of('g')!=string::npos; ignoreCase = flags.find_first_of('i')!=string::npos; sticky = flags.find_first_of('y')!=string::npos; } else global = ignoreCase = sticky = false; } return CScriptVarPtr(); }
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 string this2string(const CFunctionsScopePtr &c) { CScriptVarPtr This = c->getArgument("this"); CheckObjectCoercible(This); return This->toString(); }