Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
parser.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
5#include "parser.h"
6#include <qtextstream.h>
7#include <qregularexpression.h>
8#include <qfileinfo.h>
9
10static void removeOffsetRange(qsizetype begin, qsizetype end, QList<LineNumber> &offsets)
11{
12 qsizetype count = end - begin;
13 qsizetype i = 0;
14 DEBUGPRINTF2(printf("tracepointgen: removeOffsetRange: %llu %llu\n", begin, end));
15 while (i < offsets.size()) {
16 LineNumber &cur = offsets[i];
17 if (begin > cur.end) {
18 i++;
19 } else if (begin >= cur.begin && begin <= cur.end) {
20 cur.end = begin;
21 i++;
22 } else if (begin < cur.begin && end > cur.end) {
23 offsets.remove(i);
24 DEBUGPRINTF2(printf("tracepointgen: removeOffsetRange: %llu, %llu, %d\n", cur.begin, cur.end, cur.line));
25 } else if (end >= cur.begin && end <= cur.end) {
26 cur.begin = begin;
27 cur.end -= count;
28 i++;
29 } else if (end < cur.begin) {
30 cur.begin -= count;
31 cur.end -= count;
32 i++;
33 }
34 }
35}
36
37static bool findSpaceRange(const QString &data, qsizetype &offset, qsizetype &end) {
38 qsizetype cur = data.indexOf(QLatin1Char(' '), offset);
39 if (cur >= 0) {
40 qsizetype i = cur + 1;
41 while (data.constData()[i] == QLatin1Char(' ')) i++;
42 if (i - cur > 1) {
43 offset = cur;
44 end = i - 1;
45 return true;
46 }
47 cur = data.indexOf(QLatin1Char(' '), cur + 1);
48 }
49 return false;
50}
51
52static void simplifyData(QString &data, QList<LineNumber> &offsets)
53{
54 qsizetype offset = data.indexOf(QStringLiteral("//"));
55 while (offset >= 0) {
56 qsizetype endOfLine = data.indexOf(QLatin1Char('\n'), offset);
57 if (endOfLine == -1)
58 endOfLine = data.length();
59 removeOffsetRange(offset, endOfLine, offsets);
60 data.remove(offset, endOfLine - offset);
61 offset = data.indexOf(QStringLiteral("//"), offset);
62 }
63 offset = data.indexOf(QStringLiteral("/*"));
64 while (offset >= 0) {
65 qsizetype endOfComment = data.indexOf(QStringLiteral("*/"), offset);
66 if (endOfComment == -1)
67 break;
68 removeOffsetRange(offset, endOfComment + 2, offsets);
69 data.remove(offset, endOfComment - offset + 2);
70 offset = data.indexOf(QStringLiteral("/*"), offset);
71 }
72 offset = 0;
73 qsizetype end = 0;
74 data.replace(QLatin1Char('\n'), QLatin1Char(' '));
75 while (findSpaceRange(data, offset, end)) {
76 removeOffsetRange(offset, end, offsets);
77 data.remove(offset, end - offset);
78 }
79}
80
81static void simplifyData(QString &data)
82{
83 qsizetype offset = data.indexOf(QStringLiteral("//"));
84 while (offset >= 0) {
85 qsizetype endOfLine = data.indexOf(QLatin1Char('\n'), offset);
86 if (endOfLine == -1)
87 endOfLine = data.length();
88 data.remove(offset, endOfLine - offset);
89 offset = data.indexOf(QStringLiteral("//"), offset);
90 }
91 offset = data.indexOf(QStringLiteral("/*"));
92 while (offset >= 0) {
93 qsizetype endOfComment = data.indexOf(QStringLiteral("*/"), offset);
94 if (endOfComment == -1)
95 break;
96 data.remove(offset, endOfComment - offset + 2);
97 offset = data.indexOf(QStringLiteral("/*"), offset);
98 }
99 offset = 0;
100 qsizetype end = 0;
101 while (findSpaceRange(data, offset, end))
102 data.remove(offset, end - offset);
103}
104
105static QString preprocessMetadata(const QString &in)
106{
107 DEBUGPRINTF(printf("in: %s\n", qPrintable(in)));
108 QList<QString> lines = in.split(QLatin1Char('\\'));
109 QString out;
110 for (int i = 0; i < lines.size(); i++) {
111 QString l = lines.at(i).simplified();
112 DEBUGPRINTF(printf("line: %s\n", qPrintable(l)));
113 if (l.length() < 2)
114 continue;
115 if (l.startsWith(QStringLiteral("\"")))
116 l = l.right(l.length() - 1);
117 if (l.endsWith(QStringLiteral("\"")))
118 l = l.left(l.length() - 1);
119 l = l.simplified();
120
121 if (l.length() > 1) {
122 if (out.size() > 0)
123 out.append(QLatin1Char('\n'));
124 out.append(l);
125 }
126 }
127 DEBUGPRINTF(printf("out: %s\n", qPrintable(out)));
128 return out;
129}
130
131int Parser::lineNumber(qsizetype offset) const
132{
133 DEBUGPRINTF(printf("tracepointgen: lineNumber: offset %llu, line count: %llu\n", offset , m_offsets.size()));
134 for (const auto line : m_offsets) {
135 DEBUGPRINTF(printf("tracepointgen: lineNumber: %llu %llu %d\n", line.begin, line.end, line.line));
136 if (offset >= line.begin && offset <= line.end)
137 return line.line;
138 }
139 return 0;
140}
141
142void Parser::parseParamReplace(const QString &data, qsizetype offset, const QString &name)
143{
144 Replace rep;
145 qsizetype beginBrace = data.indexOf(QLatin1Char('('), offset);
146 qsizetype endBrace = data.indexOf(QLatin1Char(')'), beginBrace);
147 QString params = data.mid(beginBrace + 1, endBrace - beginBrace -1);
148 int punc = params.indexOf(QLatin1Char(','));
149 if (punc < 0)
150 panic("Syntax error in Q_TRACE_PARAM_REPLACE at file %s, line %llu", qPrintable(name), lineNumber(offset));
151 rep.in = params.left(punc).simplified();
152 rep.out = params.right(params.length() - punc - 1).simplified();
153 if (rep.in.endsWith(QLatin1Char('*')) || rep.out.endsWith(QLatin1Char(']')))
154 rep.out.append(QLatin1Char(' '));
155 DEBUGPRINTF(printf("tracepointgen: replace: %s with %s\n", qPrintable(rep.in), qPrintable(rep.out)));
156 m_replaces.push_back(rep);
157}
158
159void Parser::parseInstrument(const QString &data, qsizetype offset)
160{
161 qsizetype beginOfProvider = data.indexOf(QLatin1Char('('), offset);
162 qsizetype endOfProvider = data.indexOf(QLatin1Char(')'), beginOfProvider);
163 Function func;
164 QString provider = data.mid(beginOfProvider + 1, endOfProvider - beginOfProvider - 1).simplified();
165 if (provider != m_provider)
166 return;
167
168 qsizetype classMarker = data.indexOf(QStringLiteral("::"), endOfProvider);
169 qsizetype beginOfFunctionMarker = data.indexOf(QLatin1Char('{'), classMarker);
170 QString begin = data.mid(endOfProvider + 1, classMarker - endOfProvider - 1);
171 QString end = data.mid(classMarker + 2, beginOfFunctionMarker - classMarker - 2);
172 int spaceIndex = begin.lastIndexOf(QLatin1Char(' '));
173 if (spaceIndex == -1)
174 func.className = begin;
175 else
176 func.className = begin.mid(spaceIndex + 1, begin.length() - spaceIndex - 1);
177 qsizetype braceIndex = end.indexOf(QLatin1Char('('));
178 spaceIndex = end.indexOf(QLatin1Char(' '));
179 if (spaceIndex < braceIndex)
180 func.functionName = end.left(spaceIndex).simplified();
181 else
182 func.functionName = end.left(braceIndex).simplified();
183
184 qsizetype lastBraceIndex = end.lastIndexOf(QLatin1Char(')'));
185 func.functionParameters = end.mid(braceIndex + 1, lastBraceIndex - braceIndex - 1).simplified();
186
187 DEBUGPRINTF(printf("tracepointgen: %s(%s)\n", qPrintable(func.functionName), qPrintable(func.functionParameters)));
188
189 m_functions.push_back(func);
190}
191
192void Parser::parsePoint(const QString &data, qsizetype offset)
193{
194 qsizetype beginOfProvider = data.indexOf(QLatin1Char('('), offset);
195 qsizetype endOfProvider = data.indexOf(QLatin1Char(','), beginOfProvider);
196 Point point;
197 QString provider = data.mid(beginOfProvider + 1, endOfProvider - beginOfProvider - 1).simplified();
198 if (provider != m_provider)
199 return;
200
201 qsizetype endOfPoint = data.indexOf(QLatin1Char(','), endOfProvider + 1);
202 qsizetype endOfPoint2 = data.indexOf(QLatin1Char(')'), endOfProvider + 1);
203 bool params = true;
204 if (endOfPoint == -1 || endOfPoint2 < endOfPoint) {
205 endOfPoint = endOfPoint2;
206 params = false;
207 }
208 point.name = data.mid(endOfProvider + 1, endOfPoint - endOfProvider - 1).simplified();
209 if (params) {
210 int endOfParams = data.indexOf(QLatin1Char(')'), endOfPoint);
211 point.parameters = data.mid(endOfPoint + 1, endOfParams - endOfPoint - 1).simplified();
212 }
213
214 DEBUGPRINTF(printf("tracepointgen: %s(%s)\n", qPrintable(point.name), qPrintable(point.parameters)));
215
216 m_points.push_back(point);
217}
218
219void Parser::parsePrefix(const QString &data, qsizetype offset)
220{
221 qsizetype beginOfProvider = data.indexOf(QLatin1Char('('), offset);
222 qsizetype endOfProvider = data.indexOf(QLatin1Char(','), beginOfProvider);
223 QString prefix;
224 QString provider = data.mid(beginOfProvider + 1, endOfProvider - beginOfProvider - 1).simplified();
225 if (provider != m_provider)
226 return;
227
228 qsizetype endOfPoint = data.indexOf(QLatin1Char(')'), endOfProvider + 1);
229 prefix = data.mid(endOfProvider + 1, endOfPoint - endOfProvider - 1).simplified();
230
231 DEBUGPRINTF(printf("tracepointgen: prefix: %s\n", qPrintable(prefix)));
232
233 if (!m_prefixes.contains(prefix))
234 m_prefixes.push_back(preprocessMetadata(prefix));
235}
236
237QStringList Parser::findEnumValues(const QString &name, const QStringList &includes)
238{
239 QStringList split = name.split(QStringLiteral("::"));
240 QString enumName = split.last();
241 DEBUGPRINTF(printf("searching for %s\n", qPrintable(name)));
242 QStringList ret;
243 for (const QString &filename : includes) {
244 QFile input(filename);
245 if (!input.open(QIODevice::ReadOnly | QIODevice::Text)) {
246 DEBUGPRINTF(printf("Cannot open '%s' for reading: %s\n",
247 qPrintable(filename), qPrintable(input.errorString())));
248 return ret;
249 }
250 QString data;
251 QTextStream stream(&input);
252 while (!stream.atEnd()) {
253 QString line = stream.readLine().trimmed();
254 data += line + QLatin1Char('\n');
255 }
256 simplifyData(data);
257
258 int pos = 0;
259 bool valid = true;
260 for (int i = 0; i < split.size() - 1; i++) {
261 QRegularExpression macro(QStringLiteral("(struct|class|namespace) +([A-Za-z0-9_]*)? +([A-Za-z0-9]*;?)"));
262 QRegularExpressionMatchIterator m = macro.globalMatch(data);
263 bool found = false;
264 while (m.hasNext() && !found) {
265 QRegularExpressionMatch match = m.next();
266 QString n = match.captured(2);
267 if (!n.endsWith(QLatin1Char(';')) && n == split[i] && match.capturedStart(2) > pos) {
268 pos = match.capturedStart(2);
269 found = true;
270 break;
271 }
272 if (match.hasCaptured(3)) {
273 n = match.captured(3);
274 if (!n.endsWith(QLatin1Char(';')) && n == split[i] && match.capturedStart(3) > pos) {
275 pos = match.capturedStart(3);
276 found = true;
277 break;
278 }
279 }
280 }
281 if (!found) {
282 valid = false;
283 break;
284 }
285 }
286
287 if (valid) {
288 QRegularExpression macro(QStringLiteral("enum +([A-Za-z0-9_]*)"));
289 QRegularExpressionMatchIterator m = macro.globalMatch(data);
290 while (m.hasNext()) {
291 QRegularExpressionMatch match = m.next();
292
293 if (match.capturedStart() < pos)
294 continue;
295
296 QString n = match.captured(1);
297
298 if (n == enumName) {
299 DEBUGPRINTF(printf("Found enum: %s\n", qPrintable(n)));
300 int begin = data.indexOf(QLatin1Char('{'), match.capturedEnd());
301 int end = data.indexOf(QLatin1Char('}'), begin);
302 QString block = data.mid(begin + 1, end - begin - 1);
303 const QStringList enums = block.split(QLatin1Char('\n'));
304 for (const auto &e : enums) {
305 const auto trimmed = e.trimmed();
306 if (!trimmed.isEmpty() && !trimmed.startsWith(QLatin1Char('#')))
307 ret << trimmed;
308 }
309
310 return ret;
311 }
312 }
313 }
314 }
315 return ret;
316}
317
319{
320 QString name;
321 QString valueStr;
322 int value;
323};
324
325static QList<EnumNameValue> enumsToValues(const QStringList &values)
326{
327 int cur = 0;
328 QList<EnumNameValue> ret;
329 for (const QString &value : values) {
330 EnumNameValue r;
331 if (value.contains(QLatin1Char('='))) {
332 size_t offset = value.indexOf(QLatin1Char('='));
333 r.name = value.left(offset).trimmed();
334 QString val = value.right(value.length() - offset - 1).trimmed();
335 if (val.endsWith(QLatin1Char(',')))
336 val = val.left(val.length() - 1);
337 bool valid = false;
338 int integer = val.toInt(&valid);
339 if (!valid)
340 integer = val.toInt(&valid, 16);
341 if (valid) {
342 cur = r.value = integer;
343 ret << r;
344 } else {
345 auto iter = std::find_if(ret.begin(), ret.end(), [&val](const EnumNameValue &elem){
346 return elem.name == val;
347 });
348 if (iter != ret.end()) {
349 cur = r.value = iter->value;
350 ret << r;
351 } else {
352 DEBUGPRINTF(printf("Invalid value: %s %s\n", qPrintable(r.name), qPrintable(value)));
353 }
354 }
355 } else {
356 if (value.endsWith(QLatin1Char(',')))
357 r.name = value.left(value.length() - 1);
358 else
359 r.name = value;
360 r.value = ++cur;
361 ret << r;
362 }
363 }
364 return ret;
365}
366
367void Parser::parseMetadata(const QString &data, qsizetype offset, const QStringList &includes)
368{
369 qsizetype beginOfProvider = data.indexOf(QLatin1Char('('), offset);
370 qsizetype endOfProvider = data.indexOf(QLatin1Char(','), beginOfProvider);
371 QString metadata;
372 QString provider = data.mid(beginOfProvider + 1, endOfProvider - beginOfProvider - 1).simplified();
373 if (provider != m_provider)
374 return;
375
376 qsizetype endOfPoint = data.indexOf(QLatin1Char(')'), endOfProvider + 1);
377 metadata = data.mid(endOfProvider + 1, endOfPoint - endOfProvider - 1).simplified();
378
379 DEBUGPRINTF(printf("tracepointgen: metadata: %s", qPrintable(metadata)));
380
381 QString preprocessed = preprocessMetadata(metadata);
382
383 DEBUGPRINTF2(printf("preprocessed %s\n", qPrintable(preprocessed)));
384
385 QRegularExpression macro(QStringLiteral("([A-Z]*) ?{ ?([A-Za-z0-9=_,. ]*) ?} ?([A-Za-z0-9_:]*) ?;"));
386 QRegularExpressionMatchIterator i = macro.globalMatch(preprocessed);
387 qsizetype prev = 0;
388 while (i.hasNext()) {
389 QRegularExpressionMatch match = i.next();
390 QString values = match.captured(2).trimmed();
391 int cur = match.capturedStart();
392 if (cur > prev)
393 m_metadata.append(preprocessed.mid(prev, cur - prev));
394
395 prev = match.capturedEnd() + 1;
396 DEBUGPRINTF2(printf("values: %s\n", qPrintable(values)));
397 if (values.isEmpty() || values.startsWith(QStringLiteral("AUTO"))) {
398 values.replace(QLatin1Char('\n'), QLatin1Char(' '));
399 QStringList ranges;
400 if (values.contains(QStringLiteral("RANGE"))) {
401 QRegularExpression rangeMacro(QStringLiteral("RANGE +([A-Za-z0-9_]*) +... +([A-Za-z0-9_]*)"));
402 QRegularExpressionMatchIterator r = rangeMacro.globalMatch(values);
403 while (r.hasNext()) {
404 QRegularExpressionMatch rm = r.next();
405 ranges << rm.captured(1);
406 ranges << rm.captured(2);
407 DEBUGPRINTF2(printf("range: %s ... %s\n", qPrintable(rm.captured(1)), qPrintable(rm.captured(2))));
408 }
409 }
410
411 const auto enumOrFlag = match.captured(1);
412 const auto name = match.captured(3);
413 const bool flags = enumOrFlag == QStringLiteral("FLAGS");
414
415 QStringList values = findEnumValues(name, includes);
416 if (values.isEmpty()) {
417 if (flags && name.endsWith(QLatin1Char('s')))
418 values = findEnumValues(name.left(name.length() - 1), includes);
419 if (values.isEmpty()) {
420 DEBUGPRINTF(printf("Unable to find values for %s\n", qPrintable(name)));
421 }
422 }
423 if (!values.isEmpty()) {
424 auto moreValues = enumsToValues(values);
425 if (ranges.size()) {
426 for (int i = 0; i < ranges.size() / 2; i++) {
427 bool rangeFound = false;
428 for (auto &v : moreValues) {
429 if (v.name == ranges[2 * i]) {
430 rangeFound = true;
431 QString rangeEnd = ranges[2 * i + 1];
432 auto iter = std::find_if(moreValues.begin(), moreValues.end(), [&rangeEnd](const EnumNameValue &elem){
433 return elem.name == rangeEnd;
434 });
435 if (iter != moreValues.end())
436 v.valueStr = QStringLiteral("RANGE(%1, %2 ... %3)").arg(v.name).arg(v.value).arg(iter->value);
437 else
438 panic("Unable to find range end: %s\n", qPrintable(rangeEnd));
439 break;
440 }
441 }
442 if (rangeFound == false)
443 panic("Unable to find range begin: %s\n", qPrintable(ranges[2 * i]));
444 }
445 }
446 std::sort(moreValues.begin(), moreValues.end(), [](const EnumNameValue &a, const EnumNameValue &b) {
447 return a.value < b.value;
448 });
449 values.clear();
450 int prevValue = std::as_const(moreValues).front().value;
451 for (const auto &v : std::as_const(moreValues)) {
452 QString a;
453 if (v.valueStr.isNull()) {
454 if (v.value == prevValue + 1 && !flags)
455 a = v.name;
456 else
457 a = QStringLiteral("%1 = %2").arg(v.name).arg(v.value);
458 prevValue = v.value;
459 } else {
460 a = v.valueStr;
461 }
462 values << a;
463 }
464
465 metadata = QStringLiteral("%1 {\n %2 \n} %3;").arg(enumOrFlag).arg(values.join(QStringLiteral(",\n"))).arg(name);
466 if (!m_metadata.contains(metadata))
467 m_metadata.append(metadata);
468 }
469 } else {
470 if (!m_metadata.contains(match.captured()))
471 m_metadata.append(match.captured());
472 }
473 }
474 if (prev < preprocessed.length())
475 m_metadata.append(preprocessed.mid(prev, preprocessed.length() - prev));
476}
477
478QString Parser::resolveInclude(const QString &filename)
479{
480 QFileInfo info(filename);
481 if (info.exists())
482 return info.absoluteFilePath();
483 for (const QString &sp : std::as_const(m_includeDirs)) {
484 info = QFileInfo(sp + QLatin1Char('/') + filename);
485 if (info.exists())
486 return info.absoluteFilePath();
487 }
488 return {};
489}
490
491void Parser::addIncludesRecursive(const QString &filename, QList<QString> &includes)
492{
493 QFileInfo info(filename);
494 DEBUGPRINTF(printf("check include: %s\n", qPrintable(filename)));
495 QFile input(filename);
496 if (!input.open(QIODevice::ReadOnly | QIODevice::Text)) {
497 DEBUGPRINTF(printf("Cannot open '%s' for reading: %s\n",
498 qPrintable(filename), qPrintable(input.errorString())));
499 return;
500 }
501 QString data;
502 QTextStream stream(&input);
503 while (!stream.atEnd()) {
504 QString line = stream.readLine().trimmed();
505 data += line + QLatin1Char(QLatin1Char('\n'));
506 }
507
508 QRegularExpression includeMacro(QStringLiteral("#include [\"<]([A-Za-z0-9_./-]*.h)[\">]"));
509 QRegularExpressionMatchIterator i = includeMacro.globalMatch(data);
510 while (i.hasNext()) {
511 QRegularExpressionMatch match = i.next();
512 QString filename = match.captured(1);
513
514 QString rinc = filename;
515 if (filename.startsWith(QStringLiteral("../"))) {
516 QFileInfo info2(info.absolutePath() + QLatin1Char('/') + filename);
517 if (!info2.exists()) {
518 DEBUGPRINTF(printf("unable to find %s\n", qPrintable(filename)));
519 continue;
520 }
521 rinc = info2.absoluteFilePath();
522 filename = info2.fileName();
523 }
524 // only search possible qt headers
525 if (QFileInfo(filename).baseName().startsWith(QLatin1Char('q'), Qt::CaseInsensitive)) {
526 QString resolved = resolveInclude(rinc);
527 if (!resolved.isEmpty() && !includes.contains(resolved)) {
528 includes.push_back(resolved);
529 addIncludesRecursive(resolved, includes);
530 }
531 }
532 }
533}
534
535void Parser::parse(QIODevice &input, const QString &name)
536{
537 QString data;
538 QTextStream stream(&input);
539 int lineNumber = 1;
540 qsizetype prev = 0;
541 while (!stream.atEnd()) {
542 QString line = stream.readLine().trimmed();
543 m_offsets.push_back({prev, prev + line.length(), lineNumber++});
544 prev += line.length() + 1;
545 data += line + QLatin1Char(QLatin1Char('\n'));
546 }
547
548 simplifyData(data, m_offsets);
549
550 QStringList includes;
551
552 QRegularExpression includeMacro(QStringLiteral("#include [\"<]([A-Za-z0-9_./-]*.h)[\">]"));
553 QRegularExpressionMatchIterator i = includeMacro.globalMatch(data);
554 while (i.hasNext()) {
555 QRegularExpressionMatch match = i.next();
556 const QString filename = match.captured(1);
557 // only search possible qt headers
558 if (filename.startsWith(QLatin1Char('q'), Qt::CaseInsensitive)) {
559 const QString resolved = resolveInclude(filename);
560 if (!resolved.isEmpty() && !includes.contains(resolved)) {
561 includes.push_back(resolved);
562 addIncludesRecursive(resolved, includes);
563 }
564 }
565 }
566
567 QRegularExpression traceMacro(QStringLiteral("Q_TRACE_([A-Z_]*)"));
568 i = traceMacro.globalMatch(data);
569 while (i.hasNext()) {
570 QRegularExpressionMatch match = i.next();
571
572 QString macroType = match.captured(1);
573 if (macroType == QStringLiteral("PARAM_REPLACE"))
574 parseParamReplace(data, match.capturedEnd(), name);
575 else if (macroType == QStringLiteral("INSTRUMENT"))
576 parseInstrument(data, match.capturedEnd());
577 else if (macroType == QStringLiteral("POINT"))
578 parsePoint(data, match.capturedEnd());
579 else if (macroType == QStringLiteral("PREFIX"))
580 parsePrefix(data, match.capturedEnd());
581 else if (macroType == QStringLiteral("METADATA"))
582 parseMetadata(data, match.capturedEnd(), includes);
583 }
584
585 for (auto &func : m_functions) {
586 for (auto &rep : m_replaces)
587 func.functionParameters.replace(rep.in, rep.out);
588 }
589}
590
591void Parser::write(QIODevice &input) const
592{
593 QTextStream out(&input);
594 if (m_prefixes.size() > 0) {
595 out << QStringLiteral("{\n");
596 for (const auto &prefix : m_prefixes)
597 out << prefix << "\n";
598 out << QStringLiteral("}\n");
599 }
600 for (const auto &m : m_metadata)
601 out << m << "\n";
602 for (const auto &func : m_functions) {
603 out << func.className << "_" << func.functionName << "_entry(" << func.functionParameters << ")\n";
604 out << func.className << "_" << func.functionName << "_exit()\n";
605 }
606 for (const auto &point : m_points)
607 out << point.name << "(" << point.parameters << ")\n";
608}
int lineNumber(qsizetype offset) const
Definition parser.cpp:131
void parseParamReplace(const QString &data, qsizetype offset, const QString &name)
Definition parser.cpp:142
void parseMetadata(const QString &data, qsizetype offset, const QStringList &includes)
Definition parser.cpp:367
void parsePrefix(const QString &data, qsizetype offset)
Definition parser.cpp:219
QString resolveInclude(const QString &filename)
Definition parser.cpp:478
QStringList findEnumValues(const QString &name, const QStringList &includes)
Definition parser.cpp:237
void parseInstrument(const QString &data, qsizetype offset)
Definition parser.cpp:159
void parsePoint(const QString &data, qsizetype offset)
Definition parser.cpp:192
Definition qlist.h:80
QT_FORWARD_DECLARE_CLASS(QTextStream)
QString valueStr
Definition parser.cpp:321
QString name
Definition parser.cpp:320
Definition parser.h:19
static void removeOffsetRange(qsizetype begin, qsizetype end, QList< LineNumber > &offsets)
Definition parser.cpp:10
static void simplifyData(QString &data, QList< LineNumber > &offsets)
Definition parser.cpp:52
static void simplifyData(QString &data)
Definition parser.cpp:81
static QList< EnumNameValue > enumsToValues(const QStringList &values)
Definition parser.cpp:325
static bool findSpaceRange(const QString &data, qsizetype &offset, qsizetype &end)
Definition parser.cpp:37
static QString preprocessMetadata(const QString &in)
Definition parser.cpp:105
#define DEBUGPRINTF2(x)
#define DEBUGPRINTF(x)