1#!@SHELL@
2## A utility -*- sh -*- filter highlighting disassembled code with ANSI escapes
3## Copyright (C) 2017 Luca Saiu
4## Written by Luca Saiu
5
6## This file is part of Jitter.
7
8## Jitter is free software: you can redistribute it and/or modify
9## it under the terms of the GNU General Public License as published by
10## the Free Software Foundation, either version 3 of the License, or
11## (at your option) any later version.
12
13## Jitter is distributed in the hope that it will be useful,
14## but WITHOUT ANY WARRANTY; without even the implied warranty of
15## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16## GNU General Public License for more details.
17
18## You should have received a copy of the GNU General Public License
19## along with Jitter.  If not, see <http://www.gnu.org/licenses/>.
20
21
22# Warnings.
23# ################################################################
24
25
26# This filter script is just provided as a convenience for debugging.  It makes
27# no serious attempt at being portable, and may rely on the GNU utilities.  It
28# accepts no arguments.
29
30# The intended way of using the script is as the last stage of a shell pipeline,
31# filtering the output of a Jitter VM program which is disassembling code.
32
33
34# Terminal escape sequence definitions.
35# ################################################################
36
37ESC=$(echo -e '\033')
38
39BLACK=$ESC[0m$ESC[30m
40BLUE=$ESC[0m$ESC[34m
41GREEN=$ESC[0m$ESC[32m
42CYAN=$ESC[0m$ESC[36m
43RED=$ESC[0m$ESC[31m
44MAGENTA=$ESC[0m$ESC[35m
45BROWN=$ESC[0m$ESC[33m
46LIGHTGRAY=$ESC[0m$ESC[37m
47DARKGRAY=$ESC[1m$ESC[30m
48LIGHTBLUE=$ESC[1m$ESC[34m
49LIGHTGREEN=$ESC[1m$ESC[32m
50LIGHTCYAN=$ESC[1m$ESC[36m
51LIGHTRED=$ESC[1m$ESC[31m
52LIGHTMAGENTA=$ESC[1m$ESC[35m
53YELLOW=$ESC[1m$ESC[33m
54WHITE=$ESC[1m$ESC[37m
55
56NOATTR=$ESC[0m
57
58BOLD=$ESC[1m
59FAINT=$ESC[2m
60ITALIC=$ESC[3m
61CROSSOUT=$ESC[9m
62UNDERLINE=$ESC[4m
63
64export REVERSE=$ESC[7m
65# Depending on the terminal BLINK could brighten the background
66export SLOWBLINK=$ESC[5m
67
68# Unsupported on all the terminals I've tried:
69export FASTBLINK=$ESC[6m
70export FRAME=$ESC[51m
71export ENCIRCLE=$ESC[52m
72export OVERLINE=$ESC[53m
73
74export CLEAR=$ESC[2J
75export TOPLEFT=$ESC[1\;1H
76
77# This is for setting the title of an Xterm window:
78export BEGINTITLE=\\033]0;
79export ENDTITLE=\\007
80
81
82# Define which attributes are to be used for highlighting.
83# ################################################################
84
85# Specialized instructions and threads.
86SPECIALIZED="$YELLOW"
87
88# Native instruction address.
89ADDRESS="$LIGHTMAGENTA"
90
91# Native instruction hexadecimal encoding.
92INSTRUCTION="$LIGHTGREEN"
93
94# Disassembled native instructions.
95DISASSEMBLY="$LIGHTCYAN"
96
97
98# Define sed commands.
99# ################################################################
100
101# I can easily insert, display and edit tab characters in the source code with
102# Emacs, but inferior editors will have problem showing it.  Let's define a
103# shell variable just for other people's sake.
104TAB=$(echo -e '\011')
105
106# Match entire lines starting with '#'; those contain specialized instructions,
107# with threads and arguments.
108COMMAND_SPECIALIZED="s/^\\(#.*\\)\$/${SPECIALIZED}\\1${NOATTR}/g"
109
110# Filter out space characters immediately preceding a tab character.  This lets
111# me remove one redundant space at the end of the instruction encoding as
112# displayed by objdump.
113REMOVE_SPACES_BEFORE_TAB="s/ *${TAB}/${TAB}/g"
114
115# Match the more complex disassembly lines, in the format generated by objdump
116# --disassembly (and my own compatibile fallback hexadecimal dumper).
117# Each of these line starts indented with spaces (filtered out); then, in order:
118# * the native instruction address (the initial "0x" is filtered out);
119# * the instruction hexadecimal encoding, possibly with bytes separated by
120#   spaces (on some architectures), and possibly with a final space;
121# * the instruction disassembly, preceded by a tab.
122COMMAND_NOT_SPECIALIZED="s/^\\(  *\\)\\?\\(0x\\)\\?\\([0-9a-f]*\\):\\?\\( *\\)\\([^${TAB}]*\\)\\t\\(.*\\)\$/${ADDRESS}\\3${NOATTR}${TAB}${INSTRUCTION}\\5${NOATTR}${TAB}${DISASSEMBLY}\\6${NOATTR}/g"
123
124# Replace sequences of multiple whitespace characters containing a tab with a
125# single tab.  Replace multiple consecutive spaces with a single space.
126NORMALIZE_WHITESPACE="s/ *${TAB} */${TAB}/g;s/  */ /g"
127
128# Replace the first two tabs in each line with a space (to keep the address and
129# instruction encoding visually close in each disassembly line) and an otherwise
130# unused character, respectively; then replace any remaining tab with a space
131# (this removes any tab in the disassembly part, making it narrower); replace
132# back any occurrence of the unused character with a tab, to restore the visual
133# separation between instruction encoding and disassembly.
134UNUSED=$(echo -e '\a')
135NORMALIZE_TABS="s/^\\([^${TAB}]*\\)${TAB}\\([^${TAB}]*\\)${TAB}\\(.*\\)\$/\\1 \\2${UNUSED}\\3/g;s/${TAB}/ /g;s/${UNUSED}/${TAB}/g"
136
137
138# Run a sed program obtained by concatenating commands.
139# ################################################################
140
141# Read on stdin, write on stdout.
142@SED@ \
143  "${REMOVE_SPACES_BEFORE_TAB};
144   ${COMMAND_SPECIALIZED};
145   ${COMMAND_NOT_SPECIALIZED};
146   ${NORMALIZE_WHITESPACE};
147   ${NORMALIZE_TABS}"
148