// ----------------------------------------------------------------------- void st_drop(struct st *stx) { if (!stx) return; free(stx->str); free(stx->data); free(stx->loc_file); st_drop(stx->next); st_drop(stx->args); free(stx); }
// ----------------------------------------------------------------------- int main(int argc, char **argv) { int ret = 1; int res; FILE *outf; res = parse_args(argc, argv); if (res) { printf("\n"); usage(); goto cleanup; } if (kw_init() < 0) { printf("Internal dictionary initialization failed.\n"); goto cleanup; } sym = dh_create(16000, 1); if (!sym) { printf("Failed to create symbol table.\n"); goto cleanup; } if (input_file) { yyin = fopen(input_file, "r"); loc_push(input_file); } else { yyin = stdin; loc_push("(stdin)"); } if (!yyin) { printf("Cannot open source file: '%s'\n", input_file); goto cleanup; } inc_path_add("."); AADEBUG("==== Parse ================================"); if (yyparse()) { if (yyin) fclose(yyin); goto cleanup; } if (yyin) fclose(yyin); if (!program) { // shouldn't happen - parser should always produce program (even empty one) printf("Parse produced empty tree.\n"); goto cleanup; } res = assemble(program, 1); if (res < 0) { printf("%s\n", aerr); goto cleanup; } else if (res > 0) { if (otype == O_EMELF) { if (assemble(program, 1) < 0) { printf("%s\n", aerr); goto cleanup; } } else { if (assemble(program, 0)) { printf("%s\n", aerr); goto cleanup; } } } if (otype != O_DEBUG) { if (!output_file) { output_file = strdup("a.out"); } outf = fopen(output_file, "w"); } else { if (!output_file) { output_file = strdup("(stdout)"); } outf = stdout; } if (!outf) { printf("Cannot open output file '%s' for writing\n", output_file); goto cleanup; } switch (otype) { case O_RAW: res = writer_raw(program, outf); break; case O_DEBUG: res = writer_debug(program, outf); break; case O_EMELF: res = writer_emelf(program, sym, outf); break; default: printf("Unknown output type.\n"); fclose(outf); goto cleanup; } fclose(outf); if (res) { printf("%s\n", aerr); goto cleanup; } ret = 0; cleanup: yylex_destroy(); st_drop(inc_paths); st_drop(filenames); st_drop(program); dh_destroy(sym); st_drop(entry); kw_destroy(); free(output_file); return ret; }