1/*
2 SPDX-FileCopyrightText: 2006 Kevin Ottens <ervin@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5*/
6
7extern "C" {
8#include "predicateparse.h"
9
10void PredicateParse_mainParse(const char *_code);
11}
12
13#include "predicate.h"
14#include "soliddefs_p.h"
15
16#include <stdlib.h>
17
18#include <QStringList>
19#include <QThreadStorage>
20
21namespace Solid
22{
23namespace PredicateParse
24{
25struct ParsingData {
26 ParsingData()
27 : result(nullptr)
28 {
29 }
30
31 Solid::Predicate *result;
32 QByteArray buffer;
33};
34
35}
36}
37
38Q_GLOBAL_STATIC(QThreadStorage<Solid::PredicateParse::ParsingData *>, s_parsingData)
39
40Solid::Predicate Solid::Predicate::fromString(const QString &predicate)
41{
42 Solid::PredicateParse::ParsingData *data = new Solid::PredicateParse::ParsingData();
43 s_parsingData->setLocalData(data);
44 data->buffer = predicate.toLatin1();
45 PredicateParse_mainParse(code: data->buffer.constData());
46 Predicate result;
47 if (data->result) {
48 result = Predicate(*data->result);
49 delete data->result;
50 }
51 s_parsingData->setLocalData(nullptr);
52 return result;
53}
54
55void PredicateParse_setResult(void *result)
56{
57 Solid::PredicateParse::ParsingData *data = s_parsingData->localData();
58 data->result = (Solid::Predicate *)result;
59}
60
61void PredicateParse_errorDetected(const char *s)
62{
63 qWarning(msg: "ERROR from solid predicate parser: %s", s);
64 s_parsingData->localData()->result = nullptr;
65}
66
67void PredicateParse_destroy(void *pred)
68{
69 Solid::PredicateParse::ParsingData *data = s_parsingData->localData();
70 Solid::Predicate *p = (Solid::Predicate *)pred;
71 if (p != data->result) {
72 delete p;
73 }
74}
75
76void *PredicateParse_newAtom(char *interface, char *property, void *value)
77{
78 QString iface = QString::fromLatin1(str: interface, size: -1);
79 QString prop = QString::fromLatin1(str: property, size: -1);
80 QVariant *val = (QVariant *)value;
81
82 Solid::Predicate *result = new Solid::Predicate(iface, prop, *val);
83
84 delete val;
85 free(ptr: interface);
86 free(ptr: property);
87
88 return result;
89}
90
91void *PredicateParse_newMaskAtom(char *interface, char *property, void *value)
92{
93 QString iface = QString::fromLatin1(str: interface, size: -1);
94 QString prop = QString::fromLatin1(str: property, size: -1);
95 QVariant *val = (QVariant *)value;
96
97 Solid::Predicate *result = new Solid::Predicate(iface, prop, *val, Solid::Predicate::Mask);
98
99 delete val;
100 free(ptr: interface);
101 free(ptr: property);
102
103 return result;
104}
105
106void *PredicateParse_newIsAtom(char *interface)
107{
108 QString iface = QString::fromLatin1(ba: interface);
109
110 Solid::Predicate *result = new Solid::Predicate(iface);
111
112 free(ptr: interface);
113
114 return result;
115}
116
117void *PredicateParse_newIsNotAtom(char *interface)
118{
119 QString iface = QString::fromLatin1(ba: interface);
120
121 Solid::Predicate *result = new Solid::Predicate(iface, Solid::Predicate::NOT);
122
123 free(ptr: interface);
124
125 return result;
126}
127
128void *PredicateParse_newAnd(void *pred1, void *pred2)
129{
130 Solid::Predicate *result = new Solid::Predicate();
131
132 Solid::PredicateParse::ParsingData *data = s_parsingData->localData();
133 Solid::Predicate *p1 = (Solid::Predicate *)pred1;
134 Solid::Predicate *p2 = (Solid::Predicate *)pred2;
135
136 if (p1 == data->result || p2 == data->result) {
137 data->result = nullptr;
138 }
139
140 *result = *p1 & *p2;
141
142 delete p1;
143 delete p2;
144
145 return result;
146}
147
148void *PredicateParse_newOr(void *pred1, void *pred2)
149{
150 Solid::Predicate *result = new Solid::Predicate();
151
152 Solid::PredicateParse::ParsingData *data = s_parsingData->localData();
153 Solid::Predicate *p1 = (Solid::Predicate *)pred1;
154 Solid::Predicate *p2 = (Solid::Predicate *)pred2;
155
156 if (p1 == data->result || p2 == data->result) {
157 data->result = nullptr;
158 }
159
160 *result = *p1 | *p2;
161
162 delete p1;
163 delete p2;
164
165 return result;
166}
167
168void *PredicateParse_newStringValue(char *val)
169{
170 QString s = QString::fromLatin1(ba: val);
171
172 free(ptr: val);
173
174 return new QVariant(s);
175}
176
177void *PredicateParse_newBoolValue(int val)
178{
179 bool b = (val != 0);
180 return new QVariant(b);
181}
182
183void *PredicateParse_newNumValue(int val)
184{
185 return new QVariant(val);
186}
187
188void *PredicateParse_newDoubleValue(double val)
189{
190 return new QVariant(val);
191}
192
193void *PredicateParse_newEmptyStringListValue()
194{
195 return new QVariant(QStringList());
196}
197
198void *PredicateParse_newStringListValue(char *name)
199{
200 QStringList list{QString::fromLatin1(ba: name)};
201
202 free(ptr: name);
203
204 return new QVariant(list);
205}
206
207void *PredicateParse_appendStringListValue(char *name, void *list)
208{
209 QVariant *variant = (QVariant *)list;
210
211 QStringList new_list = variant->toStringList();
212
213 new_list << QString::fromLatin1(ba: name);
214
215 delete variant;
216 free(ptr: name);
217
218 return new QVariant(new_list);
219}
220
221void PredicateLexer_unknownToken(const char *text)
222{
223 qWarning(msg: "ERROR from solid predicate parser: unrecognized token '%s' in predicate '%s'\n", text, s_parsingData->localData()->buffer.constData());
224}
225

source code of solid/src/solid/devices/predicateparse.cpp