diff options
-rw-r--r-- | info/argparser.texinfo | 5 | ||||
-rw-r--r-- | src/argparser.py | 67 | ||||
-rwxr-xr-x | src/test.py | 4 |
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)) |