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