Skip to content

Commit 5d691d4

Browse files
committed
debug: Allow type-specification of JSON output for cortex-debug
1 parent ef72bde commit 5d691d4

File tree

4 files changed

+83
-6
lines changed

4 files changed

+83
-6
lines changed

Diff for: commands/debug/debug_info.go

+35-6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"context"
2020
"encoding/json"
2121
"regexp"
22+
"strconv"
2223
"strings"
2324

2425
"github.com/arduino/arduino-cli/arduino"
@@ -209,28 +210,56 @@ func getDebugProperties(req *rpc.GetDebugConfigRequest, pme *packagemanager.Expl
209210
// my.indexed.array.2=third
210211
//
211212
// into the corresponding JSON arrays.
213+
// If a value should be converted into a JSON type different from string, the value
214+
// may be prefiex with "[boolean]", "[number]", or "[object]":
215+
//
216+
// my.stringValue=a string
217+
// my.booleanValue=[boolean]true
218+
// my.numericValue=[number]20
212219
func convertToJsonMap(in *properties.Map) string {
213-
// XXX: Maybe this method could be a good candidate for propertis.Map?
214-
215220
// Find the values that should be kept as is, and the indexed arrays
216221
// that should be later converted into arrays.
217222
arraysKeys := map[string]bool{}
218-
stringKeys := []string{}
223+
scalarKeys := []string{}
219224
trailingNumberMatcher := regexp.MustCompile(`^(.*)\.[0-9]+$`)
220225
for _, k := range in.Keys() {
221226
match := trailingNumberMatcher.FindAllStringSubmatch(k, -1)
222227
if len(match) > 0 && len(match[0]) > 1 {
223228
arraysKeys[match[0][1]] = true
224229
} else {
225-
stringKeys = append(stringKeys, k)
230+
scalarKeys = append(scalarKeys, k)
226231
}
227232
}
228233

229234
// Compose a map that can be later marshaled into JSON keeping
230235
// the arrays where they are expected to be.
231236
res := map[string]any{}
232-
for _, k := range stringKeys {
233-
res[k] = in.Get(k)
237+
for _, k := range scalarKeys {
238+
v := in.Get(k)
239+
switch {
240+
case strings.HasPrefix(v, "[boolean]"):
241+
v = strings.TrimSpace(strings.TrimPrefix(v, "[boolean]"))
242+
if strings.EqualFold(v, "true") {
243+
res[k] = true
244+
} else if strings.EqualFold(v, "false") {
245+
res[k] = false
246+
}
247+
case strings.HasPrefix(v, "[number]"):
248+
v = strings.TrimPrefix(v, "[number]")
249+
if i, err := strconv.Atoi(v); err == nil {
250+
res[k] = i
251+
} else if f, err := strconv.ParseFloat(v, 64); err == nil {
252+
res[k] = f
253+
}
254+
case strings.HasPrefix(v, "[object]"):
255+
v = strings.TrimPrefix(v, "[object]")
256+
var o interface{}
257+
if err := json.Unmarshal([]byte(v), &o); err == nil {
258+
res[k] = o
259+
}
260+
default:
261+
res[k] = v
262+
}
234263
}
235264
for k := range arraysKeys {
236265
res[k] = in.ExtractSubIndexLists(k)

Diff for: docs/platform-specification.md

+24
Original file line numberDiff line numberDiff line change
@@ -1403,6 +1403,30 @@ will result in the following JSON to be merged in the Arduino IDE generated `lau
14031403
}
14041404
```
14051405

1406+
All the values are converted by default to a string in the resulting JSON. If another type is needed the value can be
1407+
prefixed with the tags `[boolean]`, `[number]`, or `[object]` to force a specific type in the JSON, for example:
1408+
1409+
```
1410+
debug.cortex-debug.custom.aBoolean=[boolean]true
1411+
debug.cortex-debug.custom.anNumber=[number]10
1412+
debug.cortex-debug.custom.anotherNumber=[number]10.20
1413+
debug.cortex-debug.custom.anObject=[object]{"key":"value", "boolean":true}
1414+
```
1415+
1416+
will result in the following JSON:
1417+
1418+
```json
1419+
{
1420+
"aBoolean": true,
1421+
"anNumber": 10,
1422+
"anotherNumber": 10.2,
1423+
"anObject": {
1424+
"boolean": true,
1425+
"key": "value"
1426+
}
1427+
}
1428+
```
1429+
14061430
### Optimization level for debugging
14071431

14081432
The compiler optimization level that is appropriate for normal usage will often not provide a good experience while

Diff for: internal/integrationtest/debug/debug_test.go

+18
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,15 @@ func testAllDebugInformation(t *testing.T, env *integrationtest.Environment, cli
133133
},
134134
"svd_file": "svd-file",
135135
"cortex-debug_custom_configuration": {
136+
"aBoolean": true,
137+
"aStringBoolean": "true",
138+
"aStringNumber": "10",
139+
"anNumber": 10,
140+
"anotherNumber": 10.2,
141+
"anObject": {
142+
"boolean": true,
143+
"key": "value"
144+
},
136145
"anotherStringParamer": "hellooo",
137146
"overrideRestartCommands": [
138147
"monitor reset halt",
@@ -176,6 +185,15 @@ func testAllDebugInformation(t *testing.T, env *integrationtest.Environment, cli
176185
},
177186
"svd_file": "svd-file",
178187
"cortex-debug_custom_configuration": {
188+
"aBoolean": true,
189+
"aStringBoolean": "true",
190+
"aStringNumber": "10",
191+
"anNumber": 10,
192+
"anotherNumber": 10.2,
193+
"anObject": {
194+
"boolean": true,
195+
"key": "value"
196+
},
179197
"anotherStringParamer": "hellooo",
180198
"overrideRestartCommands": [
181199
"monitor reset halt",

Diff for: internal/integrationtest/debug/testdata/hardware/my/samd/boards.txt

+6
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ my.debug.cortex-debug.custom.overrideRestartCommands.1=monitor gdb_sync
4444
my.debug.cortex-debug.custom.overrideRestartCommands.2=thb setup
4545
my.debug.cortex-debug.custom.overrideRestartCommands.3=c
4646
my.debug.cortex-debug.custom.anotherStringParamer=hellooo
47+
my.debug.cortex-debug.custom.aBoolean=[boolean]true
48+
my.debug.cortex-debug.custom.aStringBoolean=true
49+
my.debug.cortex-debug.custom.anNumber=[number]10
50+
my.debug.cortex-debug.custom.anotherNumber=[number]10.20
51+
my.debug.cortex-debug.custom.aStringNumber=10
52+
my.debug.cortex-debug.custom.anObject=[object]{"key":"value", "boolean":true}
4753
my.debug.svd_file=svd-file
4854

4955
my2.name=My Cool Board

0 commit comments

Comments
 (0)