doc.odin 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. package flags implements a command-line argument parser.
  3. It works by using Odin's run-time type information to determine where and how
  4. to store data on a struct provided by the program. Type conversion is handled
  5. automatically and errors are reported with useful messages.
  6. Command-Line Syntax:
  7. Arguments are treated differently depending on how they're formatted.
  8. The format is similar to the Odin binary's way of handling compiler flags.
  9. ```
  10. type handling
  11. ------------ ------------------------
  12. <positional> depends on struct layout
  13. -<flag> set a bool true
  14. -<flag:option> set flag to option
  15. -<flag=option> set flag to option, alternative syntax
  16. -<map>:<key>=<value> set map[key] to value
  17. ```
  18. Struct Tags:
  19. Users of the `core:encoding/json` package may be familiar with using tags to
  20. annotate struct metadata. The same technique is used here to annotate where
  21. arguments should go and which are required.
  22. Under the `args` tag, there are the following subtags:
  23. - `name=S`: set `S` as the flag's name.
  24. - `pos=N`: place positional argument `N` into this flag.
  25. - `hidden`: hide this flag from the usage documentation.
  26. - `required`: cause verification to fail if this argument is not set.
  27. - `variadic`: take all remaining arguments when set, UNIX-style only.
  28. - `file`: for `os.Handle` types, file open mode.
  29. - `perms`: for `os.Handle` types, file open permissions.
  30. - `indistinct`: allow the setting of distinct types by their base type.
  31. `required` may be given a range specifier in the following formats:
  32. ```
  33. min
  34. <max
  35. min<max
  36. ```
  37. `max` is not inclusive in this range, as noted by the less-than `<` sign, so if
  38. you want to require 3 and only 3 arguments in a dynamic array, you would
  39. specify `required=3<4`.
  40. `variadic` may be given a number (`variadic=N`) above 1 to limit how many extra
  41. arguments it consumes.
  42. `file` determines the file open mode for an `os.Handle`.
  43. It accepts a string of flags that can be mixed together:
  44. - r: read
  45. - w: write
  46. - c: create, create the file if it doesn't exist
  47. - a: append, add any new writes to the end of the file
  48. - t: truncate, erase the file on open
  49. `perms` determines the file open permissions for an `os.Handle`.
  50. The permissions are represented by three numbers in octal format. The first
  51. number is the owner, the second is the group, and the third is other. Read is
  52. represented by 4, write by 2, and execute by 1.
  53. These numbers are added together to get combined permissions. For example, 644
  54. represents read/write for the owner, read for the group, and read for other.
  55. Note that this may only have effect on UNIX-like platforms. By default, `perms`
  56. is set to 444 when only reading and 644 when writing.
  57. `indistinct` tells the parser that it's okay to treat distinct types as their
  58. underlying base type. Normally, the parser will hand those types off to the
  59. custom type setter (more about that later) if one is available, if it doesn't
  60. know how to handle the type.
  61. Usage Tag:
  62. There is also the `usage` tag, which is a plain string to be printed alongside
  63. the flag in the usage output. If `usage` contains a newline, it will be
  64. properly aligned when printed.
  65. All surrounding whitespace is trimmed when formatting with multiple lines.
  66. Supported Flag Data Types:
  67. - all booleans
  68. - all integers
  69. - all floats
  70. - all enums
  71. - all complex numbers
  72. - all quaternions
  73. - all bit_sets
  74. - `string` and `cstring`
  75. - `rune`
  76. - `os.Handle`
  77. - `time.Time`
  78. - `datetime.DateTime`
  79. - `net.Host_Or_Endpoint`,
  80. - additional custom types, see Custom Types below
  81. - `dynamic` arrays with element types of the above
  82. - `map[string]`s or `map[cstring]`s with value types of the above
  83. Validation:
  84. The parser will ensure `required` arguments are set, if no errors occurred
  85. during parsing. This is on by default.
  86. Additionally, you may call `register_flag_checker` to set your own argument
  87. validation procedure that will be called after the default checker.
  88. Strict:
  89. The parser will return on the first error and stop parsing. This is on by
  90. default. Otherwise, all arguments that can be parsed, will be, and only the
  91. last error is returned.
  92. Error Messages:
  93. All error message strings are allocated using the context's `temp_allocator`,
  94. so if you need them to persist, make sure to clone the underlying `message`.
  95. Help:
  96. By default, `-h` and `-help` are reserved flags which raise their own error
  97. type when set, allowing the program to handle the request differently from
  98. other errors.
  99. Custom Types:
  100. You may specify your own type setter for program-specific structs and other
  101. named types. Call `register_type_setter` with an appropriate proc before
  102. calling any of the parsing procs.
  103. A compliant `Custom_Type_Setter` must return three values:
  104. - an error message if one occurred,
  105. - a boolean indicating if the proc handles the type, and
  106. - an `Allocator_Error` if any occurred.
  107. If the setter does not handle the type, simply return without setting any of
  108. the values.
  109. UNIX-style:
  110. This package also supports parsing arguments in a limited flavor of UNIX.
  111. Odin and UNIX style are mutually exclusive, and which one to be used is chosen
  112. at parse time.
  113. ```
  114. --flag
  115. --flag=argument
  116. --flag argument
  117. --flag argument repeating-argument
  118. ```
  119. `-flag` may also be substituted for `--flag`.
  120. Do note that map flags are not currently supported in this parsing style.
  121. Example:
  122. A complete example is given in the `example` subdirectory.
  123. */
  124. package flags