summaryrefslogtreecommitdiff
path: root/plugins/Popup/src/formula.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/Popup/src/formula.cpp')
-rw-r--r--plugins/Popup/src/formula.cpp177
1 files changed, 177 insertions, 0 deletions
diff --git a/plugins/Popup/src/formula.cpp b/plugins/Popup/src/formula.cpp
new file mode 100644
index 0000000000..37002c9d18
--- /dev/null
+++ b/plugins/Popup/src/formula.cpp
@@ -0,0 +1,177 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/formula.cpp $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+
+static inline bool myisspace(char ch)
+{
+ return (ch >= 0) && (ch <= 32);
+}
+
+int Formula::eval_neq(char *&s, Args *args, bool *vars) const
+{
+ int left = eval_sum(s, args, vars);
+ while (*s)
+ {
+ if (myisspace(*s))
+ {
+ ++s;
+ } else
+ if (*s == '<')
+ {
+ // this is needed due to side effects caused by min() macro...
+ int tmp = eval_sum(++s, args, vars);
+ left = min(left, tmp);
+ } else
+ if (*s == '>')
+ {
+ // this is needed due to side effects caused by max() macro...
+ int tmp = eval_sum(++s, args, vars);
+ left = max(left, tmp);
+ } else
+ {
+ break;
+ }
+ }
+ return left;
+}
+
+int Formula::eval_sum(char *&s, Args *args, bool *vars) const
+{
+ int left = eval_mul(s, args, vars);
+ while (*s)
+ {
+ if (myisspace(*s))
+ {
+ ++s;
+ } else
+ if (*s == '+')
+ {
+ left += eval_mul(++s, args, vars);
+ } else
+ if (*s == '-')
+ {
+ left -= eval_mul(++s, args, vars);
+ } else
+ {
+ break;
+ }
+ }
+ return left;
+}
+
+int Formula::eval_mul(char *&s, Args *args, bool *vars) const
+{
+ int left = eval_atom(s, args, vars);
+ while (*s)
+ {
+ if (myisspace(*s))
+ {
+ ++s;
+ } else
+ if(*s == '*')
+ {
+ left *= eval_atom(++s, args, vars);
+ } else
+ if(*s == '/')
+ {
+ if (int right = eval_atom(++s, args, vars))
+ left /= right;
+ } else
+ if(*s == '%')
+ {
+ if (int right = eval_atom(++s, args, vars))
+ left %= right;
+ } else
+ {
+ break;
+ }
+ }
+ return left;
+}
+
+int Formula::eval_atom(char *&s, Args *args, bool *vars) const
+{
+ while (*s)
+ {
+ if (myisspace(*s))
+ {
+ ++s;
+ } else
+ if (*s == '(')
+ {
+ int res = eval_neq(++s, args, vars);
+ if (*s == ')')
+ ++s;
+ return res;
+ } else
+ if ((*s == '+') || (*s == '-'))
+ {
+ int sign = 1;
+ if (*s == '-')
+ sign = -1;
+ return sign * eval_neq(++s, args, vars);
+ } else
+ if (*s == '!')
+ {
+ return !eval_neq(++s, args, vars);
+ } else
+ if ((*s >= '0') && (*s <= '9'))
+ {
+ int res = 0;
+ while ((*s >= '0') && (*s <= '9'))
+ res = res * 10 + *s++ - '0';
+ return res;
+ } else
+ {
+ if (!args)
+ return 0;
+ char buf[1024];
+ char *bufptr = buf;
+ while (((*s >= '0') && (*s <= '9')) || ((*s >= 'a') && (*s <= 'z')) || ((*s >= 'A') && (*s <= 'A')) || (*s == '_') || (*s == '.'))
+ *bufptr++ = *s++;
+ *bufptr = 0;
+ int res = args->get(buf);
+ if (vars) *vars = true;
+ return res;
+ }
+ }
+ return 0;
+}
+
+int Formula::eval(Args *args, bool *vars) const
+{
+ if (vars) *vars = false;
+ char *s = m_str;
+ int res = eval_neq(s, args, vars);
+ return res;
+}