mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
e651eaa072
Update the dict that takes care of mapping PTML tokens to their color with the updated list of PTML tokens.
127 lines
4.0 KiB
Python
127 lines
4.0 KiB
Python
#
|
|
# This file is distributed under the MIT License. See LICENSE.md for details.
|
|
#
|
|
|
|
import re
|
|
import sys
|
|
from io import TextIOWrapper
|
|
from typing import Dict
|
|
from xml.dom import Node
|
|
from xml.dom.minidom import Document, parseString
|
|
|
|
from .common import handle_file, log, normalize_filter_extract
|
|
|
|
COLOR_CONVERSION = {
|
|
"comment": "white",
|
|
"asm.label": "bright_red",
|
|
"asm.label-indicator": "bright_white",
|
|
"asm.mnemonic": "dodger_blue1",
|
|
"asm.mnemonic-prefix": "bright_green",
|
|
"asm.mnemonic-suffix": "bright_green",
|
|
"asm.immediate-value": "dark_slate_gray2",
|
|
"asm.memory-operand": "dodger_blue1",
|
|
"asm.register": "orange1",
|
|
"asm.helper": "dodger_blue1",
|
|
"asm.directive": "sea_green1",
|
|
"asm.instruction-address": "medium_purple1",
|
|
"asm.raw-bytes": "white",
|
|
"c.function": "bright_red",
|
|
"c.type": "sea_green1",
|
|
"c.operator": "dodger_blue1",
|
|
"c.comparison": "dodger_blue1",
|
|
"c.function_parameter": "orange1",
|
|
"c.variable": "orange1",
|
|
"c.field": "orange1",
|
|
"c.constant": "dark_slate_gray2",
|
|
"c.string_literal": "medium_purple1",
|
|
"c.keyword": "dodger_blue1",
|
|
"c.directive": "dodger_blue1",
|
|
"doxygen.keyword": "turquoise2",
|
|
"doxygen.identifier": "tan",
|
|
}
|
|
|
|
|
|
class PlainConsole:
|
|
def __init__(self, file: TextIOWrapper):
|
|
self.file = file
|
|
|
|
def print(self, text: str, *, end: str = "\n", **kwargs): # noqa: A003
|
|
self.file.write(f"{text}{end}")
|
|
|
|
def __del__(self):
|
|
self.file.flush()
|
|
|
|
|
|
def parse_ptml_plain(content: str, console):
|
|
dom = parseString(content)
|
|
_parse_ptml_node(dom, console, "", {})
|
|
|
|
|
|
def parse_ptml_yaml(content: Dict[str, str], console):
|
|
for key, value in content.items():
|
|
# Output the yaml key manually, this is for two main reasons:
|
|
# * rich.Console works well with file object, having strings would be cumbersome
|
|
# * pyyaml cannot output strings as flow scalars without some hacking around
|
|
console.print(f"{key}:", style="yellow1", end="")
|
|
console.print(" |-")
|
|
dom = parseString(value)
|
|
console.print(" ", end="")
|
|
_parse_ptml_node(dom, console, " ", {})
|
|
console.print("\n", end="")
|
|
|
|
|
|
def _parse_ptml_node(node: Document, console, indent: str, metadata: Dict[str, str]):
|
|
for node in node.childNodes:
|
|
if node.nodeType == Node.TEXT_NODE:
|
|
content = re.sub("\n", f"\n{indent}", node.nodeValue)
|
|
if "data-token" in metadata and metadata["data-token"] in COLOR_CONVERSION:
|
|
console.print(content, end="", style=COLOR_CONVERSION[metadata["data-token"]])
|
|
else:
|
|
console.print(content, end="")
|
|
elif node.nodeType == Node.ELEMENT_NODE:
|
|
new_metadata = {**metadata}
|
|
for key, value in node.attributes.items():
|
|
new_metadata[key] = value
|
|
_parse_ptml_node(node, console, indent, new_metadata)
|
|
|
|
|
|
def cmd_text(args):
|
|
if args.inplace and args.input == sys.stdin.buffer:
|
|
log("Cannot strip inplace while reading from stdin")
|
|
return 1
|
|
|
|
filters = normalize_filter_extract(args.filter, args.extract)
|
|
content = args.input.read()
|
|
|
|
if args.inplace:
|
|
args.input.seek(0)
|
|
args.input.truncate(0)
|
|
output = TextIOWrapper(args.input, "utf-8")
|
|
else:
|
|
output = args.output
|
|
|
|
if not args.color:
|
|
console = PlainConsole(output)
|
|
else:
|
|
try:
|
|
# rich takes a while to import, do it if needed
|
|
from rich.console import Console
|
|
|
|
console = Console(markup=False, highlight=False, force_terminal=True, file=output)
|
|
console.options.no_wrap = True
|
|
color = True
|
|
except ImportError:
|
|
console = PlainConsole(output)
|
|
color = False
|
|
|
|
if args.color and not color:
|
|
log("Module 'rich' not found, please install it to use color mode")
|
|
return 1
|
|
|
|
return handle_file(
|
|
content,
|
|
lambda x: parse_ptml_plain(x, console),
|
|
lambda x: parse_ptml_yaml(x, console),
|
|
filters,
|
|
)
|