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; }
ArgSet::eInitArgsStat ArgSet::InitArgs (TextStream & text, int numExpected) { // we'll re-init even if we've been init'd already _args.Clear (); if (! numExpected) { // If no args expected, don't try to consume "()" return kInitNoError; } if (! text.Expect ("(")) return kInitNoStartParen; while (numExpected--) { ArgDef thisArg; ArgDef::eInitStat stat; if (! text.GetLength()) return kInitArgsTooFew; // // why did this line cause Purify to // think there was a memory leak? // // if (text.Expect(")")) TextStream closeParen (")"); if (text.Expect(closeParen)) { return kInitArgsTooFew; } stat = thisArg.Init (text); switch (stat) { case ArgDef::kInitBadEscape: return kInitNoEndParen; case ArgDef::kInitNotTerminated: return kInitNoEndParen; default: // unknown error assert (0); break; case ArgDef::kInitNoError: _args.Append (thisArg); break; } } if (! text.Expect(")")) { return kInitArgsTooMany; } return kInitNoError; }
void MacroDef::Test () { // // ctor // MacroDef md; assert (0 == md._numArgs); assert (0 == md._name.GetLength()); assert (0 == md._definition.GetLength()); // // Init() // TextStream name = "mac"; md.Init (name, 2); assert (2 == md._numArgs); assert (3 == md._name.GetLength()); assert (md._name.Snoop("mac")); // // AppendMacroExpansion() // TextStream exp; eAppendStat aStat; TextStream ts; exp = "arg %03 too great"; aStat = md.AppendMacroExpansion (exp); assert (kAppendArgRange == aStat); exp = "arg %x illegal"; aStat = md.AppendMacroExpansion (exp); assert (kAppendBadArg == aStat); md.Init (name, 2); // re-init to clear out old macro def crap assert (0 == md._definition.GetLength()); exp = "Second=%02, First=%01"; aStat = md.AppendMacroExpansion (exp); assert (kAppendNoError == aStat); assert (0 != md._definition.GetLength()); ts = md._definition; assert (ts.GetLength()); assert (ts.Expect ("Second=%02, First=%01")); assert (! ts.GetLength()); // // IsMacro() // TextStream input; bool stat; input = "amac"; stat = md.IsMacro (input); assert (! stat); input = "macro"; stat = md.IsMacro (input); assert (stat); input = "macanudo"; stat = md.IsMacro (input); assert (stat); input = "madness"; stat = md.IsMacro (input); assert (! stat); // // InvokeMacro() // TextStream output; eInvokeMacroStat iStat; SourceInfo si ("foo", 2); ArgSet as; ArgSet::eInitArgsStat iasStat; TextStream argText; argText = "(ONE!,TWO!,THREE!)"; iasStat = as.InitArgs (argText, 3); assert (ArgSet::kInitNoError == iasStat); assert (0 == output.GetLength()); iStat = md.InvokeMacro(as, output, si); assert (kInvokeWrongArgCount == iStat); assert (0 == output.GetLength()); MacroDef md2; iStat = md2.InvokeMacro(as, output, si); assert (kInvokeNotInited == iStat); md2.Init (name, 2); iStat = md2.InvokeMacro(as, output, si); assert (kInvokeWrongArgCount == iStat); assert (0 == output.GetLength()); argText = "(ONE!,TWO!)"; iasStat = as.InitArgs (argText, 2); assert (ArgSet::kInitNoError == iasStat); assert (0 == output.GetLength()); iStat = md.InvokeMacro(as, output, si); assert (kInvokeNoError == iStat); assert (0 != output.GetLength()); stat = output.Expect ("Second=TWO!, First=ONE!"); assert (stat); assert (0 == output.GetLength()); // // GetNumArgs() // assert (2 == md2.GetNumArgs()); md2.Init (name, 0); assert (0 == md2.GetNumArgs()); assert (2 == md.GetNumArgs()); }
bool MacroDef::IsMacro (TextStream & testName) const { return testName.Expect (_name); }
void ArgDef::Test () { // // Init(), GetText() // ArgDef ad; TextStream ts; TextStream input; eInitStat stat; assert (0 == ad._rep.GetLength()); input = "something"; stat = ad.Init (input); assert (kInitNotTerminated == stat); input = "proper)"; stat = ad.Init (input); assert (kInitNoError == stat); ts = ad.GetText (); assert (0 != ts.GetLength()); assert (ts.Expect ("proper")); assert (0 == ts.GetLength()); assert (input.Expect (")")); assert (0 == input.GetLength()); input = "(paren in arg)"; stat = ad.Init (input); assert (kInitNoError == stat); ts = ad.GetText (); assert (0 != ts.GetLength()); assert (ts.Expect ("(paren in arg")); assert (0 == ts.GetLength()); assert (input.Expect (")")); assert (0 == input.GetLength()); input = "middle arg,yup)"; stat = ad.Init (input); assert (kInitNoError == stat); ts = ad.GetText (); assert (0 != ts.GetLength()); assert (ts.Expect ("middle arg")); assert (0 == ts.GetLength()); assert (input.Expect ("yup)")); assert (0 == input.GetLength()); input = "comma in\\, arg, here"; stat = ad.Init (input); assert (kInitNoError == stat); ts = ad.GetText (); assert (0 != ts.GetLength()); assert (ts.Expect ("comma in, arg")); assert (0 == ts.GetLength()); assert (input.Expect (" here")); assert (0 == input.GetLength()); input = " \t\t\n\t White\tspace in here.,"; stat = ad.Init (input); assert (kInitNoError == stat); ts = ad.GetText (); assert (0 != ts.GetLength()); assert (ts.Expect ("White\tspace in here.")); assert (0 == ts.GetLength()); assert (0 == input.GetLength()); input = "bad escape\\"; stat = ad.Init (input); assert (kInitBadEscape == stat); }