diff options
| author | 2018-06-01 08:37:21 +0200 | |
|---|---|---|
| committer | 2018-06-01 08:37:21 +0200 | |
| commit | 61f141ca6a5b6f3d7ab0eade8d6f8fbe0ac6a28e (patch) | |
| tree | 98f75dfc4348b0b1a48288e4e998844bb6eca3cf | |
| parent | Added example of how to parse Zig args with clap.core (diff) | |
| download | zig-clap-61f141ca6a5b6f3d7ab0eade8d6f8fbe0ac6a28e.tar.gz zig-clap-61f141ca6a5b6f3d7ab0eade8d6f8fbe0ac6a28e.tar.xz zig-clap-61f141ca6a5b6f3d7ab0eade8d6f8fbe0ac6a28e.zip | |
Core args now have a pointer to the param that the arg belongs to
| -rw-r--r-- | examples/core.zig | 240 | ||||
| -rw-r--r-- | src/core.zig | 22 |
2 files changed, 183 insertions, 79 deletions
diff --git a/examples/core.zig b/examples/core.zig index f393e0f..8bcc928 100644 --- a/examples/core.zig +++ b/examples/core.zig | |||
| @@ -7,32 +7,21 @@ const mem = std.mem; | |||
| 7 | const Names = clap.Names; | 7 | const Names = clap.Names; |
| 8 | const Param = clap.Param; | 8 | const Param = clap.Param; |
| 9 | 9 | ||
| 10 | const Command = enum { | 10 | // TODO: More specific error in this func type. |
| 11 | Help, | 11 | const Command = fn(&mem.Allocator, &clap.ArgIterator) error!void; |
| 12 | Build, | ||
| 13 | BuildExe, | ||
| 14 | BuildLib, | ||
| 15 | BuildObj, | ||
| 16 | Fmt, | ||
| 17 | Run, | ||
| 18 | Targets, | ||
| 19 | Test, | ||
| 20 | Version, | ||
| 21 | Zen, | ||
| 22 | }; | ||
| 23 | 12 | ||
| 24 | const params = []Param(Command){ | 13 | const params = []Param(Command){ |
| 25 | Param(Command).init(Command.Help, false, Names.prefix("help")), | 14 | Param(Command).init(help, false, Names.prefix("help")), |
| 26 | Param(Command).init(Command.Build, false, Names.bare("build")), | 15 | Param(Command).init(cmdBuild, false, Names.bare("build")), |
| 27 | Param(Command).init(Command.BuildExe, false, Names.bare("build-exe")), | 16 | Param(Command).init(cmdBuildExe, false, Names.bare("build-exe")), |
| 28 | Param(Command).init(Command.BuildLib, false, Names.bare("build-lib")), | 17 | Param(Command).init(cmdBuildLib, false, Names.bare("build-lib")), |
| 29 | Param(Command).init(Command.BuildObj, false, Names.bare("build-obj")), | 18 | Param(Command).init(cmdBuildObj, false, Names.bare("build-obj")), |
| 30 | Param(Command).init(Command.Fmt, false, Names.bare("fmt")), | 19 | Param(Command).init(cmdFmt, false, Names.bare("fmt")), |
| 31 | Param(Command).init(Command.Run, false, Names.bare("run")), | 20 | Param(Command).init(cmdRun, false, Names.bare("run")), |
| 32 | Param(Command).init(Command.Targets, false, Names.bare("targets")), | 21 | Param(Command).init(cmdTargets, false, Names.bare("targets")), |
| 33 | Param(Command).init(Command.Test, false, Names.bare("test")), | 22 | Param(Command).init(cmdTest, false, Names.bare("test")), |
| 34 | Param(Command).init(Command.Version, false, Names.bare("version")), | 23 | Param(Command).init(cmdVersion, false, Names.bare("version")), |
| 35 | Param(Command).init(Command.Zen, false, Names.bare("zen")), | 24 | Param(Command).init(cmdZen, false, Names.bare("zen")), |
| 36 | }; | 25 | }; |
| 37 | 26 | ||
| 38 | const usage = | 27 | const usage = |
| @@ -79,24 +68,16 @@ pub fn main() !void { | |||
| 79 | return error.NoCommandFound; | 68 | return error.NoCommandFound; |
| 80 | }; | 69 | }; |
| 81 | 70 | ||
| 82 | switch (arg.id) { | 71 | try arg.param.id(allocator, parser.iter); |
| 83 | Command.Help => return, // debug.warn(usage), TODO: error: evaluation exceeded 1000 backwards branches | 72 | } |
| 84 | Command.Build => try cmdBuild(allocator, parser.iter), | 73 | |
| 85 | Command.BuildExe, | 74 | pub fn help(allocator: &mem.Allocator, args: &clap.ArgIterator) (error{}!void) { |
| 86 | Command.BuildLib, | 75 | // debug.warn(usage); TODO: error: evaluation exceeded 1000 backwards branches |
| 87 | Command.BuildObj, | ||
| 88 | Command.Fmt, | ||
| 89 | Command.Run, | ||
| 90 | Command.Targets, | ||
| 91 | Command.Test, | ||
| 92 | Command.Version, | ||
| 93 | Command.Zen => unreachable, | ||
| 94 | } | ||
| 95 | } | 76 | } |
| 96 | 77 | ||
| 97 | // cmd:build /////////////////////////////////////////////////////////////////////////////////////// | 78 | // cmd:build /////////////////////////////////////////////////////////////////////////////////////// |
| 98 | 79 | ||
| 99 | const BuildArg = enum { | 80 | const Build = enum { |
| 100 | Help, | 81 | Help, |
| 101 | Init, | 82 | Init, |
| 102 | BuildFile, | 83 | BuildFile, |
| @@ -111,20 +92,20 @@ const BuildArg = enum { | |||
| 111 | VerboseCImport, | 92 | VerboseCImport, |
| 112 | }; | 93 | }; |
| 113 | 94 | ||
| 114 | const build_params = []Param(BuildArg){ | 95 | const build_params = []Param(Build){ |
| 115 | Param(BuildArg).init(BuildArg.Help, false, Names.prefix("help")), | 96 | Param(Build).init(Build.Help, false, Names.prefix("help")), |
| 116 | Param(BuildArg).init(BuildArg.Init, false, Names.long("init")), | 97 | Param(Build).init(Build.Init, false, Names.long("init")), |
| 117 | Param(BuildArg).init(BuildArg.BuildFile, true, Names.long("build-file")), | 98 | Param(Build).init(Build.BuildFile, true, Names.long("build-file")), |
| 118 | Param(BuildArg).init(BuildArg.CacheDir, true, Names.long("cache-dir")), | 99 | Param(Build).init(Build.CacheDir, true, Names.long("cache-dir")), |
| 119 | Param(BuildArg).init(BuildArg.Verbose, false, Names.prefix("verbose")), | 100 | Param(Build).init(Build.Verbose, false, Names.prefix("verbose")), |
| 120 | Param(BuildArg).init(BuildArg.Prefix, true, Names.long("prefix")), | 101 | Param(Build).init(Build.Prefix, true, Names.long("prefix")), |
| 121 | 102 | ||
| 122 | Param(BuildArg).init(BuildArg.VerboseTokenize, false, Names.prefix("verbose-tokenize")), | 103 | Param(Build).init(Build.VerboseTokenize, false, Names.prefix("verbose-tokenize")), |
| 123 | Param(BuildArg).init(BuildArg.VerboseAst, false, Names.prefix("verbose-ast")), | 104 | Param(Build).init(Build.VerboseAst, false, Names.prefix("verbose-ast")), |
| 124 | Param(BuildArg).init(BuildArg.VerboseLink, false, Names.prefix("verbose-link")), | 105 | Param(Build).init(Build.VerboseLink, false, Names.prefix("verbose-link")), |
| 125 | Param(BuildArg).init(BuildArg.VerboseIr, false, Names.prefix("verbose-ir")), | 106 | Param(Build).init(Build.VerboseIr, false, Names.prefix("verbose-ir")), |
| 126 | Param(BuildArg).init(BuildArg.VerboseLlvmIr, false, Names.prefix("verbose-llvm-ir")), | 107 | Param(Build).init(Build.VerboseLlvmIr, false, Names.prefix("verbose-llvm-ir")), |
| 127 | Param(BuildArg).init(BuildArg.VerboseCImport, false, Names.prefix("verbose-cimport")), | 108 | Param(Build).init(Build.VerboseCImport, false, Names.prefix("verbose-cimport")), |
| 128 | }; | 109 | }; |
| 129 | 110 | ||
| 130 | const build_usage = | 111 | const build_usage = |
| @@ -176,26 +157,26 @@ fn cmdBuild(allocator: &mem.Allocator, args: &clap.ArgIterator) !void { | |||
| 176 | var verbose_llvm_ir = false; | 157 | var verbose_llvm_ir = false; |
| 177 | var verbose_cimport = false; | 158 | var verbose_cimport = false; |
| 178 | 159 | ||
| 179 | var parser = clap.Clap(BuildArg).init(build_params, args, allocator); | 160 | var parser = clap.Clap(Build).init(build_params, args, allocator); |
| 180 | defer parser.deinit(); | 161 | defer parser.deinit(); |
| 181 | 162 | ||
| 182 | while (parser.next() catch |err| { | 163 | while (parser.next() catch |err| { |
| 183 | debug.warn("{}.\n", @errorName(err)); | 164 | debug.warn("{}.\n", @errorName(err)); |
| 184 | // debug.warn(build_usage); TODO: error: evaluation exceeded 1000 backwards branches | 165 | // debug.warn(build_usage); TODO: error: evaluation exceeded 1000 backwards branches |
| 185 | return err; | 166 | return err; |
| 186 | }) |arg| switch (arg.id) { | 167 | }) |arg| switch (arg.param.id) { |
| 187 | BuildArg.Help => return, // debug.warn(build_usage) TODO: error: evaluation exceeded 1000 backwards branches, | 168 | Build.Help => return, // debug.warn(build_usage) TODO: error: evaluation exceeded 1000 backwards branches, |
| 188 | BuildArg.Init => init = true, | 169 | Build.Init => init = true, |
| 189 | BuildArg.BuildFile => build_file = ??arg.value, | 170 | Build.BuildFile => build_file = ??arg.value, |
| 190 | BuildArg.CacheDir => cache_dir = ??arg.value, | 171 | Build.CacheDir => cache_dir = ??arg.value, |
| 191 | BuildArg.Verbose => verbose = true, | 172 | Build.Verbose => verbose = true, |
| 192 | BuildArg.Prefix => prefix = ??arg.value, | 173 | Build.Prefix => prefix = ??arg.value, |
| 193 | BuildArg.VerboseTokenize => verbose_tokenize = true, | 174 | Build.VerboseTokenize => verbose_tokenize = true, |
| 194 | BuildArg.VerboseAst => verbose_ast = true, | 175 | Build.VerboseAst => verbose_ast = true, |
| 195 | BuildArg.VerboseLink => verbose_link = true, | 176 | Build.VerboseLink => verbose_link = true, |
| 196 | BuildArg.VerboseIr => verbose_ir = true, | 177 | Build.VerboseIr => verbose_ir = true, |
| 197 | BuildArg.VerboseLlvmIr => verbose_llvm_ir = true, | 178 | Build.VerboseLlvmIr => verbose_llvm_ir = true, |
| 198 | BuildArg.VerboseCImport => verbose_cimport = true, | 179 | Build.VerboseCImport => verbose_cimport = true, |
| 199 | }; | 180 | }; |
| 200 | 181 | ||
| 201 | debug.warn("command: build\n"); | 182 | debug.warn("command: build\n"); |
| @@ -270,8 +251,8 @@ const BuildGeneric = enum { | |||
| 270 | VerPatch, | 251 | VerPatch, |
| 271 | }; | 252 | }; |
| 272 | 253 | ||
| 273 | const build_generic_params = []Param(BuildArg){ | 254 | const build_generic_params = []Param(BuildGeneric){ |
| 274 | Param(BuildArg).init(BuildArg.Help, false, Names.prefix("help")), | 255 | Param(BuildGeneric).init(BuildGeneric.Help, false, Names.prefix("help")), |
| 275 | }; | 256 | }; |
| 276 | 257 | ||
| 277 | const build_generic_usage = | 258 | const build_generic_usage = |
| @@ -338,3 +319,126 @@ const build_generic_usage = | |||
| 338 | \\ | 319 | \\ |
| 339 | \\ | 320 | \\ |
| 340 | ; | 321 | ; |
| 322 | |||
| 323 | |||
| 324 | fn cmdBuildExe(allocator: &mem.Allocator, args: &clap.ArgIterator) (error{}!void) { | ||
| 325 | } | ||
| 326 | |||
| 327 | // cmd:build-lib /////////////////////////////////////////////////////////////////////////////////// | ||
| 328 | |||
| 329 | fn cmdBuildLib(allocator: &mem.Allocator, args: &clap.ArgIterator) (error{}!void) { | ||
| 330 | } | ||
| 331 | |||
| 332 | // cmd:build-obj /////////////////////////////////////////////////////////////////////////////////// | ||
| 333 | |||
| 334 | fn cmdBuildObj(allocator: &mem.Allocator, args: &clap.ArgIterator) (error{}!void) { | ||
| 335 | } | ||
| 336 | |||
| 337 | // cmd:fmt ///////////////////////////////////////////////////////////////////////////////////////// | ||
| 338 | |||
| 339 | const usage_fmt = | ||
| 340 | \\usage: zig fmt [file]... | ||
| 341 | \\ | ||
| 342 | \\ Formats the input files and modifies them in-place. | ||
| 343 | \\ | ||
| 344 | \\Options: | ||
| 345 | \\ --help Print this help and exit | ||
| 346 | \\ --color [auto|off|on] Enable or disable colored error messages | ||
| 347 | \\ | ||
| 348 | \\ | ||
| 349 | ; | ||
| 350 | |||
| 351 | fn cmdFmt(allocator: &mem.Allocator, args: &clap.ArgIterator) (error{}!void) { | ||
| 352 | } | ||
| 353 | |||
| 354 | // cmd:targets ///////////////////////////////////////////////////////////////////////////////////// | ||
| 355 | |||
| 356 | fn cmdTargets(allocator: &mem.Allocator, args: &clap.ArgIterator) (error{}!void) { | ||
| 357 | } | ||
| 358 | |||
| 359 | // cmd:version ///////////////////////////////////////////////////////////////////////////////////// | ||
| 360 | |||
| 361 | fn cmdVersion(allocator: &mem.Allocator, args: &clap.ArgIterator) (error{}!void) { | ||
| 362 | } | ||
| 363 | |||
| 364 | // cmd:test //////////////////////////////////////////////////////////////////////////////////////// | ||
| 365 | |||
| 366 | const usage_test = | ||
| 367 | \\usage: zig test [file]... | ||
| 368 | \\ | ||
| 369 | \\Options: | ||
| 370 | \\ --help Print this help and exit | ||
| 371 | \\ | ||
| 372 | \\ | ||
| 373 | ; | ||
| 374 | |||
| 375 | fn cmdTest(allocator: &mem.Allocator, args: &clap.ArgIterator) (error{}!void) { | ||
| 376 | } | ||
| 377 | |||
| 378 | // cmd:run ///////////////////////////////////////////////////////////////////////////////////////// | ||
| 379 | |||
| 380 | // Run should be simple and not expose the full set of arguments provided by build-exe. If specific | ||
| 381 | // build requirements are need, the user should `build-exe` then `run` manually. | ||
| 382 | const usage_run = | ||
| 383 | \\usage: zig run [file] -- <runtime args> | ||
| 384 | \\ | ||
| 385 | \\Options: | ||
| 386 | \\ --help Print this help and exit | ||
| 387 | \\ | ||
| 388 | \\ | ||
| 389 | ; | ||
| 390 | |||
| 391 | fn cmdRun(allocator: &mem.Allocator, args: &clap.ArgIterator) (error{}!void) { | ||
| 392 | } | ||
| 393 | |||
| 394 | // cmd:translate-c ///////////////////////////////////////////////////////////////////////////////// | ||
| 395 | |||
| 396 | const usage_translate_c = | ||
| 397 | \\usage: zig translate-c [file] | ||
| 398 | \\ | ||
| 399 | \\Options: | ||
| 400 | \\ --help Print this help and exit | ||
| 401 | \\ --enable-timing-info Print timing diagnostics | ||
| 402 | \\ --output [path] Output file to write generated zig file (default: stdout) | ||
| 403 | \\ | ||
| 404 | \\ | ||
| 405 | ; | ||
| 406 | |||
| 407 | fn cmdTranslateC(allocator: &mem.Allocator, args: &clap.ArgIterator) (error{}!void) { | ||
| 408 | } | ||
| 409 | |||
| 410 | // cmd:zen ///////////////////////////////////////////////////////////////////////////////////////// | ||
| 411 | |||
| 412 | const info_zen = | ||
| 413 | \\ | ||
| 414 | \\ * Communicate intent precisely. | ||
| 415 | \\ * Edge cases matter. | ||
| 416 | \\ * Favor reading code over writing code. | ||
| 417 | \\ * Only one obvious way to do things. | ||
| 418 | \\ * Runtime crashes are better than bugs. | ||
| 419 | \\ * Compile errors are better than runtime crashes. | ||
| 420 | \\ * Incremental improvements. | ||
| 421 | \\ * Avoid local maximums. | ||
| 422 | \\ * Reduce the amount one must remember. | ||
| 423 | \\ * Minimize energy spent on coding style. | ||
| 424 | \\ * Together we serve end users. | ||
| 425 | \\ | ||
| 426 | \\ | ||
| 427 | ; | ||
| 428 | |||
| 429 | fn cmdZen(allocator: &mem.Allocator, args: &clap.ArgIterator) (error{}!void) { | ||
| 430 | } | ||
| 431 | |||
| 432 | // cmd:internal //////////////////////////////////////////////////////////////////////////////////// | ||
| 433 | |||
| 434 | const usage_internal = | ||
| 435 | \\usage: zig internal [subcommand] | ||
| 436 | \\ | ||
| 437 | \\Sub-Commands: | ||
| 438 | \\ build-info Print static compiler build-info | ||
| 439 | \\ | ||
| 440 | \\ | ||
| 441 | ; | ||
| 442 | |||
| 443 | fn cmdInternal(allocator: &mem.Allocator, args: &clap.ArgIterator) (error{}!void) { | ||
| 444 | } | ||
diff --git a/src/core.zig b/src/core.zig index 22b5df2..8570220 100644 --- a/src/core.zig +++ b/src/core.zig | |||
| @@ -123,12 +123,12 @@ pub fn Arg(comptime Id: type) type { | |||
| 123 | return struct { | 123 | return struct { |
| 124 | const Self = this; | 124 | const Self = this; |
| 125 | 125 | ||
| 126 | id: Id, | 126 | param: &const Param(Id), |
| 127 | value: ?[]const u8, | 127 | value: ?[]const u8, |
| 128 | 128 | ||
| 129 | pub fn init(id: Id, value: ?[]const u8) Self { | 129 | pub fn init(param: &const Param(Id), value: ?[]const u8) Self { |
| 130 | return Self { | 130 | return Self { |
| 131 | .id = id, | 131 | .param = param, |
| 132 | .value = value, | 132 | .value = value, |
| 133 | }; | 133 | }; |
| 134 | } | 134 | } |
| @@ -287,7 +287,7 @@ pub fn Clap(comptime Id: type) type { | |||
| 287 | if (maybe_value != null) | 287 | if (maybe_value != null) |
| 288 | return error.DoesntTakeValue; | 288 | return error.DoesntTakeValue; |
| 289 | 289 | ||
| 290 | return Arg(Id).init(param.id, null); | 290 | return Arg(Id).init(param, null); |
| 291 | } | 291 | } |
| 292 | 292 | ||
| 293 | const value = blk: { | 293 | const value = blk: { |
| @@ -297,7 +297,7 @@ pub fn Clap(comptime Id: type) type { | |||
| 297 | break :blk (try clap.nextNoParse()) ?? return error.MissingValue; | 297 | break :blk (try clap.nextNoParse()) ?? return error.MissingValue; |
| 298 | }; | 298 | }; |
| 299 | 299 | ||
| 300 | return Arg(Id).init(param.id, value); | 300 | return Arg(Id).init(param, value); |
| 301 | } | 301 | } |
| 302 | }, | 302 | }, |
| 303 | ArgInfo.Kind.Short => { | 303 | ArgInfo.Kind.Short => { |
| @@ -315,7 +315,7 @@ pub fn Clap(comptime Id: type) type { | |||
| 315 | if (param.names.short) |_| continue; | 315 | if (param.names.short) |_| continue; |
| 316 | if (param.names.long) |_| continue; | 316 | if (param.names.long) |_| continue; |
| 317 | 317 | ||
| 318 | return Arg(Id).init(param.id, arg); | 318 | return Arg(Id).init(param, arg); |
| 319 | } | 319 | } |
| 320 | } | 320 | } |
| 321 | 321 | ||
| @@ -330,7 +330,7 @@ pub fn Clap(comptime Id: type) type { | |||
| 330 | const index = state.index; | 330 | const index = state.index; |
| 331 | const next_index = index + 1; | 331 | const next_index = index + 1; |
| 332 | 332 | ||
| 333 | for (clap.params) |param| { | 333 | for (clap.params) |*param| { |
| 334 | const short = param.names.short ?? continue; | 334 | const short = param.names.short ?? continue; |
| 335 | if (short != arg[index]) | 335 | if (short != arg[index]) |
| 336 | continue; | 336 | continue; |
| @@ -348,18 +348,18 @@ pub fn Clap(comptime Id: type) type { | |||
| 348 | } | 348 | } |
| 349 | 349 | ||
| 350 | if (!param.takes_value) | 350 | if (!param.takes_value) |
| 351 | return Arg(Id).init(param.id, null); | 351 | return Arg(Id).init(param, null); |
| 352 | 352 | ||
| 353 | if (arg.len <= next_index) { | 353 | if (arg.len <= next_index) { |
| 354 | const value = (try clap.nextNoParse()) ?? return error.MissingValue; | 354 | const value = (try clap.nextNoParse()) ?? return error.MissingValue; |
| 355 | return Arg(Id).init(param.id, value); | 355 | return Arg(Id).init(param, value); |
| 356 | } | 356 | } |
| 357 | 357 | ||
| 358 | if (arg[next_index] == '=') { | 358 | if (arg[next_index] == '=') { |
| 359 | return Arg(Id).init(param.id, arg[next_index + 1..]); | 359 | return Arg(Id).init(param, arg[next_index + 1..]); |
| 360 | } | 360 | } |
| 361 | 361 | ||
| 362 | return Arg(Id).init(param.id, arg[next_index..]); | 362 | return Arg(Id).init(param, arg[next_index..]); |
| 363 | } | 363 | } |
| 364 | 364 | ||
| 365 | return error.InvalidArgument; | 365 | return error.InvalidArgument; |