You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2016/09/13 03:42:00 UTC
incubator-mynewt-newt git commit: newt syscfg / sysinit.
Repository: incubator-mynewt-newt
Updated Branches:
refs/heads/sterly_refactor [created] 0ae71ef1a
newt syscfg / sysinit.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/commit/0ae71ef1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/tree/0ae71ef1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/diff/0ae71ef1
Branch: refs/heads/sterly_refactor
Commit: 0ae71ef1a900bba44936069d053f90d8797c8650
Parents: 0baf3a3
Author: Christopher Collins <cc...@apache.org>
Authored: Mon Sep 12 20:35:34 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Mon Sep 12 20:35:34 2016 -0700
----------------------------------------------------------------------
newt/Godeps/Godeps.json | 14 +-
newt/builder/build.go | 270 ++++---
newt/builder/buildpackage.go | 102 +--
newt/builder/buildutil.go | 36 +-
newt/builder/load.go | 3 +-
newt/builder/targetbuild.go | 12 +-
newt/cli/build_cmds.go | 127 ++-
newt/cli/complete_cmd.go | 32 +-
newt/cli/target_cmds.go | 109 ++-
newt/newt.go | 8 +-
newt/newtutil/newtutil.go | 72 +-
newt/pkg/localpackage.go | 62 +-
newt/pkg/package.go | 5 +-
newt/pkg/packageutil.go | 32 +
newt/project/project.go | 2 -
newt/syscfg/syscfg.go | 801 +++++++++++++++++++
newt/sysinit/sysinit.go | 154 ++++
newt/toolchain/compiler.go | 6 +-
newt/toolchain/deps.go | 8 +
newt/vendor/mynewt.apache.org/newt/DISCLAIMER | 8 -
newt/vendor/mynewt.apache.org/newt/LICENSE | 244 ------
newt/vendor/mynewt.apache.org/newt/NOTICE | 8 -
newt/vendor/mynewt.apache.org/newt/util/util.go | 21 +
23 files changed, 1556 insertions(+), 580 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/Godeps/Godeps.json
----------------------------------------------------------------------
diff --git a/newt/Godeps/Godeps.json b/newt/Godeps/Godeps.json
index cf4c345..4dcc675 100644
--- a/newt/Godeps/Godeps.json
+++ b/newt/Godeps/Godeps.json
@@ -1,7 +1,7 @@
{
"ImportPath": "mynewt.apache.org/newt/newt",
"GoVersion": "go1.6",
- "GodepVersion": "v74",
+ "GodepVersion": "v58",
"Deps": [
{
"ImportPath": "github.com/Sirupsen/logrus",
@@ -52,18 +52,18 @@
},
{
"ImportPath": "mynewt.apache.org/newt/util",
- "Comment": "mynewt_0_9_0_rc3_tag-91-g904f79b",
- "Rev": "904f79b15feeefe76a9e4ecc139c56fd54aa4412"
+ "Comment": "mynewt_0_9_0_tag-139-g8dddcf6",
+ "Rev": "8dddcf664861e0904e4c89b2bb4c2d498d4cb3a2"
},
{
"ImportPath": "mynewt.apache.org/newt/viper",
- "Comment": "mynewt_0_9_0_rc3_tag-91-g904f79b",
- "Rev": "904f79b15feeefe76a9e4ecc139c56fd54aa4412"
+ "Comment": "mynewt_0_9_0_tag-139-g8dddcf6",
+ "Rev": "8dddcf664861e0904e4c89b2bb4c2d498d4cb3a2"
},
{
"ImportPath": "mynewt.apache.org/newt/yaml",
- "Comment": "mynewt_0_9_0_rc3_tag-91-g904f79b",
- "Rev": "904f79b15feeefe76a9e4ecc139c56fd54aa4412"
+ "Comment": "mynewt_0_9_0_tag-139-g8dddcf6",
+ "Rev": "8dddcf664861e0904e4c89b2bb4c2d498d4cb3a2"
}
]
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/builder/build.go
----------------------------------------------------------------------
diff --git a/newt/builder/build.go b/newt/builder/build.go
index b8cbd39..17b64d1 100644
--- a/newt/builder/build.go
+++ b/newt/builder/build.go
@@ -29,7 +29,10 @@ import (
log "github.com/Sirupsen/logrus"
"mynewt.apache.org/newt/newt/pkg"
+ "mynewt.apache.org/newt/newt/project"
"mynewt.apache.org/newt/newt/symbol"
+ "mynewt.apache.org/newt/newt/syscfg"
+ "mynewt.apache.org/newt/newt/sysinit"
"mynewt.apache.org/newt/newt/target"
"mynewt.apache.org/newt/newt/toolchain"
"mynewt.apache.org/newt/util"
@@ -37,58 +40,31 @@ import (
type Builder struct {
Packages map[*pkg.LocalPackage]*BuildPackage
- features map[string]bool
apis map[string]*BuildPackage
appPkg *BuildPackage
BspPkg *pkg.LocalPackage
compilerInfo *toolchain.CompilerInfo
- featureWhiteList []map[string]interface{}
- featureBlackList []map[string]interface{}
target *TargetBuilder
linkerScript string
buildName string
LinkElf string
-}
-
-func NewBuilder(t *TargetBuilder, buildName string) (*Builder, error) {
- b := &Builder{}
-
- b.buildName = buildName
- /* TODO */
- b.Init(t)
-
- return b, nil
-}
+ injectedSettings map[string]string
-func (b *Builder) Init(t *TargetBuilder) error {
-
- b.target = t
- b.Packages = map[*pkg.LocalPackage]*BuildPackage{}
- b.features = map[string]bool{}
- b.apis = map[string]*BuildPackage{}
- b.LinkElf = ""
-
- return nil
+ Cfg syscfg.Cfg
}
-func (b *Builder) AllFeatures() map[string]bool {
- return b.features
-}
-
-func (b *Builder) Features(pkg pkg.Package) map[string]bool {
- featureList := map[string]bool{}
-
- for fname, _ := range b.features {
- if b.CheckValidFeature(pkg, fname) {
- featureList[fname] = true
- }
+func NewBuilder(t *TargetBuilder, buildName string) (*Builder, error) {
+ b := &Builder{
+ Packages: map[*pkg.LocalPackage]*BuildPackage{},
+ buildName: buildName,
+ apis: map[string]*BuildPackage{},
+ LinkElf: "",
+ target: t,
+ injectedSettings: map[string]string{},
+ Cfg: syscfg.Cfg{},
}
- return featureList
-}
-
-func (b *Builder) AddFeature(feature string) {
- b.features[feature] = true
+ return b, nil
}
func (b *Builder) AddPackage(npkg *pkg.LocalPackage) *BuildPackage {
@@ -122,29 +98,56 @@ func (b *Builder) AddApi(apiString string, bpkg *BuildPackage) bool {
}
}
-func (b *Builder) loadDeps() error {
- // Circularly resolve dependencies, identities, APIs, and required APIs
- // until no new ones exist.
+func (b *Builder) ApiNames() []string {
+ apiNames := make([]string, len(b.apis), len(b.apis))
+
+ i := 0
+ for api, _ := range b.apis {
+ apiNames[i] = api
+ i += 1
+ }
+
+ return apiNames
+}
+
+// @return changed,err
+func (b *Builder) reloadCfg() (bool, error) {
+ apis := make([]string, len(b.apis))
+ i := 0
+ for api, _ := range b.apis {
+ apis[i] = api
+ i++
+ }
+
+ cfg, err := syscfg.Read(b.sortedLocalPackages(), apis, b.injectedSettings)
+ if err != nil {
+ return false, err
+ }
+
+ changed := false
+ for k, v := range cfg {
+ oldval, ok := b.Cfg[k]
+ if !ok || len(oldval.History) != len(v.History) {
+ b.Cfg = cfg
+ changed = true
+ }
+ }
+
+ return changed, nil
+}
+
+func (b *Builder) loadDepsOnce() (bool, error) {
+ // Circularly resolve dependencies, APIs, and required APIs until no new
+ // ones exist.
+ newDeps := false
for {
reprocess := false
for _, bpkg := range b.Packages {
- newDeps, newFeatures, err := bpkg.Resolve(b)
+ newDeps, err := bpkg.Resolve(b, b.Cfg)
if err != nil {
- return err
+ return false, err
}
- if newFeatures {
- // A new supported feature was discovered. It is impossible
- // to determine what new dependency and API requirements are
- // generated as a result. All packages need to be
- // reprocessed.
- for _, bpkg := range b.Packages {
- bpkg.depsResolved = false
- bpkg.apisSatisfied = false
- }
- reprocess = true
- break
- }
if newDeps {
// The new dependencies need to be processed. Iterate again
// after this iteration completes.
@@ -157,6 +160,43 @@ func (b *Builder) loadDeps() error {
}
}
+ return newDeps, nil
+}
+
+func (b *Builder) loadDeps() error {
+ if _, err := b.loadDepsOnce(); err != nil {
+ return err
+ }
+
+ for {
+ cfgChanged, err := b.reloadCfg()
+ if err != nil {
+ return err
+ }
+ if cfgChanged {
+ // A new supported feature was discovered. It is impossible
+ // to determine what new dependency and API requirements are
+ // generated as a result. All packages need to be
+ // reprocessed.
+ for _, bpkg := range b.Packages {
+ bpkg.depsResolved = false
+ bpkg.apisSatisfied = false
+ }
+ }
+
+ newDeps, err := b.loadDepsOnce()
+ if err != nil {
+ return err
+ }
+
+ if !newDeps && !cfgChanged {
+ break
+ }
+ }
+
+ // Log the final syscfg.
+ syscfg.Log(b.Cfg)
+
return nil
}
@@ -233,12 +273,6 @@ func (b *Builder) newCompiler(bpkg *BuildPackage,
c.AddInfo(ci)
}
- // Specify all the source yml files as dependencies. If a yml file has
- // changed, a full rebuild is required.
- for _, bp := range b.Packages {
- c.AddDeps(bp.CfgFilenames()...)
- }
-
return c, nil
}
@@ -271,25 +305,10 @@ func (b *Builder) buildPackage(bpkg *BuildPackage) error {
srcDirs = append(srcDirs, srcDir)
}
- // Build the package source in two phases:
- // 1. Non-test code.
- // 2. Test code (if the "test" feature is enabled).
- //
- // This is done in two passes because the structure of
- // architecture-specific directories is different for normal code and test
- // code, and not easy to generalize into a single operation:
- // * src/arch/<target-arch>
- // * src/test/arch/<target-arch>
for _, dir := range srcDirs {
- if err = buildDir(dir, c, b.target.Bsp.Arch, []string{"test"}); err != nil {
+ if err = buildDir(dir, c, b.target.Bsp.Arch, nil); err != nil {
return err
}
- if b.features["TEST"] {
- testSrcDir := dir + "/test"
- if err = buildDir(testSrcDir, c, b.target.Bsp.Arch, nil); err != nil {
- return err
- }
- }
}
// Create a static library ("archive").
@@ -347,7 +366,7 @@ func (b *Builder) link(elfName string, linkerScript string,
}
if linkerScript != "" {
- c.LinkerScript = b.target.Bsp.BasePath() + linkerScript
+ c.LinkerScript = b.target.Bsp.BasePath() + "/" + linkerScript
}
err = c.CompileElf(elfName, pkgNames, keepSymbols, b.LinkElf)
if err != nil {
@@ -363,9 +382,6 @@ func (b *Builder) link(elfName string, linkerScript string,
func (b *Builder) PrepBuild(appPkg *pkg.LocalPackage,
bspPkg *pkg.LocalPackage, targetPkg *pkg.LocalPackage) error {
- b.featureBlackList = []map[string]interface{}{}
- b.featureWhiteList = []map[string]interface{}{}
-
// Seed the builder with the app (if present), bsp, and target packages.
b.BspPkg = bspPkg
@@ -377,9 +393,6 @@ func (b *Builder) PrepBuild(appPkg *pkg.LocalPackage,
appBpkg = b.AddPackage(appPkg)
}
b.appPkg = appBpkg
-
- b.featureBlackList = append(b.featureBlackList, appBpkg.FeatureBlackList())
- b.featureWhiteList = append(b.featureWhiteList, appBpkg.FeatureWhiteList())
}
bspBpkg := b.Packages[bspPkg]
@@ -388,14 +401,8 @@ func (b *Builder) PrepBuild(appPkg *pkg.LocalPackage,
bspBpkg = b.AddPackage(bspPkg)
}
- b.featureBlackList = append(b.featureBlackList, bspPkg.FeatureBlackList())
- b.featureWhiteList = append(b.featureWhiteList, bspPkg.FeatureWhiteList())
-
targetBpkg := b.AddPackage(targetPkg)
- b.featureBlackList = append(b.featureBlackList, targetBpkg.FeatureBlackList())
- b.featureWhiteList = append(b.featureWhiteList, targetBpkg.FeatureWhiteList())
-
// Populate the full set of packages to be built and resolve the feature
// set.
if err := b.loadDeps(); err != nil {
@@ -428,12 +435,12 @@ func (b *Builder) PrepBuild(appPkg *pkg.LocalPackage,
baseCi := toolchain.NewCompilerInfo()
// Target flags.
- log.Debugf("Generating build flags for target %s", b.target.target.FullName())
+ log.Debugf("Generating build flags for target %s",
+ b.target.target.FullName())
targetCi, err := targetBpkg.CompilerInfo(b)
if err != nil {
return err
}
-
baseCi.AddCompilerInfo(targetCi)
// App flags.
@@ -443,6 +450,7 @@ func (b *Builder) PrepBuild(appPkg *pkg.LocalPackage,
if err != nil {
return err
}
+
baseCi.AddCompilerInfo(appCi)
}
@@ -468,6 +476,18 @@ func (b *Builder) PrepBuild(appPkg *pkg.LocalPackage,
// package being built are calculated.
b.compilerInfo = baseCi
+ lpkgs := b.sortedLocalPackages()
+ if err := syscfg.EnsureWritten(b.Cfg, lpkgs, b.ApiNames(),
+ targetPkg.BasePath()); err != nil {
+ return err
+ }
+
+ if err := sysinit.EnsureWritten(lpkgs, targetPkg.BasePath()); err != nil {
+ return err
+ }
+
+ b.compilerInfo = baseCi
+
return nil
}
@@ -493,29 +513,11 @@ func (b *Builder) matchFeature(flist []map[string]interface{},
return false
}
-func (b *Builder) CheckValidFeature(pkg pkg.Package,
- feature string) bool {
-
- // If the feature is not in the blacklist, automatically valid
- if match := b.matchFeature(b.featureBlackList, pkg, feature); !match {
- return true
- }
-
- // If it is in the blacklist, check if its in the whitelist
- // if not, override the feature definition.
- if match := b.matchFeature(b.featureWhiteList, pkg, feature); match {
- return true
- } else {
- return false
- }
-}
-
func (b *Builder) AddCompilerInfo(info *toolchain.CompilerInfo) {
b.compilerInfo.AddCompilerInfo(info)
}
func (b *Builder) Build() error {
-
// Build the packages alphabetically to ensure a consistent order.
bpkgs := b.sortedBuildPackages()
for _, bpkg := range bpkgs {
@@ -555,32 +557,50 @@ func (b *Builder) TestLink(linkerScript string) error {
return nil
}
-func (b *Builder) Test(p *pkg.LocalPackage) error {
+func (b *Builder) pkgWithPath(path string) *BuildPackage {
+ for _, p := range b.Packages {
+ if p.BasePath() == path {
+ return p
+ }
+ }
- // Seed the builder with the package under test.
- testBpkg := b.AddPackage(p)
+ return nil
+}
- // Define the PKG_TEST symbol while the package under test is being
- // compiled. This symbol enables the appropriate main function that
- // usually comes from an app.
- testPkgCi, err := testBpkg.CompilerInfo(b)
- if err != nil {
- return err
+func (b *Builder) testOwner(p *BuildPackage) *BuildPackage {
+ if p.Type() != pkg.PACKAGE_TYPE_UNITTEST {
+ panic("Expected unittest package; got: " + p.Name())
}
- testPkgCi.Cflags = append(testPkgCi.Cflags, "-DMYNEWT_SELFTEST")
+ curPath := p.BasePath()
+
+ for {
+ parentPath := filepath.Dir(curPath)
+ if parentPath == project.GetProject().BasePath || parentPath == "." {
+ return nil
+ }
+
+ parentPkg := b.pkgWithPath(parentPath)
+ if parentPkg != nil && parentPkg.Type() != pkg.PACKAGE_TYPE_UNITTEST {
+ log.Debugf("OWNER=%s", parentPkg.Name())
+ return parentPkg
+ }
+
+ curPath = parentPath
+ }
+}
+
+func (b *Builder) Test(p *pkg.LocalPackage) error {
// Build the packages alphabetically to ensure a consistent order.
bpkgs := b.sortedBuildPackages()
for _, bpkg := range bpkgs {
- err = b.buildPackage(bpkg)
- if err != nil {
+ if err := b.buildPackage(bpkg); err != nil {
return err
}
}
testFilename := b.TestExePath(p.Name())
- err = b.link(testFilename, "", nil)
- if err != nil {
+ if err := b.link(testFilename, "", nil); err != nil {
return err
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/builder/buildpackage.go
----------------------------------------------------------------------
diff --git a/newt/builder/buildpackage.go b/newt/builder/buildpackage.go
index b2d59fe..2cdd75b 100644
--- a/newt/builder/buildpackage.go
+++ b/newt/builder/buildpackage.go
@@ -30,6 +30,7 @@ import (
"mynewt.apache.org/newt/newt/newtutil"
"mynewt.apache.org/newt/newt/pkg"
"mynewt.apache.org/newt/newt/project"
+ "mynewt.apache.org/newt/newt/syscfg"
"mynewt.apache.org/newt/newt/toolchain"
"mynewt.apache.org/newt/util"
)
@@ -139,20 +140,21 @@ func (bpkg *BuildPackage) CompilerInfo(b *Builder) (*toolchain.CompilerInfo, err
}
ci := toolchain.NewCompilerInfo()
- ci.Cflags = newtutil.GetStringSliceFeatures(bpkg.Viper, b.Features(bpkg),
+ features := syscfg.FeaturesForLpkg(b.Cfg, bpkg.LocalPackage)
+ ci.Cflags = newtutil.GetStringSliceFeatures(bpkg.Viper, features,
"pkg.cflags")
- ci.Lflags = newtutil.GetStringSliceFeatures(bpkg.Viper, b.Features(bpkg),
+ ci.Lflags = newtutil.GetStringSliceFeatures(bpkg.Viper, features,
"pkg.lflags")
- ci.Aflags = newtutil.GetStringSliceFeatures(bpkg.Viper, b.Features(bpkg),
+ ci.Aflags = newtutil.GetStringSliceFeatures(bpkg.Viper, features,
"pkg.aflags")
- for fname, _ := range b.Features(bpkg) {
- ci.Cflags = append(ci.Cflags, fmt.Sprintf("-DFEATURE_%s", fname))
+ for k, _ := range bpkg.InjectedSettings() {
+ ci.Cflags = append(ci.Cflags, syscfg.FeatureToCflag(k))
}
ci.IgnoreFiles = []*regexp.Regexp{}
ignPats := newtutil.GetStringSliceFeatures(bpkg.Viper,
- b.Features(bpkg), "pkg.ign_files")
+ features, "pkg.ign_files")
for _, str := range ignPats {
re, err := regexp.Compile(str)
if err != nil {
@@ -164,7 +166,7 @@ func (bpkg *BuildPackage) CompilerInfo(b *Builder) (*toolchain.CompilerInfo, err
ci.IgnoreDirs = []*regexp.Regexp{}
ignPats = newtutil.GetStringSliceFeatures(bpkg.Viper,
- b.Features(bpkg), "pkg.ign_dirs")
+ features, "pkg.ign_dirs")
for _, str := range ignPats {
re, err := regexp.Compile(str)
if err != nil {
@@ -175,38 +177,19 @@ func (bpkg *BuildPackage) CompilerInfo(b *Builder) (*toolchain.CompilerInfo, err
}
bpkg.SourceDirectories = newtutil.GetStringSliceFeatures(bpkg.Viper,
- b.Features(bpkg), "pkg.src_dirs")
+ features, "pkg.src_dirs")
includePaths, err := bpkg.recursiveIncludePaths(b)
if err != nil {
return nil, err
}
+
ci.Includes = append(bpkg.privateIncludeDirs(b), includePaths...)
bpkg.ci = ci
return bpkg.ci, nil
}
-func (bpkg *BuildPackage) loadFeatures(b *Builder) (map[string]bool, bool) {
- features := b.AllFeatures()
-
- foundNewFeature := false
-
- newFeatures := newtutil.GetStringSliceFeatures(bpkg.Viper, features,
- "pkg.features")
- for _, nfeature := range newFeatures {
- _, ok := features[nfeature]
- if !ok {
- b.AddFeature(nfeature)
- foundNewFeature = true
- log.Debugf("Detected new feature: %s (%s)", nfeature,
- bpkg.Name())
- }
- }
-
- return b.Features(bpkg), foundNewFeature
-}
-
// Searches for a package which can satisfy bpkg's API requirement. If such a
// package is found, bpkg's API requirement is marked as satisfied, and the
// package is added to bpkg's dependency list.
@@ -270,8 +253,7 @@ func (bpkg *BuildPackage) loadDeps(b *Builder,
// Determine if this package supports any APIs that we haven't seen
// yet. If so, another full iteration is required.
- apis := newtutil.GetStringSliceFeatures(bpkg.Viper, b.Features(bpkg),
- "pkg.apis")
+ apis := newtutil.GetStringSliceFeatures(bpkg.Viper, features, "pkg.apis")
for _, api := range apis {
newApi := b.AddApi(api, bpkg)
if newApi {
@@ -285,7 +267,9 @@ func (bpkg *BuildPackage) loadDeps(b *Builder,
// @return bool true if a new dependency was detected as a
// result of satisfying an API for this
// package.
-func (bpkg *BuildPackage) satisfyApis(b *Builder) bool {
+func (bpkg *BuildPackage) satisfyApis(b *Builder,
+ features map[string]bool) bool {
+
// Assume all this package's APIs are satisfied and that no new
// dependencies will be detected.
bpkg.apisSatisfied = true
@@ -293,7 +277,7 @@ func (bpkg *BuildPackage) satisfyApis(b *Builder) bool {
// Determine if any of the package's API requirements can now be satisfied.
// If so, another full iteration is required.
- reqApis := newtutil.GetStringSliceFeatures(bpkg.Viper, b.Features(bpkg),
+ reqApis := newtutil.GetStringSliceFeatures(bpkg.Viper, features,
"pkg.req_apis")
for _, reqApi := range reqApis {
reqStatus, ok := bpkg.reqApiMap[reqApi]
@@ -364,19 +348,25 @@ func (bpkg *BuildPackage) privateIncludeDirs(b *Builder) []string {
incls = append(incls, srcDir)
incls = append(incls, srcDir+"/arch/"+b.target.Bsp.Arch)
- if b.Features(bpkg)["TEST"] {
- testSrcDir := srcDir + "/test"
- incls = append(incls, testSrcDir)
- incls = append(incls, testSrcDir+"/arch/"+b.target.Bsp.Arch)
- }
-
- // If pkgType == SDK, include all the items in "ext" directly into the
- // include path
- if bpkg.Type() == pkg.PACKAGE_TYPE_SDK {
+ switch bpkg.Type() {
+ case pkg.PACKAGE_TYPE_SDK:
+ // If pkgType == SDK, include all the items in "ext" directly into the
+ // include path
incls = append(incls, b.target.Bsp.BasePath()+"/include/bsp/")
sdkIncls := bpkg.findSdkIncludes()
incls = append(incls, sdkIncls...)
+
+ case pkg.PACKAGE_TYPE_UNITTEST:
+ // A unittest package gets access to its parent package's private
+ // includes.
+ parentPkg := b.testOwner(bpkg)
+ if parentPkg != nil {
+ parentIncls := parentPkg.privateIncludeDirs(b)
+ incls = append(incls, parentIncls...)
+ }
+
+ default:
}
return incls
@@ -396,42 +386,38 @@ func (bpkg *BuildPackage) privateIncludeDirs(b *Builder) []string {
//
// @return bool true if >=1 dependencies were resolved
// bool true if >=1 new features were detected
-func (bpkg *BuildPackage) Resolve(b *Builder) (bool, bool, error) {
+func (bpkg *BuildPackage) Resolve(b *Builder,
+ cfg syscfg.Cfg) (bool, error) {
+
var err error
newDeps := false
- newFeatures := false
- if !bpkg.depsResolved {
- var features map[string]bool
+ features := syscfg.FeaturesForLpkg(cfg, bpkg.LocalPackage)
- features, newFeatures = bpkg.loadFeatures(b)
+ if !bpkg.depsResolved {
newDeps, err = bpkg.loadDeps(b, features)
if err != nil {
- return false, false, err
+ return false, err
}
- bpkg.depsResolved = !newFeatures && !newDeps
-
+ bpkg.depsResolved = !newDeps
}
if !bpkg.apisSatisfied {
- newApiDep := bpkg.satisfyApis(b)
+ newApiDep := bpkg.satisfyApis(b, features)
if newApiDep {
newDeps = true
}
}
- return newDeps, newFeatures, nil
-}
-
-func (bp *BuildPackage) Init(pkg *pkg.LocalPackage) {
- bp.LocalPackage = pkg
- bp.reqApiMap = map[string]reqApiStatus{}
+ return newDeps, nil
}
func NewBuildPackage(pkg *pkg.LocalPackage) *BuildPackage {
- bpkg := &BuildPackage{}
- bpkg.Init(pkg)
+ bpkg := &BuildPackage{
+ LocalPackage: pkg,
+ reqApiMap: map[string]reqApiStatus{},
+ }
return bpkg
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/builder/buildutil.go
----------------------------------------------------------------------
diff --git a/newt/builder/buildutil.go b/newt/builder/buildutil.go
index ca5a157..f35a1db 100644
--- a/newt/builder/buildutil.go
+++ b/newt/builder/buildutil.go
@@ -23,10 +23,13 @@ import (
"bytes"
"path/filepath"
"sort"
+ "strings"
log "github.com/Sirupsen/logrus"
+ "mynewt.apache.org/newt/newt/pkg"
"mynewt.apache.org/newt/newt/project"
+ "mynewt.apache.org/newt/newt/syscfg"
"mynewt.apache.org/newt/util"
)
@@ -77,25 +80,27 @@ func (b *Builder) AppBinBasePath() string {
return b.PkgBinDir(pkgName) + "/" + filepath.Base(pkgName)
}
+func TestTargetName(testPkgName string) string {
+ return strings.Replace(testPkgName, "/", "_", -1)
+}
+
func (b *Builder) TestExePath(pkgName string) string {
- return b.PkgBinDir(pkgName) + "/test_" + filepath.Base(pkgName)
+ return b.PkgBinDir(pkgName) + "/" + TestTargetName(pkgName)
}
func (b *Builder) FeatureString() string {
var buffer bytes.Buffer
- features := make([]string, 0, len(b.Features(nil)))
- for f, _ := range b.Features(nil) {
- features = append(features, f)
+ featureMap := syscfg.Features(b.Cfg)
+ featureSlice := make([]string, 0, len(featureMap))
+ for k, _ := range featureMap {
+ featureSlice = append(featureSlice, k)
}
- sort.Strings(features)
+ sort.Strings(featureSlice)
- first := true
- for _, feature := range features {
- if !first {
+ for i, feature := range featureSlice {
+ if i != 0 {
buffer.WriteString(" ")
- } else {
- first = false
}
buffer.WriteString(feature)
@@ -168,6 +173,17 @@ func (b *Builder) sortedBuildPackages() []*BuildPackage {
return sorter.bpkgs
}
+func (b *Builder) sortedLocalPackages() []*pkg.LocalPackage {
+ bpkgs := b.sortedBuildPackages()
+
+ lpkgs := make([]*pkg.LocalPackage, len(bpkgs), len(bpkgs))
+ for i, bpkg := range bpkgs {
+ lpkgs[i] = bpkg.LocalPackage
+ }
+
+ return lpkgs
+}
+
func (b *Builder) logDepInfo() {
// Log feature set.
log.Debugf("Feature set: [" + b.FeatureString() + "]")
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/builder/load.go
----------------------------------------------------------------------
diff --git a/newt/builder/load.go b/newt/builder/load.go
index 0c1a85b..9596532 100644
--- a/newt/builder/load.go
+++ b/newt/builder/load.go
@@ -25,6 +25,7 @@ import (
"path/filepath"
"mynewt.apache.org/newt/newt/project"
+ "mynewt.apache.org/newt/newt/syscfg"
"mynewt.apache.org/newt/util"
)
@@ -87,7 +88,7 @@ func (b *Builder) Load(image_slot int, extraJtagCmd string) error {
downloadCmd := fmt.Sprintf("%s %s %s %s", envSettings, downloadScript, bspPath,
binBaseName)
- features := b.Features(nil)
+ features := syscfg.Features(b.Cfg)
if _, ok := features["bootloader"]; ok {
util.StatusMessage(util.VERBOSITY_DEFAULT,
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/builder/targetbuild.go
----------------------------------------------------------------------
diff --git a/newt/builder/targetbuild.go b/newt/builder/targetbuild.go
index 3d9d96b..96b43f0 100644
--- a/newt/builder/targetbuild.go
+++ b/newt/builder/targetbuild.go
@@ -27,6 +27,7 @@ import (
"mynewt.apache.org/newt/newt/pkg"
"mynewt.apache.org/newt/newt/project"
"mynewt.apache.org/newt/newt/symbol"
+ "mynewt.apache.org/newt/newt/syscfg"
"mynewt.apache.org/newt/newt/target"
"mynewt.apache.org/newt/newt/toolchain"
"mynewt.apache.org/newt/util"
@@ -156,7 +157,7 @@ func (t *TargetBuilder) Build() error {
/* Build the Apps */
project.ResetDeps(t.AppList)
- if err := t.Bsp.Reload(t.App.Features(t.App.BspPkg)); err != nil {
+ if err := t.Bsp.Reload(syscfg.Features(t.App.Cfg)); err != nil {
return err
}
@@ -181,7 +182,7 @@ func (t *TargetBuilder) Build() error {
/* rebuild the loader */
project.ResetDeps(t.LoaderList)
- if err = t.Bsp.Reload(t.Loader.Features(t.Loader.BspPkg)); err != nil {
+ if err = t.Bsp.Reload(syscfg.Features(t.Loader.Cfg)); err != nil {
return err
}
@@ -403,10 +404,11 @@ func (t *TargetBuilder) Test(p *pkg.LocalPackage) error {
// used:
// * TEST: ensures that the test code gets compiled.
// * SELFTEST: indicates that there is no app.
- t.App.AddFeature("TEST")
- t.App.AddFeature("SELFTEST")
+ t.App.injectedSettings["TEST"] = "1"
+ p.InjectedSettings()["SELFTEST"] = "1"
- err = t.App.PrepBuild(p, bspPkg, targetPkg)
+ t.App.AddPackage(p)
+ err = t.App.PrepBuild(nil, bspPkg, targetPkg)
if err != nil {
return err
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/cli/build_cmds.go
----------------------------------------------------------------------
diff --git a/newt/cli/build_cmds.go b/newt/cli/build_cmds.go
index bc19cf5..a26deb7 100644
--- a/newt/cli/build_cmds.go
+++ b/newt/cli/build_cmds.go
@@ -22,6 +22,7 @@ package cli
import (
"fmt"
"os"
+ "path/filepath"
"github.com/spf13/cobra"
"mynewt.apache.org/newt/newt/builder"
@@ -33,12 +34,68 @@ import (
const TARGET_TEST_NAME = "unittest"
-var extraJtagCmd string
+var testablePkgMap map[*pkg.LocalPackage]struct{}
+
+func testablePkgs() map[*pkg.LocalPackage]struct{} {
+ if testablePkgMap != nil {
+ return testablePkgMap
+ }
+
+ testablePkgMap := map[*pkg.LocalPackage]struct{}{}
+
+ // Create a map of path => lclPkg.
+ proj := project.GetProject()
+ allPkgs := proj.PackagesOfType(-1)
+ pathLpkgMap := make(map[string]*pkg.LocalPackage, len(allPkgs))
+ for _, p := range allPkgs {
+ lpkg := p.(*pkg.LocalPackage)
+ pathLpkgMap[lpkg.BasePath()] = lpkg
+ }
+
+ // Add all unit test packages to the testable package map.
+ testPkgs := proj.PackagesOfType(pkg.PACKAGE_TYPE_UNITTEST)
+ for _, p := range testPkgs {
+ lclPack := p.(*pkg.LocalPackage)
+ testablePkgMap[lclPack] = struct{}{}
+ }
+
+ // Next add first ancestor of each test package.
+ for testPkg, _ := range testablePkgMap {
+ for cur := filepath.Dir(testPkg.BasePath()); cur != proj.BasePath; cur = filepath.Dir(cur) {
+ lpkg := pathLpkgMap[cur]
+ if lpkg != nil && lpkg.Type() != pkg.PACKAGE_TYPE_UNITTEST {
+ testablePkgMap[lpkg] = struct{}{}
+ break
+ }
+ }
+ }
-func pkgIsTestable(pack *pkg.LocalPackage) bool {
- return util.NodeExist(pack.BasePath() + "/src/test")
+ return testablePkgMap
}
+func pkgToUnitTests(pack *pkg.LocalPackage) []*pkg.LocalPackage {
+ // If the user specified a unittest package, just test that one.
+ if pack.Type() == pkg.PACKAGE_TYPE_UNITTEST {
+ return []*pkg.LocalPackage{pack}
+ }
+
+ // Otherwise, return all the package's direct descendants that are unit
+ // test packages.
+ result := []*pkg.LocalPackage{}
+ srcPath := pack.BasePath()
+ for p, _ := range testablePkgs() {
+ if p.Type() == pkg.PACKAGE_TYPE_UNITTEST &&
+ filepath.Dir(p.BasePath()) == srcPath {
+
+ result = append(result, p)
+ }
+ }
+
+ return result
+}
+
+var extraJtagCmd string
+
func buildRunCmd(cmd *cobra.Command, args []string) {
if err := project.Initialize(); err != nil {
NewtUsage(cmd, err)
@@ -132,10 +189,17 @@ func cleanRunCmd(cmd *cobra.Command, args []string) {
}
}
-func testRunCmd(cmd *cobra.Command, args []string) {
- if err := project.Initialize(); err != nil {
- NewtUsage(cmd, err)
+func pkgnames(pkgs []*pkg.LocalPackage) string {
+ s := ""
+
+ for _, p := range pkgs {
+ s += p.Name() + " "
}
+
+ return s
+}
+
+func testRunCmd(cmd *cobra.Command, args []string) {
if len(args) < 1 {
NewtUsage(cmd, nil)
}
@@ -152,26 +216,26 @@ func testRunCmd(cmd *cobra.Command, args []string) {
NewtUsage(cmd, err)
}
- if !pkgIsTestable(pack) {
+ testPkgs := pkgToUnitTests(pack)
+ if len(testPkgs) == 0 {
NewtUsage(nil, util.FmtNewtError("Package %s contains no "+
"unit tests", pack.FullName()))
}
- packs = append(packs, pack)
+ packs = append(packs, testPkgs...)
}
}
+ proj := project.GetProject()
+
if testAll {
- packs = []*pkg.LocalPackage{}
- for _, repoHash := range project.GetProject().PackageList() {
- for _, pack := range *repoHash {
- lclPack := pack.(*pkg.LocalPackage)
-
- if pkgIsTestable(lclPack) {
- packs = append(packs, lclPack)
- }
- }
+ packItfs := proj.PackagesOfType(pkg.PACKAGE_TYPE_UNITTEST)
+ packs = make([]*pkg.LocalPackage, len(packItfs))
+ for i, p := range packItfs {
+ packs[i] = p.(*pkg.LocalPackage)
}
+
+ packs = pkg.SortLclPkgs(packs)
}
if len(packs) == 0 {
@@ -186,13 +250,36 @@ func testRunCmd(cmd *cobra.Command, args []string) {
NewtUsage(nil, err)
}
- // Use the standard unit test target for all tests.
- t := ResolveTarget(TARGET_TEST_NAME)
- if t == nil {
+ // Each unit test package gets its own target. This target is a copy
+ // of the base unit test package, just with an appropriate name. The
+ // reason each test needs a unique target is: syscfg and sysinit are
+ // target-specific. If each test package shares a target, they will
+ // overwrite these generated headers each time they are run. Worse, if
+ // two tests are run back-to-back, the timestamps may indicate that the
+ // headers have not changed between tests, causing build failures.
+ baseTarget := ResolveTarget(TARGET_TEST_NAME)
+ if baseTarget == nil {
NewtUsage(nil, util.NewNewtError("Can't find unit test target: "+
TARGET_TEST_NAME))
}
+ targetName := fmt.Sprintf("%s/%s/%s",
+ TARGET_DEFAULT_DIR, TARGET_TEST_NAME,
+ builder.TestTargetName(pack.Name()))
+
+ t := ResolveTarget(targetName)
+ if t == nil {
+ targetName, err := ResolveNewTargetName(targetName)
+ if err != nil {
+ NewtUsage(nil, err)
+ }
+
+ t = baseTarget.Clone(proj.LocalRepo(), targetName)
+ if err := t.Save(); err != nil {
+ NewtUsage(nil, err)
+ }
+ }
+
b, err := builder.NewTargetBuilder(t)
if err != nil {
NewtUsage(nil, err)
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/cli/complete_cmd.go
----------------------------------------------------------------------
diff --git a/newt/cli/complete_cmd.go b/newt/cli/complete_cmd.go
index c01410c..b2e83b6 100644
--- a/newt/cli/complete_cmd.go
+++ b/newt/cli/complete_cmd.go
@@ -54,35 +54,17 @@ func targetList() []string {
return targetNames
}
-/* return a list of all packages */
+/* @return A slice of all testable package names. */
func packageList() []string {
-
- err := project.Initialize()
-
- var list []string
-
- if err != nil {
- return list
- }
- for _, repoHash := range project.GetProject().PackageList() {
- for _, pack := range *repoHash {
- lclPack := pack.(*pkg.LocalPackage)
-
- if pkgIsTestable(lclPack) {
- list = append(list, lclPack.FullName())
- }
+ packs := testablePkgs()
+ names := make([]string, 0, len(packs))
+ for pack, _ := range packs {
+ if pack.Type() != pkg.PACKAGE_TYPE_UNITTEST {
+ names = append(names, pack.FullName())
}
}
- return list
-}
-func isValueInList(value string, list []string) int {
- for i, v := range list {
- if v == value {
- return i
- }
- }
- return -1
+ return names
}
func completeRunCmd(cmd *cobra.Command, args []string) {
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/cli/target_cmds.go
----------------------------------------------------------------------
diff --git a/newt/cli/target_cmds.go b/newt/cli/target_cmds.go
index b9ebada..364fbaf 100644
--- a/newt/cli/target_cmds.go
+++ b/newt/cli/target_cmds.go
@@ -29,8 +29,10 @@ import (
"strings"
"github.com/spf13/cobra"
+ "mynewt.apache.org/newt/newt/builder"
"mynewt.apache.org/newt/newt/pkg"
"mynewt.apache.org/newt/newt/project"
+ "mynewt.apache.org/newt/newt/syscfg"
"mynewt.apache.org/newt/newt/target"
"mynewt.apache.org/newt/util"
)
@@ -333,6 +335,90 @@ func targetCopyCmd(cmd *cobra.Command, args []string) {
}
}
+func printSetting(entry syscfg.CfgEntry) {
+ util.StatusMessage(util.VERBOSITY_DEFAULT,
+ " * Setting: %s\n", entry.Name)
+
+ util.StatusMessage(util.VERBOSITY_DEFAULT,
+ " * Description: %s\n", entry.Description)
+
+ util.StatusMessage(util.VERBOSITY_DEFAULT,
+ " * Value: %s", entry.Value)
+
+ unfixed := syscfg.UnfixedValue(entry)
+ if unfixed != entry.Value {
+ util.StatusMessage(util.VERBOSITY_DEFAULT, " [%s]", unfixed)
+ }
+ util.StatusMessage(util.VERBOSITY_DEFAULT, "\n")
+
+ if len(entry.History) > 1 {
+ util.StatusMessage(util.VERBOSITY_DEFAULT,
+ " * Overridden: ")
+ for i := 1; i < len(entry.History); i++ {
+ util.StatusMessage(util.VERBOSITY_DEFAULT, "%s, ",
+ entry.History[i].Source.Name())
+ }
+ util.StatusMessage(util.VERBOSITY_DEFAULT,
+ "default=%s\n", entry.History[0].Value)
+ }
+}
+
+func printPkgCfg(pkgName string, cfg syscfg.Cfg, entries []syscfg.CfgEntry) {
+ util.StatusMessage(util.VERBOSITY_DEFAULT, "* PACKAGE: %s\n", pkgName)
+
+ settingNames := make([]string, len(entries))
+ for i, entry := range entries {
+ settingNames[i] = entry.Name
+ }
+ sort.Strings(settingNames)
+
+ for _, name := range settingNames {
+ printSetting(cfg[name])
+ }
+}
+
+func printCfg(cfg syscfg.Cfg) {
+ pkgNameEntryMap := syscfg.EntriesByPkg(cfg)
+
+ pkgNames := make([]string, 0, len(pkgNameEntryMap))
+ for pkgName, _ := range pkgNameEntryMap {
+ pkgNames = append(pkgNames, pkgName)
+ }
+ sort.Strings(pkgNames)
+
+ for i, pkgName := range pkgNames {
+ if i > 0 {
+ util.StatusMessage(util.VERBOSITY_DEFAULT, "\n")
+ }
+ printPkgCfg(pkgName, cfg, pkgNameEntryMap[pkgName])
+ }
+}
+
+func targetConfigCmd(cmd *cobra.Command, args []string) {
+ if err := project.Initialize(); err != nil {
+ NewtUsage(cmd, err)
+ }
+ if len(args) != 1 {
+ NewtUsage(cmd, util.NewNewtError("Must specify target name"))
+ }
+
+ t, err := resolveExistingTargetArg(args[0])
+ if err != nil {
+ NewtUsage(cmd, err)
+ }
+
+ b, err := builder.NewTargetBuilder(t)
+ if err != nil {
+ NewtUsage(nil, err)
+ }
+
+ if err := b.PrepBuild(); err != nil {
+ NewtUsage(nil, err)
+ }
+
+ printCfg(b.App.Cfg)
+}
+
func AddTargetCommands(cmd *cobra.Command) {
targetHelpText := ""
targetHelpEx := ""
@@ -415,12 +501,25 @@ func AddTargetCommands(cmd *cobra.Command) {
copyHelpEx += " newt target copy blinky_sim my_target"
copyCmd := &cobra.Command{
- Use: "copy",
- Short: "Copy target",
- Long: copyHelpText,
- Example: copyHelpEx,
- Run: targetCopyCmd,
+ Use: "copy",
+ Short: "Copy target",
+ Long: copyHelpText,
+ Example: copyHelpEx,
+ Run: targetCopyCmd,
+ ValidArgs: targetList(),
}
targetCmd.AddCommand(copyCmd)
+
+ configHelpText := "View a target's system configuration."
+
+ configCmd := &cobra.Command{
+ Use: "config <target-name>",
+ Short: "View target system configuration",
+ Long: configHelpText,
+ Run: targetConfigCmd,
+ ValidArgs: targetList(),
+ }
+
+ targetCmd.AddCommand(configCmd)
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/newt.go
----------------------------------------------------------------------
diff --git a/newt/newt.go b/newt/newt.go
index 03fb8de..f1e0c2d 100644
--- a/newt/newt.go
+++ b/newt/newt.go
@@ -28,6 +28,7 @@ import (
"mynewt.apache.org/newt/newt/cli"
"mynewt.apache.org/newt/newt/newtutil"
+ "mynewt.apache.org/newt/newt/project"
"mynewt.apache.org/newt/util"
)
@@ -114,13 +115,14 @@ func newtCmd() *cobra.Command {
}
func main() {
-
cmd := newtCmd()
/* some of the setup code logs which messes with autocomplete */
hold_lvl := log.GetLevel()
log.SetLevel(log.FatalLevel)
+ initErr := project.Initialize()
+
cli.AddCompleteCommands(cmd)
cli.AddProjectCommands(cmd)
cli.AddTargetCommands(cmd)
@@ -146,6 +148,10 @@ func main() {
cmd.SilenceUsage = false
}
+ if initErr != nil {
+ cli.NewtUsage(nil, initErr)
+ }
+
log.SetLevel(hold_lvl)
cmd.Execute()
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/newtutil/newtutil.go
----------------------------------------------------------------------
diff --git a/newt/newtutil/newtutil.go b/newt/newtutil/newtutil.go
index 42e68fb..947ab49 100644
--- a/newt/newtutil/newtutil.go
+++ b/newt/newtutil/newtutil.go
@@ -27,6 +27,8 @@ import (
"strconv"
"strings"
+ "github.com/spf13/cast"
+
"mynewt.apache.org/newt/util"
"mynewt.apache.org/newt/viper"
)
@@ -34,6 +36,51 @@ import (
var NewtVersionStr string = "Apache Newt (incubating) version: 0.9.0"
var NewtBlinkyTag string = "mynewt_0_9_0_tag"
+func GetSliceFeatures(v *viper.Viper, features map[string]bool,
+ key string) []interface{} {
+
+ val := v.Get(key)
+ vals := []interface{}{val}
+
+ // Process the features in alphabetical order to ensure consistent
+ // results across repeated runs.
+ var featureKeys []string
+ for feature, _ := range features {
+ featureKeys = append(featureKeys, feature)
+ }
+ sort.Strings(featureKeys)
+
+ for _, feature := range featureKeys {
+ overwriteVal := v.Get(key + "." + feature + ".OVERWRITE")
+ if overwriteVal != nil {
+ return []interface{}{overwriteVal}
+ }
+
+ appendVal := v.Get(key + "." + feature)
+ if appendVal != nil {
+ vals = append(vals, appendVal)
+ }
+ }
+
+ return vals
+}
+
+func GetStringMapFeatures(v *viper.Viper, features map[string]bool,
+ key string) map[string]interface{} {
+
+ result := map[string]interface{}{}
+
+ slice := GetSliceFeatures(v, features, key)
+ for _, itf := range slice {
+ sub := cast.ToStringMap(itf)
+ for k, v := range sub {
+ result[k] = v
+ }
+ }
+
+ return result
+}
+
func GetStringFeatures(v *viper.Viper, features map[string]bool,
key string) string {
val := v.GetString(key)
@@ -87,28 +134,15 @@ func GetBoolFeatures(v *viper.Viper, features map[string]bool,
func GetStringSliceFeatures(v *viper.Viper, features map[string]bool,
key string) []string {
- val := v.GetStringSlice(key)
+ vals := GetSliceFeatures(v, features, key)
- // string empty items
- result := []string{}
- for _, item := range val {
- if item == "" || item == " " {
- continue
- }
- result = append(result, item)
+ strVals := []string{}
+ for _, v := range vals {
+ subVals := cast.ToStringSlice(v)
+ strVals = append(strVals, subVals...)
}
- for item, _ := range features {
- overwriteVal := v.GetStringSlice(key + "." + item + ".OVERWRITE")
- if overwriteVal != nil {
- result = overwriteVal
- break
- }
-
- result = append(result, v.GetStringSlice(key+"."+item)...)
- }
-
- return result
+ return strVals
}
// Parses a string of the following form:
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/pkg/localpackage.go
----------------------------------------------------------------------
diff --git a/newt/pkg/localpackage.go b/newt/pkg/localpackage.go
index 0e73d8d..86c5777 100644
--- a/newt/pkg/localpackage.go
+++ b/newt/pkg/localpackage.go
@@ -60,15 +60,15 @@ type LocalPackage struct {
desc *PackageDesc
// Dependencies for this package
deps []*Dependency
- // APIs that this package exports
- apis []string
- // APIs that this package requires
- reqApis []string
- // This is only used for top-level packages, but make no distinction
- // and always read it in.
- featureBlackList map[string]interface{}
- featureWhiteList map[string]interface{}
+ // Package init function name and stage. These are used to generate the
+ // sysinit C file.
+ initFnName string
+ initStage int
+
+ // Extra package-specific settings that don't come from syscfg. For
+ // example, SELFTEST gets set when the newt test command is used.
+ injectedSettings map[string]string
// Pointer to pkg.yml configuration structure
Viper *viper.Viper
@@ -82,8 +82,10 @@ func NewLocalPackage(r *repo.Repo, pkgDir string) *LocalPackage {
desc: &PackageDesc{},
// XXX: Initialize viper object; clients should not need to check for
// nil pointer.
+ repo: r,
+ basePath: filepath.Clean(pkgDir) + "/", // XXX: Remove slash.
+ injectedSettings: map[string]string{},
}
- pkg.Init(r, pkgDir)
return pkg
}
@@ -101,7 +103,7 @@ func (pkg *LocalPackage) FullName() string {
}
func (pkg *LocalPackage) BasePath() string {
- return pkg.basePath
+ return filepath.Clean(pkg.basePath)
}
func (pkg *LocalPackage) Type() interfaces.PackageType {
@@ -201,22 +203,6 @@ func (pkg *LocalPackage) Deps() []*Dependency {
return pkg.deps
}
-func (pkg *LocalPackage) AddApi(api string) {
- pkg.apis = append(pkg.apis, api)
-}
-
-func (pkg *LocalPackage) Apis() []string {
- return pkg.apis
-}
-
-func (pkg *LocalPackage) AddReqApi(api string) {
- pkg.reqApis = append(pkg.reqApis, api)
-}
-
-func (pkg *LocalPackage) ReqApis() []string {
- return pkg.reqApis
-}
-
func (pkg *LocalPackage) readDesc(v *viper.Viper) (*PackageDesc, error) {
pdesc := &PackageDesc{}
@@ -228,11 +214,6 @@ func (pkg *LocalPackage) readDesc(v *viper.Viper) (*PackageDesc, error) {
return pdesc, nil
}
-func (pkg *LocalPackage) Init(repo *repo.Repo, pkgDir string) {
- pkg.repo = repo
- pkg.basePath = filepath.Clean(pkgDir) + "/"
-}
-
func (pkg *LocalPackage) sequenceString(key string) string {
var buffer bytes.Buffer
@@ -314,8 +295,8 @@ func (pkg *LocalPackage) Load() error {
}
}
- pkg.featureBlackList = v.GetStringMap("pkg.feature_blacklist")
- pkg.featureWhiteList = v.GetStringMap("pkg.feature_whitelist")
+ pkg.initFnName = v.GetString("pkg.init_function")
+ pkg.initStage = v.GetInt("pkg.init_stage")
// Read the package description from the file
pkg.desc, err = pkg.readDesc(v)
@@ -328,12 +309,16 @@ func (pkg *LocalPackage) Load() error {
return nil
}
-func (pkg *LocalPackage) FeatureBlackList() map[string]interface{} {
- return pkg.featureBlackList
+func (pkg *LocalPackage) InitStage() int {
+ return pkg.initStage
+}
+
+func (pkg *LocalPackage) InitFnName() string {
+ return pkg.initFnName
}
-func (pkg *LocalPackage) FeatureWhiteList() map[string]interface{} {
- return pkg.featureWhiteList
+func (pkg *LocalPackage) InjectedSettings() map[string]string {
+ return pkg.injectedSettings
}
func (pkg *LocalPackage) Clone(newRepo *repo.Repo,
@@ -356,8 +341,7 @@ func (pkg *LocalPackage) Clone(newRepo *repo.Repo,
}
func LoadLocalPackage(repo *repo.Repo, pkgDir string) (*LocalPackage, error) {
- pkg := &LocalPackage{}
- pkg.Init(repo, pkgDir)
+ pkg := NewLocalPackage(repo, pkgDir)
err := pkg.Load()
return pkg, err
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/pkg/package.go
----------------------------------------------------------------------
diff --git a/newt/pkg/package.go b/newt/pkg/package.go
index 4fa988c..644889e 100644
--- a/newt/pkg/package.go
+++ b/newt/pkg/package.go
@@ -1,5 +1,4 @@
/**
- PACKAGE_TYPE_LIB: "lib",
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,7 +15,7 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
-*/
+ */
package pkg
@@ -37,6 +36,7 @@ const (
PACKAGE_TYPE_COMPILER
PACKAGE_TYPE_LIB
PACKAGE_TYPE_TARGET
+ PACKAGE_TYPE_UNITTEST
)
var PackageTypeNames = map[interfaces.PackageType]string{
@@ -46,6 +46,7 @@ var PackageTypeNames = map[interfaces.PackageType]string{
PACKAGE_TYPE_COMPILER: "compiler",
PACKAGE_TYPE_LIB: "lib",
PACKAGE_TYPE_TARGET: "target",
+ PACKAGE_TYPE_UNITTEST: "unittest",
}
// An interface, representing information about a Package
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/pkg/packageutil.go
----------------------------------------------------------------------
diff --git a/newt/pkg/packageutil.go b/newt/pkg/packageutil.go
new file mode 100644
index 0000000..f3f6132
--- /dev/null
+++ b/newt/pkg/packageutil.go
@@ -0,0 +1,32 @@
+package pkg
+
+import (
+ "sort"
+)
+
+type lpkgSorter struct {
+ pkgs []*LocalPackage
+}
+
+func (s lpkgSorter) Len() int {
+ return len(s.pkgs)
+}
+func (s lpkgSorter) Swap(i, j int) {
+ s.pkgs[i], s.pkgs[j] = s.pkgs[j], s.pkgs[i]
+}
+func (s lpkgSorter) Less(i, j int) bool {
+ return s.pkgs[i].Name() < s.pkgs[j].Name()
+}
+
+func SortLclPkgs(pkgs []*LocalPackage) []*LocalPackage {
+ sorter := lpkgSorter{
+ pkgs: make([]*LocalPackage, 0, len(pkgs)),
+ }
+
+ for _, p := range pkgs {
+ sorter.pkgs = append(sorter.pkgs, p)
+ }
+
+ sort.Sort(sorter)
+ return sorter.pkgs
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/project/project.go
----------------------------------------------------------------------
diff --git a/newt/project/project.go b/newt/project/project.go
index 78585af..29646e5 100644
--- a/newt/project/project.go
+++ b/newt/project/project.go
@@ -497,7 +497,6 @@ func findProjectDir(dir string) (string, error) {
log.Debugf("Searching for project file %s", projFile)
if util.NodeExist(projFile) {
- log.Infof("Project file found at %s", projFile)
break
}
@@ -518,7 +517,6 @@ func (proj *Project) loadPackageList() error {
// packages / store them in the project package list.
repos := proj.Repos()
for name, repo := range repos {
- log.Debugf("Loading packages in repository %s", repo.Path())
list, err := pkg.ReadLocalPackages(repo, repo.Path())
if err != nil {
return err
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/syscfg/syscfg.go
----------------------------------------------------------------------
diff --git a/newt/syscfg/syscfg.go b/newt/syscfg/syscfg.go
new file mode 100644
index 0000000..c94abfb
--- /dev/null
+++ b/newt/syscfg/syscfg.go
@@ -0,0 +1,801 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package syscfg
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "sort"
+ "strconv"
+ "strings"
+
+ log "github.com/Sirupsen/logrus"
+ "github.com/spf13/cast"
+
+ "mynewt.apache.org/newt/newt/newtutil"
+ "mynewt.apache.org/newt/newt/pkg"
+ "mynewt.apache.org/newt/util"
+)
+
+const SYSCFG_INCLUDE_SUBDIR = "include/syscfg"
+const SYSCFG_HEADER_FILENAME = "syscfg.h"
+
+const SYSCFG_PREFIX_API = "MYNEWT_API_"
+const SYSCFG_PREFIX_PKG = "MYNEWT_PKG_"
+const SYSCFG_PREFIX_SETTING = "MYNEWT_VAL_"
+
+type CfgSettingType int
+
+const (
+ CFG_SETTING_TYPE_RAW CfgSettingType = iota
+ CFG_SETTING_TYPE_TASK_PRIO
+ CFG_SETTING_TYPE_INTERRUPT_PRIO
+)
+
+const SYSCFG_PRIO_ANY = "any"
+
+// Reserve last 16 priorities for the system (sanity, idle).
+const SYSCFG_TASK_PRIO_MAX = 0xef
+
+// The range of interrupt priorities is hardware dependent, so don't limit
+// these here.
+const SYSCFG_INTERRUPT_PRIO_MAX = 0xffffffff
+
+var cfgSettingNameTypeMap = map[string]CfgSettingType{
+ "raw": CFG_SETTING_TYPE_RAW,
+ "task_priority": CFG_SETTING_TYPE_TASK_PRIO,
+ "interrupt_priority": CFG_SETTING_TYPE_INTERRUPT_PRIO,
+}
+
+type CfgPoint struct {
+ Value string
+ Source *pkg.LocalPackage
+}
+
+type CfgEntry struct {
+ Name string
+ Value string
+ History []CfgPoint
+ Description string
+ SettingType CfgSettingType
+}
+
+type Cfg map[string]CfgEntry
+
+type cfgRoster struct {
+ settings map[string]string
+ pkgsPresent map[string]bool
+ apisPresent map[string]bool
+}
+
+func WritePreamble(w io.Writer) {
+ fmt.Fprintf(w, "/**\n * This file was generated by %s\n */\n\n",
+ newtutil.NewtVersionStr)
+}
+
+func ValueIsTrue(val string) bool {
+ if val == "" {
+ return false
+ }
+
+ i, err := util.AtoiNoOct(val)
+ if err == nil && i == 0 {
+ return false
+ }
+
+ return true
+}
+
+func Features(cfg Cfg) map[string]bool {
+ features := map[string]bool{}
+ for k, v := range cfg {
+ if v.IsTrue() {
+ features[k] = true
+ }
+ }
+
+ return features
+}
+
+func FeaturesForLpkg(cfg Cfg, lpkg *pkg.LocalPackage) map[string]bool {
+ features := Features(cfg)
+
+ for k, v := range lpkg.InjectedSettings() {
+ _, ok := features[k]
+ if ok {
+ log.Warnf("Attempt to override syscfg setting %s with "+
+ "injected feature from package %s", k, lpkg.Name())
+ } else {
+ if ValueIsTrue(v) {
+ features[k] = true
+ }
+ }
+ }
+
+ return features
+}
+
+func (point CfgPoint) Name() string {
+ if point.Source == nil {
+ return "newt"
+ } else {
+ return point.Source.Name()
+ }
+}
+
+func (entry *CfgEntry) IsTrue() bool {
+ return ValueIsTrue(entry.Value)
+}
+
+func appendValue(entry *CfgEntry, lpkg *pkg.LocalPackage, value interface{}) {
+ strval := fmt.Sprintf("%+v", value)
+ point := CfgPoint{Value: strval, Source: lpkg}
+ entry.History = append(entry.History, point)
+ entry.Value = strval
+}
+
+func FeatureToCflag(featureName string) string {
+ return fmt.Sprintf("-D%s=1", settingName(featureName))
+}
+
+func stringValue(val interface{}) string {
+ return strings.TrimSpace(cast.ToString(val))
+}
+
+func readSetting(name string, lpkg *pkg.LocalPackage,
+ vals map[interface{}]interface{}) (CfgEntry, error) {
+
+ entry := CfgEntry{}
+
+ entry.Name = name
+ entry.Description = stringValue(vals["description"])
+ entry.Value = stringValue(vals["value"])
+ if vals["type"] == nil {
+ entry.SettingType = CFG_SETTING_TYPE_RAW
+ } else {
+ var ok bool
+ typename := stringValue(vals["type"])
+ entry.SettingType, ok = cfgSettingNameTypeMap[typename]
+ if !ok {
+ return entry, util.FmtNewtError(
+ "setting %s specifies invalid type: %s", name, typename)
+ }
+ }
+
+ appendValue(&entry, lpkg, entry.Value)
+
+ return entry, nil
+}
+
+func readOnce(cfg Cfg, lpkg *pkg.LocalPackage) error {
+ v := lpkg.Viper
+
+ features := FeaturesForLpkg(cfg, lpkg)
+ settings := newtutil.GetStringMapFeatures(v, features, "pkg.syscfg_defs")
+ if settings != nil {
+ for k, v := range settings {
+ vals := v.(map[interface{}]interface{})
+ entry, err := readSetting(k, lpkg, vals)
+ if err != nil {
+ return util.FmtNewtError("Config for package %s: %s",
+ lpkg.Name(), err.Error())
+ }
+
+ if _, exists := cfg[k]; exists {
+ // XXX: Better error message.
+ return util.FmtNewtError("setting %s redefined", k)
+ }
+ cfg[k] = entry
+ }
+ }
+
+ values := newtutil.GetStringMapFeatures(v, features, "pkg.syscfg_vals")
+ if values != nil {
+ for k, v := range values {
+ entry, ok := cfg[k]
+ if ok {
+ appendValue(&entry, lpkg, v)
+ cfg[k] = entry
+ } else {
+ log.Warnf("ignoring override of undefined setting; "+
+ "%s sets %s=%+v", lpkg.Name(), k, v)
+ }
+
+ }
+ }
+
+ return nil
+}
+
+func Log(cfg Cfg) {
+ keys := make([]string, len(cfg))
+ i := 0
+ for k, _ := range cfg {
+ keys[i] = k
+ i++
+ }
+ sort.Strings(keys)
+
+ log.Debugf("syscfg settings (%d entries):", len(cfg))
+ for _, k := range keys {
+ entry := cfg[k]
+
+ str := fmt.Sprintf(" %s=%s [", k, entry.Value)
+
+ for i, p := range entry.History {
+ if i != 0 {
+ str += ", "
+ }
+ str += fmt.Sprintf("%s:%s", p.Name(), p.Value)
+ }
+ str += "]"
+
+ log.Debug(str)
+ }
+}
+
+func escapeStr(s string) string {
+ s = strings.Replace(s, "/", "_", -1)
+ s = strings.Replace(s, "-", "_", -1)
+ s = strings.Replace(s, " ", "_", -1)
+ s = strings.ToUpper(s)
+ return s
+}
+
+func isSettingVal(s string) bool {
+ return strings.HasPrefix(s, SYSCFG_PREFIX_SETTING)
+}
+
+func isPkgVal(s string) bool {
+ return strings.HasPrefix(s, SYSCFG_PREFIX_PKG)
+}
+
+func isApiVal(s string) bool {
+ return strings.HasPrefix(s, SYSCFG_PREFIX_API)
+}
+
+func settingName(setting string) string {
+ return SYSCFG_PREFIX_SETTING + escapeStr(setting)
+}
+
+func pkgPresentName(pkgName string) string {
+ return SYSCFG_PREFIX_PKG + escapeStr(pkgName)
+}
+
+func apiPresentName(apiName string) string {
+ return SYSCFG_PREFIX_API + strings.ToUpper(apiName)
+}
+
+func Read(lpkgs []*pkg.LocalPackage, apis []string,
+ injectedSettings map[string]string) (Cfg, error) {
+
+ cfg := Cfg{}
+ for k, v := range injectedSettings {
+ cfg[k] = CfgEntry{
+ Name: k,
+ Description: "Injected setting",
+ Value: v,
+ History: []CfgPoint{{
+ Value: v,
+ Source: nil,
+ }},
+ }
+ }
+
+ // Read system configuration files. In case of conflicting settings, the
+ // higher priority pacakge's setting wins. Package priorities are assigned
+ // as follows (highest priority first):
+ // * target
+ // * app (if present)
+ // * unittest (if no app)
+ // * bsp
+
+ var app *pkg.LocalPackage
+ var bsp *pkg.LocalPackage
+ var target *pkg.LocalPackage
+ var unittest *pkg.LocalPackage
+
+ for _, lpkg := range lpkgs {
+ switch lpkg.Type() {
+ case pkg.PACKAGE_TYPE_LIB:
+ if err := readOnce(cfg, lpkg); err != nil {
+ return cfg, err
+ }
+
+ case pkg.PACKAGE_TYPE_APP:
+ app = lpkg
+
+ case pkg.PACKAGE_TYPE_BSP:
+ bsp = lpkg
+
+ case pkg.PACKAGE_TYPE_TARGET:
+ target = lpkg
+
+ case pkg.PACKAGE_TYPE_UNITTEST:
+ unittest = lpkg
+ }
+ }
+
+ if bsp != nil {
+ if err := readOnce(cfg, bsp); err != nil {
+ return cfg, err
+ }
+ }
+ if app != nil {
+ if err := readOnce(cfg, app); err != nil {
+ return cfg, err
+ }
+ } else if unittest != nil {
+ if err := readOnce(cfg, unittest); err != nil {
+ return cfg, err
+ }
+ }
+ if target != nil {
+ if err := readOnce(cfg, target); err != nil {
+ return cfg, err
+ }
+ }
+
+ roster := buildCfgRoster(cfg, lpkgs, apis)
+ if err := fixupSettings(cfg, roster); err != nil {
+ return cfg, err
+ }
+
+ return cfg, nil
+}
+
+func mostRecentPoint(entry CfgEntry) CfgPoint {
+ if len(entry.History) == 0 {
+ panic("invalid cfg entry; len(history) == 0")
+ }
+
+ return entry.History[len(entry.History)-1]
+}
+
+func calcPriorities(cfg Cfg, settingType CfgSettingType, max int,
+ allowDups bool) error {
+
+ // setting-name => entry
+ anyEntries := map[string]CfgEntry{}
+
+ // priority-value => entry
+ valEntries := map[int]CfgEntry{}
+
+ for name, entry := range cfg {
+ if entry.SettingType == settingType {
+ if entry.Value == SYSCFG_PRIO_ANY {
+ anyEntries[name] = entry
+ } else {
+ prio, err := util.AtoiNoOct(entry.Value)
+ if err != nil {
+ return util.FmtNewtError(
+ "invalid priority value: setting=%s value=%s pkg=%s",
+ name, entry.Value, entry.History[0].Name())
+ }
+
+ if prio > max {
+ return util.FmtNewtError(
+ "invalid priority value: value too great (> %d); "+
+ "setting=%s value=%s pkg=%s",
+ max, entry.Name, entry.Value,
+ mostRecentPoint(entry).Name())
+ }
+
+ if !allowDups {
+ if oldEntry, ok := valEntries[prio]; ok {
+ return util.FmtNewtError(
+ "duplicate priority value: setting1=%s "+
+ "setting2=%s pkg1=%s pkg2=%s value=%s",
+ oldEntry.Name, entry.Name, entry.Value,
+ oldEntry.History[0].Name(),
+ entry.History[0].Name())
+ }
+ }
+
+ valEntries[prio] = entry
+ }
+ }
+ }
+
+ greatest := 0
+ for prio, _ := range valEntries {
+ if prio > greatest {
+ greatest = prio
+ }
+ }
+
+ anyNames := make([]string, 0, len(anyEntries))
+ for name, _ := range anyEntries {
+ anyNames = append(anyNames, name)
+ }
+ sort.Strings(anyNames)
+
+ for _, name := range anyNames {
+ entry := anyEntries[name]
+
+ greatest++
+ if greatest > max {
+ return util.FmtNewtError("could not assign 'any' priority: "+
+ "value too great (> %d); setting=%s value=%s pkg=%s",
+ max, name, greatest,
+ mostRecentPoint(entry).Name())
+ }
+
+ entry.Value = strconv.Itoa(greatest)
+ cfg[name] = entry
+ }
+
+ return nil
+}
+
+func writeCheckMacros(w io.Writer) {
+ s := `/**
+ * These macros exists to ensure code includes this header when needed. If
+ * code checks the existence of a setting directly via ifdef without including
+ * this header, the setting macro will silently evaluate to 0. In contrast, an
+ * attempt to use these macros without including this header will result in a
+ * compiler error.
+ */
+#define MYNEWT_VAL(x) MYNEWT_VAL_ ## x
+#define MYNEWT_PKG(x) MYNEWT_PKG_ ## x
+#define MYNEWT_API(x) MYNEWT_API_ ## x
+`
+ fmt.Fprintf(w, "%s\n", s)
+}
+
+func writeComment(entry CfgEntry, w io.Writer) {
+ if len(entry.History) > 1 {
+ fmt.Fprintf(w, "/* Overridden by %s (defined by %s) */\n",
+ mostRecentPoint(entry).Name(),
+ entry.History[0].Name())
+ }
+}
+
+func writeDefine(key string, value string, w io.Writer) {
+ fmt.Fprintf(w, "#ifndef %s\n", key)
+ fmt.Fprintf(w, "#define %s (%s)\n", key, value)
+ fmt.Fprintf(w, "#endif\n")
+}
+
+func specialValues(cfg Cfg) (apis, pkgs, settings []string) {
+ for _, entry := range cfg {
+ if isApiVal(entry.Value) {
+ apis = append(apis, entry.Value)
+ } else if isPkgVal(entry.Value) {
+ pkgs = append(pkgs, entry.Value)
+ } else if isSettingVal(entry.Value) {
+ settings = append(settings, entry.Value)
+ }
+ }
+
+ return
+}
+
+func buildCfgRoster(cfg Cfg, lpkgs []*pkg.LocalPackage,
+ apis []string) cfgRoster {
+
+ roster := cfgRoster{
+ settings: make(map[string]string, len(cfg)),
+ pkgsPresent: make(map[string]bool, len(lpkgs)),
+ apisPresent: make(map[string]bool, len(apis)),
+ }
+
+ for k, v := range cfg {
+ roster.settings[settingName(k)] = v.Value
+ }
+
+ for _, v := range lpkgs {
+ roster.pkgsPresent[pkgPresentName(v.Name())] = true
+ }
+
+ for _, v := range apis {
+ roster.apisPresent[apiPresentName(v)] = true
+ }
+
+ apisNotPresent, pkgsNotPresent, _ := specialValues(cfg)
+
+ for _, v := range apisNotPresent {
+ _, ok := roster.apisPresent[v]
+ if !ok {
+ roster.apisPresent[v] = false
+ }
+ }
+
+ for _, v := range pkgsNotPresent {
+ _, ok := roster.pkgsPresent[v]
+ if !ok {
+ roster.pkgsPresent[v] = false
+ }
+ }
+
+ return roster
+}
+
+func settingValueToConstant(value string,
+ roster cfgRoster) (string, bool, error) {
+
+ seen := map[string]struct{}{}
+ curVal := value
+ for {
+ v, ok := roster.settings[curVal]
+ if ok {
+ if _, ok := seen[v]; ok {
+ return "", false, util.FmtNewtError("Syscfg cycle detected: "+
+ "%s <==> %s", value, v)
+ }
+ seen[v] = struct{}{}
+ curVal = v
+ } else {
+ break
+ }
+ }
+ if curVal != value {
+ return curVal, true, nil
+ }
+
+ v, ok := roster.apisPresent[value]
+ if ok {
+ if v {
+ return "1", true, nil
+ } else {
+ return "0", true, nil
+ }
+ }
+
+ v, ok = roster.pkgsPresent[value]
+ if ok {
+ if v {
+ return "1", true, nil
+ } else {
+ return "0", true, nil
+ }
+ }
+
+ return value, false, nil
+}
+
+func fixupSettings(cfg Cfg, roster cfgRoster) error {
+ for k, entry := range cfg {
+ value, changed, err := settingValueToConstant(entry.Value, roster)
+ if err != nil {
+ return err
+ }
+
+ if changed {
+ entry.Value = value
+ cfg[k] = entry
+ }
+ }
+
+ return nil
+}
+
+func UnfixedValue(entry CfgEntry) string {
+ point := mostRecentPoint(entry)
+ return point.Value
+}
+
+func EntriesByPkg(cfg Cfg) map[string][]CfgEntry {
+ pkgEntries := map[string][]CfgEntry{}
+ for _, v := range cfg {
+ name := v.History[0].Name()
+ pkgEntries[name] = append(pkgEntries[name], v)
+ }
+ return pkgEntries
+}
+
+func writeSettingsOnePkg(cfg Cfg, pkgName string, pkgEntries []CfgEntry,
+ w io.Writer) {
+
+ fmt.Fprintf(w, "/*** %s */\n", pkgName)
+
+ names := make([]string, len(pkgEntries), len(pkgEntries))
+ for i, entry := range pkgEntries {
+ names[i] = entry.Name
+ }
+ sort.Strings(names)
+
+ first := true
+ for _, n := range names {
+ entry := cfg[n]
+ if entry.Value != "" {
+ if first {
+ first = false
+ } else {
+ fmt.Fprintf(w, "\n")
+ }
+
+ writeComment(entry, w)
+ writeDefine(settingName(n), entry.Value, w)
+ }
+ }
+}
+
+func writeSettings(cfg Cfg, w io.Writer) {
+ // Group settings by package name so that the generated header file is
+ // easier to readOnce.
+ pkgEntries := EntriesByPkg(cfg)
+ for _, v := range cfg {
+ name := v.History[0].Name()
+ pkgEntries[name] = append(pkgEntries[name], v)
+ }
+
+ pkgNames := make([]string, 0, len(pkgEntries))
+ for name, _ := range pkgEntries {
+ pkgNames = append(pkgNames, name)
+ }
+ sort.Strings(pkgNames)
+
+ fmt.Fprintf(w, "/***** Settings */\n")
+
+ for _, name := range pkgNames {
+ fmt.Fprintf(w, "\n")
+ entries := pkgEntries[name]
+ writeSettingsOnePkg(cfg, name, entries, w)
+ }
+}
+
+func writePkgsPresent(roster cfgRoster, w io.Writer) {
+ present := make([]string, 0, len(roster.pkgsPresent))
+ notPresent := make([]string, 0, len(roster.pkgsPresent))
+ for k, v := range roster.pkgsPresent {
+ if v {
+ present = append(present, k)
+ } else {
+ notPresent = append(notPresent, k)
+ }
+ }
+
+ sort.Strings(present)
+ sort.Strings(notPresent)
+
+ fmt.Fprintf(w, "/*** Packages (present) */\n")
+ for _, symbol := range present {
+ fmt.Fprintf(w, "\n")
+ writeDefine(symbol, "1", w)
+ }
+
+ fmt.Fprintf(w, "\n")
+ fmt.Fprintf(w, "/*** Packages (not present)*/\n")
+ for _, symbol := range notPresent {
+ fmt.Fprintf(w, "\n")
+ writeDefine(symbol, "0", w)
+ }
+}
+
+func writeApisPresent(roster cfgRoster, w io.Writer) {
+ present := make([]string, 0, len(roster.apisPresent))
+ notPresent := make([]string, 0, len(roster.apisPresent))
+ for k, v := range roster.apisPresent {
+ if v {
+ present = append(present, k)
+ } else {
+ notPresent = append(notPresent, k)
+ }
+ }
+
+ sort.Strings(present)
+ sort.Strings(notPresent)
+
+ fmt.Fprintf(w, "/*** APIs (present) */\n")
+ for _, symbol := range present {
+ fmt.Fprintf(w, "\n")
+ writeDefine(symbol, "1", w)
+ }
+
+ fmt.Fprintf(w, "\n")
+ fmt.Fprintf(w, "/*** APIs (not present) */\n")
+ for _, symbol := range notPresent {
+ writeDefine(symbol, "0", w)
+ fmt.Fprintf(w, "\n")
+ }
+}
+
+func write(cfg Cfg, roster cfgRoster, w io.Writer) {
+ WritePreamble(w)
+
+ fmt.Fprintf(w, "#ifndef H_MYNEWT_SYSCFG_\n")
+ fmt.Fprintf(w, "#define H_MYNEWT_SYSCFG_\n\n")
+
+ writeCheckMacros(w)
+ fmt.Fprintf(w, "\n")
+
+ writeSettings(cfg, w)
+ fmt.Fprintf(w, "\n")
+
+ writePkgsPresent(roster, w)
+ fmt.Fprintf(w, "\n")
+
+ writeApisPresent(roster, w)
+ fmt.Fprintf(w, "\n")
+
+ fmt.Fprintf(w, "#endif\n")
+}
+
+func writeRequired(contents []byte, path string) (bool, error) {
+ oldHeader, err := ioutil.ReadFile(path)
+ if err != nil {
+ if os.IsNotExist(err) {
+ // File doesn't exist; write required.
+ return true, nil
+ }
+
+ return true, util.NewNewtError(err.Error())
+ }
+
+ rc := bytes.Compare(oldHeader, contents)
+ return rc != 0, nil
+}
+
+func headerPath(targetPath string) string {
+ return fmt.Sprintf("%s/%s/%s", targetPath, SYSCFG_INCLUDE_SUBDIR,
+ SYSCFG_HEADER_FILENAME)
+}
+
+func EnsureWritten(cfg Cfg, lpkgs []*pkg.LocalPackage,
+ apis []string, targetPath string) error {
+
+ if err := calcPriorities(cfg, CFG_SETTING_TYPE_TASK_PRIO,
+ SYSCFG_TASK_PRIO_MAX, false); err != nil {
+
+ return err
+ }
+
+ if err := calcPriorities(cfg, CFG_SETTING_TYPE_INTERRUPT_PRIO,
+ SYSCFG_INTERRUPT_PRIO_MAX, true); err != nil {
+
+ return err
+ }
+
+ roster := buildCfgRoster(cfg, lpkgs, apis)
+ if err := fixupSettings(cfg, roster); err != nil {
+ return err
+ }
+
+ buf := bytes.Buffer{}
+ write(cfg, roster, &buf)
+
+ path := headerPath(targetPath)
+
+ writeReqd, err := writeRequired(buf.Bytes(), path)
+ if err != nil {
+ return err
+ }
+ if !writeReqd {
+ log.Debugf("syscfg unchanged; not writing header file (%s).", path)
+ return nil
+ }
+
+ log.Debugf("syscfg changed; writing header file (%s).", path)
+
+ if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
+ return util.NewNewtError(err.Error())
+ }
+
+ if err := ioutil.WriteFile(path, buf.Bytes(), 0644); err != nil {
+ return util.NewNewtError(err.Error())
+ }
+
+ return nil
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/sysinit/sysinit.go
----------------------------------------------------------------------
diff --git a/newt/sysinit/sysinit.go b/newt/sysinit/sysinit.go
new file mode 100644
index 0000000..8e8188b
--- /dev/null
+++ b/newt/sysinit/sysinit.go
@@ -0,0 +1,154 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package sysinit
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "sort"
+
+ log "github.com/Sirupsen/logrus"
+
+ "mynewt.apache.org/newt/newt/pkg"
+ "mynewt.apache.org/newt/newt/syscfg"
+ "mynewt.apache.org/newt/util"
+)
+
+const FILENAME = "sysinit.c"
+const SYSINIT_FN_SIG = `void
+sysinit(void)
+{
+`
+
+func buildStageMap(pkgs []*pkg.LocalPackage) map[int][]*pkg.LocalPackage {
+ sm := map[int][]*pkg.LocalPackage{}
+
+ for _, p := range pkgs {
+ stage := p.InitStage()
+ sm[stage] = append(sm[stage], p)
+ }
+
+ return sm
+}
+
+func writePrototypes(pkgs []*pkg.LocalPackage, w io.Writer) {
+ sorted := pkg.SortLclPkgs(pkgs)
+ for _, p := range sorted {
+ fmt.Fprintf(w, "void %s(void);\n", p.InitFnName())
+ }
+}
+
+func writeStage(stage int, pkgs []*pkg.LocalPackage, w io.Writer) {
+ sorted := pkg.SortLclPkgs(pkgs)
+
+ fmt.Fprintf(w, " /*** Stage %d */\n", stage)
+ for i, p := range sorted {
+ fmt.Fprintf(w, " /* %d.%d: %s */\n", stage, i, p.Name())
+ fmt.Fprintf(w, " %s();\n", p.InitFnName())
+ }
+}
+
+func onlyPkgsWithInit(pkgs []*pkg.LocalPackage) []*pkg.LocalPackage {
+ good := make([]*pkg.LocalPackage, 0, len(pkgs))
+ for _, p := range pkgs {
+ if p.InitFnName() != "" {
+ good = append(good, p)
+ }
+ }
+
+ return good
+}
+
+func write(pkgs []*pkg.LocalPackage, w io.Writer) {
+ goodPkgs := onlyPkgsWithInit(pkgs)
+ stageMap := buildStageMap(goodPkgs)
+
+ i := 0
+ stages := make([]int, len(stageMap))
+ for k, _ := range stageMap {
+ stages[i] = k
+ i++
+ }
+ sort.Ints(stages)
+
+ syscfg.WritePreamble(w)
+
+ writePrototypes(goodPkgs, w)
+ fmt.Fprintf(w, "\n")
+
+ fmt.Fprintf(w, "%s", SYSINIT_FN_SIG)
+ for i, s := range stages {
+ if i != 0 {
+ fmt.Fprintf(w, "\n")
+ }
+
+ writeStage(s, stageMap[s], w)
+ }
+
+ fmt.Fprintf(w, "}\n")
+}
+
+func writeRequired(contents []byte, path string) (bool, error) {
+ oldSrc, err := ioutil.ReadFile(path)
+ if err != nil {
+ if os.IsNotExist(err) {
+ // File doesn't exist; write required.
+ return true, nil
+ }
+
+ return true, util.NewNewtError(err.Error())
+ }
+
+ rc := bytes.Compare(oldSrc, contents)
+ return rc != 0, nil
+}
+
+func EnsureWritten(pkgs []*pkg.LocalPackage, targetPath string) error {
+ buf := bytes.Buffer{}
+ write(pkgs, &buf)
+
+ path := fmt.Sprintf("%s/src/%s", targetPath, FILENAME)
+
+ writeReqd, err := writeRequired(buf.Bytes(), path)
+ if err != nil {
+ return err
+ }
+
+ if !writeReqd {
+ log.Debugf("sysinit unchanged; not writing src file (%s).", path)
+ return nil
+ }
+
+ log.Debugf("sysinit changed; writing src file (%s).", path)
+
+ if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
+ return util.NewNewtError(err.Error())
+ }
+
+ if err := ioutil.WriteFile(path, buf.Bytes(), 0644); err != nil {
+ return util.NewNewtError(err.Error())
+ }
+
+ return nil
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/toolchain/compiler.go
----------------------------------------------------------------------
diff --git a/newt/toolchain/compiler.go b/newt/toolchain/compiler.go
index b032d97..a961051 100644
--- a/newt/toolchain/compiler.go
+++ b/newt/toolchain/compiler.go
@@ -153,6 +153,10 @@ func addFlags(flagType string, orig []string, new []string) []string {
return combined
}
+func (ci *CompilerInfo) AddCflags(cflags []string) {
+ ci.Cflags = addFlags("cflag", ci.Cflags, cflags)
+}
+
func (ci *CompilerInfo) AddCompilerInfo(newCi *CompilerInfo) {
ci.Includes = append(ci.Includes, newCi.Includes...)
ci.Cflags = addFlags("cflag", ci.Cflags, newCi.Cflags)
@@ -168,7 +172,7 @@ func NewCompiler(compilerDir string, dstDir string,
c := &Compiler{
ObjPathList: map[string]bool{},
dstDir: filepath.Clean(dstDir),
- extraDeps: []string{compilerDir + COMPILER_FILENAME},
+ extraDeps: []string{},
}
c.depTracker = NewDepTracker(c)
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/toolchain/deps.go
----------------------------------------------------------------------
diff --git a/newt/toolchain/deps.go b/newt/toolchain/deps.go
index a50e265..e54c255 100644
--- a/newt/toolchain/deps.go
+++ b/newt/toolchain/deps.go
@@ -165,6 +165,7 @@ func (tracker *DepTracker) CompileRequired(srcFile string,
if err != nil {
return false, err
}
+
if commandHasChanged(objFile, cmd) {
util.StatusMessage(util.VERBOSITY_VERBOSE, "%s - rebuild required; "+
"different command\n", srcFile)
@@ -175,6 +176,13 @@ func (tracker *DepTracker) CompileRequired(srcFile string,
return true, nil
}
+ if util.NodeNotExist(depFile) {
+ err := tracker.compiler.GenDepsForFile(srcFile)
+ if err != nil {
+ return false, err
+ }
+ }
+
srcModTime, err := util.FileModificationTime(srcFile)
if err != nil {
return false, err
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/vendor/mynewt.apache.org/newt/DISCLAIMER
----------------------------------------------------------------------
diff --git a/newt/vendor/mynewt.apache.org/newt/DISCLAIMER b/newt/vendor/mynewt.apache.org/newt/DISCLAIMER
deleted file mode 100644
index 1600825..0000000
--- a/newt/vendor/mynewt.apache.org/newt/DISCLAIMER
+++ /dev/null
@@ -1,8 +0,0 @@
-Apache Mynewt is an effort undergoing incubation at The Apache Software
-Foundation (ASF), sponsored by the Incubator PMC. Incubation is
-required of all newly accepted projects until a further review indicates
-that the infrastructure, communications, and decision making process
-have stabilized in a manner consistent with other successful ASF
-projects. While incubation status is not necessarily a reflection of the
-completeness or stability of the code, it does indicate that the project
-has yet to be fully endorsed by the ASF.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/vendor/mynewt.apache.org/newt/LICENSE
----------------------------------------------------------------------
diff --git a/newt/vendor/mynewt.apache.org/newt/LICENSE b/newt/vendor/mynewt.apache.org/newt/LICENSE
deleted file mode 100644
index 88a6f68..0000000
--- a/newt/vendor/mynewt.apache.org/newt/LICENSE
+++ /dev/null
@@ -1,244 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "{}"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright {yyyy} {name of copyright owner}
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-This product bundles pretty, which is available under the MIT license. For
-details, see newt/vendor/github.com/kr/pretty/License
-
-This product bundles kr/text, which is available under the MIT license. For
-details, see newt/vendor/github.com/kr/text/License
-
-This product bundles mapstructure, which is available under the MIT license.
-For details, see newt/vendor/github.com/mitchellh/mapstructure/LICENSE
-
-This product bundles logrus, which is available under the MIT license. For
-details, see newt/vendor/github.com/Sirupsen/logrus/LICENSE
-
-This product bundles Cast, which is available under the MIT license. For
-details, see newt/vendor/github.com/spf13/cast/LICENSE
-
-This product bundles jWalterWeatherman, which is available under the MIT
-license. For details, see
-newt/vendor/github.com/spf13/jwalterweatherman/LICENSE
-
-This product bundles pflag, which is available under the "3-clause BSD"
-license. For details, see newt/vendor/github.com/spf13/pflag/LICENSE
-
-This product bundles the unix Go package, which is available under the
-"3-clause BSD" license. For details, see newt/vendor/golang.org/x/sys/LICENSE
-
-This product bundles fsnotify.v1, which is available under the "3-clause BSD"
-license. For details, see newt/vendor/gopkg.in/fsnotify.v1/LICENSE
-
-This product bundles yaml.v2's Go port of libyaml, which is available under the
-MIT license. For details, see:
- * yaml/apic.go
- * yaml/emitterc.go
- * yaml/parserc.go
- * yaml/readerc.go
- * yaml/scannerc.go
- * yaml/writerc.go
- * yaml/yamlh.go
- * yaml/yamlprivateh.go
-
-This product bundles viper, which is available under the MIT license. For
-details, see:
- * viper/LICENSE
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/vendor/mynewt.apache.org/newt/NOTICE
----------------------------------------------------------------------
diff --git a/newt/vendor/mynewt.apache.org/newt/NOTICE b/newt/vendor/mynewt.apache.org/newt/NOTICE
deleted file mode 100644
index 94bea73..0000000
--- a/newt/vendor/mynewt.apache.org/newt/NOTICE
+++ /dev/null
@@ -1,8 +0,0 @@
-Apache Mynewt (incubating)
-Copyright 2015-2016 The Apache Software Foundation
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-
-Portions of this software were developed at
-Runtime Inc, copyright 2015.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/vendor/mynewt.apache.org/newt/util/util.go
----------------------------------------------------------------------
diff --git a/newt/vendor/mynewt.apache.org/newt/util/util.go b/newt/vendor/mynewt.apache.org/newt/util/util.go
index 27b407c..930c24e 100644
--- a/newt/vendor/mynewt.apache.org/newt/util/util.go
+++ b/newt/vendor/mynewt.apache.org/newt/util/util.go
@@ -32,6 +32,7 @@ import (
"path/filepath"
"runtime"
"sort"
+ "strconv"
"strings"
"syscall"
"time"
@@ -422,3 +423,23 @@ func SortFields(wsSepStrings ...string) []string {
sort.Strings(slice)
return slice
}
+
+func AtoiNoOct(s string) (int, error) {
+ var runLen int
+ for runLen = 0; runLen < len(s)-1; runLen++ {
+ if s[runLen] != '0' || s[runLen+1] == 'x' {
+ break
+ }
+ }
+
+ if runLen > 0 {
+ s = s[runLen:]
+ }
+
+ i, err := strconv.ParseInt(s, 0, 0)
+ if err != nil {
+ return 0, NewNewtError(err.Error())
+ }
+
+ return int(i), nil
+}