Skip to content

Commit 050e279

Browse files
committed
Moved CTags preprocess subroutine in proper place
1 parent bea1361 commit 050e279

File tree

5 files changed

+108
-96
lines changed

5 files changed

+108
-96
lines changed

arduino/builder/preprocessor/ctags.go

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,115 @@ package preprocessor
1818
import (
1919
"context"
2020
"fmt"
21+
"strconv"
2122
"strings"
2223

24+
"github.com/arduino/arduino-cli/arduino/builder/preprocessor/ctags"
25+
"github.com/arduino/arduino-cli/arduino/sketch"
2326
"github.com/arduino/arduino-cli/executils"
2427
"github.com/arduino/arduino-cli/i18n"
28+
"github.com/arduino/arduino-cli/legacy/builder/utils"
2529
"github.com/arduino/go-paths-helper"
2630
"github.com/arduino/go-properties-orderedmap"
2731
"github.com/pkg/errors"
2832
)
2933

3034
var tr = i18n.Tr
3135

36+
// DebugPreprocessor when set to true the CTags preprocessor will output debugging info to stdout
37+
// this is useful for unit-testing to provide more infos
38+
var DebugPreprocessor bool
39+
40+
func CTags(sourceFile *paths.Path, targetFile *paths.Path, sketch *sketch.Sketch, lineOffset int, buildProperties *properties.Map) ([]byte, error) {
41+
ctagsOutput, ctagsStdErr, err := RunCTags(sourceFile, buildProperties)
42+
if err != nil {
43+
return ctagsStdErr, err
44+
}
45+
46+
// func PrototypesAdder(sketch *sketch.Sketch, source string, ctagsStdout []byte, lineOffset int) string {
47+
parser := &ctags.CTagsParser{}
48+
prototypes, firstFunctionLine := parser.Parse(ctagsOutput, sketch.MainFile)
49+
if firstFunctionLine == -1 {
50+
firstFunctionLine = 0
51+
}
52+
53+
var source string
54+
if sourceData, err := targetFile.ReadFile(); err != nil {
55+
return nil, err
56+
} else {
57+
source = string(sourceData)
58+
}
59+
source = strings.Replace(source, "\r\n", "\n", -1)
60+
source = strings.Replace(source, "\r", "\n", -1)
61+
sourceRows := strings.Split(source, "\n")
62+
if isFirstFunctionOutsideOfSource(firstFunctionLine, sourceRows) {
63+
return nil, nil
64+
}
65+
66+
insertionLine := firstFunctionLine + lineOffset - 1
67+
firstFunctionChar := len(strings.Join(sourceRows[:insertionLine], "\n")) + 1
68+
prototypeSection := composePrototypeSection(firstFunctionLine, prototypes)
69+
preprocessedSource := source[:firstFunctionChar] + prototypeSection + source[firstFunctionChar:]
70+
71+
if DebugPreprocessor {
72+
fmt.Println("#PREPROCESSED SOURCE")
73+
prototypesRows := strings.Split(prototypeSection, "\n")
74+
prototypesRows = prototypesRows[:len(prototypesRows)-1]
75+
for i := 0; i < len(sourceRows)+len(prototypesRows); i++ {
76+
if i < insertionLine {
77+
fmt.Printf(" |%s\n", sourceRows[i])
78+
} else if i < insertionLine+len(prototypesRows) {
79+
fmt.Printf("PRO|%s\n", prototypesRows[i-insertionLine])
80+
} else {
81+
fmt.Printf(" |%s\n", sourceRows[i-len(prototypesRows)])
82+
}
83+
}
84+
fmt.Println("#END OF PREPROCESSED SOURCE")
85+
}
86+
87+
err = targetFile.WriteFile([]byte(preprocessedSource))
88+
return ctagsStdErr, err
89+
}
90+
91+
func composePrototypeSection(line int, prototypes []*ctags.Prototype) string {
92+
if len(prototypes) == 0 {
93+
return ""
94+
}
95+
96+
str := joinPrototypes(prototypes)
97+
str += "\n#line "
98+
str += strconv.Itoa(line)
99+
str += " " + utils.QuoteCppString(prototypes[0].File)
100+
str += "\n"
101+
102+
return str
103+
}
104+
105+
func joinPrototypes(prototypes []*ctags.Prototype) string {
106+
prototypesSlice := []string{}
107+
for _, proto := range prototypes {
108+
if signatureContainsaDefaultArg(proto) {
109+
continue
110+
}
111+
prototypesSlice = append(prototypesSlice, "#line "+strconv.Itoa(proto.Line)+" "+utils.QuoteCppString(proto.File))
112+
prototypeParts := []string{}
113+
if proto.Modifiers != "" {
114+
prototypeParts = append(prototypeParts, proto.Modifiers)
115+
}
116+
prototypeParts = append(prototypeParts, proto.Prototype)
117+
prototypesSlice = append(prototypesSlice, strings.Join(prototypeParts, " "))
118+
}
119+
return strings.Join(prototypesSlice, "\n")
120+
}
121+
122+
func signatureContainsaDefaultArg(proto *ctags.Prototype) bool {
123+
return strings.Contains(proto.Prototype, "=")
124+
}
125+
126+
func isFirstFunctionOutsideOfSource(firstFunctionLine int, sourceRows []string) bool {
127+
return firstFunctionLine > len(sourceRows)-1
128+
}
129+
32130
func RunCTags(sourceFile *paths.Path, buildProperties *properties.Map) ([]byte, []byte, error) {
33131
ctagsBuildProperties := properties.NewMap()
34132
ctagsBuildProperties.Set("tools.ctags.path", "{runtime.tools.ctags.path}")

legacy/builder/container_add_prototypes.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,19 +70,21 @@ func PreprocessSketchWithCtags(ctx *types.Context) error {
7070
return err
7171
}
7272

73-
ctagsStdout, ctagsStderr, err := preprocessor.RunCTags(targetFilePath, ctx.BuildProperties)
73+
sketchCpp := ctx.SketchBuildPath.Join(fmt.Sprintf("%s.cpp", ctx.Sketch.MainFile.Base()))
74+
ctagsStderr, err := preprocessor.CTags(targetFilePath, sketchCpp, ctx.Sketch, ctx.LineOffset, ctx.BuildProperties)
7475
if ctx.Verbose {
7576
ctx.WriteStderr(ctagsStderr)
7677
}
7778
if err != nil {
7879
return err
7980
}
80-
ctx.SketchSourceAfterArduinoPreprocessing = PrototypesAdder(ctx.Sketch, ctx.SketchSourceMerged, ctagsStdout, ctx.LineOffset)
8181

82-
if err := bldr.SketchSaveItemCpp(ctx.Sketch.MainFile, []byte(ctx.SketchSourceAfterArduinoPreprocessing), ctx.SketchBuildPath); err != nil {
83-
return errors.WithStack(err)
82+
// Save preprocesssed source in context
83+
if d, err := sketchCpp.ReadFile(); err != nil {
84+
return err
85+
} else {
86+
ctx.SketchSourceAfterArduinoPreprocessing = string(d)
8487
}
85-
8688
return nil
8789
}
8890

legacy/builder/preprocess_sketch.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,5 +88,5 @@ func PreprocessSketchWithArduinoPreprocessor(ctx *types.Context) error {
8888

8989
//fmt.Printf("PREPROCESSOR OUTPUT:\n%s\n", output)
9090
ctx.SketchSourceAfterArduinoPreprocessing = string(result)
91-
return bldr.SketchSaveItemCpp(ctx.Sketch.MainFile, []byte(ctx.SketchSourceAfterArduinoPreprocessing), ctx.SketchBuildPath)
91+
return bldr.SketchSaveItemCpp(ctx.Sketch.MainFile, result, ctx.SketchBuildPath)
9292
}

legacy/builder/prototypes_adder.go

Lines changed: 0 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -14,92 +14,3 @@
1414
// To purchase a commercial license, send an email to license@arduino.cc.
1515

1616
package builder
17-
18-
import (
19-
"fmt"
20-
"strconv"
21-
"strings"
22-
23-
"github.com/arduino/arduino-cli/arduino/builder/preprocessor/ctags"
24-
"github.com/arduino/arduino-cli/arduino/sketch"
25-
"github.com/arduino/arduino-cli/legacy/builder/constants"
26-
"github.com/arduino/arduino-cli/legacy/builder/utils"
27-
)
28-
29-
var DebugPreprocessor bool
30-
31-
func PrototypesAdder(sketch *sketch.Sketch, source string, ctagsStdout []byte, lineOffset int) string {
32-
parser := &ctags.CTagsParser{}
33-
prototypes, firstFunctionLine := parser.Parse(ctagsStdout, sketch.MainFile)
34-
if firstFunctionLine == -1 {
35-
firstFunctionLine = 0
36-
}
37-
38-
source = strings.Replace(source, "\r\n", "\n", -1)
39-
source = strings.Replace(source, "\r", "\n", -1)
40-
sourceRows := strings.Split(source, "\n")
41-
if isFirstFunctionOutsideOfSource(firstFunctionLine, sourceRows) {
42-
return ""
43-
}
44-
45-
insertionLine := firstFunctionLine + lineOffset - 1
46-
firstFunctionChar := len(strings.Join(sourceRows[:insertionLine], "\n")) + 1
47-
prototypeSection := composePrototypeSection(firstFunctionLine, prototypes)
48-
preprocessedSource := source[:firstFunctionChar] + prototypeSection + source[firstFunctionChar:]
49-
50-
if DebugPreprocessor {
51-
fmt.Println("#PREPROCESSED SOURCE")
52-
prototypesRows := strings.Split(prototypeSection, "\n")
53-
prototypesRows = prototypesRows[:len(prototypesRows)-1]
54-
for i := 0; i < len(sourceRows)+len(prototypesRows); i++ {
55-
if i < insertionLine {
56-
fmt.Printf(" |%s\n", sourceRows[i])
57-
} else if i < insertionLine+len(prototypesRows) {
58-
fmt.Printf("PRO|%s\n", prototypesRows[i-insertionLine])
59-
} else {
60-
fmt.Printf(" |%s\n", sourceRows[i-len(prototypesRows)])
61-
}
62-
}
63-
fmt.Println("#END OF PREPROCESSED SOURCE")
64-
}
65-
return preprocessedSource
66-
}
67-
68-
func composePrototypeSection(line int, prototypes []*ctags.Prototype) string {
69-
if len(prototypes) == 0 {
70-
return constants.EMPTY_STRING
71-
}
72-
73-
str := joinPrototypes(prototypes)
74-
str += "\n#line "
75-
str += strconv.Itoa(line)
76-
str += " " + utils.QuoteCppString(prototypes[0].File)
77-
str += "\n"
78-
79-
return str
80-
}
81-
82-
func joinPrototypes(prototypes []*ctags.Prototype) string {
83-
prototypesSlice := []string{}
84-
for _, proto := range prototypes {
85-
if signatureContainsaDefaultArg(proto) {
86-
continue
87-
}
88-
prototypesSlice = append(prototypesSlice, "#line "+strconv.Itoa(proto.Line)+" "+utils.QuoteCppString(proto.File))
89-
prototypeParts := []string{}
90-
if proto.Modifiers != "" {
91-
prototypeParts = append(prototypeParts, proto.Modifiers)
92-
}
93-
prototypeParts = append(prototypeParts, proto.Prototype)
94-
prototypesSlice = append(prototypesSlice, strings.Join(prototypeParts, " "))
95-
}
96-
return strings.Join(prototypesSlice, "\n")
97-
}
98-
99-
func signatureContainsaDefaultArg(proto *ctags.Prototype) bool {
100-
return strings.Contains(proto.Prototype, "=")
101-
}
102-
103-
func isFirstFunctionOutsideOfSource(firstFunctionLine int, sourceRows []string) bool {
104-
return firstFunctionLine > len(sourceRows)-1
105-
}

legacy/builder/test/try_build_of_problematic_sketch_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"path/filepath"
2121
"testing"
2222

23+
"github.com/arduino/arduino-cli/arduino/builder/preprocessor"
2324
"github.com/arduino/arduino-cli/legacy/builder"
2425
"github.com/arduino/arduino-cli/legacy/builder/types"
2526
paths "github.com/arduino/go-paths-helper"
@@ -202,7 +203,7 @@ func TestTryBuild042(t *testing.T) {
202203
}
203204

204205
func makeDefaultContext() *types.Context {
205-
builder.DebugPreprocessor = true
206+
preprocessor.DebugPreprocessor = true
206207
return &types.Context{
207208
HardwareDirs: paths.NewPathList(filepath.Join("..", "hardware"), "downloaded_hardware", "downloaded_board_manager_stuff"),
208209
BuiltInToolsDirs: paths.NewPathList("downloaded_tools"),

0 commit comments

Comments
 (0)