add bunch of testapps
[cparser] / main.c
diff --git a/main.c b/main.c
index 2794b90..9615f2a 100644 (file)
--- a/main.c
+++ b/main.c
@@ -105,7 +105,7 @@ bool strict_mode = false;
 /* to switch on printing of implicit casts */
 extern bool print_implicit_casts;
 
-/* to switch on printing of  srenthesis to indicate operator precedence */
+/* to switch on printing of parenthesis to indicate operator precedence */
 extern bool print_parenthesis;
 
 static int            verbose;
@@ -166,9 +166,9 @@ static void get_output_name(char *buf, size_t buflen, const char *inputname,
        memcpy(buf+last_dot, newext, extlen);
 }
 
-static translation_unit_t *do_parsing(FILE *const in, const char *const input)
+static translation_unit_t *do_parsing(FILE *const in, const char *const input_name)
 {
-       lexer_open_stream(in, input);
+       lexer_open_stream(in, input_name);
        translation_unit_t *unit = parse();
        return unit;
 }
@@ -184,7 +184,7 @@ static void lextest(FILE *in, const char *fname)
        } while(lexer_token.type != T_EOF);
 }
 
-static FILE* preprocess(FILE* in, const char *fname)
+static FILE *preprocess(FILE *in, const char *fname)
 {
        char buf[4096];
        obstack_1grow(&cppflags_obst, '\0');
@@ -200,8 +200,8 @@ static FILE* preprocess(FILE* in, const char *fname)
        if(verbose) {
                puts(buf);
        }
-       FILEf = popen(buf, "r");
-       if (f == NULL) {
+       FILE *f = popen(buf, "r");
+       if(f == NULL) {
                fprintf(stderr, "invoking preprocessor failed\n");
                exit(1);
        }
@@ -362,6 +362,8 @@ int main(int argc, char **argv)
        const char     *dumpfunction = NULL;
        compile_mode_t  mode         = CompileAssembleLink;
        int             opt_level    = 1;
+       int             result       = EXIT_SUCCESS;
+       char            cpu_arch[16] = "ia32";
 
        obstack_init(&cppflags_obst);
        obstack_init(&ldflags_obst);
@@ -415,7 +417,6 @@ int main(int argc, char **argv)
                /* fallthrough */
        case 2:
                firm_option("inline");
-               firm_option("no-strength-red");
                firm_option("deconv");
                firm_be_option("omitfp");
                break;
@@ -496,23 +497,60 @@ int main(int argc, char **argv)
                                        argument_errors = true;
                                } else if (res == -1) {
                                        help_displayed = true;
+                               } else {
+                                       if (strncmp(opt, "isa=", 4) == 0)
+                                               strncpy(cpu_arch, opt, sizeof(cpu_arch));
                                }
                        } else if(option[0] == 'W') {
                                set_warning_opt(&option[1]);
                        } else if(option[0] == 'm') {
                                const char *opt;
+                               char arch_opt[64];
+
                                GET_ARG_AFTER(opt, "-m");
-                               char *endptr;
-                               long int value = strtol(opt, &endptr, 10);
-                               if (*endptr != '\0') {
-                                       fprintf(stderr, "error: wrong option '-m %s'\n",  opt);
-                                       argument_errors = true;
-                               }
-                               if (value != 16 && value != 32 && value != 64) {
-                                       fprintf(stderr, "error: option -m supports only 16, 32 or 64\n");
-                                       argument_errors = true;
+                               if(strncmp(opt, "arch=", 5) == 0) {
+                                       GET_ARG_AFTER(opt, "-march=");
+                                       snprintf(arch_opt, sizeof(arch_opt), "%s-arch=%s", cpu_arch, opt);
+                                       int res = firm_be_option(arch_opt);
+                                       if (res == 0)
+                                               argument_errors = true;
+                                       else {
+                                               snprintf(arch_opt, sizeof(arch_opt), "%s-opt=%s", cpu_arch, opt);
+                                               int res = firm_be_option(arch_opt);
+                                               if (res == 0)
+                                                       argument_errors = true;
+                                       }
+                               } else if(strncmp(opt, "tune=", 5) == 0) {
+                                       GET_ARG_AFTER(opt, "-mtune=");
+                                       snprintf(arch_opt, sizeof(arch_opt), "%s-opt=%s", cpu_arch, opt);
+                                       int res = firm_be_option(arch_opt);
+                                       if (res == 0)
+                                               argument_errors = true;
+                               } else if(strncmp(opt, "cpu=", 4) == 0) {
+                                       GET_ARG_AFTER(opt, "-mcpu=");
+                                       snprintf(arch_opt, sizeof(arch_opt), "%s-arch=%s", cpu_arch, opt);
+                                       int res = firm_be_option(arch_opt);
+                                       if (res == 0)
+                                               argument_errors = true;
+                               } else if(strncmp(opt, "fpu=", 4) == 0) {
+                                       GET_ARG_AFTER(opt, "-mfpu=");
+                                       snprintf(arch_opt, sizeof(arch_opt), "%s-fpunit=%s", cpu_arch, opt);
+                                       int res = firm_be_option(arch_opt);
+                                       if (res == 0)
+                                               argument_errors = true;
                                } else {
-                                       machine_size = (unsigned int)value;
+                                       char *endptr;
+                                       long int value = strtol(opt, &endptr, 10);
+                                       if (*endptr != '\0') {
+                                               fprintf(stderr, "error: wrong option '-m %s'\n",  opt);
+                                               argument_errors = true;
+                                       }
+                                       if (value != 16 && value != 32 && value != 64) {
+                                               fprintf(stderr, "error: option -m supports only 16, 32 or 64\n");
+                                               argument_errors = true;
+                                       } else {
+                                               machine_size = (unsigned int)value;
+                                       }
                                }
                        } else if (option[0] == '\0') {
                                if(input != NULL) {
@@ -521,10 +559,22 @@ int main(int argc, char **argv)
                                } else {
                                        input = arg;
                                }
+                       } else if(strcmp(option, "pg") == 0) {
+                               firm_be_option("-b gprof");
+                               obstack_printf(&ldflags_obst, " -pg");
                        } else if(strcmp(option, "pedantic") == 0) {
                                fprintf(stderr, "warning: ignoring gcc option '%s'\n", arg);
                        } else if(strncmp(option, "std=", 4) == 0) {
-                               fprintf(stderr, "warning: ignoring gcc option '%s'\n", arg);
+                               if(strcmp(&option[4], "c99") == 0) {
+                                       c_mode = _C89|_C99;
+                               } else if(strcmp(&option[4], "c89") == 0) {
+                                       c_mode = _C89;
+                               } else if(strcmp(&option[4], "gnu99") == 0) {
+                                       c_mode = _C89|_C99|_GNUC;
+                               } else if(strcmp(&option[4], "microsoft") == 0) {
+                                       c_mode = _C89|_C99|_MS;
+                               } else
+                                       fprintf(stderr, "warning: ignoring gcc option '%s'\n", arg);
                        } else if (option[0] == '-') {
                                /* double dash option */
                                ++option;
@@ -646,7 +696,14 @@ int main(int argc, char **argv)
                        outname = outnamebuf;
                        break;
                case CompileAssembleLink:
+#ifdef _WIN32
+                       /* Windows compiler typically derive the output name from
+                          the first source file */
+                       get_output_name(outnamebuf, sizeof(outnamebuf), input, ".exe");
+                       outname = outnamebuf;
+#else
                        outname = "a.out";
+#endif
                        break;
                }
        }
