Created
February 26, 2015 09:42
-
-
Save jonasc/23eb0861a9158ff03247 to your computer and use it in GitHub Desktop.
better trail file viewer for spin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import sys | |
import os | |
import subprocess | |
import re | |
colors = [ | |
'black', | |
'blue', | |
'cyan', | |
'green', | |
'magenta', | |
'red', | |
'white', | |
'yellow', | |
] | |
shortcolors = [ | |
'b', | |
'c', | |
'g', | |
'm', | |
'r', | |
'w', | |
'y', | |
] | |
def _foreground(s, color): | |
colors = { | |
'black': '\x1b[30m', | |
'blue': '\x1b[34m', | |
'cyan': '\x1b[36m', | |
'green': '\x1b[32m', | |
'magenta': '\x1b[35m', | |
'red': '\x1b[31m', | |
'white': '\x1b[37m', | |
'yellow': '\x1b[33m', | |
} | |
links = { | |
'b': 'blue', | |
'c': 'cyan', | |
'g': 'green', | |
'm': 'magenta', | |
'r': 'red', | |
'w': 'white', | |
'y': 'yellow', | |
} | |
color = colors.get(color) or colors.get(links.get(color), '') | |
return '{color}{s}'.format(color=color, s=s) | |
def _background(s, color): | |
colors = { | |
'black': '\x1b[40m', | |
'blue': '\x1b[44m', | |
'cyan': '\x1b[46m', | |
'green': '\x1b[42m', | |
'magenta': '\x1b[45m', | |
'red': '\x1b[41m', | |
'white': '\x1b[47m', | |
'yellow': '\x1b[43m', | |
} | |
links = { | |
'b': 'blue', | |
'c': 'cyan', | |
'g': 'green', | |
'm': 'magenta', | |
'r': 'red', | |
'w': 'white', | |
'y': 'yellow', | |
} | |
color = colors.get(color) or colors.get(links.get(color), '') | |
return '{color}{s}'.format(color=color, s=s) | |
def _bold(s): | |
return '{bold}{s}'.format(bold='\x1b[1m', s=s) | |
def _underline(s): | |
return '{underline}{s}'.format(underline='\x1b[4m', s=s) | |
def _reverse(s): | |
return '{reverse}{s}'.format(reverse='\x1b[7m', s=s) | |
def _reset(s): | |
return '{s}{reset}'.format(s=s, reset='\x1b[0m') | |
def color(s, foreground=None, background=None, bold=False, underline=False, | |
reverse=False): | |
'''Return the given string, wrapped in the given colour. | |
Foreground and background can be one of: | |
black, red, green, yellow, blue, magenta, cyan, white. | |
Also resets the colour and other attributes at the end of the string. | |
''' | |
# if not s or not os.isatty(1): | |
# return s | |
if foreground: | |
s = _foreground(s, foreground) | |
if background: | |
s = _background(s, background) | |
if bold: | |
s = _bold(s) | |
if underline: | |
s = _underline(s) | |
if reverse: | |
s = _reverse(s) | |
s = _reset(s) | |
return s | |
def main(): | |
proc = subprocess.Popen( | |
['spin', '-p', '-r', '-s', '-l', '-g', '-t', sys.argv[1]], | |
universal_newlines=True, | |
stdout=subprocess.PIPE | |
) | |
re_start = re.compile(r'Starting (?P<name>\S+) with pid (?P<pid>\d+)') | |
re_cmd = re.compile(r'\s*(?P<no>\d+):\s+proc\s+(?P<pid>\d+)\s+\((?P<name>\S+):(?P<nno>\d+)\)\s+(?P<file>\S+)\s+\(\S+\s+(?P<state>\d+)\)\s+\[(?P<cmd>.+)\]') | |
re_qcmd = re.compile(r'\s*(?P<no>\d+):\s+proc\s+(?P<pid>\d+)\s+\((?P<name>\S+)\)\s+(?P<file>\S+)\s+(Send|Recv)\s+(?P<msg>\S+)\s+(->|<-)\s+queue\s+(?P<queue>\d+)\s+\((?P<dir>in|out)\)') | |
re_local = re.compile(r'\s+(?P<name>\S+)\((?P<pid>\d+)\):(?P<var>\S+)\s+=\s+(?P<value>\S+)') | |
re_global = re.compile(r'\s+(?P<var>\S+)\s+=\s+(?P<value>\S+)') | |
re_queue = re.compile(r'\s+queue\s+(?P<var>\d+)[^:]+:(\s+(?P<value>\S+))?') | |
re_cycle = re.compile(r'\s+<<<<<START OF CYCLE>>>>>') | |
globals = dict() | |
locals = dict() | |
# queues = dict() | |
previous_proc = '' | |
proc_names = dict() | |
for line in proc.stdout: | |
line = line.rstrip() | |
if re_start.fullmatch(line): | |
print(color(line, foreground='yellow')) | |
pass | |
elif re_cmd.fullmatch(line): | |
m = re_cmd.fullmatch(line) | |
d = m.groupdict() | |
print('\n'.join([ | |
color('\t\t{} = {}', foreground='blue').format(k, locals[k]) | |
for k in sorted(locals.keys()) | |
if k.startswith(proc_names.get(previous_proc, '')) | |
])) | |
print('\n'.join([ | |
color('\t\t{} = {}', foreground='cyan').format(k, globals[k]) | |
for k in sorted(globals.keys()) | |
])) | |
if previous_proc != d['name']+'('+d['pid']+')': | |
print(color('='*100)) | |
print(re_cmd.sub(r'\1:\tproc \2\t(\3:\4)\t\5\t(state \6):\t'+color(r'\7', foreground='magenta', bold=True), line)) | |
previous_proc = d['name']+'('+d['pid']+')' | |
pass | |
elif re_qcmd.fullmatch(line): | |
print(line) | |
pass | |
elif re_local.fullmatch(line): | |
m = re_local.fullmatch(line) | |
d = m.groupdict() | |
locals['{}({}):{}'.format(d['name'], d['pid'], d['var'])] = d['value'] | |
proc_names[previous_proc] = '{}({})'.format(d['name'], d['pid']) | |
elif re_global.fullmatch(line): | |
m = re_global.fullmatch(line) | |
d = m.groupdict() | |
globals[d['var']] = d['value'] | |
elif re_queue.fullmatch(line): | |
# m = re_queue.fullmatch(line) | |
# d = m.groupdict() | |
# queues[d['var']] = d['value'] | |
print(color(line, foreground='green')) | |
elif re_cycle.fullmatch(line): | |
print('\n' + color( | |
'<'*40 + ' START OF CYCLE ' + '>'*40, | |
foreground='yellow', | |
background='red', | |
bold=True, | |
underline=True) + '\n') | |
else: | |
print(line) | |
pass | |
if __name__ == '__main__': | |
try: | |
main() | |
except BrokenPipeError: | |
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
better-trail $@ | /usr/bin/less |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment