Ben Cheng | d9735fc | 2013-08-22 22:10:54 -0700 | [diff] [blame] | 1 | # Extended prompt utilities. |
| 2 | # Copyright (C) 2011-2013 Free Software Foundation, Inc. |
| 3 | |
| 4 | # This program is free software; you can redistribute it and/or modify |
| 5 | # it under the terms of the GNU General Public License as published by |
| 6 | # the Free Software Foundation; either version 3 of the License, or |
| 7 | # (at your option) any later version. |
| 8 | # |
| 9 | # This program is distributed in the hope that it will be useful, |
| 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | # GNU General Public License for more details. |
| 13 | # |
| 14 | # You should have received a copy of the GNU General Public License |
| 15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 16 | |
| 17 | """ Extended prompt library functions.""" |
| 18 | |
| 19 | import gdb |
| 20 | import os |
| 21 | |
| 22 | def _prompt_pwd(ignore): |
| 23 | "The current working directory." |
| 24 | return os.getcwdu() |
| 25 | |
| 26 | def _prompt_object_attr(func, what, attr, nattr): |
| 27 | """Internal worker for fetching GDB attributes.""" |
| 28 | if attr is None: |
| 29 | attr = nattr |
| 30 | try: |
| 31 | obj = func() |
| 32 | except gdb.error: |
| 33 | return '<no %s>' % what |
| 34 | if hasattr(obj, attr): |
| 35 | result = getattr(obj, attr) |
| 36 | if callable(result): |
| 37 | result = result() |
| 38 | return result |
| 39 | else: |
| 40 | return '<no attribute %s on current %s>' % (attr, what) |
| 41 | |
| 42 | def _prompt_frame(attr): |
| 43 | "The selected frame; an argument names a frame parameter." |
| 44 | return _prompt_object_attr(gdb.selected_frame, 'frame', attr, 'name') |
| 45 | |
| 46 | def _prompt_thread(attr): |
| 47 | "The selected thread; an argument names a thread parameter." |
| 48 | return _prompt_object_attr(gdb.selected_thread, 'thread', attr, 'num') |
| 49 | |
| 50 | def _prompt_version(attr): |
| 51 | "The version of GDB." |
| 52 | return gdb.VERSION |
| 53 | |
| 54 | def _prompt_esc(attr): |
| 55 | "The ESC character." |
| 56 | return '\033' |
| 57 | |
| 58 | def _prompt_bs(attr): |
| 59 | "A backslash." |
| 60 | return '\\' |
| 61 | |
| 62 | def _prompt_n(attr): |
| 63 | "A newline." |
| 64 | return '\n' |
| 65 | |
| 66 | def _prompt_r(attr): |
| 67 | "A carriage return." |
| 68 | return '\r' |
| 69 | |
| 70 | def _prompt_param(attr): |
| 71 | "A parameter's value; the argument names the parameter." |
| 72 | return gdb.parameter(attr) |
| 73 | |
| 74 | def _prompt_noprint_begin(attr): |
| 75 | "Begins a sequence of non-printing characters." |
| 76 | return '\001' |
| 77 | |
| 78 | def _prompt_noprint_end(attr): |
| 79 | "Ends a sequence of non-printing characters." |
| 80 | return '\002' |
| 81 | |
| 82 | prompt_substitutions = { |
| 83 | 'e': _prompt_esc, |
| 84 | '\\': _prompt_bs, |
| 85 | 'n': _prompt_n, |
| 86 | 'r': _prompt_r, |
| 87 | 'v': _prompt_version, |
| 88 | 'w': _prompt_pwd, |
| 89 | 'f': _prompt_frame, |
| 90 | 't': _prompt_thread, |
| 91 | 'p': _prompt_param, |
| 92 | '[': _prompt_noprint_begin, |
| 93 | ']': _prompt_noprint_end |
| 94 | } |
| 95 | |
| 96 | def prompt_help(): |
| 97 | """Generate help dynamically from the __doc__ strings of attribute |
| 98 | functions.""" |
| 99 | |
| 100 | result = '' |
| 101 | keys = sorted (prompt_substitutions.keys()) |
| 102 | for key in keys: |
| 103 | result += ' \\%s\t%s\n' % (key, prompt_substitutions[key].__doc__) |
| 104 | result += """ |
| 105 | A substitution can be used in a simple form, like "\\f". |
| 106 | An argument can also be passed to it, like "\\f{name}". |
| 107 | The meaning of the argument depends on the particular substitution.""" |
| 108 | return result |
| 109 | |
| 110 | def substitute_prompt(prompt): |
| 111 | "Perform substitutions on PROMPT." |
| 112 | |
| 113 | result = '' |
| 114 | plen = len(prompt) |
| 115 | i = 0 |
| 116 | while i < plen: |
| 117 | if prompt[i] == '\\': |
| 118 | i = i + 1 |
| 119 | if i >= plen: |
| 120 | break |
| 121 | cmdch = prompt[i] |
| 122 | |
| 123 | if cmdch in prompt_substitutions: |
| 124 | cmd = prompt_substitutions[cmdch] |
| 125 | |
| 126 | if i + 1 < plen and prompt[i + 1] == '{': |
| 127 | j = i + 1 |
| 128 | while j < plen and prompt[j] != '}': |
| 129 | j = j + 1 |
| 130 | # Just ignore formatting errors. |
| 131 | if j >= plen or prompt[j] != '}': |
| 132 | arg = None |
| 133 | else: |
| 134 | arg = prompt[i + 2 : j] |
| 135 | i = j |
| 136 | else: |
| 137 | arg = None |
| 138 | result += str(cmd(arg)) |
| 139 | else: |
| 140 | # Unrecognized escapes are turned into the escaped |
| 141 | # character itself. |
| 142 | result += prompt[i] |
| 143 | else: |
| 144 | result += prompt[i] |
| 145 | |
| 146 | i = i + 1 |
| 147 | |
| 148 | return result |