public ExpandResult ExpandStringFull(string line, out string result, int recdepth) { int noexpansion = 0; int pos = 0; do { pos = line.IndexOf('%', pos); if (pos >= 0) { pos++; // move on, if it fails, next pos= will be past this point int startexpression = pos; int apos = pos; while (apos < line.Length && char.IsLetter(line[apos])) { apos++; } if (apos < line.Length && line[apos] == '(') // now must be bracket.. if not, its not in form, ignore %, or its past the EOL { string funcname = line.Substring(pos, apos - pos); apos++; // past the ( ConditionFunctionHandlers cfh = GetCFH(this, vars, persistentdata, recdepth); while (true) { while (apos < line.Length && char.IsWhiteSpace(line[apos])) // remove white space { apos++; } if (apos < line.Length && line[apos] == ')' && cfh.paras.Count == 0) // ) here must be on first only, and is valid { apos++; // skip by break; } int start = apos; if (apos < line.Length && (line[apos] == '"' || line[apos] == '\'')) { char quote = line[apos++]; string res = ""; while (apos < line.Length && line[apos] != quote) { if (line[apos] == '\\' && (apos + 1) < line.Length && line[apos + 1] == quote) // if \" { apos++; } res += line[apos++]; } if (apos >= line.Length) { result = "Terminal quote missing at '" + line.Substring(startexpression, apos - startexpression) + "'"; return(ExpandResult.Failed); } apos++; // remove quote string resexp; // expand out any strings.. recursion ExpandResult sexpresult = ExpandStringFull(res, out resexp, recdepth + 1); if (sexpresult == ExpandResult.Failed) { result = resexp; return(sexpresult); } cfh.paras.Add(new ConditionFunctionHandlers.Parameter() { value = resexp, isstring = true }); } else { if (funcname.Length > 0) // functions can have () embedded .. in literals { int blevel = 0; while (apos < line.Length && (blevel > 0 || "), ".IndexOf(line[apos]) == -1)) { if (line[apos] == '(') { blevel++; } else if (line[apos] == ')') { blevel--; } apos++; } } else { while (apos < line.Length && "), ".IndexOf(line[apos]) == -1) { apos++; } } if (apos == start) { result = "Missing variable name at '" + line.Substring(startexpression, apos - startexpression) + "'"; return(ExpandResult.Failed); } string res = line.Substring(start, apos - start); if (funcname.Length > 0 && line.Contains("%")) // function paramters can be expanded if they have a % { string resexp; // expand out any strings.. recursion ExpandResult sexpresult = ExpandStringFull(res, out resexp, recdepth + 1); if (sexpresult == ExpandResult.Failed) { result = resexp; return(sexpresult); } res = resexp; } cfh.paras.Add(new ConditionFunctionHandlers.Parameter() { value = res, isstring = false }); } while (apos < line.Length && char.IsWhiteSpace(line[apos])) { apos++; } char c = (apos < line.Length) ? line[apos++] : '-'; if (c == ')') // must be ) { break; } if (c != ',') // must be , { result = "Incorrectly formed parameter list at '" + line.Substring(startexpression, apos - startexpression) + "'"; return(ExpandResult.Failed); } } string expand = null; if (funcname.Length > 0) { if (!cfh.RunFunction(funcname, out expand)) { result = "Function " + funcname + ": " + expand; return(ExpandResult.Failed); } } else if (cfh.paras.Count > 1) { result = "Only functions can have multiple comma separated items at '" + line.Substring(startexpression, apos - startexpression) + "'"; return(ExpandResult.Failed); } else { if (cfh.paras[0].isstring) { result = "Must be a variable not a string for non function expansions"; return(ExpandResult.Failed); } else if (vars.Exists(cfh.paras[0].value)) { expand = vars[cfh.paras[0].value]; } else { result = "Variable " + cfh.paras[0].value + " does not exist"; return(ExpandResult.Failed); } } noexpansion++; line = line.Substring(0, pos - 1) + expand + line.Substring(apos); pos = (pos - 1) + expand.Length; // System.Diagnostics.Debug.WriteLine("<" + funcname + "> var <" + varnames[0] + ">" + " line <" + line + "> left <" + line.Substring(pos) + ">"); } } } while (pos != -1); result = line; return((noexpansion > 0) ? ExpandResult.Expansion : ExpandResult.NoExpansion); }
public ExpandResult ExpandStringFull(string line, out string result, int recdepth) { if (recdepth > 9) { result = "Recursion detected - aborting expansion"; return(ExpandResult.Failed); } int noexpansion = 0; int pos = 0; do { pos = line.IndexOf('%', pos); if (pos >= 0) { pos++; // move on, if it fails, next pos= will be past this point int startexpression = pos; int apos = pos; while (apos < line.Length && char.IsLetter(line[apos])) { apos++; } if (apos < line.Length && line[apos] == '(') // now must be bracket.. if not, its not in form, ignore %, or its past the EOL { string funcname = line.Substring(pos, apos - pos); apos++; // past the ( ConditionFunctionHandlers cfh = GetCFH(this, vars, persistentdata, recdepth); string errprefix = ""; if (funcname.Length > 0) { if (!cfh.SetFunction(funcname)) { result = "Function '" + funcname + "' does not exist"; return(ExpandResult.Failed); } errprefix = "Function " + funcname + ": "; //System.Diagnostics.Debug.WriteLine("Function " + funcname); } while (true) { while (apos < line.Length && char.IsWhiteSpace(line[apos])) // remove white space { apos++; } if (apos < line.Length && line[apos] == ')' && cfh.ParaCount == 0) // ) here must be on first only, and is valid { apos++; // skip by break; } if (!cfh.IsNextParameterAllowed) { result = errprefix + "Too many parameters"; return(ExpandResult.Failed); } int start = apos; bool isstring = false; // meaning, we can't consider it for macro names, its now a literal string res = null; if (apos < line.Length && (line[apos] == '"' || line[apos] == '\'')) { if (!cfh.IsNextStringAllowed) { result = errprefix + "String not allowed in parameter " + (cfh.ParaCount + 1); return(ExpandResult.Failed); } char quote = line[apos++]; res = string.Empty; while (apos < line.Length && line[apos] != quote) { if (line[apos] == '\\' && (apos + 1) < line.Length && line[apos + 1] == quote) // if \" { apos++; } res += line[apos++]; } if (apos >= line.Length) { result = errprefix + "Terminal quote missing at '" + line.Substring(startexpression, apos - startexpression) + "'"; return(ExpandResult.Failed); } apos++; // remove quote isstring = true; } else { if (cfh.IsFunction) // functions can have () embedded .. in literals { int blevel = 0; while (apos < line.Length && (blevel > 0 || "), ".IndexOf(line[apos]) == -1)) { if (line[apos] == '(') { blevel++; } else if (line[apos] == ')') { blevel--; } apos++; } } else { while (apos < line.Length && "), ".IndexOf(line[apos]) == -1) { apos++; } } if (apos == start) { result = errprefix + "Missing text/varname at '" + line.Substring(startexpression, apos - startexpression) + "'"; return(ExpandResult.Failed); } res = line.Substring(start, apos - start); } string err = cfh.ProcessParameter(res, isstring, recdepth); if (err != null) { result = errprefix + "Parameter " + (cfh.ParaCount + 1) + ": " + err; return(ExpandResult.Failed); } while (apos < line.Length && char.IsWhiteSpace(line[apos])) { apos++; } char c = (apos < line.Length) ? line[apos++] : '-'; if (c == ')') // must be ) { break; } if (c != ',') // must be , { result = "Incorrectly formed parameter list at '" + line.Substring(startexpression, apos - startexpression) + "'"; return(ExpandResult.Failed); } } string expand = null; if (!cfh.Run(out expand)) { result = errprefix + expand; return(ExpandResult.Failed); } //System.Diagnostics.Debug.WriteLine("Output is '" + expand + "'"); noexpansion++; line = line.Substring(0, pos - 1) + expand + line.Substring(apos); pos = (pos - 1) + expand.Length; // System.Diagnostics.Debug.WriteLine("<" + funcname + "> var <" + varnames[0] + ">" + " line <" + line + "> left <" + line.Substring(pos) + ">"); } } } while (pos != -1); result = line; return((noexpansion > 0) ? ExpandResult.Expansion : ExpandResult.NoExpansion); }