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"
|
||||
|
||||
typedef enum { FILE_NONE, FILE_C, FILE_ASM, FILE_OBJ } FileType;
|
||||
|
||||
StringArray include_paths;
|
||||
bool opt_fcommon = true;
|
||||
|
||||
static FileType opt_x;
|
||||
static StringArray opt_include;
|
||||
static bool opt_E;
|
||||
static bool opt_S;
|
||||
|
@ -23,7 +26,7 @@ static void usage(int status) {
|
|||
}
|
||||
|
||||
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++)
|
||||
if (!strcmp(arg, x[i]))
|
||||
|
@ -50,6 +53,16 @@ static void define(char *str) {
|
|||
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) {
|
||||
// Make sure that all command line options that take an argument
|
||||
// have an argument.
|
||||
|
@ -139,6 +152,16 @@ static void parse_args(int argc, char **argv) {
|
|||
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")) {
|
||||
base_file = argv[++i];
|
||||
continue;
|
||||
|
@ -434,6 +457,21 @@ static void run_linker(StringArray *inputs, char *output) {
|
|||
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) {
|
||||
atexit(cleanup);
|
||||
init_macros();
|
||||
|
@ -461,22 +499,22 @@ int main(int argc, char **argv) {
|
|||
else
|
||||
output = replace_extn(input, ".o");
|
||||
|
||||
FileType type = get_file_type(input);
|
||||
|
||||
// Handle .o
|
||||
if (endswith(input, ".o")) {
|
||||
if (type == FILE_OBJ) {
|
||||
strarray_push(&ld_args, input);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle .s
|
||||
if (endswith(input, ".s")) {
|
||||
if (type == FILE_ASM) {
|
||||
if (!opt_S)
|
||||
assemble(input, output);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle .c
|
||||
if (!endswith(input, ".c") && strcmp(input, "-"))
|
||||
error("unknown file extension: %s", input);
|
||||
assert(type == FILE_C);
|
||||
|
||||
// Just preprocess
|
||||
if (opt_E) {
|
||||
|
|
|
@ -25,7 +25,7 @@ $chibicc --help 2>&1 | grep -q chibicc
|
|||
check --help
|
||||
|
||||
# -S
|
||||
echo 'int main() {}' | $chibicc -S -o - - | grep -q 'main:'
|
||||
echo 'int main() {}' | $chibicc -S -o- -xc - | grep -q 'main:'
|
||||
check -S
|
||||
|
||||
# Default output file
|
||||
|
@ -56,7 +56,7 @@ check 'multiple input files'
|
|||
|
||||
# Run linker
|
||||
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
|
||||
check linker
|
||||
|
||||
|
@ -77,30 +77,30 @@ check a.out
|
|||
|
||||
# -E
|
||||
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
|
||||
|
||||
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
|
||||
check '-E and -o'
|
||||
|
||||
# -I
|
||||
mkdir $tmp/dir
|
||||
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
|
||||
|
||||
# -D
|
||||
echo foo | $chibicc -Dfoo -E - | grep -q 1
|
||||
echo foo | $chibicc -Dfoo -E -xc - | grep -q 1
|
||||
check -D
|
||||
|
||||
# -D
|
||||
echo foo | $chibicc -Dfoo=bar -E - | grep -q bar
|
||||
echo foo | $chibicc -Dfoo=bar -E -xc - | grep -q bar
|
||||
check -D
|
||||
|
||||
# -U
|
||||
echo foo | $chibicc -Dfoo=bar -Ufoo -E - | grep -q foo
|
||||
echo foo | $chibicc -Dfoo=bar -Ufoo -E -xc - | grep -q foo
|
||||
check -U
|
||||
|
||||
# ignored options
|
||||
|
@ -110,7 +110,7 @@ $chibicc -c -O -Wall -g -std=c11 -ffreestanding -fno-builtin \
|
|||
check 'ignored options'
|
||||
|
||||
# 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'
|
||||
|
||||
# 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
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
# -idirafter
|
||||
mkdir -p $tmp/dir1 $tmp/dir2
|
||||
echo foo > $tmp/dir1/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
|
||||
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
|
||||
|
||||
# -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)'
|
||||
|
||||
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'
|
||||
|
||||
# -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'
|
||||
|
||||
# -include
|
||||
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
|
||||
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
|
||||
|
||||
# -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
|
||||
|
|
Loading…
Reference in New Issue