diff --git a/plugins/c9.ide.run.debug/debuggers/gdb/shim.js b/plugins/c9.ide.run.debug/debuggers/gdb/shim.js index b930919d..d78f2f2b 100755 --- a/plugins/c9.ide.run.debug/debuggers/gdb/shim.js +++ b/plugins/c9.ide.run.debug/debuggers/gdb/shim.js @@ -1,3 +1,282 @@ +/** + * gdb-mi-parser + * https://github.com/llop/gdb-mi-parser + */ + +//---------------------------------------------------------- +// +// Helper string functions +// +//---------------------------------------------------------- + +function isEmpty(str) { + return !str || 0===str.length; +} +function trim(str) { + if (str) str = str.trim(); + return str; +} + + +//---------------------------------------------------------- +// +// prefix mappings +// +//---------------------------------------------------------- + +var recordTypeMapping = { + '^': 'result', + '~': 'stream', + '&': 'stream', + '@': 'stream', + '*': 'async', + '+': 'async', + '=': 'async' +}; + +var outputTypeMapping = { + '^': 'result', + '~': 'console', + '&': 'log', + '@': 'target', + '*': 'exec', + '+': 'status', + '=': 'notify' +}; + + +/* + * About gdb output + * https://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Output-Syntax.html + * + * output ==> + * ( out-of-band-record )* [ result-record ] "(gdb)" nl + * result-record ==> + * [ token ] "^" result-class ( "," result )* nl + * out-of-band-record ==> + * async-record | stream-record + * async-record ==> + * exec-async-output | status-async-output | notify-async-output + * exec-async-output ==> + * [ token ] "*" async-output nl + * status-async-output ==> + * [ token ] "+" async-output nl + * notify-async-output ==> + * [ token ] "=" async-output nl + * async-output ==> + * async-class ( "," result )* + * result-class ==> + * "done" | "running" | "connected" | "error" | "exit" + * async-class ==> + * "stopped" | others (where others will be added depending on the needs—this is still in development). + * result ==> + * variable "=" value + * variable ==> + * string + * value ==> + * const | tuple | list + * const ==> + * c-string + * tuple ==> + * "{}" | "{" result ( "," result )* "}" + * list ==> + * "[]" | "[" value ( "," value )* "]" | "[" result ( "," result )* "]" + * stream-record ==> + * console-stream-output | target-stream-output | log-stream-output + * console-stream-output ==> + * "~" c-string nl + * target-stream-output ==> + * "@" c-string nl + * log-stream-output ==> + * "&" c-string nl + * nl ==> + * CR | CR-LF + * token ==> + * any sequence of digits. + * + * Notes: + * * All output sequences end in a single line containing a period. + * * The token is from the corresponding request. Note that for all async output, while the token is allowed by + * the grammar and may be output by future versions of gdb for select async output messages, it is generally omitted. + * Frontends should treat all async output as reporting general changes in the state of the target + * and there should be no need to associate async output to any prior command. + * * status-async-output contains on-going status information about the progress of a slow operation. It can be discarded. + * All status output is prefixed by ‘+’. + * * exec-async-output contains asynchronous state change on the target (stopped, started, disappeared). + * All async output is prefixed by ‘*’. + * * notify-async-output contains supplementary information that the client should handle (e.g., a new breakpoint information). + * All notify output is prefixed by ‘=’. + * * console-stream-output is output that should be displayed as is in the console. It is the textual response to a CLI command. + * All the console output is prefixed by ‘~’. + * * target-stream-output is the output produced by the target program. All the target output is prefixed by ‘@’. + * * log-stream-output is output text coming from gdb's internals, for instance messages that should be displayed + * as part of an error log. All the log output is prefixed by ‘&’. + * * New gdb/mi commands should only output lists containing values + */ + +function eatWhitespace(line, i) { + while (i='0' && line[j]<='9') ++j; + return [j, line.substring(i, j)]; +} + +function nextClass(line, i) { + var j = i+1; + while (j ( out-of-band-record )* [ result-record ] "(gdb)" nl + return { + hasTerminator: hasTerminator, + outOfBandRecords: outOfBandRecords, + resultRecord: resultRecord + }; +} + /** * GDB Debugger plugin for Cloud9 * @@ -7,7 +286,6 @@ var net = require('net'); var fs = require('fs'); -var parseGdbMiOutput = require('gdb-mi-parser'); var spawn = require('child_process').spawn; // process arguments @@ -772,7 +1050,7 @@ function GDB() { // handle a line of stdout from gdb this._handleLine = function(line) { - var output = parseGdbMiOutput(line); + var output = parseGdbMiOut(line); if (output.hasTerminator) return;