aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--info/argparser.texinfo5
-rw-r--r--src/argparser.py67
-rwxr-xr-xsrc/test.py4
3 files changed, 60 insertions, 16 deletions
diff --git a/info/argparser.texinfo b/info/argparser.texinfo
index d774d8b..253c3bb 100644
--- a/info/argparser.texinfo
+++ b/info/argparser.texinfo
@@ -332,7 +332,10 @@ add additional options.
The trigger functions are functions that does not return any value,
and has two or three parameters: the used option alternative, the
standard option alternative, and for argumented but not variadic
-options: the used value.
+options: the used value but @code{null}@footnote{Or @code{NULL} or
+@code{None} depending on language} if there was not argument.
+In the Bash version only two arguments are used if there was not
+argument is the value of @code{$#} will be 2 instead of 3.
The the Java version, the standard option is not passed, so there
are only one or two parameters. Instead, the function is defined
diff --git a/src/argparser.py b/src/argparser.py
index 0b9fcab..39bc584 100644
--- a/src/argparser.py
+++ b/src/argparser.py
@@ -40,7 +40,12 @@ class ArgParser():
:int Option takes one argument per instance
'''
- VARIADIC = 2
+ OPTARGUMENTED = 2
+ '''
+ :int Option takes optionally one argument per instance
+ '''
+
+ VARIADIC = 3
'''
:int Option consumes all following arguments
'''
@@ -149,11 +154,11 @@ class ArgParser():
'''
Add option that takes one argument
- @param alternatives:list<str> Option names
- @param default:str|int The default argument's name or index
- @param arg:str The name of the takes argument, one word
- @param help:str? Short description, use `None` to hide the option
- @param trigger:(str, str, str)?→void Function to invoke when the option is used, with the used alternative, the standard alternative and the used argument
+ @param alternatives:list<str> Option names
+ @param default:str|int The default argument's name or index
+ @param arg:str The name of the takes argument, one word
+ @param help:str? Short description, use `None` to hide the option
+ @param trigger:(str, str, str?)?→void Function to invoke when the option is used, with the used alternative, the standard alternative and the used argument and `None` if there are not more arguments
'''
stdalt = alternatives[default] if isinstance(default, int) else default
self.__options.append((ArgParser.ARGUMENTED, alternatives, arg, help, stdalt))
@@ -162,6 +167,26 @@ class ArgParser():
self.optmap[alt] = (stdalt, ArgParser.ARGUMENTED, trigger if trigger is not None else lambda used, std, value : True)
+ def add_optargumented(self, alternatives, default = 0, arg = 'ARG', help = None, trigger = None, stickless = None):
+ '''
+ Add option that optionally takes one argument
+
+ @param alternatives:list<str> Option names
+ @param default:str|int The default argument's name or index
+ @param arg:str The name of the takes argument, one word
+ @param help:str? Short description, use `None` to hide the option
+ @param trigger:(str, str, str?)?→void Function to invoke when the option is used, with the used alternative, the standard alternative and the used argument if any
+ @parma stickless:(str)?→bool Function that should return true if the (feed) next argument can used for the argument without being sticky
+ '''
+ stdalt = alternatives[default] if isinstance(default, int) else default
+ self.__options.append((ArgParser.OPTARGUMENTED, alternatives, arg, help, stdalt))
+ self.opts[stdalt] = None
+ for alt in alternatives:
+ trigger = trigger if trigger is not None else lambda used, std, value : True
+ stickless = stickless if stickless is not None else lambda arg : not (arg.startswith('-') or arg.startswith('+'))
+ self.optmap[alt] = (stdalt, ArgParser.OPTARGUMENTED, trigger, stickless)
+
+
def add_variadic(self, alternatives, default = 0, arg = 'ARG', help = None, trigger = None):
'''
Add option that takes all following argument
@@ -216,10 +241,19 @@ class ArgParser():
queue = queue[1:]
if (get > 0) and (dontget == 0):
arg_opt = optqueue[-get]
- self.optmap[arg_opt][2](arg_opt, self.optmap[arg_opt][0], arg)
+ option = self.optmap[arg_opt]
+ passed = True
get -= 1
- argqueue.append(arg)
- elif tmpdashed:
+ if option[1] == ArgParser.OPTARGUMENTED:
+ if not option[3](arg):
+ passed = False
+ option[2](arg_opt, option[0], None)
+ argqueue.append(None)
+ if passed:
+ option[2](arg_opt, option[0], arg)
+ argqueue.append(arg)
+ continue
+ if tmpdashed:
self.files.append(arg)
tmpdashed = False
elif dashed: self.files.append(arg)
@@ -245,7 +279,7 @@ class ArgParser():
self.optmap[arg_opt][2](arg_opt, self.optmap[arg_opt][0], argqueue[-1])
else:
unrecognised(arg)
- elif (arg in self.optmap) and (self.optmap[arg][1] == ArgParser.ARGUMENTED):
+ elif (arg in self.optmap) and (self.optmap[arg][1] <= ArgParser.OPTARGUMENTED):
optqueue.append(arg)
get += 1
elif (arg in self.optmap) and (self.optmap[arg][1] == ArgParser.VARIADIC):
@@ -267,7 +301,7 @@ class ArgParser():
self.optmap[narg][2](narg, self.optmap[narg][0])
optqueue.append(narg)
argqueue.append(None)
- elif self.optmap[narg][1] == ArgParser.ARGUMENTED:
+ elif self.optmap[narg][1] < ArgParser.VARIADIC:
optqueue.append(narg)
nargarg = arg[i:]
if len(nargarg) == 0:
@@ -293,12 +327,14 @@ class ArgParser():
while i < n:
opt = optqueue[i]
arg = argqueue[i] if len(argqueue) > i else None
+ if len(argqueue) <= i:
+ option = self.optmap[opt]
+ option[2](opt, option[0], None)
i += 1
opt = self.optmap[opt][0]
if (opt not in self.opts) or (self.opts[opt] is None):
self.opts[opt] = []
- if len(argqueue) >= i:
- self.opts[opt].append(arg)
+ self.opts[opt].append(arg)
for arg in self.__options:
if arg[0] == ArgParser.VARIADIC:
@@ -463,8 +499,9 @@ class ArgParser():
if opt_alt is alts[-1]:
line += '\0' + opt_alt
l += len(opt_alt)
- if opt_type == ArgParser.ARGUMENTED: line += ' %s' % emph(opt_arg); l += len(opt_arg) + 1
- elif opt_type == ArgParser.VARIADIC: line += ' [%s...]' % emph(opt_arg); l += len(opt_arg) + 6
+ if opt_type == ArgParser.ARGUMENTED: line += ' %s' % emph(opt_arg); l += len(opt_arg) + 1
+ elif opt_type == ArgParser.OPTARGUMENTED: line += ' [%s]' % emph(opt_arg); l += len(opt_arg) + 3
+ elif opt_type == ArgParser.VARIADIC: line += ' [%s...]' % emph(opt_arg); l += len(opt_arg) + 6
else:
line += ' %s ' % dim(opt_alt)
l += len(opt_alt) + 6
diff --git a/src/test.py b/src/test.py
index cd3b2ad..26e9ff3 100755
--- a/src/test.py
+++ b/src/test.py
@@ -44,6 +44,7 @@ parser.add_argumentless(['--hello'], 0, 'Prints the text: hello world')
parser.add_argumentless(['++hidden'], 0)
parser.add_argumented(['-l', '--line'], 0, 'LINE', 'Prints the choosen line')
+parser.add_optargumented(['-L', '--Line'], 0, 'LINE', 'Prints the choosen line')
parser.add_variadic(['--l', '--lines'], 0, 'LINE', 'Prints the choosen lines')
parser.parse()
@@ -58,6 +59,9 @@ elif parser.unrecognisedCount == 0 and len(parser.arguments) > 0 and len(parser.
if parser.opts['-l'] is not None:
for line in parser.opts['--line']:
print(line)
+ if parser.opts['-L'] is not None:
+ for line in parser.opts['--Line']:
+ print(line)
if parser.opts['--lines'] is not None:
for line in parser.opts['--l']:
print(str(line))