command line argument parsing.

This commit is contained in:
Dale Weiler 2012-04-20 01:20:22 -04:00
parent 857cb72a94
commit 03295d7adc
4 changed files with 93 additions and 25 deletions

View file

@ -45,12 +45,6 @@ static char *const asm_getline(size_t *byte, FILE *fp) {
return line; return line;
} }
#define asm_rmnewline(L,S) *((L)+*(S)-1) = '\0'
#define asm_skipwhite(L) \
while((*(L)==' '||*(L)=='\t')) { \
(L)++; \
}
void asm_init(const char *file, FILE **fp) { void asm_init(const char *file, FILE **fp) {
*fp = fopen(file, "r"); *fp = fopen(file, "r");
code_init(); code_init();

View file

@ -471,4 +471,9 @@ static const struct {
void asm_init (const char *, FILE **); void asm_init (const char *, FILE **);
void asm_close(FILE *); void asm_close(FILE *);
void asm_parse(FILE *); void asm_parse(FILE *);
//======================================================================
//============================= main.c =================================
//======================================================================
extern int opts_debug;
extern int opts_memchk;
#endif #endif

79
main.c
View file

@ -21,18 +21,81 @@
* SOFTWARE. * SOFTWARE.
*/ */
#include "gmqcc.h" #include "gmqcc.h"
// todo CLEANUP this argitem thing
typedef struct { char *name, type; } argitem;
VECTOR_MAKE(argitem, items);
/* global options */
int opts_debug = 0;
int opts_memchk = 0;
static const int usage(const char *const app) {
printf("usage:\n");
printf(" %s -c<file> -- compile file\n" , app);
printf(" %s -a<file> -- assemble file\n", app);
printf(" additional flags:\n");
printf(" -debug -- turns on compiler debug messages\n");
printf(" -memchk -- turns on compiler memory leak check\n");
return -1;
}
int main(int argc, char **argv) { int main(int argc, char **argv) {
argc--; size_t itr = 0;
argv++; char *app = &argv[0][0];
FILE *fpp = NULL;
//const char *ifile = argv[0]; /*
FILE *fp; * Parse all command line arguments. This is rather annoying to do
* because of all tiny corner cases.
*/
if (argc <= 1 || (argv[1][0] != '-'))
return usage(app);
/*TODO: proper interface swith switches*/ while ((argc > 1) && argv[1][0] == '-') {
switch (argv[1][1]) {
case 'c': items_add((argitem){util_strdup(&argv[1][2]), 0}); break; /* compile */
case 'a': items_add((argitem){util_strdup(&argv[1][2]), 1}); break; /* assemble */
default:
if (!strncmp(&argv[1][1], "debug" , 5)) { opts_debug = 1; break; }
if (!strncmp(&argv[1][1], "memchk", 6)) { opts_memchk = 1; break; }
return usage(app);
asm_init ("test.qs", &fp); }
asm_parse(fp); ++argv;
asm_close(fp); --argc;
}
/*
* options could depend on another option, this is where option
* validity checking like that would take place.
*/
if (opts_memchk && !opts_debug)
printf("Warning: cannot enable -memchk, without -debug.\n");
/* multi file multi path compilation system */
for (; itr < items_elements; itr++) {
switch (items_data[itr].type) {
case 0:
fpp = fopen(items_data[itr].name, "r");
struct lex_file *lex = lex_open(fpp);
parse_gen(lex);
lex_close(lex);
break;
case 1:
asm_init (items_data[itr].name, &fpp);
asm_parse(fpp);
asm_close(fpp);
break;
}
}
/* clean list */
for (itr = 0; itr < items_elements; itr++)
mem_d(items_data[itr].name);
mem_d(items_data);
if (opts_memchk)
util_meminfo(); util_meminfo();
return 0; return 0;
} }

6
util.c
View file

@ -61,6 +61,9 @@ void util_memory_d(void *ptrn, unsigned int line, const char *file) {
} }
void util_meminfo() { void util_meminfo() {
if (!opts_memchk)
return;
util_debug("MEM", "Memory information:\n\ util_debug("MEM", "Memory information:\n\
Total allocations: %llu\n\ Total allocations: %llu\n\
Total deallocations: %llu\n\ Total deallocations: %llu\n\
@ -134,6 +137,9 @@ char *util_strrnl(char *src) {
} }
void util_debug(const char *area, const char *ms, ...) { void util_debug(const char *area, const char *ms, ...) {
if (!opts_debug)
return;
va_list va; va_list va;
va_start(va, ms); va_start(va, ms);
fprintf (stdout, "DEBUG: "); fprintf (stdout, "DEBUG: ");