diff --git a/arduino/builder/cpp.go b/arduino/builder/cpp/cpp.go similarity index 62% rename from arduino/builder/cpp.go rename to arduino/builder/cpp/cpp.go index 87610e7ed18..71c2b696702 100644 --- a/arduino/builder/cpp.go +++ b/arduino/builder/cpp/cpp.go @@ -13,29 +13,63 @@ // 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 cpp import ( + "strconv" "strings" "unicode/utf8" + + "github.com/arduino/go-paths-helper" ) -// QuoteCppString returns the given string as a quoted string for use with the C +// QuoteString returns the given string as a quoted string for use with the C // preprocessor. This adds double quotes around it and escapes any // double quotes and backslashes in the string. -func QuoteCppString(str string) string { +func QuoteString(str string) string { str = strings.Replace(str, "\\", "\\\\", -1) str = strings.Replace(str, "\"", "\\\"", -1) return "\"" + str + "\"" } -// ParseCppString parse a C-preprocessor string as emitted by the preprocessor. This +// ParseLineMarker parses the given line as a gcc line marker and returns the contained +// filename. +func ParseLineMarker(line string) *paths.Path { + // A line marker contains the line number and filename and looks like: + // # 123 /path/to/file.cpp + // It can be followed by zero or more flag number that indicate the + // preprocessor state and can be ignored. + // For exact details on this format, see: + // https://github.com/gcc-mirror/gcc/blob/edd716b6b1caa1a5cb320a8cd7f626f30198e098/gcc/c-family/c-ppoutput.c#L413-L415 + + split := strings.SplitN(line, " ", 3) + if len(split) < 3 || len(split[0]) == 0 || split[0][0] != '#' { + return nil + } + + _, err := strconv.Atoi(split[1]) + if err != nil { + return nil + } + + // If we get here, we found a # followed by a line number, so + // assume this is a line marker and see if the rest of the line + // starts with a string containing the filename + str, rest, ok := ParseString(split[2]) + + if ok && (rest == "" || rest[0] == ' ') { + return paths.New(str) + } + return nil +} + +// ParseString parse a string as emitted by the preprocessor. This // is a string contained in double quotes, with any backslashes or // quotes escaped with a backslash. If a valid string was present at the // start of the given line, returns the unquoted string contents, the // remainder of the line (everything after the closing "), and true. // Otherwise, returns the empty string, the entire line and false. -func ParseCppString(line string) (string, string, bool) { +func ParseString(line string) (string, string, bool) { // For details about how these strings are output by gcc, see: // https://github.com/gcc-mirror/gcc/blob/a588355ab948cf551bc9d2b89f18e5ae5140f52c/libcpp/macro.c#L491-L511 // Note that the documentation suggests all non-printable diff --git a/arduino/builder/cpp/cpp_test.go b/arduino/builder/cpp/cpp_test.go new file mode 100644 index 00000000000..b6ae543f558 --- /dev/null +++ b/arduino/builder/cpp/cpp_test.go @@ -0,0 +1,74 @@ +// This file is part of arduino-cli. +// +// 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. +// The terms of this license can be found at: +// https://www.gnu.org/licenses/gpl-3.0.en.html +// +// You can be released from the requirements of the above licenses by purchasing +// a commercial license. Buying such a license is mandatory if you want to +// modify or otherwise use the software for commercial activities involving the +// Arduino software without disclosing the source code of your own applications. +// To purchase a commercial license, send an email to license@arduino.cc. + +package cpp_test + +import ( + "testing" + + "github.com/arduino/arduino-cli/arduino/builder/cpp" + "github.com/stretchr/testify/require" +) + +func TestParseString(t *testing.T) { + _, _, ok := cpp.ParseString(`foo`) + require.Equal(t, false, ok) + + _, _, ok = cpp.ParseString(`"foo`) + require.Equal(t, false, ok) + + str, rest, ok := cpp.ParseString(`"foo"`) + require.Equal(t, true, ok) + require.Equal(t, `foo`, str) + require.Equal(t, ``, rest) + + str, rest, ok = cpp.ParseString(`"foo\\bar"`) + require.Equal(t, true, ok) + require.Equal(t, `foo\bar`, str) + require.Equal(t, ``, rest) + + str, rest, ok = cpp.ParseString(`"foo \"is\" quoted and \\\\bar\"\" escaped\\" and "then" some`) + require.Equal(t, true, ok) + require.Equal(t, `foo "is" quoted and \\bar"" escaped\`, str) + require.Equal(t, ` and "then" some`, rest) + + str, rest, ok = cpp.ParseString(`" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_abcdefghijklmnopqrstuvwxyz{|}~"`) + require.Equal(t, true, ok) + require.Equal(t, ` !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~`, str) + require.Equal(t, ``, rest) + + str, rest, ok = cpp.ParseString(`"/home/ççç/"`) + require.Equal(t, true, ok) + require.Equal(t, `/home/ççç/`, str) + require.Equal(t, ``, rest) + + str, rest, ok = cpp.ParseString(`"/home/ççç/ /$sdsdd\\"`) + require.Equal(t, true, ok) + require.Equal(t, `/home/ççç/ /$sdsdd\`, str) + require.Equal(t, ``, rest) +} + +func TestQuoteString(t *testing.T) { + cases := map[string]string{ + `foo`: `"foo"`, + `foo\bar`: `"foo\\bar"`, + `foo "is" quoted and \\bar"" escaped\`: `"foo \"is\" quoted and \\\\bar\"\" escaped\\"`, + // ASCII 0x20 - 0x7e, excluding ` + ` !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~`: `" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_abcdefghijklmnopqrstuvwxyz{|}~"`, + } + for input, expected := range cases { + require.Equal(t, expected, cpp.QuoteString(input)) + } +} diff --git a/arduino/builder/cpp_test.go b/arduino/builder/cpp_test.go deleted file mode 100644 index 84de5f0b254..00000000000 --- a/arduino/builder/cpp_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package builder_test - -import ( - "testing" - - "github.com/arduino/arduino-cli/arduino/builder" - "github.com/stretchr/testify/require" -) - -func TestParseCppString(t *testing.T) { - _, _, ok := builder.ParseCppString(`foo`) - require.Equal(t, false, ok) - - _, _, ok = builder.ParseCppString(`"foo`) - require.Equal(t, false, ok) - - str, rest, ok := builder.ParseCppString(`"foo"`) - require.Equal(t, true, ok) - require.Equal(t, `foo`, str) - require.Equal(t, ``, rest) - - str, rest, ok = builder.ParseCppString(`"foo\\bar"`) - require.Equal(t, true, ok) - require.Equal(t, `foo\bar`, str) - require.Equal(t, ``, rest) - - str, rest, ok = builder.ParseCppString(`"foo \"is\" quoted and \\\\bar\"\" escaped\\" and "then" some`) - require.Equal(t, true, ok) - require.Equal(t, `foo "is" quoted and \\bar"" escaped\`, str) - require.Equal(t, ` and "then" some`, rest) - - str, rest, ok = builder.ParseCppString(`" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_abcdefghijklmnopqrstuvwxyz{|}~"`) - require.Equal(t, true, ok) - require.Equal(t, ` !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~`, str) - require.Equal(t, ``, rest) - - str, rest, ok = builder.ParseCppString(`"/home/ççç/"`) - require.Equal(t, true, ok) - require.Equal(t, `/home/ççç/`, str) - require.Equal(t, ``, rest) - - str, rest, ok = builder.ParseCppString(`"/home/ççç/ /$sdsdd\\"`) - require.Equal(t, true, ok) - require.Equal(t, `/home/ççç/ /$sdsdd\`, str) - require.Equal(t, ``, rest) -} diff --git a/arduino/builder/preprocessor/ctags.go b/arduino/builder/preprocessor/ctags.go index f079f54abf2..bf5f25b4ca2 100644 --- a/arduino/builder/preprocessor/ctags.go +++ b/arduino/builder/preprocessor/ctags.go @@ -16,10 +16,17 @@ package preprocessor import ( + "bufio" + "bytes" "context" "fmt" + "io" + "strconv" "strings" + "github.com/arduino/arduino-cli/arduino/builder/cpp" + "github.com/arduino/arduino-cli/arduino/builder/preprocessor/internal/ctags" + "github.com/arduino/arduino-cli/arduino/sketch" "github.com/arduino/arduino-cli/executils" "github.com/arduino/arduino-cli/i18n" "github.com/arduino/go-paths-helper" @@ -29,6 +36,145 @@ import ( var tr = i18n.Tr +// DebugPreprocessor when set to true the CTags preprocessor will output debugging info to stdout +// this is useful for unit-testing to provide more infos +var DebugPreprocessor bool + +// PreprocessSketchWithCtags performs preprocessing of the arduino sketch using CTags. +func PreprocessSketchWithCtags(sketch *sketch.Sketch, buildPath *paths.Path, includes paths.PathList, lineOffset int, buildProperties *properties.Map, onlyUpdateCompilationDatabase bool) ([]byte, []byte, error) { + // Create a temporary working directory + tmpDir, err := paths.MkTempDir("", "") + if err != nil { + return nil, nil, err + } + defer tmpDir.RemoveAll() + ctagsTarget := tmpDir.Join("sketch_merged.cpp") + + normalOutput := &bytes.Buffer{} + verboseOutput := &bytes.Buffer{} + + // Run GCC preprocessor + sourceFile := buildPath.Join("sketch", sketch.MainFile.Base()+".cpp") + gccStdout, gccStderr, err := GCC(sourceFile, ctagsTarget, includes, buildProperties) + verboseOutput.Write(gccStdout) + verboseOutput.Write(gccStderr) + normalOutput.Write(gccStderr) + if err != nil { + if !onlyUpdateCompilationDatabase { + return normalOutput.Bytes(), verboseOutput.Bytes(), errors.WithStack(err) + } + + // Do not bail out if we are generating the compile commands database + normalOutput.WriteString(fmt.Sprintf("%s: %s", + tr("An error occurred adding prototypes"), + tr("the compilation database may be incomplete or inaccurate"))) + if err := sourceFile.CopyTo(ctagsTarget); err != nil { + return normalOutput.Bytes(), verboseOutput.Bytes(), errors.WithStack(err) + } + } + + if src, err := ctagsTarget.ReadFile(); err == nil { + filteredSource := filterSketchSource(sketch, bytes.NewReader(src), false) + if err := ctagsTarget.WriteFile([]byte(filteredSource)); err != nil { + return normalOutput.Bytes(), verboseOutput.Bytes(), err + } + } else { + return normalOutput.Bytes(), verboseOutput.Bytes(), err + } + + // Run CTags on gcc-preprocessed source + ctagsOutput, ctagsStdErr, err := RunCTags(ctagsTarget, buildProperties) + verboseOutput.Write(ctagsStdErr) + if err != nil { + return normalOutput.Bytes(), verboseOutput.Bytes(), err + } + + // Parse CTags output + parser := &ctags.Parser{} + prototypes, firstFunctionLine := parser.Parse(ctagsOutput, sketch.MainFile) + if firstFunctionLine == -1 { + firstFunctionLine = 0 + } + + // Add prototypes to the original sketch source + var source string + if sourceData, err := sourceFile.ReadFile(); err == nil { + source = string(sourceData) + } else { + return normalOutput.Bytes(), verboseOutput.Bytes(), err + } + 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 normalOutput.Bytes(), verboseOutput.Bytes(), nil + } + + insertionLine := firstFunctionLine + lineOffset - 1 + firstFunctionChar := len(strings.Join(sourceRows[:insertionLine], "\n")) + 1 + prototypeSection := composePrototypeSection(firstFunctionLine, prototypes) + preprocessedSource := source[:firstFunctionChar] + prototypeSection + source[firstFunctionChar:] + + if DebugPreprocessor { + fmt.Println("#PREPROCESSED SOURCE") + prototypesRows := strings.Split(prototypeSection, "\n") + prototypesRows = prototypesRows[:len(prototypesRows)-1] + for i := 0; i < len(sourceRows)+len(prototypesRows); i++ { + if i < insertionLine { + fmt.Printf(" |%s\n", sourceRows[i]) + } else if i < insertionLine+len(prototypesRows) { + fmt.Printf("PRO|%s\n", prototypesRows[i-insertionLine]) + } else { + fmt.Printf(" |%s\n", sourceRows[i-len(prototypesRows)]) + } + } + fmt.Println("#END OF PREPROCESSED SOURCE") + } + + // Write back arduino-preprocess output to the sourceFile + err = sourceFile.WriteFile([]byte(preprocessedSource)) + return normalOutput.Bytes(), verboseOutput.Bytes(), err +} + +func composePrototypeSection(line int, prototypes []*ctags.Prototype) string { + if len(prototypes) == 0 { + return "" + } + + str := joinPrototypes(prototypes) + str += "\n#line " + str += strconv.Itoa(line) + str += " " + cpp.QuoteString(prototypes[0].File) + str += "\n" + + return str +} + +func joinPrototypes(prototypes []*ctags.Prototype) string { + prototypesSlice := []string{} + for _, proto := range prototypes { + if signatureContainsaDefaultArg(proto) { + continue + } + prototypesSlice = append(prototypesSlice, "#line "+strconv.Itoa(proto.Line)+" "+cpp.QuoteString(proto.File)) + prototypeParts := []string{} + if proto.Modifiers != "" { + prototypeParts = append(prototypeParts, proto.Modifiers) + } + prototypeParts = append(prototypeParts, proto.Prototype) + prototypesSlice = append(prototypesSlice, strings.Join(prototypeParts, " ")) + } + return strings.Join(prototypesSlice, "\n") +} + +func signatureContainsaDefaultArg(proto *ctags.Prototype) bool { + return strings.Contains(proto.Prototype, "=") +} + +func isFirstFunctionOutsideOfSource(firstFunctionLine int, sourceRows []string) bool { + return firstFunctionLine > len(sourceRows)-1 +} + // 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() @@ -60,3 +206,29 @@ func RunCTags(sourceFile *paths.Path, buildProperties *properties.Map) ([]byte, stderr = append([]byte(args), stderr...) return stdout, stderr, err } + +func filterSketchSource(sketch *sketch.Sketch, source io.Reader, removeLineMarkers bool) string { + fileNames := paths.NewPathList() + fileNames.Add(sketch.MainFile) + fileNames.AddAll(sketch.OtherSketchFiles) + + inSketch := false + filtered := "" + + scanner := bufio.NewScanner(source) + for scanner.Scan() { + line := scanner.Text() + if filename := cpp.ParseLineMarker(line); filename != nil { + inSketch = fileNames.Contains(filename) + if inSketch && removeLineMarkers { + continue + } + } + + if inSketch { + filtered += line + "\n" + } + } + + return filtered +} diff --git a/legacy/builder/ctags/ctags_has_issues.go b/arduino/builder/preprocessor/internal/ctags/ctags_has_issues.go similarity index 89% rename from legacy/builder/ctags/ctags_has_issues.go rename to arduino/builder/preprocessor/internal/ctags/ctags_has_issues.go index a61bf6c6c46..4d4d7d48f65 100644 --- a/legacy/builder/ctags/ctags_has_issues.go +++ b/arduino/builder/preprocessor/internal/ctags/ctags_has_issues.go @@ -23,17 +23,17 @@ import ( "golang.org/x/exp/slices" ) -func (p *CTagsParser) fixCLinkageTagsDeclarations() { +func (p *Parser) fixCLinkageTagsDeclarations() { linesMap := p.FindCLinkageLines(p.tags) for i := range p.tags { if slices.Contains(linesMap[p.tags[i].Filename], p.tags[i].Line) && - !strings.Contains(p.tags[i].PrototypeModifiers, EXTERN) { - p.tags[i].PrototypeModifiers = p.tags[i].PrototypeModifiers + " " + EXTERN + !strings.Contains(p.tags[i].PrototypeModifiers, keywordExternC) { + p.tags[i].PrototypeModifiers = p.tags[i].PrototypeModifiers + " " + keywordExternC } } } -func (p *CTagsParser) prototypeAndCodeDontMatch(tag *CTag) bool { +func (p *Parser) prototypeAndCodeDontMatch(tag *Tag) bool { if tag.SkipMe { return true } @@ -98,7 +98,7 @@ func (p *CTagsParser) prototypeAndCodeDontMatch(tag *CTag) bool { return ret == -1 } -func findTemplateMultiline(tag *CTag) string { +func findTemplateMultiline(tag *Tag) string { code, _ := getFunctionProtoUntilTemplateToken(tag, tag.Code) return removeEverythingAfterClosingRoundBracket(code) } @@ -108,7 +108,7 @@ func removeEverythingAfterClosingRoundBracket(s string) string { return s[0 : n+1] } -func getFunctionProtoUntilTemplateToken(tag *CTag, code string) (string, int) { +func getFunctionProtoUntilTemplateToken(tag *Tag, code string) (string, int) { /* FIXME I'm ugly */ line := 0 @@ -128,7 +128,7 @@ func getFunctionProtoUntilTemplateToken(tag *CTag, code string) (string, int) { textBuffer = append(textBuffer, text) } - for line > 0 && !strings.Contains(code, TEMPLATE) { + for line > 0 && !strings.Contains(code, keywordTemplate) { line = line - 1 text := textBuffer[line] @@ -141,7 +141,7 @@ func getFunctionProtoUntilTemplateToken(tag *CTag, code string) (string, int) { return code, line } -func getFunctionProtoWithNPreviousCharacters(tag *CTag, code string, n int) (string, int) { +func getFunctionProtoWithNPreviousCharacters(tag *Tag, code string, n int) (string, int) { /* FIXME I'm ugly */ expectedPrototypeLen := len(code) + n @@ -204,10 +204,9 @@ func removeComments(text string, multilinecomment bool) (string, bool) { return text, multilinecomment } -/* This function scans the source files searching for "extern C" context - * It save the line numbers in a map filename -> {lines...} - */ -func (p *CTagsParser) FindCLinkageLines(tags []*CTag) map[string][]int { +// FindCLinkageLines scans the source files searching for "extern C" context +// It save the line numbers in a map filename -> {lines...} +func (p *Parser) FindCLinkageLines(tags []*Tag) map[string][]int { lines := make(map[string][]int) @@ -245,7 +244,7 @@ func (p *CTagsParser) FindCLinkageLines(tags []*CTag) map[string][]int { indentLevels := 0 line := 0 - externCDecl := removeSpacesAndTabs(EXTERN) + externCDecl := removeSpacesAndTabs(keywordExternC) for scanner.Scan() { line++ diff --git a/legacy/builder/ctags/ctags_parser.go b/arduino/builder/preprocessor/internal/ctags/ctags_parser.go similarity index 81% rename from legacy/builder/ctags/ctags_parser.go rename to arduino/builder/preprocessor/internal/ctags/ctags_parser.go index 5836f7bf337..c2e6e99585f 100644 --- a/legacy/builder/ctags/ctags_parser.go +++ b/arduino/builder/preprocessor/internal/ctags/ctags_parser.go @@ -22,26 +22,28 @@ import ( "github.com/arduino/go-paths-helper" ) -const KIND_PROTOTYPE = "prototype" -const KIND_FUNCTION = "function" +const kindPrototype = "prototype" +const kindFunction = "function" //const KIND_PROTOTYPE_MODIFIERS = "prototype_modifiers" -const TEMPLATE = "template" -const STATIC = "static" -const EXTERN = "extern \"C\"" +const keywordTemplate = "template" +const keywordStatic = "static" +const keywordExternC = "extern \"C\"" -var KNOWN_TAG_KINDS = map[string]bool{ +var knownTagKinds = map[string]bool{ "prototype": true, "function": true, } -type CTagsParser struct { - tags []*CTag +// Parser is a parser for ctags output +type Parser struct { + tags []*Tag mainFile *paths.Path } -type CTag struct { +// Tag is a tag generated by ctags +type Tag struct { FunctionName string Kind string Line int @@ -58,7 +60,8 @@ type CTag struct { PrototypeModifiers string } -func (p *CTagsParser) Parse(ctagsOutput []byte, mainFile *paths.Path) ([]*Prototype, int) { +// Parse a ctags output and generates Prototypes +func (p *Parser) Parse(ctagsOutput []byte, mainFile *paths.Path) ([]*Prototype, int) { rows := strings.Split(string(ctagsOutput), "\n") rows = removeEmpty(rows) @@ -79,7 +82,7 @@ func (p *CTagsParser) Parse(ctagsOutput []byte, mainFile *paths.Path) ([]*Protot return p.toPrototypes(), p.findLineWhereToInsertPrototypes() } -func (p *CTagsParser) addPrototypes() { +func (p *Parser) addPrototypes() { for _, tag := range p.tags { if !tag.SkipMe { addPrototype(tag) @@ -87,9 +90,9 @@ func (p *CTagsParser) addPrototypes() { } } -func addPrototype(tag *CTag) { - if strings.Index(tag.Prototype, TEMPLATE) == 0 { - if strings.Index(tag.Code, TEMPLATE) == 0 { +func addPrototype(tag *Tag) { + if strings.Index(tag.Prototype, keywordTemplate) == 0 { + if strings.Index(tag.Code, keywordTemplate) == 0 { code := tag.Code if strings.Contains(code, "{") { code = code[:strings.Index(code, "{")] @@ -106,8 +109,8 @@ func addPrototype(tag *CTag) { } tag.PrototypeModifiers = "" - if strings.Contains(tag.Code, STATIC+" ") { - tag.PrototypeModifiers = tag.PrototypeModifiers + " " + STATIC + if strings.Contains(tag.Code, keywordStatic+" ") { + tag.PrototypeModifiers = tag.PrototypeModifiers + " " + keywordStatic } // Extern "C" modifier is now added in FixCLinkageTagsDeclarations @@ -115,10 +118,10 @@ func addPrototype(tag *CTag) { tag.PrototypeModifiers = strings.TrimSpace(tag.PrototypeModifiers) } -func (p *CTagsParser) removeDefinedProtypes() { +func (p *Parser) removeDefinedProtypes() { definedPrototypes := make(map[string]bool) for _, tag := range p.tags { - if tag.Kind == KIND_PROTOTYPE { + if tag.Kind == kindPrototype { definedPrototypes[tag.Prototype] = true } } @@ -133,7 +136,7 @@ func (p *CTagsParser) removeDefinedProtypes() { } } -func (p *CTagsParser) skipDuplicates() { +func (p *Parser) skipDuplicates() { definedPrototypes := make(map[string]bool) for _, tag := range p.tags { @@ -145,9 +148,9 @@ func (p *CTagsParser) skipDuplicates() { } } -type skipFuncType func(tag *CTag) bool +type skipFuncType func(tag *Tag) bool -func (p *CTagsParser) skipTagsWhere(skipFunc skipFuncType) { +func (p *Parser) skipTagsWhere(skipFunc skipFuncType) { for _, tag := range p.tags { if !tag.SkipMe { skip := skipFunc(tag) @@ -169,11 +172,11 @@ func removeSpacesAndTabs(s string) string { return s } -func tagIsUnhandled(tag *CTag) bool { +func tagIsUnhandled(tag *Tag) bool { return !isHandled(tag) } -func isHandled(tag *CTag) bool { +func isHandled(tag *Tag) bool { if tag.Class != "" { return false } @@ -186,12 +189,12 @@ func isHandled(tag *CTag) bool { return true } -func tagIsUnknown(tag *CTag) bool { - return !KNOWN_TAG_KINDS[tag.Kind] +func tagIsUnknown(tag *Tag) bool { + return !knownTagKinds[tag.Kind] } -func parseTag(row string) *CTag { - tag := &CTag{} +func parseTag(row string) *Tag { + tag := &Tag{} parts := strings.Split(row, "\t") tag.FunctionName = parts[0] diff --git a/legacy/builder/ctags/ctags_parser_test.go b/arduino/builder/preprocessor/internal/ctags/ctags_parser_test.go similarity index 98% rename from legacy/builder/ctags/ctags_parser_test.go rename to arduino/builder/preprocessor/internal/ctags/ctags_parser_test.go index 97d5c85a4c9..7fc390cec67 100644 --- a/legacy/builder/ctags/ctags_parser_test.go +++ b/arduino/builder/preprocessor/internal/ctags/ctags_parser_test.go @@ -24,11 +24,11 @@ import ( "github.com/stretchr/testify/require" ) -func produceTags(t *testing.T, filename string) []*CTag { - bytes, err := os.ReadFile(filepath.Join("test_data", filename)) +func produceTags(t *testing.T, filename string) []*Tag { + bytes, err := os.ReadFile(filepath.Join("testdata", filename)) require.NoError(t, err) - parser := CTagsParser{} + parser := Parser{} parser.Parse(bytes, paths.New("sketch.ino")) return parser.tags } diff --git a/legacy/builder/ctags/ctags_to_prototypes.go b/arduino/builder/preprocessor/internal/ctags/ctags_to_prototypes.go similarity index 80% rename from legacy/builder/ctags/ctags_to_prototypes.go rename to arduino/builder/preprocessor/internal/ctags/ctags_to_prototypes.go index 71cc072a6fa..95fc384f116 100644 --- a/legacy/builder/ctags/ctags_to_prototypes.go +++ b/arduino/builder/preprocessor/internal/ctags/ctags_to_prototypes.go @@ -20,6 +20,7 @@ import ( "strings" ) +// Prototype is a C++ prototype generated from ctags output type Prototype struct { FunctionName string File string @@ -32,15 +33,14 @@ func (proto *Prototype) String() string { return proto.Modifiers + " " + proto.Prototype + " @ " + strconv.Itoa(proto.Line) } -func (p *CTagsParser) findLineWhereToInsertPrototypes() int { +func (p *Parser) findLineWhereToInsertPrototypes() int { firstFunctionLine := p.firstFunctionAtLine() firstFunctionPointerAsArgument := p.firstFunctionPointerUsedAsArgument() if firstFunctionLine != -1 && firstFunctionPointerAsArgument != -1 { if firstFunctionLine < firstFunctionPointerAsArgument { return firstFunctionLine - } else { - return firstFunctionPointerAsArgument } + return firstFunctionPointerAsArgument } else if firstFunctionLine != -1 { return firstFunctionLine } else if firstFunctionPointerAsArgument != -1 { @@ -50,7 +50,7 @@ func (p *CTagsParser) findLineWhereToInsertPrototypes() int { } } -func (p *CTagsParser) firstFunctionPointerUsedAsArgument() int { +func (p *Parser) firstFunctionPointerUsedAsArgument() int { functionTags := p.collectFunctions() for _, tag := range p.tags { if functionNameUsedAsFunctionPointerIn(tag, functionTags) { @@ -60,7 +60,7 @@ func (p *CTagsParser) firstFunctionPointerUsedAsArgument() int { return -1 } -func functionNameUsedAsFunctionPointerIn(tag *CTag, functionTags []*CTag) bool { +func functionNameUsedAsFunctionPointerIn(tag *Tag, functionTags []*Tag) bool { for _, functionTag := range functionTags { if tag.Line != functionTag.Line && strings.Contains(tag.Code, "&"+functionTag.FunctionName) { return true @@ -72,26 +72,26 @@ func functionNameUsedAsFunctionPointerIn(tag *CTag, functionTags []*CTag) bool { return false } -func (p *CTagsParser) collectFunctions() []*CTag { - functionTags := []*CTag{} +func (p *Parser) collectFunctions() []*Tag { + functionTags := []*Tag{} for _, tag := range p.tags { - if tag.Kind == KIND_FUNCTION && !tag.SkipMe { + if tag.Kind == kindFunction && !tag.SkipMe { functionTags = append(functionTags, tag) } } return functionTags } -func (p *CTagsParser) firstFunctionAtLine() int { +func (p *Parser) firstFunctionAtLine() int { for _, tag := range p.tags { - if !tagIsUnknown(tag) && isHandled(tag) && tag.Kind == KIND_FUNCTION && tag.Filename == p.mainFile.String() { + if !tagIsUnknown(tag) && isHandled(tag) && tag.Kind == kindFunction && tag.Filename == p.mainFile.String() { return tag.Line } } return -1 } -func (p *CTagsParser) toPrototypes() []*Prototype { +func (p *Parser) toPrototypes() []*Prototype { prototypes := []*Prototype{} for _, tag := range p.tags { if strings.TrimSpace(tag.Prototype) == "" { diff --git a/legacy/builder/ctags/ctags_to_prototypes_test.go b/arduino/builder/preprocessor/internal/ctags/ctags_to_prototypes_test.go similarity index 99% rename from legacy/builder/ctags/ctags_to_prototypes_test.go rename to arduino/builder/preprocessor/internal/ctags/ctags_to_prototypes_test.go index 98455c22202..bfec902d8d9 100644 --- a/legacy/builder/ctags/ctags_to_prototypes_test.go +++ b/arduino/builder/preprocessor/internal/ctags/ctags_to_prototypes_test.go @@ -25,10 +25,10 @@ import ( ) func producePrototypes(t *testing.T, filename string, mainFile string) ([]*Prototype, int) { - bytes, err := os.ReadFile(filepath.Join("test_data", filename)) + bytes, err := os.ReadFile(filepath.Join("testdata", filename)) require.NoError(t, err) - parser := &CTagsParser{} + parser := &Parser{} return parser.Parse(bytes, paths.New(mainFile)) } diff --git a/legacy/builder/ctags/test_data/TestCTagsParserClassMembersAreFilteredOut.txt b/arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserClassMembersAreFilteredOut.txt similarity index 100% rename from legacy/builder/ctags/test_data/TestCTagsParserClassMembersAreFilteredOut.txt rename to arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserClassMembersAreFilteredOut.txt diff --git a/legacy/builder/ctags/test_data/TestCTagsParserDefaultArguments.txt b/arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserDefaultArguments.txt similarity index 100% rename from legacy/builder/ctags/test_data/TestCTagsParserDefaultArguments.txt rename to arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserDefaultArguments.txt diff --git a/legacy/builder/ctags/test_data/TestCTagsParserFunctionPointer.txt b/arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserFunctionPointer.txt similarity index 100% rename from legacy/builder/ctags/test_data/TestCTagsParserFunctionPointer.txt rename to arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserFunctionPointer.txt diff --git a/legacy/builder/ctags/test_data/TestCTagsParserFunctionPointers.txt b/arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserFunctionPointers.txt similarity index 100% rename from legacy/builder/ctags/test_data/TestCTagsParserFunctionPointers.txt rename to arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserFunctionPointers.txt diff --git a/legacy/builder/ctags/test_data/TestCTagsParserFunctionPointersNoIndirect.txt b/arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserFunctionPointersNoIndirect.txt similarity index 100% rename from legacy/builder/ctags/test_data/TestCTagsParserFunctionPointersNoIndirect.txt rename to arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserFunctionPointersNoIndirect.txt diff --git a/legacy/builder/ctags/test_data/TestCTagsParserNamespace.txt b/arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserNamespace.txt similarity index 100% rename from legacy/builder/ctags/test_data/TestCTagsParserNamespace.txt rename to arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserNamespace.txt diff --git a/legacy/builder/ctags/test_data/TestCTagsParserShouldDealFunctionWithDifferentSignatures.txt b/arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserShouldDealFunctionWithDifferentSignatures.txt similarity index 100% rename from legacy/builder/ctags/test_data/TestCTagsParserShouldDealFunctionWithDifferentSignatures.txt rename to arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserShouldDealFunctionWithDifferentSignatures.txt diff --git a/legacy/builder/ctags/test_data/TestCTagsParserShouldDealWithClasses.txt b/arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserShouldDealWithClasses.txt similarity index 100% rename from legacy/builder/ctags/test_data/TestCTagsParserShouldDealWithClasses.txt rename to arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserShouldDealWithClasses.txt diff --git a/legacy/builder/ctags/test_data/TestCTagsParserShouldDealWithMacros.txt b/arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserShouldDealWithMacros.txt similarity index 100% rename from legacy/builder/ctags/test_data/TestCTagsParserShouldDealWithMacros.txt rename to arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserShouldDealWithMacros.txt diff --git a/legacy/builder/ctags/test_data/TestCTagsParserShouldDealWithStructs.txt b/arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserShouldDealWithStructs.txt similarity index 100% rename from legacy/builder/ctags/test_data/TestCTagsParserShouldDealWithStructs.txt rename to arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserShouldDealWithStructs.txt diff --git a/legacy/builder/ctags/test_data/TestCTagsParserShouldListPrototypes.txt b/arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserShouldListPrototypes.txt similarity index 100% rename from legacy/builder/ctags/test_data/TestCTagsParserShouldListPrototypes.txt rename to arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserShouldListPrototypes.txt diff --git a/legacy/builder/ctags/test_data/TestCTagsParserShouldListTemplates.txt b/arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserShouldListTemplates.txt similarity index 100% rename from legacy/builder/ctags/test_data/TestCTagsParserShouldListTemplates.txt rename to arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserShouldListTemplates.txt diff --git a/legacy/builder/ctags/test_data/TestCTagsParserShouldListTemplates2.txt b/arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserShouldListTemplates2.txt similarity index 100% rename from legacy/builder/ctags/test_data/TestCTagsParserShouldListTemplates2.txt rename to arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserShouldListTemplates2.txt diff --git a/legacy/builder/ctags/test_data/TestCTagsParserStatic.txt b/arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserStatic.txt similarity index 100% rename from legacy/builder/ctags/test_data/TestCTagsParserStatic.txt rename to arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserStatic.txt diff --git a/legacy/builder/ctags/test_data/TestCTagsParserStructWithFunctions.txt b/arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserStructWithFunctions.txt similarity index 100% rename from legacy/builder/ctags/test_data/TestCTagsParserStructWithFunctions.txt rename to arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsParserStructWithFunctions.txt diff --git a/legacy/builder/ctags/test_data/TestCTagsRunnerSketchWithClassFunction.txt b/arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsRunnerSketchWithClassFunction.txt similarity index 100% rename from legacy/builder/ctags/test_data/TestCTagsRunnerSketchWithClassFunction.txt rename to arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsRunnerSketchWithClassFunction.txt diff --git a/legacy/builder/ctags/test_data/TestCTagsRunnerSketchWithMultifile.txt b/arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsRunnerSketchWithMultifile.txt similarity index 100% rename from legacy/builder/ctags/test_data/TestCTagsRunnerSketchWithMultifile.txt rename to arduino/builder/preprocessor/internal/ctags/testdata/TestCTagsRunnerSketchWithMultifile.txt diff --git a/arduino/builder/sketch.go b/arduino/builder/sketch.go index 8560178a193..a79bbac4bef 100644 --- a/arduino/builder/sketch.go +++ b/arduino/builder/sketch.go @@ -20,6 +20,7 @@ import ( "fmt" "regexp" + "github.com/arduino/arduino-cli/arduino/builder/cpp" "github.com/arduino/arduino-cli/arduino/sketch" "github.com/arduino/arduino-cli/i18n" "github.com/arduino/go-paths-helper" @@ -36,17 +37,16 @@ var ( // PrepareSketchBuildPath copies the sketch source files in the build path. // The .ino files are merged together to create a .cpp file (by the way, the // .cpp file still needs to be Arduino-preprocessed to compile). -func PrepareSketchBuildPath(sketch *sketch.Sketch, sourceOverrides map[string]string, buildPath *paths.Path) (offset int, mergedSource string, err error) { - if offset, mergedSource, err = sketchMergeSources(sketch, sourceOverrides); err != nil { - return - } - if err = SketchSaveItemCpp(sketch.MainFile, []byte(mergedSource), buildPath); err != nil { - return - } - if err = sketchCopyAdditionalFiles(sketch, buildPath, sourceOverrides); err != nil { - return +func PrepareSketchBuildPath(sketch *sketch.Sketch, sourceOverrides map[string]string, buildPath *paths.Path) (int, error) { + if offset, mergedSource, err := sketchMergeSources(sketch, sourceOverrides); err != nil { + return 0, err + } else if err := SketchSaveItemCpp(sketch.MainFile, []byte(mergedSource), buildPath); err != nil { + return 0, err + } else if err := sketchCopyAdditionalFiles(sketch, buildPath, sourceOverrides); err != nil { + return 0, err + } else { + return offset, nil } - return } // SketchSaveItemCpp saves a preprocessed .cpp sketch file on disk @@ -96,7 +96,7 @@ func sketchMergeSources(sk *sketch.Sketch, overrides map[string]string) (int, st lineOffset++ } - mergedSource += "#line 1 " + QuoteCppString(sk.MainFile.String()) + "\n" + mergedSource += "#line 1 " + cpp.QuoteString(sk.MainFile.String()) + "\n" mergedSource += mainSrc + "\n" lineOffset++ @@ -105,7 +105,7 @@ func sketchMergeSources(sk *sketch.Sketch, overrides map[string]string) (int, st if err != nil { return 0, "", err } - mergedSource += "#line 1 " + QuoteCppString(file.String()) + "\n" + mergedSource += "#line 1 " + cpp.QuoteString(file.String()) + "\n" mergedSource += src + "\n" } @@ -145,7 +145,7 @@ func sketchCopyAdditionalFiles(sketch *sketch.Sketch, destPath *paths.Path, over } // tag each addtional file with the filename of the source it was copied from - sourceBytes = append([]byte("#line 1 "+QuoteCppString(file.String())+"\n"), sourceBytes...) + sourceBytes = append([]byte("#line 1 "+cpp.QuoteString(file.String())+"\n"), sourceBytes...) err = writeIfDifferent(sourceBytes, targetPath) if err != nil { diff --git a/internal/integrationtest/compile_1/compile_test.go b/internal/integrationtest/compile_1/compile_test.go index dcfb8736f19..60c6552a678 100644 --- a/internal/integrationtest/compile_1/compile_test.go +++ b/internal/integrationtest/compile_1/compile_test.go @@ -25,7 +25,7 @@ import ( "testing" "time" - "github.com/arduino/arduino-cli/arduino/builder" + "github.com/arduino/arduino-cli/arduino/builder/cpp" "github.com/arduino/arduino-cli/internal/integrationtest" "github.com/arduino/go-paths-helper" "github.com/stretchr/testify/require" @@ -1060,7 +1060,6 @@ func compileWithRelativeBuildPath(t *testing.T, env *integrationtest.Environment "core", "includes.cache", "libraries", - "preproc", "sketch", } @@ -1191,7 +1190,7 @@ void loop() { } ` - expected = strings.ReplaceAll(expected, "%SKETCH_PATH%", builder.QuoteCppString(sketchPath.Join("SketchSimple.ino").String())) + expected = strings.ReplaceAll(expected, "%SKETCH_PATH%", cpp.QuoteString(sketchPath.Join("SketchSimple.ino").String())) jsonOut, _, err := cli.Run("compile", "-b", fqbn, "--preprocess", sketchPath.String(), "--format", "json") require.NoError(t, err) diff --git a/legacy/builder/add_additional_entries_to_context.go b/legacy/builder/add_additional_entries_to_context.go index fcb9639e37c..9e9fdd80669 100644 --- a/legacy/builder/add_additional_entries_to_context.go +++ b/legacy/builder/add_additional_entries_to_context.go @@ -26,10 +26,6 @@ type AddAdditionalEntriesToContext struct{} func (*AddAdditionalEntriesToContext) Run(ctx *types.Context) error { if ctx.BuildPath != nil { buildPath := ctx.BuildPath - preprocPath, err := buildPath.Join(constants.FOLDER_PREPROC).Abs() - if err != nil { - return errors.WithStack(err) - } sketchBuildPath, err := buildPath.Join(constants.FOLDER_SKETCH).Abs() if err != nil { return errors.WithStack(err) @@ -43,7 +39,6 @@ func (*AddAdditionalEntriesToContext) Run(ctx *types.Context) error { return errors.WithStack(err) } - ctx.PreprocPath = preprocPath ctx.SketchBuildPath = sketchBuildPath ctx.LibrariesBuildPath = librariesBuildPath ctx.CoreBuildPath = coreBuildPath diff --git a/legacy/builder/builder.go b/legacy/builder/builder.go index b1b1f007c5d..fe11d684faa 100644 --- a/legacy/builder/builder.go +++ b/legacy/builder/builder.go @@ -20,6 +20,7 @@ import ( "time" "github.com/arduino/arduino-cli/arduino/builder" + "github.com/arduino/arduino-cli/arduino/builder/preprocessor" "github.com/arduino/arduino-cli/i18n" "github.com/arduino/arduino-cli/legacy/builder/phases" "github.com/arduino/arduino-cli/legacy/builder/types" @@ -49,7 +50,7 @@ func (s *Builder) Run(ctx *types.Context) error { &RecipeByPrefixSuffixRunner{Prefix: "recipe.hooks.prebuild", Suffix: ".pattern"}, types.BareCommand(func(ctx *types.Context) error { - ctx.LineOffset, ctx.SketchSourceMerged, _err = builder.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) + ctx.LineOffset, _err = builder.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), @@ -59,7 +60,7 @@ func (s *Builder) Run(ctx *types.Context) error { &WarnAboutArchIncompatibleLibraries{}, utils.LogIfVerbose(false, tr("Generating function prototypes...")), - &PreprocessSketch{}, + types.BareCommand(PreprocessSketch), utils.LogIfVerbose(false, tr("Compiling sketch...")), &RecipeByPrefixSuffixRunner{Prefix: "recipe.hooks.sketch.prebuild", Suffix: ".pattern"}, @@ -115,13 +116,19 @@ func (s *Builder) Run(ctx *types.Context) error { return otherErr } -type PreprocessSketch struct{} - -func (s *PreprocessSketch) Run(ctx *types.Context) error { +func PreprocessSketch(ctx *types.Context) error { if ctx.UseArduinoPreprocessor { return PreprocessSketchWithArduinoPreprocessor(ctx) } else { - return PreprocessSketchWithCtags(ctx) + normalOutput, verboseOutput, err := preprocessor.PreprocessSketchWithCtags( + ctx.Sketch, ctx.BuildPath, ctx.IncludeFolders, ctx.LineOffset, + ctx.BuildProperties, ctx.OnlyUpdateCompilationDatabase) + if ctx.Verbose { + ctx.WriteStdout(verboseOutput) + } else { + ctx.WriteStdout(normalOutput) + } + return err } } @@ -141,7 +148,7 @@ func (s *Preprocess) Run(ctx *types.Context) error { &RecipeByPrefixSuffixRunner{Prefix: "recipe.hooks.prebuild", Suffix: ".pattern"}, types.BareCommand(func(ctx *types.Context) error { - ctx.LineOffset, ctx.SketchSourceMerged, _err = builder.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) + ctx.LineOffset, _err = builder.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), @@ -149,7 +156,7 @@ func (s *Preprocess) Run(ctx *types.Context) error { &WarnAboutArchIncompatibleLibraries{}, - &PreprocessSketch{}, + types.BareCommand(PreprocessSketch), } if err := runCommands(ctx, commands); err != nil { @@ -157,7 +164,11 @@ func (s *Preprocess) Run(ctx *types.Context) error { } // Output arduino-preprocessed source - ctx.WriteStdout([]byte(ctx.SketchSourceAfterArduinoPreprocessing)) + preprocessedSketch, err := ctx.SketchBuildPath.Join(ctx.Sketch.MainFile.Base() + ".cpp").ReadFile() + if err != nil { + return err + } + ctx.WriteStdout(preprocessedSketch) return nil } diff --git a/legacy/builder/constants/constants.go b/legacy/builder/constants/constants.go index 36d11764ebc..a91f454ffcf 100644 --- a/legacy/builder/constants/constants.go +++ b/legacy/builder/constants/constants.go @@ -34,7 +34,6 @@ const BUILD_PROPERTIES_RUNTIME_PLATFORM_PATH = "runtime.platform.path" const EMPTY_STRING = "" const FOLDER_BOOTLOADERS = "bootloaders" const FOLDER_CORE = "core" -const FOLDER_PREPROC = "preproc" const FOLDER_SKETCH = "sketch" const FOLDER_TOOLS = "tools" const FOLDER_LIBRARIES = "libraries" diff --git a/legacy/builder/container_add_prototypes.go b/legacy/builder/container_add_prototypes.go deleted file mode 100644 index 288bb03e1f4..00000000000 --- a/legacy/builder/container_add_prototypes.go +++ /dev/null @@ -1,144 +0,0 @@ -// This file is part of arduino-cli. -// -// Copyright 2020 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. -// The terms of this license can be found at: -// https://www.gnu.org/licenses/gpl-3.0.en.html -// -// You can be released from the requirements of the above licenses by purchasing -// a commercial license. Buying such a license is mandatory if you want to -// modify or otherwise use the software for commercial activities involving the -// 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 - -import ( - "bufio" - "bytes" - "fmt" - "io" - "strconv" - "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" - "github.com/pkg/errors" -) - -func PreprocessSketchWithCtags(ctx *types.Context) error { - // Generate the full pathname for the preproc output file - if err := ctx.PreprocPath.MkdirAll(); err != nil { - return errors.WithStack(err) - } - targetFilePath := ctx.PreprocPath.Join("sketch_merged.cpp") - - // Run preprocessor - sourceFile := ctx.SketchBuildPath.Join(ctx.Sketch.MainFile.Base() + ".cpp") - gccStdout, gccStderr, err := preprocessor.GCC(sourceFile, targetFilePath, ctx.IncludeFolders, ctx.BuildProperties) - if ctx.Verbose { - ctx.WriteStdout(gccStdout) - ctx.WriteStderr(gccStderr) - } - if err != nil { - if !ctx.OnlyUpdateCompilationDatabase { - return errors.WithStack(err) - } - - // Do not bail out if we are generating the compile commands database - ctx.Info( - fmt.Sprintf("%s: %s", - tr("An error occurred adding prototypes"), - tr("the compilation database may be incomplete or inaccurate"))) - if err := sourceFile.CopyTo(targetFilePath); err != nil { - return errors.WithStack(err) - } - } - - if src, err := targetFilePath.ReadFile(); err != nil { - return err - } else { - ctx.SketchSourceAfterCppPreprocessing = filterSketchSource(ctx.Sketch, bytes.NewReader(src), false) - } - - if err := targetFilePath.WriteFile([]byte(ctx.SketchSourceAfterCppPreprocessing)); err != nil { - return err - } - - ctagsStdout, ctagsStderr, err := preprocessor.RunCTags(targetFilePath, ctx.BuildProperties) - if ctx.Verbose { - ctx.WriteStderr(ctagsStderr) - } - if err != nil { - return err - } - 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) - } - - return nil -} - -func filterSketchSource(sketch *sketch.Sketch, source io.Reader, removeLineMarkers bool) string { - fileNames := paths.NewPathList() - fileNames.Add(sketch.MainFile) - fileNames.AddAll(sketch.OtherSketchFiles) - - inSketch := false - filtered := "" - - scanner := bufio.NewScanner(source) - for scanner.Scan() { - line := scanner.Text() - if filename := parseLineMarker(line); filename != nil { - inSketch = fileNames.Contains(filename) - if inSketch && removeLineMarkers { - continue - } - } - - if inSketch { - filtered += line + "\n" - } - } - - return filtered -} - -// Parses the given line as a gcc line marker and returns the contained -// filename. -func parseLineMarker(line string) *paths.Path { - // A line marker contains the line number and filename and looks like: - // # 123 /path/to/file.cpp - // It can be followed by zero or more flag number that indicate the - // preprocessor state and can be ignored. - // For exact details on this format, see: - // https://github.com/gcc-mirror/gcc/blob/edd716b6b1caa1a5cb320a8cd7f626f30198e098/gcc/c-family/c-ppoutput.c#L413-L415 - - split := strings.SplitN(line, " ", 3) - if len(split) < 3 || len(split[0]) == 0 || split[0][0] != '#' { - return nil - } - - _, err := strconv.Atoi(split[1]) - if err != nil { - return nil - } - - // If we get here, we found a # followed by a line number, so - // assume this is a line marker and see if the rest of the line - // starts with a string containing the filename - str, rest, ok := bldr.ParseCppString(split[2]) - - if ok && (rest == "" || rest[0] == ' ') { - return paths.New(str) - } - return nil -} diff --git a/legacy/builder/create_cmake_rule.go b/legacy/builder/create_cmake_rule.go index 394b80ec49f..9cc38434286 100644 --- a/legacy/builder/create_cmake_rule.go +++ b/legacy/builder/create_cmake_rule.go @@ -115,7 +115,7 @@ func (s *ExportProjectCMake) Run(ctx *types.Context) error { fmt.Println(err) } - if err := PreprocessSketchWithCtags(ctx); err != nil { + if err := PreprocessSketch(ctx); err != nil { return err } diff --git a/legacy/builder/preprocess_sketch.go b/legacy/builder/preprocess_sketch.go index 7f8aaccec38..7dff77c7dde 100644 --- a/legacy/builder/preprocess_sketch.go +++ b/legacy/builder/preprocess_sketch.go @@ -31,12 +31,12 @@ import ( ) func PreprocessSketchWithArduinoPreprocessor(ctx *types.Context) error { - if err := ctx.PreprocPath.MkdirAll(); err != nil { + if err := ctx.BuildPath.Join("preproc").MkdirAll(); err != nil { return errors.WithStack(err) } sourceFile := ctx.SketchBuildPath.Join(ctx.Sketch.MainFile.Base() + ".cpp") - targetFile := ctx.PreprocPath.Join("sketch_merged.cpp") + targetFile := ctx.BuildPath.Join("preproc", "sketch_merged.cpp") gccStdout, gccStderr, err := preprocessor.GCC(sourceFile, targetFile, ctx.IncludeFolders, ctx.BuildProperties) if ctx.Verbose { ctx.WriteStdout(gccStdout) @@ -85,8 +85,5 @@ func PreprocessSketchWithArduinoPreprocessor(ctx *types.Context) error { } result := utils.NormalizeUTF8(buf) - - //fmt.Printf("PREPROCESSOR OUTPUT:\n%s\n", output) - ctx.SketchSourceAfterArduinoPreprocessing = string(result) - return bldr.SketchSaveItemCpp(ctx.Sketch.MainFile, []byte(ctx.SketchSourceAfterArduinoPreprocessing), ctx.SketchBuildPath) + return bldr.SketchSaveItemCpp(ctx.Sketch.MainFile, result, ctx.SketchBuildPath) } diff --git a/legacy/builder/prototypes_adder.go b/legacy/builder/prototypes_adder.go deleted file mode 100644 index e62a8486fa8..00000000000 --- a/legacy/builder/prototypes_adder.go +++ /dev/null @@ -1,105 +0,0 @@ -// This file is part of arduino-cli. -// -// Copyright 2020 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. -// The terms of this license can be found at: -// https://www.gnu.org/licenses/gpl-3.0.en.html -// -// You can be released from the requirements of the above licenses by purchasing -// a commercial license. Buying such a license is mandatory if you want to -// modify or otherwise use the software for commercial activities involving the -// 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 - -import ( - "fmt" - "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" -) - -var DebugPreprocessor bool - -func PrototypesAdder(sketch *sketch.Sketch, source string, ctagsStdout []byte, lineOffset int) string { - parser := &ctags.CTagsParser{} - prototypes, firstFunctionLine := parser.Parse(ctagsStdout, sketch.MainFile) - 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 "" - } - - insertionLine := firstFunctionLine + lineOffset - 1 - firstFunctionChar := len(strings.Join(sourceRows[:insertionLine], "\n")) + 1 - prototypeSection := composePrototypeSection(firstFunctionLine, prototypes) - preprocessedSource := source[:firstFunctionChar] + prototypeSection + source[firstFunctionChar:] - - if DebugPreprocessor { - fmt.Println("#PREPROCESSED SOURCE") - prototypesRows := strings.Split(prototypeSection, "\n") - prototypesRows = prototypesRows[:len(prototypesRows)-1] - for i := 0; i < len(sourceRows)+len(prototypesRows); i++ { - if i < insertionLine { - fmt.Printf(" |%s\n", sourceRows[i]) - } else if i < insertionLine+len(prototypesRows) { - fmt.Printf("PRO|%s\n", prototypesRows[i-insertionLine]) - } else { - fmt.Printf(" |%s\n", sourceRows[i-len(prototypesRows)]) - } - } - fmt.Println("#END OF PREPROCESSED SOURCE") - } - return preprocessedSource -} - -func composePrototypeSection(line int, prototypes []*ctags.Prototype) string { - if len(prototypes) == 0 { - return constants.EMPTY_STRING - } - - str := joinPrototypes(prototypes) - str += "\n#line " - str += strconv.Itoa(line) - str += " " + utils.QuoteCppString(prototypes[0].File) - str += "\n" - - return str -} - -func joinPrototypes(prototypes []*ctags.Prototype) string { - prototypesSlice := []string{} - for _, proto := range prototypes { - if signatureContainsaDefaultArg(proto) { - continue - } - prototypesSlice = append(prototypesSlice, "#line "+strconv.Itoa(proto.Line)+" "+utils.QuoteCppString(proto.File)) - prototypeParts := []string{} - if proto.Modifiers != "" { - prototypeParts = append(prototypeParts, proto.Modifiers) - } - prototypeParts = append(prototypeParts, proto.Prototype) - prototypesSlice = append(prototypesSlice, strings.Join(prototypeParts, " ")) - } - return strings.Join(prototypesSlice, "\n") -} - -func signatureContainsaDefaultArg(proto *ctags.Prototype) bool { - return strings.Contains(proto.Prototype, "=") -} - -func isFirstFunctionOutsideOfSource(firstFunctionLine int, sourceRows []string) bool { - return firstFunctionLine > len(sourceRows)-1 -} diff --git a/legacy/builder/test/add_additional_entries_to_context_test.go b/legacy/builder/test/add_additional_entries_to_context_test.go index 51e5452daf3..fc1edb5acb2 100644 --- a/legacy/builder/test/add_additional_entries_to_context_test.go +++ b/legacy/builder/test/add_additional_entries_to_context_test.go @@ -31,7 +31,6 @@ func TestAddAdditionalEntriesToContextNoBuildPath(t *testing.T) { command := builder.AddAdditionalEntriesToContext{} NoError(t, command.Run(ctx)) - require.Empty(t, ctx.PreprocPath) require.Empty(t, ctx.SketchBuildPath) require.Empty(t, ctx.LibrariesBuildPath) require.Empty(t, ctx.CoreBuildPath) @@ -48,7 +47,6 @@ func TestAddAdditionalEntriesToContextWithBuildPath(t *testing.T) { command := builder.AddAdditionalEntriesToContext{} NoError(t, command.Run(ctx)) - require.Equal(t, Abs(t, paths.New("folder", constants.FOLDER_PREPROC)), ctx.PreprocPath) require.Equal(t, Abs(t, paths.New("folder", constants.FOLDER_SKETCH)), ctx.SketchBuildPath) require.Equal(t, Abs(t, paths.New("folder", "libraries")), ctx.LibrariesBuildPath) require.Equal(t, Abs(t, paths.New("folder", constants.FOLDER_CORE)), ctx.CoreBuildPath) diff --git a/legacy/builder/test/builder_test.go b/legacy/builder/test/builder_test.go index e84e2d402dd..3d5740d659d 100644 --- a/legacy/builder/test/builder_test.go +++ b/legacy/builder/test/builder_test.go @@ -116,9 +116,6 @@ func TestBuilderEmptySketch(t *testing.T) { exist, err := buildPath.Join(constants.FOLDER_CORE, "HardwareSerial.cpp.o").ExistCheck() NoError(t, err) require.True(t, exist) - exist, err = buildPath.Join(constants.FOLDER_PREPROC, "sketch_merged.cpp").ExistCheck() - NoError(t, err) - require.True(t, exist) exist, err = buildPath.Join(constants.FOLDER_SKETCH, "sketch1.ino.cpp.o").ExistCheck() NoError(t, err) require.True(t, exist) @@ -143,9 +140,6 @@ func TestBuilderBridge(t *testing.T) { exist, err := buildPath.Join(constants.FOLDER_CORE, "HardwareSerial.cpp.o").ExistCheck() NoError(t, err) require.True(t, exist) - exist, err = buildPath.Join(constants.FOLDER_PREPROC, "sketch_merged.cpp").ExistCheck() - NoError(t, err) - require.True(t, exist) exist, err = buildPath.Join(constants.FOLDER_SKETCH, "Bridge.ino.cpp.o").ExistCheck() NoError(t, err) require.True(t, exist) @@ -173,9 +167,6 @@ func TestBuilderSketchWithConfig(t *testing.T) { exist, err := buildPath.Join(constants.FOLDER_CORE, "HardwareSerial.cpp.o").ExistCheck() NoError(t, err) require.True(t, exist) - exist, err = buildPath.Join(constants.FOLDER_PREPROC, "sketch_merged.cpp").ExistCheck() - NoError(t, err) - require.True(t, exist) exist, err = buildPath.Join(constants.FOLDER_SKETCH, "sketch_with_config.ino.cpp.o").ExistCheck() NoError(t, err) require.True(t, exist) @@ -208,9 +199,6 @@ func TestBuilderBridgeTwice(t *testing.T) { exist, err := buildPath.Join(constants.FOLDER_CORE, "HardwareSerial.cpp.o").ExistCheck() NoError(t, err) require.True(t, exist) - exist, err = buildPath.Join(constants.FOLDER_PREPROC, "sketch_merged.cpp").ExistCheck() - NoError(t, err) - require.True(t, exist) exist, err = buildPath.Join(constants.FOLDER_SKETCH, "Bridge.ino.cpp.o").ExistCheck() NoError(t, err) require.True(t, exist) @@ -245,9 +233,6 @@ func TestBuilderBridgeSAM(t *testing.T) { exist, err = buildPath.Join(constants.FOLDER_CORE, "avr", "dtostrf.c.d").ExistCheck() NoError(t, err) require.True(t, exist) - exist, err = buildPath.Join(constants.FOLDER_PREPROC, "sketch_merged.cpp").ExistCheck() - NoError(t, err) - require.True(t, exist) exist, err = buildPath.Join(constants.FOLDER_SKETCH, "Bridge.ino.cpp.o").ExistCheck() NoError(t, err) require.True(t, exist) @@ -286,9 +271,6 @@ func TestBuilderBridgeRedBearLab(t *testing.T) { exist, err := buildPath.Join(constants.FOLDER_CORE, "HardwareSerial.cpp.o").ExistCheck() NoError(t, err) require.True(t, exist) - exist, err = buildPath.Join(constants.FOLDER_PREPROC, "sketch_merged.cpp").ExistCheck() - NoError(t, err) - require.True(t, exist) exist, err = buildPath.Join(constants.FOLDER_SKETCH, "Bridge.ino.cpp.o").ExistCheck() NoError(t, err) require.True(t, exist) diff --git a/legacy/builder/test/ctags_runner_test.go b/legacy/builder/test/ctags_runner_test.go index d776a93c4bc..557aa34f57d 100644 --- a/legacy/builder/test/ctags_runner_test.go +++ b/legacy/builder/test/ctags_runner_test.go @@ -34,9 +34,10 @@ func ctagsRunnerTestTemplate(t *testing.T, sketchLocation *paths.Path) []byte { err := (&builder.ContainerSetupHardwareToolsLibsSketchAndProps{}).Run(ctx) NoError(t, err) - _, source, err := bldr.PrepareSketchBuildPath(ctx.Sketch, nil, ctx.SketchBuildPath) + _, err = bldr.PrepareSketchBuildPath(ctx.Sketch, nil, ctx.SketchBuildPath) NoError(t, err) + source := loadPreprocessedSketch(t, ctx) target := ctx.BuildPath.Join("ctags_target.cpp") NoError(t, target.WriteFile([]byte(source))) diff --git a/legacy/builder/test/helper.go b/legacy/builder/test/helper.go index 4581dd7c921..88432e5fc76 100644 --- a/legacy/builder/test/helper.go +++ b/legacy/builder/test/helper.go @@ -23,11 +23,11 @@ import ( "testing" "text/template" + "github.com/arduino/arduino-cli/arduino/builder/cpp" "github.com/arduino/arduino-cli/arduino/cores" "github.com/arduino/arduino-cli/arduino/libraries" "github.com/arduino/arduino-cli/legacy/builder/constants" "github.com/arduino/arduino-cli/legacy/builder/types" - "github.com/arduino/arduino-cli/legacy/builder/utils" paths "github.com/arduino/go-paths-helper" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -35,7 +35,7 @@ import ( func LoadAndInterpolate(t *testing.T, filename string, ctx *types.Context) string { funcsMap := template.FuncMap{ - "QuoteCppString": utils.QuoteCppPath, + "QuoteCppString": func(p *paths.Path) string { return cpp.QuoteString(p.String()) }, } tpl, err := template.New(filepath.Base(filename)).Funcs(funcsMap).ParseFiles(filename) diff --git a/legacy/builder/test/includes_to_include_folders_test.go b/legacy/builder/test/includes_to_include_folders_test.go index a19d0ad57f2..f457e518185 100644 --- a/legacy/builder/test/includes_to_include_folders_test.go +++ b/legacy/builder/test/includes_to_include_folders_test.go @@ -36,7 +36,7 @@ func TestIncludesToIncludeFolders(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -60,7 +60,7 @@ func TestIncludesToIncludeFoldersSketchWithIfDef(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -83,7 +83,7 @@ func TestIncludesToIncludeFoldersIRremoteLibrary(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -109,7 +109,7 @@ func TestIncludesToIncludeFoldersANewLibrary(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -140,7 +140,7 @@ func TestIncludesToIncludeFoldersDuplicateLibs(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -172,7 +172,7 @@ func TestIncludesToIncludeFoldersDuplicateLibsWithConflictingLibsOutsideOfPlatfo 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -204,7 +204,7 @@ func TestIncludesToIncludeFoldersDuplicateLibs2(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -230,7 +230,7 @@ func TestIncludesToIncludeFoldersSubfolders(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, diff --git a/legacy/builder/test/prototypes_adder_test.go b/legacy/builder/test/prototypes_adder_test.go index 64630a7ba70..024d86cf265 100644 --- a/legacy/builder/test/prototypes_adder_test.go +++ b/legacy/builder/test/prototypes_adder_test.go @@ -22,16 +22,22 @@ import ( "testing" bldr "github.com/arduino/arduino-cli/arduino/builder" + "github.com/arduino/arduino-cli/arduino/builder/cpp" "github.com/arduino/arduino-cli/legacy/builder" "github.com/arduino/arduino-cli/legacy/builder/types" - "github.com/arduino/arduino-cli/legacy/builder/utils" paths "github.com/arduino/go-paths-helper" "github.com/stretchr/testify/require" ) +func loadPreprocessedSketch(t *testing.T, ctx *types.Context) string { + res, err := ctx.SketchBuildPath.Join(ctx.Sketch.MainFile.Base() + ".cpp").ReadFile() + NoError(t, err) + return string(res) +} + func TestPrototypesAdderBridgeExample(t *testing.T) { sketchLocation := paths.New("downloaded_libraries", "Bridge", "examples", "Bridge", "Bridge.ino") - quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation)) + quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String()) ctx := prepareBuilderTestContext(t, nil, sketchLocation, "arduino:avr:leonardo") defer cleanUpBuilderTestContext(t, ctx) @@ -42,7 +48,7 @@ func TestPrototypesAdderBridgeExample(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -51,10 +57,11 @@ func TestPrototypesAdderBridgeExample(t *testing.T) { err := command.Run(ctx) NoError(t, err) } - NoError(t, builder.PreprocessSketchWithCtags(ctx)) + NoError(t, builder.PreprocessSketch(ctx)) - require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") - 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") + preprocessedSketch := loadPreprocessedSketch(t, ctx) + require.Contains(t, preprocessedSketch, "#include \n#line 1 "+quotedSketchLocation+"\n") + require.Contains(t, preprocessedSketch, "#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) { @@ -67,7 +74,7 @@ func TestPrototypesAdderSketchWithIfDef(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -76,10 +83,11 @@ func TestPrototypesAdderSketchWithIfDef(t *testing.T) { err := command.Run(ctx) NoError(t, err) } - NoError(t, builder.PreprocessSketchWithCtags(ctx)) + NoError(t, builder.PreprocessSketch(ctx)) preprocessed := LoadAndInterpolate(t, filepath.Join("SketchWithIfDef", "SketchWithIfDef.preprocessed.txt"), ctx) - require.Equal(t, preprocessed, strings.Replace(ctx.SketchSourceAfterArduinoPreprocessing, "\r\n", "\n", -1)) + preprocessedSketch := loadPreprocessedSketch(t, ctx) + require.Equal(t, preprocessed, strings.Replace(preprocessedSketch, "\r\n", "\n", -1)) } func TestPrototypesAdderBaladuino(t *testing.T) { @@ -92,7 +100,7 @@ func TestPrototypesAdderBaladuino(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -101,10 +109,11 @@ func TestPrototypesAdderBaladuino(t *testing.T) { err := command.Run(ctx) NoError(t, err) } - NoError(t, builder.PreprocessSketchWithCtags(ctx)) + NoError(t, builder.PreprocessSketch(ctx)) preprocessed := LoadAndInterpolate(t, filepath.Join("Baladuino", "Baladuino.preprocessed.txt"), ctx) - require.Equal(t, preprocessed, strings.Replace(ctx.SketchSourceAfterArduinoPreprocessing, "\r\n", "\n", -1)) + preprocessedSketch := loadPreprocessedSketch(t, ctx) + require.Equal(t, preprocessed, strings.Replace(preprocessedSketch, "\r\n", "\n", -1)) } func TestPrototypesAdderCharWithEscapedDoubleQuote(t *testing.T) { @@ -117,7 +126,7 @@ func TestPrototypesAdderCharWithEscapedDoubleQuote(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -126,10 +135,11 @@ func TestPrototypesAdderCharWithEscapedDoubleQuote(t *testing.T) { err := command.Run(ctx) NoError(t, err) } - NoError(t, builder.PreprocessSketchWithCtags(ctx)) + NoError(t, builder.PreprocessSketch(ctx)) preprocessed := LoadAndInterpolate(t, filepath.Join("CharWithEscapedDoubleQuote", "CharWithEscapedDoubleQuote.preprocessed.txt"), ctx) - require.Equal(t, preprocessed, strings.Replace(ctx.SketchSourceAfterArduinoPreprocessing, "\r\n", "\n", -1)) + preprocessedSketch := loadPreprocessedSketch(t, ctx) + require.Equal(t, preprocessed, strings.Replace(preprocessedSketch, "\r\n", "\n", -1)) } func TestPrototypesAdderIncludeBetweenMultilineComment(t *testing.T) { @@ -142,7 +152,7 @@ func TestPrototypesAdderIncludeBetweenMultilineComment(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -151,10 +161,11 @@ func TestPrototypesAdderIncludeBetweenMultilineComment(t *testing.T) { err := command.Run(ctx) NoError(t, err) } - NoError(t, builder.PreprocessSketchWithCtags(ctx)) + NoError(t, builder.PreprocessSketch(ctx)) preprocessed := LoadAndInterpolate(t, filepath.Join("IncludeBetweenMultilineComment", "IncludeBetweenMultilineComment.preprocessed.txt"), ctx) - require.Equal(t, preprocessed, strings.Replace(ctx.SketchSourceAfterArduinoPreprocessing, "\r\n", "\n", -1)) + preprocessedSketch := loadPreprocessedSketch(t, ctx) + require.Equal(t, preprocessed, strings.Replace(preprocessedSketch, "\r\n", "\n", -1)) } func TestPrototypesAdderLineContinuations(t *testing.T) { @@ -167,7 +178,7 @@ func TestPrototypesAdderLineContinuations(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -176,10 +187,11 @@ func TestPrototypesAdderLineContinuations(t *testing.T) { err := command.Run(ctx) NoError(t, err) } - NoError(t, builder.PreprocessSketchWithCtags(ctx)) + NoError(t, builder.PreprocessSketch(ctx)) preprocessed := LoadAndInterpolate(t, filepath.Join("LineContinuations", "LineContinuations.preprocessed.txt"), ctx) - require.Equal(t, preprocessed, strings.Replace(ctx.SketchSourceAfterArduinoPreprocessing, "\r\n", "\n", -1)) + preprocessedSketch := loadPreprocessedSketch(t, ctx) + require.Equal(t, preprocessed, strings.Replace(preprocessedSketch, "\r\n", "\n", -1)) } func TestPrototypesAdderStringWithComment(t *testing.T) { @@ -192,7 +204,7 @@ func TestPrototypesAdderStringWithComment(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -201,10 +213,11 @@ func TestPrototypesAdderStringWithComment(t *testing.T) { err := command.Run(ctx) NoError(t, err) } - NoError(t, builder.PreprocessSketchWithCtags(ctx)) + NoError(t, builder.PreprocessSketch(ctx)) preprocessed := LoadAndInterpolate(t, filepath.Join("StringWithComment", "StringWithComment.preprocessed.txt"), ctx) - require.Equal(t, preprocessed, strings.Replace(ctx.SketchSourceAfterArduinoPreprocessing, "\r\n", "\n", -1)) + preprocessedSketch := loadPreprocessedSketch(t, ctx) + require.Equal(t, preprocessed, strings.Replace(preprocessedSketch, "\r\n", "\n", -1)) } func TestPrototypesAdderSketchWithStruct(t *testing.T) { @@ -217,7 +230,7 @@ func TestPrototypesAdderSketchWithStruct(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -226,10 +239,11 @@ func TestPrototypesAdderSketchWithStruct(t *testing.T) { err := command.Run(ctx) NoError(t, err) } - NoError(t, builder.PreprocessSketchWithCtags(ctx)) + NoError(t, builder.PreprocessSketch(ctx)) preprocessed := LoadAndInterpolate(t, filepath.Join("SketchWithStruct", "SketchWithStruct.preprocessed.txt"), ctx) - obtained := strings.Replace(ctx.SketchSourceAfterArduinoPreprocessing, "\r\n", "\n", -1) + preprocessedSketch := loadPreprocessedSketch(t, ctx) + obtained := strings.Replace(preprocessedSketch, "\r\n", "\n", -1) // ctags based preprocessing removes the space after "dostuff", but this is still OK // TODO: remove this exception when moving to a more powerful parser preprocessed = strings.Replace(preprocessed, "void dostuff (A_NEW_TYPE * bar);", "void dostuff(A_NEW_TYPE * bar);", 1) @@ -239,7 +253,7 @@ func TestPrototypesAdderSketchWithStruct(t *testing.T) { func TestPrototypesAdderSketchWithConfig(t *testing.T) { sketchLocation := paths.New("sketch_with_config", "sketch_with_config.ino") - quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation)) + quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String()) ctx := prepareBuilderTestContext(t, nil, sketchLocation, "arduino:avr:leonardo") defer cleanUpBuilderTestContext(t, ctx) @@ -250,7 +264,7 @@ func TestPrototypesAdderSketchWithConfig(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -259,18 +273,19 @@ func TestPrototypesAdderSketchWithConfig(t *testing.T) { err := command.Run(ctx) NoError(t, err) } - NoError(t, builder.PreprocessSketchWithCtags(ctx)) + NoError(t, builder.PreprocessSketch(ctx)) - require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") - require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#line 13 "+quotedSketchLocation+"\nvoid setup();\n#line 17 "+quotedSketchLocation+"\nvoid loop();\n#line 13 "+quotedSketchLocation+"\n") + preprocessedSketch := loadPreprocessedSketch(t, ctx) + require.Contains(t, preprocessedSketch, "#include \n#line 1 "+quotedSketchLocation+"\n") + require.Contains(t, preprocessedSketch, "#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)) + require.Equal(t, preprocessed, strings.Replace(preprocessedSketch, "\r\n", "\n", -1)) } func TestPrototypesAdderSketchNoFunctionsTwoFiles(t *testing.T) { sketchLocation := paths.New("sketch_no_functions_two_files", "sketch_no_functions_two_files.ino") - quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation)) + quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String()) ctx := prepareBuilderTestContext(t, nil, paths.New("sketch_no_functions_two_files", "sketch_no_functions_two_files.ino"), "arduino:avr:leonardo") defer cleanUpBuilderTestContext(t, ctx) @@ -281,7 +296,7 @@ func TestPrototypesAdderSketchNoFunctionsTwoFiles(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -290,10 +305,12 @@ func TestPrototypesAdderSketchNoFunctionsTwoFiles(t *testing.T) { err := command.Run(ctx) NoError(t, err) } - NoError(t, builder.PreprocessSketchWithCtags(ctx)) + mergedSketch := loadPreprocessedSketch(t, ctx) + NoError(t, builder.PreprocessSketch(ctx)) - require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") - require.Equal(t, ctx.SketchSourceMerged, ctx.SketchSourceAfterArduinoPreprocessing) // No prototypes added + preprocessedSketch := loadPreprocessedSketch(t, ctx) + require.Contains(t, preprocessedSketch, "#include \n#line 1 "+quotedSketchLocation+"\n") + require.Equal(t, mergedSketch, preprocessedSketch) // No prototypes added } func TestPrototypesAdderSketchNoFunctions(t *testing.T) { @@ -303,12 +320,12 @@ func TestPrototypesAdderSketchNoFunctions(t *testing.T) { ctx.Verbose = true sketchLocation := paths.New("sketch_no_functions", "sketch_no_functions.ino") - quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation)) + quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String()) var _err error 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -317,15 +334,17 @@ func TestPrototypesAdderSketchNoFunctions(t *testing.T) { err := command.Run(ctx) NoError(t, err) } - NoError(t, builder.PreprocessSketchWithCtags(ctx)) + mergedSketch := loadPreprocessedSketch(t, ctx) + NoError(t, builder.PreprocessSketch(ctx)) - require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") - require.Equal(t, ctx.SketchSourceMerged, ctx.SketchSourceAfterArduinoPreprocessing) // No prototypes added + preprocessedSketch := loadPreprocessedSketch(t, ctx) + require.Contains(t, preprocessedSketch, "#include \n#line 1 "+quotedSketchLocation+"\n") + require.Equal(t, mergedSketch, preprocessedSketch) // No prototypes added } func TestPrototypesAdderSketchWithDefaultArgs(t *testing.T) { sketchLocation := paths.New("sketch_with_default_args", "sketch_with_default_args.ino") - quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation)) + quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String()) ctx := prepareBuilderTestContext(t, nil, sketchLocation, "arduino:avr:leonardo") defer cleanUpBuilderTestContext(t, ctx) @@ -336,7 +355,7 @@ func TestPrototypesAdderSketchWithDefaultArgs(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -345,15 +364,16 @@ func TestPrototypesAdderSketchWithDefaultArgs(t *testing.T) { err := command.Run(ctx) NoError(t, err) } - NoError(t, builder.PreprocessSketchWithCtags(ctx)) + NoError(t, builder.PreprocessSketch(ctx)) - require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") - require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#line 4 "+quotedSketchLocation+"\nvoid setup();\n#line 7 "+quotedSketchLocation+"\nvoid loop();\n#line 1 "+quotedSketchLocation+"\n") + preprocessedSketch := loadPreprocessedSketch(t, ctx) + require.Contains(t, preprocessedSketch, "#include \n#line 1 "+quotedSketchLocation+"\n") + require.Contains(t, preprocessedSketch, "#line 4 "+quotedSketchLocation+"\nvoid setup();\n#line 7 "+quotedSketchLocation+"\nvoid loop();\n#line 1 "+quotedSketchLocation+"\n") } func TestPrototypesAdderSketchWithInlineFunction(t *testing.T) { sketchLocation := paths.New("sketch_with_inline_function", "sketch_with_inline_function.ino") - quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation)) + quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String()) ctx := prepareBuilderTestContext(t, nil, sketchLocation, "arduino:avr:leonardo") defer cleanUpBuilderTestContext(t, ctx) @@ -364,7 +384,7 @@ func TestPrototypesAdderSketchWithInlineFunction(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -373,12 +393,13 @@ func TestPrototypesAdderSketchWithInlineFunction(t *testing.T) { err := command.Run(ctx) NoError(t, err) } - NoError(t, builder.PreprocessSketchWithCtags(ctx)) + NoError(t, builder.PreprocessSketch(ctx)) - require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") + preprocessedSketch := loadPreprocessedSketch(t, ctx) + require.Contains(t, preprocessedSketch, "#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.SketchSourceAfterArduinoPreprocessing + obtained := preprocessedSketch // 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) @@ -392,7 +413,7 @@ func TestPrototypesAdderSketchWithInlineFunction(t *testing.T) { func TestPrototypesAdderSketchWithFunctionSignatureInsideIFDEF(t *testing.T) { sketchLocation := paths.New("sketch_with_function_signature_inside_ifdef", "sketch_with_function_signature_inside_ifdef.ino") - quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation)) + quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String()) ctx := prepareBuilderTestContext(t, nil, sketchLocation, "arduino:avr:leonardo") defer cleanUpBuilderTestContext(t, ctx) @@ -403,7 +424,7 @@ func TestPrototypesAdderSketchWithFunctionSignatureInsideIFDEF(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -412,15 +433,16 @@ func TestPrototypesAdderSketchWithFunctionSignatureInsideIFDEF(t *testing.T) { err := command.Run(ctx) NoError(t, err) } - NoError(t, builder.PreprocessSketchWithCtags(ctx)) + NoError(t, builder.PreprocessSketch(ctx)) - require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") - 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") + preprocessedSketch := loadPreprocessedSketch(t, ctx) + require.Contains(t, preprocessedSketch, "#include \n#line 1 "+quotedSketchLocation+"\n") + require.Contains(t, preprocessedSketch, "#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) { sketchLocation := paths.New("sketch_with_usbcon", "sketch_with_usbcon.ino") - quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation)) + quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String()) ctx := &types.Context{ HardwareDirs: paths.NewPathList(filepath.Join("..", "hardware"), "downloaded_hardware"), @@ -436,7 +458,7 @@ func TestPrototypesAdderSketchWithUSBCON(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -445,15 +467,16 @@ func TestPrototypesAdderSketchWithUSBCON(t *testing.T) { err := command.Run(ctx) NoError(t, err) } - NoError(t, builder.PreprocessSketchWithCtags(ctx)) + NoError(t, builder.PreprocessSketch(ctx)) - require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") - 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") + preprocessedSketch := loadPreprocessedSketch(t, ctx) + require.Contains(t, preprocessedSketch, "#include \n#line 1 "+quotedSketchLocation+"\n") + require.Contains(t, preprocessedSketch, "#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) { sketchLocation := paths.New("sketch_with_typename", "sketch_with_typename.ino") - quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation)) + quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String()) ctx := &types.Context{ HardwareDirs: paths.NewPathList(filepath.Join("..", "hardware"), "downloaded_hardware"), @@ -468,7 +491,7 @@ func TestPrototypesAdderSketchWithTypename(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -477,11 +500,12 @@ func TestPrototypesAdderSketchWithTypename(t *testing.T) { err := command.Run(ctx) NoError(t, err) } - NoError(t, builder.PreprocessSketchWithCtags(ctx)) + NoError(t, builder.PreprocessSketch(ctx)) - require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") + preprocessedSketch := loadPreprocessedSketch(t, ctx) + require.Contains(t, preprocessedSketch, "#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.SketchSourceAfterArduinoPreprocessing + obtained := preprocessedSketch // 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) @@ -491,7 +515,7 @@ func TestPrototypesAdderSketchWithTypename(t *testing.T) { func TestPrototypesAdderSketchWithIfDef2(t *testing.T) { sketchLocation := paths.New("sketch_with_ifdef", "sketch_with_ifdef.ino") - quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation)) + quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String()) ctx := prepareBuilderTestContext(t, nil, sketchLocation, "arduino:avr:yun") defer cleanUpBuilderTestContext(t, ctx) @@ -502,7 +526,7 @@ func TestPrototypesAdderSketchWithIfDef2(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -511,18 +535,19 @@ func TestPrototypesAdderSketchWithIfDef2(t *testing.T) { err := command.Run(ctx) NoError(t, err) } - NoError(t, builder.PreprocessSketchWithCtags(ctx)) + NoError(t, builder.PreprocessSketch(ctx)) - require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") - 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") + preprocessedSketch := loadPreprocessedSketch(t, ctx) + require.Contains(t, preprocessedSketch, "#include \n#line 1 "+quotedSketchLocation+"\n") + require.Contains(t, preprocessedSketch, "#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)) + require.Equal(t, expectedSource, strings.Replace(preprocessedSketch, "\r\n", "\n", -1)) } func TestPrototypesAdderSketchWithIfDef2SAM(t *testing.T) { sketchLocation := paths.New("sketch_with_ifdef", "sketch_with_ifdef.ino") - quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation)) + quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String()) ctx := prepareBuilderTestContext(t, nil, sketchLocation, "arduino:sam:arduino_due_x_dbg") defer cleanUpBuilderTestContext(t, ctx) @@ -533,7 +558,7 @@ func TestPrototypesAdderSketchWithIfDef2SAM(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -542,18 +567,19 @@ func TestPrototypesAdderSketchWithIfDef2SAM(t *testing.T) { err := command.Run(ctx) NoError(t, err) } - NoError(t, builder.PreprocessSketchWithCtags(ctx)) + NoError(t, builder.PreprocessSketch(ctx)) - require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") - 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") + preprocessedSketch := loadPreprocessedSketch(t, ctx) + require.Contains(t, preprocessedSketch, "#include \n#line 1 "+quotedSketchLocation+"\n") + require.Contains(t, preprocessedSketch, "#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)) + require.Equal(t, expectedSource, strings.Replace(preprocessedSketch, "\r\n", "\n", -1)) } func TestPrototypesAdderSketchWithConst(t *testing.T) { sketchLocation := paths.New("sketch_with_const", "sketch_with_const.ino") - quotedSketchLocation := utils.QuoteCppPath(Abs(t, sketchLocation)) + quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String()) ctx := prepareBuilderTestContext(t, nil, sketchLocation, "arduino:avr:uno") defer cleanUpBuilderTestContext(t, ctx) @@ -564,7 +590,7 @@ func TestPrototypesAdderSketchWithConst(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -573,10 +599,11 @@ func TestPrototypesAdderSketchWithConst(t *testing.T) { err := command.Run(ctx) NoError(t, err) } - NoError(t, builder.PreprocessSketchWithCtags(ctx)) + NoError(t, builder.PreprocessSketch(ctx)) - require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "#include \n#line 1 "+quotedSketchLocation+"\n") - 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") + preprocessedSketch := loadPreprocessedSketch(t, ctx) + require.Contains(t, preprocessedSketch, "#include \n#line 1 "+quotedSketchLocation+"\n") + require.Contains(t, preprocessedSketch, "#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) { @@ -589,7 +616,7 @@ func TestPrototypesAdderSketchWithDosEol(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -598,13 +625,13 @@ func TestPrototypesAdderSketchWithDosEol(t *testing.T) { err := command.Run(ctx) NoError(t, err) } - NoError(t, builder.PreprocessSketchWithCtags(ctx)) + NoError(t, builder.PreprocessSketch(ctx)) // only requires no error as result } func TestPrototypesAdderSketchWithSubstringFunctionMember(t *testing.T) { sketchLocation := paths.New("sketch_with_class_and_method_substring", "sketch_with_class_and_method_substring.ino") - quotedSketchLocation := utils.QuoteCppString(Abs(t, sketchLocation).String()) + quotedSketchLocation := cpp.QuoteString(Abs(t, sketchLocation).String()) ctx := prepareBuilderTestContext(t, nil, sketchLocation, "arduino:avr:uno") defer cleanUpBuilderTestContext(t, ctx) @@ -615,7 +642,7 @@ func TestPrototypesAdderSketchWithSubstringFunctionMember(t *testing.T) { 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) + ctx.LineOffset, _err = bldr.PrepareSketchBuildPath(ctx.Sketch, ctx.SourceOverride, ctx.SketchBuildPath) return _err }), &builder.ContainerFindIncludes{}, @@ -624,7 +651,8 @@ func TestPrototypesAdderSketchWithSubstringFunctionMember(t *testing.T) { err := command.Run(ctx) NoError(t, err) } - NoError(t, builder.PreprocessSketchWithCtags(ctx)) + NoError(t, builder.PreprocessSketch(ctx)) - require.Contains(t, ctx.SketchSourceAfterArduinoPreprocessing, "class Foo {\nint blooper(int x) { return x+1; }\n};\n\nFoo foo;\n\n#line 7 "+quotedSketchLocation+"\nvoid setup();") + preprocessedSketch := loadPreprocessedSketch(t, ctx) + require.Contains(t, preprocessedSketch, "class Foo {\nint blooper(int x) { return x+1; }\n};\n\nFoo foo;\n\n#line 7 "+quotedSketchLocation+"\nvoid setup();") } 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 bb6457728ae..90f3633f2b6 100644 --- a/legacy/builder/test/try_build_of_problematic_sketch_test.go +++ b/legacy/builder/test/try_build_of_problematic_sketch_test.go @@ -20,6 +20,7 @@ import ( "path/filepath" "testing" + "github.com/arduino/arduino-cli/arduino/builder/preprocessor" "github.com/arduino/arduino-cli/legacy/builder" "github.com/arduino/arduino-cli/legacy/builder/types" paths "github.com/arduino/go-paths-helper" @@ -202,7 +203,7 @@ func TestTryBuild042(t *testing.T) { } func makeDefaultContext() *types.Context { - builder.DebugPreprocessor = true + preprocessor.DebugPreprocessor = true return &types.Context{ HardwareDirs: paths.NewPathList(filepath.Join("..", "hardware"), "downloaded_hardware", "downloaded_board_manager_stuff"), BuiltInToolsDirs: paths.NewPathList("downloaded_tools"), diff --git a/legacy/builder/test/utils_test.go b/legacy/builder/test/utils_test.go index ec34a7bb670..a6a4dea8fb4 100644 --- a/legacy/builder/test/utils_test.go +++ b/legacy/builder/test/utils_test.go @@ -40,16 +40,3 @@ func TestPrintableCommand(t *testing.T) { result := utils.PrintableCommand(parts) require.Equal(t, correct, result) } - -func TestQuoteCppString(t *testing.T) { - cases := map[string]string{ - `foo`: `"foo"`, - `foo\bar`: `"foo\\bar"`, - `foo "is" quoted and \\bar"" escaped\`: `"foo \"is\" quoted and \\\\bar\"\" escaped\\"`, - // ASCII 0x20 - 0x7e, excluding ` - ` !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~`: `" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_abcdefghijklmnopqrstuvwxyz{|}~"`, - } - for input, expected := range cases { - require.Equal(t, expected, utils.QuoteCppString(input)) - } -} diff --git a/legacy/builder/types/context.go b/legacy/builder/types/context.go index 2b5fd27b679..8bbd05f7308 100644 --- a/legacy/builder/types/context.go +++ b/legacy/builder/types/context.go @@ -94,21 +94,12 @@ type Context struct { CoreObjectsFiles paths.PathList LibrariesBuildPath *paths.Path LibrariesObjectFiles paths.PathList - PreprocPath *paths.Path SketchObjectFiles paths.PathList IgnoreSketchFolderNameErrors bool Sketch *sketch.Sketch WarningsLevel string - // Arduino sketch (.ino) to C++ (.cpp) conversion steps: - // 1. Concatenate *.ino files into a single merged source file -> SketchSourceMerged - SketchSourceMerged string - // 2. Run a pass of C++ preprocessor to remove macro definitions and ifdef-ed code -> SketchSourceAfterCppPreprocessing - SketchSourceAfterCppPreprocessing string - // 3. Do the Arduino preprocessing of the sketch (add missing prototypes) -> SketchSourceAfterArduinoPreprocessing - SketchSourceAfterArduinoPreprocessing string - // Libraries handling LibrariesManager *librariesmanager.LibrariesManager LibrariesResolver *librariesresolver.Cpp diff --git a/legacy/builder/utils/utils.go b/legacy/builder/utils/utils.go index 056940308fe..3efc8b73d6d 100644 --- a/legacy/builder/utils/utils.go +++ b/legacy/builder/utils/utils.go @@ -262,19 +262,6 @@ func LogIfVerbose(warn bool, msg string) types.Command { return &loggerAction{onlyIfVerbose: true, warn: warn, msg: msg} } -// Returns the given string as a quoted string for use with the C -// preprocessor. This adds double quotes around it and escapes any -// double quotes and backslashes in the string. -func QuoteCppString(str string) string { - str = strings.Replace(str, "\\", "\\\\", -1) - str = strings.Replace(str, "\"", "\\\"", -1) - return "\"" + str + "\"" -} - -func QuoteCppPath(path *paths.Path) string { - return QuoteCppString(path.String()) -} - // Normalizes an UTF8 byte slice // TODO: use it more often troughout all the project (maybe on logger interface?) func NormalizeUTF8(buf []byte) []byte {