Version 7.0
Copyright © 2021 Lowell D. Thomas
APG
… an ABNF Parser Generator
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 * *************************************************************************************/
37 #include <unistd.h>
38 //#include <limits.h>
39 
40 #include "../api/api.h"
41 #include "./config.h"
42 
43 static const void* s_vpMagicNumber = (void*)"config";
44 static char* s_cpCommandLineError = "COMMAND LINE ERROR: ";
45 
49 typedef struct {
50  const void* vpValidate;
52  void* vpMem;
53  void* vpVecArgs;
54  void* vpVecCwd;
55  void* vpVecOutput;
56  void* vpVecInput;
58  void* vpVecPRules;
60  void* vpVecGrammar;
62  void* vpVecConfigIn;
63  void* vpVecHtmlOut;
65  void* vpVecLfOut;
66  void* vpVecCrLfOut;
81  FILE* spConfigFile;
82 // char caErrorMsg[1024]; /**< \brief error messages are stored here for later display */
83 // jmp_buf aJmpBuf; /**< \brief long jumps are used to recover from errors deep in the collection of the options */
85 } config_ctx;
86 
87 static void vExtractFileOptions(config_ctx* spCtx);
88 static void vExtractArgOptions(config_ctx* spCtx, char* cpParams);
89 static config* spGetConfig(config_ctx* spCtx);
90 static void vGetArgs(config_ctx* spCtx, int iArgCount, char** cppArgs);
91 
97 void* vpConfigCtor(exception* spEx) {
98  if(!bExValidate(spEx)){
99  vExContext();
100  }
101  config_ctx* spCtx = NULL;
102  aint uiSmall = 256;
103  aint uiMedium = 1024;
104  aint uiLarge = 4096;
105  char caCwd[PATH_MAX];
106  aint uiLen;
107  void* vpMem = vpMemCtor(spEx);
108  spCtx = (config_ctx*) vpMemAlloc(vpMem, (aint) sizeof(config_ctx));
109  memset((void*) spCtx, 0, (aint) sizeof(config_ctx));
110  spCtx->vpMem = vpMem;
111  spCtx->spException = spEx;
112 
113  // string of arguments, null-term string of strings
114  spCtx->vpVecArgs = vpVecCtor(vpMem, (aint) sizeof(char), uiSmall);
115 
116  // the current working directory
117  if (getcwd(caCwd, PATH_MAX) == NULL) {
118  XTHROW(spEx, "system error - can't get current working directory");
119  }
120  uiLen = (aint)strlen(caCwd) + 1;
121  spCtx->vpVecCwd = vpVecCtor(vpMem, (aint) sizeof(char), (uiLen + 1));
122 
123  // the output file name
124  spCtx->vpVecOutput = vpVecCtor(vpMem, (aint) sizeof(char), uiSmall);
125 
126  // the input file name(s)
127  spCtx->vpVecInput = vpVecCtor(vpMem, (aint) sizeof(char), uiMedium);
128 
129  // the input file name(s)
130  spCtx->vpVecPRules = vpVecCtor(vpMem, (aint) sizeof(char), uiMedium);
131 
132  // the array of input file name addresses
133  spCtx->vpVecInputAddrs = vpVecCtor(vpMem, (aint) sizeof(char*), uiSmall);
134 
135  // the array of input file name addresses
136  spCtx->vpVecPRulesAddrs = vpVecCtor(vpMem, (aint) sizeof(char*), uiSmall);
137 
138  // the grammar file
139  spCtx->vpVecGrammar = vpVecCtor(vpMem, (aint) sizeof(char), uiLarge);
140 
141  // the file name of the generated default configuration file
142  spCtx->vpVecConfigOut = vpVecCtor(vpMem, (aint) sizeof(char), uiSmall);
143 
144  // the file name of the HTML annotated input grammar
145  spCtx->vpVecHtmlOut = vpVecCtor(vpMem, (aint) sizeof(char), uiSmall);
146 
147  // the file name of the HTML rule/UDT dependencies
148  spCtx->vpVecRulesHtmlOut = vpVecCtor(vpMem, (aint) sizeof(char), uiSmall);
149 
150  // the file name of the configuration file to read
151  spCtx->vpVecConfigIn = vpVecCtor(vpMem, (aint) sizeof(char), uiSmall);
152 
153  // the file name of the LF line ends conversion
154  spCtx->vpVecLfOut = vpVecCtor(vpMem, (aint) sizeof(char), uiSmall);
155 
156  // the file name of the CRLF line ends conversion
157  spCtx->vpVecCrLfOut = vpVecCtor(vpMem, (aint) sizeof(char), uiSmall);
158 
159  // success
160  spCtx->vpValidate = s_vpMagicNumber;
161  return (void*) spCtx;
162 }
163 
171 void vConfigDtor(void* vpCtx) {
172  config_ctx* spCtx = (config_ctx*) vpCtx;
173  if (vpCtx) {
174  if (spCtx->vpValidate == s_vpMagicNumber) {
175  if(spCtx->spConfigFile){
176  fclose(spCtx->spConfigFile);
177  }
178  void* vpMem = spCtx->vpMem;
179  memset(vpCtx, 0, sizeof(*spCtx));
180  vMemDtor(vpMem);
181  }else{
182  vExContext();
183  }
184  }
185 }
186 
194 const config* spConfigOptions(void* vpCtx, int iArgCount, char** cppArgs) {
195  config_ctx* spCtx = (config_ctx*)vpCtx;;
196  vGetArgs(spCtx, iArgCount, cppArgs);
197  if(!(spCtx->bHelp || spCtx->bVersion || vpVecFirst(spCtx->vpVecConfigOut))){
198  if(vpVecFirst(spCtx->vpVecConfigIn)){
199  vExtractFileOptions(spCtx);
200  }
201  }
202 
203  // success
204  return spGetConfig(spCtx);
205 }
206 
210 void vConfigHelp(void){
211  printf("usage: apg options\n");
212  printf("binary options:\n");
213  printf("-i filename : the file name of the input grammar (see note 5.)\n");
214  printf("-o filename : the file name of the generated C-language header and source files (see note 6.)\n");
215  printf("\n");
216  printf("unary options:\n");
217  printf("--input=filename : the file name of the input grammar (see note 5.)\n");
218  printf("--output=filename : the file name of the generated C-language header and source files (see note 6.)\n");
219  printf("-c : generate a default configuration file named \"%s\"\n", CONFIG_FILE);
220  printf("--config-file=fname : generate a default configuration file named \"fname\"\n");
221  printf("--p-rules=name[,name] : comma-delimited list of protected rule names (see note 9.)\n");
222  printf("--grammar-html=fname : display input grammar in HTML format on file \"fname\"\n");
223  printf("--rules-html=fname : display rule/UDT names and dependencies in HTML format on file \"fname\"\n");
224  printf("--lf=filename : converts all input line end to LF(\\n) on file \"filename\" (see note 8.)\n");
225  printf("--crlf=filename : converts all input line end to CRLF(\\r\\n) on file \"filename\" (see note 8.)\n");
226  printf("@ : read the options from the configuration file named \"%s\"\n", CONFIG_FILE);
227  printf("@filename : read the options from the configuration file named \"filename\"\n");
228  printf("\n");
229  printf("flags: true if present, otherwise false\n");
230  printf("? : display this help screen\n");
231  printf("-h : display this help screen\n");
232  printf("--help : display this help screen\n");
233  printf("-v : display version information\n");
234  printf("--version : display version information\n");
235  printf("--strict : only ABNF as strictly defined in RFC 5234 allowed\n");
236  printf("--no-pppt : do not produce Partially-Predictive Parsing Tables (PPPTs)\n");
237  printf("\n");
238  printf("display flags\n");
239  printf("-dv : verbose - sets flags -dc, -dg, dr, -dp and -da\n");
240  printf("-dc : display the complete configuration found on the command line or in the command file\n");
241  printf("-dg : display an annotated version of the input grammar\n");
242  printf("-dr : display the grammar rule names, in the order they are found in the grammar\n");
243  printf("-dra : display the grammar rule names, in alphabetical order\n");
244  printf("-da : display the rule attributes\n");
245  printf("-dp : display the Partially-Predictive Parsing Table (PPPT) sizes\n");
246  printf("-do : display the opcodes in human-readable format (warning: may generate many lines of output)\n");
247  printf("\n");
248  printf("NOTES:\n");
249  printf("1. All options and flags are case sensitive.\n");
250  printf("2. Binary options require one or more spaces between the flag and the name.\n");
251  printf("3. No spaces are allowed in unary options or flags (no space before or after \"=\").\n");
252  printf("4. If any or all of -h, -v or -c (or any of their alternatives) is present all other options are ignored.\n");
253  printf("5. File names may be absolute (/home/user/filname) or relative ([./ | ../]mydir/filename).\n");
254  printf(" Directories in the path name must exist.\n");
255  printf("6. Any file name extension will be stripped and replaced with .h for the header file and .c for the source file.\n");
256  printf("7. Absent -h, -v or -c, if a configuration file is indicated (@ or @filename) all other options are ignored.\n");
257  printf("8. Both --lf and --crlf may be present. If either is present, all other options except -h, -v and -c are ignored.\n");
258  printf("9. Protected rules are protected from being hidden under predictive PPPT-mapped nodes.\n");
259  printf(" Rule names are case insensitive. The argument may be a comma-delimited list with no spaces allowed.\n");
260  printf(" Multiple instances of the --p-rules flag will accumulate rule names in the list.\n");
261  printf("10. No command line arguments generates this help screen.\n");
262  printf("\n");
263 }
264 
266 void vConfigVersion(void){
267  printf(" version: APG Version %s\n", APG_VERSION);
268  printf("copyright: %s\n", APG_COPYRIGHT);
269  printf(" license: %s\n", APG_LICENSE);
270 }
271 
282 void vConfigDefault(void* vpCtx, char* cpFileName) {
283  config_ctx* spCtx = (config_ctx*) vpCtx;
284  if(!vpCtx || (spCtx->vpValidate != s_vpMagicNumber)){
285  vExContext();
286  }
287  FILE* spFile = stdout;
288  if(cpFileName){
289  spFile = fopen(cpFileName, "wb");
290  if(!spFile){
291  char caBuf[128];
292  snprintf(caBuf, 128, "can't open file \"%s\" for writing default configuration file", cpFileName);
293  XTHROW(spCtx->spException, caBuf);
294  }
295  }
296  fprintf(spFile, "# APG CONFIGURATION FILE\n");
297  fprintf(spFile, "#\n");
298  fprintf(spFile, "# Comments begin with \"#\" and continue to end of line\n");
299  fprintf(spFile, "# Blank lines are ignored\n");
300  fprintf(spFile, "# Options must begin on first character of a line and must not contain spaces.\n");
301  fprintf(spFile, "# File names must not contain spaces.\n");
302  fprintf(spFile, "# Trailing white space after an option is stripped.\n");
303  fprintf(spFile, "# APG command-line options, -c, --config-file=filename, @, and @filename are not allowed in configuration files.\n");
304  fprintf(spFile, "# If present they will generate an error.\n");
305  fprintf(spFile, "#\n");
306  fprintf(spFile, "# THE INPUT GRAMMAR\n");
307  fprintf(spFile,
308  "# The --input option is used to specify the input grammar file.\n");
309  fprintf(spFile, "# The file name may be absolute (/home/user/dir) or relative (../backone/dir)\n");
310  fprintf(spFile, "# If multiple --input parameters are specified the named files \n");
311  fprintf(spFile, "# will be concatenated into a single input grammar file in the order presented\n");
312  fprintf(spFile, "#\n");
313  fprintf(spFile, "#--input=grammar.bnf\n");
314  fprintf(spFile, "#\n");
315  fprintf(spFile, "# THE OUTPUT, GENERATED C-LANGUAGE FILES\n");
316  fprintf(spFile, "# This option names names the output files, filename.h & filename.c.\n");
317  fprintf(spFile, "# The extension, if any, will be stripped and \".c\" added for the source file and \".h\" added for the header file\n");
318  fprintf(spFile, "# The file name may be absolute (/home/user/dir) or relative (../backone/dir)\n");
319  fprintf(spFile, "# If no --output option exists, no output is generated.\n");
320  fprintf(spFile, "#\n");
321  fprintf(spFile, "#--output=filename\n");
322  fprintf(spFile, "#\n");
323  fprintf(spFile, "# ANNOTATED GRAMMAR IN HTML\n");
324  fprintf(spFile, "# Output the annotated grammar in HTML format to filename\n");
325  fprintf(spFile, "# (file name should have .html file extension)\n");
326  fprintf(spFile, "#\n");
327  fprintf(spFile, "#--grammar-html=filename\n");
328  fprintf(spFile, "#\n");
329  fprintf(spFile, "# RULE/UDT NAMES AND DEPENDENCIES IN HTML\n");
330  fprintf(spFile, "# Output the rule/UDT names and dependencies in HTML format to filename\n");
331  fprintf(spFile, "# (file name should have .html file extension)\n");
332  fprintf(spFile, "#\n");
333  fprintf(spFile, "#--rules-html=filename\n");
334  fprintf(spFile, "#\n");
335  fprintf(spFile, "# LINE ENDING CONVERSIONS\n");
336  fprintf(spFile, "# Convert the grammar's line endings to LF(linefeed, \n, 0x0A) to filename\n");
337  fprintf(spFile, "#\n");
338  fprintf(spFile, "#--lf=filename\n");
339  fprintf(spFile, "#\n");
340  fprintf(spFile, "# Convert the grammar's line endings to CRLF(carriage return + linefeed, \r\n, 0x0D0A) to filename\n");
341  fprintf(spFile, "#\n");
342  fprintf(spFile, "#--crlf=filename\n");
343  fprintf(spFile, "#\n");
344  fprintf(spFile, "# THE HELP SCREEN\n");
345  fprintf(spFile, "# If present this option will display a usage or help screen and quit.\n");
346  fprintf(spFile, "#\n");
347  fprintf(spFile, "#--help\n");
348  fprintf(spFile, "#\n");
349  fprintf(spFile, "# THE VERSION NUMBER AND COPYRIGHT\n");
350  fprintf(spFile, "# If present this option will display the version number and copyright and quit.\n");
351  fprintf(spFile, "#\n");
352  fprintf(spFile, "#--version\n");
353  fprintf(spFile, "#\n");
354  fprintf(spFile, "# STRICT ABNF\n");
355  fprintf(spFile, "# If the strict flag is set, the input grammar must conform strictly to ABNF as\n");
356  fprintf(spFile, "# defined in RFCs 5234 & 7405.\n");
357  fprintf(spFile, "#\n");
358  fprintf(spFile, "#--strict\n");
359  fprintf(spFile, "#\n");
360  fprintf(spFile, "# IGNORE ATTRIBUTES\n");
361  fprintf(spFile, "# If this flag is set, the input grammar attribute calculation will be skipped.\n");
362  fprintf(spFile, "# The generator will proceed to output a parser whether there are attribute errors are not.\n");
363  fprintf(spFile, "# Proceed at your own risk, or only if you know from previous runs that the attributes are OK.\n");
364  fprintf(spFile, "# NOTE: rule/UDT dependencies will not be available if this option is chosen.\n");
365  fprintf(spFile, "#\n");
366  fprintf(spFile, "#--ignore-attributes\n");
367  fprintf(spFile, "#\n");
368  fprintf(spFile, "# IGNORE PPPT\n");
369  fprintf(spFile, "# If this flag is set, the Partially-Predictive Parsing Tables (PPPTs) calculation will be skipped.\n");
370  fprintf(spFile, "# If set, best to compile parsing applications with the macro APG_NO_PPPT defined.\n");
371  fprintf(spFile, "#\n");
372  fprintf(spFile, "#--no-pppt\n");
373  fprintf(spFile, "#\n");
374  fprintf(spFile, "# PROTECTED RULES\n");
375  fprintf(spFile, "# This option allows for a list of rule names to be protected from being hidden under fully-predictive\n");
376  fprintf(spFile, "# PPPT-mapped nodes in the parse tree. The argument may be a comma-delimited list.\n");
377  fprintf(spFile, "# Multiple instances of the --p-rules option will accumulate rule names to the list.\n");
378  fprintf(spFile, "# Rule names are case insensitive.\n");
379  fprintf(spFile, "#\n");
380  fprintf(spFile, "#--p-rules=rule[,rule[,rule]...]\n");
381  fprintf(spFile, "#\n");
382  fprintf(spFile, "# DISPLAY OPTIONS\n");
383  fprintf(spFile, "# Display option all begin with \"d\"\n");
384  fprintf(spFile, "#\n");
385  fprintf(spFile, "# verbose display, turn on the flags, -dc, -dg, dr, and -da\n");
386  fprintf(spFile, "#-dv\n");
387  fprintf(spFile, "#\n");
388  fprintf(spFile, "# Display the input grammar with line numbers and explicit control characters, \\t, \\n & \\r.\n");
389  fprintf(spFile, "# as ASCII on the stream stdout.\n");
390  fprintf(spFile, "#-dg\n");
391  fprintf(spFile, "#\n");
392  fprintf(spFile, "# Displays the full contents of the final configuration file.\n");
393  fprintf(spFile, "#-dc\n");
394  fprintf(spFile, "#\n");
395  fprintf(spFile, "# Display the input grammar with line numbers and explicit control characters, \\t, \\n & \\r.\n");
396  fprintf(spFile, "# as HTML on the file filename.\n");
397  fprintf(spFile, "#--display-html=filename\n");
398  fprintf(spFile, "#\n");
399  fprintf(spFile, "# Display a list of all of the rules, in the order they are found in the grammar.\n");
400  fprintf(spFile, "#-dr\n");
401  fprintf(spFile, "#\n");
402  fprintf(spFile, "# Display a list of all of the rules, in alphabetical order.\n");
403  fprintf(spFile, "#-dra\n");
404  fprintf(spFile, "#\n");
405  fprintf(spFile, "# Display the rule attributes.\n");
406  fprintf(spFile, "#-da\n");
407  fprintf(spFile, "#\n");
408  fprintf(spFile, "# Display the Partially-Predictive Parsing Table (PPPT) sizes.\n");
409  fprintf(spFile, "#-dp\n");
410  fprintf(spFile, "#\n");
411  fprintf(spFile, "# Display the opcodes for each rule in human-readable form (warning: may generate lots of lines).\n");
412  fprintf(spFile, "#-do\n");
413  fprintf(spFile, "#\n");
414  if(spFile != stdout){
415  fclose(spFile);
416  }
417 }
418 
431 void vConfigDisplay(const config* spConfig, int iArgCount, char** cppArgs){
432  int i = 0;
433  char* cpTrue = "TRUE";
434  char* cpFalse = "FALSE";
435 
436  printf(" THE APG CONFIGURATION:\n");
437  printf(" command line args(%d):", iArgCount);
438  for(; i < iArgCount; i += 1){
439  printf(" %s", cppArgs[i]);
440  }
441  printf("\n");
442  printf(" cwd: %s\n", spConfig->cpCwd);
443  if(spConfig->uiInputFiles == 0){
444  printf(" input file: \"none\"\n");
445  }else if(spConfig->uiInputFiles == 1){
446  printf(" input files: %s\n", spConfig->cppInput[0]);
447  }else{
448  printf(" input files(s):\n");
449  for(i = 0; i < (int)(spConfig->uiInputFiles); i += 1){
450  printf(" %d. %s\n", (i+1), spConfig->cppInput[i]);
451  }
452  }
453  if(spConfig->uiPRules == 0){
454  printf(" protected rule names: \"none\"\n");
455  }else if(spConfig->uiPRules == 1){
456  printf(" protected rule names: %s\n", spConfig->cppPRules[0]);
457  }else{
458  printf(" protected rule names:\n");
459  for(i = 0; i < (int)(spConfig->uiPRules); i += 1){
460  printf(" %d. %s\n", (i+1), spConfig->cppPRules[i]);
461  }
462  }
463  if(spConfig->cpOutput){
464  printf(" output files(s): %s\n", spConfig->cpOutput);
465  }else{
466  printf(" output path name: \"none\"\n");
467  }
468  if(!spConfig->cpLfOut){
469  printf(" LF line ends file: \"none\"\n");
470  }else{
471  printf(" LF line ends file: %s\n", spConfig->cpLfOut);
472  }
473  if(!spConfig->cpCrLfOut){
474  printf(" CRLF line ends file: \"none\"\n");
475  }else{
476  printf(" CRLF line ends file: %s\n", spConfig->cpCrLfOut);
477  }
478  if(!spConfig->cpGrammarHtml){
479  printf(" grammar to html file: \"none\"\n");
480  }else{
481  printf(" grammar to html file: %s\n", spConfig->cpGrammarHtml);
482  }
483  if(!spConfig->cpRulesHtml){
484  printf("rules/UDT to html file: \"none\"\n");
485  }else{
486  printf("rules/UDT to html file: %s\n", spConfig->cpRulesHtml);
487  }
488  if(spConfig->cpDefaultConfig){
489  printf(" create default file: %s\n", spConfig->cpDefaultConfig);
490  }else{
491  printf(" create default file: no\n");
492  }
493  if(spConfig->cpUseConfig){
494  printf("use configuration file: %s\n", spConfig->cpUseConfig);
495  }else{
496  printf("use configuration file: no\n");
497  }
498  printf(" --help: %s\n", (spConfig->bHelp ? cpTrue : cpFalse));
499  printf(" --version: %s\n", (spConfig->bVersion ? cpTrue : cpFalse));
500  printf(" --strict: %s\n", (spConfig->bStrict ? cpTrue : cpFalse));
501  printf(" --no-pppt: %s\n", (spConfig->bNoPppt? cpTrue : cpFalse));
502  printf(" -dv: %s\n", (spConfig->bDv ? cpTrue : cpFalse));
503  printf(" -dc: %s\n", (spConfig->bDc ? cpTrue : cpFalse));
504  printf(" -dg: %s\n", (spConfig->bDg ? cpTrue : cpFalse));
505  printf(" -da: %s\n", (spConfig->bDa ? cpTrue : cpFalse));
506  printf(" -dr: %s\n", (spConfig->bDr ? cpTrue : cpFalse));
507  printf(" -dp: %s\n", (spConfig->bDp ? cpTrue : cpFalse));
508  printf(" -dra: %s\n", (spConfig->bDra ? cpTrue : cpFalse));
509  printf(" -do: %s\n", (spConfig->bDo ? cpTrue : cpFalse));
510 }
511 
512 static void vGetArgs(config_ctx* spCtx, int iArgCount, char** cppArgs){
513  aint uiStrLen;
514  char cZero = 0;
515  int iOption = 0;
516  for (; iOption < iArgCount; iOption += 1) {
517  uiStrLen = (aint) (strlen(cppArgs[iOption]) + 1);
518  vpVecPushn(spCtx->vpVecArgs, cppArgs[iOption], uiStrLen);
519  }
520  vpVecPush(spCtx->vpVecArgs, &cZero);
521  vExtractArgOptions(spCtx, (char*)vpVecFirst(spCtx->vpVecArgs));
522 }
523 static char* s_cpPos = NULL;
524 static char* cpGetFirstName(char* cpBegin, aint* uipLength){
525  s_cpPos = cpBegin;
526  aint uiOffset = 0;
527  while(APG_TRUE){
528  if(*s_cpPos == ','){
529  s_cpPos++;
530  break;
531  }
532  if(*s_cpPos == 0){
533  s_cpPos = NULL;
534  break;
535  }
536  s_cpPos++;
537  uiOffset++;
538  }
539  *uipLength = uiOffset;
540  return cpBegin;
541 }
542 static char* cpGetNextName(aint* uipLength){
543  char* cpReturn = s_cpPos;
544  aint uiOffset = 0;
545  if(s_cpPos){
546  while(APG_TRUE){
547  if(*s_cpPos == ','){
548  s_cpPos++;
549  break;
550  }
551  if(*s_cpPos == 0){
552  s_cpPos = NULL;
553  break;
554  }
555  s_cpPos++;
556  uiOffset++;
557  }
558  }
559  *uipLength = uiOffset;
560  return cpReturn;
561 }
562 static void vExtractArgOptions(config_ctx* spCtx, char* cpParams) {
563  aint uiStrLen;
564  char cZero = 0;
565  int iOption = 1;
566 
567  // skip over the first argument
568  cpParams = (char*)vpVecFirst(spCtx->vpVecArgs);
569  uiStrLen = (aint) (strlen(cpParams) + 1);
570  cpParams += uiStrLen;
571  if (*cpParams == 0) {
572  // no parameters, set help flag
573  spCtx->bHelp = APG_TRUE;
574  return;
575  }
576  while (*cpParams != 0) {
577  uiStrLen = (aint) (strlen(cpParams) + 1);
578  if (strcmp(cpParams, "-i") == 0) {
579  uiStrLen = (aint) (strlen(cpParams) + 1);
580  cpParams += uiStrLen;
581  if (*cpParams == 0) {
582  XTHROW(spCtx->spException, "options error: -i has no following input file name");
583  }
584  uiStrLen = (aint) (strlen(cpParams) + 1);
585  vpVecPushn(spCtx->vpVecInput, cpParams, uiStrLen);
586  cpParams += uiStrLen;
587  spCtx->uiInputFiles++;
588  } else if (strncmp(cpParams, "--input=", 8) == 0) {
589  uiStrLen = (aint) (strlen(&cpParams[8]) + 1);
590  vpVecPushn(spCtx->vpVecInput, &cpParams[8], uiStrLen);
591  spCtx->uiInputFiles++;
592  uiStrLen = (aint) (strlen(cpParams) + 1);
593  cpParams += uiStrLen;
594  } else if (strncmp(cpParams, "--p-rules=", 10) == 0) {
595  char cZero = 0;
596  char* cpName = cpGetFirstName(&cpParams[10], &uiStrLen);
597  vpVecPushn(spCtx->vpVecPRules, cpName, uiStrLen);
598  vpVecPush(spCtx->vpVecPRules, &cZero);
599  spCtx->uiPRules++;
600  while((cpName = cpGetNextName(&uiStrLen))){
601  vpVecPushn(spCtx->vpVecPRules, cpName, uiStrLen);
602  vpVecPush(spCtx->vpVecPRules, &cZero);
603  spCtx->uiPRules++;
604  }
605  uiStrLen = (aint) (strlen(cpParams) + 1);
606  cpParams += uiStrLen;
607  } else if (strcmp(cpParams, "-o") == 0) {
608  uiStrLen = (aint) (strlen(cpParams) + 1);
609  cpParams += uiStrLen;
610  if (*cpParams == 0) {
611  XTHROW(spCtx->spException, "options error: -o has no following output file name");
612  }
613  uiStrLen = (aint) (strlen(cpParams) + 1);
614  vpVecPushn(spCtx->vpVecOutput, cpParams, uiStrLen);
615  cpParams += uiStrLen;
616  } else if (strncmp(cpParams, "--output=", 9) == 0) {
617  uiStrLen = (aint) (strlen(&cpParams[9]) + 1);
618  vpVecPushn(spCtx->vpVecOutput, &cpParams[9], uiStrLen);
619  uiStrLen = (aint) (strlen(cpParams) + 1);
620  cpParams += uiStrLen;
621  } else if (strncmp(cpParams, "--grammar-html=", 15) == 0) {
622  uiStrLen = (aint) (strlen(&cpParams[15]) + 1);
623  vpVecPushn(spCtx->vpVecHtmlOut, &cpParams[15], uiStrLen);
624  uiStrLen = (aint) (strlen(cpParams) + 1);
625  cpParams += uiStrLen;
626  } else if (strncmp(cpParams, "--rules-html=", 13) == 0) {
627  uiStrLen = (aint) (strlen(&cpParams[13]) + 1);
628  vpVecPushn(spCtx->vpVecRulesHtmlOut, &cpParams[13], uiStrLen);
629  uiStrLen = (aint) (strlen(cpParams) + 1);
630  cpParams += uiStrLen;
631  } else if (strncmp(cpParams, "--lf=", 5) == 0) {
632  uiStrLen = (aint) (strlen(&cpParams[5]) + 1);
633  vpVecPushn(spCtx->vpVecLfOut, &cpParams[5], uiStrLen);
634  uiStrLen = (aint) (strlen(cpParams) + 1);
635  cpParams += uiStrLen;
636  } else if (strncmp(cpParams, "--crlf=", 7) == 0) {
637  uiStrLen = (aint) (strlen(&cpParams[7]) + 1);
638  vpVecPushn(spCtx->vpVecCrLfOut, &cpParams[7], uiStrLen);
639  uiStrLen = (aint) (strlen(cpParams) + 1);
640  cpParams += uiStrLen;
641  } else if (strcmp(cpParams, "-c") == 0) {
642  uiStrLen = (aint) (strlen(CONFIG_FILE) + 1);
643  vpVecPushn(spCtx->vpVecConfigOut, CONFIG_FILE, uiStrLen);
644  uiStrLen = (aint) (strlen(cpParams) + 1);
645  cpParams += uiStrLen;
646  } else if (strncmp(cpParams, "--config-file=", 13) == 0) {
647  if (cpParams[13] == '='){
648  uiStrLen = (aint) (strlen(&cpParams[14]) + 1);
649  vpVecPushn(spCtx->vpVecConfigOut, &cpParams[14], uiStrLen);
650  } else {
651  vpVecPushn(spCtx->vpVecConfigOut, CONFIG_FILE, uiStrLen);
652  }
653  uiStrLen = (aint) (strlen(cpParams) + 1);
654  cpParams += uiStrLen;
655  } else if (cpParams[0] == '@') {
656  if (cpParams[1] == 0) {
657  uiStrLen = (aint) (strlen(CONFIG_FILE) + 1);
658  vpVecPushn(spCtx->vpVecConfigIn, CONFIG_FILE, uiStrLen);
659  } else {
660  uiStrLen = (aint) (strlen(&cpParams[1]) + 1);
661  vpVecPushn(spCtx->vpVecConfigIn, &cpParams[1], uiStrLen);
662  }
663  uiStrLen = (aint) (strlen(cpParams) + 1);
664  cpParams += uiStrLen;
665  } else if (strcmp(cpParams, "-v") == 0) {
666  spCtx->bVersion = APG_TRUE;
667  uiStrLen = (aint) (strlen(cpParams) + 1);
668  cpParams += uiStrLen;
669  } else if (strcmp(cpParams, "--version") == 0) {
670  spCtx->bVersion = APG_TRUE;
671  uiStrLen = (aint) (strlen(cpParams) + 1);
672  cpParams += uiStrLen;
673  } else if (strcmp(cpParams, "?") == 0) {
674  spCtx->bHelp = APG_TRUE;
675  uiStrLen = (aint) (strlen(cpParams) + 1);
676  cpParams += uiStrLen;
677  } else if (strcmp(cpParams, "-h") == 0) {
678  spCtx->bHelp = APG_TRUE;
679  uiStrLen = (aint) (strlen(cpParams) + 1);
680  cpParams += uiStrLen;
681  } else if (strcmp(cpParams, "--help") == 0) {
682  spCtx->bHelp = APG_TRUE;
683  uiStrLen = (aint) (strlen(cpParams) + 1);
684  cpParams += uiStrLen;
685  } else if (strcmp(cpParams, "-s") == 0) {
686  spCtx->bStrict = APG_TRUE;
687  uiStrLen = (aint) (strlen(cpParams) + 1);
688  cpParams += uiStrLen;
689  } else if (strcmp(cpParams, "--strict") == 0) {
690  spCtx->bStrict = APG_TRUE;
691  uiStrLen = (aint) (strlen(cpParams) + 1);
692  cpParams += uiStrLen;
693  } else if (strcmp(cpParams, "--no-pppt") == 0) {
694  spCtx->bNoPppt = APG_TRUE;
695  uiStrLen = (aint) (strlen(cpParams) + 1);
696  cpParams += uiStrLen;
697  } else if (strcmp(cpParams, "-dra") == 0) {
698  spCtx->bDra = APG_TRUE;
699  uiStrLen = (aint) (strlen(cpParams) + 1);
700  cpParams += uiStrLen;
701  } else if (strcmp(cpParams, "-dr") == 0) {
702  spCtx->bDr = APG_TRUE;
703  uiStrLen = (aint) (strlen(cpParams) + 1);
704  cpParams += uiStrLen;
705  } else if (strcmp(cpParams, "-dg") == 0) {
706  spCtx->bDg = APG_TRUE;
707  uiStrLen = (aint) (strlen(cpParams) + 1);
708  cpParams += uiStrLen;
709  } else if (strcmp(cpParams, "-da") == 0) {
710  spCtx->bDa = APG_TRUE;
711  uiStrLen = (aint) (strlen(cpParams) + 1);
712  cpParams += uiStrLen;
713  } else if (strcmp(cpParams, "-dc") == 0) {
714  spCtx->bDc = APG_TRUE;
715  uiStrLen = (aint) (strlen(cpParams) + 1);
716  cpParams += uiStrLen;
717  } else if (strcmp(cpParams, "-do") == 0) {
718  spCtx->bDo = APG_TRUE;
719  uiStrLen = (aint) (strlen(cpParams) + 1);
720  cpParams += uiStrLen;
721  } else if (strcmp(cpParams, "-dp") == 0) {
722  spCtx->bDp = APG_TRUE;
723  uiStrLen = (aint) (strlen(cpParams) + 1);
724  cpParams += uiStrLen;
725  } else if (strcmp(cpParams, "-dv") == 0) {
726  spCtx->bDv = APG_TRUE;
727  uiStrLen = (aint) (strlen(cpParams) + 1);
728  cpParams += uiStrLen;
729  } else {
730  printf("unrecognized option[%d]: %s\n", iOption, cpParams);
731  spCtx->bHelp = APG_TRUE;
732  uiStrLen = (aint) (strlen(cpParams) + 1);
733  cpParams += uiStrLen;
734  }
735  iOption++;
736  }
737  // push the final null-term on the string of input file names
738  vpVecPush(spCtx->vpVecInput, &cZero);
739 
740  // get the current working directory
741  char cwd[PATH_MAX];
742  if (getcwd(cwd, sizeof(cwd)) != NULL) {
743  vpVecPushn(spCtx->vpVecCwd, cwd, (aint)(strlen(cwd) + 1));
744  } else {
745  XTHROW(spCtx->spException, "getcwd() failed\n");
746  }
747 
748  if(spCtx->bDv){
749  spCtx->bDg = APG_TRUE;
750  spCtx->bDr = APG_TRUE;
751  spCtx->bDc = APG_TRUE;
752  spCtx->bDp = APG_TRUE;
753  spCtx->bDa = APG_TRUE;
754  }
755 }
756 
757 static void vExtractFileOptions(config_ctx* spCtx){
758  void* vpVec = spCtx->vpVecArgs;
759  char cZero = 0;
760  char c;
761  int iChar;
762  aint uiNewLine = 1;
763  aint uiLineEnd = 2;
764  aint uiComment = 3;
765  aint uiOption = 4;
766  aint uiState = uiNewLine;
767  char* cpIn;
768  char* cpHelp = "--help";
769  char* cpOption;
770  aint uiSize;
771  aint uiOptionCount;
772  char* cpFirst = "args from configuration file";
773  char cHyphen = 45;
774  char cLF = 10;
775  char cCR = 13;
776  char cLB = 35;
777  char cSP = 32;
778  char cTAB = 9;
779  char caBuf[128];
780 
781  vVecClear(vpVec);
782  cpIn = (char*)vpVecFirst(spCtx->vpVecConfigIn);
783  if(!cpIn){
784  snprintf(caBuf, 128, "%s\nno input configuration file name", s_cpCommandLineError);
785  XTHROW(spCtx->spException, caBuf);
786  }
787  spCtx->spConfigFile = fopen(cpIn, "rb");
788  if(!spCtx->spConfigFile){
789  snprintf(caBuf, 128, "%s\nunable to open configuration file: %s", s_cpCommandLineError, cpIn);
790  XTHROW(spCtx->spException, caBuf);
791  }
792  uiSize = (aint) (strlen(cpFirst) + 1);
793  vpVecPushn(vpVec, (void*)cpFirst, uiSize);
794  while((iChar = fgetc(spCtx->spConfigFile)) != EOF){
795  c = (char)iChar;
796  if(uiState == uiOption){
797  if(c == cLB || c == cSP || c == cTAB || c == cLF || c == cCR){
798  vpVecPush(vpVec, &cZero);
799  if(c == cLF || c == cCR){
800  uiState = uiLineEnd;
801  }else{
802  uiState = uiComment;
803  }
804  }else{
805  vpVecPush(vpVec, &c);
806  }
807  }else if(uiState == uiComment){
808  if(c == cLF || c == cCR){
809  uiState = uiLineEnd;
810  }
811  }else if( uiState == uiNewLine){
812  if(c == cHyphen){
813  uiState = uiOption;
814  vpVecPush(vpVec, &c);
815  }else if(c == cLF || c == cCR){
816  uiState = uiLineEnd;
817  }else{
818  uiState = uiComment;
819  }
820  }else if(uiState == uiLineEnd){
821  if(!(c == cLF || c == cCR)){
822  uiState = uiNewLine;
823  if(c == cHyphen){
824  uiState = uiOption;
825  vpVecPush(vpVec, &c);
826  }else{
827  uiState = uiComment;
828  }
829  }
830  }
831  }
832  fclose(spCtx->spConfigFile);
833  spCtx->spConfigFile = NULL;
834  vpVecPush(vpVec, &cZero);
835 
836  // validate the options
837  cpOption = (char*)vpVecFirst(vpVec);
838  cpOption += (aint)(strlen(cpOption) + 1);
839  uiOptionCount = 0;
840  while(cpOption[0] != 0){
841  while(APG_TRUE){
842  if(strncmp(cpOption, "--output", 8) == 0){
843  break;
844  }
845  if(strncmp(cpOption, "--input", 7) == 0){
846  break;
847  }
848  if(strncmp(cpOption, "--p-rules", 7) == 0){
849  break;
850  }
851  if(strncmp(cpOption, "--grammar-html", 14) == 0){
852  break;
853  }
854  if(strncmp(cpOption, "--rules-html", 12) == 0){
855  break;
856  }
857  if(strncmp(cpOption, "--lf", 4) == 0){
858  break;
859  }
860  if(strncmp(cpOption, "--crlf", 4) == 0){
861  break;
862  }
863  if(strcmp(cpOption, "--help") == 0){
864  break;
865  }
866  if(strcmp(cpOption, "--version") == 0){
867  break;
868  }
869  if(strcmp(cpOption, "--strict") == 0){
870  break;
871  }
872  if(strcmp(cpOption, "--ignore-attributes") == 0){
873  break;
874  }
875  if(strcmp(cpOption, "--no-pppt") == 0){
876  break;
877  }
878  if(strcmp(cpOption, "-dc") == 0){
879  break;
880  }
881  if(strcmp(cpOption, "-dv") == 0){
882  break;
883  }
884  if(strcmp(cpOption, "-do") == 0){
885  break;
886  }
887  if(strcmp(cpOption, "-dp") == 0){
888  break;
889  }
890  if(strcmp(cpOption, "-dr") == 0){
891  break;
892  }
893  if(strcmp(cpOption, "-dra") == 0){
894  break;
895  }
896  if(strcmp(cpOption, "-dg") == 0){
897  break;
898  }
899  if(strcmp(cpOption, "-da") == 0){
900  break;
901  }
902  snprintf(caBuf, 128,
903  "%s\noption unrecognized or not allowed in configuration file: %s", s_cpCommandLineError, cpOption);
904  XTHROW(spCtx->spException, caBuf);
905  }
906  cpOption += (aint)(strlen(cpOption) + 1);
907  uiOptionCount++;
908  }
909  if(!uiOptionCount){
910  vpVecPushn(vpVec, cpHelp, (aint)(strlen(cpHelp) + 1));
911  }
912 
913  // put options in config_ctx
914  vVecClear(spCtx->vpVecOutput);
915  vVecClear(spCtx->vpVecInput);
916  vVecClear(spCtx->vpVecGrammar);
917  vVecClear(spCtx->vpVecConfigOut);
918  vExtractArgOptions(spCtx, (char*)vpVecFirst(vpVec));
919 }
920 
921 static config* spGetConfig(config_ctx* spCtx){
922  config* spConfig = &spCtx->sConfig;
923  spConfig->uiInputFiles = spCtx->uiInputFiles;
924  spConfig->uiPRules = spCtx->uiPRules;
925  spConfig->bHelp = spCtx->bHelp;
926  spConfig->bVersion = spCtx->bVersion;
927  spConfig->bStrict = spCtx->bStrict;
928  spConfig->bNoPppt = spCtx->bNoPppt;
929  spConfig->bDc = spCtx->bDc;
930  spConfig->bDv = spCtx->bDv;
931  spConfig->bDo = spCtx->bDo;
932  spConfig->bDp = spCtx->bDp;
933  spConfig->bDr = spCtx->bDr;
934  spConfig->bDa = spCtx->bDa;
935  spConfig->bDra = spCtx->bDra;
936  spConfig->bDg = spCtx->bDg;
937  spConfig->cpCwd = (char*)vpVecFirst(spCtx->vpVecCwd);
938  spConfig->cpDefaultConfig = (char*)vpVecFirst(spCtx->vpVecConfigOut);
939  spConfig->cpGrammarHtml= (char*)vpVecFirst(spCtx->vpVecHtmlOut);
940  spConfig->cpRulesHtml= (char*)vpVecFirst(spCtx->vpVecRulesHtmlOut);
941  spConfig->cpUseConfig = (char*)vpVecFirst(spCtx->vpVecConfigIn);
942  spConfig->cpOutput = (char*)vpVecFirst(spCtx->vpVecOutput);
943  spConfig->cpLfOut = (char*)vpVecFirst(spCtx->vpVecLfOut);
944  spConfig->cpCrLfOut = (char*)vpVecFirst(spCtx->vpVecCrLfOut);
945  vVecClear(spCtx->vpVecInputAddrs);
946  vVecClear(spCtx->vpVecPRulesAddrs);
947  aint ui = 0;
948  char* cpName = (char*)vpVecFirst(spCtx->vpVecInput);
949  for(; ui < spCtx->uiInputFiles; ui += 1){
950  vpVecPush(spCtx->vpVecInputAddrs, (void*)&cpName);
951  cpName += strlen(cpName) + 1;
952  }
953  spConfig->cppInput = (char**)vpVecFirst(spCtx->vpVecInputAddrs);
954  cpName = (char*)vpVecFirst(spCtx->vpVecPRules);
955  for(ui = 0; ui < spCtx->uiPRules; ui += 1){
956  vpVecPush(spCtx->vpVecPRulesAddrs, (void*)&cpName);
957  cpName += strlen(cpName) + 1;
958  }
959  spConfig->cppPRules = (char**)vpVecFirst(spCtx->vpVecPRulesAddrs);
960  return spConfig;
961 }
config::cpRulesHtml
char * cpRulesHtml
if non-null, the file name for the HTML version of the rule/UDT names and dependencies
Definition: config.h:112
vConfigDefault
void vConfigDefault(void *vpCtx, char *cpFileName)
Prints a default configuration file.
Definition: config.c:282
config_ctx::vpValidate
const void * vpValidate
a "magic number" to validate the context
Definition: config.c:50
config_ctx::vpVecPRulesAddrs
void * vpVecPRulesAddrs
addresses of the rule names
Definition: config.c:59
config_ctx::vpVecInputAddrs
void * vpVecInputAddrs
addresses of the input file name, can be used for "char** argv" type access to file names
Definition: config.c:57
config::cppInput
char ** cppInput
array of uiInputFiles input file names
Definition: config.h:115
config::uiPRules
aint uiPRules
the number of protected rule names found
Definition: config.h:118
vMemDtor
void vMemDtor(void *vpCtx)
Destroys a Memory component. Frees all memory allocated.
Definition: memory.c:141
config::bDo
abool bDo
display the opcodes for each rule in human-readable form
Definition: config.h:129
config::bDv
abool bDv
verobose - sets options -dc, -dg, -dr, and -da
Definition: config.h:123
config::cpDefaultConfig
char * cpDefaultConfig
if non-n=NULL, generate a default configuration file using this file name
Definition: config.h:108
config::uiInputFiles
aint uiInputFiles
the number of input files found
Definition: config.h:116
config_ctx::bNoPppt
abool bNoPppt
if set, skip the PPPT calculation
Definition: config.c:72
config_ctx::vpVecArgs
void * vpVecArgs
command line or configuration file options as a null-terminated string of strings
Definition: config.c:53
config
This data controls the flow of the main program of the APG parser generator.
Definition: config.h:106
config::bHelp
abool bHelp
the help flag, if set the help screen is printed and processing stops
Definition: config.h:119
config_ctx::vpMem
void * vpMem
memory component context handle
Definition: config.c:52
config_ctx::vpVecPRules
void * vpVecPRules
one or more protected rule names as a null-terminated string of strings
Definition: config.c:58
config::bDp
abool bDp
display the PPPT size
Definition: config.h:130
config_ctx::vpVecCwd
void * vpVecCwd
the current working directory, the directory "main" is being run in
Definition: config.c:54
vExContext
void vExContext()
Handles bad context pointers.
Definition: exception.c:126
config::bNoPppt
abool bNoPppt
if set, Partially-Predictive Parsing Tables (PPPTs) will not be produced
Definition: config.h:122
vConfigHelp
void vConfigHelp(void)
Prints the help screen when requested or if there is a command line options error.
Definition: config.c:210
config::cpCwd
char * cpCwd
the current working directory
Definition: config.h:107
spConfigOptions
const config * spConfigOptions(void *vpCtx, int iArgCount, char **cppArgs)
Reads the command line arguments and parses them into a configuration structure.
Definition: config.c:194
config_ctx::spConfigFile
FILE * spConfigFile
Open file handle for reading a configuration file. NULL if not open.
Definition: config.c:81
config_ctx::vpVecCrLfOut
void * vpVecCrLfOut
if non-empty string, put CRLF translated line ends on file name
Definition: config.c:66
config_ctx::vpVecHtmlOut
void * vpVecHtmlOut
if non-empty string, put HTML version of annotated input grammar on file name
Definition: config.c:63
config_ctx::bStrict
abool bStrict
if set, the grammar is treated as strict ABNF
Definition: config.c:71
XTHROW
#define XTHROW(ctx, msg)
Exception throw macro.
Definition: exception.h:67
config::bDc
abool bDc
display the complete configuration as found on command line or configuration file
Definition: config.h:124
config_ctx::bHelp
abool bHelp
the help flag, if set the help screen is printed and processing stops
Definition: config.c:69
config_ctx::vpVecGrammar
void * vpVecGrammar
the input grammar, a concatenation of all input files
Definition: config.c:60
config::bStrict
abool bStrict
if set, the grammar is treated as strict ABNF
Definition: config.h:121
APG_LICENSE
#define APG_LICENSE
Definition: apg.h:67
aint
uint_fast32_t aint
The APG parser's unsigned integer type.
Definition: apg.h:79
config_ctx::bDo
abool bDo
display human-readable opcodes
Definition: config.c:77
config_ctx::vpVecInput
void * vpVecInput
one or more input file names as a null-terminated string of strings
Definition: config.c:56
config_ctx::vpVecOutput
void * vpVecOutput
if non-empty string, the output file name, the name.h and name.c files will be the generated files
Definition: config.c:55
config::cpLfOut
char * cpLfOut
if non-null, the file name for the converted LF line ends file
Definition: config.h:113
vpMemAlloc
void * vpMemAlloc(void *vpCtx, aint uiBytes)
Allocates memory.
Definition: memory.c:196
APG_COPYRIGHT
#define APG_COPYRIGHT
Definition: apg.h:66
vConfigVersion
void vConfigVersion(void)
Display the version number.
Definition: config.c:266
config::cpGrammarHtml
char * cpGrammarHtml
if non-null, the file name for the HTML version of the annotated input grammar
Definition: config.h:111
vpVecCtor
void * vpVecCtor(void *vpMem, aint uiElementSize, aint uiInitialAlloc)
The vector object constructor.
Definition: vector.c:118
config::bDra
abool bDra
display the grammar rule/UDT names alphabetically
Definition: config.h:128
config_ctx::sConfig
config sConfig
the form of the options presented to the user
Definition: config.c:84
exception
A structure to describe the type and location of a caught exception.
Definition: exception.h:47
config::bDg
abool bDg
display an annotated version of the input grammar
Definition: config.h:125
config_ctx::bDra
abool bDra
display the grammar rule/UDT names alphabetically
Definition: config.c:80
config::cpCrLfOut
char * cpCrLfOut
if non-null, the file name for the converted CRLF line ends file
Definition: config.h:114
APG_VERSION
#define APG_VERSION
Definition: apg.h:65
config_ctx::bDa
abool bDa
display the rule attributes
Definition: config.c:76
config_ctx::vpVecConfigOut
void * vpVecConfigOut
if non-empty string, generate a default configuration file here
Definition: config.c:61
bExValidate
abool bExValidate(exception *spException)
Test an exception structure for validity.
Definition: exception.c:70
config_ctx
The configuration component context.
Definition: config.c:49
config_ctx::bDc
abool bDc
display the complete configuration as found on command line or configuration file
Definition: config.c:73
vpVecFirst
void * vpVecFirst(void *vpCtx)
Get the first element one the vector. The vector is not altered.
Definition: vector.c:326
config::cppPRules
char ** cppPRules
array of protected rule names
Definition: config.h:117
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
config_ctx::bDg
abool bDg
display an annotated version of the input grammar
Definition: config.c:75
config::cpUseConfig
char * cpUseConfig
if non-n=NULL, use this configuration file instead of command line arguments
Definition: config.h:109
config_ctx::uiPRules
aint uiPRules
the number of protected rule names found
Definition: config.c:68
vConfigDisplay
void vConfigDisplay(const config *spConfig, int iArgCount, char **cppArgs)
Displays the full configuration as determined from the command line or command file arguments.
Definition: config.c:431
config::bDr
abool bDr
display grammar rule/UDT names in the order they occur in the grammar
Definition: config.h:127
config_ctx::uiInputFiles
aint uiInputFiles
the number of input files found
Definition: config.c:67
APG_TRUE
#define APG_TRUE
Definition: apg.h:291
config::bVersion
abool bVersion
the version flag, if set the version number is printed and processing stops
Definition: config.h:120
config_ctx::bDp
abool bDp
display PPPT sizes
Definition: config.c:78
config_ctx::spException
exception * spException
Definition: config.c:51
abool
uint8_t abool
abool is the APG bool type.
Definition: apg.h:140
config.h
The configuration object header file.
config_ctx::bDv
abool bDv
verbose display of information during processing - sets uiDg, uiDa, uiDr and uiDc
Definition: config.c:74
vConfigDtor
void vConfigDtor(void *vpCtx)
The configuration destructor.
Definition: config.c:171
config_ctx::bDr
abool bDr
display grammar rule/UDT names in the order they occur in the grammar
Definition: config.c:79
config_ctx::vpVecRulesHtmlOut
void * vpVecRulesHtmlOut
if non-empty string, put HTML version of rule/UDT dependencies on file name
Definition: config.c:64
config::cpOutput
char * cpOutput
the path name for the generated C source & header files
Definition: config.h:110
config::bDa
abool bDa
display grammar attributes
Definition: config.h:126
CONFIG_FILE
#define CONFIG_FILE
The default file name for generated configuration files.
Definition: config.h:99
config_ctx::bVersion
abool bVersion
the version flag, if set the version number is printed and processing stops
Definition: config.c:70
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
config_ctx::vpVecLfOut
void * vpVecLfOut
if non-empty string, put LF translated line ends on file name
Definition: config.c:65
vpConfigCtor
void * vpConfigCtor(exception *spEx)
Constructs a configuration object to hold all data relating to this instance of the configuration.
Definition: config.c:97
config_ctx::vpVecConfigIn
void * vpVecConfigIn
if non-empty string, read the configuration from this file name
Definition: config.c:62
APG Version 7.0 is licensed under the 2-Clause BSD License,
an Open Source Initiative Approved License.