/// <summary>Parses all the keywords/macros in a string and replaces them recursively</summary> /// <param name="text">Source text to parse</param> /// <param name="depth">Debugging output depth</param> /// <returns>Fully parsed text</returns> /// <exception cref="Logic::FileFormatException">Macro contains wrong number of parameters</exception> /// <exception cref="Logic::Language::RegularExpressionException">RegEx error</exception> wstring DescriptionParser::Parse(wstring text, int depth) const { UINT Position; wsmatch match; wstring r; try { #ifdef PRINT_CONSOLE Console << Cons::Cyan << Indent(depth) << "Parsing: " << Cons::White << text << ENDL; #endif // Find/Replace all macros: {AAAA:bbb}, {AAAA:bbb,ccc}, {AAAA:bbb,ccc,ddd} ... for (Position = 0; regex_search(text.cbegin()+Position, text.cend(), match, MatchMacro); ) // Manually track position for in-place replacement + avoid infinite loop { // Recursively generate replacement text r = onMatchMacro(match, depth); #ifdef PRINT_CONSOLE Console << Indent(depth) << "Replacing text: " << Cons::Yellow << match[0].str() << Cons::White << " with " << Cons::Green << r << ENDL; #endif // Advance position to beyond inserted text, and insert text Position = (match[0].first - text.cbegin()) + r.length(); text.replace(match[0].first, match[0].second, r); } // Find/Replace all keywords: {AAAAA}, AAAAA for (Position = 0; regex_search(text.cbegin()+Position, text.cend(), match, MatchKeyword); ) { // Recursively generate replacement text r = onMatchKeyword(match, depth); #ifdef PRINT_CONSOLE Console << Indent(depth) << "Replacing text: " << Cons::Yellow << match[0].str() << Cons::White << " with " << Cons::Green << r << ENDL; #endif // Advance position to beyond inserted text, and insert text Position = (match[0].first - text.cbegin()) + r.length(); text.replace(match[0].first, match[0].second, r); } return text; } catch (regex_error& e) { throw RegularExpressionException(HERE, e); } }
/// <summary>Populates the parameters markers within the description source text.</summary> /// <param name="src">source text.</param> /// <param name="cmd">command syntax.</param> /// <returns></returns> wstring DescriptionParser::Populate(wstring src, CommandSyntaxRef cmd) { wsmatch match; wstring r; // Replace all {aaa,bbb} markers. Manually track position for in-place replacement + avoid infinite loop for (int Position = 0; regex_search(src.cbegin()+Position, src.cend(), match, MartchParameterMarker); ) { r = onParameterMarker(match, cmd); #ifdef PRINT_CONSOLE Console << " Replace: " << Cons::Yellow << match[0].str() << Cons::White << " with " << Cons::Green << r << ENDL; #endif // Advance position + perform replacement Position = (match[0].first - src.cbegin()) + r.length(); src.replace(match[0].first, match[0].second, r); } return src; }
bool ConnectedShortcut::startsWith(const wstring& tested, const wstring& prefix) { return (tested.length() >= prefix.length()) && (std::mismatch(prefix.cbegin(), prefix.cend(), tested.cbegin()).first == prefix.cend()); }