#include "driver/firm_opt.h"
#include "driver/firm_cmdline.h"
#include "adt/error.h"
-#include "write_fluffy.h"
-#include "write_caml.h"
+#include "wrappergen/write_fluffy.h"
+#include "wrappergen/write_caml.h"
+#include "wrappergen/write_jna.h"
#include "revision.h"
#include "warning.h"
#include "mangle.h"
#ifndef PREPROCESSOR
-#ifdef __APPLE__
+#ifndef __WIN32__
#define PREPROCESSOR "gcc -E -std=c99 -m32 -U__STRICT_ANSI__"
#else
#define PREPROCESSOR "cpp -std=c99 -m32 -U__STRICT_ANSI__"
static void get_output_name(char *buf, size_t buflen, const char *inputname,
const char *newext)
{
- size_t last_dot = 0xffffffff;
- size_t i = 0;
-
- if (inputname == NULL) {
- snprintf(buf, buflen, "a%s", newext);
- return;
- }
-
- for (const char *c = inputname; *c != 0; ++c) {
- if (*c == '.')
- last_dot = i;
- ++i;
- }
- if (last_dot == 0xffffffff)
- last_dot = i;
-
- if (last_dot >= buflen)
- panic("filename too long");
- memcpy(buf, inputname, last_dot);
-
- size_t extlen = strlen(newext) + 1;
- if (extlen + last_dot >= buflen)
+ if (inputname == NULL)
+ inputname = "a";
+
+ char const *const last_slash = strrchr(inputname, '/');
+ char const *const filename =
+ last_slash != NULL ? last_slash + 1 : inputname;
+ char const *const last_dot = strrchr(filename, '.');
+ char const *const name_end =
+ last_dot != NULL ? last_dot : strchr(filename, '\0');
+
+ int const len = snprintf(buf, buflen, "%.*s%s",
+ (int)(name_end - filename), filename, newext);
+#ifdef _WIN32
+ if (len < 0 || buflen <= (size_t)len)
+#else
+ if (buflen <= (size_t)len)
+#endif
panic("filename too long");
- memcpy(buf+last_dot, newext, extlen);
}
#include "builtins.h"
{
char buf[4096];
va_list ap;
+
va_start(ap, format);
+#ifdef _WIN32
+ int len =
+#endif
+ vsnprintf(buf, sizeof(buf), format, ap);
+ va_end(ap);
obstack_1grow(obst, ' ');
#ifdef _WIN32
obstack_1grow(obst, '"');
- int len = vsnprintf(buf, sizeof(buf), format, ap);
obstack_grow(obst, buf, len);
obstack_1grow(obst, '"');
#else
- char buf[4096];
- vsnprintf(buf, sizeof(buf), format, ap);
- va_end(ap);
-
/* escape stuff... */
for (char *c = buf; *c != '\0'; ++c) {
switch(*c) {
- case '"':
- case '\'':
- case '`':
case ' ':
- case '\t':
- case '\n':
- case '\r':
- case '\\':
+ case '"':
case '$':
+ case '&':
case '(':
case ')':
+ case ';':
+ case '<':
+ case '>':
+ case '\'':
+ case '\\':
+ case '\n':
+ case '\r':
+ case '\t':
+ case '`':
+ case '|':
obstack_1grow(obst, '\\');
/* FALLTHROUGH */
default:
}
}
#endif
- va_end(ap);
}
static const char *type_to_string(type_t *type)
add_flag(&cppflags_obst, "-U__SIZE_TYPE__");
add_flag(&cppflags_obst, "-D__SIZE_TYPE__=%s", type_to_string(type_size_t));
+ /* TODO hack... */
+ add_flag(&cppflags_obst, "-D__builtin_abort=abort");
+ add_flag(&cppflags_obst, "-D__builtin_abs=abs");
+ add_flag(&cppflags_obst, "-D__builtin_exit=exit");
+ add_flag(&cppflags_obst, "-D__builtin_malloc=malloc");
+ add_flag(&cppflags_obst, "-D__builtin_memcmp=memcmp");
+ add_flag(&cppflags_obst, "-D__builtin_memcpy=memcpy");
+ add_flag(&cppflags_obst, "-D__builtin_memset=memset");
+ add_flag(&cppflags_obst, "-D__builtin_strlen=strlen");
+ add_flag(&cppflags_obst, "-D__builtin_strcmp=strcmp");
+ add_flag(&cppflags_obst, "-D__builtin_strcpy=strcpy");
+
/* handle dependency generation */
if (dep_target[0] != '\0') {
add_flag(&cppflags_obst, "-MF");
}
}
+static void print_file_name(const char *file)
+{
+ add_flag(&ldflags_obst, "-print-file-name=%s", file);
+
+ obstack_1grow(&ldflags_obst, '\0');
+ const char *flags = obstack_finish(&ldflags_obst);
+
+ /* construct commandline */
+ obstack_printf(&ldflags_obst, "%s ", LINKER);
+ obstack_printf(&ldflags_obst, "%s", flags);
+ obstack_1grow(&ldflags_obst, '\0');
+
+ char *commandline = obstack_finish(&ldflags_obst);
+
+ if (verbose) {
+ puts(commandline);
+ }
+ int err = system(commandline);
+ if (err != EXIT_SUCCESS) {
+ fprintf(stderr, "linker reported an error\n");
+ exit(1);
+ }
+}
+
static const char *try_dir(const char *dir)
{
if (dir == NULL)
LexTest,
PrintAst,
PrintFluffy,
- PrintCaml
+ PrintCaml,
+ PrintJna
} compile_mode_t;
static void usage(const char *argv0)
}
static void print_cparser_version(void) {
- firm_version_t ver;
- firm_get_version(&ver);
-
printf("cparser (%s) using libFirm (%u.%u",
- cparser_REVISION, ver.major, ver.minor);
- if (ver.revision[0] != 0) {
+ cparser_REVISION, ir_get_version_major(),
+ ir_get_version_minor());
+
+ const char *revision = ir_get_version_revision();
+ if (revision[0] != 0) {
putchar(' ');
- fputs(ver.revision, stdout);
+ fputs(revision, stdout);
}
- if (ver.build[0] != 0) {
+
+ const char *build = ir_get_version_build();
+ if (build[0] != 0) {
putchar(' ');
- fputs(ver.build, stdout);
+ fputs(build, stdout);
}
puts(")\n");
}
initialize_firm();
const char *dumpfunction = NULL;
+ const char *print_file_name_file = NULL;
compile_mode_t mode = CompileAssembleLink;
int opt_level = 1;
int result = EXIT_SUCCESS;
GET_ARG_AFTER(opt, "-MT");
add_flag(&cppflags_obst, "-%s", option);
add_flag(&cppflags_obst, "%s", opt);
+ } else if (streq(option, "include")) {
+ const char *opt;
+ GET_ARG_AFTER(opt, "-include");
+ add_flag(&cppflags_obst, "-include");
+ add_flag(&cppflags_obst, "%s", opt);
+ } else if (streq(option, "isystem")) {
+ const char *opt;
+ GET_ARG_AFTER(opt, "-isystem");
+ add_flag(&cppflags_obst, "-isystem");
+ add_flag(&cppflags_obst, "%s", opt);
+ } else if (streq(option, "nostdinc")
+ || streq(option, "trigraphs")) {
+ /* pass these through to the preprocessor */
+ add_flag(&cppflags_obst, "%s", arg);
} else if (streq(option, "pipe")) {
/* here for gcc compatibility */
} else if (option[0] == 'f') {
strstart(orig_opt, "align-jumps=") ||
strstart(orig_opt, "align-functions=")) {
fprintf(stderr, "ignoring gcc option '-f%s'\n", orig_opt);
+ } else if (strstart(orig_opt, "input-charset=")) {
+ char const* const encoding = strchr(orig_opt, '=') + 1;
+ select_input_encoding(encoding);
+ } else if (streq(orig_opt, "verbose-asm")) {
+ /* ignore: we always print verbose assembler */
} else {
char const *opt = orig_opt;
bool truth_value = true;
opt += 3;
}
- if (streq(opt, "dollars-in-identifiers")) {
- allow_dollar_in_symbol = truth_value;
- } if (streq(opt, "builtins")) {
+ if (streq(opt, "builtins")) {
use_builtins = truth_value;
+ } else if (streq(opt, "dollars-in-identifiers")) {
+ allow_dollar_in_symbol = truth_value;
+ } else if (streq(opt, "omit-frame-pointer")) {
+ set_be_option(truth_value ? "omitfp" : "omitfp=no");
} else if (streq(opt, "short-wchar")) {
wchar_atomic_kind = truth_value ? ATOMIC_TYPE_USHORT
: ATOMIC_TYPE_INT;
- } else if (streq(opt, "syntax-only")) {
- mode = truth_value ? ParseOnly : CompileAssembleLink;
- } else if (streq(opt, "omit-frame-pointer")) {
- set_be_option(truth_value ? "omitfp" : "omitfp=no");
+ } else if (streq(opt, "signed-char")) {
+ char_is_signed = truth_value;
} else if (streq(opt, "strength-reduce")) {
firm_option(truth_value ? "strength-red" : "no-strength-red");
+ } else if (streq(opt, "syntax-only")) {
+ mode = truth_value ? ParseOnly : CompileAssembleLink;
+ } else if (streq(opt, "unsigned-char")) {
+ char_is_signed = !truth_value;
} else if (streq(opt, "fast-math") ||
streq(opt, "jump-tables") ||
streq(opt, "unroll-loops") ||
strncpy(cpu_arch, opt, sizeof(cpu_arch));
}
} else if (option[0] == 'W') {
- if (strstart(option + 1, "l,")) // a gcc-style linker option
- {
+ if (strstart(option + 1, "p,")) {
+ // pass options directly to the preprocessor
+ const char *opt;
+ GET_ARG_AFTER(opt, "-Wp,");
+ add_flag(&cppflags_obst, "-Wp,%s", opt);
+ } else if (strstart(option + 1, "l,")) {
+ // pass options directly to the linker
const char *opt;
GET_ARG_AFTER(opt, "-Wl,");
add_flag(&ldflags_obst, "-Wl,%s", opt);
+ } else if (streq(option + 1, "no-trigraphs")
+ || streq(option + 1, "undef")) {
+ add_flag(&cppflags_obst, "%s", arg);
+ } else {
+ set_warning_opt(&option[1]);
}
- else set_warning_opt(&option[1]);
} else if (option[0] == 'm') {
/* -m options */
const char *opt;
(fprintf(stderr, "warning: ignoring gcc option '%s'\n", arg), standard);
} else if (streq(option, "version")) {
print_cparser_version();
+ } else if (strstart(option, "print-file-name=")) {
+ GET_ARG_AFTER(print_file_name_file, "-print-file-name=");
} else if (option[0] == '-') {
/* double dash option */
++option;
} else if (streq(option, "no-ms")) {
features_on &= ~_MS;
features_off |= _MS;
- } else if (streq(option, "signed-chars")) {
- char_is_signed = true;
- } else if (streq(option, "unsigned-chars")) {
- char_is_signed = false;
} else if (streq(option, "strict")) {
strict_mode = true;
} else if (streq(option, "lextest")) {
mode = PrintFluffy;
} else if (streq(option, "print-caml")) {
mode = PrintCaml;
+ } else if (streq(option, "print-jna")) {
+ mode = PrintJna;
} else if (streq(option, "version")) {
print_cparser_version();
exit(EXIT_SUCCESS);
}
}
+ if (print_file_name_file != NULL) {
+ print_file_name(print_file_name_file);
+ return 0;
+ }
+
if (files == NULL) {
fprintf(stderr, "error: no input files specified\n");
argument_errors = true;
case PrintAst:
case PrintFluffy:
case PrintCaml:
+ case PrintJna:
case LexTest:
case PreprocessOnly:
case ParseOnly:
FILE *preprocessed_in = NULL;
switch (filetype) {
- case FILETYPE_C: filetype = FILETYPE_PREPROCESSED_C; goto preprocess;
- case FILETYPE_CXX: filetype = FILETYPE_PREPROCESSED_CXX; goto preprocess;
- case FILETYPE_ASSEMBLER: filetype = FILETYPE_PREPROCESSED_ASSEMBLER; goto preprocess;
+ case FILETYPE_C:
+ filetype = FILETYPE_PREPROCESSED_C;
+ goto preprocess;
+ case FILETYPE_CXX:
+ filetype = FILETYPE_PREPROCESSED_CXX;
+ goto preprocess;
+ case FILETYPE_ASSEMBLER:
+ filetype = FILETYPE_PREPROCESSED_ASSEMBLER;
+ add_flag(&cppflags_obst, "-x");
+ add_flag(&cppflags_obst, "assembler-with-cpp");
+ goto preprocess;
preprocess:
/* no support for input on FILE* yet */
if (in != NULL)
copy_file(out, preprocessed_in);
int result = pclose(preprocessed_in);
fclose(out);
+ /* remove output file in case of error */
+ if (out != stdout && result != EXIT_SUCCESS) {
+ unlink(outname);
+ }
return result;
}
if (in == preprocessed_in) {
int pp_result = pclose(preprocessed_in);
if (pp_result != EXIT_SUCCESS) {
+ /* remove output file */
+ if (out != stdout)
+ unlink(outname);
exit(EXIT_FAILURE);
}
}
} else if (mode == PrintCaml) {
write_caml_decls(out, unit);
continue;
+ } else if (mode == PrintJna) {
+ write_jna_decls(out, unit);
+ continue;
}
translation_unit_to_firm(unit);
if (in == preprocessed_in) {
int pp_result = pclose(preprocessed_in);
if (pp_result != EXIT_SUCCESS) {
+ /* remove output in error case */
+ if (out != stdout)
+ unlink(outname);
return pp_result;
}
}
file->type = filetype;
}
- if (result != EXIT_SUCCESS)
+ if (result != EXIT_SUCCESS) {
+ if (out != stdout)
+ unlink(outname);
return result;
+ }
/* link program file */
if (mode == CompileAssembleLink) {