Version 7.0
Copyright © 2021 Lowell D. Thomas
APG
… an ABNF Parser Generator
trace-config.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 * *************************************************************************************/
35 #include "./apg.h"
36 #ifdef APG_TRACE
37 
38 #include <time.h>
39 #include <errno.h>
40 
41 #include "../utilities/utilities.h"
42 #include "./parserp.h"
43 #include "./tracep.h"
44 
45 #define BUF_SIZE 512
46 
47 static char* s_cpTrue = "true";
48 static char* s_cpFalse = "false";
49 
50 static aint* uipUintValue(char* cpValue, aint* uipResult);
51 static abool* bpBoolValue(char* cpValue, abool* bpResult);
52 
56 void vSetDefaultConfig(trace* spTrace) {
57  aint ui;
58  parser* spParser = spTrace->spParserCtx;
59  spTrace->sConfig.uiOutputType = TRACE_ASCII;
61  spTrace->sConfig.bAllRules = APG_TRUE;
62  spTrace->sConfig.bAllOps = APG_TRUE;
63  spTrace->sConfig.bCountOnly = APG_FALSE;
64  spTrace->sConfig.bPppt = (spTrace->spParserCtx->ucpMaps && PPPT_DEFINED) ? APG_TRUE : APG_FALSE;
65  spTrace->sConfig.uiFirstRecord = 0;
67  for (ui = 0; ui < spParser->uiRuleCount; ui++) {
68  // default all rules
69  spTrace->sConfig.bpRules[ui] = APG_TRUE;
70  }
71  if (spParser->uiUdtCount) {
72  for (ui = 0; ui < spParser->uiUdtCount; ui++) {
73  // default all UDTs
74  spTrace->sConfig.bpUdts[ui] = APG_TRUE;
75  }
76  }
77  for (ui = 0; ui < ID_GEN; ui++) {
78  // default all opcodes
79  spTrace->sConfig.bpOps[ui] = APG_TRUE;
80  }
81 }
82 
90 void vTraceOutputType(void* vpCtx, aint uiType){
91  trace* spCtx = (trace*) vpCtx;
92  if(!bParserValidate(spCtx->spParserCtx)){
93  vExContext();
94  }
95  char caBuf[128];
96  char* cpFormat = "trace output type %"PRIuMAX" not recognized\n"
97  "must be TRACE_ASCII or TRACE_HTML";
99  switch(uiType){
100  case TRACE_ASCII:
102  break;
103  case TRACE_HTML:
105  break;
106  default:
107  snprintf(caBuf, 128, cpFormat, (luint)uiType);
108  XTHROW(spCtx->spException, caBuf);
109  break;
110  }
111 }
112 
116 void vTraceApgexType(void* vpCtx, aint uiType){
117  trace* spCtx = (trace*) vpCtx;
118  if(!bParserValidate(spCtx->spParserCtx)){
119  vExContext();
120  }
121  char caBuf[128];
122  char* cpFormat = "trace header type %"PRIuMAX" not recognized\n"
123  "must be TRACE_HEADER_TRACE or TRACE_HEADER_APGEX";
124  switch(uiType){
125  case TRACE_HEADER_TRACE:
127  break;
128  case TRACE_HEADER_APGEX:
130  break;
131  default:
132  snprintf(caBuf, 128, cpFormat, (luint)uiType);
133  XTHROW(spCtx->spException, caBuf);
134  break;
135  }
136 }
137 
143 void vTraceConfig(void* vpCtx, const char* cpFileName) {
144  trace* spCtx = (trace*) vpCtx;
145  if(!bParserValidate(spCtx->spParserCtx)){
146  vExContext();
147  }
148  if(!cpFileName){
149  XTHROW(spCtx->spException, "configuration file name cannot be NULL");
150  }
151  if(cpFileName[0] == 0){
152  XTHROW(spCtx->spException, "configuration file name cannot be empty");
153  }
154 
155  // open the configuration file
156  FILE* spIn = NULL;
157  spCtx->spOpenFile = fopen(cpFileName, "rb");
158  if (!spCtx->spOpenFile) {
159  XTHROW(spCtx->spException, "can't open the configuration file for reading");
160  }
161  spIn = spCtx->spOpenFile;
162  spCtx->vpLog = vpMsgsCtor(spCtx->spException);
163 
164  // start with the defaults
165  vSetDefaultConfig(spCtx);
166  trace_config* spConfig = &spCtx->sConfig;
167  char* cpDelim1 = " =\t\n\r";
168  char* cpDelim2 = " \t\n\r";
169  char* cpKey, *cpValue;
170  abool bValue, bEqual;
171  aint ui, uiKeyLen, uiLineLen, uiValue;
172  char caLineBuf[BUF_SIZE];
173  char caLineSave[BUF_SIZE];
174  char caBuf[(2*BUF_SIZE)];
175  while(fgets(caLineBuf, BUF_SIZE, spIn)){
176  if(caLineBuf[0] == 0x23){
177  continue;
178  }
179  if((caLineBuf[0] == 0x20) || (caLineBuf[0] == 0x09) || (caLineBuf[0] == 0x0A) || (caLineBuf[0] == 0x0D)){
180  continue;
181  }
182 
183  // save a copy of the line for error reporting
184  strcpy(caLineSave, caLineBuf);
185 
186  // get the key
187  uiLineLen = (aint)strlen(caLineBuf);
188  cpKey = strtok(caLineBuf, cpDelim1);
189  if(!cpKey){
190  vMsgsLog(spCtx->vpLog, "invalid key");
191  vMsgsLog(spCtx->vpLog, caLineSave);
192  continue;
193  }
194 
195  // skip the =
196  uiKeyLen = (aint)strlen(cpKey);
197  bEqual = APG_FALSE;
198  for(ui = (uiKeyLen + 1); ui < uiLineLen; ui++){
199  if(caLineBuf[ui] == 0x3D){
200  bEqual = APG_TRUE;
201  continue;
202  }
203  if(((caLineBuf[ui] == 0x20) || (caLineBuf[ui] == 0x09))){
204  continue;
205  }
206  break;
207  }
208  if(!bEqual){
209  vMsgsLog(spCtx->vpLog, "key/value pair not separated with =");
210  vMsgsLog(spCtx->vpLog, caLineSave);
211  continue;
212  }
213 
214  cpValue = strtok(&caLineBuf[ui], cpDelim2);
215  if(!cpValue){
216  vMsgsLog(spCtx->vpLog, "invalid value");
217  vMsgsLog(spCtx->vpLog, caLineSave);
218  continue;
219  }
220 
221  // handle the integer values
222  if (strcmp("first-record", cpKey) == 0) {
223  if(!uipUintValue(cpValue, &uiValue)){
224  vMsgsLog(spCtx->vpLog, "invalid unsigned integer value");
225  vMsgsLog(spCtx->vpLog, caLineSave);
226  continue;
227  }
228  spConfig->uiFirstRecord = uiValue;
229  continue;
230  }
231  if (strcmp("max-records", cpKey) == 0) {
232  if(!uipUintValue(cpValue, &uiValue)){
233  vMsgsLog(spCtx->vpLog, "invalid unsigned integer value");
234  vMsgsLog(spCtx->vpLog, caLineSave);
235  continue;
236  }
237  if(uiValue){
238  spConfig->uiMaxRecords = uiValue;
239  }else{
240  spConfig->uiMaxRecords = APG_MAX_AINT;
241  }
242  continue;
243  }
244 
245  // handle the boolean values
246  if(!bpBoolValue(cpValue, &bValue)){
247  vMsgsLog(spCtx->vpLog, "invalid true/false value");
248  vMsgsLog(spCtx->vpLog, caLineSave);
249  continue;
250  }
251  if (strcmp("all-rules", cpKey) == 0) {
252  spConfig->bAllRules = bValue;
253  for(ui = 0; ui < spCtx->spParserCtx->uiRuleCount; ui++){
254  spConfig->bpRules[ui] = bValue;
255  }
256  for(ui = 0; ui < spCtx->spParserCtx->uiUdtCount; ui++){
257  spConfig->bpUdts[ui] = bValue;
258  }
259  continue;
260  }
261  if (strcmp("all-ops", cpKey) == 0) {
262  spConfig->bAllOps = bValue;
263  for (ui = 0; ui < ID_GEN; ui++) {
264  spConfig->bpOps[ui] = bValue;
265  }
266  continue;
267  }
268  if (strcmp("count-only", cpKey) == 0) {
269  spConfig->bCountOnly = bValue;
270  continue;
271  }
272  if (strcmp("PPPT", cpKey) == 0) {
273  if(bValue){
274  spConfig->bPppt = (spCtx->spParserCtx->ucpMaps && PPPT_DEFINED) ? APG_TRUE : APG_FALSE;
275  }else{
276  spConfig->bPppt = APG_FALSE;
277  }
278  continue;
279  }
280  if (strcmp("ALT", cpKey) == 0) {
281  spConfig->bpOps[ID_ALT] = bValue;
282  continue;
283  }
284  if (strcmp("CAT", cpKey) == 0) {
285  spConfig->bpOps[ID_CAT] = bValue;
286  continue;
287  }
288  if (strcmp("REP", cpKey) == 0) {
289  spConfig->bpOps[ID_REP] = bValue;
290  continue;
291  }
292  if (strcmp("TRG", cpKey) == 0) {
293  spConfig->bpOps[ID_TRG] = bValue;
294  continue;
295  }
296  if (strcmp("TLS", cpKey) == 0) {
297  spConfig->bpOps[ID_TLS] = bValue;
298  continue;
299  }
300  if (strcmp("TBS", cpKey) == 0) {
301  spConfig->bpOps[ID_TBS] = bValue;
302  continue;
303  }
304  if (strcmp("BKR", cpKey) == 0) {
305  spConfig->bpOps[ID_BKR] = bValue;
306  continue;
307  }
308  if (strcmp("AND", cpKey) == 0) {
309  spConfig->bpOps[ID_AND] = bValue;
310  continue;
311  }
312  if (strcmp("NOT", cpKey) == 0) {
313  spConfig->bpOps[ID_NOT] = bValue;
314  continue;
315  }
316  if (strcmp("BKA", cpKey) == 0) {
317  spConfig->bpOps[ID_BKA] = bValue;
318  continue;
319  }
320  if (strcmp("BKN", cpKey) == 0) {
321  spConfig->bpOps[ID_BKN] = bValue;
322  continue;
323  }
324  if (strcmp("ABG", cpKey) == 0) {
325  spConfig->bpOps[ID_ABG] = bValue;
326  continue;
327  }
328  if (strcmp("AEN", cpKey) == 0) {
329  spConfig->bpOps[ID_AEN] = bValue;
330  continue;
331  }
332  if (strncmp("rule:", cpKey, 5) == 0) {
333  rule* spRule = spCtx->spParserCtx->spRules;
334  for (ui = 0; ui < spCtx->spParserCtx->uiRuleCount; ui++, spRule++) {
335  if (iStriCmp(spRule->cpRuleName, &cpKey[5]) == 0) {
336  spConfig->bpRules[spRule->uiRuleIndex] = bValue;
337  goto foundr;
338  }
339  }
340  snprintf(caBuf, (2*BUF_SIZE), "rule name \"%s\" not recognized", cpKey);
341  vMsgsLog(spCtx->vpLog, caBuf);
342  vMsgsLog(spCtx->vpLog, caLineSave);
343  foundr:;
344  continue;
345  }
346  if (strncmp("UDT:", cpKey, 4) == 0) {
347  udt* spUdt = spCtx->spParserCtx->spUdts;
348  for (ui = 0; ui < spCtx->spParserCtx->uiUdtCount; ui++, spUdt++) {
349  if (iStriCmp(spUdt->cpUdtName, &cpKey[4]) == 0) {
350  spConfig->bpUdts[spUdt->uiUdtIndex] = bValue;
351  goto foundu;
352  }
353  }
354  snprintf(caBuf, (2*BUF_SIZE), "UDT name \"%s\" not recognized", cpKey);
355  vMsgsLog(spCtx->vpLog, caBuf);
356  vMsgsLog(spCtx->vpLog, caLineSave);
357  foundu:;
358  continue;
359  }
360  vMsgsLog(spCtx->vpLog, "key/value pair not recognized");
361  vMsgsLog(spCtx->vpLog, caLineSave);
362  }
363 
364  // close the file
365  if (spIn) {
366  fclose(spIn);
367  spCtx->spOpenFile = NULL;
368  }
369 
370  // display error messages if any
371  if(uiMsgsCount(spCtx->vpLog)){
372  vUtilPrintMsgs(spCtx->vpLog);
373  vMsgsDtor(spCtx->vpLog);
374  spCtx->vpLog = NULL;
375  XTHROW(spCtx->spException, "errors in trace configuration file");
376  }
377  vMsgsDtor(spCtx->vpLog);
378  spCtx->vpLog = NULL;
379 }
387 void vTraceConfigDisplay(void* vpCtx, const char* cpFileName) {
388  trace* spCtx = (trace*) vpCtx;
389  if(!bParserValidate(spCtx->spParserCtx)){
390  vExContext();
391  }
392  FILE* spOut = stdout;
393  trace_config* spCfg = &spCtx->sConfig;
394  aint ui;
395  if (cpFileName) {
396  spOut = fopen(cpFileName, "wb");
397  if (!spOut) {
398  XTHROW(spCtx->spException, "can't open display file for writing");
399  }
400  }
401  fprintf(spOut, "TRACE CONFIGURATION\n");
402  fprintf(spOut, " %-15s: %s\n", "all-rules", (spCfg->bAllRules ? s_cpTrue : s_cpFalse));
403  fprintf(spOut, " %-15s: %s\n", "all-ops", (spCfg->bAllOps ? s_cpTrue : s_cpFalse));
404  fprintf(spOut, " %-15s: %s\n", "count-only", (spCfg->bCountOnly ? s_cpTrue : s_cpFalse));
405  fprintf(spOut, " %-15s: %s\n", "PPPT display", (spCfg->bPppt ? s_cpTrue : s_cpFalse));
406  fprintf(spOut, " %-15s: %"PRIuMAX"\n", "first-record", (luint) spCfg->uiFirstRecord);
407  fprintf(spOut, " %-15s: %"PRIuMAX"\n", "max-records", (luint) spCfg->uiMaxRecords);
408  fprintf(spOut, "OPCODES\n");
409  fprintf(spOut, " %-15s: %s\n", "ALT", (spCfg->bpOps[ID_ALT] ? s_cpTrue : s_cpFalse));
410  fprintf(spOut, " %-15s: %s\n", "CAT", (spCfg->bpOps[ID_CAT] ? s_cpTrue : s_cpFalse));
411  fprintf(spOut, " %-15s: %s\n", "REP", (spCfg->bpOps[ID_REP] ? s_cpTrue : s_cpFalse));
412  fprintf(spOut, " %-15s: %s\n", "TRG", (spCfg->bpOps[ID_TRG] ? s_cpTrue : s_cpFalse));
413  fprintf(spOut, " %-15s: %s\n", "TBS", (spCfg->bpOps[ID_TBS] ? s_cpTrue : s_cpFalse));
414  fprintf(spOut, " %-15s: %s\n", "TLS", (spCfg->bpOps[ID_TLS] ? s_cpTrue : s_cpFalse));
415  fprintf(spOut, " %-15s: %s\n", "BKR", (spCfg->bpOps[ID_BKR] ? s_cpTrue : s_cpFalse));
416  fprintf(spOut, " %-15s: %s\n", "AND", (spCfg->bpOps[ID_AND] ? s_cpTrue : s_cpFalse));
417  fprintf(spOut, " %-15s: %s\n", "NOT", (spCfg->bpOps[ID_NOT] ? s_cpTrue : s_cpFalse));
418  fprintf(spOut, " %-15s: %s\n", "BKA", (spCfg->bpOps[ID_BKA] ? s_cpTrue : s_cpFalse));
419  fprintf(spOut, " %-15s: %s\n", "BKN", (spCfg->bpOps[ID_BKN] ? s_cpTrue : s_cpFalse));
420  fprintf(spOut, " %-15s: %s\n", "ABG", (spCfg->bpOps[ID_ABG] ? s_cpTrue : s_cpFalse));
421  fprintf(spOut, " %-15s: %s\n", "AEN", (spCfg->bpOps[ID_AEN] ? s_cpTrue : s_cpFalse));
422  fprintf(spOut, "RULES\n");
423  rule* spRule = spCtx->spParserCtx->spRules;
424  for (ui = 0; ui < spCtx->spParserCtx->uiRuleCount; ui++, spRule++) {
425  fprintf(spOut, " %-15s: %s\n", spRule->cpRuleName,
426  (spCfg->bpRules[spRule->uiRuleIndex] ? s_cpTrue : s_cpFalse));
427  }
428  if (spCtx->spParserCtx->uiUdtCount) {
429  fprintf(spOut, "UDTS\n");
430  udt* spUdt = spCtx->spParserCtx->spUdts;
431  for (ui = 0; ui < spCtx->spParserCtx->uiUdtCount; ui++, spUdt++) {
432  fprintf(spOut, " %-15s: %s\n", spUdt->cpUdtName,
433  (spCfg->bpUdts[spUdt->uiUdtIndex] ? s_cpTrue : s_cpFalse));
434  }
435  }
436  if (spOut != stdout) {
437  fclose(spOut);
438  }
439 }
440 
452 void vTraceConfigGen(void *vpCtx, const char *cpFileName) {
453  trace *spCtx = (trace*) vpCtx;
454  if (!bParserValidate(spCtx->spParserCtx)) {
455  vExContext();
456  }
457  FILE *spOut = NULL;
458  aint ui;
459  spCtx->spOpenFile = stdout;
460  while (APG_TRUE) {
461  if (cpFileName) {
462  spCtx->spOpenFile = fopen(cpFileName, "wb");
463  if (!spCtx->spOpenFile) {
464  XTHROW(spCtx->spException, "can't open configuration file for writing");
465  break;
466  }
467  }
468  spOut = spCtx->spOpenFile;
469  time_t tTime = time(NULL);
470  fprintf(spOut, "# TRACE CONFIGURATION\n");
471  fprintf(spOut, "# Generated by: %s\n", __func__);
472  fprintf(spOut, "# %s", asctime(gmtime(&tTime)));
473  fprintf(spOut, "#\n");
474  fprintf(spOut, "# NOTE 1) All keys and values are case sensitive including the \"rule:\" and \"UDT:\" prefixes.\n");
475  fprintf(spOut, "# However, rule and UDT names are case insensitive\n");
476  fprintf(spOut, "# NOTE 2) true may be represented by true or t or 1\n");
477  fprintf(spOut, "# false may be represented by false or f or 0\n");
478  fprintf(spOut, "# NOTE 3) Lines beginning with # (0x23) or white space (0x09, 0x0A, 0x0D or 0x20) are ignored.\n");
479  fprintf(spOut, "# NOTE 4) Missing keys assume the listed default values.\n");
480  fprintf(spOut, "# NOTE 5) Unrecognized keys and values will result in error messages and a thrown exception.\n");
481  fprintf(spOut, "#\n");
482  fprintf(spOut, "# Sets all rule and UDT names to value. Default = true\n");
483  fprintf(spOut, "all-rules = true\n");
484  fprintf(spOut, "#\n");
485  fprintf(spOut, "# Sets all opcodes to value. Default = true\n");
486  fprintf(spOut, "all-ops = true\n");
487  fprintf(spOut, "#\n");
488  fprintf(spOut, "# If \"PPPT\" is true the Partially-Predictive Parsing Table (PPPT) form of output will be used.\n");
489  fprintf(spOut, "# The PPPT form indicates when a predictive table value was used in place of an opcode.\n");
490  fprintf(spOut, "# If no PPPT data is available \"PPPT\" is automatically set to false.\n");
491  fprintf(spOut, "# \"PPPT\" defaults to true if PPPT data is available, false otherwise.\n");
492  fprintf(spOut, "PPPT = true\n");
493  fprintf(spOut, "#\n");
494  fprintf(spOut, "# If \"count-only\" is true, only a count of the total number of records is displayed.\n");
495  fprintf(spOut, "# The printing of individual records is suppressed.\n");
496  fprintf(spOut, "# Handy for a first run on large grammars or input strings.\n");
497  fprintf(spOut, "# It can help in setting the \"first-record\" and \"max-records\" parameters.\n");
498  fprintf(spOut, "# Default = false\n");
499  fprintf(spOut, "count-only = false\n");
500  fprintf(spOut, "#\n");
501  fprintf(spOut, "# \"first-record\" sets the record number of the first record to display.\n");
502  fprintf(spOut, "# Records prior are not displayed. Default = 0.\n");
503  fprintf(spOut, "first-record = 0\n");
504  fprintf(spOut, "#\n");
505  fprintf(spOut, "# \"max-records\" sets the maximum number of records to display.\n");
506  fprintf(spOut, "# If 0, the maximum number of records is set to APG_MAX_AINT. Default = 0.\n");
507  fprintf(spOut, "max-records = 0\n");
508  fprintf(spOut, "#\n");
509  fprintf(spOut, "# Set the opcodes to be displayed individually.\n");
510  fprintf(spOut, "# They all default to the \"all-ops\" value.\n");
511  fprintf(spOut, "# Un-comment and set the value if different from \"all-ops\".\n");
512  fprintf(spOut, "# Note that depending on the SABNF grammar and input string,\n");
513  fprintf(spOut, "# not all of these operators may generate trace records.\n");
514  fprintf(spOut, "#ALT = true\n");
515  fprintf(spOut, "#CAT = true\n");
516  fprintf(spOut, "#REP = true\n");
517  fprintf(spOut, "#TRG = true\n");
518  fprintf(spOut, "#TBS = true\n");
519  fprintf(spOut, "#TLS = true\n");
520  fprintf(spOut, "#BKR = true\n");
521  fprintf(spOut, "#AND = true\n");
522  fprintf(spOut, "#NOT = true\n");
523  fprintf(spOut, "#BKA = true\n");
524  fprintf(spOut, "#BKN = true\n");
525  fprintf(spOut, "#ABG = true\n");
526  fprintf(spOut, "#AEN = true\n");
527  fprintf(spOut, "#\n");
528  fprintf(spOut, "# Set the rule & UDT names to be displayed individually.\n");
529  fprintf(spOut, "# They all default to the \"all-rules\" value.\n");
530  fprintf(spOut, "# Un-comment and set the value if different from \"all-rules\".\n");
531  fprintf(spOut, "# Note that rule names must begin with \"rule:\" with no trailing spaces.\n");
532  fprintf(spOut, "# and UDT names must begin with \"UDT:\" with no trailing spaces.\n");
533  rule *spRule = spCtx->spParserCtx->spRules;
534  for (ui = 0; ui < spCtx->spParserCtx->uiRuleCount; ui++, spRule++) {
535  fprintf(spOut, "#rule:%s = true\n", spRule->cpRuleName);
536  }
537  if (spCtx->spParserCtx->uiUdtCount) {
538  fprintf(spOut, "#\n");
539  udt *spUdt = spCtx->spParserCtx->spUdts;
540  for (ui = 0; ui < spCtx->spParserCtx->uiUdtCount; ui++, spUdt++) {
541  fprintf(spOut, "#UDT: %s = true\n", spUdt->cpUdtName);
542  }
543  }
544  break;
545  }
546  if (spOut != stdout) {
547  fclose(spOut);
548  spCtx->spOpenFile = NULL;
549  }
550 }
551 
552 static abool* bpBoolValue(char* cpValue, abool* bpResult){
553  abool* bpReturn = NULL;
554  if(cpValue[0] == 116 || cpValue[0] == 49){
555  *bpResult = APG_TRUE;
556  bpReturn = bpResult;
557  }else if(cpValue[0] == 102 || cpValue[0] == 48){
558  *bpResult = APG_FALSE;
559  bpReturn = bpResult;
560  }
561  return bpReturn;
562 }
563 static aint* uipUintValue(char* cpValue, aint* uipResult){
564  char* cpTailPtr;
565  errno = 0;
566  long int iLong = strtol(cpValue, &cpTailPtr, 10);
567  if(cpTailPtr == cpValue || errno != 0){
568  return NULL;
569  }
570  if(iLong < 0){
571  return NULL;
572  }
573  if(iLong > APG_MAX_AINT){
574  return NULL;
575  }
576  *uipResult = (aint)iLong;
577  return uipResult;
578 }
579 
580 #endif /* APG_TRACE */
vMsgsLog
void vMsgsLog(void *vpCtx, const char *cpMsg)
Logs a message.
Definition: msglog.c:141
trace_config::bAllRules
abool bAllRules
If true, all rule nodes will be displayed.
Definition: tracep.h:81
PPPT_DEFINED
#define PPPT_DEFINED
Definition: apg.h:277
vTraceConfigDisplay
void vTraceConfigDisplay(void *vpCtx, const char *cpFileName)
Display the trace object's current configuration.
Definition: trace-config.c:387
apg.h
The APG header file.
APG_INFINITE
#define APG_INFINITE
Definition: apg.h:320
trace::spParserCtx
parser * spParserCtx
Pointer back to the parent parser's context.
Definition: tracep.h:95
parserp.h
Private header for the SABNF parser.
uiMsgsCount
aint uiMsgsCount(void *vpCtx)
Get the number of logged messages.
Definition: msglog.c:213
trace_config
Configuration defining the subset of nodes to display information for.
Definition: tracep.h:73
ID_ALT
#define ID_ALT
alternation
Definition: parser.h:43
ID_BKR
#define ID_BKR
back reference to a previously matched rule or UDT name
Definition: parser.h:58
vUtilPrintMsgs
void vUtilPrintMsgs(void *vpMsgs)
Display the list of messages in a message object to stdout.
Definition: utilities.c:747
trace::spOpenFile
FILE * spOpenFile
Pointer to any other open file.
Definition: tracep.h:99
vExContext
void vExContext()
Handles bad context pointers.
Definition: exception.c:126
trace_config::bPppt
abool bPppt
However, no records are actually displayed.
Definition: tracep.h:85
trace_config::bpUdts
abool * bpUdts
An array of true/false indicators for each UDT in the SABNF grammar.
Definition: tracep.h:75
iStriCmp
int iStriCmp(const char *cpLeft, const char *cpRight)
Compare two strings. A case-insensitive version of strcmp().
Definition: tools.c:53
trace_config::uiMaxRecords
aint uiMaxRecords
Maximun number of records to display.
Definition: tracep.h:80
ID_NOT
#define ID_NOT
negative look ahead
Definition: parser.h:57
ID_AND
#define ID_AND
positive look ahead
Definition: parser.h:56
trace_config::bpOps
abool * bpOps
An array of true/false indicators for each opcode in the SABNF grammar.
Definition: tracep.h:76
trace::sConfig
trace_config sConfig
Pointer to the trace configuration.
Definition: tracep.h:110
XTHROW
#define XTHROW(ctx, msg)
Exception throw macro.
Definition: exception.h:67
rule::uiRuleIndex
aint uiRuleIndex
The rule index - zero-based order in which the rule appears in the SABNF grammar.
Definition: parserp.h:127
aint
uint_fast32_t aint
The APG parser's unsigned integer type.
Definition: apg.h:79
trace_config::uiOutputType
aint uiOutputType
Output type identifier (TRACE_ASCII or TRACE_HTML)
Definition: tracep.h:77
vpMsgsCtor
void * vpMsgsCtor(exception *spEx)
The Message Log constructor.
Definition: msglog.c:68
ID_CAT
#define ID_CAT
concatenation
Definition: parser.h:44
udt::cpUdtName
const char * cpUdtName
Pointer to the (null-terminated) ASCII rule name.
Definition: parserp.h:134
ID_TRG
#define ID_TRG
terminal range
Definition: parser.h:47
ID_REP
#define ID_REP
repetition
Definition: parser.h:45
trace_config::bAllOps
abool bAllOps
If true, all UDT nodes will be displayed.
Definition: tracep.h:82
vMsgsDtor
void vMsgsDtor(void *vpCtx)
The object destructor.
Definition: msglog.c:92
luint
uintmax_t luint
luint is used to cast integers suitable for the %"PRIuMAX" printf format.
Definition: apg.h:133
ID_BKA
#define ID_BKA
positive look behind
Definition: parser.h:59
trace_config::uiHeaderType
aint uiHeaderType
Indicates whether the trace is being done by apgex.
Definition: tracep.h:78
ID_GEN
#define ID_GEN
general opcode (not SABNF). Serves to locate the ID in any opcode structure and must be larger than a...
Definition: parser.h:63
vTraceConfigGen
void vTraceConfigGen(void *vpCtx, const char *cpFileName)
Generate a configuration file for the current parser.
Definition: trace-config.c:452
TRACE_HEADER_APGEX
#define TRACE_HEADER_APGEX
Identifies apgex as the header handler.
Definition: tracep.h:50
tracep.h
Private header file for the trace functions.
ID_TLS
#define ID_TLS
terminal literal string
Definition: parser.h:49
rule
Data structure for a single rule.
Definition: parserp.h:119
APG_TRUE
#define APG_TRUE
Definition: apg.h:291
vTraceApgexType
void vTraceApgexType(void *vpCtx, aint uiType)
Called only by apgex. Sets the display type for apgex tracing.
Definition: trace-config.c:116
BUF_SIZE
#define BUF_SIZE
Definition: trace-config.c:45
TRACE_HTML
#define TRACE_HTML
Identifier for HTML trace record format.
Definition: trace.h:45
APG_MAX_AINT
#define APG_MAX_AINT
Since the maximum unsigned integer value is used to indicate Infinite and Undefined values,...
Definition: apg.h:329
ID_BKN
#define ID_BKN
negative look behind
Definition: parser.h:60
vTraceConfig
void vTraceConfig(void *vpCtx, const char *cpFileName)
Read a configuration file and set the trace configuration accordingly.
Definition: trace-config.c:143
abool
uint8_t abool
abool is the APG bool type.
Definition: apg.h:140
trace_config::bpRules
abool * bpRules
An array of true/false indicators for each rule in the SABNF grammar.
Definition: tracep.h:74
TRACE_HEADER_TRACE
#define TRACE_HEADER_TRACE
Identifies the trace object as the header handler.
Definition: tracep.h:54
TRACE_ASCII
#define TRACE_ASCII
Identifier for plain ASCII trace record format.
Definition: trace.h:41
ID_ABG
#define ID_ABG
anchor - beginning of string
Definition: parser.h:61
trace
The trace object context. Maintains the trace object's state.
Definition: tracep.h:91
trace_config::uiFirstRecord
aint uiFirstRecord
Number of the first record to display.
Definition: tracep.h:79
vTraceOutputType
void vTraceOutputType(void *vpCtx, aint uiType)
Set the trace record display type.
Definition: trace-config.c:90
ID_TBS
#define ID_TBS
terminal binary string
Definition: parser.h:48
trace_config::bCountOnly
abool bCountOnly
If true, trace will only count the number of records that would have been displayed.
Definition: tracep.h:83
bParserValidate
abool bParserValidate(void *vpCtx)
Validate the context pointer of a parser.
Definition: parser.c:422
udt
Data structure for a single UDT.
Definition: parserp.h:133
trace::vpLog
void * vpLog
Pointer to a message log object for reporting configuration errors.
Definition: tracep.h:94
udt::uiUdtIndex
aint uiUdtIndex
The UDT index - the zero-based order in which the UDT appears in the SABNF grammar.
Definition: parserp.h:139
rule::cpRuleName
const char * cpRuleName
Pointer to the (null-terminated) ASCII rule name.
Definition: parserp.h:120
trace::spException
exception * spException
Pointer to the exception to use to report fatal errors back to the parser's catch block.
Definition: tracep.h:93
vSetDefaultConfig
void vSetDefaultConfig(trace *spTrace)
Sets the default trace configuration on construction.
Definition: trace-config.c:56
ID_AEN
#define ID_AEN
anchor - end of string
Definition: parser.h:62
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.