I am trying to setup a problemMatcher for a build task inside VSCode, the command generate messages like the following:
14 : ../../Dsrc/path/to/file.h:44:58: error: class ‘tf::ARandomClass’ does not have any field named ‘epsilon’
Using https://regex101.com/ I constructed a the following expression to build the problem matcher: \.\.\/\.\.\/Dsrc\/(.*?):(.*?):(.*?): (.*?): (.*?)$
However, the following problem matcher inside VS Code does not work:
"problemMatcher": {
"owner": "cpp",
"fileLocation": ["relative", "${workspaceFolder}"],
"pattern": {
"regexp": "\.\.\/\.\.\/Dsrc\/(.*?):(.*?):(.*?): (.*?): (.*?)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
},
Even if I remove the \.\.\/\.\.\/Dsrc\/ part, it does seems do match anything inside the terminal. What I am doing wrong ?
try the regex:
^\d+\s*:\s*([^:]+):(\d+):(\d+): (.*?): (.*?)$
Because the configuration file is JSON, you need to escape your escapes in the regexp value (i.e., double up your backslashes):
"regexp": "\\.\\.\\/\\.\\.\\/Dsrc\\/(.*?):(.*?):(.*?): (.*?): (.*?)$",
Related
The GNU linker emits error messages in this style:
_Boot/Debug/libs\Common.a(oled.o):V:\OneDrive\Emb\App_M2S_S32G/Common/src/oled.c:40: multiple definition of `time'; _Boot/Debug/libs\Boot.a(bootloader.o):V:\OneDrive\Emb\App_M2S_S32G/Boot/src/bootloader.c:27: first defined here
I want to create two problems from this single line, for the two files and line numbers mentioned in the message, so that I can click both of them and navigate to the offending lines (oled.c:40 and bootloader.c:27).
It's possible to create patterns for the compiler and for both parts of the linker message:
"problemMatcher": [
// Compiler
{
"base": "$gcc",
"fileLocation": [
"autodetect",
"${workspaceFolder}"
]
},
// Linker 1
{
"source": "ld",
"pattern": {
"regexp": "^.+; .*(.:.+):([0-9]+): (.+)",
"file": 1,
"line": 2,
"message": 3
},
"fileLocation": [
"autodetect",
"${workspaceFolder}"
]
},
// Linker 2
{
"source": "ld",
"pattern": {
"regexp": "^.+; .*(.:.+):([0-9]+): (.+)",
"file": 1,
"line": 2,
"message": 3
},
"fileLocation": [
"autodetect",
"${workspaceFolder}"
]
}
],
This does not work, because if the Linker 1 pattern matched, the Linker 2 is not executed at all. If I copy the regexp from Linker 2 to Linker 1, the second part of the message is parsed properly.
Is it somehow possible to tell Code to always attempt to match all patterns, even if a previous one already matched? Or any other way to create multiple problems from one message line?
I have a bunch of custom build tasks in VS Code and I want a custom problem matcher for the C++ ones.
So I decided to take the default problem matcher example in VS Code docs (https://code.visualstudio.com/Docs/editor/tasks#_defining-a-problem-matcher) and modified it slightly.
"problemMatcher": {
"fileLocation": ["relative", "${workspaceFolder}"],
"pattern": {
"regexp": "^(\\.\\.\\/+)(.*):(\\d+):(\\d+):\\s+(.*):\\s+(.*)$",
"file": 2,
"line": 3,
"column": 4,
"severity": 5,
"message": 6
}
My error messages have the following structure:
../../../module/src/module/specific/File.cpp:155:31: error: errorMessage
The three directory-up instructions (../../../) bring me back to ${workspaceFolder}. So the idea was to use the second capture group as a relative path from my workspace folder to follow up to the file.
Unfortunately, the file path does not highlight and it doesn't tell me to Ctrl+click to follow the message. I double checked the regex on https://regexr.com/ and it seems to be correct. I tried using the the default problem matcher too, without any luck.
This is the full build task:
{
"label": "build_c++",
"type": "shell",
"command": "${workspaceFolder}/build_command",
"problemMatcher": [ {
"fileLocation": ["relative", "${workspaceFolder}"],
"pattern": {
"regexp": "^(\\.\\.\\/+)(.*):(\\d+):(\\d+):\\s+(.*):\\s+(.*)$",
"file": 2,
"line": 3,
"column": 4,
"severity": 5,
"message": 6
}
}],
"group": {
"kind": "build",
"isDefault": true
}
},
Any ideas?
The following Tasks.json
Problem matcher regular expression should match the following typical warning. But it doesn't.
ctc W505: ["somedirectory/somefile.c" 350/18] implicit declaration blah blah blah
What is the issue ? I verified the built-in parser matches gcc output errors and warnings.
Thanks,
Satish K
"tasks": [
{
"label": "build.bat",
"type": "shell",
"command": "build.bat",
"problemMatcher": {
"owner": "cpptools",
"fileLocation": [
"relative",
"${env:PWD}"
],
"pattern": {
"regexp": "^ctc W(\\d+): \\[\\\"(.*)\\\" (\\d+)\\\/(\\d+)\\] (.*)$",
"file": 2,
"line": 3,
"column": 4,
"message": 5
}
},
"group": {
"kind": "build",
"isDefault": true
}
}
]
You add an additional \ to the expression, you only need to escape the " and you don't need to escape /
"tasks": [
{
"label": "build.bat",
"type": "shell",
"command": "build.bat",
"problemMatcher": {
"owner": "cpptools",
"fileLocation": [
"relative",
"${env:PWD}"
],
"pattern": {
"regexp": "^ctc W(\\d+): \\[\"(.*)\" (\\d+)/(\\d+)\\] (.*)$",
"file": 2,
"line": 3,
"column": 4,
"message": 5
}
},
"group": {
"kind": "build",
"isDefault": true
}
}
]
Edit
This works in regex101 (flavor Javascript)
^ctc W(\d+): \["(.*)" (\d+)\/(\d+)\] (.*)$
To translate it to a JSON string, escape \" and regex also wants you to escape / but that would only be needed if you use the regex in a literal Javascript (like /\d+/g) but we don't do that in VSC, but it won't hurt.
Resulting in:
"^ctc W(\\d+): \\[\"(.*)\" (\\d+)\\/(\\d+)\\] (.*)$"
I couldn't get this to work. But I ran the working regex101 through a json escpare. It did some more escaping of slashes and ended up as:
"regexp": "^ctc W(\\d+): \\[\\\"(.*)\\\" (\\d+)\\/(\\d+)\\] (.*)$",
I have a problem matcher defined like this:
"fileLocation": ["relative", "${workspaceFolder}"],
And I only know the name of the file and NOT the relative path from my compilation output.
Than it only opens files when they are in the root of the workspace.
E.g.
Problem matcher searches for: Package.sql
But the file is under
root
Other Subfolders
PKGs
Package.sql
Is there a setting to let the problem matcher "find" that file, even if it's in a (unknown) subfolder?
(Assumed all filenames are distinct)
You can use "command" string for print file with relative or absolute path like this:
echo FILEBEGIN${relativeFile}FILEEND
or
echo FILEBEGIN${file}FILEEND
And it will be easy to get file by regex.
If you are using oracle and powershell you can try my task:
{
"label": "compile",
"type": "shell",
"command": "echo 'set define off' 'set serveroutput on' '#${file}' 'exit' | sqlplus ${config:plsql-language.connection.activeInfos} | Select-String -Pattern '(\\d+/\\d+.*|.*created.*)' | % {'${relativeFile}:' + $($_.matches.value)}",
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": {
"owner": "PLSQL",
"severity": "error",
"fileLocation": ["relative", "${workspaceFolder}"],
"pattern":
{
"regexp": "^(.*):(\\d+)\\/(\\d+)\\s+((PLS|ORA)-\\d+):(.*)$",
"file": 1,
"line": 2,
"column": 3,
"code": 4,
"message": 6
}
}
}
The problem matcher should return either absolute path, or path relative to a fixed folder inside the workspace. If you have a filename only, without absolute/relative path, in my understanding Code won't be able to locate the file as the name only is not enough information.
There is also the autodetect option. You can try something like this:
"fileLocation": ["autodetect", "${workspaceFolder}/subfolder1/subfolder2"]
I have a task for Powershell in VSCode, but can't figure out how to make the problemMatch work
{
"version": "0.1.0",
"command": "PowerShell.exe",
"isShellCommand": true,
"suppressTaskName": true,
"args": [
"& '${file}'"
],
"tasks": [
{
"taskName": "Build",
"isBuildCommand": true,
"showOutput": "always",
"fileLocation": ["absolute"],
"problemMatcher": [
{
"pattern": {
"regexp": "At (.*\\.ps1):(\\d*) char:(\\d*)(.*)\\n\\+(.*)\\n\\+(.*)\\n(.*)",
"file": 1,
"line": 2,
"column": 3,
"message": 7
}
}]
}]
}
Regex targets as so :
At C:\tmp\C1-INT to C1-QA\a.ps1:1 char:11
+ "asdasds" !
+ ~
Unexpected token '!' in expression or statement.
file: Group 1 "C:\tmp\C1-INT to C1-QA\a.ps1"
line: Group 2 "1"
column: Group 3 "11"
message: Group 7 Unexpected token '!' in expression or statement.
I'm not sure that the regex for a problem matcher can handle line breaks. By default problem matchers are single line, but you can create multi-line matchers as described here: https://code.visualstudio.com/Docs/editor/tasks#_defining-a-multiline-problem-matcher
Essentially you provide multiple regex's. For your scenario you could try something like the following:
"problemMatcher": {
"owner": "custom",
"fileLocation": ["absolute"],
"pattern": [{
"regexp": "At (.*\\.ps1):(\\d*) char:(\\d*)(.*)",
"file": 1,
"line": 2,
"column": 3
}, {
"regexp": "\\+.*"
},{
"regexp": "\\+.*"
},{
"regexp": "(.+)",
"message": 1
}]
}
The first pattern matches the file, line and column in the first line. The second and third patterns match the next two lines of output but don't capture any values. The final line matches the next output line and captures it all as the message.
Hope that helps!