Skip to content

Commit d39e061

Browse files
committed
Factored all c++ source lines parsers
1 parent cfc62d6 commit d39e061

File tree

9 files changed

+105
-102
lines changed

9 files changed

+105
-102
lines changed

arduino/builder/cpp.go renamed to arduino/builder/cpp/cpp.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
// Arduino software without disclosing the source code of your own applications.
1414
// To purchase a commercial license, send an email to license@arduino.cc.
1515

16-
package builder
16+
package cpp
1717

1818
import (
1919
"strconv"
@@ -23,18 +23,18 @@ import (
2323
"github.com/arduino/go-paths-helper"
2424
)
2525

26-
// quoteCppString returns the given string as a quoted string for use with the C
26+
// QuoteString returns the given string as a quoted string for use with the C
2727
// preprocessor. This adds double quotes around it and escapes any
2828
// double quotes and backslashes in the string.
29-
func quoteCppString(str string) string {
29+
func QuoteString(str string) string {
3030
str = strings.Replace(str, "\\", "\\\\", -1)
3131
str = strings.Replace(str, "\"", "\\\"", -1)
3232
return "\"" + str + "\""
3333
}
3434

35-
// Parses the given line as a gcc line marker and returns the contained
35+
// ParseLineMarker parses the given line as a gcc line marker and returns the contained
3636
// filename.
37-
func parseLineMarker(line string) *paths.Path {
37+
func ParseLineMarker(line string) *paths.Path {
3838
// A line marker contains the line number and filename and looks like:
3939
// # 123 /path/to/file.cpp
4040
// It can be followed by zero or more flag number that indicate the
@@ -55,7 +55,7 @@ func parseLineMarker(line string) *paths.Path {
5555
// If we get here, we found a # followed by a line number, so
5656
// assume this is a line marker and see if the rest of the line
5757
// starts with a string containing the filename
58-
str, rest, ok := ParseCppString(split[2])
58+
str, rest, ok := ParseString(split[2])
5959

6060
if ok && (rest == "" || rest[0] == ' ') {
6161
return paths.New(str)
@@ -69,7 +69,7 @@ func parseLineMarker(line string) *paths.Path {
6969
// start of the given line, returns the unquoted string contents, the
7070
// remainder of the line (everything after the closing "), and true.
7171
// Otherwise, returns the empty string, the entire line and false.
72-
func ParseCppString(line string) (string, string, bool) {
72+
func ParseString(line string) (string, string, bool) {
7373
// For details about how these strings are output by gcc, see:
7474
// https://github.com/gcc-mirror/gcc/blob/a588355ab948cf551bc9d2b89f18e5ae5140f52c/libcpp/macro.c#L491-L511
7575
// Note that the documentation suggests all non-printable

arduino/builder/cpp/cpp_test.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// This file is part of arduino-cli.
2+
//
3+
// Copyright 2023 ARDUINO SA (http://www.arduino.cc/)
4+
//
5+
// This software is released under the GNU General Public License version 3,
6+
// which covers the main part of arduino-cli.
7+
// The terms of this license can be found at:
8+
// https://www.gnu.org/licenses/gpl-3.0.en.html
9+
//
10+
// You can be released from the requirements of the above licenses by purchasing
11+
// a commercial license. Buying such a license is mandatory if you want to
12+
// modify or otherwise use the software for commercial activities involving the
13+
// Arduino software without disclosing the source code of your own applications.
14+
// To purchase a commercial license, send an email to license@arduino.cc.
15+
16+
package cpp_test
17+
18+
import (
19+
"testing"
20+
21+
"github.com/arduino/arduino-cli/arduino/builder/cpp"
22+
"github.com/stretchr/testify/require"
23+
)
24+
25+
func TestParseString(t *testing.T) {
26+
_, _, ok := cpp.ParseString(`foo`)
27+
require.Equal(t, false, ok)
28+
29+
_, _, ok = cpp.ParseString(`"foo`)
30+
require.Equal(t, false, ok)
31+
32+
str, rest, ok := cpp.ParseString(`"foo"`)
33+
require.Equal(t, true, ok)
34+
require.Equal(t, `foo`, str)
35+
require.Equal(t, ``, rest)
36+
37+
str, rest, ok = cpp.ParseString(`"foo\\bar"`)
38+
require.Equal(t, true, ok)
39+
require.Equal(t, `foo\bar`, str)
40+
require.Equal(t, ``, rest)
41+
42+
str, rest, ok = cpp.ParseString(`"foo \"is\" quoted and \\\\bar\"\" escaped\\" and "then" some`)
43+
require.Equal(t, true, ok)
44+
require.Equal(t, `foo "is" quoted and \\bar"" escaped\`, str)
45+
require.Equal(t, ` and "then" some`, rest)
46+
47+
str, rest, ok = cpp.ParseString(`" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_abcdefghijklmnopqrstuvwxyz{|}~"`)
48+
require.Equal(t, true, ok)
49+
require.Equal(t, ` !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~`, str)
50+
require.Equal(t, ``, rest)
51+
52+
str, rest, ok = cpp.ParseString(`"/home/ççç/"`)
53+
require.Equal(t, true, ok)
54+
require.Equal(t, `/home/ççç/`, str)
55+
require.Equal(t, ``, rest)
56+
57+
str, rest, ok = cpp.ParseString(`"/home/ççç/ /$sdsdd\\"`)
58+
require.Equal(t, true, ok)
59+
require.Equal(t, `/home/ççç/ /$sdsdd\`, str)
60+
require.Equal(t, ``, rest)
61+
}
62+
63+
func TestQuoteString(t *testing.T) {
64+
cases := map[string]string{
65+
`foo`: `"foo"`,
66+
`foo\bar`: `"foo\\bar"`,
67+
`foo "is" quoted and \\bar"" escaped\`: `"foo \"is\" quoted and \\\\bar\"\" escaped\\"`,
68+
// ASCII 0x20 - 0x7e, excluding `
69+
` !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~`: `" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_abcdefghijklmnopqrstuvwxyz{|}~"`,
70+
}
71+
for input, expected := range cases {
72+
require.Equal(t, expected, cpp.QuoteString(input))
73+
}
74+
}

arduino/builder/cpp_test.go

Lines changed: 0 additions & 46 deletions
This file was deleted.

arduino/builder/preprocessor/ctags.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ import (
2121
"strconv"
2222
"strings"
2323

24+
"github.com/arduino/arduino-cli/arduino/builder/cpp"
2425
"github.com/arduino/arduino-cli/arduino/builder/preprocessor/ctags"
2526
"github.com/arduino/arduino-cli/arduino/sketch"
2627
"github.com/arduino/arduino-cli/executils"
2728
"github.com/arduino/arduino-cli/i18n"
28-
"github.com/arduino/arduino-cli/legacy/builder/utils"
2929
"github.com/arduino/go-paths-helper"
3030
"github.com/arduino/go-properties-orderedmap"
3131
"github.com/pkg/errors"
@@ -93,7 +93,7 @@ func composePrototypeSection(line int, prototypes []*ctags.Prototype) string {
9393
str := joinPrototypes(prototypes)
9494
str += "\n#line "
9595
str += strconv.Itoa(line)
96-
str += " " + utils.QuoteCppString(prototypes[0].File)
96+
str += " " + cpp.QuoteString(prototypes[0].File)
9797
str += "\n"
9898

9999
return str
@@ -105,7 +105,7 @@ func joinPrototypes(prototypes []*ctags.Prototype) string {
105105
if signatureContainsaDefaultArg(proto) {
106106
continue
107107
}
108-
prototypesSlice = append(prototypesSlice, "#line "+strconv.Itoa(proto.Line)+" "+utils.QuoteCppString(proto.File))
108+
prototypesSlice = append(prototypesSlice, "#line "+strconv.Itoa(proto.Line)+" "+cpp.QuoteString(proto.File))
109109
prototypeParts := []string{}
110110
if proto.Modifiers != "" {
111111
prototypeParts = append(prototypeParts, proto.Modifiers)

arduino/builder/sketch.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"io"
2323
"regexp"
2424

25+
"github.com/arduino/arduino-cli/arduino/builder/cpp"
2526
"github.com/arduino/arduino-cli/arduino/sketch"
2627
"github.com/arduino/arduino-cli/i18n"
2728
"github.com/arduino/go-paths-helper"
@@ -97,7 +98,7 @@ func sketchMergeSources(sk *sketch.Sketch, overrides map[string]string) (int, st
9798
lineOffset++
9899
}
99100

100-
mergedSource += "#line 1 " + quoteCppString(sk.MainFile.String()) + "\n"
101+
mergedSource += "#line 1 " + cpp.QuoteString(sk.MainFile.String()) + "\n"
101102
mergedSource += mainSrc + "\n"
102103
lineOffset++
103104

@@ -106,7 +107,7 @@ func sketchMergeSources(sk *sketch.Sketch, overrides map[string]string) (int, st
106107
if err != nil {
107108
return 0, "", err
108109
}
109-
mergedSource += "#line 1 " + quoteCppString(file.String()) + "\n"
110+
mergedSource += "#line 1 " + cpp.QuoteString(file.String()) + "\n"
110111
mergedSource += src + "\n"
111112
}
112113

@@ -146,7 +147,7 @@ func sketchCopyAdditionalFiles(sketch *sketch.Sketch, destPath *paths.Path, over
146147
}
147148

148149
// tag each addtional file with the filename of the source it was copied from
149-
sourceBytes = append([]byte("#line 1 "+quoteCppString(file.String())+"\n"), sourceBytes...)
150+
sourceBytes = append([]byte("#line 1 "+cpp.QuoteString(file.String())+"\n"), sourceBytes...)
150151

151152
err = writeIfDifferent(sourceBytes, targetPath)
152153
if err != nil {
@@ -190,7 +191,7 @@ func FilterSketchSource(sketch *sketch.Sketch, source io.Reader, removeLineMarke
190191
scanner := bufio.NewScanner(source)
191192
for scanner.Scan() {
192193
line := scanner.Text()
193-
if filename := parseLineMarker(line); filename != nil {
194+
if filename := cpp.ParseLineMarker(line); filename != nil {
194195
inSketch = fileNames.Contains(filename)
195196
if inSketch && removeLineMarkers {
196197
continue

legacy/builder/test/helper.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,19 @@ import (
2323
"testing"
2424
"text/template"
2525

26+
"github.com/arduino/arduino-cli/arduino/builder/cpp"
2627
"github.com/arduino/arduino-cli/arduino/libraries"
2728
"github.com/arduino/arduino-cli/arduino/sketch"
2829
"github.com/arduino/arduino-cli/legacy/builder/constants"
2930
"github.com/arduino/arduino-cli/legacy/builder/types"
30-
"github.com/arduino/arduino-cli/legacy/builder/utils"
3131
paths "github.com/arduino/go-paths-helper"
3232
"github.com/stretchr/testify/assert"
3333
"github.com/stretchr/testify/require"
3434
)
3535

3636
func LoadAndInterpolate(t *testing.T, filename string, ctx *types.Context) string {
3737
funcsMap := template.FuncMap{
38-
"QuoteCppString": utils.QuoteCppPath,
38+
"QuoteCppString": func(p *paths.Path) string { return cpp.QuoteString(p.String()) },
3939
}
4040

4141
tpl, err := template.New(filepath.Base(filename)).Funcs(funcsMap).ParseFiles(filename)

legacy/builder/test/prototypes_adder_test.go

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ import (
2222
"testing"
2323

2424
bldr "github.com/arduino/arduino-cli/arduino/builder"
25+
"github.com/arduino/arduino-cli/arduino/builder/cpp"
2526
"github.com/arduino/arduino-cli/legacy/builder"
2627
"github.com/arduino/arduino-cli/legacy/builder/types"
27-
"github.com/arduino/arduino-cli/legacy/builder/utils"
2828
paths "github.com/arduino/go-paths-helper"
2929
"github.com/stretchr/testify/require"
3030
)
@@ -33,7 +33,7 @@ func TestPrototypesAdderBridgeExample(t *testing.T) {
3333
DownloadCoresAndToolsAndLibraries(t)
3434

3535
sketchLocation := paths.New("downloaded_libraries", "Bridge", "examples", "Bridge", "Bridge.ino")
36-
quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation))
36+
quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String())
3737

3838
ctx := &types.Context{
3939
HardwareDirs: paths.NewPathList(filepath.Join("..", "hardware"), "downloaded_hardware"),
@@ -321,7 +321,7 @@ func TestPrototypesAdderSketchWithConfig(t *testing.T) {
321321
DownloadCoresAndToolsAndLibraries(t)
322322

323323
sketchLocation := paths.New("sketch_with_config", "sketch_with_config.ino")
324-
quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation))
324+
quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String())
325325

326326
ctx := &types.Context{
327327
HardwareDirs: paths.NewPathList(filepath.Join("..", "hardware"), "downloaded_hardware"),
@@ -362,7 +362,7 @@ func TestPrototypesAdderSketchNoFunctionsTwoFiles(t *testing.T) {
362362
DownloadCoresAndToolsAndLibraries(t)
363363

364364
sketchLocation := paths.New("sketch_no_functions_two_files", "sketch_no_functions_two_files.ino")
365-
quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation))
365+
quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String())
366366

367367
ctx := &types.Context{
368368
HardwareDirs: paths.NewPathList(filepath.Join("..", "hardware"), "downloaded_hardware"),
@@ -413,7 +413,7 @@ func TestPrototypesAdderSketchNoFunctions(t *testing.T) {
413413
defer buildPath.RemoveAll()
414414

415415
sketchLocation := paths.New("sketch_no_functions", "sketch_no_functions.ino")
416-
quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation))
416+
quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String())
417417
var _err error
418418
commands := []types.Command{
419419
&builder.ContainerSetupHardwareToolsLibsSketchAndProps{},
@@ -438,7 +438,7 @@ func TestPrototypesAdderSketchWithDefaultArgs(t *testing.T) {
438438
DownloadCoresAndToolsAndLibraries(t)
439439

440440
sketchLocation := paths.New("sketch_with_default_args", "sketch_with_default_args.ino")
441-
quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation))
441+
quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String())
442442

443443
ctx := &types.Context{
444444
HardwareDirs: paths.NewPathList(filepath.Join("..", "hardware"), "downloaded_hardware"),
@@ -476,7 +476,7 @@ func TestPrototypesAdderSketchWithInlineFunction(t *testing.T) {
476476
DownloadCoresAndToolsAndLibraries(t)
477477

478478
sketchLocation := paths.New("sketch_with_inline_function", "sketch_with_inline_function.ino")
479-
quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation))
479+
quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String())
480480

481481
ctx := &types.Context{
482482
HardwareDirs: paths.NewPathList(filepath.Join("..", "hardware"), "downloaded_hardware"),
@@ -525,7 +525,7 @@ func TestPrototypesAdderSketchWithFunctionSignatureInsideIFDEF(t *testing.T) {
525525
DownloadCoresAndToolsAndLibraries(t)
526526

527527
sketchLocation := paths.New("sketch_with_function_signature_inside_ifdef", "sketch_with_function_signature_inside_ifdef.ino")
528-
quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation))
528+
quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String())
529529

530530
ctx := &types.Context{
531531
HardwareDirs: paths.NewPathList(filepath.Join("..", "hardware"), "downloaded_hardware"),
@@ -563,7 +563,7 @@ func TestPrototypesAdderSketchWithUSBCON(t *testing.T) {
563563
DownloadCoresAndToolsAndLibraries(t)
564564

565565
sketchLocation := paths.New("sketch_with_usbcon", "sketch_with_usbcon.ino")
566-
quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation))
566+
quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String())
567567

568568
ctx := &types.Context{
569569
HardwareDirs: paths.NewPathList(filepath.Join("..", "hardware"), "downloaded_hardware"),
@@ -601,7 +601,7 @@ func TestPrototypesAdderSketchWithTypename(t *testing.T) {
601601
DownloadCoresAndToolsAndLibraries(t)
602602

603603
sketchLocation := paths.New("sketch_with_typename", "sketch_with_typename.ino")
604-
quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation))
604+
quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String())
605605

606606
ctx := &types.Context{
607607
HardwareDirs: paths.NewPathList(filepath.Join("..", "hardware"), "downloaded_hardware"),
@@ -644,7 +644,7 @@ func TestPrototypesAdderSketchWithIfDef2(t *testing.T) {
644644
DownloadCoresAndToolsAndLibraries(t)
645645

646646
sketchLocation := paths.New("sketch_with_ifdef", "sketch_with_ifdef.ino")
647-
quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation))
647+
quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String())
648648

649649
ctx := &types.Context{
650650
HardwareDirs: paths.NewPathList(filepath.Join("..", "hardware"), "downloaded_hardware"),
@@ -685,7 +685,7 @@ func TestPrototypesAdderSketchWithIfDef2SAM(t *testing.T) {
685685
DownloadCoresAndToolsAndLibraries(t)
686686

687687
sketchLocation := paths.New("sketch_with_ifdef", "sketch_with_ifdef.ino")
688-
quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation))
688+
quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String())
689689

690690
ctx := &types.Context{
691691
HardwareDirs: paths.NewPathList(filepath.Join("..", "hardware"), "downloaded_hardware"),
@@ -726,7 +726,7 @@ func TestPrototypesAdderSketchWithConst(t *testing.T) {
726726
DownloadCoresAndToolsAndLibraries(t)
727727

728728
sketchLocation := paths.New("sketch_with_const", "sketch_with_const.ino")
729-
quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation))
729+
quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String())
730730

731731
ctx := &types.Context{
732732
HardwareDirs: paths.NewPathList(filepath.Join("..", "hardware"), "downloaded_hardware"),
@@ -796,7 +796,7 @@ func TestPrototypesAdderSketchWithDosEol(t *testing.T) {
796796
func TestPrototypesAdderSketchWithSubstringFunctionMember(t *testing.T) {
797797
DownloadCoresAndToolsAndLibraries(t)
798798
sketchLocation := paths.New("sketch_with_class_and_method_substring", "sketch_with_class_and_method_substring.ino")
799-
quotedSketchLocation := utils.QuoteCppString(Abs(t, sketchLocation).String())
799+
quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String())
800800

801801
ctx := &types.Context{
802802
HardwareDirs: paths.NewPathList(filepath.Join("..", "hardware"), "downloaded_hardware"),

0 commit comments

Comments
 (0)