Doxygen
Loading...
Searching...
No Matches
xml.l File Reference
#include <stdint.h>
#include <ctype.h>
#include <vector>
#include <stdio.h>
#include "xml.h"
+ Include dependency graph for xml.l:

Go to the source code of this file.

Classes

struct  xmlYY_state
 
struct  XMLParser::Private
 

Macros

#define YY_NEVER_INTERACTIVE   1
 
#define YY_NO_INPUT   1
 
#define YY_NO_UNISTD_H   1
 
#define YY_INPUT(buf, result, max_size)
 

Functions

static int yyread (yyscan_t yyscanner, char *buf, int max_size)
 
static void initElement (yyscan_t yyscanner)
 
static void addCharacters (yyscan_t yyscanner)
 
static void addElement (yyscan_t yyscanner)
 
static void addAttribute (yyscan_t yyscanner)
 
static void countLines (yyscan_t yyscanner, const char *txt, yy_size_t len)
 
static void reportError (yyscan_t yyscanner, const std::string &msg)
 
static std::string processData (yyscan_t yyscanner, const char *txt, yy_size_t len)
 
int yylex (yyscan_t yyscanner)
 
static void checkAndUpdatePath (yyscan_t yyscanner)
 
static std::string trimSpaces (const std::string &str)
 

Variables

static const char * entities_enc [] = { "amp", "quot", "gt", "lt", "apos" }
 
static const char entities_dec [] = { '&', '"', '>', '<', '\'' }
 
static const int num_entities = 5
 

Macro Definition Documentation

◆ YY_INPUT

#define YY_INPUT ( buf,
result,
max_size )
Value:
result=yyread(yyscanner,buf,max_size);
static int yyread(yyscan_t yyscanner, char *buf, int max_size)
Definition xml.l:230

Definition at line 75 of file xml.l.

◆ YY_NEVER_INTERACTIVE

#define YY_NEVER_INTERACTIVE   1

Definition at line 35 of file xml.l.

◆ YY_NO_INPUT

#define YY_NO_INPUT   1

Definition at line 36 of file xml.l.

◆ YY_NO_UNISTD_H

#define YY_NO_UNISTD_H   1

Definition at line 37 of file xml.l.

Function Documentation

◆ addAttribute()

static void addAttribute ( yyscan_t yyscanner)
static

Definition at line 350 of file xml.l.

351{
352 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
353 std::string val = yyextra->attrValue;
354 if (!yyextra->encoding.empty() && !yyextra->transcodeFunc(val,yyextra->encoding.c_str()))
355 {
356 reportError(yyscanner,"failed to transcode string '"+val+"' from encoding '"+yyextra->encoding+"' to UTF-8");
357 }
358 yyextra->attrs.insert(std::make_pair(yyextra->attrName,val));
static void reportError(yyscan_t yyscanner, const std::string &msg)
Definition xml.l:361
359}

References reportError().

◆ addCharacters()

static void addCharacters ( yyscan_t yyscanner)
static

Definition at line 329 of file xml.l.

330{
331 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
332 std::string data = trimSpaces(yyextra->data);
333 if (!yyextra->encoding.empty() && !yyextra->transcodeFunc(data,yyextra->encoding.c_str()))
334 {
335 reportError(yyscanner,"failed to transcode string '"+data+"' from encoding '"+yyextra->encoding+"' to UTF-8");
336 }
337 if (yyextra->handlers.characters)
338 {
339 yyextra->handlers.characters(data);
340 }
341 if (!data.empty())
342 {
343 if (yy_flex_debug)
344 {
345 fprintf(stderr,"characters(%s)\n",data.c_str());
346 }
347 }
static std::string trimSpaces(const std::string &str)
Definition xml.l:320
348}

References reportError(), and trimSpaces().

◆ addElement()

static void addElement ( yyscan_t yyscanner)
static

Definition at line 286 of file xml.l.

287{
288 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
289 if (!yyextra->isEnd)
290 {
291 yyextra->xpath.push_back(yyextra->name);
292 if (yyextra->handlers.startElement)
293 {
294 yyextra->handlers.startElement(yyextra->name,yyextra->attrs);
295 }
296 if (yy_flex_debug)
297 {
298 fprintf(stderr,"%d: startElement(%s,attr=[",yyextra->lineNr,yyextra->name.data());
299 for (auto attr : yyextra->attrs)
300 {
301 fprintf(stderr,"%s='%s' ",attr.first.c_str(),attr.second.c_str());
302 }
303 fprintf(stderr,"])\n");
304 }
305 }
306 if (yyextra->isEnd || yyextra->selfClose)
307 {
308 if (yy_flex_debug)
309 {
310 fprintf(stderr,"%d: endElement(%s)\n",yyextra->lineNr,yyextra->name.data());
311 }
312 checkAndUpdatePath(yyscanner);
313 if (yyextra->handlers.endElement)
314 {
315 yyextra->handlers.endElement(yyextra->name);
316 }
317 }
static void checkAndUpdatePath(yyscan_t yyscanner)
Definition xml.l:263
318}

