Version 7.0
Copyright © 2021 Lowell D. Thomas
APG
… an ABNF Parser Generator
elements.c
Go to the documentation of this file.
1 /* *************************************************************************************
2  Copyright (c) 2021, Lowell D. Thomas
3  All rights reserved.
4 
5  This file is part of APG Version 7.0.
6  APG Version 7.0 may be used under the terms of the BSD 2-Clause License.
7 
8  Redistribution and use in source and binary forms, with or without
9  modification, are permitted provided that the following conditions are met:
10 
11  1. Redistributions of source code must retain the above copyright notice, this
12  list of conditions and the following disclaimer.
13 
14  2. Redistributions in binary form must reproduce the above copyright notice,
15  this list of conditions and the following disclaimer in the documentation
16  and/or other materials provided with the distribution.
17 
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 * *************************************************************************************/
34 #include "callbacks.h"
35 
36 typedef struct {
40 } att_cdata;
41 static att_cdata sMakeAtts(xml*spXml, element_frame* spF, aint uiOffset);
42 static abool bAttNameLookup(xml* spXml, uint32_t* uipName, uint32_t uiLen);
43 static att_decl* spElNameLookup(xml* spXml, uint32_t* uipEName, uint32_t uiELen);
44 
45 static uint8_t s_ucRightBracket = 93;
46 
47 /*********************************************************
48  * ELEMENTS ++++++++++++++++++++++++++++++++++++++++++++++
49  ********************************************************/
50 void vEStart(callback_data* spData){
51  if(spData->uiParserState == ID_MATCH){
52  xml* spXml = (xml*)spData->vpUserData;
53  // check for default attributes
54  element_frame* spF = spXml->spCurrentFrame; // convenience
55  uint32_t* uipChars = (uint32_t*)vpVecFirst(spXml->vpVec32);
56  uint32_t* uipName = uipChars + spF->sSName.uiOffset;
57  att_decl* spDecl = spElNameLookup(spXml, uipName, spF->sSName.uiLength);
58  if(spDecl){
59  // this element has default attribute values
60  att_decl* spEnd = spDecl + spDecl->uiAttCount;
61  for(; spDecl < spEnd; spDecl++){
62  uipName = uipChars + spDecl->sAttName.uiOffset;
63  if(!bAttNameLookup(spXml, uipName, spDecl->sAttName.uiLength)){
64  // no attribute of this default name exists - add the attribute with its default value
65  named_value* spNew = (named_value*)vpVecPush(spXml->vpVecAttList, NULL);
66  spNew->sName = spDecl->sAttName;
67  spNew->sValue = spDecl->sAttValue;
68  spF->uiAttCount++;
69  }
70  }
71  }
72  }
73 }
74 void vEOpen(callback_data* spData){
75  if(spData->uiParserState == ID_MATCH){
76  xml* spXml = (xml*)spData->vpUserData;
77  aint uiLen = uiVecLen(spXml->vpVecName);
78  vPushFrame(spData);
79  spXml->spCurrentFrame->uiElementOffset = spData->uiParserOffset;
80  spXml->spCurrentFrame->sSName.uiOffset = uiVecLen(spXml->vpVec32);
81  spXml->spCurrentFrame->sSName.uiLength = (uint32_t)uiLen;
82  vpVecPushn(spXml->vpVec32, vpVecFirst(spXml->vpVecName), uiLen);
83  }
84 }
85 void vEReserved(callback_data* spData){
86  if(spData->uiParserState == ID_MATCH){
87  xml* spXml = (xml*)spData->vpUserData;
88  XML_THROW("Tag names beginning with \"xml:\" are reserved - Extensible Markup Language (XML) 1.0 (Fifth Edition) errata\n"
89  "https://www.w3.org/XML/xml-V10-5e-errata");
90  }
91 }
92 void vEmptyClose(callback_data* spData){
93  if(spData->uiParserState == ID_MATCH){
94  xml* spXml = (xml*)spData->vpUserData;
95  if(spXml->pfnEmptyTagCallback){
96  att_cdata sAttData = sMakeAtts(spXml, spXml->spCurrentFrame, spData->uiParserOffset);
97  spXml->pfnEmptyTagCallback(&sAttData.sName, sAttData.spAttNames, sAttData.spAttValues,
98  spXml->spCurrentFrame->uiAttCount, spXml->vpEmptyTagData);
99  }
100  vPopFrame(spData);
101  }
102 }
103 void vSTagClose(callback_data* spData){
104  if(spData->uiParserState == ID_MATCH){
105  xml* spXml = (xml*)spData->vpUserData;
106  if(spXml->pfnStartTagCallback){
107  att_cdata sAttData = sMakeAtts(spXml, spXml->spCurrentFrame, spData->uiParserOffset);
108  spXml->pfnStartTagCallback(&sAttData.sName, sAttData.spAttNames, sAttData.spAttValues,
109  spXml->spCurrentFrame->uiAttCount, spXml->vpStartTagData);
110  }
111 
112  // initialize content
113  spXml->spCurrentFrame->sContent.uiOffset = (uint32_t)uiVecLen(spXml->vpVec32);
114  spXml->spCurrentFrame->sContent.uiLength = 0;
115  }else if(spData->uiParserState == ID_NOMATCH){
116  xml* spXml = (xml*)spData->vpUserData;
117  XML_THROW("malformed start tag");
118  }
119 }
120 void vETagClose(callback_data* spData){
121  if(spData->uiParserState == ID_MATCH){
122  xml* spXml = (xml*)spData->vpUserData;
123  element_frame* spF = spXml->spCurrentFrame; // convenience
124  uint32_t uiELen = (uint32_t)uiVecLen(spXml->vpVecName);
125  uint32_t* uipEName = (uint32_t*)vpVecFirst(spXml->vpVecName);
126  uint32_t* uipSName = (uint32_t*)vpVecAt(spXml->vpVec32, spF->sSName.uiOffset);
127  uint32_t uiSLen = spF->sSName.uiLength;
128  if(!bCompNames(uipSName, uiSLen, uipEName, uiELen)){
129  XML_THROW("Well-formedness constraint: Element Type Match\n"
130  "The Name in an element's end-tag MUST match the element type in the start-tag.");
131  }
132  spF->sContent.uiLength = (uint32_t)uiVecLen(spXml->vpVec32) - spF->sContent.uiOffset;
133 
134  // copy name to end tag name and call the user's call back function, if any
135  spF->sEName.uiOffset = (uint32_t)uiVecLen(spXml->vpVec32);
136  spF->sEName.uiLength = uiELen;
137  vpVecPushn(spXml->vpVec32, vpVecFirst(spXml->vpVecName), (aint)uiELen);
138  if(spXml->pfnEndTagCallback){
139  u32_phrase sName;
140  u32_phrase sContent;
141  vMakeCDataDisplay(spXml, &spF->sEName, &sName, spData->uiParserOffset);
142  vMakeCDataDisplay(spXml, &spF->sContent, &sContent, spData->uiParserOffset);
143  spXml->pfnEndTagCallback(&sName, &sContent, spXml->vpEndTagData);
144  }
145  vPopFrame(spData);
146  }else if(spData->uiParserState == ID_NOMATCH){
147  xml* spXml = (xml*)spData->vpUserData;
148  XML_THROW("malformed end tag");
149  }
150 }
151 /*********************************************************
152  * ELEMENTS ----------------------------------------------
153  ********************************************************/
154 /*********************************************************
155  * ATTRIBUTES ++++++++++++++++++++++++++++++++++++++++++++
156  ********************************************************/
157 void vElAttName(callback_data* spData){
158  if(spData->uiParserState == ID_MATCH){
159  xml* spXml = (xml*)spData->vpUserData;
160 
161  // validate the name - make sure it is not a duplicate
162  aint uiNameLen = uiVecLen(spXml->vpVecName);
163  if(bAttNameLookup(spXml, (uint32_t*)vpVecFirst(spXml->vpVecName), (uint32_t)uiNameLen)){
164  XML_THROW("Well-formedness constraint: Unique Att Spec\n"
165  "An attribute name MUST NOT appear more than once in the same start-tag or empty-element tag.");
166  }
167 
168  // push the name on the 32 data
169  named_value* spNv = (named_value*)vpVecPush(spXml->vpVecAttList, NULL);
170  spNv->sName.uiOffset = uiVecLen(spXml->vpVec32);
171  spNv->sName.uiLength = uiVecLen(spXml->vpVecName);
172  vpVecPushn(spXml->vpVec32, vpVecFirst(spXml->vpVecName), uiNameLen);
173  spNv->sValue.uiOffset = uiVecLen(spXml->vpVec32);
174  }
175 }
176 void vAttValue(callback_data* spData){
177  if(spData->uiParserState == ID_MATCH){
178  xml* spXml = (xml*)spData->vpUserData;
179  named_value* spNv = (named_value*)vpVecLast(spXml->vpVecAttList);
180  spNv->sValue.uiLength = (uint32_t)(uiVecLen(spXml->vpVec32) - spNv->sValue.uiOffset);
181  spXml->spCurrentFrame->uiAttCount++;
182 
183  // validate the value
184  uint32_t* uipData = (uint32_t*)vpVecFirst(spXml->vpVec32) + spNv->sValue.uiOffset;
185  uint32_t* uipDataEnd = uipData + spNv->sValue.uiLength;
186  for(; uipData < uipDataEnd; uipData++){
187  if(*uipData == 60){
188  XML_THROW("Well-formedness constraint: No < in Attribute Values\n"
189  "The replacement text of any entity referred to directly or indirectly in an attribute value MUST NOT contain a <.");
190  }
191  }
192  }
193 }
194 void vDvalue(callback_data* spData){
195  if(spData->uiParserState == ID_MATCH){
196  xml* spXml = (xml*)spData->vpUserData;
197  vpVecPush(spXml->vpVec32, &spXml->uiChar);
198  }
199 }
200 void vDChar(callback_data* spData){
201  if(spData->uiParserState == ID_MATCH){
202  xml* spXml = (xml*)spData->vpUserData;
203  // normalize the attribute value here
204  if((spXml->uiChar == 9) || (spXml->uiChar == 10) || (spXml->uiChar == 13)){
205  spXml->uiChar = 32;
206  }
207  }
208 }
209 void vEntityRef(callback_data* spData){
210  if(spData->uiParserState == ID_MATCH){
211  xml* spXml = (xml*)spData->vpUserData;
212  // look up the entity name
213  uint32_t* uipName = (uint32_t*)vpVecFirst(spXml->vpVecName);
214  uint32_t uiNameLen = (uint32_t)uiVecLen(spXml->vpVecName);
215  entity_decl* spEntity = spEntityNameLookup(spXml, spXml->spCurrentFrame->uiElementOffset, uipName, uiNameLen);
216  if(!spEntity){
217  XML_THROW("Well-formedness constraint: Entity Declared\n"
218  "The replacement text of any entity referred to directly or indirectly in an attribute value MUST NOT contain a <.");
219  }
220  if(!spEntity->bExpanded){
221  vExpandEntity(spXml, spData->uiParserOffset, spEntity);
222  }
223 
224  // push the entity value on vpVec32
225  uint32_t* uipValue = (uint32_t*)vpVecFirst(spXml->vpVec32) + spEntity->sValue.uiOffset;
226  vpVecPushn(spXml->vpVec32, uipValue, spEntity->sValue.uiLength);
227  }
228 }
229 void vDecValue(callback_data* spData){
230  if(spData->uiParserState == ID_MATCH){
231  xml* spXml = (xml*)spData->vpUserData;
232  aint ui;
233  const achar* acpChar = &spData->acpString[spData->uiParserOffset];
234  uint32_t uiSum, uiDigit;
235  uiSum = 0;
236  for(ui = 0; ui < spData->uiParserPhraseLength; ui++, acpChar++){
237  uiDigit = *acpChar - 48;
238  if(!bMultiply32(uiSum, 10, &uiSum)){
239  XML_THROW("decimal value in Reference is too large: causes uint32_t overflow");
240  }
241  if(!bSum32(uiSum, uiDigit, &uiSum)){
242  XML_THROW("decimal value in Reference is too large: causes uint32_t overflow");
243  }
244  }
245  if(!bValidateChar(uiSum)){
246  char caBuf[CABUF_LEN];
247  snprintf(caBuf, CABUF_LEN, "Well-formedness Constraint: Legal Character\n"
248  "Characters referred to using character references MUST match the production for Char\n"
249  "https://www.w3.org/TR/REC-xml/#sec-references\n"
250  "decimal character: %u", uiSum);
251  XML_THROW(caBuf);
252  }
253  spXml->uiChar = uiSum;
254  }else if(spData->uiParserState == ID_NOMATCH){
255  xml* spXml = (xml*)spData->vpUserData;
256  XML_THROW("decimal character reference error");
257  }
258 }
259 void vHexValue(callback_data* spData){
260  if(spData->uiParserState == ID_MATCH){
261  xml* spXml = (xml*)spData->vpUserData;
262  aint ui;
263  char caBuf[CABUF_LEN];
264  const achar* acpChar = &spData->acpString[spData->uiParserOffset];
265  uint32_t uiSum = 0;
266  uint32_t uiDigit = 0;
267  for(ui = 0; ui < spData->uiParserPhraseLength; ui++, acpChar++){
268  if(*acpChar >= 48 && *acpChar <= 57){
269  uiDigit = *acpChar - 48;
270  }else if(*acpChar >= 65 && *acpChar <= 70){
271  uiDigit = *acpChar - 55;
272  }else if(*acpChar >= 97 && *acpChar <= 102){
273  uiDigit = *acpChar - 87;
274  }else{
275  snprintf(caBuf, CABUF_LEN, "illegal hex digit in Reference: %c", *(char*)acpChar);
276  XML_THROW(caBuf);
277  }
278  if(!bMultiply32(uiSum, 16, &uiSum)){
279  XML_THROW("hex value in Reference is too large: causes 32-bit overflow");
280  }
281  if(!bSum32(uiSum, uiDigit, &uiSum)){
282  XML_THROW("hex value in Reference is too large: causes 32-bit overflow");
283  }
284  }
285  if(!bValidateChar(uiSum)){
286  char caBuf[CABUF_LEN];
287  snprintf(caBuf, CABUF_LEN, "Well-formedness Constraint: Legal Character\n"
288  "Characters referred to using character references MUST match the production for Char\n"
289  "https://www.w3.org/TR/REC-xml/#sec-references\n"
290  "hex character: 0x%X", uiSum);
291  XML_THROW(caBuf);
292  }
293  spXml->uiChar = uiSum;
294  }else if(spData->uiParserState == ID_NOMATCH){
295  xml* spXml = (xml*)spData->vpUserData;
296  XML_THROW("hex character reference error");
297  }
298 }
299 /*********************************************************
300  * ATTRIBUTES --------------------------------------------
301  ********************************************************/
306 static abool bAttNameLookup(xml* spXml, uint32_t* uipName, uint32_t uiLen){
307  if(spXml->spCurrentFrame->uiAttCount){
308  uint32_t* uipChars = (uint32_t*)vpVecFirst(spXml->vpVec32);
309  uint32_t* uipLName;
310  uint32_t uiLLen;
311  named_value* spValue = (named_value*)vpVecFirst(spXml->vpVecAttList);
312  named_value* spEnd = spValue + spXml->spCurrentFrame->uiAttCount;
313  for(; spValue < spEnd; spValue++){
314  uipLName = uipChars + spValue->sName.uiOffset;
315  uiLLen = spValue->sName.uiLength;
316  if(bCompNames(uipLName, uiLLen, uipName, uiLen)){
317  return APG_TRUE;
318  }
319  }
320  }
321  return APG_FALSE;
322 }
323 static att_decl* spElNameLookup(xml* spXml, uint32_t* uipEName, uint32_t uiELen){
324  aint uiCount = uiVecLen(spXml->vpVecAttDecls);
325  if(uiCount){
326  uint32_t* uipChars = (uint32_t*)vpVecFirst(spXml->vpVec32);
327  att_decl* spDecl = (att_decl*)vpVecFirst(spXml->vpVecAttDecls);
328  att_decl* spEnd = spDecl + uiCount;
329  for(; spDecl < spEnd; spDecl++){
330  if(bCompNames((uipChars + spDecl->sElementName.uiOffset), spDecl->sElementName.uiLength, uipEName, uiELen)){
331  return spDecl;
332  }
333  }
334  }
335  return NULL;
336 }
337 
338 /*********************************************************
339  * CONTENT --------------------------------------------
340  ********************************************************/
341 void vCharData(callback_data* spData){
342  if(spData->uiParserState == ID_MATCH){
343  xml* spXml = (xml*)spData->vpUserData;
344  vpVecPush(spXml->vpVec32, &spXml->uiChar);
345  }
346 }
347 void vCDSectEnd(callback_data* spData){
348  if(spData->uiParserState == ID_MATCH){
349  xml* spXml = (xml*)spData->vpUserData;
350  XML_THROW("\"]]>\" not allowed in content character data");
351  }
352 }
353 
354 static att_cdata sMakeAtts(xml*spXml, element_frame* spF, aint uiOffset){
355  att_cdata sReturn;
356  vVecClear(spXml->vpVecString);
357  vVecClear(spXml->vpVecCData);
358  vMakeCDataDisplay(spXml, &spF->sSName, &sReturn.sName, uiOffset);
359  if(spF->uiAttCount){
360  sReturn.spAttNames = (u32_phrase*)vpVecPushn(spXml->vpVecCData, NULL, (2 * spF->uiAttCount));
361  sReturn.spAttValues = sReturn.spAttNames + spF->uiAttCount;
362  uint32_t ui = 0;
363  named_value* spAtt = (named_value*)vpVecFirst(spXml->vpVecAttList) + spF->uiBaseAtt;
364  for(; ui < spF->uiAttCount; ui++){
365  vMakeCDataDisplay(spXml, &spAtt[ui].sName, &sReturn.spAttNames[ui], uiOffset);
366  vMakeCDataDisplay(spXml, &spAtt[ui].sValue, &sReturn.spAttValues[ui], uiOffset);
367  }
368  }
369  return sReturn;
370 }
371 
372 /*********************************************************
373  * CDATA SECTIONS-----------------------------------------
374  ********************************************************/
375 void vCDEnd(callback_data* spData){
376  if(spData->uiParserState == ID_NOMATCH){
377  xml* spXml = (xml*)spData->vpUserData;
378  XML_THROW("expected end of CDATA section ']]>' not found");
379  }
380 }
381 void vCDRb(callback_data* spData){
382  if(spData->uiParserState == ID_MATCH){
383  xml* spXml = (xml*)spData->vpUserData;
384  vpVecPush(spXml->vpVec32, &s_ucRightBracket);
385  vpVecPush(spXml->vpVec32, &spXml->uiChar);
386  }
387 }
388 void vCD2Rb(callback_data* spData){
389  if(spData->uiParserState == ID_MATCH){
390  xml* spXml = (xml*)spData->vpUserData;
391  vpVecPush(spXml->vpVec32, &s_ucRightBracket);
392  vpVecPush(spXml->vpVec32, &s_ucRightBracket);
393  vpVecPush(spXml->vpVec32, &spXml->uiChar);
394  }
395 }
vETagClose
void vETagClose(callback_data *spData)
Definition: elements.c:120
vExpandEntity
void vExpandEntity(xml *spXml, aint uiOffset, entity_decl *spThisEntity)
Definition: basics.c:855
cdata_id::uiLength
uint32_t uiLength
The number of 32-bit data characters.
Definition: xmlp.h:44
callback_data::uiParserOffset
aint uiParserOffset
[read only] Offset from acpString to the first character to match
Definition: parser.h:160
vDChar
void vDChar(callback_data *spData)
Definition: elements.c:200
vEStart
void vEStart(callback_data *spData)
Definition: elements.c:50
vPopFrame
void vPopFrame(callback_data *spData)
Definition: basics.c:86
callback_data::acpString
const achar * acpString
[read only] Pointer to the input sub-string,
Definition: parser.h:156
bCompNames
abool bCompNames(const uint32_t *uipLName, uint32_t uiLLen, const uint32_t *uipRName, uint32_t uiRLen)
Definition: basics.c:676
element_frame
A stack is used to track which element is currently being parsed. This frame struct contains all of t...
Definition: xmlp.h:95
xml
This is the encapsulated data for the xml component. The component context or handle is an opaque poi...
att_decl::sAttValue
cdata_id sAttValue
The attribute normalized value, offset and length.
Definition: xmlp.h:65
callback_data::uiParserState
aint uiParserState
[read only] ID_ACTIVE if the parser is going down the tree. ID_MATCH or ID_NOMATCH if coming up the t...
Definition: parser.h:158
att_cdata::spAttValues
u32_phrase * spAttValues
Definition: elements.c:39
att_cdata
Definition: elements.c:36
achar
uint_fast8_t achar
achar is the type for the parser's alphabet characters.
Definition: apg.h:91
vPushFrame
void vPushFrame(callback_data *spData)
Definition: basics.c:77
att_cdata::sName
u32_phrase sName
Definition: elements.c:37
element_frame::sSName
cdata_id sSName
Identifies the location of the start tag name.
Definition: xmlp.h:102
entity_decl
Provides the offset into the general 32-bit vector and length of a name and value pair.
Definition: xmlp.h:80
vSTagClose
void vSTagClose(callback_data *spData)
Definition: elements.c:103
vpVecAt
void * vpVecAt(void *vpCtx, aint uiIndex)
Get a the indexed vector element. The vector is not altered.
Definition: vector.c:362
vDvalue
void vDvalue(callback_data *spData)
Definition: elements.c:194
vDecValue
void vDecValue(callback_data *spData)
Definition: elements.c:229
vCharData
void vCharData(callback_data *spData)
Definition: elements.c:341
aint
uint_fast32_t aint
The APG parser's unsigned integer type.
Definition: apg.h:79
vpVecLast
void * vpVecLast(void *vpCtx)
Get the last element one the vector. The vector is not altered.
Definition: vector.c:343
entity_decl::sValue
cdata_id sValue
The offset (into vpVec32) and length of the value.
Definition: xmlp.h:83
callbacks.h
Declaration for all of the XML Component parser callback functions.
entity_decl::bExpanded
abool bExpanded
True if this entity value has been expanded.
Definition: xmlp.h:88
cdata_id::uiOffset
uint32_t uiOffset
The offset into vpVec32 array for the start of the data.
Definition: xmlp.h:43
bMultiply32
abool bMultiply32(uint32_t uiL, uint32_t uiR, uint32_t *uipA)
Multiply two 32-bit unsigned integers with overflow notification.
Definition: tools.c:150
att_decl::sElementName
cdata_id sElementName
The element name, offset and length.
Definition: xmlp.h:62
att_cdata::spAttNames
u32_phrase * spAttNames
Definition: elements.c:38
uiVecLen
aint uiVecLen(void *vpCtx)
Get the vector length. That is, the number of elements on the vector.
Definition: vector.c:385
named_value
Provides offsets and lengths in the vpVec32 array for a name and value pair.
Definition: xmlp.h:50
vEntityRef
void vEntityRef(callback_data *spData)
Definition: elements.c:209
vMakeCDataDisplay
void vMakeCDataDisplay(xml *spXml, cdata_id *spDataId, u32_phrase *spCData, aint uiOffset)
Definition: basics.c:156
element_frame::uiBaseAtt
aint uiBaseAtt
Base index in vpVecAttList for this element. Pop to uiBaseAtt at end of element.
Definition: xmlp.h:100
vElAttName
void vElAttName(callback_data *spData)
Definition: elements.c:157
ID_MATCH
#define ID_MATCH
indicates a matched phrase parser state on return from parse tree below this node
Definition: parser.h:73
callback_data
The data struct passed to each callback function.
Definition: parser.h:134
spEntityNameLookup
entity_decl * spEntityNameLookup(xml *spXml, aint uiOffset, uint32_t *uipName, uint32_t uiNameLen)
Find the left-most occurrence of the given entity name.
Definition: basics.c:645
XML_THROW
#define XML_THROW(msg)
Definition: callbacks.h:53
att_decl::uiAttCount
aint uiAttCount
The number of different attribute names associated with this element name.
Definition: xmlp.h:66
vEmptyClose
void vEmptyClose(callback_data *spData)
Definition: elements.c:92
vpVecFirst
void * vpVecFirst(void *vpCtx)
Get the first element one the vector. The vector is not altered.
Definition: vector.c:326
vpVecPushn
void * vpVecPushn(void *vpCtx, void *vpElement, aint uiCount)
Adds one or more elements to the end of the array.
Definition: vector.c:221
vEReserved
void vEReserved(callback_data *spData)
Definition: elements.c:85
bValidateChar
abool bValidateChar(uint32_t uiChar)
Definition: basics.c:124
named_value::sName
cdata_id sName
Points to offset and length of the datum's name.
Definition: xmlp.h:51
callback_data::vpUserData
void * vpUserData
[input/output] User-defined data passed to to the parser in parser_config.
Definition: parser.h:136
APG_TRUE
#define APG_TRUE
Definition: apg.h:291
vCDEnd
void vCDEnd(callback_data *spData)
Definition: elements.c:375
named_value::sValue
cdata_id sValue
Points to offset and length of the datum's value.
Definition: xmlp.h:52
vCDRb
void vCDRb(callback_data *spData)
Definition: elements.c:381
vCDSectEnd
void vCDSectEnd(callback_data *spData)
Definition: elements.c:347
att_decl::sAttName
cdata_id sAttName
The attribute name, offset and length.
Definition: xmlp.h:63
abool
uint8_t abool
abool is the APG bool type.
Definition: apg.h:140
ID_NOMATCH
#define ID_NOMATCH
indicates that no phrase was matched on return from parse tree below this node
Definition: parser.h:74
vEOpen
void vEOpen(callback_data *spData)
Definition: elements.c:74
element_frame::uiAttCount
aint uiAttCount
The number of attributes found in the start tag.
Definition: xmlp.h:101
bSum32
abool bSum32(uint32_t uiL, uint32_t uiR, uint32_t *uipA)
Sum two 32-bit unsigned integers with overflow notification.
Definition: tools.c:170
u32_phrase
Defines a pointer to an array of 32-bit unsigned integers plus its length. Typically needed by Unicod...
Definition: lib.h:73
vCD2Rb
void vCD2Rb(callback_data *spData)
Definition: elements.c:388
att_decl
Identifies the element name, attribute name and default attribute value of attribute list declaration...
Definition: xmlp.h:60
CABUF_LEN
#define CABUF_LEN
Definition: callbacks.h:51
vpVecPush
void * vpVecPush(void *vpCtx, void *vpElement)
Adds one element to the end of the array.
Definition: vector.c:193
vVecClear
void vVecClear(void *vpCtx)
Clears all used elements in a vector component.
Definition: vector.c:420
vHexValue
void vHexValue(callback_data *spData)
Definition: elements.c:259
vAttValue
void vAttValue(callback_data *spData)
Definition: elements.c:176
APG_FALSE
#define APG_FALSE
Definition: apg.h:292
APG Version 7.0 is licensed under the 2-Clause BSD License,
an Open Source Initiative Approved License.