Skip to content

Commit 9d6acc0

Browse files
committed
Moved CTags preprocess subroutine in proper place
1 parent 1551f87 commit 9d6acc0

File tree

5 files changed

+109
-112
lines changed

5 files changed

+109
-112
lines changed

arduino/builder/preprocessor/ctags.go

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,116 @@ 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+
// CTags performs a run of ctags on the given source file. Returns the ctags output and the stderr contents.
41+
func CTags(sourceFile *paths.Path, targetFile *paths.Path, sketch *sketch.Sketch, lineOffset int, buildProperties *properties.Map) ([]byte, error) {
42+
ctagsOutput, ctagsStdErr, err := RunCTags(sourceFile, buildProperties)
43+
if err != nil {
44+
return ctagsStdErr, err
45+
}
46+
47+
// func PrototypesAdder(sketch *sketch.Sketch, source string, ctagsStdout []byte, lineOffset int) string {
48+
parser := &ctags.CTagsParser{}
49+
prototypes, firstFunctionLine := parser.Parse(ctagsOutput, sketch.MainFile)
50+
if firstFunctionLine == -1 {
51+
firstFunctionLine = 0
52+
}
53+
54+
var source string
55+
if sourceData, err := targetFile.ReadFile(); err != nil {
56+
return nil, err
57+
} else {
58+
source = string(sourceData)
59+
}
60+
source = strings.Replace(source, "\r\n", "\n", -1)
61+
source = strings.Replace(source, "\r", "\n", -1)
62+
sourceRows := strings.Split(source, "\n")
63+
if isFirstFunctionOutsideOfSource(firstFunctionLine, sourceRows) {
64+
return nil, nil
65+
}
66+
67+
insertionLine := firstFunctionLine + lineOffset - 1
68+
firstFunctionChar := len(strings.Join(sourceRows[:insertionLine], "\n")) + 1
69+
prototypeSection := composePrototypeSection(firstFunctionLine, prototypes)
70+
preprocessedSource := source[:firstFunctionChar] + prototypeSection + source[firstFunctionChar:]
71+
72+
if DebugPreprocessor {
73+
fmt.Println("#PREPROCESSED SOURCE")
74+
prototypesRows := strings.Split(prototypeSection, "\n")
75+
prototypesRows = prototypesRows[:len(prototypesRows)-1]
76+
for i := 0; i < len(sourceRows)+len(prototypesRows); i++ {
77+
if i < insertionLine {
78+
fmt.Printf(" |%s\n", sourceRows[i])
79+
} else if i < insertionLine+len(prototypesRows) {
80+
fmt.Printf("PRO|%s\n", prototypesRows[i-insertionLine])
81+
} else {
82+
fmt.Printf(" |%s\n", sourceRows[i-len(prototypesRows)])
83+
}
84+
}
85+
fmt.Println("#END OF PREPROCESSED SOURCE")
86+
}
87+
88+
err = targetFile.WriteFile([]byte(preprocessedSource))
89+
return ctagsStdErr, err
90+
}
91+
92+
func composePrototypeSection(line int, prototypes []*ctags.Prototype) string {
93+
if len(prototypes) == 0 {
94+
return ""
95+
}
96+
97+
str := joinPrototypes(prototypes)
98+
str += "\n#line "
99+
str += strconv.Itoa(line)
100+
str += " " + utils.QuoteCppString(prototypes[0].File)
101+
str += "\n"
102+
103+
return str
104+
}
105+
106+
func joinPrototypes(prototypes []*ctags.Prototype) string {
107+
prototypesSlice := []string{}
108+
for _, proto := range prototypes {
109+
if signatureContainsaDefaultArg(proto) {
110+
continue
111+
}
112+
prototypesSlice = append(prototypesSlice, "#line "+strconv.Itoa(proto.Line)+" "+utils.QuoteCppString(proto.File))
113+
prototypeParts := []string{}
114+
if proto.Modifiers != "" {
115+
prototypeParts = append(prototypeParts, proto.Modifiers)
116+
}
117+
prototypeParts = append(prototypeParts, proto.Prototype)
118+
prototypesSlice = append(prototypesSlice, strings.Join(prototypeParts, " "))
119+
}
120+
return strings.Join(prototypesSlice, "\n")
121+
}
122+
123+
func signatureContainsaDefaultArg(proto *ctags.Prototype) bool {
124+
return strings.Contains(proto.Prototype, "=")
125+
}
126+
127+
func isFirstFunctionOutsideOfSource(firstFunctionLine int, sourceRows []string) bool {
128+
return firstFunctionLine > len(sourceRows)-1
129+
}
130+
32131
// RunCTags performs a run of ctags on the given source file. Returns the ctags output and the stderr contents.
33132
func RunCTags(sourceFile *paths.Path, buildProperties *properties.Map) ([]byte, []byte, error) {
34133
ctagsBuildProperties := properties.NewMap()

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 & 105 deletions
This file was deleted.

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)