References checkAndUpdatePath().

◆ checkAndUpdatePath()

static void checkAndUpdatePath ( yyscan_t yyscanner)
static

Definition at line 263 of file xml.l.

264{
265 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
266 if (yyextra->xpath.empty())
267 {
268 std::string msg = "found closing tag '"+yyextra->name+"' without matching opening tag";
269 reportError(yyscanner,msg);
270 }
271 else
272 {
273 std::string expectedTagName = yyextra->xpath.back();
274 if (expectedTagName!=yyextra->name)
275 {
276 std::string msg = "Found closing tag '"+yyextra->name+"' that does not match the opening tag '"+expectedTagName+"' at the same level";
277 reportError(yyscanner,msg);
278 }
279 else // matching end tag
280 {
281 yyextra->xpath.pop_back();
282 }
283 }
void msg(const char *fmt,...)
Definition message.cpp:98
284}

References msg(), and reportError().

Referenced by addElement().

◆ countLines()

static void countLines ( yyscan_t yyscanner,
const char * txt,
yy_size_t len )
static

Definition at line 245 of file xml.l.

246{
247 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
248 for (yy_size_t i=0;i<len;i++)
249 {
250 if (txt[i]=='\n') yyextra->lineNr++;
251 }
252}

◆ initElement()

static void initElement ( yyscan_t yyscanner)
static

Definition at line 254 of file xml.l.

255{
256 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
257 yyextra->isEnd = false; // true => </tag>
258 yyextra->selfClose = false; // true => <tag/>
259 yyextra->name = "";
260 yyextra->attrs.clear();
261}

◆ processData()

static std::string processData ( yyscan_t yyscanner,
const char * txt,
yy_size_t len )
static

Definition at line 380 of file xml.l.

381{
382 std::string result;
383 result.reserve(len);
384 for (yy_size_t i=0; i<len; i++)
385 {
386 char c = txt[i];
387 if (c=='&')
388 {
389 const int maxEntityLen = 10;
390 char entity[maxEntityLen+1];
391 entity[maxEntityLen]='\0';
392 for (yy_size_t j=0; j<maxEntityLen && i+j+1<len; j++)
393 {
394 if (txt[i+j+1]!=';')
395 {
396 entity[j]=txt[i+j+1];
397 }
398 else
399 {
400 entity[j]=0;
401 break;
402 }
403 }
404 bool found=false;
405 for (int e=0; !found && e<num_entities; e++)
406 {
407 if (strcmp(entity,entities_enc[e])==0)
408 {
409 result+=entities_dec[e];
410 i+=strlen(entities_enc[e])+1;
411 found=true;
412 }
413 }
414 if (!found)
415 {
416 std::string msg = std::string("Invalid character entity '&") + entity + ";' found\n";
417 reportError(yyscanner,msg);
418 }
419 }
420 else
421 {
422 result+=c;
423 }
424 }
425 return result;
bool found
Definition util.cpp:984
static const int num_entities
Definition xml.l:376
static const char entities_dec[]
Definition xml.l:375
static const char * entities_enc[]
Definition xml.l:374
426}

References entities_dec, entities_enc, found, msg(), num_entities, and reportError().

◆ reportError()

static void reportError ( yyscan_t yyscanner,
const std::string & msg )
static

Definition at line 361 of file xml.l.

362{
363 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
364 if (yy_flex_debug)
365 {
366 fprintf(stderr,"%s:%d: Error '%s'\n",yyextra->fileName.c_str(),yyextra->lineNr,msg.c_str());
367 }
368 if (yyextra->handlers.error)
369 {
370 yyextra->handlers.error(yyextra->fileName,yyextra->lineNr,msg);
371 }
372}

References msg().

Referenced by addAttribute(), addCharacters(), checkAndUpdatePath(), XMLParser::parse(), and processData().

◆ trimSpaces()

static std::string trimSpaces ( const std::string & str)
static

Definition at line 320 of file xml.l.

321{
322 const int l = static_cast<int>(str.length());
323 int s=0, e=l-1;
324 while (s<l && isspace(str.at(s))) s++;
325 while (e>s && isspace(str.at(e))) e--;
326 return str.substr(s,1+e-s);
327}

Referenced by addCharacters().

◆ yylex()

int yylex ( yyscan_t yyscanner)

Definition at line 110 of file xml.l.

