import * as os from 'os' ; import * as nls from 'vscode-nls' ; nls . config ( { messageFormat : nls . MessageFormat . bundle , bundleFormat : nls . BundleFormat . standalone } ) ( ) ; const localize = nls . loadMessageBundle ( ) ; export enum DebuggerType { cppvsdbg , cppdbg } export interface IConfigurationSnippet { label : string ; description : string ; bodyText : string ; isInitialConfiguration ? : boolean ; debuggerType : DebuggerType ; } export function indentJsonString ( json , numTabs = 1 ) { return json . split ( '\n' ) . map ( line => '\t' . repeat ( numTabs ) + line ) . join ( '\n' ) . trim ( ) ; } function formatString ( format , args ) { args . forEach ( ( arg , index ) => { format = format . replace ( "{" + index + "}" , arg ) ; } ) ; return format ; } function createLaunchString ( name , type , executable ) { return `"name": "${ name }",
"type": "${ type }",
"request": "launch",
"program": "${ localize ( "enter.program.name" , "enter program name, for example {0}" , "$\{workspaceFolder\}" + "/" + executable ) . replace ( /\"/g , "\\\"" ) }",
"args": [],
"stopAtEntry": false,
"cwd": "$\{fileDirname\}",
"environment": [],
${ type === "cppdbg" ? `"externalConsole": false` : `"console": "externalTerminal"` }
` ; } function createAttachString ( name , type , executable ) { return formatString ( `
"name": "${ name }",
"type": "${ type }",
"request": "attach",{0}
"processId": "$\{command:pickProcess\}"
` , [ type === "cppdbg" ? `${ os . EOL }"program": "${ localize ( "enter.program.name" , "enter program name, for example {0}" , "$\{workspaceFolder\}" + "/" + executable ) . replace ( /\"/g , "\\\"" ) }",` : "" ] ) ; } function createRemoteAttachString ( name , type , executable ) { return `
"name": "${ name }",
"type": "${ type }",
"request": "attach",
"program": "${ localize ( "enter.program.name" , "enter program name, for example {0}" , "$\{workspaceFolder\}" + "/" + executable ) . replace ( /\"/g , "\\\"" ) }",
"processId": "$\{command:pickRemoteProcess\}"
` ; } function createPipeTransportString ( pipeProgram , debuggerProgram , pipeArgs = [ ] ) { return `
"pipeTransport": {
\t"debuggerPath": "/usr/bin/${ debuggerProgram }",
\t"pipeProgram": "${ pipeProgram }",
\t"pipeArgs": ${ JSON . stringify ( pipeArgs ) },
\t"pipeCwd": ""
}` ; } export interface IConfiguration { GetLaunchConfiguration ( ) : IConfigurationSnippet ; GetAttachConfiguration ( ) : IConfigurationSnippet ; } abstract class Configuration implements IConfiguration { public snippetPrefix = "C/C++: " ; public executable : string ; public pipeProgram : string ; public MIMode : string ; public additionalProperties : string ; public miDebugger = "cppdbg" ; public windowsDebugger = "cppvsdbg" ; constructor ( MIMode , executable , pipeProgram , additionalProperties = "" ) { this . MIMode = MIMode ; this . executable = executable ; this . pipeProgram = pipeProgram ; this . additionalProperties = additionalProperties ; } abstract GetLaunchConfiguration ( ) ; abstract GetAttachConfiguration ( ) ; } export class MIConfigurations extends Configuration { public GetLaunchConfiguration ( ) { const name = `(${ this . MIMode }) ${ localize ( "launch.string" , "Launch" ) . replace ( /\"/g , "\\\"" ) }` ; const body = formatString ( `{
\t${ indentJsonString ( createLaunchString ( name , this . miDebugger , this . executable ) ) },
\t"MIMode": "${ this . MIMode }"{0}{1}
}` , [ this . miDebugger === "cppdbg" && os . platform ( ) === "win32" ? `,${ os . EOL }\t"miDebuggerPath": "/path/to/gdb"` : "" , this . additionalProperties ? `,${ os . EOL }\t${ indentJsonString ( this . additionalProperties ) }` : "" ] ) ; return { "label" : this . snippetPrefix + name , "description" : localize ( "launch.with" , "Launch with {0}." , this . MIMode ) . replace ( /\"/g , "\\\"" ) , "bodyText" : body . trim ( ) , "isInitialConfiguration" : true , "debuggerType" : DebuggerType . cppdbg } ; } public GetAttachConfiguration ( ) { const name = `(${ this . MIMode }) ${ localize ( "attach.string" , "Attach" ) . replace ( /\"/g , "\\\"" ) }` ; const body = formatString ( `{
\t${ indentJsonString ( createAttachString ( name , this . miDebugger , this . executable ) ) },
\t"MIMode": "${ this . MIMode }"{0}{1}
}` , [ this . miDebugger === "cppdbg" && os . platform ( ) === "win32" ? `,${ os . EOL }\t"miDebuggerPath": "/path/to/gdb"` : "" , this . additionalProperties ? `,${ os . EOL }\t${ indentJsonString ( this . additionalProperties ) }` : "" ] ) ; return { "label" : this . snippetPrefix + name , "description" : localize ( "attach.with" , "Attach with {0}." , this . MIMode ) . replace ( /\"/g , "\\\"" ) , "bodyText" : body . trim ( ) , "debuggerType" : DebuggerType . cppdbg } ; } } export class PipeTransportConfigurations extends Configuration { public GetLaunchConfiguration ( ) { const name = `(${ this . MIMode }) ${ localize ( "pipe.launch" , "Pipe Launch" ) . replace ( /\"/g , "\\\"" ) }` ; const body = formatString ( `
{
\t${ indentJsonString ( createLaunchString ( name , this . miDebugger , this . executable ) ) },
\t${ indentJsonString ( createPipeTransportString ( this . pipeProgram , this . MIMode ) ) },
\t"MIMode": "${ this . MIMode }"{0}
}` , [ this . additionalProperties ? `,${ os . EOL }\t${ indentJsonString ( this . additionalProperties ) }` : "" ] ) ; return { "label" : this . snippetPrefix + name , "description" : localize ( "pipe.launch.with" , "Pipe Launch with {0}." , this . MIMode ) . replace ( /\"/g , "\\\"" ) , "bodyText" : body . trim ( ) , "debuggerType" : DebuggerType . cppdbg } ; } public GetAttachConfiguration ( ) { const name = `(${ this . MIMode }) ${ localize ( "pipe.attach" , "Pipe Attach" ) . replace ( /\"/g , "\\\"" ) }` ; const body = formatString ( `
{
\t${ indentJsonString ( createRemoteAttachString ( name , this . miDebugger , this . executable ) ) },
\t${ indentJsonString ( createPipeTransportString ( this . pipeProgram , this . MIMode ) ) },
\t"MIMode": "${ this . MIMode }"{0}
}` , [ this . additionalProperties ? `,${ os . EOL }\t${ indentJsonString ( this . additionalProperties ) }` : "" ] ) ; return { "label" : this . snippetPrefix + name , "description" : localize ( "pipe.attach.with" , "Pipe Attach with {0}." , this . MIMode ) . replace ( /\"/g , "\\\"" ) , "bodyText" : body . trim ( ) , "debuggerType" : DebuggerType . cppdbg } ; } } export class WindowsConfigurations extends Configuration { public GetLaunchConfiguration ( ) { const name = `(Windows) ${ localize ( "launch.string" , "Launch" ) . replace ( /\"/g , "\\\"" ) }` ; const body = `
{
\t${ indentJsonString ( createLaunchString ( name , this . windowsDebugger , this . executable ) ) }
}` ; return { "label" : this . snippetPrefix + name , "description" : localize ( "launch.with.vs.debugger" , "Launch with the Visual Studio C/C++ debugger." ) . replace ( /\"/g , "\\\"" ) , "bodyText" : body . trim ( ) , "isInitialConfiguration" : true , "debuggerType" : DebuggerType . cppvsdbg } ; } public GetAttachConfiguration ( ) { const name = `(Windows) ${ localize ( "attach.string" , "Attach" ) . replace ( /\"/g , "\\\"" ) }` ; const body = `
{
\t${ indentJsonString ( createAttachString ( name , this . windowsDebugger , this . executable ) ) }
}` ; return { "label" : this . snippetPrefix + name , "description" : localize ( "attach.with.vs.debugger" , "Attach to a process with the Visual Studio C/C++ debugger." ) . replace ( /\"/g , "\\\"" ) , "bodyText" : body . trim ( ) , "debuggerType" : DebuggerType . cppvsdbg } ; } } export class WSLConfigurations extends Configuration { public bashPipeProgram = process . arch === 'ia32' ? "${env:windir}\\\\sysnative\\\\bash.exe" : "${env:windir}\\\\system32\\\\bash.exe" ; public GetLaunchConfiguration ( ) { const name = `(${ this . MIMode }) ${ localize ( "bash.on.windows.launch" , "Bash on Windows Launch" ) . replace ( /\"/g , "\\\"" ) }` ; const body = formatString ( `
{
\t${ indentJsonString ( createLaunchString ( name , this . miDebugger , this . executable ) ) },
\t${ indentJsonString ( createPipeTransportString ( this . bashPipeProgram , this . MIMode , [ "-c" ] ) ) }{0}
}` , [ this . additionalProperties ? `,${ os . EOL }\t${ indentJsonString ( this . additionalProperties ) }` : "" ] ) ; return { "label" : this . snippetPrefix + name , "description" : localize ( "launch.bash.windows" , "Launch in Bash on Windows using {0}." , this . MIMode ) . replace ( /\"/g , "\\\"" ) , "bodyText" : body . trim ( ) , "debuggerType" : DebuggerType . cppdbg } ; } public GetAttachConfiguration ( ) { const name = `(${ this . MIMode }) ${ localize ( "bash.on.windows.attach" , "Bash on Windows Attach" ) . replace ( /\"/g , "\\\"" ) }` ; const body = formatString ( `
{
\t${ indentJsonString ( createRemoteAttachString ( name , this . miDebugger , this . executable ) ) },
\t${ indentJsonString ( createPipeTransportString ( this . bashPipeProgram , this . MIMode , [ "-c" ] ) ) }{0}
}` , [ this . additionalProperties ? `,${ os . EOL }\t${ indentJsonString ( this . additionalProperties ) }` : "" ] ) ; return { "label" : this . snippetPrefix + name , "description" : localize ( "remote.attach.bash.windows" , "Attach to a remote process running in Bash on Windows using {0}." , this . MIMode ) . replace ( /\"/g , "\\\"" ) , "bodyText" : body . trim ( ) , "debuggerType" : DebuggerType . cppdbg } ; } }