Skip to content

Commit e284509

Browse files
committed
Moved ctag preprocessor into proper location
1 parent 73c04fd commit e284509

11 files changed

+121
-202
lines changed

Diff for: arduino/builder/preprocessor/ctags.go

+84-10
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@
1616
package preprocessor
1717

1818
import (
19+
"bufio"
20+
"bytes"
1921
"context"
2022
"fmt"
23+
"io"
2124
"strconv"
2225
"strings"
2326

@@ -37,30 +40,74 @@ var tr = i18n.Tr
3740
// this is useful for unit-testing to provide more infos
3841
var DebugPreprocessor bool
3942

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)
43+
// PreprocessSketchWithCtags performs preprocessing of the arduino sketch using CTags.
44+
func PreprocessSketchWithCtags(sketch *sketch.Sketch, buildPath *paths.Path, includes paths.PathList, lineOffset int, buildProperties *properties.Map, onlyUpdateCompilationDatabase bool) ([]byte, []byte, error) {
45+
// Create a temporary working directory
46+
tmpDir, err := paths.MkTempDir("", "")
4247
if err != nil {
43-
return ctagsStdErr, err
48+
return nil, nil, err
49+
}
50+
defer tmpDir.RemoveAll()
51+
ctagsTarget := tmpDir.Join("sketch_merged.cpp")
52+
53+
normalOutput := &bytes.Buffer{}
54+
verboseOutput := &bytes.Buffer{}
55+
56+
// Run GCC preprocessor
57+
sourceFile := buildPath.Join("sketch", sketch.MainFile.Base()+".cpp")
58+
gccStdout, gccStderr, err := GCC(sourceFile, ctagsTarget, includes, buildProperties)
59+
verboseOutput.Write(gccStdout)
60+
verboseOutput.Write(gccStderr)
61+
normalOutput.Write(gccStderr)
62+
if err != nil {
63+
if !onlyUpdateCompilationDatabase {
64+
return normalOutput.Bytes(), verboseOutput.Bytes(), errors.WithStack(err)
65+
}
66+
67+
// Do not bail out if we are generating the compile commands database
68+
normalOutput.WriteString(fmt.Sprintf("%s: %s",
69+
tr("An error occurred adding prototypes"),
70+
tr("the compilation database may be incomplete or inaccurate")))
71+
if err := sourceFile.CopyTo(ctagsTarget); err != nil {
72+
return normalOutput.Bytes(), verboseOutput.Bytes(), errors.WithStack(err)
73+
}
4474
}
4575

46-
// func PrototypesAdder(sketch *sketch.Sketch, source string, ctagsStdout []byte, lineOffset int) string {
76+
if src, err := ctagsTarget.ReadFile(); err == nil {
77+
filteredSource := filterSketchSource(sketch, bytes.NewReader(src), false)
78+
if err := ctagsTarget.WriteFile([]byte(filteredSource)); err != nil {
79+
return normalOutput.Bytes(), verboseOutput.Bytes(), err
80+
}
81+
} else {
82+
return normalOutput.Bytes(), verboseOutput.Bytes(), err
83+
}
84+
85+
// Run CTags on gcc-preprocessed source
86+
ctagsOutput, ctagsStdErr, err := RunCTags(ctagsTarget, buildProperties)
87+
verboseOutput.Write(ctagsStdErr)
88+
if err != nil {
89+
return normalOutput.Bytes(), verboseOutput.Bytes(), err
90+
}
91+
92+
// Parse CTags output
4793
parser := &ctags.CTagsParser{}
4894
prototypes, firstFunctionLine := parser.Parse(ctagsOutput, sketch.MainFile)
4995
if firstFunctionLine == -1 {
5096
firstFunctionLine = 0
5197
}
5298

99+
// Add prototypes to the original sketch source
53100
var source string
54-
if sourceData, err := targetFile.ReadFile(); err != nil {
55-
return nil, err
56-
} else {
101+
if sourceData, err := sourceFile.ReadFile(); err == nil {
57102
source = string(sourceData)
103+
} else {
104+
return normalOutput.Bytes(), verboseOutput.Bytes(), err
58105
}
59106
source = strings.Replace(source, "\r\n", "\n", -1)
60107
source = strings.Replace(source, "\r", "\n", -1)
61108
sourceRows := strings.Split(source, "\n")
62109
if isFirstFunctionOutsideOfSource(firstFunctionLine, sourceRows) {
63-
return nil, nil
110+
return normalOutput.Bytes(), verboseOutput.Bytes(), nil
64111
}
65112

66113
insertionLine := firstFunctionLine + lineOffset - 1
@@ -84,8 +131,9 @@ func CTags(sourceFile *paths.Path, targetFile *paths.Path, sketch *sketch.Sketch
84131
fmt.Println("#END OF PREPROCESSED SOURCE")
85132
}
86133

87-
err = targetFile.WriteFile([]byte(preprocessedSource))
88-
return ctagsStdErr, err
134+
// Write back arduino-preprocess output to the sourceFile
135+
err = sourceFile.WriteFile([]byte(preprocessedSource))
136+
return normalOutput.Bytes(), verboseOutput.Bytes(), err
89137
}
90138

91139
func composePrototypeSection(line int, prototypes []*ctags.Prototype) string {
@@ -157,3 +205,29 @@ func RunCTags(sourceFile *paths.Path, buildProperties *properties.Map) ([]byte,
157205
stderr = append([]byte(args), stderr...)
158206
return stdout, stderr, err
159207
}
208+
209+
func filterSketchSource(sketch *sketch.Sketch, source io.Reader, removeLineMarkers bool) string {
210+
fileNames := paths.NewPathList()
211+
fileNames.Add(sketch.MainFile)
212+
fileNames.AddAll(sketch.OtherSketchFiles)
213+
214+
inSketch := false
215+
filtered := ""
216+
217+
scanner := bufio.NewScanner(source)
218+
for scanner.Scan() {
219+
line := scanner.Text()
220+
if filename := cpp.ParseLineMarker(line); filename != nil {
221+
inSketch = fileNames.Contains(filename)
222+
if inSketch && removeLineMarkers {
223+
continue
224+
}
225+
}
226+
227+
if inSketch {
228+
filtered += line + "\n"
229+
}
230+
}
231+
232+
return filtered
233+
}

Diff for: legacy/builder/add_additional_entries_to_context.go

-5
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,6 @@ type AddAdditionalEntriesToContext struct{}
2626
func (*AddAdditionalEntriesToContext) Run(ctx *types.Context) error {
2727
if ctx.BuildPath != nil {
2828
buildPath := ctx.BuildPath
29-
preprocPath, err := buildPath.Join(constants.FOLDER_PREPROC).Abs()
30-
if err != nil {
31-
return errors.WithStack(err)
32-
}
3329
sketchBuildPath, err := buildPath.Join(constants.FOLDER_SKETCH).Abs()
3430
if err != nil {
3531
return errors.WithStack(err)
@@ -43,7 +39,6 @@ func (*AddAdditionalEntriesToContext) Run(ctx *types.Context) error {
4339
return errors.WithStack(err)
4440
}
4541

46-
ctx.PreprocPath = preprocPath
4742
ctx.SketchBuildPath = sketchBuildPath
4843
ctx.LibrariesBuildPath = librariesBuildPath
4944
ctx.CoreBuildPath = coreBuildPath

Diff for: legacy/builder/builder.go

+13-6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"time"
2121

2222
"github.com/arduino/arduino-cli/arduino/builder"
23+
"github.com/arduino/arduino-cli/arduino/builder/preprocessor"
2324
"github.com/arduino/arduino-cli/i18n"
2425
"github.com/arduino/arduino-cli/legacy/builder/phases"
2526
"github.com/arduino/arduino-cli/legacy/builder/types"
@@ -59,7 +60,7 @@ func (s *Builder) Run(ctx *types.Context) error {
5960
&WarnAboutArchIncompatibleLibraries{},
6061

6162
utils.LogIfVerbose(false, tr("Generating function prototypes...")),
62-
&PreprocessSketch{},
63+
types.BareCommand(PreprocessSketch),
6364

6465
utils.LogIfVerbose(false, tr("Compiling sketch...")),
6566
&RecipeByPrefixSuffixRunner{Prefix: "recipe.hooks.sketch.prebuild", Suffix: ".pattern"},
@@ -115,13 +116,19 @@ func (s *Builder) Run(ctx *types.Context) error {
115116
return otherErr
116117
}
117118

118-
type PreprocessSketch struct{}
119-
120-
func (s *PreprocessSketch) Run(ctx *types.Context) error {
119+
func PreprocessSketch(ctx *types.Context) error {
121120
if ctx.UseArduinoPreprocessor {
122121
return PreprocessSketchWithArduinoPreprocessor(ctx)
123122
} else {
124-
return PreprocessSketchWithCtags(ctx)
123+
normalOutput, verboseOutput, err := preprocessor.PreprocessSketchWithCtags(
124+
ctx.Sketch, ctx.BuildPath, ctx.IncludeFolders, ctx.LineOffset,
125+
ctx.BuildProperties, ctx.OnlyUpdateCompilationDatabase)
126+
if ctx.Verbose {
127+
ctx.WriteStdout(verboseOutput)
128+
} else {
129+
ctx.WriteStdout(normalOutput)
130+
}
131+
return err
125132
}
126133
}
127134

@@ -149,7 +156,7 @@ func (s *Preprocess) Run(ctx *types.Context) error {
149156

150157
&WarnAboutArchIncompatibleLibraries{},
151158

152-
&PreprocessSketch{},
159+
types.BareCommand(PreprocessSketch),
153160
}
154161

155162
if err := runCommands(ctx, commands); err != nil {

Diff for: legacy/builder/constants/constants.go

-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ const BUILD_PROPERTIES_RUNTIME_PLATFORM_PATH = "runtime.platform.path"
3434
const EMPTY_STRING = ""
3535
const FOLDER_BOOTLOADERS = "bootloaders"
3636
const FOLDER_CORE = "core"
37-
const FOLDER_PREPROC = "preproc"
3837
const FOLDER_SKETCH = "sketch"
3938
const FOLDER_TOOLS = "tools"
4039
const FOLDER_LIBRARIES = "libraries"

Diff for: legacy/builder/container_add_prototypes.go

-135
This file was deleted.

Diff for: legacy/builder/create_cmake_rule.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ func (s *ExportProjectCMake) Run(ctx *types.Context) error {
115115
fmt.Println(err)
116116
}
117117

118-
if err := PreprocessSketchWithCtags(ctx); err != nil {
118+
if err := PreprocessSketch(ctx); err != nil {
119119
return err
120120
}
121121

Diff for: legacy/builder/preprocess_sketch.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ import (
3131
)
3232

3333
func PreprocessSketchWithArduinoPreprocessor(ctx *types.Context) error {
34-
if err := ctx.PreprocPath.MkdirAll(); err != nil {
34+
if err := ctx.BuildPath.Join("preproc").MkdirAll(); err != nil {
3535
return errors.WithStack(err)
3636
}
3737

3838
sourceFile := ctx.SketchBuildPath.Join(ctx.Sketch.MainFile.Base() + ".cpp")
39-
targetFile := ctx.PreprocPath.Join("sketch_merged.cpp")
39+
targetFile := ctx.BuildPath.Join("preproc", "sketch_merged.cpp")
4040
gccStdout, gccStderr, err := preprocessor.GCC(sourceFile, targetFile, ctx.IncludeFolders, ctx.BuildProperties)
4141
if ctx.Verbose {
4242
ctx.WriteStdout(gccStdout)

Diff for: legacy/builder/test/add_additional_entries_to_context_test.go

-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ func TestAddAdditionalEntriesToContextNoBuildPath(t *testing.T) {
3131
command := builder.AddAdditionalEntriesToContext{}
3232
NoError(t, command.Run(ctx))
3333

34-
require.Empty(t, ctx.PreprocPath)
3534
require.Empty(t, ctx.SketchBuildPath)
3635
require.Empty(t, ctx.LibrariesBuildPath)
3736
require.Empty(t, ctx.CoreBuildPath)
@@ -48,7 +47,6 @@ func TestAddAdditionalEntriesToContextWithBuildPath(t *testing.T) {
4847
command := builder.AddAdditionalEntriesToContext{}
4948
NoError(t, command.Run(ctx))
5049

51-
require.Equal(t, Abs(t, paths.New("folder", constants.FOLDER_PREPROC)), ctx.PreprocPath)
5250
require.Equal(t, Abs(t, paths.New("folder", constants.FOLDER_SKETCH)), ctx.SketchBuildPath)
5351
require.Equal(t, Abs(t, paths.New("folder", "libraries")), ctx.LibrariesBuildPath)
5452
require.Equal(t, Abs(t, paths.New("folder", constants.FOLDER_CORE)), ctx.CoreBuildPath)

0 commit comments

Comments
 (0)