From ec6c2c495c246be1b383b3d882a3d0fee89f0c7c Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Wed, 4 Nov 2015 14:26:42 +0100 Subject: [PATCH 01/85] Updating ctags and ensuring namespaces are ignored when generating prototypes. Fixes #44 Signed-off-by: Federico Fissore --- src/arduino.cc/builder/ctags_parser.go | 4 +- .../ctags_output/TestCTagsParserNamespace.txt | 4 ++ .../builder/test/ctags_parser_test.go | 18 ++++++++ .../builder/test/ctags_runner_test.go | 45 +++++++++++++++++++ .../builder/test/helper_tools_downloader.go | 10 ++--- .../test/sketch_with_namespace/sketch.ino | 8 ++++ 6 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 src/arduino.cc/builder/test/ctags_output/TestCTagsParserNamespace.txt create mode 100644 src/arduino.cc/builder/test/sketch_with_namespace/sketch.ino diff --git a/src/arduino.cc/builder/ctags_parser.go b/src/arduino.cc/builder/ctags_parser.go index 073f209c..e0448dcb 100644 --- a/src/arduino.cc/builder/ctags_parser.go +++ b/src/arduino.cc/builder/ctags_parser.go @@ -45,13 +45,14 @@ const FIELD_CODE = "code" const FIELD_FUNCTION_NAME = "functionName" const FIELD_CLASS = "class" const FIELD_STRUCT = "struct" +const FIELD_NAMESPACE = "namespace" const FIELD_SKIP = "skipMe" const KIND_PROTOTYPE = "prototype" const TEMPLATE = "template" -var FIELDS = map[string]bool{"kind": true, "line": true, "typeref": true, "signature": true, "returntype": true, "class": true, "struct": true} +var FIELDS = map[string]bool{"kind": true, "line": true, "typeref": true, "signature": true, "returntype": true, "class": true, "struct": true, "namespace": true} var KNOWN_TAG_KINDS = map[string]bool{"prototype": true, "function": true} type CTagsParser struct { @@ -71,6 +72,7 @@ func (s *CTagsParser) Run(context map[string]interface{}) error { tags = filterOutUnknownTags(tags) tags = filterOutTagsWithField(tags, FIELD_CLASS) tags = filterOutTagsWithField(tags, FIELD_STRUCT) + tags = filterOutTagsWithField(tags, FIELD_NAMESPACE) tags = skipTagsWhere(tags, signatureContainsDefaultArg) tags = addPrototypes(tags) tags = removeDefinedProtypes(tags) diff --git a/src/arduino.cc/builder/test/ctags_output/TestCTagsParserNamespace.txt b/src/arduino.cc/builder/test/ctags_output/TestCTagsParserNamespace.txt new file mode 100644 index 00000000..8a12c235 --- /dev/null +++ b/src/arduino.cc/builder/test/ctags_output/TestCTagsParserNamespace.txt @@ -0,0 +1,4 @@ +value /tmp/test030883150/preproc/ctags_target.cpp /^ int value() {$/;" kind:function line:3 namespace:Test signature:() returntype:int +setup /tmp/test030883150/preproc/ctags_target.cpp /^void setup() {}$/;" kind:function line:8 signature:() returntype:void +loop /tmp/test030883150/preproc/ctags_target.cpp /^void loop() {}$/;" kind:function line:9 signature:() returntype:void + diff --git a/src/arduino.cc/builder/test/ctags_parser_test.go b/src/arduino.cc/builder/test/ctags_parser_test.go index efae491c..441c0ba9 100644 --- a/src/arduino.cc/builder/test/ctags_parser_test.go +++ b/src/arduino.cc/builder/test/ctags_parser_test.go @@ -225,3 +225,21 @@ func TestCTagsParserDefaultArguments(t *testing.T) { require.Equal(t, "void setup();", prototypes[0].Prototype) require.Equal(t, "void loop();", prototypes[1].Prototype) } + +func TestCTagsParserNamespace(t *testing.T) { + context := make(map[string]interface{}) + + bytes, err := ioutil.ReadFile(filepath.Join("ctags_output", "TestCTagsParserNamespace.txt")) + NoError(t, err) + + context[constants.CTX_CTAGS_OUTPUT] = string(bytes) + + ctagsParser := builder.CTagsParser{PrototypesField: constants.CTX_PROTOTYPES} + ctagsParser.Run(context) + + prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) + + require.Equal(t, 2, len(prototypes)) + require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "void loop();", prototypes[1].Prototype) +} diff --git a/src/arduino.cc/builder/test/ctags_runner_test.go b/src/arduino.cc/builder/test/ctags_runner_test.go index 0a0420c2..af5a3c81 100644 --- a/src/arduino.cc/builder/test/ctags_runner_test.go +++ b/src/arduino.cc/builder/test/ctags_runner_test.go @@ -181,3 +181,48 @@ func TestCTagsRunnerSketchWithTypename(t *testing.T) { require.Equal(t, expectedOutput, strings.Replace(context[constants.CTX_CTAGS_OUTPUT].(string), "\r\n", "\n", -1)) } + +func TestCTagsRunnerSketchWithNamespace(t *testing.T) { + DownloadCoresAndToolsAndLibraries(t) + + context := make(map[string]interface{}) + + buildPath := SetupBuildPath(t, context) + defer os.RemoveAll(buildPath) + + context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} + context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} + context[constants.CTX_FQBN] = "arduino:avr:leonardo" + context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_namespace", "sketch.ino") + context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" + context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} + context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} + context[constants.CTX_VERBOSE] = true + + commands := []types.Command{ + &builder.SetupHumanLoggerIfMissing{}, + + &builder.ContainerSetupHardwareToolsLibsSketchAndProps{}, + + &builder.ContainerMergeCopySketchFiles{}, + + &builder.ContainerFindIncludes{}, + + &builder.PrintUsedLibrariesIfVerbose{}, + &builder.WarnAboutArchIncompatibleLibraries{}, + &builder.CTagsTargetFileSaver{SourceField: constants.CTX_SOURCE}, + &builder.CTagsRunner{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + ctagsTempFileName := context[constants.CTX_CTAGS_TEMP_FILE_NAME].(string) + expectedOutput := "value\t" + ctagsTempFileName + "\t/^\tint value() {$/;\"\tkind:function\tline:3\tnamespace:Test\tsignature:()\treturntype:int\n" + + "setup\t" + ctagsTempFileName + "\t/^void setup() {}$/;\"\tkind:function\tline:8\tsignature:()\treturntype:void\n" + + "loop\t" + ctagsTempFileName + "\t/^void loop() {}$/;\"\tkind:function\tline:9\tsignature:()\treturntype:void\n" + + require.Equal(t, expectedOutput, strings.Replace(context[constants.CTX_CTAGS_OUTPUT].(string), "\r\n", "\n", -1)) +} diff --git a/src/arduino.cc/builder/test/helper_tools_downloader.go b/src/arduino.cc/builder/test/helper_tools_downloader.go index f9b34ba2..f953a921 100644 --- a/src/arduino.cc/builder/test/helper_tools_downloader.go +++ b/src/arduino.cc/builder/test/helper_tools_downloader.go @@ -108,12 +108,12 @@ func DownloadCoresAndToolsAndLibraries(t *testing.T) { OsUrl{Os: "i686-mingw32", Url: "http://downloads.arduino.cc/tools/coan-5.2-i686-mingw32.zip"}, OsUrl{Os: "x86_64-apple-darwin", Url: "http://downloads.arduino.cc/tools/coan-5.2-x86_64-apple-darwin.zip"}, }}, - Tool{Name: "ctags", Version: "5.8-arduino2", + Tool{Name: "ctags", Version: "5.8-arduino3", OsUrls: []OsUrl{ - OsUrl{Os: "i686-pc-linux-gnu", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino2-i686-pc-linux-gnu.tar.bz2"}, - OsUrl{Os: "x86_64-pc-linux-gnu", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino2-x86_64-pc-linux-gnu.tar.bz2"}, - OsUrl{Os: "i686-mingw32", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino2-i686-mingw32.zip"}, - OsUrl{Os: "x86_64-apple-darwin", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino2-x86_64-apple-darwin.zip"}, + OsUrl{Os: "i686-pc-linux-gnu", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino3-i686-pc-linux-gnu.tar.bz2"}, + OsUrl{Os: "x86_64-pc-linux-gnu", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino3-x86_64-pc-linux-gnu.tar.bz2"}, + OsUrl{Os: "i686-mingw32", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino3-i686-mingw32.zip"}, + OsUrl{Os: "x86_64-apple-darwin", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino3-x86_64-apple-darwin.zip"}, }}, } diff --git a/src/arduino.cc/builder/test/sketch_with_namespace/sketch.ino b/src/arduino.cc/builder/test/sketch_with_namespace/sketch.ino new file mode 100644 index 00000000..178ba312 --- /dev/null +++ b/src/arduino.cc/builder/test/sketch_with_namespace/sketch.ino @@ -0,0 +1,8 @@ +namespace Test { + int value() { + return 42; + } + int ciao = 24; +} +void setup() {} +void loop() {} From 48f1e0681fa7098135af3e8001c0198b082a1193 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Wed, 4 Nov 2015 15:00:21 +0100 Subject: [PATCH 02/85] Previous ctags updated failed to deliver. Shipping a new one Signed-off-by: Federico Fissore --- src/arduino.cc/builder/test/helper_tools_downloader.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/arduino.cc/builder/test/helper_tools_downloader.go b/src/arduino.cc/builder/test/helper_tools_downloader.go index f953a921..88db48fa 100644 --- a/src/arduino.cc/builder/test/helper_tools_downloader.go +++ b/src/arduino.cc/builder/test/helper_tools_downloader.go @@ -108,12 +108,12 @@ func DownloadCoresAndToolsAndLibraries(t *testing.T) { OsUrl{Os: "i686-mingw32", Url: "http://downloads.arduino.cc/tools/coan-5.2-i686-mingw32.zip"}, OsUrl{Os: "x86_64-apple-darwin", Url: "http://downloads.arduino.cc/tools/coan-5.2-x86_64-apple-darwin.zip"}, }}, - Tool{Name: "ctags", Version: "5.8-arduino3", + Tool{Name: "ctags", Version: "5.8-arduino4", OsUrls: []OsUrl{ - OsUrl{Os: "i686-pc-linux-gnu", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino3-i686-pc-linux-gnu.tar.bz2"}, - OsUrl{Os: "x86_64-pc-linux-gnu", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino3-x86_64-pc-linux-gnu.tar.bz2"}, - OsUrl{Os: "i686-mingw32", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino3-i686-mingw32.zip"}, - OsUrl{Os: "x86_64-apple-darwin", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino3-x86_64-apple-darwin.zip"}, + OsUrl{Os: "i686-pc-linux-gnu", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino4-i686-pc-linux-gnu.tar.bz2"}, + OsUrl{Os: "x86_64-pc-linux-gnu", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino4-x86_64-pc-linux-gnu.tar.bz2"}, + OsUrl{Os: "i686-mingw32", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino4-i686-mingw32.zip"}, + OsUrl{Os: "x86_64-apple-darwin", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino4-x86_64-apple-darwin.zip"}, }}, } From 278b13e1987888f343345e6b84f6969c948a457c Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Wed, 4 Nov 2015 15:09:07 +0100 Subject: [PATCH 03/85] Releasing 1.0.6 Signed-off-by: Federico Fissore --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 4387a941..0e1ca3fb 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,7 @@ import ( "syscall" ) -const VERSION = "1.0.5" +const VERSION = "1.0.6" const FLAG_COMPILE = "compile" const FLAG_DUMP_PREFS = "dump-prefs" From c7a18f8214a21e28b2c3dd45dadc9f4e61ddfe0e Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Thu, 5 Nov 2015 09:25:48 +0100 Subject: [PATCH 04/85] Sketch sources files were recursively copied BUT not compiled. See https://github.com/arduino/Arduino/issues/1004#issuecomment-153891462 Signed-off-by: Federico Fissore --- .../builder/phases/sketch_builder.go | 2 +- src/arduino.cc/builder/test/builder_test.go | 21 +++++++++++++++++++ .../builder/test/sketch_loader_test.go | 3 ++- .../sketch_with_subfolders.ino | 10 +++++++++ .../subfolder/other.cpp | 10 +++++++++ .../sketch_with_subfolders/subfolder/other.h | 12 +++++++++++ 6 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 src/arduino.cc/builder/test/sketch_with_subfolders/subfolder/other.h diff --git a/src/arduino.cc/builder/phases/sketch_builder.go b/src/arduino.cc/builder/phases/sketch_builder.go index e5f70ac9..8ceb81c6 100644 --- a/src/arduino.cc/builder/phases/sketch_builder.go +++ b/src/arduino.cc/builder/phases/sketch_builder.go @@ -54,7 +54,7 @@ func (s *SketchBuilder) Run(context map[string]interface{}) error { } var objectFiles []string - objectFiles, err = builder_utils.CompileFiles(objectFiles, sketchBuildPath, false, sketchBuildPath, buildProperties, includes, verbose, warningsLevel, logger) + objectFiles, err = builder_utils.CompileFiles(objectFiles, sketchBuildPath, true, sketchBuildPath, buildProperties, includes, verbose, warningsLevel, logger) if err != nil { return utils.WrapError(err) } diff --git a/src/arduino.cc/builder/test/builder_test.go b/src/arduino.cc/builder/test/builder_test.go index eab664be..979c7a8d 100644 --- a/src/arduino.cc/builder/test/builder_test.go +++ b/src/arduino.cc/builder/test/builder_test.go @@ -313,3 +313,24 @@ func TestBuilderSketchWithOldLib(t *testing.T) { err := command.Run(context) NoError(t, err) } + +func TestBuilderSketchWithSubfolders(t *testing.T) { + DownloadCoresAndToolsAndLibraries(t) + + context := make(map[string]interface{}) + + buildPath := SetupBuildPath(t, context) + defer os.RemoveAll(buildPath) + + context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} + context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} + context[constants.CTX_FQBN] = "arduino:avr:uno" + context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_subfolders", "sketch_with_subfolders.ino") + context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} + context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} + context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" + + command := builder.Builder{} + err := command.Run(context) + NoError(t, err) +} diff --git a/src/arduino.cc/builder/test/sketch_loader_test.go b/src/arduino.cc/builder/test/sketch_loader_test.go index 15db8d2a..0b964029 100644 --- a/src/arduino.cc/builder/test/sketch_loader_test.go +++ b/src/arduino.cc/builder/test/sketch_loader_test.go @@ -136,8 +136,9 @@ func TestLoadSketchFromFolder(t *testing.T) { require.True(t, strings.Index(sketch.MainFile.Name, "sketch_with_subfolders.ino") != -1) - require.Equal(t, 1, len(sketch.AdditionalFiles)) + require.Equal(t, 2, len(sketch.AdditionalFiles)) require.True(t, strings.Index(sketch.AdditionalFiles[0].Name, "other.cpp") != -1) + require.True(t, strings.Index(sketch.AdditionalFiles[1].Name, "other.h") != -1) } func TestLoadSketchWithBackup(t *testing.T) { diff --git a/src/arduino.cc/builder/test/sketch_with_subfolders/sketch_with_subfolders.ino b/src/arduino.cc/builder/test/sketch_with_subfolders/sketch_with_subfolders.ino index e69de29b..738378f1 100644 --- a/src/arduino.cc/builder/test/sketch_with_subfolders/sketch_with_subfolders.ino +++ b/src/arduino.cc/builder/test/sketch_with_subfolders/sketch_with_subfolders.ino @@ -0,0 +1,10 @@ +#include "subfolder/other.h" + +MyClass myClass; + +void setup() { + myClass.init ( &Serial ); +} + +void loop() { +} \ No newline at end of file diff --git a/src/arduino.cc/builder/test/sketch_with_subfolders/subfolder/other.cpp b/src/arduino.cc/builder/test/sketch_with_subfolders/subfolder/other.cpp index e69de29b..21a3a249 100644 --- a/src/arduino.cc/builder/test/sketch_with_subfolders/subfolder/other.cpp +++ b/src/arduino.cc/builder/test/sketch_with_subfolders/subfolder/other.cpp @@ -0,0 +1,10 @@ +#include // Arduino 1.0 + +#include "other.h" + +MyClass::MyClass() { +} + +void MyClass::init ( Stream *stream ) { + controllerStream = stream; +} diff --git a/src/arduino.cc/builder/test/sketch_with_subfolders/subfolder/other.h b/src/arduino.cc/builder/test/sketch_with_subfolders/subfolder/other.h new file mode 100644 index 00000000..9312702c --- /dev/null +++ b/src/arduino.cc/builder/test/sketch_with_subfolders/subfolder/other.h @@ -0,0 +1,12 @@ +#ifndef other__h +#define other__h + +class MyClass { + public: + MyClass(); + void init ( Stream *controllerStream ); + + private: + Stream *controllerStream; +}; +#endif \ No newline at end of file From d17b4a8748f2a2b87b33ecb33988136c67620482 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Thu, 5 Nov 2015 09:49:55 +0100 Subject: [PATCH 05/85] Releasing 1.0.7 Signed-off-by: Federico Fissore --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 0e1ca3fb..12805e93 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,7 @@ import ( "syscall" ) -const VERSION = "1.0.6" +const VERSION = "1.0.7" const FLAG_COMPILE = "compile" const FLAG_DUMP_PREFS = "dump-prefs" From a0dfb78e43229388e9f542e951bcc3b54a65448d Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Thu, 5 Nov 2015 16:48:52 +0100 Subject: [PATCH 06/85] Added --preprocess action: preprocess (doesn't compile) given sketch. Better call arduino-compiler with the new -quite flag, otherwise output will get cluttered Signed-off-by: Federico Fissore --- main.go | 57 ++++++++++--------- src/arduino.cc/builder/builder.go | 34 +++++++++++ src/arduino.cc/builder/i18n/i18n.go | 10 ++++ .../builder/print_preprocessed_source.go | 45 +++++++++++++++ 4 files changed, 118 insertions(+), 28 deletions(-) create mode 100644 src/arduino.cc/builder/print_preprocessed_source.go diff --git a/main.go b/main.go index 12805e93..7da5c632 100644 --- a/main.go +++ b/main.go @@ -49,8 +49,9 @@ import ( const VERSION = "1.0.7" -const FLAG_COMPILE = "compile" -const FLAG_DUMP_PREFS = "dump-prefs" +const FLAG_ACTION_COMPILE = "compile" +const FLAG_ACTION_PREPROCESS = "preprocess" +const FLAG_ACTION_DUMP_PREFS = "dump-prefs" const FLAG_BUILD_OPTIONS_FILE = "build-options-file" const FLAG_HARDWARE = "hardware" const FLAG_TOOLS = "tools" @@ -61,6 +62,7 @@ const FLAG_FQBN = "fqbn" const FLAG_IDE_VERSION = "ide-version" const FLAG_BUILD_PATH = "build-path" const FLAG_VERBOSE = "verbose" +const FLAG_QUITE = "quite" const FLAG_DEBUG_LEVEL = "debug-level" const FLAG_WARNINGS = "warnings" const FLAG_WARNINGS_NONE = "none" @@ -97,6 +99,7 @@ func (h *slice) Set(csv string) error { } var compileFlag *bool +var preprocessFlag *bool var dumpPrefsFlag *bool var buildOptionsFileFlag *string var hardwareFoldersFlag slice @@ -108,6 +111,7 @@ var fqbnFlag *string var ideVersionFlag *string var buildPathFlag *string var verboseFlag *bool +var quiteFlag *bool var debugLevelFlag *int var libraryDiscoveryRecursionDepthFlag *int var warningsLevelFlag *string @@ -116,8 +120,9 @@ var versionFlag *bool var vidPidFlag *string func init() { - compileFlag = flag.Bool(FLAG_COMPILE, false, "compiles the given sketch") - dumpPrefsFlag = flag.Bool(FLAG_DUMP_PREFS, false, "dumps build properties used when compiling") + compileFlag = flag.Bool(FLAG_ACTION_COMPILE, false, "compiles the given sketch") + preprocessFlag = flag.Bool(FLAG_ACTION_PREPROCESS, false, "preprocess the given sketch") + dumpPrefsFlag = flag.Bool(FLAG_ACTION_DUMP_PREFS, false, "dumps build properties used when compiling") buildOptionsFileFlag = flag.String(FLAG_BUILD_OPTIONS_FILE, "", "Instead of specifying --"+FLAG_HARDWARE+", --"+FLAG_TOOLS+" etc every time, you can load all such options from a file") flag.Var(&hardwareFoldersFlag, FLAG_HARDWARE, "Specify a 'hardware' folder. Can be added multiple times for specifying multiple 'hardware' folders") flag.Var(&toolsFoldersFlag, FLAG_TOOLS, "Specify a 'tools' folder. Can be added multiple times for specifying multiple 'tools' folders") @@ -128,6 +133,7 @@ func init() { ideVersionFlag = flag.String(FLAG_IDE_VERSION, "10600", "fake IDE version") buildPathFlag = flag.String(FLAG_BUILD_PATH, "", "build path") verboseFlag = flag.Bool(FLAG_VERBOSE, false, "if 'true' prints lots of stuff") + quiteFlag = flag.Bool(FLAG_QUITE, false, "if 'true' doesn't print any warnings or progress or whatever") debugLevelFlag = flag.Int(FLAG_DEBUG_LEVEL, builder.DEFAULT_DEBUG_LEVEL, "Turns on debugging messages. The higher, the chattier") warningsLevelFlag = flag.String(FLAG_WARNINGS, "", "Sets warnings level. Available values are '"+FLAG_WARNINGS_NONE+"', '"+FLAG_WARNINGS_DEFAULT+"', '"+FLAG_WARNINGS_MORE+"' and '"+FLAG_WARNINGS_ALL+"'") loggerFlag = flag.String(FLAG_LOGGER, FLAG_LOGGER_HUMAN, "Sets type of logger. Available values are '"+FLAG_LOGGER_HUMAN+"', '"+FLAG_LOGGER_MACHINE+"'") @@ -149,19 +155,6 @@ func main() { return } - compile := *compileFlag - dumpPrefs := *dumpPrefsFlag - - if compile && dumpPrefs { - fmt.Fprintln(os.Stderr, "You can either specify --"+FLAG_COMPILE+" or --"+FLAG_DUMP_PREFS+", not both") - defer os.Exit(1) - return - } - - if !compile && !dumpPrefs { - compile = true - } - context := make(map[string]interface{}) buildOptions := make(map[string]string) @@ -265,13 +258,6 @@ func main() { context[constants.CTX_VIDPID] = *vidPidFlag } - if compile && flag.NArg() == 0 { - fmt.Fprintln(os.Stderr, "Last parameter must be the sketch to compile") - flag.Usage() - defer os.Exit(1) - return - } - if flag.NArg() > 0 { sketchLocation := flag.Arg(0) sketchLocation, err := gohasissues.Unquote(sketchLocation) @@ -283,6 +269,11 @@ func main() { context[constants.CTX_SKETCH_LOCATION] = sketchLocation } + if *verboseFlag && *quiteFlag { + *verboseFlag = false + *quiteFlag = false + } + context[constants.CTX_VERBOSE] = *verboseFlag ideVersion := "" @@ -305,16 +296,26 @@ func main() { context[constants.CTX_LIBRARY_DISCOVERY_RECURSION_DEPTH] = *libraryDiscoveryRecursionDepthFlag } - if *loggerFlag == FLAG_LOGGER_MACHINE { + if *quiteFlag { + context[constants.CTX_LOGGER] = i18n.NoopLogger{} + } else if *loggerFlag == FLAG_LOGGER_MACHINE { context[constants.CTX_LOGGER] = i18n.MachineLogger{} } else { context[constants.CTX_LOGGER] = i18n.HumanLogger{} } - if compile { - err = builder.RunBuilder(context) - } else if dumpPrefs { + if *dumpPrefsFlag { err = builder.RunParseHardwareAndDumpBuildProperties(context) + } else if *preprocessFlag { + err = builder.RunPreprocess(context) + } else { + if flag.NArg() == 0 { + fmt.Fprintln(os.Stderr, "Last parameter must be the sketch to compile") + flag.Usage() + defer os.Exit(1) + return + } + err = builder.RunBuilder(context) } exitCode := 0 diff --git a/src/arduino.cc/builder/builder.go b/src/arduino.cc/builder/builder.go index 78179748..42e869ff 100644 --- a/src/arduino.cc/builder/builder.go +++ b/src/arduino.cc/builder/builder.go @@ -128,6 +128,35 @@ func (s *Builder) Run(context map[string]interface{}) error { return otherErr } +type Preprocess struct{} + +func (s *Preprocess) Run(context map[string]interface{}) error { + commands := []types.Command{ + &SetupHumanLoggerIfMissing{}, + + &GenerateBuildPathIfMissing{}, + &EnsureBuildPathExists{}, + + &ContainerSetupHardwareToolsLibsSketchAndProps{}, + + &ContainerBuildOptions{}, + + &RecipeByPrefixSuffixRunner{Prefix: constants.HOOKS_PREBUILD, Suffix: constants.HOOKS_PATTERN_SUFFIX}, + + &ContainerMergeCopySketchFiles{}, + + &ContainerFindIncludes{}, + + &WarnAboutArchIncompatibleLibraries{}, + + &ContainerAddPrototypes{}, + + &PrintPreprocessedSource{}, + } + + return runCommands(context, commands, true) +} + type ParseHardwareAndDumpBuildProperties struct{} func (s *ParseHardwareAndDumpBuildProperties) Run(context map[string]interface{}) error { @@ -190,3 +219,8 @@ func RunParseHardwareAndDumpBuildProperties(context map[string]interface{}) erro command := ParseHardwareAndDumpBuildProperties{} return command.Run(context) } + +func RunPreprocess(context map[string]interface{}) error { + command := Preprocess{} + return command.Run(context) +} diff --git a/src/arduino.cc/builder/i18n/i18n.go b/src/arduino.cc/builder/i18n/i18n.go index bfeff72a..02212481 100644 --- a/src/arduino.cc/builder/i18n/i18n.go +++ b/src/arduino.cc/builder/i18n/i18n.go @@ -48,6 +48,16 @@ type Logger interface { Name() string } +type NoopLogger struct{} + +func (s NoopLogger) Fprintln(w io.Writer, format string, a ...interface{}) {} + +func (s NoopLogger) Println(format string, a ...interface{}) {} + +func (s NoopLogger) Name() string { + return "noop" +} + type HumanLogger struct{} func (s HumanLogger) Fprintln(w io.Writer, format string, a ...interface{}) { diff --git a/src/arduino.cc/builder/print_preprocessed_source.go b/src/arduino.cc/builder/print_preprocessed_source.go new file mode 100644 index 00000000..5a444d10 --- /dev/null +++ b/src/arduino.cc/builder/print_preprocessed_source.go @@ -0,0 +1,45 @@ +/* + * This file is part of Arduino Builder. + * + * Arduino Builder is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As a special exception, you may use this file as part of a free software + * library without restriction. Specifically, if other files instantiate + * templates or use macros or inline functions from this file, or you compile + * this file and link it with other files to produce an executable, this + * file does not by itself cause the resulting executable to be covered by + * the GNU General Public License. This exception does not however + * invalidate any other reasons why the executable file might be covered by + * the GNU General Public License. + * + * Copyright 2015 Arduino LLC (http://www.arduino.cc/) + */ + +package builder + +import ( + "arduino.cc/builder/constants" + "fmt" +) + +type PrintPreprocessedSource struct{} + +func (s *PrintPreprocessedSource) Run(context map[string]interface{}) error { + source := context[constants.CTX_GCC_MINUS_E_SOURCE].(string) + + fmt.Println(source) + + return nil +} From 0af3f7f96bbd2441e004438b32aa5df4f985fd1e Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Thu, 5 Nov 2015 17:11:14 +0100 Subject: [PATCH 07/85] Updated README.md Signed-off-by: Federico Fissore --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 61471f14..aa8dcd4c 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ This tool generates function prototypes and gathers library paths, providing `gc ### Usage -* `-compile` or `-dump-prefs`: Optional. If omitted, defaults to `-compile`. `-dump-prefs` will just print all build preferences used, `-compile` will use those preferences to run the actual compiler. +* `-compile` or `-dump-prefs` or `-preprocess`: Optional. If omitted, defaults to `-compile`. `-dump-prefs` will just print all build preferences used, `-compile` will use those preferences to run the actual compiler, `-preprocess` will only print preprocessed code to stdout. * `-hardware`: Mandatory. Folder containing Arduino platforms. An example is the `hardware` folder shipped with the Arduino IDE, or the `packages` folder created by Arduino Boards Manager. Can be specified multiple times. If conflicting hardware definitions are specified, the last one wins. @@ -27,6 +27,8 @@ This tool generates function prototypes and gathers library paths, providing `gc * `-verbose`: Optional, turns on verbose mode. +* `-quite`: Optional, supresses almost every output. + * `-debug-level`: Optional, defaults to "5". Used for debugging. Set it to 10 when submitting an issue. * `-ide-version`: Optional, defaults to "10600". The version of the Arduino IDE which is using this tool. From 539cb7d6fa86f52597bf550aeca6708c0d38116d Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Fri, 6 Nov 2015 10:55:15 +0100 Subject: [PATCH 08/85] Preserving 'static' keyword when generating function prototypes. Fixes #47 Signed-off-by: Federico Fissore --- src/arduino.cc/builder/ctags_parser.go | 10 ++++++++-- .../ctags_output/TestCTagsParserStatic.txt | 3 +++ .../builder/test/ctags_parser_test.go | 19 +++++++++++++++++++ .../builder/test/prototypes_adder_test.go | 2 +- 4 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 src/arduino.cc/builder/test/ctags_output/TestCTagsParserStatic.txt diff --git a/src/arduino.cc/builder/ctags_parser.go b/src/arduino.cc/builder/ctags_parser.go index e0448dcb..1cf4be19 100644 --- a/src/arduino.cc/builder/ctags_parser.go +++ b/src/arduino.cc/builder/ctags_parser.go @@ -51,6 +51,7 @@ const FIELD_SKIP = "skipMe" const KIND_PROTOTYPE = "prototype" const TEMPLATE = "template" +const STATIC = "static" var FIELDS = map[string]bool{"kind": true, "line": true, "typeref": true, "signature": true, "returntype": true, "class": true, "struct": true, "namespace": true} var KNOWN_TAG_KINDS = map[string]bool{"prototype": true, "function": true} @@ -120,8 +121,13 @@ func addPrototype(tag map[string]string) { code = code[:strings.LastIndex(code, ")")+1] } tag[KIND_PROTOTYPE] = code + ";" - } else { - tag[KIND_PROTOTYPE] = tag[FIELD_RETURNTYPE] + " " + tag[FIELD_FUNCTION_NAME] + tag[FIELD_SIGNATURE] + ";" + return + } + + tag[KIND_PROTOTYPE] = tag[FIELD_RETURNTYPE] + " " + tag[FIELD_FUNCTION_NAME] + tag[FIELD_SIGNATURE] + ";" + + if strings.Index(tag[FIELD_CODE], STATIC+" ") != -1 { + tag[KIND_PROTOTYPE] = STATIC + " " + tag[KIND_PROTOTYPE] } } diff --git a/src/arduino.cc/builder/test/ctags_output/TestCTagsParserStatic.txt b/src/arduino.cc/builder/test/ctags_output/TestCTagsParserStatic.txt new file mode 100644 index 00000000..ec1bdb14 --- /dev/null +++ b/src/arduino.cc/builder/test/ctags_output/TestCTagsParserStatic.txt @@ -0,0 +1,3 @@ +setup /tmp/test542833488/preproc/ctags_target.cpp /^void setup(){}$/;" kind:function line:2 signature:() returntype:void +loop /tmp/test542833488/preproc/ctags_target.cpp /^void loop(){}$/;" kind:function line:3 signature:() returntype:void +doStuff /tmp/test542833488/preproc/ctags_target.cpp /^static void doStuff() {}$/;" kind:function line:4 signature:() returntype:void diff --git a/src/arduino.cc/builder/test/ctags_parser_test.go b/src/arduino.cc/builder/test/ctags_parser_test.go index 441c0ba9..22faecd6 100644 --- a/src/arduino.cc/builder/test/ctags_parser_test.go +++ b/src/arduino.cc/builder/test/ctags_parser_test.go @@ -243,3 +243,22 @@ func TestCTagsParserNamespace(t *testing.T) { require.Equal(t, "void setup();", prototypes[0].Prototype) require.Equal(t, "void loop();", prototypes[1].Prototype) } + +func TestCTagsParserStatic(t *testing.T) { + context := make(map[string]interface{}) + + bytes, err := ioutil.ReadFile(filepath.Join("ctags_output", "TestCTagsParserStatic.txt")) + NoError(t, err) + + context[constants.CTX_CTAGS_OUTPUT] = string(bytes) + + ctagsParser := builder.CTagsParser{PrototypesField: constants.CTX_PROTOTYPES} + ctagsParser.Run(context) + + prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) + + require.Equal(t, 3, len(prototypes)) + require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "void loop();", prototypes[1].Prototype) + require.Equal(t, "static void doStuff();", prototypes[2].Prototype) +} diff --git a/src/arduino.cc/builder/test/prototypes_adder_test.go b/src/arduino.cc/builder/test/prototypes_adder_test.go index 996b5554..d483d0f3 100644 --- a/src/arduino.cc/builder/test/prototypes_adder_test.go +++ b/src/arduino.cc/builder/test/prototypes_adder_test.go @@ -574,7 +574,7 @@ func TestPrototypesAdderSketchWithInlineFunction(t *testing.T) { } require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) - require.Equal(t, "void setup();\nvoid loop();\nshort unsigned int testInt();\nint8_t testInline();\nuint8_t testAttribute();\n#line 1\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + require.Equal(t, "void setup();\nvoid loop();\nshort unsigned int testInt();\nstatic int8_t testInline();\nuint8_t testAttribute();\n#line 1\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) } func TestPrototypesAdderSketchWithFunctionSignatureInsideIFDEF(t *testing.T) { From a28be5f870e91c6f1247cbd407ff65c7fb882ccf Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Fri, 6 Nov 2015 11:05:01 +0100 Subject: [PATCH 09/85] Releasing 1.1.0 Signed-off-by: Federico Fissore --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 7da5c632..edd104a0 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,7 @@ import ( "syscall" ) -const VERSION = "1.0.7" +const VERSION = "1.1.0" const FLAG_ACTION_COMPILE = "compile" const FLAG_ACTION_PREPROCESS = "preprocess" From fb44606799fb498ad9d1cdae142ca4df6f170238 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Fri, 6 Nov 2015 15:34:42 +0100 Subject: [PATCH 10/85] TargetBoardResolver was handling 4th fqbn value too late and setting 'core' to a wrong value. Fixes #46 Signed-off-by: Federico Fissore --- .../builder/target_board_resolver.go | 8 +- .../test/hardware/watterott/avr/boards.txt | 130 ++++++++++++++++ .../test/hardware/watterott/avr/platform.txt | 146 ++++++++++++++++++ .../hardware/watterott/avr/programmers.txt | 0 .../builder/test/hardware_loader_test.go | 10 +- .../test/target_board_resolver_test.go | 26 ++++ 6 files changed, 311 insertions(+), 9 deletions(-) create mode 100644 src/arduino.cc/builder/test/hardware/watterott/avr/boards.txt create mode 100644 src/arduino.cc/builder/test/hardware/watterott/avr/platform.txt create mode 100644 src/arduino.cc/builder/test/hardware/watterott/avr/programmers.txt diff --git a/src/arduino.cc/builder/target_board_resolver.go b/src/arduino.cc/builder/target_board_resolver.go index d34409e9..fc67917d 100644 --- a/src/arduino.cc/builder/target_board_resolver.go +++ b/src/arduino.cc/builder/target_board_resolver.go @@ -68,15 +68,15 @@ func (s *TargetBoardResolver) Run(context map[string]interface{}) error { context[constants.CTX_TARGET_PLATFORM] = targetPlatform context[constants.CTX_TARGET_BOARD] = targetBoard + if len(fqbnParts) > 3 { + addAdditionalPropertiesToTargetBoard(targetBoard, fqbnParts[3]) + } + core := targetBoard.Properties[constants.BUILD_PROPERTIES_BUILD_CORE] if core == constants.EMPTY_STRING { core = DEFAULT_BUILD_CORE } - if len(fqbnParts) > 3 { - addAdditionalPropertiesToTargetBoard(targetBoard, fqbnParts[3]) - } - var corePlatform *types.Platform coreParts := strings.Split(core, ":") if len(coreParts) > 1 { diff --git a/src/arduino.cc/builder/test/hardware/watterott/avr/boards.txt b/src/arduino.cc/builder/test/hardware/watterott/avr/boards.txt new file mode 100644 index 00000000..be844787 --- /dev/null +++ b/src/arduino.cc/builder/test/hardware/watterott/avr/boards.txt @@ -0,0 +1,130 @@ +# VID 0x6666 is a prototype product Vendor ID +# http://www.linux-usb.org/usb.ids + +menu.speed=Speed +menu.core=Core +menu.info=Info + + +# ATmega32u4 @ 16 MHz +atmega32u4.name=ATmega32u4 +atmega32u4.menu.speed.16mhz=16 MHz +atmega32u4.menu.speed.16mhz.build.f_cpu=16000000L +atmega32u4.menu.speed.16mhz.bootloader.file=caterina_16mhz.hex +atmega32u4.menu.speed.8mhz=8 MHz +atmega32u4.menu.speed.8mhz.build.f_cpu=8000000L +atmega32u4.menu.speed.8mhz.bootloader.file=caterina_8mhz.hex +atmega32u4.vid.0=0x1D50 +atmega32u4.pid.0=0x60B0 +atmega32u4.vid.1=0x6666 +atmega32u4.pid.1=0x60B0 +atmega32u4.vid.2=0x2341 +atmega32u4.pid.2=0x0036 +atmega32u4.vid.3=0x2341 +atmega32u4.pid.3=0x8036 +atmega32u4.vid.4=0x2A03 +atmega32u4.pid.4=0x0036 +atmega32u4.vid.5=0x2A03 +atmega32u4.pid.5=0x8036 +atmega32u4.bootloader.tool=avrdude +atmega32u4.bootloader.low_fuses=0xff +atmega32u4.bootloader.high_fuses=0xd8 +atmega32u4.bootloader.extended_fuses=0xcb +#atmega32u4.bootloader.file=caterina_16mhz.hex +atmega32u4.bootloader.unlock_bits=0x3F +atmega32u4.bootloader.lock_bits=0x2F +atmega32u4.upload.tool=avrdude +atmega32u4.upload.protocol=avr109 +atmega32u4.upload.maximum_size=28672 +atmega32u4.upload.maximum_data_size=2560 +atmega32u4.upload.speed=57600 +atmega32u4.upload.disable_flushing=true +atmega32u4.upload.use_1200bps_touch=true +atmega32u4.upload.wait_for_upload_port=true +atmega32u4.build.mcu=atmega32u4 +#atmega32u4.build.f_cpu=16000000L +atmega32u4.build.vid=0x6666 +atmega32u4.build.pid=0x60B0 +atmega32u4.build.usb_product="USB IO Board" +atmega32u4.build.usb_manufacturer="ATmega32u4" +atmega32u4.build.board=AVR_LEONARDO +atmega32u4.build.core=arduino:arduino +atmega32u4.build.variant=leonardo +atmega32u4.build.extra_flags={build.usb_flags} -DMOUSE_ABS_ENABLED + + +# ATtiny841 @ internal 8 MHz +attiny841.name=ATtiny841 (8 MHz) +# use Standard Arduino Core +attiny841.menu.core.arduino=Standard Arduino +attiny841.menu.core.arduino.build.core=arduino:arduino +attiny841.menu.core.arduino.build.variant=tiny14 +# use Spence Konde Core: https://github.com/SpenceKonde/arduino-tiny-841/ +attiny841.menu.core.spencekonde=ATtiny841 (by Spence Konde) +#attiny841.menu.core.spencekonde.build.core=arduino-tiny-841:tiny +attiny841.menu.core.spencekonde.build.core=tiny841 +attiny841.menu.core.spencekonde.build.variant=tiny14 +# info menu item +attiny841.menu.info.info=Press Reset, when Uploading is shown. +attiny841.vid.0=0x16D0 +attiny841.pid.0=0x0753 +attiny841.bootloader.tool=avrdude +attiny841.bootloader.low_fuses=0xE2 +attiny841.bootloader.high_fuses=0xDD +attiny841.bootloader.extended_fuses=0xFE +attiny841.bootloader.unlock_bits=0xFF +attiny841.bootloader.lock_bits=0xFF +attiny841.bootloader.file=micronucleus-t841.hex +attiny841.upload.tool=micronucleus +attiny841.upload.protocol=usb +attiny841.upload.wait_for_upload_port=false +attiny841.upload.use_1200bps_touch=false +attiny841.upload.disable_flushing=false +attiny841.upload.maximum_size=6500 +attiny841.build.mcu=attiny841 +attiny841.build.f_cpu=8000000L +attiny841.build.board=AVR_ATTINY841 +#attiny841.build.core=arduino:arduino +#attiny841.build.variant=tiny14 + + +# ATtiny85 @ internal 16.5 MHz +attiny85.name=ATtiny85 (16.5 MHz) +# use Standard Arduino Core +attiny85.menu.core.arduino=Standard Arduino +attiny85.menu.core.arduino.build.board=AVR_ATTINY85 +attiny85.menu.core.arduino.build.core=arduino:arduino +attiny85.menu.core.arduino.build.variant=tiny8 +# use Spence Konde Core: https://github.com/SpenceKonde/ATTinyCore +attiny85.menu.core.spencekonde=ATtiny85 (by Spence Konde) +attiny85.menu.core.spencekonde.build.board=AVR_ATTINY85 +#attiny85.menu.core.spencekonde.build.core=ATTinyCore:tiny +attiny85.menu.core.spencekonde.build.core=tiny85 +attiny85.menu.core.spencekonde.build.variant=tiny8 +# use Digistump Core: https://github.com/digistump/DigistumpArduino +attiny85.menu.core.digistump=Digistump/Digispark +attiny85.menu.core.digistump.build.board=AVR_DIGISPARK +attiny85.menu.core.digistump.build.core=digistump:tiny +attiny85.menu.core.digistump.build.variant=digispark +# info menu item +attiny85.menu.info.info=Press Reset, when Uploading is shown. +attiny85.vid.0=0x16D0 +attiny85.pid.0=0x0753 +attiny85.bootloader.tool=avrdude +attiny85.bootloader.low_fuses=0xE1 +attiny85.bootloader.high_fuses=0xDD +attiny85.bootloader.extended_fuses=0xFE +attiny85.bootloader.unlock_bits=0xFF +attiny85.bootloader.lock_bits=0xFF +attiny85.bootloader.file=micronucleus-t85.hex +attiny85.upload.tool=micronucleus +attiny85.upload.protocol=usb +attiny85.upload.wait_for_upload_port=false +attiny85.upload.use_1200bps_touch=false +attiny85.upload.disable_flushing=false +attiny85.upload.maximum_size=6300 +attiny85.build.mcu=attiny85 +attiny85.build.f_cpu=16500000L +attiny85.build.board=AVR_ATTINY85 +#attiny85.build.core=arduino:arduino +#attiny85.build.variant=tiny8 diff --git a/src/arduino.cc/builder/test/hardware/watterott/avr/platform.txt b/src/arduino.cc/builder/test/hardware/watterott/avr/platform.txt new file mode 100644 index 00000000..13d46cea --- /dev/null +++ b/src/arduino.cc/builder/test/hardware/watterott/avr/platform.txt @@ -0,0 +1,146 @@ + +# Watterott AVR Core and platform. +# ------------------------------ +# +# For more info: +# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification + +name=Watterott AVR Boards +version=1.0.0 + +# AVR compile variables +# --------------------- + +compiler.warning_flags=-w +compiler.warning_flags.none=-w +compiler.warning_flags.default= +compiler.warning_flags.more=-Wall +compiler.warning_flags.all=-Wall -Wextra + +# Default "compiler.path" is correct, change only if you want to overidde the initial value +#compiler.path={runtime.ide.path}/hardware/tools/avr/bin/ +compiler.path={runtime.tools.avr-gcc.path}/bin/ +compiler.c.cmd=avr-gcc +compiler.c.flags=-c -g -Os {compiler.warning_flags} -ffunction-sections -fdata-sections -MMD +# -w flag added to avoid printing a wrong warning http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59396 +# This is fixed in gcc 4.8.3 and will be removed as soon as we update the toolchain +compiler.c.elf.flags=-Os {compiler.warning_flags} -Wl,--gc-sections +compiler.c.elf.cmd=avr-gcc +compiler.S.flags=-c -g -x assembler-with-cpp +compiler.cpp.cmd=avr-g++ +compiler.cpp.flags=-c -g -Os {compiler.warning_flags} -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD +compiler.ar.cmd=avr-ar +compiler.ar.flags=rcs +compiler.objcopy.cmd=avr-objcopy +compiler.objcopy.eep.flags=-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 +compiler.elf2hex.flags=-O ihex -R .eeprom +compiler.elf2hex.cmd=avr-objcopy +compiler.ldflags= +compiler.size.cmd=avr-size + +# This can be overriden in boards.txt +build.extra_flags= + +# These can be overridden in platform.local.txt +compiler.c.extra_flags= +compiler.c.elf.extra_flags= +compiler.S.extra_flags= +compiler.cpp.extra_flags= +compiler.ar.extra_flags= +compiler.objcopy.eep.extra_flags= +compiler.elf2hex.extra_flags= + +# AVR compile patterns +# -------------------- + +## Compile c files +recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" + +## Compile c++ files +recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" + +## Compile S files +recipe.S.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.S.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" + +## Create archives +recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{build.path}/{archive_file}" "{object_file}" + +## Combine gc-sections, archives, and objects +recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mmcu={build.mcu} {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -lm + +## Create output files (.eep and .hex) +recipe.objcopy.eep.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.objcopy.eep.flags} {compiler.objcopy.eep.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.eep" +recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex" + +## Save hex +recipe.output.tmp_file={build.project_name}.hex +recipe.output.save_file={build.project_name}.{build.variant}.hex + +## Compute size +recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" +recipe.size.regex=^(?:\.text|\.data|\.bootloader)\s+([0-9]+).* +recipe.size.regex.data=^(?:\.data|\.bss|\.noinit)\s+([0-9]+).* +recipe.size.regex.eeprom=^(?:\.eeprom)\s+([0-9]+).* + +## Preprocessor +preproc.includes.flags=-w -x c++ -M -MG -MP +recipe.preproc.includes="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.includes.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" +preproc.macros.flags=-w -x c++ -E -CC +recipe.preproc.macros="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.macros.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" + + +# AVR Uploader/Programmers tools +# ------------------------------ + +## AVRdude +#tools.avrdude.path={runtime.ide.path}/hardware/tools/avr/ +tools.avrdude.path={runtime.tools.avrdude.path} +tools.avrdude.cmd.path={path}/bin/avrdude +#tools.avrdude.config.path={path}/etc/avrdude.conf +tools.avrdude.config.path={runtime.platform.path}/tools/avrdude.conf + +tools.avrdude.upload.params.verbose=-v +tools.avrdude.upload.params.quiet=-q -q +tools.avrdude.upload.pattern="{cmd.path}" "-C{config.path}" {upload.verbose} -p{build.mcu} -c{upload.protocol} -P{serial.port} -b{upload.speed} -D "-Uflash:w:{build.path}/{build.project_name}.hex:i" + +tools.avrdude.program.params.verbose=-v +tools.avrdude.program.params.quiet=-q -q +tools.avrdude.program.pattern="{cmd.path}" "-C{config.path}" {program.verbose} -p{build.mcu} -c{protocol} -P{serial.port} {program.extra_params} "-Uflash:w:{build.path}/{build.project_name}.hex:i" + +tools.avrdude.erase.params.verbose=-v +tools.avrdude.erase.params.quiet=-q -q +tools.avrdude.erase.pattern="{cmd.path}" "-C{config.path}" {erase.verbose} -p{build.mcu} -c{protocol} -P{serial.port} {program.extra_params} -e -Ulock:w:{bootloader.unlock_bits}:m -Uefuse:w:{bootloader.extended_fuses}:m -Uhfuse:w:{bootloader.high_fuses}:m -Ulfuse:w:{bootloader.low_fuses}:m + +tools.avrdude.bootloader.params.verbose=-v +tools.avrdude.bootloader.params.quiet=-q -q +tools.avrdude.bootloader.pattern="{cmd.path}" "-C{config.path}" {bootloader.verbose} -p{build.mcu} -c{protocol} -P{serial.port} {program.extra_params} "-Uflash:w:{runtime.platform.path}/bootloaders/{bootloader.file}:i" -Ulock:w:{bootloader.lock_bits}:m + +## Micronucleus +tools.micronucleus.path={runtime.tools.micronucleus.path} +tools.micronucleus.cmd=micronucleus +tools.micronucleus.cmd.windows=micronucleus.exe + +tools.micronucleus.upload.params.verbose= +tools.micronucleus.upload.params.quiet= +tools.micronucleus.upload.pattern="{path}/{cmd}" --run --timeout 60 "{build.path}/{build.project_name}.hex" + +tools.micronucleus.program.params.verbose= +tools.micronucleus.program.params.quiet= +tools.micronucleus.program.pattern="{path}/{cmd}" --run --timeout 60 "{build.path}/{build.project_name}.hex" + +tools.micronucleus.erase.params.verbose= +tools.micronucleus.erase.params.quiet= +tools.micronucleus.erase.pattern= +#tools.micronucleus.erase.pattern="{path}/{cmd}" --erase-only --timeout 60 + +tools.micronucleus.bootloader.params.verbose= +tools.micronucleus.bootloader.params.quiet= +tools.micronucleus.bootloader.pattern="{path}/{cmd}" --run --timeout 60 "{runtime.platform.path}/bootloaders/{bootloader.file}" + + +# USB Default Flags +# Default blank usb manufacturer will be filled it at compile time +# - from numeric vendor ID, set to Unknown otherwise +build.usb_manufacturer="Unknown" +build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' + diff --git a/src/arduino.cc/builder/test/hardware/watterott/avr/programmers.txt b/src/arduino.cc/builder/test/hardware/watterott/avr/programmers.txt new file mode 100644 index 00000000..e69de29b diff --git a/src/arduino.cc/builder/test/hardware_loader_test.go b/src/arduino.cc/builder/test/hardware_loader_test.go index 27d7ad9f..948b1bcb 100644 --- a/src/arduino.cc/builder/test/hardware_loader_test.go +++ b/src/arduino.cc/builder/test/hardware_loader_test.go @@ -55,7 +55,7 @@ func TestLoadHardware(t *testing.T) { } packages := context[constants.CTX_HARDWARE].(*types.Packages) - require.Equal(t, 1, len(packages.Packages)) + require.Equal(t, 2, len(packages.Packages)) require.NotNil(t, packages.Packages["arduino"]) require.Equal(t, 2, len(packages.Packages["arduino"].Platforms)) @@ -105,9 +105,9 @@ func TestLoadHardwareMixingUserHardwareFolder(t *testing.T) { if runtime.GOOS == "windows" { //a package is a symlink, and windows does not support them - require.Equal(t, 2, len(packages.Packages)) - } else { require.Equal(t, 3, len(packages.Packages)) + } else { + require.Equal(t, 4, len(packages.Packages)) } require.NotNil(t, packages.Packages["arduino"]) @@ -222,9 +222,9 @@ func TestLoadLotsOfHardware(t *testing.T) { if runtime.GOOS == "windows" { //a package is a symlink, and windows does not support them - require.Equal(t, 4, len(packages.Packages)) - } else { require.Equal(t, 5, len(packages.Packages)) + } else { + require.Equal(t, 6, len(packages.Packages)) } require.NotNil(t, packages.Packages["arduino"]) diff --git a/src/arduino.cc/builder/test/target_board_resolver_test.go b/src/arduino.cc/builder/test/target_board_resolver_test.go index 1836346e..19268b26 100644 --- a/src/arduino.cc/builder/test/target_board_resolver_test.go +++ b/src/arduino.cc/builder/test/target_board_resolver_test.go @@ -165,3 +165,29 @@ func TestTargetBoardResolverCustomYun(t *testing.T) { require.Equal(t, "atmega32u4", targetBoard.Properties[constants.BUILD_PROPERTIES_BUILD_MCU]) require.Equal(t, "AVR_YUN", targetBoard.Properties[constants.BUILD_PROPERTIES_BUILD_BOARD]) } + +func TestTargetBoardResolverCustomCore(t *testing.T) { + context := make(map[string]interface{}) + context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware", "user_hardware"} + context[constants.CTX_FQBN] = "watterott:avr:attiny841:core=spencekonde,info=info" + + commands := []types.Command{ + &builder.SetupHumanLoggerIfMissing{}, + &builder.HardwareLoader{}, + &builder.TargetBoardResolver{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + targetPackage := context[constants.CTX_TARGET_PACKAGE].(*types.Package) + require.Equal(t, "watterott", targetPackage.PackageId) + targetPlatform := context[constants.CTX_TARGET_PLATFORM].(*types.Platform) + require.Equal(t, "avr", targetPlatform.PlatformId) + targetBoard := context[constants.CTX_TARGET_BOARD].(*types.Board) + require.Equal(t, "attiny841", targetBoard.BoardId) + require.Equal(t, "tiny841", context[constants.CTX_BUILD_CORE].(string)) + require.Equal(t, "tiny14", targetBoard.Properties[constants.BUILD_PROPERTIES_BUILD_VARIANT]) +} From 5246463746acd563eaa926a143890dd9f332765d Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Fri, 6 Nov 2015 15:48:01 +0100 Subject: [PATCH 11/85] Releasing 1.1.1 Signed-off-by: Federico Fissore --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index edd104a0..95322b6c 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,7 @@ import ( "syscall" ) -const VERSION = "1.1.0" +const VERSION = "1.1.1" const FLAG_ACTION_COMPILE = "compile" const FLAG_ACTION_PREPROCESS = "preprocess" From 70099c87e936fcb9e34f14fa2d67a54a49d43f90 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 9 Nov 2015 10:47:33 +0100 Subject: [PATCH 12/85] Updating AVR, SAM and SAMD cores to the latest; updating related tests as well Signed-off-by: Federico Fissore --- src/arduino.cc/builder/test/builder_test.go | 2 +- .../builder/test/helper_tools_downloader.go | 82 +++++++++++++++---- .../builder/test/libraries_loader_test.go | 8 +- .../test/setup_build_properties_test.go | 8 +- .../builder/test/tools_loader_test.go | 35 ++++---- 5 files changed, 99 insertions(+), 36 deletions(-) diff --git a/src/arduino.cc/builder/test/builder_test.go b/src/arduino.cc/builder/test/builder_test.go index 979c7a8d..0ffce3c9 100644 --- a/src/arduino.cc/builder/test/builder_test.go +++ b/src/arduino.cc/builder/test/builder_test.go @@ -201,7 +201,7 @@ func TestBuilderBridgeSAM(t *testing.T) { _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_CORE, "syscalls_sam3.c.o")) NoError(t, err) - _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_CORE, "USB", "HID.cpp.o")) + _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_CORE, "USB", "PluggableUSB.cpp.o")) NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_CORE, "avr", "dtostrf.c.d")) NoError(t, err) diff --git a/src/arduino.cc/builder/test/helper_tools_downloader.go b/src/arduino.cc/builder/test/helper_tools_downloader.go index 88db48fa..2faa271a 100644 --- a/src/arduino.cc/builder/test/helper_tools_downloader.go +++ b/src/arduino.cc/builder/test/helper_tools_downloader.go @@ -84,22 +84,25 @@ type Core struct { func DownloadCoresAndToolsAndLibraries(t *testing.T) { cores := []Core{ - Core{Maintainer: "arduino", Arch: "avr", Version: "1.6.8"}, - Core{Maintainer: "arduino", Arch: "sam", Version: "1.6.4"}, + Core{Maintainer: "arduino", Arch: "avr", Version: "1.6.9"}, + Core{Maintainer: "arduino", Arch: "sam", Version: "1.6.5"}, } boardsManagerCores := []Core{ - Core{Maintainer: "arduino", Arch: "samd", Version: "1.6.1"}, + Core{Maintainer: "arduino", Arch: "samd", Version: "1.6.2"}, } boardsManagerRedBearCores := []Core{ Core{Maintainer: "RedBearLab", Arch: "avr", Version: "1.0.0", Url: "https://redbearlab.github.io/arduino/Blend/blend_boards.zip"}, } + toolsMultipleVersions := []Tool{ + Tool{Name: "bossac", Version: "1.6.1-arduino"}, + Tool{Name: "bossac", Version: "1.5-arduino"}, + } + tools := []Tool{ Tool{Name: "avrdude", Version: "6.0.1-arduino5"}, - Tool{Name: "bossac", Version: "1.3a-arduino"}, - Tool{Name: "bossac", Version: "1.5-arduino"}, Tool{Name: "avr-gcc", Version: "4.8.1-arduino5"}, Tool{Name: "arm-none-eabi-gcc", Version: "4.8.3-2014q1"}, Tool{Name: "coan", Version: "5.2", OsUrls: []OsUrl{ @@ -133,7 +136,7 @@ func DownloadCoresAndToolsAndLibraries(t *testing.T) { Library{Name: "Robot IR Remote", Version: "1.0.2"}, } - download(t, cores, boardsManagerCores, boardsManagerRedBearCores, tools, boardsManagerTools, boardsManagerRFduinoTools, libraries) + download(t, cores, boardsManagerCores, boardsManagerRedBearCores, tools, toolsMultipleVersions, boardsManagerTools, boardsManagerRFduinoTools, libraries) patchFiles(t) } @@ -157,7 +160,7 @@ func patchFiles(t *testing.T) { } } -func download(t *testing.T, cores, boardsManagerCores, boardsManagerRedBearCores []Core, tools, boardsManagerTools, boardsManagerRFduinoTools []Tool, libraries []Library) { +func download(t *testing.T, cores, boardsManagerCores, boardsManagerRedBearCores []Core, tools, toolsMultipleVersions, boardsManagerTools, boardsManagerRFduinoTools []Tool, libraries []Library) { allCoresDownloaded, err := allCoresAlreadyDownloadedAndUnpacked(HARDWARE_FOLDER, cores) NoError(t, err) if allCoresDownloaded && @@ -166,6 +169,7 @@ func download(t *testing.T, cores, boardsManagerCores, boardsManagerRedBearCores allBoardsManagerToolsAlreadyDownloadedAndUnpacked(BOARD_MANAGER_FOLDER, boardsManagerTools) && allBoardsManagerToolsAlreadyDownloadedAndUnpacked(BOARD_MANAGER_FOLDER, boardsManagerRFduinoTools) && allToolsAlreadyDownloadedAndUnpacked(TOOLS_FOLDER, tools) && + allToolsAlreadyDownloadedAndUnpacked(TOOLS_FOLDER, toolsMultipleVersions) && allLibrariesAlreadyDownloadedAndUnpacked(LIBRARIES_FOLDER, libraries) { return } @@ -182,6 +186,9 @@ func download(t *testing.T, cores, boardsManagerCores, boardsManagerRedBearCores err = downloadTools(tools, index) NoError(t, err) + err = downloadToolsMultipleVersions(toolsMultipleVersions, index) + NoError(t, err) + err = downloadBoardsManagerTools(boardsManagerTools, index) NoError(t, err) @@ -279,7 +286,36 @@ func downloadTools(tools []Tool, index map[string]interface{}) error { if err != nil { return utils.WrapError(err) } - err = downloadAndUnpackTool(tool, url, TOOLS_FOLDER) + err = downloadAndUnpackTool(tool, url, TOOLS_FOLDER, true) + if err != nil { + return utils.WrapError(err) + } + } + + return nil +} + +func downloadToolsMultipleVersions(tools []Tool, index map[string]interface{}) error { + host := translateGOOSGOARCHToPackageIndexValue() + + for _, tool := range tools { + if !toolAlreadyDownloadedAndUnpacked(TOOLS_FOLDER, tool) { + _, err := os.Stat(filepath.Join(TOOLS_FOLDER, tool.Name)) + if err == nil { + err = os.RemoveAll(filepath.Join(TOOLS_FOLDER, tool.Name)) + if err != nil { + return utils.WrapError(err) + } + } + } + } + + for _, tool := range tools { + url, err := findToolUrl(index, tool, host) + if err != nil { + return utils.WrapError(err) + } + err = downloadAndUnpackTool(tool, url, TOOLS_FOLDER, false) if err != nil { return utils.WrapError(err) } @@ -422,6 +458,14 @@ func downloadAndUnpackCore(core Core, url string, targetPath string) error { } defer os.RemoveAll(unpackFolder) + _, err = os.Stat(filepath.Join(targetPath, core.Maintainer, core.Arch)) + if err == nil { + err = os.RemoveAll(filepath.Join(targetPath, core.Maintainer, core.Arch)) + if err != nil { + return utils.WrapError(err) + } + } + if len(files) == 1 && files[0].IsDir() { err = os.MkdirAll(filepath.Join(targetPath, core.Maintainer), os.FileMode(0755)) if err != nil { @@ -463,6 +507,14 @@ func downloadAndUnpackBoardManagerCore(core Core, url string, targetPath string) } defer os.RemoveAll(unpackFolder) + _, err = os.Stat(filepath.Join(targetPath, core.Maintainer, "hardware", core.Arch)) + if err == nil { + err = os.RemoveAll(filepath.Join(targetPath, core.Maintainer, "hardware", core.Arch)) + if err != nil { + return utils.WrapError(err) + } + } + if len(files) == 1 && files[0].IsDir() { err = os.MkdirAll(filepath.Join(targetPath, core.Maintainer, "hardware", core.Arch), os.FileMode(0755)) if err != nil { @@ -529,7 +581,7 @@ func downloadAndUnpackBoardsManagerTool(tool Tool, url string, targetPath string return nil } -func downloadAndUnpackTool(tool Tool, url string, targetPath string) error { +func downloadAndUnpackTool(tool Tool, url string, targetPath string, deleteIfMissing bool) error { if toolAlreadyDownloadedAndUnpacked(targetPath, tool) { return nil } @@ -545,11 +597,13 @@ func downloadAndUnpackTool(tool Tool, url string, targetPath string) error { } defer os.RemoveAll(unpackFolder) - _, err = os.Stat(filepath.Join(targetPath, tool.Name)) - if err == nil { - err = os.RemoveAll(filepath.Join(targetPath, tool.Name)) - if err != nil { - return utils.WrapError(err) + if deleteIfMissing { + _, err = os.Stat(filepath.Join(targetPath, tool.Name)) + if err == nil { + err = os.RemoveAll(filepath.Join(targetPath, tool.Name)) + if err != nil { + return utils.WrapError(err) + } } } diff --git a/src/arduino.cc/builder/test/libraries_loader_test.go b/src/arduino.cc/builder/test/libraries_loader_test.go index ea895417..bd4ba608 100644 --- a/src/arduino.cc/builder/test/libraries_loader_test.go +++ b/src/arduino.cc/builder/test/libraries_loader_test.go @@ -69,7 +69,7 @@ func TestLoadLibrariesAVR(t *testing.T) { require.Equal(t, Abs(t, filepath.Join("libraries")), librariesFolders[2]) libraries := context[constants.CTX_LIBRARIES].([]*types.Library) - require.Equal(t, 16, len(libraries)) + require.Equal(t, 17, len(libraries)) sort.Sort(ByLibraryName(libraries)) @@ -109,6 +109,8 @@ func TestLoadLibrariesAVR(t *testing.T) { idx++ require.Equal(t, "FakeAudio", libraries[idx].Name) idx++ + require.Equal(t, "HID", libraries[idx].Name) + idx++ require.Equal(t, "IRremote", libraries[idx].Name) idx++ require.Equal(t, "Robot_IR_Remote", libraries[idx].Name) @@ -173,7 +175,7 @@ func TestLoadLibrariesSAM(t *testing.T) { require.Equal(t, Abs(t, filepath.Join("libraries")), librariesFolders[2]) libraries := context[constants.CTX_LIBRARIES].([]*types.Library) - require.Equal(t, 14, len(libraries)) + require.Equal(t, 15, len(libraries)) sort.Sort(ByLibraryName(libraries)) @@ -192,6 +194,8 @@ func TestLoadLibrariesSAM(t *testing.T) { idx++ require.Equal(t, "FakeAudio", libraries[idx].Name) idx++ + require.Equal(t, "HID", libraries[idx].Name) + idx++ require.Equal(t, "IRremote", libraries[idx].Name) idx++ require.Equal(t, "Robot_IR_Remote", libraries[idx].Name) diff --git a/src/arduino.cc/builder/test/setup_build_properties_test.go b/src/arduino.cc/builder/test/setup_build_properties_test.go index 16e9bcf6..d63f87ec 100644 --- a/src/arduino.cc/builder/test/setup_build_properties_test.go +++ b/src/arduino.cc/builder/test/setup_build_properties_test.go @@ -87,9 +87,9 @@ func TestSetupBuildProperties(t *testing.T) { require.Equal(t, Abs(t, "./downloaded_tools/arm-none-eabi-gcc/4.8.3-2014q1"), buildProperties["runtime.tools.arm-none-eabi-gcc.path"]) require.Equal(t, Abs(t, "./downloaded_tools/arm-none-eabi-gcc/4.8.3-2014q1"), buildProperties["runtime.tools.arm-none-eabi-gcc-4.8.3-2014q1.path"]) - require.Equal(t, Abs(t, "./downloaded_tools/bossac/1.3a-arduino"), buildProperties["runtime.tools.bossac-1.3a-arduino.path"]) + require.Equal(t, Abs(t, "./downloaded_tools/bossac/1.6.1-arduino"), buildProperties["runtime.tools.bossac-1.6.1-arduino.path"]) require.Equal(t, Abs(t, "./downloaded_tools/bossac/1.5-arduino"), buildProperties["runtime.tools.bossac-1.5-arduino.path"]) - require.True(t, buildProperties["runtime.tools.bossac.path"] == Abs(t, "./downloaded_tools/bossac/1.3a-arduino") || buildProperties["runtime.tools.bossac.path"] == Abs(t, "./downloaded_tools/bossac/1.5-arduino")) + require.True(t, buildProperties["runtime.tools.bossac.path"] == Abs(t, "./downloaded_tools/bossac/1.6.1-arduino") || buildProperties["runtime.tools.bossac.path"] == Abs(t, "./downloaded_tools/bossac/1.5-arduino")) require.Equal(t, Abs(t, "./downloaded_tools/avrdude/6.0.1-arduino5"), buildProperties["runtime.tools.avrdude.path"]) require.Equal(t, Abs(t, "./downloaded_tools/avrdude/6.0.1-arduino5"), buildProperties["runtime.tools.avrdude-6.0.1-arduino5.path"]) require.Equal(t, Abs(t, "./downloaded_tools/avr-gcc/4.8.1-arduino5"), buildProperties["runtime.tools.avr-gcc.path"]) @@ -228,9 +228,9 @@ func TestSetupBuildPropertiesWithMissingPropsFromParentPlatformTxtFiles(t *testi require.Equal(t, Abs(t, "./downloaded_tools/arm-none-eabi-gcc/4.8.3-2014q1"), buildProperties["runtime.tools.arm-none-eabi-gcc.path"]) require.Equal(t, Abs(t, "./downloaded_tools/arm-none-eabi-gcc/4.8.3-2014q1"), buildProperties["runtime.tools.arm-none-eabi-gcc-4.8.3-2014q1.path"]) - require.Equal(t, Abs(t, "./downloaded_tools/bossac/1.3a-arduino"), buildProperties["runtime.tools.bossac-1.3a-arduino.path"]) + require.Equal(t, Abs(t, "./downloaded_tools/bossac/1.6.1-arduino"), buildProperties["runtime.tools.bossac-1.6.1-arduino.path"]) require.Equal(t, Abs(t, "./downloaded_tools/bossac/1.5-arduino"), buildProperties["runtime.tools.bossac-1.5-arduino.path"]) - require.True(t, buildProperties["runtime.tools.bossac.path"] == Abs(t, "./downloaded_tools/bossac/1.3a-arduino") || buildProperties["runtime.tools.bossac.path"] == Abs(t, "./downloaded_tools/bossac/1.5-arduino")) + require.True(t, buildProperties["runtime.tools.bossac.path"] == Abs(t, "./downloaded_tools/bossac/1.6.1-arduino") || buildProperties["runtime.tools.bossac.path"] == Abs(t, "./downloaded_tools/bossac/1.5-arduino")) require.Equal(t, Abs(t, "./downloaded_tools/avrdude/6.0.1-arduino5"), buildProperties["runtime.tools.avrdude.path"]) require.Equal(t, Abs(t, "./downloaded_tools/avrdude/6.0.1-arduino5"), buildProperties["runtime.tools.avrdude-6.0.1-arduino5.path"]) require.Equal(t, Abs(t, "./downloaded_tools/avr-gcc/4.8.1-arduino5"), buildProperties["runtime.tools.avr-gcc.path"]) diff --git a/src/arduino.cc/builder/test/tools_loader_test.go b/src/arduino.cc/builder/test/tools_loader_test.go index 1b03437e..c3d7a18c 100644 --- a/src/arduino.cc/builder/test/tools_loader_test.go +++ b/src/arduino.cc/builder/test/tools_loader_test.go @@ -68,21 +68,26 @@ func TestLoadTools(t *testing.T) { sort.Sort(ByToolIDAndVersion(tools)) - require.Equal(t, "arm-none-eabi-gcc", tools[0].Name) - require.Equal(t, "4.8.3-2014q1", tools[0].Version) - require.Equal(t, Abs(t, "./downloaded_tools/arm-none-eabi-gcc/4.8.3-2014q1"), tools[0].Folder) - require.Equal(t, "avr-gcc", tools[1].Name) - require.Equal(t, "4.8.1-arduino5", tools[1].Version) - require.Equal(t, Abs(t, "./downloaded_tools/avr-gcc/4.8.1-arduino5"), tools[1].Folder) - require.Equal(t, "avrdude", tools[2].Name) - require.Equal(t, "6.0.1-arduino5", tools[2].Version) - require.Equal(t, Abs(t, "./downloaded_tools/avrdude/6.0.1-arduino5"), tools[2].Folder) - require.Equal(t, "bossac", tools[3].Name) - require.Equal(t, "1.3a-arduino", tools[3].Version) - require.Equal(t, Abs(t, "./downloaded_tools/bossac/1.3a-arduino"), tools[3].Folder) - require.Equal(t, "bossac", tools[4].Name) - require.Equal(t, "1.5-arduino", tools[4].Version) - require.Equal(t, Abs(t, "./downloaded_tools/bossac/1.5-arduino"), tools[4].Folder) + idx := 0 + require.Equal(t, "arm-none-eabi-gcc", tools[idx].Name) + require.Equal(t, "4.8.3-2014q1", tools[idx].Version) + require.Equal(t, Abs(t, "./downloaded_tools/arm-none-eabi-gcc/4.8.3-2014q1"), tools[idx].Folder) + idx++ + require.Equal(t, "avr-gcc", tools[idx].Name) + require.Equal(t, "4.8.1-arduino5", tools[idx].Version) + require.Equal(t, Abs(t, "./downloaded_tools/avr-gcc/4.8.1-arduino5"), tools[idx].Folder) + idx++ + require.Equal(t, "avrdude", tools[idx].Name) + require.Equal(t, "6.0.1-arduino5", tools[idx].Version) + require.Equal(t, Abs(t, "./downloaded_tools/avrdude/6.0.1-arduino5"), tools[idx].Folder) + idx++ + require.Equal(t, "bossac", tools[idx].Name) + require.Equal(t, "1.5-arduino", tools[idx].Version) + require.Equal(t, Abs(t, "./downloaded_tools/bossac/1.5-arduino"), tools[idx].Folder) + idx++ + require.Equal(t, "bossac", tools[idx].Name) + require.Equal(t, "1.6.1-arduino", tools[idx].Version) + require.Equal(t, Abs(t, "./downloaded_tools/bossac/1.6.1-arduino"), tools[idx].Folder) } func TestLoadToolsWithBoardManagerFolderStructure(t *testing.T) { From bfe2e9c54a057f00f618c3ccf5b7b8b89976446f Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 9 Nov 2015 11:30:39 +0100 Subject: [PATCH 13/85] Collecting prototype modifiers in Modifiers struct key Signed-off-by: Federico Fissore --- src/arduino.cc/builder/ctags_parser.go | 7 +++++-- src/arduino.cc/builder/prototypes_adder.go | 13 +++++++++---- src/arduino.cc/builder/test/ctags_parser_test.go | 3 ++- src/arduino.cc/builder/types/types.go | 1 + 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/arduino.cc/builder/ctags_parser.go b/src/arduino.cc/builder/ctags_parser.go index 1cf4be19..d42810ec 100644 --- a/src/arduino.cc/builder/ctags_parser.go +++ b/src/arduino.cc/builder/ctags_parser.go @@ -49,6 +49,7 @@ const FIELD_NAMESPACE = "namespace" const FIELD_SKIP = "skipMe" const KIND_PROTOTYPE = "prototype" +const KIND_PROTOTYPE_MODIFIERS = "prototype_modifiers" const TEMPLATE = "template" const STATIC = "static" @@ -98,7 +99,7 @@ func toPrototypes(tags []map[string]string) []*types.Prototype { prototypes := []*types.Prototype{} for _, tag := range tags { if tag[FIELD_SKIP] != "true" { - ctag := types.Prototype{FunctionName: tag[FIELD_FUNCTION_NAME], Prototype: tag[KIND_PROTOTYPE], Fields: tag} + ctag := types.Prototype{FunctionName: tag[FIELD_FUNCTION_NAME], Prototype: tag[KIND_PROTOTYPE], Modifiers: tag[KIND_PROTOTYPE_MODIFIERS], Fields: tag} prototypes = append(prototypes, &ctag) } } @@ -126,9 +127,11 @@ func addPrototype(tag map[string]string) { tag[KIND_PROTOTYPE] = tag[FIELD_RETURNTYPE] + " " + tag[FIELD_FUNCTION_NAME] + tag[FIELD_SIGNATURE] + ";" + tag[KIND_PROTOTYPE_MODIFIERS] = "" if strings.Index(tag[FIELD_CODE], STATIC+" ") != -1 { - tag[KIND_PROTOTYPE] = STATIC + " " + tag[KIND_PROTOTYPE] + tag[KIND_PROTOTYPE_MODIFIERS] = tag[KIND_PROTOTYPE_MODIFIERS] + " " + STATIC } + tag[KIND_PROTOTYPE_MODIFIERS] = strings.TrimSpace(tag[KIND_PROTOTYPE_MODIFIERS]) } func removeDefinedProtypes(tags []map[string]string) []map[string]string { diff --git a/src/arduino.cc/builder/prototypes_adder.go b/src/arduino.cc/builder/prototypes_adder.go index d550f239..b0da6d04 100644 --- a/src/arduino.cc/builder/prototypes_adder.go +++ b/src/arduino.cc/builder/prototypes_adder.go @@ -75,7 +75,7 @@ func composePrototypeSection(line int, prototypes []*types.Prototype) string { } str := joinPrototypes(prototypes) - str += "#line " + str += "\n#line " str += strconv.Itoa(line) str += "\n" @@ -83,11 +83,16 @@ func composePrototypeSection(line int, prototypes []*types.Prototype) string { } func joinPrototypes(prototypes []*types.Prototype) string { - join := "" + prototypesSlice := []string{} for _, proto := range prototypes { - join = join + proto.Prototype + "\n" + prototypeParts := []string{} + if proto.Modifiers != "" { + prototypeParts = append(prototypeParts, proto.Modifiers) + } + prototypeParts = append(prototypeParts, proto.Prototype) + prototypesSlice = append(prototypesSlice, strings.Join(prototypeParts, " ")) } - return join + return strings.Join(prototypesSlice, "\n") } func composeIncludeArduinoSection() string { diff --git a/src/arduino.cc/builder/test/ctags_parser_test.go b/src/arduino.cc/builder/test/ctags_parser_test.go index 22faecd6..382aab12 100644 --- a/src/arduino.cc/builder/test/ctags_parser_test.go +++ b/src/arduino.cc/builder/test/ctags_parser_test.go @@ -260,5 +260,6 @@ func TestCTagsParserStatic(t *testing.T) { require.Equal(t, 3, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) require.Equal(t, "void loop();", prototypes[1].Prototype) - require.Equal(t, "static void doStuff();", prototypes[2].Prototype) + require.Equal(t, "void doStuff();", prototypes[2].Prototype) + require.Equal(t, "static", prototypes[2].Modifiers) } diff --git a/src/arduino.cc/builder/types/types.go b/src/arduino.cc/builder/types/types.go index 22cf2693..d9169657 100644 --- a/src/arduino.cc/builder/types/types.go +++ b/src/arduino.cc/builder/types/types.go @@ -154,6 +154,7 @@ type Command interface { type Prototype struct { FunctionName string Prototype string + Modifiers string Fields map[string]string } From de7d31e6ac49d3a80c1fc54589876d552e3d2e71 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 9 Nov 2015 11:36:35 +0100 Subject: [PATCH 14/85] "quiet", not "quite" (facepalm) Signed-off-by: Federico Fissore --- README.md | 2 +- main.go | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index aa8dcd4c..ac8846d3 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ This tool generates function prototypes and gathers library paths, providing `gc * `-verbose`: Optional, turns on verbose mode. -* `-quite`: Optional, supresses almost every output. +* `-quiet`: Optional, supresses almost every output. * `-debug-level`: Optional, defaults to "5". Used for debugging. Set it to 10 when submitting an issue. diff --git a/main.go b/main.go index 95322b6c..f02c55f5 100644 --- a/main.go +++ b/main.go @@ -62,7 +62,7 @@ const FLAG_FQBN = "fqbn" const FLAG_IDE_VERSION = "ide-version" const FLAG_BUILD_PATH = "build-path" const FLAG_VERBOSE = "verbose" -const FLAG_QUITE = "quite" +const FLAG_QUIET = "quiet" const FLAG_DEBUG_LEVEL = "debug-level" const FLAG_WARNINGS = "warnings" const FLAG_WARNINGS_NONE = "none" @@ -111,7 +111,7 @@ var fqbnFlag *string var ideVersionFlag *string var buildPathFlag *string var verboseFlag *bool -var quiteFlag *bool +var quietFlag *bool var debugLevelFlag *int var libraryDiscoveryRecursionDepthFlag *int var warningsLevelFlag *string @@ -133,7 +133,7 @@ func init() { ideVersionFlag = flag.String(FLAG_IDE_VERSION, "10600", "fake IDE version") buildPathFlag = flag.String(FLAG_BUILD_PATH, "", "build path") verboseFlag = flag.Bool(FLAG_VERBOSE, false, "if 'true' prints lots of stuff") - quiteFlag = flag.Bool(FLAG_QUITE, false, "if 'true' doesn't print any warnings or progress or whatever") + quietFlag = flag.Bool(FLAG_QUIET, false, "if 'true' doesn't print any warnings or progress or whatever") debugLevelFlag = flag.Int(FLAG_DEBUG_LEVEL, builder.DEFAULT_DEBUG_LEVEL, "Turns on debugging messages. The higher, the chattier") warningsLevelFlag = flag.String(FLAG_WARNINGS, "", "Sets warnings level. Available values are '"+FLAG_WARNINGS_NONE+"', '"+FLAG_WARNINGS_DEFAULT+"', '"+FLAG_WARNINGS_MORE+"' and '"+FLAG_WARNINGS_ALL+"'") loggerFlag = flag.String(FLAG_LOGGER, FLAG_LOGGER_HUMAN, "Sets type of logger. Available values are '"+FLAG_LOGGER_HUMAN+"', '"+FLAG_LOGGER_MACHINE+"'") @@ -269,9 +269,9 @@ func main() { context[constants.CTX_SKETCH_LOCATION] = sketchLocation } - if *verboseFlag && *quiteFlag { + if *verboseFlag && *quietFlag { *verboseFlag = false - *quiteFlag = false + *quietFlag = false } context[constants.CTX_VERBOSE] = *verboseFlag @@ -296,7 +296,7 @@ func main() { context[constants.CTX_LIBRARY_DISCOVERY_RECURSION_DEPTH] = *libraryDiscoveryRecursionDepthFlag } - if *quiteFlag { + if *quietFlag { context[constants.CTX_LOGGER] = i18n.NoopLogger{} } else if *loggerFlag == FLAG_LOGGER_MACHINE { context[constants.CTX_LOGGER] = i18n.MachineLogger{} From 3081e1973756894034ccec3324aafdf1be82e42a Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Thu, 8 Oct 2015 12:22:59 +0200 Subject: [PATCH 15/85] Comparing prototypes with original functions. If they don't match, prototype is skipped Signed-off-by: Federico Fissore --- src/arduino.cc/builder/ctags_parser.go | 19 +++++++++++++++++++ .../TestCTagsParserFunctionPointers.txt | 5 +++++ .../builder/test/ctags_parser_test.go | 18 ++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 src/arduino.cc/builder/test/ctags_output/TestCTagsParserFunctionPointers.txt diff --git a/src/arduino.cc/builder/ctags_parser.go b/src/arduino.cc/builder/ctags_parser.go index d42810ec..d7d7c493 100644 --- a/src/arduino.cc/builder/ctags_parser.go +++ b/src/arduino.cc/builder/ctags_parser.go @@ -79,6 +79,7 @@ func (s *CTagsParser) Run(context map[string]interface{}) error { tags = addPrototypes(tags) tags = removeDefinedProtypes(tags) tags = removeDuplicate(tags) + tags = skipTagsWhere(tags, prototypeAndCodeDontMatch) if len(tags) > 0 { line, err := strconv.Atoi(tags[0][FIELD_LINE]) @@ -181,6 +182,24 @@ func signatureContainsDefaultArg(tag map[string]string) bool { return strings.Contains(tag[FIELD_SIGNATURE], "=") } +func prototypeAndCodeDontMatch(tag map[string]string) bool { + if tag[FIELD_SKIP] == "true" { + return true + } + + code := removeSpacesAndTabs(tag[FIELD_CODE]) + prototype := removeSpacesAndTabs(tag[KIND_PROTOTYPE]) + prototype = prototype[0 : len(prototype)-1] + + return strings.Index(code, prototype) == -1 +} + +func removeSpacesAndTabs(s string) string { + s = strings.Replace(s, " ", "", -1) + s = strings.Replace(s, "\t", "", -1) + return s +} + func filterOutTagsWithField(tags []map[string]string, field string) []map[string]string { var newTags []map[string]string for _, tag := range tags { diff --git a/src/arduino.cc/builder/test/ctags_output/TestCTagsParserFunctionPointers.txt b/src/arduino.cc/builder/test/ctags_output/TestCTagsParserFunctionPointers.txt new file mode 100644 index 00000000..0aa1e06a --- /dev/null +++ b/src/arduino.cc/builder/test/ctags_output/TestCTagsParserFunctionPointers.txt @@ -0,0 +1,5 @@ +setup /tmp/test907446433/preproc/ctags_target.cpp /^void setup(){$/;" kind:function line:2 signature:() returntype:void +loop /tmp/test907446433/preproc/ctags_target.cpp /^void loop(){}$/;" kind:function line:5 signature:() returntype:void +func /tmp/test907446433/preproc/ctags_target.cpp /^void (*func())(){$/;" kind:function line:7 signature:() returntype:void +funcArr /tmp/test907446433/preproc/ctags_target.cpp /^int (&funcArr())[5]{$/;" kind:function line:11 signature:() returntype:int +funcCombo /tmp/test907446433/preproc/ctags_target.cpp /^void (*(&funcCombo(void (*(&in)[5])(int)))[5])(int){$/;" kind:function line:15 signature:(void (*(&in)[5])(int)) returntype:void diff --git a/src/arduino.cc/builder/test/ctags_parser_test.go b/src/arduino.cc/builder/test/ctags_parser_test.go index 382aab12..8b84e259 100644 --- a/src/arduino.cc/builder/test/ctags_parser_test.go +++ b/src/arduino.cc/builder/test/ctags_parser_test.go @@ -263,3 +263,21 @@ func TestCTagsParserStatic(t *testing.T) { require.Equal(t, "void doStuff();", prototypes[2].Prototype) require.Equal(t, "static", prototypes[2].Modifiers) } + +func TestCTagsParserFunctionPointers(t *testing.T) { + context := make(map[string]interface{}) + + bytes, err := ioutil.ReadFile(filepath.Join("ctags_output", "TestCTagsParserFunctionPointers.txt")) + NoError(t, err) + + context[constants.CTX_CTAGS_OUTPUT] = string(bytes) + + ctagsParser := builder.CTagsParser{PrototypesField: constants.CTX_PROTOTYPES} + ctagsParser.Run(context) + + prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) + + require.Equal(t, 2, len(prototypes)) + require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "void loop();", prototypes[1].Prototype) +} From 951f1f920028fbf4fdbdcc5c29560c62e55c5e1a Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Thu, 8 Oct 2015 14:57:07 +0200 Subject: [PATCH 16/85] Extracted function for readability Signed-off-by: Federico Fissore --- src/arduino.cc/builder/ctags_parser.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/arduino.cc/builder/ctags_parser.go b/src/arduino.cc/builder/ctags_parser.go index d7d7c493..512b48bf 100644 --- a/src/arduino.cc/builder/ctags_parser.go +++ b/src/arduino.cc/builder/ctags_parser.go @@ -189,11 +189,15 @@ func prototypeAndCodeDontMatch(tag map[string]string) bool { code := removeSpacesAndTabs(tag[FIELD_CODE]) prototype := removeSpacesAndTabs(tag[KIND_PROTOTYPE]) - prototype = prototype[0 : len(prototype)-1] + prototype = removeTralingSemicolon(prototype) return strings.Index(code, prototype) == -1 } +func removeTralingSemicolon(s string) string { + return s[0 : len(s)-1] +} + func removeSpacesAndTabs(s string) string { s = strings.Replace(s, " ", "", -1) s = strings.Replace(s, "\t", "", -1) From 45b586513f9f9e8079aa12048d192604009e3523 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 27 Oct 2015 18:23:27 +0100 Subject: [PATCH 17/85] Testing that prototype of a function containing a typename is not generated Signed-off-by: Federico Fissore --- .../builder/test/prototypes_adder_test.go | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/arduino.cc/builder/test/prototypes_adder_test.go b/src/arduino.cc/builder/test/prototypes_adder_test.go index d483d0f3..8777ffd4 100644 --- a/src/arduino.cc/builder/test/prototypes_adder_test.go +++ b/src/arduino.cc/builder/test/prototypes_adder_test.go @@ -658,3 +658,43 @@ func TestPrototypesAdderSketchWithUSBCON(t *testing.T) { require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) require.Equal(t, "void ciao();\nvoid setup();\nvoid loop();\n#line 3\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) } + +func TestPrototypesAdderSketchWithTypename(t *testing.T) { + DownloadCoresAndToolsAndLibraries(t) + + context := make(map[string]interface{}) + + buildPath := SetupBuildPath(t, context) + defer os.RemoveAll(buildPath) + + context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} + context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} + context[constants.CTX_FQBN] = "arduino:avr:leonardo" + context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_typename", "sketch.ino") + context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" + context[constants.CTX_LIBRARIES_FOLDERS] = []string{"libraries", "downloaded_libraries"} + context[constants.CTX_VERBOSE] = true + + commands := []types.Command{ + &builder.SetupHumanLoggerIfMissing{}, + + &builder.ContainerSetupHardwareToolsLibsSketchAndProps{}, + + &builder.ContainerMergeCopySketchFiles{}, + + &builder.ContainerFindIncludes{}, + + &builder.PrintUsedLibrariesIfVerbose{}, + &builder.WarnAboutArchIncompatibleLibraries{}, + + &builder.ContainerAddPrototypes{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) + require.Equal(t, "void setup();\nvoid loop();\n#line 6\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) +} From 9199f50459ef6c93e672375e3f7ee9b6b73d7e15 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 9 Nov 2015 15:19:49 +0100 Subject: [PATCH 18/85] If code line contains a function pointer (eg: &functionName), then prototypes are written above that line. Mitigates #50 Signed-off-by: Federico Fissore --- src/arduino.cc/builder/constants/constants.go | 2 +- src/arduino.cc/builder/ctags_parser.go | 155 ++++++++++++------ src/arduino.cc/builder/prototypes_adder.go | 4 +- .../TestCTagsParserFunctionPointer.txt | 4 + .../builder/test/ctags_parser_test.go | 61 +++++++ .../sketch_with_function_pointer/sketch.ino | 4 + src/arduino.cc/builder/types/types.go | 4 + 7 files changed, 184 insertions(+), 50 deletions(-) create mode 100644 src/arduino.cc/builder/test/ctags_output/TestCTagsParserFunctionPointer.txt create mode 100644 src/arduino.cc/builder/test/sketch_with_function_pointer/sketch.ino diff --git a/src/arduino.cc/builder/constants/constants.go b/src/arduino.cc/builder/constants/constants.go index 48e9cd32..87cfe210 100644 --- a/src/arduino.cc/builder/constants/constants.go +++ b/src/arduino.cc/builder/constants/constants.go @@ -88,7 +88,7 @@ const CTX_CTAGS_OUTPUT = "ctagsOutput" const CTX_CTAGS_TEMP_FILE_NAME = "ctagsTempFileName" const CTX_CUSTOM_BUILD_PROPERTIES = "customBuildProperties" const CTX_DEBUG_LEVEL = "debugLevel" -const CTX_FIRST_FUNCTION_AT_LINE = "firstFunctionAtLine" +const CTX_LINE_WHERE_TO_INSERT_PROTOTYPES = "lineWhereToInsertPrototypes" const CTX_FOLDERS_WITH_SOURCES_QUEUE = "foldersWithSourcesQueue" const CTX_FQBN = "fqbn" const CTX_GCC_MINUS_E_SOURCE = "gccMinusESource" diff --git a/src/arduino.cc/builder/ctags_parser.go b/src/arduino.cc/builder/ctags_parser.go index 512b48bf..0fb6730e 100644 --- a/src/arduino.cc/builder/ctags_parser.go +++ b/src/arduino.cc/builder/ctags_parser.go @@ -49,13 +49,16 @@ const FIELD_NAMESPACE = "namespace" const FIELD_SKIP = "skipMe" const KIND_PROTOTYPE = "prototype" +const KIND_FUNCTION = "function" const KIND_PROTOTYPE_MODIFIERS = "prototype_modifiers" const TEMPLATE = "template" const STATIC = "static" +const TRUE = "true" var FIELDS = map[string]bool{"kind": true, "line": true, "typeref": true, "signature": true, "returntype": true, "class": true, "struct": true, "namespace": true} var KNOWN_TAG_KINDS = map[string]bool{"prototype": true, "function": true} +var FIELDS_MARKING_UNHANDLED_TAGS = []string{FIELD_CLASS, FIELD_STRUCT, FIELD_NAMESPACE} type CTagsParser struct { PrototypesField string @@ -71,22 +74,20 @@ func (s *CTagsParser) Run(context map[string]interface{}) error { tags = append(tags, parseTag(row)) } - tags = filterOutUnknownTags(tags) - tags = filterOutTagsWithField(tags, FIELD_CLASS) - tags = filterOutTagsWithField(tags, FIELD_STRUCT) - tags = filterOutTagsWithField(tags, FIELD_NAMESPACE) - tags = skipTagsWhere(tags, signatureContainsDefaultArg) - tags = addPrototypes(tags) - tags = removeDefinedProtypes(tags) - tags = removeDuplicate(tags) - tags = skipTagsWhere(tags, prototypeAndCodeDontMatch) - - if len(tags) > 0 { - line, err := strconv.Atoi(tags[0][FIELD_LINE]) - if err != nil { - return utils.WrapError(err) - } - context[constants.CTX_FIRST_FUNCTION_AT_LINE] = line + skipTagsWhere(tags, tagIsUnknown) + skipTagsWithField(tags, FIELDS_MARKING_UNHANDLED_TAGS) + skipTagsWhere(tags, signatureContainsDefaultArg) + addPrototypes(tags) + removeDefinedProtypes(tags) + removeDuplicate(tags) + skipTagsWhere(tags, prototypeAndCodeDontMatch) + + lineWhereToInsertPrototypes, err := findLineWhereToInsertPrototypes(tags) + if err != nil { + return utils.WrapError(err) + } + if lineWhereToInsertPrototypes != -1 { + context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES] = lineWhereToInsertPrototypes } prototypes := toPrototypes(tags) @@ -96,10 +97,70 @@ func (s *CTagsParser) Run(context map[string]interface{}) error { return nil } +func findLineWhereToInsertPrototypes(tags []map[string]string) (int, error) { + firstFunctionLine, err := firstFunctionAtLine(tags) + if err != nil { + return -1, utils.WrapError(err) + } + firstFunctionPointerAsArgument, err := firstFunctionPointerUsedAsArgument(tags) + if err != nil { + return -1, utils.WrapError(err) + } + if firstFunctionLine != -1 && firstFunctionPointerAsArgument != -1 { + if firstFunctionLine < firstFunctionPointerAsArgument { + return firstFunctionLine, nil + } else { + return firstFunctionPointerAsArgument, nil + } + } else if firstFunctionLine == -1 { + return firstFunctionPointerAsArgument, nil + } else { + return firstFunctionLine, nil + } +} + +func firstFunctionPointerUsedAsArgument(tags []map[string]string) (int, error) { + functionNames := collectFunctionNames(tags) + for _, tag := range tags { + if functionNameUsedAsFunctionPointerIn(tag, functionNames) { + return strconv.Atoi(tag[FIELD_LINE]) + } + } + return -1, nil +} + +func functionNameUsedAsFunctionPointerIn(tag map[string]string, functionNames []string) bool { + for _, functionName := range functionNames { + if strings.Index(tag[FIELD_CODE], "&"+functionName) != -1 { + return true + } + } + return false +} + +func collectFunctionNames(tags []map[string]string) []string { + names := []string{} + for _, tag := range tags { + if tag[FIELD_KIND] == KIND_FUNCTION { + names = append(names, tag[FIELD_FUNCTION_NAME]) + } + } + return names +} + +func firstFunctionAtLine(tags []map[string]string) (int, error) { + for _, tag := range tags { + if !tagIsUnknown(tag) && !tagHasAtLeastOneField(tag, FIELDS_MARKING_UNHANDLED_TAGS) && tag[FIELD_KIND] == KIND_FUNCTION { + return strconv.Atoi(tag[FIELD_LINE]) + } + } + return -1, nil +} + func toPrototypes(tags []map[string]string) []*types.Prototype { prototypes := []*types.Prototype{} for _, tag := range tags { - if tag[FIELD_SKIP] != "true" { + if tag[FIELD_SKIP] != TRUE { ctag := types.Prototype{FunctionName: tag[FIELD_FUNCTION_NAME], Prototype: tag[KIND_PROTOTYPE], Modifiers: tag[KIND_PROTOTYPE_MODIFIERS], Fields: tag} prototypes = append(prototypes, &ctag) } @@ -107,11 +168,12 @@ func toPrototypes(tags []map[string]string) []*types.Prototype { return prototypes } -func addPrototypes(tags []map[string]string) []map[string]string { +func addPrototypes(tags []map[string]string) { for _, tag := range tags { - addPrototype(tag) + if tag[FIELD_SKIP] != TRUE { + addPrototype(tag) + } } - return tags } func addPrototype(tag map[string]string) { @@ -135,7 +197,7 @@ func addPrototype(tag map[string]string) { tag[KIND_PROTOTYPE_MODIFIERS] = strings.TrimSpace(tag[KIND_PROTOTYPE_MODIFIERS]) } -func removeDefinedProtypes(tags []map[string]string) []map[string]string { +func removeDefinedProtypes(tags []map[string]string) { definedPrototypes := make(map[string]bool) for _, tag := range tags { if tag[FIELD_KIND] == KIND_PROTOTYPE { @@ -143,39 +205,37 @@ func removeDefinedProtypes(tags []map[string]string) []map[string]string { } } - var newTags []map[string]string for _, tag := range tags { - if !definedPrototypes[tag[KIND_PROTOTYPE]] { - newTags = append(newTags, tag) + if definedPrototypes[tag[KIND_PROTOTYPE]] { + tag[FIELD_SKIP] = TRUE } } - return newTags } -func removeDuplicate(tags []map[string]string) []map[string]string { +func removeDuplicate(tags []map[string]string) { definedPrototypes := make(map[string]bool) - var newTags []map[string]string for _, tag := range tags { if !definedPrototypes[tag[KIND_PROTOTYPE]] { - newTags = append(newTags, tag) definedPrototypes[tag[KIND_PROTOTYPE]] = true + } else { + tag[FIELD_SKIP] = TRUE } } - return newTags } type skipFuncType func(tag map[string]string) bool -func skipTagsWhere(tags []map[string]string, skipFuncs ...skipFuncType) []map[string]string { +func skipTagsWhere(tags []map[string]string, skipFuncs ...skipFuncType) { for _, tag := range tags { - skip := skipFuncs[0](tag) - for _, skipFunc := range skipFuncs[1:] { - skip = skip || skipFunc(tag) + if tag[FIELD_SKIP] != TRUE { + skip := skipFuncs[0](tag) + for _, skipFunc := range skipFuncs[1:] { + skip = skip || skipFunc(tag) + } + tag[FIELD_SKIP] = strconv.FormatBool(skip) } - tag[FIELD_SKIP] = strconv.FormatBool(skip) } - return tags } func signatureContainsDefaultArg(tag map[string]string) bool { @@ -183,7 +243,7 @@ func signatureContainsDefaultArg(tag map[string]string) bool { } func prototypeAndCodeDontMatch(tag map[string]string) bool { - if tag[FIELD_SKIP] == "true" { + if tag[FIELD_SKIP] == TRUE { return true } @@ -204,24 +264,25 @@ func removeSpacesAndTabs(s string) string { return s } -func filterOutTagsWithField(tags []map[string]string, field string) []map[string]string { - var newTags []map[string]string +func skipTagsWithField(tags []map[string]string, fields []string) { for _, tag := range tags { - if tag[field] == constants.EMPTY_STRING { - newTags = append(newTags, tag) + if tagHasAtLeastOneField(tag, fields) { + tag[FIELD_SKIP] = TRUE } } - return newTags } -func filterOutUnknownTags(tags []map[string]string) []map[string]string { - var newTags []map[string]string - for _, tag := range tags { - if KNOWN_TAG_KINDS[tag[FIELD_KIND]] { - newTags = append(newTags, tag) +func tagHasAtLeastOneField(tag map[string]string, fields []string) bool { + for _, field := range fields { + if tag[field] != constants.EMPTY_STRING { + return true } } - return newTags + return false +} + +func tagIsUnknown(tag map[string]string) bool { + return !KNOWN_TAG_KINDS[tag[FIELD_KIND]] } func parseTag(row string) map[string]string { diff --git a/src/arduino.cc/builder/prototypes_adder.go b/src/arduino.cc/builder/prototypes_adder.go index b0da6d04..70252b09 100644 --- a/src/arduino.cc/builder/prototypes_adder.go +++ b/src/arduino.cc/builder/prototypes_adder.go @@ -43,11 +43,11 @@ func (s *PrototypesAdder) Run(context map[string]interface{}) error { source := context[constants.CTX_SOURCE].(string) sourceRows := strings.Split(source, "\n") - if !utils.MapHas(context, constants.CTX_FIRST_FUNCTION_AT_LINE) { + if !utils.MapHas(context, constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES) { return nil } - firstFunctionLine := context[constants.CTX_FIRST_FUNCTION_AT_LINE].(int) + firstFunctionLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) if firstFunctionOutsideOfSource(firstFunctionLine, sourceRows) { return nil } diff --git a/src/arduino.cc/builder/test/ctags_output/TestCTagsParserFunctionPointer.txt b/src/arduino.cc/builder/test/ctags_output/TestCTagsParserFunctionPointer.txt new file mode 100644 index 00000000..b36c5928 --- /dev/null +++ b/src/arduino.cc/builder/test/ctags_output/TestCTagsParserFunctionPointer.txt @@ -0,0 +1,4 @@ +t1Callback /tmp/test547238273/preproc/ctags_target.cpp /^Task t1(&t1Callback);$/;" kind:variable line:2 +t1Callback /tmp/test547238273/preproc/ctags_target.cpp /^void t1Callback() {}$/;" kind:function line:3 signature:() returntype:void +setup /tmp/test547238273/preproc/ctags_target.cpp /^void setup() {}$/;" kind:function line:4 signature:() returntype:void +loop /tmp/test547238273/preproc/ctags_target.cpp /^void loop() {}$/;" kind:function line:5 signature:() returntype:void diff --git a/src/arduino.cc/builder/test/ctags_parser_test.go b/src/arduino.cc/builder/test/ctags_parser_test.go index 8b84e259..d99e1e6b 100644 --- a/src/arduino.cc/builder/test/ctags_parser_test.go +++ b/src/arduino.cc/builder/test/ctags_parser_test.go @@ -58,6 +58,9 @@ func TestCTagsParserShouldListPrototypes(t *testing.T) { require.Equal(t, "void digitalCommand(YunClient client);", prototypes[2].Prototype) require.Equal(t, "void analogCommand(YunClient client);", prototypes[3].Prototype) require.Equal(t, "void modeCommand(YunClient client);", prototypes[4].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 33, prototypeLine) } func TestCTagsParserShouldListTemplates(t *testing.T) { @@ -77,6 +80,9 @@ func TestCTagsParserShouldListTemplates(t *testing.T) { require.Equal(t, "template T minimum (T a, T b);", prototypes[0].Prototype) require.Equal(t, "void setup();", prototypes[1].Prototype) require.Equal(t, "void loop();", prototypes[2].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 2, prototypeLine) } func TestCTagsParserShouldListTemplates2(t *testing.T) { @@ -97,6 +103,9 @@ func TestCTagsParserShouldListTemplates2(t *testing.T) { require.Equal(t, "void loop();", prototypes[1].Prototype) require.Equal(t, "template int SRAM_writeAnything(int ee, const T& value);", prototypes[2].Prototype) require.Equal(t, "template int SRAM_readAnything(int ee, T& value);", prototypes[3].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 1, prototypeLine) } func TestCTagsParserShouldDealWithClasses(t *testing.T) { @@ -113,6 +122,9 @@ func TestCTagsParserShouldDealWithClasses(t *testing.T) { prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) require.Equal(t, 0, len(prototypes)) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 8, prototypeLine) } func TestCTagsParserShouldDealWithStructs(t *testing.T) { @@ -132,6 +144,9 @@ func TestCTagsParserShouldDealWithStructs(t *testing.T) { require.Equal(t, "void setup();", prototypes[0].Prototype) require.Equal(t, "void loop();", prototypes[1].Prototype) require.Equal(t, "void dostuff(A_NEW_TYPE * bar);", prototypes[2].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 9, prototypeLine) } func TestCTagsParserShouldDealWithMacros(t *testing.T) { @@ -153,6 +168,9 @@ func TestCTagsParserShouldDealWithMacros(t *testing.T) { require.Equal(t, "void debug();", prototypes[2].Prototype) require.Equal(t, "void disabledIsDefined();", prototypes[3].Prototype) require.Equal(t, "int useMyType(MyType type);", prototypes[4].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 18, prototypeLine) } func TestCTagsParserShouldDealFunctionWithDifferentSignatures(t *testing.T) { @@ -170,6 +188,9 @@ func TestCTagsParserShouldDealFunctionWithDifferentSignatures(t *testing.T) { require.Equal(t, 1, len(prototypes)) require.Equal(t, "boolean getBytes( byte addr, int amount );", prototypes[0].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 5031, prototypeLine) } func TestCTagsParserClassMembersAreFilteredOut(t *testing.T) { @@ -188,6 +209,9 @@ func TestCTagsParserClassMembersAreFilteredOut(t *testing.T) { require.Equal(t, 2, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) require.Equal(t, "void loop();", prototypes[1].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 14, prototypeLine) } func TestCTagsParserStructWithFunctions(t *testing.T) { @@ -206,6 +230,9 @@ func TestCTagsParserStructWithFunctions(t *testing.T) { require.Equal(t, 2, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) require.Equal(t, "void loop();", prototypes[1].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 16, prototypeLine) } func TestCTagsParserDefaultArguments(t *testing.T) { @@ -224,6 +251,9 @@ func TestCTagsParserDefaultArguments(t *testing.T) { require.Equal(t, 2, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) require.Equal(t, "void loop();", prototypes[1].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 2, prototypeLine) } func TestCTagsParserNamespace(t *testing.T) { @@ -242,6 +272,9 @@ func TestCTagsParserNamespace(t *testing.T) { require.Equal(t, 2, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) require.Equal(t, "void loop();", prototypes[1].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 8, prototypeLine) } func TestCTagsParserStatic(t *testing.T) { @@ -262,6 +295,31 @@ func TestCTagsParserStatic(t *testing.T) { require.Equal(t, "void loop();", prototypes[1].Prototype) require.Equal(t, "void doStuff();", prototypes[2].Prototype) require.Equal(t, "static", prototypes[2].Modifiers) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 2, prototypeLine) +} + +func TestCTagsParserFunctionPointer(t *testing.T) { + context := make(map[string]interface{}) + + bytes, err := ioutil.ReadFile(filepath.Join("ctags_output", "TestCTagsParserFunctionPointer.txt")) + NoError(t, err) + + context[constants.CTX_CTAGS_OUTPUT] = string(bytes) + + ctagsParser := builder.CTagsParser{PrototypesField: constants.CTX_PROTOTYPES} + ctagsParser.Run(context) + + prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) + + require.Equal(t, 3, len(prototypes)) + require.Equal(t, "void t1Callback();", prototypes[0].Prototype) + require.Equal(t, "void setup();", prototypes[1].Prototype) + require.Equal(t, "void loop();", prototypes[2].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 2, prototypeLine) } func TestCTagsParserFunctionPointers(t *testing.T) { @@ -280,4 +338,7 @@ func TestCTagsParserFunctionPointers(t *testing.T) { require.Equal(t, 2, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) require.Equal(t, "void loop();", prototypes[1].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 2, prototypeLine) } diff --git a/src/arduino.cc/builder/test/sketch_with_function_pointer/sketch.ino b/src/arduino.cc/builder/test/sketch_with_function_pointer/sketch.ino new file mode 100644 index 00000000..a758f4e2 --- /dev/null +++ b/src/arduino.cc/builder/test/sketch_with_function_pointer/sketch.ino @@ -0,0 +1,4 @@ +Task t1(&t1Callback); +void t1Callback() {} +void setup() {} +void loop() {} \ No newline at end of file diff --git a/src/arduino.cc/builder/types/types.go b/src/arduino.cc/builder/types/types.go index d9169657..546d1197 100644 --- a/src/arduino.cc/builder/types/types.go +++ b/src/arduino.cc/builder/types/types.go @@ -158,6 +158,10 @@ type Prototype struct { Fields map[string]string } +func (proto *Prototype) String() string { + return proto.Modifiers + " " + proto.Prototype +} + type SourceFolder struct { Folder string Recurse bool From 1c13cc8eb9a643b024b1e244ddc1b8392979c352 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 9 Nov 2015 16:02:38 +0100 Subject: [PATCH 19/85] Releasing 1.1.2 Signed-off-by: Federico Fissore --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index f02c55f5..ff473c6e 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,7 @@ import ( "syscall" ) -const VERSION = "1.1.1" +const VERSION = "1.1.2" const FLAG_ACTION_COMPILE = "compile" const FLAG_ACTION_PREPROCESS = "preprocess" From 40328a0a169b2d3cbc5f42348b134d4782f66ca9 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 10 Nov 2015 11:05:01 +0100 Subject: [PATCH 20/85] Reviewed how prototypes are generated and ctags output is parsed: - added --line-directives to ctags command line: makes "line" fields aware of #line directives (thanks @matthijskooijman for the hint) - prototypes get generated after ctags are produced for both gcc -E output and original sketch. This allows to consider functions used in callbacks. See #50 - each prototype is preceded by #line directives that points to its function. This allows error in function declarations themselves to be properly reported to the IDE - split ctags target files (added "ctags_target_for_gcc_minus_e.cpp") for easier debugging Signed-off-by: Federico Fissore --- ...ototypes_from_source_and_preproc_source.go | 15 +- src/arduino.cc/builder/constants/constants.go | 11 +- .../builder/container_add_prototypes.go | 9 +- src/arduino.cc/builder/ctags_parser.go | 92 +--- .../builder/ctags_target_file_saver.go | 3 +- src/arduino.cc/builder/ctags_to_prototypes.go | 99 ++++ src/arduino.cc/builder/hardware/platform.txt | 2 +- src/arduino.cc/builder/prototypes_adder.go | 6 +- src/arduino.cc/builder/test/builder_test.go | 12 + .../builder/test/ctags_parser_test.go | 395 ++++++++++------ .../builder/test/ctags_runner_test.go | 66 +-- .../builder/test/ctags_to_prototypes_test.go | 442 ++++++++++++++++++ .../builder/test/hardware/platform.txt | 2 +- .../builder/test/hardware_loader_test.go | 4 +- .../builder/test/prototypes_adder_test.go | 72 ++- .../sketch2/SketchWithIfDef.preprocessed.txt | 5 + .../test/sketch3/Baladuino.preprocessed.txt | 2 + ...harWithEscapedDoubleQuote.preprocessed.txt | 21 + ...deBetweenMultilineComment.preprocessed.txt | 2 + .../LineContinuations.preprocessed.txt | 2 + .../StringWithComment.preprocessed.txt | 2 + .../sketch8/SketchWithStruct.preprocessed.txt | 3 + .../sketch_with_config.preprocessed.txt | 2 + .../builder/test/sketch_with_ifdef/sketch.ino | 17 + .../sketch_with_ifdef/sketch.preprocessed.txt | 31 ++ src/arduino.cc/builder/types/types.go | 3 +- src/arduino.cc/builder/utils/utils.go | 4 +- 27 files changed, 1027 insertions(+), 297 deletions(-) create mode 100644 src/arduino.cc/builder/ctags_to_prototypes.go create mode 100644 src/arduino.cc/builder/test/ctags_to_prototypes_test.go create mode 100644 src/arduino.cc/builder/test/sketch_with_ifdef/sketch.ino create mode 100644 src/arduino.cc/builder/test/sketch_with_ifdef/sketch.preprocessed.txt diff --git a/src/arduino.cc/builder/compare_prototypes_from_source_and_preproc_source.go b/src/arduino.cc/builder/compare_prototypes_from_source_and_preproc_source.go index 35556e91..48a90b63 100644 --- a/src/arduino.cc/builder/compare_prototypes_from_source_and_preproc_source.go +++ b/src/arduino.cc/builder/compare_prototypes_from_source_and_preproc_source.go @@ -31,24 +31,23 @@ package builder import ( "arduino.cc/builder/constants" - "arduino.cc/builder/types" "arduino.cc/builder/utils" ) type ComparePrototypesFromSourceAndPreprocSource struct{} func (s *ComparePrototypesFromSourceAndPreprocSource) Run(context map[string]interface{}) error { - prototypesOfSource := context[constants.CTX_PROTOTYPES_OF_SOURCE].([]*types.Prototype) - prototypesOfPreprocSource := context[constants.CTX_PROTOTYPES_OF_PREPROC_SOURCE].([]*types.Prototype) + ctagsOfSource := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + ctagsOfPreprocSource := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) - actualPrototypes := []*types.Prototype{} - for _, prototypeOfPreprocSource := range prototypesOfPreprocSource { - if utils.SliceContainsPrototype(prototypesOfSource, prototypeOfPreprocSource) { - actualPrototypes = append(actualPrototypes, prototypeOfPreprocSource) + actualCTags := []map[string]string{} + for _, ctagOfPreprocSource := range ctagsOfPreprocSource { + if utils.SliceContainsCTag(ctagsOfSource, ctagOfPreprocSource) { + actualCTags = append(actualCTags, ctagOfPreprocSource) } } - context[constants.CTX_PROTOTYPES] = actualPrototypes + context[constants.CTX_COLLECTED_CTAGS] = actualCTags return nil } diff --git a/src/arduino.cc/builder/constants/constants.go b/src/arduino.cc/builder/constants/constants.go index 87cfe210..ac528958 100644 --- a/src/arduino.cc/builder/constants/constants.go +++ b/src/arduino.cc/builder/constants/constants.go @@ -72,6 +72,7 @@ const BUILD_PROPERTIES_TOOLS_KEY = "tools" const BUILD_PROPERTIES_VID = "vid" const COAN = "coan" const CTAGS = "ctags" +const CTAGS_FIELD_FUNCTION_NAME = "functionName" const CTX_ACTUAL_PLATFORM = "actualPlatform" const CTX_ARCHIVE_FILE_PATH_CORE = "archiveFileCore" const CTX_BUILD_CORE = "buildCore" @@ -82,13 +83,15 @@ const CTX_BUILD_PATH = "buildPath" const CTX_BUILD_PROPERTIES = "buildProperties" const CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION = "runtime.ide.version" const CTX_BUILT_IN_LIBRARIES_FOLDERS = "builtInLibrariesFolders" +const CTX_COLLECTED_CTAGS = "collectedCTags" const CTX_COLLECTED_SOURCE_FILES_QUEUE = "collectedSourceFilesQueue" const CTX_CORE_BUILD_PATH = "coreBuildPath" +const CTX_CTAGS_OF_PREPROC_SOURCE = "ctagsOfPreprocSource" +const CTX_CTAGS_OF_SOURCE = "ctagsOfSource" const CTX_CTAGS_OUTPUT = "ctagsOutput" const CTX_CTAGS_TEMP_FILE_NAME = "ctagsTempFileName" const CTX_CUSTOM_BUILD_PROPERTIES = "customBuildProperties" const CTX_DEBUG_LEVEL = "debugLevel" -const CTX_LINE_WHERE_TO_INSERT_PROTOTYPES = "lineWhereToInsertPrototypes" const CTX_FOLDERS_WITH_SOURCES_QUEUE = "foldersWithSourcesQueue" const CTX_FQBN = "fqbn" const CTX_GCC_MINUS_E_SOURCE = "gccMinusESource" @@ -106,6 +109,9 @@ const CTX_LIBRARIES = "libraries" const CTX_LIBRARY_DISCOVERY_RECURSION_DEPTH = "libraryDiscoveryRecursionDepth" const CTX_LIBRARY_RESOLUTION_RESULTS = "libraryResolutionResults" const CTX_LINE_OFFSET = "lineOffset" +const CTX_LINE_WHERE_TO_INSERT_PROTOTYPES = "lineWhereToInsertPrototypes" +const CTX_LINE_WHERE_TO_INSERT_PROTOTYPES_OF_PREPROC_SOURCE = "lineWhereToInsertPrototypesOfPreprocSource" +const CTX_LINE_WHERE_TO_INSERT_PROTOTYPES_OF_SOURCE = "lineWhereToInsertPrototypesOfSource" const CTX_LOGGER = "logger" const CTX_OBJECT_FILES_LIBRARIES = "objectFilesLibraries" const CTX_OBJECT_FILES_SKETCH = "objectFilesSketch" @@ -113,8 +119,6 @@ const CTX_OTHER_LIBRARIES_FOLDERS = "otherLibrariesFolders" const CTX_PLATFORM_KEYS_REWRITE = "platformKeysRewrite" const CTX_PREPROC_PATH = "preprocPath" const CTX_PROTOTYPE_SECTION = "prototypeSection" -const CTX_PROTOTYPES_OF_PREPROC_SOURCE = "prototypesOfPreprocSource" -const CTX_PROTOTYPES_OF_SOURCE = "prototypesOfSource" const CTX_PROTOTYPES = "prototypes" const CTX_SKETCH_BUILD_PATH = "sketchBuildPath" const CTX_SKETCH_LOCATION = "sketchLocation" @@ -134,6 +138,7 @@ const FILE_BOARDS_TXT = "boards.txt" const FILE_BUILTIN_TOOLS_VERSIONS_TXT = "builtin_tools_versions.txt" const FILE_COAN_TARGET = "coan_target.cpp" const FILE_CTAGS_TARGET = "ctags_target.cpp" +const FILE_CTAGS_TARGET_FOR_GCC_MINUS_E = "ctags_target_for_gcc_minus_e.cpp" const FILE_GCC_PREPROC_TARGET = "gcc_preproc_target.cpp" const FILE_PLATFORM_KEYS_REWRITE_TXT = "platform.keys.rewrite.txt" const FILE_PLATFORM_LOCAL_TXT = "platform.local.txt" diff --git a/src/arduino.cc/builder/container_add_prototypes.go b/src/arduino.cc/builder/container_add_prototypes.go index 90993e43..7f992c36 100644 --- a/src/arduino.cc/builder/container_add_prototypes.go +++ b/src/arduino.cc/builder/container_add_prototypes.go @@ -40,13 +40,14 @@ type ContainerAddPrototypes struct{} func (s *ContainerAddPrototypes) Run(context map[string]interface{}) error { commands := []types.Command{ &GCCPreprocRunner{}, - &CTagsTargetFileSaver{SourceField: constants.CTX_GCC_MINUS_E_SOURCE}, + &CTagsTargetFileSaver{SourceField: constants.CTX_GCC_MINUS_E_SOURCE, Filename: constants.FILE_CTAGS_TARGET_FOR_GCC_MINUS_E}, &CTagsRunner{}, - &CTagsParser{PrototypesField: constants.CTX_PROTOTYPES_OF_PREPROC_SOURCE}, - &CTagsTargetFileSaver{SourceField: constants.CTX_SOURCE}, + &CTagsParser{CTagsField: constants.CTX_CTAGS_OF_PREPROC_SOURCE}, + &CTagsTargetFileSaver{SourceField: constants.CTX_SOURCE, Filename: constants.FILE_CTAGS_TARGET}, &CTagsRunner{}, - &CTagsParser{PrototypesField: constants.CTX_PROTOTYPES_OF_SOURCE}, + &CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE}, &ComparePrototypesFromSourceAndPreprocSource{}, + &CTagsToPrototypes{}, &PrototypesAdder{}, &SketchSaver{}, } diff --git a/src/arduino.cc/builder/ctags_parser.go b/src/arduino.cc/builder/ctags_parser.go index 0fb6730e..183f1b6b 100644 --- a/src/arduino.cc/builder/ctags_parser.go +++ b/src/arduino.cc/builder/ctags_parser.go @@ -31,8 +31,6 @@ package builder import ( "arduino.cc/builder/constants" - "arduino.cc/builder/types" - "arduino.cc/builder/utils" "strconv" "strings" ) @@ -42,7 +40,6 @@ const FIELD_LINE = "line" const FIELD_SIGNATURE = "signature" const FIELD_RETURNTYPE = "returntype" const FIELD_CODE = "code" -const FIELD_FUNCTION_NAME = "functionName" const FIELD_CLASS = "class" const FIELD_STRUCT = "struct" const FIELD_NAMESPACE = "namespace" @@ -61,7 +58,7 @@ var KNOWN_TAG_KINDS = map[string]bool{"prototype": true, "function": true} var FIELDS_MARKING_UNHANDLED_TAGS = []string{FIELD_CLASS, FIELD_STRUCT, FIELD_NAMESPACE} type CTagsParser struct { - PrototypesField string + CTagsField string } func (s *CTagsParser) Run(context map[string]interface{}) error { @@ -82,92 +79,11 @@ func (s *CTagsParser) Run(context map[string]interface{}) error { removeDuplicate(tags) skipTagsWhere(tags, prototypeAndCodeDontMatch) - lineWhereToInsertPrototypes, err := findLineWhereToInsertPrototypes(tags) - if err != nil { - return utils.WrapError(err) - } - if lineWhereToInsertPrototypes != -1 { - context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES] = lineWhereToInsertPrototypes - } - - prototypes := toPrototypes(tags) - - context[s.PrototypesField] = prototypes + context[s.CTagsField] = tags return nil } -func findLineWhereToInsertPrototypes(tags []map[string]string) (int, error) { - firstFunctionLine, err := firstFunctionAtLine(tags) - if err != nil { - return -1, utils.WrapError(err) - } - firstFunctionPointerAsArgument, err := firstFunctionPointerUsedAsArgument(tags) - if err != nil { - return -1, utils.WrapError(err) - } - if firstFunctionLine != -1 && firstFunctionPointerAsArgument != -1 { - if firstFunctionLine < firstFunctionPointerAsArgument { - return firstFunctionLine, nil - } else { - return firstFunctionPointerAsArgument, nil - } - } else if firstFunctionLine == -1 { - return firstFunctionPointerAsArgument, nil - } else { - return firstFunctionLine, nil - } -} - -func firstFunctionPointerUsedAsArgument(tags []map[string]string) (int, error) { - functionNames := collectFunctionNames(tags) - for _, tag := range tags { - if functionNameUsedAsFunctionPointerIn(tag, functionNames) { - return strconv.Atoi(tag[FIELD_LINE]) - } - } - return -1, nil -} - -func functionNameUsedAsFunctionPointerIn(tag map[string]string, functionNames []string) bool { - for _, functionName := range functionNames { - if strings.Index(tag[FIELD_CODE], "&"+functionName) != -1 { - return true - } - } - return false -} - -func collectFunctionNames(tags []map[string]string) []string { - names := []string{} - for _, tag := range tags { - if tag[FIELD_KIND] == KIND_FUNCTION { - names = append(names, tag[FIELD_FUNCTION_NAME]) - } - } - return names -} - -func firstFunctionAtLine(tags []map[string]string) (int, error) { - for _, tag := range tags { - if !tagIsUnknown(tag) && !tagHasAtLeastOneField(tag, FIELDS_MARKING_UNHANDLED_TAGS) && tag[FIELD_KIND] == KIND_FUNCTION { - return strconv.Atoi(tag[FIELD_LINE]) - } - } - return -1, nil -} - -func toPrototypes(tags []map[string]string) []*types.Prototype { - prototypes := []*types.Prototype{} - for _, tag := range tags { - if tag[FIELD_SKIP] != TRUE { - ctag := types.Prototype{FunctionName: tag[FIELD_FUNCTION_NAME], Prototype: tag[KIND_PROTOTYPE], Modifiers: tag[KIND_PROTOTYPE_MODIFIERS], Fields: tag} - prototypes = append(prototypes, &ctag) - } - } - return prototypes -} - func addPrototypes(tags []map[string]string) { for _, tag := range tags { if tag[FIELD_SKIP] != TRUE { @@ -188,7 +104,7 @@ func addPrototype(tag map[string]string) { return } - tag[KIND_PROTOTYPE] = tag[FIELD_RETURNTYPE] + " " + tag[FIELD_FUNCTION_NAME] + tag[FIELD_SIGNATURE] + ";" + tag[KIND_PROTOTYPE] = tag[FIELD_RETURNTYPE] + " " + tag[constants.CTAGS_FIELD_FUNCTION_NAME] + tag[FIELD_SIGNATURE] + ";" tag[KIND_PROTOTYPE_MODIFIERS] = "" if strings.Index(tag[FIELD_CODE], STATIC+" ") != -1 { @@ -289,7 +205,7 @@ func parseTag(row string) map[string]string { tag := make(map[string]string) parts := strings.Split(row, "\t") - tag[FIELD_FUNCTION_NAME] = parts[0] + tag[constants.CTAGS_FIELD_FUNCTION_NAME] = parts[0] parts = parts[1:] for _, part := range parts { diff --git a/src/arduino.cc/builder/ctags_target_file_saver.go b/src/arduino.cc/builder/ctags_target_file_saver.go index c98467ab..e97dbd95 100644 --- a/src/arduino.cc/builder/ctags_target_file_saver.go +++ b/src/arduino.cc/builder/ctags_target_file_saver.go @@ -39,6 +39,7 @@ import ( type CTagsTargetFileSaver struct { SourceField string + Filename string } func (s *CTagsTargetFileSaver) Run(context map[string]interface{}) error { @@ -50,7 +51,7 @@ func (s *CTagsTargetFileSaver) Run(context map[string]interface{}) error { return utils.WrapError(err) } - ctagsTargetFileName := filepath.Join(preprocPath, constants.FILE_CTAGS_TARGET) + ctagsTargetFileName := filepath.Join(preprocPath, s.Filename) err = ioutil.WriteFile(ctagsTargetFileName, []byte(source), os.FileMode(0644)) if err != nil { return utils.WrapError(err) diff --git a/src/arduino.cc/builder/ctags_to_prototypes.go b/src/arduino.cc/builder/ctags_to_prototypes.go new file mode 100644 index 00000000..4c9fdc77 --- /dev/null +++ b/src/arduino.cc/builder/ctags_to_prototypes.go @@ -0,0 +1,99 @@ +package builder + +import ( + "arduino.cc/builder/constants" + "arduino.cc/builder/types" + "arduino.cc/builder/utils" + "strconv" + "strings" +) + +type CTagsToPrototypes struct{} + +func (s *CTagsToPrototypes) Run(context map[string]interface{}) error { + tags := context[constants.CTX_COLLECTED_CTAGS].([]map[string]string) + + lineWhereToInsertPrototypes, err := findLineWhereToInsertPrototypes(tags) + if err != nil { + return utils.WrapError(err) + } + if lineWhereToInsertPrototypes != -1 { + context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES] = lineWhereToInsertPrototypes + } + + prototypes := toPrototypes(tags) + context[constants.CTX_PROTOTYPES] = prototypes + + return nil +} + +func findLineWhereToInsertPrototypes(tags []map[string]string) (int, error) { + firstFunctionLine, err := firstFunctionAtLine(tags) + if err != nil { + return -1, utils.WrapError(err) + } + firstFunctionPointerAsArgument, err := firstFunctionPointerUsedAsArgument(tags) + if err != nil { + return -1, utils.WrapError(err) + } + if firstFunctionLine != -1 && firstFunctionPointerAsArgument != -1 { + if firstFunctionLine < firstFunctionPointerAsArgument { + return firstFunctionLine, nil + } else { + return firstFunctionPointerAsArgument, nil + } + } else if firstFunctionLine == -1 { + return firstFunctionPointerAsArgument, nil + } else { + return firstFunctionLine, nil + } +} + +func firstFunctionPointerUsedAsArgument(tags []map[string]string) (int, error) { + functionNames := collectFunctionNames(tags) + for _, tag := range tags { + if functionNameUsedAsFunctionPointerIn(tag, functionNames) { + return strconv.Atoi(tag[FIELD_LINE]) + } + } + return -1, nil +} + +func functionNameUsedAsFunctionPointerIn(tag map[string]string, functionNames []string) bool { + for _, functionName := range functionNames { + if strings.Index(tag[FIELD_CODE], "&"+functionName) != -1 { + return true + } + } + return false +} + +func collectFunctionNames(tags []map[string]string) []string { + names := []string{} + for _, tag := range tags { + if tag[FIELD_KIND] == KIND_FUNCTION { + names = append(names, tag[constants.CTAGS_FIELD_FUNCTION_NAME]) + } + } + return names +} + +func firstFunctionAtLine(tags []map[string]string) (int, error) { + for _, tag := range tags { + if !tagIsUnknown(tag) && !tagHasAtLeastOneField(tag, FIELDS_MARKING_UNHANDLED_TAGS) && tag[FIELD_KIND] == KIND_FUNCTION { + return strconv.Atoi(tag[FIELD_LINE]) + } + } + return -1, nil +} + +func toPrototypes(tags []map[string]string) []*types.Prototype { + prototypes := []*types.Prototype{} + for _, tag := range tags { + if tag[FIELD_SKIP] != TRUE { + ctag := types.Prototype{FunctionName: tag[constants.CTAGS_FIELD_FUNCTION_NAME], Prototype: tag[KIND_PROTOTYPE], Modifiers: tag[KIND_PROTOTYPE_MODIFIERS], Line: tag[FIELD_LINE], Fields: tag} + prototypes = append(prototypes, &ctag) + } + } + return prototypes +} diff --git a/src/arduino.cc/builder/hardware/platform.txt b/src/arduino.cc/builder/hardware/platform.txt index c75396dc..1bae1d65 100644 --- a/src/arduino.cc/builder/hardware/platform.txt +++ b/src/arduino.cc/builder/hardware/platform.txt @@ -2,7 +2,7 @@ # ------------------------------ tools.ctags.path={runtime.tools.ctags.path} tools.ctags.cmd.path={path}/ctags -tools.ctags.pattern="{cmd.path}" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns "{source_file}" +tools.ctags.pattern="{cmd.path}" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "{source_file}" # additional entries tools.avrdude.path={runtime.tools.avrdude.path} diff --git a/src/arduino.cc/builder/prototypes_adder.go b/src/arduino.cc/builder/prototypes_adder.go index 70252b09..3cfdfb41 100644 --- a/src/arduino.cc/builder/prototypes_adder.go +++ b/src/arduino.cc/builder/prototypes_adder.go @@ -52,10 +52,7 @@ func (s *PrototypesAdder) Run(context map[string]interface{}) error { return nil } - firstFunctionChar := len(strings.Join(sourceRows[:firstFunctionLine-1], "\n")) + 1 - if firstFunctionLine > 1 { - firstFunctionLine -= context[constants.CTX_LINE_OFFSET].(int) - } + firstFunctionChar := len(strings.Join(sourceRows[:firstFunctionLine+context[constants.CTX_LINE_OFFSET].(int)-1], "\n")) + 1 prototypeSection := composePrototypeSection(firstFunctionLine, context[constants.CTX_PROTOTYPES].([]*types.Prototype)) context[constants.CTX_PROTOTYPE_SECTION] = prototypeSection source = source[:firstFunctionChar] + prototypeSection + source[firstFunctionChar:] @@ -85,6 +82,7 @@ func composePrototypeSection(line int, prototypes []*types.Prototype) string { func joinPrototypes(prototypes []*types.Prototype) string { prototypesSlice := []string{} for _, proto := range prototypes { + prototypesSlice = append(prototypesSlice, "#line "+proto.Line) prototypeParts := []string{} if proto.Modifiers != "" { prototypeParts = append(prototypeParts, proto.Modifiers) diff --git a/src/arduino.cc/builder/test/builder_test.go b/src/arduino.cc/builder/test/builder_test.go index 0ffce3c9..5e74f697 100644 --- a/src/arduino.cc/builder/test/builder_test.go +++ b/src/arduino.cc/builder/test/builder_test.go @@ -64,6 +64,8 @@ func TestBuilderEmptySketch(t *testing.T) { NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET)) NoError(t, err) + _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET_FOR_GCC_MINUS_E)) + NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_SKETCH, "sketch.ino.cpp.o")) NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, "sketch.ino.elf")) @@ -96,6 +98,8 @@ func TestBuilderBridge(t *testing.T) { NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET)) NoError(t, err) + _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET_FOR_GCC_MINUS_E)) + NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_SKETCH, "Bridge.ino.cpp.o")) NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, "Bridge.ino.elf")) @@ -130,6 +134,8 @@ func TestBuilderSketchWithConfig(t *testing.T) { NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET)) NoError(t, err) + _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET_FOR_GCC_MINUS_E)) + NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_SKETCH, "sketch_with_config.ino.cpp.o")) NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, "sketch_with_config.ino.elf")) @@ -168,6 +174,8 @@ func TestBuilderBridgeTwice(t *testing.T) { NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET)) NoError(t, err) + _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET_FOR_GCC_MINUS_E)) + NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_SKETCH, "Bridge.ino.cpp.o")) NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, "Bridge.ino.elf")) @@ -207,6 +215,8 @@ func TestBuilderBridgeSAM(t *testing.T) { NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET)) NoError(t, err) + _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET_FOR_GCC_MINUS_E)) + NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_SKETCH, "Bridge.ino.cpp.o")) NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, "Bridge.ino.elf")) @@ -241,6 +251,8 @@ func TestBuilderBridgeRedBearLab(t *testing.T) { NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET)) NoError(t, err) + _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET_FOR_GCC_MINUS_E)) + NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_SKETCH, "Bridge.ino.cpp.o")) NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, "Bridge.ino.elf")) diff --git a/src/arduino.cc/builder/test/ctags_parser_test.go b/src/arduino.cc/builder/test/ctags_parser_test.go index d99e1e6b..29c51f9a 100644 --- a/src/arduino.cc/builder/test/ctags_parser_test.go +++ b/src/arduino.cc/builder/test/ctags_parser_test.go @@ -32,7 +32,6 @@ package test import ( "arduino.cc/builder" "arduino.cc/builder/constants" - "arduino.cc/builder/types" "github.com/stretchr/testify/require" "io/ioutil" "path/filepath" @@ -47,20 +46,36 @@ func TestCTagsParserShouldListPrototypes(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{PrototypesField: constants.CTX_PROTOTYPES} + ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} ctagsParser.Run(context) - prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) - - require.Equal(t, 5, len(prototypes)) - require.Equal(t, "void setup();", prototypes[0].Prototype) - require.Equal(t, "void loop();", prototypes[1].Prototype) - require.Equal(t, "void digitalCommand(YunClient client);", prototypes[2].Prototype) - require.Equal(t, "void analogCommand(YunClient client);", prototypes[3].Prototype) - require.Equal(t, "void modeCommand(YunClient client);", prototypes[4].Prototype) - - prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) - require.Equal(t, 33, prototypeLine) + ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + + require.Equal(t, 8, len(ctags)) + idx := 0 + require.Equal(t, "server", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "variable", ctags[idx]["kind"]) + idx++ + require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "process", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "prototype", ctags[idx]["kind"]) + idx++ + require.Equal(t, "process", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "digitalCommand", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "analogCommand", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "modeCommand", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) } func TestCTagsParserShouldListTemplates(t *testing.T) { @@ -71,18 +86,22 @@ func TestCTagsParserShouldListTemplates(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{PrototypesField: constants.CTX_PROTOTYPES} + ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} ctagsParser.Run(context) - prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) - - require.Equal(t, 3, len(prototypes)) - require.Equal(t, "template T minimum (T a, T b);", prototypes[0].Prototype) - require.Equal(t, "void setup();", prototypes[1].Prototype) - require.Equal(t, "void loop();", prototypes[2].Prototype) - - prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) - require.Equal(t, 2, prototypeLine) + ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + + require.Equal(t, 3, len(ctags)) + idx := 0 + require.Equal(t, "minimum", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "(T a, T b)", ctags[idx]["signature"]) + idx++ + require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) } func TestCTagsParserShouldListTemplates2(t *testing.T) { @@ -93,19 +112,26 @@ func TestCTagsParserShouldListTemplates2(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{PrototypesField: constants.CTX_PROTOTYPES} + ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} ctagsParser.Run(context) - prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) - - require.Equal(t, 4, len(prototypes)) - require.Equal(t, "void setup();", prototypes[0].Prototype) - require.Equal(t, "void loop();", prototypes[1].Prototype) - require.Equal(t, "template int SRAM_writeAnything(int ee, const T& value);", prototypes[2].Prototype) - require.Equal(t, "template int SRAM_readAnything(int ee, T& value);", prototypes[3].Prototype) - - prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) - require.Equal(t, 1, prototypeLine) + ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + + require.Equal(t, 4, len(ctags)) + idx := 0 + require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "SRAM_writeAnything", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "(int ee, const T& value)", ctags[idx]["signature"]) + idx++ + require.Equal(t, "SRAM_readAnything", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "(int ee, T& value)", ctags[idx]["signature"]) } func TestCTagsParserShouldDealWithClasses(t *testing.T) { @@ -116,15 +142,18 @@ func TestCTagsParserShouldDealWithClasses(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{PrototypesField: constants.CTX_PROTOTYPES} + ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} ctagsParser.Run(context) - prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) - - require.Equal(t, 0, len(prototypes)) + ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) - prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) - require.Equal(t, 8, prototypeLine) + require.Equal(t, 2, len(ctags)) + idx := 0 + require.Equal(t, "SleepCycle", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "prototype", ctags[idx]["kind"]) + idx++ + require.Equal(t, "SleepCycle", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) } func TestCTagsParserShouldDealWithStructs(t *testing.T) { @@ -135,18 +164,28 @@ func TestCTagsParserShouldDealWithStructs(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{PrototypesField: constants.CTX_PROTOTYPES} + ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} ctagsParser.Run(context) - prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) - - require.Equal(t, 3, len(prototypes)) - require.Equal(t, "void setup();", prototypes[0].Prototype) - require.Equal(t, "void loop();", prototypes[1].Prototype) - require.Equal(t, "void dostuff(A_NEW_TYPE * bar);", prototypes[2].Prototype) - - prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) - require.Equal(t, 9, prototypeLine) + ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + + require.Equal(t, 5, len(ctags)) + idx := 0 + require.Equal(t, "A_NEW_TYPE", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "struct", ctags[idx]["kind"]) + idx++ + require.Equal(t, "foo", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "variable", ctags[idx]["kind"]) + require.Equal(t, "struct:A_NEW_TYPE", ctags[idx]["typeref"]) + idx++ + require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "dostuff", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) } func TestCTagsParserShouldDealWithMacros(t *testing.T) { @@ -157,20 +196,36 @@ func TestCTagsParserShouldDealWithMacros(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{PrototypesField: constants.CTX_PROTOTYPES} + ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} ctagsParser.Run(context) - prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) - - require.Equal(t, 5, len(prototypes)) - require.Equal(t, "void setup();", prototypes[0].Prototype) - require.Equal(t, "void loop();", prototypes[1].Prototype) - require.Equal(t, "void debug();", prototypes[2].Prototype) - require.Equal(t, "void disabledIsDefined();", prototypes[3].Prototype) - require.Equal(t, "int useMyType(MyType type);", prototypes[4].Prototype) - - prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) - require.Equal(t, 18, prototypeLine) + ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + + require.Equal(t, 8, len(ctags)) + idx := 0 + require.Equal(t, "DEBUG", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "macro", ctags[idx]["kind"]) + idx++ + require.Equal(t, "DISABLED", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "macro", ctags[idx]["kind"]) + idx++ + require.Equal(t, "hello", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "variable", ctags[idx]["kind"]) + idx++ + require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "debug", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "disabledIsDefined", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "useMyType", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) } func TestCTagsParserShouldDealFunctionWithDifferentSignatures(t *testing.T) { @@ -181,16 +236,21 @@ func TestCTagsParserShouldDealFunctionWithDifferentSignatures(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{PrototypesField: constants.CTX_PROTOTYPES} + ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} ctagsParser.Run(context) - prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) - - require.Equal(t, 1, len(prototypes)) - require.Equal(t, "boolean getBytes( byte addr, int amount );", prototypes[0].Prototype) - - prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) - require.Equal(t, 5031, prototypeLine) + ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + + require.Equal(t, 3, len(ctags)) + idx := 0 + require.Equal(t, "getBytes", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "prototype", ctags[idx]["kind"]) + idx++ + require.Equal(t, "getBytes", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "getBytes", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) } func TestCTagsParserClassMembersAreFilteredOut(t *testing.T) { @@ -201,17 +261,30 @@ func TestCTagsParserClassMembersAreFilteredOut(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{PrototypesField: constants.CTX_PROTOTYPES} + ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} ctagsParser.Run(context) - prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) - - require.Equal(t, 2, len(prototypes)) - require.Equal(t, "void setup();", prototypes[0].Prototype) - require.Equal(t, "void loop();", prototypes[1].Prototype) - - prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) - require.Equal(t, 14, prototypeLine) + ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + + require.Equal(t, 5, len(ctags)) + idx := 0 + require.Equal(t, "set_values", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "prototype", ctags[idx]["kind"]) + require.Equal(t, "Rectangle", ctags[idx]["class"]) + idx++ + require.Equal(t, "area", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "Rectangle", ctags[idx]["class"]) + idx++ + require.Equal(t, "set_values", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "Rectangle", ctags[idx]["class"]) + idx++ + require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) } func TestCTagsParserStructWithFunctions(t *testing.T) { @@ -222,17 +295,38 @@ func TestCTagsParserStructWithFunctions(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{PrototypesField: constants.CTX_PROTOTYPES} + ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} ctagsParser.Run(context) - prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) - - require.Equal(t, 2, len(prototypes)) - require.Equal(t, "void setup();", prototypes[0].Prototype) - require.Equal(t, "void loop();", prototypes[1].Prototype) - - prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) - require.Equal(t, 16, prototypeLine) + ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + + require.Equal(t, 8, len(ctags)) + idx := 0 + require.Equal(t, "sensorData", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "struct", ctags[idx]["kind"]) + idx++ + require.Equal(t, "sensorData", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "sensorData", ctags[idx]["struct"]) + idx++ + require.Equal(t, "sensorData", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "sensorData", ctags[idx]["struct"]) + idx++ + require.Equal(t, "sensors", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "variable", ctags[idx]["kind"]) + idx++ + require.Equal(t, "sensor1", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "variable", ctags[idx]["kind"]) + idx++ + require.Equal(t, "sensor2", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "variable", ctags[idx]["kind"]) + idx++ + require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) } func TestCTagsParserDefaultArguments(t *testing.T) { @@ -243,17 +337,22 @@ func TestCTagsParserDefaultArguments(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{PrototypesField: constants.CTX_PROTOTYPES} + ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} ctagsParser.Run(context) - prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) - - require.Equal(t, 2, len(prototypes)) - require.Equal(t, "void setup();", prototypes[0].Prototype) - require.Equal(t, "void loop();", prototypes[1].Prototype) - - prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) - require.Equal(t, 2, prototypeLine) + ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + + require.Equal(t, 3, len(ctags)) + idx := 0 + require.Equal(t, "test", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "(int x = 1)", ctags[idx]["signature"]) + idx++ + require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) } func TestCTagsParserNamespace(t *testing.T) { @@ -264,17 +363,22 @@ func TestCTagsParserNamespace(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{PrototypesField: constants.CTX_PROTOTYPES} + ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} ctagsParser.Run(context) - prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) - - require.Equal(t, 2, len(prototypes)) - require.Equal(t, "void setup();", prototypes[0].Prototype) - require.Equal(t, "void loop();", prototypes[1].Prototype) - - prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) - require.Equal(t, 8, prototypeLine) + ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + + require.Equal(t, 3, len(ctags)) + idx := 0 + require.Equal(t, "value", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "Test", ctags[idx]["namespace"]) + idx++ + require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) } func TestCTagsParserStatic(t *testing.T) { @@ -285,19 +389,21 @@ func TestCTagsParserStatic(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{PrototypesField: constants.CTX_PROTOTYPES} + ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} ctagsParser.Run(context) - prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) - - require.Equal(t, 3, len(prototypes)) - require.Equal(t, "void setup();", prototypes[0].Prototype) - require.Equal(t, "void loop();", prototypes[1].Prototype) - require.Equal(t, "void doStuff();", prototypes[2].Prototype) - require.Equal(t, "static", prototypes[2].Modifiers) - - prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) - require.Equal(t, 2, prototypeLine) + ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + + require.Equal(t, 3, len(ctags)) + idx := 0 + require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "doStuff", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) } func TestCTagsParserFunctionPointer(t *testing.T) { @@ -308,18 +414,24 @@ func TestCTagsParserFunctionPointer(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{PrototypesField: constants.CTX_PROTOTYPES} + ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} ctagsParser.Run(context) - prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) - - require.Equal(t, 3, len(prototypes)) - require.Equal(t, "void t1Callback();", prototypes[0].Prototype) - require.Equal(t, "void setup();", prototypes[1].Prototype) - require.Equal(t, "void loop();", prototypes[2].Prototype) - - prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) - require.Equal(t, 2, prototypeLine) + ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + + require.Equal(t, 4, len(ctags)) + idx := 0 + require.Equal(t, "t1Callback", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "variable", ctags[idx]["kind"]) + idx++ + require.Equal(t, "t1Callback", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) } func TestCTagsParserFunctionPointers(t *testing.T) { @@ -330,15 +442,28 @@ func TestCTagsParserFunctionPointers(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{PrototypesField: constants.CTX_PROTOTYPES} + ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} ctagsParser.Run(context) - prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) - - require.Equal(t, 2, len(prototypes)) - require.Equal(t, "void setup();", prototypes[0].Prototype) - require.Equal(t, "void loop();", prototypes[1].Prototype) + ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + + require.Equal(t, 5, len(ctags)) + idx := 0 + require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "func", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + idx++ + require.Equal(t, "funcArr", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "()", ctags[idx]["signature"]) + idx++ + require.Equal(t, "funcCombo", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "(void (*(&in)[5])(int))", ctags[idx]["signature"]) - prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) - require.Equal(t, 2, prototypeLine) } diff --git a/src/arduino.cc/builder/test/ctags_runner_test.go b/src/arduino.cc/builder/test/ctags_runner_test.go index af5a3c81..321cf982 100644 --- a/src/arduino.cc/builder/test/ctags_runner_test.go +++ b/src/arduino.cc/builder/test/ctags_runner_test.go @@ -48,10 +48,11 @@ func TestCTagsRunner(t *testing.T) { buildPath := SetupBuildPath(t, context) defer os.RemoveAll(buildPath) + sketchLocation := Abs(t, filepath.Join("downloaded_libraries", "Bridge", "examples", "Bridge", "Bridge.ino")) context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} context[constants.CTX_FQBN] = "arduino:avr:leonardo" - context[constants.CTX_SKETCH_LOCATION] = filepath.Join("downloaded_libraries", "Bridge", "examples", "Bridge", "Bridge.ino") + context[constants.CTX_SKETCH_LOCATION] = sketchLocation context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} @@ -68,7 +69,7 @@ func TestCTagsRunner(t *testing.T) { &builder.PrintUsedLibrariesIfVerbose{}, &builder.WarnAboutArchIncompatibleLibraries{}, - &builder.CTagsTargetFileSaver{SourceField: constants.CTX_SOURCE}, + &builder.CTagsTargetFileSaver{SourceField: constants.CTX_SOURCE, Filename: constants.FILE_CTAGS_TARGET}, &builder.CTagsRunner{}, } @@ -77,14 +78,13 @@ func TestCTagsRunner(t *testing.T) { NoError(t, err) } - ctagsTempFileName := context[constants.CTX_CTAGS_TEMP_FILE_NAME].(string) - expectedOutput := "server " + ctagsTempFileName + " /^BridgeServer server;$/;\" kind:variable line:32\n" + - "setup " + ctagsTempFileName + " /^void setup() {$/;\" kind:function line:34 signature:() returntype:void\n" + - "loop " + ctagsTempFileName + " /^void loop() {$/;\" kind:function line:47 signature:() returntype:void\n" + - "process " + ctagsTempFileName + " /^void process(BridgeClient client) {$/;\" kind:function line:63 signature:(BridgeClient client) returntype:void\n" + - "digitalCommand " + ctagsTempFileName + " /^void digitalCommand(BridgeClient client) {$/;\" kind:function line:83 signature:(BridgeClient client) returntype:void\n" + - "analogCommand " + ctagsTempFileName + " /^void analogCommand(BridgeClient client) {$/;\" kind:function line:110 signature:(BridgeClient client) returntype:void\n" + - "modeCommand " + ctagsTempFileName + " /^void modeCommand(BridgeClient client) {$/;\" kind:function line:150 signature:(BridgeClient client) returntype:void\n" + expectedOutput := "server " + sketchLocation + " /^BridgeServer server;$/;\" kind:variable line:31\n" + + "setup " + sketchLocation + " /^void setup() {$/;\" kind:function line:33 signature:() returntype:void\n" + + "loop " + sketchLocation + " /^void loop() {$/;\" kind:function line:46 signature:() returntype:void\n" + + "process " + sketchLocation + " /^void process(BridgeClient client) {$/;\" kind:function line:62 signature:(BridgeClient client) returntype:void\n" + + "digitalCommand " + sketchLocation + " /^void digitalCommand(BridgeClient client) {$/;\" kind:function line:82 signature:(BridgeClient client) returntype:void\n" + + "analogCommand " + sketchLocation + " /^void analogCommand(BridgeClient client) {$/;\" kind:function line:109 signature:(BridgeClient client) returntype:void\n" + + "modeCommand " + sketchLocation + " /^void modeCommand(BridgeClient client) {$/;\" kind:function line:149 signature:(BridgeClient client) returntype:void\n" require.Equal(t, expectedOutput, strings.Replace(context[constants.CTX_CTAGS_OUTPUT].(string), "\r\n", "\n", -1)) } @@ -97,10 +97,11 @@ func TestCTagsRunnerSketchWithClass(t *testing.T) { buildPath := SetupBuildPath(t, context) defer os.RemoveAll(buildPath) + sketchLocation := Abs(t, filepath.Join("sketch_with_class", "sketch.ino")) context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} context[constants.CTX_FQBN] = "arduino:avr:leonardo" - context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_class", "sketch.ino") + context[constants.CTX_SKETCH_LOCATION] = sketchLocation context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} @@ -117,7 +118,7 @@ func TestCTagsRunnerSketchWithClass(t *testing.T) { &builder.PrintUsedLibrariesIfVerbose{}, &builder.WarnAboutArchIncompatibleLibraries{}, - &builder.CTagsTargetFileSaver{SourceField: constants.CTX_SOURCE}, + &builder.CTagsTargetFileSaver{SourceField: constants.CTX_SOURCE, Filename: constants.FILE_CTAGS_TARGET}, &builder.CTagsRunner{}, } @@ -126,12 +127,11 @@ func TestCTagsRunnerSketchWithClass(t *testing.T) { NoError(t, err) } - ctagsTempFileName := context[constants.CTX_CTAGS_TEMP_FILE_NAME].(string) - expectedOutput := "set_values\t" + ctagsTempFileName + "\t/^ void set_values (int,int);$/;\"\tkind:prototype\tline:5\tclass:Rectangle\tsignature:(int,int)\treturntype:void\n" + - "area\t" + ctagsTempFileName + "\t/^ int area() {return width*height;}$/;\"\tkind:function\tline:6\tclass:Rectangle\tsignature:()\treturntype:int\n" + - "set_values\t" + ctagsTempFileName + "\t/^void Rectangle::set_values (int x, int y) {$/;\"\tkind:function\tline:9\tclass:Rectangle\tsignature:(int x, int y)\treturntype:void\n" + - "setup\t" + ctagsTempFileName + "\t/^void setup() {$/;\"\tkind:function\tline:14\tsignature:()\treturntype:void\n" + - "loop\t" + ctagsTempFileName + "\t/^void loop() {$/;\"\tkind:function\tline:18\tsignature:()\treturntype:void\n" + expectedOutput := "set_values\t" + sketchLocation + "\t/^ void set_values (int,int);$/;\"\tkind:prototype\tline:4\tclass:Rectangle\tsignature:(int,int)\treturntype:void\n" + + "area\t" + sketchLocation + "\t/^ int area() {return width*height;}$/;\"\tkind:function\tline:5\tclass:Rectangle\tsignature:()\treturntype:int\n" + + "set_values\t" + sketchLocation + "\t/^void Rectangle::set_values (int x, int y) {$/;\"\tkind:function\tline:8\tclass:Rectangle\tsignature:(int x, int y)\treturntype:void\n" + + "setup\t" + sketchLocation + "\t/^void setup() {$/;\"\tkind:function\tline:13\tsignature:()\treturntype:void\n" + + "loop\t" + sketchLocation + "\t/^void loop() {$/;\"\tkind:function\tline:17\tsignature:()\treturntype:void\n" require.Equal(t, expectedOutput, strings.Replace(context[constants.CTX_CTAGS_OUTPUT].(string), "\r\n", "\n", -1)) } @@ -144,14 +144,15 @@ func TestCTagsRunnerSketchWithTypename(t *testing.T) { buildPath := SetupBuildPath(t, context) defer os.RemoveAll(buildPath) + sketchLocation := Abs(t, filepath.Join("sketch_with_typename", "sketch.ino")) context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} context[constants.CTX_FQBN] = "arduino:avr:leonardo" - context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_typename", "sketch.ino") + context[constants.CTX_SKETCH_LOCATION] = sketchLocation context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = true + context[constants.CTX_VERBOSE] = false commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -164,7 +165,7 @@ func TestCTagsRunnerSketchWithTypename(t *testing.T) { &builder.PrintUsedLibrariesIfVerbose{}, &builder.WarnAboutArchIncompatibleLibraries{}, - &builder.CTagsTargetFileSaver{SourceField: constants.CTX_SOURCE}, + &builder.CTagsTargetFileSaver{SourceField: constants.CTX_SOURCE, Filename: constants.FILE_CTAGS_TARGET}, &builder.CTagsRunner{}, } @@ -173,11 +174,10 @@ func TestCTagsRunnerSketchWithTypename(t *testing.T) { NoError(t, err) } - ctagsTempFileName := context[constants.CTX_CTAGS_TEMP_FILE_NAME].(string) - expectedOutput := "Foo\t" + ctagsTempFileName + "\t/^ struct Foo{$/;\"\tkind:struct\tline:3\n" + - "setup\t" + ctagsTempFileName + "\t/^void setup() {$/;\"\tkind:function\tline:7\tsignature:()\treturntype:void\n" + - "loop\t" + ctagsTempFileName + "\t/^void loop() {}$/;\"\tkind:function\tline:11\tsignature:()\treturntype:void\n" + - "func\t" + ctagsTempFileName + "\t/^typename Foo::Bar func(){$/;\"\tkind:function\tline:13\tsignature:()\treturntype:Foo::Bar\n" + expectedOutput := "Foo\t" + sketchLocation + "\t/^ struct Foo{$/;\"\tkind:struct\tline:2\n" + + "setup\t" + sketchLocation + "\t/^void setup() {$/;\"\tkind:function\tline:6\tsignature:()\treturntype:void\n" + + "loop\t" + sketchLocation + "\t/^void loop() {}$/;\"\tkind:function\tline:10\tsignature:()\treturntype:void\n" + + "func\t" + sketchLocation + "\t/^typename Foo::Bar func(){$/;\"\tkind:function\tline:12\tsignature:()\treturntype:Foo::Bar\n" require.Equal(t, expectedOutput, strings.Replace(context[constants.CTX_CTAGS_OUTPUT].(string), "\r\n", "\n", -1)) } @@ -190,14 +190,15 @@ func TestCTagsRunnerSketchWithNamespace(t *testing.T) { buildPath := SetupBuildPath(t, context) defer os.RemoveAll(buildPath) + sketchLocation := Abs(t, filepath.Join("sketch_with_namespace", "sketch.ino")) context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} context[constants.CTX_FQBN] = "arduino:avr:leonardo" - context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_namespace", "sketch.ino") + context[constants.CTX_SKETCH_LOCATION] = sketchLocation context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = true + context[constants.CTX_VERBOSE] = false commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -210,7 +211,7 @@ func TestCTagsRunnerSketchWithNamespace(t *testing.T) { &builder.PrintUsedLibrariesIfVerbose{}, &builder.WarnAboutArchIncompatibleLibraries{}, - &builder.CTagsTargetFileSaver{SourceField: constants.CTX_SOURCE}, + &builder.CTagsTargetFileSaver{SourceField: constants.CTX_SOURCE, Filename: constants.FILE_CTAGS_TARGET}, &builder.CTagsRunner{}, } @@ -219,10 +220,9 @@ func TestCTagsRunnerSketchWithNamespace(t *testing.T) { NoError(t, err) } - ctagsTempFileName := context[constants.CTX_CTAGS_TEMP_FILE_NAME].(string) - expectedOutput := "value\t" + ctagsTempFileName + "\t/^\tint value() {$/;\"\tkind:function\tline:3\tnamespace:Test\tsignature:()\treturntype:int\n" + - "setup\t" + ctagsTempFileName + "\t/^void setup() {}$/;\"\tkind:function\tline:8\tsignature:()\treturntype:void\n" + - "loop\t" + ctagsTempFileName + "\t/^void loop() {}$/;\"\tkind:function\tline:9\tsignature:()\treturntype:void\n" + expectedOutput := "value\t" + sketchLocation + "\t/^\tint value() {$/;\"\tkind:function\tline:2\tnamespace:Test\tsignature:()\treturntype:int\n" + + "setup\t" + sketchLocation + "\t/^void setup() {}$/;\"\tkind:function\tline:7\tsignature:()\treturntype:void\n" + + "loop\t" + sketchLocation + "\t/^void loop() {}$/;\"\tkind:function\tline:8\tsignature:()\treturntype:void\n" require.Equal(t, expectedOutput, strings.Replace(context[constants.CTX_CTAGS_OUTPUT].(string), "\r\n", "\n", -1)) } diff --git a/src/arduino.cc/builder/test/ctags_to_prototypes_test.go b/src/arduino.cc/builder/test/ctags_to_prototypes_test.go new file mode 100644 index 00000000..970d4642 --- /dev/null +++ b/src/arduino.cc/builder/test/ctags_to_prototypes_test.go @@ -0,0 +1,442 @@ +/* + * This file is part of Arduino Builder. + * + * Arduino Builder is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As a special exception, you may use this file as part of a free software + * library without restriction. Specifically, if other files instantiate + * templates or use macros or inline functions from this file, or you compile + * this file and link it with other files to produce an executable, this + * file does not by itself cause the resulting executable to be covered by + * the GNU General Public License. This exception does not however + * invalidate any other reasons why the executable file might be covered by + * the GNU General Public License. + * + * Copyright 2015 Arduino LLC (http://www.arduino.cc/) + */ + +package test + +import ( + "arduino.cc/builder" + "arduino.cc/builder/constants" + "arduino.cc/builder/types" + "github.com/stretchr/testify/require" + "io/ioutil" + "path/filepath" + "testing" +) + +func TestCTagsToPrototypesShouldListPrototypes(t *testing.T) { + context := make(map[string]interface{}) + + bytes, err := ioutil.ReadFile(filepath.Join("ctags_output", "TestCTagsParserShouldListPrototypes.txt")) + NoError(t, err) + + context[constants.CTX_CTAGS_OUTPUT] = string(bytes) + + commands := []types.Command{ + &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsToPrototypes{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) + + require.Equal(t, 5, len(prototypes)) + require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "void loop();", prototypes[1].Prototype) + require.Equal(t, "void digitalCommand(YunClient client);", prototypes[2].Prototype) + require.Equal(t, "void analogCommand(YunClient client);", prototypes[3].Prototype) + require.Equal(t, "void modeCommand(YunClient client);", prototypes[4].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 33, prototypeLine) +} + +func TestCTagsToPrototypesShouldListTemplates(t *testing.T) { + context := make(map[string]interface{}) + + bytes, err := ioutil.ReadFile(filepath.Join("ctags_output", "TestCTagsParserShouldListTemplates.txt")) + NoError(t, err) + + context[constants.CTX_CTAGS_OUTPUT] = string(bytes) + + commands := []types.Command{ + &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsToPrototypes{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) + + require.Equal(t, 3, len(prototypes)) + require.Equal(t, "template T minimum (T a, T b);", prototypes[0].Prototype) + require.Equal(t, "void setup();", prototypes[1].Prototype) + require.Equal(t, "void loop();", prototypes[2].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 2, prototypeLine) +} + +func TestCTagsToPrototypesShouldListTemplates2(t *testing.T) { + context := make(map[string]interface{}) + + bytes, err := ioutil.ReadFile(filepath.Join("ctags_output", "TestCTagsParserShouldListTemplates2.txt")) + NoError(t, err) + + context[constants.CTX_CTAGS_OUTPUT] = string(bytes) + + commands := []types.Command{ + &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsToPrototypes{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) + + require.Equal(t, 4, len(prototypes)) + require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "void loop();", prototypes[1].Prototype) + require.Equal(t, "template int SRAM_writeAnything(int ee, const T& value);", prototypes[2].Prototype) + require.Equal(t, "template int SRAM_readAnything(int ee, T& value);", prototypes[3].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 1, prototypeLine) +} + +func TestCTagsToPrototypesShouldDealWithClasses(t *testing.T) { + context := make(map[string]interface{}) + + bytes, err := ioutil.ReadFile(filepath.Join("ctags_output", "TestCTagsParserShouldDealWithClasses.txt")) + NoError(t, err) + + context[constants.CTX_CTAGS_OUTPUT] = string(bytes) + + commands := []types.Command{ + &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsToPrototypes{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) + + require.Equal(t, 0, len(prototypes)) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 8, prototypeLine) +} + +func TestCTagsToPrototypesShouldDealWithStructs(t *testing.T) { + context := make(map[string]interface{}) + + bytes, err := ioutil.ReadFile(filepath.Join("ctags_output", "TestCTagsParserShouldDealWithStructs.txt")) + NoError(t, err) + + context[constants.CTX_CTAGS_OUTPUT] = string(bytes) + + commands := []types.Command{ + &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsToPrototypes{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) + + require.Equal(t, 3, len(prototypes)) + require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "void loop();", prototypes[1].Prototype) + require.Equal(t, "void dostuff(A_NEW_TYPE * bar);", prototypes[2].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 9, prototypeLine) +} + +func TestCTagsToPrototypesShouldDealWithMacros(t *testing.T) { + context := make(map[string]interface{}) + + bytes, err := ioutil.ReadFile(filepath.Join("ctags_output", "TestCTagsParserShouldDealWithMacros.txt")) + NoError(t, err) + + context[constants.CTX_CTAGS_OUTPUT] = string(bytes) + + commands := []types.Command{ + &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsToPrototypes{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) + + require.Equal(t, 5, len(prototypes)) + require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "void loop();", prototypes[1].Prototype) + require.Equal(t, "void debug();", prototypes[2].Prototype) + require.Equal(t, "void disabledIsDefined();", prototypes[3].Prototype) + require.Equal(t, "int useMyType(MyType type);", prototypes[4].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 18, prototypeLine) +} + +func TestCTagsToPrototypesShouldDealFunctionWithDifferentSignatures(t *testing.T) { + context := make(map[string]interface{}) + + bytes, err := ioutil.ReadFile(filepath.Join("ctags_output", "TestCTagsParserShouldDealFunctionWithDifferentSignatures.txt")) + NoError(t, err) + + context[constants.CTX_CTAGS_OUTPUT] = string(bytes) + + commands := []types.Command{ + &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsToPrototypes{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) + + require.Equal(t, 1, len(prototypes)) + require.Equal(t, "boolean getBytes( byte addr, int amount );", prototypes[0].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 5031, prototypeLine) +} + +func TestCTagsToPrototypesClassMembersAreFilteredOut(t *testing.T) { + context := make(map[string]interface{}) + + bytes, err := ioutil.ReadFile(filepath.Join("ctags_output", "TestCTagsParserClassMembersAreFilteredOut.txt")) + NoError(t, err) + + context[constants.CTX_CTAGS_OUTPUT] = string(bytes) + + commands := []types.Command{ + &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsToPrototypes{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) + + require.Equal(t, 2, len(prototypes)) + require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "void loop();", prototypes[1].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 14, prototypeLine) +} + +func TestCTagsToPrototypesStructWithFunctions(t *testing.T) { + context := make(map[string]interface{}) + + bytes, err := ioutil.ReadFile(filepath.Join("ctags_output", "TestCTagsParserStructWithFunctions.txt")) + NoError(t, err) + + context[constants.CTX_CTAGS_OUTPUT] = string(bytes) + + commands := []types.Command{ + &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsToPrototypes{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) + + require.Equal(t, 2, len(prototypes)) + require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "void loop();", prototypes[1].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 16, prototypeLine) +} + +func TestCTagsToPrototypesDefaultArguments(t *testing.T) { + context := make(map[string]interface{}) + + bytes, err := ioutil.ReadFile(filepath.Join("ctags_output", "TestCTagsParserDefaultArguments.txt")) + NoError(t, err) + + context[constants.CTX_CTAGS_OUTPUT] = string(bytes) + + commands := []types.Command{ + &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsToPrototypes{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) + + require.Equal(t, 2, len(prototypes)) + require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "void loop();", prototypes[1].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 2, prototypeLine) +} + +func TestCTagsToPrototypesNamespace(t *testing.T) { + context := make(map[string]interface{}) + + bytes, err := ioutil.ReadFile(filepath.Join("ctags_output", "TestCTagsParserNamespace.txt")) + NoError(t, err) + + context[constants.CTX_CTAGS_OUTPUT] = string(bytes) + + commands := []types.Command{ + &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsToPrototypes{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) + + require.Equal(t, 2, len(prototypes)) + require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "void loop();", prototypes[1].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 8, prototypeLine) +} + +func TestCTagsToPrototypesStatic(t *testing.T) { + context := make(map[string]interface{}) + + bytes, err := ioutil.ReadFile(filepath.Join("ctags_output", "TestCTagsParserStatic.txt")) + NoError(t, err) + + context[constants.CTX_CTAGS_OUTPUT] = string(bytes) + + commands := []types.Command{ + &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsToPrototypes{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) + + require.Equal(t, 3, len(prototypes)) + require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "void loop();", prototypes[1].Prototype) + require.Equal(t, "void doStuff();", prototypes[2].Prototype) + require.Equal(t, "static", prototypes[2].Modifiers) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 2, prototypeLine) +} + +func TestCTagsToPrototypesFunctionPointer(t *testing.T) { + context := make(map[string]interface{}) + + bytes, err := ioutil.ReadFile(filepath.Join("ctags_output", "TestCTagsParserFunctionPointer.txt")) + NoError(t, err) + + context[constants.CTX_CTAGS_OUTPUT] = string(bytes) + + commands := []types.Command{ + &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsToPrototypes{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) + + require.Equal(t, 3, len(prototypes)) + require.Equal(t, "void t1Callback();", prototypes[0].Prototype) + require.Equal(t, "void setup();", prototypes[1].Prototype) + require.Equal(t, "void loop();", prototypes[2].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 2, prototypeLine) +} + +func TestCTagsToPrototypesFunctionPointers(t *testing.T) { + context := make(map[string]interface{}) + + bytes, err := ioutil.ReadFile(filepath.Join("ctags_output", "TestCTagsParserFunctionPointers.txt")) + NoError(t, err) + + context[constants.CTX_CTAGS_OUTPUT] = string(bytes) + + commands := []types.Command{ + &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsToPrototypes{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) + + require.Equal(t, 2, len(prototypes)) + require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "void loop();", prototypes[1].Prototype) + + prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) + require.Equal(t, 2, prototypeLine) +} diff --git a/src/arduino.cc/builder/test/hardware/platform.txt b/src/arduino.cc/builder/test/hardware/platform.txt index 0755c3ab..a76dcd3e 100644 --- a/src/arduino.cc/builder/test/hardware/platform.txt +++ b/src/arduino.cc/builder/test/hardware/platform.txt @@ -2,7 +2,7 @@ # ------------------------------ tools.ctags.path={runtime.tools.ctags.path} tools.ctags.cmd.path={path}/ctags -tools.ctags.pattern="{cmd.path}" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns "{source_file}" +tools.ctags.pattern="{cmd.path}" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "{source_file}" # coan # ------------------------------ diff --git a/src/arduino.cc/builder/test/hardware_loader_test.go b/src/arduino.cc/builder/test/hardware_loader_test.go index 948b1bcb..e0fec6e3 100644 --- a/src/arduino.cc/builder/test/hardware_loader_test.go +++ b/src/arduino.cc/builder/test/hardware_loader_test.go @@ -79,7 +79,7 @@ func TestLoadHardware(t *testing.T) { require.Equal(t, "AVRISP mkII", avrPlatform.Programmers["avrispmkii"][constants.PROGRAMMER_NAME]) require.Equal(t, "{runtime.tools.ctags.path}", packages.Properties["tools.ctags.path"]) - require.Equal(t, "\"{cmd.path}\" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns \"{source_file}\"", packages.Properties["tools.ctags.pattern"]) + require.Equal(t, "\"{cmd.path}\" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives \"{source_file}\"", packages.Properties["tools.ctags.pattern"]) require.Equal(t, "{runtime.tools.avrdude.path}", packages.Properties["tools.avrdude.path"]) require.Equal(t, "-w -x c++ -E -CC", packages.Properties["preproc.macros.flags"]) } @@ -144,7 +144,7 @@ func TestLoadHardwareMixingUserHardwareFolder(t *testing.T) { require.False(t, utils.MapStringStringHas(myAVRPlatformAvrArch.Properties, "preproc.includes.flags")) require.Equal(t, "{runtime.tools.ctags.path}", packages.Properties["tools.ctags.path"]) - require.Equal(t, "\"{cmd.path}\" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns \"{source_file}\"", packages.Properties["tools.ctags.pattern"]) + require.Equal(t, "\"{cmd.path}\" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives \"{source_file}\"", packages.Properties["tools.ctags.pattern"]) require.Equal(t, "{runtime.tools.avrdude.path}", packages.Properties["tools.avrdude.path"]) require.Equal(t, "-w -x c++ -E -CC", packages.Properties["preproc.macros.flags"]) require.Equal(t, "{build.mbed_api_include} {build.nRF51822_api_include} {build.ble_api_include} {compiler.libsam.c.flags} {compiler.arm.cmsis.path} {build.variant_system_include}", packages.Properties["preproc.macros.compatibility_flags"]) diff --git a/src/arduino.cc/builder/test/prototypes_adder_test.go b/src/arduino.cc/builder/test/prototypes_adder_test.go index 8777ffd4..32a3fb69 100644 --- a/src/arduino.cc/builder/test/prototypes_adder_test.go +++ b/src/arduino.cc/builder/test/prototypes_adder_test.go @@ -79,7 +79,7 @@ func TestPrototypesAdderBridgeExample(t *testing.T) { } require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) - require.Equal(t, "void setup();\nvoid loop();\nvoid process(BridgeClient client);\nvoid digitalCommand(BridgeClient client);\nvoid analogCommand(BridgeClient client);\nvoid modeCommand(BridgeClient client);\n#line 33\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + require.Equal(t, "#line 33\nvoid setup();\n#line 46\nvoid loop();\n#line 62\nvoid process(BridgeClient client);\n#line 82\nvoid digitalCommand(BridgeClient client);\n#line 109\nvoid analogCommand(BridgeClient client);\n#line 149\nvoid modeCommand(BridgeClient client);\n#line 33\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) } func TestPrototypesAdderSketchWithIfDef(t *testing.T) { @@ -97,7 +97,7 @@ func TestPrototypesAdderSketchWithIfDef(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = true + context[constants.CTX_VERBOSE] = false commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -220,7 +220,7 @@ func TestPrototypesAdderIncludeBetweenMultilineComment(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = true + context[constants.CTX_VERBOSE] = false commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -407,7 +407,7 @@ func TestPrototypesAdderSketchWithConfig(t *testing.T) { } require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) - require.Equal(t, "void setup();\nvoid loop();\n#line 13\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + require.Equal(t, "#line 13\nvoid setup();\n#line 17\nvoid loop();\n#line 13\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) preprocessed := LoadAndInterpolate(t, filepath.Join("sketch_with_config", "sketch_with_config.preprocessed.txt"), context) require.Equal(t, preprocessed, strings.Replace(context[constants.CTX_SOURCE].(string), "\r\n", "\n", -1)) @@ -428,7 +428,7 @@ func TestPrototypesAdderSketchNoFunctionsTwoFiles(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = true + context[constants.CTX_VERBOSE] = false commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -469,7 +469,7 @@ func TestPrototypesAdderSketchNoFunctions(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = true + context[constants.CTX_VERBOSE] = false commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -533,7 +533,7 @@ func TestPrototypesAdderSketchWithDefaultArgs(t *testing.T) { } require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) - require.Equal(t, "void setup();\nvoid loop();\n#line 1\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + require.Equal(t, "#line 4\nvoid setup();\n#line 7\nvoid loop();\n#line 1\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) } func TestPrototypesAdderSketchWithInlineFunction(t *testing.T) { @@ -574,7 +574,7 @@ func TestPrototypesAdderSketchWithInlineFunction(t *testing.T) { } require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) - require.Equal(t, "void setup();\nvoid loop();\nshort unsigned int testInt();\nstatic int8_t testInline();\nuint8_t testAttribute();\n#line 1\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + require.Equal(t, "#line 1\nvoid setup();\n#line 2\nvoid loop();\n#line 4\nshort unsigned int testInt();\n#line 8\nstatic int8_t testInline();\n#line 12\nuint8_t testAttribute();\n#line 1\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) } func TestPrototypesAdderSketchWithFunctionSignatureInsideIFDEF(t *testing.T) { @@ -592,7 +592,7 @@ func TestPrototypesAdderSketchWithFunctionSignatureInsideIFDEF(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = true + context[constants.CTX_VERBOSE] = false commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -615,7 +615,7 @@ func TestPrototypesAdderSketchWithFunctionSignatureInsideIFDEF(t *testing.T) { } require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) - require.Equal(t, "void setup();\nvoid loop();\nint8_t adalight();\n#line 1\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + require.Equal(t, "#line 1\nvoid setup();\n#line 3\nvoid loop();\n#line 15\nint8_t adalight();\n#line 1\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) } func TestPrototypesAdderSketchWithUSBCON(t *testing.T) { @@ -633,7 +633,7 @@ func TestPrototypesAdderSketchWithUSBCON(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = true + context[constants.CTX_VERBOSE] = false commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -656,7 +656,7 @@ func TestPrototypesAdderSketchWithUSBCON(t *testing.T) { } require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) - require.Equal(t, "void ciao();\nvoid setup();\nvoid loop();\n#line 3\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + require.Equal(t, "#line 3\nvoid ciao();\n#line 8\nvoid setup();\n#line 13\nvoid loop();\n#line 3\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) } func TestPrototypesAdderSketchWithTypename(t *testing.T) { @@ -673,7 +673,7 @@ func TestPrototypesAdderSketchWithTypename(t *testing.T) { context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_typename", "sketch.ino") context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_LIBRARIES_FOLDERS] = []string{"libraries", "downloaded_libraries"} - context[constants.CTX_VERBOSE] = true + context[constants.CTX_VERBOSE] = false commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -696,5 +696,49 @@ func TestPrototypesAdderSketchWithTypename(t *testing.T) { } require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) - require.Equal(t, "void setup();\nvoid loop();\n#line 6\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + require.Equal(t, "#line 6\nvoid setup();\n#line 10\nvoid loop();\n#line 6\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) +} + +func TestPrototypesAdderSketchWithIfDef2(t *testing.T) { + DownloadCoresAndToolsAndLibraries(t) + + context := make(map[string]interface{}) + + buildPath := SetupBuildPath(t, context) + defer os.RemoveAll(buildPath) + + context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} + context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} + context[constants.CTX_FQBN] = "arduino:avr:yun" + context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_ifdef", "sketch.ino") + context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" + context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} + context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} + context[constants.CTX_VERBOSE] = false + + commands := []types.Command{ + &builder.SetupHumanLoggerIfMissing{}, + + &builder.ContainerSetupHardwareToolsLibsSketchAndProps{}, + + &builder.ContainerMergeCopySketchFiles{}, + + &builder.ContainerFindIncludes{}, + + &builder.PrintUsedLibrariesIfVerbose{}, + &builder.WarnAboutArchIncompatibleLibraries{}, + + &builder.ContainerAddPrototypes{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) + require.Equal(t, "#line 7\nvoid elseBranch();\n#line 11\nvoid f1();\n#line 12\nvoid f2();\n#line 14\nvoid setup();\n#line 16\nvoid loop();\n#line 7\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + + expectedSource := LoadAndInterpolate(t, filepath.Join("sketch_with_ifdef", "sketch.preprocessed.txt"), context) + require.Equal(t, expectedSource, strings.Replace(context[constants.CTX_SOURCE].(string), "\r\n", "\n", -1)) } diff --git a/src/arduino.cc/builder/test/sketch2/SketchWithIfDef.preprocessed.txt b/src/arduino.cc/builder/test/sketch2/SketchWithIfDef.preprocessed.txt index b7a637d5..e5f36e8b 100644 --- a/src/arduino.cc/builder/test/sketch2/SketchWithIfDef.preprocessed.txt +++ b/src/arduino.cc/builder/test/sketch2/SketchWithIfDef.preprocessed.txt @@ -16,10 +16,15 @@ typedef MyType int; #include "empty_2.h" +#line 16 void setup(); +#line 21 void loop(); +#line 33 void debug(); +#line 44 void disabledIsDefined(); +#line 48 int useMyType(MyType type); #line 16 void setup() { diff --git a/src/arduino.cc/builder/test/sketch3/Baladuino.preprocessed.txt b/src/arduino.cc/builder/test/sketch3/Baladuino.preprocessed.txt index 3f8700c5..01a0bbaf 100644 --- a/src/arduino.cc/builder/test/sketch3/Baladuino.preprocessed.txt +++ b/src/arduino.cc/builder/test/sketch3/Baladuino.preprocessed.txt @@ -88,7 +88,9 @@ WII Wii(&Btd); // The Wii library can communicate with Wiimotes and the Nunchuck // This can also be done using the Android or Processing application #endif +#line 88 void setup(); +#line 204 void loop(); #line 88 void setup() { diff --git a/src/arduino.cc/builder/test/sketch4/CharWithEscapedDoubleQuote.preprocessed.txt b/src/arduino.cc/builder/test/sketch4/CharWithEscapedDoubleQuote.preprocessed.txt index 51351faf..8cc7e690 100644 --- a/src/arduino.cc/builder/test/sketch4/CharWithEscapedDoubleQuote.preprocessed.txt +++ b/src/arduino.cc/builder/test/sketch4/CharWithEscapedDoubleQuote.preprocessed.txt @@ -39,26 +39,47 @@ Code Exclusively for GPRS shield: // Default set of instructions for GPRS Shield power control // +#line 39 void setPowerStateTo( int newState ); +#line 64 int getPowerState(); +#line 75 void powerUpOrDown(); +#line 90 void clearBufferArray(); +#line 96 void makeMissedCall( char num[] ); +#line 111 void sendTextMessage( char number[], char messg[] ); +#line 129 void analise(byte incoming[], int length); +#line 179 byte decToBcd( byte b ); +#line 184 boolean getBit( byte addr, int pos ); +#line 190 void setBit( byte addr, int pos, boolean newBit ); +#line 204 byte getByte( byte addr ); +#line 213 boolean getBytes( byte addr, int amount ); +#line 230 void setByte( byte addr, byte newByte ); +#line 235 void setBytes( byte addr, byte newBytes[], int amount ); +#line 244 void getTime(); +#line 260 void setTime( byte newTime[ 7 ] ); +#line 267 void getRTCTemperature(); +#line 277 void gprsListen(); +#line 294 void printTime(); +#line 317 void setup(); +#line 334 void loop(); #line 39 void setPowerStateTo( int newState ) diff --git a/src/arduino.cc/builder/test/sketch5/IncludeBetweenMultilineComment.preprocessed.txt b/src/arduino.cc/builder/test/sketch5/IncludeBetweenMultilineComment.preprocessed.txt index a7e6a1ca..fa6ac7b6 100644 --- a/src/arduino.cc/builder/test/sketch5/IncludeBetweenMultilineComment.preprocessed.txt +++ b/src/arduino.cc/builder/test/sketch5/IncludeBetweenMultilineComment.preprocessed.txt @@ -6,7 +6,9 @@ #include */ CapacitiveSensor cs_13_8 = CapacitiveSensor(13,8); +#line 6 void setup(); +#line 10 void loop(); #line 6 void setup() diff --git a/src/arduino.cc/builder/test/sketch6/LineContinuations.preprocessed.txt b/src/arduino.cc/builder/test/sketch6/LineContinuations.preprocessed.txt index f1680a19..7bec9d91 100644 --- a/src/arduino.cc/builder/test/sketch6/LineContinuations.preprocessed.txt +++ b/src/arduino.cc/builder/test/sketch6/LineContinuations.preprocessed.txt @@ -7,7 +7,9 @@ world\n"; //" delete this comment line and the IDE parser will crash +#line 7 void setup(); +#line 11 void loop(); #line 7 void setup() diff --git a/src/arduino.cc/builder/test/sketch7/StringWithComment.preprocessed.txt b/src/arduino.cc/builder/test/sketch7/StringWithComment.preprocessed.txt index de22ef9b..54e09671 100644 --- a/src/arduino.cc/builder/test/sketch7/StringWithComment.preprocessed.txt +++ b/src/arduino.cc/builder/test/sketch7/StringWithComment.preprocessed.txt @@ -1,7 +1,9 @@ #include #line 1 #line 1 "{{EscapeBackSlashes .sketch.MainFile.Name}}" +#line 1 void setup(); +#line 10 void loop(); #line 1 void setup() { diff --git a/src/arduino.cc/builder/test/sketch8/SketchWithStruct.preprocessed.txt b/src/arduino.cc/builder/test/sketch8/SketchWithStruct.preprocessed.txt index 3519359e..be35eaee 100644 --- a/src/arduino.cc/builder/test/sketch8/SketchWithStruct.preprocessed.txt +++ b/src/arduino.cc/builder/test/sketch8/SketchWithStruct.preprocessed.txt @@ -9,8 +9,11 @@ struct A_NEW_TYPE { int c; } foo; +#line 9 void setup(); +#line 13 void loop(); +#line 17 void dostuff(A_NEW_TYPE * bar); #line 9 void setup() { diff --git a/src/arduino.cc/builder/test/sketch_with_config/sketch_with_config.preprocessed.txt b/src/arduino.cc/builder/test/sketch_with_config/sketch_with_config.preprocessed.txt index f8e85df5..55b48b3e 100644 --- a/src/arduino.cc/builder/test/sketch_with_config/sketch_with_config.preprocessed.txt +++ b/src/arduino.cc/builder/test/sketch_with_config/sketch_with_config.preprocessed.txt @@ -13,7 +13,9 @@ #include +#line 13 void setup(); +#line 17 void loop(); #line 13 void setup() { diff --git a/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.ino b/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.ino new file mode 100644 index 00000000..04854715 --- /dev/null +++ b/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.ino @@ -0,0 +1,17 @@ +#include + +#if false +void ifBranch() { +} +#else +void elseBranch() { +} +#endif + +void f1(){ f2(); } +void f2(){;} + +void setup() { +} +void loop() { +} \ No newline at end of file diff --git a/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.preprocessed.txt b/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.preprocessed.txt new file mode 100644 index 00000000..df49a704 --- /dev/null +++ b/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.preprocessed.txt @@ -0,0 +1,31 @@ +#include +#line 1 +#line 1 "{{EscapeBackSlashes .sketch.MainFile.Name}}" +#include + +#if false +void ifBranch() { +} +#else +#line 7 +void elseBranch(); +#line 11 +void f1(); +#line 12 +void f2(); +#line 14 +void setup(); +#line 16 +void loop(); +#line 7 +void elseBranch() { +} +#endif + +void f1(){ f2(); } +void f2(){;} + +void setup() { +} +void loop() { +} diff --git a/src/arduino.cc/builder/types/types.go b/src/arduino.cc/builder/types/types.go index 546d1197..71777dc8 100644 --- a/src/arduino.cc/builder/types/types.go +++ b/src/arduino.cc/builder/types/types.go @@ -155,11 +155,12 @@ type Prototype struct { FunctionName string Prototype string Modifiers string + Line string Fields map[string]string } func (proto *Prototype) String() string { - return proto.Modifiers + " " + proto.Prototype + return proto.Modifiers + " " + proto.Prototype + " @ " + proto.Line } type SourceFolder struct { diff --git a/src/arduino.cc/builder/utils/utils.go b/src/arduino.cc/builder/utils/utils.go index 592819ee..8983c821 100644 --- a/src/arduino.cc/builder/utils/utils.go +++ b/src/arduino.cc/builder/utils/utils.go @@ -205,9 +205,9 @@ func SliceContains(slice []string, target string) bool { return false } -func SliceContainsPrototype(slice []*types.Prototype, target *types.Prototype) bool { +func SliceContainsCTag(slice []map[string]string, target map[string]string) bool { for _, value := range slice { - if value.FunctionName == target.FunctionName { + if value[constants.CTAGS_FIELD_FUNCTION_NAME] == target[constants.CTAGS_FIELD_FUNCTION_NAME] { return true } } From 4191e1ccce2776e697dc80210760a39a7d488096 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 10 Nov 2015 12:42:59 +0100 Subject: [PATCH 21/85] Windows: ctags outputs paths with double back slashes Signed-off-by: Federico Fissore --- src/arduino.cc/builder/test/ctags_runner_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/arduino.cc/builder/test/ctags_runner_test.go b/src/arduino.cc/builder/test/ctags_runner_test.go index 321cf982..6acdb6c5 100644 --- a/src/arduino.cc/builder/test/ctags_runner_test.go +++ b/src/arduino.cc/builder/test/ctags_runner_test.go @@ -78,6 +78,7 @@ func TestCTagsRunner(t *testing.T) { NoError(t, err) } + sketchLocation = strings.Replace(sketchLocation, "\\", "\\\\", -1) expectedOutput := "server " + sketchLocation + " /^BridgeServer server;$/;\" kind:variable line:31\n" + "setup " + sketchLocation + " /^void setup() {$/;\" kind:function line:33 signature:() returntype:void\n" + "loop " + sketchLocation + " /^void loop() {$/;\" kind:function line:46 signature:() returntype:void\n" + @@ -127,6 +128,7 @@ func TestCTagsRunnerSketchWithClass(t *testing.T) { NoError(t, err) } + sketchLocation = strings.Replace(sketchLocation, "\\", "\\\\", -1) expectedOutput := "set_values\t" + sketchLocation + "\t/^ void set_values (int,int);$/;\"\tkind:prototype\tline:4\tclass:Rectangle\tsignature:(int,int)\treturntype:void\n" + "area\t" + sketchLocation + "\t/^ int area() {return width*height;}$/;\"\tkind:function\tline:5\tclass:Rectangle\tsignature:()\treturntype:int\n" + "set_values\t" + sketchLocation + "\t/^void Rectangle::set_values (int x, int y) {$/;\"\tkind:function\tline:8\tclass:Rectangle\tsignature:(int x, int y)\treturntype:void\n" + @@ -174,6 +176,7 @@ func TestCTagsRunnerSketchWithTypename(t *testing.T) { NoError(t, err) } + sketchLocation = strings.Replace(sketchLocation, "\\", "\\\\", -1) expectedOutput := "Foo\t" + sketchLocation + "\t/^ struct Foo{$/;\"\tkind:struct\tline:2\n" + "setup\t" + sketchLocation + "\t/^void setup() {$/;\"\tkind:function\tline:6\tsignature:()\treturntype:void\n" + "loop\t" + sketchLocation + "\t/^void loop() {}$/;\"\tkind:function\tline:10\tsignature:()\treturntype:void\n" + @@ -220,6 +223,7 @@ func TestCTagsRunnerSketchWithNamespace(t *testing.T) { NoError(t, err) } + sketchLocation = strings.Replace(sketchLocation, "\\", "\\\\", -1) expectedOutput := "value\t" + sketchLocation + "\t/^\tint value() {$/;\"\tkind:function\tline:2\tnamespace:Test\tsignature:()\treturntype:int\n" + "setup\t" + sketchLocation + "\t/^void setup() {}$/;\"\tkind:function\tline:7\tsignature:()\treturntype:void\n" + "loop\t" + sketchLocation + "\t/^void loop() {}$/;\"\tkind:function\tline:8\tsignature:()\treturntype:void\n" From 1b218d376a59a20085cecf8f1d552e3de82c6698 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 10 Nov 2015 12:45:47 +0100 Subject: [PATCH 22/85] Releasing 1.1.3 Signed-off-by: Federico Fissore --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index ff473c6e..7a64da9a 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,7 @@ import ( "syscall" ) -const VERSION = "1.1.2" +const VERSION = "1.1.3" const FLAG_ACTION_COMPILE = "compile" const FLAG_ACTION_PREPROCESS = "preprocess" From 0188cc0b417cfd5a56ebc954d2771042004e96ee Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 10 Nov 2015 15:56:35 +0100 Subject: [PATCH 23/85] Extracting ExecRecipeSpecifyStdOutStdErr, parametric version of ExecRecipe Signed-off-by: Federico Fissore --- src/arduino.cc/builder/builder_utils/utils.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/arduino.cc/builder/builder_utils/utils.go b/src/arduino.cc/builder/builder_utils/utils.go index 2c83ad6a..afe6e831 100644 --- a/src/arduino.cc/builder/builder_utils/utils.go +++ b/src/arduino.cc/builder/builder_utils/utils.go @@ -35,6 +35,7 @@ import ( "arduino.cc/builder/props" "arduino.cc/builder/utils" "fmt" + "io" "os" "path/filepath" "strings" @@ -278,6 +279,10 @@ func ArchiveCompiledFiles(buildPath string, archiveFile string, objectFiles []st } func ExecRecipe(properties map[string]string, recipe string, removeUnsetProperties bool, echoCommandLine bool, echoOutput bool, logger i18n.Logger) ([]byte, error) { + return ExecRecipeSpecifyStdOutStdErr(properties, recipe, removeUnsetProperties, echoCommandLine, echoOutput, logger, os.Stdout, os.Stderr) +} + +func ExecRecipeSpecifyStdOutStdErr(properties map[string]string, recipe string, removeUnsetProperties bool, echoCommandLine bool, echoOutput bool, logger i18n.Logger, stdout io.Writer, stderr io.Writer) ([]byte, error) { pattern := properties[recipe] if pattern == constants.EMPTY_STRING { return nil, utils.ErrorfWithLogger(logger, constants.MSG_PATTERN_MISSING, recipe) @@ -302,10 +307,10 @@ func ExecRecipe(properties map[string]string, recipe string, removeUnsetProperti } if echoOutput { - command.Stdout = os.Stdout + command.Stdout = stdout } - command.Stderr = os.Stderr + command.Stderr = stderr if echoOutput { err := command.Run() From d46c7ce032fd8e2d2050eb56eb9b744f7cbeffe5 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 10 Nov 2015 15:57:17 +0100 Subject: [PATCH 24/85] Added missing license header Signed-off-by: Federico Fissore --- src/arduino.cc/builder/ctags_to_prototypes.go | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/arduino.cc/builder/ctags_to_prototypes.go b/src/arduino.cc/builder/ctags_to_prototypes.go index 4c9fdc77..293494eb 100644 --- a/src/arduino.cc/builder/ctags_to_prototypes.go +++ b/src/arduino.cc/builder/ctags_to_prototypes.go @@ -1,3 +1,32 @@ +/* + * This file is part of Arduino Builder. + * + * Arduino Builder is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As a special exception, you may use this file as part of a free software + * library without restriction. Specifically, if other files instantiate + * templates or use macros or inline functions from this file, or you compile + * this file and link it with other files to produce an executable, this + * file does not by itself cause the resulting executable to be covered by + * the GNU General Public License. This exception does not however + * invalidate any other reasons why the executable file might be covered by + * the GNU General Public License. + * + * Copyright 2015 Arduino LLC (http://www.arduino.cc/) + */ + package builder import ( From f28fffbf4328b768f2974d65d27e28203e72a0b1 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Wed, 11 Nov 2015 14:36:00 +0100 Subject: [PATCH 25/85] Brand new way of discovering libraries and related -I gcc parameters For each source file found, gcc -E is continuously run until it doesn't report any error. When it reports an error, it is in the form of Ethernet.h: No such file or directory #include Ethernet.h is searched from known libraries, its -I param added to gcc -E and gcc -E is rerun If Ethernet.h is not found, preprocessing fails and reports an error If found, the collected list of -I params is used to preprocess another (sketch or library) source file, until all dependendent libraries are resolved Fixes #33 Signed-off-by: Federico Fissore --- src/arduino.cc/builder/builder_utils/utils.go | 55 ++++++-- src/arduino.cc/builder/constants/constants.go | 2 + .../builder/container_find_includes.go | 63 ++++++---- .../builder/gcc_minus_m_output_parser.go | 7 +- src/arduino.cc/builder/gcc_preproc_runner.go | 43 +++++-- .../hardware/platform.keys.rewrite.txt | 7 ++ src/arduino.cc/builder/hardware/platform.txt | 7 +- .../builder/includes_finder_with_regexp.go | 18 ++- src/arduino.cc/builder/test/builder_test.go | 4 +- .../builder/test/coan_runner_test.go | 2 +- .../builder/test/ctags_runner_test.go | 8 +- .../builder/test/hardware_loader_test.go | 8 +- .../builder/test/helper_tools_downloader.go | 1 + .../test/includes_finder_with_gcc_test.go | 117 +++++++++++++++--- .../test/includes_finder_with_regexp_test.go | 68 +++++++++- .../test/includes_to_include_folders_test.go | 13 +- .../test/platform_keys_rewrite_loader_test.go | 2 +- .../builder/test/prototypes_adder_test.go | 34 ++--- .../sketch.ino | 8 ++ .../sketch.ino | 9 ++ .../builder/test/tools_loader_test.go | 24 ++-- .../my_avr_platform/avr/boards.txt | 2 +- src/arduino.cc/builder/utils/utils.go | 9 ++ 23 files changed, 380 insertions(+), 131 deletions(-) create mode 100644 src/arduino.cc/builder/test/sketch_that_checks_if_SPI_has_transactions/sketch.ino create mode 100644 src/arduino.cc/builder/test/sketch_that_checks_if_SPI_has_transactions_and_includes_missing_Ethernet/sketch.ino diff --git a/src/arduino.cc/builder/builder_utils/utils.go b/src/arduino.cc/builder/builder_utils/utils.go index afe6e831..94e43873 100644 --- a/src/arduino.cc/builder/builder_utils/utils.go +++ b/src/arduino.cc/builder/builder_utils/utils.go @@ -34,9 +34,10 @@ import ( "arduino.cc/builder/i18n" "arduino.cc/builder/props" "arduino.cc/builder/utils" + "bufio" "fmt" - "io" "os" + "os/exec" "path/filepath" "strings" ) @@ -279,10 +280,27 @@ func ArchiveCompiledFiles(buildPath string, archiveFile string, objectFiles []st } func ExecRecipe(properties map[string]string, recipe string, removeUnsetProperties bool, echoCommandLine bool, echoOutput bool, logger i18n.Logger) ([]byte, error) { - return ExecRecipeSpecifyStdOutStdErr(properties, recipe, removeUnsetProperties, echoCommandLine, echoOutput, logger, os.Stdout, os.Stderr) + command, err := PrepareCommandForRecipe(properties, recipe, removeUnsetProperties, echoCommandLine, echoOutput, logger) + if err != nil { + return nil, utils.WrapError(err) + } + + if echoOutput { + command.Stdout = os.Stdout + } + + command.Stderr = os.Stderr + + if echoOutput { + err := command.Run() + return nil, utils.WrapError(err) + } + + bytes, err := command.Output() + return bytes, utils.WrapError(err) } -func ExecRecipeSpecifyStdOutStdErr(properties map[string]string, recipe string, removeUnsetProperties bool, echoCommandLine bool, echoOutput bool, logger i18n.Logger, stdout io.Writer, stderr io.Writer) ([]byte, error) { +func PrepareCommandForRecipe(properties map[string]string, recipe string, removeUnsetProperties bool, echoCommandLine bool, echoOutput bool, logger i18n.Logger) (*exec.Cmd, error) { pattern := properties[recipe] if pattern == constants.EMPTY_STRING { return nil, utils.ErrorfWithLogger(logger, constants.MSG_PATTERN_MISSING, recipe) @@ -306,19 +324,34 @@ func ExecRecipeSpecifyStdOutStdErr(properties map[string]string, recipe string, fmt.Println(commandLine) } - if echoOutput { - command.Stdout = stdout + return command, nil +} + +func ExecRecipeCollectStdErr(properties map[string]string, recipe string, removeUnsetProperties bool, echoCommandLine bool, echoOutput bool, logger i18n.Logger) (string, error, error) { + command, err := PrepareCommandForRecipe(properties, recipe, removeUnsetProperties, echoCommandLine, echoOutput, logger) + if err != nil { + return "", nil, utils.WrapError(err) } - command.Stderr = stderr + stderr, err := command.StderrPipe() + if err != nil { + return "", nil, utils.WrapError(err) + } - if echoOutput { - err := command.Run() - return nil, utils.WrapError(err) + err = command.Start() + if err != nil { + return "", nil, utils.WrapError(err) } - bytes, err := command.Output() - return bytes, utils.WrapError(err) + collectedStdErr := "" + sc := bufio.NewScanner(stderr) + for sc.Scan() { + collectedStdErr += sc.Text() + "\n" + } + + err = command.Wait() + + return collectedStdErr, err, nil } func RemoveHyphenMDDFlagFromGCCCommandLine(properties map[string]string) { diff --git a/src/arduino.cc/builder/constants/constants.go b/src/arduino.cc/builder/constants/constants.go index ac528958..35412ff8 100644 --- a/src/arduino.cc/builder/constants/constants.go +++ b/src/arduino.cc/builder/constants/constants.go @@ -95,6 +95,7 @@ const CTX_DEBUG_LEVEL = "debugLevel" const CTX_FOLDERS_WITH_SOURCES_QUEUE = "foldersWithSourcesQueue" const CTX_FQBN = "fqbn" const CTX_GCC_MINUS_E_SOURCE = "gccMinusESource" +const CTX_GCC_MINUS_E_STDERR = "gccMinusEOutput" const CTX_GCC_MINUS_M_OUTPUT = "gccMinusMOutput" const CTX_HARDWARE_FOLDERS = "hardwareFolders" const CTX_HARDWARE = "hardware" @@ -103,6 +104,7 @@ const CTX_IMPORTED_LIBRARIES = "importedLibraries" const CTX_INCLUDE_FOLDERS = "includeFolders" const CTX_INCLUDE_SECTION = "includeSection" const CTX_INCLUDES = "includes" +const CTX_INCLUDES_JUST_FOUND = "includesJustFound" const CTX_LIBRARIES_BUILD_PATH = "librariesBuildPath" const CTX_LIBRARIES_FOLDERS = "librariesFolders" const CTX_LIBRARIES = "libraries" diff --git a/src/arduino.cc/builder/container_find_includes.go b/src/arduino.cc/builder/container_find_includes.go index 92593d80..cddca8fe 100644 --- a/src/arduino.cc/builder/container_find_includes.go +++ b/src/arduino.cc/builder/container_find_includes.go @@ -44,22 +44,11 @@ func (s *ContainerFindIncludes) Run(context map[string]interface{}) error { return utils.WrapError(err) } - sketch := context[constants.CTX_SKETCH].(*types.Sketch) sketchBuildPath := context[constants.CTX_SKETCH_BUILD_PATH].(string) - wheelSpins := context[constants.CTX_LIBRARY_DISCOVERY_RECURSION_DEPTH].(int) - for i := 0; i < wheelSpins; i++ { - commands := []types.Command{ - &IncludesFinderWithGCC{SourceFile: filepath.Join(sketchBuildPath, filepath.Base(sketch.MainFile.Name)+".cpp")}, - &GCCMinusMOutputParser{}, - &IncludesToIncludeFolders{}, - } - - for _, command := range commands { - err := runCommand(context, command) - if err != nil { - return utils.WrapError(err) - } - } + sketch := context[constants.CTX_SKETCH].(*types.Sketch) + err = findIncludesUntilDone(context, filepath.Join(sketchBuildPath, filepath.Base(sketch.MainFile.Name)+".cpp")) + if err != nil { + return utils.WrapError(err) } foldersWithSources := context[constants.CTX_FOLDERS_WITH_SOURCES_QUEUE].(*types.UniqueSourceFolderQueue) @@ -81,18 +70,13 @@ func (s *ContainerFindIncludes) Run(context map[string]interface{}) error { sourceFiles := context[constants.CTX_COLLECTED_SOURCE_FILES_QUEUE].(*types.UniqueStringQueue) for !sourceFiles.Empty() { - commands := []types.Command{ - &IncludesFinderWithGCC{SourceFile: sourceFiles.Pop().(string)}, - &GCCMinusMOutputParser{}, - &IncludesToIncludeFolders{}, - &CollectAllSourceFilesFromFoldersWithSources{}, + err = findIncludesUntilDone(context, sourceFiles.Pop().(string)) + if err != nil { + return utils.WrapError(err) } - - for _, command := range commands { - err := runCommand(context, command) - if err != nil { - return utils.WrapError(err) - } + err := runCommand(context, &CollectAllSourceFilesFromFoldersWithSources{}) + if err != nil { + return utils.WrapError(err) } } @@ -107,3 +91,30 @@ func runCommand(context map[string]interface{}, command types.Command) error { } return nil } + +func findIncludesUntilDone(context map[string]interface{}, sourceFile string) error { + importedLibraries := context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library) + done := false + for !done { + commands := []types.Command{ + &GCCPreprocRunnerForDiscoveringIncludes{SourceFile: sourceFile}, + &IncludesFinderWithRegExp{ContextField: constants.CTX_GCC_MINUS_E_SOURCE}, + &IncludesToIncludeFolders{}, + } + for _, command := range commands { + err := runCommand(context, command) + if err != nil { + return utils.WrapError(err) + } + } + if len(context[constants.CTX_INCLUDES_JUST_FOUND].([]string)) == 0 { + done = true + } else if len(context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library)) == len(importedLibraries) { + err := runCommand(context, &GCCPreprocRunner{}) + return utils.WrapError(err) + } + importedLibraries = context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library) + context[constants.CTX_INCLUDES_JUST_FOUND] = []string{} + } + return nil +} diff --git a/src/arduino.cc/builder/gcc_minus_m_output_parser.go b/src/arduino.cc/builder/gcc_minus_m_output_parser.go index d9a2c6de..757181ca 100644 --- a/src/arduino.cc/builder/gcc_minus_m_output_parser.go +++ b/src/arduino.cc/builder/gcc_minus_m_output_parser.go @@ -60,12 +60,7 @@ func (s *GCCMinusMOutputParser) Run(context map[string]interface{}) error { return nil } - previousIncludes := utils.SliceToMapStringBool(context[constants.CTX_INCLUDES].([]string), true) - currentIncludes := utils.SliceToMapStringBool(includes, true) - - mergedIncludes := utils.MergeMapsOfStringBool(previousIncludes, currentIncludes) - - context[constants.CTX_INCLUDES] = utils.KeysOfMapOfStringBool(mergedIncludes) + context[constants.CTX_INCLUDES] = utils.AddStringsToStringsSet(context[constants.CTX_INCLUDES].([]string), includes) return nil } diff --git a/src/arduino.cc/builder/gcc_preproc_runner.go b/src/arduino.cc/builder/gcc_preproc_runner.go index b3b18d72..c240b1bf 100644 --- a/src/arduino.cc/builder/gcc_preproc_runner.go +++ b/src/arduino.cc/builder/gcc_preproc_runner.go @@ -42,17 +42,9 @@ import ( type GCCPreprocRunner struct{} func (s *GCCPreprocRunner) Run(context map[string]interface{}) error { - buildProperties := utils.GetMapStringStringOrDefault(context, constants.CTX_BUILD_PROPERTIES) - properties := utils.MergeMapsOfStrings(make(map[string]string), buildProperties) - sketchBuildPath := context[constants.CTX_SKETCH_BUILD_PATH].(string) sketch := context[constants.CTX_SKETCH].(*types.Sketch) - properties[constants.BUILD_PROPERTIES_SOURCE_FILE] = filepath.Join(sketchBuildPath, filepath.Base(sketch.MainFile.Name)+".cpp") - - includes := context[constants.CTX_INCLUDE_FOLDERS].([]string) - includes = utils.Map(includes, utils.WrapWithHyphenI) - properties[constants.BUILD_PROPERTIES_INCLUDES] = strings.Join(includes, constants.SPACE) - builder_utils.RemoveHyphenMDDFlagFromGCCCommandLine(properties) + properties := prepareGCCPreprocRecipeProperties(context, filepath.Join(sketchBuildPath, filepath.Base(sketch.MainFile.Name)+".cpp")) verbose := context[constants.CTX_VERBOSE].(bool) logger := context[constants.CTX_LOGGER].(i18n.Logger) @@ -65,3 +57,36 @@ func (s *GCCPreprocRunner) Run(context map[string]interface{}) error { return nil } + +type GCCPreprocRunnerForDiscoveringIncludes struct { + SourceFile string +} + +func (s *GCCPreprocRunnerForDiscoveringIncludes) Run(context map[string]interface{}) error { + properties := prepareGCCPreprocRecipeProperties(context, s.SourceFile) + + verbose := context[constants.CTX_VERBOSE].(bool) + logger := context[constants.CTX_LOGGER].(i18n.Logger) + output, _, err := builder_utils.ExecRecipeCollectStdErr(properties, constants.RECIPE_PREPROC_MACROS, true, verbose, false, logger) + if err != nil { + return utils.WrapError(err) + } + + context[constants.CTX_GCC_MINUS_E_SOURCE] = string(output) + + return nil +} + +func prepareGCCPreprocRecipeProperties(context map[string]interface{}, sourceFile string) map[string]string { + buildProperties := utils.GetMapStringStringOrDefault(context, constants.CTX_BUILD_PROPERTIES) + properties := utils.MergeMapsOfStrings(make(map[string]string), buildProperties) + + properties[constants.BUILD_PROPERTIES_SOURCE_FILE] = sourceFile + + includes := context[constants.CTX_INCLUDE_FOLDERS].([]string) + includes = utils.Map(includes, utils.WrapWithHyphenI) + properties[constants.BUILD_PROPERTIES_INCLUDES] = strings.Join(includes, constants.SPACE) + builder_utils.RemoveHyphenMDDFlagFromGCCCommandLine(properties) + + return properties +} diff --git a/src/arduino.cc/builder/hardware/platform.keys.rewrite.txt b/src/arduino.cc/builder/hardware/platform.keys.rewrite.txt index fccaca39..bd653d16 100644 --- a/src/arduino.cc/builder/hardware/platform.keys.rewrite.txt +++ b/src/arduino.cc/builder/hardware/platform.keys.rewrite.txt @@ -36,3 +36,10 @@ new.10.recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} old.11.recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mmcu={build.mcu} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -lm new.11.recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mmcu={build.mcu} -o "{build.path}/{build.project_name}.elf" {object_files} "{archive_file_path}" "-L{build.path}" -lm + +#generic again +old.12.preproc.includes.flags=-w -x c++ -M -MG -MP +new.12.preproc.includes.flags=-w -x c++ -M -MG -MP -include Arduino.h + +old.13.preproc.macros.flags=-w -x c++ -E -CC +new.13.preproc.macros.flags=-w -x c++ -E -CC -include Arduino.h diff --git a/src/arduino.cc/builder/hardware/platform.txt b/src/arduino.cc/builder/hardware/platform.txt index 1bae1d65..ca718cc1 100644 --- a/src/arduino.cc/builder/hardware/platform.txt +++ b/src/arduino.cc/builder/hardware/platform.txt @@ -7,9 +7,10 @@ tools.ctags.pattern="{cmd.path}" -u --language-force=c++ -f - --c++-kinds=svpf - # additional entries tools.avrdude.path={runtime.tools.avrdude.path} -preproc.includes.flags=-w -x c++ -M -MG -MP -recipe.preproc.includes="{compiler.path}{compiler.cpp.cmd}" {preproc.includes.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" +preproc.includes.flags=-w -x c++ -M -MG -MP -include Arduino.h +preproc.includes.compatibility_flags={build.mbed_api_include} {build.nRF51822_api_include} {build.ble_api_include} {compiler.libsam.c.flags} {compiler.arm.cmsis.path} {build.variant_system_include} +recipe.preproc.includes="{compiler.path}{compiler.cpp.cmd}" {preproc.includes.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {preproc.includes.compatibility_flags} {includes} "{source_file}" -preproc.macros.flags=-w -x c++ -E -CC +preproc.macros.flags=-w -x c++ -E -CC -include Arduino.h preproc.macros.compatibility_flags={build.mbed_api_include} {build.nRF51822_api_include} {build.ble_api_include} {compiler.libsam.c.flags} {compiler.arm.cmsis.path} {build.variant_system_include} recipe.preproc.macros="{compiler.path}{compiler.cpp.cmd}" {compiler.cpreprocessor.flags} {compiler.cpp.flags} {preproc.macros.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {preproc.macros.compatibility_flags} {includes} "{source_file}" diff --git a/src/arduino.cc/builder/includes_finder_with_regexp.go b/src/arduino.cc/builder/includes_finder_with_regexp.go index 874454ef..216dd6eb 100644 --- a/src/arduino.cc/builder/includes_finder_with_regexp.go +++ b/src/arduino.cc/builder/includes_finder_with_regexp.go @@ -31,24 +31,34 @@ package builder import ( "arduino.cc/builder/constants" + "arduino.cc/builder/utils" "regexp" "strings" ) var INCLUDE_REGEXP = regexp.MustCompile("(?ms)^\\s*#include\\s*[<\"](\\S+)[\">]") -type IncludesFinderWithRegExp struct{} +type IncludesFinderWithRegExp struct { + ContextField string +} func (s *IncludesFinderWithRegExp) Run(context map[string]interface{}) error { - source := context[constants.CTX_SOURCE].(string) + source := context[s.ContextField].(string) matches := INCLUDE_REGEXP.FindAllStringSubmatch(source, -1) - var includes []string + includes := []string{} for _, match := range matches { includes = append(includes, strings.TrimSpace(match[1])) } - context[constants.CTX_INCLUDES] = includes + context[constants.CTX_INCLUDES_JUST_FOUND] = includes + + if !utils.MapHas(context, constants.CTX_INCLUDES) { + context[constants.CTX_INCLUDES] = includes + return nil + } + + context[constants.CTX_INCLUDES] = utils.AddStringsToStringsSet(context[constants.CTX_INCLUDES].([]string), includes) return nil } diff --git a/src/arduino.cc/builder/test/builder_test.go b/src/arduino.cc/builder/test/builder_test.go index 5e74f697..2c09c362 100644 --- a/src/arduino.cc/builder/test/builder_test.go +++ b/src/arduino.cc/builder/test/builder_test.go @@ -53,8 +53,8 @@ func TestBuilderEmptySketch(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" - // context[constants.CTX_VERBOSE] = true - // context[constants.CTX_DEBUG_LEVEL] = 10 + context[constants.CTX_VERBOSE] = true + context[constants.CTX_DEBUG_LEVEL] = 10 command := builder.Builder{} err := command.Run(context) diff --git a/src/arduino.cc/builder/test/coan_runner_test.go b/src/arduino.cc/builder/test/coan_runner_test.go index 02d4cd54..0393455b 100644 --- a/src/arduino.cc/builder/test/coan_runner_test.go +++ b/src/arduino.cc/builder/test/coan_runner_test.go @@ -54,7 +54,7 @@ func TestCoanRunner(t *testing.T) { context[constants.CTX_FQBN] = "arduino:avr:leonardo" context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch2", "SketchWithIfDef.ino") context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, diff --git a/src/arduino.cc/builder/test/ctags_runner_test.go b/src/arduino.cc/builder/test/ctags_runner_test.go index 6acdb6c5..30ce129e 100644 --- a/src/arduino.cc/builder/test/ctags_runner_test.go +++ b/src/arduino.cc/builder/test/ctags_runner_test.go @@ -56,7 +56,7 @@ func TestCTagsRunner(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -106,7 +106,7 @@ func TestCTagsRunnerSketchWithClass(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -154,7 +154,7 @@ func TestCTagsRunnerSketchWithTypename(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -201,7 +201,7 @@ func TestCTagsRunnerSketchWithNamespace(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, diff --git a/src/arduino.cc/builder/test/hardware_loader_test.go b/src/arduino.cc/builder/test/hardware_loader_test.go index e0fec6e3..2f540479 100644 --- a/src/arduino.cc/builder/test/hardware_loader_test.go +++ b/src/arduino.cc/builder/test/hardware_loader_test.go @@ -81,7 +81,7 @@ func TestLoadHardware(t *testing.T) { require.Equal(t, "{runtime.tools.ctags.path}", packages.Properties["tools.ctags.path"]) require.Equal(t, "\"{cmd.path}\" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives \"{source_file}\"", packages.Properties["tools.ctags.pattern"]) require.Equal(t, "{runtime.tools.avrdude.path}", packages.Properties["tools.avrdude.path"]) - require.Equal(t, "-w -x c++ -E -CC", packages.Properties["preproc.macros.flags"]) + require.Equal(t, "-w -x c++ -E -CC -include Arduino.h", packages.Properties["preproc.macros.flags"]) } func TestLoadHardwareMixingUserHardwareFolder(t *testing.T) { @@ -130,8 +130,8 @@ func TestLoadHardwareMixingUserHardwareFolder(t *testing.T) { require.Equal(t, "AVRISP mkII", avrPlatform.Programmers["avrispmkii"][constants.PROGRAMMER_NAME]) - require.Equal(t, "-w -x c++ -M -MG -MP", avrPlatform.Properties["preproc.includes.flags"]) - require.Equal(t, "-w -x c++ -E -CC", avrPlatform.Properties["preproc.macros.flags"]) + require.Equal(t, "-w -x c++ -M -MG -MP -include Arduino.h", avrPlatform.Properties["preproc.includes.flags"]) + require.Equal(t, "-w -x c++ -E -CC -include Arduino.h", avrPlatform.Properties["preproc.macros.flags"]) require.Equal(t, "\"{compiler.path}{compiler.cpp.cmd}\" {compiler.cpp.flags} {preproc.includes.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} \"{source_file}\"", avrPlatform.Properties[constants.RECIPE_PREPROC_INCLUDES]) require.False(t, utils.MapStringStringHas(avrPlatform.Properties, "preproc.macros.compatibility_flags")) @@ -146,7 +146,7 @@ func TestLoadHardwareMixingUserHardwareFolder(t *testing.T) { require.Equal(t, "{runtime.tools.ctags.path}", packages.Properties["tools.ctags.path"]) require.Equal(t, "\"{cmd.path}\" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives \"{source_file}\"", packages.Properties["tools.ctags.pattern"]) require.Equal(t, "{runtime.tools.avrdude.path}", packages.Properties["tools.avrdude.path"]) - require.Equal(t, "-w -x c++ -E -CC", packages.Properties["preproc.macros.flags"]) + require.Equal(t, "-w -x c++ -E -CC -include Arduino.h", packages.Properties["preproc.macros.flags"]) require.Equal(t, "{build.mbed_api_include} {build.nRF51822_api_include} {build.ble_api_include} {compiler.libsam.c.flags} {compiler.arm.cmsis.path} {build.variant_system_include}", packages.Properties["preproc.macros.compatibility_flags"]) if runtime.GOOS != "windows" { diff --git a/src/arduino.cc/builder/test/helper_tools_downloader.go b/src/arduino.cc/builder/test/helper_tools_downloader.go index 2faa271a..f4618e8b 100644 --- a/src/arduino.cc/builder/test/helper_tools_downloader.go +++ b/src/arduino.cc/builder/test/helper_tools_downloader.go @@ -122,6 +122,7 @@ func DownloadCoresAndToolsAndLibraries(t *testing.T) { boardsManagerTools := []Tool{ Tool{Name: "openocd", Version: "0.9.0-arduino", Package: "arduino"}, + Tool{Name: "CMSIS", Version: "4.0.0-atmel", Package: "arduino"}, } boardsManagerRFduinoTools := []Tool{ diff --git a/src/arduino.cc/builder/test/includes_finder_with_gcc_test.go b/src/arduino.cc/builder/test/includes_finder_with_gcc_test.go index 8c2808a5..7f2c3e11 100644 --- a/src/arduino.cc/builder/test/includes_finder_with_gcc_test.go +++ b/src/arduino.cc/builder/test/includes_finder_with_gcc_test.go @@ -54,7 +54,7 @@ func TestIncludesFinderWithGCC(t *testing.T) { context[constants.CTX_FQBN] = "arduino:avr:leonardo" context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch2", "SketchWithIfDef.ino") context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -71,12 +71,7 @@ func TestIncludesFinderWithGCC(t *testing.T) { NoError(t, err) } - require.NotNil(t, context[constants.CTX_INCLUDES]) - includes := context[constants.CTX_INCLUDES].([]string) - require.Equal(t, 2, len(includes)) - sort.Strings(includes) - require.Equal(t, filepath.Join(buildPath, constants.FOLDER_SKETCH, "empty_1.h"), includes[0]) - require.Equal(t, filepath.Join(buildPath, constants.FOLDER_SKETCH, "empty_2.h"), includes[1]) + require.Nil(t, context[constants.CTX_INCLUDES]) } func TestIncludesFinderWithGCCSketchWithConfig(t *testing.T) { @@ -94,7 +89,7 @@ func TestIncludesFinderWithGCCSketchWithConfig(t *testing.T) { context[constants.CTX_FQBN] = "arduino:avr:leonardo" context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_config", "sketch_with_config.ino") context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -113,8 +108,7 @@ func TestIncludesFinderWithGCCSketchWithConfig(t *testing.T) { require.NotNil(t, context[constants.CTX_INCLUDES]) includes := context[constants.CTX_INCLUDES].([]string) - require.True(t, utils.SliceContains(includes, filepath.Join(buildPath, constants.FOLDER_SKETCH, "config.h"))) - require.True(t, utils.SliceContains(includes, filepath.Join(buildPath, constants.FOLDER_SKETCH, "includes")+"/de bug.h")) + require.Equal(t, 1, len(includes)) require.True(t, utils.SliceContains(includes, "Bridge.h")) importedLibraries := context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library) @@ -136,7 +130,7 @@ func TestIncludesFinderWithGCCSketchWithDependendLibraries(t *testing.T) { context[constants.CTX_FQBN] = "arduino:avr:leonardo" context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_dependend_libraries", "sketch.ino") context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -155,16 +149,13 @@ func TestIncludesFinderWithGCCSketchWithDependendLibraries(t *testing.T) { require.NotNil(t, context[constants.CTX_INCLUDES]) includes := context[constants.CTX_INCLUDES].([]string) - require.Equal(t, 7, len(includes)) + require.Equal(t, 4, len(includes)) sort.Strings(includes) - require.Equal(t, Abs(t, filepath.Join("dependent_libraries", "library1"))+"/library1.h", includes[0]) - require.Equal(t, Abs(t, filepath.Join("dependent_libraries", "library2"))+"/library2.h", includes[1]) - require.Equal(t, Abs(t, filepath.Join("dependent_libraries", "library3"))+"/library3.h", includes[2]) - require.Equal(t, "library1.h", includes[3]) - require.Equal(t, "library2.h", includes[4]) - require.Equal(t, "library3.h", includes[5]) - require.Equal(t, "library4.h", includes[6]) + require.Equal(t, "library1.h", includes[0]) + require.Equal(t, "library2.h", includes[1]) + require.Equal(t, "library3.h", includes[2]) + require.Equal(t, "library4.h", includes[3]) importedLibraries := context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library) require.Equal(t, 4, len(importedLibraries)) @@ -175,3 +166,91 @@ func TestIncludesFinderWithGCCSketchWithDependendLibraries(t *testing.T) { require.Equal(t, "library3", importedLibraries[2].Name) require.Equal(t, "library4", importedLibraries[3].Name) } + +func TestIncludesFinderWithGCCSketchWithThatChecksIfSPIHasTransactions(t *testing.T) { + DownloadCoresAndToolsAndLibraries(t) + + context := make(map[string]interface{}) + + buildPath := SetupBuildPath(t, context) + defer os.RemoveAll(buildPath) + + context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} + context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} + context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} + context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"dependent_libraries", "libraries"} + context[constants.CTX_FQBN] = "arduino:avr:leonardo" + context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_that_checks_if_SPI_has_transactions", "sketch.ino") + context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" + context[constants.CTX_VERBOSE] = true + + commands := []types.Command{ + &builder.SetupHumanLoggerIfMissing{}, + + &builder.ContainerSetupHardwareToolsLibsSketchAndProps{}, + + &builder.ContainerMergeCopySketchFiles{}, + + &builder.ContainerFindIncludes{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + require.NotNil(t, context[constants.CTX_INCLUDES]) + includes := context[constants.CTX_INCLUDES].([]string) + require.Equal(t, 1, len(includes)) + require.Equal(t, "SPI.h", includes[0]) + + importedLibraries := context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library) + require.Equal(t, 1, len(importedLibraries)) + require.Equal(t, "SPI", importedLibraries[0].Name) +} + +func TestIncludesFinderWithGCCSketchWithThatChecksIfSPIHasTransactionsAndIncludesMissingEthernet(t *testing.T) { + DownloadCoresAndToolsAndLibraries(t) + + context := make(map[string]interface{}) + + buildPath := SetupBuildPath(t, context) + defer os.RemoveAll(buildPath) + + context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} + context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} + context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} + context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"dependent_libraries", "libraries"} + context[constants.CTX_FQBN] = "arduino:avr:leonardo" + context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_that_checks_if_SPI_has_transactions_and_includes_missing_Ethernet", "sketch.ino") + context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" + context[constants.CTX_VERBOSE] = true + + commands := []types.Command{ + &builder.SetupHumanLoggerIfMissing{}, + + &builder.ContainerSetupHardwareToolsLibsSketchAndProps{}, + + &builder.ContainerMergeCopySketchFiles{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + command := &builder.ContainerFindIncludes{} + err := command.Run(context) + require.Error(t, err) + + require.NotNil(t, context[constants.CTX_INCLUDES]) + includes := context[constants.CTX_INCLUDES].([]string) + require.Equal(t, 2, len(includes)) + sort.Strings(includes) + require.Equal(t, "Ethernet.h", includes[0]) + require.Equal(t, "SPI.h", includes[1]) + + importedLibraries := context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library) + require.Equal(t, 1, len(importedLibraries)) + require.Equal(t, "SPI", importedLibraries[0].Name) +} diff --git a/src/arduino.cc/builder/test/includes_finder_with_regexp_test.go b/src/arduino.cc/builder/test/includes_finder_with_regexp_test.go index 46a07d98..3bc7e781 100644 --- a/src/arduino.cc/builder/test/includes_finder_with_regexp_test.go +++ b/src/arduino.cc/builder/test/includes_finder_with_regexp_test.go @@ -39,7 +39,7 @@ import ( "testing" ) -func TestIncludesFinderWithRegExp(t *testing.T) { +func TestIncludesFinderWithRegExpCoanOutput(t *testing.T) { DownloadCoresAndToolsAndLibraries(t) context := make(map[string]interface{}) @@ -52,7 +52,7 @@ func TestIncludesFinderWithRegExp(t *testing.T) { context[constants.CTX_FQBN] = "arduino:avr:leonardo" context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch2", "SketchWithIfDef.ino") context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -62,6 +62,8 @@ func TestIncludesFinderWithRegExp(t *testing.T) { &builder.ContainerMergeCopySketchFiles{}, &builder.CoanRunner{}, + + &builder.IncludesFinderWithRegExp{ContextField: constants.CTX_SOURCE}, } for _, command := range commands { @@ -69,13 +71,67 @@ func TestIncludesFinderWithRegExp(t *testing.T) { NoError(t, err) } - includesFinder := builder.IncludesFinderWithRegExp{} - err := includesFinder.Run(context) - NoError(t, err) - require.NotNil(t, context[constants.CTX_INCLUDES]) includes := context[constants.CTX_INCLUDES].([]string) require.Equal(t, 2, len(includes)) require.Equal(t, "empty_1.h", includes[0]) require.Equal(t, "empty_2.h", includes[1]) } + +func TestIncludesFinderWithRegExp(t *testing.T) { + context := make(map[string]interface{}) + + output := "/home/federico/materiale/works_Arduino/arduino-builder/src/arduino.cc/builder/test/sketch_that_checks_if_SPI_has_transactions/sketch.ino:1:17: fatal error: SPI.h: No such file or directory\n" + + "#include \n" + + "^\n" + + "compilation terminated." + context[constants.CTX_GCC_MINUS_E_STDERR] = output + + parser := builder.IncludesFinderWithRegExp{ContextField: constants.CTX_GCC_MINUS_E_STDERR} + err := parser.Run(context) + NoError(t, err) + + require.NotNil(t, context[constants.CTX_INCLUDES]) + includes := context[constants.CTX_INCLUDES].([]string) + require.Equal(t, 1, len(includes)) + require.Equal(t, "SPI.h", includes[0]) +} + +func TestIncludesFinderWithRegExpEmptyOutput(t *testing.T) { + context := make(map[string]interface{}) + + output := "" + + context[constants.CTX_GCC_MINUS_E_STDERR] = output + + parser := builder.IncludesFinderWithRegExp{ContextField: constants.CTX_GCC_MINUS_E_STDERR} + err := parser.Run(context) + NoError(t, err) + + require.NotNil(t, context[constants.CTX_INCLUDES]) + includes := context[constants.CTX_INCLUDES].([]string) + require.Equal(t, 0, len(includes)) +} + +func TestIncludesFinderWithRegExpPreviousIncludes(t *testing.T) { + context := make(map[string]interface{}) + + context[constants.CTX_INCLUDES] = []string{"test.h"} + + output := "/home/federico/materiale/works_Arduino/arduino-builder/src/arduino.cc/builder/test/sketch_that_checks_if_SPI_has_transactions/sketch.ino:1:17: fatal error: SPI.h: No such file or directory\n" + + "#include \n" + + "^\n" + + "compilation terminated." + + context[constants.CTX_GCC_MINUS_E_STDERR] = output + + parser := builder.IncludesFinderWithRegExp{ContextField: constants.CTX_GCC_MINUS_E_STDERR} + err := parser.Run(context) + NoError(t, err) + + require.NotNil(t, context[constants.CTX_INCLUDES]) + includes := context[constants.CTX_INCLUDES].([]string) + require.Equal(t, 2, len(includes)) + require.Equal(t, "test.h", includes[0]) + require.Equal(t, "SPI.h", includes[1]) +} diff --git a/src/arduino.cc/builder/test/includes_to_include_folders_test.go b/src/arduino.cc/builder/test/includes_to_include_folders_test.go index b035221e..8d29018b 100644 --- a/src/arduino.cc/builder/test/includes_to_include_folders_test.go +++ b/src/arduino.cc/builder/test/includes_to_include_folders_test.go @@ -55,7 +55,7 @@ func TestIncludesToIncludeFolders(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -96,7 +96,7 @@ func TestIncludesToIncludeFoldersSketchWithIfDef(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -135,7 +135,7 @@ func TestIncludesToIncludeFoldersIRremoteLibrary(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -179,7 +179,7 @@ func TestIncludesToIncludeFoldersANewLibrary(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -222,7 +222,7 @@ func TestIncludesToIncludeFoldersDuplicateLibs(t *testing.T) { context[constants.CTX_SKETCH_LOCATION] = filepath.Join("user_hardware", "my_avr_platform", "avr", "libraries", "SPI", "examples", "BarometricPressureSensor", "BarometricPressureSensor.ino") context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -265,7 +265,7 @@ func TestIncludesToIncludeFoldersDuplicateLibsWithConflictingLibsOutsideOfPlatfo context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -308,6 +308,7 @@ func TestIncludesToIncludeFoldersDuplicateLibs2(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, diff --git a/src/arduino.cc/builder/test/platform_keys_rewrite_loader_test.go b/src/arduino.cc/builder/test/platform_keys_rewrite_loader_test.go index e8b714e5..be1a938e 100644 --- a/src/arduino.cc/builder/test/platform_keys_rewrite_loader_test.go +++ b/src/arduino.cc/builder/test/platform_keys_rewrite_loader_test.go @@ -54,7 +54,7 @@ func TestLoadPlatformKeysRewrite(t *testing.T) { platformKeysRewrite := context[constants.CTX_PLATFORM_KEYS_REWRITE].(types.PlatforKeysRewrite) - require.Equal(t, 12, len(platformKeysRewrite.Rewrites)) + require.Equal(t, 14, len(platformKeysRewrite.Rewrites)) require.Equal(t, constants.BUILD_PROPERTIES_COMPILER_PATH, platformKeysRewrite.Rewrites[0].Key) require.Equal(t, "{runtime.ide.path}/hardware/tools/avr/bin/", platformKeysRewrite.Rewrites[0].OldValue) require.Equal(t, "{runtime.tools.avr-gcc.path}/bin/", platformKeysRewrite.Rewrites[0].NewValue) diff --git a/src/arduino.cc/builder/test/prototypes_adder_test.go b/src/arduino.cc/builder/test/prototypes_adder_test.go index 32a3fb69..0107546b 100644 --- a/src/arduino.cc/builder/test/prototypes_adder_test.go +++ b/src/arduino.cc/builder/test/prototypes_adder_test.go @@ -56,7 +56,7 @@ func TestPrototypesAdderBridgeExample(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -97,7 +97,7 @@ func TestPrototypesAdderSketchWithIfDef(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -138,7 +138,7 @@ func TestPrototypesAdderBaladuino(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -179,7 +179,7 @@ func TestPrototypesAdderCharWithEscapedDoubleQuote(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -220,7 +220,7 @@ func TestPrototypesAdderIncludeBetweenMultilineComment(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -261,7 +261,7 @@ func TestPrototypesAdderLineContinuations(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -302,7 +302,7 @@ func TestPrototypesAdderStringWithComment(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -343,7 +343,7 @@ func TestPrototypesAdderSketchWithStruct(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -384,7 +384,7 @@ func TestPrototypesAdderSketchWithConfig(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -428,7 +428,7 @@ func TestPrototypesAdderSketchNoFunctionsTwoFiles(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -469,7 +469,7 @@ func TestPrototypesAdderSketchNoFunctions(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -510,7 +510,7 @@ func TestPrototypesAdderSketchWithDefaultArgs(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -551,7 +551,7 @@ func TestPrototypesAdderSketchWithInlineFunction(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -592,7 +592,7 @@ func TestPrototypesAdderSketchWithFunctionSignatureInsideIFDEF(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -633,7 +633,7 @@ func TestPrototypesAdderSketchWithUSBCON(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -673,7 +673,7 @@ func TestPrototypesAdderSketchWithTypename(t *testing.T) { context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_typename", "sketch.ino") context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_LIBRARIES_FOLDERS] = []string{"libraries", "downloaded_libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -714,7 +714,7 @@ func TestPrototypesAdderSketchWithIfDef2(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, diff --git a/src/arduino.cc/builder/test/sketch_that_checks_if_SPI_has_transactions/sketch.ino b/src/arduino.cc/builder/test/sketch_that_checks_if_SPI_has_transactions/sketch.ino new file mode 100644 index 00000000..106c39f2 --- /dev/null +++ b/src/arduino.cc/builder/test/sketch_that_checks_if_SPI_has_transactions/sketch.ino @@ -0,0 +1,8 @@ +#include + +#if !defined(SPI_HAS_TRANSACTION) || !SPI_HAS_TRANSACTION +#error "Where is my SPI_HAS_TRANSACTION!?!?" +#endif + +void setup() {} +void loop() {} diff --git a/src/arduino.cc/builder/test/sketch_that_checks_if_SPI_has_transactions_and_includes_missing_Ethernet/sketch.ino b/src/arduino.cc/builder/test/sketch_that_checks_if_SPI_has_transactions_and_includes_missing_Ethernet/sketch.ino new file mode 100644 index 00000000..1a2f81c1 --- /dev/null +++ b/src/arduino.cc/builder/test/sketch_that_checks_if_SPI_has_transactions_and_includes_missing_Ethernet/sketch.ino @@ -0,0 +1,9 @@ +#include +#include + +#if !defined(SPI_HAS_TRANSACTION) || !SPI_HAS_TRANSACTION +#error "Where is my SPI_HAS_TRANSACTION!?!?" +#endif + +void setup() {} +void loop() {} diff --git a/src/arduino.cc/builder/test/tools_loader_test.go b/src/arduino.cc/builder/test/tools_loader_test.go index c3d7a18c..07965598 100644 --- a/src/arduino.cc/builder/test/tools_loader_test.go +++ b/src/arduino.cc/builder/test/tools_loader_test.go @@ -101,17 +101,18 @@ func TestLoadToolsWithBoardManagerFolderStructure(t *testing.T) { NoError(t, err) tools := context[constants.CTX_TOOLS].([]*types.Tool) - require.Equal(t, 2, len(tools)) + require.Equal(t, 3, len(tools)) sort.Sort(ByToolIDAndVersion(tools)) - require.Equal(t, "arm-none-eabi-gcc", tools[0].Name) - require.Equal(t, "4.8.3-2014q1", tools[0].Version) - require.Equal(t, Abs(t, "./downloaded_board_manager_stuff/RFduino/tools/arm-none-eabi-gcc/4.8.3-2014q1"), tools[0].Folder) + require.Equal(t, "CMSIS", tools[0].Name) + require.Equal(t, "arm-none-eabi-gcc", tools[1].Name) + require.Equal(t, "4.8.3-2014q1", tools[1].Version) + require.Equal(t, Abs(t, "./downloaded_board_manager_stuff/RFduino/tools/arm-none-eabi-gcc/4.8.3-2014q1"), tools[1].Folder) - require.Equal(t, "openocd", tools[1].Name) - require.Equal(t, "0.9.0-arduino", tools[1].Version) - require.Equal(t, Abs(t, "./downloaded_board_manager_stuff/arduino/tools/openocd/0.9.0-arduino"), tools[1].Folder) + require.Equal(t, "openocd", tools[2].Name) + require.Equal(t, "0.9.0-arduino", tools[2].Version) + require.Equal(t, Abs(t, "./downloaded_board_manager_stuff/arduino/tools/openocd/0.9.0-arduino"), tools[2].Folder) } func TestLoadLotsOfTools(t *testing.T) { @@ -125,12 +126,13 @@ func TestLoadLotsOfTools(t *testing.T) { NoError(t, err) tools := context[constants.CTX_TOOLS].([]*types.Tool) - require.Equal(t, 8, len(tools)) + require.Equal(t, 9, len(tools)) require.Equal(t, "arm-none-eabi-gcc", tools[0].Name) require.Equal(t, "4.8.3-2014q1", tools[0].Version) - require.Equal(t, "openocd", tools[7].Name) - require.Equal(t, "0.9.0-arduino", tools[7].Version) - require.Equal(t, Abs(t, "./downloaded_board_manager_stuff/arduino/tools/openocd/0.9.0-arduino"), tools[7].Folder) + require.Equal(t, "CMSIS", tools[7].Name) + require.Equal(t, "openocd", tools[8].Name) + require.Equal(t, "0.9.0-arduino", tools[8].Version) + require.Equal(t, Abs(t, "./downloaded_board_manager_stuff/arduino/tools/openocd/0.9.0-arduino"), tools[8].Folder) } diff --git a/src/arduino.cc/builder/test/user_hardware/my_avr_platform/avr/boards.txt b/src/arduino.cc/builder/test/user_hardware/my_avr_platform/avr/boards.txt index 92a60d27..75bfb3dc 100644 --- a/src/arduino.cc/builder/test/user_hardware/my_avr_platform/avr/boards.txt +++ b/src/arduino.cc/builder/test/user_hardware/my_avr_platform/avr/boards.txt @@ -30,7 +30,7 @@ custom_yun.build.vid=0x2341 custom_yun.build.pid=0x8041 custom_yun.build.usb_product="Arduino My" custom_yun.build.board=AVR_YUN -custom_yun.build.variant=yun +custom_yun.build.variant=arduino:yun custom_yun.build.extra_flags={build.usb_flags} mymega.name=Arduino Mega or Mega 2560 diff --git a/src/arduino.cc/builder/utils/utils.go b/src/arduino.cc/builder/utils/utils.go index 8983c821..83719b7b 100644 --- a/src/arduino.cc/builder/utils/utils.go +++ b/src/arduino.cc/builder/utils/utils.go @@ -426,3 +426,12 @@ func LibraryToSourceFolder(library *types.Library) []types.SourceFolder { } return sourceFolders } + +func AddStringsToStringsSet(accumulator []string, stringsToAdd []string) []string { + previousStringsSet := SliceToMapStringBool(accumulator, true) + stringsSetToAdd := SliceToMapStringBool(stringsToAdd, true) + + newStringsSet := MergeMapsOfStringBool(previousStringsSet, stringsSetToAdd) + + return KeysOfMapOfStringBool(newStringsSet) +} From 565aab0f15d32c2f2e447b1940260c48516a5cee Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Wed, 11 Nov 2015 15:00:59 +0100 Subject: [PATCH 26/85] Sorting test output, otherwise test may randomly fail Signed-off-by: Federico Fissore --- .../builder/test/includes_finder_with_regexp_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/arduino.cc/builder/test/includes_finder_with_regexp_test.go b/src/arduino.cc/builder/test/includes_finder_with_regexp_test.go index 3bc7e781..0165ce90 100644 --- a/src/arduino.cc/builder/test/includes_finder_with_regexp_test.go +++ b/src/arduino.cc/builder/test/includes_finder_with_regexp_test.go @@ -36,6 +36,7 @@ import ( "github.com/stretchr/testify/require" "os" "path/filepath" + "sort" "testing" ) @@ -132,6 +133,7 @@ func TestIncludesFinderWithRegExpPreviousIncludes(t *testing.T) { require.NotNil(t, context[constants.CTX_INCLUDES]) includes := context[constants.CTX_INCLUDES].([]string) require.Equal(t, 2, len(includes)) - require.Equal(t, "test.h", includes[0]) - require.Equal(t, "SPI.h", includes[1]) + sort.Strings(includes) + require.Equal(t, "SPI.h", includes[0]) + require.Equal(t, "test.h", includes[1]) } From 49fd1f8f19540b894f3deb87bf314d7189693546 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Wed, 11 Nov 2015 16:46:05 +0100 Subject: [PATCH 27/85] Better way of collecting output from stderr Signed-off-by: Federico Fissore --- src/arduino.cc/builder/builder_utils/utils.go | 29 +++++-------------- src/arduino.cc/builder/gcc_preproc_runner.go | 2 +- 2 files changed, 8 insertions(+), 23 deletions(-) diff --git a/src/arduino.cc/builder/builder_utils/utils.go b/src/arduino.cc/builder/builder_utils/utils.go index 94e43873..26accab6 100644 --- a/src/arduino.cc/builder/builder_utils/utils.go +++ b/src/arduino.cc/builder/builder_utils/utils.go @@ -34,7 +34,7 @@ import ( "arduino.cc/builder/i18n" "arduino.cc/builder/props" "arduino.cc/builder/utils" - "bufio" + "bytes" "fmt" "os" "os/exec" @@ -327,31 +327,16 @@ func PrepareCommandForRecipe(properties map[string]string, recipe string, remove return command, nil } -func ExecRecipeCollectStdErr(properties map[string]string, recipe string, removeUnsetProperties bool, echoCommandLine bool, echoOutput bool, logger i18n.Logger) (string, error, error) { +func ExecRecipeCollectStdErr(properties map[string]string, recipe string, removeUnsetProperties bool, echoCommandLine bool, echoOutput bool, logger i18n.Logger) (string, error) { command, err := PrepareCommandForRecipe(properties, recipe, removeUnsetProperties, echoCommandLine, echoOutput, logger) if err != nil { - return "", nil, utils.WrapError(err) - } - - stderr, err := command.StderrPipe() - if err != nil { - return "", nil, utils.WrapError(err) - } - - err = command.Start() - if err != nil { - return "", nil, utils.WrapError(err) - } - - collectedStdErr := "" - sc := bufio.NewScanner(stderr) - for sc.Scan() { - collectedStdErr += sc.Text() + "\n" + return "", utils.WrapError(err) } - err = command.Wait() - - return collectedStdErr, err, nil + buffer := &bytes.Buffer{} + command.Stderr = buffer + command.Run() + return string(buffer.Bytes()), nil } func RemoveHyphenMDDFlagFromGCCCommandLine(properties map[string]string) { diff --git a/src/arduino.cc/builder/gcc_preproc_runner.go b/src/arduino.cc/builder/gcc_preproc_runner.go index c240b1bf..b6097e64 100644 --- a/src/arduino.cc/builder/gcc_preproc_runner.go +++ b/src/arduino.cc/builder/gcc_preproc_runner.go @@ -67,7 +67,7 @@ func (s *GCCPreprocRunnerForDiscoveringIncludes) Run(context map[string]interfac verbose := context[constants.CTX_VERBOSE].(bool) logger := context[constants.CTX_LOGGER].(i18n.Logger) - output, _, err := builder_utils.ExecRecipeCollectStdErr(properties, constants.RECIPE_PREPROC_MACROS, true, verbose, false, logger) + output, err := builder_utils.ExecRecipeCollectStdErr(properties, constants.RECIPE_PREPROC_MACROS, true, verbose, false, logger) if err != nil { return utils.WrapError(err) } From cad108ba590e872bc35b08cb2ab58d05a7edc605 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Wed, 11 Nov 2015 17:27:21 +0100 Subject: [PATCH 28/85] Splitting preprocessing in two commands, with different params. New gcc -E -dM is just like gcc -E but does NOT outputs preprocessed code which makes arduino-builder run faster on Windows Signed-off-by: Federico Fissore --- src/arduino.cc/builder/constants/constants.go | 1 + src/arduino.cc/builder/gcc_preproc_runner.go | 2 +- .../hardware/platform.keys.rewrite.txt | 7 ++----- src/arduino.cc/builder/hardware/platform.txt | 6 +++++- src/arduino.cc/builder/test/builder_test.go | 1 + .../avr_platform_patch.patch | 21 +++++++------------ .../builder/test/hardware/platform.txt | 6 ------ .../builder/test/hardware_loader_test.go | 9 ++++---- .../test/platform_keys_rewrite_loader_test.go | 2 +- 9 files changed, 24 insertions(+), 31 deletions(-) diff --git a/src/arduino.cc/builder/constants/constants.go b/src/arduino.cc/builder/constants/constants.go index 35412ff8..3837c542 100644 --- a/src/arduino.cc/builder/constants/constants.go +++ b/src/arduino.cc/builder/constants/constants.go @@ -252,6 +252,7 @@ const RECIPE_AR_PATTERN = "recipe.ar.pattern" const RECIPE_C_COMBINE_PATTERN = "recipe.c.combine.pattern" const RECIPE_C_PATTERN = "recipe.c.o.pattern" const RECIPE_CPP_PATTERN = "recipe.cpp.o.pattern" +const RECIPE_PREPROC_FINAL = "recipe.preproc.final" const RECIPE_PREPROC_INCLUDES = "recipe.preproc.includes" const RECIPE_PREPROC_MACROS = "recipe.preproc.macros" const RECIPE_S_PATTERN = "recipe.S.o.pattern" diff --git a/src/arduino.cc/builder/gcc_preproc_runner.go b/src/arduino.cc/builder/gcc_preproc_runner.go index b6097e64..d77fcd08 100644 --- a/src/arduino.cc/builder/gcc_preproc_runner.go +++ b/src/arduino.cc/builder/gcc_preproc_runner.go @@ -48,7 +48,7 @@ func (s *GCCPreprocRunner) Run(context map[string]interface{}) error { verbose := context[constants.CTX_VERBOSE].(bool) logger := context[constants.CTX_LOGGER].(i18n.Logger) - output, err := builder_utils.ExecRecipe(properties, constants.RECIPE_PREPROC_MACROS, true, verbose, false, logger) + output, err := builder_utils.ExecRecipe(properties, constants.RECIPE_PREPROC_FINAL, true, verbose, false, logger) if err != nil { return utils.WrapError(err) } diff --git a/src/arduino.cc/builder/hardware/platform.keys.rewrite.txt b/src/arduino.cc/builder/hardware/platform.keys.rewrite.txt index bd653d16..6fb8d9b3 100644 --- a/src/arduino.cc/builder/hardware/platform.keys.rewrite.txt +++ b/src/arduino.cc/builder/hardware/platform.keys.rewrite.txt @@ -38,8 +38,5 @@ old.11.recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler. new.11.recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mmcu={build.mcu} -o "{build.path}/{build.project_name}.elf" {object_files} "{archive_file_path}" "-L{build.path}" -lm #generic again -old.12.preproc.includes.flags=-w -x c++ -M -MG -MP -new.12.preproc.includes.flags=-w -x c++ -M -MG -MP -include Arduino.h - -old.13.preproc.macros.flags=-w -x c++ -E -CC -new.13.preproc.macros.flags=-w -x c++ -E -CC -include Arduino.h +old.12.preproc.macros.flags=-w -x c++ -E -CC +new.12.preproc.macros.flags=-w -x c++ -E -CC -dM -include Arduino.h diff --git a/src/arduino.cc/builder/hardware/platform.txt b/src/arduino.cc/builder/hardware/platform.txt index ca718cc1..d3c0d977 100644 --- a/src/arduino.cc/builder/hardware/platform.txt +++ b/src/arduino.cc/builder/hardware/platform.txt @@ -11,6 +11,10 @@ preproc.includes.flags=-w -x c++ -M -MG -MP -include Arduino.h preproc.includes.compatibility_flags={build.mbed_api_include} {build.nRF51822_api_include} {build.ble_api_include} {compiler.libsam.c.flags} {compiler.arm.cmsis.path} {build.variant_system_include} recipe.preproc.includes="{compiler.path}{compiler.cpp.cmd}" {preproc.includes.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {preproc.includes.compatibility_flags} {includes} "{source_file}" -preproc.macros.flags=-w -x c++ -E -CC -include Arduino.h +preproc.macros.flags=-w -x c++ -E -CC -dM -include Arduino.h preproc.macros.compatibility_flags={build.mbed_api_include} {build.nRF51822_api_include} {build.ble_api_include} {compiler.libsam.c.flags} {compiler.arm.cmsis.path} {build.variant_system_include} recipe.preproc.macros="{compiler.path}{compiler.cpp.cmd}" {compiler.cpreprocessor.flags} {compiler.cpp.flags} {preproc.macros.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {preproc.macros.compatibility_flags} {includes} "{source_file}" + +preproc.final.flags=-w -x c++ -E -CC -include Arduino.h +preproc.final.compatibility_flags={build.mbed_api_include} {build.nRF51822_api_include} {build.ble_api_include} {compiler.libsam.c.flags} {compiler.arm.cmsis.path} {build.variant_system_include} +recipe.preproc.final="{compiler.path}{compiler.cpp.cmd}" {compiler.cpreprocessor.flags} {compiler.cpp.flags} {preproc.final.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {preproc.final.compatibility_flags} {includes} "{source_file}" diff --git a/src/arduino.cc/builder/test/builder_test.go b/src/arduino.cc/builder/test/builder_test.go index 2c09c362..81c78ca3 100644 --- a/src/arduino.cc/builder/test/builder_test.go +++ b/src/arduino.cc/builder/test/builder_test.go @@ -89,6 +89,7 @@ func TestBuilderBridge(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" + context[constants.CTX_VERBOSE] = true command := builder.Builder{} err := command.Run(context) diff --git a/src/arduino.cc/builder/test/downloaded_stuff_patches/avr_platform_patch.patch b/src/arduino.cc/builder/test/downloaded_stuff_patches/avr_platform_patch.patch index 57e3f495..9c04c2f4 100644 --- a/src/arduino.cc/builder/test/downloaded_stuff_patches/avr_platform_patch.patch +++ b/src/arduino.cc/builder/test/downloaded_stuff_patches/avr_platform_patch.patch @@ -1,17 +1,12 @@ -diff --git a/downloaded_hardware/arduino/avr/platform.txt b/downloaded_hardware/arduino/avr/platform.txt -index 537fcc5..4e526d9 100644 ---- a/downloaded_hardware/arduino/avr/platform.txt -+++ b/downloaded_hardware/arduino/avr/platform.txt -@@ -81,6 +81,12 @@ recipe.size.regex=^(?:\.text|\.data|\.bootloader)\s+([0-9]+).* - recipe.size.regex.data=^(?:\.data|\.bss|\.noinit)\s+([0-9]+).* - recipe.size.regex.eeprom=^(?:\.eeprom)\s+([0-9]+).* +--- a/downloaded_hardware/arduino/avr/platform.txt.orig 2015-11-11 17:20:47.731372477 +0100 ++++ b/downloaded_hardware/arduino/avr/platform.txt 2015-11-11 17:21:21.463373279 +0100 +@@ -88,6 +88,9 @@ + preproc.macros.flags=-w -x c++ -E -CC + recipe.preproc.macros="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.macros.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -+## Preprocessor -+preproc.includes.flags=-w -x c++ -M -MG -MP -+recipe.preproc.includes="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.includes.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" ++preproc.final.flags=-w -x c++ -E -CC ++recipe.preproc.final="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.final.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" + -+preproc.macros.flags=-w -x c++ -E -CC -+recipe.preproc.macros="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.macros.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" - # AVR Uploader/Programmers tools # ------------------------------ + diff --git a/src/arduino.cc/builder/test/hardware/platform.txt b/src/arduino.cc/builder/test/hardware/platform.txt index a76dcd3e..25054c03 100644 --- a/src/arduino.cc/builder/test/hardware/platform.txt +++ b/src/arduino.cc/builder/test/hardware/platform.txt @@ -1,9 +1,3 @@ -# ctags -# ------------------------------ -tools.ctags.path={runtime.tools.ctags.path} -tools.ctags.cmd.path={path}/ctags -tools.ctags.pattern="{cmd.path}" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "{source_file}" - # coan # ------------------------------ tools.coan.path={runtime.tools.coan.path} diff --git a/src/arduino.cc/builder/test/hardware_loader_test.go b/src/arduino.cc/builder/test/hardware_loader_test.go index 2f540479..9c89a26a 100644 --- a/src/arduino.cc/builder/test/hardware_loader_test.go +++ b/src/arduino.cc/builder/test/hardware_loader_test.go @@ -81,7 +81,8 @@ func TestLoadHardware(t *testing.T) { require.Equal(t, "{runtime.tools.ctags.path}", packages.Properties["tools.ctags.path"]) require.Equal(t, "\"{cmd.path}\" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives \"{source_file}\"", packages.Properties["tools.ctags.pattern"]) require.Equal(t, "{runtime.tools.avrdude.path}", packages.Properties["tools.avrdude.path"]) - require.Equal(t, "-w -x c++ -E -CC -include Arduino.h", packages.Properties["preproc.macros.flags"]) + require.Equal(t, "-w -x c++ -E -CC -include Arduino.h", packages.Properties["preproc.final.flags"]) + require.Equal(t, "-w -x c++ -E -CC -dM -include Arduino.h", packages.Properties["preproc.macros.flags"]) } func TestLoadHardwareMixingUserHardwareFolder(t *testing.T) { @@ -130,8 +131,8 @@ func TestLoadHardwareMixingUserHardwareFolder(t *testing.T) { require.Equal(t, "AVRISP mkII", avrPlatform.Programmers["avrispmkii"][constants.PROGRAMMER_NAME]) - require.Equal(t, "-w -x c++ -M -MG -MP -include Arduino.h", avrPlatform.Properties["preproc.includes.flags"]) - require.Equal(t, "-w -x c++ -E -CC -include Arduino.h", avrPlatform.Properties["preproc.macros.flags"]) + require.Equal(t, "-w -x c++ -M -MG -MP", avrPlatform.Properties["preproc.includes.flags"]) + require.Equal(t, "-w -x c++ -E -CC -dM -include Arduino.h", avrPlatform.Properties["preproc.macros.flags"]) require.Equal(t, "\"{compiler.path}{compiler.cpp.cmd}\" {compiler.cpp.flags} {preproc.includes.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} \"{source_file}\"", avrPlatform.Properties[constants.RECIPE_PREPROC_INCLUDES]) require.False(t, utils.MapStringStringHas(avrPlatform.Properties, "preproc.macros.compatibility_flags")) @@ -146,7 +147,7 @@ func TestLoadHardwareMixingUserHardwareFolder(t *testing.T) { require.Equal(t, "{runtime.tools.ctags.path}", packages.Properties["tools.ctags.path"]) require.Equal(t, "\"{cmd.path}\" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives \"{source_file}\"", packages.Properties["tools.ctags.pattern"]) require.Equal(t, "{runtime.tools.avrdude.path}", packages.Properties["tools.avrdude.path"]) - require.Equal(t, "-w -x c++ -E -CC -include Arduino.h", packages.Properties["preproc.macros.flags"]) + require.Equal(t, "-w -x c++ -E -CC -dM -include Arduino.h", packages.Properties["preproc.macros.flags"]) require.Equal(t, "{build.mbed_api_include} {build.nRF51822_api_include} {build.ble_api_include} {compiler.libsam.c.flags} {compiler.arm.cmsis.path} {build.variant_system_include}", packages.Properties["preproc.macros.compatibility_flags"]) if runtime.GOOS != "windows" { diff --git a/src/arduino.cc/builder/test/platform_keys_rewrite_loader_test.go b/src/arduino.cc/builder/test/platform_keys_rewrite_loader_test.go index be1a938e..694d33af 100644 --- a/src/arduino.cc/builder/test/platform_keys_rewrite_loader_test.go +++ b/src/arduino.cc/builder/test/platform_keys_rewrite_loader_test.go @@ -54,7 +54,7 @@ func TestLoadPlatformKeysRewrite(t *testing.T) { platformKeysRewrite := context[constants.CTX_PLATFORM_KEYS_REWRITE].(types.PlatforKeysRewrite) - require.Equal(t, 14, len(platformKeysRewrite.Rewrites)) + require.Equal(t, 13, len(platformKeysRewrite.Rewrites)) require.Equal(t, constants.BUILD_PROPERTIES_COMPILER_PATH, platformKeysRewrite.Rewrites[0].Key) require.Equal(t, "{runtime.ide.path}/hardware/tools/avr/bin/", platformKeysRewrite.Rewrites[0].OldValue) require.Equal(t, "{runtime.tools.avr-gcc.path}/bin/", platformKeysRewrite.Rewrites[0].NewValue) From d7a7b18e670af542c47132feffa54fd821f6b57f Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Wed, 11 Nov 2015 17:43:20 +0100 Subject: [PATCH 29/85] AVR patch is not properly formatted. Fixed Signed-off-by: Federico Fissore --- .../test/downloaded_stuff_patches/avr_platform_patch.patch | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/arduino.cc/builder/test/downloaded_stuff_patches/avr_platform_patch.patch b/src/arduino.cc/builder/test/downloaded_stuff_patches/avr_platform_patch.patch index 9c04c2f4..e7503863 100644 --- a/src/arduino.cc/builder/test/downloaded_stuff_patches/avr_platform_patch.patch +++ b/src/arduino.cc/builder/test/downloaded_stuff_patches/avr_platform_patch.patch @@ -1,5 +1,7 @@ ---- a/downloaded_hardware/arduino/avr/platform.txt.orig 2015-11-11 17:20:47.731372477 +0100 -+++ b/downloaded_hardware/arduino/avr/platform.txt 2015-11-11 17:21:21.463373279 +0100 +diff --git a/downloaded_hardware/arduino/avr/platform.txt b/downloaded_hardware/arduino/avr/platform.txt +index 537fcc5..4e526d9 100644 +--- a/downloaded_hardware/arduino/avr/platform.txt ++++ b/downloaded_hardware/arduino/avr/platform.txt @@ -88,6 +88,9 @@ preproc.macros.flags=-w -x c++ -E -CC recipe.preproc.macros="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.macros.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" From 3e0793be09ca97c58048877caa1609607bdcddc7 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Thu, 12 Nov 2015 08:55:19 +0100 Subject: [PATCH 30/85] Removing some duplication by introducing - utils.EnsureFolderExists - utils.WriteFileBytes - utils.WriteFile - utils.TouchFile Signed-off-by: Federico Fissore --- main.go | 2 +- .../builder/additional_sketch_files_copier.go | 10 ++++++---- src/arduino.cc/builder/builder_utils/utils.go | 2 +- src/arduino.cc/builder/coan_runner.go | 6 ++---- .../builder/ctags_target_file_saver.go | 6 ++---- .../builder/ensure_buildpath_exists.go | 3 +-- .../builder/gcc_preproc_source_saver.go | 6 ++---- .../builder/merge_sketch_with_bootloader.go | 3 +-- src/arduino.cc/builder/phases/core_builder.go | 3 +-- .../builder/phases/libraries_builder.go | 4 ++-- .../builder/phases/sketch_builder.go | 3 +-- src/arduino.cc/builder/sketch_saver.go | 6 ++---- .../builder/store_build_options_map.go | 5 ++--- .../builder/test/builder_utils_test.go | 7 ++++--- .../builder/test/helper_tools_downloader.go | 20 +++++++++---------- .../load_previous_build_options_map_test.go | 3 +-- .../test/merge_sketch_with_bootloader_test.go | 9 +++++---- ...uild_path_if_build_options_changed_test.go | 8 ++++---- src/arduino.cc/builder/utils/utils.go | 16 +++++++++++++++ 19 files changed, 64 insertions(+), 58 deletions(-) diff --git a/main.go b/main.go index 7a64da9a..e43e8389 100644 --- a/main.go +++ b/main.go @@ -245,7 +245,7 @@ func main() { return } - err = os.MkdirAll(buildPath, os.FileMode(0755)) + err = utils.EnsureFolderExists(buildPath) if err != nil { printCompleteError(err) defer os.Exit(1) diff --git a/src/arduino.cc/builder/additional_sketch_files_copier.go b/src/arduino.cc/builder/additional_sketch_files_copier.go index 90d4189a..5610dd25 100644 --- a/src/arduino.cc/builder/additional_sketch_files_copier.go +++ b/src/arduino.cc/builder/additional_sketch_files_copier.go @@ -34,7 +34,6 @@ import ( "arduino.cc/builder/types" "arduino.cc/builder/utils" "io/ioutil" - "os" "path/filepath" ) @@ -44,7 +43,7 @@ func (s *AdditionalSketchFilesCopier) Run(context map[string]interface{}) error sketch := context[constants.CTX_SKETCH].(*types.Sketch) sketchBuildPath := context[constants.CTX_SKETCH_BUILD_PATH].(string) - err := os.MkdirAll(sketchBuildPath, os.FileMode(0755)) + err := utils.EnsureFolderExists(sketchBuildPath) if err != nil { return utils.WrapError(err) } @@ -58,14 +57,17 @@ func (s *AdditionalSketchFilesCopier) Run(context map[string]interface{}) error } targetFilePath := filepath.Join(sketchBuildPath, relativePath) - os.MkdirAll(filepath.Dir(targetFilePath), os.FileMode(0755)) + err = utils.EnsureFolderExists(filepath.Dir(targetFilePath)) + if err != nil { + return utils.WrapError(err) + } bytes, err := ioutil.ReadFile(file.Name) if err != nil { return utils.WrapError(err) } - ioutil.WriteFile(targetFilePath, bytes, os.FileMode(0644)) + utils.WriteFileBytes(targetFilePath, bytes) } return nil diff --git a/src/arduino.cc/builder/builder_utils/utils.go b/src/arduino.cc/builder/builder_utils/utils.go index 26accab6..aaf1c240 100644 --- a/src/arduino.cc/builder/builder_utils/utils.go +++ b/src/arduino.cc/builder/builder_utils/utils.go @@ -138,7 +138,7 @@ func compileFileWithRecipe(sourcePath string, source string, buildPath string, b } properties[constants.BUILD_PROPERTIES_OBJECT_FILE] = filepath.Join(buildPath, relativeSource+".o") - err = os.MkdirAll(filepath.Dir(properties[constants.BUILD_PROPERTIES_OBJECT_FILE]), os.FileMode(0755)) + err = utils.EnsureFolderExists(filepath.Dir(properties[constants.BUILD_PROPERTIES_OBJECT_FILE])) if err != nil { return "", utils.WrapError(err) } diff --git a/src/arduino.cc/builder/coan_runner.go b/src/arduino.cc/builder/coan_runner.go index 2e3b3ad6..f4630621 100644 --- a/src/arduino.cc/builder/coan_runner.go +++ b/src/arduino.cc/builder/coan_runner.go @@ -35,8 +35,6 @@ import ( "arduino.cc/builder/props" "arduino.cc/builder/utils" "fmt" - "io/ioutil" - "os" "path/filepath" "regexp" ) @@ -51,13 +49,13 @@ func (s *CoanRunner) Run(context map[string]interface{}) error { verbose := context[constants.CTX_VERBOSE].(bool) preprocPath := context[constants.CTX_PREPROC_PATH].(string) - err := os.MkdirAll(preprocPath, os.FileMode(0755)) + err := utils.EnsureFolderExists(preprocPath) if err != nil { return utils.WrapError(err) } coanTargetFileName := filepath.Join(preprocPath, constants.FILE_COAN_TARGET) - err = ioutil.WriteFile(coanTargetFileName, []byte(source), os.FileMode(0644)) + err = utils.WriteFile(coanTargetFileName, source) if err != nil { return utils.WrapError(err) } diff --git a/src/arduino.cc/builder/ctags_target_file_saver.go b/src/arduino.cc/builder/ctags_target_file_saver.go index e97dbd95..249cd2b6 100644 --- a/src/arduino.cc/builder/ctags_target_file_saver.go +++ b/src/arduino.cc/builder/ctags_target_file_saver.go @@ -32,8 +32,6 @@ package builder import ( "arduino.cc/builder/constants" "arduino.cc/builder/utils" - "io/ioutil" - "os" "path/filepath" ) @@ -46,13 +44,13 @@ func (s *CTagsTargetFileSaver) Run(context map[string]interface{}) error { source := context[s.SourceField].(string) preprocPath := context[constants.CTX_PREPROC_PATH].(string) - err := os.MkdirAll(preprocPath, os.FileMode(0755)) + err := utils.EnsureFolderExists(preprocPath) if err != nil { return utils.WrapError(err) } ctagsTargetFileName := filepath.Join(preprocPath, s.Filename) - err = ioutil.WriteFile(ctagsTargetFileName, []byte(source), os.FileMode(0644)) + err = utils.WriteFile(ctagsTargetFileName, source) if err != nil { return utils.WrapError(err) } diff --git a/src/arduino.cc/builder/ensure_buildpath_exists.go b/src/arduino.cc/builder/ensure_buildpath_exists.go index 7f343c8b..d3fc6dc5 100644 --- a/src/arduino.cc/builder/ensure_buildpath_exists.go +++ b/src/arduino.cc/builder/ensure_buildpath_exists.go @@ -32,7 +32,6 @@ package builder import ( "arduino.cc/builder/constants" "arduino.cc/builder/utils" - "os" ) type EnsureBuildPathExists struct{} @@ -40,7 +39,7 @@ type EnsureBuildPathExists struct{} func (s *EnsureBuildPathExists) Run(context map[string]interface{}) error { buildPath := context[constants.CTX_BUILD_PATH].(string) - err := os.MkdirAll(buildPath, os.FileMode(0755)) + err := utils.EnsureFolderExists(buildPath) if err != nil { return utils.WrapError(err) } diff --git a/src/arduino.cc/builder/gcc_preproc_source_saver.go b/src/arduino.cc/builder/gcc_preproc_source_saver.go index bdb1ac75..43d8e494 100644 --- a/src/arduino.cc/builder/gcc_preproc_source_saver.go +++ b/src/arduino.cc/builder/gcc_preproc_source_saver.go @@ -32,8 +32,6 @@ package builder import ( "arduino.cc/builder/constants" "arduino.cc/builder/utils" - "io/ioutil" - "os" "path/filepath" ) @@ -41,13 +39,13 @@ type GCCPreprocSourceSaver struct{} func (s *GCCPreprocSourceSaver) Run(context map[string]interface{}) error { preprocPath := context[constants.CTX_PREPROC_PATH].(string) - err := os.MkdirAll(preprocPath, os.FileMode(0755)) + err := utils.EnsureFolderExists(preprocPath) if err != nil { return utils.WrapError(err) } source := context[constants.CTX_SOURCE].(string) - err = ioutil.WriteFile(filepath.Join(preprocPath, constants.FILE_GCC_PREPROC_TARGET), []byte(source), os.FileMode(0644)) + err = utils.WriteFile(filepath.Join(preprocPath, constants.FILE_GCC_PREPROC_TARGET), source) return utils.WrapError(err) } diff --git a/src/arduino.cc/builder/merge_sketch_with_bootloader.go b/src/arduino.cc/builder/merge_sketch_with_bootloader.go index 69fbfbc8..364ed040 100644 --- a/src/arduino.cc/builder/merge_sketch_with_bootloader.go +++ b/src/arduino.cc/builder/merge_sketch_with_bootloader.go @@ -34,7 +34,6 @@ import ( "arduino.cc/builder/i18n" "arduino.cc/builder/types" "arduino.cc/builder/utils" - "io/ioutil" "os" "path/filepath" "strings" @@ -101,5 +100,5 @@ func merge(builtSketchPath, bootloaderPath, mergedSketchPath string) error { sketch = append(sketch, row) } - return ioutil.WriteFile(mergedSketchPath, []byte(strings.Join(sketch, "\n")), os.FileMode(0644)) + return utils.WriteFile(mergedSketchPath, strings.Join(sketch, "\n")) } diff --git a/src/arduino.cc/builder/phases/core_builder.go b/src/arduino.cc/builder/phases/core_builder.go index 67a44f4d..79bf882e 100644 --- a/src/arduino.cc/builder/phases/core_builder.go +++ b/src/arduino.cc/builder/phases/core_builder.go @@ -34,7 +34,6 @@ import ( "arduino.cc/builder/constants" "arduino.cc/builder/i18n" "arduino.cc/builder/utils" - "os" ) type CoreBuilder struct{} @@ -46,7 +45,7 @@ func (s *CoreBuilder) Run(context map[string]interface{}) error { warningsLevel := context[constants.CTX_WARNINGS_LEVEL].(string) logger := context[constants.CTX_LOGGER].(i18n.Logger) - err := os.MkdirAll(coreBuildPath, os.FileMode(0755)) + err := utils.EnsureFolderExists(coreBuildPath) if err != nil { return utils.WrapError(err) } diff --git a/src/arduino.cc/builder/phases/libraries_builder.go b/src/arduino.cc/builder/phases/libraries_builder.go index fd8753de..bb01f8e8 100644 --- a/src/arduino.cc/builder/phases/libraries_builder.go +++ b/src/arduino.cc/builder/phases/libraries_builder.go @@ -51,7 +51,7 @@ func (s *LibrariesBuilder) Run(context map[string]interface{}) error { warningsLevel := context[constants.CTX_WARNINGS_LEVEL].(string) logger := context[constants.CTX_LOGGER].(i18n.Logger) - err := os.MkdirAll(librariesBuildPath, os.FileMode(0755)) + err := utils.EnsureFolderExists(librariesBuildPath) if err != nil { return utils.WrapError(err) } @@ -83,7 +83,7 @@ func compileLibraries(libraries []*types.Library, buildPath string, buildPropert func compileLibrary(library *types.Library, buildPath string, buildProperties map[string]string, includes []string, verbose bool, warningsLevel string, logger i18n.Logger) ([]string, error) { libraryBuildPath := filepath.Join(buildPath, library.Name) - err := os.MkdirAll(libraryBuildPath, os.FileMode(0755)) + err := utils.EnsureFolderExists(libraryBuildPath) if err != nil { return nil, utils.WrapError(err) } diff --git a/src/arduino.cc/builder/phases/sketch_builder.go b/src/arduino.cc/builder/phases/sketch_builder.go index 8ceb81c6..27d26d59 100644 --- a/src/arduino.cc/builder/phases/sketch_builder.go +++ b/src/arduino.cc/builder/phases/sketch_builder.go @@ -34,7 +34,6 @@ import ( "arduino.cc/builder/constants" "arduino.cc/builder/i18n" "arduino.cc/builder/utils" - "os" ) type SketchBuilder struct{} @@ -48,7 +47,7 @@ func (s *SketchBuilder) Run(context map[string]interface{}) error { warningsLevel := context[constants.CTX_WARNINGS_LEVEL].(string) logger := context[constants.CTX_LOGGER].(i18n.Logger) - err := os.MkdirAll(sketchBuildPath, os.FileMode(0755)) + err := utils.EnsureFolderExists(sketchBuildPath) if err != nil { return utils.WrapError(err) } diff --git a/src/arduino.cc/builder/sketch_saver.go b/src/arduino.cc/builder/sketch_saver.go index 01f10ae4..1a6bfb57 100644 --- a/src/arduino.cc/builder/sketch_saver.go +++ b/src/arduino.cc/builder/sketch_saver.go @@ -33,8 +33,6 @@ import ( "arduino.cc/builder/constants" "arduino.cc/builder/types" "arduino.cc/builder/utils" - "io/ioutil" - "os" "path/filepath" ) @@ -45,11 +43,11 @@ func (s *SketchSaver) Run(context map[string]interface{}) error { sketchBuildPath := context[constants.CTX_SKETCH_BUILD_PATH].(string) source := context[constants.CTX_SOURCE].(string) - err := os.MkdirAll(sketchBuildPath, os.FileMode(0755)) + err := utils.EnsureFolderExists(sketchBuildPath) if err != nil { return utils.WrapError(err) } - err = ioutil.WriteFile(filepath.Join(sketchBuildPath, filepath.Base(sketch.MainFile.Name)+".cpp"), []byte(source), os.FileMode(0644)) + err = utils.WriteFile(filepath.Join(sketchBuildPath, filepath.Base(sketch.MainFile.Name)+".cpp"), source) return utils.WrapError(err) } diff --git a/src/arduino.cc/builder/store_build_options_map.go b/src/arduino.cc/builder/store_build_options_map.go index a0d221ec..4e2172a4 100644 --- a/src/arduino.cc/builder/store_build_options_map.go +++ b/src/arduino.cc/builder/store_build_options_map.go @@ -31,8 +31,7 @@ package builder import ( "arduino.cc/builder/constants" - "io/ioutil" - "os" + "arduino.cc/builder/utils" "path/filepath" ) @@ -42,7 +41,7 @@ func (s *StoreBuildOptionsMap) Run(context map[string]interface{}) error { buildPath := context[constants.CTX_BUILD_PATH].(string) buildOptionsJson := context[constants.CTX_BUILD_OPTIONS_JSON].(string) - ioutil.WriteFile(filepath.Join(buildPath, constants.BUILD_OPTIONS_FILE), []byte(buildOptionsJson), os.FileMode(0644)) + utils.WriteFile(filepath.Join(buildPath, constants.BUILD_OPTIONS_FILE), buildOptionsJson) return nil } diff --git a/src/arduino.cc/builder/test/builder_utils_test.go b/src/arduino.cc/builder/test/builder_utils_test.go index 1fe1aa14..dcb85509 100644 --- a/src/arduino.cc/builder/test/builder_utils_test.go +++ b/src/arduino.cc/builder/test/builder_utils_test.go @@ -31,6 +31,7 @@ package test import ( "arduino.cc/builder/builder_utils" + "arduino.cc/builder/utils" "github.com/stretchr/testify/require" "io/ioutil" "os" @@ -119,7 +120,7 @@ func TestObjFileIsUpToDateDepIsNewer(t *testing.T) { headerFile := tempFile(t, "header") defer os.RemoveAll(headerFile) - ioutil.WriteFile(depFile, []byte(objFile+": \\\n\t"+sourceFile+" \\\n\t"+headerFile), os.FileMode(0644)) + utils.WriteFile(depFile, objFile+": \\\n\t"+sourceFile+" \\\n\t"+headerFile) upToDate, err := builder_utils.ObjFileIsUpToDate(sourceFile, objFile, depFile) NoError(t, err) @@ -140,7 +141,7 @@ func TestObjFileIsUpToDateDepIsOlder(t *testing.T) { depFile := tempFile(t, "dep") defer os.RemoveAll(depFile) - ioutil.WriteFile(depFile, []byte(objFile+": \\\n\t"+sourceFile+" \\\n\t"+headerFile), os.FileMode(0644)) + utils.WriteFile(depFile, objFile+": \\\n\t"+sourceFile+" \\\n\t"+headerFile) upToDate, err := builder_utils.ObjFileIsUpToDate(sourceFile, objFile, depFile) NoError(t, err) @@ -163,7 +164,7 @@ func TestObjFileIsUpToDateDepIsWrong(t *testing.T) { headerFile := tempFile(t, "header") defer os.RemoveAll(headerFile) - ioutil.WriteFile(depFile, []byte(sourceFile+": \\\n\t"+sourceFile+" \\\n\t"+headerFile), os.FileMode(0644)) + utils.WriteFile(depFile, sourceFile+": \\\n\t"+sourceFile+" \\\n\t"+headerFile) upToDate, err := builder_utils.ObjFileIsUpToDate(sourceFile, objFile, depFile) NoError(t, err) diff --git a/src/arduino.cc/builder/test/helper_tools_downloader.go b/src/arduino.cc/builder/test/helper_tools_downloader.go index f4618e8b..ccc11d7a 100644 --- a/src/arduino.cc/builder/test/helper_tools_downloader.go +++ b/src/arduino.cc/builder/test/helper_tools_downloader.go @@ -155,7 +155,7 @@ func patchFiles(t *testing.T) { NoError(t, err) operations, err := patchSet.Apply(ioutil.ReadFile) for _, op := range operations { - ioutil.WriteFile(op.Dst, op.Data, os.FileMode(0644)) + utils.WriteFileBytes(op.Dst, op.Data) } } } @@ -468,7 +468,7 @@ func downloadAndUnpackCore(core Core, url string, targetPath string) error { } if len(files) == 1 && files[0].IsDir() { - err = os.MkdirAll(filepath.Join(targetPath, core.Maintainer), os.FileMode(0755)) + err = utils.EnsureFolderExists(filepath.Join(targetPath, core.Maintainer)) if err != nil { return utils.WrapError(err) } @@ -477,7 +477,7 @@ func downloadAndUnpackCore(core Core, url string, targetPath string) error { return utils.WrapError(err) } } else { - err = os.MkdirAll(filepath.Join(targetPath, core.Maintainer, core.Arch), os.FileMode(0755)) + err = utils.EnsureFolderExists(filepath.Join(targetPath, core.Maintainer, core.Arch)) if err != nil { return utils.WrapError(err) } @@ -517,7 +517,7 @@ func downloadAndUnpackBoardManagerCore(core Core, url string, targetPath string) } if len(files) == 1 && files[0].IsDir() { - err = os.MkdirAll(filepath.Join(targetPath, core.Maintainer, "hardware", core.Arch), os.FileMode(0755)) + err = utils.EnsureFolderExists(filepath.Join(targetPath, core.Maintainer, "hardware", core.Arch)) if err != nil { return utils.WrapError(err) } @@ -526,7 +526,7 @@ func downloadAndUnpackBoardManagerCore(core Core, url string, targetPath string) return utils.WrapError(err) } } else { - err = os.MkdirAll(filepath.Join(targetPath, core.Maintainer, "hardware", core.Arch, core.Version), os.FileMode(0755)) + err = utils.EnsureFolderExists(filepath.Join(targetPath, core.Maintainer, "hardware", core.Arch, core.Version)) if err != nil { return utils.WrapError(err) } @@ -558,7 +558,7 @@ func downloadAndUnpackBoardsManagerTool(tool Tool, url string, targetPath string defer os.RemoveAll(unpackFolder) if len(files) == 1 && files[0].IsDir() { - err = os.MkdirAll(filepath.Join(targetPath, tool.Package, constants.FOLDER_TOOLS, tool.Name), os.FileMode(0755)) + err = utils.EnsureFolderExists(filepath.Join(targetPath, tool.Package, constants.FOLDER_TOOLS, tool.Name)) if err != nil { return utils.WrapError(err) } @@ -567,7 +567,7 @@ func downloadAndUnpackBoardsManagerTool(tool Tool, url string, targetPath string return utils.WrapError(err) } } else { - err = os.MkdirAll(filepath.Join(targetPath, tool.Package, constants.FOLDER_TOOLS, tool.Name, tool.Version), os.FileMode(0755)) + err = utils.EnsureFolderExists(filepath.Join(targetPath, tool.Package, constants.FOLDER_TOOLS, tool.Name, tool.Version)) if err != nil { return utils.WrapError(err) } @@ -609,7 +609,7 @@ func downloadAndUnpackTool(tool Tool, url string, targetPath string, deleteIfMis } if len(files) == 1 && files[0].IsDir() { - err = os.MkdirAll(filepath.Join(targetPath, tool.Name), os.FileMode(0755)) + err = utils.EnsureFolderExists(filepath.Join(targetPath, tool.Name)) if err != nil { return utils.WrapError(err) } @@ -618,7 +618,7 @@ func downloadAndUnpackTool(tool Tool, url string, targetPath string, deleteIfMis return utils.WrapError(err) } } else { - err = os.MkdirAll(filepath.Join(targetPath, tool.Name, tool.Version), os.FileMode(0755)) + err = utils.EnsureFolderExists(filepath.Join(targetPath, tool.Name, tool.Version)) if err != nil { return utils.WrapError(err) } @@ -656,7 +656,7 @@ func downloadAndUnpack(url string) (string, []os.FileInfo, error) { } res.Body.Close() - ioutil.WriteFile(archiveFilePath, bytes, os.FileMode(0644)) + utils.WriteFileBytes(archiveFilePath, bytes) cmd := buildUnpackCmd(archiveFilePath) out, err := cmd.CombinedOutput() diff --git a/src/arduino.cc/builder/test/load_previous_build_options_map_test.go b/src/arduino.cc/builder/test/load_previous_build_options_map_test.go index bc94252b..295e6e3c 100644 --- a/src/arduino.cc/builder/test/load_previous_build_options_map_test.go +++ b/src/arduino.cc/builder/test/load_previous_build_options_map_test.go @@ -34,7 +34,6 @@ import ( "arduino.cc/builder/constants" "arduino.cc/builder/utils" "github.com/stretchr/testify/require" - "io/ioutil" "os" "path/filepath" "testing" @@ -46,7 +45,7 @@ func TestLoadPreviousBuildOptionsMap(t *testing.T) { buildPath := SetupBuildPath(t, context) defer os.RemoveAll(buildPath) - err := ioutil.WriteFile(filepath.Join(buildPath, constants.BUILD_OPTIONS_FILE), []byte("test"), os.FileMode(0644)) + err := utils.WriteFile(filepath.Join(buildPath, constants.BUILD_OPTIONS_FILE), "test") NoError(t, err) command := builder.LoadPreviousBuildOptionsMap{} diff --git a/src/arduino.cc/builder/test/merge_sketch_with_bootloader_test.go b/src/arduino.cc/builder/test/merge_sketch_with_bootloader_test.go index 9a3cca27..ea7e3442 100644 --- a/src/arduino.cc/builder/test/merge_sketch_with_bootloader_test.go +++ b/src/arduino.cc/builder/test/merge_sketch_with_bootloader_test.go @@ -33,6 +33,7 @@ import ( "arduino.cc/builder" "arduino.cc/builder/constants" "arduino.cc/builder/types" + "arduino.cc/builder/utils" "github.com/stretchr/testify/require" "io/ioutil" "os" @@ -57,12 +58,12 @@ func TestMergeSketchWithBootloader(t *testing.T) { context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch1", "sketch.ino") context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" - err := os.MkdirAll(filepath.Join(buildPath, "sketch"), os.FileMode(0755)) + err := utils.EnsureFolderExists(filepath.Join(buildPath, "sketch")) NoError(t, err) fakeSketchHex := "row 1\n" + "row 2\n" - err = ioutil.WriteFile(filepath.Join(buildPath, "sketch", "sketch.ino.hex"), []byte(fakeSketchHex), os.FileMode(0644)) + err = utils.WriteFile(filepath.Join(buildPath, "sketch", "sketch.ino.hex"), fakeSketchHex) NoError(t, err) commands := []types.Command{ @@ -100,12 +101,12 @@ func TestMergeSketchWithBootloaderSketchInBuildPath(t *testing.T) { context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch1", "sketch.ino") context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" - err := os.MkdirAll(filepath.Join(buildPath, "sketch"), os.FileMode(0755)) + err := utils.EnsureFolderExists(filepath.Join(buildPath, "sketch")) NoError(t, err) fakeSketchHex := "row 1\n" + "row 2\n" - err = ioutil.WriteFile(filepath.Join(buildPath, "sketch.ino.hex"), []byte(fakeSketchHex), os.FileMode(0644)) + err = utils.WriteFile(filepath.Join(buildPath, "sketch.ino.hex"), fakeSketchHex) NoError(t, err) commands := []types.Command{ diff --git a/src/arduino.cc/builder/test/wipeout_build_path_if_build_options_changed_test.go b/src/arduino.cc/builder/test/wipeout_build_path_if_build_options_changed_test.go index 7ef728ec..d72b05b2 100644 --- a/src/arduino.cc/builder/test/wipeout_build_path_if_build_options_changed_test.go +++ b/src/arduino.cc/builder/test/wipeout_build_path_if_build_options_changed_test.go @@ -34,8 +34,8 @@ import ( "arduino.cc/builder/constants" "arduino.cc/builder/gohasissues" "arduino.cc/builder/types" + "arduino.cc/builder/utils" "github.com/stretchr/testify/require" - "io/ioutil" "os" "path/filepath" "testing" @@ -50,7 +50,7 @@ func TestWipeoutBuildPathIfBuildOptionsChanged(t *testing.T) { context[constants.CTX_BUILD_OPTIONS_PREVIOUS_JSON] = "old" context[constants.CTX_BUILD_OPTIONS_JSON] = "new" - ioutil.WriteFile(filepath.Join(buildPath, "should_be_deleted.txt"), []byte{}, os.FileMode(0644)) + utils.TouchFile(filepath.Join(buildPath, "should_be_deleted.txt")) commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -81,7 +81,7 @@ func TestWipeoutBuildPathIfBuildOptionsChangedNoPreviousBuildOptions(t *testing. context[constants.CTX_BUILD_OPTIONS_JSON] = "new" - ioutil.WriteFile(filepath.Join(buildPath, "should_not_be_deleted.txt"), []byte{}, os.FileMode(0644)) + utils.TouchFile(filepath.Join(buildPath, "should_not_be_deleted.txt")) commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -113,7 +113,7 @@ func TestWipeoutBuildPathIfBuildOptionsChangedBuildOptionsMatch(t *testing.T) { context[constants.CTX_BUILD_OPTIONS_PREVIOUS_JSON] = "options" context[constants.CTX_BUILD_OPTIONS_JSON] = "options" - ioutil.WriteFile(filepath.Join(buildPath, "should_not_be_deleted.txt"), []byte{}, os.FileMode(0644)) + utils.TouchFile(filepath.Join(buildPath, "should_not_be_deleted.txt")) commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, diff --git a/src/arduino.cc/builder/utils/utils.go b/src/arduino.cc/builder/utils/utils.go index 83719b7b..2574a61e 100644 --- a/src/arduino.cc/builder/utils/utils.go +++ b/src/arduino.cc/builder/utils/utils.go @@ -435,3 +435,19 @@ func AddStringsToStringsSet(accumulator []string, stringsToAdd []string) []strin return KeysOfMapOfStringBool(newStringsSet) } + +func EnsureFolderExists(folder string) error { + return os.MkdirAll(folder, os.FileMode(0755)) +} + +func WriteFileBytes(targetFilePath string, data []byte) error { + return ioutil.WriteFile(targetFilePath, data, os.FileMode(0644)) +} + +func WriteFile(targetFilePath string, data string) error { + return WriteFileBytes(targetFilePath, []byte(data)) +} + +func TouchFile(targetFilePath string) error { + return WriteFileBytes(targetFilePath, []byte{}) +} From 044817d70ae041b4ff6ca45b54a17487c0962906 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Thu, 12 Nov 2015 11:16:54 +0100 Subject: [PATCH 31/85] gcc -E calls now save output to files. This clutters a bit temp "preproc" folder, but avoids comunication between go and gcc, which is a performance bottleneck Signed-off-by: Federico Fissore --- src/arduino.cc/builder/constants/constants.go | 5 +- .../builder/container_add_prototypes.go | 7 ++- .../builder/container_find_includes.go | 15 +++-- src/arduino.cc/builder/ctags_runner.go | 4 +- .../builder/ctags_target_file_saver.go | 10 ++-- src/arduino.cc/builder/gcc_preproc_runner.go | 39 +++++++++---- .../hardware/platform.keys.rewrite.txt | 4 +- src/arduino.cc/builder/hardware/platform.txt | 10 +--- src/arduino.cc/builder/prototypes_adder.go | 11 ---- .../builder/read_file_and_store_in_context.go | 51 +++++++++++++++++ .../builder/sketch_source_merger.go | 19 +++++-- .../builder/test/ctags_runner_test.go | 8 +-- .../test/downloaded_stuff_patches/.gitkeep | 0 .../avr_platform_patch.patch | 14 ----- .../builder/test/hardware_loader_test.go | 7 +-- .../test/includes_finder_with_regexp_test.go | 7 ++- .../builder/test/prototypes_adder_test.go | 52 ++++++++++++++++-- .../read_file_and_store_in_context_test.go | 55 +++++++++++++++++++ .../builder/test/sketch1/merged_sketch.txt | 2 + .../SketchWithIfDef.resolved.directives.txt | 2 + .../builder/test/sketch_with_ifdef/sketch.ino | 4 +- .../sketch.preprocessed.SAM.txt | 29 ++++++++++ .../sketch_with_ifdef/sketch.preprocessed.txt | 16 +++--- .../test/sketch_with_usbcon/sketch.ino | 4 +- 24 files changed, 280 insertions(+), 95 deletions(-) create mode 100644 src/arduino.cc/builder/read_file_and_store_in_context.go create mode 100644 src/arduino.cc/builder/test/downloaded_stuff_patches/.gitkeep delete mode 100644 src/arduino.cc/builder/test/downloaded_stuff_patches/avr_platform_patch.patch create mode 100644 src/arduino.cc/builder/test/read_file_and_store_in_context_test.go create mode 100644 src/arduino.cc/builder/test/sketch_with_ifdef/sketch.preprocessed.SAM.txt diff --git a/src/arduino.cc/builder/constants/constants.go b/src/arduino.cc/builder/constants/constants.go index 3837c542..98205550 100644 --- a/src/arduino.cc/builder/constants/constants.go +++ b/src/arduino.cc/builder/constants/constants.go @@ -60,6 +60,7 @@ const BUILD_PROPERTIES_OBJECT_FILE = "object_file" const BUILD_PROPERTIES_OBJECT_FILES = "object_files" const BUILD_PROPERTIES_PATTERN = "pattern" const BUILD_PROPERTIES_PID = "pid" +const BUILD_PROPERTIES_PREPROCESSED_FILE_PATH = "preprocessed_file_path" const BUILD_PROPERTIES_RUNTIME_HARDWARE_PATH = "runtime.hardware.path" const BUILD_PROPERTIES_RUNTIME_OS = "runtime.os" const BUILD_PROPERTIES_RUNTIME_PLATFORM_PATH = "runtime.platform.path" @@ -89,9 +90,10 @@ const CTX_CORE_BUILD_PATH = "coreBuildPath" const CTX_CTAGS_OF_PREPROC_SOURCE = "ctagsOfPreprocSource" const CTX_CTAGS_OF_SOURCE = "ctagsOfSource" const CTX_CTAGS_OUTPUT = "ctagsOutput" -const CTX_CTAGS_TEMP_FILE_NAME = "ctagsTempFileName" +const CTX_CTAGS_TEMP_FILE_PATH = "ctagsTempFilePath" const CTX_CUSTOM_BUILD_PROPERTIES = "customBuildProperties" const CTX_DEBUG_LEVEL = "debugLevel" +const CTX_FILE_PATH_TO_READ = "filePathToRead" const CTX_FOLDERS_WITH_SOURCES_QUEUE = "foldersWithSourcesQueue" const CTX_FQBN = "fqbn" const CTX_GCC_MINUS_E_SOURCE = "gccMinusESource" @@ -252,7 +254,6 @@ const RECIPE_AR_PATTERN = "recipe.ar.pattern" const RECIPE_C_COMBINE_PATTERN = "recipe.c.combine.pattern" const RECIPE_C_PATTERN = "recipe.c.o.pattern" const RECIPE_CPP_PATTERN = "recipe.cpp.o.pattern" -const RECIPE_PREPROC_FINAL = "recipe.preproc.final" const RECIPE_PREPROC_INCLUDES = "recipe.preproc.includes" const RECIPE_PREPROC_MACROS = "recipe.preproc.macros" const RECIPE_S_PATTERN = "recipe.S.o.pattern" diff --git a/src/arduino.cc/builder/container_add_prototypes.go b/src/arduino.cc/builder/container_add_prototypes.go index 7f992c36..7a70d703 100644 --- a/src/arduino.cc/builder/container_add_prototypes.go +++ b/src/arduino.cc/builder/container_add_prototypes.go @@ -39,11 +39,12 @@ type ContainerAddPrototypes struct{} func (s *ContainerAddPrototypes) Run(context map[string]interface{}) error { commands := []types.Command{ - &GCCPreprocRunner{}, - &CTagsTargetFileSaver{SourceField: constants.CTX_GCC_MINUS_E_SOURCE, Filename: constants.FILE_CTAGS_TARGET_FOR_GCC_MINUS_E}, + &GCCPreprocRunner{TargetFileName: constants.FILE_CTAGS_TARGET_FOR_GCC_MINUS_E}, + &ReadFileAndStoreInContext{TargetField: constants.CTX_GCC_MINUS_E_SOURCE}, + &CTagsTargetFileSaver{SourceField: constants.CTX_GCC_MINUS_E_SOURCE, TargetFileName: constants.FILE_CTAGS_TARGET_FOR_GCC_MINUS_E}, &CTagsRunner{}, &CTagsParser{CTagsField: constants.CTX_CTAGS_OF_PREPROC_SOURCE}, - &CTagsTargetFileSaver{SourceField: constants.CTX_SOURCE, Filename: constants.FILE_CTAGS_TARGET}, + &CTagsTargetFileSaver{SourceField: constants.CTX_SOURCE, TargetFileName: constants.FILE_CTAGS_TARGET}, &CTagsRunner{}, &CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE}, &ComparePrototypesFromSourceAndPreprocSource{}, diff --git a/src/arduino.cc/builder/container_find_includes.go b/src/arduino.cc/builder/container_find_includes.go index cddca8fe..d015651f 100644 --- a/src/arduino.cc/builder/container_find_includes.go +++ b/src/arduino.cc/builder/container_find_includes.go @@ -33,7 +33,9 @@ import ( "arduino.cc/builder/constants" "arduino.cc/builder/types" "arduino.cc/builder/utils" + "math/rand" "path/filepath" + "strconv" ) type ContainerFindIncludes struct{} @@ -67,10 +69,10 @@ func (s *ContainerFindIncludes) Run(context map[string]interface{}) error { return utils.WrapError(err) } - sourceFiles := context[constants.CTX_COLLECTED_SOURCE_FILES_QUEUE].(*types.UniqueStringQueue) + sourceFilePaths := context[constants.CTX_COLLECTED_SOURCE_FILES_QUEUE].(*types.UniqueStringQueue) - for !sourceFiles.Empty() { - err = findIncludesUntilDone(context, sourceFiles.Pop().(string)) + for !sourceFilePaths.Empty() { + err = findIncludesUntilDone(context, sourceFilePaths.Pop().(string)) if err != nil { return utils.WrapError(err) } @@ -92,12 +94,13 @@ func runCommand(context map[string]interface{}, command types.Command) error { return nil } -func findIncludesUntilDone(context map[string]interface{}, sourceFile string) error { +func findIncludesUntilDone(context map[string]interface{}, sourceFilePath string) error { + targetFileName := filepath.Base(sourceFilePath) + "_" + strconv.Itoa(rand.Int()) + "_preprocessed.cpp" importedLibraries := context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library) done := false for !done { commands := []types.Command{ - &GCCPreprocRunnerForDiscoveringIncludes{SourceFile: sourceFile}, + &GCCPreprocRunnerForDiscoveringIncludes{SourceFilePath: sourceFilePath, TargetFileName: targetFileName}, &IncludesFinderWithRegExp{ContextField: constants.CTX_GCC_MINUS_E_SOURCE}, &IncludesToIncludeFolders{}, } @@ -110,7 +113,7 @@ func findIncludesUntilDone(context map[string]interface{}, sourceFile string) er if len(context[constants.CTX_INCLUDES_JUST_FOUND].([]string)) == 0 { done = true } else if len(context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library)) == len(importedLibraries) { - err := runCommand(context, &GCCPreprocRunner{}) + err := runCommand(context, &GCCPreprocRunner{TargetFileName: constants.FILE_CTAGS_TARGET_FOR_GCC_MINUS_E}) return utils.WrapError(err) } importedLibraries = context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library) diff --git a/src/arduino.cc/builder/ctags_runner.go b/src/arduino.cc/builder/ctags_runner.go index 219ee928..20c9eb7c 100644 --- a/src/arduino.cc/builder/ctags_runner.go +++ b/src/arduino.cc/builder/ctags_runner.go @@ -41,11 +41,11 @@ type CTagsRunner struct{} func (s *CTagsRunner) Run(context map[string]interface{}) error { buildProperties := context[constants.CTX_BUILD_PROPERTIES].(map[string]string) - ctagsTargetFileName := context[constants.CTX_CTAGS_TEMP_FILE_NAME].(string) + ctagsTargetFilePath := context[constants.CTX_CTAGS_TEMP_FILE_PATH].(string) logger := context[constants.CTX_LOGGER].(i18n.Logger) properties := utils.MergeMapsOfStrings(make(map[string]string), buildProperties, props.SubTree(props.SubTree(buildProperties, constants.BUILD_PROPERTIES_TOOLS_KEY), constants.CTAGS)) - properties[constants.BUILD_PROPERTIES_SOURCE_FILE] = ctagsTargetFileName + properties[constants.BUILD_PROPERTIES_SOURCE_FILE] = ctagsTargetFilePath pattern := properties[constants.BUILD_PROPERTIES_PATTERN] if pattern == constants.EMPTY_STRING { diff --git a/src/arduino.cc/builder/ctags_target_file_saver.go b/src/arduino.cc/builder/ctags_target_file_saver.go index 249cd2b6..f6fe259a 100644 --- a/src/arduino.cc/builder/ctags_target_file_saver.go +++ b/src/arduino.cc/builder/ctags_target_file_saver.go @@ -36,8 +36,8 @@ import ( ) type CTagsTargetFileSaver struct { - SourceField string - Filename string + SourceField string + TargetFileName string } func (s *CTagsTargetFileSaver) Run(context map[string]interface{}) error { @@ -49,13 +49,13 @@ func (s *CTagsTargetFileSaver) Run(context map[string]interface{}) error { return utils.WrapError(err) } - ctagsTargetFileName := filepath.Join(preprocPath, s.Filename) - err = utils.WriteFile(ctagsTargetFileName, source) + ctagsTargetFilePath := filepath.Join(preprocPath, s.TargetFileName) + err = utils.WriteFile(ctagsTargetFilePath, source) if err != nil { return utils.WrapError(err) } - context[constants.CTX_CTAGS_TEMP_FILE_NAME] = ctagsTargetFileName + context[constants.CTX_CTAGS_TEMP_FILE_PATH] = ctagsTargetFilePath return nil } diff --git a/src/arduino.cc/builder/gcc_preproc_runner.go b/src/arduino.cc/builder/gcc_preproc_runner.go index d77fcd08..d67e322a 100644 --- a/src/arduino.cc/builder/gcc_preproc_runner.go +++ b/src/arduino.cc/builder/gcc_preproc_runner.go @@ -39,54 +39,71 @@ import ( "strings" ) -type GCCPreprocRunner struct{} +type GCCPreprocRunner struct { + TargetFileName string +} func (s *GCCPreprocRunner) Run(context map[string]interface{}) error { sketchBuildPath := context[constants.CTX_SKETCH_BUILD_PATH].(string) sketch := context[constants.CTX_SKETCH].(*types.Sketch) - properties := prepareGCCPreprocRecipeProperties(context, filepath.Join(sketchBuildPath, filepath.Base(sketch.MainFile.Name)+".cpp")) + properties, targetFilePath, err := prepareGCCPreprocRecipeProperties(context, filepath.Join(sketchBuildPath, filepath.Base(sketch.MainFile.Name)+".cpp"), s.TargetFileName) + if err != nil { + return utils.WrapError(err) + } verbose := context[constants.CTX_VERBOSE].(bool) logger := context[constants.CTX_LOGGER].(i18n.Logger) - output, err := builder_utils.ExecRecipe(properties, constants.RECIPE_PREPROC_FINAL, true, verbose, false, logger) + _, err = builder_utils.ExecRecipe(properties, constants.RECIPE_PREPROC_MACROS, true, verbose, false, logger) if err != nil { return utils.WrapError(err) } - context[constants.CTX_GCC_MINUS_E_SOURCE] = string(output) + context[constants.CTX_FILE_PATH_TO_READ] = targetFilePath return nil } type GCCPreprocRunnerForDiscoveringIncludes struct { - SourceFile string + SourceFilePath string + TargetFileName string } func (s *GCCPreprocRunnerForDiscoveringIncludes) Run(context map[string]interface{}) error { - properties := prepareGCCPreprocRecipeProperties(context, s.SourceFile) + properties, _, err := prepareGCCPreprocRecipeProperties(context, s.SourceFilePath, s.TargetFileName) + if err != nil { + return utils.WrapError(err) + } verbose := context[constants.CTX_VERBOSE].(bool) logger := context[constants.CTX_LOGGER].(i18n.Logger) - output, err := builder_utils.ExecRecipeCollectStdErr(properties, constants.RECIPE_PREPROC_MACROS, true, verbose, false, logger) + stderr, err := builder_utils.ExecRecipeCollectStdErr(properties, constants.RECIPE_PREPROC_MACROS, true, verbose, false, logger) if err != nil { return utils.WrapError(err) } - context[constants.CTX_GCC_MINUS_E_SOURCE] = string(output) + context[constants.CTX_GCC_MINUS_E_SOURCE] = string(stderr) return nil } -func prepareGCCPreprocRecipeProperties(context map[string]interface{}, sourceFile string) map[string]string { +func prepareGCCPreprocRecipeProperties(context map[string]interface{}, sourceFilePath string, targetFileName string) (map[string]string, string, error) { + preprocPath := context[constants.CTX_PREPROC_PATH].(string) + err := utils.EnsureFolderExists(preprocPath) + if err != nil { + return nil, "", utils.WrapError(err) + } + targetFilePath := filepath.Join(preprocPath, targetFileName) + buildProperties := utils.GetMapStringStringOrDefault(context, constants.CTX_BUILD_PROPERTIES) properties := utils.MergeMapsOfStrings(make(map[string]string), buildProperties) - properties[constants.BUILD_PROPERTIES_SOURCE_FILE] = sourceFile + properties[constants.BUILD_PROPERTIES_SOURCE_FILE] = sourceFilePath + properties[constants.BUILD_PROPERTIES_PREPROCESSED_FILE_PATH] = targetFilePath includes := context[constants.CTX_INCLUDE_FOLDERS].([]string) includes = utils.Map(includes, utils.WrapWithHyphenI) properties[constants.BUILD_PROPERTIES_INCLUDES] = strings.Join(includes, constants.SPACE) builder_utils.RemoveHyphenMDDFlagFromGCCCommandLine(properties) - return properties + return properties, targetFilePath, nil } diff --git a/src/arduino.cc/builder/hardware/platform.keys.rewrite.txt b/src/arduino.cc/builder/hardware/platform.keys.rewrite.txt index 6fb8d9b3..4e8c93fb 100644 --- a/src/arduino.cc/builder/hardware/platform.keys.rewrite.txt +++ b/src/arduino.cc/builder/hardware/platform.keys.rewrite.txt @@ -38,5 +38,5 @@ old.11.recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler. new.11.recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mmcu={build.mcu} -o "{build.path}/{build.project_name}.elf" {object_files} "{archive_file_path}" "-L{build.path}" -lm #generic again -old.12.preproc.macros.flags=-w -x c++ -E -CC -new.12.preproc.macros.flags=-w -x c++ -E -CC -dM -include Arduino.h +old.12.recipe.preproc.macros="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.macros.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" +new.12.recipe.preproc.macros="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.macros.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{preprocessed_file_path}" \ No newline at end of file diff --git a/src/arduino.cc/builder/hardware/platform.txt b/src/arduino.cc/builder/hardware/platform.txt index d3c0d977..8adc28a3 100644 --- a/src/arduino.cc/builder/hardware/platform.txt +++ b/src/arduino.cc/builder/hardware/platform.txt @@ -7,14 +7,10 @@ tools.ctags.pattern="{cmd.path}" -u --language-force=c++ -f - --c++-kinds=svpf - # additional entries tools.avrdude.path={runtime.tools.avrdude.path} -preproc.includes.flags=-w -x c++ -M -MG -MP -include Arduino.h +preproc.includes.flags=-w -x c++ -M -MG -MP preproc.includes.compatibility_flags={build.mbed_api_include} {build.nRF51822_api_include} {build.ble_api_include} {compiler.libsam.c.flags} {compiler.arm.cmsis.path} {build.variant_system_include} recipe.preproc.includes="{compiler.path}{compiler.cpp.cmd}" {preproc.includes.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {preproc.includes.compatibility_flags} {includes} "{source_file}" -preproc.macros.flags=-w -x c++ -E -CC -dM -include Arduino.h +preproc.macros.flags=-w -x c++ -E -CC preproc.macros.compatibility_flags={build.mbed_api_include} {build.nRF51822_api_include} {build.ble_api_include} {compiler.libsam.c.flags} {compiler.arm.cmsis.path} {build.variant_system_include} -recipe.preproc.macros="{compiler.path}{compiler.cpp.cmd}" {compiler.cpreprocessor.flags} {compiler.cpp.flags} {preproc.macros.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {preproc.macros.compatibility_flags} {includes} "{source_file}" - -preproc.final.flags=-w -x c++ -E -CC -include Arduino.h -preproc.final.compatibility_flags={build.mbed_api_include} {build.nRF51822_api_include} {build.ble_api_include} {compiler.libsam.c.flags} {compiler.arm.cmsis.path} {build.variant_system_include} -recipe.preproc.final="{compiler.path}{compiler.cpp.cmd}" {compiler.cpreprocessor.flags} {compiler.cpp.flags} {preproc.final.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {preproc.final.compatibility_flags} {includes} "{source_file}" +recipe.preproc.macros="{compiler.path}{compiler.cpp.cmd}" {compiler.cpreprocessor.flags} {compiler.cpp.flags} {preproc.macros.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {preproc.macros.compatibility_flags} {includes} "{source_file}" -o "{preprocessed_file_path}" diff --git a/src/arduino.cc/builder/prototypes_adder.go b/src/arduino.cc/builder/prototypes_adder.go index 3cfdfb41..1da983bb 100644 --- a/src/arduino.cc/builder/prototypes_adder.go +++ b/src/arduino.cc/builder/prototypes_adder.go @@ -57,10 +57,6 @@ func (s *PrototypesAdder) Run(context map[string]interface{}) error { context[constants.CTX_PROTOTYPE_SECTION] = prototypeSection source = source[:firstFunctionChar] + prototypeSection + source[firstFunctionChar:] - includeSection := composeIncludeArduinoSection() - context[constants.CTX_INCLUDE_SECTION] = includeSection - source = includeSection + source - context[constants.CTX_SOURCE] = source return nil @@ -93,13 +89,6 @@ func joinPrototypes(prototypes []*types.Prototype) string { return strings.Join(prototypesSlice, "\n") } -func composeIncludeArduinoSection() string { - str := "#include \n" - str += "#line 1\n" - - return str -} - func firstFunctionOutsideOfSource(firstFunctionLine int, sourceRows []string) bool { return firstFunctionLine > len(sourceRows)-1 } diff --git a/src/arduino.cc/builder/read_file_and_store_in_context.go b/src/arduino.cc/builder/read_file_and_store_in_context.go new file mode 100644 index 00000000..03eaa2a9 --- /dev/null +++ b/src/arduino.cc/builder/read_file_and_store_in_context.go @@ -0,0 +1,51 @@ +/* + * This file is part of Arduino Builder. + * + * Arduino Builder is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As a special exception, you may use this file as part of a free software + * library without restriction. Specifically, if other files instantiate + * templates or use macros or inline functions from this file, or you compile + * this file and link it with other files to produce an executable, this + * file does not by itself cause the resulting executable to be covered by + * the GNU General Public License. This exception does not however + * invalidate any other reasons why the executable file might be covered by + * the GNU General Public License. + * + * Copyright 2015 Arduino LLC (http://www.arduino.cc/) + */ + +package builder + +import ( + "arduino.cc/builder/constants" + "arduino.cc/builder/utils" + "io/ioutil" +) + +type ReadFileAndStoreInContext struct { + TargetField string +} + +func (s *ReadFileAndStoreInContext) Run(context map[string]interface{}) error { + bytes, err := ioutil.ReadFile(context[constants.CTX_FILE_PATH_TO_READ].(string)) + if err != nil { + return utils.WrapError(err) + } + + context[s.TargetField] = string(bytes) + + return nil +} diff --git a/src/arduino.cc/builder/sketch_source_merger.go b/src/arduino.cc/builder/sketch_source_merger.go index 197ecb92..7afd2b84 100644 --- a/src/arduino.cc/builder/sketch_source_merger.go +++ b/src/arduino.cc/builder/sketch_source_merger.go @@ -41,21 +41,32 @@ type SketchSourceMerger struct{} func (s *SketchSourceMerger) Run(context map[string]interface{}) error { sketch := context[constants.CTX_SKETCH].(*types.Sketch) - source := addPreprocLine(&sketch.MainFile) + includeSection := composeIncludeArduinoSection() + context[constants.CTX_INCLUDE_SECTION] = includeSection + + source := includeSection + source += addSourceWrappedWithLineDirective(&sketch.MainFile) for _, file := range sketch.OtherSketchFiles { - source += addPreprocLine(&file) + source += addSourceWrappedWithLineDirective(&file) } - context[constants.CTX_LINE_OFFSET] = 1 + context[constants.CTX_LINE_OFFSET] = 3 context[constants.CTX_SOURCE] = source return nil } -func addPreprocLine(sketch *types.SketchFile) string { +func addSourceWrappedWithLineDirective(sketch *types.SketchFile) string { source := "#line 1 \"" + strings.Replace(sketch.Name, "\\", "\\\\", -1) + "\"\n" source += sketch.Source source += "\n" return source } + +func composeIncludeArduinoSection() string { + str := "#include \n" + str += "#line 1\n" + + return str +} diff --git a/src/arduino.cc/builder/test/ctags_runner_test.go b/src/arduino.cc/builder/test/ctags_runner_test.go index 30ce129e..9abab566 100644 --- a/src/arduino.cc/builder/test/ctags_runner_test.go +++ b/src/arduino.cc/builder/test/ctags_runner_test.go @@ -69,7 +69,7 @@ func TestCTagsRunner(t *testing.T) { &builder.PrintUsedLibrariesIfVerbose{}, &builder.WarnAboutArchIncompatibleLibraries{}, - &builder.CTagsTargetFileSaver{SourceField: constants.CTX_SOURCE, Filename: constants.FILE_CTAGS_TARGET}, + &builder.CTagsTargetFileSaver{SourceField: constants.CTX_SOURCE, TargetFileName: constants.FILE_CTAGS_TARGET}, &builder.CTagsRunner{}, } @@ -119,7 +119,7 @@ func TestCTagsRunnerSketchWithClass(t *testing.T) { &builder.PrintUsedLibrariesIfVerbose{}, &builder.WarnAboutArchIncompatibleLibraries{}, - &builder.CTagsTargetFileSaver{SourceField: constants.CTX_SOURCE, Filename: constants.FILE_CTAGS_TARGET}, + &builder.CTagsTargetFileSaver{SourceField: constants.CTX_SOURCE, TargetFileName: constants.FILE_CTAGS_TARGET}, &builder.CTagsRunner{}, } @@ -167,7 +167,7 @@ func TestCTagsRunnerSketchWithTypename(t *testing.T) { &builder.PrintUsedLibrariesIfVerbose{}, &builder.WarnAboutArchIncompatibleLibraries{}, - &builder.CTagsTargetFileSaver{SourceField: constants.CTX_SOURCE, Filename: constants.FILE_CTAGS_TARGET}, + &builder.CTagsTargetFileSaver{SourceField: constants.CTX_SOURCE, TargetFileName: constants.FILE_CTAGS_TARGET}, &builder.CTagsRunner{}, } @@ -214,7 +214,7 @@ func TestCTagsRunnerSketchWithNamespace(t *testing.T) { &builder.PrintUsedLibrariesIfVerbose{}, &builder.WarnAboutArchIncompatibleLibraries{}, - &builder.CTagsTargetFileSaver{SourceField: constants.CTX_SOURCE, Filename: constants.FILE_CTAGS_TARGET}, + &builder.CTagsTargetFileSaver{SourceField: constants.CTX_SOURCE, TargetFileName: constants.FILE_CTAGS_TARGET}, &builder.CTagsRunner{}, } diff --git a/src/arduino.cc/builder/test/downloaded_stuff_patches/.gitkeep b/src/arduino.cc/builder/test/downloaded_stuff_patches/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/src/arduino.cc/builder/test/downloaded_stuff_patches/avr_platform_patch.patch b/src/arduino.cc/builder/test/downloaded_stuff_patches/avr_platform_patch.patch deleted file mode 100644 index e7503863..00000000 --- a/src/arduino.cc/builder/test/downloaded_stuff_patches/avr_platform_patch.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/downloaded_hardware/arduino/avr/platform.txt b/downloaded_hardware/arduino/avr/platform.txt -index 537fcc5..4e526d9 100644 ---- a/downloaded_hardware/arduino/avr/platform.txt -+++ b/downloaded_hardware/arduino/avr/platform.txt -@@ -88,6 +88,9 @@ - preproc.macros.flags=-w -x c++ -E -CC - recipe.preproc.macros="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.macros.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" - -+preproc.final.flags=-w -x c++ -E -CC -+recipe.preproc.final="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.final.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -+ - # AVR Uploader/Programmers tools - # ------------------------------ - diff --git a/src/arduino.cc/builder/test/hardware_loader_test.go b/src/arduino.cc/builder/test/hardware_loader_test.go index 9c89a26a..e0fec6e3 100644 --- a/src/arduino.cc/builder/test/hardware_loader_test.go +++ b/src/arduino.cc/builder/test/hardware_loader_test.go @@ -81,8 +81,7 @@ func TestLoadHardware(t *testing.T) { require.Equal(t, "{runtime.tools.ctags.path}", packages.Properties["tools.ctags.path"]) require.Equal(t, "\"{cmd.path}\" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives \"{source_file}\"", packages.Properties["tools.ctags.pattern"]) require.Equal(t, "{runtime.tools.avrdude.path}", packages.Properties["tools.avrdude.path"]) - require.Equal(t, "-w -x c++ -E -CC -include Arduino.h", packages.Properties["preproc.final.flags"]) - require.Equal(t, "-w -x c++ -E -CC -dM -include Arduino.h", packages.Properties["preproc.macros.flags"]) + require.Equal(t, "-w -x c++ -E -CC", packages.Properties["preproc.macros.flags"]) } func TestLoadHardwareMixingUserHardwareFolder(t *testing.T) { @@ -132,7 +131,7 @@ func TestLoadHardwareMixingUserHardwareFolder(t *testing.T) { require.Equal(t, "AVRISP mkII", avrPlatform.Programmers["avrispmkii"][constants.PROGRAMMER_NAME]) require.Equal(t, "-w -x c++ -M -MG -MP", avrPlatform.Properties["preproc.includes.flags"]) - require.Equal(t, "-w -x c++ -E -CC -dM -include Arduino.h", avrPlatform.Properties["preproc.macros.flags"]) + require.Equal(t, "-w -x c++ -E -CC", avrPlatform.Properties["preproc.macros.flags"]) require.Equal(t, "\"{compiler.path}{compiler.cpp.cmd}\" {compiler.cpp.flags} {preproc.includes.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} \"{source_file}\"", avrPlatform.Properties[constants.RECIPE_PREPROC_INCLUDES]) require.False(t, utils.MapStringStringHas(avrPlatform.Properties, "preproc.macros.compatibility_flags")) @@ -147,7 +146,7 @@ func TestLoadHardwareMixingUserHardwareFolder(t *testing.T) { require.Equal(t, "{runtime.tools.ctags.path}", packages.Properties["tools.ctags.path"]) require.Equal(t, "\"{cmd.path}\" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives \"{source_file}\"", packages.Properties["tools.ctags.pattern"]) require.Equal(t, "{runtime.tools.avrdude.path}", packages.Properties["tools.avrdude.path"]) - require.Equal(t, "-w -x c++ -E -CC -dM -include Arduino.h", packages.Properties["preproc.macros.flags"]) + require.Equal(t, "-w -x c++ -E -CC", packages.Properties["preproc.macros.flags"]) require.Equal(t, "{build.mbed_api_include} {build.nRF51822_api_include} {build.ble_api_include} {compiler.libsam.c.flags} {compiler.arm.cmsis.path} {build.variant_system_include}", packages.Properties["preproc.macros.compatibility_flags"]) if runtime.GOOS != "windows" { diff --git a/src/arduino.cc/builder/test/includes_finder_with_regexp_test.go b/src/arduino.cc/builder/test/includes_finder_with_regexp_test.go index 0165ce90..3e5bbf57 100644 --- a/src/arduino.cc/builder/test/includes_finder_with_regexp_test.go +++ b/src/arduino.cc/builder/test/includes_finder_with_regexp_test.go @@ -74,9 +74,10 @@ func TestIncludesFinderWithRegExpCoanOutput(t *testing.T) { require.NotNil(t, context[constants.CTX_INCLUDES]) includes := context[constants.CTX_INCLUDES].([]string) - require.Equal(t, 2, len(includes)) - require.Equal(t, "empty_1.h", includes[0]) - require.Equal(t, "empty_2.h", includes[1]) + require.Equal(t, 3, len(includes)) + require.Equal(t, "Arduino.h", includes[0]) + require.Equal(t, "empty_1.h", includes[1]) + require.Equal(t, "empty_2.h", includes[2]) } func TestIncludesFinderWithRegExp(t *testing.T) { diff --git a/src/arduino.cc/builder/test/prototypes_adder_test.go b/src/arduino.cc/builder/test/prototypes_adder_test.go index 0107546b..bf70e054 100644 --- a/src/arduino.cc/builder/test/prototypes_adder_test.go +++ b/src/arduino.cc/builder/test/prototypes_adder_test.go @@ -450,7 +450,7 @@ func TestPrototypesAdderSketchNoFunctionsTwoFiles(t *testing.T) { NoError(t, err) } - require.Nil(t, context[constants.CTX_INCLUDE_SECTION]) + require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) require.Nil(t, context[constants.CTX_PROTOTYPE_SECTION]) } @@ -491,7 +491,7 @@ func TestPrototypesAdderSketchNoFunctions(t *testing.T) { NoError(t, err) } - require.Nil(t, context[constants.CTX_INCLUDE_SECTION]) + require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) require.Nil(t, context[constants.CTX_PROTOTYPE_SECTION]) } @@ -656,7 +656,7 @@ func TestPrototypesAdderSketchWithUSBCON(t *testing.T) { } require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) - require.Equal(t, "#line 3\nvoid ciao();\n#line 8\nvoid setup();\n#line 13\nvoid loop();\n#line 3\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + require.Equal(t, "#line 5\nvoid ciao();\n#line 10\nvoid setup();\n#line 15\nvoid loop();\n#line 5\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) } func TestPrototypesAdderSketchWithTypename(t *testing.T) { @@ -737,8 +737,52 @@ func TestPrototypesAdderSketchWithIfDef2(t *testing.T) { } require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) - require.Equal(t, "#line 7\nvoid elseBranch();\n#line 11\nvoid f1();\n#line 12\nvoid f2();\n#line 14\nvoid setup();\n#line 16\nvoid loop();\n#line 7\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + require.Equal(t, "#line 5\nvoid elseBranch();\n#line 9\nvoid f1();\n#line 10\nvoid f2();\n#line 12\nvoid setup();\n#line 14\nvoid loop();\n#line 5\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) expectedSource := LoadAndInterpolate(t, filepath.Join("sketch_with_ifdef", "sketch.preprocessed.txt"), context) require.Equal(t, expectedSource, strings.Replace(context[constants.CTX_SOURCE].(string), "\r\n", "\n", -1)) } + +func TestPrototypesAdderSketchWithIfDef2SAM(t *testing.T) { + DownloadCoresAndToolsAndLibraries(t) + + context := make(map[string]interface{}) + + _ = SetupBuildPath(t, context) + //defer os.RemoveAll(buildPath) + + context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} + context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} + context[constants.CTX_FQBN] = "arduino:sam:arduino_due_x_dbg" + context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_ifdef", "sketch.ino") + context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" + context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} + context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} + context[constants.CTX_VERBOSE] = true + + commands := []types.Command{ + &builder.SetupHumanLoggerIfMissing{}, + + &builder.ContainerSetupHardwareToolsLibsSketchAndProps{}, + + &builder.ContainerMergeCopySketchFiles{}, + + &builder.ContainerFindIncludes{}, + + &builder.PrintUsedLibrariesIfVerbose{}, + &builder.WarnAboutArchIncompatibleLibraries{}, + + &builder.ContainerAddPrototypes{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) + require.Equal(t, "#line 2\nvoid ifBranch();\n#line 9\nvoid f1();\n#line 10\nvoid f2();\n#line 12\nvoid setup();\n#line 14\nvoid loop();\n#line 2\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + + expectedSource := LoadAndInterpolate(t, filepath.Join("sketch_with_ifdef", "sketch.preprocessed.SAM.txt"), context) + require.Equal(t, expectedSource, strings.Replace(context[constants.CTX_SOURCE].(string), "\r\n", "\n", -1)) +} diff --git a/src/arduino.cc/builder/test/read_file_and_store_in_context_test.go b/src/arduino.cc/builder/test/read_file_and_store_in_context_test.go new file mode 100644 index 00000000..09452157 --- /dev/null +++ b/src/arduino.cc/builder/test/read_file_and_store_in_context_test.go @@ -0,0 +1,55 @@ +/* + * This file is part of Arduino Builder. + * + * Arduino Builder is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As a special exception, you may use this file as part of a free software + * library without restriction. Specifically, if other files instantiate + * templates or use macros or inline functions from this file, or you compile + * this file and link it with other files to produce an executable, this + * file does not by itself cause the resulting executable to be covered by + * the GNU General Public License. This exception does not however + * invalidate any other reasons why the executable file might be covered by + * the GNU General Public License. + * + * Copyright 2015 Arduino LLC (http://www.arduino.cc/) + */ + +package test + +import ( + "arduino.cc/builder" + "arduino.cc/builder/constants" + "arduino.cc/builder/utils" + "github.com/stretchr/testify/require" + "io/ioutil" + "testing" +) + +func TestReadFileAndStoreInContext(t *testing.T) { + file, err := ioutil.TempFile("", "test") + NoError(t, err) + + utils.WriteFile(file.Name(), "test test\nciao") + + context := make(map[string]interface{}) + context[constants.CTX_FILE_PATH_TO_READ] = file.Name() + + command := &builder.ReadFileAndStoreInContext{TargetField: constants.CTX_GCC_MINUS_E_SOURCE} + err = command.Run(context) + NoError(t, err) + + require.Equal(t, "test test\nciao", context[constants.CTX_GCC_MINUS_E_SOURCE].(string)) +} diff --git a/src/arduino.cc/builder/test/sketch1/merged_sketch.txt b/src/arduino.cc/builder/test/sketch1/merged_sketch.txt index a342aec5..362cfc82 100644 --- a/src/arduino.cc/builder/test/sketch1/merged_sketch.txt +++ b/src/arduino.cc/builder/test/sketch1/merged_sketch.txt @@ -1,3 +1,5 @@ +#include +#line 1 #line 1 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void setup() { diff --git a/src/arduino.cc/builder/test/sketch2/SketchWithIfDef.resolved.directives.txt b/src/arduino.cc/builder/test/sketch2/SketchWithIfDef.resolved.directives.txt index 1c964ddf..75f8b730 100644 --- a/src/arduino.cc/builder/test/sketch2/SketchWithIfDef.resolved.directives.txt +++ b/src/arduino.cc/builder/test/sketch2/SketchWithIfDef.resolved.directives.txt @@ -1,3 +1,5 @@ +#include +#line 1 #line 1 "{{EscapeBackSlashes .sketch.MainFile.Name}}" #define DEBUG 1 #define DISABLED 0 diff --git a/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.ino b/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.ino index 04854715..3d3e2f49 100644 --- a/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.ino +++ b/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.ino @@ -1,6 +1,4 @@ -#include - -#if false +#if __SAM3X8E__ void ifBranch() { } #else diff --git a/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.preprocessed.SAM.txt b/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.preprocessed.SAM.txt new file mode 100644 index 00000000..39bafd85 --- /dev/null +++ b/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.preprocessed.SAM.txt @@ -0,0 +1,29 @@ +#include +#line 1 +#line 1 "{{EscapeBackSlashes .sketch.MainFile.Name}}" +#if __SAM3X8E__ +#line 2 +void ifBranch(); +#line 9 +void f1(); +#line 10 +void f2(); +#line 12 +void setup(); +#line 14 +void loop(); +#line 2 +void ifBranch() { +} +#else +void elseBranch() { +} +#endif + +void f1(){ f2(); } +void f2(){;} + +void setup() { +} +void loop() { +} diff --git a/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.preprocessed.txt b/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.preprocessed.txt index df49a704..ba441c06 100644 --- a/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.preprocessed.txt +++ b/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.preprocessed.txt @@ -1,23 +1,21 @@ #include #line 1 #line 1 "{{EscapeBackSlashes .sketch.MainFile.Name}}" -#include - -#if false +#if __SAM3X8E__ void ifBranch() { } #else -#line 7 +#line 5 void elseBranch(); -#line 11 +#line 9 void f1(); -#line 12 +#line 10 void f2(); -#line 14 +#line 12 void setup(); -#line 16 +#line 14 void loop(); -#line 7 +#line 5 void elseBranch() { } #endif diff --git a/src/arduino.cc/builder/test/sketch_with_usbcon/sketch.ino b/src/arduino.cc/builder/test/sketch_with_usbcon/sketch.ino index 350c9c3f..1fa15390 100644 --- a/src/arduino.cc/builder/test/sketch_with_usbcon/sketch.ino +++ b/src/arduino.cc/builder/test/sketch_with_usbcon/sketch.ino @@ -1,4 +1,6 @@ -#include +#if !defined(USBCON) +#error "Where's my USBCON?" +#endif #if defined(USBCON) void ciao() { From 89f7ece36cc321a677622c0214392180fbef8d65 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Thu, 12 Nov 2015 14:12:54 +0100 Subject: [PATCH 32/85] prototypes line directives now contain original sketch file name. Useful when sketckes are made of multiple .ino files Signed-off-by: Federico Fissore --- ...ototypes_from_source_and_preproc_source.go | 12 +- src/arduino.cc/builder/constants/constants.go | 1 - src/arduino.cc/builder/ctags_parser.go | 10 +- src/arduino.cc/builder/ctags_to_prototypes.go | 6 +- src/arduino.cc/builder/prototypes_adder.go | 2 +- .../builder/test/ctags_parser_test.go | 136 +++++++++--------- .../builder/test/ctags_to_prototypes_test.go | 13 ++ .../builder/test/prototypes_adder_test.go | 67 ++++++--- .../sketch2/SketchWithIfDef.preprocessed.txt | 10 +- .../test/sketch3/Baladuino.preprocessed.txt | 4 +- ...harWithEscapedDoubleQuote.preprocessed.txt | 42 +++--- ...deBetweenMultilineComment.preprocessed.txt | 4 +- .../LineContinuations.preprocessed.txt | 4 +- .../StringWithComment.preprocessed.txt | 4 +- .../sketch8/SketchWithStruct.preprocessed.txt | 6 +- .../sketch_with_config.preprocessed.txt | 4 +- .../sketch.preprocessed.SAM.txt | 10 +- .../sketch_with_ifdef/sketch.preprocessed.txt | 10 +- src/arduino.cc/builder/types/types.go | 1 + src/arduino.cc/builder/utils/utils.go | 9 -- 20 files changed, 203 insertions(+), 152 deletions(-) diff --git a/src/arduino.cc/builder/compare_prototypes_from_source_and_preproc_source.go b/src/arduino.cc/builder/compare_prototypes_from_source_and_preproc_source.go index 48a90b63..718dc542 100644 --- a/src/arduino.cc/builder/compare_prototypes_from_source_and_preproc_source.go +++ b/src/arduino.cc/builder/compare_prototypes_from_source_and_preproc_source.go @@ -31,7 +31,6 @@ package builder import ( "arduino.cc/builder/constants" - "arduino.cc/builder/utils" ) type ComparePrototypesFromSourceAndPreprocSource struct{} @@ -42,7 +41,7 @@ func (s *ComparePrototypesFromSourceAndPreprocSource) Run(context map[string]int actualCTags := []map[string]string{} for _, ctagOfPreprocSource := range ctagsOfPreprocSource { - if utils.SliceContainsCTag(ctagsOfSource, ctagOfPreprocSource) { + if sliceContainsCTag(ctagsOfSource, ctagOfPreprocSource) { actualCTags = append(actualCTags, ctagOfPreprocSource) } } @@ -51,3 +50,12 @@ func (s *ComparePrototypesFromSourceAndPreprocSource) Run(context map[string]int return nil } + +func sliceContainsCTag(slice []map[string]string, target map[string]string) bool { + for _, value := range slice { + if value[FIELD_FUNCTION_NAME] == target[FIELD_FUNCTION_NAME] { + return true + } + } + return false +} diff --git a/src/arduino.cc/builder/constants/constants.go b/src/arduino.cc/builder/constants/constants.go index 98205550..2d894175 100644 --- a/src/arduino.cc/builder/constants/constants.go +++ b/src/arduino.cc/builder/constants/constants.go @@ -73,7 +73,6 @@ const BUILD_PROPERTIES_TOOLS_KEY = "tools" const BUILD_PROPERTIES_VID = "vid" const COAN = "coan" const CTAGS = "ctags" -const CTAGS_FIELD_FUNCTION_NAME = "functionName" const CTX_ACTUAL_PLATFORM = "actualPlatform" const CTX_ARCHIVE_FILE_PATH_CORE = "archiveFileCore" const CTX_BUILD_CORE = "buildCore" diff --git a/src/arduino.cc/builder/ctags_parser.go b/src/arduino.cc/builder/ctags_parser.go index 183f1b6b..3113c81b 100644 --- a/src/arduino.cc/builder/ctags_parser.go +++ b/src/arduino.cc/builder/ctags_parser.go @@ -43,7 +43,9 @@ const FIELD_CODE = "code" const FIELD_CLASS = "class" const FIELD_STRUCT = "struct" const FIELD_NAMESPACE = "namespace" +const FIELD_FILENAME = "filename" const FIELD_SKIP = "skipMe" +const FIELD_FUNCTION_NAME = "functionName" const KIND_PROTOTYPE = "prototype" const KIND_FUNCTION = "function" @@ -104,7 +106,7 @@ func addPrototype(tag map[string]string) { return } - tag[KIND_PROTOTYPE] = tag[FIELD_RETURNTYPE] + " " + tag[constants.CTAGS_FIELD_FUNCTION_NAME] + tag[FIELD_SIGNATURE] + ";" + tag[KIND_PROTOTYPE] = tag[FIELD_RETURNTYPE] + " " + tag[FIELD_FUNCTION_NAME] + tag[FIELD_SIGNATURE] + ";" tag[KIND_PROTOTYPE_MODIFIERS] = "" if strings.Index(tag[FIELD_CODE], STATIC+" ") != -1 { @@ -205,8 +207,10 @@ func parseTag(row string) map[string]string { tag := make(map[string]string) parts := strings.Split(row, "\t") - tag[constants.CTAGS_FIELD_FUNCTION_NAME] = parts[0] - parts = parts[1:] + tag[FIELD_FUNCTION_NAME] = parts[0] + tag[FIELD_FILENAME] = parts[1] + + parts = parts[2:] for _, part := range parts { if strings.Contains(part, ":") { diff --git a/src/arduino.cc/builder/ctags_to_prototypes.go b/src/arduino.cc/builder/ctags_to_prototypes.go index 293494eb..589efca0 100644 --- a/src/arduino.cc/builder/ctags_to_prototypes.go +++ b/src/arduino.cc/builder/ctags_to_prototypes.go @@ -101,7 +101,7 @@ func collectFunctionNames(tags []map[string]string) []string { names := []string{} for _, tag := range tags { if tag[FIELD_KIND] == KIND_FUNCTION { - names = append(names, tag[constants.CTAGS_FIELD_FUNCTION_NAME]) + names = append(names, tag[FIELD_FUNCTION_NAME]) } } return names @@ -120,8 +120,8 @@ func toPrototypes(tags []map[string]string) []*types.Prototype { prototypes := []*types.Prototype{} for _, tag := range tags { if tag[FIELD_SKIP] != TRUE { - ctag := types.Prototype{FunctionName: tag[constants.CTAGS_FIELD_FUNCTION_NAME], Prototype: tag[KIND_PROTOTYPE], Modifiers: tag[KIND_PROTOTYPE_MODIFIERS], Line: tag[FIELD_LINE], Fields: tag} - prototypes = append(prototypes, &ctag) + prototype := &types.Prototype{FunctionName: tag[FIELD_FUNCTION_NAME], File: tag[FIELD_FILENAME], Prototype: tag[KIND_PROTOTYPE], Modifiers: tag[KIND_PROTOTYPE_MODIFIERS], Line: tag[FIELD_LINE], Fields: tag} + prototypes = append(prototypes, prototype) } } return prototypes diff --git a/src/arduino.cc/builder/prototypes_adder.go b/src/arduino.cc/builder/prototypes_adder.go index 1da983bb..40c84f5e 100644 --- a/src/arduino.cc/builder/prototypes_adder.go +++ b/src/arduino.cc/builder/prototypes_adder.go @@ -78,7 +78,7 @@ func composePrototypeSection(line int, prototypes []*types.Prototype) string { func joinPrototypes(prototypes []*types.Prototype) string { prototypesSlice := []string{} for _, proto := range prototypes { - prototypesSlice = append(prototypesSlice, "#line "+proto.Line) + prototypesSlice = append(prototypesSlice, "#line "+proto.Line+" \""+proto.File+"\"") prototypeParts := []string{} if proto.Modifiers != "" { prototypeParts = append(prototypeParts, proto.Modifiers) diff --git a/src/arduino.cc/builder/test/ctags_parser_test.go b/src/arduino.cc/builder/test/ctags_parser_test.go index 29c51f9a..bdc9ce84 100644 --- a/src/arduino.cc/builder/test/ctags_parser_test.go +++ b/src/arduino.cc/builder/test/ctags_parser_test.go @@ -53,29 +53,37 @@ func TestCTagsParserShouldListPrototypes(t *testing.T) { require.Equal(t, 8, len(ctags)) idx := 0 - require.Equal(t, "server", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "server", ctags[idx]["functionName"]) require.Equal(t, "variable", ctags[idx]["kind"]) + require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx]["filename"]) idx++ - require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "setup", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx]["filename"]) idx++ - require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "loop", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx]["filename"]) idx++ - require.Equal(t, "process", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "process", ctags[idx]["functionName"]) require.Equal(t, "prototype", ctags[idx]["kind"]) + require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx]["filename"]) idx++ - require.Equal(t, "process", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "process", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx]["filename"]) idx++ - require.Equal(t, "digitalCommand", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "digitalCommand", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx]["filename"]) idx++ - require.Equal(t, "analogCommand", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "analogCommand", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx]["filename"]) idx++ - require.Equal(t, "modeCommand", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "modeCommand", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx]["filename"]) } func TestCTagsParserShouldListTemplates(t *testing.T) { @@ -93,14 +101,14 @@ func TestCTagsParserShouldListTemplates(t *testing.T) { require.Equal(t, 3, len(ctags)) idx := 0 - require.Equal(t, "minimum", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "minimum", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) require.Equal(t, "(T a, T b)", ctags[idx]["signature"]) idx++ - require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "setup", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) idx++ - require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "loop", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) } @@ -119,17 +127,17 @@ func TestCTagsParserShouldListTemplates2(t *testing.T) { require.Equal(t, 4, len(ctags)) idx := 0 - require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "setup", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) idx++ - require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "loop", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) idx++ - require.Equal(t, "SRAM_writeAnything", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "SRAM_writeAnything", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) require.Equal(t, "(int ee, const T& value)", ctags[idx]["signature"]) idx++ - require.Equal(t, "SRAM_readAnything", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "SRAM_readAnything", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) require.Equal(t, "(int ee, T& value)", ctags[idx]["signature"]) } @@ -149,10 +157,10 @@ func TestCTagsParserShouldDealWithClasses(t *testing.T) { require.Equal(t, 2, len(ctags)) idx := 0 - require.Equal(t, "SleepCycle", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "SleepCycle", ctags[idx]["functionName"]) require.Equal(t, "prototype", ctags[idx]["kind"]) idx++ - require.Equal(t, "SleepCycle", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "SleepCycle", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) } @@ -171,20 +179,20 @@ func TestCTagsParserShouldDealWithStructs(t *testing.T) { require.Equal(t, 5, len(ctags)) idx := 0 - require.Equal(t, "A_NEW_TYPE", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "A_NEW_TYPE", ctags[idx]["functionName"]) require.Equal(t, "struct", ctags[idx]["kind"]) idx++ - require.Equal(t, "foo", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "foo", ctags[idx]["functionName"]) require.Equal(t, "variable", ctags[idx]["kind"]) require.Equal(t, "struct:A_NEW_TYPE", ctags[idx]["typeref"]) idx++ - require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "setup", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) idx++ - require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "loop", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) idx++ - require.Equal(t, "dostuff", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "dostuff", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) } @@ -203,28 +211,28 @@ func TestCTagsParserShouldDealWithMacros(t *testing.T) { require.Equal(t, 8, len(ctags)) idx := 0 - require.Equal(t, "DEBUG", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "DEBUG", ctags[idx]["functionName"]) require.Equal(t, "macro", ctags[idx]["kind"]) idx++ - require.Equal(t, "DISABLED", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "DISABLED", ctags[idx]["functionName"]) require.Equal(t, "macro", ctags[idx]["kind"]) idx++ - require.Equal(t, "hello", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "hello", ctags[idx]["functionName"]) require.Equal(t, "variable", ctags[idx]["kind"]) idx++ - require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "setup", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) idx++ - require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "loop", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) idx++ - require.Equal(t, "debug", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "debug", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) idx++ - require.Equal(t, "disabledIsDefined", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "disabledIsDefined", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) idx++ - require.Equal(t, "useMyType", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "useMyType", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) } @@ -243,13 +251,13 @@ func TestCTagsParserShouldDealFunctionWithDifferentSignatures(t *testing.T) { require.Equal(t, 3, len(ctags)) idx := 0 - require.Equal(t, "getBytes", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "getBytes", ctags[idx]["functionName"]) require.Equal(t, "prototype", ctags[idx]["kind"]) idx++ - require.Equal(t, "getBytes", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "getBytes", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) idx++ - require.Equal(t, "getBytes", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "getBytes", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) } @@ -268,22 +276,22 @@ func TestCTagsParserClassMembersAreFilteredOut(t *testing.T) { require.Equal(t, 5, len(ctags)) idx := 0 - require.Equal(t, "set_values", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "set_values", ctags[idx]["functionName"]) require.Equal(t, "prototype", ctags[idx]["kind"]) require.Equal(t, "Rectangle", ctags[idx]["class"]) idx++ - require.Equal(t, "area", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "area", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) require.Equal(t, "Rectangle", ctags[idx]["class"]) idx++ - require.Equal(t, "set_values", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "set_values", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) require.Equal(t, "Rectangle", ctags[idx]["class"]) idx++ - require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "setup", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) idx++ - require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "loop", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) } @@ -302,30 +310,30 @@ func TestCTagsParserStructWithFunctions(t *testing.T) { require.Equal(t, 8, len(ctags)) idx := 0 - require.Equal(t, "sensorData", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "sensorData", ctags[idx]["functionName"]) require.Equal(t, "struct", ctags[idx]["kind"]) idx++ - require.Equal(t, "sensorData", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "sensorData", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) require.Equal(t, "sensorData", ctags[idx]["struct"]) idx++ - require.Equal(t, "sensorData", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "sensorData", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) require.Equal(t, "sensorData", ctags[idx]["struct"]) idx++ - require.Equal(t, "sensors", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "sensors", ctags[idx]["functionName"]) require.Equal(t, "variable", ctags[idx]["kind"]) idx++ - require.Equal(t, "sensor1", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "sensor1", ctags[idx]["functionName"]) require.Equal(t, "variable", ctags[idx]["kind"]) idx++ - require.Equal(t, "sensor2", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "sensor2", ctags[idx]["functionName"]) require.Equal(t, "variable", ctags[idx]["kind"]) idx++ - require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "setup", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) idx++ - require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "loop", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) } @@ -344,14 +352,14 @@ func TestCTagsParserDefaultArguments(t *testing.T) { require.Equal(t, 3, len(ctags)) idx := 0 - require.Equal(t, "test", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "test", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) require.Equal(t, "(int x = 1)", ctags[idx]["signature"]) idx++ - require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "setup", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) idx++ - require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "loop", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) } @@ -370,14 +378,14 @@ func TestCTagsParserNamespace(t *testing.T) { require.Equal(t, 3, len(ctags)) idx := 0 - require.Equal(t, "value", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "value", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) require.Equal(t, "Test", ctags[idx]["namespace"]) idx++ - require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "setup", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) idx++ - require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "loop", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) } @@ -396,13 +404,13 @@ func TestCTagsParserStatic(t *testing.T) { require.Equal(t, 3, len(ctags)) idx := 0 - require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "setup", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) idx++ - require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "loop", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) idx++ - require.Equal(t, "doStuff", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "doStuff", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) } @@ -421,16 +429,16 @@ func TestCTagsParserFunctionPointer(t *testing.T) { require.Equal(t, 4, len(ctags)) idx := 0 - require.Equal(t, "t1Callback", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "t1Callback", ctags[idx]["functionName"]) require.Equal(t, "variable", ctags[idx]["kind"]) idx++ - require.Equal(t, "t1Callback", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "t1Callback", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) idx++ - require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "setup", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) idx++ - require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "loop", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) } @@ -449,20 +457,20 @@ func TestCTagsParserFunctionPointers(t *testing.T) { require.Equal(t, 5, len(ctags)) idx := 0 - require.Equal(t, "setup", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "setup", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) idx++ - require.Equal(t, "loop", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "loop", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) idx++ - require.Equal(t, "func", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "func", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) idx++ - require.Equal(t, "funcArr", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "funcArr", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) require.Equal(t, "()", ctags[idx]["signature"]) idx++ - require.Equal(t, "funcCombo", ctags[idx][constants.CTAGS_FIELD_FUNCTION_NAME]) + require.Equal(t, "funcCombo", ctags[idx]["functionName"]) require.Equal(t, "function", ctags[idx]["kind"]) require.Equal(t, "(void (*(&in)[5])(int))", ctags[idx]["signature"]) diff --git a/src/arduino.cc/builder/test/ctags_to_prototypes_test.go b/src/arduino.cc/builder/test/ctags_to_prototypes_test.go index 970d4642..b49c0fcb 100644 --- a/src/arduino.cc/builder/test/ctags_to_prototypes_test.go +++ b/src/arduino.cc/builder/test/ctags_to_prototypes_test.go @@ -61,6 +61,7 @@ func TestCTagsToPrototypesShouldListPrototypes(t *testing.T) { require.Equal(t, 5, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "/tmp/sketch7210316334309249705.cpp", prototypes[0].File) require.Equal(t, "void loop();", prototypes[1].Prototype) require.Equal(t, "void digitalCommand(YunClient client);", prototypes[2].Prototype) require.Equal(t, "void analogCommand(YunClient client);", prototypes[3].Prototype) @@ -92,6 +93,7 @@ func TestCTagsToPrototypesShouldListTemplates(t *testing.T) { require.Equal(t, 3, len(prototypes)) require.Equal(t, "template T minimum (T a, T b);", prototypes[0].Prototype) + require.Equal(t, "/tmp/sketch8398023134925534708.cpp", prototypes[0].File) require.Equal(t, "void setup();", prototypes[1].Prototype) require.Equal(t, "void loop();", prototypes[2].Prototype) @@ -121,6 +123,7 @@ func TestCTagsToPrototypesShouldListTemplates2(t *testing.T) { require.Equal(t, 4, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "/tmp/sketch463160524247569568.cpp", prototypes[0].File) require.Equal(t, "void loop();", prototypes[1].Prototype) require.Equal(t, "template int SRAM_writeAnything(int ee, const T& value);", prototypes[2].Prototype) require.Equal(t, "template int SRAM_readAnything(int ee, T& value);", prototypes[3].Prototype) @@ -177,6 +180,7 @@ func TestCTagsToPrototypesShouldDealWithStructs(t *testing.T) { require.Equal(t, 3, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "/tmp/sketch8930345717354294915.cpp", prototypes[0].File) require.Equal(t, "void loop();", prototypes[1].Prototype) require.Equal(t, "void dostuff(A_NEW_TYPE * bar);", prototypes[2].Prototype) @@ -206,6 +210,7 @@ func TestCTagsToPrototypesShouldDealWithMacros(t *testing.T) { require.Equal(t, 5, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "/tmp/sketch5976699731718729500.cpp", prototypes[0].File) require.Equal(t, "void loop();", prototypes[1].Prototype) require.Equal(t, "void debug();", prototypes[2].Prototype) require.Equal(t, "void disabledIsDefined();", prototypes[3].Prototype) @@ -237,6 +242,7 @@ func TestCTagsToPrototypesShouldDealFunctionWithDifferentSignatures(t *testing.T require.Equal(t, 1, len(prototypes)) require.Equal(t, "boolean getBytes( byte addr, int amount );", prototypes[0].Prototype) + require.Equal(t, "/tmp/test260613593/preproc/ctags_target.cpp", prototypes[0].File) prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) require.Equal(t, 5031, prototypeLine) @@ -264,6 +270,7 @@ func TestCTagsToPrototypesClassMembersAreFilteredOut(t *testing.T) { require.Equal(t, 2, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "/tmp/test834438754/preproc/ctags_target.cpp", prototypes[0].File) require.Equal(t, "void loop();", prototypes[1].Prototype) prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) @@ -292,6 +299,7 @@ func TestCTagsToPrototypesStructWithFunctions(t *testing.T) { require.Equal(t, 2, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "/tmp/build7315640391316178285.tmp/preproc/ctags_target.cpp", prototypes[0].File) require.Equal(t, "void loop();", prototypes[1].Prototype) prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) @@ -320,6 +328,7 @@ func TestCTagsToPrototypesDefaultArguments(t *testing.T) { require.Equal(t, 2, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "/tmp/test179252494/preproc/ctags_target.cpp", prototypes[0].File) require.Equal(t, "void loop();", prototypes[1].Prototype) prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) @@ -348,6 +357,7 @@ func TestCTagsToPrototypesNamespace(t *testing.T) { require.Equal(t, 2, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "/tmp/test030883150/preproc/ctags_target.cpp", prototypes[0].File) require.Equal(t, "void loop();", prototypes[1].Prototype) prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) @@ -376,6 +386,7 @@ func TestCTagsToPrototypesStatic(t *testing.T) { require.Equal(t, 3, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "/tmp/test542833488/preproc/ctags_target.cpp", prototypes[0].File) require.Equal(t, "void loop();", prototypes[1].Prototype) require.Equal(t, "void doStuff();", prototypes[2].Prototype) require.Equal(t, "static", prototypes[2].Modifiers) @@ -406,6 +417,7 @@ func TestCTagsToPrototypesFunctionPointer(t *testing.T) { require.Equal(t, 3, len(prototypes)) require.Equal(t, "void t1Callback();", prototypes[0].Prototype) + require.Equal(t, "/tmp/test547238273/preproc/ctags_target.cpp", prototypes[0].File) require.Equal(t, "void setup();", prototypes[1].Prototype) require.Equal(t, "void loop();", prototypes[2].Prototype) @@ -435,6 +447,7 @@ func TestCTagsToPrototypesFunctionPointers(t *testing.T) { require.Equal(t, 2, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "/tmp/test907446433/preproc/ctags_target.cpp", prototypes[0].File) require.Equal(t, "void loop();", prototypes[1].Prototype) prototypeLine := context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES].(int) diff --git a/src/arduino.cc/builder/test/prototypes_adder_test.go b/src/arduino.cc/builder/test/prototypes_adder_test.go index bf70e054..01fab5ce 100644 --- a/src/arduino.cc/builder/test/prototypes_adder_test.go +++ b/src/arduino.cc/builder/test/prototypes_adder_test.go @@ -49,10 +49,13 @@ func TestPrototypesAdderBridgeExample(t *testing.T) { buildPath := SetupBuildPath(t, context) defer os.RemoveAll(buildPath) + sketchLocation := filepath.Join("downloaded_libraries", "Bridge", "examples", "Bridge", "Bridge.ino") + absoluteSketchLocation := strings.Replace(Abs(t, sketchLocation), "\\", "\\\\", -1) + context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} context[constants.CTX_FQBN] = "arduino:avr:leonardo" - context[constants.CTX_SKETCH_LOCATION] = filepath.Join("downloaded_libraries", "Bridge", "examples", "Bridge", "Bridge.ino") + context[constants.CTX_SKETCH_LOCATION] = sketchLocation context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} @@ -79,7 +82,7 @@ func TestPrototypesAdderBridgeExample(t *testing.T) { } require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) - require.Equal(t, "#line 33\nvoid setup();\n#line 46\nvoid loop();\n#line 62\nvoid process(BridgeClient client);\n#line 82\nvoid digitalCommand(BridgeClient client);\n#line 109\nvoid analogCommand(BridgeClient client);\n#line 149\nvoid modeCommand(BridgeClient client);\n#line 33\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + require.Equal(t, "#line 33 \""+absoluteSketchLocation+"\"\nvoid setup();\n#line 46 \""+absoluteSketchLocation+"\"\nvoid loop();\n#line 62 \""+absoluteSketchLocation+"\"\nvoid process(BridgeClient client);\n#line 82 \""+absoluteSketchLocation+"\"\nvoid digitalCommand(BridgeClient client);\n#line 109 \""+absoluteSketchLocation+"\"\nvoid analogCommand(BridgeClient client);\n#line 149 \""+absoluteSketchLocation+"\"\nvoid modeCommand(BridgeClient client);\n#line 33\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) } func TestPrototypesAdderSketchWithIfDef(t *testing.T) { @@ -377,10 +380,13 @@ func TestPrototypesAdderSketchWithConfig(t *testing.T) { buildPath := SetupBuildPath(t, context) defer os.RemoveAll(buildPath) + sketchLocation := filepath.Join("sketch_with_config", "sketch_with_config.ino") + absoluteSketchLocation := strings.Replace(Abs(t, sketchLocation), "\\", "\\\\", -1) + context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} context[constants.CTX_FQBN] = "arduino:avr:leonardo" - context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_config", "sketch_with_config.ino") + context[constants.CTX_SKETCH_LOCATION] = sketchLocation context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} @@ -407,7 +413,7 @@ func TestPrototypesAdderSketchWithConfig(t *testing.T) { } require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) - require.Equal(t, "#line 13\nvoid setup();\n#line 17\nvoid loop();\n#line 13\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + require.Equal(t, "#line 13 \""+absoluteSketchLocation+"\"\nvoid setup();\n#line 17 \""+absoluteSketchLocation+"\"\nvoid loop();\n#line 13\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) preprocessed := LoadAndInterpolate(t, filepath.Join("sketch_with_config", "sketch_with_config.preprocessed.txt"), context) require.Equal(t, preprocessed, strings.Replace(context[constants.CTX_SOURCE].(string), "\r\n", "\n", -1)) @@ -503,10 +509,13 @@ func TestPrototypesAdderSketchWithDefaultArgs(t *testing.T) { buildPath := SetupBuildPath(t, context) defer os.RemoveAll(buildPath) + sketchLocation := filepath.Join("sketch_with_default_args", "sketch.ino") + absoluteSketchLocation := strings.Replace(Abs(t, sketchLocation), "\\", "\\\\", -1) + context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} context[constants.CTX_FQBN] = "arduino:avr:leonardo" - context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_default_args", "sketch.ino") + context[constants.CTX_SKETCH_LOCATION] = sketchLocation context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} @@ -533,7 +542,7 @@ func TestPrototypesAdderSketchWithDefaultArgs(t *testing.T) { } require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) - require.Equal(t, "#line 4\nvoid setup();\n#line 7\nvoid loop();\n#line 1\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + require.Equal(t, "#line 4 \""+absoluteSketchLocation+"\"\nvoid setup();\n#line 7 \""+absoluteSketchLocation+"\"\nvoid loop();\n#line 1\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) } func TestPrototypesAdderSketchWithInlineFunction(t *testing.T) { @@ -544,10 +553,13 @@ func TestPrototypesAdderSketchWithInlineFunction(t *testing.T) { buildPath := SetupBuildPath(t, context) defer os.RemoveAll(buildPath) + sketchLocation := filepath.Join("sketch_with_inline_function", "sketch.ino") + absoluteSketchLocation := strings.Replace(Abs(t, sketchLocation), "\\", "\\\\", -1) + context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} context[constants.CTX_FQBN] = "arduino:avr:leonardo" - context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_inline_function", "sketch.ino") + context[constants.CTX_SKETCH_LOCATION] = sketchLocation context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} @@ -574,7 +586,7 @@ func TestPrototypesAdderSketchWithInlineFunction(t *testing.T) { } require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) - require.Equal(t, "#line 1\nvoid setup();\n#line 2\nvoid loop();\n#line 4\nshort unsigned int testInt();\n#line 8\nstatic int8_t testInline();\n#line 12\nuint8_t testAttribute();\n#line 1\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + require.Equal(t, "#line 1 \""+absoluteSketchLocation+"\"\nvoid setup();\n#line 2 \""+absoluteSketchLocation+"\"\nvoid loop();\n#line 4 \""+absoluteSketchLocation+"\"\nshort unsigned int testInt();\n#line 8 \""+absoluteSketchLocation+"\"\nstatic int8_t testInline();\n#line 12 \""+absoluteSketchLocation+"\"\nuint8_t testAttribute();\n#line 1\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) } func TestPrototypesAdderSketchWithFunctionSignatureInsideIFDEF(t *testing.T) { @@ -585,10 +597,13 @@ func TestPrototypesAdderSketchWithFunctionSignatureInsideIFDEF(t *testing.T) { buildPath := SetupBuildPath(t, context) defer os.RemoveAll(buildPath) + sketchLocation := filepath.Join("sketch_with_function_signature_inside_ifdef", "sketch.ino") + absoluteSketchLocation := strings.Replace(Abs(t, sketchLocation), "\\", "\\\\", -1) + context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} context[constants.CTX_FQBN] = "arduino:avr:leonardo" - context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_function_signature_inside_ifdef", "sketch.ino") + context[constants.CTX_SKETCH_LOCATION] = sketchLocation context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} @@ -615,7 +630,7 @@ func TestPrototypesAdderSketchWithFunctionSignatureInsideIFDEF(t *testing.T) { } require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) - require.Equal(t, "#line 1\nvoid setup();\n#line 3\nvoid loop();\n#line 15\nint8_t adalight();\n#line 1\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + require.Equal(t, "#line 1 \""+absoluteSketchLocation+"\"\nvoid setup();\n#line 3 \""+absoluteSketchLocation+"\"\nvoid loop();\n#line 15 \""+absoluteSketchLocation+"\"\nint8_t adalight();\n#line 1\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) } func TestPrototypesAdderSketchWithUSBCON(t *testing.T) { @@ -626,10 +641,13 @@ func TestPrototypesAdderSketchWithUSBCON(t *testing.T) { buildPath := SetupBuildPath(t, context) defer os.RemoveAll(buildPath) + sketchLocation := filepath.Join("sketch_with_usbcon", "sketch.ino") + absoluteSketchLocation := strings.Replace(Abs(t, sketchLocation), "\\", "\\\\", -1) + context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} context[constants.CTX_FQBN] = "arduino:avr:leonardo" - context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_usbcon", "sketch.ino") + context[constants.CTX_SKETCH_LOCATION] = sketchLocation context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} @@ -656,7 +674,7 @@ func TestPrototypesAdderSketchWithUSBCON(t *testing.T) { } require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) - require.Equal(t, "#line 5\nvoid ciao();\n#line 10\nvoid setup();\n#line 15\nvoid loop();\n#line 5\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + require.Equal(t, "#line 5 \""+absoluteSketchLocation+"\"\nvoid ciao();\n#line 10 \""+absoluteSketchLocation+"\"\nvoid setup();\n#line 15 \""+absoluteSketchLocation+"\"\nvoid loop();\n#line 5\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) } func TestPrototypesAdderSketchWithTypename(t *testing.T) { @@ -667,10 +685,13 @@ func TestPrototypesAdderSketchWithTypename(t *testing.T) { buildPath := SetupBuildPath(t, context) defer os.RemoveAll(buildPath) + sketchLocation := filepath.Join("sketch_with_typename", "sketch.ino") + absoluteSketchLocation := strings.Replace(Abs(t, sketchLocation), "\\", "\\\\", -1) + context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} context[constants.CTX_FQBN] = "arduino:avr:leonardo" - context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_typename", "sketch.ino") + context[constants.CTX_SKETCH_LOCATION] = sketchLocation context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_LIBRARIES_FOLDERS] = []string{"libraries", "downloaded_libraries"} context[constants.CTX_VERBOSE] = true @@ -696,7 +717,7 @@ func TestPrototypesAdderSketchWithTypename(t *testing.T) { } require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) - require.Equal(t, "#line 6\nvoid setup();\n#line 10\nvoid loop();\n#line 6\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + require.Equal(t, "#line 6 \""+absoluteSketchLocation+"\"\nvoid setup();\n#line 10 \""+absoluteSketchLocation+"\"\nvoid loop();\n#line 6\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) } func TestPrototypesAdderSketchWithIfDef2(t *testing.T) { @@ -707,10 +728,13 @@ func TestPrototypesAdderSketchWithIfDef2(t *testing.T) { buildPath := SetupBuildPath(t, context) defer os.RemoveAll(buildPath) + sketchLocation := filepath.Join("sketch_with_ifdef", "sketch.ino") + absoluteSketchLocation := strings.Replace(Abs(t, sketchLocation), "\\", "\\\\", -1) + context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} context[constants.CTX_FQBN] = "arduino:avr:yun" - context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_ifdef", "sketch.ino") + context[constants.CTX_SKETCH_LOCATION] = sketchLocation context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} @@ -737,7 +761,7 @@ func TestPrototypesAdderSketchWithIfDef2(t *testing.T) { } require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) - require.Equal(t, "#line 5\nvoid elseBranch();\n#line 9\nvoid f1();\n#line 10\nvoid f2();\n#line 12\nvoid setup();\n#line 14\nvoid loop();\n#line 5\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + require.Equal(t, "#line 5 \""+absoluteSketchLocation+"\"\nvoid elseBranch();\n#line 9 \""+absoluteSketchLocation+"\"\nvoid f1();\n#line 10 \""+absoluteSketchLocation+"\"\nvoid f2();\n#line 12 \""+absoluteSketchLocation+"\"\nvoid setup();\n#line 14 \""+absoluteSketchLocation+"\"\nvoid loop();\n#line 5\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) expectedSource := LoadAndInterpolate(t, filepath.Join("sketch_with_ifdef", "sketch.preprocessed.txt"), context) require.Equal(t, expectedSource, strings.Replace(context[constants.CTX_SOURCE].(string), "\r\n", "\n", -1)) @@ -748,13 +772,16 @@ func TestPrototypesAdderSketchWithIfDef2SAM(t *testing.T) { context := make(map[string]interface{}) - _ = SetupBuildPath(t, context) - //defer os.RemoveAll(buildPath) + buildPath := SetupBuildPath(t, context) + defer os.RemoveAll(buildPath) + + sketchLocation := filepath.Join("sketch_with_ifdef", "sketch.ino") + absoluteSketchLocation := strings.Replace(Abs(t, sketchLocation), "\\", "\\\\", -1) context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} context[constants.CTX_FQBN] = "arduino:sam:arduino_due_x_dbg" - context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_ifdef", "sketch.ino") + context[constants.CTX_SKETCH_LOCATION] = sketchLocation context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} @@ -781,7 +808,7 @@ func TestPrototypesAdderSketchWithIfDef2SAM(t *testing.T) { } require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) - require.Equal(t, "#line 2\nvoid ifBranch();\n#line 9\nvoid f1();\n#line 10\nvoid f2();\n#line 12\nvoid setup();\n#line 14\nvoid loop();\n#line 2\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + require.Equal(t, "#line 2 \""+absoluteSketchLocation+"\"\nvoid ifBranch();\n#line 9 \""+absoluteSketchLocation+"\"\nvoid f1();\n#line 10 \""+absoluteSketchLocation+"\"\nvoid f2();\n#line 12 \""+absoluteSketchLocation+"\"\nvoid setup();\n#line 14 \""+absoluteSketchLocation+"\"\nvoid loop();\n#line 2\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) expectedSource := LoadAndInterpolate(t, filepath.Join("sketch_with_ifdef", "sketch.preprocessed.SAM.txt"), context) require.Equal(t, expectedSource, strings.Replace(context[constants.CTX_SOURCE].(string), "\r\n", "\n", -1)) diff --git a/src/arduino.cc/builder/test/sketch2/SketchWithIfDef.preprocessed.txt b/src/arduino.cc/builder/test/sketch2/SketchWithIfDef.preprocessed.txt index e5f36e8b..cd473ce8 100644 --- a/src/arduino.cc/builder/test/sketch2/SketchWithIfDef.preprocessed.txt +++ b/src/arduino.cc/builder/test/sketch2/SketchWithIfDef.preprocessed.txt @@ -16,15 +16,15 @@ typedef MyType int; #include "empty_2.h" -#line 16 +#line 16 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void setup(); -#line 21 +#line 21 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void loop(); -#line 33 +#line 33 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void debug(); -#line 44 +#line 44 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void disabledIsDefined(); -#line 48 +#line 48 "{{EscapeBackSlashes .sketch.MainFile.Name}}" int useMyType(MyType type); #line 16 void setup() { diff --git a/src/arduino.cc/builder/test/sketch3/Baladuino.preprocessed.txt b/src/arduino.cc/builder/test/sketch3/Baladuino.preprocessed.txt index 01a0bbaf..e11411d8 100644 --- a/src/arduino.cc/builder/test/sketch3/Baladuino.preprocessed.txt +++ b/src/arduino.cc/builder/test/sketch3/Baladuino.preprocessed.txt @@ -88,9 +88,9 @@ WII Wii(&Btd); // The Wii library can communicate with Wiimotes and the Nunchuck // This can also be done using the Android or Processing application #endif -#line 88 +#line 88 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void setup(); -#line 204 +#line 204 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void loop(); #line 88 void setup() { diff --git a/src/arduino.cc/builder/test/sketch4/CharWithEscapedDoubleQuote.preprocessed.txt b/src/arduino.cc/builder/test/sketch4/CharWithEscapedDoubleQuote.preprocessed.txt index 8cc7e690..caa42958 100644 --- a/src/arduino.cc/builder/test/sketch4/CharWithEscapedDoubleQuote.preprocessed.txt +++ b/src/arduino.cc/builder/test/sketch4/CharWithEscapedDoubleQuote.preprocessed.txt @@ -39,47 +39,47 @@ Code Exclusively for GPRS shield: // Default set of instructions for GPRS Shield power control // -#line 39 +#line 39 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void setPowerStateTo( int newState ); -#line 64 +#line 64 "{{EscapeBackSlashes .sketch.MainFile.Name}}" int getPowerState(); -#line 75 +#line 75 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void powerUpOrDown(); -#line 90 +#line 90 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void clearBufferArray(); -#line 96 +#line 96 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void makeMissedCall( char num[] ); -#line 111 +#line 111 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void sendTextMessage( char number[], char messg[] ); -#line 129 +#line 129 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void analise(byte incoming[], int length); -#line 179 +#line 179 "{{EscapeBackSlashes .sketch.MainFile.Name}}" byte decToBcd( byte b ); -#line 184 +#line 184 "{{EscapeBackSlashes .sketch.MainFile.Name}}" boolean getBit( byte addr, int pos ); -#line 190 +#line 190 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void setBit( byte addr, int pos, boolean newBit ); -#line 204 +#line 204 "{{EscapeBackSlashes .sketch.MainFile.Name}}" byte getByte( byte addr ); -#line 213 +#line 213 "{{EscapeBackSlashes .sketch.MainFile.Name}}" boolean getBytes( byte addr, int amount ); -#line 230 +#line 230 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void setByte( byte addr, byte newByte ); -#line 235 +#line 235 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void setBytes( byte addr, byte newBytes[], int amount ); -#line 244 +#line 244 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void getTime(); -#line 260 +#line 260 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void setTime( byte newTime[ 7 ] ); -#line 267 +#line 267 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void getRTCTemperature(); -#line 277 +#line 277 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void gprsListen(); -#line 294 +#line 294 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void printTime(); -#line 317 +#line 317 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void setup(); -#line 334 +#line 334 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void loop(); #line 39 void setPowerStateTo( int newState ) diff --git a/src/arduino.cc/builder/test/sketch5/IncludeBetweenMultilineComment.preprocessed.txt b/src/arduino.cc/builder/test/sketch5/IncludeBetweenMultilineComment.preprocessed.txt index fa6ac7b6..8dcc3599 100644 --- a/src/arduino.cc/builder/test/sketch5/IncludeBetweenMultilineComment.preprocessed.txt +++ b/src/arduino.cc/builder/test/sketch5/IncludeBetweenMultilineComment.preprocessed.txt @@ -6,9 +6,9 @@ #include */ CapacitiveSensor cs_13_8 = CapacitiveSensor(13,8); -#line 6 +#line 6 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void setup(); -#line 10 +#line 10 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void loop(); #line 6 void setup() diff --git a/src/arduino.cc/builder/test/sketch6/LineContinuations.preprocessed.txt b/src/arduino.cc/builder/test/sketch6/LineContinuations.preprocessed.txt index 7bec9d91..5742adcc 100644 --- a/src/arduino.cc/builder/test/sketch6/LineContinuations.preprocessed.txt +++ b/src/arduino.cc/builder/test/sketch6/LineContinuations.preprocessed.txt @@ -7,9 +7,9 @@ world\n"; //" delete this comment line and the IDE parser will crash -#line 7 +#line 7 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void setup(); -#line 11 +#line 11 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void loop(); #line 7 void setup() diff --git a/src/arduino.cc/builder/test/sketch7/StringWithComment.preprocessed.txt b/src/arduino.cc/builder/test/sketch7/StringWithComment.preprocessed.txt index 54e09671..9e6f2bcf 100644 --- a/src/arduino.cc/builder/test/sketch7/StringWithComment.preprocessed.txt +++ b/src/arduino.cc/builder/test/sketch7/StringWithComment.preprocessed.txt @@ -1,9 +1,9 @@ #include #line 1 #line 1 "{{EscapeBackSlashes .sketch.MainFile.Name}}" -#line 1 +#line 1 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void setup(); -#line 10 +#line 10 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void loop(); #line 1 void setup() { diff --git a/src/arduino.cc/builder/test/sketch8/SketchWithStruct.preprocessed.txt b/src/arduino.cc/builder/test/sketch8/SketchWithStruct.preprocessed.txt index be35eaee..8808f91e 100644 --- a/src/arduino.cc/builder/test/sketch8/SketchWithStruct.preprocessed.txt +++ b/src/arduino.cc/builder/test/sketch8/SketchWithStruct.preprocessed.txt @@ -9,11 +9,11 @@ struct A_NEW_TYPE { int c; } foo; -#line 9 +#line 9 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void setup(); -#line 13 +#line 13 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void loop(); -#line 17 +#line 17 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void dostuff(A_NEW_TYPE * bar); #line 9 void setup() { diff --git a/src/arduino.cc/builder/test/sketch_with_config/sketch_with_config.preprocessed.txt b/src/arduino.cc/builder/test/sketch_with_config/sketch_with_config.preprocessed.txt index 55b48b3e..f706e579 100644 --- a/src/arduino.cc/builder/test/sketch_with_config/sketch_with_config.preprocessed.txt +++ b/src/arduino.cc/builder/test/sketch_with_config/sketch_with_config.preprocessed.txt @@ -13,9 +13,9 @@ #include -#line 13 +#line 13 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void setup(); -#line 17 +#line 17 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void loop(); #line 13 void setup() { diff --git a/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.preprocessed.SAM.txt b/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.preprocessed.SAM.txt index 39bafd85..c483fd33 100644 --- a/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.preprocessed.SAM.txt +++ b/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.preprocessed.SAM.txt @@ -2,15 +2,15 @@ #line 1 #line 1 "{{EscapeBackSlashes .sketch.MainFile.Name}}" #if __SAM3X8E__ -#line 2 +#line 2 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void ifBranch(); -#line 9 +#line 9 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void f1(); -#line 10 +#line 10 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void f2(); -#line 12 +#line 12 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void setup(); -#line 14 +#line 14 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void loop(); #line 2 void ifBranch() { diff --git a/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.preprocessed.txt b/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.preprocessed.txt index ba441c06..9482b870 100644 --- a/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.preprocessed.txt +++ b/src/arduino.cc/builder/test/sketch_with_ifdef/sketch.preprocessed.txt @@ -5,15 +5,15 @@ void ifBranch() { } #else -#line 5 +#line 5 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void elseBranch(); -#line 9 +#line 9 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void f1(); -#line 10 +#line 10 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void f2(); -#line 12 +#line 12 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void setup(); -#line 14 +#line 14 "{{EscapeBackSlashes .sketch.MainFile.Name}}" void loop(); #line 5 void elseBranch() { diff --git a/src/arduino.cc/builder/types/types.go b/src/arduino.cc/builder/types/types.go index 71777dc8..c966f2a6 100644 --- a/src/arduino.cc/builder/types/types.go +++ b/src/arduino.cc/builder/types/types.go @@ -153,6 +153,7 @@ type Command interface { type Prototype struct { FunctionName string + File string Prototype string Modifiers string Line string diff --git a/src/arduino.cc/builder/utils/utils.go b/src/arduino.cc/builder/utils/utils.go index 2574a61e..56129fc5 100644 --- a/src/arduino.cc/builder/utils/utils.go +++ b/src/arduino.cc/builder/utils/utils.go @@ -205,15 +205,6 @@ func SliceContains(slice []string, target string) bool { return false } -func SliceContainsCTag(slice []map[string]string, target map[string]string) bool { - for _, value := range slice { - if value[constants.CTAGS_FIELD_FUNCTION_NAME] == target[constants.CTAGS_FIELD_FUNCTION_NAME] { - return true - } - } - return false -} - type mapFunc func(string) string func Map(slice []string, fn mapFunc) []string { From cdd452ba49b3e19537c47e7a05f730dd36eeffd2 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Thu, 12 Nov 2015 16:20:56 +0100 Subject: [PATCH 33/85] Releasing 1.2.0 Signed-off-by: Federico Fissore --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index e43e8389..dd92cc53 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,7 @@ import ( "syscall" ) -const VERSION = "1.1.3" +const VERSION = "1.2.0" const FLAG_ACTION_COMPILE = "compile" const FLAG_ACTION_PREPROCESS = "preprocess" From 8d4dce343e3f5c3c886002abd61339c5214d4da6 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 16 Nov 2015 10:41:03 +0100 Subject: [PATCH 34/85] CTags is now run only once, using the file it reports to filter prototypes which belong to the sketch. Fixes #52 Signed-off-by: Federico Fissore --- .../collect_ctags_from_sketch_files.go | 63 +++++++++++++++++++ .../builder/container_add_prototypes.go | 5 +- src/arduino.cc/builder/test/builder_test.go | 12 ---- 3 files changed, 64 insertions(+), 16 deletions(-) create mode 100644 src/arduino.cc/builder/collect_ctags_from_sketch_files.go diff --git a/src/arduino.cc/builder/collect_ctags_from_sketch_files.go b/src/arduino.cc/builder/collect_ctags_from_sketch_files.go new file mode 100644 index 00000000..b1232bee --- /dev/null +++ b/src/arduino.cc/builder/collect_ctags_from_sketch_files.go @@ -0,0 +1,63 @@ +/* + * This file is part of Arduino Builder. + * + * Arduino Builder is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As a special exception, you may use this file as part of a free software + * library without restriction. Specifically, if other files instantiate + * templates or use macros or inline functions from this file, or you compile + * this file and link it with other files to produce an executable, this + * file does not by itself cause the resulting executable to be covered by + * the GNU General Public License. This exception does not however + * invalidate any other reasons why the executable file might be covered by + * the GNU General Public License. + * + * Copyright 2015 Arduino LLC (http://www.arduino.cc/) + */ + +package builder + +import ( + "arduino.cc/builder/constants" + "arduino.cc/builder/types" + "arduino.cc/builder/utils" +) + +type CollectCTagsFromSketchFiles struct{} + +func (s *CollectCTagsFromSketchFiles) Run(context map[string]interface{}) error { + sketch := context[constants.CTX_SKETCH].(*types.Sketch) + sketchFileNames := collectSketchFileNamesFrom(sketch) + + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) + ctagsOfSketch := []map[string]string{} + for _, ctag := range ctags { + if utils.SliceContains(sketchFileNames, ctag[FIELD_FILENAME]) { + ctagsOfSketch = append(ctagsOfSketch, ctag) + } + } + + context[constants.CTX_COLLECTED_CTAGS] = ctagsOfSketch + + return nil +} + +func collectSketchFileNamesFrom(sketch *types.Sketch) []string { + fileNames := []string{sketch.MainFile.Name} + for _, file := range sketch.OtherSketchFiles { + fileNames = append(fileNames, file.Name) + } + return fileNames +} diff --git a/src/arduino.cc/builder/container_add_prototypes.go b/src/arduino.cc/builder/container_add_prototypes.go index 7a70d703..48aa04a1 100644 --- a/src/arduino.cc/builder/container_add_prototypes.go +++ b/src/arduino.cc/builder/container_add_prototypes.go @@ -44,10 +44,7 @@ func (s *ContainerAddPrototypes) Run(context map[string]interface{}) error { &CTagsTargetFileSaver{SourceField: constants.CTX_GCC_MINUS_E_SOURCE, TargetFileName: constants.FILE_CTAGS_TARGET_FOR_GCC_MINUS_E}, &CTagsRunner{}, &CTagsParser{CTagsField: constants.CTX_CTAGS_OF_PREPROC_SOURCE}, - &CTagsTargetFileSaver{SourceField: constants.CTX_SOURCE, TargetFileName: constants.FILE_CTAGS_TARGET}, - &CTagsRunner{}, - &CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE}, - &ComparePrototypesFromSourceAndPreprocSource{}, + &CollectCTagsFromSketchFiles{}, &CTagsToPrototypes{}, &PrototypesAdder{}, &SketchSaver{}, diff --git a/src/arduino.cc/builder/test/builder_test.go b/src/arduino.cc/builder/test/builder_test.go index 81c78ca3..977bd508 100644 --- a/src/arduino.cc/builder/test/builder_test.go +++ b/src/arduino.cc/builder/test/builder_test.go @@ -62,8 +62,6 @@ func TestBuilderEmptySketch(t *testing.T) { _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_CORE, "HardwareSerial.cpp.o")) NoError(t, err) - _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET)) - NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET_FOR_GCC_MINUS_E)) NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_SKETCH, "sketch.ino.cpp.o")) @@ -97,8 +95,6 @@ func TestBuilderBridge(t *testing.T) { _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_CORE, "HardwareSerial.cpp.o")) NoError(t, err) - _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET)) - NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET_FOR_GCC_MINUS_E)) NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_SKETCH, "Bridge.ino.cpp.o")) @@ -133,8 +129,6 @@ func TestBuilderSketchWithConfig(t *testing.T) { _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_CORE, "HardwareSerial.cpp.o")) NoError(t, err) - _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET)) - NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET_FOR_GCC_MINUS_E)) NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_SKETCH, "sketch_with_config.ino.cpp.o")) @@ -173,8 +167,6 @@ func TestBuilderBridgeTwice(t *testing.T) { _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_CORE, "HardwareSerial.cpp.o")) NoError(t, err) - _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET)) - NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET_FOR_GCC_MINUS_E)) NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_SKETCH, "Bridge.ino.cpp.o")) @@ -214,8 +206,6 @@ func TestBuilderBridgeSAM(t *testing.T) { NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_CORE, "avr", "dtostrf.c.d")) NoError(t, err) - _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET)) - NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET_FOR_GCC_MINUS_E)) NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_SKETCH, "Bridge.ino.cpp.o")) @@ -250,8 +240,6 @@ func TestBuilderBridgeRedBearLab(t *testing.T) { _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_CORE, "HardwareSerial.cpp.o")) NoError(t, err) - _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET)) - NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_PREPROC, constants.FILE_CTAGS_TARGET_FOR_GCC_MINUS_E)) NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_SKETCH, "Bridge.ino.cpp.o")) From 90b63a5bfe016ba0dbe058ba6960839f8d574617 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 16 Nov 2015 10:43:01 +0100 Subject: [PATCH 35/85] Cleaned up some unused constants Signed-off-by: Federico Fissore --- src/arduino.cc/builder/constants/constants.go | 3 --- .../builder/test/includes_finder_with_regexp_test.go | 12 ++++++------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/arduino.cc/builder/constants/constants.go b/src/arduino.cc/builder/constants/constants.go index 2d894175..4c0b3549 100644 --- a/src/arduino.cc/builder/constants/constants.go +++ b/src/arduino.cc/builder/constants/constants.go @@ -96,7 +96,6 @@ const CTX_FILE_PATH_TO_READ = "filePathToRead" const CTX_FOLDERS_WITH_SOURCES_QUEUE = "foldersWithSourcesQueue" const CTX_FQBN = "fqbn" const CTX_GCC_MINUS_E_SOURCE = "gccMinusESource" -const CTX_GCC_MINUS_E_STDERR = "gccMinusEOutput" const CTX_GCC_MINUS_M_OUTPUT = "gccMinusMOutput" const CTX_HARDWARE_FOLDERS = "hardwareFolders" const CTX_HARDWARE = "hardware" @@ -113,8 +112,6 @@ const CTX_LIBRARY_DISCOVERY_RECURSION_DEPTH = "libraryDiscoveryRecursionDepth" const CTX_LIBRARY_RESOLUTION_RESULTS = "libraryResolutionResults" const CTX_LINE_OFFSET = "lineOffset" const CTX_LINE_WHERE_TO_INSERT_PROTOTYPES = "lineWhereToInsertPrototypes" -const CTX_LINE_WHERE_TO_INSERT_PROTOTYPES_OF_PREPROC_SOURCE = "lineWhereToInsertPrototypesOfPreprocSource" -const CTX_LINE_WHERE_TO_INSERT_PROTOTYPES_OF_SOURCE = "lineWhereToInsertPrototypesOfSource" const CTX_LOGGER = "logger" const CTX_OBJECT_FILES_LIBRARIES = "objectFilesLibraries" const CTX_OBJECT_FILES_SKETCH = "objectFilesSketch" diff --git a/src/arduino.cc/builder/test/includes_finder_with_regexp_test.go b/src/arduino.cc/builder/test/includes_finder_with_regexp_test.go index 3e5bbf57..4185c856 100644 --- a/src/arduino.cc/builder/test/includes_finder_with_regexp_test.go +++ b/src/arduino.cc/builder/test/includes_finder_with_regexp_test.go @@ -87,9 +87,9 @@ func TestIncludesFinderWithRegExp(t *testing.T) { "#include \n" + "^\n" + "compilation terminated." - context[constants.CTX_GCC_MINUS_E_STDERR] = output + context["source"] = output - parser := builder.IncludesFinderWithRegExp{ContextField: constants.CTX_GCC_MINUS_E_STDERR} + parser := builder.IncludesFinderWithRegExp{ContextField: "source"} err := parser.Run(context) NoError(t, err) @@ -104,9 +104,9 @@ func TestIncludesFinderWithRegExpEmptyOutput(t *testing.T) { output := "" - context[constants.CTX_GCC_MINUS_E_STDERR] = output + context["source"] = output - parser := builder.IncludesFinderWithRegExp{ContextField: constants.CTX_GCC_MINUS_E_STDERR} + parser := builder.IncludesFinderWithRegExp{ContextField: "source"} err := parser.Run(context) NoError(t, err) @@ -125,9 +125,9 @@ func TestIncludesFinderWithRegExpPreviousIncludes(t *testing.T) { "^\n" + "compilation terminated." - context[constants.CTX_GCC_MINUS_E_STDERR] = output + context["source"] = output - parser := builder.IncludesFinderWithRegExp{ContextField: constants.CTX_GCC_MINUS_E_STDERR} + parser := builder.IncludesFinderWithRegExp{ContextField: "source"} err := parser.Run(context) NoError(t, err) From 4d77fe691b8dfb826f92c70e328b4f36aa7c00f7 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 16 Nov 2015 11:16:49 +0100 Subject: [PATCH 36/85] Made clearer from where LINE_OFFSET comes from Signed-off-by: Federico Fissore --- src/arduino.cc/builder/sketch_source_merger.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/arduino.cc/builder/sketch_source_merger.go b/src/arduino.cc/builder/sketch_source_merger.go index 7afd2b84..1e99a57f 100644 --- a/src/arduino.cc/builder/sketch_source_merger.go +++ b/src/arduino.cc/builder/sketch_source_merger.go @@ -41,16 +41,19 @@ type SketchSourceMerger struct{} func (s *SketchSourceMerger) Run(context map[string]interface{}) error { sketch := context[constants.CTX_SKETCH].(*types.Sketch) + lineOffset := 0 includeSection := composeIncludeArduinoSection() + lineOffset += 2 context[constants.CTX_INCLUDE_SECTION] = includeSection source := includeSection source += addSourceWrappedWithLineDirective(&sketch.MainFile) + lineOffset += 1 for _, file := range sketch.OtherSketchFiles { source += addSourceWrappedWithLineDirective(&file) } - context[constants.CTX_LINE_OFFSET] = 3 + context[constants.CTX_LINE_OFFSET] = lineOffset context[constants.CTX_SOURCE] = source return nil From b2e05861d668bcfaf7b1afb98e57d73a92c6036d Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 16 Nov 2015 11:24:31 +0100 Subject: [PATCH 37/85] Removing stale test file once test completes Signed-off-by: Federico Fissore --- .../builder/test/read_file_and_store_in_context_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/arduino.cc/builder/test/read_file_and_store_in_context_test.go b/src/arduino.cc/builder/test/read_file_and_store_in_context_test.go index 09452157..8b927353 100644 --- a/src/arduino.cc/builder/test/read_file_and_store_in_context_test.go +++ b/src/arduino.cc/builder/test/read_file_and_store_in_context_test.go @@ -36,11 +36,13 @@ import ( "github.com/stretchr/testify/require" "io/ioutil" "testing" + "os" ) func TestReadFileAndStoreInContext(t *testing.T) { file, err := ioutil.TempFile("", "test") NoError(t, err) + defer os.RemoveAll(file.Name()) utils.WriteFile(file.Name(), "test test\nciao") From 52bd9f1eb973666d47f6f31758c725be8b18c935 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 16 Nov 2015 12:02:56 +0100 Subject: [PATCH 38/85] Converting windows path in ctags output to normal paths, when looking for the sketch path in gcc -E output (Windows is always a bit harder) Signed-off-by: Federico Fissore --- src/arduino.cc/builder/collect_ctags_from_sketch_files.go | 3 ++- .../builder/test/read_file_and_store_in_context_test.go | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/arduino.cc/builder/collect_ctags_from_sketch_files.go b/src/arduino.cc/builder/collect_ctags_from_sketch_files.go index b1232bee..f7106dfc 100644 --- a/src/arduino.cc/builder/collect_ctags_from_sketch_files.go +++ b/src/arduino.cc/builder/collect_ctags_from_sketch_files.go @@ -33,6 +33,7 @@ import ( "arduino.cc/builder/constants" "arduino.cc/builder/types" "arduino.cc/builder/utils" + "strings" ) type CollectCTagsFromSketchFiles struct{} @@ -44,7 +45,7 @@ func (s *CollectCTagsFromSketchFiles) Run(context map[string]interface{}) error ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) ctagsOfSketch := []map[string]string{} for _, ctag := range ctags { - if utils.SliceContains(sketchFileNames, ctag[FIELD_FILENAME]) { + if utils.SliceContains(sketchFileNames, strings.Replace(ctag[FIELD_FILENAME], "\\\\", "\\", -1)) { ctagsOfSketch = append(ctagsOfSketch, ctag) } } diff --git a/src/arduino.cc/builder/test/read_file_and_store_in_context_test.go b/src/arduino.cc/builder/test/read_file_and_store_in_context_test.go index 8b927353..2734725a 100644 --- a/src/arduino.cc/builder/test/read_file_and_store_in_context_test.go +++ b/src/arduino.cc/builder/test/read_file_and_store_in_context_test.go @@ -35,8 +35,8 @@ import ( "arduino.cc/builder/utils" "github.com/stretchr/testify/require" "io/ioutil" - "testing" "os" + "testing" ) func TestReadFileAndStoreInContext(t *testing.T) { From 5ee45857e6442688dfa15ca57985b9574106d2ff Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 16 Nov 2015 12:42:52 +0100 Subject: [PATCH 39/85] Added library path to error message about both src and utility folders used by library. Fixes #56 Signed-off-by: Federico Fissore --- src/arduino.cc/builder/constants/constants.go | 2 +- src/arduino.cc/builder/libraries_loader.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/arduino.cc/builder/constants/constants.go b/src/arduino.cc/builder/constants/constants.go index 4c0b3549..f183aecb 100644 --- a/src/arduino.cc/builder/constants/constants.go +++ b/src/arduino.cc/builder/constants/constants.go @@ -210,7 +210,7 @@ const MSG_LIB_LEGACY = "(legacy)" const MSG_LIBRARIES_MULTIPLE_LIBS_FOUND_FOR = "Multiple libraries were found for \"{0}\"" const MSG_LIBRARIES_NOT_USED = " Not used: {0}" const MSG_LIBRARIES_USED = " Used: {0}" -const MSG_LIBRARY_CAN_USE_SRC_AND_UTILITY_FOLDERS = "Library can't use both 'src' and 'utility' folders." +const MSG_LIBRARY_CAN_USE_SRC_AND_UTILITY_FOLDERS = "Library can't use both 'src' and 'utility' folders. Double ckeck {0}" const MSG_LIBRARY_INCOMPATIBLE_ARCH = "WARNING: library {0} claims to run on {1} architecture(s) and may be incompatible with your current board which runs on {2} architecture(s)." const MSG_LOOKING_FOR_RECIPES = "Looking for recipes like {0}*{1}" const MSG_MISSING_BUILD_BOARD = "Board {0}:{1}:{2} doesn''t define a ''build.board'' preference. Auto-set to: {3}" diff --git a/src/arduino.cc/builder/libraries_loader.go b/src/arduino.cc/builder/libraries_loader.go index ef66412f..60c31d74 100644 --- a/src/arduino.cc/builder/libraries_loader.go +++ b/src/arduino.cc/builder/libraries_loader.go @@ -149,7 +149,7 @@ func makeNewLibrary(libraryFolder string, debugLevel int, logger i18n.Logger) (* library.Layout = types.LIBRARY_RECURSIVE library.SrcFolder = filepath.Join(libraryFolder, constants.LIBRARY_FOLDER_SRC) if stat, err := os.Stat(filepath.Join(libraryFolder, constants.LIBRARY_FOLDER_UTILITY)); err == nil && stat.IsDir() { - return nil, utils.ErrorfWithLogger(logger, constants.MSG_LIBRARY_CAN_USE_SRC_AND_UTILITY_FOLDERS) + return nil, utils.ErrorfWithLogger(logger, constants.MSG_LIBRARY_CAN_USE_SRC_AND_UTILITY_FOLDERS, libraryFolder) } } else { library.Layout = types.LIBRARY_FLAT From 94831202ce92fcba3284fd87980be2c9fe1482fb Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 16 Nov 2015 13:52:52 +0100 Subject: [PATCH 40/85] Allowing spaces and tabs between hash and include. Fixes #64 Signed-off-by: Federico Fissore --- .../builder/includes_finder_with_regexp.go | 2 +- .../test/includes_finder_with_regexp_test.go | 48 ++++++++++++++++++- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/arduino.cc/builder/includes_finder_with_regexp.go b/src/arduino.cc/builder/includes_finder_with_regexp.go index 216dd6eb..6fa357a3 100644 --- a/src/arduino.cc/builder/includes_finder_with_regexp.go +++ b/src/arduino.cc/builder/includes_finder_with_regexp.go @@ -36,7 +36,7 @@ import ( "strings" ) -var INCLUDE_REGEXP = regexp.MustCompile("(?ms)^\\s*#include\\s*[<\"](\\S+)[\">]") +var INCLUDE_REGEXP = regexp.MustCompile("(?ms)^\\s*#[ \t]*include\\s*[<\"](\\S+)[\">]") type IncludesFinderWithRegExp struct { ContextField string diff --git a/src/arduino.cc/builder/test/includes_finder_with_regexp_test.go b/src/arduino.cc/builder/test/includes_finder_with_regexp_test.go index 4185c856..d6be6bbc 100644 --- a/src/arduino.cc/builder/test/includes_finder_with_regexp_test.go +++ b/src/arduino.cc/builder/test/includes_finder_with_regexp_test.go @@ -83,7 +83,7 @@ func TestIncludesFinderWithRegExpCoanOutput(t *testing.T) { func TestIncludesFinderWithRegExp(t *testing.T) { context := make(map[string]interface{}) - output := "/home/federico/materiale/works_Arduino/arduino-builder/src/arduino.cc/builder/test/sketch_that_checks_if_SPI_has_transactions/sketch.ino:1:17: fatal error: SPI.h: No such file or directory\n" + + output := "/some/path/sketch.ino:1:17: fatal error: SPI.h: No such file or directory\n" + "#include \n" + "^\n" + "compilation terminated." @@ -120,7 +120,7 @@ func TestIncludesFinderWithRegExpPreviousIncludes(t *testing.T) { context[constants.CTX_INCLUDES] = []string{"test.h"} - output := "/home/federico/materiale/works_Arduino/arduino-builder/src/arduino.cc/builder/test/sketch_that_checks_if_SPI_has_transactions/sketch.ino:1:17: fatal error: SPI.h: No such file or directory\n" + + output := "/some/path/sketch.ino:1:17: fatal error: SPI.h: No such file or directory\n" + "#include \n" + "^\n" + "compilation terminated." @@ -138,3 +138,47 @@ func TestIncludesFinderWithRegExpPreviousIncludes(t *testing.T) { require.Equal(t, "SPI.h", includes[0]) require.Equal(t, "test.h", includes[1]) } + +func TestIncludesFinderWithRegExpPaddedIncludes(t *testing.T) { + context := make(map[string]interface{}) + + context[constants.CTX_INCLUDES] = []string{} + + output := "/some/path/sketch.ino:1:33: fatal error: Wire.h: No such file or directory\n" + + " # include \n" + + " ^\n" + + "compilation terminated.\n" + context["source"] = output + + parser := builder.IncludesFinderWithRegExp{ContextField: "source"} + err := parser.Run(context) + NoError(t, err) + + require.NotNil(t, context[constants.CTX_INCLUDES]) + includes := context[constants.CTX_INCLUDES].([]string) + require.Equal(t, 1, len(includes)) + sort.Strings(includes) + require.Equal(t, "Wire.h", includes[0]) +} + +func TestIncludesFinderWithRegExpPaddedIncludes2(t *testing.T) { + context := make(map[string]interface{}) + + context[constants.CTX_INCLUDES] = []string{} + + output := "/some/path/sketch.ino:1:33: fatal error: Wire.h: No such file or directory\n" + + " #\t\t\tinclude \n" + + " ^\n" + + "compilation terminated.\n" + context["source"] = output + + parser := builder.IncludesFinderWithRegExp{ContextField: "source"} + err := parser.Run(context) + NoError(t, err) + + require.NotNil(t, context[constants.CTX_INCLUDES]) + includes := context[constants.CTX_INCLUDES].([]string) + require.Equal(t, 1, len(includes)) + sort.Strings(includes) + require.Equal(t, "Wire.h", includes[0]) +} From 0baaca2bd232bc17bafc1e0bb055492527554b51 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 16 Nov 2015 14:08:32 +0100 Subject: [PATCH 41/85] Expanding properties of bootloader key before checking for its existence. Fixes #63 Signed-off-by: Federico Fissore --- .../builder/merge_sketch_with_bootloader.go | 2 + .../test/merge_sketch_with_bootloader_test.go | 43 ++ .../my_avr_platform/avr/boards.txt | 6 +- .../stk500v2/stk500boot_v2_mega2560.hex | 469 ++++++++++++++++++ 4 files changed, 518 insertions(+), 2 deletions(-) create mode 100644 src/arduino.cc/builder/test/user_hardware/my_avr_platform/avr/bootloaders/stk500v2/stk500boot_v2_mega2560.hex diff --git a/src/arduino.cc/builder/merge_sketch_with_bootloader.go b/src/arduino.cc/builder/merge_sketch_with_bootloader.go index 364ed040..0864ea78 100644 --- a/src/arduino.cc/builder/merge_sketch_with_bootloader.go +++ b/src/arduino.cc/builder/merge_sketch_with_bootloader.go @@ -32,6 +32,7 @@ package builder import ( "arduino.cc/builder/constants" "arduino.cc/builder/i18n" + "arduino.cc/builder/props" "arduino.cc/builder/types" "arduino.cc/builder/utils" "os" @@ -70,6 +71,7 @@ func (s *MergeSketchWithBootloader) Run(context map[string]interface{}) error { } else { bootloader = buildProperties[constants.BUILD_PROPERTIES_BOOTLOADER_FILE] } + bootloader = props.ExpandPropsInString(buildProperties, bootloader) bootloaderPath := filepath.Join(buildProperties[constants.BUILD_PROPERTIES_RUNTIME_PLATFORM_PATH], constants.FOLDER_BOOTLOADERS, bootloader) if _, err := os.Stat(bootloaderPath); err != nil { diff --git a/src/arduino.cc/builder/test/merge_sketch_with_bootloader_test.go b/src/arduino.cc/builder/test/merge_sketch_with_bootloader_test.go index ea7e3442..8bfd4913 100644 --- a/src/arduino.cc/builder/test/merge_sketch_with_bootloader_test.go +++ b/src/arduino.cc/builder/test/merge_sketch_with_bootloader_test.go @@ -166,3 +166,46 @@ func TestMergeSketchWithBootloaderWhenNoBootloaderAvailable(t *testing.T) { require.Error(t, err) require.True(t, os.IsNotExist(err)) } + +func TestMergeSketchWithBootloaderPathIsParameterized(t *testing.T) { + DownloadCoresAndToolsAndLibraries(t) + + context := make(map[string]interface{}) + + buildPath := SetupBuildPath(t, context) + defer os.RemoveAll(buildPath) + + context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware", "user_hardware"} + context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} + context[constants.CTX_FQBN] = "my_avr_platform:avr:mymega:cpu=atmega2560" + context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} + context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} + context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch1", "sketch.ino") + context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" + + err := utils.EnsureFolderExists(filepath.Join(buildPath, "sketch")) + NoError(t, err) + + fakeSketchHex := "row 1\n" + + "row 2\n" + err = utils.WriteFile(filepath.Join(buildPath, "sketch", "sketch.ino.hex"), fakeSketchHex) + NoError(t, err) + + commands := []types.Command{ + &builder.SetupHumanLoggerIfMissing{}, + &builder.ContainerSetupHardwareToolsLibsSketchAndProps{}, + &builder.MergeSketchWithBootloader{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + bytes, err := ioutil.ReadFile(filepath.Join(buildPath, "sketch", "sketch.ino.with_bootloader.hex")) + NoError(t, err) + mergedSketchHex := string(bytes) + + require.True(t, strings.HasPrefix(mergedSketchHex, "row 1\n:020000023000CC")) + require.True(t, strings.HasSuffix(mergedSketchHex, ":040000033000E000E9\n:00000001FF\n")) +} diff --git a/src/arduino.cc/builder/test/user_hardware/my_avr_platform/avr/boards.txt b/src/arduino.cc/builder/test/user_hardware/my_avr_platform/avr/boards.txt index 75bfb3dc..6b98abf5 100644 --- a/src/arduino.cc/builder/test/user_hardware/my_avr_platform/avr/boards.txt +++ b/src/arduino.cc/builder/test/user_hardware/my_avr_platform/avr/boards.txt @@ -62,9 +62,10 @@ mymega.menu.cpu.atmega2560.upload.protocol=wiring mymega.menu.cpu.atmega2560.upload.maximum_size=253952 mymega.menu.cpu.atmega2560.upload.speed=115200 +mymega.menu.cpu.atmega2560.bootloader._folder=stk500v2 mymega.menu.cpu.atmega2560.bootloader.high_fuses=0xD8 mymega.menu.cpu.atmega2560.bootloader.extended_fuses=0xFD -mymega.menu.cpu.atmega2560.bootloader.file=stk500v2/stk500boot_v2_mega2560.hex +mymega.menu.cpu.atmega2560.bootloader.file={bootloader._folder}/stk500boot_v2_mega2560.hex mymega.menu.cpu.atmega2560.build.mcu=atmega2560 mymega.menu.cpu.atmega2560.build.board=AVR_MEGA2560 @@ -75,9 +76,10 @@ mymega.menu.cpu.atmega1280.upload.protocol=arduino mymega.menu.cpu.atmega1280.upload.maximum_size=126976 mymega.menu.cpu.atmega1280.upload.speed=57600 +mymega.menu.cpu.atmega1280.bootloader._folder=atmega mymega.menu.cpu.atmega1280.bootloader.high_fuses=0xDA mymega.menu.cpu.atmega1280.bootloader.extended_fuses=0xF5 -mymega.menu.cpu.atmega1280.bootloader.file=atmega/ATmegaBOOT_168_atmega1280.hex +mymega.menu.cpu.atmega1280.bootloader.file={bootloader._folder}/ATmegaBOOT_168_atmega1280.hex mymega.menu.cpu.atmega1280.build.mcu=atmega1280 mymega.menu.cpu.atmega1280.build.board=AVR_MEGA diff --git a/src/arduino.cc/builder/test/user_hardware/my_avr_platform/avr/bootloaders/stk500v2/stk500boot_v2_mega2560.hex b/src/arduino.cc/builder/test/user_hardware/my_avr_platform/avr/bootloaders/stk500v2/stk500boot_v2_mega2560.hex new file mode 100644 index 00000000..c52e690a --- /dev/null +++ b/src/arduino.cc/builder/test/user_hardware/my_avr_platform/avr/bootloaders/stk500v2/stk500boot_v2_mega2560.hex @@ -0,0 +1,469 @@ +:020000023000CC +:10E000000D9489F10D94B2F10D94B2F10D94B2F129 +:10E010000D94B2F10D94B2F10D94B2F10D94B2F1F0 +:10E020000D94B2F10D94B2F10D94B2F10D94B2F1E0 +:10E030000D94B2F10D94B2F10D94B2F10D94B2F1D0 +:10E040000D94B2F10D94B2F10D94B2F10D94B2F1C0 +:10E050000D94B2F10D94B2F10D94B2F10D94B2F1B0 +:10E060000D94B2F10D94B2F10D94B2F10D94B2F1A0 +:10E070000D94B2F10D94B2F10D94B2F10D94B2F190 +:10E080000D94B2F10D94B2F10D94B2F10D94B2F180 +:10E090000D94B2F10D94B2F10D94B2F10D94B2F170 +:10E0A0000D94B2F10D94B2F10D94B2F10D94B2F160 +:10E0B0000D94B2F10D94B2F10D94B2F10D94B2F150 +:10E0C0000D94B2F10D94B2F10D94B2F10D94B2F140 +:10E0D0000D94B2F10D94B2F10D94B2F10D94B2F130 +:10E0E0000D94B2F141546D656761323536300041AF +:10E0F000726475696E6F206578706C6F72657220DE +:10E1000073746B3530305632206279204D4C530099 +:10E11000426F6F746C6F616465723E004875683F52 +:10E1200000436F6D70696C6564206F6E203D200048 +:10E130004350552054797065202020203D20005FF9 +:10E140005F4156525F415243485F5F3D2000415658 +:10E1500052204C696243205665723D20004743437C +:10E160002056657273696F6E203D20004350552024 +:10E1700049442020202020203D20004C6F7720663D +:10E18000757365202020203D20004869676820665F +:10E190007573652020203D200045787420667573D6 +:10E1A00065202020203D20004C6F636B2066757336 +:10E1B000652020203D20004D617220203720323024 +:10E1C000313300312E362E3800342E332E350056A2 +:10E1D00023202020414444522020206F7020636F70 +:10E1E00064652020202020696E73747275637469E1 +:10E1F0006F6E2061646472202020496E74657272B3 +:10E20000757074006E6F20766563746F7200726A49 +:10E210006D702020006A6D70200057686174207056 +:10E220006F72743A00506F7274206E6F7420737541 +:10E2300070706F72746564004D7573742062652030 +:10E2400061206C6574746572002000577269747483 +:10E25000696E672045450052656164696E672045B7 +:10E26000450045452065727220636E743D00504F35 +:10E27000525400303D5A65726F2061646472003FF1 +:10E280003D43505520737461747300403D454550C3 +:10E29000524F4D207465737400423D426C696E6B41 +:10E2A000204C454400453D44756D70204545505215 +:10E2B0004F4D00463D44756D7020464C415348001B +:10E2C000483D48656C70004C3D4C69737420492F83 +:10E2D0004F20506F72747300513D51756974005234 +:10E2E0003D44756D702052414D00563D73686F7707 +:10E2F00020696E7465727275707420566563746FF0 +:10E30000727300593D506F727420626C696E6B00BD +:10E310002A0011241FBECFEFD1E2DEBFCDBF01E046 +:10E320000CBF12E0A0E0B2E0EEE1FDEF03E00BBFB6 +:10E3300002C007900D92A030B107D9F712E0A0E01B +:10E34000B2E001C01D92AE30B107E1F70F9460F367 +:10E350000D948DFE01E20EBF0FEF0DBF11241FBE05 +:10E360000D9460F30D9400F020E030E040ED57E0B4 +:10E3700005C0FA013197F1F72F5F3F4F2817390792 +:10E38000C0F308959C01260F311DC901A0E0B0E043 +:10E390002F5F3F4FABBFFC018791882361F08093D3 +:10E3A000C6008091C00086FFFCCF8091C0008064D1 +:10E3B0008093C000EACF08958DE08093C6008091DD +:10E3C000C00086FFFCCF8091C00080648093C000B5 +:10E3D0008AE08093C6008091C00086FFFCCF8091C8 +:10E3E000C00080648093C00008950F94C2F10F9420 +:10E3F000DCF10895FC019081992359F09093C600B7 +:10E400008091C00086FFFCCF8091C0008064809323 +:10E41000C0003196992379F70895282F982F929567 +:10E420009F70892F805D8A3308F0895F8093C600D2 +:10E430008091C00086FFFCCF8091C00080648093F3 +:10E44000C000822F8F70982F905D9A3308F0995FEB +:10E450009093C6008091C00086FFFCCF8091C000E1 +:10E4600080648093C00008959C01FB01853691056E +:10E470001CF46330710594F0C90164E670E00F94F8 +:10E480002EFE605D7F4F6093C6008091C00086FFC6 +:10E49000FCCF8091C00080648093C0002B30310598 +:10E4A00014F43297B4F0C90164E670E00F942EFEC4 +:10E4B0006AE070E00F942EFE605D7F4F6093C600AF +:10E4C0008091C00086FFFCCF8091C0008064809363 +:10E4D000C000C9016AE070E00F942EFEC0968093E0 +:10E4E000C6008091C00086FFFCCF8091C000806490 +:10E4F0008093C00008951F93182F8EE692EE60E07F +:10E500000F94C2F11093C6008091C00086FFFCCF2B +:10E510008091C00080648093C0000F94DCF11F9153 +:10E5200008952F923F924F925F926F927F928F92B7 +:10E530009F92AF92BF92CF92DF92EF92FF920F9392 +:10E540001F93DF93CF93CDB7DEB762970FB6F894E2 +:10E55000DEBF0FBECDBF382E622ECA01DB015C01CB +:10E560006D01772420E2222E2E010894411C511CBB +:10E570008BC081E0A81680E0B80681E0C80680E084 +:10E58000D80628F0C601AA27BB270F940DF2BB2797 +:10E59000AD2D9C2D8B2D0F940DF28A2D0F940DF225 +:10E5A0002092C6008091C00086FFFCCF8091C00001 +:10E5B00080648093C0009DE29093C6008091C0006B +:10E5C00086FFFCCF8091C00080648093C0002092C1 +:10E5D000C6008091C00086FFFCCF8091C00080649F +:10E5E0008093C00019828601750188249924A1E0D6 +:10E5F0003A1651F03A1620F0B2E03B1661F409C029 +:10E600000BBFF701779007C0C7010F9477FE782EF4 +:10E6100002C0F7017080872D0F940DF22092C60082 +:10E620008091C00086FFFCCF8091C0008064809301 +:10E63000C000872D8052F401EF70F0708F3520F408 +:10E64000E40DF51D708204C0E40DF51D8EE280839B +:10E650000894E11CF11C011D111D0894811C911CE2 +:10E6600090E18916910409F0C2CF80E190E0A0E02A +:10E67000B0E0A80EB91ECA1EDB1E198AC2010F9493 +:10E68000FAF10F94DCF16A94662009F072CF629679 +:10E690000FB6F894DEBF0FBECDBFCF91DF911F91B3 +:10E6A0000F91FF90EF90DF90CF90BF90AF909F9031 +:10E6B0008F907F906F905F904F903F902F90089534 +:10E6C0002F923F924F925F926F927F928F929F9282 +:10E6D000AF92BF92CF92DF92EF92FF920F931F9370 +:10E6E000DF93CF93CDB7DEB7CD53D1400FB6F894BB +:10E6F000DEBF0FBECDBF01E20EBF0FEF0DBF94B75F +:10E70000F894A89514BE80916000886180936000A1 +:10E7100010926000789493FF05C0E0910002F091A0 +:10E7200001021995279A2F9A8091C00082608093E8 +:10E73000C00080E18093C40088E18093C1000000A4 +:10E74000EE24FF24870144E0A42EB12CCC24DD2448 +:10E7500024C0C5010197F1F70894E11CF11C011DCB +:10E76000111D21E2E2162EE4F20620E0020720E06D +:10E77000120718F031E0C32ED12CC801B70127ECE5 +:10E780003BE140E050E00F9441FE611571058105C9 +:10E79000910519F485B1805885B98091C00087FD35 +:10E7A00003C0C114D104A9F2A6014F5F5F4FC25E3E +:10E7B000DE4F59834883CE51D140C25EDE4F8881FF +:10E7C0009981CE51D140019711F00D9410FEC05D9A +:10E7D000DE4F19821882C053D14060E0C15DDE4F28 +:10E7E0001882CF52D14088249924C35DDE4F19820C +:10E7F0001882CD52D140C05EDE4F188219821A8233 +:10E800001B82C052D140CE5CDE4F188219821A8220 +:10E810001B82C253D140EE24FF2487010BBFF701B6 +:10E8200007911691C45CDE4F19830883CC53D14005 +:10E830000D940BFEC25EDE4F28813981CE51D1404E +:10E840002130310509F52091C600C25EDE4F1982E4 +:10E850001882CE51D14022C02F5F3F4F4F4F5F4FA4 +:10E86000213082E138078AE7480780E0580780F0C6 +:10E87000C45CDE4FE881F981CC53D140EF5FFF4F9C +:10E8800019F0EE27FF27099420E030E040E050E047 +:10E890008091C00087FFE0CF2091C600C35DDE4FAE +:10E8A00048815981CD52D1404F5F5F4FC35DDE4FEC +:10E8B00059834883CD52D140213209F063C64A3092 +:10E8C000510508F05FC60894811C911C53E0851621 +:10E8D000910409F059C600E010E018C081E280936D +:10E8E000C6008091C00086FFFCCF8091C00080648C +:10E8F0008093C0002F5F3F4F2931310579F70F9486 +:10E90000DCF10F5F1F4F0530110519F020E030E0FA +:10E91000E5CF10920A0210920B0210920C02109294 +:10E920000D02109206021092070210920802109235 +:10E930000902109202021092030210920402109235 +:10E9400005028FEE90EE60E00F94F5F180E191EE1C +:10E9500060E00F94C2F18091C00087FFFCCF9091DE +:10E96000C600903608F09F759032B8F09093C600BC +:10E970008091C00086FFFCCF8091C00080648093AE +:10E98000C000A0E2A093C6008091C00086FFFCCF2B +:10E990008091C00080648093C000983409F4D7C18E +:10E9A0009934B8F4923409F459C1933458F490333B +:10E9B00019F1903308F4E3C59F33A1F1903409F0C5 +:10E9C000DEC5BDC0953409F470C1963409F0D7C5D1 +:10E9D00098C1923509F42BC2933538F49C3409F46C +:10E9E000F5C1913509F0CBC518C2963509F445C279 +:10E9F000993509F0C4C567C483E792EE62E00F94CD +:10EA0000F5F110920602109207021092080210927D +:10EA1000090210920A0210920B0210920C0210923C +:10EA20000D0213C18FE792EE62E00F94F5F18FEEC5 +:10EA300090EE60E00F94F5F181E291EE60E00F94CA +:10EA4000C2F187EB91EE60E00F94F5F180E391EE77 +:10EA500060E00F94C2F184EE90EE60E00F94F5F167 +:10EA60008FE391EE60E00F94C2F186E090E061E008 +:10EA700070E00F9434F20F94DCF18DE591EE60E0DC +:10EA80000F94C2F189EC91EE60E00F94F5F18EE401 +:10EA900091EE60E00F94C2F183EC91EE60E00F9490 +:10EAA000F5F18CE691EE60E00F94C2F18EE10F94E7 +:10EAB0000DF288E90F940DF281E00F940DF20F949E +:10EAC000DCF18BE791EE60E00F94C2F119E0E0E039 +:10EAD000F0E010935700E4918E2F0F940DF20F94F5 +:10EAE000DCF18AE891EE60E00F94C2F1E3E0F0E03F +:10EAF00010935700E4918E2F0F940DF20F94DCF1D8 +:10EB000089E991EE60E00F94C2F1E2E0F0E0109349 +:10EB10005700E4918E2F0F940DF20F94DCF188EAE8 +:10EB200091EE60E00F94C2F1E1E0F0E01093570045 +:10EB30001491812F0F940DF20F94DCF107CF8BE825 +:10EB400092EE62E00F94F5F18BE492EE60E00F94A8 +:10EB5000F5F10F94DCF100E010E019C0C8016F2D51 +:10EB60000F947FFEFF2031F489E492EE60E00F9471 +:10EB7000C2F10BC0F092C6008091C00086FFFCCFAE +:10EB80008091C00080648093C0000F5F1F4FC80158 +:10EB900081519F41A0E0B0E0ABBFFC01F790BAE229 +:10EBA000FB1621F0E2E000301E07C1F60F94DCF105 +:10EBB0000F94DCF187E592EE60E00F94F5F10F948D +:10EBC000DCF1CC24DD2400E010E01EC0C8010F946D +:10EBD00077FEF82E882331F489E492EE60E00F94FA +:10EBE000C2F10BC08093C6008091C00086FFFCCFAD +:10EBF0008091C00080648093C000FE1419F00894D6 +:10EC0000C11CD11C0F5F1F4FC80181519F41A0E063 +:10EC1000B0E0ABBFFC01E790FAE2EF1621F022E092 +:10EC20000030120799F60F94DCF10F94DCF182E6C4 +:10EC300092EE60E00F94C2F1C60161E070E00F94C3 +:10EC400034F20F94DCF10F94DCF110920202109276 +:10EC50000302109204021092050278CE89E992EE26 +:10EC600062E00F94F5F1279A2F9A16C02F9880E052 +:10EC700090E0E0EDF7E03197F1F7019684369105E9 +:10EC8000C1F72F9A80E090E0E0EDF7E03197F1F7DF +:10EC9000019684369105C1F78091C00087FFE6CFC9 +:10ECA0008091C00087FFFCCF64C485EA92EE62E0E9 +:10ECB0000F94F5F140910202509103026091040219 +:10ECC0007091050281E020E10F9491F2809102029F +:10ECD00090910302A0910402B091050280509F4FD1 +:10ECE000AF4FBF4F8093020290930302A0930402A0 +:10ECF000B093050280509041A040B04008F426CE69 +:10ED0000A4CF83EB92EE62E00F94F5F140910602FE +:10ED100050910702609108027091090280E020E1A1 +:10ED20000F9491F28091060290910702A09108023F +:10ED3000B091090280509F4FAF4FBF4F80930602A2 +:10ED400090930702A0930802B0930902FFCD80ECD4 +:10ED500092EE62E00F94F5F183E792EE60E00F949B +:10ED6000F5F18FE792EE60E00F94F5F18BE892EE0B +:10ED700060E00F94F5F189E992EE60E00F94F5F10F +:10ED800085EA92EE60E00F94F5F183EB92EE60E09D +:10ED90000F94F5F180EC92EE60E00F94F5F187ECC2 +:10EDA00092EE60E00F94F5F188ED92EE60E00F9442 +:10EDB000F5F18FED92EE60E00F94F5F18AEE92EEB0 +:10EDC00060E00F94F5F183E093EEBDCD87EC92EE19 +:10EDD00062E00F94F5F181E40F947BF282E40F94EA +:10EDE0007BF283E40F947BF284E40F947BF285E45E +:10EDF0000F947BF286E40F947BF287E40F947BF20E +:10EE000088E40F947BF28AE40F947BF28BE40F94F6 +:10EE10007BF28CE40F947BF299CD88ED92EE62E068 +:10EE20000F94F5F1772473948824992409C48FED05 +:10EE300092EE62E00F94F5F140910A0250910B02BC +:10EE400060910C0270910D0282E020E10F9491F22A +:10EE500080910A0290910B02A0910C02B0910D02D8 +:10EE600080509F4FAF4FBF4F80930A0290930B0289 +:10EE7000A0930C02B0930D0269CD8AEE92EE62E08F +:10EE80000F94F5F184EE90EE60E00F94F5F18FECC5 +:10EE900091EE60E00F94F5F1662477244301CC5D98 +:10EEA000DE4F19821882C452D140D401C301B695F5 +:10EEB000A79597958795CA5DDE4F88839983AA8326 +:10EEC000BB83C652D140CC5DDE4FA881B981C4520C +:10EED000D1401196CC5DDE4FB983A883C452D14096 +:10EEE000CD0162E070E00F9434F2B0E2B093C6005E +:10EEF0008091C00086FFFCCF8091C0008064809329 +:10EF0000C000EDE2E093C6008091C00086FFFCCF18 +:10EF10008091C00080648093C000F0E2F093C6004E +:10EF20008091C00086FFFCCF8091C00080648093F8 +:10EF3000C000CA5DDE4FE880F9800A811B81C6529D +:10EF4000D140BB27A12F902F8F2D0F940DF2CA5DBA +:10EF5000DE4F8881C652D1400F940DF2B0E2FB2EF5 +:10EF6000F092C6008091C00086FFFCCF8091C00067 +:10EF700080648093C0000DE30093C6008091C000C0 +:10EF800086FFFCCF8091C00080648093C00010E2B7 +:10EF90001093C6008091C00086FFFCCF8091C00016 +:10EFA00080648093C0008BBEF3012791C65DDE4F65 +:10EFB0002883CA52D140A22EBB24CC24DD2408943D +:10EFC000611C711C811C911C8BBEF3018791282E42 +:10EFD0003324442455240894611C711C811C911C09 +:10EFE0008BBEF3013791C55DDE4F3883CB52D140E4 +:10EFF0000894611C711C811C911C8BBEF30147910C +:10F00000C45DDE4F4883CC52D140ADEFEA2EAFEF66 +:10F01000FA2EAFEF0A2FAFEF1A2F6E0C7F1C801E57 +:10F02000911E142D032DF22CEE24EA0CFB1C0C1D5A +:10F030001D1D0F940DF220E22093C6008091C000A8 +:10F0400086FFFCCF8091C00080648093C000C65DC5 +:10F05000DE4F8881CA52D1400F940DF230E23093D6 +:10F06000C6008091C00086FFFCCF8091C000806404 +:10F070008093C000C45DDE4F8881CC52D1400F9494 +:10F080000DF240E24093C6008091C00086FFFCCFA5 +:10F090008091C00080648093C000C55DDE4F888190 +:10F0A000CB52D1400F940DF250E25093C6008091A4 +:10F0B000C00086FFFCCF8091C00080648093C000B8 +:10F0C0008FEFE8168FEFF80680E0080780E018075A +:10F0D00031F484E092EE60E00F94C2F1DFC0D80119 +:10F0E000C7018070907CA070B0708050904CA040A0 +:10F0F000B040D1F52FEF3FE340E050E0E222F322B1 +:10F1000004231523CA5DDE4FA880B980CA80DB8046 +:10F11000C652D140AE0CBF1CC01ED11EAA0CBB1CD7 +:10F12000CC1CDD1C8EE092EE60E00F94C2F1BB2798 +:10F13000A12F902F8F2D0F940DF28E2D0F940DF285 +:10F1400030E23093C6008091C00086FFFCCF8091F2 +:10F15000C00080648093C0004EE34093C60080915D +:10F16000C00086FFFCCF87C08EE09EEFA0E0B0E03D +:10F17000E822F9220A231B239CE0E91694E9F90608 +:10F1800090E0090790E0190709F088C0C45DDE4FE0 +:10F19000A881CC52D140EA2EFF2400E010E0102FCD +:10F1A0000F2DFE2CEE24C55DDE4FB881CB52D14031 +:10F1B000EB0EF11C011D111DD601C501817090706F +:10F1C000A070B070DC0199278827E80EF91E0A1F8D +:10F1D0001B1F20EF30E040E050E0A222B322C42207 +:10F1E000D52241E1AA0CBB1CCC1CDD1C4A95D1F7F1 +:10F1F000EA0CFB1C0C1D1D1D81E090E0A0E0B0E0BE +:10F20000282239224A225B2235E1220C331C441C7D +:10F21000551C3A95D1F7E20CF31C041D151D57013E +:10F220006801AA0CBB1CCC1CDD1C85E192EE60E0E1 +:10F230000F94C2F1C801AA27BB270F940DF2BB2778 +:10F24000A12F902F8F2D0F940DF28E2D0F940DF274 +:10F2500090E29093C6008091C00086FFFCCF809121 +:10F26000C00080648093C000AEE3A093C60080918C +:10F27000C00086FFFCCF8091C00080648093C000F6 +:10F28000C601AA27BB270F940DF2BB27AD2D9C2DDD +:10F290008B2D0F940DF28A2D0F940DF20F94DCF14B +:10F2A000CC5DDE4FE881F981C452D140F99709F471 +:10F2B0004DCBF4E0EF2EF12C012D112D6E0C7F1CA7 +:10F2C000801E911EF2CD83E093EE62E00F94F5F183 +:10F2D0008AE192EE60E00F94C2F18091C00087FF56 +:10F2E000FCCF1091C6001F751093C6008091C0001E +:10F2F00086FFFCCF8091C00080648093C0000F9493 +:10F30000DCF1812F81548A3108F036C1163409F4BA +:10F3100095C0173490F4133409F44EC0143430F40B +:10F320001134F1F0123409F01DC130C0143409F465 +:10F3300059C0153409F016C16BC01A3409F4C4C0A1 +:10F340001B3438F4173409F48FC0183409F00AC19B +:10F35000A1C01B3409F4D2C01C3409F003C1E8C0B9 +:10F360008FEF81B90DC082B1809582B980E090E0C5 +:10F37000E0EDF7E03197F1F70196883C9105C1F790 +:10F380008091C00087FFEFCF12B8EFC08FEF84B934 +:10F390000DC085B1809585B980E090E0E0EDF7E0A3 +:10F3A0003197F1F70196883C9105C1F78091C00033 +:10F3B00087FFEFCF15B8D9C08FEF87B90DC088B1DF +:10F3C000809588B980E090E0E0EDF7E03197F1F7C3 +:10F3D0000196883C9105C1F78091C00087FFEFCF6F +:10F3E00018B8C3C08FEF8AB90DC08BB180958BB9A7 +:10F3F00080E090E0E0EDF7E03197F1F70196883C8E +:10F400009105C1F78091C00087FFEFCF1BB8ADC059 +:10F410008FEF8DB90DC08EB180958EB980E090E0F0 +:10F42000E0EDF7E03197F1F70196883C9105C1F7DF +:10F430008091C00087FFEFCF1EB897C08FEF80BBD1 +:10F440000DC081B3809581BB80E090E0E0EDF7E0F6 +:10F450003197F1F70196883C9105C1F78091C00082 +:10F4600087FFEFCF11BA81C08FEF83BB0DC084B38C +:10F47000809584BB80E090E0E0EDF7E03197F1F714 +:10F480000196883C9105C1F78091C00087FFEFCFBE +:10F4900014BA6BC08FEF809301010FC080910201FD +:10F4A00080958093020180E090E0E0EDF7E03197F5 +:10F4B000F1F70196883C9105C1F78091C00087FF64 +:10F4C000EDCF1092020151C08FEF809304010FC065 +:10F4D0008091050180958093050180E090E0E0ED4A +:10F4E000F7E03197F1F70196883C9105C1F78091DB +:10F4F000C00087FFEDCF1092050137C08FEF8093DA +:10F5000007010FC08091080180958093080180E079 +:10F5100090E0E0EDF7E03197F1F70196883C910536 +:10F52000C1F78091C00087FFEDCF109208011DC088 +:10F530008FEF80930A010FC080910B01809580931B +:10F540000B0180E090E0E0EDF7E03197F1F70196F4 +:10F55000883C9105C1F78091C00087FFEDCF1092E4 +:10F560000B0103C085E292EEEEC98091C00087FFD7 +:10F57000FCCF8091C600EAC988E392EEE4C98CE131 +:10F5800091EEE1C988249924933011F1943028F444 +:10F59000913089F09230B8F408C0953061F195301F +:10F5A000F0F0963009F048C043C02B3109F042C951 +:10F5B00091E06BE13FC96227C15DDE4F2883CF52E6 +:10F5C000D14092E037C9B22FA0E0622793E032C960 +:10F5D000822F90E0A82BB92B622794E02BC92E3004 +:10F5E00009F039C3622795E0C05DDE4F19821882A9 +:10F5F000C053D1401FC9E1E0F0E0EC0FFD1FC05D3A +:10F60000DE4F08811981C053D140E00FF11F2083E4 +:10F610000F5F1F4FC05DDE4F19830883C053D14079 +:10F6200062270A171B0709F005C9D80196E002C92D +:10F63000261709F010C303C0973009F0FBC87724E0 +:10F640009981933109F412C19431C8F4963009F4C8 +:10F65000D8C0973050F4923009F406C1933009F4C1 +:10F660006DC0913009F059C253C0913109F477C08F +:10F67000923108F0BBC0903109F04FC2F5C098310B +:10F6800009F487C0993150F4953109F4EFC09531F0 +:10F6900008F4C6C1963109F040C2C2C19A3109F4DA +:10F6A0006CC09A3108F491C09B3109F45BC09D3164 +:10F6B00009F033C29D81903359F48F81882311F46E +:10F6C0009EE11CC0813011F091E018C098E916C08D +:10F6D000892F807591F0903539F4E0E0F0E089E011 +:10F6E0008093570094910AC0983539F4E3E0F0E034 +:10F6F00089E080935700949101C090E01A821B82A8 +:10F700008D818C831D829E831F8227E030E009C299 +:10F710001A8288E08B8381E48C8386E58D8382E581 +:10F720008E8389E48F8383E5888780E589878FE5E9 +:10F730008A8782E38B872BE030E0F3C18A818139AD +:10F7400041F0823941F0803911F48FE005C080E04A +:10F7500003C082E001C08AE01A828B8344C0772410 +:10F76000739482C08D81882311F48EE12CC0813086 +:10F7700011F081E028C088E926C01A82E1E0F0E0BB +:10F7800089E08093570084918B831C8224E030E0D1 +:10F79000C8C18B81803589F48C81883039F4E2E0EE +:10F7A000F0E089E08093570084910DC0E0E0F0E044 +:10F7B00089E080935700849106C0E3E0F0E089E09F +:10F7C0008093570084911A82DFCF8D81836C99E0FA +:10F7D000E1E0F0E0082E90935700E89507B600FCB2 +:10F7E000FDCF1A821B8223E030E09BC180EC8A832C +:10F7F000CE5CDE4F188219821A821B82C253D1401E +:10F800008EC18A8190E0A0E0B0E0582F44273327D2 +:10F8100022278B8190E0A0E0B0E0DC0199278827C7 +:10F82000282B392B4A2B5B2B8D8190E0A0E0B0E098 +:10F83000282B392B4A2B5B2B8C8190E0A0E0B0E089 +:10F84000BA2FA92F982F8827282B392B4A2B5B2BCF +:10F85000220F331F441F551FC05EDE4F288339839C +:10F860004A835B83C052D1401A8259C13A81C95C34 +:10F87000DE4F3883C753D140CA5CDE4F1882C6536F +:10F88000D1408B81C82EDD24CA5CDE4F488159816E +:10F89000C653D140C42AD52A933109F082C0CE5C28 +:10F8A000DE4F88819981AA81BB81C253D1408050AB +:10F8B000904CA340B04030F583E0CE5CDE4FE88052 +:10F8C000F9800A811B81C253D140F70100935B008C +:10F8D00080935700E89507B600FCFDCFCE5CDE4F65 +:10F8E000088119812A813B81C253D14000501F4FAA +:10F8F0002F4F3F4FCE5CDE4F088319832A833B8313 +:10F90000C253D140C05EDE4F488159816A817B81FC +:10F91000C052D140DE011B9631E08C9111962C91A2 +:10F9200011971296C75CDE4F2883C953D140C85C3B +:10F93000DE4F1882C853D14090E0C85CDE4FE881AA +:10F94000F981C853D1408E2B9F2B0C01FA01609393 +:10F950005B0030935700E89511244E5F5F4F6F4F67 +:10F960007F4F0EEFE02E0FEFF02ECE0CDF1CC114F8 +:10F97000D10499F685E0C05EDE4F088119812A81A5 +:10F980003B81C052D140F80120935B008093570027 +:10F99000E89507B600FCFDCF81E180935700E8951C +:10F9A00035C0C05EDE4F88819981AA81BB81C0527B +:10F9B000D140B695A795979587957C018601ABE0D8 +:10F9C000AA2EB12CAC0EBD1E0BC0D5016D915D01F0 +:10F9D000C7010F947FFE0894E11CF11C01501040F8 +:10F9E0000115110591F7A60160E070E0440F551F65 +:10F9F000661F771FC05EDE4FE880F9800A811B8199 +:10FA0000C052D1404E0D5F1D601F711F1A82C05E33 +:10FA1000DE4F488359836A837B83C052D1407FC0C5 +:10FA2000FA80C55CDE4FF882CB53D140C65CDE4F16 +:10FA30001882CA53D1408B81C82EDD24C65CDE4FAC +:10FA400008811981CA53D140C02AD12A1A828981DA +:10FA5000BE016D5F7F4F843121F59601C05EDE4FA0 +:10FA6000E880F9800A811B81C052D1400BBFF701A9 +:10FA700087919691DB018C9311969C936E5F7F4FDB +:10FA8000D801C7010296A11DB11DC05EDE4F88835B +:10FA90009983AA83BB83C052D14022503040F1F6F3 +:10FAA00036C0C05EDE4F288139814A815B81C052F9 +:10FAB000D1400894C108D108760100E010E0089414 +:10FAC000C11CD11C0894E11CF11C011D111DE20E8A +:10FAD000F31E041F151F21BDBB27A52F942F832FB5 +:10FAE00082BD2F5F3F4F4F4F5F4FF89A80B5DB01CC +:10FAF0008D93BD012E153F054007510761F7C05E8C +:10FB0000DE4F288339834A835B83C052D1409601FC +:10FB10002D5F3F4FFB01108204C080EC8A8322E0FE +:10FB200030E08BE18093C6008091C00086FFFCCF5F +:10FB30008091C00080648093C000C15DDE4FF88179 +:10FB4000CF52D140F093C6008091C00086FFFCCF19 +:10FB50008091C00080648093C000432F3093C60022 +:10FB60008091C00086FFFCCF8091C00080648093AC +:10FB7000C000922F2093C6008091C00086FFFCCF6A +:10FB80008091C00080648093C0008EE08093C600A6 +:10FB90008091C00086FFFCCF8091C000806480937C +:10FBA000C00065E1C15DDE4FE880CF52D1406E25D7 +:10FBB00069276427FE01319610C090819093C6009A +:10FBC0008091C00086FFFCCF31968091C000806498 +:10FBD0008093C0006927215030402115310569F715 +:10FBE0006093C6008091C00086FFFCCF8091C0006A +:10FBF00080648093C00085B1805885B9772081F4F6 +:10FC0000C15DDE4F0881CF52D1400F5FC15DDE4F35 +:10FC10000883CF52D14090E0A0E0B0E00D941AF4F8 +:10FC200027982F9880E090E020ED37E0F901319798 +:10FC3000F1F7019684369105C9F700008091C00064 +:10FC40008D7F8093C00081E180935700E895EE2777 +:10FC5000FF270994FFCF90E00D941AF497FB092E2B +:10FC600007260AD077FD04D02ED006D000201AF443 +:10FC7000709561957F4F0895F6F7909581959F4F08 +:10FC80000895A1E21A2EAA1BBB1BFD010DC0AA1FDD +:10FC9000BB1FEE1FFF1FA217B307E407F50720F0F5 +:10FCA000A21BB30BE40BF50B661F771F881F991F70 +:10FCB0001A9469F760957095809590959B01AC01B9 +:10FCC000BD01CF010895AA1BBB1B51E107C0AA1FAC +:10FCD000BB1FA617B70710F0A61BB70B881F991FED +:10FCE0005A95A9F780959095BC01CD010895F99991 +:10FCF000FECF92BD81BDF89A992780B50895262F31 +:10FD0000F999FECF1FBA92BD81BD20BD0FB6F89400 +:0EFD1000FA9AF99A0FBE01960895F894FFCF63 +:040000033000E000E9 +:00000001FF From 43771ebebf46b206841e640d027141cd2667ce9c Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 16 Nov 2015 14:15:03 +0100 Subject: [PATCH 42/85] Releasing 1.2.1 Signed-off-by: Federico Fissore --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index dd92cc53..7be97117 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,7 @@ import ( "syscall" ) -const VERSION = "1.2.0" +const VERSION = "1.2.1" const FLAG_ACTION_COMPILE = "compile" const FLAG_ACTION_PREPROCESS = "preprocess" From 3ac00843e2eb7f8780028ad072c7186fd96fc40e Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 17 Nov 2015 10:05:16 +0100 Subject: [PATCH 43/85] Added .ino file to a subfolder to be sure SketchLoader doesn't load it. See #65 Signed-off-by: Federico Fissore --- src/arduino.cc/builder/test/sketch_loader_test.go | 2 ++ .../test/sketch_with_subfolders/subfolder/dont_load_me.ino | 1 + 2 files changed, 3 insertions(+) create mode 100644 src/arduino.cc/builder/test/sketch_with_subfolders/subfolder/dont_load_me.ino diff --git a/src/arduino.cc/builder/test/sketch_loader_test.go b/src/arduino.cc/builder/test/sketch_loader_test.go index 0b964029..219fcc9b 100644 --- a/src/arduino.cc/builder/test/sketch_loader_test.go +++ b/src/arduino.cc/builder/test/sketch_loader_test.go @@ -136,6 +136,8 @@ func TestLoadSketchFromFolder(t *testing.T) { require.True(t, strings.Index(sketch.MainFile.Name, "sketch_with_subfolders.ino") != -1) + require.Equal(t, 0, len(sketch.OtherSketchFiles)) + require.Equal(t, 2, len(sketch.AdditionalFiles)) require.True(t, strings.Index(sketch.AdditionalFiles[0].Name, "other.cpp") != -1) require.True(t, strings.Index(sketch.AdditionalFiles[1].Name, "other.h") != -1) diff --git a/src/arduino.cc/builder/test/sketch_with_subfolders/subfolder/dont_load_me.ino b/src/arduino.cc/builder/test/sketch_with_subfolders/subfolder/dont_load_me.ino new file mode 100644 index 00000000..1d32675e --- /dev/null +++ b/src/arduino.cc/builder/test/sketch_with_subfolders/subfolder/dont_load_me.ino @@ -0,0 +1 @@ +#error "Whattya looking at?" From 487837daad508e2b053c39738c75dff7e36e2239 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 17 Nov 2015 16:20:08 +0100 Subject: [PATCH 44/85] If no libs are imported, PrintUsedLibrariesIfVerbose would fail. Fixed Signed-off-by: Federico Fissore --- src/arduino.cc/builder/print_used_libraries_if_verbose.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/arduino.cc/builder/print_used_libraries_if_verbose.go b/src/arduino.cc/builder/print_used_libraries_if_verbose.go index 20c96965..cc5ffd03 100644 --- a/src/arduino.cc/builder/print_used_libraries_if_verbose.go +++ b/src/arduino.cc/builder/print_used_libraries_if_verbose.go @@ -33,6 +33,7 @@ import ( "arduino.cc/builder/constants" "arduino.cc/builder/i18n" "arduino.cc/builder/types" + "arduino.cc/builder/utils" "time" ) @@ -42,7 +43,7 @@ func (s *PrintUsedLibrariesIfVerbose) Run(context map[string]interface{}) error verbose := context[constants.CTX_VERBOSE].(bool) logger := context[constants.CTX_LOGGER].(i18n.Logger) - if !verbose { + if !verbose || !utils.MapHas(context, constants.CTX_IMPORTED_LIBRARIES) { return nil } From c347f64dfe3fcc33e5df2a6adbf45f4cd2c0d323 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 17 Nov 2015 16:21:16 +0100 Subject: [PATCH 45/85] Moved some library consistency checks into FailIfImportedLibraryIsWrong, which loops on imported libs only (not on all libs). Fixes #62 Signed-off-by: Federico Fissore --- .../builder/container_find_includes.go | 5 ++ .../fail_if_imported_library_is_wrong.go | 70 +++++++++++++++++++ src/arduino.cc/builder/libraries_loader.go | 13 +--- .../libraries/wronglib/library.properties | 8 +++ .../test/libraries/wronglib/src/.gitkeep | 0 .../test/libraries/wronglib/utility/.gitkeep | 0 .../builder/test/libraries_loader_test.go | 4 +- src/arduino.cc/builder/types/types.go | 1 + 8 files changed, 87 insertions(+), 14 deletions(-) create mode 100644 src/arduino.cc/builder/fail_if_imported_library_is_wrong.go create mode 100644 src/arduino.cc/builder/test/libraries/wronglib/library.properties create mode 100644 src/arduino.cc/builder/test/libraries/wronglib/src/.gitkeep create mode 100644 src/arduino.cc/builder/test/libraries/wronglib/utility/.gitkeep diff --git a/src/arduino.cc/builder/container_find_includes.go b/src/arduino.cc/builder/container_find_includes.go index d015651f..9341248c 100644 --- a/src/arduino.cc/builder/container_find_includes.go +++ b/src/arduino.cc/builder/container_find_includes.go @@ -82,6 +82,11 @@ func (s *ContainerFindIncludes) Run(context map[string]interface{}) error { } } + err = runCommand(context, &FailIfImportedLibraryIsWrong{}) + if err != nil { + return utils.WrapError(err) + } + return nil } diff --git a/src/arduino.cc/builder/fail_if_imported_library_is_wrong.go b/src/arduino.cc/builder/fail_if_imported_library_is_wrong.go new file mode 100644 index 00000000..ab261996 --- /dev/null +++ b/src/arduino.cc/builder/fail_if_imported_library_is_wrong.go @@ -0,0 +1,70 @@ +/* + * This file is part of Arduino Builder. + * + * Arduino Builder is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As a special exception, you may use this file as part of a free software + * library without restriction. Specifically, if other files instantiate + * templates or use macros or inline functions from this file, or you compile + * this file and link it with other files to produce an executable, this + * file does not by itself cause the resulting executable to be covered by + * the GNU General Public License. This exception does not however + * invalidate any other reasons why the executable file might be covered by + * the GNU General Public License. + * + * Copyright 2015 Arduino LLC (http://www.arduino.cc/) + */ + +package builder + +import ( + "arduino.cc/builder/constants" + "arduino.cc/builder/i18n" + "arduino.cc/builder/types" + "arduino.cc/builder/utils" + "os" + "path/filepath" +) + +type FailIfImportedLibraryIsWrong struct{} + +func (s *FailIfImportedLibraryIsWrong) Run(context map[string]interface{}) error { + if !utils.MapHas(context, constants.CTX_IMPORTED_LIBRARIES) { + return nil + } + + logger := context[constants.CTX_LOGGER].(i18n.Logger) + importedLibraries := context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library) + + for _, library := range importedLibraries { + if !library.IsLegacy { + if stat, err := os.Stat(filepath.Join(library.Folder, constants.LIBRARY_FOLDER_ARCH)); err == nil && stat.IsDir() { + return utils.ErrorfWithLogger(logger, constants.MSG_ARCH_FOLDER_NOT_SUPPORTED) + } + for _, propName := range LIBRARY_MANDATORY_PROPERTIES { + if _, ok := library.Properties[propName]; !ok { + return utils.ErrorfWithLogger(logger, constants.MSG_PROP_IN_LIBRARY, propName, library.Folder) + } + } + if library.Layout == types.LIBRARY_RECURSIVE { + if stat, err := os.Stat(filepath.Join(library.Folder, constants.LIBRARY_FOLDER_UTILITY)); err == nil && stat.IsDir() { + return utils.ErrorfWithLogger(logger, constants.MSG_LIBRARY_CAN_USE_SRC_AND_UTILITY_FOLDERS, library.Folder) + } + } + } + } + + return nil +} diff --git a/src/arduino.cc/builder/libraries_loader.go b/src/arduino.cc/builder/libraries_loader.go index 60c31d74..d59a473e 100644 --- a/src/arduino.cc/builder/libraries_loader.go +++ b/src/arduino.cc/builder/libraries_loader.go @@ -129,15 +129,6 @@ func makeNewLibrary(libraryFolder string, debugLevel int, logger i18n.Logger) (* properties[constants.LIBRARY_MAINTAINER] = properties[constants.LIBRARY_EMAIL] } - if stat, err := os.Stat(filepath.Join(libraryFolder, constants.LIBRARY_FOLDER_ARCH)); err == nil && stat.IsDir() { - return nil, utils.ErrorfWithLogger(logger, constants.MSG_ARCH_FOLDER_NOT_SUPPORTED) - } - - for _, propName := range LIBRARY_MANDATORY_PROPERTIES { - if _, ok := properties[propName]; !ok { - return nil, utils.ErrorfWithLogger(logger, constants.MSG_PROP_IN_LIBRARY, propName, libraryFolder) - } - } for _, propName := range LIBRARY_NOT_SO_MANDATORY_PROPERTIES { if properties[propName] == constants.EMPTY_STRING { properties[propName] = "-" @@ -148,9 +139,6 @@ func makeNewLibrary(libraryFolder string, debugLevel int, logger i18n.Logger) (* if stat, err := os.Stat(filepath.Join(libraryFolder, constants.LIBRARY_FOLDER_SRC)); err == nil && stat.IsDir() { library.Layout = types.LIBRARY_RECURSIVE library.SrcFolder = filepath.Join(libraryFolder, constants.LIBRARY_FOLDER_SRC) - if stat, err := os.Stat(filepath.Join(libraryFolder, constants.LIBRARY_FOLDER_UTILITY)); err == nil && stat.IsDir() { - return nil, utils.ErrorfWithLogger(logger, constants.MSG_LIBRARY_CAN_USE_SRC_AND_UTILITY_FOLDERS, libraryFolder) - } } else { library.Layout = types.LIBRARY_FLAT library.SrcFolder = libraryFolder @@ -199,6 +187,7 @@ func makeNewLibrary(libraryFolder string, debugLevel int, logger i18n.Logger) (* library.URL = strings.TrimSpace(properties[constants.LIBRARY_URL]) library.IsLegacy = false library.DotALinkage = strings.TrimSpace(properties[constants.LIBRARY_DOT_A_LINKAGE]) == "true" + library.Properties = properties return library, nil } diff --git a/src/arduino.cc/builder/test/libraries/wronglib/library.properties b/src/arduino.cc/builder/test/libraries/wronglib/library.properties new file mode 100644 index 00000000..26c53df4 --- /dev/null +++ b/src/arduino.cc/builder/test/libraries/wronglib/library.properties @@ -0,0 +1,8 @@ +name=wronglib +version=1.0 +author=Arduino +maintainer=Arduino +sentence=sentence +paragraph=paragraph +url=url +architectures=* diff --git a/src/arduino.cc/builder/test/libraries/wronglib/src/.gitkeep b/src/arduino.cc/builder/test/libraries/wronglib/src/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/src/arduino.cc/builder/test/libraries/wronglib/utility/.gitkeep b/src/arduino.cc/builder/test/libraries/wronglib/utility/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/src/arduino.cc/builder/test/libraries_loader_test.go b/src/arduino.cc/builder/test/libraries_loader_test.go index bd4ba608..71b7e04a 100644 --- a/src/arduino.cc/builder/test/libraries_loader_test.go +++ b/src/arduino.cc/builder/test/libraries_loader_test.go @@ -69,7 +69,7 @@ func TestLoadLibrariesAVR(t *testing.T) { require.Equal(t, Abs(t, filepath.Join("libraries")), librariesFolders[2]) libraries := context[constants.CTX_LIBRARIES].([]*types.Library) - require.Equal(t, 17, len(libraries)) + require.Equal(t, 18, len(libraries)) sort.Sort(ByLibraryName(libraries)) @@ -175,7 +175,7 @@ func TestLoadLibrariesSAM(t *testing.T) { require.Equal(t, Abs(t, filepath.Join("libraries")), librariesFolders[2]) libraries := context[constants.CTX_LIBRARIES].([]*types.Library) - require.Equal(t, 15, len(libraries)) + require.Equal(t, 16, len(libraries)) sort.Sort(ByLibraryName(libraries)) diff --git a/src/arduino.cc/builder/types/types.go b/src/arduino.cc/builder/types/types.go index c966f2a6..7745e7df 100644 --- a/src/arduino.cc/builder/types/types.go +++ b/src/arduino.cc/builder/types/types.go @@ -112,6 +112,7 @@ type Library struct { URL string Category string License string + Properties map[string]string } func (library *Library) String() string { From 33af6401fcd0af72eb47c5268ea17251f24204b6 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 17 Nov 2015 16:26:31 +0100 Subject: [PATCH 46/85] Releasing 1.2.2 Signed-off-by: Federico Fissore --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 7be97117..cfab4918 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,7 @@ import ( "syscall" ) -const VERSION = "1.2.1" +const VERSION = "1.2.2" const FLAG_ACTION_COMPILE = "compile" const FLAG_ACTION_PREPROCESS = "preprocess" From afe614062abefa086ee7dc88fe520eb2f42678a4 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Wed, 18 Nov 2015 09:46:30 +0100 Subject: [PATCH 47/85] Fixed typo Signed-off-by: Federico Fissore --- src/arduino.cc/builder/constants/constants.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arduino.cc/builder/constants/constants.go b/src/arduino.cc/builder/constants/constants.go index f183aecb..69539bc5 100644 --- a/src/arduino.cc/builder/constants/constants.go +++ b/src/arduino.cc/builder/constants/constants.go @@ -210,7 +210,7 @@ const MSG_LIB_LEGACY = "(legacy)" const MSG_LIBRARIES_MULTIPLE_LIBS_FOUND_FOR = "Multiple libraries were found for \"{0}\"" const MSG_LIBRARIES_NOT_USED = " Not used: {0}" const MSG_LIBRARIES_USED = " Used: {0}" -const MSG_LIBRARY_CAN_USE_SRC_AND_UTILITY_FOLDERS = "Library can't use both 'src' and 'utility' folders. Double ckeck {0}" +const MSG_LIBRARY_CAN_USE_SRC_AND_UTILITY_FOLDERS = "Library can't use both 'src' and 'utility' folders. Double check {0}" const MSG_LIBRARY_INCOMPATIBLE_ARCH = "WARNING: library {0} claims to run on {1} architecture(s) and may be incompatible with your current board which runs on {2} architecture(s)." const MSG_LOOKING_FOR_RECIPES = "Looking for recipes like {0}*{1}" const MSG_MISSING_BUILD_BOARD = "Board {0}:{1}:{2} doesn''t define a ''build.board'' preference. Auto-set to: {3}" From b074e0ee1d1544b3e1b8de3cd52675305e61875c Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Wed, 18 Nov 2015 09:50:51 +0100 Subject: [PATCH 48/85] Releasing 1.2.3 Signed-off-by: Federico Fissore --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index cfab4918..21ac5f2a 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,7 @@ import ( "syscall" ) -const VERSION = "1.2.2" +const VERSION = "1.2.3" const FLAG_ACTION_COMPILE = "compile" const FLAG_ACTION_PREPROCESS = "preprocess" From fe14f457b446b45605f96ffafdf53eef57ff6ce9 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Thu, 19 Nov 2015 11:04:23 +0100 Subject: [PATCH 49/85] Removed CTagsField from CTagsParser: hard coded ctx key to CTX_CTAGS_OF_PREPROC_SOURCE Signed-off-by: Federico Fissore --- .../builder/container_add_prototypes.go | 2 +- src/arduino.cc/builder/ctags_parser.go | 6 +- .../builder/test/ctags_parser_test.go | 56 +++++++++---------- .../builder/test/ctags_to_prototypes_test.go | 42 +++++++++----- src/arduino.cc/builder/test/helper.go | 10 ++++ 5 files changed, 69 insertions(+), 47 deletions(-) diff --git a/src/arduino.cc/builder/container_add_prototypes.go b/src/arduino.cc/builder/container_add_prototypes.go index 48aa04a1..427a3056 100644 --- a/src/arduino.cc/builder/container_add_prototypes.go +++ b/src/arduino.cc/builder/container_add_prototypes.go @@ -43,7 +43,7 @@ func (s *ContainerAddPrototypes) Run(context map[string]interface{}) error { &ReadFileAndStoreInContext{TargetField: constants.CTX_GCC_MINUS_E_SOURCE}, &CTagsTargetFileSaver{SourceField: constants.CTX_GCC_MINUS_E_SOURCE, TargetFileName: constants.FILE_CTAGS_TARGET_FOR_GCC_MINUS_E}, &CTagsRunner{}, - &CTagsParser{CTagsField: constants.CTX_CTAGS_OF_PREPROC_SOURCE}, + &CTagsParser{}, &CollectCTagsFromSketchFiles{}, &CTagsToPrototypes{}, &PrototypesAdder{}, diff --git a/src/arduino.cc/builder/ctags_parser.go b/src/arduino.cc/builder/ctags_parser.go index 3113c81b..2bd3fd30 100644 --- a/src/arduino.cc/builder/ctags_parser.go +++ b/src/arduino.cc/builder/ctags_parser.go @@ -59,9 +59,7 @@ var FIELDS = map[string]bool{"kind": true, "line": true, "typeref": true, "signa var KNOWN_TAG_KINDS = map[string]bool{"prototype": true, "function": true} var FIELDS_MARKING_UNHANDLED_TAGS = []string{FIELD_CLASS, FIELD_STRUCT, FIELD_NAMESPACE} -type CTagsParser struct { - CTagsField string -} +type CTagsParser struct{} func (s *CTagsParser) Run(context map[string]interface{}) error { rows := strings.Split(context[constants.CTX_CTAGS_OUTPUT].(string), "\n") @@ -81,7 +79,7 @@ func (s *CTagsParser) Run(context map[string]interface{}) error { removeDuplicate(tags) skipTagsWhere(tags, prototypeAndCodeDontMatch) - context[s.CTagsField] = tags + context[constants.CTX_CTAGS_OF_PREPROC_SOURCE] = tags return nil } diff --git a/src/arduino.cc/builder/test/ctags_parser_test.go b/src/arduino.cc/builder/test/ctags_parser_test.go index bdc9ce84..80a18fa4 100644 --- a/src/arduino.cc/builder/test/ctags_parser_test.go +++ b/src/arduino.cc/builder/test/ctags_parser_test.go @@ -46,10 +46,10 @@ func TestCTagsParserShouldListPrototypes(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} + ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) require.Equal(t, 8, len(ctags)) idx := 0 @@ -94,10 +94,10 @@ func TestCTagsParserShouldListTemplates(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} + ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) require.Equal(t, 3, len(ctags)) idx := 0 @@ -120,10 +120,10 @@ func TestCTagsParserShouldListTemplates2(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} + ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) require.Equal(t, 4, len(ctags)) idx := 0 @@ -150,10 +150,10 @@ func TestCTagsParserShouldDealWithClasses(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} + ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) require.Equal(t, 2, len(ctags)) idx := 0 @@ -172,10 +172,10 @@ func TestCTagsParserShouldDealWithStructs(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} + ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) require.Equal(t, 5, len(ctags)) idx := 0 @@ -204,10 +204,10 @@ func TestCTagsParserShouldDealWithMacros(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} + ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) require.Equal(t, 8, len(ctags)) idx := 0 @@ -244,10 +244,10 @@ func TestCTagsParserShouldDealFunctionWithDifferentSignatures(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} + ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) require.Equal(t, 3, len(ctags)) idx := 0 @@ -269,10 +269,10 @@ func TestCTagsParserClassMembersAreFilteredOut(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} + ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) require.Equal(t, 5, len(ctags)) idx := 0 @@ -303,10 +303,10 @@ func TestCTagsParserStructWithFunctions(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} + ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) require.Equal(t, 8, len(ctags)) idx := 0 @@ -345,10 +345,10 @@ func TestCTagsParserDefaultArguments(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} + ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) require.Equal(t, 3, len(ctags)) idx := 0 @@ -371,10 +371,10 @@ func TestCTagsParserNamespace(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} + ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) require.Equal(t, 3, len(ctags)) idx := 0 @@ -397,10 +397,10 @@ func TestCTagsParserStatic(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} + ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) require.Equal(t, 3, len(ctags)) idx := 0 @@ -422,10 +422,10 @@ func TestCTagsParserFunctionPointer(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} + ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) require.Equal(t, 4, len(ctags)) idx := 0 @@ -450,10 +450,10 @@ func TestCTagsParserFunctionPointers(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) - ctagsParser := builder.CTagsParser{CTagsField: constants.CTX_CTAGS_OF_SOURCE} + ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) require.Equal(t, 5, len(ctags)) idx := 0 diff --git a/src/arduino.cc/builder/test/ctags_to_prototypes_test.go b/src/arduino.cc/builder/test/ctags_to_prototypes_test.go index b49c0fcb..c0a4ed6c 100644 --- a/src/arduino.cc/builder/test/ctags_to_prototypes_test.go +++ b/src/arduino.cc/builder/test/ctags_to_prototypes_test.go @@ -48,7 +48,8 @@ func TestCTagsToPrototypesShouldListPrototypes(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) commands := []types.Command{ - &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsParser{}, + &CopyContextKeys{From: constants.CTX_CTAGS_OF_PREPROC_SOURCE, To: constants.CTX_COLLECTED_CTAGS}, &builder.CTagsToPrototypes{}, } @@ -80,7 +81,8 @@ func TestCTagsToPrototypesShouldListTemplates(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) commands := []types.Command{ - &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsParser{}, + &CopyContextKeys{From: constants.CTX_CTAGS_OF_PREPROC_SOURCE, To: constants.CTX_COLLECTED_CTAGS}, &builder.CTagsToPrototypes{}, } @@ -110,7 +112,8 @@ func TestCTagsToPrototypesShouldListTemplates2(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) commands := []types.Command{ - &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsParser{}, + &CopyContextKeys{From: constants.CTX_CTAGS_OF_PREPROC_SOURCE, To: constants.CTX_COLLECTED_CTAGS}, &builder.CTagsToPrototypes{}, } @@ -141,7 +144,8 @@ func TestCTagsToPrototypesShouldDealWithClasses(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) commands := []types.Command{ - &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsParser{}, + &CopyContextKeys{From: constants.CTX_CTAGS_OF_PREPROC_SOURCE, To: constants.CTX_COLLECTED_CTAGS}, &builder.CTagsToPrototypes{}, } @@ -167,7 +171,8 @@ func TestCTagsToPrototypesShouldDealWithStructs(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) commands := []types.Command{ - &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsParser{}, + &CopyContextKeys{From: constants.CTX_CTAGS_OF_PREPROC_SOURCE, To: constants.CTX_COLLECTED_CTAGS}, &builder.CTagsToPrototypes{}, } @@ -197,7 +202,8 @@ func TestCTagsToPrototypesShouldDealWithMacros(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) commands := []types.Command{ - &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsParser{}, + &CopyContextKeys{From: constants.CTX_CTAGS_OF_PREPROC_SOURCE, To: constants.CTX_COLLECTED_CTAGS}, &builder.CTagsToPrototypes{}, } @@ -229,7 +235,8 @@ func TestCTagsToPrototypesShouldDealFunctionWithDifferentSignatures(t *testing.T context[constants.CTX_CTAGS_OUTPUT] = string(bytes) commands := []types.Command{ - &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsParser{}, + &CopyContextKeys{From: constants.CTX_CTAGS_OF_PREPROC_SOURCE, To: constants.CTX_COLLECTED_CTAGS}, &builder.CTagsToPrototypes{}, } @@ -257,7 +264,8 @@ func TestCTagsToPrototypesClassMembersAreFilteredOut(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) commands := []types.Command{ - &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsParser{}, + &CopyContextKeys{From: constants.CTX_CTAGS_OF_PREPROC_SOURCE, To: constants.CTX_COLLECTED_CTAGS}, &builder.CTagsToPrototypes{}, } @@ -286,7 +294,8 @@ func TestCTagsToPrototypesStructWithFunctions(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) commands := []types.Command{ - &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsParser{}, + &CopyContextKeys{From: constants.CTX_CTAGS_OF_PREPROC_SOURCE, To: constants.CTX_COLLECTED_CTAGS}, &builder.CTagsToPrototypes{}, } @@ -315,7 +324,8 @@ func TestCTagsToPrototypesDefaultArguments(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) commands := []types.Command{ - &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsParser{}, + &CopyContextKeys{From: constants.CTX_CTAGS_OF_PREPROC_SOURCE, To: constants.CTX_COLLECTED_CTAGS}, &builder.CTagsToPrototypes{}, } @@ -344,7 +354,8 @@ func TestCTagsToPrototypesNamespace(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) commands := []types.Command{ - &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsParser{}, + &CopyContextKeys{From: constants.CTX_CTAGS_OF_PREPROC_SOURCE, To: constants.CTX_COLLECTED_CTAGS}, &builder.CTagsToPrototypes{}, } @@ -373,7 +384,8 @@ func TestCTagsToPrototypesStatic(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) commands := []types.Command{ - &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsParser{}, + &CopyContextKeys{From: constants.CTX_CTAGS_OF_PREPROC_SOURCE, To: constants.CTX_COLLECTED_CTAGS}, &builder.CTagsToPrototypes{}, } @@ -404,7 +416,8 @@ func TestCTagsToPrototypesFunctionPointer(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) commands := []types.Command{ - &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsParser{}, + &CopyContextKeys{From: constants.CTX_CTAGS_OF_PREPROC_SOURCE, To: constants.CTX_COLLECTED_CTAGS}, &builder.CTagsToPrototypes{}, } @@ -434,7 +447,8 @@ func TestCTagsToPrototypesFunctionPointers(t *testing.T) { context[constants.CTX_CTAGS_OUTPUT] = string(bytes) commands := []types.Command{ - &builder.CTagsParser{CTagsField: constants.CTX_COLLECTED_CTAGS}, + &builder.CTagsParser{}, + &CopyContextKeys{From: constants.CTX_CTAGS_OF_PREPROC_SOURCE, To: constants.CTX_COLLECTED_CTAGS}, &builder.CTagsToPrototypes{}, } diff --git a/src/arduino.cc/builder/test/helper.go b/src/arduino.cc/builder/test/helper.go index 50560b27..0bdffa51 100644 --- a/src/arduino.cc/builder/test/helper.go +++ b/src/arduino.cc/builder/test/helper.go @@ -95,3 +95,13 @@ func (s ByLibraryName) Swap(i, j int) { func (s ByLibraryName) Less(i, j int) bool { return s[i].Name < s[j].Name } + +type CopyContextKeys struct { + From string + To string +} + +func (s *CopyContextKeys) Run(context map[string]interface{}) error { + context[s.To] = context[s.From] + return nil +} From e755138a8ea5a4846c8e35d709647ac0d841a87b Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Thu, 19 Nov 2015 11:07:29 +0100 Subject: [PATCH 50/85] Added debug logging to CTagsParser, turned on only when debug level >= 10 Signed-off-by: Federico Fissore --- src/arduino.cc/builder/constants/constants.go | 3 ++ src/arduino.cc/builder/ctags_parser.go | 43 ++++++++++--------- src/arduino.cc/builder/ctags_to_prototypes.go | 3 +- .../builder/test/prototypes_adder_test.go | 18 ++++++++ src/arduino.cc/builder/utils/utils.go | 9 ++++ 5 files changed, 54 insertions(+), 22 deletions(-) diff --git a/src/arduino.cc/builder/constants/constants.go b/src/arduino.cc/builder/constants/constants.go index 69539bc5..759626d0 100644 --- a/src/arduino.cc/builder/constants/constants.go +++ b/src/arduino.cc/builder/constants/constants.go @@ -225,6 +225,9 @@ const MSG_RUNNING_COMMAND = "Running: {0}" const MSG_RUNNING_RECIPE = "Running recipe: {0}" const MSG_SETTING_BUILD_PATH = "Setting build path to {0}" const MSG_SKETCH_CANT_BE_IN_BUILDPATH = "Sketch cannot be located in build path. Please specify a different build path" +const MSG_SKIPPING_TAG_ALREADY_DEFINED = "Skipping tag {0} because prototype is already defined" +const MSG_SKIPPING_TAG_BECAUSE_HAS_FIELD = "Skipping tag {0} because it has field {0}" +const MSG_SKIPPING_TAG_WITH_REASON = "Skipping tag {0}. Reason: {1}" const MSG_UNHANDLED_TYPE_IN_CONTEXT = "Unhandled type {0} in context key {1}" const MSG_UNKNOWN_SKETCH_EXT = "Unknown sketch file extension: {0}" const MSG_USING_LIBRARY_AT_VERSION = "Using library {0} at version {1} in folder: {2} {3}" diff --git a/src/arduino.cc/builder/ctags_parser.go b/src/arduino.cc/builder/ctags_parser.go index 2bd3fd30..9c086165 100644 --- a/src/arduino.cc/builder/ctags_parser.go +++ b/src/arduino.cc/builder/ctags_parser.go @@ -31,6 +31,10 @@ package builder import ( "arduino.cc/builder/constants" + "arduino.cc/builder/utils" + "os" + "reflect" + "runtime" "strconv" "strings" ) @@ -71,13 +75,13 @@ func (s *CTagsParser) Run(context map[string]interface{}) error { tags = append(tags, parseTag(row)) } - skipTagsWhere(tags, tagIsUnknown) - skipTagsWithField(tags, FIELDS_MARKING_UNHANDLED_TAGS) - skipTagsWhere(tags, signatureContainsDefaultArg) + skipTagsWhere(tags, tagIsUnknown, context) + skipTagsWithField(tags, FIELDS_MARKING_UNHANDLED_TAGS, context) + skipTagsWhere(tags, signatureContainsDefaultArg, context) addPrototypes(tags) - removeDefinedProtypes(tags) + removeDefinedProtypes(tags, context) removeDuplicate(tags) - skipTagsWhere(tags, prototypeAndCodeDontMatch) + skipTagsWhere(tags, prototypeAndCodeDontMatch, context) context[constants.CTX_CTAGS_OF_PREPROC_SOURCE] = tags @@ -113,7 +117,7 @@ func addPrototype(tag map[string]string) { tag[KIND_PROTOTYPE_MODIFIERS] = strings.TrimSpace(tag[KIND_PROTOTYPE_MODIFIERS]) } -func removeDefinedProtypes(tags []map[string]string) { +func removeDefinedProtypes(tags []map[string]string, context map[string]interface{}) { definedPrototypes := make(map[string]bool) for _, tag := range tags { if tag[FIELD_KIND] == KIND_PROTOTYPE { @@ -123,6 +127,9 @@ func removeDefinedProtypes(tags []map[string]string) { for _, tag := range tags { if definedPrototypes[tag[KIND_PROTOTYPE]] { + if utils.DebugLevel(context) >= 10 { + utils.Logger(context).Fprintln(os.Stderr, constants.MSG_SKIPPING_TAG_ALREADY_DEFINED, tag[FIELD_FUNCTION_NAME]) + } tag[FIELD_SKIP] = TRUE } } @@ -142,12 +149,12 @@ func removeDuplicate(tags []map[string]string) { type skipFuncType func(tag map[string]string) bool -func skipTagsWhere(tags []map[string]string, skipFuncs ...skipFuncType) { +func skipTagsWhere(tags []map[string]string, skipFunc skipFuncType, context map[string]interface{}) { for _, tag := range tags { if tag[FIELD_SKIP] != TRUE { - skip := skipFuncs[0](tag) - for _, skipFunc := range skipFuncs[1:] { - skip = skip || skipFunc(tag) + skip := skipFunc(tag) + if skip && utils.DebugLevel(context) >= 10 { + utils.Logger(context).Fprintln(os.Stderr, constants.MSG_SKIPPING_TAG_WITH_REASON, tag[FIELD_FUNCTION_NAME], runtime.FuncForPC(reflect.ValueOf(skipFunc).Pointer()).Name()) } tag[FIELD_SKIP] = strconv.FormatBool(skip) } @@ -180,23 +187,17 @@ func removeSpacesAndTabs(s string) string { return s } -func skipTagsWithField(tags []map[string]string, fields []string) { +func skipTagsWithField(tags []map[string]string, fields []string, context map[string]interface{}) { for _, tag := range tags { - if tagHasAtLeastOneField(tag, fields) { + if field, skip := utils.TagHasAtLeastOneField(tag, fields); skip { + if utils.DebugLevel(context) >= 10 { + utils.Logger(context).Fprintln(os.Stderr, constants.MSG_SKIPPING_TAG_BECAUSE_HAS_FIELD, field) + } tag[FIELD_SKIP] = TRUE } } } -func tagHasAtLeastOneField(tag map[string]string, fields []string) bool { - for _, field := range fields { - if tag[field] != constants.EMPTY_STRING { - return true - } - } - return false -} - func tagIsUnknown(tag map[string]string) bool { return !KNOWN_TAG_KINDS[tag[FIELD_KIND]] } diff --git a/src/arduino.cc/builder/ctags_to_prototypes.go b/src/arduino.cc/builder/ctags_to_prototypes.go index 589efca0..b7f20477 100644 --- a/src/arduino.cc/builder/ctags_to_prototypes.go +++ b/src/arduino.cc/builder/ctags_to_prototypes.go @@ -109,7 +109,8 @@ func collectFunctionNames(tags []map[string]string) []string { func firstFunctionAtLine(tags []map[string]string) (int, error) { for _, tag := range tags { - if !tagIsUnknown(tag) && !tagHasAtLeastOneField(tag, FIELDS_MARKING_UNHANDLED_TAGS) && tag[FIELD_KIND] == KIND_FUNCTION { + _, tagHasAtLeastOneField := utils.TagHasAtLeastOneField(tag, FIELDS_MARKING_UNHANDLED_TAGS) + if !tagIsUnknown(tag) && !tagHasAtLeastOneField && tag[FIELD_KIND] == KIND_FUNCTION { return strconv.Atoi(tag[FIELD_LINE]) } } diff --git a/src/arduino.cc/builder/test/prototypes_adder_test.go b/src/arduino.cc/builder/test/prototypes_adder_test.go index 01fab5ce..b767f8bf 100644 --- a/src/arduino.cc/builder/test/prototypes_adder_test.go +++ b/src/arduino.cc/builder/test/prototypes_adder_test.go @@ -60,6 +60,7 @@ func TestPrototypesAdderBridgeExample(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true + context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -101,6 +102,7 @@ func TestPrototypesAdderSketchWithIfDef(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true + context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -142,6 +144,7 @@ func TestPrototypesAdderBaladuino(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true + context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -183,6 +186,7 @@ func TestPrototypesAdderCharWithEscapedDoubleQuote(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true + context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -224,6 +228,7 @@ func TestPrototypesAdderIncludeBetweenMultilineComment(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true + context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -265,6 +270,7 @@ func TestPrototypesAdderLineContinuations(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true + context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -306,6 +312,7 @@ func TestPrototypesAdderStringWithComment(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true + context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -347,6 +354,7 @@ func TestPrototypesAdderSketchWithStruct(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true + context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -391,6 +399,7 @@ func TestPrototypesAdderSketchWithConfig(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true + context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -435,6 +444,7 @@ func TestPrototypesAdderSketchNoFunctionsTwoFiles(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true + context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -476,6 +486,7 @@ func TestPrototypesAdderSketchNoFunctions(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true + context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -520,6 +531,7 @@ func TestPrototypesAdderSketchWithDefaultArgs(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true + context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -564,6 +576,7 @@ func TestPrototypesAdderSketchWithInlineFunction(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true + context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -608,6 +621,7 @@ func TestPrototypesAdderSketchWithFunctionSignatureInsideIFDEF(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true + context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -652,6 +666,7 @@ func TestPrototypesAdderSketchWithUSBCON(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true + context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -695,6 +710,7 @@ func TestPrototypesAdderSketchWithTypename(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_LIBRARIES_FOLDERS] = []string{"libraries", "downloaded_libraries"} context[constants.CTX_VERBOSE] = true + context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -739,6 +755,7 @@ func TestPrototypesAdderSketchWithIfDef2(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true + context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -786,6 +803,7 @@ func TestPrototypesAdderSketchWithIfDef2SAM(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true + context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, diff --git a/src/arduino.cc/builder/utils/utils.go b/src/arduino.cc/builder/utils/utils.go index 56129fc5..c6c8bbe8 100644 --- a/src/arduino.cc/builder/utils/utils.go +++ b/src/arduino.cc/builder/utils/utils.go @@ -442,3 +442,12 @@ func WriteFile(targetFilePath string, data string) error { func TouchFile(targetFilePath string) error { return WriteFileBytes(targetFilePath, []byte{}) } + +func TagHasAtLeastOneField(tag map[string]string, fields []string) (string, bool) { + for _, field := range fields { + if tag[field] != constants.EMPTY_STRING { + return field, true + } + } + return "", false +} From dc6600104ea554e6e9fc1fc9a604122ff93f2ad4 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Thu, 19 Nov 2015 16:39:39 +0100 Subject: [PATCH 51/85] Releasing 1.2.4 Signed-off-by: Federico Fissore --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 21ac5f2a..c397e978 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,7 @@ import ( "syscall" ) -const VERSION = "1.2.3" +const VERSION = "1.2.4" const FLAG_ACTION_COMPILE = "compile" const FLAG_ACTION_PREPROCESS = "preprocess" From e70010bdd94ad4a98803c35a2b25fe53c6ebc8e4 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 23 Nov 2015 10:57:11 +0100 Subject: [PATCH 52/85] Updated ctags to 5.8-arduino5. Added test that ensure proper space is put after 'const'. Fixes #69 Signed-off-by: Federico Fissore --- .../builder/test/helper_tools_downloader.go | 10 +-- .../builder/test/prototypes_adder_test.go | 61 +++++++++++++------ .../builder/test/sketch_with_const/sketch.ino | 10 +++ 3 files changed, 59 insertions(+), 22 deletions(-) create mode 100644 src/arduino.cc/builder/test/sketch_with_const/sketch.ino diff --git a/src/arduino.cc/builder/test/helper_tools_downloader.go b/src/arduino.cc/builder/test/helper_tools_downloader.go index ccc11d7a..9922d79d 100644 --- a/src/arduino.cc/builder/test/helper_tools_downloader.go +++ b/src/arduino.cc/builder/test/helper_tools_downloader.go @@ -111,12 +111,12 @@ func DownloadCoresAndToolsAndLibraries(t *testing.T) { OsUrl{Os: "i686-mingw32", Url: "http://downloads.arduino.cc/tools/coan-5.2-i686-mingw32.zip"}, OsUrl{Os: "x86_64-apple-darwin", Url: "http://downloads.arduino.cc/tools/coan-5.2-x86_64-apple-darwin.zip"}, }}, - Tool{Name: "ctags", Version: "5.8-arduino4", + Tool{Name: "ctags", Version: "5.8-arduino5", OsUrls: []OsUrl{ - OsUrl{Os: "i686-pc-linux-gnu", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino4-i686-pc-linux-gnu.tar.bz2"}, - OsUrl{Os: "x86_64-pc-linux-gnu", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino4-x86_64-pc-linux-gnu.tar.bz2"}, - OsUrl{Os: "i686-mingw32", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino4-i686-mingw32.zip"}, - OsUrl{Os: "x86_64-apple-darwin", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino4-x86_64-apple-darwin.zip"}, + OsUrl{Os: "i686-pc-linux-gnu", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino5-i686-pc-linux-gnu.tar.bz2"}, + OsUrl{Os: "x86_64-pc-linux-gnu", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino5-x86_64-pc-linux-gnu.tar.bz2"}, + OsUrl{Os: "i686-mingw32", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino5-i686-mingw32.zip"}, + OsUrl{Os: "x86_64-apple-darwin", Url: "http://downloads.arduino.cc/tools/ctags-5.8-arduino5-x86_64-apple-darwin.zip"}, }}, } diff --git a/src/arduino.cc/builder/test/prototypes_adder_test.go b/src/arduino.cc/builder/test/prototypes_adder_test.go index b767f8bf..0be24def 100644 --- a/src/arduino.cc/builder/test/prototypes_adder_test.go +++ b/src/arduino.cc/builder/test/prototypes_adder_test.go @@ -102,7 +102,6 @@ func TestPrototypesAdderSketchWithIfDef(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true - context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -144,7 +143,6 @@ func TestPrototypesAdderBaladuino(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true - context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -186,7 +184,6 @@ func TestPrototypesAdderCharWithEscapedDoubleQuote(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true - context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -228,7 +225,6 @@ func TestPrototypesAdderIncludeBetweenMultilineComment(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true - context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -270,7 +266,6 @@ func TestPrototypesAdderLineContinuations(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true - context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -312,7 +307,6 @@ func TestPrototypesAdderStringWithComment(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true - context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -354,7 +348,6 @@ func TestPrototypesAdderSketchWithStruct(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true - context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -399,7 +392,6 @@ func TestPrototypesAdderSketchWithConfig(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true - context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -444,7 +436,6 @@ func TestPrototypesAdderSketchNoFunctionsTwoFiles(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true - context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -486,7 +477,6 @@ func TestPrototypesAdderSketchNoFunctions(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true - context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -531,7 +521,6 @@ func TestPrototypesAdderSketchWithDefaultArgs(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true - context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -576,7 +565,6 @@ func TestPrototypesAdderSketchWithInlineFunction(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true - context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -621,7 +609,6 @@ func TestPrototypesAdderSketchWithFunctionSignatureInsideIFDEF(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true - context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -666,7 +653,6 @@ func TestPrototypesAdderSketchWithUSBCON(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true - context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -710,7 +696,6 @@ func TestPrototypesAdderSketchWithTypename(t *testing.T) { context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_LIBRARIES_FOLDERS] = []string{"libraries", "downloaded_libraries"} context[constants.CTX_VERBOSE] = true - context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -755,7 +740,6 @@ func TestPrototypesAdderSketchWithIfDef2(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true - context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -803,7 +787,6 @@ func TestPrototypesAdderSketchWithIfDef2SAM(t *testing.T) { context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} context[constants.CTX_VERBOSE] = true - context[constants.CTX_DEBUG_LEVEL] = 10 commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -831,3 +814,47 @@ func TestPrototypesAdderSketchWithIfDef2SAM(t *testing.T) { expectedSource := LoadAndInterpolate(t, filepath.Join("sketch_with_ifdef", "sketch.preprocessed.SAM.txt"), context) require.Equal(t, expectedSource, strings.Replace(context[constants.CTX_SOURCE].(string), "\r\n", "\n", -1)) } + +func TestPrototypesAdderSketchWithConst(t *testing.T) { + DownloadCoresAndToolsAndLibraries(t) + + context := make(map[string]interface{}) + + buildPath := SetupBuildPath(t, context) + defer os.RemoveAll(buildPath) + + sketchLocation := filepath.Join("sketch_with_const", "sketch.ino") + absoluteSketchLocation := strings.Replace(Abs(t, sketchLocation), "\\", "\\\\", -1) + + context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} + context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} + context[constants.CTX_FQBN] = "arduino:avr:uno" + context[constants.CTX_SKETCH_LOCATION] = sketchLocation + context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" + context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} + context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} + context[constants.CTX_VERBOSE] = true + + commands := []types.Command{ + &builder.SetupHumanLoggerIfMissing{}, + + &builder.ContainerSetupHardwareToolsLibsSketchAndProps{}, + + &builder.ContainerMergeCopySketchFiles{}, + + &builder.ContainerFindIncludes{}, + + &builder.PrintUsedLibrariesIfVerbose{}, + &builder.WarnAboutArchIncompatibleLibraries{}, + + &builder.ContainerAddPrototypes{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) + require.Equal(t, "#line 1 \""+absoluteSketchLocation+"\"\nvoid setup();\n#line 2 \""+absoluteSketchLocation+"\"\nvoid loop();\n#line 4 \""+absoluteSketchLocation+"\"\nconst __FlashStringHelper* test();\n#line 6 \""+absoluteSketchLocation+"\"\nconst int test3();\n#line 8 \""+absoluteSketchLocation+"\"\nvolatile __FlashStringHelper* test2();\n#line 10 \""+absoluteSketchLocation+"\"\nvolatile int test4();\n#line 1\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) +} diff --git a/src/arduino.cc/builder/test/sketch_with_const/sketch.ino b/src/arduino.cc/builder/test/sketch_with_const/sketch.ino new file mode 100644 index 00000000..f4f52ca0 --- /dev/null +++ b/src/arduino.cc/builder/test/sketch_with_const/sketch.ino @@ -0,0 +1,10 @@ +void setup() {} +void loop() {} + +const __FlashStringHelper* test() {} + +const int test3() {} + +volatile __FlashStringHelper* test2() {} + +volatile int test4() {} From f5edd23c01f0f21063b5000368cafff0e5cf4908 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 23 Nov 2015 11:15:35 +0100 Subject: [PATCH 53/85] Avoid warning about SCCS folders in libraries, just ignore them. Fixes #70 Signed-off-by: Federico Fissore --- src/arduino.cc/builder/libraries_loader.go | 4 +++- src/arduino.cc/builder/utils/utils.go | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/arduino.cc/builder/libraries_loader.go b/src/arduino.cc/builder/libraries_loader.go index d59a473e..e47c1d4e 100644 --- a/src/arduino.cc/builder/libraries_loader.go +++ b/src/arduino.cc/builder/libraries_loader.go @@ -152,7 +152,9 @@ func makeNewLibrary(libraryFolder string, debugLevel int, logger i18n.Logger) (* if debugLevel > 0 { for _, subFolder := range subFolders { if utils.IsSCCSOrHiddenFile(subFolder) { - logger.Fprintln(os.Stderr, constants.MSG_WARNING_SPURIOUS_FILE_IN_LIB, filepath.Base(subFolder.Name()), properties[constants.LIBRARY_NAME]) + if !utils.IsSCCSFile(subFolder) && utils.IsHiddenFile(subFolder) { + logger.Fprintln(os.Stderr, constants.MSG_WARNING_SPURIOUS_FILE_IN_LIB, filepath.Base(subFolder.Name()), properties[constants.LIBRARY_NAME]) + } } } } diff --git a/src/arduino.cc/builder/utils/utils.go b/src/arduino.cc/builder/utils/utils.go index c6c8bbe8..ce01fdc3 100644 --- a/src/arduino.cc/builder/utils/utils.go +++ b/src/arduino.cc/builder/utils/utils.go @@ -184,11 +184,22 @@ func FilterFilesWithExtension(extension string) filterFiles { var SOURCE_CONTROL_FOLDERS = map[string]bool{"CVS": true, "RCS": true, ".git": true, ".svn": true, ".hg": true, ".bzr": true} func IsSCCSOrHiddenFile(file os.FileInfo) bool { + return IsSCCSFile(file) || IsHiddenFile(file) +} + +func IsHiddenFile(file os.FileInfo) bool { name := filepath.Base(file.Name()) if name[0] == '.' { return true } + + return false +} + +func IsSCCSFile(file os.FileInfo) bool { + name := filepath.Base(file.Name()) + if SOURCE_CONTROL_FOLDERS[name] { return true } From 5f397234421cdfb63f2f6e851b32382b01d35514 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 23 Nov 2015 11:20:18 +0100 Subject: [PATCH 54/85] Releasing 1.2.5 Signed-off-by: Federico Fissore --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index c397e978..450f400b 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,7 @@ import ( "syscall" ) -const VERSION = "1.2.4" +const VERSION = "1.2.5" const FLAG_ACTION_COMPILE = "compile" const FLAG_ACTION_PREPROCESS = "preprocess" From c3f43f861e2397e069f0b454e20516cf8e4278d9 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 23 Nov 2015 15:21:02 +0100 Subject: [PATCH 55/85] Platform rewrite warnings are now emitted only for the actual selected library. Fixes #57 Signed-off-by: Federico Fissore --- .../add_additional_entries_to_context.go | 1 + src/arduino.cc/builder/builder.go | 2 + src/arduino.cc/builder/constants/constants.go | 1 + .../builder/rewrite_hardware_keys.go | 19 +++--- .../builder/warn_about_platform_rewrites.go | 67 +++++++++++++++++++ 5 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 src/arduino.cc/builder/warn_about_platform_rewrites.go diff --git a/src/arduino.cc/builder/add_additional_entries_to_context.go b/src/arduino.cc/builder/add_additional_entries_to_context.go index 5729634a..316a4c17 100644 --- a/src/arduino.cc/builder/add_additional_entries_to_context.go +++ b/src/arduino.cc/builder/add_additional_entries_to_context.go @@ -86,6 +86,7 @@ func (s *AddAdditionalEntriesToContext) Run(context map[string]interface{}) erro context[constants.CTX_FOLDERS_WITH_SOURCES_QUEUE] = foldersWithSources context[constants.CTX_LIBRARY_RESOLUTION_RESULTS] = make(map[string]types.LibraryResolutionResult) + context[constants.CTX_HARDWARE_REWRITE_RESULTS] = make(map[*types.Platform][]types.PlatforKeyRewrite) return nil } diff --git a/src/arduino.cc/builder/builder.go b/src/arduino.cc/builder/builder.go index 42e869ff..d76f8461 100644 --- a/src/arduino.cc/builder/builder.go +++ b/src/arduino.cc/builder/builder.go @@ -77,6 +77,8 @@ func (s *Builder) Run(context map[string]interface{}) error { &ContainerBuildOptions{}, + &WarnAboutPlatformRewrites{}, + &RecipeByPrefixSuffixRunner{Prefix: constants.HOOKS_PREBUILD, Suffix: constants.HOOKS_PATTERN_SUFFIX}, &ContainerMergeCopySketchFiles{}, diff --git a/src/arduino.cc/builder/constants/constants.go b/src/arduino.cc/builder/constants/constants.go index 759626d0..06610f57 100644 --- a/src/arduino.cc/builder/constants/constants.go +++ b/src/arduino.cc/builder/constants/constants.go @@ -99,6 +99,7 @@ const CTX_GCC_MINUS_E_SOURCE = "gccMinusESource" const CTX_GCC_MINUS_M_OUTPUT = "gccMinusMOutput" const CTX_HARDWARE_FOLDERS = "hardwareFolders" const CTX_HARDWARE = "hardware" +const CTX_HARDWARE_REWRITE_RESULTS = "hardwareRewriteResults" const CTX_HEADER_TO_LIBRARIES = "headerToLibraries" const CTX_IMPORTED_LIBRARIES = "importedLibraries" const CTX_INCLUDE_FOLDERS = "includeFolders" diff --git a/src/arduino.cc/builder/rewrite_hardware_keys.go b/src/arduino.cc/builder/rewrite_hardware_keys.go index 042254f4..b027165a 100644 --- a/src/arduino.cc/builder/rewrite_hardware_keys.go +++ b/src/arduino.cc/builder/rewrite_hardware_keys.go @@ -31,10 +31,8 @@ package builder import ( "arduino.cc/builder/constants" - "arduino.cc/builder/i18n" "arduino.cc/builder/types" "arduino.cc/builder/utils" - "os" ) type RewriteHardwareKeys struct{} @@ -46,9 +44,7 @@ func (s *RewriteHardwareKeys) Run(context map[string]interface{}) error { packages := context[constants.CTX_HARDWARE].(*types.Packages) platformKeysRewrite := context[constants.CTX_PLATFORM_KEYS_REWRITE].(types.PlatforKeysRewrite) - logger := context[constants.CTX_LOGGER].(i18n.Logger) - - warn := utils.DebugLevel(context) > 0 + hardwareRewriteResults := context[constants.CTX_HARDWARE_REWRITE_RESULTS].(map[*types.Platform][]types.PlatforKeyRewrite) for _, aPackage := range packages.Packages { for _, platform := range aPackage.Platforms { @@ -56,9 +52,9 @@ func (s *RewriteHardwareKeys) Run(context map[string]interface{}) error { for _, rewrite := range platformKeysRewrite.Rewrites { if platform.Properties[rewrite.Key] != constants.EMPTY_STRING && platform.Properties[rewrite.Key] == rewrite.OldValue { platform.Properties[rewrite.Key] = rewrite.NewValue - if warn { - logger.Fprintln(os.Stderr, constants.MSG_WARNING_PLATFORM_OLD_VALUES, platform.Properties[constants.PLATFORM_NAME], rewrite.Key+"="+rewrite.OldValue, rewrite.Key+"="+rewrite.NewValue) - } + appliedRewrites := rewritesAppliedToPlatform(platform, hardwareRewriteResults) + appliedRewrites = append(appliedRewrites, rewrite) + hardwareRewriteResults[platform] = appliedRewrites } } } @@ -67,3 +63,10 @@ func (s *RewriteHardwareKeys) Run(context map[string]interface{}) error { return nil } + +func rewritesAppliedToPlatform(platform *types.Platform, hardwareRewriteResults map[*types.Platform][]types.PlatforKeyRewrite) []types.PlatforKeyRewrite { + if hardwareRewriteResults[platform] == nil { + hardwareRewriteResults[platform] = []types.PlatforKeyRewrite{} + } + return hardwareRewriteResults[platform] +} diff --git a/src/arduino.cc/builder/warn_about_platform_rewrites.go b/src/arduino.cc/builder/warn_about_platform_rewrites.go new file mode 100644 index 00000000..93f6da71 --- /dev/null +++ b/src/arduino.cc/builder/warn_about_platform_rewrites.go @@ -0,0 +1,67 @@ +/* + * This file is part of Arduino Builder. + * + * Arduino Builder is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As a special exception, you may use this file as part of a free software + * library without restriction. Specifically, if other files instantiate + * templates or use macros or inline functions from this file, or you compile + * this file and link it with other files to produce an executable, this + * file does not by itself cause the resulting executable to be covered by + * the GNU General Public License. This exception does not however + * invalidate any other reasons why the executable file might be covered by + * the GNU General Public License. + * + * Copyright 2015 Arduino LLC (http://www.arduino.cc/) + */ + +package builder + +import ( + "arduino.cc/builder/constants" + "arduino.cc/builder/i18n" + "arduino.cc/builder/types" + "arduino.cc/builder/utils" + "os" +) + +type WarnAboutPlatformRewrites struct{} + +func (s *WarnAboutPlatformRewrites) Run(context map[string]interface{}) error { + warn := utils.DebugLevel(context) > 0 + if !warn { + return nil + } + + logger := context[constants.CTX_LOGGER].(i18n.Logger) + hardwareRewriteResults := context[constants.CTX_HARDWARE_REWRITE_RESULTS].(map[*types.Platform][]types.PlatforKeyRewrite) + targetPlatform := context[constants.CTX_TARGET_PLATFORM].(*types.Platform) + actualPlatform := context[constants.CTX_ACTUAL_PLATFORM].(*types.Platform) + + platforms := []*types.Platform{targetPlatform} + if actualPlatform != targetPlatform { + platforms = append(platforms, actualPlatform) + } + + for _, platform := range platforms { + if hardwareRewriteResults[platform] != nil { + for _, rewrite := range hardwareRewriteResults[platform] { + logger.Fprintln(os.Stderr, constants.MSG_WARNING_PLATFORM_OLD_VALUES, platform.Properties[constants.PLATFORM_NAME], rewrite.Key+"="+rewrite.OldValue, rewrite.Key+"="+rewrite.NewValue) + } + } + } + + return nil +} From 4a933e9a45bab537c90f423e5051e4225c1fc9a5 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 23 Nov 2015 15:24:32 +0100 Subject: [PATCH 56/85] Releasing 1.2.6 Signed-off-by: Federico Fissore --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 450f400b..4075871d 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,7 @@ import ( "syscall" ) -const VERSION = "1.2.5" +const VERSION = "1.2.6" const FLAG_ACTION_COMPILE = "compile" const FLAG_ACTION_PREPROCESS = "preprocess" From d1ebf853bc8133eedeb1b0131af5c1dc8329367b Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 23 Nov 2015 17:36:14 +0100 Subject: [PATCH 57/85] lib-discovery-recursion-depth is not needed since 1.2.0. Hence removing CLI param Signed-off-by: Federico Fissore --- README.md | 2 -- main.go | 7 ------- .../builder/add_additional_entries_to_context.go | 4 ---- src/arduino.cc/builder/builder.go | 1 - src/arduino.cc/builder/constants/constants.go | 1 - .../builder/test/add_additional_entries_to_context_test.go | 2 -- 6 files changed, 17 deletions(-) diff --git a/README.md b/README.md index ac8846d3..457fd27d 100644 --- a/README.md +++ b/README.md @@ -35,8 +35,6 @@ This tool generates function prototypes and gathers library paths, providing `gc * `-logger`: Optional, can be "human" or "machine". Defaults to "human". If "machine", messages emitted will be in a format which the Arduino IDE understands and that it uses for I18N. -* `-lib-discovery-recursion-depth`: Optional. Defaults to 4. How deep should library discovery go down looking for included libraries. - * `-version`: if specified, prints version and exits. * `-build-options-file`: it specifies path to a local `build.options.json` file (see paragraph below), which allows you to omit specifying params such as `-hardware`, `-tools`, `-libraries`, `-fqbn`, `-pref` and `-ide-version`. diff --git a/main.go b/main.go index 4075871d..39827770 100644 --- a/main.go +++ b/main.go @@ -72,7 +72,6 @@ const FLAG_WARNINGS_ALL = "all" const FLAG_LOGGER = "logger" const FLAG_LOGGER_HUMAN = "human" const FLAG_LOGGER_MACHINE = "machine" -const FLAG_LIB_DISCOVERY_RECURSION_PATH = "lib-discovery-recursion-depth" const FLAG_VERSION = "version" const FLAG_VID_PID = "vid-pid" @@ -113,7 +112,6 @@ var buildPathFlag *string var verboseFlag *bool var quietFlag *bool var debugLevelFlag *int -var libraryDiscoveryRecursionDepthFlag *int var warningsLevelFlag *string var loggerFlag *string var versionFlag *bool @@ -137,7 +135,6 @@ func init() { debugLevelFlag = flag.Int(FLAG_DEBUG_LEVEL, builder.DEFAULT_DEBUG_LEVEL, "Turns on debugging messages. The higher, the chattier") warningsLevelFlag = flag.String(FLAG_WARNINGS, "", "Sets warnings level. Available values are '"+FLAG_WARNINGS_NONE+"', '"+FLAG_WARNINGS_DEFAULT+"', '"+FLAG_WARNINGS_MORE+"' and '"+FLAG_WARNINGS_ALL+"'") loggerFlag = flag.String(FLAG_LOGGER, FLAG_LOGGER_HUMAN, "Sets type of logger. Available values are '"+FLAG_LOGGER_HUMAN+"', '"+FLAG_LOGGER_MACHINE+"'") - libraryDiscoveryRecursionDepthFlag = flag.Int(FLAG_LIB_DISCOVERY_RECURSION_PATH, builder.DEFAULT_LIBRARY_DISCOVERY_RECURSION_DEPTH, "How deep should library discovery go down looking for included libraries") versionFlag = flag.Bool(FLAG_VERSION, false, "prints version and exits") vidPidFlag = flag.String(FLAG_VID_PID, "", "specify to use vid/pid specific build properties, as defined in boards.txt") } @@ -292,10 +289,6 @@ func main() { context[constants.CTX_DEBUG_LEVEL] = *debugLevelFlag } - if *libraryDiscoveryRecursionDepthFlag > 0 { - context[constants.CTX_LIBRARY_DISCOVERY_RECURSION_DEPTH] = *libraryDiscoveryRecursionDepthFlag - } - if *quietFlag { context[constants.CTX_LOGGER] = i18n.NoopLogger{} } else if *loggerFlag == FLAG_LOGGER_MACHINE { diff --git a/src/arduino.cc/builder/add_additional_entries_to_context.go b/src/arduino.cc/builder/add_additional_entries_to_context.go index 316a4c17..742c0be1 100644 --- a/src/arduino.cc/builder/add_additional_entries_to_context.go +++ b/src/arduino.cc/builder/add_additional_entries_to_context.go @@ -76,10 +76,6 @@ func (s *AddAdditionalEntriesToContext) Run(context map[string]interface{}) erro context[constants.CTX_DEBUG_LEVEL] = DEFAULT_DEBUG_LEVEL } - if !utils.MapHas(context, constants.CTX_LIBRARY_DISCOVERY_RECURSION_DEPTH) { - context[constants.CTX_LIBRARY_DISCOVERY_RECURSION_DEPTH] = DEFAULT_LIBRARY_DISCOVERY_RECURSION_DEPTH - } - sourceFiles := &types.UniqueStringQueue{} context[constants.CTX_COLLECTED_SOURCE_FILES_QUEUE] = sourceFiles foldersWithSources := &types.UniqueSourceFolderQueue{} diff --git a/src/arduino.cc/builder/builder.go b/src/arduino.cc/builder/builder.go index d76f8461..ea2d173a 100644 --- a/src/arduino.cc/builder/builder.go +++ b/src/arduino.cc/builder/builder.go @@ -62,7 +62,6 @@ const DEFAULT_DEBUG_LEVEL = 5 const DEFAULT_WARNINGS_LEVEL = "none" const DEFAULT_SOFTWARE = "ARDUINO" const DEFAULT_BUILD_CORE = "arduino" -const DEFAULT_LIBRARY_DISCOVERY_RECURSION_DEPTH = 4 type Builder struct{} diff --git a/src/arduino.cc/builder/constants/constants.go b/src/arduino.cc/builder/constants/constants.go index 06610f57..fcf364c0 100644 --- a/src/arduino.cc/builder/constants/constants.go +++ b/src/arduino.cc/builder/constants/constants.go @@ -109,7 +109,6 @@ const CTX_INCLUDES_JUST_FOUND = "includesJustFound" const CTX_LIBRARIES_BUILD_PATH = "librariesBuildPath" const CTX_LIBRARIES_FOLDERS = "librariesFolders" const CTX_LIBRARIES = "libraries" -const CTX_LIBRARY_DISCOVERY_RECURSION_DEPTH = "libraryDiscoveryRecursionDepth" const CTX_LIBRARY_RESOLUTION_RESULTS = "libraryResolutionResults" const CTX_LINE_OFFSET = "lineOffset" const CTX_LINE_WHERE_TO_INSERT_PROTOTYPES = "lineWhereToInsertPrototypes" diff --git a/src/arduino.cc/builder/test/add_additional_entries_to_context_test.go b/src/arduino.cc/builder/test/add_additional_entries_to_context_test.go index 7001a01e..416f5335 100644 --- a/src/arduino.cc/builder/test/add_additional_entries_to_context_test.go +++ b/src/arduino.cc/builder/test/add_additional_entries_to_context_test.go @@ -52,7 +52,6 @@ func TestAddAdditionalEntriesToContextNoBuildPath(t *testing.T) { require.NotNil(t, context[constants.CTX_WARNINGS_LEVEL]) require.NotNil(t, context[constants.CTX_VERBOSE]) require.NotNil(t, context[constants.CTX_DEBUG_LEVEL]) - require.NotNil(t, context[constants.CTX_LIBRARY_DISCOVERY_RECURSION_DEPTH]) require.True(t, context[constants.CTX_COLLECTED_SOURCE_FILES_QUEUE].(*types.UniqueStringQueue).Empty()) require.True(t, context[constants.CTX_FOLDERS_WITH_SOURCES_QUEUE].(*types.UniqueSourceFolderQueue).Empty()) @@ -76,7 +75,6 @@ func TestAddAdditionalEntriesToContextWithBuildPath(t *testing.T) { require.NotNil(t, context[constants.CTX_WARNINGS_LEVEL]) require.NotNil(t, context[constants.CTX_VERBOSE]) require.NotNil(t, context[constants.CTX_DEBUG_LEVEL]) - require.NotNil(t, context[constants.CTX_LIBRARY_DISCOVERY_RECURSION_DEPTH]) require.True(t, context[constants.CTX_COLLECTED_SOURCE_FILES_QUEUE].(*types.UniqueStringQueue).Empty()) require.True(t, context[constants.CTX_FOLDERS_WITH_SOURCES_QUEUE].(*types.UniqueSourceFolderQueue).Empty()) From 12ad2243611351b1ae7ce487cbfe12b6f2edd6aa Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Wed, 25 Nov 2015 11:11:14 +0100 Subject: [PATCH 58/85] Variant files must NOT be included in core.a, they MUST be passed to linker one by one. Fixes #72 Signed-off-by: Federico Fissore --- src/arduino.cc/builder/constants/constants.go | 1 + src/arduino.cc/builder/phases/core_builder.go | 21 +++++++++---------- src/arduino.cc/builder/phases/linker.go | 2 ++ src/arduino.cc/builder/test/builder_test.go | 6 ++++++ 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/arduino.cc/builder/constants/constants.go b/src/arduino.cc/builder/constants/constants.go index fcf364c0..9e557f4b 100644 --- a/src/arduino.cc/builder/constants/constants.go +++ b/src/arduino.cc/builder/constants/constants.go @@ -113,6 +113,7 @@ const CTX_LIBRARY_RESOLUTION_RESULTS = "libraryResolutionResults" const CTX_LINE_OFFSET = "lineOffset" const CTX_LINE_WHERE_TO_INSERT_PROTOTYPES = "lineWhereToInsertPrototypes" const CTX_LOGGER = "logger" +const CTX_OBJECT_FILES_CORE = "objectFilesCore" const CTX_OBJECT_FILES_LIBRARIES = "objectFilesLibraries" const CTX_OBJECT_FILES_SKETCH = "objectFilesSketch" const CTX_OTHER_LIBRARIES_FOLDERS = "otherLibrariesFolders" diff --git a/src/arduino.cc/builder/phases/core_builder.go b/src/arduino.cc/builder/phases/core_builder.go index 79bf882e..cf1c761d 100644 --- a/src/arduino.cc/builder/phases/core_builder.go +++ b/src/arduino.cc/builder/phases/core_builder.go @@ -50,21 +50,22 @@ func (s *CoreBuilder) Run(context map[string]interface{}) error { return utils.WrapError(err) } - archiveFile, err := compileCore(coreBuildPath, buildProperties, verbose, warningsLevel, logger) + archiveFile, objectFiles, err := compileCore(coreBuildPath, buildProperties, verbose, warningsLevel, logger) if err != nil { return utils.WrapError(err) } context[constants.CTX_ARCHIVE_FILE_PATH_CORE] = archiveFile + context[constants.CTX_OBJECT_FILES_CORE] = objectFiles return nil } -func compileCore(buildPath string, buildProperties map[string]string, verbose bool, warningsLevel string, logger i18n.Logger) (string, error) { +func compileCore(buildPath string, buildProperties map[string]string, verbose bool, warningsLevel string, logger i18n.Logger) (string, []string, error) { coreFolder := buildProperties[constants.BUILD_PROPERTIES_BUILD_CORE_PATH] variantFolder := buildProperties[constants.BUILD_PROPERTIES_BUILD_VARIANT_PATH] - var includes []string + includes := []string{} includes = append(includes, coreFolder) if variantFolder != constants.EMPTY_STRING { includes = append(includes, variantFolder) @@ -73,25 +74,23 @@ func compileCore(buildPath string, buildProperties map[string]string, verbose bo var err error - var variantObjectFiles []string + variantObjectFiles := []string{} if variantFolder != constants.EMPTY_STRING { variantObjectFiles, err = builder_utils.CompileFiles(variantObjectFiles, variantFolder, true, buildPath, buildProperties, includes, verbose, warningsLevel, logger) if err != nil { - return "", utils.WrapError(err) + return "", nil, utils.WrapError(err) } } coreObjectFiles, err := builder_utils.CompileFiles([]string{}, coreFolder, true, buildPath, buildProperties, includes, verbose, warningsLevel, logger) if err != nil { - return "", utils.WrapError(err) + return "", nil, utils.WrapError(err) } - objectFiles := append(coreObjectFiles, variantObjectFiles...) - - archiveFile, err := builder_utils.ArchiveCompiledFiles(buildPath, "core.a", objectFiles, buildProperties, verbose, logger) + archiveFile, err := builder_utils.ArchiveCompiledFiles(buildPath, "core.a", coreObjectFiles, buildProperties, verbose, logger) if err != nil { - return "", utils.WrapError(err) + return "", nil, utils.WrapError(err) } - return archiveFile, nil + return archiveFile, variantObjectFiles, nil } diff --git a/src/arduino.cc/builder/phases/linker.go b/src/arduino.cc/builder/phases/linker.go index 347f9959..7b9fd319 100644 --- a/src/arduino.cc/builder/phases/linker.go +++ b/src/arduino.cc/builder/phases/linker.go @@ -43,10 +43,12 @@ type Linker struct{} func (s *Linker) Run(context map[string]interface{}) error { objectFilesSketch := context[constants.CTX_OBJECT_FILES_SKETCH].([]string) objectFilesLibraries := context[constants.CTX_OBJECT_FILES_LIBRARIES].([]string) + objectFilesCore := context[constants.CTX_OBJECT_FILES_CORE].([]string) var objectFiles []string objectFiles = append(objectFiles, objectFilesSketch...) objectFiles = append(objectFiles, objectFilesLibraries...) + objectFiles = append(objectFiles, objectFilesCore...) coreArchiveFilePath := context[constants.CTX_ARCHIVE_FILE_PATH_CORE].(string) buildPath := context[constants.CTX_BUILD_PATH].(string) diff --git a/src/arduino.cc/builder/test/builder_test.go b/src/arduino.cc/builder/test/builder_test.go index 977bd508..9acf6f4a 100644 --- a/src/arduino.cc/builder/test/builder_test.go +++ b/src/arduino.cc/builder/test/builder_test.go @@ -34,6 +34,7 @@ import ( "arduino.cc/builder/constants" "github.com/stretchr/testify/require" "os" + "os/exec" "path/filepath" "testing" ) @@ -216,6 +217,11 @@ func TestBuilderBridgeSAM(t *testing.T) { NoError(t, err) _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_LIBRARIES, "Bridge", "Mailbox.cpp.o")) NoError(t, err) + + cmd := exec.Command(filepath.Join("downloaded_tools", "arm-none-eabi-gcc", "4.8.3-2014q1", "bin", "arm-none-eabi-objdump"), "-f", filepath.Join(buildPath, constants.FOLDER_CORE, "core.a")) + bytes, err := cmd.CombinedOutput() + NoError(t, err) + require.NotContains(t, string(bytes), "variant.cpp.o") } func TestBuilderBridgeRedBearLab(t *testing.T) { From a1bec11cf140f03cbaf18461da7733637f857364 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Wed, 25 Nov 2015 11:28:57 +0100 Subject: [PATCH 59/85] Tests: using require.Contains instead of strings.Index Signed-off-by: Federico Fissore --- .../builder/test/sketch_loader_test.go | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/arduino.cc/builder/test/sketch_loader_test.go b/src/arduino.cc/builder/test/sketch_loader_test.go index 219fcc9b..16a3495b 100644 --- a/src/arduino.cc/builder/test/sketch_loader_test.go +++ b/src/arduino.cc/builder/test/sketch_loader_test.go @@ -35,7 +35,6 @@ import ( "arduino.cc/builder/types" "github.com/stretchr/testify/require" "path/filepath" - "strings" "testing" ) @@ -90,15 +89,15 @@ func TestLoadSketch(t *testing.T) { sketch := context[constants.CTX_SKETCH].(*types.Sketch) require.NotNil(t, sketch) - require.True(t, strings.Index(sketch.MainFile.Name, "sketch.ino") != -1) + require.Contains(t, sketch.MainFile.Name, "sketch.ino") require.Equal(t, 2, len(sketch.OtherSketchFiles)) - require.True(t, strings.Index(sketch.OtherSketchFiles[0].Name, "old.pde") != -1) - require.True(t, strings.Index(sketch.OtherSketchFiles[1].Name, "other.ino") != -1) + require.Contains(t, sketch.OtherSketchFiles[0].Name, "old.pde") + require.Contains(t, sketch.OtherSketchFiles[1].Name, "other.ino") require.Equal(t, 2, len(sketch.AdditionalFiles)) - require.True(t, strings.Index(sketch.AdditionalFiles[0].Name, "header.h") != -1) - require.True(t, strings.Index(sketch.AdditionalFiles[1].Name, "helper.h") != -1) + require.Contains(t, sketch.AdditionalFiles[0].Name, "header.h") + require.Contains(t, sketch.AdditionalFiles[1].Name, "helper.h") } func TestFailToLoadSketchFromFolder(t *testing.T) { @@ -134,13 +133,13 @@ func TestLoadSketchFromFolder(t *testing.T) { sketch := context[constants.CTX_SKETCH].(*types.Sketch) require.NotNil(t, sketch) - require.True(t, strings.Index(sketch.MainFile.Name, "sketch_with_subfolders.ino") != -1) + require.Contains(t, sketch.MainFile.Name, "sketch_with_subfolders.ino") require.Equal(t, 0, len(sketch.OtherSketchFiles)) require.Equal(t, 2, len(sketch.AdditionalFiles)) - require.True(t, strings.Index(sketch.AdditionalFiles[0].Name, "other.cpp") != -1) - require.True(t, strings.Index(sketch.AdditionalFiles[1].Name, "other.h") != -1) + require.Contains(t, sketch.AdditionalFiles[0].Name, "other.cpp") + require.Contains(t, sketch.AdditionalFiles[1].Name, "other.h") } func TestLoadSketchWithBackup(t *testing.T) { @@ -160,7 +159,7 @@ func TestLoadSketchWithBackup(t *testing.T) { sketch := context[constants.CTX_SKETCH].(*types.Sketch) require.NotNil(t, sketch) - require.True(t, strings.Index(sketch.MainFile.Name, "sketch.ino") != -1) + require.Contains(t, sketch.MainFile.Name, "sketch.ino") require.Equal(t, 0, len(sketch.AdditionalFiles)) require.Equal(t, 0, len(sketch.OtherSketchFiles)) From c678647347c411648fb988142e45f7f0c48f2379 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Wed, 25 Nov 2015 11:16:35 +0100 Subject: [PATCH 60/85] Releasing 1.3.0 Signed-off-by: Federico Fissore --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 39827770..4adeb603 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,7 @@ import ( "syscall" ) -const VERSION = "1.2.6" +const VERSION = "1.3.0" const FLAG_ACTION_COMPILE = "compile" const FLAG_ACTION_PREPROCESS = "preprocess" From 5da1da3911a7ec0e3571cf24203fa8eaa09b76d1 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Thu, 26 Nov 2015 16:04:11 +0100 Subject: [PATCH 61/85] Then debug level is 10, timestamp is printed before command name Signed-off-by: Federico Fissore --- src/arduino.cc/builder/builder.go | 3 ++- src/arduino.cc/builder/constants/constants.go | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/arduino.cc/builder/builder.go b/src/arduino.cc/builder/builder.go index ea2d173a..8d717f44 100644 --- a/src/arduino.cc/builder/builder.go +++ b/src/arduino.cc/builder/builder.go @@ -37,6 +37,7 @@ import ( "os" "reflect" "strconv" + "time" ) var MAIN_FILE_VALID_EXTENSIONS = map[string]bool{".ino": true, ".pde": true} @@ -207,7 +208,7 @@ func printProgressIfProgressEnabledAndMachineLogger(progressEnabled bool, contex func PrintRingNameIfDebug(context map[string]interface{}, command types.Command) { if utils.DebugLevel(context) >= 10 { - utils.Logger(context).Fprintln(os.Stderr, constants.MSG_RUNNING_COMMAND, reflect.Indirect(reflect.ValueOf(command)).Type().Name()) + utils.Logger(context).Fprintln(os.Stderr, constants.MSG_RUNNING_COMMAND, time.Now().Unix(), reflect.Indirect(reflect.ValueOf(command)).Type().Name()) } } diff --git a/src/arduino.cc/builder/constants/constants.go b/src/arduino.cc/builder/constants/constants.go index 9e557f4b..531250d5 100644 --- a/src/arduino.cc/builder/constants/constants.go +++ b/src/arduino.cc/builder/constants/constants.go @@ -222,7 +222,7 @@ const MSG_PATTERN_MISSING = "{0} pattern is missing" const MSG_PLATFORM_UNKNOWN = "Platform {0} (package {1}) is unknown" const MSG_PROGRESS = "Progress {0}" const MSG_PROP_IN_LIBRARY = "Missing '{0}' from library in {1}" -const MSG_RUNNING_COMMAND = "Running: {0}" +const MSG_RUNNING_COMMAND = "Ts: {0} - Running: {1}" const MSG_RUNNING_RECIPE = "Running recipe: {0}" const MSG_SETTING_BUILD_PATH = "Setting build path to {0}" const MSG_SKETCH_CANT_BE_IN_BUILDPATH = "Sketch cannot be located in build path. Please specify a different build path" From 8067591d8bcc7e7dc904fd93cb41c77998c9f699 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Thu, 26 Nov 2015 16:51:09 +0100 Subject: [PATCH 62/85] Timestamp needs to be converted to string, otherwise go clutters the output Signed-off-by: Federico Fissore --- src/arduino.cc/builder/builder.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arduino.cc/builder/builder.go b/src/arduino.cc/builder/builder.go index 8d717f44..cd8b4b7b 100644 --- a/src/arduino.cc/builder/builder.go +++ b/src/arduino.cc/builder/builder.go @@ -208,7 +208,7 @@ func printProgressIfProgressEnabledAndMachineLogger(progressEnabled bool, contex func PrintRingNameIfDebug(context map[string]interface{}, command types.Command) { if utils.DebugLevel(context) >= 10 { - utils.Logger(context).Fprintln(os.Stderr, constants.MSG_RUNNING_COMMAND, time.Now().Unix(), reflect.Indirect(reflect.ValueOf(command)).Type().Name()) + utils.Logger(context).Fprintln(os.Stderr, constants.MSG_RUNNING_COMMAND, strconv.FormatInt(time.Now().Unix(), 10), reflect.Indirect(reflect.ValueOf(command)).Type().Name()) } } From b06c7ec629e748f580e15673b0289c2fa1a7bd12 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 30 Nov 2015 10:45:35 +0100 Subject: [PATCH 63/85] .S files of a sketch were ignored. Fixes #74 Signed-off-by: Federico Fissore --- src/arduino.cc/builder/builder.go | 4 ++-- .../builder/test/additional_sketch_files_copier_test.go | 5 +++-- src/arduino.cc/builder/test/sketch1/s_file.S | 0 src/arduino.cc/builder/test/sketch_loader_test.go | 5 +++-- 4 files changed, 8 insertions(+), 6 deletions(-) create mode 100644 src/arduino.cc/builder/test/sketch1/s_file.S diff --git a/src/arduino.cc/builder/builder.go b/src/arduino.cc/builder/builder.go index cd8b4b7b..5e446ec2 100644 --- a/src/arduino.cc/builder/builder.go +++ b/src/arduino.cc/builder/builder.go @@ -41,8 +41,8 @@ import ( ) var MAIN_FILE_VALID_EXTENSIONS = map[string]bool{".ino": true, ".pde": true} -var ADDITIONAL_FILE_VALID_EXTENSIONS = map[string]bool{".h": true, ".c": true, ".hpp": true, ".cpp": true} -var ADDITIONAL_FILE_VALID_EXTENSIONS_NO_HEADERS = map[string]bool{".c": true, ".cpp": true} +var ADDITIONAL_FILE_VALID_EXTENSIONS = map[string]bool{".h": true, ".c": true, ".hpp": true, ".cpp": true, ".s": true} +var ADDITIONAL_FILE_VALID_EXTENSIONS_NO_HEADERS = map[string]bool{".c": true, ".cpp": true, ".s": true} var LIBRARY_MANDATORY_PROPERTIES = []string{constants.LIBRARY_NAME, constants.LIBRARY_VERSION, constants.LIBRARY_AUTHOR, constants.LIBRARY_MAINTAINER} var LIBRARY_NOT_SO_MANDATORY_PROPERTIES = []string{constants.LIBRARY_SENTENCE, constants.LIBRARY_PARAGRAPH, constants.LIBRARY_URL} diff --git a/src/arduino.cc/builder/test/additional_sketch_files_copier_test.go b/src/arduino.cc/builder/test/additional_sketch_files_copier_test.go index 2659ea71..2425cd83 100644 --- a/src/arduino.cc/builder/test/additional_sketch_files_copier_test.go +++ b/src/arduino.cc/builder/test/additional_sketch_files_copier_test.go @@ -78,11 +78,12 @@ func TestCopyOtherFiles(t *testing.T) { files, err1 := gohasissues.ReadDir(filepath.Join(buildPath, constants.FOLDER_SKETCH)) NoError(t, err1) - require.Equal(t, 2, len(files)) + require.Equal(t, 3, len(files)) sort.Sort(ByFileInfoName(files)) require.Equal(t, "header.h", files[0].Name()) - require.Equal(t, "subfolder", files[1].Name()) + require.Equal(t, "s_file.S", files[1].Name()) + require.Equal(t, "subfolder", files[2].Name()) files, err1 = gohasissues.ReadDir(filepath.Join(buildPath, constants.FOLDER_SKETCH, "subfolder")) NoError(t, err1) diff --git a/src/arduino.cc/builder/test/sketch1/s_file.S b/src/arduino.cc/builder/test/sketch1/s_file.S new file mode 100644 index 00000000..e69de29b diff --git a/src/arduino.cc/builder/test/sketch_loader_test.go b/src/arduino.cc/builder/test/sketch_loader_test.go index 16a3495b..20090fa3 100644 --- a/src/arduino.cc/builder/test/sketch_loader_test.go +++ b/src/arduino.cc/builder/test/sketch_loader_test.go @@ -95,9 +95,10 @@ func TestLoadSketch(t *testing.T) { require.Contains(t, sketch.OtherSketchFiles[0].Name, "old.pde") require.Contains(t, sketch.OtherSketchFiles[1].Name, "other.ino") - require.Equal(t, 2, len(sketch.AdditionalFiles)) + require.Equal(t, 3, len(sketch.AdditionalFiles)) require.Contains(t, sketch.AdditionalFiles[0].Name, "header.h") - require.Contains(t, sketch.AdditionalFiles[1].Name, "helper.h") + require.Contains(t, sketch.AdditionalFiles[1].Name, "s_file.S") + require.Contains(t, sketch.AdditionalFiles[2].Name, "helper.h") } func TestFailToLoadSketchFromFolder(t *testing.T) { From 72c4659dbd74078cc1a0691911b728607c53a515 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 30 Nov 2015 11:03:12 +0100 Subject: [PATCH 64/85] Releasing 1.3.1 Signed-off-by: Federico Fissore --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 4adeb603..0d508fe6 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,7 @@ import ( "syscall" ) -const VERSION = "1.3.0" +const VERSION = "1.3.1" const FLAG_ACTION_COMPILE = "compile" const FLAG_ACTION_PREPROCESS = "preprocess" From c0fc12543061f20b37f432765209b2e2c8fe283e Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 1 Dec 2015 09:46:03 +0100 Subject: [PATCH 65/85] Removing stale libraries object files, resulting from previous compilations Signed-off-by: Federico Fissore --- src/arduino.cc/builder/builder.go | 1 + src/arduino.cc/builder/test/builder_test.go | 29 +++++++ .../unused_compiled_libraries_remover_test.go | 77 +++++++++++++++++ .../unused_compiled_libraries_remover.go | 82 +++++++++++++++++++ 4 files changed, 189 insertions(+) create mode 100644 src/arduino.cc/builder/test/unused_compiled_libraries_remover_test.go create mode 100644 src/arduino.cc/builder/unused_compiled_libraries_remover.go diff --git a/src/arduino.cc/builder/builder.go b/src/arduino.cc/builder/builder.go index 5e446ec2..f521cb1d 100644 --- a/src/arduino.cc/builder/builder.go +++ b/src/arduino.cc/builder/builder.go @@ -94,6 +94,7 @@ func (s *Builder) Run(context map[string]interface{}) error { &RecipeByPrefixSuffixRunner{Prefix: constants.HOOKS_SKETCH_POSTBUILD, Suffix: constants.HOOKS_PATTERN_SUFFIX}, &RecipeByPrefixSuffixRunner{Prefix: constants.HOOKS_LIBRARIES_PREBUILD, Suffix: constants.HOOKS_PATTERN_SUFFIX}, + &UnusedCompiledLibrariesRemover{}, &phases.LibrariesBuilder{}, &RecipeByPrefixSuffixRunner{Prefix: constants.HOOKS_LIBRARIES_POSTBUILD, Suffix: constants.HOOKS_PATTERN_SUFFIX}, diff --git a/src/arduino.cc/builder/test/builder_test.go b/src/arduino.cc/builder/test/builder_test.go index 9acf6f4a..3ec2c459 100644 --- a/src/arduino.cc/builder/test/builder_test.go +++ b/src/arduino.cc/builder/test/builder_test.go @@ -341,3 +341,32 @@ func TestBuilderSketchWithSubfolders(t *testing.T) { err := command.Run(context) NoError(t, err) } + +func TestBuilderSketchBuildPathContainsUnusedPreviouslyCompiledLibrary(t *testing.T) { + DownloadCoresAndToolsAndLibraries(t) + + context := make(map[string]interface{}) + + buildPath := SetupBuildPath(t, context) + defer os.RemoveAll(buildPath) + + NoError(t, os.MkdirAll(filepath.Join(buildPath, constants.FOLDER_LIBRARIES, "SPI"), os.FileMode(0755))) + + context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} + context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} + context[constants.CTX_FQBN] = "arduino:avr:leonardo" + context[constants.CTX_SKETCH_LOCATION] = filepath.Join("downloaded_libraries", "Bridge", "examples", "Bridge", "Bridge.ino") + context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} + context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} + context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" + + command := builder.Builder{} + err := command.Run(context) + NoError(t, err) + + _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_LIBRARIES, "SPI")) + require.Error(t, err) + require.True(t, os.IsNotExist(err)) + _, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_LIBRARIES, "Bridge")) + NoError(t, err) +} diff --git a/src/arduino.cc/builder/test/unused_compiled_libraries_remover_test.go b/src/arduino.cc/builder/test/unused_compiled_libraries_remover_test.go new file mode 100644 index 00000000..1c77bc69 --- /dev/null +++ b/src/arduino.cc/builder/test/unused_compiled_libraries_remover_test.go @@ -0,0 +1,77 @@ +/* + * This file is part of Arduino Builder. + * + * Arduino Builder is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As a special exception, you may use this file as part of a free software + * library without restriction. Specifically, if other files instantiate + * templates or use macros or inline functions from this file, or you compile + * this file and link it with other files to produce an executable, this + * file does not by itself cause the resulting executable to be covered by + * the GNU General Public License. This exception does not however + * invalidate any other reasons why the executable file might be covered by + * the GNU General Public License. + * + * Copyright 2015 Arduino LLC (http://www.arduino.cc/) + */ + +package test + +import ( + "arduino.cc/builder" + "arduino.cc/builder/constants" + "arduino.cc/builder/types" + "github.com/stretchr/testify/require" + "io/ioutil" + "os" + "path/filepath" + "testing" +) + +func TestUnusedCompiledLibrariesRemover(t *testing.T) { + temp, err := ioutil.TempDir("", "test") + NoError(t, err) + defer os.RemoveAll(temp) + + NoError(t, os.MkdirAll(filepath.Join(temp, "SPI"), os.FileMode(0755))) + NoError(t, os.MkdirAll(filepath.Join(temp, "Bridge"), os.FileMode(0755))) + NoError(t, ioutil.WriteFile(filepath.Join(temp, "dummy_file"), []byte{}, os.FileMode(0644))) + + context := make(map[string]interface{}) + context[constants.CTX_LIBRARIES_BUILD_PATH] = temp + context[constants.CTX_IMPORTED_LIBRARIES] = []*types.Library{&types.Library{Name: "Bridge"}} + + cmd := builder.UnusedCompiledLibrariesRemover{} + err = cmd.Run(context) + NoError(t, err) + + _, err = os.Stat(filepath.Join(temp, "SPI")) + require.Error(t, err) + require.True(t, os.IsNotExist(err)) + _, err = os.Stat(filepath.Join(temp, "Bridge")) + NoError(t, err) + _, err = os.Stat(filepath.Join(temp, "dummy_file")) + NoError(t, err) +} + +func TestUnusedCompiledLibrariesRemoverLibDoesNotExist(t *testing.T) { + context := make(map[string]interface{}) + context[constants.CTX_LIBRARIES_BUILD_PATH] = filepath.Join(os.TempDir(), "test") + context[constants.CTX_IMPORTED_LIBRARIES] = []*types.Library{&types.Library{Name: "Bridge"}} + + cmd := builder.UnusedCompiledLibrariesRemover{} + err := cmd.Run(context) + NoError(t, err) +} diff --git a/src/arduino.cc/builder/unused_compiled_libraries_remover.go b/src/arduino.cc/builder/unused_compiled_libraries_remover.go new file mode 100644 index 00000000..07f7ccff --- /dev/null +++ b/src/arduino.cc/builder/unused_compiled_libraries_remover.go @@ -0,0 +1,82 @@ +/* + * This file is part of Arduino Builder. + * + * Arduino Builder is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As a special exception, you may use this file as part of a free software + * library without restriction. Specifically, if other files instantiate + * templates or use macros or inline functions from this file, or you compile + * this file and link it with other files to produce an executable, this + * file does not by itself cause the resulting executable to be covered by + * the GNU General Public License. This exception does not however + * invalidate any other reasons why the executable file might be covered by + * the GNU General Public License. + * + * Copyright 2015 Arduino LLC (http://www.arduino.cc/) + */ + +package builder + +import ( + "arduino.cc/builder/constants" + "arduino.cc/builder/types" + "arduino.cc/builder/utils" + "io/ioutil" + "os" + "path/filepath" +) + +type UnusedCompiledLibrariesRemover struct{} + +func (s *UnusedCompiledLibrariesRemover) Run(context map[string]interface{}) error { + librariesBuildPath := context[constants.CTX_LIBRARIES_BUILD_PATH].(string) + libraries := context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library) + + if len(libraries) == 0 { + return nil + } + + _, err := os.Stat(librariesBuildPath) + if err != nil && os.IsNotExist(err) { + return nil + } + + libraryNames := toLibraryNames(libraries) + + files, err := ioutil.ReadDir(librariesBuildPath) + if err != nil { + return utils.WrapError(err) + } + for _, file := range files { + if file.IsDir() { + if !utils.SliceContains(libraryNames, file.Name()) { + err := os.RemoveAll(filepath.Join(librariesBuildPath, file.Name())) + if err != nil { + return utils.WrapError(err) + } + } + } + } + + return nil +} + +func toLibraryNames(libraries []*types.Library) []string { + libraryNames := []string{} + for _, library := range libraries { + libraryNames = append(libraryNames, library.Name) + } + return libraryNames +} From ccadaaee4b27676cdcf827ba17f2cb0f41be14e5 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 1 Dec 2015 09:53:19 +0100 Subject: [PATCH 66/85] Releasing 1.3.2 Signed-off-by: Federico Fissore --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 0d508fe6..ac97732a 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,7 @@ import ( "syscall" ) -const VERSION = "1.3.1" +const VERSION = "1.3.2" const FLAG_ACTION_COMPILE = "compile" const FLAG_ACTION_PREPROCESS = "preprocess" From ce9d3b25bc925e4388ef95ebcfde9b978557ebc1 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 1 Dec 2015 10:06:58 +0100 Subject: [PATCH 67/85] Even when no libraries are used, precompiled ones must be removed Signed-off-by: Federico Fissore --- .../unused_compiled_libraries_remover_test.go | 27 +++++++++++++++++++ .../unused_compiled_libraries_remover.go | 4 --- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/arduino.cc/builder/test/unused_compiled_libraries_remover_test.go b/src/arduino.cc/builder/test/unused_compiled_libraries_remover_test.go index 1c77bc69..d82af8c0 100644 --- a/src/arduino.cc/builder/test/unused_compiled_libraries_remover_test.go +++ b/src/arduino.cc/builder/test/unused_compiled_libraries_remover_test.go @@ -75,3 +75,30 @@ func TestUnusedCompiledLibrariesRemoverLibDoesNotExist(t *testing.T) { err := cmd.Run(context) NoError(t, err) } + +func TestUnusedCompiledLibrariesRemoverNoUsedLibraries(t *testing.T) { + temp, err := ioutil.TempDir("", "test") + NoError(t, err) + defer os.RemoveAll(temp) + + NoError(t, os.MkdirAll(filepath.Join(temp, "SPI"), os.FileMode(0755))) + NoError(t, os.MkdirAll(filepath.Join(temp, "Bridge"), os.FileMode(0755))) + NoError(t, ioutil.WriteFile(filepath.Join(temp, "dummy_file"), []byte{}, os.FileMode(0644))) + + context := make(map[string]interface{}) + context[constants.CTX_LIBRARIES_BUILD_PATH] = temp + context[constants.CTX_IMPORTED_LIBRARIES] = []*types.Library{} + + cmd := builder.UnusedCompiledLibrariesRemover{} + err = cmd.Run(context) + NoError(t, err) + + _, err = os.Stat(filepath.Join(temp, "SPI")) + require.Error(t, err) + require.True(t, os.IsNotExist(err)) + _, err = os.Stat(filepath.Join(temp, "Bridge")) + require.Error(t, err) + require.True(t, os.IsNotExist(err)) + _, err = os.Stat(filepath.Join(temp, "dummy_file")) + NoError(t, err) +} diff --git a/src/arduino.cc/builder/unused_compiled_libraries_remover.go b/src/arduino.cc/builder/unused_compiled_libraries_remover.go index 07f7ccff..cd743b04 100644 --- a/src/arduino.cc/builder/unused_compiled_libraries_remover.go +++ b/src/arduino.cc/builder/unused_compiled_libraries_remover.go @@ -44,10 +44,6 @@ func (s *UnusedCompiledLibrariesRemover) Run(context map[string]interface{}) err librariesBuildPath := context[constants.CTX_LIBRARIES_BUILD_PATH].(string) libraries := context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library) - if len(libraries) == 0 { - return nil - } - _, err := os.Stat(librariesBuildPath) if err != nil && os.IsNotExist(err) { return nil From 9642ec5e3dca790872daa087b04870a8fcbf75dd Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 1 Dec 2015 10:11:01 +0100 Subject: [PATCH 68/85] Releasing 1.3.3 Signed-off-by: Federico Fissore --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index ac97732a..2c6ae6e6 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,7 @@ import ( "syscall" ) -const VERSION = "1.3.2" +const VERSION = "1.3.3" const FLAG_ACTION_COMPILE = "compile" const FLAG_ACTION_PREPROCESS = "preprocess" From 2d65db882ff0d5c0291c18212738ec78661d69fb Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Wed, 2 Dec 2015 12:05:14 +0100 Subject: [PATCH 69/85] Moved LibraryResolutionResult from accessories into types Signed-off-by: Federico Fissore --- src/arduino.cc/builder/types/accessories.go | 6 ------ src/arduino.cc/builder/types/types.go | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/arduino.cc/builder/types/accessories.go b/src/arduino.cc/builder/types/accessories.go index f37004fa..1d7b7fc2 100644 --- a/src/arduino.cc/builder/types/accessories.go +++ b/src/arduino.cc/builder/types/accessories.go @@ -74,9 +74,3 @@ func (queue *UniqueSourceFolderQueue) Pop() interface{} { func (queue *UniqueSourceFolderQueue) Empty() bool { return queue.Len() == 0 } - -type LibraryResolutionResult struct { - Library *Library - IsLibraryFromPlatform bool - NotUsedLibraries []*Library -} diff --git a/src/arduino.cc/builder/types/types.go b/src/arduino.cc/builder/types/types.go index 7745e7df..a4cf477b 100644 --- a/src/arduino.cc/builder/types/types.go +++ b/src/arduino.cc/builder/types/types.go @@ -169,3 +169,9 @@ type SourceFolder struct { Folder string Recurse bool } + +type LibraryResolutionResult struct { + Library *Library + IsLibraryFromPlatform bool + NotUsedLibraries []*Library +} From f4e9997a9c8957854aa936a8f7ed0149cd88889e Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Fri, 27 Nov 2015 14:24:31 +0100 Subject: [PATCH 70/85] Preprocessor calls to gcc are now saved into the NULL file: "nul" on Windows, "/dev/null" on Linux & OSX Signed-off-by: Federico Fissore --- .../builder/container_find_includes.go | 6 ++---- src/arduino.cc/builder/gcc_preproc_runner.go | 18 ++++++++++-------- src/arduino.cc/builder/utils/utils.go | 7 +++++++ 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/arduino.cc/builder/container_find_includes.go b/src/arduino.cc/builder/container_find_includes.go index 9341248c..35408f21 100644 --- a/src/arduino.cc/builder/container_find_includes.go +++ b/src/arduino.cc/builder/container_find_includes.go @@ -33,9 +33,7 @@ import ( "arduino.cc/builder/constants" "arduino.cc/builder/types" "arduino.cc/builder/utils" - "math/rand" "path/filepath" - "strconv" ) type ContainerFindIncludes struct{} @@ -100,12 +98,12 @@ func runCommand(context map[string]interface{}, command types.Command) error { } func findIncludesUntilDone(context map[string]interface{}, sourceFilePath string) error { - targetFileName := filepath.Base(sourceFilePath) + "_" + strconv.Itoa(rand.Int()) + "_preprocessed.cpp" + targetFilePath := utils.NULLFile() importedLibraries := context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library) done := false for !done { commands := []types.Command{ - &GCCPreprocRunnerForDiscoveringIncludes{SourceFilePath: sourceFilePath, TargetFileName: targetFileName}, + &GCCPreprocRunnerForDiscoveringIncludes{SourceFilePath: sourceFilePath, TargetFilePath: targetFilePath}, &IncludesFinderWithRegExp{ContextField: constants.CTX_GCC_MINUS_E_SOURCE}, &IncludesToIncludeFolders{}, } diff --git a/src/arduino.cc/builder/gcc_preproc_runner.go b/src/arduino.cc/builder/gcc_preproc_runner.go index d67e322a..8950c12c 100644 --- a/src/arduino.cc/builder/gcc_preproc_runner.go +++ b/src/arduino.cc/builder/gcc_preproc_runner.go @@ -65,11 +65,11 @@ func (s *GCCPreprocRunner) Run(context map[string]interface{}) error { type GCCPreprocRunnerForDiscoveringIncludes struct { SourceFilePath string - TargetFileName string + TargetFilePath string } func (s *GCCPreprocRunnerForDiscoveringIncludes) Run(context map[string]interface{}) error { - properties, _, err := prepareGCCPreprocRecipeProperties(context, s.SourceFilePath, s.TargetFileName) + properties, _, err := prepareGCCPreprocRecipeProperties(context, s.SourceFilePath, s.TargetFilePath) if err != nil { return utils.WrapError(err) } @@ -86,13 +86,15 @@ func (s *GCCPreprocRunnerForDiscoveringIncludes) Run(context map[string]interfac return nil } -func prepareGCCPreprocRecipeProperties(context map[string]interface{}, sourceFilePath string, targetFileName string) (map[string]string, string, error) { - preprocPath := context[constants.CTX_PREPROC_PATH].(string) - err := utils.EnsureFolderExists(preprocPath) - if err != nil { - return nil, "", utils.WrapError(err) +func prepareGCCPreprocRecipeProperties(context map[string]interface{}, sourceFilePath string, targetFilePath string) (map[string]string, string, error) { + if !filepath.IsAbs(targetFilePath) { + preprocPath := context[constants.CTX_PREPROC_PATH].(string) + err := utils.EnsureFolderExists(preprocPath) + if err != nil { + return nil, "", utils.WrapError(err) + } + targetFilePath = filepath.Join(preprocPath, targetFilePath) } - targetFilePath := filepath.Join(preprocPath, targetFileName) buildProperties := utils.GetMapStringStringOrDefault(context, constants.CTX_BUILD_PROPERTIES) properties := utils.MergeMapsOfStrings(make(map[string]string), buildProperties) diff --git a/src/arduino.cc/builder/utils/utils.go b/src/arduino.cc/builder/utils/utils.go index ce01fdc3..f41561b0 100644 --- a/src/arduino.cc/builder/utils/utils.go +++ b/src/arduino.cc/builder/utils/utils.go @@ -462,3 +462,10 @@ func TagHasAtLeastOneField(tag map[string]string, fields []string) (string, bool } return "", false } + +func NULLFile() string { + if runtime.GOOS == "windows" { + return "nul" + } + return "/dev/null" +} From 2f1f64c57e8366a17e45cffe9383c09504a09f78 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Wed, 2 Dec 2015 16:33:22 +0100 Subject: [PATCH 71/85] Releasing 1.3.4 Signed-off-by: Federico Fissore --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 2c6ae6e6..226e983b 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,7 @@ import ( "syscall" ) -const VERSION = "1.3.3" +const VERSION = "1.3.4" const FLAG_ACTION_COMPILE = "compile" const FLAG_ACTION_PREPROCESS = "preprocess" From afb26d69040956c92a72f6996c9f14835586a0d9 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Thu, 3 Dec 2015 09:38:54 +0100 Subject: [PATCH 72/85] Windows: fixed wrong NULL file check Signed-off-by: Federico Fissore --- src/arduino.cc/builder/gcc_preproc_runner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arduino.cc/builder/gcc_preproc_runner.go b/src/arduino.cc/builder/gcc_preproc_runner.go index 8950c12c..5c5b87d1 100644 --- a/src/arduino.cc/builder/gcc_preproc_runner.go +++ b/src/arduino.cc/builder/gcc_preproc_runner.go @@ -87,7 +87,7 @@ func (s *GCCPreprocRunnerForDiscoveringIncludes) Run(context map[string]interfac } func prepareGCCPreprocRecipeProperties(context map[string]interface{}, sourceFilePath string, targetFilePath string) (map[string]string, string, error) { - if !filepath.IsAbs(targetFilePath) { + if targetFilePath != utils.NULLFile() { preprocPath := context[constants.CTX_PREPROC_PATH].(string) err := utils.EnsureFolderExists(preprocPath) if err != nil { From be64c59793f7f4fd669a0bdac392f54be89c50f8 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Thu, 3 Dec 2015 09:46:58 +0100 Subject: [PATCH 73/85] Releasing 1.3.5 Signed-off-by: Federico Fissore --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 226e983b..7c437b49 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,7 @@ import ( "syscall" ) -const VERSION = "1.3.4" +const VERSION = "1.3.5" const FLAG_ACTION_COMPILE = "compile" const FLAG_ACTION_PREPROCESS = "preprocess" From 892ebf9dc0844daf810c94e067dbce64f5e4111b Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Fri, 4 Dec 2015 12:49:01 +0100 Subject: [PATCH 74/85] Moving MD5Sum function to utils Signed-off-by: Federico Fissore --- src/arduino.cc/builder/generate_buildpath_if_missing.go | 5 +---- src/arduino.cc/builder/utils/utils.go | 7 +++++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/arduino.cc/builder/generate_buildpath_if_missing.go b/src/arduino.cc/builder/generate_buildpath_if_missing.go index 89a3fb35..886ea3f0 100644 --- a/src/arduino.cc/builder/generate_buildpath_if_missing.go +++ b/src/arduino.cc/builder/generate_buildpath_if_missing.go @@ -33,8 +33,6 @@ import ( "arduino.cc/builder/constants" "arduino.cc/builder/i18n" "arduino.cc/builder/utils" - "crypto/md5" - "encoding/hex" "os" "path/filepath" "strings" @@ -48,8 +46,7 @@ func (s *GenerateBuildPathIfMissing) Run(context map[string]interface{}) error { } sketchLocation := context[constants.CTX_SKETCH_LOCATION].(string) - md5sumBytes := md5.Sum([]byte(sketchLocation)) - md5sum := hex.EncodeToString(md5sumBytes[:]) + md5sum := utils.MD5Sum([]byte(sketchLocation)) buildPath := filepath.Join(os.TempDir(), "arduino-sketch-"+strings.ToUpper(md5sum)) _, err := os.Stat(buildPath) diff --git a/src/arduino.cc/builder/utils/utils.go b/src/arduino.cc/builder/utils/utils.go index f41561b0..8a3a53a5 100644 --- a/src/arduino.cc/builder/utils/utils.go +++ b/src/arduino.cc/builder/utils/utils.go @@ -34,6 +34,8 @@ import ( "arduino.cc/builder/gohasissues" "arduino.cc/builder/i18n" "arduino.cc/builder/types" + "crypto/md5" + "encoding/hex" "github.com/go-errors/errors" "io/ioutil" "os" @@ -469,3 +471,8 @@ func NULLFile() string { } return "/dev/null" } + +func MD5Sum(data []byte) string { + md5sumBytes := md5.Sum(data) + return hex.EncodeToString(md5sumBytes[:]) +} From 0329b1c6f8d90c4c6a0be98d5a62d3e9c20af210 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Fri, 4 Dec 2015 12:49:44 +0100 Subject: [PATCH 75/85] Writing additional sketch files to target folder ONLY if they changed. Fixes #77 Signed-off-by: Federico Fissore --- .../builder/additional_sketch_files_copier.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/arduino.cc/builder/additional_sketch_files_copier.go b/src/arduino.cc/builder/additional_sketch_files_copier.go index 5610dd25..2bceb723 100644 --- a/src/arduino.cc/builder/additional_sketch_files_copier.go +++ b/src/arduino.cc/builder/additional_sketch_files_copier.go @@ -33,6 +33,7 @@ import ( "arduino.cc/builder/constants" "arduino.cc/builder/types" "arduino.cc/builder/utils" + "bytes" "io/ioutil" "path/filepath" ) @@ -67,8 +68,22 @@ func (s *AdditionalSketchFilesCopier) Run(context map[string]interface{}) error return utils.WrapError(err) } - utils.WriteFileBytes(targetFilePath, bytes) + if targetFileChanged(bytes, targetFilePath) { + err := utils.WriteFileBytes(targetFilePath, bytes) + if err != nil { + return utils.WrapError(err) + } + } } return nil } + +func targetFileChanged(currentBytes []byte, targetFilePath string) bool { + oldBytes, err := ioutil.ReadFile(targetFilePath) + if err != nil { + return true + } + + return bytes.Compare(currentBytes, oldBytes) != 0 +} From 833d393a91c6ea5d9d4475a51acca29bb7a4080c Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Fri, 4 Dec 2015 13:08:37 +0100 Subject: [PATCH 76/85] Testing that AdditionalSketchFilesCopier doesn't copy unchanged files. See #77 Signed-off-by: Federico Fissore --- .../additional_sketch_files_copier_test.go | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/arduino.cc/builder/test/additional_sketch_files_copier_test.go b/src/arduino.cc/builder/test/additional_sketch_files_copier_test.go index 2425cd83..326f6d77 100644 --- a/src/arduino.cc/builder/test/additional_sketch_files_copier_test.go +++ b/src/arduino.cc/builder/test/additional_sketch_files_copier_test.go @@ -39,6 +39,7 @@ import ( "path/filepath" "sort" "testing" + "time" ) type ByFileInfoName []os.FileInfo @@ -90,3 +91,43 @@ func TestCopyOtherFiles(t *testing.T) { require.Equal(t, 1, len(files)) require.Equal(t, "helper.h", files[0].Name()) } + +func TestCopyOtherFilesOnlyIfChanged(t *testing.T) { + context := make(map[string]interface{}) + + buildPath := SetupBuildPath(t, context) + defer os.RemoveAll(buildPath) + + context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch1", "sketch.ino") + + commands := []types.Command{ + &builder.SetupHumanLoggerIfMissing{}, + &builder.AddAdditionalEntriesToContext{}, + &builder.SketchLoader{}, + &builder.AdditionalSketchFilesCopier{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + headerStatBefore, err := os.Stat(filepath.Join(buildPath, constants.FOLDER_SKETCH, "header.h")) + NoError(t, err) + + time.Sleep(2 * time.Second) + + context = make(map[string]interface{}) + context[constants.CTX_BUILD_PATH] = buildPath + context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch1", "sketch.ino") + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + headerStatAfter, err := os.Stat(filepath.Join(buildPath, constants.FOLDER_SKETCH, "header.h")) + NoError(t, err) + + require.Equal(t, headerStatBefore.ModTime().Unix(), headerStatAfter.ModTime().Unix()) +} From c8509d0548c896581c32df32a4cb0ee9e3f83ef3 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Fri, 4 Dec 2015 13:56:31 +0100 Subject: [PATCH 77/85] Releasing 1.3.6 Signed-off-by: Federico Fissore --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 7c437b49..e6e458bb 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,7 @@ import ( "syscall" ) -const VERSION = "1.3.5" +const VERSION = "1.3.6" const FLAG_ACTION_COMPILE = "compile" const FLAG_ACTION_PREPROCESS = "preprocess" From 90ba6d5684fe0cbac4efaef5dd806b0feb533faa Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Fri, 4 Dec 2015 16:34:21 +0100 Subject: [PATCH 78/85] Removed useless TODO Signed-off-by: Federico Fissore --- src/arduino.cc/builder/test/helper_tools_downloader.go | 1 - 1 file changed, 1 deletion(-) diff --git a/src/arduino.cc/builder/test/helper_tools_downloader.go b/src/arduino.cc/builder/test/helper_tools_downloader.go index 9922d79d..04e18c54 100644 --- a/src/arduino.cc/builder/test/helper_tools_downloader.go +++ b/src/arduino.cc/builder/test/helper_tools_downloader.go @@ -142,7 +142,6 @@ func DownloadCoresAndToolsAndLibraries(t *testing.T) { patchFiles(t) } -// FIXME: once patched cores are released, patching them will be unnecessary func patchFiles(t *testing.T) { files, err := ioutil.ReadDir(PATCHES_FOLDER) NoError(t, err) From f15ff61f3f127ca99b35664e9f65b32cfa2d974b Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 23 Nov 2015 01:22:07 +0100 Subject: [PATCH 79/85] Refactoring: ctags parser now uses a CTag structure Signed-off-by: Cristian Maglie --- .../collect_ctags_from_sketch_files.go | 6 +- ...ototypes_from_source_and_preproc_source.go | 10 +- src/arduino.cc/builder/ctags_parser.go | 173 ++++++---- src/arduino.cc/builder/ctags_to_prototypes.go | 39 ++- src/arduino.cc/builder/prototypes_adder.go | 2 +- .../builder/test/ctags_parser_test.go | 326 +++++++++--------- src/arduino.cc/builder/types/types.go | 6 +- src/arduino.cc/builder/utils/utils.go | 9 - 8 files changed, 300 insertions(+), 271 deletions(-) diff --git a/src/arduino.cc/builder/collect_ctags_from_sketch_files.go b/src/arduino.cc/builder/collect_ctags_from_sketch_files.go index f7106dfc..3a111a51 100644 --- a/src/arduino.cc/builder/collect_ctags_from_sketch_files.go +++ b/src/arduino.cc/builder/collect_ctags_from_sketch_files.go @@ -42,10 +42,10 @@ func (s *CollectCTagsFromSketchFiles) Run(context map[string]interface{}) error sketch := context[constants.CTX_SKETCH].(*types.Sketch) sketchFileNames := collectSketchFileNamesFrom(sketch) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) - ctagsOfSketch := []map[string]string{} + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*CTag) + ctagsOfSketch := []*CTag{} for _, ctag := range ctags { - if utils.SliceContains(sketchFileNames, strings.Replace(ctag[FIELD_FILENAME], "\\\\", "\\", -1)) { + if utils.SliceContains(sketchFileNames, strings.Replace(ctag.Filename, "\\\\", "\\", -1)) { ctagsOfSketch = append(ctagsOfSketch, ctag) } } diff --git a/src/arduino.cc/builder/compare_prototypes_from_source_and_preproc_source.go b/src/arduino.cc/builder/compare_prototypes_from_source_and_preproc_source.go index 718dc542..72596e4f 100644 --- a/src/arduino.cc/builder/compare_prototypes_from_source_and_preproc_source.go +++ b/src/arduino.cc/builder/compare_prototypes_from_source_and_preproc_source.go @@ -36,10 +36,10 @@ import ( type ComparePrototypesFromSourceAndPreprocSource struct{} func (s *ComparePrototypesFromSourceAndPreprocSource) Run(context map[string]interface{}) error { - ctagsOfSource := context[constants.CTX_CTAGS_OF_SOURCE].([]map[string]string) - ctagsOfPreprocSource := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) + ctagsOfSource := context[constants.CTX_CTAGS_OF_SOURCE].([]*CTag) + ctagsOfPreprocSource := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*CTag) - actualCTags := []map[string]string{} + actualCTags := []*CTag{} for _, ctagOfPreprocSource := range ctagsOfPreprocSource { if sliceContainsCTag(ctagsOfSource, ctagOfPreprocSource) { actualCTags = append(actualCTags, ctagOfPreprocSource) @@ -51,9 +51,9 @@ func (s *ComparePrototypesFromSourceAndPreprocSource) Run(context map[string]int return nil } -func sliceContainsCTag(slice []map[string]string, target map[string]string) bool { +func sliceContainsCTag(slice []*CTag, target *CTag) bool { for _, value := range slice { - if value[FIELD_FUNCTION_NAME] == target[FIELD_FUNCTION_NAME] { + if value.FunctionName == target.FunctionName { return true } } diff --git a/src/arduino.cc/builder/ctags_parser.go b/src/arduino.cc/builder/ctags_parser.go index 9c086165..76703fef 100644 --- a/src/arduino.cc/builder/ctags_parser.go +++ b/src/arduino.cc/builder/ctags_parser.go @@ -39,44 +39,52 @@ import ( "strings" ) -const FIELD_KIND = "kind" -const FIELD_LINE = "line" -const FIELD_SIGNATURE = "signature" -const FIELD_RETURNTYPE = "returntype" -const FIELD_CODE = "code" -const FIELD_CLASS = "class" -const FIELD_STRUCT = "struct" -const FIELD_NAMESPACE = "namespace" -const FIELD_FILENAME = "filename" -const FIELD_SKIP = "skipMe" -const FIELD_FUNCTION_NAME = "functionName" - const KIND_PROTOTYPE = "prototype" const KIND_FUNCTION = "function" -const KIND_PROTOTYPE_MODIFIERS = "prototype_modifiers" + +//const KIND_PROTOTYPE_MODIFIERS = "prototype_modifiers" const TEMPLATE = "template" const STATIC = "static" -const TRUE = "true" -var FIELDS = map[string]bool{"kind": true, "line": true, "typeref": true, "signature": true, "returntype": true, "class": true, "struct": true, "namespace": true} -var KNOWN_TAG_KINDS = map[string]bool{"prototype": true, "function": true} -var FIELDS_MARKING_UNHANDLED_TAGS = []string{FIELD_CLASS, FIELD_STRUCT, FIELD_NAMESPACE} +var KNOWN_TAG_KINDS = map[string]bool{ + "prototype": true, + "function": true, +} type CTagsParser struct{} +type CTag struct { + FunctionName string + Kind string + Line int + Signature string + Returntype string + Code string + Class string + Struct string + Namespace string + Filename string + Typeref string + SkipMe bool + + Prototype string + Function string + PrototypeModifiers string +} + func (s *CTagsParser) Run(context map[string]interface{}) error { rows := strings.Split(context[constants.CTX_CTAGS_OUTPUT].(string), "\n") rows = removeEmpty(rows) - var tags []map[string]string + var tags []*CTag for _, row := range rows { tags = append(tags, parseTag(row)) } skipTagsWhere(tags, tagIsUnknown, context) - skipTagsWithField(tags, FIELDS_MARKING_UNHANDLED_TAGS, context) + skipTagsWhere(tags, tagIsUnhandled, context) skipTagsWhere(tags, signatureContainsDefaultArg, context) addPrototypes(tags) removeDefinedProtypes(tags, context) @@ -88,90 +96,90 @@ func (s *CTagsParser) Run(context map[string]interface{}) error { return nil } -func addPrototypes(tags []map[string]string) { +func addPrototypes(tags []*CTag) { for _, tag := range tags { - if tag[FIELD_SKIP] != TRUE { - addPrototype(tag) + if !tag.SkipMe { + tag.AddPrototype() } } } -func addPrototype(tag map[string]string) { - if strings.Index(tag[FIELD_RETURNTYPE], TEMPLATE) == 0 || strings.Index(tag[FIELD_CODE], TEMPLATE) == 0 { - code := tag[FIELD_CODE] +func (tag *CTag) AddPrototype() { + if strings.Index(tag.Returntype, TEMPLATE) == 0 || strings.Index(tag.Code, TEMPLATE) == 0 { + code := tag.Code if strings.Contains(code, "{") { code = code[:strings.Index(code, "{")] } else { code = code[:strings.LastIndex(code, ")")+1] } - tag[KIND_PROTOTYPE] = code + ";" + tag.Prototype = code + ";" return } - tag[KIND_PROTOTYPE] = tag[FIELD_RETURNTYPE] + " " + tag[FIELD_FUNCTION_NAME] + tag[FIELD_SIGNATURE] + ";" + tag.Prototype = tag.Returntype + " " + tag.FunctionName + tag.Signature + ";" - tag[KIND_PROTOTYPE_MODIFIERS] = "" - if strings.Index(tag[FIELD_CODE], STATIC+" ") != -1 { - tag[KIND_PROTOTYPE_MODIFIERS] = tag[KIND_PROTOTYPE_MODIFIERS] + " " + STATIC + tag.PrototypeModifiers = "" + if strings.Index(tag.Code, STATIC+" ") != -1 { + tag.PrototypeModifiers = tag.PrototypeModifiers + " " + STATIC } - tag[KIND_PROTOTYPE_MODIFIERS] = strings.TrimSpace(tag[KIND_PROTOTYPE_MODIFIERS]) + tag.PrototypeModifiers = strings.TrimSpace(tag.PrototypeModifiers) } -func removeDefinedProtypes(tags []map[string]string, context map[string]interface{}) { +func removeDefinedProtypes(tags []*CTag, context map[string]interface{}) { definedPrototypes := make(map[string]bool) for _, tag := range tags { - if tag[FIELD_KIND] == KIND_PROTOTYPE { - definedPrototypes[tag[KIND_PROTOTYPE]] = true + if tag.Kind == KIND_PROTOTYPE { + definedPrototypes[tag.Prototype] = true } } for _, tag := range tags { - if definedPrototypes[tag[KIND_PROTOTYPE]] { + if definedPrototypes[tag.Prototype] { if utils.DebugLevel(context) >= 10 { - utils.Logger(context).Fprintln(os.Stderr, constants.MSG_SKIPPING_TAG_ALREADY_DEFINED, tag[FIELD_FUNCTION_NAME]) + utils.Logger(context).Fprintln(os.Stderr, constants.MSG_SKIPPING_TAG_ALREADY_DEFINED, tag.FunctionName) } - tag[FIELD_SKIP] = TRUE + tag.SkipMe = true } } } -func removeDuplicate(tags []map[string]string) { +func removeDuplicate(tags []*CTag) { definedPrototypes := make(map[string]bool) for _, tag := range tags { - if !definedPrototypes[tag[KIND_PROTOTYPE]] { - definedPrototypes[tag[KIND_PROTOTYPE]] = true + if !definedPrototypes[tag.Prototype] { + definedPrototypes[tag.Prototype] = true } else { - tag[FIELD_SKIP] = TRUE + tag.SkipMe = true } } } -type skipFuncType func(tag map[string]string) bool +type skipFuncType func(tag *CTag) bool -func skipTagsWhere(tags []map[string]string, skipFunc skipFuncType, context map[string]interface{}) { +func skipTagsWhere(tags []*CTag, skipFunc skipFuncType, context map[string]interface{}) { for _, tag := range tags { - if tag[FIELD_SKIP] != TRUE { + if !tag.SkipMe { skip := skipFunc(tag) if skip && utils.DebugLevel(context) >= 10 { - utils.Logger(context).Fprintln(os.Stderr, constants.MSG_SKIPPING_TAG_WITH_REASON, tag[FIELD_FUNCTION_NAME], runtime.FuncForPC(reflect.ValueOf(skipFunc).Pointer()).Name()) + utils.Logger(context).Fprintln(os.Stderr, constants.MSG_SKIPPING_TAG_WITH_REASON, tag.FunctionName, runtime.FuncForPC(reflect.ValueOf(skipFunc).Pointer()).Name()) } - tag[FIELD_SKIP] = strconv.FormatBool(skip) + tag.SkipMe = skip } } } -func signatureContainsDefaultArg(tag map[string]string) bool { - return strings.Contains(tag[FIELD_SIGNATURE], "=") +func signatureContainsDefaultArg(tag *CTag) bool { + return strings.Contains(tag.Signature, "=") } -func prototypeAndCodeDontMatch(tag map[string]string) bool { - if tag[FIELD_SKIP] == TRUE { +func prototypeAndCodeDontMatch(tag *CTag) bool { + if tag.SkipMe { return true } - code := removeSpacesAndTabs(tag[FIELD_CODE]) - prototype := removeSpacesAndTabs(tag[KIND_PROTOTYPE]) + code := removeSpacesAndTabs(tag.Code) + prototype := removeSpacesAndTabs(tag.Prototype) prototype = removeTralingSemicolon(prototype) return strings.Index(code, prototype) == -1 @@ -187,41 +195,66 @@ func removeSpacesAndTabs(s string) string { return s } -func skipTagsWithField(tags []map[string]string, fields []string, context map[string]interface{}) { - for _, tag := range tags { - if field, skip := utils.TagHasAtLeastOneField(tag, fields); skip { - if utils.DebugLevel(context) >= 10 { - utils.Logger(context).Fprintln(os.Stderr, constants.MSG_SKIPPING_TAG_BECAUSE_HAS_FIELD, field) - } - tag[FIELD_SKIP] = TRUE - } +func tagIsUnhandled(tag *CTag) bool { + return !tag.IsHandled() +} + +func (tag *CTag) IsHandled() bool { + if tag.Class != "" { + return false + } + if tag.Struct != "" { + return false + } + if tag.Namespace != "" { + return false } + return true } -func tagIsUnknown(tag map[string]string) bool { - return !KNOWN_TAG_KINDS[tag[FIELD_KIND]] +func tagIsUnknown(tag *CTag) bool { + return !KNOWN_TAG_KINDS[tag.Kind] } -func parseTag(row string) map[string]string { - tag := make(map[string]string) +func parseTag(row string) *CTag { + tag := &CTag{} parts := strings.Split(row, "\t") - tag[FIELD_FUNCTION_NAME] = parts[0] - tag[FIELD_FILENAME] = parts[1] + tag.FunctionName = parts[0] + tag.Filename = parts[1] parts = parts[2:] for _, part := range parts { if strings.Contains(part, ":") { - field := part[:strings.Index(part, ":")] - if FIELDS[field] { - tag[field] = strings.TrimSpace(part[strings.Index(part, ":")+1:]) + colon := strings.Index(part, ":") + field := part[:colon] + value := strings.TrimSpace(part[colon+1:]) + switch field { + case "kind": + tag.Kind = value + case "line": + val, _ := strconv.Atoi(value) + // TODO: Check err from strconv.Atoi + tag.Line = val + case "typeref": + tag.Typeref = value + case "signature": + tag.Signature = value + case "returntype": + tag.Returntype = value + case "class": + tag.Class = value + case "struct": + tag.Struct = value + case "namespace": + tag.Namespace = value } } } if strings.Contains(row, "/^") && strings.Contains(row, "$/;") { - tag[FIELD_CODE] = row[strings.Index(row, "/^")+2 : strings.Index(row, "$/;")] + tag.Code = row[strings.Index(row, "/^")+2 : strings.Index(row, "$/;")] } return tag diff --git a/src/arduino.cc/builder/ctags_to_prototypes.go b/src/arduino.cc/builder/ctags_to_prototypes.go index b7f20477..d7d206ca 100644 --- a/src/arduino.cc/builder/ctags_to_prototypes.go +++ b/src/arduino.cc/builder/ctags_to_prototypes.go @@ -33,14 +33,13 @@ import ( "arduino.cc/builder/constants" "arduino.cc/builder/types" "arduino.cc/builder/utils" - "strconv" "strings" ) type CTagsToPrototypes struct{} func (s *CTagsToPrototypes) Run(context map[string]interface{}) error { - tags := context[constants.CTX_COLLECTED_CTAGS].([]map[string]string) + tags := context[constants.CTX_COLLECTED_CTAGS].([]*CTag) lineWhereToInsertPrototypes, err := findLineWhereToInsertPrototypes(tags) if err != nil { @@ -56,7 +55,7 @@ func (s *CTagsToPrototypes) Run(context map[string]interface{}) error { return nil } -func findLineWhereToInsertPrototypes(tags []map[string]string) (int, error) { +func findLineWhereToInsertPrototypes(tags []*CTag) (int, error) { firstFunctionLine, err := firstFunctionAtLine(tags) if err != nil { return -1, utils.WrapError(err) @@ -78,50 +77,56 @@ func findLineWhereToInsertPrototypes(tags []map[string]string) (int, error) { } } -func firstFunctionPointerUsedAsArgument(tags []map[string]string) (int, error) { +func firstFunctionPointerUsedAsArgument(tags []*CTag) (int, error) { functionNames := collectFunctionNames(tags) for _, tag := range tags { if functionNameUsedAsFunctionPointerIn(tag, functionNames) { - return strconv.Atoi(tag[FIELD_LINE]) + return tag.Line, nil } } return -1, nil } -func functionNameUsedAsFunctionPointerIn(tag map[string]string, functionNames []string) bool { +func functionNameUsedAsFunctionPointerIn(tag *CTag, functionNames []string) bool { for _, functionName := range functionNames { - if strings.Index(tag[FIELD_CODE], "&"+functionName) != -1 { + if strings.Index(tag.Code, "&"+functionName) != -1 { return true } } return false } -func collectFunctionNames(tags []map[string]string) []string { +func collectFunctionNames(tags []*CTag) []string { names := []string{} for _, tag := range tags { - if tag[FIELD_KIND] == KIND_FUNCTION { - names = append(names, tag[FIELD_FUNCTION_NAME]) + if tag.Kind == KIND_FUNCTION { + names = append(names, tag.FunctionName) } } return names } -func firstFunctionAtLine(tags []map[string]string) (int, error) { +func firstFunctionAtLine(tags []*CTag) (int, error) { for _, tag := range tags { - _, tagHasAtLeastOneField := utils.TagHasAtLeastOneField(tag, FIELDS_MARKING_UNHANDLED_TAGS) - if !tagIsUnknown(tag) && !tagHasAtLeastOneField && tag[FIELD_KIND] == KIND_FUNCTION { - return strconv.Atoi(tag[FIELD_LINE]) + if !tagIsUnknown(tag) && tag.IsHandled() && tag.Kind == KIND_FUNCTION { + return tag.Line, nil } } return -1, nil } -func toPrototypes(tags []map[string]string) []*types.Prototype { +func toPrototypes(tags []*CTag) []*types.Prototype { prototypes := []*types.Prototype{} for _, tag := range tags { - if tag[FIELD_SKIP] != TRUE { - prototype := &types.Prototype{FunctionName: tag[FIELD_FUNCTION_NAME], File: tag[FIELD_FILENAME], Prototype: tag[KIND_PROTOTYPE], Modifiers: tag[KIND_PROTOTYPE_MODIFIERS], Line: tag[FIELD_LINE], Fields: tag} + if !tag.SkipMe { + prototype := &types.Prototype{ + FunctionName: tag.FunctionName, + File: tag.Filename, + Prototype: tag.Prototype, + Modifiers: tag.PrototypeModifiers, + Line: tag.Line, + //Fields: tag, + } prototypes = append(prototypes, prototype) } } diff --git a/src/arduino.cc/builder/prototypes_adder.go b/src/arduino.cc/builder/prototypes_adder.go index 40c84f5e..fe58c8b5 100644 --- a/src/arduino.cc/builder/prototypes_adder.go +++ b/src/arduino.cc/builder/prototypes_adder.go @@ -78,7 +78,7 @@ func composePrototypeSection(line int, prototypes []*types.Prototype) string { func joinPrototypes(prototypes []*types.Prototype) string { prototypesSlice := []string{} for _, proto := range prototypes { - prototypesSlice = append(prototypesSlice, "#line "+proto.Line+" \""+proto.File+"\"") + prototypesSlice = append(prototypesSlice, "#line "+strconv.Itoa(proto.Line)+" \""+proto.File+"\"") prototypeParts := []string{} if proto.Modifiers != "" { prototypeParts = append(prototypeParts, proto.Modifiers) diff --git a/src/arduino.cc/builder/test/ctags_parser_test.go b/src/arduino.cc/builder/test/ctags_parser_test.go index 80a18fa4..fba7629c 100644 --- a/src/arduino.cc/builder/test/ctags_parser_test.go +++ b/src/arduino.cc/builder/test/ctags_parser_test.go @@ -49,41 +49,41 @@ func TestCTagsParserShouldListPrototypes(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) require.Equal(t, 8, len(ctags)) idx := 0 - require.Equal(t, "server", ctags[idx]["functionName"]) - require.Equal(t, "variable", ctags[idx]["kind"]) - require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx]["filename"]) + require.Equal(t, "server", ctags[idx].FunctionName) + require.Equal(t, "variable", ctags[idx].Kind) + require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx].Filename) idx++ - require.Equal(t, "setup", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) - require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx]["filename"]) + require.Equal(t, "setup", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) + require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx].Filename) idx++ - require.Equal(t, "loop", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) - require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx]["filename"]) + require.Equal(t, "loop", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) + require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx].Filename) idx++ - require.Equal(t, "process", ctags[idx]["functionName"]) - require.Equal(t, "prototype", ctags[idx]["kind"]) - require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx]["filename"]) + require.Equal(t, "process", ctags[idx].FunctionName) + require.Equal(t, "prototype", ctags[idx].Kind) + require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx].Filename) idx++ - require.Equal(t, "process", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) - require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx]["filename"]) + require.Equal(t, "process", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) + require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx].Filename) idx++ - require.Equal(t, "digitalCommand", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) - require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx]["filename"]) + require.Equal(t, "digitalCommand", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) + require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx].Filename) idx++ - require.Equal(t, "analogCommand", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) - require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx]["filename"]) + require.Equal(t, "analogCommand", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) + require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx].Filename) idx++ - require.Equal(t, "modeCommand", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) - require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx]["filename"]) + require.Equal(t, "modeCommand", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) + require.Equal(t, "/tmp/sketch7210316334309249705.cpp", ctags[idx].Filename) } func TestCTagsParserShouldListTemplates(t *testing.T) { @@ -97,19 +97,19 @@ func TestCTagsParserShouldListTemplates(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) require.Equal(t, 3, len(ctags)) idx := 0 - require.Equal(t, "minimum", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) - require.Equal(t, "(T a, T b)", ctags[idx]["signature"]) + require.Equal(t, "minimum", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) + require.Equal(t, "(T a, T b)", ctags[idx].Signature) idx++ - require.Equal(t, "setup", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "setup", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) idx++ - require.Equal(t, "loop", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "loop", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) } func TestCTagsParserShouldListTemplates2(t *testing.T) { @@ -123,23 +123,23 @@ func TestCTagsParserShouldListTemplates2(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) require.Equal(t, 4, len(ctags)) idx := 0 - require.Equal(t, "setup", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "setup", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) idx++ - require.Equal(t, "loop", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "loop", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) idx++ - require.Equal(t, "SRAM_writeAnything", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) - require.Equal(t, "(int ee, const T& value)", ctags[idx]["signature"]) + require.Equal(t, "SRAM_writeAnything", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) + require.Equal(t, "(int ee, const T& value)", ctags[idx].Signature) idx++ - require.Equal(t, "SRAM_readAnything", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) - require.Equal(t, "(int ee, T& value)", ctags[idx]["signature"]) + require.Equal(t, "SRAM_readAnything", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) + require.Equal(t, "(int ee, T& value)", ctags[idx].Signature) } func TestCTagsParserShouldDealWithClasses(t *testing.T) { @@ -153,15 +153,15 @@ func TestCTagsParserShouldDealWithClasses(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) require.Equal(t, 2, len(ctags)) idx := 0 - require.Equal(t, "SleepCycle", ctags[idx]["functionName"]) - require.Equal(t, "prototype", ctags[idx]["kind"]) + require.Equal(t, "SleepCycle", ctags[idx].FunctionName) + require.Equal(t, "prototype", ctags[idx].Kind) idx++ - require.Equal(t, "SleepCycle", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "SleepCycle", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) } func TestCTagsParserShouldDealWithStructs(t *testing.T) { @@ -175,25 +175,25 @@ func TestCTagsParserShouldDealWithStructs(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) require.Equal(t, 5, len(ctags)) idx := 0 - require.Equal(t, "A_NEW_TYPE", ctags[idx]["functionName"]) - require.Equal(t, "struct", ctags[idx]["kind"]) + require.Equal(t, "A_NEW_TYPE", ctags[idx].FunctionName) + require.Equal(t, "struct", ctags[idx].Kind) idx++ - require.Equal(t, "foo", ctags[idx]["functionName"]) - require.Equal(t, "variable", ctags[idx]["kind"]) - require.Equal(t, "struct:A_NEW_TYPE", ctags[idx]["typeref"]) + require.Equal(t, "foo", ctags[idx].FunctionName) + require.Equal(t, "variable", ctags[idx].Kind) + require.Equal(t, "struct:A_NEW_TYPE", ctags[idx].Typeref) idx++ - require.Equal(t, "setup", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "setup", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) idx++ - require.Equal(t, "loop", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "loop", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) idx++ - require.Equal(t, "dostuff", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "dostuff", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) } func TestCTagsParserShouldDealWithMacros(t *testing.T) { @@ -207,33 +207,33 @@ func TestCTagsParserShouldDealWithMacros(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) require.Equal(t, 8, len(ctags)) idx := 0 - require.Equal(t, "DEBUG", ctags[idx]["functionName"]) - require.Equal(t, "macro", ctags[idx]["kind"]) + require.Equal(t, "DEBUG", ctags[idx].FunctionName) + require.Equal(t, "macro", ctags[idx].Kind) idx++ - require.Equal(t, "DISABLED", ctags[idx]["functionName"]) - require.Equal(t, "macro", ctags[idx]["kind"]) + require.Equal(t, "DISABLED", ctags[idx].FunctionName) + require.Equal(t, "macro", ctags[idx].Kind) idx++ - require.Equal(t, "hello", ctags[idx]["functionName"]) - require.Equal(t, "variable", ctags[idx]["kind"]) + require.Equal(t, "hello", ctags[idx].FunctionName) + require.Equal(t, "variable", ctags[idx].Kind) idx++ - require.Equal(t, "setup", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "setup", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) idx++ - require.Equal(t, "loop", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "loop", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) idx++ - require.Equal(t, "debug", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "debug", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) idx++ - require.Equal(t, "disabledIsDefined", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "disabledIsDefined", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) idx++ - require.Equal(t, "useMyType", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "useMyType", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) } func TestCTagsParserShouldDealFunctionWithDifferentSignatures(t *testing.T) { @@ -247,18 +247,18 @@ func TestCTagsParserShouldDealFunctionWithDifferentSignatures(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) require.Equal(t, 3, len(ctags)) idx := 0 - require.Equal(t, "getBytes", ctags[idx]["functionName"]) - require.Equal(t, "prototype", ctags[idx]["kind"]) + require.Equal(t, "getBytes", ctags[idx].FunctionName) + require.Equal(t, "prototype", ctags[idx].Kind) idx++ - require.Equal(t, "getBytes", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "getBytes", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) idx++ - require.Equal(t, "getBytes", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "getBytes", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) } func TestCTagsParserClassMembersAreFilteredOut(t *testing.T) { @@ -272,27 +272,27 @@ func TestCTagsParserClassMembersAreFilteredOut(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) require.Equal(t, 5, len(ctags)) idx := 0 - require.Equal(t, "set_values", ctags[idx]["functionName"]) - require.Equal(t, "prototype", ctags[idx]["kind"]) - require.Equal(t, "Rectangle", ctags[idx]["class"]) + require.Equal(t, "set_values", ctags[idx].FunctionName) + require.Equal(t, "prototype", ctags[idx].Kind) + require.Equal(t, "Rectangle", ctags[idx].Class) idx++ - require.Equal(t, "area", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) - require.Equal(t, "Rectangle", ctags[idx]["class"]) + require.Equal(t, "area", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) + require.Equal(t, "Rectangle", ctags[idx].Class) idx++ - require.Equal(t, "set_values", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) - require.Equal(t, "Rectangle", ctags[idx]["class"]) + require.Equal(t, "set_values", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) + require.Equal(t, "Rectangle", ctags[idx].Class) idx++ - require.Equal(t, "setup", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "setup", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) idx++ - require.Equal(t, "loop", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "loop", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) } func TestCTagsParserStructWithFunctions(t *testing.T) { @@ -306,35 +306,35 @@ func TestCTagsParserStructWithFunctions(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) require.Equal(t, 8, len(ctags)) idx := 0 - require.Equal(t, "sensorData", ctags[idx]["functionName"]) - require.Equal(t, "struct", ctags[idx]["kind"]) + require.Equal(t, "sensorData", ctags[idx].FunctionName) + require.Equal(t, "struct", ctags[idx].Kind) idx++ - require.Equal(t, "sensorData", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) - require.Equal(t, "sensorData", ctags[idx]["struct"]) + require.Equal(t, "sensorData", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) + require.Equal(t, "sensorData", ctags[idx].Struct) idx++ - require.Equal(t, "sensorData", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) - require.Equal(t, "sensorData", ctags[idx]["struct"]) + require.Equal(t, "sensorData", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) + require.Equal(t, "sensorData", ctags[idx].Struct) idx++ - require.Equal(t, "sensors", ctags[idx]["functionName"]) - require.Equal(t, "variable", ctags[idx]["kind"]) + require.Equal(t, "sensors", ctags[idx].FunctionName) + require.Equal(t, "variable", ctags[idx].Kind) idx++ - require.Equal(t, "sensor1", ctags[idx]["functionName"]) - require.Equal(t, "variable", ctags[idx]["kind"]) + require.Equal(t, "sensor1", ctags[idx].FunctionName) + require.Equal(t, "variable", ctags[idx].Kind) idx++ - require.Equal(t, "sensor2", ctags[idx]["functionName"]) - require.Equal(t, "variable", ctags[idx]["kind"]) + require.Equal(t, "sensor2", ctags[idx].FunctionName) + require.Equal(t, "variable", ctags[idx].Kind) idx++ - require.Equal(t, "setup", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "setup", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) idx++ - require.Equal(t, "loop", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "loop", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) } func TestCTagsParserDefaultArguments(t *testing.T) { @@ -348,19 +348,19 @@ func TestCTagsParserDefaultArguments(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) require.Equal(t, 3, len(ctags)) idx := 0 - require.Equal(t, "test", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) - require.Equal(t, "(int x = 1)", ctags[idx]["signature"]) + require.Equal(t, "test", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) + require.Equal(t, "(int x = 1)", ctags[idx].Signature) idx++ - require.Equal(t, "setup", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "setup", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) idx++ - require.Equal(t, "loop", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "loop", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) } func TestCTagsParserNamespace(t *testing.T) { @@ -374,19 +374,19 @@ func TestCTagsParserNamespace(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) require.Equal(t, 3, len(ctags)) idx := 0 - require.Equal(t, "value", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) - require.Equal(t, "Test", ctags[idx]["namespace"]) + require.Equal(t, "value", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) + require.Equal(t, "Test", ctags[idx].Namespace) idx++ - require.Equal(t, "setup", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "setup", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) idx++ - require.Equal(t, "loop", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "loop", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) } func TestCTagsParserStatic(t *testing.T) { @@ -400,18 +400,18 @@ func TestCTagsParserStatic(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) require.Equal(t, 3, len(ctags)) idx := 0 - require.Equal(t, "setup", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "setup", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) idx++ - require.Equal(t, "loop", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "loop", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) idx++ - require.Equal(t, "doStuff", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "doStuff", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) } func TestCTagsParserFunctionPointer(t *testing.T) { @@ -425,21 +425,21 @@ func TestCTagsParserFunctionPointer(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) require.Equal(t, 4, len(ctags)) idx := 0 - require.Equal(t, "t1Callback", ctags[idx]["functionName"]) - require.Equal(t, "variable", ctags[idx]["kind"]) + require.Equal(t, "t1Callback", ctags[idx].FunctionName) + require.Equal(t, "variable", ctags[idx].Kind) idx++ - require.Equal(t, "t1Callback", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "t1Callback", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) idx++ - require.Equal(t, "setup", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "setup", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) idx++ - require.Equal(t, "loop", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "loop", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) } func TestCTagsParserFunctionPointers(t *testing.T) { @@ -453,25 +453,25 @@ func TestCTagsParserFunctionPointers(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]map[string]string) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) require.Equal(t, 5, len(ctags)) idx := 0 - require.Equal(t, "setup", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "setup", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) idx++ - require.Equal(t, "loop", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "loop", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) idx++ - require.Equal(t, "func", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) + require.Equal(t, "func", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) idx++ - require.Equal(t, "funcArr", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) - require.Equal(t, "()", ctags[idx]["signature"]) + require.Equal(t, "funcArr", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) + require.Equal(t, "()", ctags[idx].Signature) idx++ - require.Equal(t, "funcCombo", ctags[idx]["functionName"]) - require.Equal(t, "function", ctags[idx]["kind"]) - require.Equal(t, "(void (*(&in)[5])(int))", ctags[idx]["signature"]) + require.Equal(t, "funcCombo", ctags[idx].FunctionName) + require.Equal(t, "function", ctags[idx].Kind) + require.Equal(t, "(void (*(&in)[5])(int))", ctags[idx].Signature) } diff --git a/src/arduino.cc/builder/types/types.go b/src/arduino.cc/builder/types/types.go index a4cf477b..088f3d0b 100644 --- a/src/arduino.cc/builder/types/types.go +++ b/src/arduino.cc/builder/types/types.go @@ -31,6 +31,7 @@ package types import ( "arduino.cc/builder/constants" + "strconv" ) type SketchFile struct { @@ -157,12 +158,11 @@ type Prototype struct { File string Prototype string Modifiers string - Line string - Fields map[string]string + Line int } func (proto *Prototype) String() string { - return proto.Modifiers + " " + proto.Prototype + " @ " + proto.Line + return proto.Modifiers + " " + proto.Prototype + " @ " + strconv.Itoa(proto.Line) } type SourceFolder struct { diff --git a/src/arduino.cc/builder/utils/utils.go b/src/arduino.cc/builder/utils/utils.go index 8a3a53a5..b66ce6ae 100644 --- a/src/arduino.cc/builder/utils/utils.go +++ b/src/arduino.cc/builder/utils/utils.go @@ -456,15 +456,6 @@ func TouchFile(targetFilePath string) error { return WriteFileBytes(targetFilePath, []byte{}) } -func TagHasAtLeastOneField(tag map[string]string, fields []string) (string, bool) { - for _, field := range fields { - if tag[field] != constants.EMPTY_STRING { - return field, true - } - } - return "", false -} - func NULLFile() string { if runtime.GOOS == "windows" { return "nul" From 2d30efdd4a784f99606df88bf217939a8f6ce8e9 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 23 Nov 2015 01:38:23 +0100 Subject: [PATCH 80/85] ctag parser: removed useless return errors Signed-off-by: Cristian Maglie --- src/arduino.cc/builder/ctags_to_prototypes.go | 38 +++++++------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/src/arduino.cc/builder/ctags_to_prototypes.go b/src/arduino.cc/builder/ctags_to_prototypes.go index d7d206ca..04e33158 100644 --- a/src/arduino.cc/builder/ctags_to_prototypes.go +++ b/src/arduino.cc/builder/ctags_to_prototypes.go @@ -32,7 +32,6 @@ package builder import ( "arduino.cc/builder/constants" "arduino.cc/builder/types" - "arduino.cc/builder/utils" "strings" ) @@ -41,10 +40,7 @@ type CTagsToPrototypes struct{} func (s *CTagsToPrototypes) Run(context map[string]interface{}) error { tags := context[constants.CTX_COLLECTED_CTAGS].([]*CTag) - lineWhereToInsertPrototypes, err := findLineWhereToInsertPrototypes(tags) - if err != nil { - return utils.WrapError(err) - } + lineWhereToInsertPrototypes := findLineWhereToInsertPrototypes(tags) if lineWhereToInsertPrototypes != -1 { context[constants.CTX_LINE_WHERE_TO_INSERT_PROTOTYPES] = lineWhereToInsertPrototypes } @@ -55,36 +51,30 @@ func (s *CTagsToPrototypes) Run(context map[string]interface{}) error { return nil } -func findLineWhereToInsertPrototypes(tags []*CTag) (int, error) { - firstFunctionLine, err := firstFunctionAtLine(tags) - if err != nil { - return -1, utils.WrapError(err) - } - firstFunctionPointerAsArgument, err := firstFunctionPointerUsedAsArgument(tags) - if err != nil { - return -1, utils.WrapError(err) - } +func findLineWhereToInsertPrototypes(tags []*CTag) int { + firstFunctionLine := firstFunctionAtLine(tags) + firstFunctionPointerAsArgument := firstFunctionPointerUsedAsArgument(tags) if firstFunctionLine != -1 && firstFunctionPointerAsArgument != -1 { if firstFunctionLine < firstFunctionPointerAsArgument { - return firstFunctionLine, nil + return firstFunctionLine } else { - return firstFunctionPointerAsArgument, nil + return firstFunctionPointerAsArgument } } else if firstFunctionLine == -1 { - return firstFunctionPointerAsArgument, nil + return firstFunctionPointerAsArgument } else { - return firstFunctionLine, nil + return firstFunctionLine } } -func firstFunctionPointerUsedAsArgument(tags []*CTag) (int, error) { +func firstFunctionPointerUsedAsArgument(tags []*CTag) int { functionNames := collectFunctionNames(tags) for _, tag := range tags { if functionNameUsedAsFunctionPointerIn(tag, functionNames) { - return tag.Line, nil + return tag.Line } } - return -1, nil + return -1 } func functionNameUsedAsFunctionPointerIn(tag *CTag, functionNames []string) bool { @@ -106,13 +96,13 @@ func collectFunctionNames(tags []*CTag) []string { return names } -func firstFunctionAtLine(tags []*CTag) (int, error) { +func firstFunctionAtLine(tags []*CTag) int { for _, tag := range tags { if !tagIsUnknown(tag) && tag.IsHandled() && tag.Kind == KIND_FUNCTION { - return tag.Line, nil + return tag.Line } } - return -1, nil + return -1 } func toPrototypes(tags []*CTag) []*types.Prototype { From 2f78246ba71a1986920a97d2682d0100d89b73f3 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Thu, 10 Dec 2015 10:21:47 +0100 Subject: [PATCH 81/85] Moved CTag struct from CTagsParser to types package. Because it's not local to CTagsParser command, CTag type must be equally accessible by all commands Signed-off-by: Federico Fissore --- .../collect_ctags_from_sketch_files.go | 4 +- ...ototypes_from_source_and_preproc_source.go | 9 ++-- src/arduino.cc/builder/ctags_parser.go | 52 ++++++------------- src/arduino.cc/builder/ctags_to_prototypes.go | 16 +++--- .../builder/test/ctags_parser_test.go | 29 ++++++----- src/arduino.cc/builder/types/types.go | 19 +++++++ 6 files changed, 66 insertions(+), 63 deletions(-) diff --git a/src/arduino.cc/builder/collect_ctags_from_sketch_files.go b/src/arduino.cc/builder/collect_ctags_from_sketch_files.go index 3a111a51..a836c4d3 100644 --- a/src/arduino.cc/builder/collect_ctags_from_sketch_files.go +++ b/src/arduino.cc/builder/collect_ctags_from_sketch_files.go @@ -42,8 +42,8 @@ func (s *CollectCTagsFromSketchFiles) Run(context map[string]interface{}) error sketch := context[constants.CTX_SKETCH].(*types.Sketch) sketchFileNames := collectSketchFileNamesFrom(sketch) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*CTag) - ctagsOfSketch := []*CTag{} + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*types.CTag) + ctagsOfSketch := []*types.CTag{} for _, ctag := range ctags { if utils.SliceContains(sketchFileNames, strings.Replace(ctag.Filename, "\\\\", "\\", -1)) { ctagsOfSketch = append(ctagsOfSketch, ctag) diff --git a/src/arduino.cc/builder/compare_prototypes_from_source_and_preproc_source.go b/src/arduino.cc/builder/compare_prototypes_from_source_and_preproc_source.go index 72596e4f..7139da2d 100644 --- a/src/arduino.cc/builder/compare_prototypes_from_source_and_preproc_source.go +++ b/src/arduino.cc/builder/compare_prototypes_from_source_and_preproc_source.go @@ -31,15 +31,16 @@ package builder import ( "arduino.cc/builder/constants" + "arduino.cc/builder/types" ) type ComparePrototypesFromSourceAndPreprocSource struct{} func (s *ComparePrototypesFromSourceAndPreprocSource) Run(context map[string]interface{}) error { - ctagsOfSource := context[constants.CTX_CTAGS_OF_SOURCE].([]*CTag) - ctagsOfPreprocSource := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*CTag) + ctagsOfSource := context[constants.CTX_CTAGS_OF_SOURCE].([]*types.CTag) + ctagsOfPreprocSource := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*types.CTag) - actualCTags := []*CTag{} + actualCTags := []*types.CTag{} for _, ctagOfPreprocSource := range ctagsOfPreprocSource { if sliceContainsCTag(ctagsOfSource, ctagOfPreprocSource) { actualCTags = append(actualCTags, ctagOfPreprocSource) @@ -51,7 +52,7 @@ func (s *ComparePrototypesFromSourceAndPreprocSource) Run(context map[string]int return nil } -func sliceContainsCTag(slice []*CTag, target *CTag) bool { +func sliceContainsCTag(slice []*types.CTag, target *types.CTag) bool { for _, value := range slice { if value.FunctionName == target.FunctionName { return true diff --git a/src/arduino.cc/builder/ctags_parser.go b/src/arduino.cc/builder/ctags_parser.go index 76703fef..d83d51b2 100644 --- a/src/arduino.cc/builder/ctags_parser.go +++ b/src/arduino.cc/builder/ctags_parser.go @@ -31,6 +31,7 @@ package builder import ( "arduino.cc/builder/constants" + "arduino.cc/builder/types" "arduino.cc/builder/utils" "os" "reflect" @@ -54,31 +55,12 @@ var KNOWN_TAG_KINDS = map[string]bool{ type CTagsParser struct{} -type CTag struct { - FunctionName string - Kind string - Line int - Signature string - Returntype string - Code string - Class string - Struct string - Namespace string - Filename string - Typeref string - SkipMe bool - - Prototype string - Function string - PrototypeModifiers string -} - func (s *CTagsParser) Run(context map[string]interface{}) error { rows := strings.Split(context[constants.CTX_CTAGS_OUTPUT].(string), "\n") rows = removeEmpty(rows) - var tags []*CTag + var tags []*types.CTag for _, row := range rows { tags = append(tags, parseTag(row)) } @@ -96,15 +78,15 @@ func (s *CTagsParser) Run(context map[string]interface{}) error { return nil } -func addPrototypes(tags []*CTag) { +func addPrototypes(tags []*types.CTag) { for _, tag := range tags { if !tag.SkipMe { - tag.AddPrototype() + addPrototype(tag) } } } -func (tag *CTag) AddPrototype() { +func addPrototype(tag *types.CTag) { if strings.Index(tag.Returntype, TEMPLATE) == 0 || strings.Index(tag.Code, TEMPLATE) == 0 { code := tag.Code if strings.Contains(code, "{") { @@ -125,7 +107,7 @@ func (tag *CTag) AddPrototype() { tag.PrototypeModifiers = strings.TrimSpace(tag.PrototypeModifiers) } -func removeDefinedProtypes(tags []*CTag, context map[string]interface{}) { +func removeDefinedProtypes(tags []*types.CTag, context map[string]interface{}) { definedPrototypes := make(map[string]bool) for _, tag := range tags { if tag.Kind == KIND_PROTOTYPE { @@ -143,7 +125,7 @@ func removeDefinedProtypes(tags []*CTag, context map[string]interface{}) { } } -func removeDuplicate(tags []*CTag) { +func removeDuplicate(tags []*types.CTag) { definedPrototypes := make(map[string]bool) for _, tag := range tags { @@ -155,9 +137,9 @@ func removeDuplicate(tags []*CTag) { } } -type skipFuncType func(tag *CTag) bool +type skipFuncType func(tag *types.CTag) bool -func skipTagsWhere(tags []*CTag, skipFunc skipFuncType, context map[string]interface{}) { +func skipTagsWhere(tags []*types.CTag, skipFunc skipFuncType, context map[string]interface{}) { for _, tag := range tags { if !tag.SkipMe { skip := skipFunc(tag) @@ -169,11 +151,11 @@ func skipTagsWhere(tags []*CTag, skipFunc skipFuncType, context map[string]inter } } -func signatureContainsDefaultArg(tag *CTag) bool { +func signatureContainsDefaultArg(tag *types.CTag) bool { return strings.Contains(tag.Signature, "=") } -func prototypeAndCodeDontMatch(tag *CTag) bool { +func prototypeAndCodeDontMatch(tag *types.CTag) bool { if tag.SkipMe { return true } @@ -195,11 +177,11 @@ func removeSpacesAndTabs(s string) string { return s } -func tagIsUnhandled(tag *CTag) bool { - return !tag.IsHandled() +func tagIsUnhandled(tag *types.CTag) bool { + return !isHandled(tag) } -func (tag *CTag) IsHandled() bool { +func isHandled(tag *types.CTag) bool { if tag.Class != "" { return false } @@ -212,12 +194,12 @@ func (tag *CTag) IsHandled() bool { return true } -func tagIsUnknown(tag *CTag) bool { +func tagIsUnknown(tag *types.CTag) bool { return !KNOWN_TAG_KINDS[tag.Kind] } -func parseTag(row string) *CTag { - tag := &CTag{} +func parseTag(row string) *types.CTag { + tag := &types.CTag{} parts := strings.Split(row, "\t") tag.FunctionName = parts[0] diff --git a/src/arduino.cc/builder/ctags_to_prototypes.go b/src/arduino.cc/builder/ctags_to_prototypes.go index 04e33158..d8cde83b 100644 --- a/src/arduino.cc/builder/ctags_to_prototypes.go +++ b/src/arduino.cc/builder/ctags_to_prototypes.go @@ -38,7 +38,7 @@ import ( type CTagsToPrototypes struct{} func (s *CTagsToPrototypes) Run(context map[string]interface{}) error { - tags := context[constants.CTX_COLLECTED_CTAGS].([]*CTag) + tags := context[constants.CTX_COLLECTED_CTAGS].([]*types.CTag) lineWhereToInsertPrototypes := findLineWhereToInsertPrototypes(tags) if lineWhereToInsertPrototypes != -1 { @@ -51,7 +51,7 @@ func (s *CTagsToPrototypes) Run(context map[string]interface{}) error { return nil } -func findLineWhereToInsertPrototypes(tags []*CTag) int { +func findLineWhereToInsertPrototypes(tags []*types.CTag) int { firstFunctionLine := firstFunctionAtLine(tags) firstFunctionPointerAsArgument := firstFunctionPointerUsedAsArgument(tags) if firstFunctionLine != -1 && firstFunctionPointerAsArgument != -1 { @@ -67,7 +67,7 @@ func findLineWhereToInsertPrototypes(tags []*CTag) int { } } -func firstFunctionPointerUsedAsArgument(tags []*CTag) int { +func firstFunctionPointerUsedAsArgument(tags []*types.CTag) int { functionNames := collectFunctionNames(tags) for _, tag := range tags { if functionNameUsedAsFunctionPointerIn(tag, functionNames) { @@ -77,7 +77,7 @@ func firstFunctionPointerUsedAsArgument(tags []*CTag) int { return -1 } -func functionNameUsedAsFunctionPointerIn(tag *CTag, functionNames []string) bool { +func functionNameUsedAsFunctionPointerIn(tag *types.CTag, functionNames []string) bool { for _, functionName := range functionNames { if strings.Index(tag.Code, "&"+functionName) != -1 { return true @@ -86,7 +86,7 @@ func functionNameUsedAsFunctionPointerIn(tag *CTag, functionNames []string) bool return false } -func collectFunctionNames(tags []*CTag) []string { +func collectFunctionNames(tags []*types.CTag) []string { names := []string{} for _, tag := range tags { if tag.Kind == KIND_FUNCTION { @@ -96,16 +96,16 @@ func collectFunctionNames(tags []*CTag) []string { return names } -func firstFunctionAtLine(tags []*CTag) int { +func firstFunctionAtLine(tags []*types.CTag) int { for _, tag := range tags { - if !tagIsUnknown(tag) && tag.IsHandled() && tag.Kind == KIND_FUNCTION { + if !tagIsUnknown(tag) && isHandled(tag) && tag.Kind == KIND_FUNCTION { return tag.Line } } return -1 } -func toPrototypes(tags []*CTag) []*types.Prototype { +func toPrototypes(tags []*types.CTag) []*types.Prototype { prototypes := []*types.Prototype{} for _, tag := range tags { if !tag.SkipMe { diff --git a/src/arduino.cc/builder/test/ctags_parser_test.go b/src/arduino.cc/builder/test/ctags_parser_test.go index fba7629c..cb6353dc 100644 --- a/src/arduino.cc/builder/test/ctags_parser_test.go +++ b/src/arduino.cc/builder/test/ctags_parser_test.go @@ -32,6 +32,7 @@ package test import ( "arduino.cc/builder" "arduino.cc/builder/constants" + "arduino.cc/builder/types" "github.com/stretchr/testify/require" "io/ioutil" "path/filepath" @@ -49,7 +50,7 @@ func TestCTagsParserShouldListPrototypes(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*types.CTag) require.Equal(t, 8, len(ctags)) idx := 0 @@ -97,7 +98,7 @@ func TestCTagsParserShouldListTemplates(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*types.CTag) require.Equal(t, 3, len(ctags)) idx := 0 @@ -123,7 +124,7 @@ func TestCTagsParserShouldListTemplates2(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*types.CTag) require.Equal(t, 4, len(ctags)) idx := 0 @@ -153,7 +154,7 @@ func TestCTagsParserShouldDealWithClasses(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*types.CTag) require.Equal(t, 2, len(ctags)) idx := 0 @@ -175,7 +176,7 @@ func TestCTagsParserShouldDealWithStructs(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*types.CTag) require.Equal(t, 5, len(ctags)) idx := 0 @@ -207,7 +208,7 @@ func TestCTagsParserShouldDealWithMacros(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*types.CTag) require.Equal(t, 8, len(ctags)) idx := 0 @@ -247,7 +248,7 @@ func TestCTagsParserShouldDealFunctionWithDifferentSignatures(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*types.CTag) require.Equal(t, 3, len(ctags)) idx := 0 @@ -272,7 +273,7 @@ func TestCTagsParserClassMembersAreFilteredOut(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*types.CTag) require.Equal(t, 5, len(ctags)) idx := 0 @@ -306,7 +307,7 @@ func TestCTagsParserStructWithFunctions(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*types.CTag) require.Equal(t, 8, len(ctags)) idx := 0 @@ -348,7 +349,7 @@ func TestCTagsParserDefaultArguments(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*types.CTag) require.Equal(t, 3, len(ctags)) idx := 0 @@ -374,7 +375,7 @@ func TestCTagsParserNamespace(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*types.CTag) require.Equal(t, 3, len(ctags)) idx := 0 @@ -400,7 +401,7 @@ func TestCTagsParserStatic(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*types.CTag) require.Equal(t, 3, len(ctags)) idx := 0 @@ -425,7 +426,7 @@ func TestCTagsParserFunctionPointer(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*types.CTag) require.Equal(t, 4, len(ctags)) idx := 0 @@ -453,7 +454,7 @@ func TestCTagsParserFunctionPointers(t *testing.T) { ctagsParser := builder.CTagsParser{} ctagsParser.Run(context) - ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*builder.CTag) + ctags := context[constants.CTX_CTAGS_OF_PREPROC_SOURCE].([]*types.CTag) require.Equal(t, 5, len(ctags)) idx := 0 diff --git a/src/arduino.cc/builder/types/types.go b/src/arduino.cc/builder/types/types.go index 088f3d0b..57da8897 100644 --- a/src/arduino.cc/builder/types/types.go +++ b/src/arduino.cc/builder/types/types.go @@ -175,3 +175,22 @@ type LibraryResolutionResult struct { IsLibraryFromPlatform bool NotUsedLibraries []*Library } + +type CTag struct { + FunctionName string + Kind string + Line int + Signature string + Returntype string + Code string + Class string + Struct string + Namespace string + Filename string + Typeref string + SkipMe bool + + Prototype string + Function string + PrototypeModifiers string +} From 4be87e588070d8d65195155f94b8aafa630b2ef3 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Thu, 10 Dec 2015 16:15:43 +0100 Subject: [PATCH 82/85] Introducing log levels. ALL messages are now printed on stdout, with an initial info/debug/warn/error log level. Output from child processes is still redirected to stdout/stderr Signed-off-by: Federico Fissore --- .../add_build_board_property_if_missing.go | 2 +- src/arduino.cc/builder/builder.go | 4 +-- src/arduino.cc/builder/builder_utils/utils.go | 2 +- src/arduino.cc/builder/constants/constants.go | 4 +++ src/arduino.cc/builder/ctags_parser.go | 4 +-- .../builder/generate_buildpath_if_missing.go | 2 +- src/arduino.cc/builder/i18n/i18n.go | 26 +++++++++---------- src/arduino.cc/builder/libraries_loader.go | 4 +-- .../builder/merge_sketch_with_bootloader.go | 2 +- .../print_used_and_not_used_libraries.go | 6 ++--- .../print_used_libraries_if_verbose.go | 4 +-- src/arduino.cc/builder/recipe_runner.go | 4 +-- src/arduino.cc/builder/test/i18n_test.go | 5 ++-- src/arduino.cc/builder/utils/utils.go | 2 +- .../warn_about_arch_incompatible_libraries.go | 2 +- .../builder/warn_about_platform_rewrites.go | 2 +- ...out_build_path_if_build_options_changed.go | 2 +- 17 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/arduino.cc/builder/add_build_board_property_if_missing.go b/src/arduino.cc/builder/add_build_board_property_if_missing.go index ef422d14..b819a424 100644 --- a/src/arduino.cc/builder/add_build_board_property_if_missing.go +++ b/src/arduino.cc/builder/add_build_board_property_if_missing.go @@ -48,7 +48,7 @@ func (s *AddBuildBoardPropertyIfMissing) Run(context map[string]interface{}) err for _, board := range platform.Boards { if board.Properties[constants.BUILD_PROPERTIES_BUILD_BOARD] == constants.EMPTY_STRING { board.Properties[constants.BUILD_PROPERTIES_BUILD_BOARD] = strings.ToUpper(platform.PlatformId + "_" + board.BoardId) - logger.Fprintln(os.Stderr, constants.MSG_MISSING_BUILD_BOARD, aPackage.PackageId, platform.PlatformId, board.BoardId, board.Properties[constants.BUILD_PROPERTIES_BUILD_BOARD]) + logger.Fprintln(os.Stdout, constants.LOG_LEVEL_WARN, constants.MSG_MISSING_BUILD_BOARD, aPackage.PackageId, platform.PlatformId, board.BoardId, board.Properties[constants.BUILD_PROPERTIES_BUILD_BOARD]) } } } diff --git a/src/arduino.cc/builder/builder.go b/src/arduino.cc/builder/builder.go index f521cb1d..9fb4206f 100644 --- a/src/arduino.cc/builder/builder.go +++ b/src/arduino.cc/builder/builder.go @@ -203,13 +203,13 @@ func printProgressIfProgressEnabledAndMachineLogger(progressEnabled bool, contex log := utils.Logger(context) if log.Name() == "machine" { - log.Println(constants.MSG_PROGRESS, strconv.FormatFloat(float64(progress), 'f', 2, 32)) + log.Println(constants.LOG_LEVEL_INFO, constants.MSG_PROGRESS, strconv.FormatFloat(float64(progress), 'f', 2, 32)) } } func PrintRingNameIfDebug(context map[string]interface{}, command types.Command) { if utils.DebugLevel(context) >= 10 { - utils.Logger(context).Fprintln(os.Stderr, constants.MSG_RUNNING_COMMAND, strconv.FormatInt(time.Now().Unix(), 10), reflect.Indirect(reflect.ValueOf(command)).Type().Name()) + utils.Logger(context).Fprintln(os.Stdout, constants.LOG_LEVEL_DEBUG, constants.MSG_RUNNING_COMMAND, strconv.FormatInt(time.Now().Unix(), 10), reflect.Indirect(reflect.ValueOf(command)).Type().Name()) } } diff --git a/src/arduino.cc/builder/builder_utils/utils.go b/src/arduino.cc/builder/builder_utils/utils.go index aaf1c240..18ab284e 100644 --- a/src/arduino.cc/builder/builder_utils/utils.go +++ b/src/arduino.cc/builder/builder_utils/utils.go @@ -154,7 +154,7 @@ func compileFileWithRecipe(sourcePath string, source string, buildPath string, b return "", utils.WrapError(err) } } else if verbose { - logger.Println(constants.MSG_USING_PREVIOUS_COMPILED_FILE, properties[constants.BUILD_PROPERTIES_OBJECT_FILE]) + logger.Println(constants.LOG_LEVEL_INFO, constants.MSG_USING_PREVIOUS_COMPILED_FILE, properties[constants.BUILD_PROPERTIES_OBJECT_FILE]) } return properties[constants.BUILD_PROPERTIES_OBJECT_FILE], nil diff --git a/src/arduino.cc/builder/constants/constants.go b/src/arduino.cc/builder/constants/constants.go index 531250d5..d80d232c 100644 --- a/src/arduino.cc/builder/constants/constants.go +++ b/src/arduino.cc/builder/constants/constants.go @@ -201,6 +201,10 @@ const LIBRARY_PROPERTIES = "library.properties" const LIBRARY_SENTENCE = "sentence" const LIBRARY_URL = "url" const LIBRARY_VERSION = "version" +const LOG_LEVEL_DEBUG = "debug" +const LOG_LEVEL_ERROR = "error" +const LOG_LEVEL_INFO = "info" +const LOG_LEVEL_WARN = "warn" const MSG_ARCH_FOLDER_NOT_SUPPORTED = "'arch' folder is no longer supported! See http://goo.gl/gfFJzU for more information" const MSG_BOARD_UNKNOWN = "Board {0} (platform {1}, package {2}) is unknown" const MSG_BOOTLOADER_FILE_MISSING = "Bootloader file specified but missing: {0}" diff --git a/src/arduino.cc/builder/ctags_parser.go b/src/arduino.cc/builder/ctags_parser.go index d83d51b2..09a01d51 100644 --- a/src/arduino.cc/builder/ctags_parser.go +++ b/src/arduino.cc/builder/ctags_parser.go @@ -118,7 +118,7 @@ func removeDefinedProtypes(tags []*types.CTag, context map[string]interface{}) { for _, tag := range tags { if definedPrototypes[tag.Prototype] { if utils.DebugLevel(context) >= 10 { - utils.Logger(context).Fprintln(os.Stderr, constants.MSG_SKIPPING_TAG_ALREADY_DEFINED, tag.FunctionName) + utils.Logger(context).Fprintln(os.Stdout, constants.LOG_LEVEL_DEBUG, constants.MSG_SKIPPING_TAG_ALREADY_DEFINED, tag.FunctionName) } tag.SkipMe = true } @@ -144,7 +144,7 @@ func skipTagsWhere(tags []*types.CTag, skipFunc skipFuncType, context map[string if !tag.SkipMe { skip := skipFunc(tag) if skip && utils.DebugLevel(context) >= 10 { - utils.Logger(context).Fprintln(os.Stderr, constants.MSG_SKIPPING_TAG_WITH_REASON, tag.FunctionName, runtime.FuncForPC(reflect.ValueOf(skipFunc).Pointer()).Name()) + utils.Logger(context).Fprintln(os.Stdout, constants.LOG_LEVEL_DEBUG, constants.MSG_SKIPPING_TAG_WITH_REASON, tag.FunctionName, runtime.FuncForPC(reflect.ValueOf(skipFunc).Pointer()).Name()) } tag.SkipMe = skip } diff --git a/src/arduino.cc/builder/generate_buildpath_if_missing.go b/src/arduino.cc/builder/generate_buildpath_if_missing.go index 886ea3f0..5a04272d 100644 --- a/src/arduino.cc/builder/generate_buildpath_if_missing.go +++ b/src/arduino.cc/builder/generate_buildpath_if_missing.go @@ -56,7 +56,7 @@ func (s *GenerateBuildPathIfMissing) Run(context map[string]interface{}) error { if utils.DebugLevel(context) > 5 { logger := context[constants.CTX_LOGGER].(i18n.Logger) - logger.Fprintln(os.Stderr, constants.MSG_SETTING_BUILD_PATH, buildPath) + logger.Fprintln(os.Stdout, constants.LOG_LEVEL_WARN, constants.MSG_SETTING_BUILD_PATH, buildPath) } context[constants.CTX_BUILD_PATH] = buildPath diff --git a/src/arduino.cc/builder/i18n/i18n.go b/src/arduino.cc/builder/i18n/i18n.go index 02212481..2769e587 100644 --- a/src/arduino.cc/builder/i18n/i18n.go +++ b/src/arduino.cc/builder/i18n/i18n.go @@ -43,16 +43,16 @@ import ( var PLACEHOLDER = regexp.MustCompile("{(\\d)}") type Logger interface { - Fprintln(w io.Writer, format string, a ...interface{}) - Println(format string, a ...interface{}) + Fprintln(w io.Writer, level string, format string, a ...interface{}) + Println(level string, format string, a ...interface{}) Name() string } type NoopLogger struct{} -func (s NoopLogger) Fprintln(w io.Writer, format string, a ...interface{}) {} +func (s NoopLogger) Fprintln(w io.Writer, level string, format string, a ...interface{}) {} -func (s NoopLogger) Println(format string, a ...interface{}) {} +func (s NoopLogger) Println(level string, format string, a ...interface{}) {} func (s NoopLogger) Name() string { return "noop" @@ -60,12 +60,12 @@ func (s NoopLogger) Name() string { type HumanLogger struct{} -func (s HumanLogger) Fprintln(w io.Writer, format string, a ...interface{}) { +func (s HumanLogger) Fprintln(w io.Writer, level string, format string, a ...interface{}) { fmt.Fprintln(w, Format(format, a...)) } -func (s HumanLogger) Println(format string, a ...interface{}) { - s.Fprintln(os.Stdout, Format(format, a...)) +func (s HumanLogger) Println(level string, format string, a ...interface{}) { + s.Fprintln(os.Stdout, level, Format(format, a...)) } func (s HumanLogger) Name() string { @@ -74,7 +74,7 @@ func (s HumanLogger) Name() string { type MachineLogger struct{} -func (s MachineLogger) printWithoutFormatting(w io.Writer, format string, a []interface{}) { +func (s MachineLogger) printWithoutFormatting(w io.Writer, level string, format string, a []interface{}) { a = append([]interface{}(nil), a...) for idx, value := range a { typeof := reflect.Indirect(reflect.ValueOf(value)).Kind() @@ -82,16 +82,16 @@ func (s MachineLogger) printWithoutFormatting(w io.Writer, format string, a []in a[idx] = url.QueryEscape(value.(string)) } } - fmt.Fprintf(w, "===%s ||| %s", format, a) + fmt.Fprintf(w, "===%s ||| %s ||| %s", level, format, a) fmt.Fprintln(w) } -func (s MachineLogger) Fprintln(w io.Writer, format string, a ...interface{}) { - s.printWithoutFormatting(w, format, a) +func (s MachineLogger) Fprintln(w io.Writer, level string, format string, a ...interface{}) { + s.printWithoutFormatting(w, level, format, a) } -func (s MachineLogger) Println(format string, a ...interface{}) { - s.printWithoutFormatting(os.Stdout, format, a) +func (s MachineLogger) Println(level string, format string, a ...interface{}) { + s.printWithoutFormatting(os.Stdout, level, format, a) } func (s MachineLogger) Name() string { diff --git a/src/arduino.cc/builder/libraries_loader.go b/src/arduino.cc/builder/libraries_loader.go index e47c1d4e..0c043801 100644 --- a/src/arduino.cc/builder/libraries_loader.go +++ b/src/arduino.cc/builder/libraries_loader.go @@ -153,7 +153,7 @@ func makeNewLibrary(libraryFolder string, debugLevel int, logger i18n.Logger) (* for _, subFolder := range subFolders { if utils.IsSCCSOrHiddenFile(subFolder) { if !utils.IsSCCSFile(subFolder) && utils.IsHiddenFile(subFolder) { - logger.Fprintln(os.Stderr, constants.MSG_WARNING_SPURIOUS_FILE_IN_LIB, filepath.Base(subFolder.Name()), properties[constants.LIBRARY_NAME]) + logger.Fprintln(os.Stdout, constants.LOG_LEVEL_WARN, constants.MSG_WARNING_SPURIOUS_FILE_IN_LIB, filepath.Base(subFolder.Name()), properties[constants.LIBRARY_NAME]) } } } @@ -169,7 +169,7 @@ func makeNewLibrary(libraryFolder string, debugLevel int, logger i18n.Logger) (* properties[constants.LIBRARY_CATEGORY] = strings.TrimSpace(properties[constants.LIBRARY_CATEGORY]) if !LIBRARY_CATEGORIES[properties[constants.LIBRARY_CATEGORY]] { - logger.Fprintln(os.Stderr, constants.MSG_WARNING_LIB_INVALID_CATEGORY, properties[constants.LIBRARY_CATEGORY], properties[constants.LIBRARY_NAME], constants.LIB_CATEGORY_UNCATEGORIZED) + logger.Fprintln(os.Stdout, constants.LOG_LEVEL_WARN, constants.MSG_WARNING_LIB_INVALID_CATEGORY, properties[constants.LIBRARY_CATEGORY], properties[constants.LIBRARY_NAME], constants.LIB_CATEGORY_UNCATEGORIZED) properties[constants.LIBRARY_CATEGORY] = constants.LIB_CATEGORY_UNCATEGORIZED } library.Category = properties[constants.LIBRARY_CATEGORY] diff --git a/src/arduino.cc/builder/merge_sketch_with_bootloader.go b/src/arduino.cc/builder/merge_sketch_with_bootloader.go index 0864ea78..0d73afc4 100644 --- a/src/arduino.cc/builder/merge_sketch_with_bootloader.go +++ b/src/arduino.cc/builder/merge_sketch_with_bootloader.go @@ -75,7 +75,7 @@ func (s *MergeSketchWithBootloader) Run(context map[string]interface{}) error { bootloaderPath := filepath.Join(buildProperties[constants.BUILD_PROPERTIES_RUNTIME_PLATFORM_PATH], constants.FOLDER_BOOTLOADERS, bootloader) if _, err := os.Stat(bootloaderPath); err != nil { - logger.Fprintln(os.Stderr, constants.MSG_BOOTLOADER_FILE_MISSING, bootloaderPath) + logger.Fprintln(os.Stdout, constants.LOG_LEVEL_WARN, constants.MSG_BOOTLOADER_FILE_MISSING, bootloaderPath) return nil } diff --git a/src/arduino.cc/builder/print_used_and_not_used_libraries.go b/src/arduino.cc/builder/print_used_and_not_used_libraries.go index 88cbfbd3..7979e6b6 100644 --- a/src/arduino.cc/builder/print_used_and_not_used_libraries.go +++ b/src/arduino.cc/builder/print_used_and_not_used_libraries.go @@ -50,10 +50,10 @@ func (s *PrintUsedAndNotUsedLibraries) Run(context map[string]interface{}) error for header, libResResult := range libraryResolutionResults { if !libResResult.IsLibraryFromPlatform { - logger.Fprintln(os.Stderr, constants.MSG_LIBRARIES_MULTIPLE_LIBS_FOUND_FOR, header) - logger.Fprintln(os.Stderr, constants.MSG_LIBRARIES_USED, libResResult.Library.Folder) + logger.Fprintln(os.Stdout, constants.LOG_LEVEL_WARN, constants.MSG_LIBRARIES_MULTIPLE_LIBS_FOUND_FOR, header) + logger.Fprintln(os.Stdout, constants.LOG_LEVEL_WARN, constants.MSG_LIBRARIES_USED, libResResult.Library.Folder) for _, notUsedLibrary := range libResResult.NotUsedLibraries { - logger.Fprintln(os.Stderr, constants.MSG_LIBRARIES_NOT_USED, notUsedLibrary.Folder) + logger.Fprintln(os.Stdout, constants.LOG_LEVEL_WARN, constants.MSG_LIBRARIES_NOT_USED, notUsedLibrary.Folder) } } } diff --git a/src/arduino.cc/builder/print_used_libraries_if_verbose.go b/src/arduino.cc/builder/print_used_libraries_if_verbose.go index cc5ffd03..c3528a1a 100644 --- a/src/arduino.cc/builder/print_used_libraries_if_verbose.go +++ b/src/arduino.cc/builder/print_used_libraries_if_verbose.go @@ -55,9 +55,9 @@ func (s *PrintUsedLibrariesIfVerbose) Run(context map[string]interface{}) error legacy = constants.MSG_LIB_LEGACY } if library.Version == constants.EMPTY_STRING { - logger.Println(constants.MSG_USING_LIBRARY, library.Name, library.Folder, legacy) + logger.Println(constants.LOG_LEVEL_INFO, constants.MSG_USING_LIBRARY, library.Name, library.Folder, legacy) } else { - logger.Println(constants.MSG_USING_LIBRARY_AT_VERSION, library.Name, library.Version, library.Folder, legacy) + logger.Println(constants.LOG_LEVEL_INFO, constants.MSG_USING_LIBRARY_AT_VERSION, library.Name, library.Version, library.Folder, legacy) } } diff --git a/src/arduino.cc/builder/recipe_runner.go b/src/arduino.cc/builder/recipe_runner.go index 706528d3..05d3920d 100644 --- a/src/arduino.cc/builder/recipe_runner.go +++ b/src/arduino.cc/builder/recipe_runner.go @@ -47,7 +47,7 @@ type RecipeByPrefixSuffixRunner struct { func (s *RecipeByPrefixSuffixRunner) Run(context map[string]interface{}) error { logger := context[constants.CTX_LOGGER].(i18n.Logger) if utils.DebugLevel(context) >= 10 { - logger.Fprintln(os.Stderr, constants.MSG_LOOKING_FOR_RECIPES, s.Prefix, s.Suffix) + logger.Fprintln(os.Stdout, constants.LOG_LEVEL_DEBUG, constants.MSG_LOOKING_FOR_RECIPES, s.Prefix, s.Suffix) } buildProperties := utils.GetMapStringStringOrDefault(context, constants.CTX_BUILD_PROPERTIES) @@ -58,7 +58,7 @@ func (s *RecipeByPrefixSuffixRunner) Run(context map[string]interface{}) error { properties := utils.MergeMapsOfStrings(make(map[string]string), buildProperties) for _, recipe := range recipes { if utils.DebugLevel(context) >= 10 { - logger.Fprintln(os.Stderr, constants.MSG_RUNNING_RECIPE, recipe) + logger.Fprintln(os.Stdout, constants.LOG_LEVEL_DEBUG, constants.MSG_RUNNING_RECIPE, recipe) } _, err := builder_utils.ExecRecipe(properties, recipe, false, verbose, verbose, logger) if err != nil { diff --git a/src/arduino.cc/builder/test/i18n_test.go b/src/arduino.cc/builder/test/i18n_test.go index eb838207..9836c731 100644 --- a/src/arduino.cc/builder/test/i18n_test.go +++ b/src/arduino.cc/builder/test/i18n_test.go @@ -30,6 +30,7 @@ package test import ( + "arduino.cc/builder/constants" "arduino.cc/builder/i18n" "fmt" "github.com/stretchr/testify/require" @@ -64,8 +65,8 @@ func TestI18NSyntax(t *testing.T) { func TestI18NInheritance(t *testing.T) { var logger i18n.Logger logger = i18n.HumanLogger{} - logger.Println("good {0} {1}", "morning", "vietnam!") + logger.Println(constants.LOG_LEVEL_INFO, "good {0} {1}", "morning", "vietnam!") logger = i18n.MachineLogger{} - logger.Println("good {0} {1}", "morning", "vietnam!") + logger.Println(constants.LOG_LEVEL_INFO, "good {0} {1}", "morning", "vietnam!") } diff --git a/src/arduino.cc/builder/utils/utils.go b/src/arduino.cc/builder/utils/utils.go index b66ce6ae..c4f4820f 100644 --- a/src/arduino.cc/builder/utils/utils.go +++ b/src/arduino.cc/builder/utils/utils.go @@ -296,7 +296,7 @@ func Errorf(context map[string]interface{}, format string, a ...interface{}) *er func ErrorfWithLogger(log i18n.Logger, format string, a ...interface{}) *errors.Error { if log.Name() == "machine" { - log.Fprintln(os.Stderr, format, a...) + log.Fprintln(os.Stderr, constants.LOG_LEVEL_ERROR, format, a...) return errors.Errorf(constants.EMPTY_STRING) } return errors.Errorf(i18n.Format(format, a...)) diff --git a/src/arduino.cc/builder/warn_about_arch_incompatible_libraries.go b/src/arduino.cc/builder/warn_about_arch_incompatible_libraries.go index 20de4642..4cad2db7 100644 --- a/src/arduino.cc/builder/warn_about_arch_incompatible_libraries.go +++ b/src/arduino.cc/builder/warn_about_arch_incompatible_libraries.go @@ -62,7 +62,7 @@ func (s *WarnAboutArchIncompatibleLibraries) Run(context map[string]interface{}) importedLibraries := context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library) for _, importedLibrary := range importedLibraries { if !importedLibrary.SupportsArchitectures(archs) { - logger.Fprintln(os.Stderr, constants.MSG_LIBRARY_INCOMPATIBLE_ARCH, importedLibrary.Name, importedLibrary.Archs, archs) + logger.Fprintln(os.Stdout, constants.LOG_LEVEL_WARN, constants.MSG_LIBRARY_INCOMPATIBLE_ARCH, importedLibrary.Name, importedLibrary.Archs, archs) } } diff --git a/src/arduino.cc/builder/warn_about_platform_rewrites.go b/src/arduino.cc/builder/warn_about_platform_rewrites.go index 93f6da71..a6be00ab 100644 --- a/src/arduino.cc/builder/warn_about_platform_rewrites.go +++ b/src/arduino.cc/builder/warn_about_platform_rewrites.go @@ -58,7 +58,7 @@ func (s *WarnAboutPlatformRewrites) Run(context map[string]interface{}) error { for _, platform := range platforms { if hardwareRewriteResults[platform] != nil { for _, rewrite := range hardwareRewriteResults[platform] { - logger.Fprintln(os.Stderr, constants.MSG_WARNING_PLATFORM_OLD_VALUES, platform.Properties[constants.PLATFORM_NAME], rewrite.Key+"="+rewrite.OldValue, rewrite.Key+"="+rewrite.NewValue) + logger.Fprintln(os.Stdout, constants.LOG_LEVEL_WARN, constants.MSG_WARNING_PLATFORM_OLD_VALUES, platform.Properties[constants.PLATFORM_NAME], rewrite.Key+"="+rewrite.OldValue, rewrite.Key+"="+rewrite.NewValue) } } } diff --git a/src/arduino.cc/builder/wipeout_build_path_if_build_options_changed.go b/src/arduino.cc/builder/wipeout_build_path_if_build_options_changed.go index 762f2660..71a30e01 100644 --- a/src/arduino.cc/builder/wipeout_build_path_if_build_options_changed.go +++ b/src/arduino.cc/builder/wipeout_build_path_if_build_options_changed.go @@ -53,7 +53,7 @@ func (s *WipeoutBuildPathIfBuildOptionsChanged) Run(context map[string]interface return nil } - logger.Println(constants.MSG_BUILD_OPTIONS_CHANGED) + logger.Println(constants.LOG_LEVEL_INFO, constants.MSG_BUILD_OPTIONS_CHANGED) buildPath := context[constants.CTX_BUILD_PATH].(string) files, err := gohasissues.ReadDir(buildPath) From b875fc2e1d2b90482e3979322ef6975f24f46b44 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Thu, 10 Dec 2015 16:21:36 +0100 Subject: [PATCH 83/85] Releasing 1.3.7 Signed-off-by: Federico Fissore --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index e6e458bb..6cdcc8a0 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,7 @@ import ( "syscall" ) -const VERSION = "1.3.6" +const VERSION = "1.3.7" const FLAG_ACTION_COMPILE = "compile" const FLAG_ACTION_PREPROCESS = "preprocess" From d44f4118945b7586ca883e3a2bbde574b48fb808 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Fri, 11 Dec 2015 09:30:55 +0100 Subject: [PATCH 84/85] Ignoring all files that start with a dot. Fixes #82 Signed-off-by: Federico Fissore --- ..._source_files_from_folders_with_sources.go | 6 +++-- src/arduino.cc/builder/sketch_loader.go | 6 +++-- .../builder/test/sketch_loader_test.go | 23 +++++++++++++++++++ .../sketch_with_macosx_garbage/.#sketch.ino | 2 ++ .../sketch_with_macosx_garbage/sketch.ino | 2 ++ src/arduino.cc/builder/utils/utils.go | 7 +++--- 6 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 src/arduino.cc/builder/test/sketch_with_macosx_garbage/.#sketch.ino create mode 100644 src/arduino.cc/builder/test/sketch_with_macosx_garbage/sketch.ino diff --git a/src/arduino.cc/builder/collect_all_source_files_from_folders_with_sources.go b/src/arduino.cc/builder/collect_all_source_files_from_folders_with_sources.go index ef2548dc..d9b26c60 100644 --- a/src/arduino.cc/builder/collect_all_source_files_from_folders_with_sources.go +++ b/src/arduino.cc/builder/collect_all_source_files_from_folders_with_sources.go @@ -68,8 +68,10 @@ func (s *CollectAllSourceFilesFromFoldersWithSources) Run(context map[string]int } func collectByWalk(filePaths *[]string, folder string) error { - checkExtensionFunc := func(ext string) bool { - return ADDITIONAL_FILE_VALID_EXTENSIONS_NO_HEADERS[ext] + checkExtensionFunc := func(filePath string) bool { + name := filepath.Base(filePath) + ext := strings.ToLower(filepath.Ext(filePath)) + return !strings.HasPrefix(name, ".") && ADDITIONAL_FILE_VALID_EXTENSIONS_NO_HEADERS[ext] } walkFunc := utils.CollectAllReadableFiles(filePaths, checkExtensionFunc) err := gohasissues.Walk(folder, walkFunc) diff --git a/src/arduino.cc/builder/sketch_loader.go b/src/arduino.cc/builder/sketch_loader.go index 62ffd655..2c2ec10c 100644 --- a/src/arduino.cc/builder/sketch_loader.go +++ b/src/arduino.cc/builder/sketch_loader.go @@ -87,8 +87,10 @@ func (s *SketchLoader) Run(context map[string]interface{}) error { func collectAllSketchFiles(from string) ([]string, error) { filePaths := []string{} - checkExtensionFunc := func(ext string) bool { - return MAIN_FILE_VALID_EXTENSIONS[ext] || ADDITIONAL_FILE_VALID_EXTENSIONS[ext] + checkExtensionFunc := func(filePath string) bool { + name := filepath.Base(filePath) + ext := strings.ToLower(filepath.Ext(filePath)) + return !strings.HasPrefix(name, ".") && MAIN_FILE_VALID_EXTENSIONS[ext] || ADDITIONAL_FILE_VALID_EXTENSIONS[ext] } walkFunc := utils.CollectAllReadableFiles(&filePaths, checkExtensionFunc) err := gohasissues.Walk(from, walkFunc) diff --git a/src/arduino.cc/builder/test/sketch_loader_test.go b/src/arduino.cc/builder/test/sketch_loader_test.go index 20090fa3..120c68f1 100644 --- a/src/arduino.cc/builder/test/sketch_loader_test.go +++ b/src/arduino.cc/builder/test/sketch_loader_test.go @@ -165,3 +165,26 @@ func TestLoadSketchWithBackup(t *testing.T) { require.Equal(t, 0, len(sketch.AdditionalFiles)) require.Equal(t, 0, len(sketch.OtherSketchFiles)) } + +func TestLoadSketchWithMacOSXGarbage(t *testing.T) { + context := make(map[string]interface{}) + context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_macosx_garbage", "sketch.ino") + + commands := []types.Command{ + &builder.SetupHumanLoggerIfMissing{}, + &builder.SketchLoader{}, + } + + for _, command := range commands { + err := command.Run(context) + NoError(t, err) + } + + sketch := context[constants.CTX_SKETCH].(*types.Sketch) + require.NotNil(t, sketch) + + require.Contains(t, sketch.MainFile.Name, "sketch.ino") + + require.Equal(t, 0, len(sketch.AdditionalFiles)) + require.Equal(t, 0, len(sketch.OtherSketchFiles)) +} diff --git a/src/arduino.cc/builder/test/sketch_with_macosx_garbage/.#sketch.ino b/src/arduino.cc/builder/test/sketch_with_macosx_garbage/.#sketch.ino new file mode 100644 index 00000000..71048175 --- /dev/null +++ b/src/arduino.cc/builder/test/sketch_with_macosx_garbage/.#sketch.ino @@ -0,0 +1,2 @@ +void setup() +void loop) } \ No newline at end of file diff --git a/src/arduino.cc/builder/test/sketch_with_macosx_garbage/sketch.ino b/src/arduino.cc/builder/test/sketch_with_macosx_garbage/sketch.ino new file mode 100644 index 00000000..4f069e3b --- /dev/null +++ b/src/arduino.cc/builder/test/sketch_with_macosx_garbage/sketch.ino @@ -0,0 +1,2 @@ +void setup() {} +void loop() {} \ No newline at end of file diff --git a/src/arduino.cc/builder/utils/utils.go b/src/arduino.cc/builder/utils/utils.go index c4f4820f..100598d3 100644 --- a/src/arduino.cc/builder/utils/utils.go +++ b/src/arduino.cc/builder/utils/utils.go @@ -384,9 +384,9 @@ func FilterOutFoldersByNames(folders []os.FileInfo, names ...string) []os.FileIn return filtered } -type CheckFileExtensionFunc func(ext string) bool +type CheckFilePathFunc func(filePath string) bool -func CollectAllReadableFiles(collector *[]string, test CheckFileExtensionFunc) filepath.WalkFunc { +func CollectAllReadableFiles(collector *[]string, test CheckFilePathFunc) filepath.WalkFunc { walkFunc := func(currentPath string, info os.FileInfo, err error) error { if err != nil { return err @@ -395,8 +395,7 @@ func CollectAllReadableFiles(collector *[]string, test CheckFileExtensionFunc) f if info.IsDir() { return nil } - ext := strings.ToLower(filepath.Ext(currentPath)) - if !test(ext) { + if !test(currentPath) { return nil } currentFile, err := os.Open(currentPath) From 344967246e88533845d3088b0ec77e7fdc25b7a0 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Fri, 11 Dec 2015 14:24:15 +0100 Subject: [PATCH 85/85] Releasing 1.3.8 Signed-off-by: Federico Fissore --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 6cdcc8a0..cdba4273 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,7 @@ import ( "syscall" ) -const VERSION = "1.3.7" +const VERSION = "1.3.8" const FLAG_ACTION_COMPILE = "compile" const FLAG_ACTION_PREPROCESS = "preprocess"