File indexing completed on 2024-04-28 04:00:48

0001 /*
0002     SPDX-FileCopyrightText: 2006 Kevin Ottens <ervin@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 extern "C" {
0008 #include "predicateparse.h"
0009 
0010 void PredicateParse_mainParse(const char *_code);
0011 }
0012 
0013 #include "predicate.h"
0014 #include "soliddefs_p.h"
0015 
0016 #include <stdlib.h>
0017 
0018 #include <QStringList>
0019 #include <QThreadStorage>
0020 
0021 namespace Solid
0022 {
0023 namespace PredicateParse
0024 {
0025 struct ParsingData {
0026     ParsingData()
0027         : result(nullptr)
0028     {
0029     }
0030 
0031     Solid::Predicate *result;
0032     QByteArray buffer;
0033 };
0034 
0035 }
0036 }
0037 
0038 Q_GLOBAL_STATIC(QThreadStorage<Solid::PredicateParse::ParsingData *>, s_parsingData)
0039 
0040 Solid::Predicate Solid::Predicate::fromString(const QString &predicate)
0041 {
0042     Solid::PredicateParse::ParsingData *data = new Solid::PredicateParse::ParsingData();
0043     s_parsingData->setLocalData(data);
0044     data->buffer = predicate.toLatin1();
0045     PredicateParse_mainParse(data->buffer.constData());
0046     Predicate result;
0047     if (data->result) {
0048         result = Predicate(*data->result);
0049         delete data->result;
0050     }
0051     s_parsingData->setLocalData(nullptr);
0052     return result;
0053 }
0054 
0055 void PredicateParse_setResult(void *result)
0056 {
0057     Solid::PredicateParse::ParsingData *data = s_parsingData->localData();
0058     data->result = (Solid::Predicate *)result;
0059 }
0060 
0061 void PredicateParse_errorDetected(const char *s)
0062 {
0063     qWarning("ERROR from solid predicate parser: %s", s);
0064     s_parsingData->localData()->result = nullptr;
0065 }
0066 
0067 void PredicateParse_destroy(void *pred)
0068 {
0069     Solid::PredicateParse::ParsingData *data = s_parsingData->localData();
0070     Solid::Predicate *p = (Solid::Predicate *)pred;
0071     if (p != data->result) {
0072         delete p;
0073     }
0074 }
0075 
0076 void *PredicateParse_newAtom(char *interface, char *property, void *value)
0077 {
0078     QString iface(interface);
0079     QString prop(property);
0080     QVariant *val = (QVariant *)value;
0081 
0082     Solid::Predicate *result = new Solid::Predicate(iface, prop, *val);
0083 
0084     delete val;
0085     free(interface);
0086     free(property);
0087 
0088     return result;
0089 }
0090 
0091 void *PredicateParse_newMaskAtom(char *interface, char *property, void *value)
0092 {
0093     QString iface(interface);
0094     QString prop(property);
0095     QVariant *val = (QVariant *)value;
0096 
0097     Solid::Predicate *result = new Solid::Predicate(iface, prop, *val, Solid::Predicate::Mask);
0098 
0099     delete val;
0100     free(interface);
0101     free(property);
0102 
0103     return result;
0104 }
0105 
0106 void *PredicateParse_newIsAtom(char *interface)
0107 {
0108     QString iface(interface);
0109 
0110     Solid::Predicate *result = new Solid::Predicate(iface);
0111 
0112     free(interface);
0113 
0114     return result;
0115 }
0116 
0117 void *PredicateParse_newAnd(void *pred1, void *pred2)
0118 {
0119     Solid::Predicate *result = new Solid::Predicate();
0120 
0121     Solid::PredicateParse::ParsingData *data = s_parsingData->localData();
0122     Solid::Predicate *p1 = (Solid::Predicate *)pred1;
0123     Solid::Predicate *p2 = (Solid::Predicate *)pred2;
0124 
0125     if (p1 == data->result || p2 == data->result) {
0126         data->result = nullptr;
0127     }
0128 
0129     *result = *p1 & *p2;
0130 
0131     delete p1;
0132     delete p2;
0133 
0134     return result;
0135 }
0136 
0137 void *PredicateParse_newOr(void *pred1, void *pred2)
0138 {
0139     Solid::Predicate *result = new Solid::Predicate();
0140 
0141     Solid::PredicateParse::ParsingData *data = s_parsingData->localData();
0142     Solid::Predicate *p1 = (Solid::Predicate *)pred1;
0143     Solid::Predicate *p2 = (Solid::Predicate *)pred2;
0144 
0145     if (p1 == data->result || p2 == data->result) {
0146         data->result = nullptr;
0147     }
0148 
0149     *result = *p1 | *p2;
0150 
0151     delete p1;
0152     delete p2;
0153 
0154     return result;
0155 }
0156 
0157 void *PredicateParse_newStringValue(char *val)
0158 {
0159     QString s(val);
0160 
0161     free(val);
0162 
0163     return new QVariant(s);
0164 }
0165 
0166 void *PredicateParse_newBoolValue(int val)
0167 {
0168     bool b = (val != 0);
0169     return new QVariant(b);
0170 }
0171 
0172 void *PredicateParse_newNumValue(int val)
0173 {
0174     return new QVariant(val);
0175 }
0176 
0177 void *PredicateParse_newDoubleValue(double val)
0178 {
0179     return new QVariant(val);
0180 }
0181 
0182 void *PredicateParse_newEmptyStringListValue()
0183 {
0184     return new QVariant(QStringList());
0185 }
0186 
0187 void *PredicateParse_newStringListValue(char *name)
0188 {
0189     QStringList list;
0190     list << QString(name);
0191 
0192     free(name);
0193 
0194     return new QVariant(list);
0195 }
0196 
0197 void *PredicateParse_appendStringListValue(char *name, void *list)
0198 {
0199     QVariant *variant = (QVariant *)list;
0200 
0201     QStringList new_list = variant->toStringList();
0202 
0203     new_list << QString(name);
0204 
0205     delete variant;
0206     free(name);
0207 
0208     return new QVariant(new_list);
0209 }
0210 
0211 void PredicateLexer_unknownToken(const char *text)
0212 {
0213     qWarning("ERROR from solid predicate parser: unrecognized token '%s' in predicate '%s'\n", text, s_parsingData->localData()->buffer.constData());
0214 }