From f0190df6ecb392c6b0f5c983cbad93ec86153914 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 5 Apr 2023 13:02:18 +0200 Subject: [PATCH 1/8] Converted CTagsRunner into a function --- legacy/builder/container_add_prototypes.go | 10 ++- legacy/builder/ctags_runner.go | 88 +++++++++++----------- legacy/builder/test/ctags_runner_test.go | 45 +++++++---- 3 files changed, 81 insertions(+), 62 deletions(-) diff --git a/legacy/builder/container_add_prototypes.go b/legacy/builder/container_add_prototypes.go index 43d1fa36d35..99059b0fb76 100644 --- a/legacy/builder/container_add_prototypes.go +++ b/legacy/builder/container_add_prototypes.go @@ -62,8 +62,14 @@ func PreprocessSketchWithCtags(ctx *types.Context) error { ctx.SketchSourceAfterCppPreprocessing = filterSketchSource(ctx.Sketch, bytes.NewReader(src), false) } - if err := (&CTagsRunner{Source: &ctx.SketchSourceAfterCppPreprocessing, TargetFileName: "sketch_merged.cpp"}).Run(ctx); err != nil { - return errors.WithStack(err) + var ctagsStderr []byte + _, ctagsStderr, ctx.PrototypesLineWhereToInsert, ctx.Prototypes, err = RunCTags( + ctx.Sketch, ctx.SketchSourceAfterCppPreprocessing, "sketch_merged.cpp", ctx.BuildProperties, ctx.PreprocPath) + if ctx.Verbose { + ctx.WriteStderr(ctagsStderr) + } + if err != nil { + return err } ctx.SketchSourceAfterArduinoPreprocessing, ctx.PrototypesSection = PrototypesAdder(ctx.SketchSourceMerged, ctx.PrototypesLineWhereToInsert, ctx.LineOffset, ctx.Prototypes, ctx.DebugPreprocessor) diff --git a/legacy/builder/ctags_runner.go b/legacy/builder/ctags_runner.go index 40ef36434d1..563444f0b7d 100644 --- a/legacy/builder/ctags_runner.go +++ b/legacy/builder/ctags_runner.go @@ -16,74 +16,72 @@ package builder import ( - "os" - "os/exec" + "bytes" + "strings" + "github.com/arduino/arduino-cli/arduino/sketch" + "github.com/arduino/arduino-cli/executils" "github.com/arduino/arduino-cli/legacy/builder/ctags" - "github.com/arduino/arduino-cli/legacy/builder/types" - "github.com/arduino/arduino-cli/legacy/builder/utils" + "github.com/arduino/go-paths-helper" properties "github.com/arduino/go-properties-orderedmap" "github.com/pkg/errors" ) -type CTagsRunner struct { - Source *string - TargetFileName string - - // Needed for unit-testing - CtagsOutput []byte -} - -func (r *CTagsRunner) Run(ctx *types.Context) error { - source := *r.Source - - preprocPath := ctx.PreprocPath - if err := preprocPath.MkdirAll(); err != nil { - return errors.WithStack(err) +func RunCTags(sketch *sketch.Sketch, source string, targetFileName string, buildProperties *properties.Map, preprocPath *paths.Path, +) (ctagsStdout, ctagsStderr []byte, prototypesLineWhereToInsert int, prototypes []*ctags.Prototype, err error) { + if err = preprocPath.MkdirAll(); err != nil { + return } - ctagsTargetFilePath := preprocPath.Join(r.TargetFileName) - if err := ctagsTargetFilePath.WriteFile([]byte(source)); err != nil { - return errors.WithStack(err) + ctagsTargetFilePath := preprocPath.Join(targetFileName) + if err = ctagsTargetFilePath.WriteFile([]byte(source)); err != nil { + return } - buildProperties := properties.NewMap() - buildProperties.Set("tools.ctags.path", "{runtime.tools.ctags.path}") - buildProperties.Set("tools.ctags.cmd.path", "{path}/ctags") - buildProperties.Set("tools.ctags.pattern", `"{cmd.path}" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "{source_file}"`) - buildProperties.Merge(ctx.BuildProperties) - buildProperties.Merge(buildProperties.SubTree("tools").SubTree("ctags")) - buildProperties.SetPath("source_file", ctagsTargetFilePath) + ctagsBuildProperties := properties.NewMap() + ctagsBuildProperties.Set("tools.ctags.path", "{runtime.tools.ctags.path}") + ctagsBuildProperties.Set("tools.ctags.cmd.path", "{path}/ctags") + ctagsBuildProperties.Set("tools.ctags.pattern", `"{cmd.path}" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "{source_file}"`) + ctagsBuildProperties.Merge(buildProperties) + ctagsBuildProperties.Merge(ctagsBuildProperties.SubTree("tools").SubTree("ctags")) + ctagsBuildProperties.SetPath("source_file", ctagsTargetFilePath) - pattern := buildProperties.Get("pattern") + pattern := ctagsBuildProperties.Get("pattern") if pattern == "" { - return errors.Errorf(tr("%s pattern is missing"), "ctags") + err = errors.Errorf(tr("%s pattern is missing"), "ctags") + return } - commandLine := buildProperties.ExpandPropsInString(pattern) + commandLine := ctagsBuildProperties.ExpandPropsInString(pattern) parts, err := properties.SplitQuotedString(commandLine, `"'`, false) if err != nil { - return errors.WithStack(err) + return } - command := exec.Command(parts[0], parts[1:]...) - command.Env = append(os.Environ(), ctx.PackageManager.GetEnvVarsForSpawnedProcess()...) - - ctagsOutput, _, err := utils.ExecCommand(ctx, command, utils.Capture /* stdout */, utils.ShowIfVerbose /* stderr */) + proc, err := executils.NewProcess(nil, parts...) if err != nil { - return errors.WithStack(err) + return + } + stdout := &bytes.Buffer{} + stderr := &bytes.Buffer{} + proc.RedirectStdoutTo(stdout) + proc.RedirectStderrTo(stderr) + if err = proc.Run(); err != nil { + return + } + stderr.WriteString(strings.Join(parts, " ")) + ctagsStdout = stdout.Bytes() + ctagsStderr = stderr.Bytes() + if err != nil { + return } parser := &ctags.CTagsParser{} - parser.Parse(ctagsOutput, ctx.Sketch.MainFile) + parser.Parse(ctagsStdout, sketch.MainFile) parser.FixCLinkageTagsDeclarations() - protos, line := parser.GeneratePrototypes() + prototypes, line := parser.GeneratePrototypes() if line != -1 { - ctx.PrototypesLineWhereToInsert = line + prototypesLineWhereToInsert = line } - ctx.Prototypes = protos - - // Needed for unit-testing - r.CtagsOutput = ctagsOutput - return nil + return } diff --git a/legacy/builder/test/ctags_runner_test.go b/legacy/builder/test/ctags_runner_test.go index 12194ccf744..069339eef48 100644 --- a/legacy/builder/test/ctags_runner_test.go +++ b/legacy/builder/test/ctags_runner_test.go @@ -32,8 +32,8 @@ func TestCTagsRunner(t *testing.T) { defer cleanUpBuilderTestContext(t, ctx) ctx.Verbose = true - ctagsRunner := &builder.CTagsRunner{Source: &ctx.SketchSourceMerged, TargetFileName: "ctags_target.cpp"} var _err error + var ctagsOutput []byte commands := []types.Command{ &builder.ContainerSetupHardwareToolsLibsSketchAndProps{}, types.BareCommand(func(ctx *types.Context) error { @@ -43,7 +43,10 @@ func TestCTagsRunner(t *testing.T) { &builder.ContainerFindIncludes{}, &builder.PrintUsedLibrariesIfVerbose{}, &builder.WarnAboutArchIncompatibleLibraries{}, - ctagsRunner, + types.BareCommand(func(ctx *types.Context) error { + ctagsOutput, _, _, _, _err = builder.RunCTags(ctx.Sketch, ctx.SketchSourceMerged, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) + return _err + }), } for _, command := range commands { err := command.Run(ctx) @@ -58,7 +61,7 @@ func TestCTagsRunner(t *testing.T) { "digitalCommand " + quotedSketchLocation + " /^void digitalCommand(BridgeClient client) {$/;\" kind:function line:82 signature:(BridgeClient client) returntype:void\n" + "analogCommand " + quotedSketchLocation + " /^void analogCommand(BridgeClient client) {$/;\" kind:function line:109 signature:(BridgeClient client) returntype:void\n" + "modeCommand " + quotedSketchLocation + " /^void modeCommand(BridgeClient client) {$/;\" kind:function line:149 signature:(BridgeClient client) returntype:void\n" - require.Equal(t, expectedOutput, strings.Replace(string(ctagsRunner.CtagsOutput), "\r\n", "\n", -1)) + require.Equal(t, expectedOutput, strings.Replace(string(ctagsOutput), "\r\n", "\n", -1)) } func TestCTagsRunnerSketchWithClass(t *testing.T) { @@ -67,8 +70,8 @@ func TestCTagsRunnerSketchWithClass(t *testing.T) { defer cleanUpBuilderTestContext(t, ctx) ctx.Verbose = true - ctagsRunner := &builder.CTagsRunner{Source: &ctx.SketchSourceMerged, TargetFileName: "ctags_target.cpp"} var _err error + var ctagsOutput []byte commands := []types.Command{ &builder.ContainerSetupHardwareToolsLibsSketchAndProps{}, types.BareCommand(func(ctx *types.Context) error { @@ -78,7 +81,10 @@ func TestCTagsRunnerSketchWithClass(t *testing.T) { &builder.ContainerFindIncludes{}, &builder.PrintUsedLibrariesIfVerbose{}, &builder.WarnAboutArchIncompatibleLibraries{}, - ctagsRunner, + types.BareCommand(func(ctx *types.Context) error { + ctagsOutput, _, _, _, _err = builder.RunCTags(ctx.Sketch, ctx.SketchSourceMerged, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) + return _err + }), } for _, command := range commands { err := command.Run(ctx) @@ -91,7 +97,7 @@ func TestCTagsRunnerSketchWithClass(t *testing.T) { "set_values\t" + quotedSketchLocation + "\t/^void Rectangle::set_values (int x, int y) {$/;\"\tkind:function\tline:8\tclass:Rectangle\tsignature:(int x, int y)\treturntype:void\n" + "setup\t" + quotedSketchLocation + "\t/^void setup() {$/;\"\tkind:function\tline:13\tsignature:()\treturntype:void\n" + "loop\t" + quotedSketchLocation + "\t/^void loop() {$/;\"\tkind:function\tline:17\tsignature:()\treturntype:void\n" - require.Equal(t, expectedOutput, strings.Replace(string(ctagsRunner.CtagsOutput), "\r\n", "\n", -1)) + require.Equal(t, expectedOutput, strings.Replace(string(ctagsOutput), "\r\n", "\n", -1)) } func TestCTagsRunnerSketchWithTypename(t *testing.T) { @@ -100,8 +106,8 @@ func TestCTagsRunnerSketchWithTypename(t *testing.T) { defer cleanUpBuilderTestContext(t, ctx) ctx.Verbose = true - ctagsRunner := &builder.CTagsRunner{Source: &ctx.SketchSourceMerged, TargetFileName: "ctags_target.cpp"} var _err error + var ctagsOutput []byte commands := []types.Command{ &builder.ContainerSetupHardwareToolsLibsSketchAndProps{}, types.BareCommand(func(ctx *types.Context) error { @@ -111,7 +117,10 @@ func TestCTagsRunnerSketchWithTypename(t *testing.T) { &builder.ContainerFindIncludes{}, &builder.PrintUsedLibrariesIfVerbose{}, &builder.WarnAboutArchIncompatibleLibraries{}, - ctagsRunner, + types.BareCommand(func(ctx *types.Context) error { + ctagsOutput, _, _, _, _err = builder.RunCTags(ctx.Sketch, ctx.SketchSourceMerged, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) + return _err + }), } for _, command := range commands { err := command.Run(ctx) @@ -123,7 +132,7 @@ func TestCTagsRunnerSketchWithTypename(t *testing.T) { "setup\t" + quotedSketchLocation + "\t/^void setup() {$/;\"\tkind:function\tline:6\tsignature:()\treturntype:void\n" + "loop\t" + quotedSketchLocation + "\t/^void loop() {}$/;\"\tkind:function\tline:10\tsignature:()\treturntype:void\n" + "func\t" + quotedSketchLocation + "\t/^typename Foo::Bar func(){$/;\"\tkind:function\tline:12\tsignature:()\treturntype:Foo::Bar\n" - require.Equal(t, expectedOutput, strings.Replace(string(ctagsRunner.CtagsOutput), "\r\n", "\n", -1)) + require.Equal(t, expectedOutput, strings.Replace(string(ctagsOutput), "\r\n", "\n", -1)) } func TestCTagsRunnerSketchWithNamespace(t *testing.T) { @@ -132,8 +141,8 @@ func TestCTagsRunnerSketchWithNamespace(t *testing.T) { defer cleanUpBuilderTestContext(t, ctx) ctx.Verbose = true - ctagsRunner := &builder.CTagsRunner{Source: &ctx.SketchSourceMerged, TargetFileName: "ctags_target.cpp"} var _err error + var ctagsOutput []byte commands := []types.Command{ &builder.ContainerSetupHardwareToolsLibsSketchAndProps{}, types.BareCommand(func(ctx *types.Context) error { @@ -143,7 +152,10 @@ func TestCTagsRunnerSketchWithNamespace(t *testing.T) { &builder.ContainerFindIncludes{}, &builder.PrintUsedLibrariesIfVerbose{}, &builder.WarnAboutArchIncompatibleLibraries{}, - ctagsRunner, + types.BareCommand(func(ctx *types.Context) error { + ctagsOutput, _, _, _, _err = builder.RunCTags(ctx.Sketch, ctx.SketchSourceMerged, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) + return _err + }), } for _, command := range commands { err := command.Run(ctx) @@ -154,7 +166,7 @@ func TestCTagsRunnerSketchWithNamespace(t *testing.T) { expectedOutput := "value\t" + quotedSketchLocation + "\t/^\tint value() {$/;\"\tkind:function\tline:2\tnamespace:Test\tsignature:()\treturntype:int\n" + "setup\t" + quotedSketchLocation + "\t/^void setup() {}$/;\"\tkind:function\tline:7\tsignature:()\treturntype:void\n" + "loop\t" + quotedSketchLocation + "\t/^void loop() {}$/;\"\tkind:function\tline:8\tsignature:()\treturntype:void\n" - require.Equal(t, expectedOutput, strings.Replace(string(ctagsRunner.CtagsOutput), "\r\n", "\n", -1)) + require.Equal(t, expectedOutput, strings.Replace(string(ctagsOutput), "\r\n", "\n", -1)) } func TestCTagsRunnerSketchWithTemplates(t *testing.T) { @@ -163,8 +175,8 @@ func TestCTagsRunnerSketchWithTemplates(t *testing.T) { defer cleanUpBuilderTestContext(t, ctx) ctx.Verbose = true - ctagsRunner := &builder.CTagsRunner{Source: &ctx.SketchSourceMerged, TargetFileName: "ctags_target.cpp"} var _err error + var ctagsOutput []byte commands := []types.Command{ &builder.ContainerSetupHardwareToolsLibsSketchAndProps{}, types.BareCommand(func(ctx *types.Context) error { @@ -174,7 +186,10 @@ func TestCTagsRunnerSketchWithTemplates(t *testing.T) { &builder.ContainerFindIncludes{}, &builder.PrintUsedLibrariesIfVerbose{}, &builder.WarnAboutArchIncompatibleLibraries{}, - ctagsRunner, + types.BareCommand(func(ctx *types.Context) error { + ctagsOutput, _, _, _, _err = builder.RunCTags(ctx.Sketch, ctx.SketchSourceMerged, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) + return _err + }), } for _, command := range commands { err := command.Run(ctx) @@ -186,5 +201,5 @@ func TestCTagsRunnerSketchWithTemplates(t *testing.T) { "bVar\t" + quotedSketchLocation + "\t/^c< 8 > bVar;$/;\"\tkind:variable\tline:15\n" + "aVar\t" + quotedSketchLocation + "\t/^c< 1<<8 > aVar;$/;\"\tkind:variable\tline:16\n" + "func\t" + quotedSketchLocation + "\t/^template func( c< 1< & aParam) {$/;\"\tkind:function\tline:18\tsignature:( c< 1< & aParam)\treturntype:template\n" - require.Equal(t, expectedOutput, strings.Replace(string(ctagsRunner.CtagsOutput), "\r\n", "\n", -1)) + require.Equal(t, expectedOutput, strings.Replace(string(ctagsOutput), "\r\n", "\n", -1)) } From a58c90143f9ff6d2087b28d0b11b920df1e77e7d Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 5 Apr 2023 13:03:58 +0200 Subject: [PATCH 2/8] Removed useless tasks from ctags_runner test --- legacy/builder/test/ctags_runner_test.go | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/legacy/builder/test/ctags_runner_test.go b/legacy/builder/test/ctags_runner_test.go index 069339eef48..7c3bdfaf75f 100644 --- a/legacy/builder/test/ctags_runner_test.go +++ b/legacy/builder/test/ctags_runner_test.go @@ -40,9 +40,6 @@ func TestCTagsRunner(t *testing.T) { ctx.LineOffset, ctx.SketchSourceMerged, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), - &builder.ContainerFindIncludes{}, - &builder.PrintUsedLibrariesIfVerbose{}, - &builder.WarnAboutArchIncompatibleLibraries{}, types.BareCommand(func(ctx *types.Context) error { ctagsOutput, _, _, _, _err = builder.RunCTags(ctx.Sketch, ctx.SketchSourceMerged, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) return _err @@ -78,9 +75,6 @@ func TestCTagsRunnerSketchWithClass(t *testing.T) { ctx.LineOffset, ctx.SketchSourceMerged, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), - &builder.ContainerFindIncludes{}, - &builder.PrintUsedLibrariesIfVerbose{}, - &builder.WarnAboutArchIncompatibleLibraries{}, types.BareCommand(func(ctx *types.Context) error { ctagsOutput, _, _, _, _err = builder.RunCTags(ctx.Sketch, ctx.SketchSourceMerged, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) return _err @@ -114,9 +108,6 @@ func TestCTagsRunnerSketchWithTypename(t *testing.T) { ctx.LineOffset, ctx.SketchSourceMerged, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), - &builder.ContainerFindIncludes{}, - &builder.PrintUsedLibrariesIfVerbose{}, - &builder.WarnAboutArchIncompatibleLibraries{}, types.BareCommand(func(ctx *types.Context) error { ctagsOutput, _, _, _, _err = builder.RunCTags(ctx.Sketch, ctx.SketchSourceMerged, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) return _err @@ -149,9 +140,6 @@ func TestCTagsRunnerSketchWithNamespace(t *testing.T) { ctx.LineOffset, ctx.SketchSourceMerged, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), - &builder.ContainerFindIncludes{}, - &builder.PrintUsedLibrariesIfVerbose{}, - &builder.WarnAboutArchIncompatibleLibraries{}, types.BareCommand(func(ctx *types.Context) error { ctagsOutput, _, _, _, _err = builder.RunCTags(ctx.Sketch, ctx.SketchSourceMerged, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) return _err @@ -183,9 +171,6 @@ func TestCTagsRunnerSketchWithTemplates(t *testing.T) { ctx.LineOffset, ctx.SketchSourceMerged, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), - &builder.ContainerFindIncludes{}, - &builder.PrintUsedLibrariesIfVerbose{}, - &builder.WarnAboutArchIncompatibleLibraries{}, types.BareCommand(func(ctx *types.Context) error { ctagsOutput, _, _, _, _err = builder.RunCTags(ctx.Sketch, ctx.SketchSourceMerged, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) return _err From aa9e438062c94013592b793af9f870e423f27aea Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 5 Apr 2023 13:12:31 +0200 Subject: [PATCH 3/8] Simplified ctags_runner test --- legacy/builder/test/ctags_runner_test.go | 115 ++++++----------------- 1 file changed, 30 insertions(+), 85 deletions(-) diff --git a/legacy/builder/test/ctags_runner_test.go b/legacy/builder/test/ctags_runner_test.go index 7c3bdfaf75f..460a3cee3f4 100644 --- a/legacy/builder/test/ctags_runner_test.go +++ b/legacy/builder/test/ctags_runner_test.go @@ -32,23 +32,12 @@ func TestCTagsRunner(t *testing.T) { defer cleanUpBuilderTestContext(t, ctx) ctx.Verbose = true - var _err error - var ctagsOutput []byte - commands := []types.Command{ - &builder.ContainerSetupHardwareToolsLibsSketchAndProps{}, - types.BareCommand(func(ctx *types.Context) error { - ctx.LineOffset, ctx.SketchSourceMerged, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) - return _err - }), - types.BareCommand(func(ctx *types.Context) error { - ctagsOutput, _, _, _, _err = builder.RunCTags(ctx.Sketch, ctx.SketchSourceMerged, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) - return _err - }), - } - for _, command := range commands { - err := command.Run(ctx) - NoError(t, err) - } + err := (&builder.ContainerSetupHardwareToolsLibsSketchAndProps{}).Run(ctx) + NoError(t, err) + _, source, err := bldr.PrepareSketchBuildPath(ctx.Sketch, nil, ctx.SketchBuildPath) + NoError(t, err) + ctagsOutput, _, _, _, err := builder.RunCTags(ctx.Sketch, source, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) + NoError(t, err) quotedSketchLocation := strings.Replace(sketchLocation.String(), "\\", "\\\\", -1) expectedOutput := "server " + quotedSketchLocation + " /^BridgeServer server;$/;\" kind:variable line:31\n" + @@ -67,23 +56,12 @@ func TestCTagsRunnerSketchWithClass(t *testing.T) { defer cleanUpBuilderTestContext(t, ctx) ctx.Verbose = true - var _err error - var ctagsOutput []byte - commands := []types.Command{ - &builder.ContainerSetupHardwareToolsLibsSketchAndProps{}, - types.BareCommand(func(ctx *types.Context) error { - ctx.LineOffset, ctx.SketchSourceMerged, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) - return _err - }), - types.BareCommand(func(ctx *types.Context) error { - ctagsOutput, _, _, _, _err = builder.RunCTags(ctx.Sketch, ctx.SketchSourceMerged, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) - return _err - }), - } - for _, command := range commands { - err := command.Run(ctx) - NoError(t, err) - } + err := (&builder.ContainerSetupHardwareToolsLibsSketchAndProps{}).Run(ctx) + NoError(t, err) + _, source, err := bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) + NoError(t, err) + ctagsOutput, _, _, _, err := builder.RunCTags(ctx.Sketch, source, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) + NoError(t, err) quotedSketchLocation := strings.Replace(sketchLocation.String(), "\\", "\\\\", -1) expectedOutput := "set_values\t" + quotedSketchLocation + "\t/^ void set_values (int,int);$/;\"\tkind:prototype\tline:4\tclass:Rectangle\tsignature:(int,int)\treturntype:void\n" + @@ -100,23 +78,12 @@ func TestCTagsRunnerSketchWithTypename(t *testing.T) { defer cleanUpBuilderTestContext(t, ctx) ctx.Verbose = true - var _err error - var ctagsOutput []byte - commands := []types.Command{ - &builder.ContainerSetupHardwareToolsLibsSketchAndProps{}, - types.BareCommand(func(ctx *types.Context) error { - ctx.LineOffset, ctx.SketchSourceMerged, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) - return _err - }), - types.BareCommand(func(ctx *types.Context) error { - ctagsOutput, _, _, _, _err = builder.RunCTags(ctx.Sketch, ctx.SketchSourceMerged, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) - return _err - }), - } - for _, command := range commands { - err := command.Run(ctx) - NoError(t, err) - } + err := (&builder.ContainerSetupHardwareToolsLibsSketchAndProps{}).Run(ctx) + NoError(t, err) + _, source, err := bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) + NoError(t, err) + ctagsOutput, _, _, _, err := builder.RunCTags(ctx.Sketch, source, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) + NoError(t, err) quotedSketchLocation := strings.Replace(sketchLocation.String(), "\\", "\\\\", -1) expectedOutput := "Foo\t" + quotedSketchLocation + "\t/^ struct Foo{$/;\"\tkind:struct\tline:2\n" + @@ -132,23 +99,12 @@ func TestCTagsRunnerSketchWithNamespace(t *testing.T) { defer cleanUpBuilderTestContext(t, ctx) ctx.Verbose = true - var _err error - var ctagsOutput []byte - commands := []types.Command{ - &builder.ContainerSetupHardwareToolsLibsSketchAndProps{}, - types.BareCommand(func(ctx *types.Context) error { - ctx.LineOffset, ctx.SketchSourceMerged, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) - return _err - }), - types.BareCommand(func(ctx *types.Context) error { - ctagsOutput, _, _, _, _err = builder.RunCTags(ctx.Sketch, ctx.SketchSourceMerged, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) - return _err - }), - } - for _, command := range commands { - err := command.Run(ctx) - NoError(t, err) - } + err := (&builder.ContainerSetupHardwareToolsLibsSketchAndProps{}).Run(ctx) + NoError(t, err) + _, source, err := bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) + NoError(t, err) + ctagsOutput, _, _, _, err := builder.RunCTags(ctx.Sketch, source, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) + NoError(t, err) quotedSketchLocation := strings.Replace(sketchLocation.String(), "\\", "\\\\", -1) expectedOutput := "value\t" + quotedSketchLocation + "\t/^\tint value() {$/;\"\tkind:function\tline:2\tnamespace:Test\tsignature:()\treturntype:int\n" + @@ -163,23 +119,12 @@ func TestCTagsRunnerSketchWithTemplates(t *testing.T) { defer cleanUpBuilderTestContext(t, ctx) ctx.Verbose = true - var _err error - var ctagsOutput []byte - commands := []types.Command{ - &builder.ContainerSetupHardwareToolsLibsSketchAndProps{}, - types.BareCommand(func(ctx *types.Context) error { - ctx.LineOffset, ctx.SketchSourceMerged, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) - return _err - }), - types.BareCommand(func(ctx *types.Context) error { - ctagsOutput, _, _, _, _err = builder.RunCTags(ctx.Sketch, ctx.SketchSourceMerged, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) - return _err - }), - } - for _, command := range commands { - err := command.Run(ctx) - NoError(t, err) - } + err := (&builder.ContainerSetupHardwareToolsLibsSketchAndProps{}).Run(ctx) + NoError(t, err) + _, source, err := bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) + NoError(t, err) + ctagsOutput, _, _, _, err := builder.RunCTags(ctx.Sketch, source, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) + NoError(t, err) quotedSketchLocation := strings.Replace(sketchLocation.String(), "\\", "\\\\", -1) expectedOutput := "printGyro\t" + quotedSketchLocation + "\t/^void printGyro()$/;\"\tkind:function\tline:10\tsignature:()\treturntype:void\n" + From 5875f09231b10110b93de5b3ecc7ff3bc3a40272 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 5 Apr 2023 16:57:12 +0200 Subject: [PATCH 4/8] Removed some ctags related fields from builder context The last piece in RunCTags: parser := &ctags.CTagsParser{} parser.Parse(ctagsStdout, sketch.MainFile) parser.FixCLinkageTagsDeclarations() prototypes, line := parser.GeneratePrototypes() if line != -1 { prototypesLineWhereToInsert = line } has been moved at the beginning of PrototypesAdder. RunCTags now returns the output of ctags instead of `prototypes` and `line`. This also allows to remove the context variables that keeps those information. --- legacy/builder/container_add_prototypes.go | 8 ++-- legacy/builder/ctags_runner.go | 41 ++++++-------------- legacy/builder/prototypes_adder.go | 20 +++++++--- legacy/builder/test/ctags_runner_test.go | 10 ++--- legacy/builder/test/prototypes_adder_test.go | 28 ++++++------- legacy/builder/types/context.go | 6 +-- 6 files changed, 51 insertions(+), 62 deletions(-) diff --git a/legacy/builder/container_add_prototypes.go b/legacy/builder/container_add_prototypes.go index 99059b0fb76..35b575b76a8 100644 --- a/legacy/builder/container_add_prototypes.go +++ b/legacy/builder/container_add_prototypes.go @@ -62,16 +62,16 @@ func PreprocessSketchWithCtags(ctx *types.Context) error { ctx.SketchSourceAfterCppPreprocessing = filterSketchSource(ctx.Sketch, bytes.NewReader(src), false) } - var ctagsStderr []byte - _, ctagsStderr, ctx.PrototypesLineWhereToInsert, ctx.Prototypes, err = RunCTags( - ctx.Sketch, ctx.SketchSourceAfterCppPreprocessing, "sketch_merged.cpp", ctx.BuildProperties, ctx.PreprocPath) + ctagsStdout, ctagsStderr, err := RunCTags( + ctx.SketchSourceAfterCppPreprocessing, "sketch_merged.cpp", ctx.BuildProperties, ctx.PreprocPath) if ctx.Verbose { ctx.WriteStderr(ctagsStderr) } if err != nil { return err } - ctx.SketchSourceAfterArduinoPreprocessing, ctx.PrototypesSection = PrototypesAdder(ctx.SketchSourceMerged, ctx.PrototypesLineWhereToInsert, ctx.LineOffset, ctx.Prototypes, ctx.DebugPreprocessor) + ctx.SketchSourceAfterArduinoPreprocessing = PrototypesAdder( + ctx.Sketch, ctx.SketchSourceMerged, ctagsStdout, ctx.LineOffset, ctx.DebugPreprocessor) if err := bldr.SketchSaveItemCpp(ctx.Sketch.MainFile, []byte(ctx.SketchSourceAfterArduinoPreprocessing), ctx.SketchBuildPath); err != nil { return errors.WithStack(err) diff --git a/legacy/builder/ctags_runner.go b/legacy/builder/ctags_runner.go index 563444f0b7d..38ddc4b4e0a 100644 --- a/legacy/builder/ctags_runner.go +++ b/legacy/builder/ctags_runner.go @@ -19,23 +19,21 @@ import ( "bytes" "strings" - "github.com/arduino/arduino-cli/arduino/sketch" "github.com/arduino/arduino-cli/executils" - "github.com/arduino/arduino-cli/legacy/builder/ctags" "github.com/arduino/go-paths-helper" properties "github.com/arduino/go-properties-orderedmap" "github.com/pkg/errors" ) -func RunCTags(sketch *sketch.Sketch, source string, targetFileName string, buildProperties *properties.Map, preprocPath *paths.Path, -) (ctagsStdout, ctagsStderr []byte, prototypesLineWhereToInsert int, prototypes []*ctags.Prototype, err error) { - if err = preprocPath.MkdirAll(); err != nil { - return +func RunCTags(source string, targetFileName string, buildProperties *properties.Map, preprocPath *paths.Path, +) ([]byte, []byte, error) { + if err := preprocPath.MkdirAll(); err != nil { + return nil, nil, err } ctagsTargetFilePath := preprocPath.Join(targetFileName) - if err = ctagsTargetFilePath.WriteFile([]byte(source)); err != nil { - return + if err := ctagsTargetFilePath.WriteFile([]byte(source)); err != nil { + return nil, nil, err } ctagsBuildProperties := properties.NewMap() @@ -48,40 +46,25 @@ func RunCTags(sketch *sketch.Sketch, source string, targetFileName string, build pattern := ctagsBuildProperties.Get("pattern") if pattern == "" { - err = errors.Errorf(tr("%s pattern is missing"), "ctags") - return + return nil, nil, errors.Errorf(tr("%s pattern is missing"), "ctags") } commandLine := ctagsBuildProperties.ExpandPropsInString(pattern) parts, err := properties.SplitQuotedString(commandLine, `"'`, false) if err != nil { - return + return nil, nil, err } proc, err := executils.NewProcess(nil, parts...) if err != nil { - return + return nil, nil, err } stdout := &bytes.Buffer{} stderr := &bytes.Buffer{} proc.RedirectStdoutTo(stdout) proc.RedirectStderrTo(stderr) if err = proc.Run(); err != nil { - return + return nil, nil, err } - stderr.WriteString(strings.Join(parts, " ")) - ctagsStdout = stdout.Bytes() - ctagsStderr = stderr.Bytes() - if err != nil { - return - } - - parser := &ctags.CTagsParser{} - parser.Parse(ctagsStdout, sketch.MainFile) - parser.FixCLinkageTagsDeclarations() - - prototypes, line := parser.GeneratePrototypes() - if line != -1 { - prototypesLineWhereToInsert = line - } - return + _, _ = stderr.WriteString(strings.Join(parts, " ")) + return stdout.Bytes(), stderr.Bytes(), err } diff --git a/legacy/builder/prototypes_adder.go b/legacy/builder/prototypes_adder.go index a7676d42038..4d5f468ae83 100644 --- a/legacy/builder/prototypes_adder.go +++ b/legacy/builder/prototypes_adder.go @@ -20,23 +20,33 @@ import ( "strconv" "strings" + "github.com/arduino/arduino-cli/arduino/sketch" "github.com/arduino/arduino-cli/legacy/builder/constants" "github.com/arduino/arduino-cli/legacy/builder/ctags" "github.com/arduino/arduino-cli/legacy/builder/utils" ) -func PrototypesAdder(source string, firstFunctionLine, lineOffset int, prototypes []*ctags.Prototype, debugOutput bool) (preprocessedSource, prototypeSection string) { +func PrototypesAdder(sketch *sketch.Sketch, source string, ctagsStdout []byte, lineOffset int, debugOutput bool) string { + parser := &ctags.CTagsParser{} + parser.Parse(ctagsStdout, sketch.MainFile) + parser.FixCLinkageTagsDeclarations() + + prototypes, firstFunctionLine := parser.GeneratePrototypes() + if firstFunctionLine == -1 { + firstFunctionLine = 0 + } + source = strings.Replace(source, "\r\n", "\n", -1) source = strings.Replace(source, "\r", "\n", -1) sourceRows := strings.Split(source, "\n") if isFirstFunctionOutsideOfSource(firstFunctionLine, sourceRows) { - return + return "" } insertionLine := firstFunctionLine + lineOffset - 1 firstFunctionChar := len(strings.Join(sourceRows[:insertionLine], "\n")) + 1 - prototypeSection = composePrototypeSection(firstFunctionLine, prototypes) - preprocessedSource = source[:firstFunctionChar] + prototypeSection + source[firstFunctionChar:] + prototypeSection := composePrototypeSection(firstFunctionLine, prototypes) + preprocessedSource := source[:firstFunctionChar] + prototypeSection + source[firstFunctionChar:] if debugOutput { fmt.Println("#PREPROCESSED SOURCE") @@ -53,7 +63,7 @@ func PrototypesAdder(source string, firstFunctionLine, lineOffset int, prototype } fmt.Println("#END OF PREPROCESSED SOURCE") } - return + return preprocessedSource } func composePrototypeSection(line int, prototypes []*ctags.Prototype) string { diff --git a/legacy/builder/test/ctags_runner_test.go b/legacy/builder/test/ctags_runner_test.go index 460a3cee3f4..3b46a20751c 100644 --- a/legacy/builder/test/ctags_runner_test.go +++ b/legacy/builder/test/ctags_runner_test.go @@ -36,7 +36,7 @@ func TestCTagsRunner(t *testing.T) { NoError(t, err) _, source, err := bldr.PrepareSketchBuildPath(ctx.Sketch, nil, ctx.SketchBuildPath) NoError(t, err) - ctagsOutput, _, _, _, err := builder.RunCTags(ctx.Sketch, source, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) + ctagsOutput, _, err := builder.RunCTags(source, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) NoError(t, err) quotedSketchLocation := strings.Replace(sketchLocation.String(), "\\", "\\\\", -1) @@ -60,7 +60,7 @@ func TestCTagsRunnerSketchWithClass(t *testing.T) { NoError(t, err) _, source, err := bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) NoError(t, err) - ctagsOutput, _, _, _, err := builder.RunCTags(ctx.Sketch, source, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) + ctagsOutput, _, err := builder.RunCTags(source, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) NoError(t, err) quotedSketchLocation := strings.Replace(sketchLocation.String(), "\\", "\\\\", -1) @@ -82,7 +82,7 @@ func TestCTagsRunnerSketchWithTypename(t *testing.T) { NoError(t, err) _, source, err := bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) NoError(t, err) - ctagsOutput, _, _, _, err := builder.RunCTags(ctx.Sketch, source, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) + ctagsOutput, _, err := builder.RunCTags(source, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) NoError(t, err) quotedSketchLocation := strings.Replace(sketchLocation.String(), "\\", "\\\\", -1) @@ -103,7 +103,7 @@ func TestCTagsRunnerSketchWithNamespace(t *testing.T) { NoError(t, err) _, source, err := bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) NoError(t, err) - ctagsOutput, _, _, _, err := builder.RunCTags(ctx.Sketch, source, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) + ctagsOutput, _, err := builder.RunCTags(source, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) NoError(t, err) quotedSketchLocation := strings.Replace(sketchLocation.String(), "\\", "\\\\", -1) @@ -123,7 +123,7 @@ func TestCTagsRunnerSketchWithTemplates(t *testing.T) { NoError(t, err) _, source, err := bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) NoError(t, err) - ctagsOutput, _, _, _, err := builder.RunCTags(ctx.Sketch, source, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) + ctagsOutput, _, err := builder.RunCTags(source, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) NoError(t, err) quotedSketchLocation := strings.Replace(sketchLocation.String(), "\\", "\\\\", -1) diff --git a/legacy/builder/test/prototypes_adder_test.go b/legacy/builder/test/prototypes_adder_test.go index 947f5bdbf02..64630a7ba70 100644 --- a/legacy/builder/test/prototypes_adder_test.go +++ b/legacy/builder/test/prototypes_adder_test.go @@ -54,7 +54,7 @@ func TestPrototypesAdderBridgeExample(t *testing.T) { NoError(t, builder.PreprocessSketchWithCtags(ctx)) require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") - require.Equal(t, "#line 33 "+quotedSketchLocation+"\nvoid setup();\n#line 46 "+quotedSketchLocation+"\nvoid loop();\n#line 62 "+quotedSketchLocation+"\nvoid process(BridgeClient client);\n#line 82 "+quotedSketchLocation+"\nvoid digitalCommand(BridgeClient client);\n#line 109 "+quotedSketchLocation+"\nvoid analogCommand(BridgeClient client);\n#line 149 "+quotedSketchLocation+"\nvoid modeCommand(BridgeClient client);\n#line 33 "+quotedSketchLocation+"\n", ctx.PrototypesSection) + require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#line 33 "+quotedSketchLocation+"\nvoid setup();\n#line 46 "+quotedSketchLocation+"\nvoid loop();\n#line 62 "+quotedSketchLocation+"\nvoid process(BridgeClient client);\n#line 82 "+quotedSketchLocation+"\nvoid digitalCommand(BridgeClient client);\n#line 109 "+quotedSketchLocation+"\nvoid analogCommand(BridgeClient client);\n#line 149 "+quotedSketchLocation+"\nvoid modeCommand(BridgeClient client);\n#line 33 "+quotedSketchLocation+"\n") } func TestPrototypesAdderSketchWithIfDef(t *testing.T) { @@ -262,7 +262,7 @@ func TestPrototypesAdderSketchWithConfig(t *testing.T) { NoError(t, builder.PreprocessSketchWithCtags(ctx)) require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") - require.Equal(t, "#line 13 "+quotedSketchLocation+"\nvoid setup();\n#line 17 "+quotedSketchLocation+"\nvoid loop();\n#line 13 "+quotedSketchLocation+"\n", ctx.PrototypesSection) + require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#line 13 "+quotedSketchLocation+"\nvoid setup();\n#line 17 "+quotedSketchLocation+"\nvoid loop();\n#line 13 "+quotedSketchLocation+"\n") preprocessed := LoadAndInterpolate(t, filepath.Join("sketch_with_config", "sketch_with_config.preprocessed.txt"), ctx) require.Equal(t, preprocessed, strings.Replace(ctx.SketchSourceAfterArduinoPreprocessing, "\r\n", "\n", -1)) @@ -293,7 +293,7 @@ func TestPrototypesAdderSketchNoFunctionsTwoFiles(t *testing.T) { NoError(t, builder.PreprocessSketchWithCtags(ctx)) require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") - require.Equal(t, "", ctx.PrototypesSection) + require.Equal(t, ctx.SketchSourceMerged, ctx.SketchSourceAfterArduinoPreprocessing) // No prototypes added } func TestPrototypesAdderSketchNoFunctions(t *testing.T) { @@ -320,7 +320,7 @@ func TestPrototypesAdderSketchNoFunctions(t *testing.T) { NoError(t, builder.PreprocessSketchWithCtags(ctx)) require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") - require.Equal(t, "", ctx.PrototypesSection) + require.Equal(t, ctx.SketchSourceMerged, ctx.SketchSourceAfterArduinoPreprocessing) // No prototypes added } func TestPrototypesAdderSketchWithDefaultArgs(t *testing.T) { @@ -348,7 +348,7 @@ func TestPrototypesAdderSketchWithDefaultArgs(t *testing.T) { NoError(t, builder.PreprocessSketchWithCtags(ctx)) require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") - require.Equal(t, "#line 4 "+quotedSketchLocation+"\nvoid setup();\n#line 7 "+quotedSketchLocation+"\nvoid loop();\n#line 1 "+quotedSketchLocation+"\n", ctx.PrototypesSection) + require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#line 4 "+quotedSketchLocation+"\nvoid setup();\n#line 7 "+quotedSketchLocation+"\nvoid loop();\n#line 1 "+quotedSketchLocation+"\n") } func TestPrototypesAdderSketchWithInlineFunction(t *testing.T) { @@ -378,7 +378,7 @@ func TestPrototypesAdderSketchWithInlineFunction(t *testing.T) { require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") expected := "#line 1 " + quotedSketchLocation + "\nvoid setup();\n#line 2 " + quotedSketchLocation + "\nvoid loop();\n#line 4 " + quotedSketchLocation + "\nshort unsigned int testInt();\n#line 8 " + quotedSketchLocation + "\nstatic int8_t testInline();\n#line 12 " + quotedSketchLocation + "\n__attribute__((always_inline)) uint8_t testAttribute();\n#line 1 " + quotedSketchLocation + "\n" - obtained := ctx.PrototypesSection + obtained := ctx.SketchSourceAfterArduinoPreprocessing // ctags based preprocessing removes "inline" but this is still OK // TODO: remove this exception when moving to a more powerful parser expected = strings.Replace(expected, "static inline int8_t testInline();", "static int8_t testInline();", -1) @@ -387,7 +387,7 @@ func TestPrototypesAdderSketchWithInlineFunction(t *testing.T) { // TODO: remove this exception when moving to a more powerful parser expected = strings.Replace(expected, "__attribute__((always_inline)) uint8_t testAttribute();", "uint8_t testAttribute();", -1) obtained = strings.Replace(obtained, "__attribute__((always_inline)) uint8_t testAttribute();", "uint8_t testAttribute();", -1) - require.Equal(t, expected, obtained) + require.Contains(t, obtained, expected) } func TestPrototypesAdderSketchWithFunctionSignatureInsideIFDEF(t *testing.T) { @@ -415,7 +415,7 @@ func TestPrototypesAdderSketchWithFunctionSignatureInsideIFDEF(t *testing.T) { NoError(t, builder.PreprocessSketchWithCtags(ctx)) require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") - require.Equal(t, "#line 1 "+quotedSketchLocation+"\nvoid setup();\n#line 3 "+quotedSketchLocation+"\nvoid loop();\n#line 15 "+quotedSketchLocation+"\nint8_t adalight();\n#line 1 "+quotedSketchLocation+"\n", ctx.PrototypesSection) + require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#line 1 "+quotedSketchLocation+"\nvoid setup();\n#line 3 "+quotedSketchLocation+"\nvoid loop();\n#line 15 "+quotedSketchLocation+"\nint8_t adalight();\n#line 1 "+quotedSketchLocation+"\n") } func TestPrototypesAdderSketchWithUSBCON(t *testing.T) { @@ -448,7 +448,7 @@ func TestPrototypesAdderSketchWithUSBCON(t *testing.T) { NoError(t, builder.PreprocessSketchWithCtags(ctx)) require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") - require.Equal(t, "#line 5 "+quotedSketchLocation+"\nvoid ciao();\n#line 10 "+quotedSketchLocation+"\nvoid setup();\n#line 15 "+quotedSketchLocation+"\nvoid loop();\n#line 5 "+quotedSketchLocation+"\n", ctx.PrototypesSection) + require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#line 5 "+quotedSketchLocation+"\nvoid ciao();\n#line 10 "+quotedSketchLocation+"\nvoid setup();\n#line 15 "+quotedSketchLocation+"\nvoid loop();\n#line 5 "+quotedSketchLocation+"\n") } func TestPrototypesAdderSketchWithTypename(t *testing.T) { @@ -481,12 +481,12 @@ func TestPrototypesAdderSketchWithTypename(t *testing.T) { require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") expected := "#line 6 " + quotedSketchLocation + "\nvoid setup();\n#line 10 " + quotedSketchLocation + "\nvoid loop();\n#line 12 " + quotedSketchLocation + "\ntypename Foo::Bar func();\n#line 6 " + quotedSketchLocation + "\n" - obtained := ctx.PrototypesSection + obtained := ctx.SketchSourceAfterArduinoPreprocessing // ctags based preprocessing ignores line with typename // TODO: remove this exception when moving to a more powerful parser expected = strings.Replace(expected, "#line 12 "+quotedSketchLocation+"\ntypename Foo::Bar func();\n", "", -1) obtained = strings.Replace(obtained, "#line 12 "+quotedSketchLocation+"\ntypename Foo::Bar func();\n", "", -1) - require.Equal(t, expected, obtained) + require.Contains(t, obtained, expected) } func TestPrototypesAdderSketchWithIfDef2(t *testing.T) { @@ -514,7 +514,7 @@ func TestPrototypesAdderSketchWithIfDef2(t *testing.T) { NoError(t, builder.PreprocessSketchWithCtags(ctx)) require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") - require.Equal(t, "#line 5 "+quotedSketchLocation+"\nvoid elseBranch();\n#line 9 "+quotedSketchLocation+"\nvoid f1();\n#line 10 "+quotedSketchLocation+"\nvoid f2();\n#line 12 "+quotedSketchLocation+"\nvoid setup();\n#line 14 "+quotedSketchLocation+"\nvoid loop();\n#line 5 "+quotedSketchLocation+"\n", ctx.PrototypesSection) + require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#line 5 "+quotedSketchLocation+"\nvoid elseBranch();\n#line 9 "+quotedSketchLocation+"\nvoid f1();\n#line 10 "+quotedSketchLocation+"\nvoid f2();\n#line 12 "+quotedSketchLocation+"\nvoid setup();\n#line 14 "+quotedSketchLocation+"\nvoid loop();\n#line 5 "+quotedSketchLocation+"\n") expectedSource := LoadAndInterpolate(t, filepath.Join("sketch_with_ifdef", "sketch.preprocessed.txt"), ctx) require.Equal(t, expectedSource, strings.Replace(ctx.SketchSourceAfterArduinoPreprocessing, "\r\n", "\n", -1)) @@ -545,7 +545,7 @@ func TestPrototypesAdderSketchWithIfDef2SAM(t *testing.T) { NoError(t, builder.PreprocessSketchWithCtags(ctx)) require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") - require.Equal(t, "#line 2 "+quotedSketchLocation+"\nvoid ifBranch();\n#line 9 "+quotedSketchLocation+"\nvoid f1();\n#line 10 "+quotedSketchLocation+"\nvoid f2();\n#line 12 "+quotedSketchLocation+"\nvoid setup();\n#line 14 "+quotedSketchLocation+"\nvoid loop();\n#line 2 "+quotedSketchLocation+"\n", ctx.PrototypesSection) + require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#line 2 "+quotedSketchLocation+"\nvoid ifBranch();\n#line 9 "+quotedSketchLocation+"\nvoid f1();\n#line 10 "+quotedSketchLocation+"\nvoid f2();\n#line 12 "+quotedSketchLocation+"\nvoid setup();\n#line 14 "+quotedSketchLocation+"\nvoid loop();\n#line 2 "+quotedSketchLocation+"\n") expectedSource := LoadAndInterpolate(t, filepath.Join("sketch_with_ifdef", "sketch.preprocessed.SAM.txt"), ctx) require.Equal(t, expectedSource, strings.Replace(ctx.SketchSourceAfterArduinoPreprocessing, "\r\n", "\n", -1)) @@ -576,7 +576,7 @@ func TestPrototypesAdderSketchWithConst(t *testing.T) { NoError(t, builder.PreprocessSketchWithCtags(ctx)) require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") - require.Equal(t, "#line 1 "+quotedSketchLocation+"\nvoid setup();\n#line 2 "+quotedSketchLocation+"\nvoid loop();\n#line 4 "+quotedSketchLocation+"\nconst __FlashStringHelper* test();\n#line 6 "+quotedSketchLocation+"\nconst int test3();\n#line 8 "+quotedSketchLocation+"\nvolatile __FlashStringHelper* test2();\n#line 10 "+quotedSketchLocation+"\nvolatile int test4();\n#line 1 "+quotedSketchLocation+"\n", ctx.PrototypesSection) + require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#line 1 "+quotedSketchLocation+"\nvoid setup();\n#line 2 "+quotedSketchLocation+"\nvoid loop();\n#line 4 "+quotedSketchLocation+"\nconst __FlashStringHelper* test();\n#line 6 "+quotedSketchLocation+"\nconst int test3();\n#line 8 "+quotedSketchLocation+"\nvolatile __FlashStringHelper* test2();\n#line 10 "+quotedSketchLocation+"\nvolatile int test4();\n#line 1 "+quotedSketchLocation+"\n") } func TestPrototypesAdderSketchWithDosEol(t *testing.T) { diff --git a/legacy/builder/types/context.go b/legacy/builder/types/context.go index ed21f25ebf1..9f71f527198 100644 --- a/legacy/builder/types/context.go +++ b/legacy/builder/types/context.go @@ -29,7 +29,6 @@ import ( "github.com/arduino/arduino-cli/arduino/libraries/librariesmanager" "github.com/arduino/arduino-cli/arduino/libraries/librariesresolver" "github.com/arduino/arduino-cli/arduino/sketch" - "github.com/arduino/arduino-cli/legacy/builder/ctags" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" paths "github.com/arduino/go-paths-helper" properties "github.com/arduino/go-properties-orderedmap" @@ -119,10 +118,7 @@ type Context struct { UseCachedLibrariesResolution bool // C++ Parsing - LineOffset int - PrototypesSection string - PrototypesLineWhereToInsert int - Prototypes []*ctags.Prototype + LineOffset int // Verbosity settings Verbose bool From 34084451c485f5cee0138fd44d50db8e09d02a50 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 5 Apr 2023 22:45:32 +0200 Subject: [PATCH 5/8] Simplified RunCTags / factored test subroutine --- legacy/builder/container_add_prototypes.go | 7 ++- legacy/builder/ctags_runner.go | 14 +---- legacy/builder/test/ctags_runner_test.go | 62 +++++++--------------- 3 files changed, 25 insertions(+), 58 deletions(-) diff --git a/legacy/builder/container_add_prototypes.go b/legacy/builder/container_add_prototypes.go index 35b575b76a8..49fecab0784 100644 --- a/legacy/builder/container_add_prototypes.go +++ b/legacy/builder/container_add_prototypes.go @@ -62,8 +62,11 @@ func PreprocessSketchWithCtags(ctx *types.Context) error { ctx.SketchSourceAfterCppPreprocessing = filterSketchSource(ctx.Sketch, bytes.NewReader(src), false) } - ctagsStdout, ctagsStderr, err := RunCTags( - ctx.SketchSourceAfterCppPreprocessing, "sketch_merged.cpp", ctx.BuildProperties, ctx.PreprocPath) + if err := targetFilePath.WriteFile([]byte(ctx.SketchSourceAfterCppPreprocessing)); err != nil { + return err + } + + ctagsStdout, ctagsStderr, err := RunCTags(targetFilePath, ctx.BuildProperties) if ctx.Verbose { ctx.WriteStderr(ctagsStderr) } diff --git a/legacy/builder/ctags_runner.go b/legacy/builder/ctags_runner.go index 38ddc4b4e0a..9463b635f7a 100644 --- a/legacy/builder/ctags_runner.go +++ b/legacy/builder/ctags_runner.go @@ -25,24 +25,14 @@ import ( "github.com/pkg/errors" ) -func RunCTags(source string, targetFileName string, buildProperties *properties.Map, preprocPath *paths.Path, -) ([]byte, []byte, error) { - if err := preprocPath.MkdirAll(); err != nil { - return nil, nil, err - } - - ctagsTargetFilePath := preprocPath.Join(targetFileName) - if err := ctagsTargetFilePath.WriteFile([]byte(source)); err != nil { - return nil, nil, err - } - +func RunCTags(sourceFile *paths.Path, buildProperties *properties.Map) ([]byte, []byte, error) { ctagsBuildProperties := properties.NewMap() ctagsBuildProperties.Set("tools.ctags.path", "{runtime.tools.ctags.path}") ctagsBuildProperties.Set("tools.ctags.cmd.path", "{path}/ctags") ctagsBuildProperties.Set("tools.ctags.pattern", `"{cmd.path}" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "{source_file}"`) ctagsBuildProperties.Merge(buildProperties) ctagsBuildProperties.Merge(ctagsBuildProperties.SubTree("tools").SubTree("ctags")) - ctagsBuildProperties.SetPath("source_file", ctagsTargetFilePath) + ctagsBuildProperties.SetPath("source_file", sourceFile) pattern := ctagsBuildProperties.Get("pattern") if pattern == "" { diff --git a/legacy/builder/test/ctags_runner_test.go b/legacy/builder/test/ctags_runner_test.go index 3b46a20751c..036547afae6 100644 --- a/legacy/builder/test/ctags_runner_test.go +++ b/legacy/builder/test/ctags_runner_test.go @@ -21,24 +21,34 @@ import ( bldr "github.com/arduino/arduino-cli/arduino/builder" "github.com/arduino/arduino-cli/legacy/builder" - "github.com/arduino/arduino-cli/legacy/builder/types" paths "github.com/arduino/go-paths-helper" "github.com/stretchr/testify/require" ) -func TestCTagsRunner(t *testing.T) { - sketchLocation := Abs(t, paths.New("downloaded_libraries", "Bridge", "examples", "Bridge", "Bridge.ino")) +func ctagsRunnerTestTemplate(t *testing.T, sketchLocation *paths.Path) []byte { ctx := prepareBuilderTestContext(t, nil, sketchLocation, "arduino:avr:leonardo") defer cleanUpBuilderTestContext(t, ctx) ctx.Verbose = true err := (&builder.ContainerSetupHardwareToolsLibsSketchAndProps{}).Run(ctx) NoError(t, err) + _, source, err := bldr.PrepareSketchBuildPath(ctx.Sketch, nil, ctx.SketchBuildPath) NoError(t, err) - ctagsOutput, _, err := builder.RunCTags(source, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) + + target := ctx.BuildPath.Join("ctags_target.cpp") + NoError(t, target.WriteFile([]byte(source))) + + ctagsOutput, _, err := builder.RunCTags(target, ctx.BuildProperties) NoError(t, err) + return ctagsOutput +} + +func TestCTagsRunner(t *testing.T) { + sketchLocation := Abs(t, paths.New("downloaded_libraries", "Bridge", "examples", "Bridge", "Bridge.ino")) + ctagsOutput := ctagsRunnerTestTemplate(t, sketchLocation) + quotedSketchLocation := strings.Replace(sketchLocation.String(), "\\", "\\\\", -1) expectedOutput := "server " + quotedSketchLocation + " /^BridgeServer server;$/;\" kind:variable line:31\n" + "setup " + quotedSketchLocation + " /^void setup() {$/;\" kind:function line:33 signature:() returntype:void\n" + @@ -52,16 +62,7 @@ func TestCTagsRunner(t *testing.T) { func TestCTagsRunnerSketchWithClass(t *testing.T) { sketchLocation := Abs(t, paths.New("sketch_with_class", "sketch_with_class.ino")) - ctx := prepareBuilderTestContext(t, nil, sketchLocation, "arduino:avr:leonardo") - defer cleanUpBuilderTestContext(t, ctx) - ctx.Verbose = true - - err := (&builder.ContainerSetupHardwareToolsLibsSketchAndProps{}).Run(ctx) - NoError(t, err) - _, source, err := bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) - NoError(t, err) - ctagsOutput, _, err := builder.RunCTags(source, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) - NoError(t, err) + ctagsOutput := ctagsRunnerTestTemplate(t, sketchLocation) quotedSketchLocation := strings.Replace(sketchLocation.String(), "\\", "\\\\", -1) expectedOutput := "set_values\t" + quotedSketchLocation + "\t/^ void set_values (int,int);$/;\"\tkind:prototype\tline:4\tclass:Rectangle\tsignature:(int,int)\treturntype:void\n" + @@ -74,16 +75,7 @@ func TestCTagsRunnerSketchWithClass(t *testing.T) { func TestCTagsRunnerSketchWithTypename(t *testing.T) { sketchLocation := Abs(t, paths.New("sketch_with_typename", "sketch_with_typename.ino")) - ctx := prepareBuilderTestContext(t, nil, sketchLocation, "arduino:avr:leonardo") - defer cleanUpBuilderTestContext(t, ctx) - ctx.Verbose = true - - err := (&builder.ContainerSetupHardwareToolsLibsSketchAndProps{}).Run(ctx) - NoError(t, err) - _, source, err := bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) - NoError(t, err) - ctagsOutput, _, err := builder.RunCTags(source, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) - NoError(t, err) + ctagsOutput := ctagsRunnerTestTemplate(t, sketchLocation) quotedSketchLocation := strings.Replace(sketchLocation.String(), "\\", "\\\\", -1) expectedOutput := "Foo\t" + quotedSketchLocation + "\t/^ struct Foo{$/;\"\tkind:struct\tline:2\n" + @@ -95,16 +87,7 @@ func TestCTagsRunnerSketchWithTypename(t *testing.T) { func TestCTagsRunnerSketchWithNamespace(t *testing.T) { sketchLocation := Abs(t, paths.New("sketch_with_namespace", "sketch_with_namespace.ino")) - ctx := prepareBuilderTestContext(t, nil, sketchLocation, "arduino:avr:leonardo") - defer cleanUpBuilderTestContext(t, ctx) - ctx.Verbose = true - - err := (&builder.ContainerSetupHardwareToolsLibsSketchAndProps{}).Run(ctx) - NoError(t, err) - _, source, err := bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) - NoError(t, err) - ctagsOutput, _, err := builder.RunCTags(source, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) - NoError(t, err) + ctagsOutput := ctagsRunnerTestTemplate(t, sketchLocation) quotedSketchLocation := strings.Replace(sketchLocation.String(), "\\", "\\\\", -1) expectedOutput := "value\t" + quotedSketchLocation + "\t/^\tint value() {$/;\"\tkind:function\tline:2\tnamespace:Test\tsignature:()\treturntype:int\n" + @@ -115,16 +98,7 @@ func TestCTagsRunnerSketchWithNamespace(t *testing.T) { func TestCTagsRunnerSketchWithTemplates(t *testing.T) { sketchLocation := Abs(t, paths.New("sketch_with_templates_and_shift", "sketch_with_templates_and_shift.ino")) - ctx := prepareBuilderTestContext(t, nil, sketchLocation, "arduino:avr:leonardo") - defer cleanUpBuilderTestContext(t, ctx) - ctx.Verbose = true - - err := (&builder.ContainerSetupHardwareToolsLibsSketchAndProps{}).Run(ctx) - NoError(t, err) - _, source, err := bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) - NoError(t, err) - ctagsOutput, _, err := builder.RunCTags(source, "ctags_target.cpp", ctx.BuildProperties, ctx.PreprocPath) - NoError(t, err) + ctagsOutput := ctagsRunnerTestTemplate(t, sketchLocation) quotedSketchLocation := strings.Replace(sketchLocation.String(), "\\", "\\\\", -1) expectedOutput := "printGyro\t" + quotedSketchLocation + "\t/^void printGyro()$/;\"\tkind:function\tline:10\tsignature:()\treturntype:void\n" + From 818b0e7d991bfc79652cada058ee31c04a320834 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 5 Apr 2023 22:55:53 +0200 Subject: [PATCH 6/8] Removed DebugPreprocessor from builder ctx --- legacy/builder/container_add_prototypes.go | 3 +-- legacy/builder/prototypes_adder.go | 6 ++++-- legacy/builder/test/try_build_of_problematic_sketch_test.go | 2 +- legacy/builder/types/context.go | 3 +-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/legacy/builder/container_add_prototypes.go b/legacy/builder/container_add_prototypes.go index 49fecab0784..e19549fd400 100644 --- a/legacy/builder/container_add_prototypes.go +++ b/legacy/builder/container_add_prototypes.go @@ -73,8 +73,7 @@ func PreprocessSketchWithCtags(ctx *types.Context) error { if err != nil { return err } - ctx.SketchSourceAfterArduinoPreprocessing = PrototypesAdder( - ctx.Sketch, ctx.SketchSourceMerged, ctagsStdout, ctx.LineOffset, ctx.DebugPreprocessor) + ctx.SketchSourceAfterArduinoPreprocessing = PrototypesAdder(ctx.Sketch, ctx.SketchSourceMerged, ctagsStdout, ctx.LineOffset) if err := bldr.SketchSaveItemCpp(ctx.Sketch.MainFile, []byte(ctx.SketchSourceAfterArduinoPreprocessing), ctx.SketchBuildPath); err != nil { return errors.WithStack(err) diff --git a/legacy/builder/prototypes_adder.go b/legacy/builder/prototypes_adder.go index 4d5f468ae83..fba8dd94e4c 100644 --- a/legacy/builder/prototypes_adder.go +++ b/legacy/builder/prototypes_adder.go @@ -26,7 +26,9 @@ import ( "github.com/arduino/arduino-cli/legacy/builder/utils" ) -func PrototypesAdder(sketch *sketch.Sketch, source string, ctagsStdout []byte, lineOffset int, debugOutput bool) string { +var DebugPreprocessor bool + +func PrototypesAdder(sketch *sketch.Sketch, source string, ctagsStdout []byte, lineOffset int) string { parser := &ctags.CTagsParser{} parser.Parse(ctagsStdout, sketch.MainFile) parser.FixCLinkageTagsDeclarations() @@ -48,7 +50,7 @@ func PrototypesAdder(sketch *sketch.Sketch, source string, ctagsStdout []byte, l prototypeSection := composePrototypeSection(firstFunctionLine, prototypes) preprocessedSource := source[:firstFunctionChar] + prototypeSection + source[firstFunctionChar:] - if debugOutput { + if DebugPreprocessor { fmt.Println("#PREPROCESSED SOURCE") prototypesRows := strings.Split(prototypeSection, "\n") prototypesRows = prototypesRows[:len(prototypesRows)-1] diff --git a/legacy/builder/test/try_build_of_problematic_sketch_test.go b/legacy/builder/test/try_build_of_problematic_sketch_test.go index c82c6e0b290..bb6457728ae 100644 --- a/legacy/builder/test/try_build_of_problematic_sketch_test.go +++ b/legacy/builder/test/try_build_of_problematic_sketch_test.go @@ -202,13 +202,13 @@ func TestTryBuild042(t *testing.T) { } func makeDefaultContext() *types.Context { + builder.DebugPreprocessor = true return &types.Context{ HardwareDirs: paths.NewPathList(filepath.Join("..", "hardware"), "downloaded_hardware", "downloaded_board_manager_stuff"), BuiltInToolsDirs: paths.NewPathList("downloaded_tools"), BuiltInLibrariesDirs: paths.New("downloaded_libraries"), OtherLibrariesDirs: paths.NewPathList("libraries"), Verbose: true, - DebugPreprocessor: true, } } diff --git a/legacy/builder/types/context.go b/legacy/builder/types/context.go index 9f71f527198..2b5fd27b679 100644 --- a/legacy/builder/types/context.go +++ b/legacy/builder/types/context.go @@ -121,8 +121,7 @@ type Context struct { LineOffset int // Verbosity settings - Verbose bool - DebugPreprocessor bool + Verbose bool // Dry run, only create progress map Progress ProgressStruct From 91770d89d5955efb28af2cbe361dbaaeeb563b24 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 6 Apr 2023 00:05:24 +0200 Subject: [PATCH 7/8] Added executils.RunAndCaptureOutput --- executils/process.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/executils/process.go b/executils/process.go index 6044275af85..7e0ac135089 100644 --- a/executils/process.go +++ b/executils/process.go @@ -16,6 +16,7 @@ package executils import ( + "bytes" "context" "io" "os" @@ -174,3 +175,15 @@ func (p *Process) RunWithinContext(ctx context.Context) error { }() return p.Wait() } + +// RunAndCaptureOutput starts the specified command and waits for it to complete. If the given context +// is canceled before the normal process termination, the process is killed. The standard output and +// standard error of the process are captured and returned at process termination. +func (p *Process) RunAndCaptureOutput(ctx context.Context) ([]byte, []byte, error) { + stdout := &bytes.Buffer{} + stderr := &bytes.Buffer{} + p.RedirectStdoutTo(stdout) + p.RedirectStderrTo(stderr) + err := p.RunWithinContext(ctx) + return stdout.Bytes(), stderr.Bytes(), err +} From 3eac673a2d77875c46ac8d6721efcb8cd7a92188 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 6 Apr 2023 00:05:59 +0200 Subject: [PATCH 8/8] Moved RunCTags out of legacy package --- .../builder/preprocessor/ctags.go | 28 ++++++++++--------- legacy/builder/container_add_prototypes.go | 3 +- legacy/builder/test/ctags_runner_test.go | 3 +- 3 files changed, 19 insertions(+), 15 deletions(-) rename legacy/builder/ctags_runner.go => arduino/builder/preprocessor/ctags.go (77%) diff --git a/legacy/builder/ctags_runner.go b/arduino/builder/preprocessor/ctags.go similarity index 77% rename from legacy/builder/ctags_runner.go rename to arduino/builder/preprocessor/ctags.go index 9463b635f7a..f079f54abf2 100644 --- a/legacy/builder/ctags_runner.go +++ b/arduino/builder/preprocessor/ctags.go @@ -1,6 +1,6 @@ // This file is part of arduino-cli. // -// Copyright 2020 ARDUINO SA (http://www.arduino.cc/) +// Copyright 2023 ARDUINO SA (http://www.arduino.cc/) // // This software is released under the GNU General Public License version 3, // which covers the main part of arduino-cli. @@ -13,18 +13,23 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package builder +package preprocessor import ( - "bytes" + "context" + "fmt" "strings" "github.com/arduino/arduino-cli/executils" + "github.com/arduino/arduino-cli/i18n" "github.com/arduino/go-paths-helper" - properties "github.com/arduino/go-properties-orderedmap" + "github.com/arduino/go-properties-orderedmap" "github.com/pkg/errors" ) +var tr = i18n.Tr + +// RunCTags performs a run of ctags on the given source file. Returns the ctags output and the stderr contents. func RunCTags(sourceFile *paths.Path, buildProperties *properties.Map) ([]byte, []byte, error) { ctagsBuildProperties := properties.NewMap() ctagsBuildProperties.Set("tools.ctags.path", "{runtime.tools.ctags.path}") @@ -48,13 +53,10 @@ func RunCTags(sourceFile *paths.Path, buildProperties *properties.Map) ([]byte, if err != nil { return nil, nil, err } - stdout := &bytes.Buffer{} - stderr := &bytes.Buffer{} - proc.RedirectStdoutTo(stdout) - proc.RedirectStderrTo(stderr) - if err = proc.Run(); err != nil { - return nil, nil, err - } - _, _ = stderr.WriteString(strings.Join(parts, " ")) - return stdout.Bytes(), stderr.Bytes(), err + stdout, stderr, err := proc.RunAndCaptureOutput(context.Background()) + + // Append ctags arguments to stderr + args := fmt.Sprintln(strings.Join(parts, " ")) + stderr = append([]byte(args), stderr...) + return stdout, stderr, err } diff --git a/legacy/builder/container_add_prototypes.go b/legacy/builder/container_add_prototypes.go index e19549fd400..a372abb9250 100644 --- a/legacy/builder/container_add_prototypes.go +++ b/legacy/builder/container_add_prototypes.go @@ -24,6 +24,7 @@ import ( "strings" bldr "github.com/arduino/arduino-cli/arduino/builder" + "github.com/arduino/arduino-cli/arduino/builder/preprocessor" "github.com/arduino/arduino-cli/arduino/sketch" "github.com/arduino/arduino-cli/legacy/builder/types" "github.com/arduino/go-paths-helper" @@ -66,7 +67,7 @@ func PreprocessSketchWithCtags(ctx *types.Context) error { return err } - ctagsStdout, ctagsStderr, err := RunCTags(targetFilePath, ctx.BuildProperties) + ctagsStdout, ctagsStderr, err := preprocessor.RunCTags(targetFilePath, ctx.BuildProperties) if ctx.Verbose { ctx.WriteStderr(ctagsStderr) } diff --git a/legacy/builder/test/ctags_runner_test.go b/legacy/builder/test/ctags_runner_test.go index 036547afae6..d776a93c4bc 100644 --- a/legacy/builder/test/ctags_runner_test.go +++ b/legacy/builder/test/ctags_runner_test.go @@ -20,6 +20,7 @@ import ( "testing" bldr "github.com/arduino/arduino-cli/arduino/builder" + "github.com/arduino/arduino-cli/arduino/builder/preprocessor" "github.com/arduino/arduino-cli/legacy/builder" paths "github.com/arduino/go-paths-helper" "github.com/stretchr/testify/require" @@ -39,7 +40,7 @@ func ctagsRunnerTestTemplate(t *testing.T, sketchLocation *paths.Path) []byte { target := ctx.BuildPath.Join("ctags_target.cpp") NoError(t, target.WriteFile([]byte(source))) - ctagsOutput, _, err := builder.RunCTags(target, ctx.BuildProperties) + ctagsOutput, _, err := preprocessor.RunCTags(target, ctx.BuildProperties) NoError(t, err) return ctagsOutput