diff --git a/scripts/codemap.py b/scripts/codemap.py index 2dc9f546..0d9b7230 100755 --- a/scripts/codemap.py +++ b/scripts/codemap.py @@ -474,19 +474,45 @@ def si2(x): # attrs can override __getitem__ for lazy attr generation def punescape(s, attrs=None): pattern = re.compile( - '%[%n]' - '|' '%x..' - '|' '%u....' - '|' '%U........' - '|' '%\((?P[^)]*)\)' - '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])') + '%' '(?P[0-9]*)' '(?P' + '[%ns]' + '|' 'x..' + '|' 'u....' + '|' 'U........' + '|' '\((?P[^)]*)\)' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' + '|' '\{(?P(?:[^%]|%[^}])*)%\}' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' ')') + + def format(f, v): + if f[-1] in 'dboxX': + if isinstance(v, str): + v = dat(v, 0) + v = int(v) + elif f[-1] in 'iIfFeEgG': + if isinstance(v, str): + v = dat(v, 0) + v = float(v) + if f[-1] in 'iI': + v = (si if 'i' in f[-1] else si2)(v) + f = f.replace('i', 's').replace('I', 's') + if '+' in f and not v.startswith('-'): + v = '+'+v + f = f.replace('+', '').replace('-', '') + else: + f = ('<' if '-' in f else '>') + f.replace('-', '') + v = str(v) + # note we need Python's new format syntax for binary + return ('{:%s}' % f).format(v) + def unescape(m): - if m.group()[1] == '%': return '%' - elif m.group()[1] == 'n': return '\n' - elif m.group()[1] == 'x': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == 'u': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == 'U': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == '(': + if m.group('pun')[0] == '%': s = '%' + elif m.group('pun')[0] == 'n': s = '\n' + elif m.group('pun')[0] == 's': s = ' ' + elif m.group('pun')[0] == 'x': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == 'u': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == 'U': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == '(': if attrs is not None: try: v = attrs[m.group('field')] @@ -494,39 +520,33 @@ def punescape(s, attrs=None): return m.group() else: return m.group() - f = m.group('format') - if f[-1] in 'dboxX': - if isinstance(v, str): - v = dat(v, 0) - v = int(v) - elif f[-1] in 'iIfFeEgG': - if isinstance(v, str): - v = dat(v, 0) - v = float(v) - if f[-1] in 'iI': - v = (si if 'i' in f[-1] else si2)(v) - f = f.replace('i', 's').replace('I', 's') - if '+' in f and not v.startswith('-'): - v = '+'+v - f = f.replace('+', '').replace('-', '') - else: - f = ('<' if '-' in f else '>') + f.replace('-', '') - v = str(v) - # note we need Python's new format syntax for binary - return ('{:%s}' % f).format(v) - else: assert False + s = format(m.group('format'), v) + elif m.group('pun')[0] == '{': + v = punescape(m.group('substring'), attrs) + s = format(m.group('subformat'), v) + else: + return m.group() + + if m.group('rep'): + s = int(m.group('rep'), 10) * s + + return s return re.sub(pattern, unescape, s) # split %-escaped strings into chars def psplit(s): pattern = re.compile( - '%[%n]' - '|' '%x..' - '|' '%u....' - '|' '%U........' - '|' '%\((?P[^)]*)\)' - '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])') + '%' '(?P[0-9]*)' '(?P' + '[%ns]' + '|' 'x..' + '|' 'u....' + '|' 'U........' + '|' '\((?P[^)]*)\)' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' + '|' '\{(?P(?:[^%]|%[^}])*)%\}' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' ')') + return [m.group() for m in re.finditer(pattern.pattern + '|.', s)] diff --git a/scripts/codemapsvg.py b/scripts/codemapsvg.py index 6e451640..e762f036 100755 --- a/scripts/codemapsvg.py +++ b/scripts/codemapsvg.py @@ -336,19 +336,45 @@ def si2(x): # attrs can override __getitem__ for lazy attr generation def punescape(s, attrs=None): pattern = re.compile( - '%[%n]' - '|' '%x..' - '|' '%u....' - '|' '%U........' - '|' '%\((?P[^)]*)\)' - '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])') + '%' '(?P[0-9]*)' '(?P' + '[%ns]' + '|' 'x..' + '|' 'u....' + '|' 'U........' + '|' '\((?P[^)]*)\)' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' + '|' '\{(?P(?:[^%]|%[^}])*)%\}' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' ')') + + def format(f, v): + if f[-1] in 'dboxX': + if isinstance(v, str): + v = dat(v, 0) + v = int(v) + elif f[-1] in 'iIfFeEgG': + if isinstance(v, str): + v = dat(v, 0) + v = float(v) + if f[-1] in 'iI': + v = (si if 'i' in f[-1] else si2)(v) + f = f.replace('i', 's').replace('I', 's') + if '+' in f and not v.startswith('-'): + v = '+'+v + f = f.replace('+', '').replace('-', '') + else: + f = ('<' if '-' in f else '>') + f.replace('-', '') + v = str(v) + # note we need Python's new format syntax for binary + return ('{:%s}' % f).format(v) + def unescape(m): - if m.group()[1] == '%': return '%' - elif m.group()[1] == 'n': return '\n' - elif m.group()[1] == 'x': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == 'u': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == 'U': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == '(': + if m.group('pun')[0] == '%': s = '%' + elif m.group('pun')[0] == 'n': s = '\n' + elif m.group('pun')[0] == 's': s = ' ' + elif m.group('pun')[0] == 'x': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == 'u': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == 'U': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == '(': if attrs is not None: try: v = attrs[m.group('field')] @@ -356,27 +382,17 @@ def punescape(s, attrs=None): return m.group() else: return m.group() - f = m.group('format') - if f[-1] in 'dboxX': - if isinstance(v, str): - v = dat(v, 0) - v = int(v) - elif f[-1] in 'iIfFeEgG': - if isinstance(v, str): - v = dat(v, 0) - v = float(v) - if f[-1] in 'iI': - v = (si if 'i' in f[-1] else si2)(v) - f = f.replace('i', 's').replace('I', 's') - if '+' in f and not v.startswith('-'): - v = '+'+v - f = f.replace('+', '').replace('-', '') - else: - f = ('<' if '-' in f else '>') + f.replace('-', '') - v = str(v) - # note we need Python's new format syntax for binary - return ('{:%s}' % f).format(v) - else: assert False + s = format(m.group('format'), v) + elif m.group('pun')[0] == '{': + v = punescape(m.group('substring'), attrs) + s = format(m.group('subformat'), v) + else: + return m.group() + + if m.group('rep'): + s = int(m.group('rep'), 10) * s + + return s return re.sub(pattern, unescape, s) diff --git a/scripts/csv.py b/scripts/csv.py index 6b1b33fa..54f26150 100755 --- a/scripts/csv.py +++ b/scripts/csv.py @@ -1712,19 +1712,45 @@ def si2(x): # attrs can override __getitem__ for lazy attr generation def punescape(s, attrs=None): pattern = re.compile( - '%[%n]' - '|' '%x..' - '|' '%u....' - '|' '%U........' - '|' '%\((?P[^)]*)\)' - '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])') + '%' '(?P[0-9]*)' '(?P' + '[%ns]' + '|' 'x..' + '|' 'u....' + '|' 'U........' + '|' '\((?P[^)]*)\)' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' + '|' '\{(?P(?:[^%]|%[^}])*)%\}' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' ')') + + def format(f, v): + if f[-1] in 'dboxX': + if isinstance(v, str): + v = dat(v, 0) + v = int(v) + elif f[-1] in 'iIfFeEgG': + if isinstance(v, str): + v = dat(v, 0) + v = float(v) + if f[-1] in 'iI': + v = (si if 'i' in f[-1] else si2)(v) + f = f.replace('i', 's').replace('I', 's') + if '+' in f and not v.startswith('-'): + v = '+'+v + f = f.replace('+', '').replace('-', '') + else: + f = ('<' if '-' in f else '>') + f.replace('-', '') + v = str(v) + # note we need Python's new format syntax for binary + return ('{:%s}' % f).format(v) + def unescape(m): - if m.group()[1] == '%': return '%' - elif m.group()[1] == 'n': return '\n' - elif m.group()[1] == 'x': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == 'u': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == 'U': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == '(': + if m.group('pun')[0] == '%': s = '%' + elif m.group('pun')[0] == 'n': s = '\n' + elif m.group('pun')[0] == 's': s = ' ' + elif m.group('pun')[0] == 'x': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == 'u': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == 'U': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == '(': if attrs is not None: try: v = attrs[m.group('field')] @@ -1732,27 +1758,17 @@ def punescape(s, attrs=None): return m.group() else: return m.group() - f = m.group('format') - if f[-1] in 'dboxX': - if isinstance(v, str): - v = dat(v, 0) - v = int(v) - elif f[-1] in 'iIfFeEgG': - if isinstance(v, str): - v = dat(v, 0) - v = float(v) - if f[-1] in 'iI': - v = (si if 'i' in f[-1] else si2)(v) - f = f.replace('i', 's').replace('I', 's') - if '+' in f and not v.startswith('-'): - v = '+'+v - f = f.replace('+', '').replace('-', '') - else: - f = ('<' if '-' in f else '>') + f.replace('-', '') - v = str(v) - # note we need Python's new format syntax for binary - return ('{:%s}' % f).format(v) - else: assert False + s = format(m.group('format'), v) + elif m.group('pun')[0] == '{': + v = punescape(m.group('substring'), attrs) + s = format(m.group('subformat'), v) + else: + return m.group() + + if m.group('rep'): + s = int(m.group('rep'), 10) * s + + return s return re.sub(pattern, unescape, s) @@ -1769,6 +1785,7 @@ def punescape_help(): print('mods:') print(' %-21s %s' % ('%%', 'A literal % character')) print(' %-21s %s' % ('%n', 'A newline')) + print(' %-21s %s' % ('%s', 'A space')) print(' %-21s %s' % ( '%xaa', 'A character with the hex value aa')) print(' %-21s %s' % ( @@ -1785,6 +1802,12 @@ def punescape_help(): '%(field)[dboxX]', 'An existing field formatted as an integer')) print(' %-21s %s' % ( '%(field)[fFeEgG]', 'An existing field formatted as a float')) + print(' %-21s %s' % ( + '%{', 'Start a substring')) + print(' %-21s %s' % ( + '%}s', 'End and format a subtring')) + print(' %-21s %s' % ( + '%aaa[mod]', 'Repeat this mod aaa times')) # open with '-' for stdin/stdout diff --git a/scripts/dbgbmap.py b/scripts/dbgbmap.py index 34bd92ca..0335143b 100755 --- a/scripts/dbgbmap.py +++ b/scripts/dbgbmap.py @@ -4207,19 +4207,45 @@ def si2(x): # attrs can override __getitem__ for lazy attr generation def punescape(s, attrs=None): pattern = re.compile( - '%[%n]' - '|' '%x..' - '|' '%u....' - '|' '%U........' - '|' '%\((?P[^)]*)\)' - '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])') + '%' '(?P[0-9]*)' '(?P' + '[%ns]' + '|' 'x..' + '|' 'u....' + '|' 'U........' + '|' '\((?P[^)]*)\)' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' + '|' '\{(?P(?:[^%]|%[^}])*)%\}' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' ')') + + def format(f, v): + if f[-1] in 'dboxX': + if isinstance(v, str): + v = dat(v, 0) + v = int(v) + elif f[-1] in 'iIfFeEgG': + if isinstance(v, str): + v = dat(v, 0) + v = float(v) + if f[-1] in 'iI': + v = (si if 'i' in f[-1] else si2)(v) + f = f.replace('i', 's').replace('I', 's') + if '+' in f and not v.startswith('-'): + v = '+'+v + f = f.replace('+', '').replace('-', '') + else: + f = ('<' if '-' in f else '>') + f.replace('-', '') + v = str(v) + # note we need Python's new format syntax for binary + return ('{:%s}' % f).format(v) + def unescape(m): - if m.group()[1] == '%': return '%' - elif m.group()[1] == 'n': return '\n' - elif m.group()[1] == 'x': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == 'u': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == 'U': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == '(': + if m.group('pun')[0] == '%': s = '%' + elif m.group('pun')[0] == 'n': s = '\n' + elif m.group('pun')[0] == 's': s = ' ' + elif m.group('pun')[0] == 'x': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == 'u': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == 'U': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == '(': if attrs is not None: try: v = attrs[m.group('field')] @@ -4227,39 +4253,33 @@ def punescape(s, attrs=None): return m.group() else: return m.group() - f = m.group('format') - if f[-1] in 'dboxX': - if isinstance(v, str): - v = dat(v, 0) - v = int(v) - elif f[-1] in 'iIfFeEgG': - if isinstance(v, str): - v = dat(v, 0) - v = float(v) - if f[-1] in 'iI': - v = (si if 'i' in f[-1] else si2)(v) - f = f.replace('i', 's').replace('I', 's') - if '+' in f and not v.startswith('-'): - v = '+'+v - f = f.replace('+', '').replace('-', '') - else: - f = ('<' if '-' in f else '>') + f.replace('-', '') - v = str(v) - # note we need Python's new format syntax for binary - return ('{:%s}' % f).format(v) - else: assert False + s = format(m.group('format'), v) + elif m.group('pun')[0] == '{': + v = punescape(m.group('substring'), attrs) + s = format(m.group('subformat'), v) + else: + return m.group() + + if m.group('rep'): + s = int(m.group('rep'), 10) * s + + return s return re.sub(pattern, unescape, s) # split %-escaped strings into chars def psplit(s): pattern = re.compile( - '%[%n]' - '|' '%x..' - '|' '%u....' - '|' '%U........' - '|' '%\((?P[^)]*)\)' - '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])') + '%' '(?P[0-9]*)' '(?P' + '[%ns]' + '|' 'x..' + '|' 'u....' + '|' 'U........' + '|' '\((?P[^)]*)\)' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' + '|' '\{(?P(?:[^%]|%[^}])*)%\}' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' ')') + return [m.group() for m in re.finditer(pattern.pattern + '|.', s)] diff --git a/scripts/dbgbmapsvg.py b/scripts/dbgbmapsvg.py index 2229f0fe..7914917b 100755 --- a/scripts/dbgbmapsvg.py +++ b/scripts/dbgbmapsvg.py @@ -4096,19 +4096,45 @@ def si2(x): # attrs can override __getitem__ for lazy attr generation def punescape(s, attrs=None): pattern = re.compile( - '%[%n]' - '|' '%x..' - '|' '%u....' - '|' '%U........' - '|' '%\((?P[^)]*)\)' - '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])') + '%' '(?P[0-9]*)' '(?P' + '[%ns]' + '|' 'x..' + '|' 'u....' + '|' 'U........' + '|' '\((?P[^)]*)\)' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' + '|' '\{(?P(?:[^%]|%[^}])*)%\}' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' ')') + + def format(f, v): + if f[-1] in 'dboxX': + if isinstance(v, str): + v = dat(v, 0) + v = int(v) + elif f[-1] in 'iIfFeEgG': + if isinstance(v, str): + v = dat(v, 0) + v = float(v) + if f[-1] in 'iI': + v = (si if 'i' in f[-1] else si2)(v) + f = f.replace('i', 's').replace('I', 's') + if '+' in f and not v.startswith('-'): + v = '+'+v + f = f.replace('+', '').replace('-', '') + else: + f = ('<' if '-' in f else '>') + f.replace('-', '') + v = str(v) + # note we need Python's new format syntax for binary + return ('{:%s}' % f).format(v) + def unescape(m): - if m.group()[1] == '%': return '%' - elif m.group()[1] == 'n': return '\n' - elif m.group()[1] == 'x': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == 'u': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == 'U': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == '(': + if m.group('pun')[0] == '%': s = '%' + elif m.group('pun')[0] == 'n': s = '\n' + elif m.group('pun')[0] == 's': s = ' ' + elif m.group('pun')[0] == 'x': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == 'u': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == 'U': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == '(': if attrs is not None: try: v = attrs[m.group('field')] @@ -4116,27 +4142,17 @@ def punescape(s, attrs=None): return m.group() else: return m.group() - f = m.group('format') - if f[-1] in 'dboxX': - if isinstance(v, str): - v = dat(v, 0) - v = int(v) - elif f[-1] in 'iIfFeEgG': - if isinstance(v, str): - v = dat(v, 0) - v = float(v) - if f[-1] in 'iI': - v = (si if 'i' in f[-1] else si2)(v) - f = f.replace('i', 's').replace('I', 's') - if '+' in f and not v.startswith('-'): - v = '+'+v - f = f.replace('+', '').replace('-', '') - else: - f = ('<' if '-' in f else '>') + f.replace('-', '') - v = str(v) - # note we need Python's new format syntax for binary - return ('{:%s}' % f).format(v) - else: assert False + s = format(m.group('format'), v) + elif m.group('pun')[0] == '{': + v = punescape(m.group('substring'), attrs) + s = format(m.group('subformat'), v) + else: + return m.group() + + if m.group('rep'): + s = int(m.group('rep'), 10) * s + + return s return re.sub(pattern, unescape, s) diff --git a/scripts/dbgtrace.py b/scripts/dbgtrace.py index d8f1698d..0df2325c 100755 --- a/scripts/dbgtrace.py +++ b/scripts/dbgtrace.py @@ -482,19 +482,45 @@ def si2(x): # attrs can override __getitem__ for lazy attr generation def punescape(s, attrs=None): pattern = re.compile( - '%[%n]' - '|' '%x..' - '|' '%u....' - '|' '%U........' - '|' '%\((?P[^)]*)\)' - '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])') + '%' '(?P[0-9]*)' '(?P' + '[%ns]' + '|' 'x..' + '|' 'u....' + '|' 'U........' + '|' '\((?P[^)]*)\)' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' + '|' '\{(?P(?:[^%]|%[^}])*)%\}' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' ')') + + def format(f, v): + if f[-1] in 'dboxX': + if isinstance(v, str): + v = dat(v, 0) + v = int(v) + elif f[-1] in 'iIfFeEgG': + if isinstance(v, str): + v = dat(v, 0) + v = float(v) + if f[-1] in 'iI': + v = (si if 'i' in f[-1] else si2)(v) + f = f.replace('i', 's').replace('I', 's') + if '+' in f and not v.startswith('-'): + v = '+'+v + f = f.replace('+', '').replace('-', '') + else: + f = ('<' if '-' in f else '>') + f.replace('-', '') + v = str(v) + # note we need Python's new format syntax for binary + return ('{:%s}' % f).format(v) + def unescape(m): - if m.group()[1] == '%': return '%' - elif m.group()[1] == 'n': return '\n' - elif m.group()[1] == 'x': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == 'u': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == 'U': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == '(': + if m.group('pun')[0] == '%': s = '%' + elif m.group('pun')[0] == 'n': s = '\n' + elif m.group('pun')[0] == 's': s = ' ' + elif m.group('pun')[0] == 'x': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == 'u': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == 'U': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == '(': if attrs is not None: try: v = attrs[m.group('field')] @@ -502,39 +528,33 @@ def punescape(s, attrs=None): return m.group() else: return m.group() - f = m.group('format') - if f[-1] in 'dboxX': - if isinstance(v, str): - v = dat(v, 0) - v = int(v) - elif f[-1] in 'iIfFeEgG': - if isinstance(v, str): - v = dat(v, 0) - v = float(v) - if f[-1] in 'iI': - v = (si if 'i' in f[-1] else si2)(v) - f = f.replace('i', 's').replace('I', 's') - if '+' in f and not v.startswith('-'): - v = '+'+v - f = f.replace('+', '').replace('-', '') - else: - f = ('<' if '-' in f else '>') + f.replace('-', '') - v = str(v) - # note we need Python's new format syntax for binary - return ('{:%s}' % f).format(v) - else: assert False + s = format(m.group('format'), v) + elif m.group('pun')[0] == '{': + v = punescape(m.group('substring'), attrs) + s = format(m.group('subformat'), v) + else: + return m.group() + + if m.group('rep'): + s = int(m.group('rep'), 10) * s + + return s return re.sub(pattern, unescape, s) # split %-escaped strings into chars def psplit(s): pattern = re.compile( - '%[%n]' - '|' '%x..' - '|' '%u....' - '|' '%U........' - '|' '%\((?P[^)]*)\)' - '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])') + '%' '(?P[0-9]*)' '(?P' + '[%ns]' + '|' 'x..' + '|' 'u....' + '|' 'U........' + '|' '\((?P[^)]*)\)' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' + '|' '\{(?P(?:[^%]|%[^}])*)%\}' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' ')') + return [m.group() for m in re.finditer(pattern.pattern + '|.', s)] diff --git a/scripts/plot.py b/scripts/plot.py index fc3f12d2..6eabdc57 100755 --- a/scripts/plot.py +++ b/scripts/plot.py @@ -640,19 +640,45 @@ class CsvAttr: # attrs can override __getitem__ for lazy attr generation def punescape(s, attrs=None): pattern = re.compile( - '%[%n]' - '|' '%x..' - '|' '%u....' - '|' '%U........' - '|' '%\((?P[^)]*)\)' - '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])') + '%' '(?P[0-9]*)' '(?P' + '[%ns]' + '|' 'x..' + '|' 'u....' + '|' 'U........' + '|' '\((?P[^)]*)\)' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' + '|' '\{(?P(?:[^%]|%[^}])*)%\}' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' ')') + + def format(f, v): + if f[-1] in 'dboxX': + if isinstance(v, str): + v = dat(v, 0) + v = int(v) + elif f[-1] in 'iIfFeEgG': + if isinstance(v, str): + v = dat(v, 0) + v = float(v) + if f[-1] in 'iI': + v = (si if 'i' in f[-1] else si2)(v) + f = f.replace('i', 's').replace('I', 's') + if '+' in f and not v.startswith('-'): + v = '+'+v + f = f.replace('+', '').replace('-', '') + else: + f = ('<' if '-' in f else '>') + f.replace('-', '') + v = str(v) + # note we need Python's new format syntax for binary + return ('{:%s}' % f).format(v) + def unescape(m): - if m.group()[1] == '%': return '%' - elif m.group()[1] == 'n': return '\n' - elif m.group()[1] == 'x': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == 'u': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == 'U': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == '(': + if m.group('pun')[0] == '%': s = '%' + elif m.group('pun')[0] == 'n': s = '\n' + elif m.group('pun')[0] == 's': s = ' ' + elif m.group('pun')[0] == 'x': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == 'u': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == 'U': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == '(': if attrs is not None: try: v = attrs[m.group('field')] @@ -660,39 +686,33 @@ def punescape(s, attrs=None): return m.group() else: return m.group() - f = m.group('format') - if f[-1] in 'dboxX': - if isinstance(v, str): - v = dat(v, 0) - v = int(v) - elif f[-1] in 'iIfFeEgG': - if isinstance(v, str): - v = dat(v, 0) - v = float(v) - if f[-1] in 'iI': - v = (si if 'i' in f[-1] else si2)(v) - f = f.replace('i', 's').replace('I', 's') - if '+' in f and not v.startswith('-'): - v = '+'+v - f = f.replace('+', '').replace('-', '') - else: - f = ('<' if '-' in f else '>') + f.replace('-', '') - v = str(v) - # note we need Python's new format syntax for binary - return ('{:%s}' % f).format(v) - else: assert False + s = format(m.group('format'), v) + elif m.group('pun')[0] == '{': + v = punescape(m.group('substring'), attrs) + s = format(m.group('subformat'), v) + else: + return m.group() + + if m.group('rep'): + s = int(m.group('rep'), 10) * s + + return s return re.sub(pattern, unescape, s) # split %-escaped strings into chars def psplit(s): pattern = re.compile( - '%[%n]' - '|' '%x..' - '|' '%u....' - '|' '%U........' - '|' '%\((?P[^)]*)\)' - '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])') + '%' '(?P[0-9]*)' '(?P' + '[%ns]' + '|' 'x..' + '|' 'u....' + '|' 'U........' + '|' '\((?P[^)]*)\)' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' + '|' '\{(?P(?:[^%]|%[^}])*)%\}' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' ')') + return [m.group() for m in re.finditer(pattern.pattern + '|.', s)] diff --git a/scripts/plotmpl.py b/scripts/plotmpl.py index b3fe3f59..45f9c24a 100755 --- a/scripts/plotmpl.py +++ b/scripts/plotmpl.py @@ -524,19 +524,45 @@ class CsvAttr: # attrs can override __getitem__ for lazy attr generation def punescape(s, attrs=None): pattern = re.compile( - '%[%n]' - '|' '%x..' - '|' '%u....' - '|' '%U........' - '|' '%\((?P[^)]*)\)' - '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])') + '%' '(?P[0-9]*)' '(?P' + '[%ns]' + '|' 'x..' + '|' 'u....' + '|' 'U........' + '|' '\((?P[^)]*)\)' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' + '|' '\{(?P(?:[^%]|%[^}])*)%\}' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' ')') + + def format(f, v): + if f[-1] in 'dboxX': + if isinstance(v, str): + v = dat(v, 0) + v = int(v) + elif f[-1] in 'iIfFeEgG': + if isinstance(v, str): + v = dat(v, 0) + v = float(v) + if f[-1] in 'iI': + v = (si if 'i' in f[-1] else si2)(v) + f = f.replace('i', 's').replace('I', 's') + if '+' in f and not v.startswith('-'): + v = '+'+v + f = f.replace('+', '').replace('-', '') + else: + f = ('<' if '-' in f else '>') + f.replace('-', '') + v = str(v) + # note we need Python's new format syntax for binary + return ('{:%s}' % f).format(v) + def unescape(m): - if m.group()[1] == '%': return '%' - elif m.group()[1] == 'n': return '\n' - elif m.group()[1] == 'x': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == 'u': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == 'U': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == '(': + if m.group('pun')[0] == '%': s = '%' + elif m.group('pun')[0] == 'n': s = '\n' + elif m.group('pun')[0] == 's': s = ' ' + elif m.group('pun')[0] == 'x': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == 'u': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == 'U': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == '(': if attrs is not None: try: v = attrs[m.group('field')] @@ -544,27 +570,17 @@ def punescape(s, attrs=None): return m.group() else: return m.group() - f = m.group('format') - if f[-1] in 'dboxX': - if isinstance(v, str): - v = dat(v, 0) - v = int(v) - elif f[-1] in 'iIfFeEgG': - if isinstance(v, str): - v = dat(v, 0) - v = float(v) - if f[-1] in 'iI': - v = (si if 'i' in f[-1] else si2)(v) - f = f.replace('i', 's').replace('I', 's') - if '+' in f and not v.startswith('-'): - v = '+'+v - f = f.replace('+', '').replace('-', '') - else: - f = ('<' if '-' in f else '>') + f.replace('-', '') - v = str(v) - # note we need Python's new format syntax for binary - return ('{:%s}' % f).format(v) - else: assert False + s = format(m.group('format'), v) + elif m.group('pun')[0] == '{': + v = punescape(m.group('substring'), attrs) + s = format(m.group('subformat'), v) + else: + return m.group() + + if m.group('rep'): + s = int(m.group('rep'), 10) * s + + return s return re.sub(pattern, unescape, s) diff --git a/scripts/treemap.py b/scripts/treemap.py index aee3bdce..c164a9f4 100755 --- a/scripts/treemap.py +++ b/scripts/treemap.py @@ -561,19 +561,45 @@ def si2(x): # attrs can override __getitem__ for lazy attr generation def punescape(s, attrs=None): pattern = re.compile( - '%[%n]' - '|' '%x..' - '|' '%u....' - '|' '%U........' - '|' '%\((?P[^)]*)\)' - '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])') + '%' '(?P[0-9]*)' '(?P' + '[%ns]' + '|' 'x..' + '|' 'u....' + '|' 'U........' + '|' '\((?P[^)]*)\)' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' + '|' '\{(?P(?:[^%]|%[^}])*)%\}' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' ')') + + def format(f, v): + if f[-1] in 'dboxX': + if isinstance(v, str): + v = dat(v, 0) + v = int(v) + elif f[-1] in 'iIfFeEgG': + if isinstance(v, str): + v = dat(v, 0) + v = float(v) + if f[-1] in 'iI': + v = (si if 'i' in f[-1] else si2)(v) + f = f.replace('i', 's').replace('I', 's') + if '+' in f and not v.startswith('-'): + v = '+'+v + f = f.replace('+', '').replace('-', '') + else: + f = ('<' if '-' in f else '>') + f.replace('-', '') + v = str(v) + # note we need Python's new format syntax for binary + return ('{:%s}' % f).format(v) + def unescape(m): - if m.group()[1] == '%': return '%' - elif m.group()[1] == 'n': return '\n' - elif m.group()[1] == 'x': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == 'u': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == 'U': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == '(': + if m.group('pun')[0] == '%': s = '%' + elif m.group('pun')[0] == 'n': s = '\n' + elif m.group('pun')[0] == 's': s = ' ' + elif m.group('pun')[0] == 'x': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == 'u': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == 'U': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == '(': if attrs is not None: try: v = attrs[m.group('field')] @@ -581,39 +607,33 @@ def punescape(s, attrs=None): return m.group() else: return m.group() - f = m.group('format') - if f[-1] in 'dboxX': - if isinstance(v, str): - v = dat(v, 0) - v = int(v) - elif f[-1] in 'iIfFeEgG': - if isinstance(v, str): - v = dat(v, 0) - v = float(v) - if f[-1] in 'iI': - v = (si if 'i' in f[-1] else si2)(v) - f = f.replace('i', 's').replace('I', 's') - if '+' in f and not v.startswith('-'): - v = '+'+v - f = f.replace('+', '').replace('-', '') - else: - f = ('<' if '-' in f else '>') + f.replace('-', '') - v = str(v) - # note we need Python's new format syntax for binary - return ('{:%s}' % f).format(v) - else: assert False + s = format(m.group('format'), v) + elif m.group('pun')[0] == '{': + v = punescape(m.group('substring'), attrs) + s = format(m.group('subformat'), v) + else: + return m.group() + + if m.group('rep'): + s = int(m.group('rep'), 10) * s + + return s return re.sub(pattern, unescape, s) # split %-escaped strings into chars def psplit(s): pattern = re.compile( - '%[%n]' - '|' '%x..' - '|' '%u....' - '|' '%U........' - '|' '%\((?P[^)]*)\)' - '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])') + '%' '(?P[0-9]*)' '(?P' + '[%ns]' + '|' 'x..' + '|' 'u....' + '|' 'U........' + '|' '\((?P[^)]*)\)' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' + '|' '\{(?P(?:[^%]|%[^}])*)%\}' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' ')') + return [m.group() for m in re.finditer(pattern.pattern + '|.', s)] diff --git a/scripts/treemapsvg.py b/scripts/treemapsvg.py index 4245823b..91b1d75c 100755 --- a/scripts/treemapsvg.py +++ b/scripts/treemapsvg.py @@ -422,19 +422,45 @@ def si2(x): # attrs can override __getitem__ for lazy attr generation def punescape(s, attrs=None): pattern = re.compile( - '%[%n]' - '|' '%x..' - '|' '%u....' - '|' '%U........' - '|' '%\((?P[^)]*)\)' - '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])') + '%' '(?P[0-9]*)' '(?P' + '[%ns]' + '|' 'x..' + '|' 'u....' + '|' 'U........' + '|' '\((?P[^)]*)\)' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' + '|' '\{(?P(?:[^%]|%[^}])*)%\}' + '(?P[+\- #0-9\.]*[siIdboxXfFeEgG])' ')') + + def format(f, v): + if f[-1] in 'dboxX': + if isinstance(v, str): + v = dat(v, 0) + v = int(v) + elif f[-1] in 'iIfFeEgG': + if isinstance(v, str): + v = dat(v, 0) + v = float(v) + if f[-1] in 'iI': + v = (si if 'i' in f[-1] else si2)(v) + f = f.replace('i', 's').replace('I', 's') + if '+' in f and not v.startswith('-'): + v = '+'+v + f = f.replace('+', '').replace('-', '') + else: + f = ('<' if '-' in f else '>') + f.replace('-', '') + v = str(v) + # note we need Python's new format syntax for binary + return ('{:%s}' % f).format(v) + def unescape(m): - if m.group()[1] == '%': return '%' - elif m.group()[1] == 'n': return '\n' - elif m.group()[1] == 'x': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == 'u': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == 'U': return chr(int(m.group()[2:], 16)) - elif m.group()[1] == '(': + if m.group('pun')[0] == '%': s = '%' + elif m.group('pun')[0] == 'n': s = '\n' + elif m.group('pun')[0] == 's': s = ' ' + elif m.group('pun')[0] == 'x': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == 'u': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == 'U': s = chr(int(m.group('pun')[1:], 16)) + elif m.group('pun')[0] == '(': if attrs is not None: try: v = attrs[m.group('field')] @@ -442,27 +468,17 @@ def punescape(s, attrs=None): return m.group() else: return m.group() - f = m.group('format') - if f[-1] in 'dboxX': - if isinstance(v, str): - v = dat(v, 0) - v = int(v) - elif f[-1] in 'iIfFeEgG': - if isinstance(v, str): - v = dat(v, 0) - v = float(v) - if f[-1] in 'iI': - v = (si if 'i' in f[-1] else si2)(v) - f = f.replace('i', 's').replace('I', 's') - if '+' in f and not v.startswith('-'): - v = '+'+v - f = f.replace('+', '').replace('-', '') - else: - f = ('<' if '-' in f else '>') + f.replace('-', '') - v = str(v) - # note we need Python's new format syntax for binary - return ('{:%s}' % f).format(v) - else: assert False + s = format(m.group('format'), v) + elif m.group('pun')[0] == '{': + v = punescape(m.group('substring'), attrs) + s = format(m.group('subformat'), v) + else: + return m.group() + + if m.group('rep'): + s = int(m.group('rep'), 10) * s + + return s return re.sub(pattern, unescape, s)