Skip to content

legacy: Arduino preprocess subroutine refactorization #2147

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 42 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
cfe6033
ctags parser.Parse signature change
cmaglie Mar 30, 2023
02d08b1
removing ctags-related data from builder ctx (part 1)
cmaglie Mar 30, 2023
4e7f2d8
removing ctags-related data from builder ctx (part 2)
cmaglie Mar 30, 2023
d96ca50
removing ctags-related data from builder ctx (part 3)
cmaglie Mar 30, 2023
aebdfec
Clearly separate Source code processing phases
cmaglie Mar 31, 2023
e11e53e
Removed Command wrapper from ContainerMergeCopySketchFiles
cmaglie Mar 31, 2023
98cd03a
Moved builder.CopySketchFilesToBuildPath into proper location
cmaglie Apr 3, 2023
c39f992
legacy: Removed ReadFileAndStoreInContext command
cmaglie Apr 3, 2023
d2e6fe3
Converted FilterSketchSource into a function
cmaglie Apr 3, 2023
98a72e6
Moved a couple of functions in the proper builder package
cmaglie Apr 3, 2023
dcfdc54
Removed unused class
cmaglie Apr 3, 2023
e806253
Replaced two accessory functions with stdlib functions
cmaglie Apr 3, 2023
fbd1e50
Movec ctags-related structs in ctags package
cmaglie Apr 3, 2023
3e5f56f
Removed unused structs
cmaglie Apr 3, 2023
d7475f7
Unified GCCPreprocRunner* functions
cmaglie Apr 3, 2023
c7cc15f
Replaced utils.SliceContains with stdlib function
cmaglie Apr 3, 2023
2adc6bd
Implemented generic algorithms (at lease until they are available in …
cmaglie Apr 3, 2023
a58f3d5
Removed useless call to FilterSketchSource
cmaglie Apr 4, 2023
c2328b5
Converted AddPrototypes into a function
cmaglie Apr 4, 2023
f4dd295
Converted CTagsRunner into a function
cmaglie Apr 5, 2023
53946e6
Removed useless tasks from ctags_runner test
cmaglie Apr 5, 2023
43515c2
Simplified ctags_runner test
cmaglie Apr 5, 2023
efd7392
Removed some ctags related fields from builder context
cmaglie Apr 5, 2023
8c07216
Simplified RunCTags / factored test subroutine
cmaglie Apr 5, 2023
3c65cb8
Removed DebugPreprocessor from builder ctx
cmaglie Apr 5, 2023
795c9dd
Added executils.RunAndCaptureOutput
cmaglie Apr 5, 2023
ed8764b
Moved RunCTags out of legacy package
cmaglie Apr 5, 2023
91e7781
Simplified GCCPreprocRunner function
cmaglie Apr 5, 2023
de8a3b6
Removed dependency on builder ctx in GCCPreprocRunner
cmaglie Apr 5, 2023
493b606
Moved GCCPreprocRunner into proper place
cmaglie Apr 5, 2023
fc92f8d
Replaced algorithm with stdlib equivalent
cmaglie Apr 6, 2023
7fd1a7f
Reduced public API surface of CTags parser
cmaglie Apr 6, 2023
bea1361
Moved CTags parser out of legacy
cmaglie Apr 6, 2023
050e279
Moved CTags preprocess subroutine in proper place
cmaglie Apr 11, 2023
9794f6d
Factored all c++ source lines parsers
cmaglie Apr 11, 2023
0f77b62
Removed useless builderCtx field SketchSourceAfterCppPreprocessing
cmaglie Apr 11, 2023
f5636a9
Removed useless builderCtx field SketchSourceAfterArduinoPreprocessing
cmaglie Apr 11, 2023
73c04fd
Removed useless builderCtx field SketchSourceMerged
cmaglie Apr 11, 2023
39548b5
Moved ctag preprocessor into proper location
cmaglie Apr 11, 2023
f043154
Renamed variable for lint checks
cmaglie Apr 26, 2023
fef8d67
Moved ctags parser shenanings into internal package
cmaglie Apr 26, 2023
651b371
Fixed linter warnings
cmaglie Apr 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions .licenses/go/golang.org/x/exp/constraints.dep.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
name: golang.org/x/exp/constraints
version: v0.0.0-20230321023759-10a507213a29
type: go
summary: Package constraints defines a set of useful constraints to be used with type
parameters.
homepage: https://pkg.go.dev/golang.org/x/exp/constraints
license: bsd-3-clause
licenses:
- sources: [email protected]/LICENSE
text: |
Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- sources: [email protected]/PATENTS
text: |
Additional IP Rights Grant (Patents)

"This implementation" means the copyrightable works distributed by
Google as part of the Go project.

Google hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as stated in this section)
patent license to make, have made, use, offer to sell, sell, import,
transfer and otherwise run, modify and propagate the contents of this
implementation of Go, where such license applies only to those patent
claims, both currently owned or controlled by Google and acquired in
the future, licensable by Google that are necessarily infringed by this
implementation of Go. This grant does not include claims that would be
infringed only as a consequence of further modification of this
implementation. If you or your agent or exclusive licensee institute or
order or agree to the institution of patent litigation against any
entity (including a cross-claim or counterclaim in a lawsuit) alleging
that this implementation of Go or any code incorporated within this
implementation of Go constitutes direct or contributory patent
infringement, or inducement of patent infringement, then any patent
rights granted to you under this License for this implementation of Go
shall terminate as of the date such litigation is filed.
notices: []
62 changes: 62 additions & 0 deletions .licenses/go/golang.org/x/exp/slices.dep.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
name: golang.org/x/exp/slices
version: v0.0.0-20230321023759-10a507213a29
type: go
summary: Package slices defines various functions useful with slices of any type.
homepage: https://pkg.go.dev/golang.org/x/exp/slices
license: bsd-3-clause
licenses:
- sources: [email protected]/LICENSE
text: |
Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- sources: [email protected]/PATENTS
text: |
Additional IP Rights Grant (Patents)

"This implementation" means the copyrightable works distributed by
Google as part of the Go project.

Google hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as stated in this section)
patent license to make, have made, use, offer to sell, sell, import,
transfer and otherwise run, modify and propagate the contents of this
implementation of Go, where such license applies only to those patent
claims, both currently owned or controlled by Google and acquired in
the future, licensable by Google that are necessarily infringed by this
implementation of Go. This grant does not include claims that would be
infringed only as a consequence of further modification of this
implementation. If you or your agent or exclusive licensee institute or
order or agree to the institution of patent litigation against any
entity (including a cross-claim or counterclaim in a lawsuit) alleging
that this implementation of Go or any code incorporated within this
implementation of Go constitutes direct or contributory patent
infringement, or inducement of patent infringement, then any patent
rights granted to you under this License for this implementation of Go
shall terminate as of the date such litigation is filed.
notices: []
108 changes: 108 additions & 0 deletions arduino/builder/cpp/cpp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// 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 [email protected].

package cpp

import (
"strconv"
"strings"
"unicode/utf8"

"github.com/arduino/go-paths-helper"
)

// 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 QuoteString(str string) string {
str = strings.Replace(str, "\\", "\\\\", -1)
str = strings.Replace(str, "\"", "\\\"", -1)
return "\"" + str + "\""
}

// 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 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
// characters are also escaped, but the implementation does not
// actually do this. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51259
if len(line) < 1 || line[0] != '"' {
return "", line, false
}

i := 1
res := ""
for {
if i >= len(line) {
return "", line, false
}

c, width := utf8.DecodeRuneInString(line[i:])

switch c {
case '\\':
// Backslash, next character is used unmodified
i += width
if i >= len(line) {
return "", line, false
}
res += string(line[i])
case '"':
// Quote, end of string
return res, line[i+width:], true
default:
res += string(c)
}

i += width
}
}
74 changes: 74 additions & 0 deletions arduino/builder/cpp/cpp_test.go
Original file line number Diff line number Diff line change
@@ -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 [email protected].

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))
}
}
Loading