mirror of
https://github.com/sshuttle/sshuttle.git
synced 2025-01-19 04:18:23 +01:00
latest options.py from bup, now with tty-width guessing.
as of bup commit bup-0.19-2-gce2ace5.
This commit is contained in:
parent
b35cfbd022
commit
2ef1c6a4c4
56
options.py
56
options.py
@ -1,19 +1,21 @@
|
|||||||
"""Command-line options parser.
|
"""Command-line options parser.
|
||||||
With the help of an options spec string, easily parse command-line options.
|
With the help of an options spec string, easily parse command-line options.
|
||||||
"""
|
"""
|
||||||
import sys
|
import sys, os, textwrap, getopt, re, struct
|
||||||
import textwrap
|
|
||||||
import getopt
|
|
||||||
import re
|
|
||||||
|
|
||||||
class OptDict:
|
class OptDict:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._opts = {}
|
self._opts = {}
|
||||||
|
|
||||||
def __setitem__(self, k, v):
|
def __setitem__(self, k, v):
|
||||||
|
if k.startswith('no-') or k.startswith('no_'):
|
||||||
|
k = k[3:]
|
||||||
|
v = not v
|
||||||
self._opts[k] = v
|
self._opts[k] = v
|
||||||
|
|
||||||
def __getitem__(self, k):
|
def __getitem__(self, k):
|
||||||
|
if k.startswith('no-') or k.startswith('no_'):
|
||||||
|
return not self._opts[k[3:]]
|
||||||
return self._opts[k]
|
return self._opts[k]
|
||||||
|
|
||||||
def __getattr__(self, k):
|
def __getattr__(self, k):
|
||||||
@ -34,6 +36,33 @@ def _intify(v):
|
|||||||
return v
|
return v
|
||||||
|
|
||||||
|
|
||||||
|
def _atoi(v):
|
||||||
|
try:
|
||||||
|
return int(v or 0)
|
||||||
|
except ValueError:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def _remove_negative_kv(k, v):
|
||||||
|
if k.startswith('no-') or k.startswith('no_'):
|
||||||
|
return k[3:], not v
|
||||||
|
return k,v
|
||||||
|
|
||||||
|
def _remove_negative_k(k):
|
||||||
|
return _remove_negative_kv(k, None)[0]
|
||||||
|
|
||||||
|
|
||||||
|
def _tty_width():
|
||||||
|
s = struct.pack("HHHH", 0, 0, 0, 0)
|
||||||
|
try:
|
||||||
|
import fcntl, termios
|
||||||
|
s = fcntl.ioctl(sys.stderr.fileno(), termios.TIOCGWINSZ, s)
|
||||||
|
except (IOError, ImportError):
|
||||||
|
return _atoi(os.environ.get('WIDTH')) or 70
|
||||||
|
(ysize,xsize,ypix,xpix) = struct.unpack('HHHH', s)
|
||||||
|
return xsize
|
||||||
|
|
||||||
|
|
||||||
class Options:
|
class Options:
|
||||||
"""Option parser.
|
"""Option parser.
|
||||||
When constructed, two strings are mandatory. The first one is the command
|
When constructed, two strings are mandatory. The first one is the command
|
||||||
@ -71,10 +100,13 @@ class Options:
|
|||||||
out.append('%s: %s\n' % (first_syn and 'usage' or ' or', l))
|
out.append('%s: %s\n' % (first_syn and 'usage' or ' or', l))
|
||||||
first_syn = False
|
first_syn = False
|
||||||
out.append('\n')
|
out.append('\n')
|
||||||
|
last_was_option = False
|
||||||
while lines:
|
while lines:
|
||||||
l = lines.pop()
|
l = lines.pop()
|
||||||
if l.startswith(' '):
|
if l.startswith(' '):
|
||||||
out.append('\n%s\n' % l.lstrip())
|
out.append('%s%s\n' % (last_was_option and '\n' or '',
|
||||||
|
l.lstrip()))
|
||||||
|
last_was_option = False
|
||||||
elif l:
|
elif l:
|
||||||
(flags, extra) = l.split(' ', 1)
|
(flags, extra) = l.split(' ', 1)
|
||||||
extra = extra.strip()
|
extra = extra.strip()
|
||||||
@ -83,7 +115,7 @@ class Options:
|
|||||||
has_parm = 1
|
has_parm = 1
|
||||||
else:
|
else:
|
||||||
has_parm = 0
|
has_parm = 0
|
||||||
g = re.search(r'\[([^\]]*)\]', extra)
|
g = re.search(r'\[([^\]]*)\]$', extra)
|
||||||
if g:
|
if g:
|
||||||
defval = g.group(1)
|
defval = g.group(1)
|
||||||
else:
|
else:
|
||||||
@ -91,16 +123,16 @@ class Options:
|
|||||||
flagl = flags.split(',')
|
flagl = flags.split(',')
|
||||||
flagl_nice = []
|
flagl_nice = []
|
||||||
for f in flagl:
|
for f in flagl:
|
||||||
self._aliases[f] = flagl[0]
|
f,dvi = _remove_negative_kv(f, _intify(defval))
|
||||||
|
self._aliases[f] = _remove_negative_k(flagl[0])
|
||||||
self._hasparms[f] = has_parm
|
self._hasparms[f] = has_parm
|
||||||
self._defaults[f] = _intify(defval)
|
self._defaults[f] = dvi
|
||||||
if len(f) == 1:
|
if len(f) == 1:
|
||||||
self._shortopts += f + (has_parm and ':' or '')
|
self._shortopts += f + (has_parm and ':' or '')
|
||||||
flagl_nice.append('-' + f)
|
flagl_nice.append('-' + f)
|
||||||
else:
|
else:
|
||||||
f_nice = re.sub(r'\W', '_', f)
|
f_nice = re.sub(r'\W', '_', f)
|
||||||
self._aliases[f_nice] = flagl[0]
|
self._aliases[f_nice] = _remove_negative_k(flagl[0])
|
||||||
assert(not f.startswith('no-')) # supported implicitly
|
|
||||||
self._longopts.append(f + (has_parm and '=' or ''))
|
self._longopts.append(f + (has_parm and '=' or ''))
|
||||||
self._longopts.append('no-' + f)
|
self._longopts.append('no-' + f)
|
||||||
flagl_nice.append('--' + f)
|
flagl_nice.append('--' + f)
|
||||||
@ -108,12 +140,14 @@ class Options:
|
|||||||
if has_parm:
|
if has_parm:
|
||||||
flags_nice += ' ...'
|
flags_nice += ' ...'
|
||||||
prefix = ' %-20s ' % flags_nice
|
prefix = ' %-20s ' % flags_nice
|
||||||
argtext = '\n'.join(textwrap.wrap(extra, width=70,
|
argtext = '\n'.join(textwrap.wrap(extra, width=_tty_width(),
|
||||||
initial_indent=prefix,
|
initial_indent=prefix,
|
||||||
subsequent_indent=' '*28))
|
subsequent_indent=' '*28))
|
||||||
out.append(argtext + '\n')
|
out.append(argtext + '\n')
|
||||||
|
last_was_option = True
|
||||||
else:
|
else:
|
||||||
out.append('\n')
|
out.append('\n')
|
||||||
|
last_was_option = False
|
||||||
return ''.join(out).rstrip() + '\n'
|
return ''.join(out).rstrip() + '\n'
|
||||||
|
|
||||||
def usage(self, msg=""):
|
def usage(self, msg=""):
|
||||||
|
Loading…
Reference in New Issue
Block a user