78 lines
2.8 KiB
Python
78 lines
2.8 KiB
Python
|
#!/usr/bin/env python
|
||
|
#
|
||
|
# Copyright (C) 2015 Elf M. Sternberg
|
||
|
# Author: Elf M. Sternberg
|
||
|
#
|
||
|
|
||
|
# This was a lot shorter and smarter in Hy...
|
||
|
|
||
|
|
||
|
def make_rational_options(options, commandline):
|
||
|
"""Takes a table of options and the commandline, and returns a
|
||
|
dictionary of those options that appear on the commandline
|
||
|
along with any extra arguments.
|
||
|
|
||
|
:param List(Tuple (string, string, boolean, string, List(string))) options,
|
||
|
The table of options: One-letter option, long option, takes arguments,
|
||
|
Help text, list of (long) options superseded by this one.
|
||
|
: param List(strings) commandline
|
||
|
The arguments as received by the start-up process
|
||
|
"""
|
||
|
|
||
|
def make_options_rationalizer(options):
|
||
|
|
||
|
"""Takes a list of option tuples, and returns a function that takes
|
||
|
the output of getopt and reduces it to the longopt key and
|
||
|
associated values as a dictionary.
|
||
|
"""
|
||
|
|
||
|
fullset = {}
|
||
|
for option in options:
|
||
|
if not option[1]:
|
||
|
continue
|
||
|
if option[0]:
|
||
|
fullset['-' + option[0]] = option[1]
|
||
|
fullset['--' + option[1]] = option[1]
|
||
|
|
||
|
def rationalizer(acc, it):
|
||
|
acc[fullset[it[0]]] = it[1]
|
||
|
return acc
|
||
|
|
||
|
return rationalizer
|
||
|
|
||
|
def remove_conflicted_options(options, request):
|
||
|
"""Takes our list of option tuples, and a cleaned copy of what was
|
||
|
requested from getopt, and returns a copy of the request
|
||
|
without any options that are marked as superseded, along with
|
||
|
the list of superseded options
|
||
|
"""
|
||
|
def get_excluded_keys(memo, opt):
|
||
|
return memo + ((len(opt) > 4 and opt[4]) or [])
|
||
|
|
||
|
keys = request.keys()
|
||
|
marked = [option for option in options if option[1] in keys]
|
||
|
exclude = reduce(get_excluded_keys, marked, [])
|
||
|
excluded = [key for key in keys if key in exclude]
|
||
|
cleaned = {key: request[key] for key in keys
|
||
|
if key not in excluded}
|
||
|
return (cleaned, excluded)
|
||
|
|
||
|
def shortoptstogo(i): return i[0] + ((i[2] and ':') or '')
|
||
|
|
||
|
def longoptstogo(i): return i[1] + ((i[2] and '=') or '')
|
||
|
|
||
|
optstringsshort = ''.join([shortoptstogo(opt) for opt in options])
|
||
|
optstringslong = [longoptstogo(opt) for opt in options]
|
||
|
(options, filenames) = getopt.getopt(commandline[1:],
|
||
|
optstringsshort,
|
||
|
optstringslong)
|
||
|
|
||
|
# Turns what getopt returns into something more human-readable
|
||
|
rationalize_options = make_options_rationalizer(options)
|
||
|
|
||
|
# Remove any options that are superseded by others.
|
||
|
(retoptions, excluded) = remove_conflicted_options(
|
||
|
optlist, reduce(rationalize_options, options, {}))
|
||
|
|
||
|
return (retoptions, filenames, excluded)
|