1 /***************************************************************************************************
2 **
3 ** Copyright (C) 2013 Ingo Berg
4 **
5 ** Permission is hereby granted, free of charge, to any person obtaining a copy of this
6 ** software and associated documentation files (the "Software"), to deal in the Software
7 ** without restriction, including without limitation the rights to use, copy, modify,
8 ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
9 ** permit persons to whom the Software is furnished to do so, subject to the following conditions:
10 **
11 ** The above copyright notice and this permission notice shall be included in all copies or
12 ** substantial portions of the Software.
13 **
14 ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15 ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 **
20 ******************************************************************************************************/
21
22 #ifndef QMUPARSERERROR_H
23 #define QMUPARSERERROR_H
24
25 #include <qcompilerdetection.h>
26 #include <QCoreApplication>
27 #include <QException>
28 #include <QMap>
29 #include <QString>
30 #include <QVector>
31 #include <QtGlobal>
32 #include <sstream>
33
34 #include "../qmuparser/qmuparser_global.h"
35 #include "qmuparser_global.h"
36 #include "qmuparserdef.h"
37 #include "qmutranslation.h"
38
39 /** @file
40 @brief This file defines the error class used by the parser.
41 */
42
43 namespace qmu
44 {
45
46 /** @brief Error codes. */
47 enum EErrorCodes
48 {
49 // Formula syntax errors
50 ecUNEXPECTED_OPERATOR = 0, ///< Unexpected binary operator found
51 ecUNASSIGNABLE_TOKEN = 1, ///< Token cant be identified.
52 ecUNEXPECTED_EOF = 2, ///< Unexpected end of formula. (Example: "2+sin(")
53 ecUNEXPECTED_ARG_SEP = 3, ///< An unexpected semicolon has been found. (Example: "1;23")
54 ecUNEXPECTED_ARG = 4, ///< An unexpected argument has been found
55 ecUNEXPECTED_VAL = 5, ///< An unexpected value token has been found
56 ecUNEXPECTED_VAR = 6, ///< An unexpected variable token has been found
57 ecUNEXPECTED_PARENS = 7, ///< Unexpected Parenthesis, opening or closing
58 ecUNEXPECTED_STR = 8, ///< A string has been found at an inapropriate position
59 ecSTRING_EXPECTED = 9, ///< A string function has been called with a different type of argument
60 ecVAL_EXPECTED = 10, ///< A numerical function has been called with a non value type of argument
61 ecMISSING_PARENS = 11, ///< Missing parens. (Example: "3*sin(3")
62 ecUNEXPECTED_FUN = 12, ///< Unexpected function found. (Example: "sin(8)cos(9)")
63 ecUNTERMINATED_STRING = 13, ///< unterminated string constant. (Example: "3*valueof("hello)")
64 ecTOO_MANY_PARAMS = 14, ///< Too many function parameters
65 ecTOO_FEW_PARAMS = 15, ///< Too few function parameters. (Example: "ite(1<2;2)")
66 ecOPRT_TYPE_CONFLICT = 16, ///< binary operators may only be applied to value items of the same type
67 ecSTR_RESULT = 17, ///< result is a string
68
69 // Invalid Parser input Parameters
70 ecINVALID_NAME = 18, ///< Invalid function, variable or constant name.
71 ecINVALID_BINOP_IDENT = 19, ///< Invalid binary operator identifier
72 ecINVALID_INFIX_IDENT = 20, ///< Invalid function, variable or constant name.
73 ecINVALID_POSTFIX_IDENT = 21, ///< Invalid function, variable or constant name.
74
75 ecBUILTIN_OVERLOAD = 22, ///< Trying to overload builtin operator
76 ecINVALID_FUN_PTR = 23, ///< Invalid callback function pointer
77 ecINVALID_VAR_PTR = 24, ///< Invalid variable pointer
78 ecEMPTY_EXPRESSION = 25, ///< The Expression is empty
79 ecNAME_CONFLICT = 26, ///< Name conflict
80 ecOPT_PRI = 27, ///< Invalid operator priority
81 //
82 ecDOMAIN_ERROR = 28, ///< catch division by zero, sqrt(-1), log(0) (currently unused)
83 ecDIV_BY_ZERO = 29, ///< Division by zero (currently unused)
84 ecGENERIC = 30, ///< Generic error
85 ecLOCALE = 31, ///< Conflict with current locale
86
87 ecUNEXPECTED_CONDITIONAL = 32,
88 ecMISSING_ELSE_CLAUSE = 33,
89 ecMISPLACED_COLON = 34,
90
91 // internal errors
92 ecINTERNAL_ERROR = 35, ///< Internal error of any kind.
93
94 // The last two are special entries
95 ecCOUNT, ///< This is no error code, It just stores just the total number of error codes
96 ecUNDEFINED = -1 ///< Undefined message, placeholder to detect unassigned error messages
97 };
98
99 //---------------------------------------------------------------------------
100 /** @brief A class that handles the error messages.
101 */
102 class QMUPARSERSHARED_EXPORT QmuParserErrorMsg
103 {
104 public:
105 typedef QmuParserErrorMsg self_type;
106
107 QmuParserErrorMsg();
108 ~QmuParserErrorMsg();
109
110 static const QmuParserErrorMsg& Instance();
111 QString operator[] ( int a_iIdx ) const;
112
113 private:
114 Q_DISABLE_COPY(QmuParserErrorMsg)
115 QMap<int, QmuTranslation> m_vErrMsg; ///< A map with the predefined error messages
116 static const self_type m_Instance; ///< The instance pointer
117 };
118
119 //---------------------------------------------------------------------------------------------------------------------
120 // cppcheck-suppress unusedFunction
Instance()121 inline const QmuParserErrorMsg& QmuParserErrorMsg::Instance()
122 {
123 return m_Instance;
124 }
125
126 //---------------------------------------------------------------------------------------------------------------------
127 inline QString QmuParserErrorMsg::operator[] ( int a_iIdx ) const
128 {
129 return m_vErrMsg.value(a_iIdx).translate(QString());
130 }
131
132 class QMUPARSERSHARED_EXPORT QmuParserWarning : public QException
133 {
134 public:
135 explicit QmuParserWarning ( const QString &sMsg );
136 QmuParserWarning ( const QmuParserWarning &a_Obj );
137 QmuParserWarning& operator= ( const QmuParserWarning &a_Obj );
~QmuParserWarning()138 virtual ~QmuParserWarning() QMUP_NOEXCEPT_EXPR (true) override {}
139
140 const QString& GetMsg() const;
141
142 Q_NORETURN virtual void raise() const override;
143 Q_REQUIRED_RESULT virtual QmuParserWarning *clone() const override;
144 private:
145 QString m_sMsg; ///< The message string
146 };
147
148 //---------------------------------------------------------------------------------------------------------------------
149 /**
150 * @brief Returns the message string for this error.
151 */
GetMsg()152 inline const QString& QmuParserWarning::GetMsg() const
153 {
154 return m_sMsg;
155 }
156
157 //---------------------------------------------------------------------------
158 /** @brief Error class of the parser.
159 @author Ingo Berg
160
161 Part of the math parser package.
162 */
163 class QMUPARSERSHARED_EXPORT QmuParserError : public QException
164 {
165 public:
166 QmuParserError();
167 explicit QmuParserError ( EErrorCodes a_iErrc );
168 explicit QmuParserError ( const QString &sMsg );
169 QmuParserError ( EErrorCodes a_iErrc, const QString &sTok, const QString &sFormula = QString(), int a_iPos = -1 );
170 QmuParserError ( EErrorCodes a_iErrc, int a_iPos, const QString &sTok );
171 QmuParserError ( const QString &szMsg, int iPos, const QString &sTok = QString() );
172 QmuParserError ( const QmuParserError &a_Obj );
173 QmuParserError& operator= ( const QmuParserError &a_Obj );
~QmuParserError()174 virtual ~QmuParserError() QMUP_NOEXCEPT_EXPR (true) override {}
175
176 void SetFormula ( const QString &a_strFormula );
177 const QString& GetExpr() const;
178 const QString& GetMsg() const;
179 int GetPos() const;
180 const QString& GetToken() const;
181 EErrorCodes GetCode() const;
182 Q_NORETURN virtual void raise() const override;
183 Q_REQUIRED_RESULT virtual QmuParserError *clone() const override;
184 private:
185 QString m_sMsg; ///< The message string
186 QString m_sExpr; ///< Formula string
187 QString m_sTok; ///< Token related with the error
188 int m_iPos; ///< Formula position related to the error
189 EErrorCodes m_iErrc; ///< Error code
190 const QmuParserErrorMsg &m_ErrMsg;
191 void Reset();
192 };
193
194 //---------------------------------------------------------------------------------------------------------------------
195 /**
196 * @brief Set the expression related to this error.
197 */
SetFormula(const QString & a_strFormula)198 inline void QmuParserError::SetFormula ( const QString &a_strFormula )
199 {
200 m_sExpr = a_strFormula;
201 }
202
203 //---------------------------------------------------------------------------------------------------------------------
204 /**
205 * @brief gets the expression related tp this error.
206 */
GetExpr()207 inline const QString& QmuParserError::GetExpr() const
208 {
209 return m_sExpr;
210 }
211
212 //---------------------------------------------------------------------------------------------------------------------
213 /**
214 * @brief Returns the message string for this error.
215 */
GetMsg()216 inline const QString& QmuParserError::GetMsg() const
217 {
218 return m_sMsg;
219 }
220
221 //---------------------------------------------------------------------------------------------------------------------
222 /**
223 * @brief Return the formula position related to the error.
224 *
225 * If the error is not related to a distinct position this will return -1
226 */
GetPos()227 inline int QmuParserError::GetPos() const
228 {
229 return m_iPos;
230 }
231
232 //---------------------------------------------------------------------------------------------------------------------
233 /**
234 * @brief Return string related with this token (if available).
235 */
GetToken()236 inline const QString& QmuParserError::GetToken() const
237 {
238 return m_sTok;
239 }
240
241 //---------------------------------------------------------------------------------------------------------------------
242 /**
243 * @brief Return the error code.
244 */
GetCode()245 inline EErrorCodes QmuParserError::GetCode() const
246 {
247 return m_iErrc;
248 }
249
250 } // namespace qmu
251
252 #endif
253