File indexing completed on 2024-06-23 05:49:02
0001 /* 0002 This file is part of the Okteta Kasten Framework, made within the KDE community. 0003 0004 SPDX-FileCopyrightText: 2012 Alex Richardson <alex.richardson@gmx.de> 0005 0006 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 */ 0008 0009 #ifndef KASTEN_PARSERUTILS_HPP 0010 #define KASTEN_PARSERUTILS_HPP 0011 0012 #include <QDebug> 0013 #include <QStringList> 0014 #include <KLocalizedString> 0015 0016 #include "../datatypes/datainformation.hpp" 0017 #include "../datatypes/strings/stringdatainformation.hpp" 0018 #include "../script/scriptlogger.hpp" 0019 0020 // forward declare so I don't have to repeat in all the parsers 0021 class ArrayDataInformation; 0022 class PrimitiveDataInformation; 0023 class AbstractBitfieldDataInformation; 0024 class StructureDataInformation; 0025 class UnionDataInformation; 0026 class EnumDataInformation; 0027 class StringDataInformation; 0028 class TaggedUnionDataInformation; 0029 class PointerDataInformation; 0030 0031 class QScriptValue; 0032 class QScriptEngine; 0033 0034 /** For use by the parsers so that the functions don't have as many parameters */ 0035 struct ParserInfo 0036 { 0037 inline ParserInfo(const QString& name, ScriptLogger* logger, DataInformation* parent, QScriptEngine* engine) 0038 : name(name) 0039 , logger(logger) 0040 , parent(parent) 0041 , engine(engine) 0042 { 0043 Q_CHECK_PTR(logger); 0044 } 0045 inline ParserInfo(const ParserInfo& i) = default; 0046 inline ~ParserInfo() = default; 0047 0048 QString name; 0049 ScriptLogger* logger; 0050 DataInformation* parent; 0051 QScriptEngine* engine; 0052 0053 inline QString context() const 0054 { 0055 return parent ? parent->fullObjectPath() + QLatin1Char('.') + name : name; 0056 } 0057 inline QDebug info() const { return logger->info(context()); } 0058 inline QDebug warn() const { return logger->warn(context()); } 0059 inline QDebug error() const { return logger->error(context()); } 0060 }; 0061 0062 class ChildrenParser 0063 { 0064 public: 0065 virtual ~ChildrenParser() = default; 0066 0067 virtual DataInformation* next() = 0; 0068 virtual bool hasNext() = 0; 0069 virtual void setParent(DataInformation* parent) = 0; 0070 }; 0071 0072 /** 0073 * Holds a number that was converted either from a QScriptValue or a QString 0074 */ 0075 template <typename T> 0076 struct ParsedNumber 0077 { 0078 ParsedNumber() = default; 0079 ParsedNumber(T val, const QString& str, bool ok) 0080 : string(str) 0081 , value(val) 0082 , isValid(ok) 0083 {} 0084 0085 QString string; 0086 T value = 0; 0087 bool isValid = false; 0088 0089 static ParsedNumber<T> badInput(const QString& str) { return ParsedNumber<T>(T(), str, false); } 0090 inline bool isError() { return !isValid && !string.isEmpty(); } 0091 inline bool isEmpty() { Q_ASSERT(!isValid); return string.isEmpty(); } 0092 }; 0093 0094 namespace ParserStrings { 0095 0096 QString TYPE_ARRAY(); 0097 QString TYPE_BITFIELD(); 0098 QString TYPE_ENUM(); 0099 QString TYPE_FLAGS(); 0100 QString TYPE_PRIMITIVE(); 0101 QString TYPE_STRING(); 0102 QString TYPE_STRUCT(); 0103 QString TYPE_UNION(); 0104 QString TYPE_POINTER(); 0105 QString TYPE_TAGGED_UNION(); 0106 /** Only needed for .osd */ 0107 QString TYPE_ENUMDEF(); 0108 QString TYPE_ALTERNATIVES(); 0109 QString TYPE_GROUP(); 0110 0111 // lock offset 0112 QString PROPERTY_DEFAULT_LOCK_OFFSET(); 0113 // all types 0114 QString PROPERTY_NAME(); 0115 QString PROPERTY_BYTEORDER(); 0116 QString PROPERTY_PARENT(); 0117 QString PROPERTY_VALIDATION_ERROR(); 0118 QString PROPERTY_VALID(); 0119 QString PROPERTY_ABLE_TO_READ(); 0120 QString PROPERTY_UPDATE_FUNC(); 0121 QString PROPERTY_VALIDATION_FUNC(); 0122 QString PROPERTY_TO_STRING_FUNC(); 0123 QString PROPERTY_DATATYPE(); 0124 QString PROPERTY_CUSTOM_TYPE_NAME(); 0125 // enum 0126 QString PROPERTY_ENUM_VALUES(); 0127 // this one is javascript only 0128 QString PROPERTY_ENUM_NAME(); 0129 // array/bitfield 0130 QString PROPERTY_TYPE(); 0131 // array 0132 QString PROPERTY_LENGTH(); 0133 // bitfield 0134 QString PROPERTY_WIDTH(); 0135 // struct/union 0136 QString PROPERTY_CHILDREN(); 0137 QString PROPERTY_CHILD_COUNT(); 0138 QString PROPERTY_CHILD(); 0139 // strings 0140 QString PROPERTY_CHAR_COUNT(); 0141 QString PROPERTY_BYTE_COUNT(); 0142 QString PROPERTY_MAX_CHAR_COUNT(); 0143 QString PROPERTY_MAX_BYTE_COUNT(); 0144 QString PROPERTY_TERMINATED_BY(); 0145 QString PROPERTY_ENCODING(); 0146 // primitive 0147 QString PROPERTY_VALUE(); 0148 // pointer 0149 QString PROPERTY_TARGET(); 0150 QString PROPERTY_SCALE(); 0151 QString PROPERTY_INTERPRET_FUNC(); 0152 // tagged union 0153 QString PROPERTY_ALTERNATIVES(); 0154 QString PROPERTY_DEFAULT_CHILDREN(); 0155 QString PROPERTY_SELECT_IF(); 0156 QString PROPERTY_STRUCT_NAME(); 0157 0158 QString PROPERTY_INTERNAL_TYPE(); 0159 0160 QStringList ALL_PROPERTIES(); 0161 0162 QString NAME_POINTER_VALUE_TYPE(); 0163 QString NAME_POINTER_TARGET(); 0164 QString NAME_ARRAY_TYPE(); 0165 0166 } 0167 0168 namespace ParserUtils { 0169 0170 /** If string starts with 0x, the remainder is interpreted as a hexadecimal (unsigned) number 0171 * otherwise it will be parsed as a decimal number 0172 * @param str the string to convert 0173 * @return a parsed number (check the isValid member to see if conversion succeeded) 0174 */ 0175 ParsedNumber<int> intFromString(const QString& str); 0176 /** @see ParserUtils::intFromString() */ 0177 ParsedNumber<uint> uintFromString(const QString& str); 0178 /** @see ParserUtils::intFromString() */ 0179 ParsedNumber<quint64> uint64FromString(const QString& str); 0180 /** Checks whether the value is a number, and if it is converts it. 0181 * Since all script values use double internally, a valid number can be out of bounds, too 0182 * @param val the value to convert 0183 * @see ParserUtils::intFromString() 0184 */ 0185 ParsedNumber<int> intFromScriptValue(const QScriptValue& val); 0186 /** @see ParserUtils::intFromScriptValue() */ 0187 ParsedNumber<uint> uintFromScriptValue(const QScriptValue& val); 0188 /** @see ParserUtils::intFromScriptValue() */ 0189 ParsedNumber<quint64> uint64FromScriptValue(const QScriptValue& val); 0190 0191 DataInformation::DataInformationEndianess byteOrderFromString(const QString& string, const LoggerWithContext& logger); 0192 QString byteOrderToString(DataInformation::DataInformationEndianess order); 0193 0194 StringDataInformation::StringType toStringEncoding(const QString& str, const LoggerWithContext& logger); 0195 0196 /** This essentially calls engine->evaluate(str), but ensures it can be a function (QTBUG-5757) */ 0197 QScriptValue functionSafeEval(QScriptEngine* engine, const QString& str); 0198 0199 } 0200 0201 #endif /* KASTEN_PARSERUTILS_HPP */