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 * *************************************************************************************/
115 #include "../../utilities/utilities.h"
116 #include "../../api/api.h"
117 
118 #include "source.h"
119 
120 static const char* cpMakeFileName(char* cpBuffer, const char* cpBase, const char* cpDivider, const char* cpName){
121  strcpy(cpBuffer, cpBase);
122  strcat(cpBuffer, cpDivider);
123  strcat(cpBuffer, cpName);
124  return cpBuffer;
125 }
126 static char caBuf[PATH_MAX];
127 
128 static char* s_cpDescription =
129  "Illustrate parser tracing and parser, memory and vector statistics.";
130 
131 static char* s_cppCases[] = {
132  "Display application information.",
133  "Illustrate default tracing with and without PPPT.",
134  "Generate a trace configuration file template.",
135  "Trace a restricted record range.",
136  "Trace rule names only.",
137  "Trace only specific rule names.",
138  "Parsing statistics, hit count vs alphabetical.",
139  "Parsing statistics, with and without PPPT.",
140  "Parsing statistics, cumulative for multiple parses.",
141  "Illustrate memory statistics.",
142  "Illustrate vector statistics.",
143 };
144 static long int s_iCaseCount = (long int)(sizeof(s_cppCases) / sizeof(s_cppCases[0]));
145 
146 static int iHelp(void){
147  long int i = 0;
149  printf("description: %s\n", s_cpDescription);
150  printf(" usage: ex-trace [arg]\n");
151  printf(" arg = n, 1 <= n <= %ld\n", s_iCaseCount);
152  printf(" execute case number n\n");
153  printf(" arg = anything else, or nothing at all\n");
154  printf(" print this help screen\n");
155  printf("\n");
156  for(; i < s_iCaseCount; i++){
157  printf("case %ld %s\n", (i + 1), s_cppCases[i]);
158  }
159  return EXIT_SUCCESS;
160 }
161 
162 static int iApp() {
163  // print the current working directory
165  printf("\n");
166 
167  // display the current APG sizes and macros
168  vUtilApgInfo();
169  return EXIT_SUCCESS;
170 }
171 
172 static int iTraceDefault() {
173  int iReturn = EXIT_SUCCESS;
174  static void* vpApi = NULL;
175  static void* vpMem = NULL;
176  static void* vpParser = NULL;
177  static void* vpParserPppt = NULL;
178  char* cpInput = "+123456789.0987654321E+100";
179  parser_config sConfig;
180  parser_state sState;
181  apg_phrase* spPhrase;
182  exception e;
183  XCTOR(e);
184  if(e.try){
185  // try block - construct the API object
186  vpApi = vpApiCtor(&e);
187 
188  // convert the input string to alphabet characters (in general, sizeof(achar) != sizeof(char))
189  vpMem = vpMemCtor(&e);
190  spPhrase = spUtilStrToPhrase(vpMem, cpInput);
191 
192  // construct a floating point parser without PPPT
193  vApiFile(vpApi, cpMakeFileName(caBuf, SOURCE_DIR, "/../input/","float.abnf"), APG_FALSE, APG_FALSE);
194  vpParser = vpApiOutputParser(vpApi);
195 
196  // display the trace without PPPT
197  printf("\nTrace without PPPT\n");
198  vpTraceCtor(vpParser);
199  memset(&sConfig, 0, sizeof(sConfig));
200  sConfig.acpInput = spPhrase->acpPhrase;
201  sConfig.uiInputLength = spPhrase->uiLength;
202  sConfig.uiStartRule = uiParserRuleLookup(vpParser, "float");
203  vParserParse(vpParser, &sConfig, &sState);
204 
205  // display the state without PPPT
206  printf("\nParser State without PPPT\n");
207  vUtilPrintParserState(&sState);
208 
209  // construct a floating point parser with PPPT
210  vApiFile(vpApi, cpMakeFileName(caBuf, SOURCE_DIR, "/../input/","float.abnf"), APG_FALSE, APG_TRUE);
211  vpParserPppt = vpApiOutputParser(vpApi);
212 
213  // display the trace with PPPT
214  printf("\nTrace with PPPT\n");
215  vpTraceCtor(vpParserPppt);
216 
217  // NOTE: input string and sConfig remain the same
218  vParserParse(vpParserPppt, &sConfig, &sState);
219 
220  // display the state without PPPT
221  printf("\nParser State with PPPT\n");
222  vUtilPrintParserState(&sState);
223 
224  // free the memory allocation
225  vMemFree(vpMem, spPhrase);
226 
227  }else{
228  // catch block - display the exception location and message
230  iReturn = EXIT_FAILURE;
231  }
232 
233  // free up all allocated resources
234  // NOTE: the trace objects are destroyed by the parser destructor
235  // no need to destroy them separately
236  vParserDtor(vpParser);
237  vParserDtor(vpParserPppt);
238  vApiDtor(vpApi);
239  vMemDtor(vpMem);
240  return iReturn;
241 }
242 
243 static int iTraceConfigGen() {
244  int iReturn = EXIT_SUCCESS;
245  static void* vpApi = NULL;
246  static void* vpParser = NULL;
247  static void* vpTrace = NULL;
248  exception e;
249  XCTOR(e);
250  if(e.try){
251  // try block - construct the API object
252  vpApi = vpApiCtor(&e);
253 
254  // construct a floating point parser without PPPT
255  vApiFile(vpApi, cpMakeFileName(caBuf, SOURCE_DIR, "/../input/","float.abnf"), APG_FALSE, APG_FALSE);
256  vpParser = vpApiOutputParser(vpApi);
257 
258  // display the trace without PPPT
259  printf("\nDisplay the Trace Configuration File to stdout\n");
260  vpTrace = vpTraceCtor(vpParser);
261  vTraceConfigGen(vpTrace, NULL);
262 
263  }else{
264  // catch block - display the exception location and message
266  iReturn = EXIT_FAILURE;
267  }
268 
269  // free up all allocated resources
270  vParserDtor(vpParser);
271  vApiDtor(vpApi);
272  return iReturn;
273 }
274 
275 static int iTraceConfigRange() {
276  int iReturn = EXIT_SUCCESS;
277  static void* vpApi = NULL;
278  static void* vpMem = NULL;
279  static void* vpParser = NULL;
280  static void* vpTrace = NULL;
281  char* cpInput = "+123456789.0987654321E+100";
282  parser_config sConfig;
283  parser_state sState;
284  apg_phrase* spPhrase;
285  exception e;
286  XCTOR(e);
287  if(e.try){
288  // try block - construct the API object
289  vpApi = vpApiCtor(&e);
290 
291  // convert the input string to alphabet characters (in general, sizeof(achar) != sizeof(char))
292  vpMem = vpMemCtor(&e);
293  spPhrase = spUtilStrToPhrase(vpMem, cpInput);
294 
295  // construct a floating point parser without PPPT
296  vApiFile(vpApi, cpMakeFileName(caBuf, SOURCE_DIR, "/../input/","float.abnf"), APG_FALSE, APG_FALSE);
297  vpParser = vpApiOutputParser(vpApi);
298 
299  // display the trace without PPPT
300  const char* cpConfig = cpMakeFileName(caBuf, SOURCE_DIR, "/../input/","float-config-range");
301  printf("\nUsing trace configuration file %s \n", cpConfig);
302  vpTrace = vpTraceCtor(vpParser);
303  vTraceConfig(vpTrace, cpConfig);
304  memset(&sConfig, 0, sizeof(sConfig));
305  sConfig.acpInput = spPhrase->acpPhrase;
306  sConfig.uiInputLength = spPhrase->uiLength;
307  sConfig.uiStartRule = uiParserRuleLookup(vpParser, "float");
308  vParserParse(vpParser, &sConfig, &sState);
309 
310  // display the state without PPPT
311  printf("\nParser State without PPPT\n");
312  vUtilPrintParserState(&sState);
313 
314  // free the memory allocation
315  vMemFree(vpMem, spPhrase);
316 
317  }else{
318  // catch block - display the exception location and message
320  iReturn = EXIT_FAILURE;
321  }
322 
323  // free up all allocated resources
324  vParserDtor(vpParser);
325  vApiDtor(vpApi);
326  vMemDtor(vpMem);
327  return iReturn;
328 }
329 
330 static int iTraceConfigRules() {
331  int iReturn = EXIT_SUCCESS;
332  static void* vpApi = NULL;
333  static void* vpMem = NULL;
334  static void* vpParser = NULL;
335  static void* vpTrace = NULL;
336  char* cpInput = "+123456789.0987654321E+100";
337  parser_config sConfig;
338  parser_state sState;
339  apg_phrase* spPhrase;
340  exception e;
341  XCTOR(e);
342  if(e.try){
343  // try block - construct the API object
344  vpApi = vpApiCtor(&e);
345 
346  // convert the input string to alphabet characters (in general, sizeof(achar) != sizeof(char))
347  vpMem = vpMemCtor(&e);
348  spPhrase = spUtilStrToPhrase(vpMem, cpInput);
349 
350  // construct a floating point parser without PPPT
351  vApiFile(vpApi, cpMakeFileName(caBuf, SOURCE_DIR, "/../input/","float.abnf"), APG_FALSE, APG_FALSE);
352  vpParser = vpApiOutputParser(vpApi);
353 
354  // display the trace without PPPT
355  const char* cpConfig = cpMakeFileName(caBuf, SOURCE_DIR, "/../input/","float-config-rules");
356  printf("\nUsing trace configuration file %s \n", cpConfig);
357  vpTrace = vpTraceCtor(vpParser);
358  vTraceConfig(vpTrace, cpConfig);
359  memset(&sConfig, 0, sizeof(sConfig));
360  sConfig.acpInput = spPhrase->acpPhrase;
361  sConfig.uiInputLength = spPhrase->uiLength;
362  sConfig.uiStartRule = uiParserRuleLookup(vpParser, "float");
363  vParserParse(vpParser, &sConfig, &sState);
364 
365  // display the state without PPPT
366  printf("\nParser State without PPPT\n");
367  vUtilPrintParserState(&sState);
368 
369  // free the memory allocation
370  vMemFree(vpMem, spPhrase);
371 
372  }else{
373  // catch block - display the exception location and message
375  iReturn = EXIT_FAILURE;
376  }
377 
378  // free up all allocated resources
379  vParserDtor(vpParser);
380  vApiDtor(vpApi);
381  vMemDtor(vpMem);
382  return iReturn;
383 }
384 
385 static int iTraceConfigSelect() {
386  int iReturn = EXIT_SUCCESS;
387  static void* vpApi = NULL;
388  static void* vpMem = NULL;
389  static void* vpParser = NULL;
390  static void* vpTrace = NULL;
391  char* cpInput = "+123456789.0987654321E+100";
392  parser_config sConfig;
393  parser_state sState;
394  apg_phrase* spPhrase;
395  exception e;
396  XCTOR(e);
397  if(e.try){
398  // try block - construct the API object
399  vpApi = vpApiCtor(&e);
400 
401  // convert the input string to alphabet characters (in general, sizeof(achar) != sizeof(char))
402  vpMem = vpMemCtor(&e);
403  spPhrase = spUtilStrToPhrase(vpMem, cpInput);
404 
405  // construct a floating point parser without PPPT
406  vApiFile(vpApi, cpMakeFileName(caBuf, SOURCE_DIR, "/../input/","float.abnf"), APG_FALSE, APG_FALSE);
407  vpParser = vpApiOutputParser(vpApi);
408 
409  // display the trace without PPPT
410  const char* cpConfig = cpMakeFileName(caBuf, SOURCE_DIR, "/../input/","float-config-select");
411  printf("\nUsing trace configuration file %s \n", cpConfig);
412  vpTrace = vpTraceCtor(vpParser);
413  vTraceConfig(vpTrace, cpConfig);
414  memset(&sConfig, 0, sizeof(sConfig));
415  sConfig.acpInput = spPhrase->acpPhrase;
416  sConfig.uiInputLength = spPhrase->uiLength;
417  sConfig.uiStartRule = uiParserRuleLookup(vpParser, "float");
418  vParserParse(vpParser, &sConfig, &sState);
419 
420  // display the state without PPPT
421  printf("\nParser State without PPPT\n");
422  vUtilPrintParserState(&sState);
423 
424  // free the memory allocation
425  vMemFree(vpMem, spPhrase);
426 
427  }else{
428  // catch block - display the exception location and message
430  iReturn = EXIT_FAILURE;
431  }
432 
433  // free up all allocated resources
434  vParserDtor(vpParser);
435  vApiDtor(vpApi);
436  vMemDtor(vpMem);
437  return iReturn;
438 }
439 
440 static int iStatsHits() {
441  int iReturn = EXIT_SUCCESS;
442  static void* vpApi = NULL;
443  static void* vpMem = NULL;
444  static void* vpParser = NULL;
445  static void* vpStats = NULL;
446  char* cpInput =
447  "{\n"
448  "\"array\": [1, true, false, null, 2345],\n"
449  "\"object\": {\n"
450  "\"inner\": {\n"
451  "\"t\": true,\n"
452  "\"f\": false,\n"
453  "\"s\": \"string\"\n"
454  "},\n"
455  "\"more\": [12345, 6789809, 234, 3456,456],\n"
456  "\"key1\": 1234,\n"
457  "\"key2\": \"end of object\"\n"
458  "}\n"
459  "}\n";
460  parser_config sConfig;
461  parser_state sState;
462  apg_phrase* spPhrase;
463  exception e;
464  XCTOR(e);
465  if(e.try){
466  // try block - construct the API object
467  vpApi = vpApiCtor(&e);
468 
469  // convert the input string to alphabet characters (in general, sizeof(achar) != sizeof(char))
470  vpMem = vpMemCtor(&e);
471  spPhrase = spUtilStrToPhrase(vpMem, cpInput);
472 
473  // construct a JSON parser without PPPT
474  vApiFile(vpApi, cpMakeFileName(caBuf, SOURCE_DIR, "/../input/","json.abnf"), APG_FALSE, APG_FALSE);
475  vpParser = vpApiOutputParser(vpApi);
476  vpStats = vpStatsCtor(vpParser);
477 
478  // parse without PPPT
479  memset(&sConfig, 0, sizeof(sConfig));
480  sConfig.acpInput = spPhrase->acpPhrase;
481  sConfig.uiInputLength = spPhrase->uiLength;
482  sConfig.uiStartRule = uiParserRuleLookup(vpParser, "JSON-text");
483  vParserParse(vpParser, &sConfig, &sState);
484 
485  // display the state
486  printf("\nParser State\n");
487  vUtilPrintParserState(&sState);
488 
489  // display the stats with hit count
490  printf("\nStatistics ordered on hit count.\n");
491  vStatsToAscii(vpStats, "h", NULL);
492 
493  // display the stats alphabetically
494  printf("\nStatistics ordered alphabetically on rule names.\n");
495  vStatsToAscii(vpStats, "a", NULL);
496 
497  // free the memory allocation
498  vMemFree(vpMem, spPhrase);
499 
500  }else{
501  // catch block - display the exception location and message
503  iReturn = EXIT_FAILURE;
504  }
505 
506  // free up all allocated resources
507  // NOTE: the statistics objects are destroyed by the parser destructor
508  // no need to destroy them separately
509  vParserDtor(vpParser);
510  vApiDtor(vpApi);
511  vMemDtor(vpMem);
512  return iReturn;
513 }
514 
515 static int iStatsPppt() {
516  int iReturn = EXIT_SUCCESS;
517  static void* vpApi = NULL;
518  static void* vpMem = NULL;
519  static void* vpParser = NULL;
520  static void* vpParserPppt = NULL;
521  static void* vpStats = NULL;
522  static void* vpStatsPppt = NULL;
523  char* cpInput =
524  "{\n"
525  "\"array\": [1, true, false, null, 2345],\n"
526  "\"object\": {\n"
527  "\"inner\": {\n"
528  "\"t\": true,\n"
529  "\"f\": false,\n"
530  "\"s\": \"string\"\n"
531  "},\n"
532  "\"more\": [12345, 6789809, 234, 3456,456],\n"
533  "\"key1\": 1234,\n"
534  "\"key2\": \"end of object\"\n"
535  "}\n"
536  "}\n";
537  parser_config sConfig;
538  parser_state sState;
539  apg_phrase* spPhrase;
540  exception e;
541  XCTOR(e);
542  if(e.try){
543  // try block - construct the API object
544  vpApi = vpApiCtor(&e);
545 
546  // convert the input string to alphabet characters (in general, sizeof(achar) != sizeof(char))
547  vpMem = vpMemCtor(&e);
548  spPhrase = spUtilStrToPhrase(vpMem, cpInput);
549 
550  // construct a JSON parser without PPPT
551  vApiFile(vpApi, cpMakeFileName(caBuf, SOURCE_DIR, "/../input/","json.abnf"), APG_FALSE, APG_FALSE);
552  vpParser = vpApiOutputParser(vpApi);
553  vpStats = vpStatsCtor(vpParser);
554 
555  // construct a JSON parser with PPPT
556  vApiFile(vpApi, cpMakeFileName(caBuf, SOURCE_DIR, "/../input/","json.abnf"), APG_FALSE, APG_TRUE);
557  vpParserPppt = vpApiOutputParser(vpApi);
558  vpStatsPppt = vpStatsCtor(vpParserPppt);
559 
560  // parse without PPPT
561  memset(&sConfig, 0, sizeof(sConfig));
562  sConfig.acpInput = spPhrase->acpPhrase;
563  sConfig.uiInputLength = spPhrase->uiLength;
564  sConfig.uiStartRule = uiParserRuleLookup(vpParser, "JSON-text");
565  vParserParse(vpParser, &sConfig, &sState);
566 
567  // display the state
568  printf("\nParser State\n");
569  vUtilPrintParserState(&sState);
570 
571  // display the stats with hit count
572  printf("\nStatistics without PPPT ordered on hit count.\n");
573  vStatsToAscii(vpStats, "h", NULL);
574 
575  // parse with PPPT
576  vParserParse(vpParserPppt, &sConfig, &sState);
577 
578  // display the state
579  printf("\nParser State\n");
580  vUtilPrintParserState(&sState);
581 
582  // display the stats with hit count
583  printf("\nStatistics with PPPT ordered on hit count.\n");
584  vStatsToAscii(vpStatsPppt, "h", NULL);
585 
586  // free the memory allocation
587  vMemFree(vpMem, spPhrase);
588 
589  }else{
590  // catch block - display the exception location and message
592  iReturn = EXIT_FAILURE;
593  }
594 
595  // free up all allocated resources
596  // NOTE: the statistics objects are destroyed by the parser destructor
597  // no need to destroy them separately
598  vParserDtor(vpParser);
599  vParserDtor(vpParserPppt);
600  vApiDtor(vpApi);
601  vMemDtor(vpMem);
602  return iReturn;
603 }
604 
605 static int iStatsCumulative() {
606  int iReturn = EXIT_SUCCESS;
607  static void* vpApi = NULL;
608  static void* vpMem = NULL;
609  static void* vpParser = NULL;
610  static void* vpStats = NULL;
611  char* cpInput2 = "[true, false, 123456, {\"key\": \"string\"}]";
612  char* cpInput =
613  "{\n"
614  "\"array\": [1, true, false, null, 2345],\n"
615  "\"object\": {\n"
616  "\"inner\": {\n"
617  "\"t\": true,\n"
618  "\"f\": false,\n"
619  "\"s\": \"string\"\n"
620  "},\n"
621  "\"more\": [12345, 6789809, 234, 3456,456],\n"
622  "\"key1\": 1234,\n"
623  "\"key2\": \"end of object\"\n"
624  "}\n"
625  "}\n";
626  parser_config sConfig;
627  parser_state sState;
628  apg_phrase* spPhrase;
629  exception e;
630  XCTOR(e);
631  if(e.try){
632  // try block - construct the API object
633  vpApi = vpApiCtor(&e);
634 
635  // convert the input string to alphabet characters (in general, sizeof(achar) != sizeof(char))
636  vpMem = vpMemCtor(&e);
637 
638  // construct a JSON parser without PPPT
639  vApiFile(vpApi, cpMakeFileName(caBuf, SOURCE_DIR, "/../input/","json.abnf"), APG_FALSE, APG_FALSE);
640  vpParser = vpApiOutputParser(vpApi);
641  vpStats = vpStatsCtor(vpParser);
642 
643  // parse input 1
644  spPhrase = spUtilStrToPhrase(vpMem, cpInput);
645  memset(&sConfig, 0, sizeof(sConfig));
646  sConfig.acpInput = spPhrase->acpPhrase;
647  sConfig.uiInputLength = spPhrase->uiLength;
648  sConfig.uiStartRule = uiParserRuleLookup(vpParser, "JSON-text");
649  vParserParse(vpParser, &sConfig, &sState);
650 
651  // display the state
652  printf("\nParser State Input 1\n");
653  vUtilPrintParserState(&sState);
654 
655  // display the stats with hit count
656  printf("\nStatistics for input 1.\n");
657  vStatsToAscii(vpStats, "h", NULL);
658 
659  // parse input 2
660  spPhrase = spUtilStrToPhrase(vpMem, cpInput2);
661  memset(&sConfig, 0, sizeof(sConfig));
662  sConfig.acpInput = spPhrase->acpPhrase;
663  sConfig.uiInputLength = spPhrase->uiLength;
664  sConfig.uiStartRule = uiParserRuleLookup(vpParser, "JSON-text");
665  vParserParse(vpParser, &sConfig, &sState);
666 
667  // display the state
668  printf("\nParser State Input 2\n");
669  vUtilPrintParserState(&sState);
670 
671  // display the stats with hit count
672  printf("\nStatistics for input 1 + input 2.\n");
673  printf("Notice that the start rule, JSON-text, appears twice, once for each parsed string.\n");
674  vStatsToAscii(vpStats, "h", NULL);
675 
676  // free the memory allocation
677  vMemFree(vpMem, spPhrase);
678 
679  }else{
680  // catch block - display the exception location and message
682  iReturn = EXIT_FAILURE;
683  }
684 
685  // free up all allocated resources
686  // NOTE: the statistics objects are destroyed by the parser destructor
687  // no need to destroy them separately
688  vParserDtor(vpParser);
689  vApiDtor(vpApi);
690  vMemDtor(vpMem);
691  return iReturn;
692 }
693 
694 static int iMemStats() {
695  int iReturn = EXIT_SUCCESS;
696  mem_stats sStats = {};
697  static void* vpMem = NULL;
698  char *cp1, *cp2;
699  exception e;
700  XCTOR(e);
701  if(e.try){
702  // try block
703  // allocate some memory
704  vpMem = vpMemCtor(&e);
705  cp1 = (char*)vpMemAlloc(vpMem, 128);
706  cp2 = (char*)vpMemAlloc(vpMem, 1280);
707  vpMemAlloc(vpMem, 12800);
708 
709  // check the stats
710  printf("\nMemory Statistics: 3 allocations.\n");
711  vMemStats(vpMem, &sStats);
712  vUtilPrintMemStats(&sStats);
713 
714  // test free & realloc
715  vMemFree(vpMem, cp1);
716  printf("\nMemory Statistics: 2 allocations after 1 free.\n");
717  vMemStats(vpMem, &sStats);
718  vUtilPrintMemStats(&sStats);
719 
720  cp2 = (char*)vpMemRealloc(vpMem, cp2, 2056);
721  printf("\nMemory Statistics: 2 allocations after 1 free and 1 reallocation.\n");
722  vMemStats(vpMem, &sStats);
723  vUtilPrintMemStats(&sStats);
724 
725  // clear and test
726  vMemClear(vpMem);
727  printf("\nMemory Statistics: after clearing the memory with vMemClear().\n");
728  vMemStats(vpMem, &sStats);
729  vUtilPrintMemStats(&sStats);
730 
731  }else{
732  // catch block
734  }
735  vMemDtor(vpMem);
736  return iReturn;
737 }
738 
739 static int iVecStats() {
740  int iReturn = EXIT_SUCCESS;
741  vec_stats sStats = {};
742  struct info{
743  aint uiIndex;
744  char caInfo[265];
745  };
746  static void* vpMem = NULL;
747  static void* vpVec = NULL;
748  exception e;
749  XCTOR(e);
750  if(e.try){
751  // try block
752  struct info sInfo;
753  struct info* spTest;
754  vpMem = vpMemCtor(&e);
755  vpVec = vpVecCtor(vpMem, sizeof(struct info), 15);
756 
757  // push some data
758  sInfo.uiIndex = 1;
759  strcpy(sInfo.caInfo, "first");
760  vpVecPush(vpVec, &sInfo);
761 
762  // check the stats
763  printf("\nVector Statistics: 1 push.\n");
764  vVecStats(vpVec, &sStats);
765  vUtilPrintVecStats(&sStats);
766 
767  // push some more data
768  spTest = (struct info*)vpVecPushn(vpVec, NULL, 3);
769  spTest[0].uiIndex = 1;
770  strcpy(spTest[0].caInfo, "second");
771  printf("\nVector Statistics: more data.\n");
772  vVecStats(vpVec, &sStats);
773  vUtilPrintVecStats(&sStats);
774 
775  // make it grow and confirm that everything is still there
776  vpVecPushn(vpVec, NULL, 20);
777  printf("\nVector Statistics: make the vector grow.\n");
778  vVecStats(vpVec, &sStats);
779  vUtilPrintVecStats(&sStats);
780 
781  // pop some data
782  vpVecPop(vpVec);
783  vpVecPop(vpVec);
784  vpVecPopn(vpVec, 3);
785  printf("\nVector Statistics: pop some data.\n");
786  vVecStats(vpVec, &sStats);
787  vUtilPrintVecStats(&sStats);
788 
789  // clean up
790  vVecClear(vpVec);
791  printf("\nVector Statistics: clear the vector.\n");
792  vVecStats(vpVec, &sStats);
793  vUtilPrintVecStats(&sStats);
794 
795  }else{
796  // catch block
798  }
799  // NOTE: Memory object destruction frees all vector allocations.
800  vMemDtor(vpMem);
801  return iReturn;
802 }
803 
814 int main(int argc, char **argv) {
815  long int iCase = 0;
816  if(argc > 1){
817  iCase = atol(argv[1]);
818  }
819  if((iCase > 0) && (iCase <= s_iCaseCount)){
820  printf("%s\n", s_cppCases[iCase -1]);
821  }
822  switch(iCase){
823  case 1:
824  return iApp();
825  case 2:
826  return iTraceDefault();
827  case 3:
828  return iTraceConfigGen();
829  case 4:
830  return iTraceConfigRange();
831  case 5:
832  return iTraceConfigRules();
833  case 6:
834  return iTraceConfigSelect();
835  case 7:
836  return iStatsHits();
837  case 8:
838  return iStatsPppt();
839  case 9:
840  return iStatsCumulative();
841  case 10:
842  return iMemStats();
843  case 11:
844  return iVecStats();
845  default:
846  return iHelp();
847  }
848 }
849 
XCTOR
#define XCTOR(e)
This macro will initialize an exception structure and prepare entry to the "try" block.
Definition: exception.h:77
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
vVecStats
void vVecStats(void *vpCtx, vec_stats *spStats)
Definition: vector.c:459
vpStatsCtor
void * vpStatsCtor(void *vpParserCtx)
The statistics object constructor.
Definition: stats.c:113
parser_config::acpInput
const achar * acpInput
Pointer to the input string.
Definition: parser.h:199
vMemClear
void vMemClear(void *vpCtx)
Frees all memory allocations.
Definition: memory.c:361
vpApiCtor
void * vpApiCtor(exception *spEx)
Construct an API component context (object).
Definition: api.c:55
vUtilPrintMemStats
void vUtilPrintMemStats(const mem_stats *spStats)
Display the memory object's statistics.
Definition: utilities.c:427
uiParserRuleLookup
aint uiParserRuleLookup(void *vpCtx, const char *cpRuleName)
Find the rule index corresponding to a rule name.
Definition: parser.c:440
vApiDtor
void vApiDtor(void *vpCtx)
The API component destructor.
Definition: api.c:84
mem_stats
Available to the user for display of memory statistics.
Definition: memory.h:45
vpMemRealloc
void * vpMemRealloc(void *vpCtx, const void *vpData, aint uiBytes)
Re-allocates memory previously allocated with vpMemAlloc().
Definition: memory.c:268
vec_stats
Vector usage statistics.
Definition: vector.h:46
vpVecPop
void * vpVecPop(void *vpCtx)
Pops one element from the end of the array.
Definition: vector.c:250
aint
uint_fast32_t aint
The APG parser's unsigned integer type.
Definition: apg.h:79
vpVecPopn
void * vpVecPopn(void *vpCtx, aint uiCount)
Pops one or more elements from the end of the array.
Definition: vector.c:271
parser_config::uiInputLength
aint uiInputLength
Number of input string alphabet characters.
Definition: parser.h:200
vpTraceCtor
void * vpTraceCtor(void *vpCtx)
The trace object constructor.
Definition: trace.c:92
parser_config
Defines the input string and other configuration parameters for the parser,.
Definition: parser.h:198
vApiFile
void vApiFile(void *vpCtx, const char *cpFileName, abool bStrict, abool bPppt)
Quicky way to generate a parser from a grammar file.
Definition: api.c:517
main
int main(int argc, char **argv)
The executable from this main function is the ABNF Parser Generator application, APG.
Definition: main.c:61
vpMemAlloc
void * vpMemAlloc(void *vpCtx, aint uiBytes)
Allocates memory.
Definition: memory.c:196
vpVecCtor
void * vpVecCtor(void *vpMem, aint uiElementSize, aint uiInitialAlloc)
The vector object constructor.
Definition: vector.c:118
parser_state
The parser's final state.
Definition: parser.h:183
vStatsToAscii
void vStatsToAscii(void *vpCtx, const char *cpMode, const char *cpFileName)
Display the statistics in ASCII format.
Definition: stats.c:412
exception
A structure to describe the type and location of a caught exception.
Definition: exception.h:47
apg_phrase
Defines a pointer to an achar array plus its length. That is, a phrase as is often used by APG.
Definition: lib.h:60
vMemFree
void vMemFree(void *vpCtx, const void *vpData)
Free memory previously allocated with vpMemAlloc().
Definition: memory.c:226
vpApiOutputParser
void * vpApiOutputParser(void *vpCtx)
Generate a parser object directly from the specified SABNF grammar.
Definition: output.c:217
vpVecPushn
void * vpVecPushn(void *vpCtx, void *vpElement, aint uiCount)
Adds one or more elements to the end of the array.
Definition: vector.c:221
vpMemCtor
void * vpMemCtor(exception *spException)
Construct a memory component.
Definition: memory.c:121
vTraceConfigGen
void vTraceConfigGen(void *vpCtx, const char *cpFileName)
Generate a configuration file for the current parser.
Definition: trace-config.c:452
APG_TRUE
#define APG_TRUE
Definition: apg.h:291
vUtilPrintVecStats
void vUtilPrintVecStats(const vec_stats *spStats)
Display the vector object's statistics.
Definition: utilities.c:440
apg_phrase::uiLength
aint uiLength
The number of characters in the array.
Definition: lib.h:62
vParserDtor
void vParserDtor(void *vpCtx)
Clears the parser component's context and frees all heap memory associated with this parser.
Definition: parser.c:245
vMemStats
void vMemStats(void *vpCtx, mem_stats *spStats)
Returns a copy of the Memory component's current statistics.
Definition: memory.c:456
vTraceConfig
void vTraceConfig(void *vpCtx, const char *cpFileName)
Read a configuration file and set the trace configuration accordingly.
Definition: trace-config.c:143
vUtilApgInfo
void vUtilApgInfo(void)
Display the current state of apg.h.
Definition: utilities.c:60
parser_config::uiStartRule
aint uiStartRule
Index of the start rule. Any rule in the SABNF grammar may be used as the start rule.
Definition: parser.h:201
spUtilStrToPhrase
apg_phrase * spUtilStrToPhrase(void *vpMem, const char *cpStr)
Convert a null-terminated ASCII string to an apg_phrase.
Definition: utilities.c:891
vUtilPrintException
void vUtilPrintException(exception *spEx)
Prints exception information from an exception structure.
Definition: utilities.c:415
vpVecPush
void * vpVecPush(void *vpCtx, void *vpElement)
Adds one element to the end of the array.
Definition: vector.c:193
vUtilCurrentWorkingDirectory
void vUtilCurrentWorkingDirectory(void)
Display the current working directory.
Definition: utilities.c:191
vVecClear
void vVecClear(void *vpCtx)
Clears all used elements in a vector component.
Definition: vector.c:420
vUtilPrintParserState
void vUtilPrintParserState(parser_state *spState)
Display the parser state in human-readable format to stdout.
Definition: utilities.c:727
apg_phrase::acpPhrase
const achar * acpPhrase
Pointer to an array of type achar APG alphabet characters.
Definition: lib.h:61
APG_FALSE
#define APG_FALSE
Definition: apg.h:292
vParserParse
void vParserParse(void *vpCtx, parser_config *spConfig, parser_state *spState)
Parse an input string of alphabet characters.
Definition: parser.c:268
APG Version 7.0 is licensed under the 2-Clause BSD License,
an Open Source Initiative Approved License.