diff options
| author | Eli Zaretskii | 2015-10-01 14:40:10 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2015-10-01 14:40:10 +0300 |
| commit | 439f483be35a000e7a3bec6acf395ce4d54d6323 (patch) | |
| tree | d21afbfe259ab35e830e999f542237b7e29fc585 | |
| parent | e8d83f4b60e373d88e37c52857f4138caac8472c (diff) | |
| download | emacs-439f483be35a000e7a3bec6acf395ce4d54d6323.tar.gz emacs-439f483be35a000e7a3bec6acf395ce4d54d6323.zip | |
Fix GUD display of GDB output with non-ASCII text
* lisp/progmodes/gdb-mi.el (gdb-mi-decode-strings): New defcustom.
(gdb-mi-decode): New function.
(gud-gdbmi-marker-filter): If gdb-mi-decode-strings is non-nil,
decode octal escapes in GDB output. (Bug#21572)
| -rw-r--r-- | lisp/progmodes/gdb-mi.el | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el index 62d18e2c7c0..47589fb6e34 100644 --- a/lisp/progmodes/gdb-mi.el +++ b/lisp/progmodes/gdb-mi.el | |||
| @@ -2315,9 +2315,67 @@ the end of the current result or async record is reached." | |||
| 2315 | ; list ==> | 2315 | ; list ==> |
| 2316 | ; "[]" | "[" value ( "," value )* "]" | "[" result ( "," result )* "]" | 2316 | ; "[]" | "[" value ( "," value )* "]" | "[" result ( "," result )* "]" |
| 2317 | 2317 | ||
| 2318 | (defcustom gdb-mi-decode-strings nil | ||
| 2319 | "When non-nil, decode octal escapes in GDB output into non-ASCII text. | ||
| 2320 | |||
| 2321 | If the value is a coding-system, use that coding-system to decode | ||
| 2322 | the bytes reconstructed from octal escapes. Any other non-nil value | ||
| 2323 | means to decode using the coding-system set for the GDB process. | ||
| 2324 | |||
| 2325 | Warning: setting this non-nil might mangle strings reported by GDB | ||
| 2326 | that have literal substrings which match the \\nnn octal escape | ||
| 2327 | patterns, where nnn is an octal number between 200 and 377. So | ||
| 2328 | we only recommend to set this variable non-nil if the program you | ||
| 2329 | are debugging really reports non-ASCII text, or some of its source | ||
| 2330 | file names include non-ASCII characters." | ||
| 2331 | :type '(choice | ||
| 2332 | (const :tag "Don't decode" nil) | ||
| 2333 | (const :tag "Decode using default coding-system" t) | ||
| 2334 | (coding-system :tag "Decode using this coding-system")) | ||
| 2335 | :group 'gdb | ||
| 2336 | :version "25.1") | ||
| 2337 | |||
| 2338 | ;; The idea of the following function was suggested | ||
| 2339 | ;; by Kenichi Handa <handa@gnu.org>. | ||
| 2340 | ;; | ||
| 2341 | ;; FIXME: This is fragile: it relies on the assumption that all the | ||
| 2342 | ;; non-ASCII strings output by GDB, including names of the source | ||
| 2343 | ;; files, values of string variables in the inferior, etc., are all | ||
| 2344 | ;; encoded in the same encoding. It also assumes that the \nnn | ||
| 2345 | ;; sequences are not split between chunks of output of the GDB process | ||
| 2346 | ;; due to buffering, and arrive together. Finally, if some string | ||
| 2347 | ;; included literal \nnn strings (as opposed to non-ASCII characters | ||
| 2348 | ;; converted by by GDB/MI to octal escapes), this decoding will mangle | ||
| 2349 | ;; those strings. When/if GDB acquires the ability to not | ||
| 2350 | ;; escape-protect non-ASCII characters in its MI output, this kludge | ||
| 2351 | ;; should be removed. | ||
| 2352 | (defun gdb-mi-decode (string) | ||
| 2353 | "Decode octal escapes in MI output STRING into multibyte text." | ||
| 2354 | (let ((coding | ||
| 2355 | (if (coding-system-p gdb-mi-decode-strings) | ||
| 2356 | gdb-mi-decode-strings | ||
| 2357 | (with-current-buffer | ||
| 2358 | (gdb-get-buffer-create 'gdb-partial-output-buffer) | ||
| 2359 | buffer-file-coding-system)))) | ||
| 2360 | (with-temp-buffer | ||
| 2361 | (set-buffer-multibyte nil) | ||
| 2362 | (insert (gdb-mi-quote string)) | ||
| 2363 | (goto-char (point-min)) | ||
| 2364 | ;; gdb-mi-quote quotes the octal escapes as well, which | ||
| 2365 | ;; interferes with their interpretation by 'read' below. Remove | ||
| 2366 | ;; the extra backslashes to countermand that. | ||
| 2367 | (while (re-search-forward "\\\\\\(\\\\[2-3][0-7][0-7]\\)" nil t) | ||
| 2368 | (replace-match "\\1" nil nil)) | ||
| 2369 | (goto-char (point-min)) | ||
| 2370 | (decode-coding-string (read (current-buffer)) coding)))) | ||
| 2371 | |||
| 2318 | (defun gud-gdbmi-marker-filter (string) | 2372 | (defun gud-gdbmi-marker-filter (string) |
| 2319 | "Filter GDB/MI output." | 2373 | "Filter GDB/MI output." |
| 2320 | 2374 | ||
| 2375 | ;; If required, decode non-ASCII text encoded with octal escapes. | ||
| 2376 | (or (null gdb-mi-decode-strings) | ||
| 2377 | (setq string (gdb-mi-decode string))) | ||
| 2378 | |||
| 2321 | ;; Record transactions if logging is enabled. | 2379 | ;; Record transactions if logging is enabled. |
| 2322 | (when gdb-enable-debug | 2380 | (when gdb-enable-debug |
| 2323 | (push (cons 'recv string) gdb-debug-log) | 2381 | (push (cons 'recv string) gdb-debug-log) |