Version 7.0
Copyright © 2021 Lowell D. Thomas
APG
… an ABNF Parser Generator
main.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 * *************************************************************************************/
79 #include "../../xml/xml.h"
80 
81 #include "source.h"
82 
83 static const char* cpMakeFileName(char* cpBuffer, const char* cpBase, const char* cpDivider, const char* cpName){
84  strcpy(cpBuffer, cpBase);
85  strcat(cpBuffer, cpDivider);
86  strcat(cpBuffer, cpName);
87  return cpBuffer;
88 }
89 static char caBuf[PATH_MAX];
90 
91 static char* s_cpDescription =
92  "Illustrate using the XML parser.";
93 
94 static char* s_cppCases[] = {
95  "Display application information.",
96  "Illustrate parsing a simple XML file with no XML declaration or DTD.",
97  "Illustrate displaying the Processing Instructions and comments found in an XML document.",
98  "Illustrate displaying implicit and explicit XML declaration and parsing UTF-16 encoded files.",
99  "Illustrate parsing the DTD and applying entities and default attributes.",
100 };
101 static long int s_iCaseCount = (long int)(sizeof(s_cppCases) / sizeof(s_cppCases[0]));
102 
103 static int iHelp(void){
104  long int i = 0;
106  printf("description: %s\n", s_cpDescription);
107  printf(" usage: ex-api arg\n");
108  printf(" arg = n, 1 <= n <= %ld\n", s_iCaseCount);
109  printf(" execute case number n\n");
110  printf(" arg = anthing else\n");
111  printf(" print this help screen\n");
112  printf("\n");
113  for(; i < s_iCaseCount; i++){
114  printf("case %ld %s\n", (i + 1), s_cppCases[i]);
115  }
116  return EXIT_SUCCESS;
117 }
118 
119 static int iApp() {
120  // print the current working directory
122  printf("\n");
123 
124  // display the current APG sizes and macros
125  vUtilApgInfo();
126  return EXIT_SUCCESS;
127 }
128 
129 static int iSimple() {
130  int iReturn = EXIT_SUCCESS;
131  static void* vpMem = NULL;
132  static void* vpXml = NULL;
133  uint8_t ucaBuf[1024];
134  aint uiBufSize = 1024;
135  aint uiSize;
136  exception e;
137  XCTOR(e);
138  if(e.try){
139  // try block
140  vpMem = vpMemCtor(&e);
141  vpXml = vpXmlCtor(&e);
142 
143  const char* cpInput = cpMakeFileName(caBuf, SOURCE_DIR, "/../input/", "simple.xml");
144 
145  // display a case header
146  char* cpHeader =
147  "This example case illustrates parsing a simple XML file.\n"
148  "The file has no XML declaration or DTD.\n"
149  "Only the tag names, attributes and tagged content are captured and displayed.\n";
150  printf("\n%s", cpHeader);
151 
152  printf("\nGet the XML file and use default call back functions for display of captured items.\n");
153  printf("XML data from file %s\n", cpInput);
154  uiSize = uiBufSize;
155  vUtilFileRead(vpMem, cpInput, ucaBuf, &uiSize);
156  if(uiSize >= uiBufSize){
157  XTHROW(&e, "buffer size too small for file");
158  }
159  ucaBuf[uiSize] = 0;
160  printf("%s\n", (char*)ucaBuf);
161  vXmlGetFile(vpXml, cpInput);
164  vXmlParse(vpXml);
165 
166 
167  }else{
168  // catch block - display the exception location and message
170  iReturn = EXIT_FAILURE;
171  }
172 
173  // clean up resources
174  vXmlDtor(vpXml);
175  vMemDtor(vpMem);
176  return iReturn;
177 }
178 
179 static int iComment() {
180  int iReturn = EXIT_SUCCESS;
181  static void* vpMem = NULL;
182  static void* vpXml = NULL;
183  uint8_t ucaBuf[1024];
184  aint uiBufSize = 1024;
185  aint uiSize;
186  exception e;
187  XCTOR(e);
188  if(e.try){
189  // try block
190  vpMem = vpMemCtor(&e);
191  vpXml = vpXmlCtor(&e);
192 
193  const char* cpInput = cpMakeFileName(caBuf, SOURCE_DIR, "/../input/", "comment.xml");
194 
195  // display a case header
196  char* cpHeader =
197  "This example case illustrates displaying the Processing Instructions and comments\n"
198  "optionally found in an XML document.\n";
199  printf("\n%s", cpHeader);
200 
201  printf("\nGet the XML file and use default call back functions for display PIs and comments.\n");
202  printf("XML data from file %s\n", cpInput);
203  uiSize = uiBufSize;
204  vUtilFileRead(vpMem, cpInput, ucaBuf, &uiSize);
205  if(uiSize >= uiBufSize){
206  XTHROW(&e, "buffer size too small for file");
207  }
208  ucaBuf[uiSize] = 0;
209  printf("%s\n", (char*)ucaBuf);
210  vXmlGetFile(vpXml, cpInput);
212  vXmlSetPICallback(vpXml, DEFAULT_CALLBACK, NULL);
213  vXmlParse(vpXml);
214 
215 
216  }else{
217  // catch block - display the exception location and message
219  iReturn = EXIT_FAILURE;
220  }
221 
222  // clean up resources
223  vXmlDtor(vpXml);
224  vMemDtor(vpMem);
225  return iReturn;
226 }
227 
228 static int iXmlDecl() {
229  int iReturn = EXIT_SUCCESS;
230  static void* vpMem = NULL;
231  static void* vpXml = NULL;
232  static void* vpFmt = NULL;
233  const char* cpLine;
234  uint8_t ucaBuf[1024];
235  aint uiBufSize = 1024;
236  aint uiSize;
237  exception e;
238  XCTOR(e);
239  if(e.try){
240  // try block
241  vpMem = vpMemCtor(&e);
242  vpXml = vpXmlCtor(&e);
243  vpFmt = vpFmtCtor(&e);
244 
245  // display a case header
246  char* cpHeader =
247  "This example case illustrates the XML declaration.\n"
248  "A display of the XML declaration is compared between\n"
249  "XML files with and without XML declarations.\n"
250  "Furthermore, the file with the declaration is UTF-16 encoded.";
251  printf("\n%s", cpHeader);
252 
253  const char* cpSimple = cpMakeFileName(caBuf, SOURCE_DIR, "/../input/", "simple.xml");
254 
255  printf("\nGet the XML files and use default call back functions for display of the XML declaration.\n");
256  printf("XML data from file %s\n", cpSimple);
257  uiSize = uiBufSize;
258  vUtilFileRead(vpMem, cpSimple, ucaBuf, &uiSize);
259  if(uiSize >= uiBufSize){
260  XTHROW(&e, "buffer size too small for file");
261  }
262  ucaBuf[uiSize] = 0;
263  printf("%s\n", (char*)ucaBuf);
264  vXmlGetFile(vpXml, cpSimple);
267  vXmlParse(vpXml);
268 
269  const char* cpDecl16le = cpMakeFileName(caBuf, SOURCE_DIR, "/../input/", "xml-decl-16le.xml");
270 
271  printf("XML data from file %s\n", cpDecl16le);
272  uiSize = uiBufSize;
273  vUtilFileRead(vpMem, cpDecl16le, ucaBuf, &uiSize);
274  if(uiSize >= uiBufSize){
275  XTHROW(&e, "buffer size too small for file");
276  }
277  ucaBuf[uiSize] = 0;
278  cpLine = cpFmtFirstBytes(vpFmt, ucaBuf, uiSize, FMT_CANONICAL, 0, 0);
279  while(cpLine){
280  printf("%s", cpLine);
281  cpLine = cpFmtNext(vpFmt);
282  }
283  vXmlGetFile(vpXml, cpDecl16le);
286  vXmlParse(vpXml);
287 
288 
289  }else{
290  // catch block - display the exception location and message
292  iReturn = EXIT_FAILURE;
293  }
294 
295  // clean up resources
296  vXmlDtor(vpXml);
297  vMemDtor(vpMem);
298  return iReturn;
299 }
300 
301 static int iDTD() {
302  int iReturn = EXIT_SUCCESS;
303  static void* vpMem = NULL;
304  static void* vpXml = NULL;
305  uint8_t ucaBuf[1024];
306  aint uiBufSize = 1024;
307  aint uiSize;
308  exception e;
309  XCTOR(e);
310  if(e.try){
311  // try block
312  vpMem = vpMemCtor(&e);
313  vpXml = vpXmlCtor(&e);
314 
315  const char* cpInput = cpMakeFileName(caBuf, SOURCE_DIR, "/../input/", "dtd-entity-attr.xml");
316 
317  // display a case header
318  char* cpHeader =
319  "This example case illustrates parsing an XML file with a Document Type Declaration (DTD).\n"
320  "The DTD will define entities and default attributes.\n"
321  "These will be reflected in the parse of the input file.\n";
322  printf("\n%s", cpHeader);
323 
324  printf("\nGet the XML file and use default call back functions for display of captured items.\n");
325  printf("XML data from file %s\n", cpInput);
326  uiSize = uiBufSize;
327  vUtilFileRead(vpMem, cpInput, ucaBuf, &uiSize);
328  if(uiSize >= uiBufSize){
329  XTHROW(&e, "buffer size too small for file");
330  }
331  ucaBuf[uiSize] = 0;
332  printf("%s\n", (char*)ucaBuf);
333  vXmlGetFile(vpXml, cpInput);
335  vXmlSetDTDCallback(vpXml, DEFAULT_CALLBACK, NULL);
338  vXmlParse(vpXml);
339 
340  }else{
341  // catch block - display the exception location and message
343  iReturn = EXIT_FAILURE;
344  }
345 
346  // clean up resources
347  vXmlDtor(vpXml);
348  vMemDtor(vpMem);
349  return iReturn;
350 }
351 
359 int main(int argc, char **argv) {
360  long int iCase = 0;
361  if(argc > 1){
362  iCase = atol(argv[1]);
363  }
364  if((iCase > 0) && (iCase <= s_iCaseCount)){
365  printf("%s\n", s_cppCases[iCase -1]);
366  }
367  switch(iCase){
368  case 1:
369  return iApp();
370  case 2:
371  return iSimple();
372  case 3:
373  return iComment();
374  case 4:
375  return iXmlDecl();
376  case 5:
377  return iDTD();
378  default:
379  return iHelp();
380  }
381 }
382 
vXmlParse
void vXmlParse(void *vpCtx)
Parse the XML data from vXmlGetFile or vXmlGetArray.
Definition: xml.c:500
XCTOR
#define XCTOR(e)
This macro will initialize an exception structure and prepare entry to the "try" block.
Definition: exception.h:77
vUtilFileRead
void vUtilFileRead(void *vpMem, const char *cpFileName, uint8_t *ucpData, aint *uipLen)
Read a file into the caller's data area.
Definition: utilities.c:252
vpXmlCtor
void * vpXmlCtor(exception *spEx)
The XML Parser constructor.
Definition: xml.c:159
vMemDtor
void vMemDtor(void *vpCtx)
Destroys a Memory component. Frees all memory allocated.
Definition: memory.c:141
exception::try
abool try
True for the try block, false for the catch block.
Definition: exception.h:49
DEFAULT_CALLBACK
#define DEFAULT_CALLBACK
Indicator for a pre-defined, default callback function.
Definition: xml.h:51
cpFmtFirstBytes
const char * cpFmtFirstBytes(void *vpCtx, const uint8_t *ucpBytes, uint64_t uiLength, int iStyle, uint64_t uiOffset, uint64_t uiLimit)
Initiate the iterator over an array of 8-bit byte data.
Definition: format.c:210
vXmlSetCommentCallback
void vXmlSetCommentCallback(void *vpCtx, pfnCommentCallback pfnCallback, void *vpUserData)
Set the user's callback function for comments.
Definition: xml.c:756
FMT_CANONICAL
#define FMT_CANONICAL
Display lines with both FMT_HEX and FMT_ASCII formats.
Definition: format.h:55
cpFmtNext
const char * cpFmtNext(void *vpCtx)
Formats the next line of data.
Definition: format.c:386
XTHROW
#define XTHROW(ctx, msg)
Exception throw macro.
Definition: exception.h:67
aint
uint_fast32_t aint
The APG parser's unsigned integer type.
Definition: apg.h:79
vXmlGetFile
void vXmlGetFile(void *vpCtx, const char *cpFileName)
Gets the XML byte stream from a file.
Definition: xml.c:277
main
int main(int argc, char **argv)
The executable from this main function is the ABNF Parser Generator application, APG.
Definition: main.c:61
exception
A structure to describe the type and location of a caught exception.
Definition: exception.h:47
vXmlSetStartTagCallback
void vXmlSetStartTagCallback(void *vpCtx, pfnStartTagCallback pfnCallback, void *vpUserData)
Set the user's callback function for the start tags (<name attr="10">).
Definition: xml.c:600
vXmlSetDTDCallback
void vXmlSetDTDCallback(void *vpCtx, pfnDTDCallback pfnCallback, void *vpUserData)
Set the user's callback function for the Processing Instruction tags(<?target instructions?...
Definition: xml.c:731
vpMemCtor
void * vpMemCtor(exception *spException)
Construct a memory component.
Definition: memory.c:121
vXmlSetEndTagCallback
void vXmlSetEndTagCallback(void *vpCtx, pfnEndTagCallback pfnCallback, void *vpUserData)
Set the user's callback function for the end tags (</name>).
Definition: xml.c:656
vXmlSetXmlDeclCallback
void vXmlSetXmlDeclCallback(void *vpCtx, pfnXmlDeclCallback pfnCallback, void *vpUserData)
Set the user's callback function for the XML declaration.
Definition: xml.c:706
vUtilApgInfo
void vUtilApgInfo(void)
Display the current state of apg.h.
Definition: utilities.c:60
vXmlSetPICallback
void vXmlSetPICallback(void *vpCtx, pfnPICallback pfnCallback, void *vpUserData)
Set the user's callback function for the Processing Instruction tags(<?target instructions?...
Definition: xml.c:681
vXmlDtor
void vXmlDtor(void *vpCtx)
The XML Parser component destructor.
Definition: xml.c:242
vUtilPrintException
void vUtilPrintException(exception *spEx)
Prints exception information from an exception structure.
Definition: utilities.c:415
vpFmtCtor
void * vpFmtCtor(exception *spEx)
The object constructor.
Definition: format.c:118
vUtilCurrentWorkingDirectory
void vUtilCurrentWorkingDirectory(void)
Display the current working directory.
Definition: utilities.c:191
APG Version 7.0 is licensed under the 2-Clause BSD License,
an Open Source Initiative Approved License.