Skip to content

Commit b0fb652

Browse files
committed
Avoid using whole ctags_target_for_gcc_minus_e for prototype generation
Ctags is FULL of bugs on c++ parsing (and c++ syntax is a nightmare), sketches are usually way more simple (and easier to debug). Using a simplified version of the ctags_target_for_gcc_minus_e file which only contains preprocessor directives and the sketch lines helps avoiding most ctags subtle bugs. Signed-off-by: Martino Facchin <m.facchin@arduino.cc>
1 parent e6f25db commit b0fb652

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

src/arduino.cc/builder/ctags_target_file_saver.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ import (
3434
"arduino.cc/builder/types"
3535
"arduino.cc/builder/utils"
3636
"path/filepath"
37+
"strconv"
38+
"strings"
3739
)
3840

3941
type CTagsTargetFileSaver struct {
@@ -50,6 +52,12 @@ func (s *CTagsTargetFileSaver) Run(ctx *types.Context) error {
5052
return i18n.WrapError(err)
5153
}
5254

55+
// drop every line which is not part of user sketch or a define/ifdef/endif/etc
56+
var searchSlice []string
57+
searchSlice = append(searchSlice, filepath.Dir(ctx.SketchLocation))
58+
searchSlice = append(searchSlice, filepath.Dir(ctx.BuildPath))
59+
source = saveLinesContainingDirectivesAndSketch(source, searchSlice)
60+
5361
ctagsTargetFilePath := filepath.Join(preprocPath, s.TargetFileName)
5462
err = utils.WriteFile(ctagsTargetFilePath, source)
5563
if err != nil {
@@ -60,3 +68,52 @@ func (s *CTagsTargetFileSaver) Run(ctx *types.Context) error {
6068

6169
return nil
6270
}
71+
72+
func saveLinesContainingDirectivesAndSketch(src string, tofind []string) string {
73+
lines := strings.Split(src, "\n")
74+
75+
saveLine := false
76+
minimizedString := ""
77+
78+
for _, line := range lines {
79+
if saveLine || startsWithHashtag(line) {
80+
minimizedString += line + "\n"
81+
}
82+
if containsAny(line, tofind) && isPreprocessorLineMarker(line) {
83+
saveLine = true
84+
}
85+
if saveLine && !containsAny(line, tofind) && isPreprocessorLineMarker(line) {
86+
saveLine = false
87+
}
88+
}
89+
return minimizedString
90+
}
91+
92+
func containsAny(src string, tofind []string) bool {
93+
for _, str := range tofind {
94+
if strings.Contains(src, str) {
95+
return true
96+
}
97+
}
98+
return false
99+
}
100+
101+
func startsWithHashtag(src string) bool {
102+
trimmedStr := strings.TrimSpace(src)
103+
if len(trimmedStr) > 0 && trimmedStr[0] == '#' {
104+
return true
105+
}
106+
return false
107+
}
108+
109+
func isPreprocessorLineMarker(src string) bool {
110+
trimmedStr := strings.TrimSpace(src)
111+
splittedStr := strings.Split(trimmedStr, " ")
112+
if len(splittedStr) > 2 && splittedStr[0] == "#" {
113+
_, err := strconv.Atoi(splittedStr[1])
114+
if err == nil {
115+
return true
116+
}
117+
}
118+
return false
119+
}

0 commit comments

Comments
 (0)