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
13 ----------------------------------------------------------------------------*/
15 #include <stdio.h> //print
16 #include <errno.h> //errors
17 #include <string.h> //strndupa
19 #include <stdlib.h> //exit
20 #include <unistd.h> //getopt, sysconf
21 #include <dirent.h> //opendir
24 #include "parser.tab.h" //bison
28 #define DEFAULT_PAGESIZE 4096
30 const uint8_t* apc_package_name
;
33 int main(int, char*[]);
38 int scanner_init(void);
40 void scanner_quit(void);
42 int scanner_scandir(DIR*);
48 int ir_condenser(void);
53 char* getcwd_basename(void);
55 #define $($)#$ //stringifier
57 #define MAXERR "-%c allows at most " $(MAXSTR) " input characters\n", opt
59 #define USAGE "Usage %s [-d dir_root][-o output_file][-h]\n", argv[0]
62 "\t\t-d\tRoot directory to parse from \t[./]\n" \
63 "\t\t-o\tOutput filename \t\t[a.asspak]\n" \
64 "\t\t-h\tPrint this help\n"
66 #undef eprintf_callback
67 #define free_and_exit(ecode) do { \
71 #define eprintf_callback(...) free_and_exit(EXIT_FAILURE)
72 /* Main entry from terminal
73 parses the command line and kicks off recursive scanning
83 cargs
= (const char**) malloc('Z');
85 switch (opt
= getopt(argc
, argv
, OPTS
))
88 while (*path_iter
++ != '\0');
90 if (*path_iter
== '/')
93 if (strnlen(optarg
, MAXSTR
) != MAXSTR
)
94 { cargs
[opt
] = optarg
;
97 fprintf(stderr
, MAXERR
);
103 free_and_exit(EXIT_SUCCESS
);
107 if ((sys_pagesize
= sysconf(_SC_PAGESIZE
)) == 0)
108 sys_pagesize
= DEFAULT_PAGESIZE
;
111 free_and_exit(EXIT_FAILURE
);
113 scanpath
= cargs
['d'] ? cargs
['d'] : "./";
115 dirp
= opendir(scanpath
);
116 if (dirp
== NULL
|| errno
)
117 eprintf("Path %s could not be accessed: %s\n", scanpath
, strerror(errno
));
119 if (chdir(scanpath
) || errno
)
120 eprintf("Could not change directory to %s: %s\n", scanpath
, strerror(errno
));
121 apc_package_name
= (uint8_t*) getcwd_basename();
122 if (scanner_scandir(dirp
))
123 eprintf(strerror(errno
));
127 free_and_exit(EXIT_SUCCESS
);
131 char* getcwd_basename
133 { char* path_iter
,* path_buf
,* path
;
138 path_buf
= (char*) malloc(MAXSTR
* pages
);
140 getcwd(path_buf
, MAXSTR
* pages
);
151 path
= path_iter
= path_buf
;
152 while (*path_iter
!= '\0')
153 { if (*path_iter
== '/')
154 path
= path_iter
+ 1;