Accept multiple input files

This commit is contained in:
Rui Ueyama 2020-08-18 09:16:57 +09:00
parent 140b43358c
commit b833cd0f29
2 changed files with 73 additions and 26 deletions

84
main.c
View File

@ -5,7 +5,10 @@ static bool opt_cc1;
static bool opt_hash_hash_hash;
static char *opt_o;
static char *input_path;
static char *base_file;
static char *output_file;
static StringArray input_paths;
static StringArray tmpfiles;
static void usage(int status) {
@ -13,7 +16,18 @@ static void usage(int status) {
exit(status);
}
static bool take_arg(char *arg) {
return !strcmp(arg, "-o");
}
static void parse_args(int argc, char **argv) {
// Make sure that all command line options that take an argument
// have an argument.
for (int i = 1; i < argc; i++)
if (take_arg(argv[i]))
if (!argv[++i])
usage(1);
for (int i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-###")) {
opt_hash_hash_hash = true;
@ -29,9 +43,7 @@ static void parse_args(int argc, char **argv) {
usage(0);
if (!strcmp(argv[i], "-o")) {
if (!argv[++i])
usage(1);
opt_o = argv[i];
opt_o = argv[++i];
continue;
}
@ -45,13 +57,23 @@ static void parse_args(int argc, char **argv) {
continue;
}
if (!strcmp(argv[i], "-cc1-input")) {
base_file = argv[++i];
continue;
}
if (!strcmp(argv[i], "-cc1-output")) {
output_file = argv[++i];
continue;
}
if (argv[i][0] == '-' && argv[i][1] != '\0')
error("unknown argument: %s", argv[i]);
input_path = argv[i];
strarray_push(&input_paths, argv[i]);
}
if (!input_path)
if (input_paths.len == 0)
error("no input files");
}
@ -118,11 +140,13 @@ static void run_cc1(int argc, char **argv, char *input, char *output) {
memcpy(args, argv, argc * sizeof(char *));
args[argc++] = "-cc1";
if (input)
if (input) {
args[argc++] = "-cc1-input";
args[argc++] = input;
}
if (output) {
args[argc++] = "-o";
args[argc++] = "-cc1-output";
args[argc++] = output;
}
@ -131,12 +155,12 @@ static void run_cc1(int argc, char **argv, char *input, char *output) {
static void cc1(void) {
// Tokenize and parse.
Token *tok = tokenize_file(input_path);
Token *tok = tokenize_file(base_file);
Obj *prog = parse(tok);
// Traverse the AST to emit assembly.
FILE *out = open_file(opt_o);
fprintf(out, ".file 1 \"%s\"\n", input_path);
FILE *out = open_file(output_file);
fprintf(out, ".file 1 \"%s\"\n", base_file);
codegen(prog, out);
}
@ -154,23 +178,31 @@ int main(int argc, char **argv) {
return 0;
}
char *output;
if (opt_o)
output = opt_o;
else if (opt_S)
output = replace_extn(input_path, ".s");
else
output = replace_extn(input_path, ".o");
if (input_paths.len > 1 && opt_o)
error("cannot specify '-o' with multiple files");
// If -S is given, assembly text is the final output.
if (opt_S) {
run_cc1(argc, argv, input_path, output);
return 0;
for (int i = 0; i < input_paths.len; i++) {
char *input = input_paths.data[i];
char *output;
if (opt_o)
output = opt_o;
else if (opt_S)
output = replace_extn(input, ".s");
else
output = replace_extn(input, ".o");
// If -S is given, assembly text is the final output.
if (opt_S) {
run_cc1(argc, argv, input, output);
continue;
}
// Otherwise, run the assembler to assemble our output.
char *tmpfile = create_tmpfile();
run_cc1(argc, argv, input, tmpfile);
assemble(tmpfile, output);
}
// Otherwise, run the assembler to assemble our output.
char *tmpfile = create_tmpfile();
run_cc1(argc, argv, input_path, tmpfile);
assemble(tmpfile, output);
return 0;
}

View File

@ -39,4 +39,19 @@ check 'default output file'
[ -f $tmp/out.s ]
check 'default output file'
# Multiple input files
rm -f $tmp/foo.o $tmp/bar.o
echo 'int x;' > $tmp/foo.c
echo 'int y;' > $tmp/bar.c
(cd $tmp; $OLDPWD/$chibicc $tmp/foo.c $tmp/bar.c)
[ -f $tmp/foo.o ] && [ -f $tmp/bar.o ]
check 'multiple input files'
rm -f $tmp/foo.s $tmp/bar.s
echo 'int x;' > $tmp/foo.c
echo 'int y;' > $tmp/bar.c
(cd $tmp; $OLDPWD/$chibicc -S $tmp/foo.c $tmp/bar.c)
[ -f $tmp/foo.s ] && [ -f $tmp/bar.s ]
check 'multiple input files'
echo OK