+ if (!opts.pp_only) {
+ if (!parser_init()) {
+ con_err("failed to initialize parser\n");
+ retval = 1;
+ goto cleanup;
+ }
+ }
+
+ if (opts.pp_only || OPTS_FLAG(FTEPP)) {
+ if (!ftepp_init()) {
+ con_err("failed to initialize parser\n");
+ retval = 1;
+ goto cleanup;
+ }
+ }
+
+ if (OPTS_FLAG(TRUE_EMPTY_STRINGS))
+ type_not_instr[TYPE_STRING] = INSTR_NOT_F;
+
+ util_debug("COM", "starting ...\n");
+
+ /* add macros */
+ if (opts.pp_only || OPTS_FLAG(FTEPP)) {
+ for (itr = 0; itr < vec_size(ppems); itr++) {
+ ftepp_add_macro(ppems[itr].name, ppems[itr].value);
+ mem_d(ppems[itr].name);
+
+ /* can be null */
+ if (ppems[itr].value)
+ mem_d(ppems[itr].value);
+ }
+ }
+
+ if (!vec_size(items)) {
+ FILE *src;
+ char *line;
+ size_t linelen = 0;
+
+ progs_src = true;
+
+ src = file_open("progs.src", "rb");
+ if (!src) {
+ con_err("failed to open `progs.src` for reading\n");
+ retval = 1;
+ goto cleanup;
+ }
+
+ line = NULL;
+ if (!progs_nextline(&line, &linelen, src) || !line[0]) {
+ con_err("illformatted progs.src file: expected output filename in first line\n");
+ retval = 1;
+ goto srcdone;
+ }
+
+ if (!opts_output_wasset) {
+ opts.output = util_strdup(line);
+ opts_output_free = true;
+ }
+
+ while (progs_nextline(&line, &linelen, src)) {
+ argitem item;
+ if (!line[0] || (line[0] == '/' && line[1] == '/'))
+ continue;
+ item.filename = util_strdup(line);
+ item.type = TYPE_QC;
+ vec_push(items, item);
+ }
+
+srcdone:
+ file_close(src);
+ mem_d(line);
+ }
+
+ if (retval)
+ goto cleanup;
+
+ if (vec_size(items)) {
+ if (!opts.quiet && !opts.pp_only) {
+ con_out("Mode: %s\n", (progs_src ? "progs.src" : "manual"));
+ con_out("There are %lu items to compile:\n", (unsigned long)vec_size(items));
+ }
+ for (itr = 0; itr < vec_size(items); ++itr) {
+ if (!opts.quiet && !opts.pp_only) {
+ con_out(" item: %s (%s)\n",
+ items[itr].filename,
+ ( (items[itr].type == TYPE_QC ? "qc" :
+ (items[itr].type == TYPE_ASM ? "asm" :
+ (items[itr].type == TYPE_SRC ? "progs.src" :
+ ("unknown"))))));
+ }
+
+ if (opts.pp_only) {
+ const char *out;
+ if (!ftepp_preprocess_file(items[itr].filename)) {
+ retval = 1;
+ goto cleanup;
+ }
+ out = ftepp_get();
+ if (out)
+ file_printf(outfile, "%s", out);
+ ftepp_flush();
+ }
+ else {
+ if (OPTS_FLAG(FTEPP)) {
+ const char *data;
+ if (!ftepp_preprocess_file(items[itr].filename)) {
+ retval = 1;
+ goto cleanup;
+ }
+ data = ftepp_get();
+ if (vec_size(data)) {
+ if (!parser_compile_string(items[itr].filename, data, vec_size(data))) {
+ retval = 1;
+ goto cleanup;
+ }
+ }
+ ftepp_flush();
+ }
+ else {
+ if (!parser_compile_file(items[itr].filename)) {
+ retval = 1;
+ goto cleanup;
+ }
+ }
+ }
+
+ if (progs_src) {
+ mem_d(items[itr].filename);
+ items[itr].filename = NULL;
+ }
+ }
+
+ ftepp_finish();
+ if (!opts.pp_only) {
+ if (!parser_finish(opts.output)) {
+ retval = 1;
+ goto cleanup;
+ }
+ }