@@ -687,29 +744,35 @@ int main(int argc, char **argv)
 
        FILE *preprocessed_in = preprocess(in, input);
        translation_unit_t *const unit = do_parsing(preprocessed_in, input);
-       int result = pclose(preprocessed_in);
-       if(result != 0) {
-               return result;
+       int res = pclose(preprocessed_in);
+       if(res != 0) {
+               return res;
        }
-       if(unit == NULL) {
+
+       if(error_count > 0) {
                /* parsing failed because of errors */
                fprintf(stderr, "%u error(s), %u warning(s)\n", error_count, warning_count);
-               return EXIT_FAILURE;
-       }
-       if (warning_count > 0) {
+               result = EXIT_FAILURE;
+       } else if(warning_count > 0) {
                fprintf(stderr, "%u warning(s)\n", warning_count);
        }
 
        if(mode == BenchmarkParser) {
-               return 0;
+               return result;
        }
 
+       /* prints the AST even if errors occurred */
        if(mode == PrintAst) {
                type_set_output(out);
                ast_set_output(out);
                print_ast(unit);
-               return 0;
+               return result;
        }
+
+       /* cannot handle other modes with errors */
+       if(result != EXIT_SUCCESS)
+               return result;
+
        if(mode == PrintFluffy) {
                type_set_output(out);
                ast_set_output(out);