| # Styling related hooks. |
| # Copyright (C) 2010-2023 Free Software Foundation, Inc. |
| |
| # This program is free software; you can redistribute it and/or modify |
| # it under the terms of the GNU General Public License as published by |
| # the Free Software Foundation; either version 3 of the License, or |
| # (at your option) any later version. |
| # |
| # This program is distributed in the hope that it will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details. |
| # |
| # You should have received a copy of the GNU General Public License |
| # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| |
| """Utilities for styling.""" |
| |
| import gdb |
| |
| try: |
| from pygments import formatters, lexers, highlight |
| from pygments.token import Error, Comment, Text |
| from pygments.filters import TokenMergeFilter |
| |
| _formatter = None |
| |
| def get_formatter(): |
| global _formatter |
| if _formatter is None: |
| _formatter = formatters.TerminalFormatter() |
| return _formatter |
| |
| def colorize(filename, contents): |
| # Don't want any errors. |
| try: |
| lexer = lexers.get_lexer_for_filename(filename, stripnl=False) |
| formatter = get_formatter() |
| return highlight(contents, lexer, formatter).encode( |
| gdb.host_charset(), "backslashreplace" |
| ) |
| except: |
| return None |
| |
| class HandleNasmComments(TokenMergeFilter): |
| @staticmethod |
| def fix_comments(lexer, stream): |
| in_comment = False |
| for ttype, value in stream: |
| if ttype is Error and value == "#": |
| in_comment = True |
| if in_comment: |
| if ttype is Text and value == "\n": |
| in_comment = False |
| else: |
| ttype = Comment.Single |
| yield ttype, value |
| |
| def filter(self, lexer, stream): |
| f = HandleNasmComments.fix_comments |
| return super().filter(lexer, f(lexer, stream)) |
| |
| _asm_lexers = {} |
| |
| def __get_asm_lexer(gdbarch): |
| lexer_type = "asm" |
| try: |
| # For an i386 based architecture, in 'intel' mode, use the nasm |
| # lexer. |
| flavor = gdb.parameter("disassembly-flavor") |
| if flavor == "intel" and gdbarch.name()[:4] == "i386": |
| lexer_type = "nasm" |
| except: |
| # If GDB is built without i386 support then attempting to fetch |
| # the 'disassembly-flavor' parameter will throw an error, which we |
| # ignore. |
| pass |
| |
| global _asm_lexers |
| if lexer_type not in _asm_lexers: |
| _asm_lexers[lexer_type] = lexers.get_lexer_by_name(lexer_type) |
| _asm_lexers[lexer_type].add_filter(HandleNasmComments()) |
| _asm_lexers[lexer_type].add_filter("raiseonerror") |
| return _asm_lexers[lexer_type] |
| |
| def colorize_disasm(content, gdbarch): |
| # Don't want any errors. |
| try: |
| lexer = __get_asm_lexer(gdbarch) |
| formatter = get_formatter() |
| return highlight(content, lexer, formatter).rstrip().encode() |
| except: |
| return content |
| |
| except: |
| |
| def colorize(filename, contents): |
| return None |
| |
| def colorize_disasm(content, gdbarch): |
| return None |