Version 7.0
Copyright © 2021 Lowell D. Thomas
APG
… an ABNF Parser Generator
input.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 "./api.h"
35 #include "./apip.h"
36 #include "./attributes.h"
37 
38 
39 #undef CR
40 #undef LF
41 #undef TAB
42 #define CR 13
43 #define LF 10
44 #define TAB 9
45 #define BUF_SIZE 128
46 
47 static void vPushInvalidChar(api* spCtx, aint uiCharIndex, uint8_t ucChar, const char* cpMsg);
48 
49 static const char* s_cpMsgInvalid =
50  "valid ABNF characters are, 0x09, 0x0A, 0x0D and 0x20-7E only";
51 static const char* s_cpMsgCRLF = "invalid line ending - must be CRLF (\\r\\n, 0x0D0A) - strict specified";
52 static const char* s_cpMsgEOF = "invalid line ending - last line has no line ending";
53 static char s_cZero = 0;
54 
61 void vApiInClear(void* vpCtx) {
62  if(!bApiValidate(vpCtx)){
63  vExContext();
64  }
65  api* spCtx = (api*) vpCtx;
66  vMsgsClear(spCtx->vpLog);
67  vVecClear(spCtx->vpAltStack);
68  vVecClear(spCtx->vpVecInput);
69  vLinesDtor(spCtx->vpLines);
70  vAttrsDtor(spCtx->vpAttrsCtx);
71  vParserDtor(spCtx->vpParser);
72  vMemFree(spCtx->vpMem, spCtx->spOpcodes);
73  spCtx->spOpcodes = NULL;
74  vMemFree(spCtx->vpMem, spCtx->spRules);
75  spCtx->spRules = NULL;
76  vMemFree(spCtx->vpMem, spCtx->spUdts);
77  spCtx->spUdts = NULL;
78  spCtx->uiRuleCount = 0;
79  spCtx->uiUdtCount = 0;
80  vMemFree(spCtx->vpMem, spCtx->luipAcharTable);
81  spCtx->luipAcharTable = NULL;
82  spCtx->uiAcharTableLength = 0;
83  vMemFree(spCtx->vpMem, spCtx->uipChildIndexTable);
84  spCtx->uipChildIndexTable = NULL;
85  vMemFree(spCtx->vpMem, spCtx->ucpPpptTable);
86  spCtx->ucpPpptTable = NULL;
87  vMemFree(spCtx->vpMem, spCtx->vpOutputAcharTable);
88  spCtx->vpOutputAcharTable = NULL;
89  vMemFree(spCtx->vpMem, spCtx->vpOutputParserInit);
90  spCtx->vpOutputParserInit = NULL;
91  vMemFree(spCtx->vpMem, spCtx->ucpPpptUndecidedMap);
92  spCtx->ucpPpptUndecidedMap = NULL;
93  vMemFree(spCtx->vpMem, spCtx->ucpPpptEmptyMap);
94  spCtx->ucpPpptEmptyMap = NULL;
95  spCtx->uiChildIndexTableLength = 0;
96  vMemFree(spCtx->vpMem, spCtx->cpStringTable);
97  spCtx->cpStringTable = NULL;
98  spCtx->vpLines = NULL;
99  spCtx->cpInput = (char*)vpVecPush(spCtx->vpVecInput, &s_cZero);
100  spCtx->uiInputLength = 0;
101  spCtx->bAttributesValid = APG_FALSE;
102  spCtx->bInputValid = APG_FALSE;
103  spCtx->bSyntaxValid = APG_FALSE;
104  spCtx->bSemanticsValid = APG_FALSE;
105  spCtx->bUsePppt = APG_FALSE;
106 }
107 
117 const char* cpApiInFile(void* vpCtx, const char* cpFileName) {
118  if(!bApiValidate(vpCtx)){
119  vExContext();
120  }
121  api* spCtx = (api*) vpCtx;
122  char caBuf[BUF_SIZE];
123  FILE* spFile = NULL;
124  aint uiRead;
125  char caReadBuf[1024];
126  size_t iBufSize = 1024;
127  vMsgsClear(spCtx->vpLog);
128  spCtx->bAttributesValid = APG_FALSE;
129  spCtx->bInputValid = APG_FALSE;
130  spCtx->bSyntaxValid = APG_FALSE;
131  spCtx->bSemanticsValid = APG_FALSE;
132  if (!cpFileName) {
133  XTHROW(spCtx->spException, "file name pointer cannot be NULL");
134  }
135  // open the file
136  spFile = fopen(cpFileName, "rb");
137  if (!spFile) {
138  snprintf(caBuf, BUF_SIZE, "unable to open file name %s for reading", cpFileName);
139  XTHROW(spCtx->spException, caBuf);
140  }
141  // pop the null-term
142  vpVecPop(spCtx->vpVecInput);
143  while((uiRead = (aint)fread(caReadBuf, sizeof(char), iBufSize, spFile)) > 0){
144  vpVecPushn(spCtx->vpVecInput, caReadBuf, uiRead);
145  }
146  fclose(spFile);
147  // push the null-term
148  spCtx->uiInputLength = uiVecLen(spCtx->vpVecInput);
149  vpVecPush(spCtx->vpVecInput, &s_cZero);
150  spCtx->cpInput = (char*) vpVecFirst(spCtx->vpVecInput);
151  vLinesDtor(spCtx->vpLines);
152  spCtx->vpLines = vpLinesCtor(spCtx->spException, spCtx->cpInput, spCtx->uiInputLength);
153  return spCtx->cpInput;
154 }
155 
165 const char* cpApiInString(void* vpCtx, const char* cpString) {
166  if(!bApiValidate(vpCtx)){
167  vExContext();
168  }
169  api* spCtx = (api*) vpCtx;
170  vMsgsClear(spCtx->vpLog);
171  spCtx->bAttributesValid = APG_FALSE;
172  spCtx->bInputValid = APG_FALSE;
173  spCtx->bSyntaxValid = APG_FALSE;
174  spCtx->bSemanticsValid = APG_FALSE;
175  aint uiLen;
176  if (!cpString) {
177  XTHROW(spCtx->spException, "input string cannot be NULL");
178  }
179  uiLen = (aint)strlen(cpString);
180  if (!uiLen) {
181  XTHROW(spCtx->spException, "input string cannot be empty");
182  }
183  // pop the null-term
184  vpVecPop(spCtx->vpVecInput);
185  vpVecPushn(spCtx->vpVecInput, (void*) cpString, uiLen);
186  // push the null-term
187  spCtx->uiInputLength = uiVecLen(spCtx->vpVecInput);
188  vpVecPush(spCtx->vpVecInput, &s_cZero);
189  spCtx->cpInput = (char*) vpVecFirst(spCtx->vpVecInput);
190  vLinesDtor(spCtx->vpLines);
191  spCtx->vpLines = vpLinesCtor(spCtx->spException, spCtx->cpInput, spCtx->uiInputLength);
192  return spCtx->cpInput;
193 }
194 
204 void vApiInValidate(void* vpCtx, abool bStrict) {
205  if(!bApiValidate(vpCtx)){
206  vExContext();
207  }
208  api* spCtx = (api*) vpCtx;
209  char caBuf[BUF_SIZE];
210  aint ui, uii, uiLines, uiEndLen;
211  line* spThis;
212  line* spLines;
213  if (!spCtx->cpInput) {
214  snprintf(caBuf, BUF_SIZE,
215  "no input grammar, see bApiInFile() & uiApiInString()\n");
216  XTHROW(spCtx->spException, caBuf);
217  }
218  spCtx->bInputValid = APG_TRUE;
219  spLines = spLinesFirst(spCtx->vpLines);
220  uiLines = uiLinesCount(spCtx->vpLines);
221  for (ui = 0; ui < uiLines; ui += 1) {
222  spThis = &spLines[ui];
223  for (uii = 0; uii < spThis->uiTextLength; uii += 1) {
224  uint8_t ucChar = (uint8_t) spCtx->cpInput[spThis->uiCharIndex + uii];
225  if (ucChar != TAB) {
226  if (ucChar < 32 || ucChar > 126) {
227  // invalid character
228  spCtx->bInputValid = APG_FALSE;
229  vPushInvalidChar(spCtx, (spThis->uiCharIndex + uii), ucChar, s_cpMsgInvalid);
230  }
231  }
232  }
233  uiEndLen = (aint) strlen(spThis->caLineEnd);
234  if (uiEndLen == 0) {
235  // EOF
236  spCtx->bInputValid = APG_FALSE;
237  vPushInvalidChar(spCtx, (spThis->uiCharIndex + uii - 1), 0, s_cpMsgEOF);
238  } else if (uiEndLen == 1) {
239  if (bStrict) {
240  // not CRLF
241  spCtx->bInputValid = APG_FALSE;
242  vPushInvalidChar(spCtx, (spThis->uiCharIndex + uii), (uint8_t) spThis->caLineEnd[0],
243  s_cpMsgCRLF);
244  }
245  }
246  }
247  if(!spCtx->bInputValid){
248  XTHROW(spCtx->spException, "grammar has invalid characters");
249  }
250 }
251 
261 void vApiInToAscii(void* vpCtx, const char* cpFileName) {
262  if(!bApiValidate(vpCtx)){
263  vExContext();
264  }
265  api* spCtx = (api*) vpCtx;
266  char caBuf[BUF_SIZE];
267  FILE* spFile = stdout;
268  aint uii;
269  line* spLine;
270  uint8_t ucChar;
271  if (cpFileName) {
272  spFile = fopen(cpFileName, "wb");
273  if (!spFile) {
274  snprintf(caBuf, BUF_SIZE, "can't open file %s for writing", cpFileName);
275  XTHROW(spCtx->spException, caBuf);
276  }
277  }
278  spLine = spLinesFirst(spCtx->vpLines);
279  while(spLine) {
280  fprintf(spFile, "%"PRIuMAX"(%"PRIuMAX"):", (luint) spLine->uiLineIndex, (luint) spLine->uiCharIndex);
281  for (uii = 0; uii < spLine->uiTextLength; uii += 1) {
282  ucChar = (uint8_t) spCtx->cpInput[spLine->uiCharIndex + uii];
283  if (ucChar == TAB) {
284  fprintf(spFile, "\\t"); // TAB
285  } else if (ucChar >= 32 && ucChar <= 126) {
286  fprintf(spFile, "%c", ucChar); // good char
287  } else {
288  fprintf(spFile, "\"\\x%02X\"", ucChar); // bad char
289  }
290  }
291  ucChar = spLine->caLineEnd[0];
292  if (ucChar == 0) {
293  fprintf(spFile, "\\EOF\n"); // bad line ending
294  } else {
295  fprintf(spFile, "%s", ucChar == LF ? "\\n" : "\\r");
296  ucChar = spLine->caLineEnd[1];
297  if (ucChar) {
298  fprintf(spFile, "%s", ucChar == LF ? "\\n" : "\\r");
299  }
300  fprintf(spFile, "\n");
301  }
302  spLine = spLinesNext(spCtx->vpLines);
303  }
304  if (spFile != stdout) {
305  fclose(spFile);
306  }
307 }
308 
319 void vApiInToHtml(void* vpCtx, const char* cpFileName, const char* cpTitle) {
320  if(!bApiValidate(vpCtx)){
321  vExContext();
322  }
323  api* spCtx = (api*) vpCtx;
324  char caBuf[BUF_SIZE];
325  FILE* spFile = NULL;
326  aint uii;
327  line* spLine;
328  uint8_t ucChar;
329  if (!cpFileName) {
330  XTHROW(spCtx->spException, "file name cannot be NULL");
331  }
332  spFile = fopen(cpFileName, "wb");
333  if (!spFile) {
334  snprintf(caBuf, BUF_SIZE, "fopen() failed for file name %s for writing", cpFileName);
335  XTHROW(spCtx->spException, caBuf);
336  }
337  if (!cpTitle) {
338  cpTitle = "SABNF Grammar";
339  }
340  vHtmlHeader(spFile, cpTitle);
341  fprintf(spFile, "%s", "<table>\n");
342  fprintf(spFile, "%s", "<table><tr><th>line<br/>index</th><th>char<br>offset</th><th>line<br/>text</th></tr>\n");
343  spLine = spLinesFirst(spCtx->vpLines);
344  while(spLine){
345  fprintf(spFile, "%s%"PRIuMAX"%s%"PRIuMAX"%s", "<tr><td>", (luint) spLine->uiLineIndex, "</td><td>",
346  (luint) spLine->uiCharIndex, "</td><td>");
347  for (uii = 0; uii < spLine->uiTextLength; uii += 1) {
348  ucChar = (uint8_t) spCtx->cpInput[spLine->uiCharIndex + uii];
349  if (ucChar == TAB) {
350  fprintf(spFile, "%s", "<var>TAB</var>");
351  } else if (ucChar >= 32 && ucChar <= 126) {
352  fprintf(spFile, "%c", ucChar);
353  } else {
354  fprintf(spFile, "%s%02X%s", "<kbd>\\x", ucChar, "</kbd>");
355  }
356  }
357  ucChar = spLine->caLineEnd[0];
358  if (ucChar == 0) {
359  fprintf(spFile, "%s", "<kbd>EOF</kbd>");
360  } else {
361  fprintf(spFile, "%s%s%s", "<var>", ((ucChar == LF) ? "LF" : "CR"), "</var>");
362  ucChar = spLine->caLineEnd[1];
363  if (ucChar) {
364  fprintf(spFile, "%s%s%s", "<var>", ((ucChar == LF) ? "LF" : "CR"), "</var>");
365  }
366  }
367  fprintf(spFile, "%s\n", "</td></tr>");
368  spLine = spLinesNext(spCtx->vpLines);
369  }
370  fprintf(spFile, "%s\n", "</table>");
371  vHtmlFooter(spFile);
372  if (spFile) {
373  fclose(spFile);
374  }
375 }
376 
383 void vLineError(api* spCtx, aint uiCharIndex, const char* cpSrc, const char* cpMsg) {
384  aint uiLine, uiRelIndex;
385  aint uiBufSize = 2014;
386  char cZero = 0;
387  char cLF = 10;
388  char caBuf[uiBufSize];
389  aint ui;
390  char* cpText;
391  char* cpCtrl;
392  uint8_t ucChar;
393  void* vpVecTemp = NULL;
394 
395  // generate the line location information
396  vpVecTemp = spCtx->vpVecTempChars;
397  vVecClear(vpVecTemp);
398  // pop the final null term if any
399  if (bLinesFindLine(spCtx->vpLines, uiCharIndex, &uiLine, &uiRelIndex)) {
400  line* spLine = spLinesFirst(spCtx->vpLines);
401  spLine = &spLine[uiLine];
402 
403  // generate the error message
404  aint uiRelCharIndex = uiCharIndex - spLine->uiCharIndex;
405  snprintf(caBuf, uiBufSize, "%s: line index: %"PRIuMAX": rel char index: %"PRIuMAX": %s",
406  cpSrc, (luint) uiLine, (luint) uiRelCharIndex, cpMsg);
407  vpVecPushn(vpVecTemp, (void*) caBuf, (aint) strlen(caBuf));
408  vpVecPush(vpVecTemp, (void*)&cLF);
409 
410  // generate the line text
411  int n = 0;
412  int len = (int)strlen(cpSrc);
413  for(; n < len; n++){
414  caBuf[n] = ' ';
415  }
416  caBuf[n++] = ':';
417  caBuf[n++] = ' ';
418  caBuf[n] = 0;
419  vpVecPushn(vpVecTemp, (void*) caBuf, (aint) strlen(caBuf));
420  cpText = &spCtx->cpInput[spLine->uiCharIndex];
421  for (ui = 0; ui < spLine->uiLineLength; ui += 1) {
422  ucChar = cpText[ui];
423  if (ucChar >= 32 && ucChar <= 126) {
424  vpVecPush(vpVecTemp, (void*) &ucChar);
425  } else if (ucChar == TAB) {
426  cpCtrl = "\\t";
427  vpVecPushn(vpVecTemp, (void*) cpCtrl, (aint) strlen(cpCtrl));
428  } else if (ucChar == LF) {
429  cpCtrl = "\\n";
430  vpVecPushn(vpVecTemp, (void*) cpCtrl, (aint) strlen(cpCtrl));
431  } else if (ucChar == CR) {
432  cpCtrl = "\\n";
433  vpVecPushn(vpVecTemp, (void*) cpCtrl, (aint) strlen(cpCtrl));
434  } else {
435  sprintf(caBuf, "\\x%02X", ucChar);
436  vpVecPushn(vpVecTemp, (void*) caBuf, (aint) strlen(caBuf));
437  }
438  }
439  vpVecPush(vpVecTemp, (void*) &cZero);
440  } else {
441  snprintf(caBuf, uiBufSize, "%s: char index out of range: %"PRIuMAX": %s",
442  cpSrc, (luint) uiCharIndex, cpMsg);
443  vpVecPushn(vpVecTemp, (void*) caBuf, (aint) (strlen(caBuf) + 1));
444  }
445 
446  // log the line error
447  vMsgsLog(spCtx->vpLog, vpVecFirst(vpVecTemp));
448  vVecClear(vpVecTemp);
449 }
450 
451 static void vPushInvalidChar(api* spCtx, aint uiCharIndex, uint8_t ucChar, const char* cpMsg) {
452  char caBuf[256];
453  // create the error message in a temp buffer
454  snprintf(caBuf, 256, "invalid character: 0x%"PRIXMAX": %s", (luint) ucChar, cpMsg);
455  vLineError(spCtx, uiCharIndex, "validate", caBuf);
456 }
vMsgsLog
void vMsgsLog(void *vpCtx, const char *cpMsg)
Logs a message.
Definition: msglog.c:141
api::ucpPpptEmptyMap
uint8_t * ucpPpptEmptyMap
Common PPPT character map for an operator that is an empty match on the next alphabet character.
Definition: apip.h:169
vApiInValidate
void vApiInValidate(void *vpCtx, abool bStrict)
Scans the input SABNF grammar for invalid characters and line ends.
Definition: input.c:204
api::uiUdtCount
aint uiUdtCount
The number of UDTs referenced in the SABNF grammar.
Definition: apip.h:148
line::uiLineLength
aint uiLineLength
The number of characters in the line, including the line end characters.
Definition: lines.h:43
bApiValidate
abool bApiValidate(void *vpCtx)
Validates an API context pointer.
Definition: api.c:104
api::ucpPpptUndecidedMap
uint8_t * ucpPpptUndecidedMap
Common PPPT character map for an operator that is indeterminate on the next alphabet character.
Definition: apip.h:168
vHtmlHeader
void vHtmlHeader(FILE *spFile, const char *cpTitle)
Prints an HTML header to an open file.
Definition: api.c:565
api::spRules
api_rule * spRules
Points to an array of rule structures.
Definition: apip.h:145
vpLinesCtor
void * vpLinesCtor(exception *spEx, const char *cpInput, aint uiLength)
The lines object constructor.
Definition: lines.c:85
api::cpInput
char * cpInput
Definition: apip.h:139
api::spOpcodes
api_op * spOpcodes
Pointer to the array of opcodes for the SANF grammar.
Definition: apip.h:162
api::vpLog
void * vpLog
A msglog context for error reporting.
Definition: apip.h:179
api::vpOutputParserInit
void * vpOutputParserInit
Storage for variable integer width output parser init data.
Definition: apip.h:132
LF
#define LF
Definition: input.c:43
apip.h
Private header file for the APG API suite of functions.
vExContext
void vExContext()
Handles bad context pointers.
Definition: exception.c:126
api::bInputValid
abool bInputValid
APG_TRUE if theer is input and it has been validated, APG_FALSE otherwise.
Definition: apip.h:182
bLinesFindLine
abool bLinesFindLine(void *vpCtx, aint uiOffset, aint *uipLine, aint *uipRelOffset)
Find the line that the given character is in.
Definition: lines.c:146
BUF_SIZE
#define BUF_SIZE
Definition: input.c:45
api::vpAttrsCtx
void * vpAttrsCtx
context handle to the attributes object
Definition: apip.h:130
api::cpStringTable
char * cpStringTable
Pointer to a list of null-terminated ASCII strings representing the rule and UDT names.
Definition: apip.h:149
XTHROW
#define XTHROW(ctx, msg)
Exception throw macro.
Definition: exception.h:67
vpVecPop
void * vpVecPop(void *vpCtx)
Pops one element from the end of the array.
Definition: vector.c:250
api::spUdts
api_udt * spUdts
Points to an array of UDT structures, if one or more UDTs are referenced in the SABNF grammar.
Definition: apip.h:147
TAB
#define TAB
Definition: input.c:44
api::uiRuleCount
aint uiRuleCount
The number of rules in the SABNF grammar and in the array.
Definition: apip.h:146
vApiInToAscii
void vApiInToAscii(void *vpCtx, const char *cpFileName)
Display the input lines with line numbers and character offsets.
Definition: input.c:261
aint
uint_fast32_t aint
The APG parser's unsigned integer type.
Definition: apg.h:79
api::uipChildIndexTable
aint * uipChildIndexTable
Pointer to a list of child indexes. ALT & CAT operators have two or more children operators....
Definition: apip.h:159
CR
#define CR
Definition: input.c:42
vApiInClear
void vApiInClear(void *vpCtx)
Clears the input and related memory.
Definition: input.c:61
vMsgsClear
void vMsgsClear(void *vpCtx)
Clears the object of all messages.
Definition: msglog.c:124
api::uiChildIndexTableLength
aint uiChildIndexTableLength
The number of indexes (integers) in the child index table.
Definition: apip.h:161
vHtmlFooter
void vHtmlFooter(FILE *spFile)
Prints an HTML footer to an open file.
Definition: api.c:589
uiVecLen
aint uiVecLen(void *vpCtx)
Get the vector length. That is, the number of elements on the vector.
Definition: vector.c:385
api::vpLines
void * vpLines
Context pointer to a lines object.
Definition: apip.h:141
vMemFree
void vMemFree(void *vpCtx, const void *vpData)
Free memory previously allocated with vpMemAlloc().
Definition: memory.c:226
api
The API context.
Definition: apip.h:123
api::luipAcharTable
luint * luipAcharTable
Pointer to the Achar Table - a table of all of the alphabet characters referenced by the terminal nod...
Definition: apip.h:157
luint
uintmax_t luint
luint is used to cast integers suitable for the %"PRIuMAX" printf format.
Definition: apg.h:133
line::uiLineIndex
aint uiLineIndex
The zero-based line index.
Definition: lines.h:41
api::bSyntaxValid
abool bSyntaxValid
APG_TRUE if the input syntax is valid, APG_FALSE otherwise.
Definition: apip.h:183
line::uiTextLength
aint uiTextLength
The number of characters in the line, excluding the line end characters.
Definition: lines.h:44
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
line
Defines the characteristics of a single line.
Definition: lines.h:40
attributes.h
Header file for the attributes functions.
spLinesNext
line * spLinesNext(void *vpCtx)
Returns the next line of text from the iterator.
Definition: lines.c:185
api::vpVecInput
void * vpVecInput
The (ASCII) input grammar files and/or strings accumulate here. Always a NULL-terminated string.
Definition: apip.h:137
api::uiInputLength
aint uiInputLength
The number of input characters.
Definition: apip.h:140
api::vpOutputAcharTable
void * vpOutputAcharTable
Storage for variable character width output parser achar table.
Definition: apip.h:131
api::uiAcharTableLength
aint uiAcharTableLength
Number of alphabet characters in the Achar Table.
Definition: apip.h:158
api::ucpPpptTable
uint8_t * ucpPpptTable
Pointer to the PPPT table of operator maps.
Definition: apip.h:170
APG_TRUE
#define APG_TRUE
Definition: apg.h:291
spLinesFirst
line * spLinesFirst(void *vpCtx)
Initialize an iterator over the lines.
Definition: lines.c:170
api::bAttributesValid
abool bAttributesValid
APG_TRUE if there the rule attributes have been computed and have no fatal errors,...
Definition: apip.h:186
api::vpVecTempChars
void * vpVecTempChars
Temporary vector of characters. Here for clean up on unusual exit.
Definition: apip.h:142
cpApiInFile
const char * cpApiInFile(void *vpCtx, const char *cpFileName)
Reads an SABNF grammar byte stream from a file.
Definition: input.c:117
vLinesDtor
void vLinesDtor(void *vpCtx)
The lines object destructor.
Definition: lines.c:123
vParserDtor
void vParserDtor(void *vpCtx)
Clears the parser component's context and frees all heap memory associated with this parser.
Definition: parser.c:245
api::bUsePppt
abool bUsePppt
True of PPPT are being used.
Definition: apip.h:167
abool
uint8_t abool
abool is the APG bool type.
Definition: apg.h:140
api::vpAltStack
void * vpAltStack
A temporary vector for the AST translator.
Definition: apip.h:128
api::vpParser
void * vpParser
context handle to the SABNF grammar parser object
Definition: apip.h:127
api::vpMem
void * vpMem
Pointer to the memory context used for all memory allocations and exceptions thrown.
Definition: apip.h:126
line::caLineEnd
char caLineEnd[3]
The actual, null-terminated string of line ending character(s), if any.
Definition: lines.h:45
cpApiInString
const char * cpApiInString(void *vpCtx, const char *cpString)
Reads an SABNF grammar byte stream from a string.
Definition: input.c:165
api::spException
exception * spException
Definition: apip.h:125
api::bSemanticsValid
abool bSemanticsValid
APG_TRUE if the the input semantics are valid. That is, the opcodes for the parser have been generate...
Definition: apip.h:184
vApiInToHtml
void vApiInToHtml(void *vpCtx, const char *cpFileName, const char *cpTitle)
Display the input lines with line numbers and character offsets.
Definition: input.c:319
vAttrsDtor
void vAttrsDtor(void *vpCtx)
The API object destructor.
Definition: attributes.c:184
vLineError
void vLineError(api *spCtx, aint uiCharIndex, const char *cpSrc, const char *cpMsg)
Finds the grammar line associated with a character index and formats an error message to the error lo...
Definition: input.c:383
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
line::uiCharIndex
aint uiCharIndex
The zero-based index of the first character of the line.
Definition: lines.h:42
api.h
Public header file for the APG API suite of functions.
APG_FALSE
#define APG_FALSE
Definition: apg.h:292
uiLinesCount
aint uiLinesCount(void *vpCtx)
Returns the number of lines of text.
Definition: lines.c:202
APG Version 7.0 is licensed under the 2-Clause BSD License,
an Open Source Initiative Approved License.