Commit Graph

71 Commits

Author SHA1 Message Date
Zoom
72e9bfe0a4 Docs: parseopt fixes, runnable examples (#25526)
Follow-up to #25506.
As I mentioned there, I was in the middle of an edit, so here it is.
Splitting to a separate doc skipped.

A couple of minor mistakes fixed, some things made a bit more concise
and short.
2026-02-16 18:26:08 +01:00
Zoom
7c873ca615 Feat: std: parseopt parser modes (#25506)
Adds configurable parser modes to std/parseopt module. **Take two.**

Initially solved the issue of not being able to pass arguments to short
options as you do with most everyday CLI programs, but reading the tests
made me add more features so that some of the behaviour could be changed
and here we are.

**`std/parseopt` now supports three parser modes** via an optional
`mode` parameter in `initOptParser` and `getopt`.

Three modes are provided:
- `NimMode` (default, fully backward compatible),
- `LaxMode` (POSIX-inspired with relaxed short option handling),
- `GnuMode` (stricter GNU-style conventions).

The new modes are marked as experimental in the documentation.

The parser behaviour is controlled by a new `ParserRules` enum, which
provides granular feature flags that modes are built from. This makes it
possible for users with specific requirements to define custom rule sets
by importing private symbols, this is mentioned but clearly marked as
unsupported.

**Backward compatibility:**

The default mode preserves existing behaviour completely, with a single
exception: `allowWhitespaceAfterColon` is deprecated.

Now, `allowWhitespaceAfterColon` doesn't make much sense as a single
tuning knob. The `ParserRule.prSepAllowDelimAfter` controls this now.
As `allowWhitespaceAfterColon` had a default, most calls never mention
it so they will silently migrate to the new `initOptParser` overload. To
cover cases when the proc param was used at call-site, I added an
overload, which modifies the default parser mode to reflect the required
`allowWhitespaceAfterColon` value. Should be all smooth for most users,
except the deprecation warning.

The only thing I think can be classified as the breaking change is a
surprising **bug** of the old parser:

```nim
let p = initOptParser("-n 10 -m20 -k= 30 -40",  shortNoVal =  {'v'})
#                                     ^-disappears
```

This is with the aforementioned `allowWhitespaceAfterColon` being true
by default, of course. In this case the `30` token is skipped
completely. I don't think that's right, so it's fixed.


Things I still don't like about how the old parser and the new default
mode behave:

1. **Parser behaviour is controlled by an emptiness of two containers**.
This is an interesting approach. It's also made more interesting because
the `shortNoVal`/`longNoVal` control both the namesakes, but *and also
how their opposites (value-taking opts) work*.
---

**Edit:**

2. `shortNoVal` is not mandatory:
    ```nim
	let p = initOptParser(@["-a=foo"], shortNoVal = {'a'})
	# Nim, Lax parses as: (cmdShortOption, "a", "foo") 
	# GnuMode  parses as: (cmdShortOption, "a", "=foo")
	```
In this case, even though the user specified `a` as no no-val, parser
ignores it, relying only on the syntax to decide the kind of the
argument. This is especially problematic with the modes that don't use
the rule `prShortAllowSep` (GnuMode), in this case the provided input is
twice invalid, regardless of the `shortNoVal`.

With the current parser architecture, parsing it this way **is
inevitable**, though. We don't have any way to signal the error state
detected with the input, so the user is expected to validate the input
for mistakes.
Bundling positional arguments is nonsensical and short option can't use
the separator character, so `[cmd "a", arg "=foo"]` and `[cmd "a", cmd
"=", cmd "f"...]` are both out of the question **and** would complicate
validating, requiring keeping track of a previous argument. Hope I'm
clear enough on the issue.
	
**Future work:**

1. Looks like the new modes are already usable, but from the discussions
elsewhere it looks like we might want to support special-casing
multi-digit short options (`-XX..`) to allow numerical options greater
than 9. This complicates bundling, though, so requires a bit of thinking
through.

2. Signaling error state?

---------

Co-authored-by: Andreas Rumpf <araq4k@proton.me>
2026-02-16 16:06:18 +01:00
ringabout
d31cce557b more strictdef fixes for stdlibs (#24535) 2024-12-13 19:06:43 +01:00
Gianmarco
96aba18963 Fixed issues when using std/parseopt in miscripts with cmdline = "" (#23785)
Using initOptParser with an empty cmdline (so that it gets the cmdline
from the command line) in nimscripts does not yield the expected
results.

Fixes #23774.
2024-07-02 08:49:21 +02:00
ringabout
4d11d0619d complete std prefixes for stdlib (#22887)
follow up https://github.com/nim-lang/Nim/pull/22851
follow up https://github.com/nim-lang/Nim/pull/22873
2023-10-30 17:03:04 +01:00
Andrey Makarov
a660c17d30 Markdown code blocks migration part 8 (#22478) 2023-08-15 06:27:36 +02:00
ringabout
3f7e1d7daa replace doAssert false with raiseAssert in lib, which works better with strictdefs (#22458) 2023-08-11 18:24:46 +02:00
Andreas Rumpf
00ef27f4d1 minor parseopt.nim improvements (#21256)
* minor parseopt.nim improvements

* attempt to make CI happy

Co-authored-by: Clay Sweetser <Varriount@users.noreply.github.com>
2023-01-18 21:37:26 +01:00
Russell Brinson
8be46f3d16 parseopt.nim documentation clarity - default values & cmdEnd in getopt (#21047)
parseopt.nim documentation clarity

Added example for default values to cmd line parameters.
Additionally, added lines in getopt documentation about case switching still requiring the `cmdEnd` kind. Hopefully this clears up any vagueness for those following along in the example but omitting the `cmdEnd` in the case because the documentation said it wasn't needed.
2023-01-11 12:20:39 -05:00
Nan Xiao
fd257a9a0f Refactor initOptParser (#19656)
Co-authored-by: flywind <xzsflywind@gmail.com>
2022-09-27 15:00:57 -04:00
Nan Xiao
065f568470 No need to export pos from OptParser (#19688)
Co-authored-by: flywind <xzsflywind@gmail.com>
2022-04-06 20:28:58 +02:00
Nan Xiao
a7024f49af fix 19655 - fixing more url fragments (#19669) 2022-04-01 13:29:15 -04:00
rockcavera
1275763284 fix 19655 - fixing url fragment (#19667) 2022-04-01 08:01:51 +02:00
Danil Yarantsev
285539c87a Replace double backticks with single backticks - Part 4 out of ~7 (#17216) 2021-03-01 18:00:58 -08:00
Danil Yarantsev
56461c280f Change stdlib imports to use std prefix in most examples (#17202) 2021-02-28 13:17:19 -08:00
hlaaftana
fad8439b8d Make parseopt available on all backends (#17009)
* Make parseopt available on all backends

* fix spaces

* fix getopt and update prelude

* no crazy unnecessary version checks, use doAssert
2021-02-13 09:05:40 +01:00
flywind
f140c92409 fix some warnings (#16952) 2021-02-08 13:50:15 +01:00
Juan Carlos
78a99587a4 Deprecate TaintedString (#15423)
Co-authored-by: Timothee Cour <timothee.cour2@gmail.com>
Co-authored-by: Dominik Picheta <dominikpicheta@googlemail.com>
2021-01-15 18:56:38 -08:00
flywind
c5f64f101b fix #13086 (#14987)
* fix #6608

* minor

* fix

* clean tests

* make testamnet happy

* again

* minor

* fix #13086
2020-07-15 03:46:17 -04:00
Dominik Picheta
bab5351d43 Fixes ambiguity errors when evaluating Nimble files. (#12674) [backport]
When trying to evaluate a Nimble file which imports a Nim module
I was getting the following errors for some reason:

```
/Users/dom/projects/nim/lib/pure/parseopt.nim(229, 46) Error: ambiguous call; both system.paramCount() [declared in /Users/dom/projects/nim/lib/system/nimscript.nim(65, 6)] and os.paramCount() [declared in /Users/dom/projects/nim/lib/pure/os.nim(2613, 8)] match for: ()
```
2019-11-18 09:26:06 +01:00
narimiran
cc3e9ca164 remove unused imports 2019-11-06 12:01:00 +01:00
narimiran
b17ed2ca9c [backport] run nimpretty on parsers 2019-09-30 13:58:08 +02:00
Timothee Cour
64168d4aea fixes #8405: -d:useNimRtl now works even when {.rtl.} procs are used at compile time; CTFFI now works with {dynlib} (#11635) 2019-07-03 23:57:52 +02:00
Araq
284a8cb58a nimpretty: bugfix [bugfix] 2019-06-28 11:45:21 +02:00
Jasper Jenkins
6b23b2d7df parseopt fix (#11363) [backport] 2019-06-01 10:44:08 +02:00
Araq
cacd6d1070 fixes #11294 2019-05-24 09:43:04 +02:00
Jjp137
a6a014a859 better docs: parseopt (#10398) 2019-01-22 14:52:43 +01:00
Timothee Cour
0a8762eb7b fix #9842 #9951: nim -r and parseopt.cmdLineRest are now correct 2019-01-14 17:00:54 -08:00
Araq
9526009e0e fixes #9120 2018-12-16 20:34:07 +01:00
Araq
3ba8f158fb added parseopt.remainingArgs; refs #9951 2018-12-14 11:41:19 +01:00
Andreas Rumpf
130c218ff9 parseopt: remove confusing dead code 2018-11-09 09:03:28 +01:00
Andreas Rumpf
c0fc2f5726 fixes #9619 2018-11-09 09:03:28 +01:00
Andreas Rumpf
36473acf47 fixes a parseopt regression (#8820) 2018-08-30 23:50:09 +02:00
Araq
a42150f9a8 make parseopt work with DLLs on Unix 2018-08-28 15:41:55 +02:00
Araq
e02e057a70 make parsopt compile under --taintMode:on 2018-08-28 15:41:55 +02:00
Araq
6f16166c60 parseopt: keep the seq of arguments as given; fixes various command line parsing edge cases; refs #6818 2018-08-28 15:41:55 +02:00
Araq
bbb0fd4eb7 remove deprecated stuff from the stdlib; introduce better deprecation warnings 2018-05-05 21:45:07 +02:00
Andreas Rumpf
203d833688 parseopt stdlib module: dont rely on the zero terminator 2018-04-29 01:31:29 +02:00
c-blake
551d7b7dc1 Add ability for users to elide ':' or '=' when CLI authors pass a (#7297)
* Add ability for users to elide ':' or '=' when CLI authors pass a
non-empty partial symbol table.  Behavior should be identical to the
old behavior if empty partial symbol tables are passed.  "Partialness"
of the symbol table refers to the fact that one need only specify
option keys that are toggles/booleans/do not take arguments, hence
the "NoArg" suffixes in shortNoArg and longNoArg.

commandLineParams() returns seq[TaintedString], so use that consistently
in getopt() and initOptParser(seq[TaintedString]) dropping the taint at
the quoting stage just as with the paramStr() logic.

Fix capitalization inconsistency of cmdLongOption.

Export OptParser.cmd and OptParser.pos so that, at least *in principle*,
users of this API can handle "--" option processing termination or some
"git-like" sub-command stop word with a separate option sub-syntax.
{ Eg., ``case p.key of "": echo "trailing non-option args: ", p.cmd[p.pos..^1]``
or ``case p.kind of cmdArgument: if p.key == "mysubcmd": ...``. }  Really,
searching for the last delimiter before p.pos is probably needed to frame
the trailing text..Not the nicest API, but still possible with effort.

* Make requested changes from string to seq[char]
(see https://github.com/nim-lang/Nim/pull/7297)

* Document new behavior and elaborate on some special cases.

* NoArg => NoVal to be less ambiguous/more clear.

* Add more documentation and an example snippet.

* Tweak language. Clarify still using ':'/'=' is ok.

* Add a test case for new NoVal behavior.
2018-03-08 08:12:34 +01:00
Andreas Rumpf
a6c7972086 make travis green again 2018-03-01 16:23:25 +01:00
Araq
ce1047f2ae added -d:nimNoArrayToString define to allow easier porting to 0.18 2018-03-01 09:42:25 +01:00
Parashurama
27e2a34340 fixes parseopt/parseopt2 custom cmdline args. 2017-06-06 13:50:26 +02:00
Araq
e0f896785d docs now build again 2015-10-12 20:58:46 +02:00
Adam Strzelecki
144dc8f8ad Move deprecated modules into lib/deprecated/
This gives clear indication what modules are now deprecated and reduce clutter
in non-deprecated module directories.
2015-09-30 12:26:25 +02:00
Araq
30829ffec4 fixes #2874 2015-07-01 16:44:16 +02:00
pdw
d18e18060e lib/pure/p-t - Dropped 'T' from types 2015-06-04 13:18:36 +02:00
Araq
21ccc5d58e parseopt is not deprecated anymore 2015-03-03 13:53:31 +01:00
Guillaume Gelin
3119fe087d Happy new year! 2015-01-06 15:26:33 +01:00
Araq
63c9c2877e updated nimgrep tool 2014-09-10 22:27:07 +02:00
Araq
4523b29d7a Nimrod renamed to Nim 2014-08-28 09:59:26 +02:00