mirror of https://github.com/rui314/chibicc
Add -x option
This commit is contained in:
parent
8f5ff07dc0
commit
ee0a951b30
50
main.c
50
main.c
|
@ -1,8 +1,11 @@
|
||||||
#include "chibicc.h"
|
#include "chibicc.h"
|
||||||
|
|
||||||
|
typedef enum { FILE_NONE, FILE_C, FILE_ASM, FILE_OBJ } FileType;
|
||||||
|
|
||||||
StringArray include_paths;
|
StringArray include_paths;
|
||||||
bool opt_fcommon = true;
|
bool opt_fcommon = true;
|
||||||
|
|
||||||
|
static FileType opt_x;
|
||||||
static StringArray opt_include;
|
static StringArray opt_include;
|
||||||
static bool opt_E;
|
static bool opt_E;
|
||||||
static bool opt_S;
|
static bool opt_S;
|
||||||
|
@ -23,7 +26,7 @@ static void usage(int status) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool take_arg(char *arg) {
|
static bool take_arg(char *arg) {
|
||||||
char *x[] = {"-o", "-I", "-idirafter", "-include"};
|
char *x[] = {"-o", "-I", "-idirafter", "-include", "-x"};
|
||||||
|
|
||||||
for (int i = 0; i < sizeof(x) / sizeof(*x); i++)
|
for (int i = 0; i < sizeof(x) / sizeof(*x); i++)
|
||||||
if (!strcmp(arg, x[i]))
|
if (!strcmp(arg, x[i]))
|
||||||
|
@ -50,6 +53,16 @@ static void define(char *str) {
|
||||||
define_macro(str, "1");
|
define_macro(str, "1");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FileType parse_opt_x(char *s) {
|
||||||
|
if (!strcmp(s, "c"))
|
||||||
|
return FILE_C;
|
||||||
|
if (!strcmp(s, "assembler"))
|
||||||
|
return FILE_ASM;
|
||||||
|
if (!strcmp(s, "none"))
|
||||||
|
return FILE_NONE;
|
||||||
|
error("<command line>: unknown argument for -x: %s", s);
|
||||||
|
}
|
||||||
|
|
||||||
static void parse_args(int argc, char **argv) {
|
static void parse_args(int argc, char **argv) {
|
||||||
// Make sure that all command line options that take an argument
|
// Make sure that all command line options that take an argument
|
||||||
// have an argument.
|
// have an argument.
|
||||||
|
@ -139,6 +152,16 @@ static void parse_args(int argc, char **argv) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[i], "-x")) {
|
||||||
|
opt_x = parse_opt_x(argv[++i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strncmp(argv[i], "-x", 2)) {
|
||||||
|
opt_x = parse_opt_x(argv[i] + 2);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!strcmp(argv[i], "-cc1-input")) {
|
if (!strcmp(argv[i], "-cc1-input")) {
|
||||||
base_file = argv[++i];
|
base_file = argv[++i];
|
||||||
continue;
|
continue;
|
||||||
|
@ -434,6 +457,21 @@ static void run_linker(StringArray *inputs, char *output) {
|
||||||
run_subprocess(arr.data);
|
run_subprocess(arr.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FileType get_file_type(char *filename) {
|
||||||
|
if (endswith(filename, ".o"))
|
||||||
|
return FILE_OBJ;
|
||||||
|
|
||||||
|
if (opt_x != FILE_NONE)
|
||||||
|
return opt_x;
|
||||||
|
|
||||||
|
if (endswith(filename, ".c"))
|
||||||
|
return FILE_C;
|
||||||
|
if (endswith(filename, ".s"))
|
||||||
|
return FILE_ASM;
|
||||||
|
|
||||||
|
error("<command line>: unknown file extension: %s", filename);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
atexit(cleanup);
|
atexit(cleanup);
|
||||||
init_macros();
|
init_macros();
|
||||||
|
@ -461,22 +499,22 @@ int main(int argc, char **argv) {
|
||||||
else
|
else
|
||||||
output = replace_extn(input, ".o");
|
output = replace_extn(input, ".o");
|
||||||
|
|
||||||
|
FileType type = get_file_type(input);
|
||||||
|
|
||||||
// Handle .o
|
// Handle .o
|
||||||
if (endswith(input, ".o")) {
|
if (type == FILE_OBJ) {
|
||||||
strarray_push(&ld_args, input);
|
strarray_push(&ld_args, input);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle .s
|
// Handle .s
|
||||||
if (endswith(input, ".s")) {
|
if (type == FILE_ASM) {
|
||||||
if (!opt_S)
|
if (!opt_S)
|
||||||
assemble(input, output);
|
assemble(input, output);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle .c
|
assert(type == FILE_C);
|
||||||
if (!endswith(input, ".c") && strcmp(input, "-"))
|
|
||||||
error("unknown file extension: %s", input);
|
|
||||||
|
|
||||||
// Just preprocess
|
// Just preprocess
|
||||||
if (opt_E) {
|
if (opt_E) {
|
||||||
|
|
|
@ -25,7 +25,7 @@ $chibicc --help 2>&1 | grep -q chibicc
|
||||||
check --help
|
check --help
|
||||||
|
|
||||||
# -S
|
# -S
|
||||||
echo 'int main() {}' | $chibicc -S -o - - | grep -q 'main:'
|
echo 'int main() {}' | $chibicc -S -o- -xc - | grep -q 'main:'
|
||||||
check -S
|
check -S
|
||||||
|
|
||||||
# Default output file
|
# Default output file
|
||||||
|
@ -56,7 +56,7 @@ check 'multiple input files'
|
||||||
|
|
||||||
# Run linker
|
# Run linker
|
||||||
rm -f $tmp/foo
|
rm -f $tmp/foo
|
||||||
echo 'int main() { return 0; }' | $chibicc -o $tmp/foo -
|
echo 'int main() { return 0; }' | $chibicc -o $tmp/foo -xc -xc -
|
||||||
$tmp/foo
|
$tmp/foo
|
||||||
check linker
|
check linker
|
||||||
|
|
||||||
|
@ -77,30 +77,30 @@ check a.out
|
||||||
|
|
||||||
# -E
|
# -E
|
||||||
echo foo > $tmp/out
|
echo foo > $tmp/out
|
||||||
echo "#include \"$tmp/out\"" | $chibicc -E - | grep -q foo
|
echo "#include \"$tmp/out\"" | $chibicc -E -xc - | grep -q foo
|
||||||
check -E
|
check -E
|
||||||
|
|
||||||
echo foo > $tmp/out1
|
echo foo > $tmp/out1
|
||||||
echo "#include \"$tmp/out1\"" | $chibicc -E -o $tmp/out2 -
|
echo "#include \"$tmp/out1\"" | $chibicc -E -o $tmp/out2 -xc -
|
||||||
cat $tmp/out2 | grep -q foo
|
cat $tmp/out2 | grep -q foo
|
||||||
check '-E and -o'
|
check '-E and -o'
|
||||||
|
|
||||||
# -I
|
# -I
|
||||||
mkdir $tmp/dir
|
mkdir $tmp/dir
|
||||||
echo foo > $tmp/dir/i-option-test
|
echo foo > $tmp/dir/i-option-test
|
||||||
echo "#include \"i-option-test\"" | $chibicc -I$tmp/dir -E - | grep -q foo
|
echo "#include \"i-option-test\"" | $chibicc -I$tmp/dir -E -xc - | grep -q foo
|
||||||
check -I
|
check -I
|
||||||
|
|
||||||
# -D
|
# -D
|
||||||
echo foo | $chibicc -Dfoo -E - | grep -q 1
|
echo foo | $chibicc -Dfoo -E -xc - | grep -q 1
|
||||||
check -D
|
check -D
|
||||||
|
|
||||||
# -D
|
# -D
|
||||||
echo foo | $chibicc -Dfoo=bar -E - | grep -q bar
|
echo foo | $chibicc -Dfoo=bar -E -xc - | grep -q bar
|
||||||
check -D
|
check -D
|
||||||
|
|
||||||
# -U
|
# -U
|
||||||
echo foo | $chibicc -Dfoo=bar -Ufoo -E - | grep -q foo
|
echo foo | $chibicc -Dfoo=bar -Ufoo -E -xc - | grep -q foo
|
||||||
check -U
|
check -U
|
||||||
|
|
||||||
# ignored options
|
# ignored options
|
||||||
|
@ -110,7 +110,7 @@ $chibicc -c -O -Wall -g -std=c11 -ffreestanding -fno-builtin \
|
||||||
check 'ignored options'
|
check 'ignored options'
|
||||||
|
|
||||||
# BOM marker
|
# BOM marker
|
||||||
printf '\xef\xbb\xbfxyz\n' | $chibicc -E -o- - | grep -q '^xyz'
|
printf '\xef\xbb\xbfxyz\n' | $chibicc -E -o- -xc - | grep -q '^xyz'
|
||||||
check 'BOM marker'
|
check 'BOM marker'
|
||||||
|
|
||||||
# Inline functions
|
# Inline functions
|
||||||
|
@ -125,67 +125,77 @@ echo 'int foo(); int main() { foo(); }' > $tmp/inline2.c
|
||||||
$chibicc -o /dev/null $tmp/inline1.c $tmp/inline2.c
|
$chibicc -o /dev/null $tmp/inline1.c $tmp/inline2.c
|
||||||
check inline
|
check inline
|
||||||
|
|
||||||
echo 'static inline void f1() {}' | $chibicc -o- -S - | grep -v -q f1:
|
echo 'static inline void f1() {}' | $chibicc -o- -S -xc - | grep -v -q f1:
|
||||||
check inline
|
check inline
|
||||||
|
|
||||||
echo 'static inline void f1() {} void foo() { f1(); }' | $chibicc -o- -S - | grep -q f1:
|
echo 'static inline void f1() {} void foo() { f1(); }' | $chibicc -o- -S -xc - | grep -q f1:
|
||||||
check inline
|
check inline
|
||||||
|
|
||||||
echo 'static inline void f1() {} static inline void f2() { f1(); } void foo() { f1(); }' | $chibicc -o- -S - | grep -q f1:
|
echo 'static inline void f1() {} static inline void f2() { f1(); } void foo() { f1(); }' | $chibicc -o- -S -xc - | grep -q f1:
|
||||||
check inline
|
check inline
|
||||||
|
|
||||||
echo 'static inline void f1() {} static inline void f2() { f1(); } void foo() { f1(); }' | $chibicc -o- -S - | grep -v -q f2:
|
echo 'static inline void f1() {} static inline void f2() { f1(); } void foo() { f1(); }' | $chibicc -o- -S -xc - | grep -v -q f2:
|
||||||
check inline
|
check inline
|
||||||
|
|
||||||
echo 'static inline void f1() {} static inline void f2() { f1(); } void foo() { f2(); }' | $chibicc -o- -S - | grep -q f1:
|
echo 'static inline void f1() {} static inline void f2() { f1(); } void foo() { f2(); }' | $chibicc -o- -S -xc - | grep -q f1:
|
||||||
check inline
|
check inline
|
||||||
|
|
||||||
echo 'static inline void f1() {} static inline void f2() { f1(); } void foo() { f2(); }' | $chibicc -o- -S - | grep -q f2:
|
echo 'static inline void f1() {} static inline void f2() { f1(); } void foo() { f2(); }' | $chibicc -o- -S -xc - | grep -q f2:
|
||||||
check inline
|
check inline
|
||||||
|
|
||||||
echo 'static inline void f2(); static inline void f1() { f2(); } static inline void f2() { f1(); } void foo() {}' | $chibicc -o- -S - | grep -v -q f1:
|
echo 'static inline void f2(); static inline void f1() { f2(); } static inline void f2() { f1(); } void foo() {}' | $chibicc -o- -S -xc - | grep -v -q f1:
|
||||||
check inline
|
check inline
|
||||||
|
|
||||||
echo 'static inline void f2(); static inline void f1() { f2(); } static inline void f2() { f1(); } void foo() {}' | $chibicc -o- -S - | grep -v -q f2:
|
echo 'static inline void f2(); static inline void f1() { f2(); } static inline void f2() { f1(); } void foo() {}' | $chibicc -o- -S -xc - | grep -v -q f2:
|
||||||
check inline
|
check inline
|
||||||
|
|
||||||
echo 'static inline void f2(); static inline void f1() { f2(); } static inline void f2() { f1(); } void foo() { f1(); }' | $chibicc -o- -S - | grep -q f1:
|
echo 'static inline void f2(); static inline void f1() { f2(); } static inline void f2() { f1(); } void foo() { f1(); }' | $chibicc -o- -S -xc - | grep -q f1:
|
||||||
check inline
|
check inline
|
||||||
|
|
||||||
echo 'static inline void f2(); static inline void f1() { f2(); } static inline void f2() { f1(); } void foo() { f1(); }' | $chibicc -o- -S - | grep -q f2:
|
echo 'static inline void f2(); static inline void f1() { f2(); } static inline void f2() { f1(); } void foo() { f1(); }' | $chibicc -o- -S -xc - | grep -q f2:
|
||||||
check inline
|
check inline
|
||||||
|
|
||||||
echo 'static inline void f2(); static inline void f1() { f2(); } static inline void f2() { f1(); } void foo() { f2(); }' | $chibicc -o- -S - | grep -q f1:
|
echo 'static inline void f2(); static inline void f1() { f2(); } static inline void f2() { f1(); } void foo() { f2(); }' | $chibicc -o- -S -xc - | grep -q f1:
|
||||||
check inline
|
check inline
|
||||||
|
|
||||||
echo 'static inline void f2(); static inline void f1() { f2(); } static inline void f2() { f1(); } void foo() { f2(); }' | $chibicc -o- -S - | grep -q f2:
|
echo 'static inline void f2(); static inline void f1() { f2(); } static inline void f2() { f1(); } void foo() { f2(); }' | $chibicc -o- -S -xc - | grep -q f2:
|
||||||
check inline
|
check inline
|
||||||
|
|
||||||
# -idirafter
|
# -idirafter
|
||||||
mkdir -p $tmp/dir1 $tmp/dir2
|
mkdir -p $tmp/dir1 $tmp/dir2
|
||||||
echo foo > $tmp/dir1/idirafter
|
echo foo > $tmp/dir1/idirafter
|
||||||
echo bar > $tmp/dir2/idirafter
|
echo bar > $tmp/dir2/idirafter
|
||||||
echo "#include \"idirafter\"" | $chibicc -I$tmp/dir1 -I$tmp/dir2 -E - | grep -q foo
|
echo "#include \"idirafter\"" | $chibicc -I$tmp/dir1 -I$tmp/dir2 -E -xc - | grep -q foo
|
||||||
check -idirafter
|
check -idirafter
|
||||||
echo "#include \"idirafter\"" | $chibicc -idirafter $tmp/dir1 -I$tmp/dir2 -E - | grep -q bar
|
echo "#include \"idirafter\"" | $chibicc -idirafter $tmp/dir1 -I$tmp/dir2 -E -xc - | grep -q bar
|
||||||
check -idirafter
|
check -idirafter
|
||||||
|
|
||||||
# -fcommon
|
# -fcommon
|
||||||
echo 'int foo;' | $chibicc -S -o- - | grep -q '\.comm foo'
|
echo 'int foo;' | $chibicc -S -o- -xc - | grep -q '\.comm foo'
|
||||||
check '-fcommon (default)'
|
check '-fcommon (default)'
|
||||||
|
|
||||||
echo 'int foo;' | $chibicc -fcommon -S -o- - | grep -q '\.comm foo'
|
echo 'int foo;' | $chibicc -fcommon -S -o- -xc - | grep -q '\.comm foo'
|
||||||
check '-fcommon'
|
check '-fcommon'
|
||||||
|
|
||||||
# -fno-common
|
# -fno-common
|
||||||
echo 'int foo;' | $chibicc -fno-common -S -o- - | grep -q '^foo:'
|
echo 'int foo;' | $chibicc -fno-common -S -o- -xc - | grep -q '^foo:'
|
||||||
check '-fno-common'
|
check '-fno-common'
|
||||||
|
|
||||||
# -include
|
# -include
|
||||||
echo foo > $tmp/out.h
|
echo foo > $tmp/out.h
|
||||||
echo bar | $chibicc -include $tmp/out.h -E -o- - | grep -q -z 'foo.*bar'
|
echo bar | $chibicc -include $tmp/out.h -E -o- -xc - | grep -q -z 'foo.*bar'
|
||||||
check -include
|
check -include
|
||||||
echo NULL | $chibicc -Iinclude -include stdio.h -E -o- - | grep -q 0
|
echo NULL | $chibicc -Iinclude -include stdio.h -E -o- -xc - | grep -q 0
|
||||||
check -include
|
check -include
|
||||||
|
|
||||||
|
# -x
|
||||||
|
echo 'int x;' | $chibicc -c -xc -o $tmp/foo.o -
|
||||||
|
check -xc
|
||||||
|
echo 'x:' | $chibicc -c -x assembler -o $tmp/foo.o -
|
||||||
|
check '-x assembler'
|
||||||
|
|
||||||
|
echo 'int x;' > $tmp/foo.c
|
||||||
|
$chibicc -c -x assembler -x none -o $tmp/foo.o $tmp/foo.c
|
||||||
|
check '-x none'
|
||||||
|
|
||||||
echo OK
|
echo OK
|
||||||
|
|
Loading…
Reference in New Issue