cmd/v: implement `help`

pull/4004/head
lutherwenxu 2020-03-14 03:52:49 +08:00 committed by GitHub
parent 920ab79665
commit c2ffd027d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 384 additions and 209 deletions

View File

@ -0,0 +1,15 @@
module vhelp
import os
pub fn show_topic(topic string) {
vexe := os.realpath(os.getenv('VEXE'))
vroot := os.dir(vexe)
target_topic := os.join_path(vroot,'cmd','v','internal','help','${topic}.txt')
content := os.read_file(target_topic) or {
eprintln('Unknown topic: $topic')
exit(1)
}
println(content)
}

View File

@ -11,6 +11,7 @@ import (
v.fmt
v.parser
v.table
vhelp
)
struct FormatOptions {
@ -93,7 +94,7 @@ fn main() {
files << file
}
if files.len == 0 {
usage()
vhelp.show_topic('fmt')
exit(0)
}
mut cli_args_no_files := []string
@ -295,22 +296,6 @@ fn (foptions &FormatOptions) post_process_file(file string, formatted_file_path
print(formatted_fc)
}
fn usage() {
print('Usage: cmd/tools/vfmt [flags] fmt path_to_source.v [path_to_other_source.v]
Formats the given V source files, and prints their formatted source to stdout.
Options:
-c check if file is already formatted.
If it is not, print filepath, and exit with code 2.
-diff display only diffs between the formatted source and the original source.
-l list files whose formatting differs from vfmt.
-w write result to (source) file(s) instead of to stdout.
-2 Use the new V parser/vfmt. NB: this is EXPERIMENTAL for now.
The new vfmt is much faster and more forgiving.
It also may EAT some of your code for now.
Please be careful, and make frequent BACKUPS, when running with -vfmt2 .
')
}
fn find_working_diff_command() ?string {
for diffcmd in ['colordiff', 'diff', 'colordiff.exe', 'diff.exe'] {
p := os.exec('$diffcmd --version') or {

View File

@ -5,6 +5,7 @@ import (
os
os.cmdline
json
vhelp
)
const (
@ -46,7 +47,7 @@ fn main() {
params := cmdline.only_non_options(args[1..])
verbose_println('cli params: $params')
if params.len < 1 {
vpm_help([])
vpm_help()
exit(5)
}
vpm_command := params[0]
@ -55,7 +56,7 @@ fn main() {
// println('module names: ') println(module_names)
match vpm_command {
'help' {
vpm_help(module_names)
vpm_help()
}
'search' {
vpm_search(module_names)
@ -82,11 +83,7 @@ fn main() {
fn vpm_search(keywords []string) {
if settings.is_help {
println('Usage:')
println(' v search keyword1 [keyword2] [...]')
println(' ^^^^^^^^^^^^^^^^^ will search https://vpm.vlang.io/ for matching modules,')
println(' and will show details about them')
show_vpm_options()
vhelp.show_topic('search')
exit(0)
}
if keywords.len == 0 {
@ -124,10 +121,7 @@ fn vpm_search(keywords []string) {
fn vpm_install(module_names []string) {
if settings.is_help {
println('Usage:')
println(' v install module [module] [module] [...]')
println(' ^^^^^^^^^^^^^ will install the modules you specified')
show_vpm_options()
vhelp.show_topic('install')
exit(0)
}
if module_names.len == 0 {
@ -209,12 +203,7 @@ fn vpm_install(module_names []string) {
fn vpm_update(m []string) {
mut module_names := m
if settings.is_help {
println('Usage: ')
println(' a) v update module [module] [module] [...]')
println(' ^^^^^^^^^^^^ will update the listed modules to their latest versions')
println(' b) v update')
println(' ^^^^^^^^^^^^ will update ALL installed modules to their latest versions')
show_vpm_options()
vhelp.show_topic('update')
exit(0)
}
if module_names.len == 0 {
@ -256,12 +245,7 @@ fn vpm_update(m []string) {
fn vpm_remove(module_names []string) {
if settings.is_help {
println('Usage: ')
println(' a) v remove module [module] [module] [...]')
println(' ^^^^^^^^^^^^ will remove the listed modules')
println(' b) v remove')
println(' ^^^^^^^^^^^^ will remove ALL installed modules')
show_vpm_options()
vhelp.show_topic('remove')
exit(0)
}
if module_names.len == 0 {
@ -312,14 +296,8 @@ fn ensure_vmodules_dir_exist() {
}
}
fn vpm_help(module_names []string) {
println('Usage:')
println(' a) v install module [module] [module] [...]')
println(' b) v update [module] [...]')
println(' c) v remove [module] [...]')
println(' d) v search keyword1 [keyword2] [...]')
println('')
println(' You can also pass -h or --help after each vpm command from the above, to see more details about it.')
fn vpm_help() {
vhelp.show_topic('vpm')
}
fn vcs_used_in_dir(dir string) ?[]string {
@ -342,7 +320,7 @@ fn get_installed_modules() []string {
}
mut modules := []string
for dir in dirs {
adir := os.join_path(settings.vmodules_path, dir)
adir := os.join_path(settings.vmodules_path,dir)
if dir in excluded_dirs || !os.is_dir(adir) {
continue
}
@ -351,7 +329,7 @@ fn get_installed_modules() []string {
continue
}
for m in mods {
vcs_used_in_dir(os.join_path(adir, m)) or {
vcs_used_in_dir(os.join_path(adir,m)) or {
continue
}
modules << '${author}.$m'
@ -399,7 +377,7 @@ fn get_all_modules() []string {
}
fn resolve_dependencies(name, module_path string, module_names []string) {
vmod_path := os.join_path(module_path, 'v.mod')
vmod_path := os.join_path(module_path,'v.mod')
if !os.exists(vmod_path) {
return
}
@ -481,13 +459,6 @@ fn init_settings() {
s.vmodules_path = os.home_dir() + '.vmodules'
}
fn show_vpm_options() {
println('Options:')
println(' -help - Show usage info')
println(' -verbose - Print more details about the performed operation')
println(' -server-url - When doing network operations, use this vpm server. Can be given multiple times.')
}
fn verbose_println(s string) {
if settings.is_verbose {
println(s)

View File

@ -41,7 +41,7 @@ fn parse_arguments(args []string) (pref.Preferences, []string) {
}
'build' {
remaining = remaining[1..]
if remaining[0] == 'module' {
if remaining.len > 0 && remaining[0] == 'module' {
remaining = remaining[1..]
//TODO Figure out module
println('V error: Module compilation is not ready yet.')
@ -169,7 +169,7 @@ fn parse_options(flag string, f mut flag.Instance, prefs mut pref.Preferences) {
'translated' {
prefs.translated = f.bool()
}
'backend' {
'b', 'backend' {
// Just consume it. The option is handled outside of this function
f.string() or { return }
}

View File

@ -0,0 +1,13 @@
Usage:
v bin2v [options] FILE [FILE]...
Converts a list of arbitrary files into a single v module file.
You can use this tool to embed binary files, like pictures or fonts inside
the executable of a v program, such that it would not need access to external
resources during runtime, and it would be as self-contained as possible.
Options:
-h, --help Show this help screen.
-m, --module <string> Name of the generated module.
-p, --prefix <string> A prefix put before each resource name.

View File

@ -0,0 +1,61 @@
Usage: v [build flags] ['build'] <file.v|directory>
This command compiles the given target, along with their dependencies, into an executable.
This help topic explores C-backend specific build flags.
For help regarding building an executable, see `v help build`.
These build flags are enabled on `build` and `run` as long as the backend is set to `c`:
-arch <architecture>
Changes the architecture that V will tell the C compiler to build.
List of supported architectures: `x86` and `x64` (default).
-cc <compiler>, -compiler <compiler>
Changes the C compiler V invokes to the specified compiler.
The C compiler is required to support C99.
Officially supported/tested C compilers include: `clang`, `gcc`, `tcc`, `mingw-w64` and `msvc`.
-cf <flag>, -cflags <flag>
Passes the provided flag as is to the C compiler.
Can be specified multiple times to provide multiple flags.
Use quotes to wrap the flag argument if it contains spaces.
-cg, -cdebug
Enables debug mode while preserving C line numbers in the compiled executable.
This allows issues regarding C compilation to be located more easily.
-compress
Strips the compiled executable to compress it.
-csource <prettify|keep|drop>
Specifies how V deals with the intermediate C source code.
* `prettify` - The C source code will be kept.
`clang-format` is used to prettify the C source code before compiling it.
* `keep` - The C source code will be kept as generated by V.
* `drop` (default) - The C source code will be deleted after compiling the executable.
-freestanding
Builds the executable without dependency on libc.
Supported only on `linux` targets currently.
-live
Builds the executable with live capabilities (`[live]`).
-manual-free
Enables manually freeing on all V code. This will cause memory leaks in vlib.
Currently enabled until a stable auto-free system is in place.
-os <os>, -target-os <os>
Changes the target OS that V tries to compile for.
By default, the target OS is the host system.
When OS is `cross`, V will attempt to output cross-platform C code.
List of OS supported by V: `linux`, `windows`, `mac`, `freebsd`, `openbsd`, `netbsd`,
`dragonfly`, `solaris`, `android` and `haiku`.
-sanitize
Passes flags related to sanitization to the C compiler.
-shared
Tells V to compile a shared object instead of an executable.
The resulting file extension will be `.dll` on Windows and `.so` on Unix systems

View File

@ -0,0 +1,92 @@
Usage: v [build flags] ['build'] <file.v|directory>
This command compiles the given target, along with their dependencies, into an executable.
When compiling packages, build ignores files that end in '_test.v'.
When compiling a single main package, build writes the resulting executable to an output file
named after the build target. ('v abc.v' and 'v abc/' both write either 'abc' or 'abc.exe')
The '.exe' suffix is added when writing a Windows executable.
By default, the executable is stored in the same directory as the compiled source code.
The -o flag forces build to write the resulting executable or object to the d output file or directory,
instead of the default behavior described in the last two paragraphs.
You can put common options inside an environment variable named VFLAGS, so that
you don't have to repeat them.
You can set it like this: `export VFLAGS="-cc clang -debug"` on *nix,
`set VFLAGS=-cc msvc` on Windows.
V respects the TMPDIR environment variable, and will put .tmp.c files in TMPDIR/v/ .
If you have not set it, a suitable platform specific folder (like /tmp) will be used.
The build flags are shared by the build and run commands:
-b <backend>, -backend <backend>
Specify the backend to use while building the executable.
Current list of supported backends:
* `c` (default) - V outputs C source code which is passed to a C compiler to be compiled.
* `js` - V outputs JS source code which can be passed to NodeJS to be ran.
* `x64` - V outputs Linux 64-bit executable directly (highly experimental!).
* `v2`/`experimental` - Invokes the experimental AST-powered V compiler that will replace the
current backends when finished
-d <flag>[=<value>], -define <flag>[=<value>]
Defines the provided flag.
If value is not provided, it is assumed to be set to `true`.
`value` should be `1` or `0` to indicate `true` and `false` respectively otherwise.
-e <experiment>, -experiments <experiment>
Enable the specified experiment.
Currently, the only experiment available is: `prealloc`
-full-rebuild
Forces a full rebuild of all dependencies.
Enabled by default currently until caching works reliably.
-g
Compiles the executable in debug mode, allowing code to be debugged more easily.
-o <output>, -output <output>
Forces V to output the executable in a specific location.
(relative to the current working directory if not absolute)
-obf, -obfuscate
Turns on obfuscation for the code being built. Currently only renames symbols.
-path
Specifies the order of path V looks up in while searching for imported dependencies,
separated by pipes (`|`). In addition to absolute paths, you can
also use these special strings too:
@vmodules - replaced with the location of the global ~/.vmodules/ folder
(modules installed with `v install` are there).
@vlib - replaced with the location of the v's vlib folder.
Using these, you can arrange for very flexible search orders for you project, for example:
-path "/v/my_project_private_modules|@vlib|@vmodules"
By default, -path is just "@vlib|@vmodules" .
-prod
Compiles the executable in production mode where most optimizations are enabled.
-prof, -profile
Compiles the executable with all functions profiled.
-stats
Enable more detailed statistics reporting, while compiling test files.
You can use that with `v test` too, for example:
v -stats test vlib/
... will run test_ functions inside all _test.v files inside vlib/ ,
and will report detailed statistics about how much time each test_ function took, how many
assertions were made, how many tests passed/failed and so on.
-translated
Enables features that are discouraged in regular V code but required for translated V code.
-v, -vv, -vvv
Enable varying verbosity in the V compiler while compiling
For C-specific build flags, use `v help build-c`.
See also:
`v help run` for documentation regarding `v run`.

View File

@ -0,0 +1,34 @@
V is a tool for managing V source code.
Usage:
v [options] [command] [arguments]
Examples:
v hello.v compile the file `hello.v` and output it as `hello` or `hello.exe`
v run hello.v same as above but also run the produced executable immediately after compilation
v -o h.c hello.v translate `hello.v` to `h.c` . Do not compile further.
The commands are:
build build V code in the provided path (default)
create setup the file structure for a V project
doc generates the documentation for a V module (coming soon in 0.3)
fmt format the V code provided
repl run the REPL
run compile and run a V program
symlink create a symbolic link for V
test run all test files in the provided directory
translate translate C code to V (coming soon in 0.3)
up run the V self-updater
self run the V self-compiler
version prints the version text and exits
install installs a module from VPM
remove removes a module that was installed from VPM
search searches for a module from VPM
update updates an installed module from VPM
Use "v help <command>" for more information about a command, example: `v help build`
Use "v help other" to see less frequently used commands.
Note: Help is required to write more help topics.
Only build, fmt, run, test, search, install, remove, update, bin2v are properly documented currently.

View File

@ -1,136 +0,0 @@
module help
pub const (
help_text = 'V is a tool for managing V source code.
Usage:
v [options] [command] [arguments]
Examples:
v hello.v compile the file `hello.v` and output it as `hello` or `hello.exe`
v run hello.v same as above but also run the produced executable immediately after compilation
The commands are:
build build V code in the provided path (default)
create setup the file structure for a V project
doc generates the documentation for a V module (coming soon in 0.3)
fmt format the V code provided
repl run the REPL
run compile and run a V program
symlink create a symbolic link for V
translate translate C code to V (coming soon in 0.3)
up run the V self-updater
self run the V self-compiler
version prints the version text and exits
install installs a module from VPM
remove removes a module that was installed from VPM
search searches for a module from VPM
update updates an installed module from VPM
bin2v embed a binary file as a constant and output it in a V file
build-examples test if all examples can be built
build-tools test if all tools can be built
build-vbinaries test if V can be built with different configuration
test run all test files in the provided directory
test-fmt test if all files in the current directory is formatted properly
test-compiler run the V self-test suite to make sure V is working properly
setup-freetype setup thirdparty freetype on Windows
For a comprehensive list of options, please refer to `v -v help`.'
//Use "v help <command>" for more information about a command.'
//TODO When docs have been written for all the subcommands, delete the verbose help text and
// tell the user to use "v help <command>" instead.
verbose_help_text = 'Usage: v [options/commands] [file.v | directory]
When V is run without any arguments, it is run in REPL mode.
When given a .v file, it will be compiled. The executable will have the
same name as the input .v file: `v foo.v` produces `./foo` on *nix systems,
`foo.exe` on Windows.
You can use -o to specify a different output executable\'s name.
When given a directory, all .v files contained in it will be compiled as
part of a single main module.
By default the executable will have the same name as the directory.
To compile all V files in current directory, run `v .`
Any file ending in _test.v, will be treated as a test.
It will be compiled and run, evaluating the assert statements in every
function named test_xxx.
You can put common options inside an environment variable named VFLAGS, so that
you don\'t have to repeat them.
You can set it like this: `export VFLAGS="-cc clang -debug"` on *nix,
`set VFLAGS=-cc msvc` on Windows.
V respects the TMPDIR environment variable, and will put .tmp.c files in TMPDIR/v/ .
If you have not set it, a suitable platform specific folder (like /tmp) will be used.
Options/commands:
-h, help Display this information.
-o <file> Write output to <file>.
-o <file>.c Produce C source without compiling it.
-o <file>.js Produce JavaScript source.
-prod Build an optimized executable.
-version Display compiler version and git hash of the compiler source.
-verbose <level> Produce a verbose log about what the compiler is doing, where it seeks for files and so on.
-v Shorthand for `-verbose 1`
-live Enable hot code reloading (required by functions marked with [live]).
-os <OS> Produce an executable for the selected OS.
OS can be linux, mac, windows, msvc.
Use msvc if you want to use the MSVC compiler on Windows.
-shared Build a shared library.
-stats Show additional stats when compiling/running tests. Try `v -stats test .`
-cache Turn on usage of the precompiled module cache.
It very significantly speeds up secondary compilations.
-obf Obfuscate the resulting binary.
-compress Compress the resulting binary.
- Shorthand for `v repl`.
Options for debugging/troubleshooting v programs:
-g Generate debugging information in the backtraces. Add *V* line numbers to the generated executable.
-cg Same as -g, but add *C* line numbers to the generated executable instead of *V* line numbers.
-csource keep Do NOT remove the generated .tmp.c files after compilation.
It is useful when using debuggers like gdb/visual studio, when given after `-g` / `-cg`.
-csource prettify Run clang-format over the generated C file, so that it looks nicer. Requires you to have clang-format.
-show_c_cmd Print the full C compilation command and how much time it took. See also `-verbose`.
-cc <ccompiler> Specify which C compiler you want to use as a C backend.
The C backend compiler should be able to handle C99 compatible C code.
Common C compilers are gcc, clang, tcc, icc, cl...
-cflags <flags> Pass additional C flags to the C backend compiler.
Example: -cflags `sdl2-config --cflags`
Commands:
up Update V. Run `v up` at least once per day, since V development is rapid and features/bugfixes are added constantly.
run <file.v> Build and execute the V program in file.v. You can add arguments for the V program *after* the file name.
build <module> Compile a module into an object file.
self Self-compile V from local source files.
repl Run the V REPL. If V is running in a tty terminal, the REPL is interactive, otherwise it just reads from stdin.
symlink Useful on Unix systems. Symlinks the current V executable to /usr/local/bin/v, so that V is globally available.
test-compiler Run all V test files, and compile all V examples.
test folder/ Run all V test files located in the folder and its subfolders. You can also pass individual _test.v files too.
fmt Run vfmt to format the source code. [wip]
doc Run vdoc over the source code and produce documentation.
translate Translates C to V. [wip, will be available in V 0.3]
create Create a new v project interactively. Answer the questions, and run it with `v run projectname`
setup-freetype Setup thirdparty freetype on Windows.
V package management commands:
search keywords Search the https://vpm.vlang.io/ module repository for matching modules and shows their details.
install <module> Install a user module from https://vpm.vlang.io/.
update [module] Updates an already installed module, or ALL installed modules at once, when no module name is given.
remove [module] Removes an installed module, or ALL installed modules at once, when no module name is given.
'
)
/*
- To disable automatic formatting:
v -nofmt file.v
*/

View File

@ -0,0 +1,15 @@
Usage:
v [flags] fmt path_to_source.v [path_to_other_source.v]
Formats the given V source files, then prints their formatted source to stdout.
Options:
-c check if file is already formatted.
If it is not, print filepath, and exit with code 2.
-diff display only diffs between the formatted source and the original source.
-l list files whose formatting differs from vfmt.
-w write result to (source) file(s) instead of to stdout.
-2 Use the new V parser/vfmt. NB: this is EXPERIMENTAL for now.
The new vfmt is much faster and more forgiving.
It also may EAT some of your code for now.
Please be careful, and make frequent BACKUPS, when running with -vfmt2 .

View File

@ -0,0 +1,31 @@
module help
//TODO: move this file outside internal, and merge it with cmd/tools/modules/vhelp/vhelp.v .
import (
os
v.pref
)
const (
unknown_topic = 'V Error: Unknown help topic provided. Use `v help` for usage information.'
)
pub fn print_and_exit(topic string) {
vexe := pref.vexe_path()
vroot := os.dir(vexe)
for b in topic {
if (b >= `a` && b <= `z`) || b == `-` || (b >= `0` && b <= `9`) {
continue
}
println(unknown_topic)
exit(1)
}
target_topic := os.join_path(vroot, 'cmd', 'v', 'internal', 'help', '${topic}.txt')
content := os.read_file(target_topic) or {
println(unknown_topic)
exit(1)
}
println(content)
exit(0)
}

View File

@ -0,0 +1,7 @@
Usage:
v install module [module] [module] [...]
^^^^^^^^^^^^^ will install the modules you specified
Options:
-help - Show usage info
-verbose - Print more details about the performed operation
-server-url - When doing network operations, use this vpm server. Can be given multiple times.

View File

@ -0,0 +1,14 @@
These are utility commands that you can also launch through v,
but which are used less frequently by users:
bin2v convert a binary file to a v source file,
that can be later embedded in a module or program
build-examples test if all examples can be built
build-tools test if all tools can be built
build-vbinaries test if V can be built with different configuration
test-fmt test if all files in the current directory is formatted properly
test-compiler test if V is working properly by running all tests, including the compiler ones
NB: this can take a minute or two to run
setup-freetype setup thirdparty freetype on Windows

View File

@ -0,0 +1,9 @@
Usage:
a) v remove module [module] [module] [...]
^^^^^^^^^^^^ will remove the listed modules
b) v remove
^^^^^^^^^^^^ will remove ALL installed modules
Options:
-help - Show usage info
-verbose - Print more details about the performed operation
-server-url - When doing network operations, use this vpm server. Can be given multiple times.

View File

@ -0,0 +1,10 @@
Usage: v [build flags] run <file.v|directory> [arguments...]
This command is equivalent to running `v build` and running the compiled executable.
The executable is passed the arguments as provided in [arguments...].
The exit status of Run will be:
* `1` if the compilation failed.
* The exit code of the compiled executable otherwise.
For more about build flags, see `v help build`.

View File

@ -0,0 +1,8 @@
Usage:
v search keyword1 [keyword2] [...]
^^^^^^^^^^^^^^^^^ will search https://vpm.vlang.io/ for matching modules,
and will show details about them
Options:
-help - Show usage info
-verbose - Print more details about the performed operation
-server-url - When doing network operations, use this vpm server. Can be given multiple times.

View File

@ -0,0 +1,26 @@
Usage:
A)
v test folder/ : run all v tests in the given folder.
v -stats test folder/ : the same, but print more stats.
B)
v test file_test.v : run test functions in a given test file.
v -stats test file_test.v : as above, but with more stats.
NB: you can also give many and mixed folder/ file_test.v arguments after test.
NB 2: very frequently, when you work on a module, you can cd into its folder,
and then you can just run:
v test .
... which will run all the module _test.v files.
NB 3: V builtin testing requires you to name your files with a _test.v
suffix, and to name your test functions with test_ prefix. Each test_
function in a _test.v file will be called automatically by the test
framework. You can use `assert condition` inside each test_ function.
If the asserted condition fails, then v will record that and produce a
more detailed error message about where the failure was.
After all test_ functions are called, if you passed -stats, v will
produce a report about how many tests passed, and how many failed.

View File

@ -0,0 +1,9 @@
Usage:
a) v update module [module] [module] [...]
^^^^^^^^^^^^ will update the listed modules to their latest versions
b) v update
^^^^^^^^^^^^ will update ALL installed modules to their latest versions
Options:
-help - Show usage info
-verbose - Print more details about the performed operation
-server-url - When doing network operations, use this vpm server. Can be given multiple times.

View File

@ -0,0 +1,7 @@
Usage:
a) v install module [module] [module] [...]
b) v update [module] [...]
c) v remove [module] [...]
d) v search keyword1 [keyword2] [...]
You can also pass -h or --help after each vpm command from the above, to see more details about it.

View File

@ -52,8 +52,7 @@ fn main() {
print_version_and_exit()
}
if values.len == 0 && prefs.action == .help {
println('Use `v help` for usage information.')
exit(1)
invoke_help_and_exit(values)
}
if values.len == 0 || values[0] == '-' || values[0] == 'repl' {
// Check for REPL.
@ -98,18 +97,8 @@ fn main() {
return
}
'help' {
// We check if the arguments are empty as we don't want to steal it from tools
// TODO Call actual help tool
disallow_unknown_flags(prefs)
if prefs.verbosity.is_higher_or_equal(.level_one) {
println(help.verbose_help_text)
}
else {
println(help.help_text)
}
if values.len > 1 {
println('Note: Actual help module is coming soon. Feel free to ask on the official channels for clarification.')
}
invoke_help_and_exit(values)
return
}
'version' {
@ -134,6 +123,21 @@ fn print_version_and_exit() {
exit(0)
}
fn invoke_help_and_exit(remaining []string) {
match remaining.len {
0, 1 {
help.print_and_exit('default')
}
2 {
help.print_and_exit(remaining[1])
}
else {}
}
println('V Error: Expected only one help topic to be provided.')
println('For usage information, use `v help`.')
exit(1)
}
[inline]
fn disallow_unknown_flags(prefs flag.MainCmdPreferences) {
if prefs.unknown_flag == '' {