be902bd5f2f9a773683417e9b1cf6aafeb36a496
[henge/webcc.git] / src / bin / tools / apc.c
1 /*!@file
2 \brief APC main driver
3 \details The driver assumes the existence of a bison-generated parser,
4 referenced by the external function 'yyparse'.
5 It also assumes the existence of a lexer which must be initialized
6 before parsing, referenced by the external function 'lexer_init'
7 which assumes standard error handling.
8 All input arguments are made available through the exposed (that is,
9 non-static) array of character pointers 'cargs', which point
10 to the non-duplicated strings in 'argv' directly from the system.
11 \author Jordan Lavatai
12 \date Aug 2016
13 ----------------------------------------------------------------------------*/
14 /* Standard */
15 #include <stdio.h> //print
16 #include <errno.h> //errors
17 #include <string.h> //strnlen
18 /* Posix */
19 #include <stdlib.h> //exit
20 #include <unistd.h> //getopt
21 /* Internal */
22 #include <apc/parser.tab.h> //bison
23
24 const char* cargs['Z'] = {0};
25
26 int main(int, char*[]);
27
28 extern //bison
29 int yyparse(void);
30 extern //lexer.c
31 int lexer_init(void);
32
33 extern //apc/parser.tab.c
34 YYSTYPE yylval;
35 extern //lexer.c
36 int lexer(void);
37
38 /* Main entry from terminal
39 parses the command line and kicks off recursive scanning
40 */
41 int main
42 ( int argc,
43 char* argv[]
44 )
45 #define $($)#$ //stringifier
46 #define MAXSTR 255
47 #define MAXERR "-%c allows at most " $(MAXSTR) " input characters\n", opt
48 #define USAGE "Usage %s [-d dir_root][-o output_file][-h]\n", argv[0]
49 #define USAGE_LONG \
50 "\tOptions:\n" \
51 "\t\t-d\tRoot directory to parse from \t[./]\n" \
52 "\t\t-o\tOutput filename \t\t[a.asspak]\n" \
53 "\t\t-h\tPrint this help\n"
54 #define DONE -1
55 { int opt;
56
57 getopt:
58 switch (opt = getopt(argc, argv, "d:o:h-"))
59 { case DONE:
60 break;
61 case 'd' :
62 case 'o' :
63 if (strnlen(optarg, MAXSTR) != MAXSTR)
64 { cargs[opt] = optarg;
65 goto getopt;
66 }
67 fprintf(stderr, MAXERR);
68 default :
69 fprintf(stderr, USAGE);
70 exit(EXIT_FAILURE);
71 case 'h' :
72 printf(USAGE);
73 printf(USAGE_LONG);
74 exit(EXIT_SUCCESS);
75 }
76 if (lexer_init())
77 { perror("lexer");
78 exit(EXIT_FAILURE);
79 }
80 yyparse();
81 exit(EXIT_SUCCESS);
82 }
83