e49d03b05c8aa0e4eab4b68ff7ad6d0c16038549
[henge/apc.git] / src / 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> //strndupa
18 /* Posix */
19 #include <stdlib.h> //exit
20 #include <unistd.h> //getopt, sysconf
21 /* Internal */
22 #include "parser.tab.h" //bison
23
24 #define DEFAULT_PAGESIZE 4096
25 const char* cargs['Z'] = {0};
26 long sys_pagesize;
27
28 int main(int, char*[]);
29
30 extern //lexer.c
31 int lexer_init(void);
32 extern //scanner.c
33 int scanner_init(void);
34 extern //scanner.c
35 void scanner_quit(void);
36 extern //scanner.c
37 int scanner_scanpath(char const*);
38 extern //ir.c
39 int ir_init(void);
40 extern //ir.c
41 int ir_linker(void);
42 extern //ir.c
43 int ir_condenser(void);
44
45 /* Main entry from terminal
46 parses the command line and kicks off recursive scanning
47 */
48 int main
49 ( int argc,
50 char* argv[]
51 )
52 #define $($)#$ //stringifier
53 #define MAXSTR 255
54 #define MAXERR "-%c allows at most " $(MAXSTR) " input characters\n", opt
55 #define OPTS "d:o:h-"
56 #define USAGE "Usage %s [-d dir_root][-o output_file][-h]\n", argv[0]
57 #define USAGE_LONG \
58 "\tOptions:\n" \
59 "\t\t-d\tRoot directory to parse from \t[./]\n" \
60 "\t\t-o\tOutput filename \t\t[a.asspak]\n" \
61 "\t\t-h\tPrint this help\n"
62 #define DONE -1
63 #define SCANPATH (cargs['d'] ? cargs['d'] : "./")
64 { int opt;
65
66 getopt:
67 switch (opt = getopt(argc, argv, OPTS))
68 { case 'd' :
69 case 'o' :
70 if (strnlen(optarg, MAXSTR) != MAXSTR)
71 { cargs[opt] = optarg;
72 goto getopt;
73 }
74 fprintf(stderr, MAXERR);
75 default :
76 fprintf(stderr, USAGE);
77 exit(EXIT_FAILURE);
78 case 'h' :
79 printf(USAGE);
80 printf(USAGE_LONG);
81 exit(EXIT_SUCCESS);
82 case DONE:
83 break;
84 }
85 if ((sys_pagesize = sysconf(_SC_PAGESIZE)) == 0)
86 sys_pagesize = DEFAULT_PAGESIZE;
87
88 if (scanner_init() || ir_init())
89 { perror("init");
90 exit(EXIT_FAILURE);
91 }
92 if (scanner_scanpath(SCANPATH))
93 { perror("scanner");
94 exit(EXIT_FAILURE);
95 }
96 scanner_quit();
97 ir_linker();
98 ir_condenser();
99 exit(EXIT_SUCCESS);
100 }
101