KOSMIndoorMap

mapcssparser.cpp
1 /*
2  SPDX-FileCopyrightText: 2020 Volker Krause <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "mapcssparser.h"
8 #include "logging.h"
9 
10 #include "mapcssparser_p.h"
11 #include "mapcssrule_p.h"
12 #include "mapcssscanner.h"
13 #include "mapcssstyle.h"
14 #include "mapcssstyle_p.h"
15 
16 #include <QDebug>
17 #include <QFile>
18 #include <QFileInfo>
19 #include <QScopeGuard>
20 
21 #include <cstring>
22 
23 char* unquoteString(const char *str)
24 {
25  const auto size = strlen(str) - 2;
26  if (size <= 0)
27  return nullptr;
28  auto out = (char*)malloc(size + 1);
29  memset(out, 0, size + 1);
30  auto outIt = out;
31  for (auto it = str + 1; it < str + size + 1; ++it, ++outIt) {
32  if (*it == '\\') {
33  ++it;
34  switch (*it) {
35  case '\\':
36  case '"':
37  *outIt = *it; break;
38  case 'n':
39  *outIt = '\n'; break;
40  case 't':
41  *outIt = '\t'; break;
42  default:
43  *outIt++ = '\\';
44  *outIt = *it;
45  }
46  } else {
47  *outIt = *it;
48  }
49  }
50  return out;
51 }
52 
53 using namespace KOSMIndoorMap;
54 
55 bool MapCSSParser::hasError() const
56 {
57  return m_error;
58 }
59 
60 QString MapCSSParser::fileName() const
61 {
62  return m_currentFileName;
63 }
64 
65 QString MapCSSParser::errorMessage() const
66 {
67  if (!m_error) {
68  return {};
69  }
70 
71  return m_errorMsg + QLatin1String(": ") + fileName() + QLatin1Char(':') + QString::number(m_line) + QLatin1Char(':') + QString::number(m_column);
72 }
73 
74 MapCSSStyle MapCSSParser::parse(const QString &fileName)
75 {
76  m_error = true;
77 
78  MapCSSStyle style;
79  parse(&style, fileName);
80  if (m_error) {
81  return MapCSSStyle();
82  }
83 
84  return style;
85 }
86 
87 void MapCSSParser::parse(MapCSSStyle *style, const QString &fileName)
88 {
89  QFile f(fileName);
90  if (!f.open(QFile::ReadOnly)) {
91  qCWarning(Log) << f.fileName() << f.errorString();
92  m_error = true;
93  m_errorMsg = f.errorString();
94  return;
95  }
96  m_currentFileName = fileName;
97  m_currentStyle = style;
98 
99  yyscan_t scanner;
100  if (yylex_init(&scanner)) {
101  return;
102  }
103  const auto lexerCleanup = qScopeGuard([&scanner]{ yylex_destroy(scanner); });
104 
105  const auto b = f.readAll();
106  YY_BUFFER_STATE state;
107  state = yy_scan_string(b.constData(), scanner);
108  if (yyparse(this, scanner)) {
109  m_error = true;
110  return;
111  }
112 
113  yy_delete_buffer(state, scanner);
114 
115  m_error = false;
116  m_currentStyle = nullptr;
117 }
118 
119 bool MapCSSParser::addImport(char* fileName)
120 {
121  auto cssFile = QString::fromUtf8(fileName);
122  free(fileName);
123 
124  if (QFileInfo(cssFile).isRelative()) {
125  cssFile = QFileInfo(m_currentFileName).absolutePath() + QLatin1Char('/') + cssFile;
126  }
127 
128  MapCSSParser p;
129  p.parse(m_currentStyle, cssFile);
130  if (p.hasError()) {
131  m_error = p.m_error;
132  m_errorMsg = p.errorMessage();
133  }
134  return !p.hasError();
135 }
136 
137 void MapCSSParser::addRule(MapCSSRule *rule)
138 {
139  MapCSSStylePrivate::get(m_currentStyle)->m_rules.push_back(std::unique_ptr<MapCSSRule>(rule));
140 }
141 
142 void MapCSSParser::setError(const QString &msg, int line, int column)
143 {
144  m_error = true;
145  m_errorMsg = msg;
146  m_line = line;
147  m_column = column;
148 }
149 
150 ClassSelectorKey MapCSSParser::makeClassSelector(const char *str, std::size_t len)
151 {
152  return MapCSSStylePrivate::get(m_currentStyle)->m_classSelectorRegistry.makeKey(str, len, OSM::StringMemory::Transient);
153 }
154 
155 LayerSelectorKey MapCSSParser::makeLayerSelector(const char *str, std::size_t len)
156 {
157  if (!str || std::strcmp(str, "default") == 0) {
158  return {};
159  }
160  return MapCSSStylePrivate::get(m_currentStyle)->m_layerSelectorRegistry.makeKey(str, len, OSM::StringMemory::Transient);
161 }
OSM-based multi-floor indoor maps for buildings.
A parsed MapCSS style sheet.
Definition: mapcssstyle.h:29
QString number(int n, int base)
QString fromUtf8(const char *str, int size)
QString absolutePath() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Oct 23 2021 23:03:45 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.