예제 #1
0
        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);
        }
예제 #2
0
        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);
        }