Skip to content

Instantly share code, notes, and snippets.

@jonasc
Created February 26, 2015 09:42
Show Gist options
  • Save jonasc/23eb0861a9158ff03247 to your computer and use it in GitHub Desktop.
Save jonasc/23eb0861a9158ff03247 to your computer and use it in GitHub Desktop.
better trail file viewer for spin
#!/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
#!/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