From 34692ab826abc8f8faa61bdb2280b742424528f1 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 7 Dec 2013 15:14:29 -0500 Subject: Remove unnecessary Src/ folders --- .../ControllerInterface/ExpressionParser.cpp | 577 +++++++++++++++++++++ 1 file changed, 577 insertions(+) create mode 100644 Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp (limited to 'Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp') diff --git a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp new file mode 100644 index 0000000000..b313559907 --- /dev/null +++ b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp @@ -0,0 +1,577 @@ + +#include "ExpressionParser.h" + +#include +#include +#include +#include +#include + +using namespace ciface::Core; + +namespace ciface +{ +namespace ExpressionParser +{ + +enum TokenType +{ + TOK_DISCARD, + TOK_INVALID, + TOK_EOF, + TOK_LPAREN, + TOK_RPAREN, + TOK_AND, + TOK_OR, + TOK_NOT, + TOK_ADD, + TOK_CONTROL, +}; + +inline std::string OpName(TokenType op) +{ + switch (op) + { + case TOK_AND: + return "And"; + case TOK_OR: + return "Or"; + case TOK_NOT: + return "Not"; + case TOK_ADD: + return "Add"; + default: + assert(false); + return ""; + } +} + +class Token +{ +public: + TokenType type; + ControlQualifier qualifier; + + Token(TokenType type_) : type(type_) {} + Token(TokenType type_, ControlQualifier qualifier_) : type(type_), qualifier(qualifier_) {} + + operator std::string() + { + switch (type) + { + case TOK_INVALID: + return "Invalid"; + case TOK_DISCARD: + return "Discard"; + case TOK_EOF: + return "EOF"; + case TOK_LPAREN: + return "("; + case TOK_RPAREN: + return ")"; + case TOK_AND: + return "&"; + case TOK_OR: + return "|"; + case TOK_NOT: + return "!"; + case TOK_ADD: + return "+"; + case TOK_CONTROL: + return "Device(" + (std::string)qualifier + ")"; + } + } +}; + +class Lexer { +public: + std::string expr; + std::string::iterator it; + + Lexer(std::string expr_) : expr(expr_) + { + it = expr.begin(); + } + + bool FetchBacktickString(std::string &value, char otherDelim = 0) + { + value = ""; + while (it != expr.end()) + { + char c = *it; + it++; + if (c == '`') + return false; + if (c > 0 && c == otherDelim) + return true; + value += c; + } + return false; + } + + Token GetFullyQualifiedControl() + { + ControlQualifier qualifier; + std::string value; + + if (FetchBacktickString(value, ':')) + { + // Found colon, this is the device name + qualifier.has_device = true; + qualifier.device_qualifier.FromString(value); + FetchBacktickString(value); + } + + qualifier.control_name = value; + + return Token(TOK_CONTROL, qualifier); + } + + Token GetBarewordsControl(char c) + { + std::string name; + name += c; + + while (it != expr.end()) { + c = *it; + if (!isalpha(c)) + break; + name += c; + it++; + } + + ControlQualifier qualifier; + qualifier.control_name = name; + return Token(TOK_CONTROL, qualifier); + } + + Token NextToken() + { + if (it == expr.end()) + return Token(TOK_EOF); + + char c = *it++; + switch (c) + { + case ' ': + case '\t': + case '\n': + case '\r': + return Token(TOK_DISCARD); + case '(': + return Token(TOK_LPAREN); + case ')': + return Token(TOK_RPAREN); + case '&': + return Token(TOK_AND); + case '|': + return Token(TOK_OR); + case '!': + return Token(TOK_NOT); + case '+': + return Token(TOK_ADD); + case '`': + return GetFullyQualifiedControl(); + default: + if (isalpha(c)) + return GetBarewordsControl(c); + else + return Token(TOK_INVALID); + } + } + + ExpressionParseStatus Tokenize(std::vector &tokens) + { + while (true) + { + Token tok = NextToken(); + + if (tok.type == TOK_DISCARD) + continue; + + if (tok.type == TOK_INVALID) + { + tokens.clear(); + return EXPRESSION_PARSE_SYNTAX_ERROR; + } + + tokens.push_back(tok); + + if (tok.type == TOK_EOF) + break; + } + return EXPRESSION_PARSE_SUCCESS; + } +}; + +class ExpressionNode +{ +public: + virtual ~ExpressionNode() {} + virtual ControlState GetValue() { return 0; } + virtual void SetValue(ControlState state) {} + virtual int CountNumControls() { return 0; } + virtual operator std::string() { return ""; } +}; + +class ControlExpression : public ExpressionNode +{ +public: + ControlQualifier qualifier; + Device::Control *control; + + ControlExpression(ControlQualifier qualifier_, Device::Control *control_) : qualifier(qualifier_), control(control_) {} + + virtual ControlState GetValue() override + { + return control->ToInput()->GetState(); + } + + virtual void SetValue(ControlState value) override + { + control->ToOutput()->SetState(value); + } + + virtual int CountNumControls() override + { + return 1; + } + + virtual operator std::string() override + { + return "`" + (std::string)qualifier + "`"; + } +}; + +class BinaryExpression : public ExpressionNode +{ +public: + TokenType op; + ExpressionNode *lhs; + ExpressionNode *rhs; + + BinaryExpression(TokenType op_, ExpressionNode *lhs_, ExpressionNode *rhs_) : op(op_), lhs(lhs_), rhs(rhs_) {} + virtual ~BinaryExpression() + { + delete lhs; + delete rhs; + } + + virtual ControlState GetValue() override + { + ControlState lhsValue = lhs->GetValue(); + ControlState rhsValue = rhs->GetValue(); + switch (op) + { + case TOK_AND: + return std::min(lhsValue, rhsValue); + case TOK_OR: + return std::max(lhsValue, rhsValue); + case TOK_ADD: + return std::min(lhsValue + rhsValue, 1.0f); + default: + assert(false); + return 0; + } + } + + virtual void SetValue(ControlState value) override + { + // Don't do anything special with the op we have. + // Treat "A & B" the same as "A | B". + lhs->SetValue(value); + rhs->SetValue(value); + } + + virtual int CountNumControls() override + { + return lhs->CountNumControls() + rhs->CountNumControls(); + } + + virtual operator std::string() override + { + return OpName(op) + "(" + (std::string)(*lhs) + ", " + (std::string)(*rhs) + ")"; + } +}; + +class UnaryExpression : public ExpressionNode +{ +public: + TokenType op; + ExpressionNode *inner; + + UnaryExpression(TokenType op_, ExpressionNode *inner_) : op(op_), inner(inner_) {} + virtual ~UnaryExpression() + { + delete inner; + } + + virtual ControlState GetValue() override + { + ControlState value = inner->GetValue(); + switch (op) + { + case TOK_NOT: + return 1.0f - value; + default: + assert(false); + return 0; + } + } + + virtual void SetValue(ControlState value) override + { + switch (op) + { + case TOK_NOT: + inner->SetValue(1.0f - value); + default: + assert(false); + } + } + + virtual int CountNumControls() override + { + return inner->CountNumControls(); + } + + virtual operator std::string() override + { + return OpName(op) + "(" + (std::string)(*inner) + ")"; + } +}; + +Device *ControlFinder::FindDevice(ControlQualifier qualifier) +{ + if (qualifier.has_device) + return container.FindDevice(qualifier.device_qualifier); + else + return container.FindDevice(default_device); +} + +Device::Control *ControlFinder::FindControl(ControlQualifier qualifier) +{ + Device *device = FindDevice(qualifier); + if (!device) + return NULL; + + if (is_input) + return device->FindInput(qualifier.control_name); + else + return device->FindOutput(qualifier.control_name); +} + +class Parser +{ +public: + + Parser(std::vector tokens_, ControlFinder &finder_) : tokens(tokens_), finder(finder_) + { + m_it = tokens.begin(); + } + + ExpressionParseStatus Parse(Expression **expr_out) + { + ExpressionNode *node; + ExpressionParseStatus status = Toplevel(&node); + if (status != EXPRESSION_PARSE_SUCCESS) + return status; + + *expr_out = new Expression(node); + return EXPRESSION_PARSE_SUCCESS; + } + +private: + std::vector tokens; + std::vector::iterator m_it; + ControlFinder &finder; + + Token Chew() + { + return *m_it++; + } + + Token Peek() + { + return *m_it; + } + + bool Expects(TokenType type) + { + Token tok = Chew(); + return tok.type == type; + } + + ExpressionParseStatus Atom(ExpressionNode **expr_out) + { + Token tok = Chew(); + switch (tok.type) + { + case TOK_CONTROL: + { + Device::Control *control = finder.FindControl(tok.qualifier); + if (control == NULL) + return EXPRESSION_PARSE_NO_DEVICE; + + *expr_out = new ControlExpression(tok.qualifier, control); + return EXPRESSION_PARSE_SUCCESS; + } + case TOK_LPAREN: + return Paren(expr_out); + default: + return EXPRESSION_PARSE_SYNTAX_ERROR; + } + } + + bool IsUnaryExpression(TokenType type) + { + switch (type) + { + case TOK_NOT: + return true; + default: + return false; + } + } + + ExpressionParseStatus Unary(ExpressionNode **expr_out) + { + ExpressionParseStatus status; + + if (IsUnaryExpression(Peek().type)) + { + Token tok = Chew(); + ExpressionNode *atom_expr; + if ((status = Atom(&atom_expr)) != EXPRESSION_PARSE_SUCCESS) + return status; + *expr_out = new UnaryExpression(tok.type, atom_expr); + return EXPRESSION_PARSE_SUCCESS; + } + + return Atom(expr_out); + } + + bool IsBinaryToken(TokenType type) + { + switch (type) + { + case TOK_AND: + case TOK_OR: + case TOK_ADD: + return true; + default: + return false; + } + } + + ExpressionParseStatus Binary(ExpressionNode **expr_out) + { + ExpressionParseStatus status; + + if ((status = Unary(expr_out)) != EXPRESSION_PARSE_SUCCESS) + return status; + + while (IsBinaryToken(Peek().type)) + { + Token tok = Chew(); + ExpressionNode *unary_expr; + if ((status = Unary(&unary_expr)) != EXPRESSION_PARSE_SUCCESS) + { + delete *expr_out; + return status; + } + + *expr_out = new BinaryExpression(tok.type, *expr_out, unary_expr); + } + + return EXPRESSION_PARSE_SUCCESS; + } + + ExpressionParseStatus Paren(ExpressionNode **expr_out) + { + ExpressionParseStatus status; + + // lparen already chewed + if ((status = Toplevel(expr_out)) != EXPRESSION_PARSE_SUCCESS) + return status; + + if (!Expects(TOK_RPAREN)) + { + delete *expr_out; + return EXPRESSION_PARSE_SYNTAX_ERROR; + } + + return EXPRESSION_PARSE_SUCCESS; + } + + ExpressionParseStatus Toplevel(ExpressionNode **expr_out) + { + return Binary(expr_out); + } +}; + +ControlState Expression::GetValue() +{ + return node->GetValue(); +} + +void Expression::SetValue(ControlState value) +{ + node->SetValue(value); +} + +Expression::Expression(ExpressionNode *node_) +{ + node = node_; + num_controls = node->CountNumControls(); +} + +Expression::~Expression() +{ + delete node; +} + +ExpressionParseStatus ParseExpressionInner(std::string str, ControlFinder &finder, Expression **expr_out) +{ + ExpressionParseStatus status; + Expression *expr; + *expr_out = NULL; + + if (str == "") + return EXPRESSION_PARSE_SUCCESS; + + Lexer l(str); + std::vector tokens; + status = l.Tokenize(tokens); + if (status != EXPRESSION_PARSE_SUCCESS) + return status; + + Parser p(tokens, finder); + status = p.Parse(&expr); + if (status != EXPRESSION_PARSE_SUCCESS) + return status; + + *expr_out = expr; + return EXPRESSION_PARSE_SUCCESS; +} + +ExpressionParseStatus ParseExpression(std::string str, ControlFinder &finder, Expression **expr_out) +{ + // Add compatibility with old simple expressions, which are simple + // barewords control names. + + ControlQualifier qualifier; + qualifier.control_name = str; + qualifier.has_device = false; + + Device::Control *control = finder.FindControl(qualifier); + if (control) { + *expr_out = new Expression(new ControlExpression(qualifier, control)); + return EXPRESSION_PARSE_SUCCESS; + } + + return ParseExpressionInner(str, finder, expr_out); +} + +} +} -- cgit v1.2.3 From d2038049f51192fbb55fbde2fc08128bacfb7707 Mon Sep 17 00:00:00 2001 From: lioncash Date: Mon, 10 Feb 2014 13:54:46 -0500 Subject: Replace all include guard ifdefs with "#pragma once" --- Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp') diff --git a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp index b313559907..7f7954d3d8 100644 --- a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp @@ -1,3 +1,6 @@ +// Copyright 2013 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. #include "ExpressionParser.h" -- cgit v1.2.3 From 404624bf0b0125e5a408021c616ee9b9e2dde382 Mon Sep 17 00:00:00 2001 From: Tillmann Karras Date: Wed, 12 Feb 2014 16:00:34 +0100 Subject: Turn loops into range-based form and some things suggested by cppcheck and compiler warnings. --- Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp') diff --git a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp index 7f7954d3d8..802d1b8f0f 100644 --- a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp @@ -102,7 +102,7 @@ public: while (it != expr.end()) { char c = *it; - it++; + ++it; if (c == '`') return false; if (c > 0 && c == otherDelim) @@ -140,7 +140,7 @@ public: if (!isalpha(c)) break; name += c; - it++; + ++it; } ControlQualifier qualifier; -- cgit v1.2.3 From 2afe2152712981e21d6bda6f029292ed2b1cf91e Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 17 Feb 2014 05:18:15 -0500 Subject: Convert all includes to relative paths. --- Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp') diff --git a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp index 802d1b8f0f..4e2f49f4d0 100644 --- a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp @@ -2,14 +2,15 @@ // Licensed under GPLv2 // Refer to the license.txt file included. -#include "ExpressionParser.h" - +#include #include #include -#include #include +#include #include +#include "InputCommon/ControllerInterface/ExpressionParser.h" + using namespace ciface::Core; namespace ciface -- cgit v1.2.3 From d802d392811be44d34ae9cd23f616db93e54c50f Mon Sep 17 00:00:00 2001 From: Tillmann Karras Date: Sun, 9 Mar 2014 21:14:26 +0100 Subject: clang-modernize -use-nullptr and s/\bNULL\b/nullptr/g for *.cpp/h/mm files not compiled on my machine --- Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp') diff --git a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp index 4e2f49f4d0..c41e82b699 100644 --- a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp @@ -357,7 +357,7 @@ Device::Control *ControlFinder::FindControl(ControlQualifier qualifier) { Device *device = FindDevice(qualifier); if (!device) - return NULL; + return nullptr; if (is_input) return device->FindInput(qualifier.control_name); @@ -414,7 +414,7 @@ private: case TOK_CONTROL: { Device::Control *control = finder.FindControl(tok.qualifier); - if (control == NULL) + if (control == nullptr) return EXPRESSION_PARSE_NO_DEVICE; *expr_out = new ControlExpression(tok.qualifier, control); @@ -539,7 +539,7 @@ ExpressionParseStatus ParseExpressionInner(std::string str, ControlFinder &finde { ExpressionParseStatus status; Expression *expr; - *expr_out = NULL; + *expr_out = nullptr; if (str == "") return EXPRESSION_PARSE_SUCCESS; -- cgit v1.2.3 From 22e1aa5bb4a159d6d66a321f978917614aa36331 Mon Sep 17 00:00:00 2001 From: degasus Date: Tue, 8 Jul 2014 14:29:26 +0200 Subject: mark all local functions as static --- Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp') diff --git a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp index c41e82b699..2261a5df98 100644 --- a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp @@ -535,7 +535,7 @@ Expression::~Expression() delete node; } -ExpressionParseStatus ParseExpressionInner(std::string str, ControlFinder &finder, Expression **expr_out) +static ExpressionParseStatus ParseExpressionInner(std::string str, ControlFinder &finder, Expression **expr_out) { ExpressionParseStatus status; Expression *expr; -- cgit v1.2.3 From 74f308338195ac6c78008def5a6a4342c8b824af Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 11 Jul 2014 10:53:51 -0400 Subject: ControllerInterface: Gate the input based on our new background input setting --- Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp') diff --git a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp index 2261a5df98..da740bbb7e 100644 --- a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp @@ -228,12 +228,12 @@ public: virtual ControlState GetValue() override { - return control->ToInput()->GetState(); + return control->ToInput()->GetGatedState(); } virtual void SetValue(ControlState value) override { - control->ToOutput()->SetState(value); + control->ToOutput()->SetGatedState(value); } virtual int CountNumControls() override -- cgit v1.2.3 From bc14d6966f996c482ea97aa9b424e34091bfc8ec Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 30 Aug 2014 16:44:28 -0400 Subject: InputCommon: Clean up brace placements --- Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp') diff --git a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp index da740bbb7e..c28356260d 100644 --- a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp @@ -136,7 +136,8 @@ public: std::string name; name += c; - while (it != expr.end()) { + while (it != expr.end()) + { c = *it; if (!isalpha(c)) break; @@ -569,7 +570,8 @@ ExpressionParseStatus ParseExpression(std::string str, ControlFinder &finder, Ex qualifier.has_device = false; Device::Control *control = finder.FindControl(qualifier); - if (control) { + if (control) + { *expr_out = new Expression(new ControlExpression(qualifier, control)); return EXPRESSION_PARSE_SUCCESS; } -- cgit v1.2.3 From 5adbc83453d14b23818442f545ceede0e4548196 Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Mon, 11 Aug 2014 13:43:26 -0400 Subject: Change ControlState typedef to double, and change all related floats/doubles to use it. Fixes an off by 1 issue related to double->float->double conversion, and eliminates numerous warnings. --- Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp') diff --git a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp index c28356260d..e93b22826d 100644 --- a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp @@ -273,7 +273,7 @@ public: case TOK_OR: return std::max(lhsValue, rhsValue); case TOK_ADD: - return std::min(lhsValue + rhsValue, 1.0f); + return std::min(lhsValue + rhsValue, 1.0); default: assert(false); return 0; -- cgit v1.2.3 From e9cb629723bb0fabbad130c2a63b3cdbaaf8ba6a Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Sun, 9 Nov 2014 15:02:18 -0500 Subject: Fix some double->float conversions. --- Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp') diff --git a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp index e93b22826d..8c9060e69c 100644 --- a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp @@ -317,7 +317,7 @@ public: switch (op) { case TOK_NOT: - return 1.0f - value; + return 1.0 - value; default: assert(false); return 0; @@ -329,7 +329,7 @@ public: switch (op) { case TOK_NOT: - inner->SetValue(1.0f - value); + inner->SetValue(1.0 - value); default: assert(false); } -- cgit v1.2.3 From c626ce58092cff0aafd2feb4c3b3570b80595399 Mon Sep 17 00:00:00 2001 From: Gabriel Corona Date: Thu, 26 Feb 2015 00:41:59 +0100 Subject: Do not fail to evaluate an expression if some input is missing My keyboard layout does not have Alt_R but ISO_Level3_Shift. As a consequence any control expression containing Alt_R fails to evaluate completely and is unusable. This modification replace the missing term of the expression by a dummy expression which always evaluate to 0. This way, the keybinding can work even if some keys are not available. --- .../ControllerInterface/ExpressionParser.cpp | 32 +++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp') diff --git a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp index 8c9060e69c..b49d4b8dce 100644 --- a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp @@ -219,6 +219,33 @@ public: virtual operator std::string() { return ""; } }; +class DummyExpression : public ExpressionNode +{ +public: + std::string name; + + DummyExpression(const std::string& name_) : name(name_) {} + + ControlState GetValue() override + { + return 0.0; + } + + void SetValue(ControlState value) override + { + } + + int CountNumControls() override + { + return 0; + } + + operator std::string() override + { + return "`" + name + "`"; + } +}; + class ControlExpression : public ExpressionNode { public: @@ -416,7 +443,10 @@ private: { Device::Control *control = finder.FindControl(tok.qualifier); if (control == nullptr) - return EXPRESSION_PARSE_NO_DEVICE; + { + *expr_out = new DummyExpression(tok.qualifier); + return EXPRESSION_PARSE_SUCCESS; + } *expr_out = new ControlExpression(tok.qualifier, control); return EXPRESSION_PARSE_SUCCESS; -- cgit v1.2.3 From 9ad35cc986aadce3ae885223ea56031533acb197 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 22 May 2015 15:02:22 -0400 Subject: ExpressionParser: Add missing break in UnaryExpression value setting --- Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp') diff --git a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp index b49d4b8dce..921e8d64f3 100644 --- a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp @@ -357,6 +357,8 @@ public: { case TOK_NOT: inner->SetValue(1.0 - value); + break; + default: assert(false); } -- cgit v1.2.3 From cefcb0ace9d363b3679b4e93bcc9ec05f1e5f4f8 Mon Sep 17 00:00:00 2001 From: Tillmann Karras Date: Mon, 18 May 2015 01:08:10 +0200 Subject: Update license headers to GPLv2+ --- Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp') diff --git a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp index 921e8d64f3..abe3043aa1 100644 --- a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp @@ -1,5 +1,5 @@ // Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 +// Licensed under GPLv2+ // Refer to the license.txt file included. #include -- cgit v1.2.3 From ac26f8e79fbf640ba770a35c1f051c2816f6346f Mon Sep 17 00:00:00 2001 From: Lioncash Date: Thu, 28 May 2015 20:28:48 -0400 Subject: Pass strings by const reference where possible --- Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp') diff --git a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp index abe3043aa1..9837ea74cb 100644 --- a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp @@ -92,7 +92,7 @@ public: std::string expr; std::string::iterator it; - Lexer(std::string expr_) : expr(expr_) + Lexer(const std::string& expr_) : expr(expr_) { it = expr.begin(); } @@ -568,7 +568,7 @@ Expression::~Expression() delete node; } -static ExpressionParseStatus ParseExpressionInner(std::string str, ControlFinder &finder, Expression **expr_out) +static ExpressionParseStatus ParseExpressionInner(const std::string& str, ControlFinder &finder, Expression **expr_out) { ExpressionParseStatus status; Expression *expr; @@ -592,7 +592,7 @@ static ExpressionParseStatus ParseExpressionInner(std::string str, ControlFinder return EXPRESSION_PARSE_SUCCESS; } -ExpressionParseStatus ParseExpression(std::string str, ControlFinder &finder, Expression **expr_out) +ExpressionParseStatus ParseExpression(const std::string& str, ControlFinder &finder, Expression **expr_out) { // Add compatibility with old simple expressions, which are simple // barewords control names. -- cgit v1.2.3