MacroDef::eAppendStat MacroDef::AppendMacroExpansion (TextStream & text) { char c; bool stat; while (text.Consume(c)) { if ('%' == c) { if (text.Expect ("%")) { // escape of '%' character: that's OK _definition.Append (c); _definition.Append (c); continue; } int argIdx = 0; for (int digitCount = 0; digitCount < 2; digitCount++) { stat = text.Consume(c); if (! stat) { return kAppendBadArg; } if ((c >= '0') && (c <= '9')) { // valid arg values if (0 == digitCount) { _definition.Append ('%'); } _definition.Append (c); argIdx = argIdx*10 + (c - '0'); if (argIdx > _numArgs) { return kAppendArgRange; } continue; } else { return kAppendBadArg; } } } else { _definition.Append (c); } } return kAppendNoError; }
MacroDef::eInvokeMacroStat MacroDef::InvokeMacro (const ArgSet & args, TextStream & outText, const SourceInfo &si) const { if (! _name.GetLength()) { return kInvokeNotInited; } if (args.GetNumArgs() != _numArgs) { return kInvokeWrongArgCount; } TextStream tmp = _definition; while (tmp.GetLength()) { bool stat; char c; stat = tmp.Consume (c); assert (stat); if ('%' != c) { outText.Append (c); } else { // Looks like a macro argument invocation, maybe! stat = tmp.Consume (c); assert (stat); // should have already checked for this in // AppendMacroExpansion() if ('%' == c) { // Not a macro, just an escaped '%' outText.Append (c); } else { int idx = c - '0'; TextStream txt; stat = tmp.Consume (c); assert (stat); // should have already checked for // this in AppendMacroExpansion() assert (c >= '0'); assert (c <= '9'); idx = idx * 10 + (c - '0'); // AppendMacroExpansion should have already checked for // proper range assert (idx > 0); assert (idx < 100); txt = args.GetArg(idx-1).GetText(); // index is 0-based outText.SetCurSourceInfo (si); outText.Append (txt); } } } return kInvokeNoError; }