diff --git a/README.md b/README.md index e660ef0..7d51051 100644 --- a/README.md +++ b/README.md @@ -180,13 +180,6 @@ Add `gdbtty` property to your `launch.json`. Here’s an example: ``` ![GdbTTY](gdbttydisplay.png) -* Linux Requirements: `xterm` - -How to install xterm on Ubuntu: -``` -sudo apt-get install xterm -``` - On Linux you can see the output of the application in Vs Code itself. Add `gdbtty` property with `vscode` value to your `launch.json`. Here is an example: ```json { @@ -203,6 +196,8 @@ On Linux you can see the output of the application in Vs Code itself. Add `gdbtt ``` ![GdbTTY](gdbttyvscode.png) +You can also use these options with `gdbtty`: `xterm`, `gnome-terminal`, `konsole` and `xfce4-terminal`. + ### Roadmap - Mac - Unit testing diff --git a/package.json b/package.json index 52e6542..91205c9 100644 --- a/package.json +++ b/package.json @@ -144,6 +144,10 @@ true, false, "vscode", + "xterm", + "gnome-terminal", + "xfce4-terminal", + "konsole", "external" ] } diff --git a/src/mi2.ts b/src/mi2.ts index a932f0b..4b90fb1 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -1066,7 +1066,7 @@ export class MI2 extends EventEmitter implements IDebugger { try_find++; if (xterm_device != "") break; } - if (xterm_device === "") this.log("stderr", "tty: Install 'xterm' to use gdb's tty option\n"); + if (xterm_device === "") this.log("stderr", "tty: Install a terminal to use gdb's tty option\n"); } if (xterm_device.includes("pts")) { this.gdbArgs.push("--tty=" + xterm_device); @@ -1114,24 +1114,113 @@ export class MI2 extends EventEmitter implements IDebugger { return strCode; } + isTerminalInstalled(terminalCommand: string): boolean { + try { + ChildProcess.execSync(`command -v ${terminalCommand}`); + return true; + } catch (error) { + return false; + } + } + + createXFCETerminal(sleepVal, target) { + let dispTarget = (target.length > 50) ? "..." + target.substr(target.length - 50, target.length) : target; + let param = "bash -c 'echo \"GnuCOBOL DEBUG\"; sleep " + sleepVal + ";'"; + const xfce4_terminal_args = [ + "--title", "GnuCOBOL Debug - " + dispTarget, + "--font=DejaVu Sans Mono 14", + "--command", param + ] + const xfce_process = ChildProcess.spawn("xfce4-terminal", xfce4_terminal_args, { + detached: true, + stdio: 'ignore' + }); + xfce_process.unref(); + } + + createKDETerminal(sleepVal, target) { + let dispTarget = (target.length > 50) ? "..." + target.substr(target.length - 50, target.length) : target; + let param = "bash -c 'echo \"GnuCOBOL DEBUG\"; sleep " + sleepVal + ";'"; + const konsole_args = [ + "--title", "GnuCOBOL Debug - " + dispTarget, + "--separate", + "--nofork", + "--hold", + "-e", + param + ] + const kde_process = ChildProcess.spawn("konsole", konsole_args, { + detached: true, + stdio: 'ignore' + }); + kde_process.unref(); + } + + createGNOMETerminal(sleepVal, target) { + let dispTarget = (target.length > 50) ? "..." + target.substr(target.length - 50, target.length) : target; + const gnome_terminal_args = [ + "--title", "GnuCOBOL Debug - " + dispTarget, + "--", + "bash", "-c","echo 'GnuCOBOL DEBUG';" + "sleep " + sleepVal + ";" + ] + const gnome_process = ChildProcess.spawn("gnome-terminal", gnome_terminal_args, { + detached: true, + stdio: 'ignore', + }); + gnome_process.unref(); + } + + createXtermTerminal(sleepVal, target) { + let dispTarget = (target.length > 50) ? "..." + target.substr(target.length - 50, target.length) : target; + const xterm_args = [ + "-title", "GnuCOBOL Debug - " + dispTarget, + "-fa", "DejaVu Sans Mono", + "-fs", "14", + "-e", "/usr/bin/tty;" + + "echo 'GnuCOBOL DEBUG';" + + "sleep " + sleepVal + ";" + ] + const xterm_process = ChildProcess.spawn("xterm", xterm_args, { + detached: true, + stdio: 'ignore', + }); + xterm_process.unref(); + } + // Opens a terminal to show the application screen - gdbtty createTerminal(gdbtty, sleepVal, target) { + let findTerminal = true; if (gdbtty != "vscode") { - let dispTarget = (target.length > 50) ? "..." + target.substr(target.length - 50, target.length) : target; - const xterm_args = [ - "-title", "GnuCOBOL Debug - " + dispTarget, - "-fa", "DejaVu Sans Mono", - "-fs", "14", - "-e", "/usr/bin/tty;" + - "echo 'GnuCOBOL DEBUG';" + - "sleep " + sleepVal + ";" - ] - - const xterm_process = ChildProcess.spawn("xterm", xterm_args, { - detached: true, - stdio: 'ignore', - }); - xterm_process.unref(); + if (typeof gdbtty === 'string' && gdbtty!="external") { + if(this.isTerminalInstalled(gdbtty)){ + findTerminal = false; + switch (gdbtty) { + case "xterm": + this.createXtermTerminal(sleepVal, target); + break; + case "gnome-terminal": + this.createGNOMETerminal(sleepVal, target); + break; + case "konsole": + this.createKDETerminal(sleepVal, target); + break; + case "xfce4-terminal": + this.createXFCETerminal(sleepVal, target); + break; + } + } + } + if(findTerminal){ + if(this.isTerminalInstalled("xterm")){ + this.createXtermTerminal(sleepVal, target); + }else if(this.isTerminalInstalled("gnome-terminal")){ + this.createGNOMETerminal(sleepVal, target); + }else if(this.isTerminalInstalled("xfce4-terminal")){ + this.createXFCETerminal(sleepVal, target); + }else if(this.isTerminalInstalled("konsole")){ + this.createKDETerminal(sleepVal, target); + } + } } else { let terminal = this.selectTerminal(); if (!terminal) { diff --git a/src/parser.c.ts b/src/parser.c.ts index 1c93e86..5778f55 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -34,6 +34,7 @@ const versionRegex = /\/\*\sGenerated by\s+cobc\s([0-9a-z\-\.]+)\s+\*\//i; const subroutineRegex = /\sPerform\s/i; const frame_ptrFindRegex = /frame\_ptr\-\-\;/; const fixOlderFormat = /cob\_trace\_stmt/; +const programExit = /\/\*\sProgram\s\exit\s+\*\//i; globalThis.varOccurs = []; @@ -67,7 +68,7 @@ export class SourceMap { private version: string; private lineBefore: string = ""; private performLine: number = -1; // 002 - stepOver in routines with "perform" - private isVersion2_2_or_3_1_1: boolean = false; + private isVersion2_2_or_3_1_1: boolean = false; constructor(cwd: string, filesCobol: string[]) { this.cwd = fs.realpathSync(nativePathFromPath.resolve(cwd)); @@ -78,6 +79,8 @@ export class SourceMap { private parse(fileC: string): void { let nat = fileC; + let hasProgramExit = false; + if (!nativePath.isAbsolute(fileC)) { nat = nativePathFromPath.resolve(this.cwd, fileC); fileC = nativePath.resolve(this.cwd, fileC); @@ -119,9 +122,9 @@ export class SourceMap { } // fix new codegen match = procedureFixRegex.exec(line); - if (match && this.lines.length > 0) { + if (match && this.lines.length > 0 && !hasProgramExit) { let isOldFormat = fixOlderFormat.exec(this.lineBefore); - if(this.isVersion2_2_or_3_1_1 || !isOldFormat){ // Is it in the old format? + if(fileNameCompare(this.lines[this.lines.length - 1].fileCobol, fileCobol) && (this.isVersion2_2_or_3_1_1 || !isOldFormat)){ // Is it in the old format? let line = this.lines.pop(); line.lineC = parseInt(match[1]); this.lines.push(line); @@ -176,6 +179,10 @@ export class SourceMap { } } this.lineBefore = line; + match = programExit.exec(line); + if (match) { + hasProgramExit=true;; + } lineNumber++; } }