stage1: Added zig help to show usage on stdout

This will make it easier to do things like `zig help | grep something`.

Invalid arguments will now display a short notice for `zig help`
instead of showing the full usage information. This will make it easier
to see the actual error.
This commit is contained in:
Jay Weisskopf 2018-09-25 20:13:02 -04:00 committed by Andrew Kelley
parent 2e562a5f36
commit 7b204649e3

View File

@ -16,14 +16,22 @@
#include <stdio.h>
static int usage(const char *arg0) {
fprintf(stderr, "Usage: %s [command] [options]\n"
static int print_error_usage(const char *arg0) {
fprintf(stderr, "See `%s help` for detailed usage information\n", arg0);
return EXIT_FAILURE;
}
static int print_full_usage(const char *arg0) {
fprintf(stdout,
"Usage: %s [command] [options]\n"
"\n"
"Commands:\n"
" build build project from build.zig\n"
" build-exe [source] create executable from source or object files\n"
" build-lib [source] create library from source or object files\n"
" build-obj [source] create object from source or assembly\n"
" builtin show the source code of that @import(\"builtin\")\n"
" help show this usage information\n"
" id print the base64-encoded compiler id\n"
" init-exe initialize a `zig build` application in the cwd\n"
" init-lib initialize a `zig build` library in the cwd\n"
@ -33,6 +41,7 @@ static int usage(const char *arg0) {
" test [source] create and run a test build\n"
" version print version number and exit\n"
" zen print zen of zig and exit\n"
"\n"
"Compile Options:\n"
" --assembly [source] add assembly file to build\n"
" --cache-dir [path] override the cache directory\n"
@ -63,6 +72,7 @@ static int usage(const char *arg0) {
" -dirafter [dir] same as -isystem but do it last\n"
" -isystem [dir] add additional search path for other .h files\n"
" -mllvm [arg] forward an arg to LLVM's option processing\n"
"\n"
"Link Options:\n"
" --dynamic-linker [path] set the path to ld.so\n"
" --each-lib-rpath add rpath for each used dynamic library\n"
@ -87,13 +97,14 @@ static int usage(const char *arg0) {
" --ver-major [ver] dynamic library semver major version\n"
" --ver-minor [ver] dynamic library semver minor version\n"
" --ver-patch [ver] dynamic library semver patch version\n"
"\n"
"Test Options:\n"
" --test-filter [text] skip tests that do not match filter\n"
" --test-name-prefix [text] add prefix to all tests\n"
" --test-cmd [arg] specify test execution command one arg at a time\n"
" --test-cmd-bin appends test binary path to test cmd args\n"
, arg0);
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
static const char *ZIG_ZEN = "\n"
@ -144,15 +155,16 @@ static int print_target_list(FILE *f) {
}
enum Cmd {
CmdInvalid,
CmdNone,
CmdBuild,
CmdBuiltin,
CmdHelp,
CmdRun,
CmdTargets,
CmdTest,
CmdTranslateC,
CmdVersion,
CmdZen,
CmdTranslateC,
CmdTargets,
};
static const char *default_zig_cache_name = "zig-cache";
@ -251,7 +263,7 @@ int main(int argc, char **argv) {
if (init_kind != InitKindNone) {
if (argc >= 3) {
fprintf(stderr, "Unexpected extra argument: %s\n", argv[2]);
return usage(arg0);
return print_error_usage(arg0);
}
Buf *cmd_template_path = buf_alloc();
os_path_join(get_zig_special_dir(), buf_create_from_str(init_cmd), cmd_template_path);
@ -326,7 +338,7 @@ int main(int argc, char **argv) {
}
}
Cmd cmd = CmdInvalid;
Cmd cmd = CmdNone;
EmitFileType emit_file_type = EmitFileTypeBinary;
const char *in_file = nullptr;
const char *out_file = nullptr;
@ -547,7 +559,7 @@ int main(int argc, char **argv) {
} else if (strcmp(arg, "--pkg-begin") == 0) {
if (i + 2 >= argc) {
fprintf(stderr, "Expected 2 arguments after --pkg-begin\n");
return usage(arg0);
return print_error_usage(arg0);
}
CliPkg *new_cur_pkg = allocate<CliPkg>(1);
i += 1;
@ -565,7 +577,7 @@ int main(int argc, char **argv) {
cur_pkg = cur_pkg->parent;
} else if (i + 1 >= argc) {
fprintf(stderr, "Expected another argument after %s\n", arg);
return usage(arg0);
return print_error_usage(arg0);
} else {
i += 1;
if (strcmp(arg, "--output") == 0) {
@ -581,7 +593,7 @@ int main(int argc, char **argv) {
color = ErrColorOff;
} else {
fprintf(stderr, "--color options are 'auto', 'on', or 'off'\n");
return usage(arg0);
return print_error_usage(arg0);
}
} else if (strcmp(arg, "--cache") == 0) {
if (strcmp(argv[i], "auto") == 0) {
@ -592,7 +604,7 @@ int main(int argc, char **argv) {
enable_cache = CacheOptOff;
} else {
fprintf(stderr, "--cache options are 'auto', 'on', or 'off'\n");
return usage(arg0);
return print_error_usage(arg0);
}
} else if (strcmp(arg, "--emit") == 0) {
if (strcmp(argv[i], "asm") == 0) {
@ -603,7 +615,7 @@ int main(int argc, char **argv) {
emit_file_type = EmitFileTypeLLVMIr;
} else {
fprintf(stderr, "--emit options are 'asm', 'bin', or 'llvm-ir'\n");
return usage(arg0);
return print_error_usage(arg0);
}
} else if (strcmp(arg, "--name") == 0) {
out_name = argv[i];
@ -672,10 +684,10 @@ int main(int argc, char **argv) {
test_exec_args.append(argv[i]);
} else {
fprintf(stderr, "Invalid argument: %s\n", arg);
return usage(arg0);
return print_error_usage(arg0);
}
}
} else if (cmd == CmdInvalid) {
} else if (cmd == CmdNone) {
if (strcmp(arg, "build-exe") == 0) {
cmd = CmdBuild;
out_type = OutTypeExe;
@ -685,6 +697,8 @@ int main(int argc, char **argv) {
} else if (strcmp(arg, "build-lib") == 0) {
cmd = CmdBuild;
out_type = OutTypeLib;
} else if (strcmp(arg, "help") == 0) {
cmd = CmdHelp;
} else if (strcmp(arg, "run") == 0) {
cmd = CmdRun;
out_type = OutTypeExe;
@ -703,7 +717,7 @@ int main(int argc, char **argv) {
cmd = CmdBuiltin;
} else {
fprintf(stderr, "Unrecognized command: %s\n", arg);
return usage(arg0);
return print_error_usage(arg0);
}
} else {
switch (cmd) {
@ -719,16 +733,17 @@ int main(int argc, char **argv) {
}
} else {
fprintf(stderr, "Unexpected extra parameter: %s\n", arg);
return usage(arg0);
return print_error_usage(arg0);
}
break;
case CmdBuiltin:
case CmdHelp:
case CmdVersion:
case CmdZen:
case CmdTargets:
fprintf(stderr, "Unexpected extra parameter: %s\n", arg);
return usage(arg0);
case CmdInvalid:
return print_error_usage(arg0);
case CmdNone:
zig_unreachable();
}
}
@ -751,19 +766,19 @@ int main(int argc, char **argv) {
if (target_arch) {
if (parse_target_arch(target_arch, &target->arch)) {
fprintf(stderr, "invalid --target-arch argument\n");
return usage(arg0);
return print_error_usage(arg0);
}
}
if (target_os) {
if (parse_target_os(target_os, &target->os)) {
fprintf(stderr, "invalid --target-os argument\n");
return usage(arg0);
return print_error_usage(arg0);
}
}
if (target_environ) {
if (parse_target_environ(target_environ, &target->env_type)) {
fprintf(stderr, "invalid --target-environ argument\n");
return usage(arg0);
return print_error_usage(arg0);
}
}
}
@ -785,13 +800,13 @@ int main(int argc, char **argv) {
{
if (cmd == CmdBuild && !in_file && objects.length == 0 && asm_files.length == 0) {
fprintf(stderr, "Expected source file argument or at least one --object or --assembly argument.\n");
return usage(arg0);
return print_error_usage(arg0);
} else if ((cmd == CmdTranslateC || cmd == CmdTest || cmd == CmdRun) && !in_file) {
fprintf(stderr, "Expected source file argument.\n");
return usage(arg0);
return print_error_usage(arg0);
} else if (cmd == CmdBuild && out_type == OutTypeObj && objects.length != 0) {
fprintf(stderr, "When building an object file, --object arguments are invalid.\n");
return usage(arg0);
return print_error_usage(arg0);
}
assert(cmd != CmdBuild || out_type != OutTypeUnknown);
@ -820,7 +835,7 @@ int main(int argc, char **argv) {
if (need_name && buf_out_name == nullptr) {
fprintf(stderr, "--name [name] not provided and unable to infer\n\n");
return usage(arg0);
return print_error_usage(arg0);
}
Buf *zig_root_source_file = (cmd == CmdTranslateC) ? nullptr : in_file_buf;
@ -1012,6 +1027,8 @@ int main(int argc, char **argv) {
zig_unreachable();
}
}
case CmdHelp:
return print_full_usage(arg0);
case CmdVersion:
printf("%s\n", ZIG_VERSION_STRING);
return EXIT_SUCCESS;
@ -1020,7 +1037,8 @@ int main(int argc, char **argv) {
return EXIT_SUCCESS;
case CmdTargets:
return print_target_list(stdout);
case CmdInvalid:
return usage(arg0);
case CmdNone:
fprintf(stderr, "Zig programming language\n");
return print_error_usage(arg0);
}
}