#include #include #include #include #include const char version[] = "FZL Compiler 1.0"; void print_help() { printf("Usage: fzc [flags] \n"); printf("Available flags:\n"); printf("\t-h\t--help\t\tPrint help\n"); printf("\t-v\t--verbose\tDisplay compilation info (tokens, AST, consts " "table, etc)\n"); printf("\t-V\t--version\tPrint compiler version\n"); printf("\t-o\t--out\t\tSet compiled file name\n"); } fzl_options_t *fzl_mkoptions(int argc, char **argv) { fzl_options_t *opts = malloc(sizeof(fzl_options_t)); if (!opts) { printf("%sBruh... Potato PC%s\n", FZL_CERROR, FZL_CRST); return NULL; } memset(opts, 0, sizeof(fzl_options_t)); opts->should_continue = true; if (argc < 2) { print_help(); opts->should_continue = false; return opts; } int i; for (i = 1; i < argc; i++) { if (argv[i][0] != '-') break; if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { print_help(); opts->should_continue = false; break; } else if (strcmp(argv[i], "-V") == 0 || strcmp(argv[i], "--version") == 0) { printf("%s\n", version); opts->should_continue = false; break; } else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0) { opts->verbose = true; } else if (strcmp(argv[i], "-o") == 0 || strcmp(argv[i], "--out") == 0) { if (i == argc - 1) { printf("%sError%s: missing out file name\n", FZL_CERROR, FZL_CRST); free(opts); return NULL; } char *filename = argv[++i]; opts->outname = filename; } else { printf("%sError%s: undefined flag '%s'\n", FZL_CERROR, FZL_CRST, argv[i]); free(opts); return NULL; } } size_t fremainder = 2; size_t fcount = 0; char **files = malloc(fremainder * sizeof(char *)); if (opts->should_continue) { for (; i < argc; i++) { if (argv[i][0] == '-') { printf("%sWarning%s: unhandled flag '%s' (should be defined before " "sources " "list)\n", FZL_CWARNING, FZL_CRST, argv[i]); continue; } if (fremainder <= fcount) { fremainder *= 2; files = realloc(files, fremainder * sizeof(char *)); } files[fcount++] = argv[i]; } } opts->files = files; opts->files_count = fcount; if (i < argc - 1) { printf("%sError%s: flags should go before source files list.\n", FZL_CERROR, FZL_CRST); printf("Remain %d arguments are not handled.\n", argc - 1 - i); free(files); free(opts); return NULL; } return opts; } void fzl_freeoptions(fzl_options_t *options) { if (!options) return; if (options->files) free(options->files); free(options); }