112 {
113 {SP} { countLines(yyscanner,yytext,yyleng); }
114 {DOCTYPE} { countLines(yyscanner,yytext,yyleng); }
115 {OPENSPECIAL} { countLines(yyscanner,yytext,yyleng); BEGIN(Prolog); }
116 {OPEN} { countLines(yyscanner,yytext,yyleng);
117 initElement(yyscanner);
118 BEGIN(Element); }
119 {COMMENT} { yyextra->commentContext = YY_START;
120 BEGIN(Comment);
121 }
static void countLines(yyscan_t yyscanner, const char *txt, yy_size_t len)
Definition xml.l:245
static void initElement(yyscan_t yyscanner)
Definition xml.l:254
122}
123<Content>{
124 {CDATA} { countLines(yyscanner,yytext,yyleng);
125 yyextra->cdataContext = YY_START;
126 BEGIN(CDataSection);
127 }
128 {PCDATA} { yyextra->data += processData(yyscanner,yytext,yyleng); }
129 {OPEN} { countLines(yyscanner,yytext,yyleng);
130 addCharacters(yyscanner);
131 initElement(yyscanner);
132 BEGIN(Element);
133 }
134 {COMMENT} { yyextra->commentContext = YY_START;
135 countLines(yyscanner,yytext,yyleng);
136 BEGIN(Comment);
137 }
static void addCharacters(yyscan_t yyscanner)
Definition xml.l:329
static std::string processData(yyscan_t yyscanner, const char *txt, yy_size_t len)
Definition xml.l:380
138}
139<Element>{
140 "/" { yyextra->isEnd = true; }
141 {NAME} { yyextra->name = yytext;
142 BEGIN(Attributes); }
143 {CLOSE} { addElement(yyscanner);
144 countLines(yyscanner,yytext,yyleng);
145 yyextra->data = "";
146 BEGIN(Content);
147 }
148 {SP} { countLines(yyscanner,yytext,yyleng); }
static void addElement(yyscan_t yyscanner)
Definition xml.l:286
149}
150<Attributes>{
151 "/" { yyextra->selfClose = true; }
152 {NAME} { yyextra->attrName = yytext; }
153 "=" { BEGIN(AttributeValue); }
154 {CLOSE} { addElement(yyscanner);
155 countLines(yyscanner,yytext,yyleng);
156 yyextra->data = "";
157 BEGIN(Content);
158 }
159 {SP} { countLines(yyscanner,yytext,yyleng); }
160}
161<AttributeValue>{
162 {SP} { countLines(yyscanner,yytext,yyleng); }
163 ['"] { yyextra->stringChar = *yytext;
164 yyextra->attrValue = "";
165 BEGIN(AttrValueStr);
166 }
167 . { std::string msg = std::string("Missing attribute value. Unexpected character `")+yytext+"` found";
168 reportError(yyscanner,msg);
169 unput(*yytext);
170 BEGIN(Attributes);
171 }
172}
173<AttrValueStr>{
174 [^'"\n]+ { yyextra->attrValue += processData(yyscanner,yytext,yyleng); }
175 ['"] { if (*yytext==yyextra->stringChar)
176 {
177 addAttribute(yyscanner);
178 BEGIN(Attributes);
179 }
180 else
181 {
182 yyextra->attrValue += processData(yyscanner,yytext,yyleng);
183 }
184 }
185 \n { yyextra->lineNr++; yyextra->attrValue+=' '; }
186}
187<CDataSection>{
188 {ENDCDATA} { BEGIN(yyextra->cdataContext); }
189 [^]\n]+ { yyextra->data += yytext; }
190 \n { yyextra->data += yytext;
191 yyextra->lineNr++;
192 }
193 . { yyextra->data += yytext; }
194}
195<Prolog>{
196 "encoding"\s*=\s*\"[^\"]*\" {
197 std::string encoding=yytext;
198 size_t i=encoding.find('"');
199 encoding=encoding.substr(i+1,yyleng-i-2);
200 if (encoding!="UTF-8") // need to transcode to UTF-8
201 {
202 yyextra->encoding=encoding;
203 }
204 }
205 {CLOSESPECIAL} { countLines(yyscanner,yytext,yyleng);
206 BEGIN(Initial);
207 }
208 \n { yyextra->lineNr++; }
209 . { }
210}
211<Comment>{
212 {COMMENTEND} { countLines(yyscanner,yytext,yyleng);
213 BEGIN(yyextra->commentContext);
214 }
215 [^\n-]+ { }
216 \n { yyextra->lineNr++; }
217 . { }
218}
219\n { yyextra->lineNr++; }
220. { std::string msg = "Unexpected character `";
221 msg+=yytext;
222 msg+="` found";
223 reportError(yyscanner,msg);
224 }
225
226%%

◆ yyread()

static int yyread ( yyscan_t yyscanner,
char * buf,
int max_size )
static

Definition at line 230 of file xml.l.

231{
232 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
233 int inputPosition = yyextra->inputPosition;
234 const char *s = yyextra->inputString + inputPosition;
235 int c=0;
236 while( c < max_size && *s)
237 {
238 *buf++ = *s++;
239 c++;
240 }
241 yyextra->inputPosition += c;
242 return c;
243}

Variable Documentation

◆ entities_dec

const char entities_dec[] = { '&', '"', '>', '<', '\'' }
static

Definition at line 375 of file xml.l.

375{ '&', '"', '>', '<', '\'' };

Referenced by processData().

◆ entities_enc

const char* entities_enc[] = { "amp", "quot", "gt", "lt", "apos" }
static

Definition at line 374 of file xml.l.

374{ "amp", "quot", "gt", "lt", "apos" };

Referenced by processData().

◆ num_entities

const int num_entities = 5
static

Definition at line 376 of file xml.l.

Referenced by processData().