mirror of
https://github.com/rui314/chibicc
synced 2024-11-25 15:49:35 +03:00
Add -o and --help options
This commit is contained in:
parent
7b8528f71c
commit
a0388bada4
1
Makefile
1
Makefile
@ -9,6 +9,7 @@ $(OBJS): chibicc.h
|
||||
|
||||
test: chibicc
|
||||
./test.sh
|
||||
./test-driver.sh
|
||||
|
||||
clean:
|
||||
rm -f chibicc *.o *~ tmp*
|
||||
|
@ -186,4 +186,4 @@ void add_type(Node *node);
|
||||
// codegen.c
|
||||
//
|
||||
|
||||
void codegen(Obj *prog);
|
||||
void codegen(Obj *prog, FILE *out);
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "chibicc.h"
|
||||
|
||||
static FILE *output_file;
|
||||
static int depth;
|
||||
static char *argreg8[] = {"%dil", "%sil", "%dl", "%cl", "%r8b", "%r9b"};
|
||||
static char *argreg64[] = {"%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%r9"};
|
||||
@ -11,9 +12,9 @@ static void gen_stmt(Node *node);
|
||||
static void println(char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vprintf(fmt, ap);
|
||||
vfprintf(output_file, fmt, ap);
|
||||
va_end(ap);
|
||||
printf("\n");
|
||||
fprintf(output_file, "\n");
|
||||
}
|
||||
|
||||
static int count(void) {
|
||||
@ -292,7 +293,9 @@ static void emit_text(Obj *prog) {
|
||||
}
|
||||
}
|
||||
|
||||
void codegen(Obj *prog) {
|
||||
void codegen(Obj *prog, FILE *out) {
|
||||
output_file = out;
|
||||
|
||||
assign_lvar_offsets(prog);
|
||||
emit_data(prog);
|
||||
emit_text(prog);
|
||||
|
55
main.c
55
main.c
@ -1,15 +1,60 @@
|
||||
#include "chibicc.h"
|
||||
|
||||
static char *opt_o;
|
||||
|
||||
static char *input_path;
|
||||
|
||||
static void usage(int status) {
|
||||
fprintf(stderr, "chibicc [ -o <path> ] <file>\n");
|
||||
exit(status);
|
||||
}
|
||||
|
||||
static void parse_args(int argc, char **argv) {
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (!strcmp(argv[i], "--help"))
|
||||
usage(0);
|
||||
|
||||
if (!strcmp(argv[i], "-o")) {
|
||||
if (!argv[++i])
|
||||
usage(1);
|
||||
opt_o = argv[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strncmp(argv[i], "-o", 2)) {
|
||||
opt_o = argv[i] + 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (argv[i][0] == '-' && argv[i][1] != '\0')
|
||||
error("unknown argument: %s", argv[i]);
|
||||
|
||||
input_path = argv[i];
|
||||
}
|
||||
|
||||
if (!input_path)
|
||||
error("no input files");
|
||||
}
|
||||
|
||||
static FILE *open_file(char *path) {
|
||||
if (!path || strcmp(path, "-") == 0)
|
||||
return stdout;
|
||||
|
||||
FILE *out = fopen(path, "w");
|
||||
if (!out)
|
||||
error("cannot open output file: %s: %s", path, strerror(errno));
|
||||
return out;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc != 2)
|
||||
error("%s: invalid number of arguments", argv[0]);
|
||||
parse_args(argc, argv);
|
||||
|
||||
// Tokenize and parse.
|
||||
Token *tok = tokenize_file(argv[1]);
|
||||
Token *tok = tokenize_file(input_path);
|
||||
Obj *prog = parse(tok);
|
||||
|
||||
// Traverse the AST to emit assembly.
|
||||
codegen(prog);
|
||||
|
||||
FILE *out = open_file(opt_o);
|
||||
codegen(prog, out);
|
||||
return 0;
|
||||
}
|
||||
|
25
test-driver.sh
Executable file
25
test-driver.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
tmp=`mktemp -d /tmp/chibicc-test-XXXXXX`
|
||||
trap 'rm -rf $tmp' INT TERM HUP EXIT
|
||||
echo > $tmp/empty.c
|
||||
|
||||
check() {
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "testing $1 ... passed"
|
||||
else
|
||||
echo "testing $1 ... failed"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# -o
|
||||
rm -f $tmp/out
|
||||
./chibicc -o $tmp/out $tmp/empty.c
|
||||
[ -f $tmp/out ]
|
||||
check -o
|
||||
|
||||
# --help
|
||||
./chibicc --help 2>&1 | grep -q chibicc
|
||||
check --help
|
||||
|
||||
echo OK
|
Loading…
Reference in New Issue
Block a user