/// <summary>
        /// returns the parameters of a function
        /// </summary>
        /// <param name="m">regex math value</param>
        /// <returns></returns>
        private object[] GetParameters(Match m)
        {
            string  strParams   = "";
            int     nIdx        = m.Index + m.Length;
            int     nDepth      = 1;
            int     nLast       = 0;
            bool    bInQuotes   = false;
            ArrayList ret       = new ArrayList();

            //Get the parameter string
            while (nDepth > 0)
            {
                if (nIdx >= Expression.Length)
                    throw new ArgumentException("Missing ')' in Expression");

                if (!bInQuotes && Expression[nIdx] == ')')
                    nDepth--;
                if (!bInQuotes && Expression[nIdx] == '(')
                    nDepth++;

                if (Expression[nIdx] == '"' && (nIdx == 0 || Expression[nIdx-1] != '\\'))
                    bInQuotes = !bInQuotes;

                if (nDepth > 0)
                    nIdx++;
            }
            strParams = Expression.Substring(m.Index + m.Length, nIdx - (m.Index + m.Length));

            if ("" + strParams == "")
                return null;

            bInQuotes = false;
            for (nIdx = 0; nIdx < strParams.Length; nIdx++)
            {
                if (!bInQuotes && strParams[nIdx] == ')')
                    nDepth--;
                if (!bInQuotes && strParams[nIdx] == '(')
                    nDepth++;

                if (strParams[nIdx] == '"' && (nIdx == 0 || strParams[nIdx - 1] != '\\'))
                    bInQuotes = !bInQuotes;

                if (!bInQuotes && nDepth == 0 && strParams[nIdx] == ',')
                {
                    ret.Add(strParams.Substring(nLast, nIdx - nLast));
                    nLast = nIdx+1;
                }
            }
            ret.Add(strParams.Substring(nLast, nIdx - nLast));

            for (nIdx = 0; nIdx < ret.Count; nIdx++)
            {
                ExpressionEval eval = new ExpressionEval(ret[nIdx].ToString());
                eval.AdditionalFunctionEventHandler += AdditionalFunctionEventHandler;
                eval._variables = this._variables;
                ret[nIdx] = eval;
            }
            return ret.ToArray();
        }
        private static bool performComparison(string[] values)
        {
            string comparisonString = "";
            string tempVar;
            bool errorFlag = false;

            for (int i = 0; i < values.Length; i++)
            {
            //Console.WriteLine(values[i]);
                 if (values[i].Equals(".lt.")) { values[i] = " < "; }
            else if (values[i].Equals(".gt.")) { values[i] = " > "; }
            else if (values[i].Equals(".eq.")) { values[i] = " == "; }
            else if (values[i].Equals(".le.")) { values[i] = " <= "; }
            else if (values[i].Equals(".ge.")) { values[i] = " >= "; }
            else if (values[i].Equals(".ne.")) { values[i] = " != "; }
            else if (values[i].Equals(".and.")) { values[i] = " && "; }
            else if (values[i].Equals(".or.")) { values[i] = " || "; }
            else if (values[i].Equals(".not.")) { values[i] = " ! "; }
            else if (isVariableName(values[i])) {
                if (variables.ContainsKey(values[i])) { variables.TryGetValue(values[i], out tempVar); values[i] = tempVar; }
                else { errorFlag = true; }
            }
                 else if (isString(values[i])) { values[i] = values[i].Replace('"', '\''); } //.Trim('\'')
                 //Console.WriteLine(values[i]);
            }

            foreach (string s in values) { comparisonString += s; }
            //Console.WriteLine(comparisonString);

            if (!errorFlag)
            {

            ExpressionEval expr = new ExpressionEval(comparisonString);
            object result = expr.Evaluate();
            //Console.WriteLine(result);
            return (bool)result;
            }
            else
            {
            return false;
            }
        }
        /// <summary>
        /// Executes the function based upon the name of the function
        /// </summary>
        /// <param name="name">name of the function to execute</param>
        /// <param name="p">parameter list</param>
        /// <returns>returned value of executed function</returns>
        //[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
        private object ExecuteFunction(string name, object[] p)
        {
            object[] parameters = null;
            if (p != null)
            {
                parameters = (object[])p.Clone();
                for (int x = 0; x < parameters.Length; x++)
                    if (parameters[x] is IExpression)
                        parameters[x] = ((IExpression)parameters[x]).Evaluate();
            }
            switch (name.ToLower(CultureInfo.CurrentCulture))
            {
                // Math functions
                case "sin":     return Math.Sin(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture));
                case "cos":     return Math.Cos(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture));
                case "tan":     return Math.Tan(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture));
                case "sec":     return 1 / Math.Cos(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture));
                case "csc":     return 1 / Math.Sin(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture));
                case "cot":     return 1 / Math.Tan(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture));
                case "asin":    return Math.Asin(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture));
                case "acos":    return Math.Acos(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture));
                case "atan":    return Math.Atan(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture));
                case "sinh":    return Math.Sinh(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture));
                case "cosh":    return Math.Cosh(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture));
                case "tanh":    return Math.Tanh(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture));
                case "abs":     return Math.Abs(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture));
                case "sqrt":    return Math.Sqrt(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture));
                case "ciel":    return Math.Ceiling(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture));
                case "floor":   return Math.Floor(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture));
                case "exp":     return Math.Exp(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture));
                case "log10":   return Math.Log10(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture));
                case "log":     return (parameters.Length > 1) ?
                                        Math.Log(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture), Convert.ToDouble(parameters[1], CultureInfo.CurrentCulture)) :
                                        Math.Log(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture));
                case "max":     return Math.Max(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture), Convert.ToDouble(parameters[1], CultureInfo.CurrentCulture));
                case "min":     return Math.Min(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture), Convert.ToDouble(parameters[1], CultureInfo.CurrentCulture));
                case "pow":     return Math.Pow(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture), Convert.ToDouble(parameters[1], CultureInfo.CurrentCulture));
                case "round":   return (parameters.Length > 1) ?
                                        Math.Round(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture), Convert.ToInt32(parameters[1], CultureInfo.CurrentCulture)) :
                                        Math.Round(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture));
                //case "trunc":   return Math.Truncate(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture));
                case "e":       return Math.E;
                case "pi":      return Math.PI;

                //DateTime functions
                case "now":     return DateTime.Now;
                case "today":   return DateTime.Today;
                case "mindate": return DateTime.MinValue;
                case "maxdate": return DateTime.MaxValue;
                case "monthname": return (new DateTime(2000, Convert.ToInt32(parameters[0]), 1)).ToString("MMMM");
                case "adddays": return Convert.ToDateTime(parameters[0]).AddDays(Convert.ToInt32(parameters[1]));
                case "addmonths": return Convert.ToDateTime(parameters[0]).AddMonths(Convert.ToInt32(parameters[1]));
                case "addyears": return Convert.ToDateTime(parameters[0]).AddYears(Convert.ToInt32(parameters[1]));
                case "addhours": return Convert.ToDateTime(parameters[0]).AddHours(Convert.ToInt32(parameters[1]));
                case "addminutes": return Convert.ToDateTime(parameters[0]).AddMinutes(Convert.ToInt32(parameters[1]));
                case "addseconds": return Convert.ToDateTime(parameters[0]).AddSeconds(Convert.ToInt32(parameters[1]));

                //Formatting Functions
                case "fmtnum":  return Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture).ToString("" + parameters[1], CultureInfo.CurrentCulture);
                case "fmtdate": return Convert.ToDateTime(parameters[0], CultureInfo.CurrentCulture).ToString("" + parameters[1], CultureInfo.CurrentCulture);

                //Numerical Expression Evaluation
                case "expr":
                    {
                        ExpressionEval eval = new ExpressionEval("" + parameters[0]);
                        eval.AdditionalFunctionEventHandler += this.AdditionalFunctionEventHandler;
                        eval._variables = this._variables;
                        return eval.Evaluate();
                    }

                //Casting Functions
                case "cdbl":    return Convert.ToDouble (parameters[0], CultureInfo.CurrentCulture);
                case "cint":    return Convert.ToInt32  (parameters[0], CultureInfo.CurrentCulture);
                case "clong":   return Convert.ToInt64  (parameters[0], CultureInfo.CurrentCulture);
                case "cuint":   return Convert.ToUInt32 (parameters[0], CultureInfo.CurrentCulture);
                case "culong":  return Convert.ToUInt64 (parameters[0], CultureInfo.CurrentCulture);
                case "cdatetime": return Convert.ToDateTime(parameters[0], CultureInfo.CurrentCulture);
                case "str":     return parameters[0].ToString();

                //Logical Functions
                case "iif":     return Iif(parameters);
                case "case":    return Case(parameters);

                //security fucntions
                case "currentuserid": return WindowsIdentity.GetCurrent().Name.ToLower()                                                                        ;

                default:        return AdditionalFunctionHelper(name, parameters);
            }
        }
