public static string SubstituteScalarsInString(string s, bool reportError, bool avoidVal) { //UPDATE: also replaces $ and $%, for instance $n or $%n. NOTE!! -> $ scalars are removed not //Will look for '%' and find alphanumeric + underscore after that, to construct a scalar name. //So STRING s = 'abc%de,%f' will find two scalars. If tilde is used, scalars are not found: //STRING s = 'abc~%de,~%f' will return abc%d,%f //Concatenation can be used: //STRING s = 'abc%d|e' will look for %d, not %de. The '|' is removed afterwards, like the '~' //Maybe we could use the tilde as escape character more generally?? So '~|' will show the '|'. And '~~' will show one '~'. if (s == null) { return(null); } string s2 = null; bool hit = false; int lastEnd = -1; for (int j = 0; j < s.Length - 1; j++) { bool tilde = (j > 0 && s[j - 1] == Globals.symbolTilde); // ~%x or ~$x or ~{x} //bool isDollarPercent = false; //bool isDollar = false; bool isCurly = false; //if (j > 0 && s[j - 1] == Globals.symbolDollar[0] && s[j - 0] == Globals.symbolMemvar) isDollarPercent = true; //if (j > 1 && s[j - 2] == Globals.symbolTilde && isDollarPercent) tilde = true; // ~$%x //if (s[j] == Globals.symbolDollar[0]) isDollar = true; if (s[j] == '{') { isCurly = true; } //if (j > 0 && s[j - 1] == Globals.symbolTilde && isDollar) tilde = true; // ~$x if ((s[j] == Globals.symbolMemvar) && !tilde) { string variable = null; int end = -1; for (int jj = j + 1; jj < s.Length; jj++) { if (G.IsLetterOrDigitOrUnderscore(s[jj])) { //do nothing, loop goes on } else { end = jj; break; } } if (end == -1) { end = s.Length; } variable = s.Substring(j + 1, end - (j + 1)); if (variable.Length > 0) { try { IVariable a = O.GetScalar(variable, false); if (a.Type() == EVariableType.String || a.Type() == EVariableType.Date || a.Type() == EVariableType.Val) { bool valfail = false; if (a.Type() == EVariableType.Val) { if (j == 0) { valfail = true; //for instance PRT %v, where v is a VAL, should no in-substitute } else { if (!G.IsLetterOrDigitOrUnderscore(s[j - 1])) { valfail = true; //for instance, PRT ab%v should in-substitute } else { //for instance, PRT ab%v, where %v = 2, should print as ab2 } } } if (!avoidVal) { valfail = false; //overriding } if (!valfail) { IVariable b = new ScalarString(""); IVariable c = b.Add(a, Globals.tNull); string s3 = c.GetString(); int x = 0; //if (isDollarPercent) x = 1; string s4 = s.Substring(lastEnd + 1, j - lastEnd - 1 - x); s2 += s4 + s3; hit = true; } } else { //should not be possible regarding %-vars } } catch { if (reportError) { throw new GekkoException(); } } lastEnd = end - 1; j = lastEnd; } } else if (isCurly && !tilde) //curly is at position j { string variable = null; int end = -1; for (int jj = j + 1; jj < s.Length; jj++) { if (s[jj] == '}') { end = jj; break; } } if (end != -1) { variable = s.Substring(j + 1, end - (j + 1)).Trim(); if (variable.StartsWith(Globals.symbolMemvar.ToString())) { variable = variable.Substring(1); } if (G.IsSimpleToken(variable)) { try { IVariable a = O.GetScalar(variable, false); if (a.Type() == EVariableType.String || a.Type() == EVariableType.Date || a.Type() == EVariableType.Val) { IVariable b = new ScalarString(""); IVariable c = b.Add(a, Globals.tNull); string s3 = c.GetString(); string s4 = s.Substring(lastEnd + 1, j - lastEnd - 1); s2 += s4 + s3; hit = true; } else { //should not be possible regarding %-vars } } catch { if (reportError) { throw new GekkoException(); } } lastEnd = end; j = lastEnd; } } } } if (hit) { s2 += s.Substring(lastEnd + 1, s.Length - lastEnd - 1); s = s2; } string tp = new string(new char[] { Globals.symbolTilde, Globals.symbolMemvar }); string p = new string(Globals.symbolMemvar, 1); s = s.Replace(tp, p); //string tp2 = new string(new char[] { Globals.symbolTilde, Globals.symbolDollar[0] }); //string p2 = new string(Globals.symbolDollar[0], 1); //s = s.Replace(tp2, p2); string tp3 = new string(new char[] { '{', Globals.symbolTilde }); //a{~n}b string p3 = new string('{', 1); s = s.Replace(tp3, p3); //Hmmm, in 'Hej~%s|du', this will become 'Hej%sdu', not 'Hej%s|du' //This is maybe not too good, but never mind string concat = new string(Globals.symbolConcatenation, 1); //The following 3 lines remove single '|', but not double '||'. //Could use regex, but this is ok. //This means that PRT f|e will be fe, but show [1 || 2] keeps the '||'. s = s.Replace(concat + concat, "[<{2concats}>]"); s = s.Replace(concat, ""); s = s.Replace("[<{2concats}>]", concat + concat); return(s); }