7C1409A4183224B8009F9411 /* SettingUpdate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C140987183224B8009F9411 /* SettingUpdate.cpp */; };
7C1409A5183224B8009F9411 /* SettingUpdate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C140987183224B8009F9411 /* SettingUpdate.cpp */; };
7C1409A6183224B8009F9411 /* SettingUpdate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C140987183224B8009F9411 /* SettingUpdate.cpp */; };
+ 7C1409A9184015C9009F9411 /* InfoExpression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C1409A7184015C6009F9411 /* InfoExpression.cpp */; };
+ 7C1409AA184015C9009F9411 /* InfoExpression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C1409A7184015C6009F9411 /* InfoExpression.cpp */; };
+ 7C1409AB184015C9009F9411 /* InfoExpression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C1409A7184015C6009F9411 /* InfoExpression.cpp */; };
7C1A492315A962EE004AF4A4 /* SeekHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C1A492115A962EE004AF4A4 /* SeekHandler.cpp */; };
7C1A85661520522500C63311 /* TextureCacheJob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C1A85631520522500C63311 /* TextureCacheJob.cpp */; };
7C1D682915A7D2FD00658B65 /* DatabaseManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C1D682715A7D2FD00658B65 /* DatabaseManager.cpp */; };
7C84A59E12FA3C1600CD1714 /* SourcesDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C84A59C12FA3C1600CD1714 /* SourcesDirectory.cpp */; };
7C87B2CE162CE39600EF897D /* PlayerController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C87B2CC162CE39600EF897D /* PlayerController.cpp */; };
7C89619213B6A16F003631FE /* GUIWindowScreensaverDim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C89619013B6A16F003631FE /* GUIWindowScreensaverDim.cpp */; };
- 7C89674613C03B22003631FE /* InfoBool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C89674313C03B22003631FE /* InfoBool.cpp */; };
7C8A14571154CB2600E5FCFA /* TextureCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8A14541154CB2600E5FCFA /* TextureCache.cpp */; };
7C8A187D115B2A8200E5FCFA /* TextureDatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8A187A115B2A8200E5FCFA /* TextureDatabase.cpp */; };
7C8FC6EE1829A4580045153D /* DirectoryProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8FC6EC1829A4580045153D /* DirectoryProvider.cpp */; };
DFF0F2C817528350002DA3A4 /* XBTFReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C7A81294222E009E7A26 /* XBTFReader.cpp */; };
DFF0F2C917528350002DA3A4 /* GenericTouchActionHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4991334174E5E5C00741B6D /* GenericTouchActionHandler.cpp */; };
DFF0F2CA17528350002DA3A4 /* ITouchInputHandling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4991342174E5E5C00741B6D /* ITouchInputHandling.cpp */; };
- DFF0F2CB17528350002DA3A4 /* InfoBool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C89674313C03B22003631FE /* InfoBool.cpp */; };
DFF0F2CC17528350002DA3A4 /* SkinVariable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF98D98A1434F47D00A6EBE1 /* SkinVariable.cpp */; };
DFF0F2CD17528350002DA3A4 /* AddonsOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB0F470161B747500D744F4 /* AddonsOperations.cpp */; };
DFF0F2CE17528350002DA3A4 /* ApplicationOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18968DC614155D7C005BA742 /* ApplicationOperations.cpp */; };
E4991331174E5DAD00741B6D /* XBTFReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C7A81294222E009E7A26 /* XBTFReader.cpp */; };
E4991345174E5E5C00741B6D /* GenericTouchActionHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4991334174E5E5C00741B6D /* GenericTouchActionHandler.cpp */; };
E499134B174E5E5C00741B6D /* ITouchInputHandling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4991342174E5E5C00741B6D /* ITouchInputHandling.cpp */; };
- E499134C174E5EB700741B6D /* InfoBool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C89674313C03B22003631FE /* InfoBool.cpp */; };
E499134D174E5EB700741B6D /* SkinVariable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF98D98A1434F47D00A6EBE1 /* SkinVariable.cpp */; };
E499134E174E5EBE00741B6D /* AddonsOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB0F470161B747500D744F4 /* AddonsOperations.cpp */; };
E499134F174E5EBE00741B6D /* ApplicationOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18968DC614155D7C005BA742 /* ApplicationOperations.cpp */; };
7C140986183224B8009F9411 /* SettingsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SettingsManager.h; path = lib/SettingsManager.h; sourceTree = "<group>"; };
7C140987183224B8009F9411 /* SettingUpdate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SettingUpdate.cpp; path = lib/SettingUpdate.cpp; sourceTree = "<group>"; };
7C140988183224B8009F9411 /* SettingUpdate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SettingUpdate.h; path = lib/SettingUpdate.h; sourceTree = "<group>"; };
+ 7C1409A7184015C6009F9411 /* InfoExpression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InfoExpression.cpp; sourceTree = "<group>"; };
+ 7C1409A8184015C8009F9411 /* InfoExpression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InfoExpression.h; sourceTree = "<group>"; };
7C1A492115A962EE004AF4A4 /* SeekHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SeekHandler.cpp; sourceTree = "<group>"; };
7C1A492215A962EE004AF4A4 /* SeekHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SeekHandler.h; sourceTree = "<group>"; };
7C1A495B15A96918004AF4A4 /* SaveFileStateJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SaveFileStateJob.h; sourceTree = "<group>"; };
7C87B2CD162CE39600EF897D /* PlayerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerController.h; sourceTree = "<group>"; };
7C89619013B6A16F003631FE /* GUIWindowScreensaverDim.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIWindowScreensaverDim.cpp; sourceTree = "<group>"; };
7C89619113B6A16F003631FE /* GUIWindowScreensaverDim.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIWindowScreensaverDim.h; sourceTree = "<group>"; };
- 7C89674313C03B22003631FE /* InfoBool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InfoBool.cpp; sourceTree = "<group>"; };
7C89674413C03B22003631FE /* InfoBool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InfoBool.h; sourceTree = "<group>"; };
7C8A14541154CB2600E5FCFA /* TextureCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextureCache.cpp; sourceTree = "<group>"; };
7C8A14551154CB2600E5FCFA /* TextureCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextureCache.h; sourceTree = "<group>"; };
7C89674213C03B21003631FE /* info */ = {
isa = PBXGroup;
children = (
- 7C89674313C03B22003631FE /* InfoBool.cpp */,
7C89674413C03B22003631FE /* InfoBool.h */,
+ 7C1409A7184015C6009F9411 /* InfoExpression.cpp */,
+ 7C1409A8184015C8009F9411 /* InfoExpression.h */,
DF98D98A1434F47D00A6EBE1 /* SkinVariable.cpp */,
DF98D98B1434F47D00A6EBE1 /* SkinVariable.h */,
);
38F4E57013CCCB3B00664821 /* Implementation.cpp in Sources */,
3802709A13D5A653009493DD /* SystemClock.cpp in Sources */,
7CEE2E5B13D6B71E000ABF2A /* TimeSmoother.cpp in Sources */,
- 7C89674613C03B22003631FE /* InfoBool.cpp in Sources */,
DFAB049813F8376700B70BFB /* InertialScrollingHandler.cpp in Sources */,
DF3488E713FD958F0026A711 /* GUIAction.cpp in Sources */,
DF34892A13FD9C780026A711 /* AirPlayServer.cpp in Sources */,
7C1409A1183224B8009F9411 /* SettingsManager.cpp in Sources */,
7C1409A4183224B8009F9411 /* SettingUpdate.cpp in Sources */,
DF0ABB73183A94A30018445D /* Utf8Utils.cpp in Sources */,
+ 7C1409A9184015C9009F9411 /* InfoExpression.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
DFF0F2C817528350002DA3A4 /* XBTFReader.cpp in Sources */,
DFF0F2C917528350002DA3A4 /* GenericTouchActionHandler.cpp in Sources */,
DFF0F2CA17528350002DA3A4 /* ITouchInputHandling.cpp in Sources */,
- DFF0F2CB17528350002DA3A4 /* InfoBool.cpp in Sources */,
DFF0F2CC17528350002DA3A4 /* SkinVariable.cpp in Sources */,
DFF0F2CD17528350002DA3A4 /* AddonsOperations.cpp in Sources */,
DFF0F2CE17528350002DA3A4 /* ApplicationOperations.cpp in Sources */,
7C1409A3183224B8009F9411 /* SettingsManager.cpp in Sources */,
7C1409A6183224B8009F9411 /* SettingUpdate.cpp in Sources */,
DF0ABB75183A94A30018445D /* Utf8Utils.cpp in Sources */,
+ 7C1409AB184015C9009F9411 /* InfoExpression.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
E4991331174E5DAD00741B6D /* XBTFReader.cpp in Sources */,
E4991345174E5E5C00741B6D /* GenericTouchActionHandler.cpp in Sources */,
E499134B174E5E5C00741B6D /* ITouchInputHandling.cpp in Sources */,
- E499134C174E5EB700741B6D /* InfoBool.cpp in Sources */,
E499134D174E5EB700741B6D /* SkinVariable.cpp in Sources */,
E499134E174E5EBE00741B6D /* AddonsOperations.cpp in Sources */,
E499134F174E5EBE00741B6D /* ApplicationOperations.cpp in Sources */,
7C1409A2183224B8009F9411 /* SettingsManager.cpp in Sources */,
7C1409A5183224B8009F9411 /* SettingUpdate.cpp in Sources */,
DF0ABB74183A94A30018445D /* Utf8Utils.cpp in Sources */,
+ 7C1409AA184015C9009F9411 /* InfoExpression.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
<ClCompile Include="..\..\xbmc\interfaces\Builtins.cpp" />
<ClCompile Include="..\..\xbmc\interfaces\generic\LanguageInvokerThread.cpp" />
<ClCompile Include="..\..\xbmc\interfaces\generic\ScriptInvocationManager.cpp" />
- <ClCompile Include="..\..\xbmc\interfaces\info\InfoBool.cpp" />
+ <ClCompile Include="..\..\xbmc\interfaces\info\InfoExpression.cpp" />
<ClCompile Include="..\..\xbmc\interfaces\info\SkinVariable.cpp" />
<ClCompile Include="..\..\xbmc\interfaces\json-rpc\AddonsOperations.cpp" />
<ClCompile Include="..\..\xbmc\interfaces\json-rpc\ApplicationOperations.cpp" />
<ClInclude Include="..\..\xbmc\interfaces\Builtins.h" />
<ClInclude Include="..\..\xbmc\interfaces\IAnnouncer.h" />
<ClInclude Include="..\..\xbmc\interfaces\info\InfoBool.h" />
+ <ClInclude Include="..\..\xbmc\interfaces\info\InfoExpression.h" />
<ClInclude Include="..\..\xbmc\interfaces\info\SkinVariable.h" />
<ClInclude Include="..\..\xbmc\interfaces\json-rpc\ApplicationOperations.h" />
<ClInclude Include="..\..\xbmc\interfaces\json-rpc\AudioLibrary.h" />
</VisualStudio>
</ProjectExtensions>
<Import Project="$(SolutionDir)\$(ProjectFileName).targets.user" Condition="Exists('$(SolutionDir)\$(ProjectFileName).targets.user')" />
-</Project>
\ No newline at end of file
+</Project>
<ClCompile Include="..\..\xbmc\input\InertialScrollingHandler.cpp">
<Filter>input</Filter>
</ClCompile>
- <ClCompile Include="..\..\xbmc\interfaces\info\InfoBool.cpp">
+ <ClCompile Include="..\..\xbmc\interfaces\info\InfoExpression.cpp">
<Filter>interfaces\info</Filter>
</ClCompile>
<ClCompile Include="..\..\xbmc\guilib\GUIAction.cpp">
<ClInclude Include="..\..\xbmc\interfaces\info\InfoBool.h">
<Filter>interfaces\info</Filter>
</ClInclude>
+ <ClInclude Include="..\..\xbmc\interfaces\info\InfoExpression.h">
+ <Filter>interfaces\info</Filter>
+ </ClInclude>
<ClInclude Include="..\..\xbmc\guilib\GUIAction.h">
<Filter>guilib</Filter>
</ClInclude>
<Filter>interfaces\swig</Filter>
</None>
</ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
#include "cores/IPlayer.h"
#include "cores/AudioEngine/Utils/AEUtil.h"
#include "cores/VideoRenderers/BaseRenderer.h"
+#include "interfaces/info/InfoExpression.h"
#if defined(TARGET_DARWIN_OSX)
#include "osx/smc.h"
+++ /dev/null
-/*
- * Copyright (C) 2005-2013 Team XBMC
- * http://xbmc.org
- *
- * 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, 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 XBMC; see the file COPYING. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "InfoBool.h"
-#include <stack>
-#include "utils/log.h"
-#include "GUIInfoManager.h"
-
-using namespace std;
-using namespace INFO;
-
-InfoSingle::InfoSingle(const std::string &expression, int context)
-: InfoBool(expression, context)
-{
- m_condition = g_infoManager.TranslateSingleString(expression);
-}
-
-void InfoSingle::Update(const CGUIListItem *item)
-{
- m_value = g_infoManager.GetBool(m_condition, m_context, item);
-}
-
-InfoExpression::InfoExpression(const std::string &expression, int context)
-: InfoBool(expression, context)
-{
- Parse(expression);
-}
-
-void InfoExpression::Update(const CGUIListItem *item)
-{
- Evaluate(item, m_value);
-}
-
-#define OPERATOR_LB 5
-#define OPERATOR_RB 4
-#define OPERATOR_NOT 3
-#define OPERATOR_AND 2
-#define OPERATOR_OR 1
-
-short InfoExpression::GetOperator(const char ch) const
-{
- if (ch == '[')
- return OPERATOR_LB;
- else if (ch == ']')
- return OPERATOR_RB;
- else if (ch == '!')
- return OPERATOR_NOT;
- else if (ch == '+')
- return OPERATOR_AND;
- else if (ch == '|')
- return OPERATOR_OR;
- else
- return 0;
-}
-
-void InfoExpression::Parse(const std::string &expression)
-{
- stack<char> operators;
- std::string operand;
- for (unsigned int i = 0; i < expression.size(); i++)
- {
- if (GetOperator(expression[i]))
- {
- // cleanup any operand, translate and put into our expression list
- if (!operand.empty())
- {
- unsigned int info = g_infoManager.Register(operand, m_context);
- if (info)
- {
- m_postfix.push_back(m_operands.size());
- m_operands.push_back(info);
- }
- operand.clear();
- }
- // handle closing parenthesis
- if (expression[i] == ']')
- {
- while (!operators.empty())
- {
- char oper = operators.top();
- operators.pop();
-
- if (oper == '[')
- break;
-
- m_postfix.push_back(-GetOperator(oper)); // negative denotes operator
- }
- }
- else
- {
- // all other operators we pop off the stack any operator
- // that has a higher priority than the one we have.
- while (!operators.empty() && GetOperator(operators.top()) > GetOperator(expression[i]))
- {
- // only handle parenthesis once they're closed.
- if (operators.top() == '[' && expression[i] != ']')
- break;
-
- m_postfix.push_back(-GetOperator(operators.top())); // negative denotes operator
- operators.pop();
- }
- operators.push(expression[i]);
- }
- }
- else
- {
- operand += expression[i];
- }
- }
-
- if (!operand.empty())
- {
- unsigned int info = g_infoManager.Register(operand, m_context);
- if (info)
- {
- m_postfix.push_back(m_operands.size());
- m_operands.push_back(info);
- }
- }
-
- // finish up by adding any operators
- while (!operators.empty())
- {
- m_postfix.push_back(-GetOperator(operators.top())); // negative denotes operator
- operators.pop();
- }
-
- // test evaluate
- bool test;
- if (!Evaluate(NULL, test))
- CLog::Log(LOGERROR, "Error evaluating boolean expression %s", expression.c_str());
-}
-
-bool InfoExpression::Evaluate(const CGUIListItem *item, bool &result)
-{
- stack<bool> save;
- for (vector<short>::const_iterator it = m_postfix.begin(); it != m_postfix.end(); ++it)
- {
- short expr = *it;
- if (expr == -OPERATOR_NOT)
- { // NOT the top item on the stack
- if (save.empty()) return false;
- bool expr = save.top();
- save.pop();
- save.push(!expr);
- }
- else if (expr == -OPERATOR_AND)
- { // AND the top two items on the stack
- if (save.size() < 2) return false;
- bool right = save.top(); save.pop();
- bool left = save.top(); save.pop();
- save.push(left && right);
- }
- else if (expr == -OPERATOR_OR)
- { // OR the top two items on the stack
- if (save.size() < 2) return false;
- bool right = save.top(); save.pop();
- bool left = save.top(); save.pop();
- save.push(left || right);
- }
- else // operand
- save.push(g_infoManager.GetBoolValue(m_operands[expr], item));
- }
- if (save.size() != 1)
- return false;
- result = save.top();
- return true;
-}
-
#pragma once
-#include <vector>
-#include <map>
#include <string>
class CGUIListItem;
unsigned int m_lastUpdate; ///< last update time (to determine dirty status)
};
-/*! \brief Class to wrap active boolean conditions
- */
-class InfoSingle : public InfoBool
-{
-public:
- InfoSingle(const std::string &condition, int context);
- virtual ~InfoSingle() {};
-
- virtual void Update(const CGUIListItem *item);
-private:
- int m_condition; ///< actual condition this represents
-};
-
-/*! \brief Class to wrap active boolean expressions
- */
-class InfoExpression : public InfoBool
-{
-public:
- InfoExpression(const std::string &expression, int context);
- virtual ~InfoExpression() {};
-
- virtual void Update(const CGUIListItem *item);
-private:
- void Parse(const std::string &expression);
- bool Evaluate(const CGUIListItem *item, bool &result);
- short GetOperator(const char ch) const;
-
- std::vector<short> m_postfix; ///< the postfix form of the expression (operators and operand indicies)
- std::vector<unsigned int> m_operands; ///< the operands in the expression
-};
-
};
--- /dev/null
+/*
+ * Copyright (C) 2005-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * 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, 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 XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "InfoExpression.h"
+#include <stack>
+#include "utils/log.h"
+#include "GUIInfoManager.h"
+
+using namespace std;
+using namespace INFO;
+
+InfoSingle::InfoSingle(const std::string &expression, int context)
+: InfoBool(expression, context)
+{
+ m_condition = g_infoManager.TranslateSingleString(expression);
+}
+
+void InfoSingle::Update(const CGUIListItem *item)
+{
+ m_value = g_infoManager.GetBool(m_condition, m_context, item);
+}
+
+InfoExpression::InfoExpression(const std::string &expression, int context)
+: InfoBool(expression, context)
+{
+ Parse(expression);
+}
+
+void InfoExpression::Update(const CGUIListItem *item)
+{
+ Evaluate(item, m_value);
+}
+
+#define OPERATOR_LB 5
+#define OPERATOR_RB 4
+#define OPERATOR_NOT 3
+#define OPERATOR_AND 2
+#define OPERATOR_OR 1
+
+short InfoExpression::GetOperator(const char ch) const
+{
+ if (ch == '[')
+ return OPERATOR_LB;
+ else if (ch == ']')
+ return OPERATOR_RB;
+ else if (ch == '!')
+ return OPERATOR_NOT;
+ else if (ch == '+')
+ return OPERATOR_AND;
+ else if (ch == '|')
+ return OPERATOR_OR;
+ else
+ return 0;
+}
+
+void InfoExpression::Parse(const std::string &expression)
+{
+ stack<char> operators;
+ std::string operand;
+ for (unsigned int i = 0; i < expression.size(); i++)
+ {
+ if (GetOperator(expression[i]))
+ {
+ // cleanup any operand, translate and put into our expression list
+ if (!operand.empty())
+ {
+ unsigned int info = g_infoManager.Register(operand, m_context);
+ if (info)
+ {
+ m_postfix.push_back(m_operands.size());
+ m_operands.push_back(info);
+ }
+ operand.clear();
+ }
+ // handle closing parenthesis
+ if (expression[i] == ']')
+ {
+ while (!operators.empty())
+ {
+ char oper = operators.top();
+ operators.pop();
+
+ if (oper == '[')
+ break;
+
+ m_postfix.push_back(-GetOperator(oper)); // negative denotes operator
+ }
+ }
+ else
+ {
+ // all other operators we pop off the stack any operator
+ // that has a higher priority than the one we have.
+ while (!operators.empty() && GetOperator(operators.top()) > GetOperator(expression[i]))
+ {
+ // only handle parenthesis once they're closed.
+ if (operators.top() == '[' && expression[i] != ']')
+ break;
+
+ m_postfix.push_back(-GetOperator(operators.top())); // negative denotes operator
+ operators.pop();
+ }
+ operators.push(expression[i]);
+ }
+ }
+ else
+ {
+ operand += expression[i];
+ }
+ }
+
+ if (!operand.empty())
+ {
+ unsigned int info = g_infoManager.Register(operand, m_context);
+ if (info)
+ {
+ m_postfix.push_back(m_operands.size());
+ m_operands.push_back(info);
+ }
+ }
+
+ // finish up by adding any operators
+ while (!operators.empty())
+ {
+ m_postfix.push_back(-GetOperator(operators.top())); // negative denotes operator
+ operators.pop();
+ }
+
+ // test evaluate
+ bool test;
+ if (!Evaluate(NULL, test))
+ CLog::Log(LOGERROR, "Error evaluating boolean expression %s", expression.c_str());
+}
+
+bool InfoExpression::Evaluate(const CGUIListItem *item, bool &result)
+{
+ stack<bool> save;
+ for (vector<short>::const_iterator it = m_postfix.begin(); it != m_postfix.end(); ++it)
+ {
+ short expr = *it;
+ if (expr == -OPERATOR_NOT)
+ { // NOT the top item on the stack
+ if (save.empty()) return false;
+ bool expr = save.top();
+ save.pop();
+ save.push(!expr);
+ }
+ else if (expr == -OPERATOR_AND)
+ { // AND the top two items on the stack
+ if (save.size() < 2) return false;
+ bool right = save.top(); save.pop();
+ bool left = save.top(); save.pop();
+ save.push(left && right);
+ }
+ else if (expr == -OPERATOR_OR)
+ { // OR the top two items on the stack
+ if (save.size() < 2) return false;
+ bool right = save.top(); save.pop();
+ bool left = save.top(); save.pop();
+ save.push(left || right);
+ }
+ else // operand
+ save.push(g_infoManager.GetBoolValue(m_operands[expr], item));
+ }
+ if (save.size() != 1)
+ return false;
+ result = save.top();
+ return true;
+}
+
--- /dev/null
+/*
+ * Copyright (C) 2005-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * 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, 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 XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#pragma once
+
+#include <vector>
+#include "InfoBool.h"
+
+class CGUIListItem;
+
+namespace INFO
+{
+/*! \brief Class to wrap active boolean conditions
+ */
+class InfoSingle : public InfoBool
+{
+public:
+ InfoSingle(const std::string &condition, int context);
+ virtual ~InfoSingle() {};
+
+ virtual void Update(const CGUIListItem *item);
+private:
+ int m_condition; ///< actual condition this represents
+};
+
+/*! \brief Class to wrap active boolean expressions
+ */
+class InfoExpression : public InfoBool
+{
+public:
+ InfoExpression(const std::string &expression, int context);
+ virtual ~InfoExpression() {};
+
+ virtual void Update(const CGUIListItem *item);
+private:
+ void Parse(const std::string &expression);
+ bool Evaluate(const CGUIListItem *item, bool &result);
+ short GetOperator(const char ch) const;
+
+ std::vector<short> m_postfix; ///< the postfix form of the expression (operators and operand indicies)
+ std::vector<unsigned int> m_operands; ///< the operands in the expression
+};
+
+};
-SRCS=InfoBool.cpp \
+SRCS=InfoExpression.cpp \
SkinVariable.cpp \
LIB=info.a