Example #4
0
        public bool IsScheduling(string cronExpression)
        {
            string buildExpression = "";
            int p = 0;
            while (p < cronExpression.Length)
            {
                char token = cronExpression[p];
                if (token == '(' || token == ')' || token == ';' || token == ':')
                {
                    buildExpression += token;
                    p++;
                    continue;
                }

                string currentExpression = token.ToString();
                p++;
                while (p < cronExpression.Length)
                {
                    token = cronExpression[p];
                    if (token != '(' && token != ')' && token != ';' && token != ':')
                    {
                        currentExpression += token;
                        p++;
                    }
                    else
                    {
                        break;
                    }
                }

                currentExpression = currentExpression.Trim(new char[] { ' ', '\t' });
                if (String.IsNullOrEmpty(currentExpression)) continue;

                bool isEntryActive = false;
                if (currentExpression.StartsWith("@"))
                {
                    // Check expresion from scheduled item with a given name
                    var eventItem = Get(currentExpression.Substring(1));
                    isEntryActive = (eventItem != null && eventItem.IsEnabled && EvaluateCronEntry(eventItem.CronExpression));
                }
                else
                {
                    isEntryActive = EvaluateCronEntry(currentExpression);
                }

                buildExpression += (isEntryActive ? "1" : "0");

            }

            buildExpression = buildExpression.Replace(":", "+");
            buildExpression = buildExpression.Replace(";", "*");

            bool success = false;
            try
            {
                ExpressionEval eval = new ExpressionEval();
                eval.Expression = buildExpression;
                success = eval.EvaluateBool();
            }
            catch (Exception ex)
            {
                masterControlProgram.HomeGenie.LogBroadcastEvent(
                    Domains.HomeAutomation_HomeGenie_Scheduler,
                    cronExpression,
                    "Scheduler Expression",
                    Properties.SCHEDULER_ERROR,
                    JsonConvert.SerializeObject(ex.Message));
            }
            return success;
        }
        public bool IsScheduling(DateTime date, string cronExpression)
        {
            string buildExpression = "";
            int p = 0;
            while (p < cronExpression.Length)
            {
                char token = cronExpression[p];
                if (token == '(' || token == ')' || token == ';' || token == ':')
                {
                    buildExpression += token;
                    p++;
                    continue;
                }

                string currentExpression = token.ToString();
                p++;
                while (p < cronExpression.Length)
                {
                    token = cronExpression[p];
                    if (token != '(' && token != ')' && token != ';' && token != ':')
                    {
                        currentExpression += token;
                        p++;
                    }
                    else
                    {
                        break;
                    }
                }

                currentExpression = currentExpression.Trim(new char[] { ' ', '\t' });
                if (String.IsNullOrEmpty(currentExpression)) continue;

                bool isEntryActive = false;
                if (currentExpression.StartsWith("@"))
                {
                    // Check expresion from scheduled item with a given name
                    var eventItem = Get(currentExpression.Substring(1));
                    if (eventItem == null)
                    {
                        masterControlProgram.HomeGenie.MigService.RaiseEvent(
                            this,
                            Domains.HomeAutomation_HomeGenie,
                            SourceModule.Scheduler,
                            cronExpression,
                            Properties.SchedulerError,
                            JsonConvert.SerializeObject("Unknown event name '"+currentExpression+"'"));
                    }
                    else if (recursionCount >= MAX_EVAL_RECURSION)
                    {
                        recursionCount = 0;
                        masterControlProgram.HomeGenie.MigService.RaiseEvent(
                            this,
                            Domains.HomeAutomation_HomeGenie,
                            SourceModule.Scheduler,
                            cronExpression,
                            Properties.SchedulerError,
                            JsonConvert.SerializeObject("Too much recursion in expression '"+currentExpression+"'"));
                        eventItem.IsEnabled = false;
                    }
                    else
                    {
                        recursionCount++;
                        try
                        {
                            isEntryActive = (eventItem.IsEnabled && IsScheduling(date, eventItem.CronExpression));
                        } catch{ }
                        recursionCount--;
                        if (recursionCount < 0)
                            recursionCount = 0;
                    }
                }
                else
                {
                    isEntryActive = EvaluateCronEntry(date, currentExpression);
                }

                buildExpression += (isEntryActive ? "1" : "0");

            }

            buildExpression = buildExpression.Replace(":", "+");
            buildExpression = buildExpression.Replace(";", "*");

            bool success = false;
            try
            {
                ExpressionEval eval = new ExpressionEval();
                eval.Expression = buildExpression;
                success = eval.EvaluateBool();
            }
            catch (Exception ex)
            {
                masterControlProgram.HomeGenie.MigService.RaiseEvent(
                    this,
                    Domains.HomeAutomation_HomeGenie,  // before v1.1 it was: Domains.HomeAutomation_HomeGenie_Automation,
                    SourceModule.Scheduler, // before v1.1 it was: cronExpression,
                    cronExpression, // before v1.1 it was: "Scheduler Expression",
                    Properties.SchedulerError,
                    JsonConvert.SerializeObject(ex.Message));
            }
            return success;
        }
