diff options
Diffstat (limited to 'src/main.cff')
| -rw-r--r-- | src/main.cff | 80 |
1 files changed, 75 insertions, 5 deletions
diff --git a/src/main.cff b/src/main.cff index b8829a7..9f9181c 100644 --- a/src/main.cff +++ b/src/main.cff @@ -1,21 +1,91 @@ import "cffc.hff"; import "common.hff"; +fn prihelp(f *FILE, progname *const u8) void { + fprintf(f, "Usage: %s: [OPTION]... [FILE]\n", progname); + fprintf(f, "Compile cffc source code in FILE\n" + "\n" + "Options:\n" + " --help, -h:\t\tshow this help message\n" + " --target triple:\tset compilation target triple\n" + " -:\t\t\tread input from stdin\n" + " -o -:\t\tset output to stdout\n" + " -o path:\t\tset output file path\n"); +} + extern fn main(argc int, argv **u8) int { - assert(argc > 1, "args?"); + let triple = #null; + let path *const u8 = #null; + let outfile *FILE = #null; + for let i = 1; i < argc; ++i { + let arg = argv[i]; + defmacro nextarg() [ + (do let $next = argv[++i]; + if $next == #null { + fprintf(stderr, "%s: error: argument expected after `%s'\n", argv[0], arg); + fprintf(stderr, "Try '%s --help' for more information\n", argv[0]); + return 1; + } + $next;); + ] + switch { + case streq(arg, "-h") or streq(arg, "--help"); + prihelp(stdout, argv[1]); + return 0; + + case streq(arg, "-"); + path = "/dev/stdin"; + + case streq(arg, "--target"); + triple = nextarg(); + + case streq(arg, "-o"); + let outpath = nextarg(); + outfile = streq(outpath, "-") ? stdout : fopen(outpath, "wb"); + if outfile == #null { + fprintf(stderr, "%s: error: cannot open '%s': %s\n", argv[0], outpath, strerror(errno)); + return 1; + } + + case *arg == '-'; + fprintf(stderr, "%s: error: unknown option '%s'\n1", argv[0], arg); + fprintf(stderr, "Try '%s --help' for more information\n", argv[0]); + return 1; + + case else + if path { + fprintf(stderr, "%s: error: path was already given\n", argv[0]); + fprintf(stderr, "Try '%s --help' for more information\n", argv[0]); + return 1; + } + path = arg; + } + } + + if path == #null { + fprintf(stderr, "%s: error: no input file\n", argv[0]); + fprintf(stderr, "Try '%s --help' for more information\n", argv[0]); + return 1; + } + + if outfile == #null { + fprintf(stderr, "%s: error: no output file\n", argv[0]); + fprintf(stderr, "Try '%s --help' for more information\n", argv[0]); + return 1; + } - let triple = host_target_triple; + triple = triple ?? host_target_triple; let targ = triple2targ(triple); if targ == #null { - fprintf(stderr, "error: unsupported target triple `%s'\n", triple); + fprintf(stderr, "%s: error: unsupported target triple `%s'\n", argv[0], triple); return 1; } targ_ini(targ); g_targ.triple = triple; let p = Parser {}; - parser_init(&p, argv[1]); - llvm_init(stdout); + parser_init(&p, path); + llvm_init(outfile); let decls = parse(&p); defer free(decls.#ptr); if p.error { return 1; } |