Closed simendsjo closed 1 year ago
Hey @simendsjo ,
What is the value associated with the -c|--clip
option, when you only invoke these?
cmd foo
cmd -c foo
cmd -c1 foo
I assume there's a default value associated with the -c|--clip
option, is that correct? If that's the case, can you simply use a regular int
option with a default value?
I assume there's a default value associated with the -c|--clip option, is that correct? If that's the case, can you simply use a regular int option with a default value?
The problem is that I want missing, present and value-set, but an int option can only give me missing (default) and value set, but not "present but without value". I need to know that the option was missing as that should show all lines to stdout. I don't care what value is stored in clip as long as it's not a positive integer in this case.
clip | result |
---|---|
nil | |
-c | 1 |
-c2 | 2 |
Hey @simendsjo ,
Maybe I'm not able to understand the use case, but wouldn't something like this work?
(defun clip/options ()
(list
(clingon:make-option :integer
:short-name #\c
:long-name "clip"
:description "the --clip option"
:key :clip/option)))
(defun clip/handler (cmd)
(let ((opt-value (clingon:getopt cmd :clip/option 1))
(opt-is-set (clingon:opt-is-set-p cmd :clip/option))
(args (clingon:command-arguments cmd)))
(format t "--clip option is set: ~A~%" opt-is-set)
(format t "--clip value is: ~A~%" opt-value)
(format t "free args: ~A~%" args)))
(defun clip/command ()
(clingon:make-command
:name "clip"
:description "clip command"
:handler #'clip/handler
:options (clip/options)))
Option is not specified on command-line, and it's value is 1
.
$ cmd foo
--clip option is set: NIL
--clip value is: 1
free args: (foo)
Option is specified on the command-line.
$ cmd -c 42 foo
--clip option is set: T
--clip value is: 42
free args: (foo)
Supporting a command-line like this in my opinion is very ambiguous, where -c
option might receive a value, or not.
$ cmd -c foo
In this case it's not clear whether -c
is a flag (option with no arguments), or whether foo
is the value associated with -c
option.
Maybe I'm not able to understand the use case, but wouldn't something like this work?
No, unfortunately, because cmd -c foo
will consume foo
even though it's not an integer.
Supporting a command-line like this in my opinion is very ambiguous, where -c option might receive a value, or not.
Yes, I totally agree, but I'm trying to be backwards compatible with an existing API so tools also works with my implementation.
I guess I can solve this by fetching uiop:command-line-arguments myself, look for -c not-an-integer
and change it to -c1 not-an-integer
. Quite hackish, but at least it should work.
Yes, not a very good API design :/
Here's my solution. Replaces "-c" with "-c1" and "--clip" with "--clip=1" if it's not followed by an integer.
And I pass the result to clingon:run
. Good enough for me :)
(cl:defun patch-args-for-clip (args cl:&aux (result (cl:copy-list args)))
(cl:dolist (spec (cl:list (cl:cons "-c" "-c1")
(cl:cons "--clip" "--clip=1"))
result)
(cl:let* ((old (cl:car spec))
(new (cl:cdr spec))
(opt (cl:member old result :test 'cl:equal))
(val (cl:cadr opt))
(int? (cl:when val (cl:parse-integer val :radix 10 :junk-allowed cl:t))))
(cl:when (cl:and opt (cl:not int?))
(cl:nsubst new old result :test 'cl:equal)))))
Thanks for all your support! Guess we can close this as a won't fix as it's not really a recommended API design.
Hi, I'm trying to use clingon to create an interface compatible with another tool, but the tool is unfortunately a bit strange, and I'm having some problems getting it right.
The problem is the
clip
option in the following interface.The following is allowed and means different things:
I've implemented a
maybe-int
option type, but I'm having problems with the second case which gobbles up thefoo
parameter. Is there a way to say that the parameter shouldn't be consumed or be put back?EDIT: I think I want something like
(push arg (command-args-to-parse cmd))
, but I don't have the command available when handling the option value.