Example #6
0
 /// <summary>
 /// Static version of the Expression Evaluator
 /// </summary>
 /// <param name="expression">expression to be evaluated</param>
 /// <param name="handler">attach a custom function handler</param>
 /// <returns></returns>
 public static object Evaluate(string expression, AdditionalFunctionEventHandler handler)
 {
     ExpressionEval expr = new ExpressionEval(expression);
     expr.AdditionalFunctionEventHandler += handler;
     return expr.Evaluate();
 }
Example #7
0
 /// <summary>
 /// Static version of the Expression Evaluator
 /// </summary>
 /// <param name="expression">expression to be evaluated</param>
 /// <returns></returns>
 public static object Evaluate(string expressionString)
 {
     ExpressionEval expression = new ExpressionEval(expressionString);
     return expression.Evaluate();
 }
Example #8
0
        /// <summary>
        /// This will search the expression for the next token (operand, operator, etc)
        /// </summary>
        /// <param name="nIdx">Start Position of Search</param>
        /// <returns>First character index after token.</returns>
        //[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
        private int NextToken(int nIdx)
        {
            Match mRet = null;
            int nRet = nIdx;
            object val = null;

            //Check for preceeding white space from last token index
            Match m = DefinedRegex.WhiteSpace.Match(Expression, nIdx);
            if (m.Success && m.Index == nIdx)
                return nIdx + m.Length;

            //Check Parenthesis
            m = DefinedRegex.Parenthesis.Match(Expression, nIdx);
            if (m.Success)
                mRet = m;

            //Check Function
            if (mRet == null || mRet.Index > nIdx)
            {
                m = DefinedRegex.Function.Match(Expression, nIdx);
                if (m.Success && (mRet == null || m.Index < mRet.Index))
                    mRet = m;
            }

            //Check Variable
            if (mRet == null || mRet.Index > nIdx)
            {
                m = DefinedRegex.Variable.Match(Expression, nIdx);
                if (m.Success && (mRet == null || m.Index < mRet.Index))
                { mRet = m; val = new Variable(m.Groups["Variable"].Value, _variables); }
            }

            //Check Unary Operator
            if (mRet == null || mRet.Index > nIdx)
            {
                m = DefinedRegex.UnaryOp.Match(Expression, nIdx);
                if (m.Success && (mRet == null || m.Index < mRet.Index))
                { mRet = m; val = new UnaryOp(m.Value); }
            }

            //Check Hexadecimal
            if (mRet == null || mRet.Index > nIdx)
            {
                m = DefinedRegex.Hexadecimal.Match(Expression, nIdx);
                if (m.Success && (mRet == null || m.Index < mRet.Index))
                { mRet = m; val = Convert.ToInt32(m.Value, 16); }
            }

            //Check Boolean
            if (mRet == null || mRet.Index > nIdx)
            {
                m = DefinedRegex.Boolean.Match(Expression, nIdx);
                if (m.Success && (mRet == null || m.Index < mRet.Index))
                { mRet = m; val = bool.Parse(m.Value); }
            }

            //Check DateTime
            if (mRet == null || mRet.Index > nIdx)
            {
                m = DefinedRegex.DateTime.Match(Expression, nIdx);
                if (m.Success && (mRet == null || m.Index < mRet.Index))
                { mRet = m; val = Convert.ToDateTime(m.Groups["DateString"].Value, CultureInfo.CurrentCulture); }
            }

            //Check Timespan
            if (mRet == null || mRet.Index > nIdx)
            {
                m = DefinedRegex.TimeSpan.Match(Expression, nIdx);
                if (m.Success && (mRet == null || m.Index < mRet.Index))
                {
                    mRet = m;
                    val = new TimeSpan(
                        int.Parse("0" + m.Groups["Days"].Value),
                        int.Parse(m.Groups["Hours"].Value),
                        int.Parse(m.Groups["Minutes"].Value),
                        int.Parse("0" + m.Groups["Seconds"].Value),
                        int.Parse("0" + m.Groups["Milliseconds"].Value)
                    );
                }
            }

            //Check Numeric
            if (mRet == null || mRet.Index > nIdx)
            {
                m = DefinedRegex.Numeric.Match(Expression, nIdx);
                if (m.Success && (mRet == null || m.Index < mRet.Index))
                {
                    while (m.Success && ("" + m.Value == ""))
                        m = m.NextMatch();
                    if (m.Success)
                    {
                        mRet = m;
                        val = double.Parse(m.Value, CultureInfo.CurrentCulture);
                    }
                }
            }

            if (mRet == null || mRet.Index > nIdx)
            {
                //Check String
                m = DefinedRegex.String.Match(Expression, nIdx);
                if (m.Success && (mRet == null || m.Index < mRet.Index))
                { mRet = m; val = m.Groups["String"].Value.Replace("\\\"", "\""); }
            }

            //Check Binary Operator
            if (mRet == null || mRet.Index > nIdx)
            {
                m = DefinedRegex.BinaryOp.Match(Expression, nIdx);
                if (m.Success && (mRet == null || m.Index < mRet.Index))
                { mRet = m; val = new BinaryOp(m.Value); }
            }

            if (mRet == null)
                throw new ArgumentException("Invalid expression construction: \"" + Expression + "\".");

            if (mRet.Index != nIdx)
            {
                throw new ArgumentException(
                    "Invalid token in expression: [" +
                        Expression.Substring(nIdx, mRet.Index - nIdx).Trim() + "]"
                );
            }

            if (mRet.Value == "(" || mRet.Value.StartsWith("$"))
            {
                nRet = mRet.Index + mRet.Length;
                int nDepth = 1;
                bool bInQuotes = false;
                while (nDepth > 0)
                {
                    if (nRet >= Expression.Length)
                        throw new ArgumentException("Missing " + (bInQuotes ? "\"" : ")") + " in Expression");
                    if (!bInQuotes && Expression[nRet] == ')')
                        nDepth--;
                    if (!bInQuotes && Expression[nRet] == '(')
                        nDepth++;

                    if (Expression[nRet] == '"' && (nRet == 0 || Expression[nRet - 1] != '\\'))
                        bInQuotes = !bInQuotes;

                    nRet++;
                }
                if (mRet.Value == "(")
                {
                    ExpressionEval expr = new ExpressionEval(
                        Expression.Substring(mRet.Index + 1, nRet - mRet.Index - 2)
                    );
                    if (this.AdditionalFunctionEventHandler != null)
                        expr.AdditionalFunctionEventHandler += this.AdditionalFunctionEventHandler;
                    expr._variables = this._variables;
                    _expressionlist.Add(expr);
                }
                else
                {
                    FunctionEval func = new FunctionEval(
                        Expression.Substring(mRet.Index, (nRet) - mRet.Index)
                    );
                    if (this.AdditionalFunctionEventHandler != null)
                        func.AdditionalFunctionEventHandler += this.AdditionalFunctionEventHandler;
                    func._variables = this._variables;
                    _expressionlist.Add(func);
                }
            }
            else
            {
                nRet = mRet.Index + mRet.Length;
                _expressionlist.Add(val);
            }

            return nRet;
        }