Merge pull request #1340 from dqminh/vndr-take2
Carry #998: Use vndr tool for vendoring
This commit is contained in:
commit
cf883a87e7
|
@ -1,6 +1,5 @@
|
|||
vendor/pkg
|
||||
/runc
|
||||
contrib/cmd/recvtty/recvtty
|
||||
Godeps/_workspace/src/github.com/opencontainers/runc
|
||||
man/man8
|
||||
release
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
{
|
||||
"ImportPath": "github.com/opencontainers/runc",
|
||||
"GoVersion": "go1.5.3",
|
||||
"GodepVersion": "v75",
|
||||
"Deps": [
|
||||
{
|
||||
"ImportPath": "github.com/Sirupsen/logrus",
|
||||
"Comment": "v0.7.3-2-g26709e2",
|
||||
"Rev": "26709e2714106fb8ad40b773b711ebce25b78914"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/urfave/cli",
|
||||
"Comment": "v1.18.0-67-gd53eb99",
|
||||
"Rev": "d53eb991652b1d438abdd34ce4bfa3ef1539108e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/coreos/go-systemd/activation",
|
||||
"Comment": "v14",
|
||||
"Rev": "48702e0da86bd25e76cfef347e2adeb434a0d0a6"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/coreos/go-systemd/dbus",
|
||||
"Comment": "v14",
|
||||
"Rev": "48702e0da86bd25e76cfef347e2adeb434a0d0a6"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/coreos/go-systemd/util",
|
||||
"Comment": "v14",
|
||||
"Rev": "48702e0da86bd25e76cfef347e2adeb434a0d0a6"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/docker/pkg/mount",
|
||||
"Comment": "v1.4.1-4831-g0f5c9d3",
|
||||
"Rev": "0f5c9d301b9b1cca66b3ea0f9dec3b5317d3686d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/docker/pkg/symlink",
|
||||
"Comment": "v1.4.1-4831-g0f5c9d3",
|
||||
"Rev": "0f5c9d301b9b1cca66b3ea0f9dec3b5317d3686d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/docker/pkg/term",
|
||||
"Comment": "v1.4.1-4831-g0f5c9d3",
|
||||
"Rev": "0f5c9d301b9b1cca66b3ea0f9dec3b5317d3686d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/go-units",
|
||||
"Comment": "v0.1.0",
|
||||
"Rev": "9b001659dd36225e356b4467c465d732e745f53d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/godbus/dbus",
|
||||
"Comment": "v3",
|
||||
"Rev": "c7fdd8b5cd55e87b4e1f4e372cdb1db61dd6c66f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/golang/protobuf/proto",
|
||||
"Rev": "f7137ae6b19afbfd61a94b746fda3b3fe0491874"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/opencontainers/runtime-spec/specs-go",
|
||||
"Comment": "v1.0.0-rc3",
|
||||
"Rev": "794ca7ac88234607f9d2c76da8a6e9bbbade8cb9"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/seccomp/libseccomp-golang",
|
||||
"Rev": "32f571b70023028bd57d9288c20efbcb237f3ce0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/syndtr/gocapability/capability",
|
||||
"Rev": "e7cb7fa329f456b3855136a2642b197bad7366ba"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vishvananda/netlink",
|
||||
"Rev": "1e2e08e8a2dcdacaae3f14ac44c5cfa31361f270"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mrunalp/fileutils",
|
||||
"Rev": "ed869b029674c0e9ce4c0dfa781405c2d9946d08"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/coreos/pkg/dlopen",
|
||||
"Comment": "v3",
|
||||
"Rev": "3ac0863d7acf3bc44daf49afef8919af12f704ef"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
This directory tree is generated automatically by godep.
|
||||
|
||||
Please do not edit.
|
||||
|
||||
See https://github.com/tools/godep for more information.
|
|
@ -1,2 +0,0 @@
|
|||
/pkg
|
||||
/bin
|
|
@ -1 +0,0 @@
|
|||
logrus
|
|
@ -1,8 +0,0 @@
|
|||
language: go
|
||||
go:
|
||||
- 1.2
|
||||
- 1.3
|
||||
- 1.4
|
||||
- tip
|
||||
install:
|
||||
- go get -t ./...
|
|
@ -1,7 +0,0 @@
|
|||
# 0.7.3
|
||||
|
||||
formatter/\*: allow configuration of timestamp layout
|
||||
|
||||
# 0.7.2
|
||||
|
||||
formatter/text: Add configuration option for time format (#158)
|
|
@ -1,50 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
var log = logrus.New()
|
||||
|
||||
func init() {
|
||||
log.Formatter = new(logrus.JSONFormatter)
|
||||
log.Formatter = new(logrus.TextFormatter) // default
|
||||
log.Level = logrus.DebugLevel
|
||||
}
|
||||
|
||||
func main() {
|
||||
defer func() {
|
||||
err := recover()
|
||||
if err != nil {
|
||||
log.WithFields(logrus.Fields{
|
||||
"omg": true,
|
||||
"err": err,
|
||||
"number": 100,
|
||||
}).Fatal("The ice breaks!")
|
||||
}
|
||||
}()
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"animal": "walrus",
|
||||
"number": 8,
|
||||
}).Debug("Started observing beach")
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"animal": "walrus",
|
||||
"size": 10,
|
||||
}).Info("A group of walrus emerges from the ocean")
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"omg": true,
|
||||
"number": 122,
|
||||
}).Warn("The group's number increased tremendously!")
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"temperature": -4,
|
||||
}).Debug("Temperature changes")
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"animal": "orca",
|
||||
"size": 9009,
|
||||
}).Panic("It's over 9000!")
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/Sirupsen/logrus/hooks/airbrake"
|
||||
)
|
||||
|
||||
var log = logrus.New()
|
||||
|
||||
func init() {
|
||||
log.Formatter = new(logrus.TextFormatter) // default
|
||||
log.Hooks.Add(airbrake.NewHook("https://example.com", "xyz", "development"))
|
||||
}
|
||||
|
||||
func main() {
|
||||
log.WithFields(logrus.Fields{
|
||||
"animal": "walrus",
|
||||
"size": 10,
|
||||
}).Info("A group of walrus emerges from the ocean")
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"omg": true,
|
||||
"number": 122,
|
||||
}).Warn("The group's number increased tremendously!")
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"omg": true,
|
||||
"number": 100,
|
||||
}).Fatal("The ice breaks!")
|
||||
}
|
56
Godeps/_workspace/src/github.com/Sirupsen/logrus/formatters/logstash/logstash.go
generated
vendored
56
Godeps/_workspace/src/github.com/Sirupsen/logrus/formatters/logstash/logstash.go
generated
vendored
|
@ -1,56 +0,0 @@
|
|||
package logstash
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Formatter generates json in logstash format.
|
||||
// Logstash site: http://logstash.net/
|
||||
type LogstashFormatter struct {
|
||||
Type string // if not empty use for logstash type field.
|
||||
|
||||
// TimestampFormat sets the format used for timestamps.
|
||||
TimestampFormat string
|
||||
}
|
||||
|
||||
func (f *LogstashFormatter) Format(entry *logrus.Entry) ([]byte, error) {
|
||||
entry.Data["@version"] = 1
|
||||
|
||||
if f.TimestampFormat == "" {
|
||||
f.TimestampFormat = logrus.DefaultTimestampFormat
|
||||
}
|
||||
|
||||
entry.Data["@timestamp"] = entry.Time.Format(f.TimestampFormat)
|
||||
|
||||
// set message field
|
||||
v, ok := entry.Data["message"]
|
||||
if ok {
|
||||
entry.Data["fields.message"] = v
|
||||
}
|
||||
entry.Data["message"] = entry.Message
|
||||
|
||||
// set level field
|
||||
v, ok = entry.Data["level"]
|
||||
if ok {
|
||||
entry.Data["fields.level"] = v
|
||||
}
|
||||
entry.Data["level"] = entry.Level.String()
|
||||
|
||||
// set type field
|
||||
if f.Type != "" {
|
||||
v, ok = entry.Data["type"]
|
||||
if ok {
|
||||
entry.Data["fields.type"] = v
|
||||
}
|
||||
entry.Data["type"] = f.Type
|
||||
}
|
||||
|
||||
serialized, err := json.Marshal(entry.Data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
|
||||
}
|
||||
return append(serialized, '\n'), nil
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
package airbrake
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/tobi/airbrake-go"
|
||||
)
|
||||
|
||||
// AirbrakeHook to send exceptions to an exception-tracking service compatible
|
||||
// with the Airbrake API.
|
||||
type airbrakeHook struct {
|
||||
APIKey string
|
||||
Endpoint string
|
||||
Environment string
|
||||
}
|
||||
|
||||
func NewHook(endpoint, apiKey, env string) *airbrakeHook {
|
||||
return &airbrakeHook{
|
||||
APIKey: apiKey,
|
||||
Endpoint: endpoint,
|
||||
Environment: env,
|
||||
}
|
||||
}
|
||||
|
||||
func (hook *airbrakeHook) Fire(entry *logrus.Entry) error {
|
||||
airbrake.ApiKey = hook.APIKey
|
||||
airbrake.Endpoint = hook.Endpoint
|
||||
airbrake.Environment = hook.Environment
|
||||
|
||||
var notifyErr error
|
||||
err, ok := entry.Data["error"].(error)
|
||||
if ok {
|
||||
notifyErr = err
|
||||
} else {
|
||||
notifyErr = errors.New(entry.Message)
|
||||
}
|
||||
|
||||
airErr := airbrake.Notify(notifyErr)
|
||||
if airErr != nil {
|
||||
return fmt.Errorf("Failed to send error to Airbrake: %s", airErr)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hook *airbrakeHook) Levels() []logrus.Level {
|
||||
return []logrus.Level{
|
||||
logrus.ErrorLevel,
|
||||
logrus.FatalLevel,
|
||||
logrus.PanicLevel,
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
package logrus_bugsnag
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/bugsnag/bugsnag-go"
|
||||
)
|
||||
|
||||
type bugsnagHook struct{}
|
||||
|
||||
// ErrBugsnagUnconfigured is returned if NewBugsnagHook is called before
|
||||
// bugsnag.Configure. Bugsnag must be configured before the hook.
|
||||
var ErrBugsnagUnconfigured = errors.New("bugsnag must be configured before installing this logrus hook")
|
||||
|
||||
// ErrBugsnagSendFailed indicates that the hook failed to submit an error to
|
||||
// bugsnag. The error was successfully generated, but `bugsnag.Notify()`
|
||||
// failed.
|
||||
type ErrBugsnagSendFailed struct {
|
||||
err error
|
||||
}
|
||||
|
||||
func (e ErrBugsnagSendFailed) Error() string {
|
||||
return "failed to send error to Bugsnag: " + e.err.Error()
|
||||
}
|
||||
|
||||
// NewBugsnagHook initializes a logrus hook which sends exceptions to an
|
||||
// exception-tracking service compatible with the Bugsnag API. Before using
|
||||
// this hook, you must call bugsnag.Configure(). The returned object should be
|
||||
// registered with a log via `AddHook()`
|
||||
//
|
||||
// Entries that trigger an Error, Fatal or Panic should now include an "error"
|
||||
// field to send to Bugsnag.
|
||||
func NewBugsnagHook() (*bugsnagHook, error) {
|
||||
if bugsnag.Config.APIKey == "" {
|
||||
return nil, ErrBugsnagUnconfigured
|
||||
}
|
||||
return &bugsnagHook{}, nil
|
||||
}
|
||||
|
||||
// Fire forwards an error to Bugsnag. Given a logrus.Entry, it extracts the
|
||||
// "error" field (or the Message if the error isn't present) and sends it off.
|
||||
func (hook *bugsnagHook) Fire(entry *logrus.Entry) error {
|
||||
var notifyErr error
|
||||
err, ok := entry.Data["error"].(error)
|
||||
if ok {
|
||||
notifyErr = err
|
||||
} else {
|
||||
notifyErr = errors.New(entry.Message)
|
||||
}
|
||||
|
||||
bugsnagErr := bugsnag.Notify(notifyErr)
|
||||
if bugsnagErr != nil {
|
||||
return ErrBugsnagSendFailed{bugsnagErr}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Levels enumerates the log levels on which the error should be forwarded to
|
||||
// bugsnag: everything at or above the "Error" level.
|
||||
func (hook *bugsnagHook) Levels() []logrus.Level {
|
||||
return []logrus.Level{
|
||||
logrus.ErrorLevel,
|
||||
logrus.FatalLevel,
|
||||
logrus.PanicLevel,
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
# Papertrail Hook for Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:" />
|
||||
|
||||
[Papertrail](https://papertrailapp.com) provides hosted log management. Once stored in Papertrail, you can [group](http://help.papertrailapp.com/kb/how-it-works/groups/) your logs on various dimensions, [search](http://help.papertrailapp.com/kb/how-it-works/search-syntax) them, and trigger [alerts](http://help.papertrailapp.com/kb/how-it-works/alerts).
|
||||
|
||||
In most deployments, you'll want to send logs to Papertrail via their [remote_syslog](http://help.papertrailapp.com/kb/configuration/configuring-centralized-logging-from-text-log-files-in-unix/) daemon, which requires no application-specific configuration. This hook is intended for relatively low-volume logging, likely in managed cloud hosting deployments where installing `remote_syslog` is not possible.
|
||||
|
||||
## Usage
|
||||
|
||||
You can find your Papertrail UDP port on your [Papertrail account page](https://papertrailapp.com/account/destinations). Substitute it below for `YOUR_PAPERTRAIL_UDP_PORT`.
|
||||
|
||||
For `YOUR_APP_NAME`, substitute a short string that will readily identify your application or service in the logs.
|
||||
|
||||
```go
|
||||
import (
|
||||
"log/syslog"
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/Sirupsen/logrus/hooks/papertrail"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log := logrus.New()
|
||||
hook, err := logrus_papertrail.NewPapertrailHook("logs.papertrailapp.com", YOUR_PAPERTRAIL_UDP_PORT, YOUR_APP_NAME)
|
||||
|
||||
if err == nil {
|
||||
log.Hooks.Add(hook)
|
||||
}
|
||||
}
|
||||
```
|
55
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go
generated
vendored
55
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go
generated
vendored
|
@ -1,55 +0,0 @@
|
|||
package logrus_papertrail
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
format = "Jan 2 15:04:05"
|
||||
)
|
||||
|
||||
// PapertrailHook to send logs to a logging service compatible with the Papertrail API.
|
||||
type PapertrailHook struct {
|
||||
Host string
|
||||
Port int
|
||||
AppName string
|
||||
UDPConn net.Conn
|
||||
}
|
||||
|
||||
// NewPapertrailHook creates a hook to be added to an instance of logger.
|
||||
func NewPapertrailHook(host string, port int, appName string) (*PapertrailHook, error) {
|
||||
conn, err := net.Dial("udp", fmt.Sprintf("%s:%d", host, port))
|
||||
return &PapertrailHook{host, port, appName, conn}, err
|
||||
}
|
||||
|
||||
// Fire is called when a log event is fired.
|
||||
func (hook *PapertrailHook) Fire(entry *logrus.Entry) error {
|
||||
date := time.Now().Format(format)
|
||||
msg, _ := entry.String()
|
||||
payload := fmt.Sprintf("<22> %s %s: %s", date, hook.AppName, msg)
|
||||
|
||||
bytesWritten, err := hook.UDPConn.Write([]byte(payload))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Unable to send log line to Papertrail via UDP. Wrote %d bytes before error: %v", bytesWritten, err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Levels returns the available logging levels.
|
||||
func (hook *PapertrailHook) Levels() []logrus.Level {
|
||||
return []logrus.Level{
|
||||
logrus.PanicLevel,
|
||||
logrus.FatalLevel,
|
||||
logrus.ErrorLevel,
|
||||
logrus.WarnLevel,
|
||||
logrus.InfoLevel,
|
||||
logrus.DebugLevel,
|
||||
}
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
# Sentry Hook for Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:" />
|
||||
|
||||
[Sentry](https://getsentry.com) provides both self-hosted and hosted
|
||||
solutions for exception tracking.
|
||||
Both client and server are
|
||||
[open source](https://github.com/getsentry/sentry).
|
||||
|
||||
## Usage
|
||||
|
||||
Every sentry application defined on the server gets a different
|
||||
[DSN](https://www.getsentry.com/docs/). In the example below replace
|
||||
`YOUR_DSN` with the one created for your application.
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/Sirupsen/logrus/hooks/sentry"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log := logrus.New()
|
||||
hook, err := logrus_sentry.NewSentryHook(YOUR_DSN, []logrus.Level{
|
||||
logrus.PanicLevel,
|
||||
logrus.FatalLevel,
|
||||
logrus.ErrorLevel,
|
||||
})
|
||||
|
||||
if err == nil {
|
||||
log.Hooks.Add(hook)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Special fields
|
||||
|
||||
Some logrus fields have a special meaning in this hook,
|
||||
these are server_name and logger.
|
||||
When logs are sent to sentry these fields are treated differently.
|
||||
- server_name (also known as hostname) is the name of the server which
|
||||
is logging the event (hostname.example.com)
|
||||
- logger is the part of the application which is logging the event.
|
||||
In go this usually means setting it to the name of the package.
|
||||
|
||||
## Timeout
|
||||
|
||||
`Timeout` is the time the sentry hook will wait for a response
|
||||
from the sentry server.
|
||||
|
||||
If this time elapses with no response from
|
||||
the server an error will be returned.
|
||||
|
||||
If `Timeout` is set to 0 the SentryHook will not wait for a reply
|
||||
and will assume a correct delivery.
|
||||
|
||||
The SentryHook has a default timeout of `100 milliseconds` when created
|
||||
with a call to `NewSentryHook`. This can be changed by assigning a value to the `Timeout` field:
|
||||
|
||||
```go
|
||||
hook, _ := logrus_sentry.NewSentryHook(...)
|
||||
hook.Timeout = 20*time.Second
|
||||
```
|
|
@ -1,100 +0,0 @@
|
|||
package logrus_sentry
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/getsentry/raven-go"
|
||||
)
|
||||
|
||||
var (
|
||||
severityMap = map[logrus.Level]raven.Severity{
|
||||
logrus.DebugLevel: raven.DEBUG,
|
||||
logrus.InfoLevel: raven.INFO,
|
||||
logrus.WarnLevel: raven.WARNING,
|
||||
logrus.ErrorLevel: raven.ERROR,
|
||||
logrus.FatalLevel: raven.FATAL,
|
||||
logrus.PanicLevel: raven.FATAL,
|
||||
}
|
||||
)
|
||||
|
||||
func getAndDel(d logrus.Fields, key string) (string, bool) {
|
||||
var (
|
||||
ok bool
|
||||
v interface{}
|
||||
val string
|
||||
)
|
||||
if v, ok = d[key]; !ok {
|
||||
return "", false
|
||||
}
|
||||
|
||||
if val, ok = v.(string); !ok {
|
||||
return "", false
|
||||
}
|
||||
delete(d, key)
|
||||
return val, true
|
||||
}
|
||||
|
||||
// SentryHook delivers logs to a sentry server.
|
||||
type SentryHook struct {
|
||||
// Timeout sets the time to wait for a delivery error from the sentry server.
|
||||
// If this is set to zero the server will not wait for any response and will
|
||||
// consider the message correctly sent
|
||||
Timeout time.Duration
|
||||
|
||||
client *raven.Client
|
||||
levels []logrus.Level
|
||||
}
|
||||
|
||||
// NewSentryHook creates a hook to be added to an instance of logger
|
||||
// and initializes the raven client.
|
||||
// This method sets the timeout to 100 milliseconds.
|
||||
func NewSentryHook(DSN string, levels []logrus.Level) (*SentryHook, error) {
|
||||
client, err := raven.NewClient(DSN, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &SentryHook{100 * time.Millisecond, client, levels}, nil
|
||||
}
|
||||
|
||||
// Called when an event should be sent to sentry
|
||||
// Special fields that sentry uses to give more information to the server
|
||||
// are extracted from entry.Data (if they are found)
|
||||
// These fields are: logger and server_name
|
||||
func (hook *SentryHook) Fire(entry *logrus.Entry) error {
|
||||
packet := &raven.Packet{
|
||||
Message: entry.Message,
|
||||
Timestamp: raven.Timestamp(entry.Time),
|
||||
Level: severityMap[entry.Level],
|
||||
Platform: "go",
|
||||
}
|
||||
|
||||
d := entry.Data
|
||||
|
||||
if logger, ok := getAndDel(d, "logger"); ok {
|
||||
packet.Logger = logger
|
||||
}
|
||||
if serverName, ok := getAndDel(d, "server_name"); ok {
|
||||
packet.ServerName = serverName
|
||||
}
|
||||
packet.Extra = map[string]interface{}(d)
|
||||
|
||||
_, errCh := hook.client.Capture(packet, nil)
|
||||
timeout := hook.Timeout
|
||||
if timeout != 0 {
|
||||
timeoutCh := time.After(timeout)
|
||||
select {
|
||||
case err := <-errCh:
|
||||
return err
|
||||
case <-timeoutCh:
|
||||
return fmt.Errorf("no response from sentry server in %s", timeout)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Levels returns the available logging levels.
|
||||
func (hook *SentryHook) Levels() []logrus.Level {
|
||||
return hook.levels
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
# Syslog Hooks for Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/>
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
import (
|
||||
"log/syslog"
|
||||
"github.com/Sirupsen/logrus"
|
||||
logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log := logrus.New()
|
||||
hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
|
||||
|
||||
if err == nil {
|
||||
log.Hooks.Add(hook)
|
||||
}
|
||||
}
|
||||
```
|
|
@ -1,59 +0,0 @@
|
|||
package logrus_syslog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/Sirupsen/logrus"
|
||||
"log/syslog"
|
||||
"os"
|
||||
)
|
||||
|
||||
// SyslogHook to send logs via syslog.
|
||||
type SyslogHook struct {
|
||||
Writer *syslog.Writer
|
||||
SyslogNetwork string
|
||||
SyslogRaddr string
|
||||
}
|
||||
|
||||
// Creates a hook to be added to an instance of logger. This is called with
|
||||
// `hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_DEBUG, "")`
|
||||
// `if err == nil { log.Hooks.Add(hook) }`
|
||||
func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) {
|
||||
w, err := syslog.Dial(network, raddr, priority, tag)
|
||||
return &SyslogHook{w, network, raddr}, err
|
||||
}
|
||||
|
||||
func (hook *SyslogHook) Fire(entry *logrus.Entry) error {
|
||||
line, err := entry.String()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
switch entry.Level {
|
||||
case logrus.PanicLevel:
|
||||
return hook.Writer.Crit(line)
|
||||
case logrus.FatalLevel:
|
||||
return hook.Writer.Crit(line)
|
||||
case logrus.ErrorLevel:
|
||||
return hook.Writer.Err(line)
|
||||
case logrus.WarnLevel:
|
||||
return hook.Writer.Warning(line)
|
||||
case logrus.InfoLevel:
|
||||
return hook.Writer.Info(line)
|
||||
case logrus.DebugLevel:
|
||||
return hook.Writer.Debug(line)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (hook *SyslogHook) Levels() []logrus.Level {
|
||||
return []logrus.Level{
|
||||
logrus.PanicLevel,
|
||||
logrus.FatalLevel,
|
||||
logrus.ErrorLevel,
|
||||
logrus.WarnLevel,
|
||||
logrus.InfoLevel,
|
||||
logrus.DebugLevel,
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
Copyright (c) 2013 Honza Pokorny
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
BIN
Godeps/_workspace/src/github.com/docker/docker/docs/project/images/red_notice.png
generated
vendored
BIN
Godeps/_workspace/src/github.com/docker/docker/docs/project/images/red_notice.png
generated
vendored
Binary file not shown.
Before Width: | Height: | Size: 44 KiB |
|
@ -1,27 +0,0 @@
|
|||
Copyright (c) 2014-2015 The Docker & Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -1,14 +0,0 @@
|
|||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Simon Eskildsen
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -1,20 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Armon Dadgar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -1,202 +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.
|
||||
|
191
Godeps/_workspace/src/github.com/docker/docker/vendor/src/github.com/docker/libkv/LICENSE
generated
vendored
191
Godeps/_workspace/src/github.com/docker/docker/vendor/src/github.com/docker/libkv/LICENSE
generated
vendored
|
@ -1,191 +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
|
||||
|
||||
Copyright 2014-2015 Docker, Inc.
|
||||
|
||||
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.
|
|
@ -1,202 +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.
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
Gocheck - A rich testing framework for Go
|
||||
|
||||
Copyright (c) 2010-2013 Gustavo Niemeyer <gustavo@niemeyer.net>
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
25
Godeps/_workspace/src/github.com/docker/docker/vendor/src/github.com/godbus/dbus/LICENSE
generated
vendored
25
Godeps/_workspace/src/github.com/docker/docker/vendor/src/github.com/godbus/dbus/LICENSE
generated
vendored
|
@ -1,25 +0,0 @@
|
|||
Copyright (c) 2013, Georg Reinke (<guelfey at gmail dot com>)
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -1,27 +0,0 @@
|
|||
Copyright (c) 2012 Rodrigo Moraes. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
Godeps/_workspace/src/github.com/docker/docker/vendor/src/github.com/gorilla/mux/LICENSE
generated
vendored
27
Godeps/_workspace/src/github.com/docker/docker/vendor/src/github.com/gorilla/mux/LICENSE
generated
vendored
|
@ -1,27 +0,0 @@
|
|||
Copyright (c) 2012 Rodrigo Moraes. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -1,354 +0,0 @@
|
|||
Mozilla Public License, version 2.0
|
||||
|
||||
1. Definitions
|
||||
|
||||
1.1. “Contributor”
|
||||
|
||||
means each individual or legal entity that creates, contributes to the
|
||||
creation of, or owns Covered Software.
|
||||
|
||||
1.2. “Contributor Version”
|
||||
|
||||
means the combination of the Contributions of others (if any) used by a
|
||||
Contributor and that particular Contributor’s Contribution.
|
||||
|
||||
1.3. “Contribution”
|
||||
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. “Covered Software”
|
||||
|
||||
means Source Code Form to which the initial Contributor has attached the
|
||||
notice in Exhibit A, the Executable Form of such Source Code Form, and
|
||||
Modifications of such Source Code Form, in each case including portions
|
||||
thereof.
|
||||
|
||||
1.5. “Incompatible With Secondary Licenses”
|
||||
means
|
||||
|
||||
a. that the initial Contributor has attached the notice described in
|
||||
Exhibit B to the Covered Software; or
|
||||
|
||||
b. that the Covered Software was made available under the terms of version
|
||||
1.1 or earlier of the License, but not also under the terms of a
|
||||
Secondary License.
|
||||
|
||||
1.6. “Executable Form”
|
||||
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. “Larger Work”
|
||||
|
||||
means a work that combines Covered Software with other material, in a separate
|
||||
file or files, that is not Covered Software.
|
||||
|
||||
1.8. “License”
|
||||
|
||||
means this document.
|
||||
|
||||
1.9. “Licensable”
|
||||
|
||||
means having the right to grant, to the maximum extent possible, whether at the
|
||||
time of the initial grant or subsequently, any and all of the rights conveyed by
|
||||
this License.
|
||||
|
||||
1.10. “Modifications”
|
||||
|
||||
means any of the following:
|
||||
|
||||
a. any file in Source Code Form that results from an addition to, deletion
|
||||
from, or modification of the contents of Covered Software; or
|
||||
|
||||
b. any new file in Source Code Form that contains any Covered Software.
|
||||
|
||||
1.11. “Patent Claims” of a Contributor
|
||||
|
||||
means any patent claim(s), including without limitation, method, process,
|
||||
and apparatus claims, in any patent Licensable by such Contributor that
|
||||
would be infringed, but for the grant of the License, by the making,
|
||||
using, selling, offering for sale, having made, import, or transfer of
|
||||
either its Contributions or its Contributor Version.
|
||||
|
||||
1.12. “Secondary License”
|
||||
|
||||
means either the GNU General Public License, Version 2.0, the GNU Lesser
|
||||
General Public License, Version 2.1, the GNU Affero General Public
|
||||
License, Version 3.0, or any later versions of those licenses.
|
||||
|
||||
1.13. “Source Code Form”
|
||||
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. “You” (or “Your”)
|
||||
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, “You” includes any entity that controls, is
|
||||
controlled by, or is under common control with You. For purposes of this
|
||||
definition, “control” means (a) the power, direct or indirect, to cause
|
||||
the direction or management of such entity, whether by contract or
|
||||
otherwise, or (b) ownership of more than fifty percent (50%) of the
|
||||
outstanding shares or beneficial ownership of such entity.
|
||||
|
||||
|
||||
2. License Grants and Conditions
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
a. under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or as
|
||||
part of a Larger Work; and
|
||||
|
||||
b. under Patent Claims of such Contributor to make, use, sell, offer for
|
||||
sale, have made, import, and otherwise transfer either its Contributions
|
||||
or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution become
|
||||
effective for each Contribution on the date the Contributor first distributes
|
||||
such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under this
|
||||
License. No additional rights or licenses will be implied from the distribution
|
||||
or licensing of Covered Software under this License. Notwithstanding Section
|
||||
2.1(b) above, no patent license is granted by a Contributor:
|
||||
|
||||
a. for any code that a Contributor has removed from Covered Software; or
|
||||
|
||||
b. for infringements caused by: (i) Your and any other third party’s
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
c. under Patent Claims infringed by Covered Software in the absence of its
|
||||
Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks, or
|
||||
logos of any Contributor (except as may be necessary to comply with the
|
||||
notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this License
|
||||
(see Section 10.2) or under the terms of a Secondary License (if permitted
|
||||
under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its Contributions
|
||||
are its original creation(s) or it has sufficient rights to grant the
|
||||
rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under applicable
|
||||
copyright doctrines of fair use, fair dealing, or other equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
|
||||
Section 2.1.
|
||||
|
||||
|
||||
3. Responsibilities
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under the
|
||||
terms of this License. You must inform recipients that the Source Code Form
|
||||
of the Covered Software is governed by the terms of this License, and how
|
||||
they can obtain a copy of this License. You may not attempt to alter or
|
||||
restrict the recipients’ rights in the Source Code Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
a. such Covered Software must also be made available in Source Code Form,
|
||||
as described in Section 3.1, and You must inform recipients of the
|
||||
Executable Form how they can obtain a copy of such Source Code Form by
|
||||
reasonable means in a timely manner, at a charge no more than the cost
|
||||
of distribution to the recipient; and
|
||||
|
||||
b. You may distribute such Executable Form under the terms of this License,
|
||||
or sublicense it under different terms, provided that the license for
|
||||
the Executable Form does not attempt to limit or alter the recipients’
|
||||
rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for the
|
||||
Covered Software. If the Larger Work is a combination of Covered Software
|
||||
with a work governed by one or more Secondary Licenses, and the Covered
|
||||
Software is not Incompatible With Secondary Licenses, this License permits
|
||||
You to additionally distribute such Covered Software under the terms of
|
||||
such Secondary License(s), so that the recipient of the Larger Work may, at
|
||||
their option, further distribute the Covered Software under the terms of
|
||||
either this License or such Secondary License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices (including
|
||||
copyright notices, patent notices, disclaimers of warranty, or limitations
|
||||
of liability) contained within the Source Code Form of the Covered
|
||||
Software, except that You may alter any license notices to the extent
|
||||
required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on behalf
|
||||
of any Contributor. You must make it absolutely clear that any such
|
||||
warranty, support, indemnity, or liability obligation is offered by You
|
||||
alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this License
|
||||
with respect to some or all of the Covered Software due to statute, judicial
|
||||
order, or regulation then You must: (a) comply with the terms of this License
|
||||
to the maximum extent possible; and (b) describe the limitations and the code
|
||||
they affect. Such description must be placed in a text file included with all
|
||||
distributions of the Covered Software under this License. Except to the
|
||||
extent prohibited by statute or regulation, such description must be
|
||||
sufficiently detailed for a recipient of ordinary skill to be able to
|
||||
understand it.
|
||||
|
||||
5. Termination
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically if You
|
||||
fail to comply with any of its terms. However, if You become compliant,
|
||||
then the rights granted under this License from a particular Contributor
|
||||
are reinstated (a) provisionally, unless and until such Contributor
|
||||
explicitly and finally terminates Your grants, and (b) on an ongoing basis,
|
||||
if such Contributor fails to notify You of the non-compliance by some
|
||||
reasonable means prior to 60 days after You have come back into compliance.
|
||||
Moreover, Your grants from a particular Contributor are reinstated on an
|
||||
ongoing basis if such Contributor notifies You of the non-compliance by
|
||||
some reasonable means, this is the first time You have received notice of
|
||||
non-compliance with this License from such Contributor, and You become
|
||||
compliant prior to 30 days after Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions, counter-claims,
|
||||
and cross-claims) alleging that a Contributor Version directly or
|
||||
indirectly infringes any patent, then the rights granted to You by any and
|
||||
all Contributors for the Covered Software under Section 2.1 of this License
|
||||
shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
|
||||
license agreements (excluding distributors and resellers) which have been
|
||||
validly granted by You or Your distributors under this License prior to
|
||||
termination shall survive termination.
|
||||
|
||||
6. Disclaimer of Warranty
|
||||
|
||||
Covered Software is provided under this License on an “as is” basis, without
|
||||
warranty of any kind, either expressed, implied, or statutory, including,
|
||||
without limitation, warranties that the Covered Software is free of defects,
|
||||
merchantable, fit for a particular purpose or non-infringing. The entire
|
||||
risk as to the quality and performance of the Covered Software is with You.
|
||||
Should any Covered Software prove defective in any respect, You (not any
|
||||
Contributor) assume the cost of any necessary servicing, repair, or
|
||||
correction. This disclaimer of warranty constitutes an essential part of this
|
||||
License. No use of any Covered Software is authorized under this License
|
||||
except under this disclaimer.
|
||||
|
||||
7. Limitation of Liability
|
||||
|
||||
Under no circumstances and under no legal theory, whether tort (including
|
||||
negligence), contract, or otherwise, shall any Contributor, or anyone who
|
||||
distributes Covered Software as permitted above, be liable to You for any
|
||||
direct, indirect, special, incidental, or consequential damages of any
|
||||
character including, without limitation, damages for lost profits, loss of
|
||||
goodwill, work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses, even if such party shall have been
|
||||
informed of the possibility of such damages. This limitation of liability
|
||||
shall not apply to liability for death or personal injury resulting from such
|
||||
party’s negligence to the extent applicable law prohibits such limitation.
|
||||
Some jurisdictions do not allow the exclusion or limitation of incidental or
|
||||
consequential damages, so this exclusion and limitation may not apply to You.
|
||||
|
||||
8. Litigation
|
||||
|
||||
Any litigation relating to this License may be brought only in the courts of
|
||||
a jurisdiction where the defendant maintains its principal place of business
|
||||
and such litigation shall be governed by laws of that jurisdiction, without
|
||||
reference to its conflict-of-law provisions. Nothing in this Section shall
|
||||
prevent a party’s ability to bring cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
|
||||
This License represents the complete agreement concerning the subject matter
|
||||
hereof. If any provision of this License is held to be unenforceable, such
|
||||
provision shall be reformed only to the extent necessary to make it
|
||||
enforceable. Any law or regulation which provides that the language of a
|
||||
contract shall be construed against the drafter shall not be used to construe
|
||||
this License against a Contributor.
|
||||
|
||||
|
||||
10. Versions of the License
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version of
|
||||
the License under which You originally received the Covered Software, or
|
||||
under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a modified
|
||||
version of this License if you rename the license and remove any
|
||||
references to the name of the license steward (except to note that such
|
||||
modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a relevant
|
||||
directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - “Incompatible With Secondary Licenses” Notice
|
||||
|
||||
This Source Code Form is “Incompatible
|
||||
With Secondary Licenses”, as defined by
|
||||
the Mozilla Public License, v. 2.0.
|
||||
|
23
Godeps/_workspace/src/github.com/docker/docker/vendor/src/github.com/kr/pty/License
generated
vendored
23
Godeps/_workspace/src/github.com/docker/docker/vendor/src/github.com/kr/pty/License
generated
vendored
|
@ -1,23 +0,0 @@
|
|||
Copyright (c) 2011 Keith Rarick
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall
|
||||
be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
||||
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -1,21 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Yasuhiro Matsumoto
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -1,22 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Microsoft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -1,201 +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 (c) 2014, OmniTI Computer Consulting, Inc.
|
||||
|
||||
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.
|
|
@ -1,8 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
Copyright (c) 2013 npipe authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -1,192 +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
|
||||
|
||||
Copyright 2014 Vishvananda Ishaya.
|
||||
Copyright 2014 Docker, Inc.
|
||||
|
||||
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.
|
|
@ -1,50 +0,0 @@
|
|||
# How to Contribute
|
||||
|
||||
## Getting Started
|
||||
|
||||
- Fork the repository on GitHub
|
||||
- Read the [README](README.markdown) for build and test instructions
|
||||
- Play with the project, submit bugs, submit patches!
|
||||
|
||||
## Contribution Flow
|
||||
|
||||
This is a rough outline of what a contributor's workflow looks like:
|
||||
|
||||
- Create a topic branch from where you want to base your work (usually master).
|
||||
- Make commits of logical units.
|
||||
- Make sure your commit messages are in the proper format (see below).
|
||||
- Push your changes to a topic branch in your fork of the repository.
|
||||
- Make sure the tests pass, and add any new tests as appropriate.
|
||||
- Submit a pull request to the original repository.
|
||||
|
||||
Thanks for your contributions!
|
||||
|
||||
### Format of the Commit Message
|
||||
|
||||
We follow a rough convention for commit messages that is designed to answer two
|
||||
questions: what changed and why. The subject line should feature the what and
|
||||
the body of the commit should describe the why.
|
||||
|
||||
```
|
||||
scripts: add the test-cluster command
|
||||
|
||||
this uses tmux to setup a test cluster that you can easily kill and
|
||||
start for debugging.
|
||||
|
||||
Fixes #38
|
||||
```
|
||||
|
||||
The format can be described more formally as follows:
|
||||
|
||||
```
|
||||
<subsystem>: <what changed>
|
||||
<BLANK LINE>
|
||||
<why this change was made>
|
||||
<BLANK LINE>
|
||||
<footer>
|
||||
```
|
||||
|
||||
The first line is the subject and should be no longer than 70 characters, the
|
||||
second line is always blank, and other lines should be wrapped at 80 characters.
|
||||
This allows the message to be easier to read on GitHub as well as in various
|
||||
git tools.
|
|
@ -1,2 +0,0 @@
|
|||
Brandon Philips <brandon@ifup.org> (@philips)
|
||||
Brian Waldon <brian@waldon.cc> (@bcwaldon)
|
|
@ -1,27 +0,0 @@
|
|||
package introspect
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"github.com/godbus/dbus"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Call calls org.freedesktop.Introspectable.Introspect on a remote object
|
||||
// and returns the introspection data.
|
||||
func Call(o dbus.BusObject) (*Node, error) {
|
||||
var xmldata string
|
||||
var node Node
|
||||
|
||||
err := o.Call("org.freedesktop.DBus.Introspectable.Introspect", 0).Store(&xmldata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = xml.NewDecoder(strings.NewReader(xmldata)).Decode(&node)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if node.Name == "" {
|
||||
node.Name = string(o.Path())
|
||||
}
|
||||
return &node, nil
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
// Package introspect provides some utilities for dealing with the DBus
|
||||
// introspection format.
|
||||
package introspect
|
||||
|
||||
import "encoding/xml"
|
||||
|
||||
// The introspection data for the org.freedesktop.DBus.Introspectable interface.
|
||||
var IntrospectData = Interface{
|
||||
Name: "org.freedesktop.DBus.Introspectable",
|
||||
Methods: []Method{
|
||||
{
|
||||
Name: "Introspect",
|
||||
Args: []Arg{
|
||||
{"out", "s", "out"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// XML document type declaration of the introspection format version 1.0
|
||||
const IntrospectDeclarationString = `
|
||||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
`
|
||||
|
||||
// The introspection data for the org.freedesktop.DBus.Introspectable interface,
|
||||
// as a string.
|
||||
const IntrospectDataString = `
|
||||
<interface name="org.freedesktop.DBus.Introspectable">
|
||||
<method name="Introspect">
|
||||
<arg name="out" direction="out" type="s"/>
|
||||
</method>
|
||||
</interface>
|
||||
`
|
||||
|
||||
// Node is the root element of an introspection.
|
||||
type Node struct {
|
||||
XMLName xml.Name `xml:"node"`
|
||||
Name string `xml:"name,attr,omitempty"`
|
||||
Interfaces []Interface `xml:"interface"`
|
||||
Children []Node `xml:"node,omitempty"`
|
||||
}
|
||||
|
||||
// Interface describes a DBus interface that is available on the message bus.
|
||||
type Interface struct {
|
||||
Name string `xml:"name,attr"`
|
||||
Methods []Method `xml:"method"`
|
||||
Signals []Signal `xml:"signal"`
|
||||
Properties []Property `xml:"property"`
|
||||
Annotations []Annotation `xml:"annotation"`
|
||||
}
|
||||
|
||||
// Method describes a Method on an Interface as retured by an introspection.
|
||||
type Method struct {
|
||||
Name string `xml:"name,attr"`
|
||||
Args []Arg `xml:"arg"`
|
||||
Annotations []Annotation `xml:"annotation"`
|
||||
}
|
||||
|
||||
// Signal describes a Signal emitted on an Interface.
|
||||
type Signal struct {
|
||||
Name string `xml:"name,attr"`
|
||||
Args []Arg `xml:"arg"`
|
||||
Annotations []Annotation `xml:"annotation"`
|
||||
}
|
||||
|
||||
// Property describes a property of an Interface.
|
||||
type Property struct {
|
||||
Name string `xml:"name,attr"`
|
||||
Type string `xml:"type,attr"`
|
||||
Access string `xml:"access,attr"`
|
||||
Annotations []Annotation `xml:"annotation"`
|
||||
}
|
||||
|
||||
// Arg represents an argument of a method or a signal.
|
||||
type Arg struct {
|
||||
Name string `xml:"name,attr,omitempty"`
|
||||
Type string `xml:"type,attr"`
|
||||
Direction string `xml:"direction,attr,omitempty"`
|
||||
}
|
||||
|
||||
// Annotation is an annotation in the introspection format.
|
||||
type Annotation struct {
|
||||
Name string `xml:"name,attr"`
|
||||
Value string `xml:"value,attr"`
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
package introspect
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"github.com/godbus/dbus"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Introspectable implements org.freedesktop.Introspectable.
|
||||
//
|
||||
// You can create it by converting the XML-formatted introspection data from a
|
||||
// string to an Introspectable or call NewIntrospectable with a Node. Then,
|
||||
// export it as org.freedesktop.Introspectable on you object.
|
||||
type Introspectable string
|
||||
|
||||
// NewIntrospectable returns an Introspectable that returns the introspection
|
||||
// data that corresponds to the given Node. If n.Interfaces doesn't contain the
|
||||
// data for org.freedesktop.DBus.Introspectable, it is added automatically.
|
||||
func NewIntrospectable(n *Node) Introspectable {
|
||||
found := false
|
||||
for _, v := range n.Interfaces {
|
||||
if v.Name == "org.freedesktop.DBus.Introspectable" {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
n.Interfaces = append(n.Interfaces, IntrospectData)
|
||||
}
|
||||
b, err := xml.Marshal(n)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return Introspectable(strings.TrimSpace(IntrospectDeclarationString) + string(b))
|
||||
}
|
||||
|
||||
// Introspect implements org.freedesktop.Introspectable.Introspect.
|
||||
func (i Introspectable) Introspect() (string, *dbus.Error) {
|
||||
return string(i), nil
|
||||
}
|
||||
|
||||
// Methods returns the description of the methods of v. This can be used to
|
||||
// create a Node which can be passed to NewIntrospectable.
|
||||
func Methods(v interface{}) []Method {
|
||||
t := reflect.TypeOf(v)
|
||||
ms := make([]Method, 0, t.NumMethod())
|
||||
for i := 0; i < t.NumMethod(); i++ {
|
||||
if t.Method(i).PkgPath != "" {
|
||||
continue
|
||||
}
|
||||
mt := t.Method(i).Type
|
||||
if mt.NumOut() == 0 ||
|
||||
mt.Out(mt.NumOut()-1) != reflect.TypeOf(&dbus.Error{}) {
|
||||
|
||||
continue
|
||||
}
|
||||
var m Method
|
||||
m.Name = t.Method(i).Name
|
||||
m.Args = make([]Arg, 0, mt.NumIn()+mt.NumOut()-2)
|
||||
for j := 1; j < mt.NumIn(); j++ {
|
||||
if mt.In(j) != reflect.TypeOf((*dbus.Sender)(nil)).Elem() &&
|
||||
mt.In(j) != reflect.TypeOf((*dbus.Message)(nil)).Elem() {
|
||||
arg := Arg{"", dbus.SignatureOfType(mt.In(j)).String(), "in"}
|
||||
m.Args = append(m.Args, arg)
|
||||
}
|
||||
}
|
||||
for j := 0; j < mt.NumOut()-1; j++ {
|
||||
arg := Arg{"", dbus.SignatureOfType(mt.Out(j)).String(), "out"}
|
||||
m.Args = append(m.Args, arg)
|
||||
}
|
||||
m.Annotations = make([]Annotation, 0)
|
||||
ms = append(ms, m)
|
||||
}
|
||||
return ms
|
||||
}
|
|
@ -1,264 +0,0 @@
|
|||
// Package prop provides the Properties struct which can be used to implement
|
||||
// org.freedesktop.DBus.Properties.
|
||||
package prop
|
||||
|
||||
import (
|
||||
"github.com/godbus/dbus"
|
||||
"github.com/godbus/dbus/introspect"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// EmitType controls how org.freedesktop.DBus.Properties.PropertiesChanged is
|
||||
// emitted for a property. If it is EmitTrue, the signal is emitted. If it is
|
||||
// EmitInvalidates, the signal is also emitted, but the new value of the property
|
||||
// is not disclosed.
|
||||
type EmitType byte
|
||||
|
||||
const (
|
||||
EmitFalse EmitType = iota
|
||||
EmitTrue
|
||||
EmitInvalidates
|
||||
)
|
||||
|
||||
// ErrIfaceNotFound is the error returned to peers who try to access properties
|
||||
// on interfaces that aren't found.
|
||||
var ErrIfaceNotFound = dbus.NewError("org.freedesktop.DBus.Properties.Error.InterfaceNotFound", nil)
|
||||
|
||||
// ErrPropNotFound is the error returned to peers trying to access properties
|
||||
// that aren't found.
|
||||
var ErrPropNotFound = dbus.NewError("org.freedesktop.DBus.Properties.Error.PropertyNotFound", nil)
|
||||
|
||||
// ErrReadOnly is the error returned to peers trying to set a read-only
|
||||
// property.
|
||||
var ErrReadOnly = dbus.NewError("org.freedesktop.DBus.Properties.Error.ReadOnly", nil)
|
||||
|
||||
// ErrInvalidArg is returned to peers if the type of the property that is being
|
||||
// changed and the argument don't match.
|
||||
var ErrInvalidArg = dbus.NewError("org.freedesktop.DBus.Properties.Error.InvalidArg", nil)
|
||||
|
||||
// The introspection data for the org.freedesktop.DBus.Properties interface.
|
||||
var IntrospectData = introspect.Interface{
|
||||
Name: "org.freedesktop.DBus.Properties",
|
||||
Methods: []introspect.Method{
|
||||
{
|
||||
Name: "Get",
|
||||
Args: []introspect.Arg{
|
||||
{"interface", "s", "in"},
|
||||
{"property", "s", "in"},
|
||||
{"value", "v", "out"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "GetAll",
|
||||
Args: []introspect.Arg{
|
||||
{"interface", "s", "in"},
|
||||
{"props", "a{sv}", "out"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Set",
|
||||
Args: []introspect.Arg{
|
||||
{"interface", "s", "in"},
|
||||
{"property", "s", "in"},
|
||||
{"value", "v", "in"},
|
||||
},
|
||||
},
|
||||
},
|
||||
Signals: []introspect.Signal{
|
||||
{
|
||||
Name: "PropertiesChanged",
|
||||
Args: []introspect.Arg{
|
||||
{"interface", "s", "out"},
|
||||
{"changed_properties", "a{sv}", "out"},
|
||||
{"invalidates_properties", "as", "out"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// The introspection data for the org.freedesktop.DBus.Properties interface, as
|
||||
// a string.
|
||||
const IntrospectDataString = `
|
||||
<interface name="org.freedesktop.DBus.Introspectable">
|
||||
<method name="Get">
|
||||
<arg name="interface" direction="in" type="s"/>
|
||||
<arg name="property" direction="in" type="s"/>
|
||||
<arg name="value" direction="out" type="v"/>
|
||||
</method>
|
||||
<method name="GetAll">
|
||||
<arg name="interface" direction="in" type="s"/>
|
||||
<arg name="props" direction="out" type="a{sv}"/>
|
||||
</method>
|
||||
<method name="Set">
|
||||
<arg name="interface" direction="in" type="s"/>
|
||||
<arg name="property" direction="in" type="s"/>
|
||||
<arg name="value" direction="in" type="v"/>
|
||||
</method>
|
||||
<signal name="PropertiesChanged">
|
||||
<arg name="interface" type="s"/>
|
||||
<arg name="changed_properties" type="a{sv}"/>
|
||||
<arg name="invalidates_properties" type="as"/>
|
||||
</signal>
|
||||
</interface>
|
||||
`
|
||||
|
||||
// Prop represents a single property. It is used for creating a Properties
|
||||
// value.
|
||||
type Prop struct {
|
||||
// Initial value. Must be a DBus-representable type.
|
||||
Value interface{}
|
||||
|
||||
// If true, the value can be modified by calls to Set.
|
||||
Writable bool
|
||||
|
||||
// Controls how org.freedesktop.DBus.Properties.PropertiesChanged is
|
||||
// emitted if this property changes.
|
||||
Emit EmitType
|
||||
|
||||
// If not nil, anytime this property is changed by Set, this function is
|
||||
// called with an appropiate Change as its argument. If the returned error
|
||||
// is not nil, it is sent back to the caller of Set and the property is not
|
||||
// changed.
|
||||
Callback func(*Change) *dbus.Error
|
||||
}
|
||||
|
||||
// Change represents a change of a property by a call to Set.
|
||||
type Change struct {
|
||||
Props *Properties
|
||||
Iface string
|
||||
Name string
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
// Properties is a set of values that can be made available to the message bus
|
||||
// using the org.freedesktop.DBus.Properties interface. It is safe for
|
||||
// concurrent use by multiple goroutines.
|
||||
type Properties struct {
|
||||
m map[string]map[string]*Prop
|
||||
mut sync.RWMutex
|
||||
conn *dbus.Conn
|
||||
path dbus.ObjectPath
|
||||
}
|
||||
|
||||
// New returns a new Properties structure that manages the given properties.
|
||||
// The key for the first-level map of props is the name of the interface; the
|
||||
// second-level key is the name of the property. The returned structure will be
|
||||
// exported as org.freedesktop.DBus.Properties on path.
|
||||
func New(conn *dbus.Conn, path dbus.ObjectPath, props map[string]map[string]*Prop) *Properties {
|
||||
p := &Properties{m: props, conn: conn, path: path}
|
||||
conn.Export(p, path, "org.freedesktop.DBus.Properties")
|
||||
return p
|
||||
}
|
||||
|
||||
// Get implements org.freedesktop.DBus.Properties.Get.
|
||||
func (p *Properties) Get(iface, property string) (dbus.Variant, *dbus.Error) {
|
||||
p.mut.RLock()
|
||||
defer p.mut.RUnlock()
|
||||
m, ok := p.m[iface]
|
||||
if !ok {
|
||||
return dbus.Variant{}, ErrIfaceNotFound
|
||||
}
|
||||
prop, ok := m[property]
|
||||
if !ok {
|
||||
return dbus.Variant{}, ErrPropNotFound
|
||||
}
|
||||
return dbus.MakeVariant(prop.Value), nil
|
||||
}
|
||||
|
||||
// GetAll implements org.freedesktop.DBus.Properties.GetAll.
|
||||
func (p *Properties) GetAll(iface string) (map[string]dbus.Variant, *dbus.Error) {
|
||||
p.mut.RLock()
|
||||
defer p.mut.RUnlock()
|
||||
m, ok := p.m[iface]
|
||||
if !ok {
|
||||
return nil, ErrIfaceNotFound
|
||||
}
|
||||
rm := make(map[string]dbus.Variant, len(m))
|
||||
for k, v := range m {
|
||||
rm[k] = dbus.MakeVariant(v.Value)
|
||||
}
|
||||
return rm, nil
|
||||
}
|
||||
|
||||
// GetMust returns the value of the given property and panics if either the
|
||||
// interface or the property name are invalid.
|
||||
func (p *Properties) GetMust(iface, property string) interface{} {
|
||||
p.mut.RLock()
|
||||
defer p.mut.RUnlock()
|
||||
return p.m[iface][property].Value
|
||||
}
|
||||
|
||||
// Introspection returns the introspection data that represents the properties
|
||||
// of iface.
|
||||
func (p *Properties) Introspection(iface string) []introspect.Property {
|
||||
p.mut.RLock()
|
||||
defer p.mut.RUnlock()
|
||||
m := p.m[iface]
|
||||
s := make([]introspect.Property, 0, len(m))
|
||||
for k, v := range m {
|
||||
p := introspect.Property{Name: k, Type: dbus.SignatureOf(v.Value).String()}
|
||||
if v.Writable {
|
||||
p.Access = "readwrite"
|
||||
} else {
|
||||
p.Access = "read"
|
||||
}
|
||||
s = append(s, p)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// set sets the given property and emits PropertyChanged if appropiate. p.mut
|
||||
// must already be locked.
|
||||
func (p *Properties) set(iface, property string, v interface{}) {
|
||||
prop := p.m[iface][property]
|
||||
prop.Value = v
|
||||
switch prop.Emit {
|
||||
case EmitFalse:
|
||||
// do nothing
|
||||
case EmitInvalidates:
|
||||
p.conn.Emit(p.path, "org.freedesktop.DBus.Properties.PropertiesChanged",
|
||||
iface, map[string]dbus.Variant{}, []string{property})
|
||||
case EmitTrue:
|
||||
p.conn.Emit(p.path, "org.freedesktop.DBus.Properties.PropertiesChanged",
|
||||
iface, map[string]dbus.Variant{property: dbus.MakeVariant(v)},
|
||||
[]string{})
|
||||
default:
|
||||
panic("invalid value for EmitType")
|
||||
}
|
||||
}
|
||||
|
||||
// Set implements org.freedesktop.Properties.Set.
|
||||
func (p *Properties) Set(iface, property string, newv dbus.Variant) *dbus.Error {
|
||||
p.mut.Lock()
|
||||
defer p.mut.Unlock()
|
||||
m, ok := p.m[iface]
|
||||
if !ok {
|
||||
return ErrIfaceNotFound
|
||||
}
|
||||
prop, ok := m[property]
|
||||
if !ok {
|
||||
return ErrPropNotFound
|
||||
}
|
||||
if !prop.Writable {
|
||||
return ErrReadOnly
|
||||
}
|
||||
if newv.Signature() != dbus.SignatureOf(prop.Value) {
|
||||
return ErrInvalidArg
|
||||
}
|
||||
if prop.Callback != nil {
|
||||
err := prop.Callback(&Change{p, iface, property, newv.Value()})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
p.set(iface, property, newv.Value())
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetMust sets the value of the given property and panics if the interface or
|
||||
// the property name are invalid.
|
||||
func (p *Properties) SetMust(iface, property string, v interface{}) {
|
||||
p.mut.Lock()
|
||||
p.set(iface, property, v)
|
||||
p.mut.Unlock()
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
# Go support for Protocol Buffers - Google's data interchange format
|
||||
#
|
||||
# Copyright 2010 The Go Authors. All rights reserved.
|
||||
# https://github.com/golang/protobuf
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
install:
|
||||
go install
|
||||
|
||||
test: install generate-test-pbs
|
||||
go test
|
||||
|
||||
|
||||
generate-test-pbs:
|
||||
make install
|
||||
make -C testdata
|
||||
make -C proto3_proto
|
||||
make
|
|
@ -1,44 +0,0 @@
|
|||
# Go support for Protocol Buffers - Google's data interchange format
|
||||
#
|
||||
# Copyright 2014 The Go Authors. All rights reserved.
|
||||
# https://github.com/golang/protobuf
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
include ../../Make.protobuf
|
||||
|
||||
all: regenerate
|
||||
|
||||
regenerate:
|
||||
rm -f proto3.pb.go
|
||||
make proto3.pb.go
|
||||
|
||||
# The following rules are just aids to development. Not needed for typical testing.
|
||||
|
||||
diff: regenerate
|
||||
git diff proto3.pb.go
|
58
Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/proto3.proto
generated
vendored
58
Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/proto3.proto
generated
vendored
|
@ -1,58 +0,0 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto3_proto;
|
||||
|
||||
message Message {
|
||||
enum Humour {
|
||||
UNKNOWN = 0;
|
||||
PUNS = 1;
|
||||
SLAPSTICK = 2;
|
||||
BILL_BAILEY = 3;
|
||||
}
|
||||
|
||||
string name = 1;
|
||||
Humour hilarity = 2;
|
||||
uint32 height_in_cm = 3;
|
||||
bytes data = 4;
|
||||
int64 result_count = 7;
|
||||
bool true_scotsman = 8;
|
||||
float score = 9;
|
||||
|
||||
repeated uint64 key = 5;
|
||||
Nested nested = 6;
|
||||
}
|
||||
|
||||
message Nested {
|
||||
string bunny = 1;
|
||||
}
|
|
@ -1,191 +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
|
||||
|
||||
Copyright 2014 Docker, Inc.
|
||||
|
||||
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.
|
|
@ -1,202 +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.
|
|
@ -1,8 +0,0 @@
|
|||
ffjson
|
||||
Copyright (c) 2014, Paul Querna
|
||||
|
||||
This product includes software developed by
|
||||
Paul Querna (http://paul.querna.org/).
|
||||
|
||||
Portions of this software were developed as
|
||||
part of Go, Copyright (c) 2012 The Go Authors.
|
|
@ -1,414 +0,0 @@
|
|||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package v1
|
||||
|
||||
// Simple byte buffer for marshaling data.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
type grower interface {
|
||||
Grow(n int)
|
||||
}
|
||||
|
||||
type truncater interface {
|
||||
Truncate(n int)
|
||||
Reset()
|
||||
}
|
||||
|
||||
type bytesReader interface {
|
||||
Bytes() []byte
|
||||
String() string
|
||||
}
|
||||
|
||||
type runeWriter interface {
|
||||
WriteRune(r rune) (n int, err error)
|
||||
}
|
||||
|
||||
type stringWriter interface {
|
||||
WriteString(s string) (n int, err error)
|
||||
}
|
||||
|
||||
type lener interface {
|
||||
Len() int
|
||||
}
|
||||
|
||||
type rewinder interface {
|
||||
Rewind(n int) (err error)
|
||||
}
|
||||
|
||||
type encoder interface {
|
||||
Encode(interface{}) error
|
||||
}
|
||||
|
||||
// TODO(pquerna): continue to reduce these interfaces
|
||||
|
||||
type EncodingBuffer interface {
|
||||
io.Writer
|
||||
io.WriterTo
|
||||
io.ByteWriter
|
||||
stringWriter
|
||||
truncater
|
||||
grower
|
||||
rewinder
|
||||
encoder
|
||||
}
|
||||
|
||||
type DecodingBuffer interface {
|
||||
io.ReadWriter
|
||||
io.ByteWriter
|
||||
stringWriter
|
||||
runeWriter
|
||||
truncater
|
||||
grower
|
||||
bytesReader
|
||||
lener
|
||||
}
|
||||
|
||||
// A Buffer is a variable-sized buffer of bytes with Read and Write methods.
|
||||
// The zero value for Buffer is an empty buffer ready to use.
|
||||
type Buffer struct {
|
||||
buf []byte // contents are the bytes buf[off : len(buf)]
|
||||
off int // read at &buf[off], write at &buf[len(buf)]
|
||||
runeBytes [utf8.UTFMax]byte // avoid allocation of slice on each WriteByte or Rune
|
||||
encoder *json.Encoder
|
||||
}
|
||||
|
||||
// ErrTooLarge is passed to panic if memory cannot be allocated to store data in a buffer.
|
||||
var ErrTooLarge = errors.New("fflib.v1.Buffer: too large")
|
||||
|
||||
// Bytes returns a slice of the contents of the unread portion of the buffer;
|
||||
// len(b.Bytes()) == b.Len(). If the caller changes the contents of the
|
||||
// returned slice, the contents of the buffer will change provided there
|
||||
// are no intervening method calls on the Buffer.
|
||||
func (b *Buffer) Bytes() []byte { return b.buf[b.off:] }
|
||||
|
||||
// String returns the contents of the unread portion of the buffer
|
||||
// as a string. If the Buffer is a nil pointer, it returns "<nil>".
|
||||
func (b *Buffer) String() string {
|
||||
if b == nil {
|
||||
// Special case, useful in debugging.
|
||||
return "<nil>"
|
||||
}
|
||||
return string(b.buf[b.off:])
|
||||
}
|
||||
|
||||
// Len returns the number of bytes of the unread portion of the buffer;
|
||||
// b.Len() == len(b.Bytes()).
|
||||
func (b *Buffer) Len() int { return len(b.buf) - b.off }
|
||||
|
||||
// Truncate discards all but the first n unread bytes from the buffer.
|
||||
// It panics if n is negative or greater than the length of the buffer.
|
||||
func (b *Buffer) Truncate(n int) {
|
||||
if n == 0 {
|
||||
b.off = 0
|
||||
b.buf = b.buf[0:0]
|
||||
} else {
|
||||
b.buf = b.buf[0 : b.off+n]
|
||||
}
|
||||
}
|
||||
|
||||
// Reset resets the buffer so it has no content.
|
||||
// b.Reset() is the same as b.Truncate(0).
|
||||
func (b *Buffer) Reset() { b.Truncate(0) }
|
||||
|
||||
// grow grows the buffer to guarantee space for n more bytes.
|
||||
// It returns the index where bytes should be written.
|
||||
// If the buffer can't grow it will panic with ErrTooLarge.
|
||||
func (b *Buffer) grow(n int) int {
|
||||
// If we have no buffer, get one from the pool
|
||||
m := b.Len()
|
||||
if m == 0 {
|
||||
if b.buf == nil {
|
||||
b.buf = makeSlice(2 * n)
|
||||
b.off = 0
|
||||
} else if b.off != 0 {
|
||||
// If buffer is empty, reset to recover space.
|
||||
b.Truncate(0)
|
||||
}
|
||||
}
|
||||
if len(b.buf)+n > cap(b.buf) {
|
||||
var buf []byte
|
||||
if m+n <= cap(b.buf)/2 {
|
||||
// We can slide things down instead of allocating a new
|
||||
// slice. We only need m+n <= cap(b.buf) to slide, but
|
||||
// we instead let capacity get twice as large so we
|
||||
// don't spend all our time copying.
|
||||
copy(b.buf[:], b.buf[b.off:])
|
||||
buf = b.buf[:m]
|
||||
} else {
|
||||
// not enough space anywhere
|
||||
buf = makeSlice(2*cap(b.buf) + n)
|
||||
copy(buf, b.buf[b.off:])
|
||||
}
|
||||
Pool(b.buf)
|
||||
b.buf = buf
|
||||
b.off = 0
|
||||
}
|
||||
b.buf = b.buf[0 : b.off+m+n]
|
||||
return b.off + m
|
||||
}
|
||||
|
||||
// Grow grows the buffer's capacity, if necessary, to guarantee space for
|
||||
// another n bytes. After Grow(n), at least n bytes can be written to the
|
||||
// buffer without another allocation.
|
||||
// If n is negative, Grow will panic.
|
||||
// If the buffer can't grow it will panic with ErrTooLarge.
|
||||
func (b *Buffer) Grow(n int) {
|
||||
if n < 0 {
|
||||
panic("bytes.Buffer.Grow: negative count")
|
||||
}
|
||||
m := b.grow(n)
|
||||
b.buf = b.buf[0:m]
|
||||
}
|
||||
|
||||
// Write appends the contents of p to the buffer, growing the buffer as
|
||||
// needed. The return value n is the length of p; err is always nil. If the
|
||||
// buffer becomes too large, Write will panic with ErrTooLarge.
|
||||
func (b *Buffer) Write(p []byte) (n int, err error) {
|
||||
m := b.grow(len(p))
|
||||
return copy(b.buf[m:], p), nil
|
||||
}
|
||||
|
||||
// WriteString appends the contents of s to the buffer, growing the buffer as
|
||||
// needed. The return value n is the length of s; err is always nil. If the
|
||||
// buffer becomes too large, WriteString will panic with ErrTooLarge.
|
||||
func (b *Buffer) WriteString(s string) (n int, err error) {
|
||||
m := b.grow(len(s))
|
||||
return copy(b.buf[m:], s), nil
|
||||
}
|
||||
|
||||
// MinRead is the minimum slice size passed to a Read call by
|
||||
// Buffer.ReadFrom. As long as the Buffer has at least MinRead bytes beyond
|
||||
// what is required to hold the contents of r, ReadFrom will not grow the
|
||||
// underlying buffer.
|
||||
const minRead = 512
|
||||
|
||||
// ReadFrom reads data from r until EOF and appends it to the buffer, growing
|
||||
// the buffer as needed. The return value n is the number of bytes read. Any
|
||||
// error except io.EOF encountered during the read is also returned. If the
|
||||
// buffer becomes too large, ReadFrom will panic with ErrTooLarge.
|
||||
func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
// If buffer is empty, reset to recover space.
|
||||
if b.off >= len(b.buf) {
|
||||
b.Truncate(0)
|
||||
}
|
||||
for {
|
||||
if free := cap(b.buf) - len(b.buf); free < minRead {
|
||||
// not enough space at end
|
||||
newBuf := b.buf
|
||||
if b.off+free < minRead {
|
||||
// not enough space using beginning of buffer;
|
||||
// double buffer capacity
|
||||
newBuf = makeSlice(2*cap(b.buf) + minRead)
|
||||
}
|
||||
copy(newBuf, b.buf[b.off:])
|
||||
Pool(b.buf)
|
||||
b.buf = newBuf[:len(b.buf)-b.off]
|
||||
b.off = 0
|
||||
}
|
||||
m, e := r.Read(b.buf[len(b.buf):cap(b.buf)])
|
||||
b.buf = b.buf[0 : len(b.buf)+m]
|
||||
n += int64(m)
|
||||
if e == io.EOF {
|
||||
break
|
||||
}
|
||||
if e != nil {
|
||||
return n, e
|
||||
}
|
||||
}
|
||||
return n, nil // err is EOF, so return nil explicitly
|
||||
}
|
||||
|
||||
// WriteTo writes data to w until the buffer is drained or an error occurs.
|
||||
// The return value n is the number of bytes written; it always fits into an
|
||||
// int, but it is int64 to match the io.WriterTo interface. Any error
|
||||
// encountered during the write is also returned.
|
||||
func (b *Buffer) WriteTo(w io.Writer) (n int64, err error) {
|
||||
if b.off < len(b.buf) {
|
||||
nBytes := b.Len()
|
||||
m, e := w.Write(b.buf[b.off:])
|
||||
if m > nBytes {
|
||||
panic("bytes.Buffer.WriteTo: invalid Write count")
|
||||
}
|
||||
b.off += m
|
||||
n = int64(m)
|
||||
if e != nil {
|
||||
return n, e
|
||||
}
|
||||
// all bytes should have been written, by definition of
|
||||
// Write method in io.Writer
|
||||
if m != nBytes {
|
||||
return n, io.ErrShortWrite
|
||||
}
|
||||
}
|
||||
// Buffer is now empty; reset.
|
||||
b.Truncate(0)
|
||||
return
|
||||
}
|
||||
|
||||
// WriteByte appends the byte c to the buffer, growing the buffer as needed.
|
||||
// The returned error is always nil, but is included to match bufio.Writer's
|
||||
// WriteByte. If the buffer becomes too large, WriteByte will panic with
|
||||
// ErrTooLarge.
|
||||
func (b *Buffer) WriteByte(c byte) error {
|
||||
m := b.grow(1)
|
||||
b.buf[m] = c
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Buffer) Rewind(n int) error {
|
||||
b.buf = b.buf[:len(b.buf)-n]
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Buffer) Encode(v interface{}) error {
|
||||
if b.encoder == nil {
|
||||
b.encoder = json.NewEncoder(b)
|
||||
}
|
||||
return b.encoder.Encode(v)
|
||||
}
|
||||
|
||||
// WriteRune appends the UTF-8 encoding of Unicode code point r to the
|
||||
// buffer, returning its length and an error, which is always nil but is
|
||||
// included to match bufio.Writer's WriteRune. The buffer is grown as needed;
|
||||
// if it becomes too large, WriteRune will panic with ErrTooLarge.
|
||||
func (b *Buffer) WriteRune(r rune) (n int, err error) {
|
||||
if r < utf8.RuneSelf {
|
||||
b.WriteByte(byte(r))
|
||||
return 1, nil
|
||||
}
|
||||
n = utf8.EncodeRune(b.runeBytes[0:], r)
|
||||
b.Write(b.runeBytes[0:n])
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// Read reads the next len(p) bytes from the buffer or until the buffer
|
||||
// is drained. The return value n is the number of bytes read. If the
|
||||
// buffer has no data to return, err is io.EOF (unless len(p) is zero);
|
||||
// otherwise it is nil.
|
||||
func (b *Buffer) Read(p []byte) (n int, err error) {
|
||||
if b.off >= len(b.buf) {
|
||||
// Buffer is empty, reset to recover space.
|
||||
b.Truncate(0)
|
||||
if len(p) == 0 {
|
||||
return
|
||||
}
|
||||
return 0, io.EOF
|
||||
}
|
||||
n = copy(p, b.buf[b.off:])
|
||||
b.off += n
|
||||
return
|
||||
}
|
||||
|
||||
// Next returns a slice containing the next n bytes from the buffer,
|
||||
// advancing the buffer as if the bytes had been returned by Read.
|
||||
// If there are fewer than n bytes in the buffer, Next returns the entire buffer.
|
||||
// The slice is only valid until the next call to a read or write method.
|
||||
func (b *Buffer) Next(n int) []byte {
|
||||
m := b.Len()
|
||||
if n > m {
|
||||
n = m
|
||||
}
|
||||
data := b.buf[b.off : b.off+n]
|
||||
b.off += n
|
||||
return data
|
||||
}
|
||||
|
||||
// ReadByte reads and returns the next byte from the buffer.
|
||||
// If no byte is available, it returns error io.EOF.
|
||||
func (b *Buffer) ReadByte() (c byte, err error) {
|
||||
if b.off >= len(b.buf) {
|
||||
// Buffer is empty, reset to recover space.
|
||||
b.Truncate(0)
|
||||
return 0, io.EOF
|
||||
}
|
||||
c = b.buf[b.off]
|
||||
b.off++
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// ReadRune reads and returns the next UTF-8-encoded
|
||||
// Unicode code point from the buffer.
|
||||
// If no bytes are available, the error returned is io.EOF.
|
||||
// If the bytes are an erroneous UTF-8 encoding, it
|
||||
// consumes one byte and returns U+FFFD, 1.
|
||||
func (b *Buffer) ReadRune() (r rune, size int, err error) {
|
||||
if b.off >= len(b.buf) {
|
||||
// Buffer is empty, reset to recover space.
|
||||
b.Truncate(0)
|
||||
return 0, 0, io.EOF
|
||||
}
|
||||
c := b.buf[b.off]
|
||||
if c < utf8.RuneSelf {
|
||||
b.off++
|
||||
return rune(c), 1, nil
|
||||
}
|
||||
r, n := utf8.DecodeRune(b.buf[b.off:])
|
||||
b.off += n
|
||||
return r, n, nil
|
||||
}
|
||||
|
||||
// ReadBytes reads until the first occurrence of delim in the input,
|
||||
// returning a slice containing the data up to and including the delimiter.
|
||||
// If ReadBytes encounters an error before finding a delimiter,
|
||||
// it returns the data read before the error and the error itself (often io.EOF).
|
||||
// ReadBytes returns err != nil if and only if the returned data does not end in
|
||||
// delim.
|
||||
func (b *Buffer) ReadBytes(delim byte) (line []byte, err error) {
|
||||
slice, err := b.readSlice(delim)
|
||||
// return a copy of slice. The buffer's backing array may
|
||||
// be overwritten by later calls.
|
||||
line = append(line, slice...)
|
||||
return
|
||||
}
|
||||
|
||||
// readSlice is like ReadBytes but returns a reference to internal buffer data.
|
||||
func (b *Buffer) readSlice(delim byte) (line []byte, err error) {
|
||||
i := bytes.IndexByte(b.buf[b.off:], delim)
|
||||
end := b.off + i + 1
|
||||
if i < 0 {
|
||||
end = len(b.buf)
|
||||
err = io.EOF
|
||||
}
|
||||
line = b.buf[b.off:end]
|
||||
b.off = end
|
||||
return line, err
|
||||
}
|
||||
|
||||
// ReadString reads until the first occurrence of delim in the input,
|
||||
// returning a string containing the data up to and including the delimiter.
|
||||
// If ReadString encounters an error before finding a delimiter,
|
||||
// it returns the data read before the error and the error itself (often io.EOF).
|
||||
// ReadString returns err != nil if and only if the returned data does not end
|
||||
// in delim.
|
||||
func (b *Buffer) ReadString(delim byte) (line string, err error) {
|
||||
slice, err := b.readSlice(delim)
|
||||
return string(slice), err
|
||||
}
|
||||
|
||||
// NewBuffer creates and initializes a new Buffer using buf as its initial
|
||||
// contents. It is intended to prepare a Buffer to read existing data. It
|
||||
// can also be used to size the internal buffer for writing. To do that,
|
||||
// buf should have the desired capacity but a length of zero.
|
||||
//
|
||||
// In most cases, new(Buffer) (or just declaring a Buffer variable) is
|
||||
// sufficient to initialize a Buffer.
|
||||
func NewBuffer(buf []byte) *Buffer { return &Buffer{buf: buf} }
|
||||
|
||||
// NewBufferString creates and initializes a new Buffer using string s as its
|
||||
// initial contents. It is intended to prepare a buffer to read an existing
|
||||
// string.
|
||||
//
|
||||
// In most cases, new(Buffer) (or just declaring a Buffer variable) is
|
||||
// sufficient to initialize a Buffer.
|
||||
func NewBufferString(s string) *Buffer {
|
||||
return &Buffer{buf: []byte(s)}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
// +build !go1.3
|
||||
|
||||
package v1
|
||||
|
||||
// Stub version of buffer_pool.go for Go 1.2, which doesn't have sync.Pool.
|
||||
|
||||
func Pool(b []byte) {}
|
||||
|
||||
func makeSlice(n int) []byte {
|
||||
return make([]byte, n)
|
||||
}
|
|
@ -1,105 +0,0 @@
|
|||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.3
|
||||
|
||||
package v1
|
||||
|
||||
// Allocation pools for Buffers.
|
||||
|
||||
import "sync"
|
||||
|
||||
var pools [14]sync.Pool
|
||||
var pool64 *sync.Pool
|
||||
|
||||
func init() {
|
||||
var i uint
|
||||
// TODO(pquerna): add science here around actual pool sizes.
|
||||
for i = 6; i < 20; i++ {
|
||||
n := 1 << i
|
||||
pools[poolNum(n)].New = func() interface{} { return make([]byte, 0, n) }
|
||||
}
|
||||
pool64 = &pools[0]
|
||||
}
|
||||
|
||||
// This returns the pool number that will give a buffer of
|
||||
// at least 'i' bytes.
|
||||
func poolNum(i int) int {
|
||||
// TODO(pquerna): convert to log2 w/ bsr asm instruction:
|
||||
// <https://groups.google.com/forum/#!topic/golang-nuts/uAb5J1_y7ns>
|
||||
if i <= 64 {
|
||||
return 0
|
||||
} else if i <= 128 {
|
||||
return 1
|
||||
} else if i <= 256 {
|
||||
return 2
|
||||
} else if i <= 512 {
|
||||
return 3
|
||||
} else if i <= 1024 {
|
||||
return 4
|
||||
} else if i <= 2048 {
|
||||
return 5
|
||||
} else if i <= 4096 {
|
||||
return 6
|
||||
} else if i <= 8192 {
|
||||
return 7
|
||||
} else if i <= 16384 {
|
||||
return 8
|
||||
} else if i <= 32768 {
|
||||
return 9
|
||||
} else if i <= 65536 {
|
||||
return 10
|
||||
} else if i <= 131072 {
|
||||
return 11
|
||||
} else if i <= 262144 {
|
||||
return 12
|
||||
} else if i <= 524288 {
|
||||
return 13
|
||||
} else {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
// Send a buffer to the Pool to reuse for other instances.
|
||||
// You may no longer utilize the content of the buffer, since it may be used
|
||||
// by other goroutines.
|
||||
func Pool(b []byte) {
|
||||
if b == nil {
|
||||
return
|
||||
}
|
||||
c := cap(b)
|
||||
|
||||
// Our smallest buffer is 64 bytes, so we discard smaller buffers.
|
||||
if c < 64 {
|
||||
return
|
||||
}
|
||||
|
||||
// We need to put the incoming buffer into the NEXT buffer,
|
||||
// since a buffer guarantees AT LEAST the number of bytes available
|
||||
// that is the top of this buffer.
|
||||
// That is the reason for dividing the cap by 2, so it gets into the NEXT bucket.
|
||||
// We add 2 to avoid rounding down if size is exactly power of 2.
|
||||
pn := poolNum((c + 2) >> 1)
|
||||
if pn != -1 {
|
||||
pools[pn].Put(b[0:0])
|
||||
}
|
||||
// if we didn't have a slot for this []byte, we just drop it and let the GC
|
||||
// take care of it.
|
||||
}
|
||||
|
||||
// makeSlice allocates a slice of size n -- it will attempt to use a pool'ed
|
||||
// instance whenever possible.
|
||||
func makeSlice(n int) []byte {
|
||||
if n <= 64 {
|
||||
return pool64.Get().([]byte)[0:n]
|
||||
}
|
||||
|
||||
pn := poolNum(n)
|
||||
|
||||
if pn != -1 {
|
||||
return pools[pn].Get().([]byte)[0:n]
|
||||
} else {
|
||||
return make([]byte, n)
|
||||
}
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
/**
|
||||
* Copyright 2014 Paul Querna
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Portions of this file are on Go stdlib's strconv/iota.go */
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/pquerna/ffjson/fflib/v1/internal"
|
||||
)
|
||||
|
||||
func ParseFloat(s []byte, bitSize int) (f float64, err error) {
|
||||
return internal.ParseFloat(s, bitSize)
|
||||
}
|
||||
|
||||
// ParseUint is like ParseInt but for unsigned numbers, and oeprating on []byte
|
||||
func ParseUint(s []byte, base int, bitSize int) (n uint64, err error) {
|
||||
if len(s) == 1 {
|
||||
switch s[0] {
|
||||
case '0':
|
||||
return 0, nil
|
||||
case '1':
|
||||
return 1, nil
|
||||
case '2':
|
||||
return 2, nil
|
||||
case '3':
|
||||
return 3, nil
|
||||
case '4':
|
||||
return 4, nil
|
||||
case '5':
|
||||
return 5, nil
|
||||
case '6':
|
||||
return 6, nil
|
||||
case '7':
|
||||
return 7, nil
|
||||
case '8':
|
||||
return 8, nil
|
||||
case '9':
|
||||
return 9, nil
|
||||
}
|
||||
}
|
||||
return internal.ParseUint(s, base, bitSize)
|
||||
}
|
||||
|
||||
func ParseInt(s []byte, base int, bitSize int) (i int64, err error) {
|
||||
if len(s) == 1 {
|
||||
switch s[0] {
|
||||
case '0':
|
||||
return 0, nil
|
||||
case '1':
|
||||
return 1, nil
|
||||
case '2':
|
||||
return 2, nil
|
||||
case '3':
|
||||
return 3, nil
|
||||
case '4':
|
||||
return 4, nil
|
||||
case '5':
|
||||
return 5, nil
|
||||
case '6':
|
||||
return 6, nil
|
||||
case '7':
|
||||
return 7, nil
|
||||
case '8':
|
||||
return 8, nil
|
||||
case '9':
|
||||
return 9, nil
|
||||
}
|
||||
}
|
||||
return internal.ParseInt(s, base, bitSize)
|
||||
}
|
|
@ -1,378 +0,0 @@
|
|||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Multiprecision decimal numbers.
|
||||
// For floating-point formatting only; not general purpose.
|
||||
// Only operations are assign and (binary) left/right shift.
|
||||
// Can do binary floating point in multiprecision decimal precisely
|
||||
// because 2 divides 10; cannot do decimal floating point
|
||||
// in multiprecision binary precisely.
|
||||
|
||||
package v1
|
||||
|
||||
type decimal struct {
|
||||
d [800]byte // digits
|
||||
nd int // number of digits used
|
||||
dp int // decimal point
|
||||
neg bool
|
||||
trunc bool // discarded nonzero digits beyond d[:nd]
|
||||
}
|
||||
|
||||
func (a *decimal) String() string {
|
||||
n := 10 + a.nd
|
||||
if a.dp > 0 {
|
||||
n += a.dp
|
||||
}
|
||||
if a.dp < 0 {
|
||||
n += -a.dp
|
||||
}
|
||||
|
||||
buf := make([]byte, n)
|
||||
w := 0
|
||||
switch {
|
||||
case a.nd == 0:
|
||||
return "0"
|
||||
|
||||
case a.dp <= 0:
|
||||
// zeros fill space between decimal point and digits
|
||||
buf[w] = '0'
|
||||
w++
|
||||
buf[w] = '.'
|
||||
w++
|
||||
w += digitZero(buf[w : w+-a.dp])
|
||||
w += copy(buf[w:], a.d[0:a.nd])
|
||||
|
||||
case a.dp < a.nd:
|
||||
// decimal point in middle of digits
|
||||
w += copy(buf[w:], a.d[0:a.dp])
|
||||
buf[w] = '.'
|
||||
w++
|
||||
w += copy(buf[w:], a.d[a.dp:a.nd])
|
||||
|
||||
default:
|
||||
// zeros fill space between digits and decimal point
|
||||
w += copy(buf[w:], a.d[0:a.nd])
|
||||
w += digitZero(buf[w : w+a.dp-a.nd])
|
||||
}
|
||||
return string(buf[0:w])
|
||||
}
|
||||
|
||||
func digitZero(dst []byte) int {
|
||||
for i := range dst {
|
||||
dst[i] = '0'
|
||||
}
|
||||
return len(dst)
|
||||
}
|
||||
|
||||
// trim trailing zeros from number.
|
||||
// (They are meaningless; the decimal point is tracked
|
||||
// independent of the number of digits.)
|
||||
func trim(a *decimal) {
|
||||
for a.nd > 0 && a.d[a.nd-1] == '0' {
|
||||
a.nd--
|
||||
}
|
||||
if a.nd == 0 {
|
||||
a.dp = 0
|
||||
}
|
||||
}
|
||||
|
||||
// Assign v to a.
|
||||
func (a *decimal) Assign(v uint64) {
|
||||
var buf [24]byte
|
||||
|
||||
// Write reversed decimal in buf.
|
||||
n := 0
|
||||
for v > 0 {
|
||||
v1 := v / 10
|
||||
v -= 10 * v1
|
||||
buf[n] = byte(v + '0')
|
||||
n++
|
||||
v = v1
|
||||
}
|
||||
|
||||
// Reverse again to produce forward decimal in a.d.
|
||||
a.nd = 0
|
||||
for n--; n >= 0; n-- {
|
||||
a.d[a.nd] = buf[n]
|
||||
a.nd++
|
||||
}
|
||||
a.dp = a.nd
|
||||
trim(a)
|
||||
}
|
||||
|
||||
// Maximum shift that we can do in one pass without overflow.
|
||||
// Signed int has 31 bits, and we have to be able to accommodate 9<<k.
|
||||
const maxShift = 27
|
||||
|
||||
// Binary shift right (* 2) by k bits. k <= maxShift to avoid overflow.
|
||||
func rightShift(a *decimal, k uint) {
|
||||
r := 0 // read pointer
|
||||
w := 0 // write pointer
|
||||
|
||||
// Pick up enough leading digits to cover first shift.
|
||||
n := 0
|
||||
for ; n>>k == 0; r++ {
|
||||
if r >= a.nd {
|
||||
if n == 0 {
|
||||
// a == 0; shouldn't get here, but handle anyway.
|
||||
a.nd = 0
|
||||
return
|
||||
}
|
||||
for n>>k == 0 {
|
||||
n = n * 10
|
||||
r++
|
||||
}
|
||||
break
|
||||
}
|
||||
c := int(a.d[r])
|
||||
n = n*10 + c - '0'
|
||||
}
|
||||
a.dp -= r - 1
|
||||
|
||||
// Pick up a digit, put down a digit.
|
||||
for ; r < a.nd; r++ {
|
||||
c := int(a.d[r])
|
||||
dig := n >> k
|
||||
n -= dig << k
|
||||
a.d[w] = byte(dig + '0')
|
||||
w++
|
||||
n = n*10 + c - '0'
|
||||
}
|
||||
|
||||
// Put down extra digits.
|
||||
for n > 0 {
|
||||
dig := n >> k
|
||||
n -= dig << k
|
||||
if w < len(a.d) {
|
||||
a.d[w] = byte(dig + '0')
|
||||
w++
|
||||
} else if dig > 0 {
|
||||
a.trunc = true
|
||||
}
|
||||
n = n * 10
|
||||
}
|
||||
|
||||
a.nd = w
|
||||
trim(a)
|
||||
}
|
||||
|
||||
// Cheat sheet for left shift: table indexed by shift count giving
|
||||
// number of new digits that will be introduced by that shift.
|
||||
//
|
||||
// For example, leftcheats[4] = {2, "625"}. That means that
|
||||
// if we are shifting by 4 (multiplying by 16), it will add 2 digits
|
||||
// when the string prefix is "625" through "999", and one fewer digit
|
||||
// if the string prefix is "000" through "624".
|
||||
//
|
||||
// Credit for this trick goes to Ken.
|
||||
|
||||
type leftCheat struct {
|
||||
delta int // number of new digits
|
||||
cutoff string // minus one digit if original < a.
|
||||
}
|
||||
|
||||
var leftcheats = []leftCheat{
|
||||
// Leading digits of 1/2^i = 5^i.
|
||||
// 5^23 is not an exact 64-bit floating point number,
|
||||
// so have to use bc for the math.
|
||||
/*
|
||||
seq 27 | sed 's/^/5^/' | bc |
|
||||
awk 'BEGIN{ print "\tleftCheat{ 0, \"\" }," }
|
||||
{
|
||||
log2 = log(2)/log(10)
|
||||
printf("\tleftCheat{ %d, \"%s\" },\t// * %d\n",
|
||||
int(log2*NR+1), $0, 2**NR)
|
||||
}'
|
||||
*/
|
||||
{0, ""},
|
||||
{1, "5"}, // * 2
|
||||
{1, "25"}, // * 4
|
||||
{1, "125"}, // * 8
|
||||
{2, "625"}, // * 16
|
||||
{2, "3125"}, // * 32
|
||||
{2, "15625"}, // * 64
|
||||
{3, "78125"}, // * 128
|
||||
{3, "390625"}, // * 256
|
||||
{3, "1953125"}, // * 512
|
||||
{4, "9765625"}, // * 1024
|
||||
{4, "48828125"}, // * 2048
|
||||
{4, "244140625"}, // * 4096
|
||||
{4, "1220703125"}, // * 8192
|
||||
{5, "6103515625"}, // * 16384
|
||||
{5, "30517578125"}, // * 32768
|
||||
{5, "152587890625"}, // * 65536
|
||||
{6, "762939453125"}, // * 131072
|
||||
{6, "3814697265625"}, // * 262144
|
||||
{6, "19073486328125"}, // * 524288
|
||||
{7, "95367431640625"}, // * 1048576
|
||||
{7, "476837158203125"}, // * 2097152
|
||||
{7, "2384185791015625"}, // * 4194304
|
||||
{7, "11920928955078125"}, // * 8388608
|
||||
{8, "59604644775390625"}, // * 16777216
|
||||
{8, "298023223876953125"}, // * 33554432
|
||||
{8, "1490116119384765625"}, // * 67108864
|
||||
{9, "7450580596923828125"}, // * 134217728
|
||||
}
|
||||
|
||||
// Is the leading prefix of b lexicographically less than s?
|
||||
func prefixIsLessThan(b []byte, s string) bool {
|
||||
for i := 0; i < len(s); i++ {
|
||||
if i >= len(b) {
|
||||
return true
|
||||
}
|
||||
if b[i] != s[i] {
|
||||
return b[i] < s[i]
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Binary shift left (/ 2) by k bits. k <= maxShift to avoid overflow.
|
||||
func leftShift(a *decimal, k uint) {
|
||||
delta := leftcheats[k].delta
|
||||
if prefixIsLessThan(a.d[0:a.nd], leftcheats[k].cutoff) {
|
||||
delta--
|
||||
}
|
||||
|
||||
r := a.nd // read index
|
||||
w := a.nd + delta // write index
|
||||
n := 0
|
||||
|
||||
// Pick up a digit, put down a digit.
|
||||
for r--; r >= 0; r-- {
|
||||
n += (int(a.d[r]) - '0') << k
|
||||
quo := n / 10
|
||||
rem := n - 10*quo
|
||||
w--
|
||||
if w < len(a.d) {
|
||||
a.d[w] = byte(rem + '0')
|
||||
} else if rem != 0 {
|
||||
a.trunc = true
|
||||
}
|
||||
n = quo
|
||||
}
|
||||
|
||||
// Put down extra digits.
|
||||
for n > 0 {
|
||||
quo := n / 10
|
||||
rem := n - 10*quo
|
||||
w--
|
||||
if w < len(a.d) {
|
||||
a.d[w] = byte(rem + '0')
|
||||
} else if rem != 0 {
|
||||
a.trunc = true
|
||||
}
|
||||
n = quo
|
||||
}
|
||||
|
||||
a.nd += delta
|
||||
if a.nd >= len(a.d) {
|
||||
a.nd = len(a.d)
|
||||
}
|
||||
a.dp += delta
|
||||
trim(a)
|
||||
}
|
||||
|
||||
// Binary shift left (k > 0) or right (k < 0).
|
||||
func (a *decimal) Shift(k int) {
|
||||
switch {
|
||||
case a.nd == 0:
|
||||
// nothing to do: a == 0
|
||||
case k > 0:
|
||||
for k > maxShift {
|
||||
leftShift(a, maxShift)
|
||||
k -= maxShift
|
||||
}
|
||||
leftShift(a, uint(k))
|
||||
case k < 0:
|
||||
for k < -maxShift {
|
||||
rightShift(a, maxShift)
|
||||
k += maxShift
|
||||
}
|
||||
rightShift(a, uint(-k))
|
||||
}
|
||||
}
|
||||
|
||||
// If we chop a at nd digits, should we round up?
|
||||
func shouldRoundUp(a *decimal, nd int) bool {
|
||||
if nd < 0 || nd >= a.nd {
|
||||
return false
|
||||
}
|
||||
if a.d[nd] == '5' && nd+1 == a.nd { // exactly halfway - round to even
|
||||
// if we truncated, a little higher than what's recorded - always round up
|
||||
if a.trunc {
|
||||
return true
|
||||
}
|
||||
return nd > 0 && (a.d[nd-1]-'0')%2 != 0
|
||||
}
|
||||
// not halfway - digit tells all
|
||||
return a.d[nd] >= '5'
|
||||
}
|
||||
|
||||
// Round a to nd digits (or fewer).
|
||||
// If nd is zero, it means we're rounding
|
||||
// just to the left of the digits, as in
|
||||
// 0.09 -> 0.1.
|
||||
func (a *decimal) Round(nd int) {
|
||||
if nd < 0 || nd >= a.nd {
|
||||
return
|
||||
}
|
||||
if shouldRoundUp(a, nd) {
|
||||
a.RoundUp(nd)
|
||||
} else {
|
||||
a.RoundDown(nd)
|
||||
}
|
||||
}
|
||||
|
||||
// Round a down to nd digits (or fewer).
|
||||
func (a *decimal) RoundDown(nd int) {
|
||||
if nd < 0 || nd >= a.nd {
|
||||
return
|
||||
}
|
||||
a.nd = nd
|
||||
trim(a)
|
||||
}
|
||||
|
||||
// Round a up to nd digits (or fewer).
|
||||
func (a *decimal) RoundUp(nd int) {
|
||||
if nd < 0 || nd >= a.nd {
|
||||
return
|
||||
}
|
||||
|
||||
// round up
|
||||
for i := nd - 1; i >= 0; i-- {
|
||||
c := a.d[i]
|
||||
if c < '9' { // can stop after this digit
|
||||
a.d[i]++
|
||||
a.nd = i + 1
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Number is all 9s.
|
||||
// Change to single 1 with adjusted decimal point.
|
||||
a.d[0] = '1'
|
||||
a.nd = 1
|
||||
a.dp++
|
||||
}
|
||||
|
||||
// Extract integer part, rounded appropriately.
|
||||
// No guarantees about overflow.
|
||||
func (a *decimal) RoundedInteger() uint64 {
|
||||
if a.dp > 20 {
|
||||
return 0xFFFFFFFFFFFFFFFF
|
||||
}
|
||||
var i int
|
||||
n := uint64(0)
|
||||
for i = 0; i < a.dp && i < a.nd; i++ {
|
||||
n = n*10 + uint64(a.d[i]-'0')
|
||||
}
|
||||
for ; i < a.dp; i++ {
|
||||
n *= 10
|
||||
}
|
||||
if shouldRoundUp(a, a.dp) {
|
||||
n++
|
||||
}
|
||||
return n
|
||||
}
|
|
@ -1,668 +0,0 @@
|
|||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package v1
|
||||
|
||||
// An extFloat represents an extended floating-point number, with more
|
||||
// precision than a float64. It does not try to save bits: the
|
||||
// number represented by the structure is mant*(2^exp), with a negative
|
||||
// sign if neg is true.
|
||||
type extFloat struct {
|
||||
mant uint64
|
||||
exp int
|
||||
neg bool
|
||||
}
|
||||
|
||||
// Powers of ten taken from double-conversion library.
|
||||
// http://code.google.com/p/double-conversion/
|
||||
const (
|
||||
firstPowerOfTen = -348
|
||||
stepPowerOfTen = 8
|
||||
)
|
||||
|
||||
var smallPowersOfTen = [...]extFloat{
|
||||
{1 << 63, -63, false}, // 1
|
||||
{0xa << 60, -60, false}, // 1e1
|
||||
{0x64 << 57, -57, false}, // 1e2
|
||||
{0x3e8 << 54, -54, false}, // 1e3
|
||||
{0x2710 << 50, -50, false}, // 1e4
|
||||
{0x186a0 << 47, -47, false}, // 1e5
|
||||
{0xf4240 << 44, -44, false}, // 1e6
|
||||
{0x989680 << 40, -40, false}, // 1e7
|
||||
}
|
||||
|
||||
var powersOfTen = [...]extFloat{
|
||||
{0xfa8fd5a0081c0288, -1220, false}, // 10^-348
|
||||
{0xbaaee17fa23ebf76, -1193, false}, // 10^-340
|
||||
{0x8b16fb203055ac76, -1166, false}, // 10^-332
|
||||
{0xcf42894a5dce35ea, -1140, false}, // 10^-324
|
||||
{0x9a6bb0aa55653b2d, -1113, false}, // 10^-316
|
||||
{0xe61acf033d1a45df, -1087, false}, // 10^-308
|
||||
{0xab70fe17c79ac6ca, -1060, false}, // 10^-300
|
||||
{0xff77b1fcbebcdc4f, -1034, false}, // 10^-292
|
||||
{0xbe5691ef416bd60c, -1007, false}, // 10^-284
|
||||
{0x8dd01fad907ffc3c, -980, false}, // 10^-276
|
||||
{0xd3515c2831559a83, -954, false}, // 10^-268
|
||||
{0x9d71ac8fada6c9b5, -927, false}, // 10^-260
|
||||
{0xea9c227723ee8bcb, -901, false}, // 10^-252
|
||||
{0xaecc49914078536d, -874, false}, // 10^-244
|
||||
{0x823c12795db6ce57, -847, false}, // 10^-236
|
||||
{0xc21094364dfb5637, -821, false}, // 10^-228
|
||||
{0x9096ea6f3848984f, -794, false}, // 10^-220
|
||||
{0xd77485cb25823ac7, -768, false}, // 10^-212
|
||||
{0xa086cfcd97bf97f4, -741, false}, // 10^-204
|
||||
{0xef340a98172aace5, -715, false}, // 10^-196
|
||||
{0xb23867fb2a35b28e, -688, false}, // 10^-188
|
||||
{0x84c8d4dfd2c63f3b, -661, false}, // 10^-180
|
||||
{0xc5dd44271ad3cdba, -635, false}, // 10^-172
|
||||
{0x936b9fcebb25c996, -608, false}, // 10^-164
|
||||
{0xdbac6c247d62a584, -582, false}, // 10^-156
|
||||
{0xa3ab66580d5fdaf6, -555, false}, // 10^-148
|
||||
{0xf3e2f893dec3f126, -529, false}, // 10^-140
|
||||
{0xb5b5ada8aaff80b8, -502, false}, // 10^-132
|
||||
{0x87625f056c7c4a8b, -475, false}, // 10^-124
|
||||
{0xc9bcff6034c13053, -449, false}, // 10^-116
|
||||
{0x964e858c91ba2655, -422, false}, // 10^-108
|
||||
{0xdff9772470297ebd, -396, false}, // 10^-100
|
||||
{0xa6dfbd9fb8e5b88f, -369, false}, // 10^-92
|
||||
{0xf8a95fcf88747d94, -343, false}, // 10^-84
|
||||
{0xb94470938fa89bcf, -316, false}, // 10^-76
|
||||
{0x8a08f0f8bf0f156b, -289, false}, // 10^-68
|
||||
{0xcdb02555653131b6, -263, false}, // 10^-60
|
||||
{0x993fe2c6d07b7fac, -236, false}, // 10^-52
|
||||
{0xe45c10c42a2b3b06, -210, false}, // 10^-44
|
||||
{0xaa242499697392d3, -183, false}, // 10^-36
|
||||
{0xfd87b5f28300ca0e, -157, false}, // 10^-28
|
||||
{0xbce5086492111aeb, -130, false}, // 10^-20
|
||||
{0x8cbccc096f5088cc, -103, false}, // 10^-12
|
||||
{0xd1b71758e219652c, -77, false}, // 10^-4
|
||||
{0x9c40000000000000, -50, false}, // 10^4
|
||||
{0xe8d4a51000000000, -24, false}, // 10^12
|
||||
{0xad78ebc5ac620000, 3, false}, // 10^20
|
||||
{0x813f3978f8940984, 30, false}, // 10^28
|
||||
{0xc097ce7bc90715b3, 56, false}, // 10^36
|
||||
{0x8f7e32ce7bea5c70, 83, false}, // 10^44
|
||||
{0xd5d238a4abe98068, 109, false}, // 10^52
|
||||
{0x9f4f2726179a2245, 136, false}, // 10^60
|
||||
{0xed63a231d4c4fb27, 162, false}, // 10^68
|
||||
{0xb0de65388cc8ada8, 189, false}, // 10^76
|
||||
{0x83c7088e1aab65db, 216, false}, // 10^84
|
||||
{0xc45d1df942711d9a, 242, false}, // 10^92
|
||||
{0x924d692ca61be758, 269, false}, // 10^100
|
||||
{0xda01ee641a708dea, 295, false}, // 10^108
|
||||
{0xa26da3999aef774a, 322, false}, // 10^116
|
||||
{0xf209787bb47d6b85, 348, false}, // 10^124
|
||||
{0xb454e4a179dd1877, 375, false}, // 10^132
|
||||
{0x865b86925b9bc5c2, 402, false}, // 10^140
|
||||
{0xc83553c5c8965d3d, 428, false}, // 10^148
|
||||
{0x952ab45cfa97a0b3, 455, false}, // 10^156
|
||||
{0xde469fbd99a05fe3, 481, false}, // 10^164
|
||||
{0xa59bc234db398c25, 508, false}, // 10^172
|
||||
{0xf6c69a72a3989f5c, 534, false}, // 10^180
|
||||
{0xb7dcbf5354e9bece, 561, false}, // 10^188
|
||||
{0x88fcf317f22241e2, 588, false}, // 10^196
|
||||
{0xcc20ce9bd35c78a5, 614, false}, // 10^204
|
||||
{0x98165af37b2153df, 641, false}, // 10^212
|
||||
{0xe2a0b5dc971f303a, 667, false}, // 10^220
|
||||
{0xa8d9d1535ce3b396, 694, false}, // 10^228
|
||||
{0xfb9b7cd9a4a7443c, 720, false}, // 10^236
|
||||
{0xbb764c4ca7a44410, 747, false}, // 10^244
|
||||
{0x8bab8eefb6409c1a, 774, false}, // 10^252
|
||||
{0xd01fef10a657842c, 800, false}, // 10^260
|
||||
{0x9b10a4e5e9913129, 827, false}, // 10^268
|
||||
{0xe7109bfba19c0c9d, 853, false}, // 10^276
|
||||
{0xac2820d9623bf429, 880, false}, // 10^284
|
||||
{0x80444b5e7aa7cf85, 907, false}, // 10^292
|
||||
{0xbf21e44003acdd2d, 933, false}, // 10^300
|
||||
{0x8e679c2f5e44ff8f, 960, false}, // 10^308
|
||||
{0xd433179d9c8cb841, 986, false}, // 10^316
|
||||
{0x9e19db92b4e31ba9, 1013, false}, // 10^324
|
||||
{0xeb96bf6ebadf77d9, 1039, false}, // 10^332
|
||||
{0xaf87023b9bf0ee6b, 1066, false}, // 10^340
|
||||
}
|
||||
|
||||
// floatBits returns the bits of the float64 that best approximates
|
||||
// the extFloat passed as receiver. Overflow is set to true if
|
||||
// the resulting float64 is ±Inf.
|
||||
func (f *extFloat) floatBits(flt *floatInfo) (bits uint64, overflow bool) {
|
||||
f.Normalize()
|
||||
|
||||
exp := f.exp + 63
|
||||
|
||||
// Exponent too small.
|
||||
if exp < flt.bias+1 {
|
||||
n := flt.bias + 1 - exp
|
||||
f.mant >>= uint(n)
|
||||
exp += n
|
||||
}
|
||||
|
||||
// Extract 1+flt.mantbits bits from the 64-bit mantissa.
|
||||
mant := f.mant >> (63 - flt.mantbits)
|
||||
if f.mant&(1<<(62-flt.mantbits)) != 0 {
|
||||
// Round up.
|
||||
mant += 1
|
||||
}
|
||||
|
||||
// Rounding might have added a bit; shift down.
|
||||
if mant == 2<<flt.mantbits {
|
||||
mant >>= 1
|
||||
exp++
|
||||
}
|
||||
|
||||
// Infinities.
|
||||
if exp-flt.bias >= 1<<flt.expbits-1 {
|
||||
// ±Inf
|
||||
mant = 0
|
||||
exp = 1<<flt.expbits - 1 + flt.bias
|
||||
overflow = true
|
||||
} else if mant&(1<<flt.mantbits) == 0 {
|
||||
// Denormalized?
|
||||
exp = flt.bias
|
||||
}
|
||||
// Assemble bits.
|
||||
bits = mant & (uint64(1)<<flt.mantbits - 1)
|
||||
bits |= uint64((exp-flt.bias)&(1<<flt.expbits-1)) << flt.mantbits
|
||||
if f.neg {
|
||||
bits |= 1 << (flt.mantbits + flt.expbits)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AssignComputeBounds sets f to the floating point value
|
||||
// defined by mant, exp and precision given by flt. It returns
|
||||
// lower, upper such that any number in the closed interval
|
||||
// [lower, upper] is converted back to the same floating point number.
|
||||
func (f *extFloat) AssignComputeBounds(mant uint64, exp int, neg bool, flt *floatInfo) (lower, upper extFloat) {
|
||||
f.mant = mant
|
||||
f.exp = exp - int(flt.mantbits)
|
||||
f.neg = neg
|
||||
if f.exp <= 0 && mant == (mant>>uint(-f.exp))<<uint(-f.exp) {
|
||||
// An exact integer
|
||||
f.mant >>= uint(-f.exp)
|
||||
f.exp = 0
|
||||
return *f, *f
|
||||
}
|
||||
expBiased := exp - flt.bias
|
||||
|
||||
upper = extFloat{mant: 2*f.mant + 1, exp: f.exp - 1, neg: f.neg}
|
||||
if mant != 1<<flt.mantbits || expBiased == 1 {
|
||||
lower = extFloat{mant: 2*f.mant - 1, exp: f.exp - 1, neg: f.neg}
|
||||
} else {
|
||||
lower = extFloat{mant: 4*f.mant - 1, exp: f.exp - 2, neg: f.neg}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Normalize normalizes f so that the highest bit of the mantissa is
|
||||
// set, and returns the number by which the mantissa was left-shifted.
|
||||
func (f *extFloat) Normalize() (shift uint) {
|
||||
mant, exp := f.mant, f.exp
|
||||
if mant == 0 {
|
||||
return 0
|
||||
}
|
||||
if mant>>(64-32) == 0 {
|
||||
mant <<= 32
|
||||
exp -= 32
|
||||
}
|
||||
if mant>>(64-16) == 0 {
|
||||
mant <<= 16
|
||||
exp -= 16
|
||||
}
|
||||
if mant>>(64-8) == 0 {
|
||||
mant <<= 8
|
||||
exp -= 8
|
||||
}
|
||||
if mant>>(64-4) == 0 {
|
||||
mant <<= 4
|
||||
exp -= 4
|
||||
}
|
||||
if mant>>(64-2) == 0 {
|
||||
mant <<= 2
|
||||
exp -= 2
|
||||
}
|
||||
if mant>>(64-1) == 0 {
|
||||
mant <<= 1
|
||||
exp -= 1
|
||||
}
|
||||
shift = uint(f.exp - exp)
|
||||
f.mant, f.exp = mant, exp
|
||||
return
|
||||
}
|
||||
|
||||
// Multiply sets f to the product f*g: the result is correctly rounded,
|
||||
// but not normalized.
|
||||
func (f *extFloat) Multiply(g extFloat) {
|
||||
fhi, flo := f.mant>>32, uint64(uint32(f.mant))
|
||||
ghi, glo := g.mant>>32, uint64(uint32(g.mant))
|
||||
|
||||
// Cross products.
|
||||
cross1 := fhi * glo
|
||||
cross2 := flo * ghi
|
||||
|
||||
// f.mant*g.mant is fhi*ghi << 64 + (cross1+cross2) << 32 + flo*glo
|
||||
f.mant = fhi*ghi + (cross1 >> 32) + (cross2 >> 32)
|
||||
rem := uint64(uint32(cross1)) + uint64(uint32(cross2)) + ((flo * glo) >> 32)
|
||||
// Round up.
|
||||
rem += (1 << 31)
|
||||
|
||||
f.mant += (rem >> 32)
|
||||
f.exp = f.exp + g.exp + 64
|
||||
}
|
||||
|
||||
var uint64pow10 = [...]uint64{
|
||||
1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
|
||||
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
|
||||
}
|
||||
|
||||
// AssignDecimal sets f to an approximate value mantissa*10^exp. It
|
||||
// returns true if the value represented by f is guaranteed to be the
|
||||
// best approximation of d after being rounded to a float64 or
|
||||
// float32 depending on flt.
|
||||
func (f *extFloat) AssignDecimal(mantissa uint64, exp10 int, neg bool, trunc bool, flt *floatInfo) (ok bool) {
|
||||
const uint64digits = 19
|
||||
const errorscale = 8
|
||||
errors := 0 // An upper bound for error, computed in errorscale*ulp.
|
||||
if trunc {
|
||||
// the decimal number was truncated.
|
||||
errors += errorscale / 2
|
||||
}
|
||||
|
||||
f.mant = mantissa
|
||||
f.exp = 0
|
||||
f.neg = neg
|
||||
|
||||
// Multiply by powers of ten.
|
||||
i := (exp10 - firstPowerOfTen) / stepPowerOfTen
|
||||
if exp10 < firstPowerOfTen || i >= len(powersOfTen) {
|
||||
return false
|
||||
}
|
||||
adjExp := (exp10 - firstPowerOfTen) % stepPowerOfTen
|
||||
|
||||
// We multiply by exp%step
|
||||
if adjExp < uint64digits && mantissa < uint64pow10[uint64digits-adjExp] {
|
||||
// We can multiply the mantissa exactly.
|
||||
f.mant *= uint64pow10[adjExp]
|
||||
f.Normalize()
|
||||
} else {
|
||||
f.Normalize()
|
||||
f.Multiply(smallPowersOfTen[adjExp])
|
||||
errors += errorscale / 2
|
||||
}
|
||||
|
||||
// We multiply by 10 to the exp - exp%step.
|
||||
f.Multiply(powersOfTen[i])
|
||||
if errors > 0 {
|
||||
errors += 1
|
||||
}
|
||||
errors += errorscale / 2
|
||||
|
||||
// Normalize
|
||||
shift := f.Normalize()
|
||||
errors <<= shift
|
||||
|
||||
// Now f is a good approximation of the decimal.
|
||||
// Check whether the error is too large: that is, if the mantissa
|
||||
// is perturbated by the error, the resulting float64 will change.
|
||||
// The 64 bits mantissa is 1 + 52 bits for float64 + 11 extra bits.
|
||||
//
|
||||
// In many cases the approximation will be good enough.
|
||||
denormalExp := flt.bias - 63
|
||||
var extrabits uint
|
||||
if f.exp <= denormalExp {
|
||||
// f.mant * 2^f.exp is smaller than 2^(flt.bias+1).
|
||||
extrabits = uint(63 - flt.mantbits + 1 + uint(denormalExp-f.exp))
|
||||
} else {
|
||||
extrabits = uint(63 - flt.mantbits)
|
||||
}
|
||||
|
||||
halfway := uint64(1) << (extrabits - 1)
|
||||
mant_extra := f.mant & (1<<extrabits - 1)
|
||||
|
||||
// Do a signed comparison here! If the error estimate could make
|
||||
// the mantissa round differently for the conversion to double,
|
||||
// then we can't give a definite answer.
|
||||
if int64(halfway)-int64(errors) < int64(mant_extra) &&
|
||||
int64(mant_extra) < int64(halfway)+int64(errors) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Frexp10 is an analogue of math.Frexp for decimal powers. It scales
|
||||
// f by an approximate power of ten 10^-exp, and returns exp10, so
|
||||
// that f*10^exp10 has the same value as the old f, up to an ulp,
|
||||
// as well as the index of 10^-exp in the powersOfTen table.
|
||||
func (f *extFloat) frexp10() (exp10, index int) {
|
||||
// The constants expMin and expMax constrain the final value of the
|
||||
// binary exponent of f. We want a small integral part in the result
|
||||
// because finding digits of an integer requires divisions, whereas
|
||||
// digits of the fractional part can be found by repeatedly multiplying
|
||||
// by 10.
|
||||
const expMin = -60
|
||||
const expMax = -32
|
||||
// Find power of ten such that x * 10^n has a binary exponent
|
||||
// between expMin and expMax.
|
||||
approxExp10 := ((expMin+expMax)/2 - f.exp) * 28 / 93 // log(10)/log(2) is close to 93/28.
|
||||
i := (approxExp10 - firstPowerOfTen) / stepPowerOfTen
|
||||
Loop:
|
||||
for {
|
||||
exp := f.exp + powersOfTen[i].exp + 64
|
||||
switch {
|
||||
case exp < expMin:
|
||||
i++
|
||||
case exp > expMax:
|
||||
i--
|
||||
default:
|
||||
break Loop
|
||||
}
|
||||
}
|
||||
// Apply the desired decimal shift on f. It will have exponent
|
||||
// in the desired range. This is multiplication by 10^-exp10.
|
||||
f.Multiply(powersOfTen[i])
|
||||
|
||||
return -(firstPowerOfTen + i*stepPowerOfTen), i
|
||||
}
|
||||
|
||||
// frexp10Many applies a common shift by a power of ten to a, b, c.
|
||||
func frexp10Many(a, b, c *extFloat) (exp10 int) {
|
||||
exp10, i := c.frexp10()
|
||||
a.Multiply(powersOfTen[i])
|
||||
b.Multiply(powersOfTen[i])
|
||||
return
|
||||
}
|
||||
|
||||
// FixedDecimal stores in d the first n significant digits
|
||||
// of the decimal representation of f. It returns false
|
||||
// if it cannot be sure of the answer.
|
||||
func (f *extFloat) FixedDecimal(d *decimalSlice, n int) bool {
|
||||
if f.mant == 0 {
|
||||
d.nd = 0
|
||||
d.dp = 0
|
||||
d.neg = f.neg
|
||||
return true
|
||||
}
|
||||
if n == 0 {
|
||||
panic("strconv: internal error: extFloat.FixedDecimal called with n == 0")
|
||||
}
|
||||
// Multiply by an appropriate power of ten to have a reasonable
|
||||
// number to process.
|
||||
f.Normalize()
|
||||
exp10, _ := f.frexp10()
|
||||
|
||||
shift := uint(-f.exp)
|
||||
integer := uint32(f.mant >> shift)
|
||||
fraction := f.mant - (uint64(integer) << shift)
|
||||
ε := uint64(1) // ε is the uncertainty we have on the mantissa of f.
|
||||
|
||||
// Write exactly n digits to d.
|
||||
needed := n // how many digits are left to write.
|
||||
integerDigits := 0 // the number of decimal digits of integer.
|
||||
pow10 := uint64(1) // the power of ten by which f was scaled.
|
||||
for i, pow := 0, uint64(1); i < 20; i++ {
|
||||
if pow > uint64(integer) {
|
||||
integerDigits = i
|
||||
break
|
||||
}
|
||||
pow *= 10
|
||||
}
|
||||
rest := integer
|
||||
if integerDigits > needed {
|
||||
// the integral part is already large, trim the last digits.
|
||||
pow10 = uint64pow10[integerDigits-needed]
|
||||
integer /= uint32(pow10)
|
||||
rest -= integer * uint32(pow10)
|
||||
} else {
|
||||
rest = 0
|
||||
}
|
||||
|
||||
// Write the digits of integer: the digits of rest are omitted.
|
||||
var buf [32]byte
|
||||
pos := len(buf)
|
||||
for v := integer; v > 0; {
|
||||
v1 := v / 10
|
||||
v -= 10 * v1
|
||||
pos--
|
||||
buf[pos] = byte(v + '0')
|
||||
v = v1
|
||||
}
|
||||
for i := pos; i < len(buf); i++ {
|
||||
d.d[i-pos] = buf[i]
|
||||
}
|
||||
nd := len(buf) - pos
|
||||
d.nd = nd
|
||||
d.dp = integerDigits + exp10
|
||||
needed -= nd
|
||||
|
||||
if needed > 0 {
|
||||
if rest != 0 || pow10 != 1 {
|
||||
panic("strconv: internal error, rest != 0 but needed > 0")
|
||||
}
|
||||
// Emit digits for the fractional part. Each time, 10*fraction
|
||||
// fits in a uint64 without overflow.
|
||||
for needed > 0 {
|
||||
fraction *= 10
|
||||
ε *= 10 // the uncertainty scales as we multiply by ten.
|
||||
if 2*ε > 1<<shift {
|
||||
// the error is so large it could modify which digit to write, abort.
|
||||
return false
|
||||
}
|
||||
digit := fraction >> shift
|
||||
d.d[nd] = byte(digit + '0')
|
||||
fraction -= digit << shift
|
||||
nd++
|
||||
needed--
|
||||
}
|
||||
d.nd = nd
|
||||
}
|
||||
|
||||
// We have written a truncation of f (a numerator / 10^d.dp). The remaining part
|
||||
// can be interpreted as a small number (< 1) to be added to the last digit of the
|
||||
// numerator.
|
||||
//
|
||||
// If rest > 0, the amount is:
|
||||
// (rest<<shift | fraction) / (pow10 << shift)
|
||||
// fraction being known with a ±ε uncertainty.
|
||||
// The fact that n > 0 guarantees that pow10 << shift does not overflow a uint64.
|
||||
//
|
||||
// If rest = 0, pow10 == 1 and the amount is
|
||||
// fraction / (1 << shift)
|
||||
// fraction being known with a ±ε uncertainty.
|
||||
//
|
||||
// We pass this information to the rounding routine for adjustment.
|
||||
|
||||
ok := adjustLastDigitFixed(d, uint64(rest)<<shift|fraction, pow10, shift, ε)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
// Trim trailing zeros.
|
||||
for i := d.nd - 1; i >= 0; i-- {
|
||||
if d.d[i] != '0' {
|
||||
d.nd = i + 1
|
||||
break
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// adjustLastDigitFixed assumes d contains the representation of the integral part
|
||||
// of some number, whose fractional part is num / (den << shift). The numerator
|
||||
// num is only known up to an uncertainty of size ε, assumed to be less than
|
||||
// (den << shift)/2.
|
||||
//
|
||||
// It will increase the last digit by one to account for correct rounding, typically
|
||||
// when the fractional part is greater than 1/2, and will return false if ε is such
|
||||
// that no correct answer can be given.
|
||||
func adjustLastDigitFixed(d *decimalSlice, num, den uint64, shift uint, ε uint64) bool {
|
||||
if num > den<<shift {
|
||||
panic("strconv: num > den<<shift in adjustLastDigitFixed")
|
||||
}
|
||||
if 2*ε > den<<shift {
|
||||
panic("strconv: ε > (den<<shift)/2")
|
||||
}
|
||||
if 2*(num+ε) < den<<shift {
|
||||
return true
|
||||
}
|
||||
if 2*(num-ε) > den<<shift {
|
||||
// increment d by 1.
|
||||
i := d.nd - 1
|
||||
for ; i >= 0; i-- {
|
||||
if d.d[i] == '9' {
|
||||
d.nd--
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
if i < 0 {
|
||||
d.d[0] = '1'
|
||||
d.nd = 1
|
||||
d.dp++
|
||||
} else {
|
||||
d.d[i]++
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ShortestDecimal stores in d the shortest decimal representation of f
|
||||
// which belongs to the open interval (lower, upper), where f is supposed
|
||||
// to lie. It returns false whenever the result is unsure. The implementation
|
||||
// uses the Grisu3 algorithm.
|
||||
func (f *extFloat) ShortestDecimal(d *decimalSlice, lower, upper *extFloat) bool {
|
||||
if f.mant == 0 {
|
||||
d.nd = 0
|
||||
d.dp = 0
|
||||
d.neg = f.neg
|
||||
return true
|
||||
}
|
||||
if f.exp == 0 && *lower == *f && *lower == *upper {
|
||||
// an exact integer.
|
||||
var buf [24]byte
|
||||
n := len(buf) - 1
|
||||
for v := f.mant; v > 0; {
|
||||
v1 := v / 10
|
||||
v -= 10 * v1
|
||||
buf[n] = byte(v + '0')
|
||||
n--
|
||||
v = v1
|
||||
}
|
||||
nd := len(buf) - n - 1
|
||||
for i := 0; i < nd; i++ {
|
||||
d.d[i] = buf[n+1+i]
|
||||
}
|
||||
d.nd, d.dp = nd, nd
|
||||
for d.nd > 0 && d.d[d.nd-1] == '0' {
|
||||
d.nd--
|
||||
}
|
||||
if d.nd == 0 {
|
||||
d.dp = 0
|
||||
}
|
||||
d.neg = f.neg
|
||||
return true
|
||||
}
|
||||
upper.Normalize()
|
||||
// Uniformize exponents.
|
||||
if f.exp > upper.exp {
|
||||
f.mant <<= uint(f.exp - upper.exp)
|
||||
f.exp = upper.exp
|
||||
}
|
||||
if lower.exp > upper.exp {
|
||||
lower.mant <<= uint(lower.exp - upper.exp)
|
||||
lower.exp = upper.exp
|
||||
}
|
||||
|
||||
exp10 := frexp10Many(lower, f, upper)
|
||||
// Take a safety margin due to rounding in frexp10Many, but we lose precision.
|
||||
upper.mant++
|
||||
lower.mant--
|
||||
|
||||
// The shortest representation of f is either rounded up or down, but
|
||||
// in any case, it is a truncation of upper.
|
||||
shift := uint(-upper.exp)
|
||||
integer := uint32(upper.mant >> shift)
|
||||
fraction := upper.mant - (uint64(integer) << shift)
|
||||
|
||||
// How far we can go down from upper until the result is wrong.
|
||||
allowance := upper.mant - lower.mant
|
||||
// How far we should go to get a very precise result.
|
||||
targetDiff := upper.mant - f.mant
|
||||
|
||||
// Count integral digits: there are at most 10.
|
||||
var integerDigits int
|
||||
for i, pow := 0, uint64(1); i < 20; i++ {
|
||||
if pow > uint64(integer) {
|
||||
integerDigits = i
|
||||
break
|
||||
}
|
||||
pow *= 10
|
||||
}
|
||||
for i := 0; i < integerDigits; i++ {
|
||||
pow := uint64pow10[integerDigits-i-1]
|
||||
digit := integer / uint32(pow)
|
||||
d.d[i] = byte(digit + '0')
|
||||
integer -= digit * uint32(pow)
|
||||
// evaluate whether we should stop.
|
||||
if currentDiff := uint64(integer)<<shift + fraction; currentDiff < allowance {
|
||||
d.nd = i + 1
|
||||
d.dp = integerDigits + exp10
|
||||
d.neg = f.neg
|
||||
// Sometimes allowance is so large the last digit might need to be
|
||||
// decremented to get closer to f.
|
||||
return adjustLastDigit(d, currentDiff, targetDiff, allowance, pow<<shift, 2)
|
||||
}
|
||||
}
|
||||
d.nd = integerDigits
|
||||
d.dp = d.nd + exp10
|
||||
d.neg = f.neg
|
||||
|
||||
// Compute digits of the fractional part. At each step fraction does not
|
||||
// overflow. The choice of minExp implies that fraction is less than 2^60.
|
||||
var digit int
|
||||
multiplier := uint64(1)
|
||||
for {
|
||||
fraction *= 10
|
||||
multiplier *= 10
|
||||
digit = int(fraction >> shift)
|
||||
d.d[d.nd] = byte(digit + '0')
|
||||
d.nd++
|
||||
fraction -= uint64(digit) << shift
|
||||
if fraction < allowance*multiplier {
|
||||
// We are in the admissible range. Note that if allowance is about to
|
||||
// overflow, that is, allowance > 2^64/10, the condition is automatically
|
||||
// true due to the limited range of fraction.
|
||||
return adjustLastDigit(d,
|
||||
fraction, targetDiff*multiplier, allowance*multiplier,
|
||||
1<<shift, multiplier*2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// adjustLastDigit modifies d = x-currentDiff*ε, to get closest to
|
||||
// d = x-targetDiff*ε, without becoming smaller than x-maxDiff*ε.
|
||||
// It assumes that a decimal digit is worth ulpDecimal*ε, and that
|
||||
// all data is known with a error estimate of ulpBinary*ε.
|
||||
func adjustLastDigit(d *decimalSlice, currentDiff, targetDiff, maxDiff, ulpDecimal, ulpBinary uint64) bool {
|
||||
if ulpDecimal < 2*ulpBinary {
|
||||
// Approximation is too wide.
|
||||
return false
|
||||
}
|
||||
for currentDiff+ulpDecimal/2+ulpBinary < targetDiff {
|
||||
d.d[d.nd-1]--
|
||||
currentDiff += ulpDecimal
|
||||
}
|
||||
if currentDiff+ulpDecimal <= targetDiff+ulpDecimal/2+ulpBinary {
|
||||
// we have two choices, and don't know what to do.
|
||||
return false
|
||||
}
|
||||
if currentDiff < ulpBinary || currentDiff > maxDiff-ulpBinary {
|
||||
// we went too far
|
||||
return false
|
||||
}
|
||||
if d.nd == 1 && d.d[0] == '0' {
|
||||
// the number has actually reached zero.
|
||||
d.nd = 0
|
||||
d.dp = 0
|
||||
}
|
||||
return true
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
/**
|
||||
* Copyright 2014 Paul Querna
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Portions of this file are on Go stdlib's encoding/json/fold.go */
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
const (
|
||||
caseMask = ^byte(0x20) // Mask to ignore case in ASCII.
|
||||
kelvin = '\u212a'
|
||||
smallLongEss = '\u017f'
|
||||
)
|
||||
|
||||
// equalFoldRight is a specialization of bytes.EqualFold when s is
|
||||
// known to be all ASCII (including punctuation), but contains an 's',
|
||||
// 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t.
|
||||
// See comments on foldFunc.
|
||||
func EqualFoldRight(s, t []byte) bool {
|
||||
for _, sb := range s {
|
||||
if len(t) == 0 {
|
||||
return false
|
||||
}
|
||||
tb := t[0]
|
||||
if tb < utf8.RuneSelf {
|
||||
if sb != tb {
|
||||
sbUpper := sb & caseMask
|
||||
if 'A' <= sbUpper && sbUpper <= 'Z' {
|
||||
if sbUpper != tb&caseMask {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
t = t[1:]
|
||||
continue
|
||||
}
|
||||
// sb is ASCII and t is not. t must be either kelvin
|
||||
// sign or long s; sb must be s, S, k, or K.
|
||||
tr, size := utf8.DecodeRune(t)
|
||||
switch sb {
|
||||
case 's', 'S':
|
||||
if tr != smallLongEss {
|
||||
return false
|
||||
}
|
||||
case 'k', 'K':
|
||||
if tr != kelvin {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
return false
|
||||
}
|
||||
t = t[size:]
|
||||
|
||||
}
|
||||
if len(t) > 0 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// asciiEqualFold is a specialization of bytes.EqualFold for use when
|
||||
// s is all ASCII (but may contain non-letters) and contains no
|
||||
// special-folding letters.
|
||||
// See comments on foldFunc.
|
||||
func AsciiEqualFold(s, t []byte) bool {
|
||||
if len(s) != len(t) {
|
||||
return false
|
||||
}
|
||||
for i, sb := range s {
|
||||
tb := t[i]
|
||||
if sb == tb {
|
||||
continue
|
||||
}
|
||||
if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') {
|
||||
if sb&caseMask != tb&caseMask {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// simpleLetterEqualFold is a specialization of bytes.EqualFold for
|
||||
// use when s is all ASCII letters (no underscores, etc) and also
|
||||
// doesn't contain 'k', 'K', 's', or 'S'.
|
||||
// See comments on foldFunc.
|
||||
func SimpleLetterEqualFold(s, t []byte) bool {
|
||||
if len(s) != len(t) {
|
||||
return false
|
||||
}
|
||||
for i, b := range s {
|
||||
if b&caseMask != t[i]&caseMask {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
|
@ -1,542 +0,0 @@
|
|||
package v1
|
||||
|
||||
/**
|
||||
* Copyright 2015 Paul Querna, Klaus Post
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Most of this file are on Go stdlib's strconv/ftoa.go */
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
import "math"
|
||||
|
||||
// TODO: move elsewhere?
|
||||
type floatInfo struct {
|
||||
mantbits uint
|
||||
expbits uint
|
||||
bias int
|
||||
}
|
||||
|
||||
var optimize = true // can change for testing
|
||||
|
||||
var float32info = floatInfo{23, 8, -127}
|
||||
var float64info = floatInfo{52, 11, -1023}
|
||||
|
||||
// AppendFloat appends the string form of the floating-point number f,
|
||||
// as generated by FormatFloat
|
||||
func AppendFloat(dst EncodingBuffer, val float64, fmt byte, prec, bitSize int) {
|
||||
var bits uint64
|
||||
var flt *floatInfo
|
||||
switch bitSize {
|
||||
case 32:
|
||||
bits = uint64(math.Float32bits(float32(val)))
|
||||
flt = &float32info
|
||||
case 64:
|
||||
bits = math.Float64bits(val)
|
||||
flt = &float64info
|
||||
default:
|
||||
panic("strconv: illegal AppendFloat/FormatFloat bitSize")
|
||||
}
|
||||
|
||||
neg := bits>>(flt.expbits+flt.mantbits) != 0
|
||||
exp := int(bits>>flt.mantbits) & (1<<flt.expbits - 1)
|
||||
mant := bits & (uint64(1)<<flt.mantbits - 1)
|
||||
|
||||
switch exp {
|
||||
case 1<<flt.expbits - 1:
|
||||
// Inf, NaN
|
||||
var s string
|
||||
switch {
|
||||
case mant != 0:
|
||||
s = "NaN"
|
||||
case neg:
|
||||
s = "-Inf"
|
||||
default:
|
||||
s = "+Inf"
|
||||
}
|
||||
dst.WriteString(s)
|
||||
return
|
||||
|
||||
case 0:
|
||||
// denormalized
|
||||
exp++
|
||||
|
||||
default:
|
||||
// add implicit top bit
|
||||
mant |= uint64(1) << flt.mantbits
|
||||
}
|
||||
exp += flt.bias
|
||||
|
||||
// Pick off easy binary format.
|
||||
if fmt == 'b' {
|
||||
fmtB(dst, neg, mant, exp, flt)
|
||||
return
|
||||
}
|
||||
|
||||
if !optimize {
|
||||
bigFtoa(dst, prec, fmt, neg, mant, exp, flt)
|
||||
return
|
||||
}
|
||||
|
||||
var digs decimalSlice
|
||||
ok := false
|
||||
// Negative precision means "only as much as needed to be exact."
|
||||
shortest := prec < 0
|
||||
if shortest {
|
||||
// Try Grisu3 algorithm.
|
||||
f := new(extFloat)
|
||||
lower, upper := f.AssignComputeBounds(mant, exp, neg, flt)
|
||||
var buf [32]byte
|
||||
digs.d = buf[:]
|
||||
ok = f.ShortestDecimal(&digs, &lower, &upper)
|
||||
if !ok {
|
||||
bigFtoa(dst, prec, fmt, neg, mant, exp, flt)
|
||||
return
|
||||
}
|
||||
// Precision for shortest representation mode.
|
||||
switch fmt {
|
||||
case 'e', 'E':
|
||||
prec = max(digs.nd-1, 0)
|
||||
case 'f':
|
||||
prec = max(digs.nd-digs.dp, 0)
|
||||
case 'g', 'G':
|
||||
prec = digs.nd
|
||||
}
|
||||
} else if fmt != 'f' {
|
||||
// Fixed number of digits.
|
||||
digits := prec
|
||||
switch fmt {
|
||||
case 'e', 'E':
|
||||
digits++
|
||||
case 'g', 'G':
|
||||
if prec == 0 {
|
||||
prec = 1
|
||||
}
|
||||
digits = prec
|
||||
}
|
||||
if digits <= 15 {
|
||||
// try fast algorithm when the number of digits is reasonable.
|
||||
var buf [24]byte
|
||||
digs.d = buf[:]
|
||||
f := extFloat{mant, exp - int(flt.mantbits), neg}
|
||||
ok = f.FixedDecimal(&digs, digits)
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
bigFtoa(dst, prec, fmt, neg, mant, exp, flt)
|
||||
return
|
||||
}
|
||||
formatDigits(dst, shortest, neg, digs, prec, fmt)
|
||||
return
|
||||
}
|
||||
|
||||
// bigFtoa uses multiprecision computations to format a float.
|
||||
func bigFtoa(dst EncodingBuffer, prec int, fmt byte, neg bool, mant uint64, exp int, flt *floatInfo) {
|
||||
d := new(decimal)
|
||||
d.Assign(mant)
|
||||
d.Shift(exp - int(flt.mantbits))
|
||||
var digs decimalSlice
|
||||
shortest := prec < 0
|
||||
if shortest {
|
||||
roundShortest(d, mant, exp, flt)
|
||||
digs = decimalSlice{d: d.d[:], nd: d.nd, dp: d.dp}
|
||||
// Precision for shortest representation mode.
|
||||
switch fmt {
|
||||
case 'e', 'E':
|
||||
prec = digs.nd - 1
|
||||
case 'f':
|
||||
prec = max(digs.nd-digs.dp, 0)
|
||||
case 'g', 'G':
|
||||
prec = digs.nd
|
||||
}
|
||||
} else {
|
||||
// Round appropriately.
|
||||
switch fmt {
|
||||
case 'e', 'E':
|
||||
d.Round(prec + 1)
|
||||
case 'f':
|
||||
d.Round(d.dp + prec)
|
||||
case 'g', 'G':
|
||||
if prec == 0 {
|
||||
prec = 1
|
||||
}
|
||||
d.Round(prec)
|
||||
}
|
||||
digs = decimalSlice{d: d.d[:], nd: d.nd, dp: d.dp}
|
||||
}
|
||||
formatDigits(dst, shortest, neg, digs, prec, fmt)
|
||||
return
|
||||
}
|
||||
|
||||
func formatDigits(dst EncodingBuffer, shortest bool, neg bool, digs decimalSlice, prec int, fmt byte) {
|
||||
switch fmt {
|
||||
case 'e', 'E':
|
||||
fmtE(dst, neg, digs, prec, fmt)
|
||||
return
|
||||
case 'f':
|
||||
fmtF(dst, neg, digs, prec)
|
||||
return
|
||||
case 'g', 'G':
|
||||
// trailing fractional zeros in 'e' form will be trimmed.
|
||||
eprec := prec
|
||||
if eprec > digs.nd && digs.nd >= digs.dp {
|
||||
eprec = digs.nd
|
||||
}
|
||||
// %e is used if the exponent from the conversion
|
||||
// is less than -4 or greater than or equal to the precision.
|
||||
// if precision was the shortest possible, use precision 6 for this decision.
|
||||
if shortest {
|
||||
eprec = 6
|
||||
}
|
||||
exp := digs.dp - 1
|
||||
if exp < -4 || exp >= eprec {
|
||||
if prec > digs.nd {
|
||||
prec = digs.nd
|
||||
}
|
||||
fmtE(dst, neg, digs, prec-1, fmt+'e'-'g')
|
||||
return
|
||||
}
|
||||
if prec > digs.dp {
|
||||
prec = digs.nd
|
||||
}
|
||||
fmtF(dst, neg, digs, max(prec-digs.dp, 0))
|
||||
return
|
||||
}
|
||||
|
||||
// unknown format
|
||||
dst.Write([]byte{'%', fmt})
|
||||
return
|
||||
}
|
||||
|
||||
// Round d (= mant * 2^exp) to the shortest number of digits
|
||||
// that will let the original floating point value be precisely
|
||||
// reconstructed. Size is original floating point size (64 or 32).
|
||||
func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) {
|
||||
// If mantissa is zero, the number is zero; stop now.
|
||||
if mant == 0 {
|
||||
d.nd = 0
|
||||
return
|
||||
}
|
||||
|
||||
// Compute upper and lower such that any decimal number
|
||||
// between upper and lower (possibly inclusive)
|
||||
// will round to the original floating point number.
|
||||
|
||||
// We may see at once that the number is already shortest.
|
||||
//
|
||||
// Suppose d is not denormal, so that 2^exp <= d < 10^dp.
|
||||
// The closest shorter number is at least 10^(dp-nd) away.
|
||||
// The lower/upper bounds computed below are at distance
|
||||
// at most 2^(exp-mantbits).
|
||||
//
|
||||
// So the number is already shortest if 10^(dp-nd) > 2^(exp-mantbits),
|
||||
// or equivalently log2(10)*(dp-nd) > exp-mantbits.
|
||||
// It is true if 332/100*(dp-nd) >= exp-mantbits (log2(10) > 3.32).
|
||||
minexp := flt.bias + 1 // minimum possible exponent
|
||||
if exp > minexp && 332*(d.dp-d.nd) >= 100*(exp-int(flt.mantbits)) {
|
||||
// The number is already shortest.
|
||||
return
|
||||
}
|
||||
|
||||
// d = mant << (exp - mantbits)
|
||||
// Next highest floating point number is mant+1 << exp-mantbits.
|
||||
// Our upper bound is halfway between, mant*2+1 << exp-mantbits-1.
|
||||
upper := new(decimal)
|
||||
upper.Assign(mant*2 + 1)
|
||||
upper.Shift(exp - int(flt.mantbits) - 1)
|
||||
|
||||
// d = mant << (exp - mantbits)
|
||||
// Next lowest floating point number is mant-1 << exp-mantbits,
|
||||
// unless mant-1 drops the significant bit and exp is not the minimum exp,
|
||||
// in which case the next lowest is mant*2-1 << exp-mantbits-1.
|
||||
// Either way, call it mantlo << explo-mantbits.
|
||||
// Our lower bound is halfway between, mantlo*2+1 << explo-mantbits-1.
|
||||
var mantlo uint64
|
||||
var explo int
|
||||
if mant > 1<<flt.mantbits || exp == minexp {
|
||||
mantlo = mant - 1
|
||||
explo = exp
|
||||
} else {
|
||||
mantlo = mant*2 - 1
|
||||
explo = exp - 1
|
||||
}
|
||||
lower := new(decimal)
|
||||
lower.Assign(mantlo*2 + 1)
|
||||
lower.Shift(explo - int(flt.mantbits) - 1)
|
||||
|
||||
// The upper and lower bounds are possible outputs only if
|
||||
// the original mantissa is even, so that IEEE round-to-even
|
||||
// would round to the original mantissa and not the neighbors.
|
||||
inclusive := mant%2 == 0
|
||||
|
||||
// Now we can figure out the minimum number of digits required.
|
||||
// Walk along until d has distinguished itself from upper and lower.
|
||||
for i := 0; i < d.nd; i++ {
|
||||
var l, m, u byte // lower, middle, upper digits
|
||||
if i < lower.nd {
|
||||
l = lower.d[i]
|
||||
} else {
|
||||
l = '0'
|
||||
}
|
||||
m = d.d[i]
|
||||
if i < upper.nd {
|
||||
u = upper.d[i]
|
||||
} else {
|
||||
u = '0'
|
||||
}
|
||||
|
||||
// Okay to round down (truncate) if lower has a different digit
|
||||
// or if lower is inclusive and is exactly the result of rounding down.
|
||||
okdown := l != m || (inclusive && l == m && i+1 == lower.nd)
|
||||
|
||||
// Okay to round up if upper has a different digit and
|
||||
// either upper is inclusive or upper is bigger than the result of rounding up.
|
||||
okup := m != u && (inclusive || m+1 < u || i+1 < upper.nd)
|
||||
|
||||
// If it's okay to do either, then round to the nearest one.
|
||||
// If it's okay to do only one, do it.
|
||||
switch {
|
||||
case okdown && okup:
|
||||
d.Round(i + 1)
|
||||
return
|
||||
case okdown:
|
||||
d.RoundDown(i + 1)
|
||||
return
|
||||
case okup:
|
||||
d.RoundUp(i + 1)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type decimalSlice struct {
|
||||
d []byte
|
||||
nd, dp int
|
||||
neg bool
|
||||
}
|
||||
|
||||
// %e: -d.ddddde±dd
|
||||
func fmtE(dst EncodingBuffer, neg bool, d decimalSlice, prec int, fmt byte) {
|
||||
// sign
|
||||
if neg {
|
||||
dst.WriteByte('-')
|
||||
}
|
||||
|
||||
// first digit
|
||||
ch := byte('0')
|
||||
if d.nd != 0 {
|
||||
ch = d.d[0]
|
||||
}
|
||||
dst.WriteByte(ch)
|
||||
|
||||
// .moredigits
|
||||
if prec > 0 {
|
||||
dst.WriteByte('.')
|
||||
i := 1
|
||||
m := min(d.nd, prec+1)
|
||||
if i < m {
|
||||
dst.Write(d.d[i:m])
|
||||
i = m
|
||||
}
|
||||
for i <= prec {
|
||||
dst.WriteByte('0')
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
// e±
|
||||
dst.WriteByte(fmt)
|
||||
exp := d.dp - 1
|
||||
if d.nd == 0 { // special case: 0 has exponent 0
|
||||
exp = 0
|
||||
}
|
||||
if exp < 0 {
|
||||
ch = '-'
|
||||
exp = -exp
|
||||
} else {
|
||||
ch = '+'
|
||||
}
|
||||
dst.WriteByte(ch)
|
||||
|
||||
// dd or ddd
|
||||
switch {
|
||||
case exp < 10:
|
||||
dst.WriteByte('0')
|
||||
dst.WriteByte(byte(exp) + '0')
|
||||
case exp < 100:
|
||||
dst.WriteByte(byte(exp/10) + '0')
|
||||
dst.WriteByte(byte(exp%10) + '0')
|
||||
default:
|
||||
dst.WriteByte(byte(exp/100) + '0')
|
||||
dst.WriteByte(byte(exp/10)%10 + '0')
|
||||
dst.WriteByte(byte(exp%10) + '0')
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// %f: -ddddddd.ddddd
|
||||
func fmtF(dst EncodingBuffer, neg bool, d decimalSlice, prec int) {
|
||||
// sign
|
||||
if neg {
|
||||
dst.WriteByte('-')
|
||||
}
|
||||
|
||||
// integer, padded with zeros as needed.
|
||||
if d.dp > 0 {
|
||||
m := min(d.nd, d.dp)
|
||||
dst.Write(d.d[:m])
|
||||
for ; m < d.dp; m++ {
|
||||
dst.WriteByte('0')
|
||||
}
|
||||
} else {
|
||||
dst.WriteByte('0')
|
||||
}
|
||||
|
||||
// fraction
|
||||
if prec > 0 {
|
||||
dst.WriteByte('.')
|
||||
for i := 0; i < prec; i++ {
|
||||
ch := byte('0')
|
||||
if j := d.dp + i; 0 <= j && j < d.nd {
|
||||
ch = d.d[j]
|
||||
}
|
||||
dst.WriteByte(ch)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// %b: -ddddddddp±ddd
|
||||
func fmtB(dst EncodingBuffer, neg bool, mant uint64, exp int, flt *floatInfo) {
|
||||
// sign
|
||||
if neg {
|
||||
dst.WriteByte('-')
|
||||
}
|
||||
|
||||
// mantissa
|
||||
formatBits(dst, mant, 10, false)
|
||||
|
||||
// p
|
||||
dst.WriteByte('p')
|
||||
|
||||
// ±exponent
|
||||
exp -= int(flt.mantbits)
|
||||
if exp >= 0 {
|
||||
dst.WriteByte('+')
|
||||
}
|
||||
formatBits(dst, uint64(exp), 10, exp < 0)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// formatBits computes the string representation of u in the given base.
|
||||
// If neg is set, u is treated as negative int64 value.
|
||||
func formatBits(dst EncodingBuffer, u uint64, base int, neg bool) {
|
||||
if base < 2 || base > len(digits) {
|
||||
panic("strconv: illegal AppendInt/FormatInt base")
|
||||
}
|
||||
// 2 <= base && base <= len(digits)
|
||||
|
||||
var a [64 + 1]byte // +1 for sign of 64bit value in base 2
|
||||
i := len(a)
|
||||
|
||||
if neg {
|
||||
u = -u
|
||||
}
|
||||
|
||||
// convert bits
|
||||
if base == 10 {
|
||||
// common case: use constants for / because
|
||||
// the compiler can optimize it into a multiply+shift
|
||||
|
||||
if ^uintptr(0)>>32 == 0 {
|
||||
for u > uint64(^uintptr(0)) {
|
||||
q := u / 1e9
|
||||
us := uintptr(u - q*1e9) // us % 1e9 fits into a uintptr
|
||||
for j := 9; j > 0; j-- {
|
||||
i--
|
||||
qs := us / 10
|
||||
a[i] = byte(us - qs*10 + '0')
|
||||
us = qs
|
||||
}
|
||||
u = q
|
||||
}
|
||||
}
|
||||
|
||||
// u guaranteed to fit into a uintptr
|
||||
us := uintptr(u)
|
||||
for us >= 10 {
|
||||
i--
|
||||
q := us / 10
|
||||
a[i] = byte(us - q*10 + '0')
|
||||
us = q
|
||||
}
|
||||
// u < 10
|
||||
i--
|
||||
a[i] = byte(us + '0')
|
||||
|
||||
} else if s := shifts[base]; s > 0 {
|
||||
// base is power of 2: use shifts and masks instead of / and %
|
||||
b := uint64(base)
|
||||
m := uintptr(b) - 1 // == 1<<s - 1
|
||||
for u >= b {
|
||||
i--
|
||||
a[i] = digits[uintptr(u)&m]
|
||||
u >>= s
|
||||
}
|
||||
// u < base
|
||||
i--
|
||||
a[i] = digits[uintptr(u)]
|
||||
|
||||
} else {
|
||||
// general case
|
||||
b := uint64(base)
|
||||
for u >= b {
|
||||
i--
|
||||
q := u / b
|
||||
a[i] = digits[uintptr(u-q*b)]
|
||||
u = q
|
||||
}
|
||||
// u < base
|
||||
i--
|
||||
a[i] = digits[uintptr(u)]
|
||||
}
|
||||
|
||||
// add sign, if any
|
||||
if neg {
|
||||
i--
|
||||
a[i] = '-'
|
||||
}
|
||||
|
||||
dst.Write(a[i:])
|
||||
}
|
|
@ -1,936 +0,0 @@
|
|||
/**
|
||||
* Copyright 2014 Paul Querna
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Portions of this file are on Go stdlib's strconv/atof.go */
|
||||
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package internal
|
||||
|
||||
// decimal to binary floating point conversion.
|
||||
// Algorithm:
|
||||
// 1) Store input in multiprecision decimal.
|
||||
// 2) Multiply/divide decimal by powers of two until in range [0.5, 1)
|
||||
// 3) Multiply by 2^precision and round to get mantissa.
|
||||
|
||||
import "math"
|
||||
|
||||
var optimize = true // can change for testing
|
||||
|
||||
func equalIgnoreCase(s1 []byte, s2 []byte) bool {
|
||||
if len(s1) != len(s2) {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < len(s1); i++ {
|
||||
c1 := s1[i]
|
||||
if 'A' <= c1 && c1 <= 'Z' {
|
||||
c1 += 'a' - 'A'
|
||||
}
|
||||
c2 := s2[i]
|
||||
if 'A' <= c2 && c2 <= 'Z' {
|
||||
c2 += 'a' - 'A'
|
||||
}
|
||||
if c1 != c2 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func special(s []byte) (f float64, ok bool) {
|
||||
if len(s) == 0 {
|
||||
return
|
||||
}
|
||||
switch s[0] {
|
||||
default:
|
||||
return
|
||||
case '+':
|
||||
if equalIgnoreCase(s, []byte("+inf")) || equalIgnoreCase(s, []byte("+infinity")) {
|
||||
return math.Inf(1), true
|
||||
}
|
||||
case '-':
|
||||
if equalIgnoreCase(s, []byte("-inf")) || equalIgnoreCase(s, []byte("-infinity")) {
|
||||
return math.Inf(-1), true
|
||||
}
|
||||
case 'n', 'N':
|
||||
if equalIgnoreCase(s, []byte("nan")) {
|
||||
return math.NaN(), true
|
||||
}
|
||||
case 'i', 'I':
|
||||
if equalIgnoreCase(s, []byte("inf")) || equalIgnoreCase(s, []byte("infinity")) {
|
||||
return math.Inf(1), true
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (b *decimal) set(s []byte) (ok bool) {
|
||||
i := 0
|
||||
b.neg = false
|
||||
b.trunc = false
|
||||
|
||||
// optional sign
|
||||
if i >= len(s) {
|
||||
return
|
||||
}
|
||||
switch {
|
||||
case s[i] == '+':
|
||||
i++
|
||||
case s[i] == '-':
|
||||
b.neg = true
|
||||
i++
|
||||
}
|
||||
|
||||
// digits
|
||||
sawdot := false
|
||||
sawdigits := false
|
||||
for ; i < len(s); i++ {
|
||||
switch {
|
||||
case s[i] == '.':
|
||||
if sawdot {
|
||||
return
|
||||
}
|
||||
sawdot = true
|
||||
b.dp = b.nd
|
||||
continue
|
||||
|
||||
case '0' <= s[i] && s[i] <= '9':
|
||||
sawdigits = true
|
||||
if s[i] == '0' && b.nd == 0 { // ignore leading zeros
|
||||
b.dp--
|
||||
continue
|
||||
}
|
||||
if b.nd < len(b.d) {
|
||||
b.d[b.nd] = s[i]
|
||||
b.nd++
|
||||
} else if s[i] != '0' {
|
||||
b.trunc = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
if !sawdigits {
|
||||
return
|
||||
}
|
||||
if !sawdot {
|
||||
b.dp = b.nd
|
||||
}
|
||||
|
||||
// optional exponent moves decimal point.
|
||||
// if we read a very large, very long number,
|
||||
// just be sure to move the decimal point by
|
||||
// a lot (say, 100000). it doesn't matter if it's
|
||||
// not the exact number.
|
||||
if i < len(s) && (s[i] == 'e' || s[i] == 'E') {
|
||||
i++
|
||||
if i >= len(s) {
|
||||
return
|
||||
}
|
||||
esign := 1
|
||||
if s[i] == '+' {
|
||||
i++
|
||||
} else if s[i] == '-' {
|
||||
i++
|
||||
esign = -1
|
||||
}
|
||||
if i >= len(s) || s[i] < '0' || s[i] > '9' {
|
||||
return
|
||||
}
|
||||
e := 0
|
||||
for ; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
|
||||
if e < 10000 {
|
||||
e = e*10 + int(s[i]) - '0'
|
||||
}
|
||||
}
|
||||
b.dp += e * esign
|
||||
}
|
||||
|
||||
if i != len(s) {
|
||||
return
|
||||
}
|
||||
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
|
||||
// readFloat reads a decimal mantissa and exponent from a float
|
||||
// string representation. It sets ok to false if the number could
|
||||
// not fit return types or is invalid.
|
||||
func readFloat(s []byte) (mantissa uint64, exp int, neg, trunc, ok bool) {
|
||||
const uint64digits = 19
|
||||
i := 0
|
||||
|
||||
// optional sign
|
||||
if i >= len(s) {
|
||||
return
|
||||
}
|
||||
switch {
|
||||
case s[i] == '+':
|
||||
i++
|
||||
case s[i] == '-':
|
||||
neg = true
|
||||
i++
|
||||
}
|
||||
|
||||
// digits
|
||||
sawdot := false
|
||||
sawdigits := false
|
||||
nd := 0
|
||||
ndMant := 0
|
||||
dp := 0
|
||||
for ; i < len(s); i++ {
|
||||
switch c := s[i]; true {
|
||||
case c == '.':
|
||||
if sawdot {
|
||||
return
|
||||
}
|
||||
sawdot = true
|
||||
dp = nd
|
||||
continue
|
||||
|
||||
case '0' <= c && c <= '9':
|
||||
sawdigits = true
|
||||
if c == '0' && nd == 0 { // ignore leading zeros
|
||||
dp--
|
||||
continue
|
||||
}
|
||||
nd++
|
||||
if ndMant < uint64digits {
|
||||
mantissa *= 10
|
||||
mantissa += uint64(c - '0')
|
||||
ndMant++
|
||||
} else if s[i] != '0' {
|
||||
trunc = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
if !sawdigits {
|
||||
return
|
||||
}
|
||||
if !sawdot {
|
||||
dp = nd
|
||||
}
|
||||
|
||||
// optional exponent moves decimal point.
|
||||
// if we read a very large, very long number,
|
||||
// just be sure to move the decimal point by
|
||||
// a lot (say, 100000). it doesn't matter if it's
|
||||
// not the exact number.
|
||||
if i < len(s) && (s[i] == 'e' || s[i] == 'E') {
|
||||
i++
|
||||
if i >= len(s) {
|
||||
return
|
||||
}
|
||||
esign := 1
|
||||
if s[i] == '+' {
|
||||
i++
|
||||
} else if s[i] == '-' {
|
||||
i++
|
||||
esign = -1
|
||||
}
|
||||
if i >= len(s) || s[i] < '0' || s[i] > '9' {
|
||||
return
|
||||
}
|
||||
e := 0
|
||||
for ; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
|
||||
if e < 10000 {
|
||||
e = e*10 + int(s[i]) - '0'
|
||||
}
|
||||
}
|
||||
dp += e * esign
|
||||
}
|
||||
|
||||
if i != len(s) {
|
||||
return
|
||||
}
|
||||
|
||||
exp = dp - ndMant
|
||||
ok = true
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
// decimal power of ten to binary power of two.
|
||||
var powtab = []int{1, 3, 6, 9, 13, 16, 19, 23, 26}
|
||||
|
||||
func (d *decimal) floatBits(flt *floatInfo) (b uint64, overflow bool) {
|
||||
var exp int
|
||||
var mant uint64
|
||||
|
||||
// Zero is always a special case.
|
||||
if d.nd == 0 {
|
||||
mant = 0
|
||||
exp = flt.bias
|
||||
goto out
|
||||
}
|
||||
|
||||
// Obvious overflow/underflow.
|
||||
// These bounds are for 64-bit floats.
|
||||
// Will have to change if we want to support 80-bit floats in the future.
|
||||
if d.dp > 310 {
|
||||
goto overflow
|
||||
}
|
||||
if d.dp < -330 {
|
||||
// zero
|
||||
mant = 0
|
||||
exp = flt.bias
|
||||
goto out
|
||||
}
|
||||
|
||||
// Scale by powers of two until in range [0.5, 1.0)
|
||||
exp = 0
|
||||
for d.dp > 0 {
|
||||
var n int
|
||||
if d.dp >= len(powtab) {
|
||||
n = 27
|
||||
} else {
|
||||
n = powtab[d.dp]
|
||||
}
|
||||
d.Shift(-n)
|
||||
exp += n
|
||||
}
|
||||
for d.dp < 0 || d.dp == 0 && d.d[0] < '5' {
|
||||
var n int
|
||||
if -d.dp >= len(powtab) {
|
||||
n = 27
|
||||
} else {
|
||||
n = powtab[-d.dp]
|
||||
}
|
||||
d.Shift(n)
|
||||
exp -= n
|
||||
}
|
||||
|
||||
// Our range is [0.5,1) but floating point range is [1,2).
|
||||
exp--
|
||||
|
||||
// Minimum representable exponent is flt.bias+1.
|
||||
// If the exponent is smaller, move it up and
|
||||
// adjust d accordingly.
|
||||
if exp < flt.bias+1 {
|
||||
n := flt.bias + 1 - exp
|
||||
d.Shift(-n)
|
||||
exp += n
|
||||
}
|
||||
|
||||
if exp-flt.bias >= 1<<flt.expbits-1 {
|
||||
goto overflow
|
||||
}
|
||||
|
||||
// Extract 1+flt.mantbits bits.
|
||||
d.Shift(int(1 + flt.mantbits))
|
||||
mant = d.RoundedInteger()
|
||||
|
||||
// Rounding might have added a bit; shift down.
|
||||
if mant == 2<<flt.mantbits {
|
||||
mant >>= 1
|
||||
exp++
|
||||
if exp-flt.bias >= 1<<flt.expbits-1 {
|
||||
goto overflow
|
||||
}
|
||||
}
|
||||
|
||||
// Denormalized?
|
||||
if mant&(1<<flt.mantbits) == 0 {
|
||||
exp = flt.bias
|
||||
}
|
||||
goto out
|
||||
|
||||
overflow:
|
||||
// ±Inf
|
||||
mant = 0
|
||||
exp = 1<<flt.expbits - 1 + flt.bias
|
||||
overflow = true
|
||||
|
||||
out:
|
||||
// Assemble bits.
|
||||
bits := mant & (uint64(1)<<flt.mantbits - 1)
|
||||
bits |= uint64((exp-flt.bias)&(1<<flt.expbits-1)) << flt.mantbits
|
||||
if d.neg {
|
||||
bits |= 1 << flt.mantbits << flt.expbits
|
||||
}
|
||||
return bits, overflow
|
||||
}
|
||||
|
||||
// Exact powers of 10.
|
||||
var float64pow10 = []float64{
|
||||
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
|
||||
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
|
||||
1e20, 1e21, 1e22,
|
||||
}
|
||||
var float32pow10 = []float32{1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10}
|
||||
|
||||
// If possible to convert decimal representation to 64-bit float f exactly,
|
||||
// entirely in floating-point math, do so, avoiding the expense of decimalToFloatBits.
|
||||
// Three common cases:
|
||||
// value is exact integer
|
||||
// value is exact integer * exact power of ten
|
||||
// value is exact integer / exact power of ten
|
||||
// These all produce potentially inexact but correctly rounded answers.
|
||||
func atof64exact(mantissa uint64, exp int, neg bool) (f float64, ok bool) {
|
||||
if mantissa>>float64info.mantbits != 0 {
|
||||
return
|
||||
}
|
||||
f = float64(mantissa)
|
||||
if neg {
|
||||
f = -f
|
||||
}
|
||||
switch {
|
||||
case exp == 0:
|
||||
// an integer.
|
||||
return f, true
|
||||
// Exact integers are <= 10^15.
|
||||
// Exact powers of ten are <= 10^22.
|
||||
case exp > 0 && exp <= 15+22: // int * 10^k
|
||||
// If exponent is big but number of digits is not,
|
||||
// can move a few zeros into the integer part.
|
||||
if exp > 22 {
|
||||
f *= float64pow10[exp-22]
|
||||
exp = 22
|
||||
}
|
||||
if f > 1e15 || f < -1e15 {
|
||||
// the exponent was really too large.
|
||||
return
|
||||
}
|
||||
return f * float64pow10[exp], true
|
||||
case exp < 0 && exp >= -22: // int / 10^k
|
||||
return f / float64pow10[-exp], true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// If possible to compute mantissa*10^exp to 32-bit float f exactly,
|
||||
// entirely in floating-point math, do so, avoiding the machinery above.
|
||||
func atof32exact(mantissa uint64, exp int, neg bool) (f float32, ok bool) {
|
||||
if mantissa>>float32info.mantbits != 0 {
|
||||
return
|
||||
}
|
||||
f = float32(mantissa)
|
||||
if neg {
|
||||
f = -f
|
||||
}
|
||||
switch {
|
||||
case exp == 0:
|
||||
return f, true
|
||||
// Exact integers are <= 10^7.
|
||||
// Exact powers of ten are <= 10^10.
|
||||
case exp > 0 && exp <= 7+10: // int * 10^k
|
||||
// If exponent is big but number of digits is not,
|
||||
// can move a few zeros into the integer part.
|
||||
if exp > 10 {
|
||||
f *= float32pow10[exp-10]
|
||||
exp = 10
|
||||
}
|
||||
if f > 1e7 || f < -1e7 {
|
||||
// the exponent was really too large.
|
||||
return
|
||||
}
|
||||
return f * float32pow10[exp], true
|
||||
case exp < 0 && exp >= -10: // int / 10^k
|
||||
return f / float32pow10[-exp], true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
const fnParseFloat = "ParseFloat"
|
||||
|
||||
func atof32(s []byte) (f float32, err error) {
|
||||
if val, ok := special(s); ok {
|
||||
return float32(val), nil
|
||||
}
|
||||
|
||||
if optimize {
|
||||
// Parse mantissa and exponent.
|
||||
mantissa, exp, neg, trunc, ok := readFloat(s)
|
||||
if ok {
|
||||
// Try pure floating-point arithmetic conversion.
|
||||
if !trunc {
|
||||
if f, ok := atof32exact(mantissa, exp, neg); ok {
|
||||
return f, nil
|
||||
}
|
||||
}
|
||||
// Try another fast path.
|
||||
ext := new(extFloat)
|
||||
if ok := ext.AssignDecimal(mantissa, exp, neg, trunc, &float32info); ok {
|
||||
b, ovf := ext.floatBits(&float32info)
|
||||
f = math.Float32frombits(uint32(b))
|
||||
if ovf {
|
||||
err = rangeError(fnParseFloat, string(s))
|
||||
}
|
||||
return f, err
|
||||
}
|
||||
}
|
||||
}
|
||||
var d decimal
|
||||
if !d.set(s) {
|
||||
return 0, syntaxError(fnParseFloat, string(s))
|
||||
}
|
||||
b, ovf := d.floatBits(&float32info)
|
||||
f = math.Float32frombits(uint32(b))
|
||||
if ovf {
|
||||
err = rangeError(fnParseFloat, string(s))
|
||||
}
|
||||
return f, err
|
||||
}
|
||||
|
||||
func atof64(s []byte) (f float64, err error) {
|
||||
if val, ok := special(s); ok {
|
||||
return val, nil
|
||||
}
|
||||
|
||||
if optimize {
|
||||
// Parse mantissa and exponent.
|
||||
mantissa, exp, neg, trunc, ok := readFloat(s)
|
||||
if ok {
|
||||
// Try pure floating-point arithmetic conversion.
|
||||
if !trunc {
|
||||
if f, ok := atof64exact(mantissa, exp, neg); ok {
|
||||
return f, nil
|
||||
}
|
||||
}
|
||||
// Try another fast path.
|
||||
ext := new(extFloat)
|
||||
if ok := ext.AssignDecimal(mantissa, exp, neg, trunc, &float64info); ok {
|
||||
b, ovf := ext.floatBits(&float64info)
|
||||
f = math.Float64frombits(b)
|
||||
if ovf {
|
||||
err = rangeError(fnParseFloat, string(s))
|
||||
}
|
||||
return f, err
|
||||
}
|
||||
}
|
||||
}
|
||||
var d decimal
|
||||
if !d.set(s) {
|
||||
return 0, syntaxError(fnParseFloat, string(s))
|
||||
}
|
||||
b, ovf := d.floatBits(&float64info)
|
||||
f = math.Float64frombits(b)
|
||||
if ovf {
|
||||
err = rangeError(fnParseFloat, string(s))
|
||||
}
|
||||
return f, err
|
||||
}
|
||||
|
||||
// ParseFloat converts the string s to a floating-point number
|
||||
// with the precision specified by bitSize: 32 for float32, or 64 for float64.
|
||||
// When bitSize=32, the result still has type float64, but it will be
|
||||
// convertible to float32 without changing its value.
|
||||
//
|
||||
// If s is well-formed and near a valid floating point number,
|
||||
// ParseFloat returns the nearest floating point number rounded
|
||||
// using IEEE754 unbiased rounding.
|
||||
//
|
||||
// The errors that ParseFloat returns have concrete type *NumError
|
||||
// and include err.Num = s.
|
||||
//
|
||||
// If s is not syntactically well-formed, ParseFloat returns err.Err = ErrSyntax.
|
||||
//
|
||||
// If s is syntactically well-formed but is more than 1/2 ULP
|
||||
// away from the largest floating point number of the given size,
|
||||
// ParseFloat returns f = ±Inf, err.Err = ErrRange.
|
||||
func ParseFloat(s []byte, bitSize int) (f float64, err error) {
|
||||
if bitSize == 32 {
|
||||
f1, err1 := atof32(s)
|
||||
return float64(f1), err1
|
||||
}
|
||||
f1, err1 := atof64(s)
|
||||
return f1, err1
|
||||
}
|
||||
|
||||
// oroginal: strconv/decimal.go, but not exported, and needed for PareFloat.
|
||||
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Multiprecision decimal numbers.
|
||||
// For floating-point formatting only; not general purpose.
|
||||
// Only operations are assign and (binary) left/right shift.
|
||||
// Can do binary floating point in multiprecision decimal precisely
|
||||
// because 2 divides 10; cannot do decimal floating point
|
||||
// in multiprecision binary precisely.
|
||||
|
||||
type decimal struct {
|
||||
d [800]byte // digits
|
||||
nd int // number of digits used
|
||||
dp int // decimal point
|
||||
neg bool
|
||||
trunc bool // discarded nonzero digits beyond d[:nd]
|
||||
}
|
||||
|
||||
func (a *decimal) String() string {
|
||||
n := 10 + a.nd
|
||||
if a.dp > 0 {
|
||||
n += a.dp
|
||||
}
|
||||
if a.dp < 0 {
|
||||
n += -a.dp
|
||||
}
|
||||
|
||||
buf := make([]byte, n)
|
||||
w := 0
|
||||
switch {
|
||||
case a.nd == 0:
|
||||
return "0"
|
||||
|
||||
case a.dp <= 0:
|
||||
// zeros fill space between decimal point and digits
|
||||
buf[w] = '0'
|
||||
w++
|
||||
buf[w] = '.'
|
||||
w++
|
||||
w += digitZero(buf[w : w+-a.dp])
|
||||
w += copy(buf[w:], a.d[0:a.nd])
|
||||
|
||||
case a.dp < a.nd:
|
||||
// decimal point in middle of digits
|
||||
w += copy(buf[w:], a.d[0:a.dp])
|
||||
buf[w] = '.'
|
||||
w++
|
||||
w += copy(buf[w:], a.d[a.dp:a.nd])
|
||||
|
||||
default:
|
||||
// zeros fill space between digits and decimal point
|
||||
w += copy(buf[w:], a.d[0:a.nd])
|
||||
w += digitZero(buf[w : w+a.dp-a.nd])
|
||||
}
|
||||
return string(buf[0:w])
|
||||
}
|
||||
|
||||
func digitZero(dst []byte) int {
|
||||
for i := range dst {
|
||||
dst[i] = '0'
|
||||
}
|
||||
return len(dst)
|
||||
}
|
||||
|
||||
// trim trailing zeros from number.
|
||||
// (They are meaningless; the decimal point is tracked
|
||||
// independent of the number of digits.)
|
||||
func trim(a *decimal) {
|
||||
for a.nd > 0 && a.d[a.nd-1] == '0' {
|
||||
a.nd--
|
||||
}
|
||||
if a.nd == 0 {
|
||||
a.dp = 0
|
||||
}
|
||||
}
|
||||
|
||||
// Assign v to a.
|
||||
func (a *decimal) Assign(v uint64) {
|
||||
var buf [24]byte
|
||||
|
||||
// Write reversed decimal in buf.
|
||||
n := 0
|
||||
for v > 0 {
|
||||
v1 := v / 10
|
||||
v -= 10 * v1
|
||||
buf[n] = byte(v + '0')
|
||||
n++
|
||||
v = v1
|
||||
}
|
||||
|
||||
// Reverse again to produce forward decimal in a.d.
|
||||
a.nd = 0
|
||||
for n--; n >= 0; n-- {
|
||||
a.d[a.nd] = buf[n]
|
||||
a.nd++
|
||||
}
|
||||
a.dp = a.nd
|
||||
trim(a)
|
||||
}
|
||||
|
||||
// Maximum shift that we can do in one pass without overflow.
|
||||
// Signed int has 31 bits, and we have to be able to accommodate 9<<k.
|
||||
const maxShift = 27
|
||||
|
||||
// Binary shift right (* 2) by k bits. k <= maxShift to avoid overflow.
|
||||
func rightShift(a *decimal, k uint) {
|
||||
r := 0 // read pointer
|
||||
w := 0 // write pointer
|
||||
|
||||
// Pick up enough leading digits to cover first shift.
|
||||
n := 0
|
||||
for ; n>>k == 0; r++ {
|
||||
if r >= a.nd {
|
||||
if n == 0 {
|
||||
// a == 0; shouldn't get here, but handle anyway.
|
||||
a.nd = 0
|
||||
return
|
||||
}
|
||||
for n>>k == 0 {
|
||||
n = n * 10
|
||||
r++
|
||||
}
|
||||
break
|
||||
}
|
||||
c := int(a.d[r])
|
||||
n = n*10 + c - '0'
|
||||
}
|
||||
a.dp -= r - 1
|
||||
|
||||
// Pick up a digit, put down a digit.
|
||||
for ; r < a.nd; r++ {
|
||||
c := int(a.d[r])
|
||||
dig := n >> k
|
||||
n -= dig << k
|
||||
a.d[w] = byte(dig + '0')
|
||||
w++
|
||||
n = n*10 + c - '0'
|
||||
}
|
||||
|
||||
// Put down extra digits.
|
||||
for n > 0 {
|
||||
dig := n >> k
|
||||
n -= dig << k
|
||||
if w < len(a.d) {
|
||||
a.d[w] = byte(dig + '0')
|
||||
w++
|
||||
} else if dig > 0 {
|
||||
a.trunc = true
|
||||
}
|
||||
n = n * 10
|
||||
}
|
||||
|
||||
a.nd = w
|
||||
trim(a)
|
||||
}
|
||||
|
||||
// Cheat sheet for left shift: table indexed by shift count giving
|
||||
// number of new digits that will be introduced by that shift.
|
||||
//
|
||||
// For example, leftcheats[4] = {2, "625"}. That means that
|
||||
// if we are shifting by 4 (multiplying by 16), it will add 2 digits
|
||||
// when the string prefix is "625" through "999", and one fewer digit
|
||||
// if the string prefix is "000" through "624".
|
||||
//
|
||||
// Credit for this trick goes to Ken.
|
||||
|
||||
type leftCheat struct {
|
||||
delta int // number of new digits
|
||||
cutoff string // minus one digit if original < a.
|
||||
}
|
||||
|
||||
var leftcheats = []leftCheat{
|
||||
// Leading digits of 1/2^i = 5^i.
|
||||
// 5^23 is not an exact 64-bit floating point number,
|
||||
// so have to use bc for the math.
|
||||
/*
|
||||
seq 27 | sed 's/^/5^/' | bc |
|
||||
awk 'BEGIN{ print "\tleftCheat{ 0, \"\" }," }
|
||||
{
|
||||
log2 = log(2)/log(10)
|
||||
printf("\tleftCheat{ %d, \"%s\" },\t// * %d\n",
|
||||
int(log2*NR+1), $0, 2**NR)
|
||||
}'
|
||||
*/
|
||||
{0, ""},
|
||||
{1, "5"}, // * 2
|
||||
{1, "25"}, // * 4
|
||||
{1, "125"}, // * 8
|
||||
{2, "625"}, // * 16
|
||||
{2, "3125"}, // * 32
|
||||
{2, "15625"}, // * 64
|
||||
{3, "78125"}, // * 128
|
||||
{3, "390625"}, // * 256
|
||||
{3, "1953125"}, // * 512
|
||||
{4, "9765625"}, // * 1024
|
||||
{4, "48828125"}, // * 2048
|
||||
{4, "244140625"}, // * 4096
|
||||
{4, "1220703125"}, // * 8192
|
||||
{5, "6103515625"}, // * 16384
|
||||
{5, "30517578125"}, // * 32768
|
||||
{5, "152587890625"}, // * 65536
|
||||
{6, "762939453125"}, // * 131072
|
||||
{6, "3814697265625"}, // * 262144
|
||||
{6, "19073486328125"}, // * 524288
|
||||
{7, "95367431640625"}, // * 1048576
|
||||
{7, "476837158203125"}, // * 2097152
|
||||
{7, "2384185791015625"}, // * 4194304
|
||||
{7, "11920928955078125"}, // * 8388608
|
||||
{8, "59604644775390625"}, // * 16777216
|
||||
{8, "298023223876953125"}, // * 33554432
|
||||
{8, "1490116119384765625"}, // * 67108864
|
||||
{9, "7450580596923828125"}, // * 134217728
|
||||
}
|
||||
|
||||
// Is the leading prefix of b lexicographically less than s?
|
||||
func prefixIsLessThan(b []byte, s string) bool {
|
||||
for i := 0; i < len(s); i++ {
|
||||
if i >= len(b) {
|
||||
return true
|
||||
}
|
||||
if b[i] != s[i] {
|
||||
return b[i] < s[i]
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Binary shift left (/ 2) by k bits. k <= maxShift to avoid overflow.
|
||||
func leftShift(a *decimal, k uint) {
|
||||
delta := leftcheats[k].delta
|
||||
if prefixIsLessThan(a.d[0:a.nd], leftcheats[k].cutoff) {
|
||||
delta--
|
||||
}
|
||||
|
||||
r := a.nd // read index
|
||||
w := a.nd + delta // write index
|
||||
n := 0
|
||||
|
||||
// Pick up a digit, put down a digit.
|
||||
for r--; r >= 0; r-- {
|
||||
n += (int(a.d[r]) - '0') << k
|
||||
quo := n / 10
|
||||
rem := n - 10*quo
|
||||
w--
|
||||
if w < len(a.d) {
|
||||
a.d[w] = byte(rem + '0')
|
||||
} else if rem != 0 {
|
||||
a.trunc = true
|
||||
}
|
||||
n = quo
|
||||
}
|
||||
|
||||
// Put down extra digits.
|
||||
for n > 0 {
|
||||
quo := n / 10
|
||||
rem := n - 10*quo
|
||||
w--
|
||||
if w < len(a.d) {
|
||||
a.d[w] = byte(rem + '0')
|
||||
} else if rem != 0 {
|
||||
a.trunc = true
|
||||
}
|
||||
n = quo
|
||||
}
|
||||
|
||||
a.nd += delta
|
||||
if a.nd >= len(a.d) {
|
||||
a.nd = len(a.d)
|
||||
}
|
||||
a.dp += delta
|
||||
trim(a)
|
||||
}
|
||||
|
||||
// Binary shift left (k > 0) or right (k < 0).
|
||||
func (a *decimal) Shift(k int) {
|
||||
switch {
|
||||
case a.nd == 0:
|
||||
// nothing to do: a == 0
|
||||
case k > 0:
|
||||
for k > maxShift {
|
||||
leftShift(a, maxShift)
|
||||
k -= maxShift
|
||||
}
|
||||
leftShift(a, uint(k))
|
||||
case k < 0:
|
||||
for k < -maxShift {
|
||||
rightShift(a, maxShift)
|
||||
k += maxShift
|
||||
}
|
||||
rightShift(a, uint(-k))
|
||||
}
|
||||
}
|
||||
|
||||
// If we chop a at nd digits, should we round up?
|
||||
func shouldRoundUp(a *decimal, nd int) bool {
|
||||
if nd < 0 || nd >= a.nd {
|
||||
return false
|
||||
}
|
||||
if a.d[nd] == '5' && nd+1 == a.nd { // exactly halfway - round to even
|
||||
// if we truncated, a little higher than what's recorded - always round up
|
||||
if a.trunc {
|
||||
return true
|
||||
}
|
||||
return nd > 0 && (a.d[nd-1]-'0')%2 != 0
|
||||
}
|
||||
// not halfway - digit tells all
|
||||
return a.d[nd] >= '5'
|
||||
}
|
||||
|
||||
// Round a to nd digits (or fewer).
|
||||
// If nd is zero, it means we're rounding
|
||||
// just to the left of the digits, as in
|
||||
// 0.09 -> 0.1.
|
||||
func (a *decimal) Round(nd int) {
|
||||
if nd < 0 || nd >= a.nd {
|
||||
return
|
||||
}
|
||||
if shouldRoundUp(a, nd) {
|
||||
a.RoundUp(nd)
|
||||
} else {
|
||||
a.RoundDown(nd)
|
||||
}
|
||||
}
|
||||
|
||||
// Round a down to nd digits (or fewer).
|
||||
func (a *decimal) RoundDown(nd int) {
|
||||
if nd < 0 || nd >= a.nd {
|
||||
return
|
||||
}
|
||||
a.nd = nd
|
||||
trim(a)
|
||||
}
|
||||
|
||||
// Round a up to nd digits (or fewer).
|
||||
func (a *decimal) RoundUp(nd int) {
|
||||
if nd < 0 || nd >= a.nd {
|
||||
return
|
||||
}
|
||||
|
||||
// round up
|
||||
for i := nd - 1; i >= 0; i-- {
|
||||
c := a.d[i]
|
||||
if c < '9' { // can stop after this digit
|
||||
a.d[i]++
|
||||
a.nd = i + 1
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Number is all 9s.
|
||||
// Change to single 1 with adjusted decimal point.
|
||||
a.d[0] = '1'
|
||||
a.nd = 1
|
||||
a.dp++
|
||||
}
|
||||
|
||||
// Extract integer part, rounded appropriately.
|
||||
// No guarantees about overflow.
|
||||
func (a *decimal) RoundedInteger() uint64 {
|
||||
if a.dp > 20 {
|
||||
return 0xFFFFFFFFFFFFFFFF
|
||||
}
|
||||
var i int
|
||||
n := uint64(0)
|
||||
for i = 0; i < a.dp && i < a.nd; i++ {
|
||||
n = n*10 + uint64(a.d[i]-'0')
|
||||
}
|
||||
for ; i < a.dp; i++ {
|
||||
n *= 10
|
||||
}
|
||||
if shouldRoundUp(a, a.dp) {
|
||||
n++
|
||||
}
|
||||
return n
|
||||
}
|
|
@ -1,213 +0,0 @@
|
|||
/**
|
||||
* Copyright 2014 Paul Querna
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Portions of this file are on Go stdlib's strconv/atoi.go */
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// ErrRange indicates that a value is out of range for the target type.
|
||||
var ErrRange = errors.New("value out of range")
|
||||
|
||||
// ErrSyntax indicates that a value does not have the right syntax for the target type.
|
||||
var ErrSyntax = errors.New("invalid syntax")
|
||||
|
||||
// A NumError records a failed conversion.
|
||||
type NumError struct {
|
||||
Func string // the failing function (ParseBool, ParseInt, ParseUint, ParseFloat)
|
||||
Num string // the input
|
||||
Err error // the reason the conversion failed (ErrRange, ErrSyntax)
|
||||
}
|
||||
|
||||
func (e *NumError) Error() string {
|
||||
return "strconv." + e.Func + ": " + "parsing " + strconv.Quote(e.Num) + ": " + e.Err.Error()
|
||||
}
|
||||
|
||||
func syntaxError(fn, str string) *NumError {
|
||||
return &NumError{fn, str, ErrSyntax}
|
||||
}
|
||||
|
||||
func rangeError(fn, str string) *NumError {
|
||||
return &NumError{fn, str, ErrRange}
|
||||
}
|
||||
|
||||
const intSize = 32 << uint(^uint(0)>>63)
|
||||
|
||||
// IntSize is the size in bits of an int or uint value.
|
||||
const IntSize = intSize
|
||||
|
||||
// Return the first number n such that n*base >= 1<<64.
|
||||
func cutoff64(base int) uint64 {
|
||||
if base < 2 {
|
||||
return 0
|
||||
}
|
||||
return (1<<64-1)/uint64(base) + 1
|
||||
}
|
||||
|
||||
// ParseUint is like ParseInt but for unsigned numbers, and oeprating on []byte
|
||||
func ParseUint(s []byte, base int, bitSize int) (n uint64, err error) {
|
||||
var cutoff, maxVal uint64
|
||||
|
||||
if bitSize == 0 {
|
||||
bitSize = int(IntSize)
|
||||
}
|
||||
|
||||
s0 := s
|
||||
switch {
|
||||
case len(s) < 1:
|
||||
err = ErrSyntax
|
||||
goto Error
|
||||
|
||||
case 2 <= base && base <= 36:
|
||||
// valid base; nothing to do
|
||||
|
||||
case base == 0:
|
||||
// Look for octal, hex prefix.
|
||||
switch {
|
||||
case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'):
|
||||
base = 16
|
||||
s = s[2:]
|
||||
if len(s) < 1 {
|
||||
err = ErrSyntax
|
||||
goto Error
|
||||
}
|
||||
case s[0] == '0':
|
||||
base = 8
|
||||
default:
|
||||
base = 10
|
||||
}
|
||||
|
||||
default:
|
||||
err = errors.New("invalid base " + strconv.Itoa(base))
|
||||
goto Error
|
||||
}
|
||||
|
||||
n = 0
|
||||
cutoff = cutoff64(base)
|
||||
maxVal = 1<<uint(bitSize) - 1
|
||||
|
||||
for i := 0; i < len(s); i++ {
|
||||
var v byte
|
||||
d := s[i]
|
||||
switch {
|
||||
case '0' <= d && d <= '9':
|
||||
v = d - '0'
|
||||
case 'a' <= d && d <= 'z':
|
||||
v = d - 'a' + 10
|
||||
case 'A' <= d && d <= 'Z':
|
||||
v = d - 'A' + 10
|
||||
default:
|
||||
n = 0
|
||||
err = ErrSyntax
|
||||
goto Error
|
||||
}
|
||||
if int(v) >= base {
|
||||
n = 0
|
||||
err = ErrSyntax
|
||||
goto Error
|
||||
}
|
||||
|
||||
if n >= cutoff {
|
||||
// n*base overflows
|
||||
n = 1<<64 - 1
|
||||
err = ErrRange
|
||||
goto Error
|
||||
}
|
||||
n *= uint64(base)
|
||||
|
||||
n1 := n + uint64(v)
|
||||
if n1 < n || n1 > maxVal {
|
||||
// n+v overflows
|
||||
n = 1<<64 - 1
|
||||
err = ErrRange
|
||||
goto Error
|
||||
}
|
||||
n = n1
|
||||
}
|
||||
|
||||
return n, nil
|
||||
|
||||
Error:
|
||||
return n, &NumError{"ParseUint", string(s0), err}
|
||||
}
|
||||
|
||||
// ParseInt interprets a string s in the given base (2 to 36) and
|
||||
// returns the corresponding value i. If base == 0, the base is
|
||||
// implied by the string's prefix: base 16 for "0x", base 8 for
|
||||
// "0", and base 10 otherwise.
|
||||
//
|
||||
// The bitSize argument specifies the integer type
|
||||
// that the result must fit into. Bit sizes 0, 8, 16, 32, and 64
|
||||
// correspond to int, int8, int16, int32, and int64.
|
||||
//
|
||||
// The errors that ParseInt returns have concrete type *NumError
|
||||
// and include err.Num = s. If s is empty or contains invalid
|
||||
// digits, err.Err = ErrSyntax and the returned value is 0;
|
||||
// if the value corresponding to s cannot be represented by a
|
||||
// signed integer of the given size, err.Err = ErrRange and the
|
||||
// returned value is the maximum magnitude integer of the
|
||||
// appropriate bitSize and sign.
|
||||
func ParseInt(s []byte, base int, bitSize int) (i int64, err error) {
|
||||
const fnParseInt = "ParseInt"
|
||||
|
||||
if bitSize == 0 {
|
||||
bitSize = int(IntSize)
|
||||
}
|
||||
|
||||
// Empty string bad.
|
||||
if len(s) == 0 {
|
||||
return 0, syntaxError(fnParseInt, string(s))
|
||||
}
|
||||
|
||||
// Pick off leading sign.
|
||||
s0 := s
|
||||
neg := false
|
||||
if s[0] == '+' {
|
||||
s = s[1:]
|
||||
} else if s[0] == '-' {
|
||||
neg = true
|
||||
s = s[1:]
|
||||
}
|
||||
|
||||
// Convert unsigned and check range.
|
||||
var un uint64
|
||||
un, err = ParseUint(s, base, bitSize)
|
||||
if err != nil && err.(*NumError).Err != ErrRange {
|
||||
err.(*NumError).Func = fnParseInt
|
||||
err.(*NumError).Num = string(s0)
|
||||
return 0, err
|
||||
}
|
||||
cutoff := uint64(1 << uint(bitSize-1))
|
||||
if !neg && un >= cutoff {
|
||||
return int64(cutoff - 1), rangeError(fnParseInt, string(s0))
|
||||
}
|
||||
if neg && un > cutoff {
|
||||
return -int64(cutoff), rangeError(fnParseInt, string(s0))
|
||||
}
|
||||
n := int64(un)
|
||||
if neg {
|
||||
n = -n
|
||||
}
|
||||
return n, nil
|
||||
}
|
668
Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/internal/extfloat.go
generated
vendored
668
Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/internal/extfloat.go
generated
vendored
|
@ -1,668 +0,0 @@
|
|||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package internal
|
||||
|
||||
// An extFloat represents an extended floating-point number, with more
|
||||
// precision than a float64. It does not try to save bits: the
|
||||
// number represented by the structure is mant*(2^exp), with a negative
|
||||
// sign if neg is true.
|
||||
type extFloat struct {
|
||||
mant uint64
|
||||
exp int
|
||||
neg bool
|
||||
}
|
||||
|
||||
// Powers of ten taken from double-conversion library.
|
||||
// http://code.google.com/p/double-conversion/
|
||||
const (
|
||||
firstPowerOfTen = -348
|
||||
stepPowerOfTen = 8
|
||||
)
|
||||
|
||||
var smallPowersOfTen = [...]extFloat{
|
||||
{1 << 63, -63, false}, // 1
|
||||
{0xa << 60, -60, false}, // 1e1
|
||||
{0x64 << 57, -57, false}, // 1e2
|
||||
{0x3e8 << 54, -54, false}, // 1e3
|
||||
{0x2710 << 50, -50, false}, // 1e4
|
||||
{0x186a0 << 47, -47, false}, // 1e5
|
||||
{0xf4240 << 44, -44, false}, // 1e6
|
||||
{0x989680 << 40, -40, false}, // 1e7
|
||||
}
|
||||
|
||||
var powersOfTen = [...]extFloat{
|
||||
{0xfa8fd5a0081c0288, -1220, false}, // 10^-348
|
||||
{0xbaaee17fa23ebf76, -1193, false}, // 10^-340
|
||||
{0x8b16fb203055ac76, -1166, false}, // 10^-332
|
||||
{0xcf42894a5dce35ea, -1140, false}, // 10^-324
|
||||
{0x9a6bb0aa55653b2d, -1113, false}, // 10^-316
|
||||
{0xe61acf033d1a45df, -1087, false}, // 10^-308
|
||||
{0xab70fe17c79ac6ca, -1060, false}, // 10^-300
|
||||
{0xff77b1fcbebcdc4f, -1034, false}, // 10^-292
|
||||
{0xbe5691ef416bd60c, -1007, false}, // 10^-284
|
||||
{0x8dd01fad907ffc3c, -980, false}, // 10^-276
|
||||
{0xd3515c2831559a83, -954, false}, // 10^-268
|
||||
{0x9d71ac8fada6c9b5, -927, false}, // 10^-260
|
||||
{0xea9c227723ee8bcb, -901, false}, // 10^-252
|
||||
{0xaecc49914078536d, -874, false}, // 10^-244
|
||||
{0x823c12795db6ce57, -847, false}, // 10^-236
|
||||
{0xc21094364dfb5637, -821, false}, // 10^-228
|
||||
{0x9096ea6f3848984f, -794, false}, // 10^-220
|
||||
{0xd77485cb25823ac7, -768, false}, // 10^-212
|
||||
{0xa086cfcd97bf97f4, -741, false}, // 10^-204
|
||||
{0xef340a98172aace5, -715, false}, // 10^-196
|
||||
{0xb23867fb2a35b28e, -688, false}, // 10^-188
|
||||
{0x84c8d4dfd2c63f3b, -661, false}, // 10^-180
|
||||
{0xc5dd44271ad3cdba, -635, false}, // 10^-172
|
||||
{0x936b9fcebb25c996, -608, false}, // 10^-164
|
||||
{0xdbac6c247d62a584, -582, false}, // 10^-156
|
||||
{0xa3ab66580d5fdaf6, -555, false}, // 10^-148
|
||||
{0xf3e2f893dec3f126, -529, false}, // 10^-140
|
||||
{0xb5b5ada8aaff80b8, -502, false}, // 10^-132
|
||||
{0x87625f056c7c4a8b, -475, false}, // 10^-124
|
||||
{0xc9bcff6034c13053, -449, false}, // 10^-116
|
||||
{0x964e858c91ba2655, -422, false}, // 10^-108
|
||||
{0xdff9772470297ebd, -396, false}, // 10^-100
|
||||
{0xa6dfbd9fb8e5b88f, -369, false}, // 10^-92
|
||||
{0xf8a95fcf88747d94, -343, false}, // 10^-84
|
||||
{0xb94470938fa89bcf, -316, false}, // 10^-76
|
||||
{0x8a08f0f8bf0f156b, -289, false}, // 10^-68
|
||||
{0xcdb02555653131b6, -263, false}, // 10^-60
|
||||
{0x993fe2c6d07b7fac, -236, false}, // 10^-52
|
||||
{0xe45c10c42a2b3b06, -210, false}, // 10^-44
|
||||
{0xaa242499697392d3, -183, false}, // 10^-36
|
||||
{0xfd87b5f28300ca0e, -157, false}, // 10^-28
|
||||
{0xbce5086492111aeb, -130, false}, // 10^-20
|
||||
{0x8cbccc096f5088cc, -103, false}, // 10^-12
|
||||
{0xd1b71758e219652c, -77, false}, // 10^-4
|
||||
{0x9c40000000000000, -50, false}, // 10^4
|
||||
{0xe8d4a51000000000, -24, false}, // 10^12
|
||||
{0xad78ebc5ac620000, 3, false}, // 10^20
|
||||
{0x813f3978f8940984, 30, false}, // 10^28
|
||||
{0xc097ce7bc90715b3, 56, false}, // 10^36
|
||||
{0x8f7e32ce7bea5c70, 83, false}, // 10^44
|
||||
{0xd5d238a4abe98068, 109, false}, // 10^52
|
||||
{0x9f4f2726179a2245, 136, false}, // 10^60
|
||||
{0xed63a231d4c4fb27, 162, false}, // 10^68
|
||||
{0xb0de65388cc8ada8, 189, false}, // 10^76
|
||||
{0x83c7088e1aab65db, 216, false}, // 10^84
|
||||
{0xc45d1df942711d9a, 242, false}, // 10^92
|
||||
{0x924d692ca61be758, 269, false}, // 10^100
|
||||
{0xda01ee641a708dea, 295, false}, // 10^108
|
||||
{0xa26da3999aef774a, 322, false}, // 10^116
|
||||
{0xf209787bb47d6b85, 348, false}, // 10^124
|
||||
{0xb454e4a179dd1877, 375, false}, // 10^132
|
||||
{0x865b86925b9bc5c2, 402, false}, // 10^140
|
||||
{0xc83553c5c8965d3d, 428, false}, // 10^148
|
||||
{0x952ab45cfa97a0b3, 455, false}, // 10^156
|
||||
{0xde469fbd99a05fe3, 481, false}, // 10^164
|
||||
{0xa59bc234db398c25, 508, false}, // 10^172
|
||||
{0xf6c69a72a3989f5c, 534, false}, // 10^180
|
||||
{0xb7dcbf5354e9bece, 561, false}, // 10^188
|
||||
{0x88fcf317f22241e2, 588, false}, // 10^196
|
||||
{0xcc20ce9bd35c78a5, 614, false}, // 10^204
|
||||
{0x98165af37b2153df, 641, false}, // 10^212
|
||||
{0xe2a0b5dc971f303a, 667, false}, // 10^220
|
||||
{0xa8d9d1535ce3b396, 694, false}, // 10^228
|
||||
{0xfb9b7cd9a4a7443c, 720, false}, // 10^236
|
||||
{0xbb764c4ca7a44410, 747, false}, // 10^244
|
||||
{0x8bab8eefb6409c1a, 774, false}, // 10^252
|
||||
{0xd01fef10a657842c, 800, false}, // 10^260
|
||||
{0x9b10a4e5e9913129, 827, false}, // 10^268
|
||||
{0xe7109bfba19c0c9d, 853, false}, // 10^276
|
||||
{0xac2820d9623bf429, 880, false}, // 10^284
|
||||
{0x80444b5e7aa7cf85, 907, false}, // 10^292
|
||||
{0xbf21e44003acdd2d, 933, false}, // 10^300
|
||||
{0x8e679c2f5e44ff8f, 960, false}, // 10^308
|
||||
{0xd433179d9c8cb841, 986, false}, // 10^316
|
||||
{0x9e19db92b4e31ba9, 1013, false}, // 10^324
|
||||
{0xeb96bf6ebadf77d9, 1039, false}, // 10^332
|
||||
{0xaf87023b9bf0ee6b, 1066, false}, // 10^340
|
||||
}
|
||||
|
||||
// floatBits returns the bits of the float64 that best approximates
|
||||
// the extFloat passed as receiver. Overflow is set to true if
|
||||
// the resulting float64 is ±Inf.
|
||||
func (f *extFloat) floatBits(flt *floatInfo) (bits uint64, overflow bool) {
|
||||
f.Normalize()
|
||||
|
||||
exp := f.exp + 63
|
||||
|
||||
// Exponent too small.
|
||||
if exp < flt.bias+1 {
|
||||
n := flt.bias + 1 - exp
|
||||
f.mant >>= uint(n)
|
||||
exp += n
|
||||
}
|
||||
|
||||
// Extract 1+flt.mantbits bits from the 64-bit mantissa.
|
||||
mant := f.mant >> (63 - flt.mantbits)
|
||||
if f.mant&(1<<(62-flt.mantbits)) != 0 {
|
||||
// Round up.
|
||||
mant += 1
|
||||
}
|
||||
|
||||
// Rounding might have added a bit; shift down.
|
||||
if mant == 2<<flt.mantbits {
|
||||
mant >>= 1
|
||||
exp++
|
||||
}
|
||||
|
||||
// Infinities.
|
||||
if exp-flt.bias >= 1<<flt.expbits-1 {
|
||||
// ±Inf
|
||||
mant = 0
|
||||
exp = 1<<flt.expbits - 1 + flt.bias
|
||||
overflow = true
|
||||
} else if mant&(1<<flt.mantbits) == 0 {
|
||||
// Denormalized?
|
||||
exp = flt.bias
|
||||
}
|
||||
// Assemble bits.
|
||||
bits = mant & (uint64(1)<<flt.mantbits - 1)
|
||||
bits |= uint64((exp-flt.bias)&(1<<flt.expbits-1)) << flt.mantbits
|
||||
if f.neg {
|
||||
bits |= 1 << (flt.mantbits + flt.expbits)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AssignComputeBounds sets f to the floating point value
|
||||
// defined by mant, exp and precision given by flt. It returns
|
||||
// lower, upper such that any number in the closed interval
|
||||
// [lower, upper] is converted back to the same floating point number.
|
||||
func (f *extFloat) AssignComputeBounds(mant uint64, exp int, neg bool, flt *floatInfo) (lower, upper extFloat) {
|
||||
f.mant = mant
|
||||
f.exp = exp - int(flt.mantbits)
|
||||
f.neg = neg
|
||||
if f.exp <= 0 && mant == (mant>>uint(-f.exp))<<uint(-f.exp) {
|
||||
// An exact integer
|
||||
f.mant >>= uint(-f.exp)
|
||||
f.exp = 0
|
||||
return *f, *f
|
||||
}
|
||||
expBiased := exp - flt.bias
|
||||
|
||||
upper = extFloat{mant: 2*f.mant + 1, exp: f.exp - 1, neg: f.neg}
|
||||
if mant != 1<<flt.mantbits || expBiased == 1 {
|
||||
lower = extFloat{mant: 2*f.mant - 1, exp: f.exp - 1, neg: f.neg}
|
||||
} else {
|
||||
lower = extFloat{mant: 4*f.mant - 1, exp: f.exp - 2, neg: f.neg}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Normalize normalizes f so that the highest bit of the mantissa is
|
||||
// set, and returns the number by which the mantissa was left-shifted.
|
||||
func (f *extFloat) Normalize() (shift uint) {
|
||||
mant, exp := f.mant, f.exp
|
||||
if mant == 0 {
|
||||
return 0
|
||||
}
|
||||
if mant>>(64-32) == 0 {
|
||||
mant <<= 32
|
||||
exp -= 32
|
||||
}
|
||||
if mant>>(64-16) == 0 {
|
||||
mant <<= 16
|
||||
exp -= 16
|
||||
}
|
||||
if mant>>(64-8) == 0 {
|
||||
mant <<= 8
|
||||
exp -= 8
|
||||
}
|
||||
if mant>>(64-4) == 0 {
|
||||
mant <<= 4
|
||||
exp -= 4
|
||||
}
|
||||
if mant>>(64-2) == 0 {
|
||||
mant <<= 2
|
||||
exp -= 2
|
||||
}
|
||||
if mant>>(64-1) == 0 {
|
||||
mant <<= 1
|
||||
exp -= 1
|
||||
}
|
||||
shift = uint(f.exp - exp)
|
||||
f.mant, f.exp = mant, exp
|
||||
return
|
||||
}
|
||||
|
||||
// Multiply sets f to the product f*g: the result is correctly rounded,
|
||||
// but not normalized.
|
||||
func (f *extFloat) Multiply(g extFloat) {
|
||||
fhi, flo := f.mant>>32, uint64(uint32(f.mant))
|
||||
ghi, glo := g.mant>>32, uint64(uint32(g.mant))
|
||||
|
||||
// Cross products.
|
||||
cross1 := fhi * glo
|
||||
cross2 := flo * ghi
|
||||
|
||||
// f.mant*g.mant is fhi*ghi << 64 + (cross1+cross2) << 32 + flo*glo
|
||||
f.mant = fhi*ghi + (cross1 >> 32) + (cross2 >> 32)
|
||||
rem := uint64(uint32(cross1)) + uint64(uint32(cross2)) + ((flo * glo) >> 32)
|
||||
// Round up.
|
||||
rem += (1 << 31)
|
||||
|
||||
f.mant += (rem >> 32)
|
||||
f.exp = f.exp + g.exp + 64
|
||||
}
|
||||
|
||||
var uint64pow10 = [...]uint64{
|
||||
1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
|
||||
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
|
||||
}
|
||||
|
||||
// AssignDecimal sets f to an approximate value mantissa*10^exp. It
|
||||
// returns true if the value represented by f is guaranteed to be the
|
||||
// best approximation of d after being rounded to a float64 or
|
||||
// float32 depending on flt.
|
||||
func (f *extFloat) AssignDecimal(mantissa uint64, exp10 int, neg bool, trunc bool, flt *floatInfo) (ok bool) {
|
||||
const uint64digits = 19
|
||||
const errorscale = 8
|
||||
errors := 0 // An upper bound for error, computed in errorscale*ulp.
|
||||
if trunc {
|
||||
// the decimal number was truncated.
|
||||
errors += errorscale / 2
|
||||
}
|
||||
|
||||
f.mant = mantissa
|
||||
f.exp = 0
|
||||
f.neg = neg
|
||||
|
||||
// Multiply by powers of ten.
|
||||
i := (exp10 - firstPowerOfTen) / stepPowerOfTen
|
||||
if exp10 < firstPowerOfTen || i >= len(powersOfTen) {
|
||||
return false
|
||||
}
|
||||
adjExp := (exp10 - firstPowerOfTen) % stepPowerOfTen
|
||||
|
||||
// We multiply by exp%step
|
||||
if adjExp < uint64digits && mantissa < uint64pow10[uint64digits-adjExp] {
|
||||
// We can multiply the mantissa exactly.
|
||||
f.mant *= uint64pow10[adjExp]
|
||||
f.Normalize()
|
||||
} else {
|
||||
f.Normalize()
|
||||
f.Multiply(smallPowersOfTen[adjExp])
|
||||
errors += errorscale / 2
|
||||
}
|
||||
|
||||
// We multiply by 10 to the exp - exp%step.
|
||||
f.Multiply(powersOfTen[i])
|
||||
if errors > 0 {
|
||||
errors += 1
|
||||
}
|
||||
errors += errorscale / 2
|
||||
|
||||
// Normalize
|
||||
shift := f.Normalize()
|
||||
errors <<= shift
|
||||
|
||||
// Now f is a good approximation of the decimal.
|
||||
// Check whether the error is too large: that is, if the mantissa
|
||||
// is perturbated by the error, the resulting float64 will change.
|
||||
// The 64 bits mantissa is 1 + 52 bits for float64 + 11 extra bits.
|
||||
//
|
||||
// In many cases the approximation will be good enough.
|
||||
denormalExp := flt.bias - 63
|
||||
var extrabits uint
|
||||
if f.exp <= denormalExp {
|
||||
// f.mant * 2^f.exp is smaller than 2^(flt.bias+1).
|
||||
extrabits = uint(63 - flt.mantbits + 1 + uint(denormalExp-f.exp))
|
||||
} else {
|
||||
extrabits = uint(63 - flt.mantbits)
|
||||
}
|
||||
|
||||
halfway := uint64(1) << (extrabits - 1)
|
||||
mant_extra := f.mant & (1<<extrabits - 1)
|
||||
|
||||
// Do a signed comparison here! If the error estimate could make
|
||||
// the mantissa round differently for the conversion to double,
|
||||
// then we can't give a definite answer.
|
||||
if int64(halfway)-int64(errors) < int64(mant_extra) &&
|
||||
int64(mant_extra) < int64(halfway)+int64(errors) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Frexp10 is an analogue of math.Frexp for decimal powers. It scales
|
||||
// f by an approximate power of ten 10^-exp, and returns exp10, so
|
||||
// that f*10^exp10 has the same value as the old f, up to an ulp,
|
||||
// as well as the index of 10^-exp in the powersOfTen table.
|
||||
func (f *extFloat) frexp10() (exp10, index int) {
|
||||
// The constants expMin and expMax constrain the final value of the
|
||||
// binary exponent of f. We want a small integral part in the result
|
||||
// because finding digits of an integer requires divisions, whereas
|
||||
// digits of the fractional part can be found by repeatedly multiplying
|
||||
// by 10.
|
||||
const expMin = -60
|
||||
const expMax = -32
|
||||
// Find power of ten such that x * 10^n has a binary exponent
|
||||
// between expMin and expMax.
|
||||
approxExp10 := ((expMin+expMax)/2 - f.exp) * 28 / 93 // log(10)/log(2) is close to 93/28.
|
||||
i := (approxExp10 - firstPowerOfTen) / stepPowerOfTen
|
||||
Loop:
|
||||
for {
|
||||
exp := f.exp + powersOfTen[i].exp + 64
|
||||
switch {
|
||||
case exp < expMin:
|
||||
i++
|
||||
case exp > expMax:
|
||||
i--
|
||||
default:
|
||||
break Loop
|
||||
}
|
||||
}
|
||||
// Apply the desired decimal shift on f. It will have exponent
|
||||
// in the desired range. This is multiplication by 10^-exp10.
|
||||
f.Multiply(powersOfTen[i])
|
||||
|
||||
return -(firstPowerOfTen + i*stepPowerOfTen), i
|
||||
}
|
||||
|
||||
// frexp10Many applies a common shift by a power of ten to a, b, c.
|
||||
func frexp10Many(a, b, c *extFloat) (exp10 int) {
|
||||
exp10, i := c.frexp10()
|
||||
a.Multiply(powersOfTen[i])
|
||||
b.Multiply(powersOfTen[i])
|
||||
return
|
||||
}
|
||||
|
||||
// FixedDecimal stores in d the first n significant digits
|
||||
// of the decimal representation of f. It returns false
|
||||
// if it cannot be sure of the answer.
|
||||
func (f *extFloat) FixedDecimal(d *decimalSlice, n int) bool {
|
||||
if f.mant == 0 {
|
||||
d.nd = 0
|
||||
d.dp = 0
|
||||
d.neg = f.neg
|
||||
return true
|
||||
}
|
||||
if n == 0 {
|
||||
panic("strconv: internal error: extFloat.FixedDecimal called with n == 0")
|
||||
}
|
||||
// Multiply by an appropriate power of ten to have a reasonable
|
||||
// number to process.
|
||||
f.Normalize()
|
||||
exp10, _ := f.frexp10()
|
||||
|
||||
shift := uint(-f.exp)
|
||||
integer := uint32(f.mant >> shift)
|
||||
fraction := f.mant - (uint64(integer) << shift)
|
||||
ε := uint64(1) // ε is the uncertainty we have on the mantissa of f.
|
||||
|
||||
// Write exactly n digits to d.
|
||||
needed := n // how many digits are left to write.
|
||||
integerDigits := 0 // the number of decimal digits of integer.
|
||||
pow10 := uint64(1) // the power of ten by which f was scaled.
|
||||
for i, pow := 0, uint64(1); i < 20; i++ {
|
||||
if pow > uint64(integer) {
|
||||
integerDigits = i
|
||||
break
|
||||
}
|
||||
pow *= 10
|
||||
}
|
||||
rest := integer
|
||||
if integerDigits > needed {
|
||||
// the integral part is already large, trim the last digits.
|
||||
pow10 = uint64pow10[integerDigits-needed]
|
||||
integer /= uint32(pow10)
|
||||
rest -= integer * uint32(pow10)
|
||||
} else {
|
||||
rest = 0
|
||||
}
|
||||
|
||||
// Write the digits of integer: the digits of rest are omitted.
|
||||
var buf [32]byte
|
||||
pos := len(buf)
|
||||
for v := integer; v > 0; {
|
||||
v1 := v / 10
|
||||
v -= 10 * v1
|
||||
pos--
|
||||
buf[pos] = byte(v + '0')
|
||||
v = v1
|
||||
}
|
||||
for i := pos; i < len(buf); i++ {
|
||||
d.d[i-pos] = buf[i]
|
||||
}
|
||||
nd := len(buf) - pos
|
||||
d.nd = nd
|
||||
d.dp = integerDigits + exp10
|
||||
needed -= nd
|
||||
|
||||
if needed > 0 {
|
||||
if rest != 0 || pow10 != 1 {
|
||||
panic("strconv: internal error, rest != 0 but needed > 0")
|
||||
}
|
||||
// Emit digits for the fractional part. Each time, 10*fraction
|
||||
// fits in a uint64 without overflow.
|
||||
for needed > 0 {
|
||||
fraction *= 10
|
||||
ε *= 10 // the uncertainty scales as we multiply by ten.
|
||||
if 2*ε > 1<<shift {
|
||||
// the error is so large it could modify which digit to write, abort.
|
||||
return false
|
||||
}
|
||||
digit := fraction >> shift
|
||||
d.d[nd] = byte(digit + '0')
|
||||
fraction -= digit << shift
|
||||
nd++
|
||||
needed--
|
||||
}
|
||||
d.nd = nd
|
||||
}
|
||||
|
||||
// We have written a truncation of f (a numerator / 10^d.dp). The remaining part
|
||||
// can be interpreted as a small number (< 1) to be added to the last digit of the
|
||||
// numerator.
|
||||
//
|
||||
// If rest > 0, the amount is:
|
||||
// (rest<<shift | fraction) / (pow10 << shift)
|
||||
// fraction being known with a ±ε uncertainty.
|
||||
// The fact that n > 0 guarantees that pow10 << shift does not overflow a uint64.
|
||||
//
|
||||
// If rest = 0, pow10 == 1 and the amount is
|
||||
// fraction / (1 << shift)
|
||||
// fraction being known with a ±ε uncertainty.
|
||||
//
|
||||
// We pass this information to the rounding routine for adjustment.
|
||||
|
||||
ok := adjustLastDigitFixed(d, uint64(rest)<<shift|fraction, pow10, shift, ε)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
// Trim trailing zeros.
|
||||
for i := d.nd - 1; i >= 0; i-- {
|
||||
if d.d[i] != '0' {
|
||||
d.nd = i + 1
|
||||
break
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// adjustLastDigitFixed assumes d contains the representation of the integral part
|
||||
// of some number, whose fractional part is num / (den << shift). The numerator
|
||||
// num is only known up to an uncertainty of size ε, assumed to be less than
|
||||
// (den << shift)/2.
|
||||
//
|
||||
// It will increase the last digit by one to account for correct rounding, typically
|
||||
// when the fractional part is greater than 1/2, and will return false if ε is such
|
||||
// that no correct answer can be given.
|
||||
func adjustLastDigitFixed(d *decimalSlice, num, den uint64, shift uint, ε uint64) bool {
|
||||
if num > den<<shift {
|
||||
panic("strconv: num > den<<shift in adjustLastDigitFixed")
|
||||
}
|
||||
if 2*ε > den<<shift {
|
||||
panic("strconv: ε > (den<<shift)/2")
|
||||
}
|
||||
if 2*(num+ε) < den<<shift {
|
||||
return true
|
||||
}
|
||||
if 2*(num-ε) > den<<shift {
|
||||
// increment d by 1.
|
||||
i := d.nd - 1
|
||||
for ; i >= 0; i-- {
|
||||
if d.d[i] == '9' {
|
||||
d.nd--
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
if i < 0 {
|
||||
d.d[0] = '1'
|
||||
d.nd = 1
|
||||
d.dp++
|
||||
} else {
|
||||
d.d[i]++
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ShortestDecimal stores in d the shortest decimal representation of f
|
||||
// which belongs to the open interval (lower, upper), where f is supposed
|
||||
// to lie. It returns false whenever the result is unsure. The implementation
|
||||
// uses the Grisu3 algorithm.
|
||||
func (f *extFloat) ShortestDecimal(d *decimalSlice, lower, upper *extFloat) bool {
|
||||
if f.mant == 0 {
|
||||
d.nd = 0
|
||||
d.dp = 0
|
||||
d.neg = f.neg
|
||||
return true
|
||||
}
|
||||
if f.exp == 0 && *lower == *f && *lower == *upper {
|
||||
// an exact integer.
|
||||
var buf [24]byte
|
||||
n := len(buf) - 1
|
||||
for v := f.mant; v > 0; {
|
||||
v1 := v / 10
|
||||
v -= 10 * v1
|
||||
buf[n] = byte(v + '0')
|
||||
n--
|
||||
v = v1
|
||||
}
|
||||
nd := len(buf) - n - 1
|
||||
for i := 0; i < nd; i++ {
|
||||
d.d[i] = buf[n+1+i]
|
||||
}
|
||||
d.nd, d.dp = nd, nd
|
||||
for d.nd > 0 && d.d[d.nd-1] == '0' {
|
||||
d.nd--
|
||||
}
|
||||
if d.nd == 0 {
|
||||
d.dp = 0
|
||||
}
|
||||
d.neg = f.neg
|
||||
return true
|
||||
}
|
||||
upper.Normalize()
|
||||
// Uniformize exponents.
|
||||
if f.exp > upper.exp {
|
||||
f.mant <<= uint(f.exp - upper.exp)
|
||||
f.exp = upper.exp
|
||||
}
|
||||
if lower.exp > upper.exp {
|
||||
lower.mant <<= uint(lower.exp - upper.exp)
|
||||
lower.exp = upper.exp
|
||||
}
|
||||
|
||||
exp10 := frexp10Many(lower, f, upper)
|
||||
// Take a safety margin due to rounding in frexp10Many, but we lose precision.
|
||||
upper.mant++
|
||||
lower.mant--
|
||||
|
||||
// The shortest representation of f is either rounded up or down, but
|
||||
// in any case, it is a truncation of upper.
|
||||
shift := uint(-upper.exp)
|
||||
integer := uint32(upper.mant >> shift)
|
||||
fraction := upper.mant - (uint64(integer) << shift)
|
||||
|
||||
// How far we can go down from upper until the result is wrong.
|
||||
allowance := upper.mant - lower.mant
|
||||
// How far we should go to get a very precise result.
|
||||
targetDiff := upper.mant - f.mant
|
||||
|
||||
// Count integral digits: there are at most 10.
|
||||
var integerDigits int
|
||||
for i, pow := 0, uint64(1); i < 20; i++ {
|
||||
if pow > uint64(integer) {
|
||||
integerDigits = i
|
||||
break
|
||||
}
|
||||
pow *= 10
|
||||
}
|
||||
for i := 0; i < integerDigits; i++ {
|
||||
pow := uint64pow10[integerDigits-i-1]
|
||||
digit := integer / uint32(pow)
|
||||
d.d[i] = byte(digit + '0')
|
||||
integer -= digit * uint32(pow)
|
||||
// evaluate whether we should stop.
|
||||
if currentDiff := uint64(integer)<<shift + fraction; currentDiff < allowance {
|
||||
d.nd = i + 1
|
||||
d.dp = integerDigits + exp10
|
||||
d.neg = f.neg
|
||||
// Sometimes allowance is so large the last digit might need to be
|
||||
// decremented to get closer to f.
|
||||
return adjustLastDigit(d, currentDiff, targetDiff, allowance, pow<<shift, 2)
|
||||
}
|
||||
}
|
||||
d.nd = integerDigits
|
||||
d.dp = d.nd + exp10
|
||||
d.neg = f.neg
|
||||
|
||||
// Compute digits of the fractional part. At each step fraction does not
|
||||
// overflow. The choice of minExp implies that fraction is less than 2^60.
|
||||
var digit int
|
||||
multiplier := uint64(1)
|
||||
for {
|
||||
fraction *= 10
|
||||
multiplier *= 10
|
||||
digit = int(fraction >> shift)
|
||||
d.d[d.nd] = byte(digit + '0')
|
||||
d.nd++
|
||||
fraction -= uint64(digit) << shift
|
||||
if fraction < allowance*multiplier {
|
||||
// We are in the admissible range. Note that if allowance is about to
|
||||
// overflow, that is, allowance > 2^64/10, the condition is automatically
|
||||
// true due to the limited range of fraction.
|
||||
return adjustLastDigit(d,
|
||||
fraction, targetDiff*multiplier, allowance*multiplier,
|
||||
1<<shift, multiplier*2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// adjustLastDigit modifies d = x-currentDiff*ε, to get closest to
|
||||
// d = x-targetDiff*ε, without becoming smaller than x-maxDiff*ε.
|
||||
// It assumes that a decimal digit is worth ulpDecimal*ε, and that
|
||||
// all data is known with a error estimate of ulpBinary*ε.
|
||||
func adjustLastDigit(d *decimalSlice, currentDiff, targetDiff, maxDiff, ulpDecimal, ulpBinary uint64) bool {
|
||||
if ulpDecimal < 2*ulpBinary {
|
||||
// Approximation is too wide.
|
||||
return false
|
||||
}
|
||||
for currentDiff+ulpDecimal/2+ulpBinary < targetDiff {
|
||||
d.d[d.nd-1]--
|
||||
currentDiff += ulpDecimal
|
||||
}
|
||||
if currentDiff+ulpDecimal <= targetDiff+ulpDecimal/2+ulpBinary {
|
||||
// we have two choices, and don't know what to do.
|
||||
return false
|
||||
}
|
||||
if currentDiff < ulpBinary || currentDiff > maxDiff-ulpBinary {
|
||||
// we went too far
|
||||
return false
|
||||
}
|
||||
if d.nd == 1 && d.d[0] == '0' {
|
||||
// the number has actually reached zero.
|
||||
d.nd = 0
|
||||
d.dp = 0
|
||||
}
|
||||
return true
|
||||
}
|
|
@ -1,475 +0,0 @@
|
|||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Binary to decimal floating point conversion.
|
||||
// Algorithm:
|
||||
// 1) store mantissa in multiprecision decimal
|
||||
// 2) shift decimal by exponent
|
||||
// 3) read digits out & format
|
||||
|
||||
package internal
|
||||
|
||||
import "math"
|
||||
|
||||
// TODO: move elsewhere?
|
||||
type floatInfo struct {
|
||||
mantbits uint
|
||||
expbits uint
|
||||
bias int
|
||||
}
|
||||
|
||||
var float32info = floatInfo{23, 8, -127}
|
||||
var float64info = floatInfo{52, 11, -1023}
|
||||
|
||||
// FormatFloat converts the floating-point number f to a string,
|
||||
// according to the format fmt and precision prec. It rounds the
|
||||
// result assuming that the original was obtained from a floating-point
|
||||
// value of bitSize bits (32 for float32, 64 for float64).
|
||||
//
|
||||
// The format fmt is one of
|
||||
// 'b' (-ddddp±ddd, a binary exponent),
|
||||
// 'e' (-d.dddde±dd, a decimal exponent),
|
||||
// 'E' (-d.ddddE±dd, a decimal exponent),
|
||||
// 'f' (-ddd.dddd, no exponent),
|
||||
// 'g' ('e' for large exponents, 'f' otherwise), or
|
||||
// 'G' ('E' for large exponents, 'f' otherwise).
|
||||
//
|
||||
// The precision prec controls the number of digits
|
||||
// (excluding the exponent) printed by the 'e', 'E', 'f', 'g', and 'G' formats.
|
||||
// For 'e', 'E', and 'f' it is the number of digits after the decimal point.
|
||||
// For 'g' and 'G' it is the total number of digits.
|
||||
// The special precision -1 uses the smallest number of digits
|
||||
// necessary such that ParseFloat will return f exactly.
|
||||
func formatFloat(f float64, fmt byte, prec, bitSize int) string {
|
||||
return string(genericFtoa(make([]byte, 0, max(prec+4, 24)), f, fmt, prec, bitSize))
|
||||
}
|
||||
|
||||
// AppendFloat appends the string form of the floating-point number f,
|
||||
// as generated by FormatFloat, to dst and returns the extended buffer.
|
||||
func appendFloat(dst []byte, f float64, fmt byte, prec int, bitSize int) []byte {
|
||||
return genericFtoa(dst, f, fmt, prec, bitSize)
|
||||
}
|
||||
|
||||
func genericFtoa(dst []byte, val float64, fmt byte, prec, bitSize int) []byte {
|
||||
var bits uint64
|
||||
var flt *floatInfo
|
||||
switch bitSize {
|
||||
case 32:
|
||||
bits = uint64(math.Float32bits(float32(val)))
|
||||
flt = &float32info
|
||||
case 64:
|
||||
bits = math.Float64bits(val)
|
||||
flt = &float64info
|
||||
default:
|
||||
panic("strconv: illegal AppendFloat/FormatFloat bitSize")
|
||||
}
|
||||
|
||||
neg := bits>>(flt.expbits+flt.mantbits) != 0
|
||||
exp := int(bits>>flt.mantbits) & (1<<flt.expbits - 1)
|
||||
mant := bits & (uint64(1)<<flt.mantbits - 1)
|
||||
|
||||
switch exp {
|
||||
case 1<<flt.expbits - 1:
|
||||
// Inf, NaN
|
||||
var s string
|
||||
switch {
|
||||
case mant != 0:
|
||||
s = "NaN"
|
||||
case neg:
|
||||
s = "-Inf"
|
||||
default:
|
||||
s = "+Inf"
|
||||
}
|
||||
return append(dst, s...)
|
||||
|
||||
case 0:
|
||||
// denormalized
|
||||
exp++
|
||||
|
||||
default:
|
||||
// add implicit top bit
|
||||
mant |= uint64(1) << flt.mantbits
|
||||
}
|
||||
exp += flt.bias
|
||||
|
||||
// Pick off easy binary format.
|
||||
if fmt == 'b' {
|
||||
return fmtB(dst, neg, mant, exp, flt)
|
||||
}
|
||||
|
||||
if !optimize {
|
||||
return bigFtoa(dst, prec, fmt, neg, mant, exp, flt)
|
||||
}
|
||||
|
||||
var digs decimalSlice
|
||||
ok := false
|
||||
// Negative precision means "only as much as needed to be exact."
|
||||
shortest := prec < 0
|
||||
if shortest {
|
||||
// Try Grisu3 algorithm.
|
||||
f := new(extFloat)
|
||||
lower, upper := f.AssignComputeBounds(mant, exp, neg, flt)
|
||||
var buf [32]byte
|
||||
digs.d = buf[:]
|
||||
ok = f.ShortestDecimal(&digs, &lower, &upper)
|
||||
if !ok {
|
||||
return bigFtoa(dst, prec, fmt, neg, mant, exp, flt)
|
||||
}
|
||||
// Precision for shortest representation mode.
|
||||
switch fmt {
|
||||
case 'e', 'E':
|
||||
prec = digs.nd - 1
|
||||
case 'f':
|
||||
prec = max(digs.nd-digs.dp, 0)
|
||||
case 'g', 'G':
|
||||
prec = digs.nd
|
||||
}
|
||||
} else if fmt != 'f' {
|
||||
// Fixed number of digits.
|
||||
digits := prec
|
||||
switch fmt {
|
||||
case 'e', 'E':
|
||||
digits++
|
||||
case 'g', 'G':
|
||||
if prec == 0 {
|
||||
prec = 1
|
||||
}
|
||||
digits = prec
|
||||
}
|
||||
if digits <= 15 {
|
||||
// try fast algorithm when the number of digits is reasonable.
|
||||
var buf [24]byte
|
||||
digs.d = buf[:]
|
||||
f := extFloat{mant, exp - int(flt.mantbits), neg}
|
||||
ok = f.FixedDecimal(&digs, digits)
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
return bigFtoa(dst, prec, fmt, neg, mant, exp, flt)
|
||||
}
|
||||
return formatDigits(dst, shortest, neg, digs, prec, fmt)
|
||||
}
|
||||
|
||||
// bigFtoa uses multiprecision computations to format a float.
|
||||
func bigFtoa(dst []byte, prec int, fmt byte, neg bool, mant uint64, exp int, flt *floatInfo) []byte {
|
||||
d := new(decimal)
|
||||
d.Assign(mant)
|
||||
d.Shift(exp - int(flt.mantbits))
|
||||
var digs decimalSlice
|
||||
shortest := prec < 0
|
||||
if shortest {
|
||||
roundShortest(d, mant, exp, flt)
|
||||
digs = decimalSlice{d: d.d[:], nd: d.nd, dp: d.dp}
|
||||
// Precision for shortest representation mode.
|
||||
switch fmt {
|
||||
case 'e', 'E':
|
||||
prec = digs.nd - 1
|
||||
case 'f':
|
||||
prec = max(digs.nd-digs.dp, 0)
|
||||
case 'g', 'G':
|
||||
prec = digs.nd
|
||||
}
|
||||
} else {
|
||||
// Round appropriately.
|
||||
switch fmt {
|
||||
case 'e', 'E':
|
||||
d.Round(prec + 1)
|
||||
case 'f':
|
||||
d.Round(d.dp + prec)
|
||||
case 'g', 'G':
|
||||
if prec == 0 {
|
||||
prec = 1
|
||||
}
|
||||
d.Round(prec)
|
||||
}
|
||||
digs = decimalSlice{d: d.d[:], nd: d.nd, dp: d.dp}
|
||||
}
|
||||
return formatDigits(dst, shortest, neg, digs, prec, fmt)
|
||||
}
|
||||
|
||||
func formatDigits(dst []byte, shortest bool, neg bool, digs decimalSlice, prec int, fmt byte) []byte {
|
||||
switch fmt {
|
||||
case 'e', 'E':
|
||||
return fmtE(dst, neg, digs, prec, fmt)
|
||||
case 'f':
|
||||
return fmtF(dst, neg, digs, prec)
|
||||
case 'g', 'G':
|
||||
// trailing fractional zeros in 'e' form will be trimmed.
|
||||
eprec := prec
|
||||
if eprec > digs.nd && digs.nd >= digs.dp {
|
||||
eprec = digs.nd
|
||||
}
|
||||
// %e is used if the exponent from the conversion
|
||||
// is less than -4 or greater than or equal to the precision.
|
||||
// if precision was the shortest possible, use precision 6 for this decision.
|
||||
if shortest {
|
||||
eprec = 6
|
||||
}
|
||||
exp := digs.dp - 1
|
||||
if exp < -4 || exp >= eprec {
|
||||
if prec > digs.nd {
|
||||
prec = digs.nd
|
||||
}
|
||||
return fmtE(dst, neg, digs, prec-1, fmt+'e'-'g')
|
||||
}
|
||||
if prec > digs.dp {
|
||||
prec = digs.nd
|
||||
}
|
||||
return fmtF(dst, neg, digs, max(prec-digs.dp, 0))
|
||||
}
|
||||
|
||||
// unknown format
|
||||
return append(dst, '%', fmt)
|
||||
}
|
||||
|
||||
// Round d (= mant * 2^exp) to the shortest number of digits
|
||||
// that will let the original floating point value be precisely
|
||||
// reconstructed. Size is original floating point size (64 or 32).
|
||||
func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) {
|
||||
// If mantissa is zero, the number is zero; stop now.
|
||||
if mant == 0 {
|
||||
d.nd = 0
|
||||
return
|
||||
}
|
||||
|
||||
// Compute upper and lower such that any decimal number
|
||||
// between upper and lower (possibly inclusive)
|
||||
// will round to the original floating point number.
|
||||
|
||||
// We may see at once that the number is already shortest.
|
||||
//
|
||||
// Suppose d is not denormal, so that 2^exp <= d < 10^dp.
|
||||
// The closest shorter number is at least 10^(dp-nd) away.
|
||||
// The lower/upper bounds computed below are at distance
|
||||
// at most 2^(exp-mantbits).
|
||||
//
|
||||
// So the number is already shortest if 10^(dp-nd) > 2^(exp-mantbits),
|
||||
// or equivalently log2(10)*(dp-nd) > exp-mantbits.
|
||||
// It is true if 332/100*(dp-nd) >= exp-mantbits (log2(10) > 3.32).
|
||||
minexp := flt.bias + 1 // minimum possible exponent
|
||||
if exp > minexp && 332*(d.dp-d.nd) >= 100*(exp-int(flt.mantbits)) {
|
||||
// The number is already shortest.
|
||||
return
|
||||
}
|
||||
|
||||
// d = mant << (exp - mantbits)
|
||||
// Next highest floating point number is mant+1 << exp-mantbits.
|
||||
// Our upper bound is halfway between, mant*2+1 << exp-mantbits-1.
|
||||
upper := new(decimal)
|
||||
upper.Assign(mant*2 + 1)
|
||||
upper.Shift(exp - int(flt.mantbits) - 1)
|
||||
|
||||
// d = mant << (exp - mantbits)
|
||||
// Next lowest floating point number is mant-1 << exp-mantbits,
|
||||
// unless mant-1 drops the significant bit and exp is not the minimum exp,
|
||||
// in which case the next lowest is mant*2-1 << exp-mantbits-1.
|
||||
// Either way, call it mantlo << explo-mantbits.
|
||||
// Our lower bound is halfway between, mantlo*2+1 << explo-mantbits-1.
|
||||
var mantlo uint64
|
||||
var explo int
|
||||
if mant > 1<<flt.mantbits || exp == minexp {
|
||||
mantlo = mant - 1
|
||||
explo = exp
|
||||
} else {
|
||||
mantlo = mant*2 - 1
|
||||
explo = exp - 1
|
||||
}
|
||||
lower := new(decimal)
|
||||
lower.Assign(mantlo*2 + 1)
|
||||
lower.Shift(explo - int(flt.mantbits) - 1)
|
||||
|
||||
// The upper and lower bounds are possible outputs only if
|
||||
// the original mantissa is even, so that IEEE round-to-even
|
||||
// would round to the original mantissa and not the neighbors.
|
||||
inclusive := mant%2 == 0
|
||||
|
||||
// Now we can figure out the minimum number of digits required.
|
||||
// Walk along until d has distinguished itself from upper and lower.
|
||||
for i := 0; i < d.nd; i++ {
|
||||
var l, m, u byte // lower, middle, upper digits
|
||||
if i < lower.nd {
|
||||
l = lower.d[i]
|
||||
} else {
|
||||
l = '0'
|
||||
}
|
||||
m = d.d[i]
|
||||
if i < upper.nd {
|
||||
u = upper.d[i]
|
||||
} else {
|
||||
u = '0'
|
||||
}
|
||||
|
||||
// Okay to round down (truncate) if lower has a different digit
|
||||
// or if lower is inclusive and is exactly the result of rounding down.
|
||||
okdown := l != m || (inclusive && l == m && i+1 == lower.nd)
|
||||
|
||||
// Okay to round up if upper has a different digit and
|
||||
// either upper is inclusive or upper is bigger than the result of rounding up.
|
||||
okup := m != u && (inclusive || m+1 < u || i+1 < upper.nd)
|
||||
|
||||
// If it's okay to do either, then round to the nearest one.
|
||||
// If it's okay to do only one, do it.
|
||||
switch {
|
||||
case okdown && okup:
|
||||
d.Round(i + 1)
|
||||
return
|
||||
case okdown:
|
||||
d.RoundDown(i + 1)
|
||||
return
|
||||
case okup:
|
||||
d.RoundUp(i + 1)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type decimalSlice struct {
|
||||
d []byte
|
||||
nd, dp int
|
||||
neg bool
|
||||
}
|
||||
|
||||
// %e: -d.ddddde±dd
|
||||
func fmtE(dst []byte, neg bool, d decimalSlice, prec int, fmt byte) []byte {
|
||||
// sign
|
||||
if neg {
|
||||
dst = append(dst, '-')
|
||||
}
|
||||
|
||||
// first digit
|
||||
ch := byte('0')
|
||||
if d.nd != 0 {
|
||||
ch = d.d[0]
|
||||
}
|
||||
dst = append(dst, ch)
|
||||
|
||||
// .moredigits
|
||||
if prec > 0 {
|
||||
dst = append(dst, '.')
|
||||
i := 1
|
||||
m := d.nd + prec + 1 - max(d.nd, prec+1)
|
||||
for i < m {
|
||||
dst = append(dst, d.d[i])
|
||||
i++
|
||||
}
|
||||
for i <= prec {
|
||||
dst = append(dst, '0')
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
// e±
|
||||
dst = append(dst, fmt)
|
||||
exp := d.dp - 1
|
||||
if d.nd == 0 { // special case: 0 has exponent 0
|
||||
exp = 0
|
||||
}
|
||||
if exp < 0 {
|
||||
ch = '-'
|
||||
exp = -exp
|
||||
} else {
|
||||
ch = '+'
|
||||
}
|
||||
dst = append(dst, ch)
|
||||
|
||||
// dddd
|
||||
var buf [3]byte
|
||||
i := len(buf)
|
||||
for exp >= 10 {
|
||||
i--
|
||||
buf[i] = byte(exp%10 + '0')
|
||||
exp /= 10
|
||||
}
|
||||
// exp < 10
|
||||
i--
|
||||
buf[i] = byte(exp + '0')
|
||||
|
||||
switch i {
|
||||
case 0:
|
||||
dst = append(dst, buf[0], buf[1], buf[2])
|
||||
case 1:
|
||||
dst = append(dst, buf[1], buf[2])
|
||||
case 2:
|
||||
// leading zeroes
|
||||
dst = append(dst, '0', buf[2])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// %f: -ddddddd.ddddd
|
||||
func fmtF(dst []byte, neg bool, d decimalSlice, prec int) []byte {
|
||||
// sign
|
||||
if neg {
|
||||
dst = append(dst, '-')
|
||||
}
|
||||
|
||||
// integer, padded with zeros as needed.
|
||||
if d.dp > 0 {
|
||||
var i int
|
||||
for i = 0; i < d.dp && i < d.nd; i++ {
|
||||
dst = append(dst, d.d[i])
|
||||
}
|
||||
for ; i < d.dp; i++ {
|
||||
dst = append(dst, '0')
|
||||
}
|
||||
} else {
|
||||
dst = append(dst, '0')
|
||||
}
|
||||
|
||||
// fraction
|
||||
if prec > 0 {
|
||||
dst = append(dst, '.')
|
||||
for i := 0; i < prec; i++ {
|
||||
ch := byte('0')
|
||||
if j := d.dp + i; 0 <= j && j < d.nd {
|
||||
ch = d.d[j]
|
||||
}
|
||||
dst = append(dst, ch)
|
||||
}
|
||||
}
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
// %b: -ddddddddp+ddd
|
||||
func fmtB(dst []byte, neg bool, mant uint64, exp int, flt *floatInfo) []byte {
|
||||
var buf [50]byte
|
||||
w := len(buf)
|
||||
exp -= int(flt.mantbits)
|
||||
esign := byte('+')
|
||||
if exp < 0 {
|
||||
esign = '-'
|
||||
exp = -exp
|
||||
}
|
||||
n := 0
|
||||
for exp > 0 || n < 1 {
|
||||
n++
|
||||
w--
|
||||
buf[w] = byte(exp%10 + '0')
|
||||
exp /= 10
|
||||
}
|
||||
w--
|
||||
buf[w] = esign
|
||||
w--
|
||||
buf[w] = 'p'
|
||||
n = 0
|
||||
for mant > 0 || n < 1 {
|
||||
n++
|
||||
w--
|
||||
buf[w] = byte(mant%10 + '0')
|
||||
mant /= 10
|
||||
}
|
||||
if neg {
|
||||
w--
|
||||
buf[w] = '-'
|
||||
}
|
||||
return append(dst, buf[w:]...)
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
|
@ -1,161 +0,0 @@
|
|||
/**
|
||||
* Copyright 2014 Paul Querna
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Portions of this file are on Go stdlib's strconv/iota.go */
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
const (
|
||||
digits = "0123456789abcdefghijklmnopqrstuvwxyz"
|
||||
digits01 = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
|
||||
digits10 = "0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999"
|
||||
)
|
||||
|
||||
var shifts = [len(digits) + 1]uint{
|
||||
1 << 1: 1,
|
||||
1 << 2: 2,
|
||||
1 << 3: 3,
|
||||
1 << 4: 4,
|
||||
1 << 5: 5,
|
||||
}
|
||||
|
||||
var smallNumbers = [][]byte{
|
||||
[]byte("0"),
|
||||
[]byte("1"),
|
||||
[]byte("2"),
|
||||
[]byte("3"),
|
||||
[]byte("4"),
|
||||
[]byte("5"),
|
||||
[]byte("6"),
|
||||
[]byte("7"),
|
||||
[]byte("8"),
|
||||
[]byte("9"),
|
||||
[]byte("10"),
|
||||
}
|
||||
|
||||
type FormatBitsWriter interface {
|
||||
io.Writer
|
||||
io.ByteWriter
|
||||
}
|
||||
|
||||
type FormatBitsScratch struct{}
|
||||
|
||||
//
|
||||
// DEPRECIATED: `scratch` is no longer used, FormatBits2 is available.
|
||||
//
|
||||
// FormatBits computes the string representation of u in the given base.
|
||||
// If neg is set, u is treated as negative int64 value. If append_ is
|
||||
// set, the string is appended to dst and the resulting byte slice is
|
||||
// returned as the first result value; otherwise the string is returned
|
||||
// as the second result value.
|
||||
//
|
||||
func FormatBits(scratch *FormatBitsScratch, dst FormatBitsWriter, u uint64, base int, neg bool) {
|
||||
FormatBits2(dst, u, base, neg)
|
||||
}
|
||||
|
||||
// FormatBits2 computes the string representation of u in the given base.
|
||||
// If neg is set, u is treated as negative int64 value. If append_ is
|
||||
// set, the string is appended to dst and the resulting byte slice is
|
||||
// returned as the first result value; otherwise the string is returned
|
||||
// as the second result value.
|
||||
//
|
||||
func FormatBits2(dst FormatBitsWriter, u uint64, base int, neg bool) {
|
||||
if base < 2 || base > len(digits) {
|
||||
panic("strconv: illegal AppendInt/FormatInt base")
|
||||
}
|
||||
// fast path for small common numbers
|
||||
if u <= 10 {
|
||||
if neg {
|
||||
dst.WriteByte('-')
|
||||
}
|
||||
dst.Write(smallNumbers[u])
|
||||
return
|
||||
}
|
||||
|
||||
// 2 <= base && base <= len(digits)
|
||||
|
||||
var a = makeSlice(65)
|
||||
// var a [64 + 1]byte // +1 for sign of 64bit value in base 2
|
||||
i := len(a)
|
||||
|
||||
if neg {
|
||||
u = -u
|
||||
}
|
||||
|
||||
// convert bits
|
||||
if base == 10 {
|
||||
// common case: use constants for / and % because
|
||||
// the compiler can optimize it into a multiply+shift,
|
||||
// and unroll loop
|
||||
for u >= 100 {
|
||||
i -= 2
|
||||
q := u / 100
|
||||
j := uintptr(u - q*100)
|
||||
a[i+1] = digits01[j]
|
||||
a[i+0] = digits10[j]
|
||||
u = q
|
||||
}
|
||||
if u >= 10 {
|
||||
i--
|
||||
q := u / 10
|
||||
a[i] = digits[uintptr(u-q*10)]
|
||||
u = q
|
||||
}
|
||||
|
||||
} else if s := shifts[base]; s > 0 {
|
||||
// base is power of 2: use shifts and masks instead of / and %
|
||||
b := uint64(base)
|
||||
m := uintptr(b) - 1 // == 1<<s - 1
|
||||
for u >= b {
|
||||
i--
|
||||
a[i] = digits[uintptr(u)&m]
|
||||
u >>= s
|
||||
}
|
||||
|
||||
} else {
|
||||
// general case
|
||||
b := uint64(base)
|
||||
for u >= b {
|
||||
i--
|
||||
a[i] = digits[uintptr(u%b)]
|
||||
u /= b
|
||||
}
|
||||
}
|
||||
|
||||
// u < base
|
||||
i--
|
||||
a[i] = digits[uintptr(u)]
|
||||
|
||||
// add sign, if any
|
||||
if neg {
|
||||
i--
|
||||
a[i] = '-'
|
||||
}
|
||||
|
||||
dst.Write(a[i:])
|
||||
|
||||
Pool(a)
|
||||
|
||||
return
|
||||
}
|
|
@ -1,512 +0,0 @@
|
|||
/**
|
||||
* Copyright 2014 Paul Querna
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Portions of this file are on Go stdlib's encoding/json/encode.go */
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
"io"
|
||||
"unicode/utf8"
|
||||
"strconv"
|
||||
"unicode/utf16"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
const hex = "0123456789abcdef"
|
||||
|
||||
type JsonStringWriter interface {
|
||||
io.Writer
|
||||
io.ByteWriter
|
||||
stringWriter
|
||||
}
|
||||
|
||||
func WriteJsonString(buf JsonStringWriter, s string) {
|
||||
WriteJson(buf, []byte(s))
|
||||
}
|
||||
|
||||
/**
|
||||
* Function ported from encoding/json: func (e *encodeState) string(s string) (int, error)
|
||||
*/
|
||||
func WriteJson(buf JsonStringWriter, s []byte) {
|
||||
buf.WriteByte('"')
|
||||
start := 0
|
||||
for i := 0; i < len(s); {
|
||||
if b := s[i]; b < utf8.RuneSelf {
|
||||
/*
|
||||
if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' && b != '&' {
|
||||
i++
|
||||
continue
|
||||
}
|
||||
*/
|
||||
if lt[b] == true {
|
||||
i++
|
||||
continue
|
||||
}
|
||||
|
||||
if start < i {
|
||||
buf.Write(s[start:i])
|
||||
}
|
||||
switch b {
|
||||
case '\\', '"':
|
||||
buf.WriteByte('\\')
|
||||
buf.WriteByte(b)
|
||||
case '\n':
|
||||
buf.WriteByte('\\')
|
||||
buf.WriteByte('n')
|
||||
case '\r':
|
||||
buf.WriteByte('\\')
|
||||
buf.WriteByte('r')
|
||||
default:
|
||||
// This encodes bytes < 0x20 except for \n and \r,
|
||||
// as well as < and >. The latter are escaped because they
|
||||
// can lead to security holes when user-controlled strings
|
||||
// are rendered into JSON and served to some browsers.
|
||||
buf.WriteString(`\u00`)
|
||||
buf.WriteByte(hex[b>>4])
|
||||
buf.WriteByte(hex[b&0xF])
|
||||
}
|
||||
i++
|
||||
start = i
|
||||
continue
|
||||
}
|
||||
c, size := utf8.DecodeRune(s[i:])
|
||||
if c == utf8.RuneError && size == 1 {
|
||||
if start < i {
|
||||
buf.Write(s[start:i])
|
||||
}
|
||||
buf.WriteString(`\ufffd`)
|
||||
i += size
|
||||
start = i
|
||||
continue
|
||||
}
|
||||
// U+2028 is LINE SEPARATOR.
|
||||
// U+2029 is PARAGRAPH SEPARATOR.
|
||||
// They are both technically valid characters in JSON strings,
|
||||
// but don't work in JSONP, which has to be evaluated as JavaScript,
|
||||
// and can lead to security holes there. It is valid JSON to
|
||||
// escape them, so we do so unconditionally.
|
||||
// See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
|
||||
if c == '\u2028' || c == '\u2029' {
|
||||
if start < i {
|
||||
buf.Write(s[start:i])
|
||||
}
|
||||
buf.WriteString(`\u202`)
|
||||
buf.WriteByte(hex[c&0xF])
|
||||
i += size
|
||||
start = i
|
||||
continue
|
||||
}
|
||||
i += size
|
||||
}
|
||||
if start < len(s) {
|
||||
buf.Write(s[start:])
|
||||
}
|
||||
buf.WriteByte('"')
|
||||
}
|
||||
|
||||
// UnquoteBytes will decode []byte containing json string to go string
|
||||
// ported from encoding/json/decode.go
|
||||
func UnquoteBytes(s []byte) (t []byte, ok bool) {
|
||||
if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' {
|
||||
return
|
||||
}
|
||||
s = s[1 : len(s)-1]
|
||||
|
||||
// Check for unusual characters. If there are none,
|
||||
// then no unquoting is needed, so return a slice of the
|
||||
// original bytes.
|
||||
r := 0
|
||||
for r < len(s) {
|
||||
c := s[r]
|
||||
if c == '\\' || c == '"' || c < ' ' {
|
||||
break
|
||||
}
|
||||
if c < utf8.RuneSelf {
|
||||
r++
|
||||
continue
|
||||
}
|
||||
rr, size := utf8.DecodeRune(s[r:])
|
||||
if rr == utf8.RuneError && size == 1 {
|
||||
break
|
||||
}
|
||||
r += size
|
||||
}
|
||||
if r == len(s) {
|
||||
return s, true
|
||||
}
|
||||
|
||||
b := make([]byte, len(s)+2*utf8.UTFMax)
|
||||
w := copy(b, s[0:r])
|
||||
for r < len(s) {
|
||||
// Out of room? Can only happen if s is full of
|
||||
// malformed UTF-8 and we're replacing each
|
||||
// byte with RuneError.
|
||||
if w >= len(b)-2*utf8.UTFMax {
|
||||
nb := make([]byte, (len(b)+utf8.UTFMax)*2)
|
||||
copy(nb, b[0:w])
|
||||
b = nb
|
||||
}
|
||||
switch c := s[r]; {
|
||||
case c == '\\':
|
||||
r++
|
||||
if r >= len(s) {
|
||||
return
|
||||
}
|
||||
switch s[r] {
|
||||
default:
|
||||
return
|
||||
case '"', '\\', '/', '\'':
|
||||
b[w] = s[r]
|
||||
r++
|
||||
w++
|
||||
case 'b':
|
||||
b[w] = '\b'
|
||||
r++
|
||||
w++
|
||||
case 'f':
|
||||
b[w] = '\f'
|
||||
r++
|
||||
w++
|
||||
case 'n':
|
||||
b[w] = '\n'
|
||||
r++
|
||||
w++
|
||||
case 'r':
|
||||
b[w] = '\r'
|
||||
r++
|
||||
w++
|
||||
case 't':
|
||||
b[w] = '\t'
|
||||
r++
|
||||
w++
|
||||
case 'u':
|
||||
r--
|
||||
rr := getu4(s[r:])
|
||||
if rr < 0 {
|
||||
return
|
||||
}
|
||||
r += 6
|
||||
if utf16.IsSurrogate(rr) {
|
||||
rr1 := getu4(s[r:])
|
||||
if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar {
|
||||
// A valid pair; consume.
|
||||
r += 6
|
||||
w += utf8.EncodeRune(b[w:], dec)
|
||||
break
|
||||
}
|
||||
// Invalid surrogate; fall back to replacement rune.
|
||||
rr = unicode.ReplacementChar
|
||||
}
|
||||
w += utf8.EncodeRune(b[w:], rr)
|
||||
}
|
||||
|
||||
// Quote, control characters are invalid.
|
||||
case c == '"', c < ' ':
|
||||
return
|
||||
|
||||
// ASCII
|
||||
case c < utf8.RuneSelf:
|
||||
b[w] = c
|
||||
r++
|
||||
w++
|
||||
|
||||
// Coerce to well-formed UTF-8.
|
||||
default:
|
||||
rr, size := utf8.DecodeRune(s[r:])
|
||||
r += size
|
||||
w += utf8.EncodeRune(b[w:], rr)
|
||||
}
|
||||
}
|
||||
return b[0:w], true
|
||||
}
|
||||
|
||||
// getu4 decodes \uXXXX from the beginning of s, returning the hex value,
|
||||
// or it returns -1.
|
||||
func getu4(s []byte) rune {
|
||||
if len(s) < 6 || s[0] != '\\' || s[1] != 'u' {
|
||||
return -1
|
||||
}
|
||||
r, err := strconv.ParseUint(string(s[2:6]), 16, 64)
|
||||
if err != nil {
|
||||
return -1
|
||||
}
|
||||
return rune(r)
|
||||
}
|
||||
|
||||
// TODO(pquerna): consider combining wibth the normal byte mask.
|
||||
var lt [256]bool = [256]bool{
|
||||
false, /* 0 */
|
||||
false, /* 1 */
|
||||
false, /* 2 */
|
||||
false, /* 3 */
|
||||
false, /* 4 */
|
||||
false, /* 5 */
|
||||
false, /* 6 */
|
||||
false, /* 7 */
|
||||
false, /* 8 */
|
||||
false, /* 9 */
|
||||
false, /* 10 */
|
||||
false, /* 11 */
|
||||
false, /* 12 */
|
||||
false, /* 13 */
|
||||
false, /* 14 */
|
||||
false, /* 15 */
|
||||
false, /* 16 */
|
||||
false, /* 17 */
|
||||
false, /* 18 */
|
||||
false, /* 19 */
|
||||
false, /* 20 */
|
||||
false, /* 21 */
|
||||
false, /* 22 */
|
||||
false, /* 23 */
|
||||
false, /* 24 */
|
||||
false, /* 25 */
|
||||
false, /* 26 */
|
||||
false, /* 27 */
|
||||
false, /* 28 */
|
||||
false, /* 29 */
|
||||
false, /* 30 */
|
||||
false, /* 31 */
|
||||
true, /* 32 */
|
||||
true, /* 33 */
|
||||
false, /* 34 */
|
||||
true, /* 35 */
|
||||
true, /* 36 */
|
||||
true, /* 37 */
|
||||
false, /* 38 */
|
||||
true, /* 39 */
|
||||
true, /* 40 */
|
||||
true, /* 41 */
|
||||
true, /* 42 */
|
||||
true, /* 43 */
|
||||
true, /* 44 */
|
||||
true, /* 45 */
|
||||
true, /* 46 */
|
||||
true, /* 47 */
|
||||
true, /* 48 */
|
||||
true, /* 49 */
|
||||
true, /* 50 */
|
||||
true, /* 51 */
|
||||
true, /* 52 */
|
||||
true, /* 53 */
|
||||
true, /* 54 */
|
||||
true, /* 55 */
|
||||
true, /* 56 */
|
||||
true, /* 57 */
|
||||
true, /* 58 */
|
||||
true, /* 59 */
|
||||
false, /* 60 */
|
||||
true, /* 61 */
|
||||
false, /* 62 */
|
||||
true, /* 63 */
|
||||
true, /* 64 */
|
||||
true, /* 65 */
|
||||
true, /* 66 */
|
||||
true, /* 67 */
|
||||
true, /* 68 */
|
||||
true, /* 69 */
|
||||
true, /* 70 */
|
||||
true, /* 71 */
|
||||
true, /* 72 */
|
||||
true, /* 73 */
|
||||
true, /* 74 */
|
||||
true, /* 75 */
|
||||
true, /* 76 */
|
||||
true, /* 77 */
|
||||
true, /* 78 */
|
||||
true, /* 79 */
|
||||
true, /* 80 */
|
||||
true, /* 81 */
|
||||
true, /* 82 */
|
||||
true, /* 83 */
|
||||
true, /* 84 */
|
||||
true, /* 85 */
|
||||
true, /* 86 */
|
||||
true, /* 87 */
|
||||
true, /* 88 */
|
||||
true, /* 89 */
|
||||
true, /* 90 */
|
||||
true, /* 91 */
|
||||
false, /* 92 */
|
||||
true, /* 93 */
|
||||
true, /* 94 */
|
||||
true, /* 95 */
|
||||
true, /* 96 */
|
||||
true, /* 97 */
|
||||
true, /* 98 */
|
||||
true, /* 99 */
|
||||
true, /* 100 */
|
||||
true, /* 101 */
|
||||
true, /* 102 */
|
||||
true, /* 103 */
|
||||
true, /* 104 */
|
||||
true, /* 105 */
|
||||
true, /* 106 */
|
||||
true, /* 107 */
|
||||
true, /* 108 */
|
||||
true, /* 109 */
|
||||
true, /* 110 */
|
||||
true, /* 111 */
|
||||
true, /* 112 */
|
||||
true, /* 113 */
|
||||
true, /* 114 */
|
||||
true, /* 115 */
|
||||
true, /* 116 */
|
||||
true, /* 117 */
|
||||
true, /* 118 */
|
||||
true, /* 119 */
|
||||
true, /* 120 */
|
||||
true, /* 121 */
|
||||
true, /* 122 */
|
||||
true, /* 123 */
|
||||
true, /* 124 */
|
||||
true, /* 125 */
|
||||
true, /* 126 */
|
||||
true, /* 127 */
|
||||
true, /* 128 */
|
||||
true, /* 129 */
|
||||
true, /* 130 */
|
||||
true, /* 131 */
|
||||
true, /* 132 */
|
||||
true, /* 133 */
|
||||
true, /* 134 */
|
||||
true, /* 135 */
|
||||
true, /* 136 */
|
||||
true, /* 137 */
|
||||
true, /* 138 */
|
||||
true, /* 139 */
|
||||
true, /* 140 */
|
||||
true, /* 141 */
|
||||
true, /* 142 */
|
||||
true, /* 143 */
|
||||
true, /* 144 */
|
||||
true, /* 145 */
|
||||
true, /* 146 */
|
||||
true, /* 147 */
|
||||
true, /* 148 */
|
||||
true, /* 149 */
|
||||
true, /* 150 */
|
||||
true, /* 151 */
|
||||
true, /* 152 */
|
||||
true, /* 153 */
|
||||
true, /* 154 */
|
||||
true, /* 155 */
|
||||
true, /* 156 */
|
||||
true, /* 157 */
|
||||
true, /* 158 */
|
||||
true, /* 159 */
|
||||
true, /* 160 */
|
||||
true, /* 161 */
|
||||
true, /* 162 */
|
||||
true, /* 163 */
|
||||
true, /* 164 */
|
||||
true, /* 165 */
|
||||
true, /* 166 */
|
||||
true, /* 167 */
|
||||
true, /* 168 */
|
||||
true, /* 169 */
|
||||
true, /* 170 */
|
||||
true, /* 171 */
|
||||
true, /* 172 */
|
||||
true, /* 173 */
|
||||
true, /* 174 */
|
||||
true, /* 175 */
|
||||
true, /* 176 */
|
||||
true, /* 177 */
|
||||
true, /* 178 */
|
||||
true, /* 179 */
|
||||
true, /* 180 */
|
||||
true, /* 181 */
|
||||
true, /* 182 */
|
||||
true, /* 183 */
|
||||
true, /* 184 */
|
||||
true, /* 185 */
|
||||
true, /* 186 */
|
||||
true, /* 187 */
|
||||
true, /* 188 */
|
||||
true, /* 189 */
|
||||
true, /* 190 */
|
||||
true, /* 191 */
|
||||
true, /* 192 */
|
||||
true, /* 193 */
|
||||
true, /* 194 */
|
||||
true, /* 195 */
|
||||
true, /* 196 */
|
||||
true, /* 197 */
|
||||
true, /* 198 */
|
||||
true, /* 199 */
|
||||
true, /* 200 */
|
||||
true, /* 201 */
|
||||
true, /* 202 */
|
||||
true, /* 203 */
|
||||
true, /* 204 */
|
||||
true, /* 205 */
|
||||
true, /* 206 */
|
||||
true, /* 207 */
|
||||
true, /* 208 */
|
||||
true, /* 209 */
|
||||
true, /* 210 */
|
||||
true, /* 211 */
|
||||
true, /* 212 */
|
||||
true, /* 213 */
|
||||
true, /* 214 */
|
||||
true, /* 215 */
|
||||
true, /* 216 */
|
||||
true, /* 217 */
|
||||
true, /* 218 */
|
||||
true, /* 219 */
|
||||
true, /* 220 */
|
||||
true, /* 221 */
|
||||
true, /* 222 */
|
||||
true, /* 223 */
|
||||
true, /* 224 */
|
||||
true, /* 225 */
|
||||
true, /* 226 */
|
||||
true, /* 227 */
|
||||
true, /* 228 */
|
||||
true, /* 229 */
|
||||
true, /* 230 */
|
||||
true, /* 231 */
|
||||
true, /* 232 */
|
||||
true, /* 233 */
|
||||
true, /* 234 */
|
||||
true, /* 235 */
|
||||
true, /* 236 */
|
||||
true, /* 237 */
|
||||
true, /* 238 */
|
||||
true, /* 239 */
|
||||
true, /* 240 */
|
||||
true, /* 241 */
|
||||
true, /* 242 */
|
||||
true, /* 243 */
|
||||
true, /* 244 */
|
||||
true, /* 245 */
|
||||
true, /* 246 */
|
||||
true, /* 247 */
|
||||
true, /* 248 */
|
||||
true, /* 249 */
|
||||
true, /* 250 */
|
||||
true, /* 251 */
|
||||
true, /* 252 */
|
||||
true, /* 253 */
|
||||
true, /* 254 */
|
||||
true, /* 255 */
|
||||
}
|
|
@ -1,944 +0,0 @@
|
|||
/**
|
||||
* Copyright 2014 Paul Querna
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Portions of this file are on derived from yajl: <https://github.com/lloyd/yajl> */
|
||||
/*
|
||||
* Copyright (c) 2007-2014, Lloyd Hilaiel <me@lloyd.io>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
type FFParseState int
|
||||
|
||||
const (
|
||||
FFParse_map_start FFParseState = iota
|
||||
FFParse_want_key
|
||||
FFParse_want_colon
|
||||
FFParse_want_value
|
||||
FFParse_after_value
|
||||
)
|
||||
|
||||
type FFTok int
|
||||
|
||||
const (
|
||||
FFTok_init FFTok = iota
|
||||
FFTok_bool FFTok = iota
|
||||
FFTok_colon FFTok = iota
|
||||
FFTok_comma FFTok = iota
|
||||
FFTok_eof FFTok = iota
|
||||
FFTok_error FFTok = iota
|
||||
FFTok_left_brace FFTok = iota
|
||||
FFTok_left_bracket FFTok = iota
|
||||
FFTok_null FFTok = iota
|
||||
FFTok_right_brace FFTok = iota
|
||||
FFTok_right_bracket FFTok = iota
|
||||
|
||||
/* we differentiate between integers and doubles to allow the
|
||||
* parser to interpret the number without re-scanning */
|
||||
FFTok_integer FFTok = iota
|
||||
FFTok_double FFTok = iota
|
||||
|
||||
FFTok_string FFTok = iota
|
||||
|
||||
/* comment tokens are not currently returned to the parser, ever */
|
||||
FFTok_comment FFTok = iota
|
||||
)
|
||||
|
||||
type FFErr int
|
||||
|
||||
const (
|
||||
FFErr_e_ok FFErr = iota
|
||||
FFErr_io FFErr = iota
|
||||
FFErr_string_invalid_utf8 FFErr = iota
|
||||
FFErr_string_invalid_escaped_char FFErr = iota
|
||||
FFErr_string_invalid_json_char FFErr = iota
|
||||
FFErr_string_invalid_hex_char FFErr = iota
|
||||
FFErr_invalid_char FFErr = iota
|
||||
FFErr_invalid_string FFErr = iota
|
||||
FFErr_missing_integer_after_decimal FFErr = iota
|
||||
FFErr_missing_integer_after_exponent FFErr = iota
|
||||
FFErr_missing_integer_after_minus FFErr = iota
|
||||
FFErr_unallowed_comment FFErr = iota
|
||||
FFErr_incomplete_comment FFErr = iota
|
||||
FFErr_unexpected_token_type FFErr = iota // TODO: improve this error
|
||||
)
|
||||
|
||||
type FFLexer struct {
|
||||
reader *ffReader
|
||||
Output DecodingBuffer
|
||||
Token FFTok
|
||||
Error FFErr
|
||||
BigError error
|
||||
// TODO: convert all of this to an interface
|
||||
lastCurrentChar int
|
||||
captureAll bool
|
||||
buf Buffer
|
||||
}
|
||||
|
||||
func NewFFLexer(input []byte) *FFLexer {
|
||||
fl := &FFLexer{
|
||||
Token: FFTok_init,
|
||||
Error: FFErr_e_ok,
|
||||
reader: newffReader(input),
|
||||
Output: &Buffer{},
|
||||
}
|
||||
// TODO: guess size?
|
||||
//fl.Output.Grow(64)
|
||||
return fl
|
||||
}
|
||||
|
||||
type LexerError struct {
|
||||
offset int
|
||||
line int
|
||||
char int
|
||||
err error
|
||||
}
|
||||
|
||||
// Reset the Lexer and add new input.
|
||||
func (ffl *FFLexer) Reset(input []byte) {
|
||||
ffl.Token = FFTok_init
|
||||
ffl.Error = FFErr_e_ok
|
||||
ffl.BigError = nil
|
||||
ffl.reader.Reset(input)
|
||||
ffl.lastCurrentChar = 0
|
||||
ffl.Output.Reset()
|
||||
}
|
||||
|
||||
func (le *LexerError) Error() string {
|
||||
return fmt.Sprintf(`ffjson error: (%T)%s offset=%d line=%d char=%d`,
|
||||
le.err, le.err.Error(),
|
||||
le.offset, le.line, le.char)
|
||||
}
|
||||
|
||||
func (ffl *FFLexer) WrapErr(err error) error {
|
||||
line, char := ffl.reader.PosWithLine()
|
||||
// TOOD: calcualte lines/characters based on offset
|
||||
return &LexerError{
|
||||
offset: ffl.reader.Pos(),
|
||||
line: line,
|
||||
char: char,
|
||||
err: err,
|
||||
}
|
||||
}
|
||||
|
||||
func (ffl *FFLexer) scanReadByte() (byte, error) {
|
||||
var c byte
|
||||
var err error
|
||||
if ffl.captureAll {
|
||||
c, err = ffl.reader.ReadByte()
|
||||
} else {
|
||||
c, err = ffl.reader.ReadByteNoWS()
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
ffl.Error = FFErr_io
|
||||
ffl.BigError = err
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (ffl *FFLexer) readByte() (byte, error) {
|
||||
|
||||
c, err := ffl.reader.ReadByte()
|
||||
if err != nil {
|
||||
ffl.Error = FFErr_io
|
||||
ffl.BigError = err
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (ffl *FFLexer) unreadByte() {
|
||||
ffl.reader.UnreadByte()
|
||||
}
|
||||
|
||||
func (ffl *FFLexer) wantBytes(want []byte, iftrue FFTok) FFTok {
|
||||
for _, b := range want {
|
||||
c, err := ffl.readByte()
|
||||
|
||||
if err != nil {
|
||||
return FFTok_error
|
||||
}
|
||||
|
||||
if c != b {
|
||||
ffl.unreadByte()
|
||||
// fmt.Printf("wanted bytes: %s\n", string(want))
|
||||
// TODO(pquerna): thsi is a bad error message
|
||||
ffl.Error = FFErr_invalid_string
|
||||
return FFTok_error
|
||||
}
|
||||
|
||||
ffl.Output.WriteByte(c)
|
||||
}
|
||||
|
||||
return iftrue
|
||||
}
|
||||
|
||||
func (ffl *FFLexer) lexComment() FFTok {
|
||||
c, err := ffl.readByte()
|
||||
if err != nil {
|
||||
return FFTok_error
|
||||
}
|
||||
|
||||
if c == '/' {
|
||||
// a // comment, scan until line ends.
|
||||
for {
|
||||
c, err := ffl.readByte()
|
||||
if err != nil {
|
||||
return FFTok_error
|
||||
}
|
||||
|
||||
if c == '\n' {
|
||||
return FFTok_comment
|
||||
}
|
||||
}
|
||||
} else if c == '*' {
|
||||
// a /* */ comment, scan */
|
||||
for {
|
||||
c, err := ffl.readByte()
|
||||
if err != nil {
|
||||
return FFTok_error
|
||||
}
|
||||
|
||||
if c == '*' {
|
||||
c, err := ffl.readByte()
|
||||
|
||||
if err != nil {
|
||||
return FFTok_error
|
||||
}
|
||||
|
||||
if c == '/' {
|
||||
return FFTok_comment
|
||||
}
|
||||
|
||||
ffl.Error = FFErr_incomplete_comment
|
||||
return FFTok_error
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ffl.Error = FFErr_incomplete_comment
|
||||
return FFTok_error
|
||||
}
|
||||
}
|
||||
|
||||
func (ffl *FFLexer) lexString() FFTok {
|
||||
if ffl.captureAll {
|
||||
ffl.buf.Reset()
|
||||
err := ffl.reader.SliceString(&ffl.buf)
|
||||
|
||||
if err != nil {
|
||||
ffl.BigError = err
|
||||
return FFTok_error
|
||||
}
|
||||
|
||||
WriteJson(ffl.Output, ffl.buf.Bytes())
|
||||
|
||||
return FFTok_string
|
||||
} else {
|
||||
err := ffl.reader.SliceString(ffl.Output)
|
||||
|
||||
if err != nil {
|
||||
ffl.BigError = err
|
||||
return FFTok_error
|
||||
}
|
||||
|
||||
return FFTok_string
|
||||
}
|
||||
}
|
||||
|
||||
func (ffl *FFLexer) lexNumber() FFTok {
|
||||
var numRead int = 0
|
||||
tok := FFTok_integer
|
||||
|
||||
c, err := ffl.readByte()
|
||||
if err != nil {
|
||||
return FFTok_error
|
||||
}
|
||||
|
||||
/* optional leading minus */
|
||||
if c == '-' {
|
||||
ffl.Output.WriteByte(c)
|
||||
c, err = ffl.readByte()
|
||||
if err != nil {
|
||||
return FFTok_error
|
||||
}
|
||||
}
|
||||
|
||||
/* a single zero, or a series of integers */
|
||||
if c == '0' {
|
||||
ffl.Output.WriteByte(c)
|
||||
c, err = ffl.readByte()
|
||||
if err != nil {
|
||||
return FFTok_error
|
||||
}
|
||||
} else if c >= '1' && c <= '9' {
|
||||
for c >= '0' && c <= '9' {
|
||||
ffl.Output.WriteByte(c)
|
||||
c, err = ffl.readByte()
|
||||
if err != nil {
|
||||
return FFTok_error
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ffl.unreadByte()
|
||||
ffl.Error = FFErr_missing_integer_after_minus
|
||||
return FFTok_error
|
||||
}
|
||||
|
||||
if c == '.' {
|
||||
numRead = 0
|
||||
ffl.Output.WriteByte(c)
|
||||
c, err = ffl.readByte()
|
||||
if err != nil {
|
||||
return FFTok_error
|
||||
}
|
||||
|
||||
for c >= '0' && c <= '9' {
|
||||
ffl.Output.WriteByte(c)
|
||||
numRead++
|
||||
c, err = ffl.readByte()
|
||||
if err != nil {
|
||||
return FFTok_error
|
||||
}
|
||||
}
|
||||
|
||||
if numRead == 0 {
|
||||
ffl.unreadByte()
|
||||
|
||||
ffl.Error = FFErr_missing_integer_after_decimal
|
||||
return FFTok_error
|
||||
}
|
||||
|
||||
tok = FFTok_double
|
||||
}
|
||||
|
||||
/* optional exponent (indicates this is floating point) */
|
||||
if c == 'e' || c == 'E' {
|
||||
numRead = 0
|
||||
ffl.Output.WriteByte(c)
|
||||
|
||||
c, err = ffl.readByte()
|
||||
if err != nil {
|
||||
return FFTok_error
|
||||
}
|
||||
|
||||
/* optional sign */
|
||||
if c == '+' || c == '-' {
|
||||
ffl.Output.WriteByte(c)
|
||||
c, err = ffl.readByte()
|
||||
if err != nil {
|
||||
return FFTok_error
|
||||
}
|
||||
}
|
||||
|
||||
for c >= '0' && c <= '9' {
|
||||
ffl.Output.WriteByte(c)
|
||||
numRead++
|
||||
c, err = ffl.readByte()
|
||||
if err != nil {
|
||||
return FFTok_error
|
||||
}
|
||||
}
|
||||
|
||||
if numRead == 0 {
|
||||
ffl.Error = FFErr_missing_integer_after_exponent
|
||||
return FFTok_error
|
||||
}
|
||||
|
||||
tok = FFTok_double
|
||||
}
|
||||
|
||||
ffl.unreadByte()
|
||||
|
||||
return tok
|
||||
}
|
||||
|
||||
var true_bytes = []byte{'r', 'u', 'e'}
|
||||
var false_bytes = []byte{'a', 'l', 's', 'e'}
|
||||
var null_bytes = []byte{'u', 'l', 'l'}
|
||||
|
||||
func (ffl *FFLexer) Scan() FFTok {
|
||||
tok := FFTok_error
|
||||
if ffl.captureAll == false {
|
||||
ffl.Output.Reset()
|
||||
}
|
||||
ffl.Token = FFTok_init
|
||||
|
||||
for {
|
||||
c, err := ffl.scanReadByte()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
return FFTok_eof
|
||||
} else {
|
||||
return FFTok_error
|
||||
}
|
||||
}
|
||||
|
||||
switch c {
|
||||
case '{':
|
||||
tok = FFTok_left_bracket
|
||||
if ffl.captureAll {
|
||||
ffl.Output.WriteByte('{')
|
||||
}
|
||||
goto lexed
|
||||
case '}':
|
||||
tok = FFTok_right_bracket
|
||||
if ffl.captureAll {
|
||||
ffl.Output.WriteByte('}')
|
||||
}
|
||||
goto lexed
|
||||
case '[':
|
||||
tok = FFTok_left_brace
|
||||
if ffl.captureAll {
|
||||
ffl.Output.WriteByte('[')
|
||||
}
|
||||
goto lexed
|
||||
case ']':
|
||||
tok = FFTok_right_brace
|
||||
if ffl.captureAll {
|
||||
ffl.Output.WriteByte(']')
|
||||
}
|
||||
goto lexed
|
||||
case ',':
|
||||
tok = FFTok_comma
|
||||
if ffl.captureAll {
|
||||
ffl.Output.WriteByte(',')
|
||||
}
|
||||
goto lexed
|
||||
case ':':
|
||||
tok = FFTok_colon
|
||||
if ffl.captureAll {
|
||||
ffl.Output.WriteByte(':')
|
||||
}
|
||||
goto lexed
|
||||
case '\t', '\n', '\v', '\f', '\r', ' ':
|
||||
if ffl.captureAll {
|
||||
ffl.Output.WriteByte(c)
|
||||
}
|
||||
break
|
||||
case 't':
|
||||
ffl.Output.WriteByte('t')
|
||||
tok = ffl.wantBytes(true_bytes, FFTok_bool)
|
||||
goto lexed
|
||||
case 'f':
|
||||
ffl.Output.WriteByte('f')
|
||||
tok = ffl.wantBytes(false_bytes, FFTok_bool)
|
||||
goto lexed
|
||||
case 'n':
|
||||
ffl.Output.WriteByte('n')
|
||||
tok = ffl.wantBytes(null_bytes, FFTok_null)
|
||||
goto lexed
|
||||
case '"':
|
||||
tok = ffl.lexString()
|
||||
goto lexed
|
||||
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||
ffl.unreadByte()
|
||||
tok = ffl.lexNumber()
|
||||
goto lexed
|
||||
case '/':
|
||||
tok = ffl.lexComment()
|
||||
goto lexed
|
||||
default:
|
||||
tok = FFTok_error
|
||||
ffl.Error = FFErr_invalid_char
|
||||
}
|
||||
}
|
||||
|
||||
lexed:
|
||||
ffl.Token = tok
|
||||
return tok
|
||||
}
|
||||
|
||||
func (ffl *FFLexer) scanField(start FFTok, capture bool) ([]byte, error) {
|
||||
switch start {
|
||||
case FFTok_left_brace,
|
||||
FFTok_left_bracket:
|
||||
{
|
||||
end := FFTok_right_brace
|
||||
if start == FFTok_left_bracket {
|
||||
end = FFTok_right_bracket
|
||||
if capture {
|
||||
ffl.Output.WriteByte('{')
|
||||
}
|
||||
} else {
|
||||
if capture {
|
||||
ffl.Output.WriteByte('[')
|
||||
}
|
||||
}
|
||||
|
||||
depth := 1
|
||||
if capture {
|
||||
ffl.captureAll = true
|
||||
}
|
||||
// TODO: work.
|
||||
scanloop:
|
||||
for {
|
||||
tok := ffl.Scan()
|
||||
//fmt.Printf("capture-token: %v end: %v depth: %v\n", tok, end, depth)
|
||||
switch tok {
|
||||
case FFTok_eof:
|
||||
return nil, errors.New("ffjson: unexpected EOF")
|
||||
case FFTok_error:
|
||||
if ffl.BigError != nil {
|
||||
return nil, ffl.BigError
|
||||
}
|
||||
return nil, ffl.Error.ToError()
|
||||
case end:
|
||||
depth--
|
||||
if depth == 0 {
|
||||
break scanloop
|
||||
}
|
||||
case start:
|
||||
depth++
|
||||
}
|
||||
}
|
||||
|
||||
if capture {
|
||||
ffl.captureAll = false
|
||||
}
|
||||
|
||||
if capture {
|
||||
return ffl.Output.Bytes(), nil
|
||||
} else {
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
case FFTok_bool,
|
||||
FFTok_integer,
|
||||
FFTok_null,
|
||||
FFTok_double:
|
||||
// simple value, return it.
|
||||
if capture {
|
||||
return ffl.Output.Bytes(), nil
|
||||
} else {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
case FFTok_string:
|
||||
//TODO(pquerna): so, other users expect this to be a quoted string :(
|
||||
if capture {
|
||||
ffl.buf.Reset()
|
||||
WriteJson(&ffl.buf, ffl.Output.Bytes())
|
||||
return ffl.buf.Bytes(), nil
|
||||
} else {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("ffjson: invalid capture type: %v", start)
|
||||
}
|
||||
panic("not reached")
|
||||
}
|
||||
|
||||
// Captures an entire field value, including recursive objects,
|
||||
// and converts them to a []byte suitable to pass to a sub-object's
|
||||
// UnmarshalJSON
|
||||
func (ffl *FFLexer) CaptureField(start FFTok) ([]byte, error) {
|
||||
return ffl.scanField(start, true)
|
||||
}
|
||||
|
||||
func (ffl *FFLexer) SkipField(start FFTok) error {
|
||||
_, err := ffl.scanField(start, false)
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO(pquerna): return line number and offset.
|
||||
func (err FFErr) ToError() error {
|
||||
switch err {
|
||||
case FFErr_e_ok:
|
||||
return nil
|
||||
case FFErr_io:
|
||||
return errors.New("ffjson: IO error")
|
||||
case FFErr_string_invalid_utf8:
|
||||
return errors.New("ffjson: string with invalid UTF-8 sequence")
|
||||
case FFErr_string_invalid_escaped_char:
|
||||
return errors.New("ffjson: string with invalid escaped character")
|
||||
case FFErr_string_invalid_json_char:
|
||||
return errors.New("ffjson: string with invalid JSON character")
|
||||
case FFErr_string_invalid_hex_char:
|
||||
return errors.New("ffjson: string with invalid hex character")
|
||||
case FFErr_invalid_char:
|
||||
return errors.New("ffjson: invalid character")
|
||||
case FFErr_invalid_string:
|
||||
return errors.New("ffjson: invalid string")
|
||||
case FFErr_missing_integer_after_decimal:
|
||||
return errors.New("ffjson: missing integer after decimal")
|
||||
case FFErr_missing_integer_after_exponent:
|
||||
return errors.New("ffjson: missing integer after exponent")
|
||||
case FFErr_missing_integer_after_minus:
|
||||
return errors.New("ffjson: missing integer after minus")
|
||||
case FFErr_unallowed_comment:
|
||||
return errors.New("ffjson: unallowed comment")
|
||||
case FFErr_incomplete_comment:
|
||||
return errors.New("ffjson: incomplete comment")
|
||||
case FFErr_unexpected_token_type:
|
||||
return errors.New("ffjson: unexpected token sequence")
|
||||
}
|
||||
|
||||
panic(fmt.Sprintf("unknown error type: %v ", err))
|
||||
}
|
||||
|
||||
func (state FFParseState) String() string {
|
||||
switch state {
|
||||
case FFParse_map_start:
|
||||
return "map:start"
|
||||
case FFParse_want_key:
|
||||
return "want_key"
|
||||
case FFParse_want_colon:
|
||||
return "want_colon"
|
||||
case FFParse_want_value:
|
||||
return "want_value"
|
||||
case FFParse_after_value:
|
||||
return "after_value"
|
||||
}
|
||||
|
||||
panic(fmt.Sprintf("unknown parse state: %d", int(state)))
|
||||
}
|
||||
|
||||
func (tok FFTok) String() string {
|
||||
switch tok {
|
||||
case FFTok_init:
|
||||
return "tok:init"
|
||||
case FFTok_bool:
|
||||
return "tok:bool"
|
||||
case FFTok_colon:
|
||||
return "tok:colon"
|
||||
case FFTok_comma:
|
||||
return "tok:comma"
|
||||
case FFTok_eof:
|
||||
return "tok:eof"
|
||||
case FFTok_error:
|
||||
return "tok:error"
|
||||
case FFTok_left_brace:
|
||||
return "tok:left_brace"
|
||||
case FFTok_left_bracket:
|
||||
return "tok:left_bracket"
|
||||
case FFTok_null:
|
||||
return "tok:null"
|
||||
case FFTok_right_brace:
|
||||
return "tok:right_brace"
|
||||
case FFTok_right_bracket:
|
||||
return "tok:right_bracket"
|
||||
case FFTok_integer:
|
||||
return "tok:integer"
|
||||
case FFTok_double:
|
||||
return "tok:double"
|
||||
case FFTok_string:
|
||||
return "tok:string"
|
||||
case FFTok_comment:
|
||||
return "comment"
|
||||
}
|
||||
|
||||
panic(fmt.Sprintf("unknown token: %d", int(tok)))
|
||||
}
|
||||
|
||||
/* a lookup table which lets us quickly determine three things:
|
||||
* cVEC - valid escaped control char
|
||||
* note. the solidus '/' may be escaped or not.
|
||||
* cIJC - invalid json char
|
||||
* cVHC - valid hex char
|
||||
* cNFP - needs further processing (from a string scanning perspective)
|
||||
* cNUC - needs utf8 checking when enabled (from a string scanning perspective)
|
||||
*/
|
||||
|
||||
const (
|
||||
cVEC int8 = 0x01
|
||||
cIJC int8 = 0x02
|
||||
cVHC int8 = 0x04
|
||||
cNFP int8 = 0x08
|
||||
cNUC int8 = 0x10
|
||||
)
|
||||
|
||||
var byteLookupTable [256]int8 = [256]int8{
|
||||
cIJC, /* 0 */
|
||||
cIJC, /* 1 */
|
||||
cIJC, /* 2 */
|
||||
cIJC, /* 3 */
|
||||
cIJC, /* 4 */
|
||||
cIJC, /* 5 */
|
||||
cIJC, /* 6 */
|
||||
cIJC, /* 7 */
|
||||
cIJC, /* 8 */
|
||||
cIJC, /* 9 */
|
||||
cIJC, /* 10 */
|
||||
cIJC, /* 11 */
|
||||
cIJC, /* 12 */
|
||||
cIJC, /* 13 */
|
||||
cIJC, /* 14 */
|
||||
cIJC, /* 15 */
|
||||
cIJC, /* 16 */
|
||||
cIJC, /* 17 */
|
||||
cIJC, /* 18 */
|
||||
cIJC, /* 19 */
|
||||
cIJC, /* 20 */
|
||||
cIJC, /* 21 */
|
||||
cIJC, /* 22 */
|
||||
cIJC, /* 23 */
|
||||
cIJC, /* 24 */
|
||||
cIJC, /* 25 */
|
||||
cIJC, /* 26 */
|
||||
cIJC, /* 27 */
|
||||
cIJC, /* 28 */
|
||||
cIJC, /* 29 */
|
||||
cIJC, /* 30 */
|
||||
cIJC, /* 31 */
|
||||
0, /* 32 */
|
||||
0, /* 33 */
|
||||
cVEC | cIJC | cNFP, /* 34 */
|
||||
0, /* 35 */
|
||||
0, /* 36 */
|
||||
0, /* 37 */
|
||||
0, /* 38 */
|
||||
0, /* 39 */
|
||||
0, /* 40 */
|
||||
0, /* 41 */
|
||||
0, /* 42 */
|
||||
0, /* 43 */
|
||||
0, /* 44 */
|
||||
0, /* 45 */
|
||||
0, /* 46 */
|
||||
cVEC, /* 47 */
|
||||
cVHC, /* 48 */
|
||||
cVHC, /* 49 */
|
||||
cVHC, /* 50 */
|
||||
cVHC, /* 51 */
|
||||
cVHC, /* 52 */
|
||||
cVHC, /* 53 */
|
||||
cVHC, /* 54 */
|
||||
cVHC, /* 55 */
|
||||
cVHC, /* 56 */
|
||||
cVHC, /* 57 */
|
||||
0, /* 58 */
|
||||
0, /* 59 */
|
||||
0, /* 60 */
|
||||
0, /* 61 */
|
||||
0, /* 62 */
|
||||
0, /* 63 */
|
||||
0, /* 64 */
|
||||
cVHC, /* 65 */
|
||||
cVHC, /* 66 */
|
||||
cVHC, /* 67 */
|
||||
cVHC, /* 68 */
|
||||
cVHC, /* 69 */
|
||||
cVHC, /* 70 */
|
||||
0, /* 71 */
|
||||
0, /* 72 */
|
||||
0, /* 73 */
|
||||
0, /* 74 */
|
||||
0, /* 75 */
|
||||
0, /* 76 */
|
||||
0, /* 77 */
|
||||
0, /* 78 */
|
||||
0, /* 79 */
|
||||
0, /* 80 */
|
||||
0, /* 81 */
|
||||
0, /* 82 */
|
||||
0, /* 83 */
|
||||
0, /* 84 */
|
||||
0, /* 85 */
|
||||
0, /* 86 */
|
||||
0, /* 87 */
|
||||
0, /* 88 */
|
||||
0, /* 89 */
|
||||
0, /* 90 */
|
||||
0, /* 91 */
|
||||
cVEC | cIJC | cNFP, /* 92 */
|
||||
0, /* 93 */
|
||||
0, /* 94 */
|
||||
0, /* 95 */
|
||||
0, /* 96 */
|
||||
cVHC, /* 97 */
|
||||
cVEC | cVHC, /* 98 */
|
||||
cVHC, /* 99 */
|
||||
cVHC, /* 100 */
|
||||
cVHC, /* 101 */
|
||||
cVEC | cVHC, /* 102 */
|
||||
0, /* 103 */
|
||||
0, /* 104 */
|
||||
0, /* 105 */
|
||||
0, /* 106 */
|
||||
0, /* 107 */
|
||||
0, /* 108 */
|
||||
0, /* 109 */
|
||||
cVEC, /* 110 */
|
||||
0, /* 111 */
|
||||
0, /* 112 */
|
||||
0, /* 113 */
|
||||
cVEC, /* 114 */
|
||||
0, /* 115 */
|
||||
cVEC, /* 116 */
|
||||
0, /* 117 */
|
||||
0, /* 118 */
|
||||
0, /* 119 */
|
||||
0, /* 120 */
|
||||
0, /* 121 */
|
||||
0, /* 122 */
|
||||
0, /* 123 */
|
||||
0, /* 124 */
|
||||
0, /* 125 */
|
||||
0, /* 126 */
|
||||
0, /* 127 */
|
||||
cNUC, /* 128 */
|
||||
cNUC, /* 129 */
|
||||
cNUC, /* 130 */
|
||||
cNUC, /* 131 */
|
||||
cNUC, /* 132 */
|
||||
cNUC, /* 133 */
|
||||
cNUC, /* 134 */
|
||||
cNUC, /* 135 */
|
||||
cNUC, /* 136 */
|
||||
cNUC, /* 137 */
|
||||
cNUC, /* 138 */
|
||||
cNUC, /* 139 */
|
||||
cNUC, /* 140 */
|
||||
cNUC, /* 141 */
|
||||
cNUC, /* 142 */
|
||||
cNUC, /* 143 */
|
||||
cNUC, /* 144 */
|
||||
cNUC, /* 145 */
|
||||
cNUC, /* 146 */
|
||||
cNUC, /* 147 */
|
||||
cNUC, /* 148 */
|
||||
cNUC, /* 149 */
|
||||
cNUC, /* 150 */
|
||||
cNUC, /* 151 */
|
||||
cNUC, /* 152 */
|
||||
cNUC, /* 153 */
|
||||
cNUC, /* 154 */
|
||||
cNUC, /* 155 */
|
||||
cNUC, /* 156 */
|
||||
cNUC, /* 157 */
|
||||
cNUC, /* 158 */
|
||||
cNUC, /* 159 */
|
||||
cNUC, /* 160 */
|
||||
cNUC, /* 161 */
|
||||
cNUC, /* 162 */
|
||||
cNUC, /* 163 */
|
||||
cNUC, /* 164 */
|
||||
cNUC, /* 165 */
|
||||
cNUC, /* 166 */
|
||||
cNUC, /* 167 */
|
||||
cNUC, /* 168 */
|
||||
cNUC, /* 169 */
|
||||
cNUC, /* 170 */
|
||||
cNUC, /* 171 */
|
||||
cNUC, /* 172 */
|
||||
cNUC, /* 173 */
|
||||
cNUC, /* 174 */
|
||||
cNUC, /* 175 */
|
||||
cNUC, /* 176 */
|
||||
cNUC, /* 177 */
|
||||
cNUC, /* 178 */
|
||||
cNUC, /* 179 */
|
||||
cNUC, /* 180 */
|
||||
cNUC, /* 181 */
|
||||
cNUC, /* 182 */
|
||||
cNUC, /* 183 */
|
||||
cNUC, /* 184 */
|
||||
cNUC, /* 185 */
|
||||
cNUC, /* 186 */
|
||||
cNUC, /* 187 */
|
||||
cNUC, /* 188 */
|
||||
cNUC, /* 189 */
|
||||
cNUC, /* 190 */
|
||||
cNUC, /* 191 */
|
||||
cNUC, /* 192 */
|
||||
cNUC, /* 193 */
|
||||
cNUC, /* 194 */
|
||||
cNUC, /* 195 */
|
||||
cNUC, /* 196 */
|
||||
cNUC, /* 197 */
|
||||
cNUC, /* 198 */
|
||||
cNUC, /* 199 */
|
||||
cNUC, /* 200 */
|
||||
cNUC, /* 201 */
|
||||
cNUC, /* 202 */
|
||||
cNUC, /* 203 */
|
||||
cNUC, /* 204 */
|
||||
cNUC, /* 205 */
|
||||
cNUC, /* 206 */
|
||||
cNUC, /* 207 */
|
||||
cNUC, /* 208 */
|
||||
cNUC, /* 209 */
|
||||
cNUC, /* 210 */
|
||||
cNUC, /* 211 */
|
||||
cNUC, /* 212 */
|
||||
cNUC, /* 213 */
|
||||
cNUC, /* 214 */
|
||||
cNUC, /* 215 */
|
||||
cNUC, /* 216 */
|
||||
cNUC, /* 217 */
|
||||
cNUC, /* 218 */
|
||||
cNUC, /* 219 */
|
||||
cNUC, /* 220 */
|
||||
cNUC, /* 221 */
|
||||
cNUC, /* 222 */
|
||||
cNUC, /* 223 */
|
||||
cNUC, /* 224 */
|
||||
cNUC, /* 225 */
|
||||
cNUC, /* 226 */
|
||||
cNUC, /* 227 */
|
||||
cNUC, /* 228 */
|
||||
cNUC, /* 229 */
|
||||
cNUC, /* 230 */
|
||||
cNUC, /* 231 */
|
||||
cNUC, /* 232 */
|
||||
cNUC, /* 233 */
|
||||
cNUC, /* 234 */
|
||||
cNUC, /* 235 */
|
||||
cNUC, /* 236 */
|
||||
cNUC, /* 237 */
|
||||
cNUC, /* 238 */
|
||||
cNUC, /* 239 */
|
||||
cNUC, /* 240 */
|
||||
cNUC, /* 241 */
|
||||
cNUC, /* 242 */
|
||||
cNUC, /* 243 */
|
||||
cNUC, /* 244 */
|
||||
cNUC, /* 245 */
|
||||
cNUC, /* 246 */
|
||||
cNUC, /* 247 */
|
||||
cNUC, /* 248 */
|
||||
cNUC, /* 249 */
|
||||
cNUC, /* 250 */
|
||||
cNUC, /* 251 */
|
||||
cNUC, /* 252 */
|
||||
cNUC, /* 253 */
|
||||
cNUC, /* 254 */
|
||||
cNUC, /* 255 */
|
||||
}
|
|
@ -1,509 +0,0 @@
|
|||
/**
|
||||
* Copyright 2014 Paul Querna
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"unicode"
|
||||
"unicode/utf16"
|
||||
)
|
||||
|
||||
const sliceStringMask = cIJC | cNFP
|
||||
|
||||
type ffReader struct {
|
||||
s []byte
|
||||
i int
|
||||
l int
|
||||
}
|
||||
|
||||
func newffReader(d []byte) *ffReader {
|
||||
return &ffReader{
|
||||
s: d,
|
||||
i: 0,
|
||||
l: len(d),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ffReader) Pos() int {
|
||||
return r.i
|
||||
}
|
||||
|
||||
// Reset the reader, and add new input.
|
||||
func (r *ffReader) Reset(d []byte) {
|
||||
r.s = d
|
||||
r.i = 0
|
||||
r.l = len(d)
|
||||
}
|
||||
|
||||
// Calcuates the Position with line and line offset,
|
||||
// because this isn't counted for performance reasons,
|
||||
// it will iterate the buffer from the beginning, and should
|
||||
// only be used in error-paths.
|
||||
func (r *ffReader) PosWithLine() (int, int) {
|
||||
currentLine := 1
|
||||
currentChar := 0
|
||||
|
||||
for i := 0; i < r.i; i++ {
|
||||
c := r.s[i]
|
||||
currentChar++
|
||||
if c == '\n' {
|
||||
currentLine++
|
||||
currentChar = 0
|
||||
}
|
||||
}
|
||||
|
||||
return currentLine, currentChar
|
||||
}
|
||||
|
||||
func (r *ffReader) ReadByteNoWS() (byte, error) {
|
||||
if r.i >= r.l {
|
||||
return 0, io.EOF
|
||||
}
|
||||
|
||||
j := r.i
|
||||
|
||||
for {
|
||||
c := r.s[j]
|
||||
j++
|
||||
|
||||
// inline whitespace parsing gives another ~8% performance boost
|
||||
// for many kinds of nicely indented JSON.
|
||||
// ... and using a [255]bool instead of multiple ifs, gives another 2%
|
||||
/*
|
||||
if c != '\t' &&
|
||||
c != '\n' &&
|
||||
c != '\v' &&
|
||||
c != '\f' &&
|
||||
c != '\r' &&
|
||||
c != ' ' {
|
||||
r.i = j
|
||||
return c, nil
|
||||
}
|
||||
*/
|
||||
if whitespaceLookupTable[c] == false {
|
||||
r.i = j
|
||||
return c, nil
|
||||
}
|
||||
|
||||
if j >= r.l {
|
||||
return 0, io.EOF
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ffReader) ReadByte() (byte, error) {
|
||||
if r.i >= r.l {
|
||||
return 0, io.EOF
|
||||
}
|
||||
|
||||
r.i++
|
||||
|
||||
return r.s[r.i-1], nil
|
||||
}
|
||||
|
||||
func (r *ffReader) UnreadByte() {
|
||||
if r.i <= 0 {
|
||||
panic("ffReader.UnreadByte: at beginning of slice")
|
||||
}
|
||||
r.i--
|
||||
}
|
||||
|
||||
func (r *ffReader) readU4(j int) (rune, error) {
|
||||
|
||||
var u4 [4]byte
|
||||
for i := 0; i < 4; i++ {
|
||||
if j >= r.l {
|
||||
return -1, io.EOF
|
||||
}
|
||||
c := r.s[j]
|
||||
if byteLookupTable[c]&cVHC != 0 {
|
||||
u4[i] = c
|
||||
j++
|
||||
continue
|
||||
} else {
|
||||
// TODO(pquerna): handle errors better. layering violation.
|
||||
return -1, fmt.Errorf("lex_string_invalid_hex_char: %v %v", c, string(u4[:]))
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(pquerna): utf16.IsSurrogate
|
||||
rr, err := ParseUint(u4[:], 16, 64)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
return rune(rr), nil
|
||||
}
|
||||
|
||||
func (r *ffReader) handleEscaped(c byte, j int, out DecodingBuffer) (int, error) {
|
||||
if j >= r.l {
|
||||
return 0, io.EOF
|
||||
}
|
||||
|
||||
c = r.s[j]
|
||||
j++
|
||||
|
||||
if c == 'u' {
|
||||
ru, err := r.readU4(j)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if utf16.IsSurrogate(ru) {
|
||||
ru2, err := r.readU4(j + 6)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
out.Write(r.s[r.i : j-2])
|
||||
r.i = j + 10
|
||||
j = r.i
|
||||
rval := utf16.DecodeRune(ru, ru2)
|
||||
if rval != unicode.ReplacementChar {
|
||||
out.WriteRune(rval)
|
||||
} else {
|
||||
return 0, fmt.Errorf("lex_string_invalid_unicode_surrogate: %v %v", ru, ru2)
|
||||
}
|
||||
} else {
|
||||
out.Write(r.s[r.i : j-2])
|
||||
r.i = j + 4
|
||||
j = r.i
|
||||
out.WriteRune(ru)
|
||||
}
|
||||
return j, nil
|
||||
} else if byteLookupTable[c]&cVEC == 0 {
|
||||
return 0, fmt.Errorf("lex_string_invalid_escaped_char: %v", c)
|
||||
} else {
|
||||
out.Write(r.s[r.i : j-2])
|
||||
r.i = j
|
||||
j = r.i
|
||||
|
||||
switch c {
|
||||
case '"':
|
||||
out.WriteByte('"')
|
||||
case '\\':
|
||||
out.WriteByte('\\')
|
||||
case '/':
|
||||
out.WriteByte('/')
|
||||
case 'b':
|
||||
out.WriteByte('\b')
|
||||
case 'f':
|
||||
out.WriteByte('\f')
|
||||
case 'n':
|
||||
out.WriteByte('\n')
|
||||
case 'r':
|
||||
out.WriteByte('\r')
|
||||
case 't':
|
||||
out.WriteByte('\t')
|
||||
}
|
||||
}
|
||||
|
||||
return j, nil
|
||||
}
|
||||
|
||||
func (r *ffReader) SliceString(out DecodingBuffer) error {
|
||||
var c byte
|
||||
// TODO(pquerna): string_with_escapes? de-escape here?
|
||||
j := r.i
|
||||
|
||||
for {
|
||||
if j >= r.l {
|
||||
return io.EOF
|
||||
}
|
||||
|
||||
j, c = scanString(r.s, j)
|
||||
|
||||
if c == '"' {
|
||||
if j != r.i {
|
||||
out.Write(r.s[r.i : j-1])
|
||||
r.i = j
|
||||
}
|
||||
return nil
|
||||
} else if c == '\\' {
|
||||
var err error
|
||||
j, err = r.handleEscaped(c, j, out)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if byteLookupTable[c]&cIJC != 0 {
|
||||
return fmt.Errorf("lex_string_invalid_json_char: %v", c)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
panic("ffjson: SliceString unreached exit")
|
||||
}
|
||||
|
||||
// TODO(pquerna): consider combining wibth the normal byte mask.
|
||||
var whitespaceLookupTable [256]bool = [256]bool{
|
||||
false, /* 0 */
|
||||
false, /* 1 */
|
||||
false, /* 2 */
|
||||
false, /* 3 */
|
||||
false, /* 4 */
|
||||
false, /* 5 */
|
||||
false, /* 6 */
|
||||
false, /* 7 */
|
||||
false, /* 8 */
|
||||
true, /* 9 */
|
||||
true, /* 10 */
|
||||
true, /* 11 */
|
||||
true, /* 12 */
|
||||
true, /* 13 */
|
||||
false, /* 14 */
|
||||
false, /* 15 */
|
||||
false, /* 16 */
|
||||
false, /* 17 */
|
||||
false, /* 18 */
|
||||
false, /* 19 */
|
||||
false, /* 20 */
|
||||
false, /* 21 */
|
||||
false, /* 22 */
|
||||
false, /* 23 */
|
||||
false, /* 24 */
|
||||
false, /* 25 */
|
||||
false, /* 26 */
|
||||
false, /* 27 */
|
||||
false, /* 28 */
|
||||
false, /* 29 */
|
||||
false, /* 30 */
|
||||
false, /* 31 */
|
||||
true, /* 32 */
|
||||
false, /* 33 */
|
||||
false, /* 34 */
|
||||
false, /* 35 */
|
||||
false, /* 36 */
|
||||
false, /* 37 */
|
||||
false, /* 38 */
|
||||
false, /* 39 */
|
||||
false, /* 40 */
|
||||
false, /* 41 */
|
||||
false, /* 42 */
|
||||
false, /* 43 */
|
||||
false, /* 44 */
|
||||
false, /* 45 */
|
||||
false, /* 46 */
|
||||
false, /* 47 */
|
||||
false, /* 48 */
|
||||
false, /* 49 */
|
||||
false, /* 50 */
|
||||
false, /* 51 */
|
||||
false, /* 52 */
|
||||
false, /* 53 */
|
||||
false, /* 54 */
|
||||
false, /* 55 */
|
||||
false, /* 56 */
|
||||
false, /* 57 */
|
||||
false, /* 58 */
|
||||
false, /* 59 */
|
||||
false, /* 60 */
|
||||
false, /* 61 */
|
||||
false, /* 62 */
|
||||
false, /* 63 */
|
||||
false, /* 64 */
|
||||
false, /* 65 */
|
||||
false, /* 66 */
|
||||
false, /* 67 */
|
||||
false, /* 68 */
|
||||
false, /* 69 */
|
||||
false, /* 70 */
|
||||
false, /* 71 */
|
||||
false, /* 72 */
|
||||
false, /* 73 */
|
||||
false, /* 74 */
|
||||
false, /* 75 */
|
||||
false, /* 76 */
|
||||
false, /* 77 */
|
||||
false, /* 78 */
|
||||
false, /* 79 */
|
||||
false, /* 80 */
|
||||
false, /* 81 */
|
||||
false, /* 82 */
|
||||
false, /* 83 */
|
||||
false, /* 84 */
|
||||
false, /* 85 */
|
||||
false, /* 86 */
|
||||
false, /* 87 */
|
||||
false, /* 88 */
|
||||
false, /* 89 */
|
||||
false, /* 90 */
|
||||
false, /* 91 */
|
||||
false, /* 92 */
|
||||
false, /* 93 */
|
||||
false, /* 94 */
|
||||
false, /* 95 */
|
||||
false, /* 96 */
|
||||
false, /* 97 */
|
||||
false, /* 98 */
|
||||
false, /* 99 */
|
||||
false, /* 100 */
|
||||
false, /* 101 */
|
||||
false, /* 102 */
|
||||
false, /* 103 */
|
||||
false, /* 104 */
|
||||
false, /* 105 */
|
||||
false, /* 106 */
|
||||
false, /* 107 */
|
||||
false, /* 108 */
|
||||
false, /* 109 */
|
||||
false, /* 110 */
|
||||
false, /* 111 */
|
||||
false, /* 112 */
|
||||
false, /* 113 */
|
||||
false, /* 114 */
|
||||
false, /* 115 */
|
||||
false, /* 116 */
|
||||
false, /* 117 */
|
||||
false, /* 118 */
|
||||
false, /* 119 */
|
||||
false, /* 120 */
|
||||
false, /* 121 */
|
||||
false, /* 122 */
|
||||
false, /* 123 */
|
||||
false, /* 124 */
|
||||
false, /* 125 */
|
||||
false, /* 126 */
|
||||
false, /* 127 */
|
||||
false, /* 128 */
|
||||
false, /* 129 */
|
||||
false, /* 130 */
|
||||
false, /* 131 */
|
||||
false, /* 132 */
|
||||
false, /* 133 */
|
||||
false, /* 134 */
|
||||
false, /* 135 */
|
||||
false, /* 136 */
|
||||
false, /* 137 */
|
||||
false, /* 138 */
|
||||
false, /* 139 */
|
||||
false, /* 140 */
|
||||
false, /* 141 */
|
||||
false, /* 142 */
|
||||
false, /* 143 */
|
||||
false, /* 144 */
|
||||
false, /* 145 */
|
||||
false, /* 146 */
|
||||
false, /* 147 */
|
||||
false, /* 148 */
|
||||
false, /* 149 */
|
||||
false, /* 150 */
|
||||
false, /* 151 */
|
||||
false, /* 152 */
|
||||
false, /* 153 */
|
||||
false, /* 154 */
|
||||
false, /* 155 */
|
||||
false, /* 156 */
|
||||
false, /* 157 */
|
||||
false, /* 158 */
|
||||
false, /* 159 */
|
||||
false, /* 160 */
|
||||
false, /* 161 */
|
||||
false, /* 162 */
|
||||
false, /* 163 */
|
||||
false, /* 164 */
|
||||
false, /* 165 */
|
||||
false, /* 166 */
|
||||
false, /* 167 */
|
||||
false, /* 168 */
|
||||
false, /* 169 */
|
||||
false, /* 170 */
|
||||
false, /* 171 */
|
||||
false, /* 172 */
|
||||
false, /* 173 */
|
||||
false, /* 174 */
|
||||
false, /* 175 */
|
||||
false, /* 176 */
|
||||
false, /* 177 */
|
||||
false, /* 178 */
|
||||
false, /* 179 */
|
||||
false, /* 180 */
|
||||
false, /* 181 */
|
||||
false, /* 182 */
|
||||
false, /* 183 */
|
||||
false, /* 184 */
|
||||
false, /* 185 */
|
||||
false, /* 186 */
|
||||
false, /* 187 */
|
||||
false, /* 188 */
|
||||
false, /* 189 */
|
||||
false, /* 190 */
|
||||
false, /* 191 */
|
||||
false, /* 192 */
|
||||
false, /* 193 */
|
||||
false, /* 194 */
|
||||
false, /* 195 */
|
||||
false, /* 196 */
|
||||
false, /* 197 */
|
||||
false, /* 198 */
|
||||
false, /* 199 */
|
||||
false, /* 200 */
|
||||
false, /* 201 */
|
||||
false, /* 202 */
|
||||
false, /* 203 */
|
||||
false, /* 204 */
|
||||
false, /* 205 */
|
||||
false, /* 206 */
|
||||
false, /* 207 */
|
||||
false, /* 208 */
|
||||
false, /* 209 */
|
||||
false, /* 210 */
|
||||
false, /* 211 */
|
||||
false, /* 212 */
|
||||
false, /* 213 */
|
||||
false, /* 214 */
|
||||
false, /* 215 */
|
||||
false, /* 216 */
|
||||
false, /* 217 */
|
||||
false, /* 218 */
|
||||
false, /* 219 */
|
||||
false, /* 220 */
|
||||
false, /* 221 */
|
||||
false, /* 222 */
|
||||
false, /* 223 */
|
||||
false, /* 224 */
|
||||
false, /* 225 */
|
||||
false, /* 226 */
|
||||
false, /* 227 */
|
||||
false, /* 228 */
|
||||
false, /* 229 */
|
||||
false, /* 230 */
|
||||
false, /* 231 */
|
||||
false, /* 232 */
|
||||
false, /* 233 */
|
||||
false, /* 234 */
|
||||
false, /* 235 */
|
||||
false, /* 236 */
|
||||
false, /* 237 */
|
||||
false, /* 238 */
|
||||
false, /* 239 */
|
||||
false, /* 240 */
|
||||
false, /* 241 */
|
||||
false, /* 242 */
|
||||
false, /* 243 */
|
||||
false, /* 244 */
|
||||
false, /* 245 */
|
||||
false, /* 246 */
|
||||
false, /* 247 */
|
||||
false, /* 248 */
|
||||
false, /* 249 */
|
||||
false, /* 250 */
|
||||
false, /* 251 */
|
||||
false, /* 252 */
|
||||
false, /* 253 */
|
||||
false, /* 254 */
|
||||
false, /* 255 */
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
// +build amd64
|
||||
// +build !appengine
|
||||
|
||||
/**
|
||||
* Copyright 2014 Paul Querna
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
func haveSSE42() bool
|
||||
func scanStringSSE(s []byte, j int) (int, byte)
|
||||
|
||||
var sse42 = haveSSE42()
|
||||
|
||||
func scanString(s []byte, j int) (int, byte) {
|
||||
// XXX The following fails to compile on Go 1.2.
|
||||
/*
|
||||
if false && sse42 {
|
||||
return scanStringSSE(s, j)
|
||||
}
|
||||
*/
|
||||
|
||||
for {
|
||||
if j >= len(s) {
|
||||
return j, 0
|
||||
}
|
||||
|
||||
c := s[j]
|
||||
j++
|
||||
if byteLookupTable[c]&sliceStringMask == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
return j, c
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
// +build !appengine
|
||||
|
||||
#define NOSPLIT 4
|
||||
|
||||
// func scanStringSSE(s []byte, j int) (int, byte)
|
||||
TEXT scanStringSSE(SB),NOSPLIT,$0
|
||||
// TODO: http://www.strchr.com/strcmp_and_strlen_using_sse_4.2
|
||||
// Equal any, operand1 set to
|
||||
RET
|
||||
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
// func haveSSE42() bool
|
||||
TEXT ·haveSSE42(SB),NOSPLIT,$0
|
||||
XORQ AX, AX
|
||||
INCL AX
|
||||
CPUID
|
||||
SHRQ $20, CX
|
||||
ANDQ $1, CX
|
||||
MOVB CX, ret+0(FP)
|
||||
RET
|
36
Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/reader_scan_generic.go
generated
vendored
36
Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/reader_scan_generic.go
generated
vendored
|
@ -1,36 +0,0 @@
|
|||
// +build !amd64 appengine
|
||||
|
||||
/**
|
||||
* Copyright 2014 Paul Querna
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
func scanString(s []byte, j int) (int, byte) {
|
||||
for {
|
||||
if j >= len(s) {
|
||||
return j, 0
|
||||
}
|
||||
|
||||
c := s[j]
|
||||
j++
|
||||
if byteLookupTable[c]&sliceStringMask == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
return j, c
|
||||
}
|
||||
}
|
92
Godeps/_workspace/src/github.com/syndtr/gocapability/capability/enumgen/gen.go
generated
vendored
92
Godeps/_workspace/src/github.com/syndtr/gocapability/capability/enumgen/gen.go
generated
vendored
|
@ -1,92 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/format"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const fileName = "enum.go"
|
||||
const genName = "enum_gen.go"
|
||||
|
||||
type generator struct {
|
||||
buf bytes.Buffer
|
||||
caps []string
|
||||
}
|
||||
|
||||
func (g *generator) writeHeader() {
|
||||
g.buf.WriteString("// generated file; DO NOT EDIT - use go generate in directory with source\n")
|
||||
g.buf.WriteString("\n")
|
||||
g.buf.WriteString("package capability")
|
||||
}
|
||||
|
||||
func (g *generator) writeStringFunc() {
|
||||
g.buf.WriteString("\n")
|
||||
g.buf.WriteString("func (c Cap) String() string {\n")
|
||||
g.buf.WriteString("switch c {\n")
|
||||
for _, cap := range g.caps {
|
||||
fmt.Fprintf(&g.buf, "case %s:\n", cap)
|
||||
fmt.Fprintf(&g.buf, "return \"%s\"\n", strings.ToLower(cap[4:]))
|
||||
}
|
||||
g.buf.WriteString("}\n")
|
||||
g.buf.WriteString("return \"unknown\"\n")
|
||||
g.buf.WriteString("}\n")
|
||||
}
|
||||
|
||||
func (g *generator) writeListFunc() {
|
||||
g.buf.WriteString("\n")
|
||||
g.buf.WriteString("// List returns list of all supported capabilities\n")
|
||||
g.buf.WriteString("func List() []Cap {\n")
|
||||
g.buf.WriteString("return []Cap{\n")
|
||||
for _, cap := range g.caps {
|
||||
fmt.Fprintf(&g.buf, "%s,\n", cap)
|
||||
}
|
||||
g.buf.WriteString("}\n")
|
||||
g.buf.WriteString("}\n")
|
||||
}
|
||||
|
||||
func main() {
|
||||
fs := token.NewFileSet()
|
||||
parsedFile, err := parser.ParseFile(fs, fileName, nil, 0)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
var caps []string
|
||||
for _, decl := range parsedFile.Decls {
|
||||
decl, ok := decl.(*ast.GenDecl)
|
||||
if !ok || decl.Tok != token.CONST {
|
||||
continue
|
||||
}
|
||||
for _, spec := range decl.Specs {
|
||||
vspec := spec.(*ast.ValueSpec)
|
||||
name := vspec.Names[0].Name
|
||||
if strings.HasPrefix(name, "CAP_") {
|
||||
caps = append(caps, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
g := &generator{caps: caps}
|
||||
g.writeHeader()
|
||||
g.writeStringFunc()
|
||||
g.writeListFunc()
|
||||
src, err := format.Source(g.buf.Bytes())
|
||||
if err != nil {
|
||||
fmt.Println("generated invalid Go code")
|
||||
fmt.Println(g.buf.String())
|
||||
log.Fatal(err)
|
||||
}
|
||||
fi, err := os.Stat(fileName)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if err := ioutil.WriteFile(genName, src, fi.Mode().Perm()); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
*.coverprofile
|
||||
node_modules/
|
|
@ -1,36 +0,0 @@
|
|||
language: go
|
||||
|
||||
sudo: false
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- node_modules
|
||||
|
||||
go:
|
||||
- 1.2.x
|
||||
- 1.3.x
|
||||
- 1.4.2
|
||||
- 1.5.x
|
||||
- 1.6.x
|
||||
- master
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- go: master
|
||||
include:
|
||||
- go: 1.6.x
|
||||
os: osx
|
||||
|
||||
before_script:
|
||||
- go get github.com/urfave/gfmrun/... || true
|
||||
- go get golang.org/x/tools/... || true
|
||||
- if [ ! -f node_modules/.bin/markdown-toc ] ; then
|
||||
npm install markdown-toc ;
|
||||
fi
|
||||
|
||||
script:
|
||||
- ./runtests gen
|
||||
- ./runtests vet
|
||||
- ./runtests test
|
||||
- ./runtests gfmrun
|
||||
- ./runtests toc
|
|
@ -1,336 +0,0 @@
|
|||
# Change Log
|
||||
|
||||
**ATTN**: This project uses [semantic versioning](http://semver.org/).
|
||||
|
||||
## [Unreleased]
|
||||
### Added
|
||||
- Flag type code generation via `go generate`
|
||||
- Write to stderr and exit 1 if action returns non-nil error
|
||||
- Added support for TOML to the `altsrc` loader
|
||||
|
||||
### Changed
|
||||
- Raise minimum tested/supported Go version to 1.2+
|
||||
|
||||
## [1.18.0] - 2016-06-27
|
||||
### Added
|
||||
- `./runtests` test runner with coverage tracking by default
|
||||
- testing on OS X
|
||||
- testing on Windows
|
||||
- `UintFlag`, `Uint64Flag`, and `Int64Flag` types and supporting code
|
||||
|
||||
### Changed
|
||||
- Use spaces for alignment in help/usage output instead of tabs, making the
|
||||
output alignment consistent regardless of tab width
|
||||
|
||||
### Fixed
|
||||
- Printing of command aliases in help text
|
||||
- Printing of visible flags for both struct and struct pointer flags
|
||||
- Display the `help` subcommand when using `CommandCategories`
|
||||
- No longer swallows `panic`s that occur within the `Action`s themselves when
|
||||
detecting the signature of the `Action` field
|
||||
|
||||
## [1.17.0] - 2016-05-09
|
||||
### Added
|
||||
- Pluggable flag-level help text rendering via `cli.DefaultFlagStringFunc`
|
||||
- `context.GlobalBoolT` was added as an analogue to `context.GlobalBool`
|
||||
- Support for hiding commands by setting `Hidden: true` -- this will hide the
|
||||
commands in help output
|
||||
|
||||
### Changed
|
||||
- `Float64Flag`, `IntFlag`, and `DurationFlag` default values are no longer
|
||||
quoted in help text output.
|
||||
- All flag types now include `(default: {value})` strings following usage when a
|
||||
default value can be (reasonably) detected.
|
||||
- `IntSliceFlag` and `StringSliceFlag` usage strings are now more consistent
|
||||
with non-slice flag types
|
||||
- Apps now exit with a code of 3 if an unknown subcommand is specified
|
||||
(previously they printed "No help topic for...", but still exited 0. This
|
||||
makes it easier to script around apps built using `cli` since they can trust
|
||||
that a 0 exit code indicated a successful execution.
|
||||
- cleanups based on [Go Report Card
|
||||
feedback](https://goreportcard.com/report/github.com/urfave/cli)
|
||||
|
||||
## [1.16.0] - 2016-05-02
|
||||
### Added
|
||||
- `Hidden` field on all flag struct types to omit from generated help text
|
||||
|
||||
### Changed
|
||||
- `BashCompletionFlag` (`--enable-bash-completion`) is now omitted from
|
||||
generated help text via the `Hidden` field
|
||||
|
||||
### Fixed
|
||||
- handling of error values in `HandleAction` and `HandleExitCoder`
|
||||
|
||||
## [1.15.0] - 2016-04-30
|
||||
### Added
|
||||
- This file!
|
||||
- Support for placeholders in flag usage strings
|
||||
- `App.Metadata` map for arbitrary data/state management
|
||||
- `Set` and `GlobalSet` methods on `*cli.Context` for altering values after
|
||||
parsing.
|
||||
- Support for nested lookup of dot-delimited keys in structures loaded from
|
||||
YAML.
|
||||
|
||||
### Changed
|
||||
- The `App.Action` and `Command.Action` now prefer a return signature of
|
||||
`func(*cli.Context) error`, as defined by `cli.ActionFunc`. If a non-nil
|
||||
`error` is returned, there may be two outcomes:
|
||||
- If the error fulfills `cli.ExitCoder`, then `os.Exit` will be called
|
||||
automatically
|
||||
- Else the error is bubbled up and returned from `App.Run`
|
||||
- Specifying an `Action` with the legacy return signature of
|
||||
`func(*cli.Context)` will produce a deprecation message to stderr
|
||||
- Specifying an `Action` that is not a `func` type will produce a non-zero exit
|
||||
from `App.Run`
|
||||
- Specifying an `Action` func that has an invalid (input) signature will
|
||||
produce a non-zero exit from `App.Run`
|
||||
|
||||
### Deprecated
|
||||
- <a name="deprecated-cli-app-runandexitonerror"></a>
|
||||
`cli.App.RunAndExitOnError`, which should now be done by returning an error
|
||||
that fulfills `cli.ExitCoder` to `cli.App.Run`.
|
||||
- <a name="deprecated-cli-app-action-signature"></a> the legacy signature for
|
||||
`cli.App.Action` of `func(*cli.Context)`, which should now have a return
|
||||
signature of `func(*cli.Context) error`, as defined by `cli.ActionFunc`.
|
||||
|
||||
### Fixed
|
||||
- Added missing `*cli.Context.GlobalFloat64` method
|
||||
|
||||
## [1.14.0] - 2016-04-03 (backfilled 2016-04-25)
|
||||
### Added
|
||||
- Codebeat badge
|
||||
- Support for categorization via `CategorizedHelp` and `Categories` on app.
|
||||
|
||||
### Changed
|
||||
- Use `filepath.Base` instead of `path.Base` in `Name` and `HelpName`.
|
||||
|
||||
### Fixed
|
||||
- Ensure version is not shown in help text when `HideVersion` set.
|
||||
|
||||
## [1.13.0] - 2016-03-06 (backfilled 2016-04-25)
|
||||
### Added
|
||||
- YAML file input support.
|
||||
- `NArg` method on context.
|
||||
|
||||
## [1.12.0] - 2016-02-17 (backfilled 2016-04-25)
|
||||
### Added
|
||||
- Custom usage error handling.
|
||||
- Custom text support in `USAGE` section of help output.
|
||||
- Improved help messages for empty strings.
|
||||
- AppVeyor CI configuration.
|
||||
|
||||
### Changed
|
||||
- Removed `panic` from default help printer func.
|
||||
- De-duping and optimizations.
|
||||
|
||||
### Fixed
|
||||
- Correctly handle `Before`/`After` at command level when no subcommands.
|
||||
- Case of literal `-` argument causing flag reordering.
|
||||
- Environment variable hints on Windows.
|
||||
- Docs updates.
|
||||
|
||||
## [1.11.1] - 2015-12-21 (backfilled 2016-04-25)
|
||||
### Changed
|
||||
- Use `path.Base` in `Name` and `HelpName`
|
||||
- Export `GetName` on flag types.
|
||||
|
||||
### Fixed
|
||||
- Flag parsing when skipping is enabled.
|
||||
- Test output cleanup.
|
||||
- Move completion check to account for empty input case.
|
||||
|
||||
## [1.11.0] - 2015-11-15 (backfilled 2016-04-25)
|
||||
### Added
|
||||
- Destination scan support for flags.
|
||||
- Testing against `tip` in Travis CI config.
|
||||
|
||||
### Changed
|
||||
- Go version in Travis CI config.
|
||||
|
||||
### Fixed
|
||||
- Removed redundant tests.
|
||||
- Use correct example naming in tests.
|
||||
|
||||
## [1.10.2] - 2015-10-29 (backfilled 2016-04-25)
|
||||
### Fixed
|
||||
- Remove unused var in bash completion.
|
||||
|
||||
## [1.10.1] - 2015-10-21 (backfilled 2016-04-25)
|
||||
### Added
|
||||
- Coverage and reference logos in README.
|
||||
|
||||
### Fixed
|
||||
- Use specified values in help and version parsing.
|
||||
- Only display app version and help message once.
|
||||
|
||||
## [1.10.0] - 2015-10-06 (backfilled 2016-04-25)
|
||||
### Added
|
||||
- More tests for existing functionality.
|
||||
- `ArgsUsage` at app and command level for help text flexibility.
|
||||
|
||||
### Fixed
|
||||
- Honor `HideHelp` and `HideVersion` in `App.Run`.
|
||||
- Remove juvenile word from README.
|
||||
|
||||
## [1.9.0] - 2015-09-08 (backfilled 2016-04-25)
|
||||
### Added
|
||||
- `FullName` on command with accompanying help output update.
|
||||
- Set default `$PROG` in bash completion.
|
||||
|
||||
### Changed
|
||||
- Docs formatting.
|
||||
|
||||
### Fixed
|
||||
- Removed self-referential imports in tests.
|
||||
|
||||
## [1.8.0] - 2015-06-30 (backfilled 2016-04-25)
|
||||
### Added
|
||||
- Support for `Copyright` at app level.
|
||||
- `Parent` func at context level to walk up context lineage.
|
||||
|
||||
### Fixed
|
||||
- Global flag processing at top level.
|
||||
|
||||
## [1.7.1] - 2015-06-11 (backfilled 2016-04-25)
|
||||
### Added
|
||||
- Aggregate errors from `Before`/`After` funcs.
|
||||
- Doc comments on flag structs.
|
||||
- Include non-global flags when checking version and help.
|
||||
- Travis CI config updates.
|
||||
|
||||
### Fixed
|
||||
- Ensure slice type flags have non-nil values.
|
||||
- Collect global flags from the full command hierarchy.
|
||||
- Docs prose.
|
||||
|
||||
## [1.7.0] - 2015-05-03 (backfilled 2016-04-25)
|
||||
### Changed
|
||||
- `HelpPrinter` signature includes output writer.
|
||||
|
||||
### Fixed
|
||||
- Specify go 1.1+ in docs.
|
||||
- Set `Writer` when running command as app.
|
||||
|
||||
## [1.6.0] - 2015-03-23 (backfilled 2016-04-25)
|
||||
### Added
|
||||
- Multiple author support.
|
||||
- `NumFlags` at context level.
|
||||
- `Aliases` at command level.
|
||||
|
||||
### Deprecated
|
||||
- `ShortName` at command level.
|
||||
|
||||
### Fixed
|
||||
- Subcommand help output.
|
||||
- Backward compatible support for deprecated `Author` and `Email` fields.
|
||||
- Docs regarding `Names`/`Aliases`.
|
||||
|
||||
## [1.5.0] - 2015-02-20 (backfilled 2016-04-25)
|
||||
### Added
|
||||
- `After` hook func support at app and command level.
|
||||
|
||||
### Fixed
|
||||
- Use parsed context when running command as subcommand.
|
||||
- Docs prose.
|
||||
|
||||
## [1.4.1] - 2015-01-09 (backfilled 2016-04-25)
|
||||
### Added
|
||||
- Support for hiding `-h / --help` flags, but not `help` subcommand.
|
||||
- Stop flag parsing after `--`.
|
||||
|
||||
### Fixed
|
||||
- Help text for generic flags to specify single value.
|
||||
- Use double quotes in output for defaults.
|
||||
- Use `ParseInt` instead of `ParseUint` for int environment var values.
|
||||
- Use `0` as base when parsing int environment var values.
|
||||
|
||||
## [1.4.0] - 2014-12-12 (backfilled 2016-04-25)
|
||||
### Added
|
||||
- Support for environment variable lookup "cascade".
|
||||
- Support for `Stdout` on app for output redirection.
|
||||
|
||||
### Fixed
|
||||
- Print command help instead of app help in `ShowCommandHelp`.
|
||||
|
||||
## [1.3.1] - 2014-11-13 (backfilled 2016-04-25)
|
||||
### Added
|
||||
- Docs and example code updates.
|
||||
|
||||
### Changed
|
||||
- Default `-v / --version` flag made optional.
|
||||
|
||||
## [1.3.0] - 2014-08-10 (backfilled 2016-04-25)
|
||||
### Added
|
||||
- `FlagNames` at context level.
|
||||
- Exposed `VersionPrinter` var for more control over version output.
|
||||
- Zsh completion hook.
|
||||
- `AUTHOR` section in default app help template.
|
||||
- Contribution guidelines.
|
||||
- `DurationFlag` type.
|
||||
|
||||
## [1.2.0] - 2014-08-02
|
||||
### Added
|
||||
- Support for environment variable defaults on flags plus tests.
|
||||
|
||||
## [1.1.0] - 2014-07-15
|
||||
### Added
|
||||
- Bash completion.
|
||||
- Optional hiding of built-in help command.
|
||||
- Optional skipping of flag parsing at command level.
|
||||
- `Author`, `Email`, and `Compiled` metadata on app.
|
||||
- `Before` hook func support at app and command level.
|
||||
- `CommandNotFound` func support at app level.
|
||||
- Command reference available on context.
|
||||
- `GenericFlag` type.
|
||||
- `Float64Flag` type.
|
||||
- `BoolTFlag` type.
|
||||
- `IsSet` flag helper on context.
|
||||
- More flag lookup funcs at context level.
|
||||
- More tests & docs.
|
||||
|
||||
### Changed
|
||||
- Help template updates to account for presence/absence of flags.
|
||||
- Separated subcommand help template.
|
||||
- Exposed `HelpPrinter` var for more control over help output.
|
||||
|
||||
## [1.0.0] - 2013-11-01
|
||||
### Added
|
||||
- `help` flag in default app flag set and each command flag set.
|
||||
- Custom handling of argument parsing errors.
|
||||
- Command lookup by name at app level.
|
||||
- `StringSliceFlag` type and supporting `StringSlice` type.
|
||||
- `IntSliceFlag` type and supporting `IntSlice` type.
|
||||
- Slice type flag lookups by name at context level.
|
||||
- Export of app and command help functions.
|
||||
- More tests & docs.
|
||||
|
||||
## 0.1.0 - 2013-07-22
|
||||
### Added
|
||||
- Initial implementation.
|
||||
|
||||
[Unreleased]: https://github.com/urfave/cli/compare/v1.18.0...HEAD
|
||||
[1.18.0]: https://github.com/urfave/cli/compare/v1.17.0...v1.18.0
|
||||
[1.17.0]: https://github.com/urfave/cli/compare/v1.16.0...v1.17.0
|
||||
[1.16.0]: https://github.com/urfave/cli/compare/v1.15.0...v1.16.0
|
||||
[1.15.0]: https://github.com/urfave/cli/compare/v1.14.0...v1.15.0
|
||||
[1.14.0]: https://github.com/urfave/cli/compare/v1.13.0...v1.14.0
|
||||
[1.13.0]: https://github.com/urfave/cli/compare/v1.12.0...v1.13.0
|
||||
[1.12.0]: https://github.com/urfave/cli/compare/v1.11.1...v1.12.0
|
||||
[1.11.1]: https://github.com/urfave/cli/compare/v1.11.0...v1.11.1
|
||||
[1.11.0]: https://github.com/urfave/cli/compare/v1.10.2...v1.11.0
|
||||
[1.10.2]: https://github.com/urfave/cli/compare/v1.10.1...v1.10.2
|
||||
[1.10.1]: https://github.com/urfave/cli/compare/v1.10.0...v1.10.1
|
||||
[1.10.0]: https://github.com/urfave/cli/compare/v1.9.0...v1.10.0
|
||||
[1.9.0]: https://github.com/urfave/cli/compare/v1.8.0...v1.9.0
|
||||
[1.8.0]: https://github.com/urfave/cli/compare/v1.7.1...v1.8.0
|
||||
[1.7.1]: https://github.com/urfave/cli/compare/v1.7.0...v1.7.1
|
||||
[1.7.0]: https://github.com/urfave/cli/compare/v1.6.0...v1.7.0
|
||||
[1.6.0]: https://github.com/urfave/cli/compare/v1.5.0...v1.6.0
|
||||
[1.5.0]: https://github.com/urfave/cli/compare/v1.4.1...v1.5.0
|
||||
[1.4.1]: https://github.com/urfave/cli/compare/v1.4.0...v1.4.1
|
||||
[1.4.0]: https://github.com/urfave/cli/compare/v1.3.1...v1.4.0
|
||||
[1.3.1]: https://github.com/urfave/cli/compare/v1.3.0...v1.3.1
|
||||
[1.3.0]: https://github.com/urfave/cli/compare/v1.2.0...v1.3.0
|
||||
[1.2.0]: https://github.com/urfave/cli/compare/v1.1.0...v1.2.0
|
||||
[1.1.0]: https://github.com/urfave/cli/compare/v1.0.0...v1.1.0
|
||||
[1.0.0]: https://github.com/urfave/cli/compare/v0.1.0...v1.0.0
|
|
@ -1,3 +0,0 @@
|
|||
package altsrc
|
||||
|
||||
//go:generate python ../generate-flag-types altsrc -i ../flag-types.json -o flag_generated.go
|
|
@ -1,263 +0,0 @@
|
|||
package altsrc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
)
|
||||
|
||||
// FlagInputSourceExtension is an extension interface of cli.Flag that
|
||||
// allows a value to be set on the existing parsed flags.
|
||||
type FlagInputSourceExtension interface {
|
||||
cli.Flag
|
||||
ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error
|
||||
}
|
||||
|
||||
// ApplyInputSourceValues iterates over all provided flags and
|
||||
// executes ApplyInputSourceValue on flags implementing the
|
||||
// FlagInputSourceExtension interface to initialize these flags
|
||||
// to an alternate input source.
|
||||
func ApplyInputSourceValues(context *cli.Context, inputSourceContext InputSourceContext, flags []cli.Flag) error {
|
||||
for _, f := range flags {
|
||||
inputSourceExtendedFlag, isType := f.(FlagInputSourceExtension)
|
||||
if isType {
|
||||
err := inputSourceExtendedFlag.ApplyInputSourceValue(context, inputSourceContext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// InitInputSource is used to to setup an InputSourceContext on a cli.Command Before method. It will create a new
|
||||
// input source based on the func provided. If there is no error it will then apply the new input source to any flags
|
||||
// that are supported by the input source
|
||||
func InitInputSource(flags []cli.Flag, createInputSource func() (InputSourceContext, error)) cli.BeforeFunc {
|
||||
return func(context *cli.Context) error {
|
||||
inputSource, err := createInputSource()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to create input source: inner error: \n'%v'", err.Error())
|
||||
}
|
||||
|
||||
return ApplyInputSourceValues(context, inputSource, flags)
|
||||
}
|
||||
}
|
||||
|
||||
// InitInputSourceWithContext is used to to setup an InputSourceContext on a cli.Command Before method. It will create a new
|
||||
// input source based on the func provided with potentially using existing cli.Context values to initialize itself. If there is
|
||||
// no error it will then apply the new input source to any flags that are supported by the input source
|
||||
func InitInputSourceWithContext(flags []cli.Flag, createInputSource func(context *cli.Context) (InputSourceContext, error)) cli.BeforeFunc {
|
||||
return func(context *cli.Context) error {
|
||||
inputSource, err := createInputSource(context)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to create input source with context: inner error: \n'%v'", err.Error())
|
||||
}
|
||||
|
||||
return ApplyInputSourceValues(context, inputSource, flags)
|
||||
}
|
||||
}
|
||||
|
||||
// ApplyInputSourceValue applies a generic value to the flagSet if required
|
||||
func (f *GenericFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
||||
if f.set != nil {
|
||||
if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVar) {
|
||||
value, err := isc.Generic(f.GenericFlag.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if value != nil {
|
||||
eachName(f.Name, func(name string) {
|
||||
f.set.Set(f.Name, value.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ApplyInputSourceValue applies a StringSlice value to the flagSet if required
|
||||
func (f *StringSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
||||
if f.set != nil {
|
||||
if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVar) {
|
||||
value, err := isc.StringSlice(f.StringSliceFlag.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if value != nil {
|
||||
var sliceValue cli.StringSlice = value
|
||||
eachName(f.Name, func(name string) {
|
||||
underlyingFlag := f.set.Lookup(f.Name)
|
||||
if underlyingFlag != nil {
|
||||
underlyingFlag.Value = &sliceValue
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ApplyInputSourceValue applies a IntSlice value if required
|
||||
func (f *IntSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
||||
if f.set != nil {
|
||||
if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVar) {
|
||||
value, err := isc.IntSlice(f.IntSliceFlag.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if value != nil {
|
||||
var sliceValue cli.IntSlice = value
|
||||
eachName(f.Name, func(name string) {
|
||||
underlyingFlag := f.set.Lookup(f.Name)
|
||||
if underlyingFlag != nil {
|
||||
underlyingFlag.Value = &sliceValue
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ApplyInputSourceValue applies a Bool value to the flagSet if required
|
||||
func (f *BoolFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
||||
if f.set != nil {
|
||||
if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVar) {
|
||||
value, err := isc.Bool(f.BoolFlag.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if value {
|
||||
eachName(f.Name, func(name string) {
|
||||
f.set.Set(f.Name, strconv.FormatBool(value))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ApplyInputSourceValue applies a BoolT value to the flagSet if required
|
||||
func (f *BoolTFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
||||
if f.set != nil {
|
||||
if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVar) {
|
||||
value, err := isc.BoolT(f.BoolTFlag.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !value {
|
||||
eachName(f.Name, func(name string) {
|
||||
f.set.Set(f.Name, strconv.FormatBool(value))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ApplyInputSourceValue applies a String value to the flagSet if required
|
||||
func (f *StringFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
||||
if f.set != nil {
|
||||
if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVar)) {
|
||||
value, err := isc.String(f.StringFlag.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if value != "" {
|
||||
eachName(f.Name, func(name string) {
|
||||
f.set.Set(f.Name, value)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ApplyInputSourceValue applies a int value to the flagSet if required
|
||||
func (f *IntFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
||||
if f.set != nil {
|
||||
if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVar)) {
|
||||
value, err := isc.Int(f.IntFlag.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if value > 0 {
|
||||
eachName(f.Name, func(name string) {
|
||||
f.set.Set(f.Name, strconv.FormatInt(int64(value), 10))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ApplyInputSourceValue applies a Duration value to the flagSet if required
|
||||
func (f *DurationFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
||||
if f.set != nil {
|
||||
if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVar)) {
|
||||
value, err := isc.Duration(f.DurationFlag.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if value > 0 {
|
||||
eachName(f.Name, func(name string) {
|
||||
f.set.Set(f.Name, value.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ApplyInputSourceValue applies a Float64 value to the flagSet if required
|
||||
func (f *Float64Flag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
||||
if f.set != nil {
|
||||
if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVar)) {
|
||||
value, err := isc.Float64(f.Float64Flag.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if value > 0 {
|
||||
floatStr := float64ToString(value)
|
||||
eachName(f.Name, func(name string) {
|
||||
f.set.Set(f.Name, floatStr)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func isEnvVarSet(envVars string) bool {
|
||||
for _, envVar := range strings.Split(envVars, ",") {
|
||||
envVar = strings.TrimSpace(envVar)
|
||||
if envVal := os.Getenv(envVar); envVal != "" {
|
||||
// TODO: Can't use this for bools as
|
||||
// set means that it was true or false based on
|
||||
// Bool flag type, should work for other types
|
||||
if len(envVal) > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func float64ToString(f float64) string {
|
||||
return fmt.Sprintf("%v", f)
|
||||
}
|
||||
|
||||
func eachName(longName string, fn func(string)) {
|
||||
parts := strings.Split(longName, ",")
|
||||
for _, name := range parts {
|
||||
name = strings.Trim(name, " ")
|
||||
fn(name)
|
||||
}
|
||||
}
|
|
@ -1,256 +0,0 @@
|
|||
package altsrc
|
||||
|
||||
import (
|
||||
"flag"
|
||||
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
)
|
||||
|
||||
// WARNING: This file is generated!
|
||||
|
||||
// BoolFlag is the flag type that wraps cli.BoolFlag to allow
|
||||
// for other values to be specified
|
||||
type BoolFlag struct {
|
||||
cli.BoolFlag
|
||||
set *flag.FlagSet
|
||||
}
|
||||
|
||||
// NewBoolFlag creates a new BoolFlag
|
||||
func NewBoolFlag(fl cli.BoolFlag) *BoolFlag {
|
||||
return &BoolFlag{BoolFlag: fl, set: nil}
|
||||
}
|
||||
|
||||
// Apply saves the flagSet for later usage calls, then calls the
|
||||
// wrapped BoolFlag.Apply
|
||||
func (f *BoolFlag) Apply(set *flag.FlagSet) {
|
||||
f.set = set
|
||||
f.BoolFlag.Apply(set)
|
||||
}
|
||||
|
||||
// BoolTFlag is the flag type that wraps cli.BoolTFlag to allow
|
||||
// for other values to be specified
|
||||
type BoolTFlag struct {
|
||||
cli.BoolTFlag
|
||||
set *flag.FlagSet
|
||||
}
|
||||
|
||||
// NewBoolTFlag creates a new BoolTFlag
|
||||
func NewBoolTFlag(fl cli.BoolTFlag) *BoolTFlag {
|
||||
return &BoolTFlag{BoolTFlag: fl, set: nil}
|
||||
}
|
||||
|
||||
// Apply saves the flagSet for later usage calls, then calls the
|
||||
// wrapped BoolTFlag.Apply
|
||||
func (f *BoolTFlag) Apply(set *flag.FlagSet) {
|
||||
f.set = set
|
||||
f.BoolTFlag.Apply(set)
|
||||
}
|
||||
|
||||
// DurationFlag is the flag type that wraps cli.DurationFlag to allow
|
||||
// for other values to be specified
|
||||
type DurationFlag struct {
|
||||
cli.DurationFlag
|
||||
set *flag.FlagSet
|
||||
}
|
||||
|
||||
// NewDurationFlag creates a new DurationFlag
|
||||
func NewDurationFlag(fl cli.DurationFlag) *DurationFlag {
|
||||
return &DurationFlag{DurationFlag: fl, set: nil}
|
||||
}
|
||||
|
||||
// Apply saves the flagSet for later usage calls, then calls the
|
||||
// wrapped DurationFlag.Apply
|
||||
func (f *DurationFlag) Apply(set *flag.FlagSet) {
|
||||
f.set = set
|
||||
f.DurationFlag.Apply(set)
|
||||
}
|
||||
|
||||
// Float64Flag is the flag type that wraps cli.Float64Flag to allow
|
||||
// for other values to be specified
|
||||
type Float64Flag struct {
|
||||
cli.Float64Flag
|
||||
set *flag.FlagSet
|
||||
}
|
||||
|
||||
// NewFloat64Flag creates a new Float64Flag
|
||||
func NewFloat64Flag(fl cli.Float64Flag) *Float64Flag {
|
||||
return &Float64Flag{Float64Flag: fl, set: nil}
|
||||
}
|
||||
|
||||
// Apply saves the flagSet for later usage calls, then calls the
|
||||
// wrapped Float64Flag.Apply
|
||||
func (f *Float64Flag) Apply(set *flag.FlagSet) {
|
||||
f.set = set
|
||||
f.Float64Flag.Apply(set)
|
||||
}
|
||||
|
||||
// GenericFlag is the flag type that wraps cli.GenericFlag to allow
|
||||
// for other values to be specified
|
||||
type GenericFlag struct {
|
||||
cli.GenericFlag
|
||||
set *flag.FlagSet
|
||||
}
|
||||
|
||||
// NewGenericFlag creates a new GenericFlag
|
||||
func NewGenericFlag(fl cli.GenericFlag) *GenericFlag {
|
||||
return &GenericFlag{GenericFlag: fl, set: nil}
|
||||
}
|
||||
|
||||
// Apply saves the flagSet for later usage calls, then calls the
|
||||
// wrapped GenericFlag.Apply
|
||||
func (f *GenericFlag) Apply(set *flag.FlagSet) {
|
||||
f.set = set
|
||||
f.GenericFlag.Apply(set)
|
||||
}
|
||||
|
||||
// Int64Flag is the flag type that wraps cli.Int64Flag to allow
|
||||
// for other values to be specified
|
||||
type Int64Flag struct {
|
||||
cli.Int64Flag
|
||||
set *flag.FlagSet
|
||||
}
|
||||
|
||||
// NewInt64Flag creates a new Int64Flag
|
||||
func NewInt64Flag(fl cli.Int64Flag) *Int64Flag {
|
||||
return &Int64Flag{Int64Flag: fl, set: nil}
|
||||
}
|
||||
|
||||
// Apply saves the flagSet for later usage calls, then calls the
|
||||
// wrapped Int64Flag.Apply
|
||||
func (f *Int64Flag) Apply(set *flag.FlagSet) {
|
||||
f.set = set
|
||||
f.Int64Flag.Apply(set)
|
||||
}
|
||||
|
||||
// IntFlag is the flag type that wraps cli.IntFlag to allow
|
||||
// for other values to be specified
|
||||
type IntFlag struct {
|
||||
cli.IntFlag
|
||||
set *flag.FlagSet
|
||||
}
|
||||
|
||||
// NewIntFlag creates a new IntFlag
|
||||
func NewIntFlag(fl cli.IntFlag) *IntFlag {
|
||||
return &IntFlag{IntFlag: fl, set: nil}
|
||||
}
|
||||
|
||||
// Apply saves the flagSet for later usage calls, then calls the
|
||||
// wrapped IntFlag.Apply
|
||||
func (f *IntFlag) Apply(set *flag.FlagSet) {
|
||||
f.set = set
|
||||
f.IntFlag.Apply(set)
|
||||
}
|
||||
|
||||
// IntSliceFlag is the flag type that wraps cli.IntSliceFlag to allow
|
||||
// for other values to be specified
|
||||
type IntSliceFlag struct {
|
||||
cli.IntSliceFlag
|
||||
set *flag.FlagSet
|
||||
}
|
||||
|
||||
// NewIntSliceFlag creates a new IntSliceFlag
|
||||
func NewIntSliceFlag(fl cli.IntSliceFlag) *IntSliceFlag {
|
||||
return &IntSliceFlag{IntSliceFlag: fl, set: nil}
|
||||
}
|
||||
|
||||
// Apply saves the flagSet for later usage calls, then calls the
|
||||
// wrapped IntSliceFlag.Apply
|
||||
func (f *IntSliceFlag) Apply(set *flag.FlagSet) {
|
||||
f.set = set
|
||||
f.IntSliceFlag.Apply(set)
|
||||
}
|
||||
|
||||
// Int64SliceFlag is the flag type that wraps cli.Int64SliceFlag to allow
|
||||
// for other values to be specified
|
||||
type Int64SliceFlag struct {
|
||||
cli.Int64SliceFlag
|
||||
set *flag.FlagSet
|
||||
}
|
||||
|
||||
// NewInt64SliceFlag creates a new Int64SliceFlag
|
||||
func NewInt64SliceFlag(fl cli.Int64SliceFlag) *Int64SliceFlag {
|
||||
return &Int64SliceFlag{Int64SliceFlag: fl, set: nil}
|
||||
}
|
||||
|
||||
// Apply saves the flagSet for later usage calls, then calls the
|
||||
// wrapped Int64SliceFlag.Apply
|
||||
func (f *Int64SliceFlag) Apply(set *flag.FlagSet) {
|
||||
f.set = set
|
||||
f.Int64SliceFlag.Apply(set)
|
||||
}
|
||||
|
||||
// StringFlag is the flag type that wraps cli.StringFlag to allow
|
||||
// for other values to be specified
|
||||
type StringFlag struct {
|
||||
cli.StringFlag
|
||||
set *flag.FlagSet
|
||||
}
|
||||
|
||||
// NewStringFlag creates a new StringFlag
|
||||
func NewStringFlag(fl cli.StringFlag) *StringFlag {
|
||||
return &StringFlag{StringFlag: fl, set: nil}
|
||||
}
|
||||
|
||||
// Apply saves the flagSet for later usage calls, then calls the
|
||||
// wrapped StringFlag.Apply
|
||||
func (f *StringFlag) Apply(set *flag.FlagSet) {
|
||||
f.set = set
|
||||
f.StringFlag.Apply(set)
|
||||
}
|
||||
|
||||
// StringSliceFlag is the flag type that wraps cli.StringSliceFlag to allow
|
||||
// for other values to be specified
|
||||
type StringSliceFlag struct {
|
||||
cli.StringSliceFlag
|
||||
set *flag.FlagSet
|
||||
}
|
||||
|
||||
// NewStringSliceFlag creates a new StringSliceFlag
|
||||
func NewStringSliceFlag(fl cli.StringSliceFlag) *StringSliceFlag {
|
||||
return &StringSliceFlag{StringSliceFlag: fl, set: nil}
|
||||
}
|
||||
|
||||
// Apply saves the flagSet for later usage calls, then calls the
|
||||
// wrapped StringSliceFlag.Apply
|
||||
func (f *StringSliceFlag) Apply(set *flag.FlagSet) {
|
||||
f.set = set
|
||||
f.StringSliceFlag.Apply(set)
|
||||
}
|
||||
|
||||
// Uint64Flag is the flag type that wraps cli.Uint64Flag to allow
|
||||
// for other values to be specified
|
||||
type Uint64Flag struct {
|
||||
cli.Uint64Flag
|
||||
set *flag.FlagSet
|
||||
}
|
||||
|
||||
// NewUint64Flag creates a new Uint64Flag
|
||||
func NewUint64Flag(fl cli.Uint64Flag) *Uint64Flag {
|
||||
return &Uint64Flag{Uint64Flag: fl, set: nil}
|
||||
}
|
||||
|
||||
// Apply saves the flagSet for later usage calls, then calls the
|
||||
// wrapped Uint64Flag.Apply
|
||||
func (f *Uint64Flag) Apply(set *flag.FlagSet) {
|
||||
f.set = set
|
||||
f.Uint64Flag.Apply(set)
|
||||
}
|
||||
|
||||
// UintFlag is the flag type that wraps cli.UintFlag to allow
|
||||
// for other values to be specified
|
||||
type UintFlag struct {
|
||||
cli.UintFlag
|
||||
set *flag.FlagSet
|
||||
}
|
||||
|
||||
// NewUintFlag creates a new UintFlag
|
||||
func NewUintFlag(fl cli.UintFlag) *UintFlag {
|
||||
return &UintFlag{UintFlag: fl, set: nil}
|
||||
}
|
||||
|
||||
// Apply saves the flagSet for later usage calls, then calls the
|
||||
// wrapped UintFlag.Apply
|
||||
func (f *UintFlag) Apply(set *flag.FlagSet) {
|
||||
f.set = set
|
||||
f.UintFlag.Apply(set)
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package altsrc
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
)
|
||||
|
||||
// InputSourceContext is an interface used to allow
|
||||
// other input sources to be implemented as needed.
|
||||
type InputSourceContext interface {
|
||||
Int(name string) (int, error)
|
||||
Duration(name string) (time.Duration, error)
|
||||
Float64(name string) (float64, error)
|
||||
String(name string) (string, error)
|
||||
StringSlice(name string) ([]string, error)
|
||||
IntSlice(name string) ([]int, error)
|
||||
Generic(name string) (cli.Generic, error)
|
||||
Bool(name string) (bool, error)
|
||||
BoolT(name string) (bool, error)
|
||||
}
|
|
@ -1,248 +0,0 @@
|
|||
package altsrc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
)
|
||||
|
||||
// MapInputSource implements InputSourceContext to return
|
||||
// data from the map that is loaded.
|
||||
type MapInputSource struct {
|
||||
valueMap map[interface{}]interface{}
|
||||
}
|
||||
|
||||
// nestedVal checks if the name has '.' delimiters.
|
||||
// If so, it tries to traverse the tree by the '.' delimited sections to find
|
||||
// a nested value for the key.
|
||||
func nestedVal(name string, tree map[interface{}]interface{}) (interface{}, bool) {
|
||||
if sections := strings.Split(name, "."); len(sections) > 1 {
|
||||
node := tree
|
||||
for _, section := range sections[:len(sections)-1] {
|
||||
if child, ok := node[section]; !ok {
|
||||
return nil, false
|
||||
} else {
|
||||
if ctype, ok := child.(map[interface{}]interface{}); !ok {
|
||||
return nil, false
|
||||
} else {
|
||||
node = ctype
|
||||
}
|
||||
}
|
||||
}
|
||||
if val, ok := node[sections[len(sections)-1]]; ok {
|
||||
return val, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// Int returns an int from the map if it exists otherwise returns 0
|
||||
func (fsm *MapInputSource) Int(name string) (int, error) {
|
||||
otherGenericValue, exists := fsm.valueMap[name]
|
||||
if exists {
|
||||
otherValue, isType := otherGenericValue.(int)
|
||||
if !isType {
|
||||
return 0, incorrectTypeForFlagError(name, "int", otherGenericValue)
|
||||
}
|
||||
return otherValue, nil
|
||||
}
|
||||
nestedGenericValue, exists := nestedVal(name, fsm.valueMap)
|
||||
if exists {
|
||||
otherValue, isType := nestedGenericValue.(int)
|
||||
if !isType {
|
||||
return 0, incorrectTypeForFlagError(name, "int", nestedGenericValue)
|
||||
}
|
||||
return otherValue, nil
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// Duration returns a duration from the map if it exists otherwise returns 0
|
||||
func (fsm *MapInputSource) Duration(name string) (time.Duration, error) {
|
||||
otherGenericValue, exists := fsm.valueMap[name]
|
||||
if exists {
|
||||
otherValue, isType := otherGenericValue.(time.Duration)
|
||||
if !isType {
|
||||
return 0, incorrectTypeForFlagError(name, "duration", otherGenericValue)
|
||||
}
|
||||
return otherValue, nil
|
||||
}
|
||||
nestedGenericValue, exists := nestedVal(name, fsm.valueMap)
|
||||
if exists {
|
||||
otherValue, isType := nestedGenericValue.(time.Duration)
|
||||
if !isType {
|
||||
return 0, incorrectTypeForFlagError(name, "duration", nestedGenericValue)
|
||||
}
|
||||
return otherValue, nil
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// Float64 returns an float64 from the map if it exists otherwise returns 0
|
||||
func (fsm *MapInputSource) Float64(name string) (float64, error) {
|
||||
otherGenericValue, exists := fsm.valueMap[name]
|
||||
if exists {
|
||||
otherValue, isType := otherGenericValue.(float64)
|
||||
if !isType {
|
||||
return 0, incorrectTypeForFlagError(name, "float64", otherGenericValue)
|
||||
}
|
||||
return otherValue, nil
|
||||
}
|
||||
nestedGenericValue, exists := nestedVal(name, fsm.valueMap)
|
||||
if exists {
|
||||
otherValue, isType := nestedGenericValue.(float64)
|
||||
if !isType {
|
||||
return 0, incorrectTypeForFlagError(name, "float64", nestedGenericValue)
|
||||
}
|
||||
return otherValue, nil
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// String returns a string from the map if it exists otherwise returns an empty string
|
||||
func (fsm *MapInputSource) String(name string) (string, error) {
|
||||
otherGenericValue, exists := fsm.valueMap[name]
|
||||
if exists {
|
||||
otherValue, isType := otherGenericValue.(string)
|
||||
if !isType {
|
||||
return "", incorrectTypeForFlagError(name, "string", otherGenericValue)
|
||||
}
|
||||
return otherValue, nil
|
||||
}
|
||||
nestedGenericValue, exists := nestedVal(name, fsm.valueMap)
|
||||
if exists {
|
||||
otherValue, isType := nestedGenericValue.(string)
|
||||
if !isType {
|
||||
return "", incorrectTypeForFlagError(name, "string", nestedGenericValue)
|
||||
}
|
||||
return otherValue, nil
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// StringSlice returns an []string from the map if it exists otherwise returns nil
|
||||
func (fsm *MapInputSource) StringSlice(name string) ([]string, error) {
|
||||
otherGenericValue, exists := fsm.valueMap[name]
|
||||
if exists {
|
||||
otherValue, isType := otherGenericValue.([]string)
|
||||
if !isType {
|
||||
return nil, incorrectTypeForFlagError(name, "[]string", otherGenericValue)
|
||||
}
|
||||
return otherValue, nil
|
||||
}
|
||||
nestedGenericValue, exists := nestedVal(name, fsm.valueMap)
|
||||
if exists {
|
||||
otherValue, isType := nestedGenericValue.([]string)
|
||||
if !isType {
|
||||
return nil, incorrectTypeForFlagError(name, "[]string", nestedGenericValue)
|
||||
}
|
||||
return otherValue, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// IntSlice returns an []int from the map if it exists otherwise returns nil
|
||||
func (fsm *MapInputSource) IntSlice(name string) ([]int, error) {
|
||||
otherGenericValue, exists := fsm.valueMap[name]
|
||||
if exists {
|
||||
otherValue, isType := otherGenericValue.([]int)
|
||||
if !isType {
|
||||
return nil, incorrectTypeForFlagError(name, "[]int", otherGenericValue)
|
||||
}
|
||||
return otherValue, nil
|
||||
}
|
||||
nestedGenericValue, exists := nestedVal(name, fsm.valueMap)
|
||||
if exists {
|
||||
otherValue, isType := nestedGenericValue.([]int)
|
||||
if !isType {
|
||||
return nil, incorrectTypeForFlagError(name, "[]int", nestedGenericValue)
|
||||
}
|
||||
return otherValue, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Generic returns an cli.Generic from the map if it exists otherwise returns nil
|
||||
func (fsm *MapInputSource) Generic(name string) (cli.Generic, error) {
|
||||
otherGenericValue, exists := fsm.valueMap[name]
|
||||
if exists {
|
||||
otherValue, isType := otherGenericValue.(cli.Generic)
|
||||
if !isType {
|
||||
return nil, incorrectTypeForFlagError(name, "cli.Generic", otherGenericValue)
|
||||
}
|
||||
return otherValue, nil
|
||||
}
|
||||
nestedGenericValue, exists := nestedVal(name, fsm.valueMap)
|
||||
if exists {
|
||||
otherValue, isType := nestedGenericValue.(cli.Generic)
|
||||
if !isType {
|
||||
return nil, incorrectTypeForFlagError(name, "cli.Generic", nestedGenericValue)
|
||||
}
|
||||
return otherValue, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Bool returns an bool from the map otherwise returns false
|
||||
func (fsm *MapInputSource) Bool(name string) (bool, error) {
|
||||
otherGenericValue, exists := fsm.valueMap[name]
|
||||
if exists {
|
||||
otherValue, isType := otherGenericValue.(bool)
|
||||
if !isType {
|
||||
return false, incorrectTypeForFlagError(name, "bool", otherGenericValue)
|
||||
}
|
||||
return otherValue, nil
|
||||
}
|
||||
nestedGenericValue, exists := nestedVal(name, fsm.valueMap)
|
||||
if exists {
|
||||
otherValue, isType := nestedGenericValue.(bool)
|
||||
if !isType {
|
||||
return false, incorrectTypeForFlagError(name, "bool", nestedGenericValue)
|
||||
}
|
||||
return otherValue, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// BoolT returns an bool from the map otherwise returns true
|
||||
func (fsm *MapInputSource) BoolT(name string) (bool, error) {
|
||||
otherGenericValue, exists := fsm.valueMap[name]
|
||||
if exists {
|
||||
otherValue, isType := otherGenericValue.(bool)
|
||||
if !isType {
|
||||
return true, incorrectTypeForFlagError(name, "bool", otherGenericValue)
|
||||
}
|
||||
return otherValue, nil
|
||||
}
|
||||
nestedGenericValue, exists := nestedVal(name, fsm.valueMap)
|
||||
if exists {
|
||||
otherValue, isType := nestedGenericValue.(bool)
|
||||
if !isType {
|
||||
return true, incorrectTypeForFlagError(name, "bool", nestedGenericValue)
|
||||
}
|
||||
return otherValue, nil
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func incorrectTypeForFlagError(name, expectedTypeName string, value interface{}) error {
|
||||
valueType := reflect.TypeOf(value)
|
||||
valueTypeName := ""
|
||||
if valueType != nil {
|
||||
valueTypeName = valueType.Name()
|
||||
}
|
||||
|
||||
return fmt.Errorf("Mismatched type for flag '%s'. Expected '%s' but actual is '%s'", name, expectedTypeName, valueTypeName)
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
// Disabling building of toml support in cases where golang is 1.0 or 1.1
|
||||
// as the encoding library is not implemented or supported.
|
||||
|
||||
// +build go1.2
|
||||
|
||||
package altsrc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
)
|
||||
|
||||
type tomlMap struct {
|
||||
Map map[interface{}]interface{}
|
||||
}
|
||||
|
||||
func unmarshalMap(i interface{}) (ret map[interface{}]interface{}, err error) {
|
||||
ret = make(map[interface{}]interface{})
|
||||
m := i.(map[string]interface{})
|
||||
for key, val := range m {
|
||||
v := reflect.ValueOf(val)
|
||||
switch v.Kind() {
|
||||
case reflect.Bool:
|
||||
ret[key] = val.(bool)
|
||||
case reflect.String:
|
||||
ret[key] = val.(string)
|
||||
case reflect.Int:
|
||||
ret[key] = int(val.(int))
|
||||
case reflect.Int8:
|
||||
ret[key] = int(val.(int8))
|
||||
case reflect.Int16:
|
||||
ret[key] = int(val.(int16))
|
||||
case reflect.Int32:
|
||||
ret[key] = int(val.(int32))
|
||||
case reflect.Int64:
|
||||
ret[key] = int(val.(int64))
|
||||
case reflect.Uint:
|
||||
ret[key] = int(val.(uint))
|
||||
case reflect.Uint8:
|
||||
ret[key] = int(val.(uint8))
|
||||
case reflect.Uint16:
|
||||
ret[key] = int(val.(uint16))
|
||||
case reflect.Uint32:
|
||||
ret[key] = int(val.(uint32))
|
||||
case reflect.Uint64:
|
||||
ret[key] = int(val.(uint64))
|
||||
case reflect.Float32:
|
||||
ret[key] = float64(val.(float32))
|
||||
case reflect.Float64:
|
||||
ret[key] = float64(val.(float64))
|
||||
case reflect.Map:
|
||||
if tmp, err := unmarshalMap(val); err == nil {
|
||||
ret[key] = tmp
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
case reflect.Array:
|
||||
fallthrough // [todo] - Support array type
|
||||
default:
|
||||
return nil, fmt.Errorf("Unsupported: type = %#v", v.Kind())
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *tomlMap) UnmarshalTOML(i interface{}) error {
|
||||
if tmp, err := unmarshalMap(i); err == nil {
|
||||
self.Map = tmp
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type tomlSourceContext struct {
|
||||
FilePath string
|
||||
}
|
||||
|
||||
// NewTomlSourceFromFile creates a new TOML InputSourceContext from a filepath.
|
||||
func NewTomlSourceFromFile(file string) (InputSourceContext, error) {
|
||||
tsc := &tomlSourceContext{FilePath: file}
|
||||
var results tomlMap = tomlMap{}
|
||||
if err := readCommandToml(tsc.FilePath, &results); err != nil {
|
||||
return nil, fmt.Errorf("Unable to load TOML file '%s': inner error: \n'%v'", tsc.FilePath, err.Error())
|
||||
}
|
||||
return &MapInputSource{valueMap: results.Map}, nil
|
||||
}
|
||||
|
||||
// NewTomlSourceFromFlagFunc creates a new TOML InputSourceContext from a provided flag name and source context.
|
||||
func NewTomlSourceFromFlagFunc(flagFileName string) func(context *cli.Context) (InputSourceContext, error) {
|
||||
return func(context *cli.Context) (InputSourceContext, error) {
|
||||
filePath := context.String(flagFileName)
|
||||
return NewTomlSourceFromFile(filePath)
|
||||
}
|
||||
}
|
||||
|
||||
func readCommandToml(filePath string, container interface{}) (err error) {
|
||||
b, err := loadDataFrom(filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = toml.Unmarshal(b, container)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = nil
|
||||
return
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
// Disabling building of yaml support in cases where golang is 1.0 or 1.1
|
||||
// as the encoding library is not implemented or supported.
|
||||
|
||||
// +build go1.2
|
||||
|
||||
package altsrc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
type yamlSourceContext struct {
|
||||
FilePath string
|
||||
}
|
||||
|
||||
// NewYamlSourceFromFile creates a new Yaml InputSourceContext from a filepath.
|
||||
func NewYamlSourceFromFile(file string) (InputSourceContext, error) {
|
||||
ysc := &yamlSourceContext{FilePath: file}
|
||||
var results map[interface{}]interface{}
|
||||
err := readCommandYaml(ysc.FilePath, &results)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Unable to load Yaml file '%s': inner error: \n'%v'", ysc.FilePath, err.Error())
|
||||
}
|
||||
|
||||
return &MapInputSource{valueMap: results}, nil
|
||||
}
|
||||
|
||||
// NewYamlSourceFromFlagFunc creates a new Yaml InputSourceContext from a provided flag name and source context.
|
||||
func NewYamlSourceFromFlagFunc(flagFileName string) func(context *cli.Context) (InputSourceContext, error) {
|
||||
return func(context *cli.Context) (InputSourceContext, error) {
|
||||
filePath := context.String(flagFileName)
|
||||
return NewYamlSourceFromFile(filePath)
|
||||
}
|
||||
}
|
||||
|
||||
func readCommandYaml(filePath string, container interface{}) (err error) {
|
||||
b, err := loadDataFrom(filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(b, container)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
|
||||
func loadDataFrom(filePath string) ([]byte, error) {
|
||||
u, err := url.Parse(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if u.Host != "" { // i have a host, now do i support the scheme?
|
||||
switch u.Scheme {
|
||||
case "http", "https":
|
||||
res, err := http.Get(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ioutil.ReadAll(res.Body)
|
||||
default:
|
||||
return nil, fmt.Errorf("scheme of %s is unsupported", filePath)
|
||||
}
|
||||
} else if u.Path != "" { // i dont have a host, but I have a path. I am a local file.
|
||||
if _, notFoundFileErr := os.Stat(filePath); notFoundFileErr != nil {
|
||||
return nil, fmt.Errorf("Cannot read from file: '%s' because it does not exist.", filePath)
|
||||
}
|
||||
return ioutil.ReadFile(filePath)
|
||||
} else {
|
||||
return nil, fmt.Errorf("unable to determine how to load from path %s", filePath)
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
version: "{build}"
|
||||
|
||||
os: Windows Server 2012 R2
|
||||
|
||||
clone_folder: c:\gopath\src\github.com\urfave\cli
|
||||
|
||||
environment:
|
||||
GOPATH: C:\gopath
|
||||
GOVERSION: 1.6
|
||||
PYTHON: C:\Python27-x64
|
||||
PYTHON_VERSION: 2.7.x
|
||||
PYTHON_ARCH: 64
|
||||
|
||||
install:
|
||||
- set PATH=%GOPATH%\bin;C:\go\bin;%PATH%
|
||||
- go version
|
||||
- go env
|
||||
- go get github.com/urfave/gfmrun/...
|
||||
- go get -v -t ./...
|
||||
|
||||
build_script:
|
||||
- python runtests vet
|
||||
- python runtests test
|
||||
- python runtests gfmrun
|
|
@ -1,14 +0,0 @@
|
|||
#! /bin/bash
|
||||
|
||||
: ${PROG:=$(basename ${BASH_SOURCE})}
|
||||
|
||||
_cli_bash_autocomplete() {
|
||||
local cur opts base
|
||||
COMPREPLY=()
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion )
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
||||
return 0
|
||||
}
|
||||
|
||||
complete -F _cli_bash_autocomplete $PROG
|
|
@ -1,5 +0,0 @@
|
|||
autoload -U compinit && compinit
|
||||
autoload -U bashcompinit && bashcompinit
|
||||
|
||||
script_dir=$(dirname $0)
|
||||
source ${script_dir}/bash_autocomplete
|
|
@ -1,93 +0,0 @@
|
|||
[
|
||||
{
|
||||
"name": "Bool",
|
||||
"type": "bool",
|
||||
"value": false,
|
||||
"context_default": "false",
|
||||
"parser": "strconv.ParseBool(f.Value.String())"
|
||||
},
|
||||
{
|
||||
"name": "BoolT",
|
||||
"type": "bool",
|
||||
"value": false,
|
||||
"doctail": " that is true by default",
|
||||
"context_default": "false",
|
||||
"parser": "strconv.ParseBool(f.Value.String())"
|
||||
},
|
||||
{
|
||||
"name": "Duration",
|
||||
"type": "time.Duration",
|
||||
"doctail": " (see https://golang.org/pkg/time/#ParseDuration)",
|
||||
"context_default": "0",
|
||||
"parser": "time.ParseDuration(f.Value.String())"
|
||||
},
|
||||
{
|
||||
"name": "Float64",
|
||||
"type": "float64",
|
||||
"context_default": "0",
|
||||
"parser": "strconv.ParseFloat(f.Value.String(), 64)"
|
||||
},
|
||||
{
|
||||
"name": "Generic",
|
||||
"type": "Generic",
|
||||
"dest": false,
|
||||
"context_default": "nil",
|
||||
"context_type": "interface{}"
|
||||
},
|
||||
{
|
||||
"name": "Int64",
|
||||
"type": "int64",
|
||||
"context_default": "0",
|
||||
"parser": "strconv.ParseInt(f.Value.String(), 0, 64)"
|
||||
},
|
||||
{
|
||||
"name": "Int",
|
||||
"type": "int",
|
||||
"context_default": "0",
|
||||
"parser": "strconv.ParseInt(f.Value.String(), 0, 64)",
|
||||
"parser_cast": "int(parsed)"
|
||||
},
|
||||
{
|
||||
"name": "IntSlice",
|
||||
"type": "*IntSlice",
|
||||
"dest": false,
|
||||
"context_default": "nil",
|
||||
"context_type": "[]int",
|
||||
"parser": "(f.Value.(*IntSlice)).Value(), error(nil)"
|
||||
},
|
||||
{
|
||||
"name": "Int64Slice",
|
||||
"type": "*Int64Slice",
|
||||
"dest": false,
|
||||
"context_default": "nil",
|
||||
"context_type": "[]int64",
|
||||
"parser": "(f.Value.(*Int64Slice)).Value(), error(nil)"
|
||||
},
|
||||
{
|
||||
"name": "String",
|
||||
"type": "string",
|
||||
"context_default": "\"\"",
|
||||
"parser": "f.Value.String(), error(nil)"
|
||||
},
|
||||
{
|
||||
"name": "StringSlice",
|
||||
"type": "*StringSlice",
|
||||
"dest": false,
|
||||
"context_default": "nil",
|
||||
"context_type": "[]string",
|
||||
"parser": "(f.Value.(*StringSlice)).Value(), error(nil)"
|
||||
},
|
||||
{
|
||||
"name": "Uint64",
|
||||
"type": "uint64",
|
||||
"context_default": "0",
|
||||
"parser": "strconv.ParseUint(f.Value.String(), 0, 64)"
|
||||
},
|
||||
{
|
||||
"name": "Uint",
|
||||
"type": "uint",
|
||||
"context_default": "0",
|
||||
"parser": "strconv.ParseUint(f.Value.String(), 0, 64)",
|
||||
"parser_cast": "uint(parsed)"
|
||||
}
|
||||
]
|
|
@ -1,248 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
"""
|
||||
The flag types that ship with the cli library have many things in common, and
|
||||
so we can take advantage of the `go generate` command to create much of the
|
||||
source code from a list of definitions. These definitions attempt to cover
|
||||
the parts that vary between flag types, and should evolve as needed.
|
||||
|
||||
An example of the minimum definition needed is:
|
||||
|
||||
{
|
||||
"name": "SomeType",
|
||||
"type": "sometype",
|
||||
"context_default": "nil"
|
||||
}
|
||||
|
||||
In this example, the code generated for the `cli` package will include a type
|
||||
named `SomeTypeFlag` that is expected to wrap a value of type `sometype`.
|
||||
Fetching values by name via `*cli.Context` will default to a value of `nil`.
|
||||
|
||||
A more complete, albeit somewhat redundant, example showing all available
|
||||
definition keys is:
|
||||
|
||||
{
|
||||
"name": "VeryMuchType",
|
||||
"type": "*VeryMuchType",
|
||||
"value": true,
|
||||
"dest": false,
|
||||
"doctail": " which really only wraps a []float64, oh well!",
|
||||
"context_type": "[]float64",
|
||||
"context_default": "nil",
|
||||
"parser": "parseVeryMuchType(f.Value.String())",
|
||||
"parser_cast": "[]float64(parsed)"
|
||||
}
|
||||
|
||||
The meaning of each field is as follows:
|
||||
|
||||
name (string) - The type "name", which will be suffixed with
|
||||
`Flag` when generating the type definition
|
||||
for `cli` and the wrapper type for `altsrc`
|
||||
type (string) - The type that the generated `Flag` type for `cli`
|
||||
is expected to "contain" as its `.Value` member
|
||||
value (bool) - Should the generated `cli` type have a `Value`
|
||||
member?
|
||||
dest (bool) - Should the generated `cli` type support a
|
||||
destination pointer?
|
||||
doctail (string) - Additional docs for the `cli` flag type comment
|
||||
context_type (string) - The literal type used in the `*cli.Context`
|
||||
reader func signature
|
||||
context_default (string) - The literal value used as the default by the
|
||||
`*cli.Context` reader funcs when no value is
|
||||
present
|
||||
parser (string) - Literal code used to parse the flag `f`,
|
||||
expected to have a return signature of
|
||||
(value, error)
|
||||
parser_cast (string) - Literal code used to cast the `parsed` value
|
||||
returned from the `parser` code
|
||||
"""
|
||||
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import textwrap
|
||||
|
||||
|
||||
class _FancyFormatter(argparse.ArgumentDefaultsHelpFormatter,
|
||||
argparse.RawDescriptionHelpFormatter):
|
||||
pass
|
||||
|
||||
|
||||
def main(sysargs=sys.argv[:]):
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Generate flag type code!',
|
||||
formatter_class=_FancyFormatter)
|
||||
parser.add_argument(
|
||||
'package',
|
||||
type=str, default='cli', choices=_WRITEFUNCS.keys(),
|
||||
help='Package for which flag types will be generated'
|
||||
)
|
||||
parser.add_argument(
|
||||
'-i', '--in-json',
|
||||
type=argparse.FileType('r'),
|
||||
default=sys.stdin,
|
||||
help='Input JSON file which defines each type to be generated'
|
||||
)
|
||||
parser.add_argument(
|
||||
'-o', '--out-go',
|
||||
type=argparse.FileType('w'),
|
||||
default=sys.stdout,
|
||||
help='Output file/stream to which generated source will be written'
|
||||
)
|
||||
parser.epilog = __doc__
|
||||
|
||||
args = parser.parse_args(sysargs[1:])
|
||||
_generate_flag_types(_WRITEFUNCS[args.package], args.out_go, args.in_json)
|
||||
return 0
|
||||
|
||||
|
||||
def _generate_flag_types(writefunc, output_go, input_json):
|
||||
types = json.load(input_json)
|
||||
|
||||
tmp = tempfile.NamedTemporaryFile(suffix='.go', delete=False)
|
||||
writefunc(tmp, types)
|
||||
tmp.close()
|
||||
|
||||
new_content = subprocess.check_output(
|
||||
['goimports', tmp.name]
|
||||
).decode('utf-8')
|
||||
|
||||
print(new_content, file=output_go, end='')
|
||||
output_go.flush()
|
||||
os.remove(tmp.name)
|
||||
|
||||
|
||||
def _set_typedef_defaults(typedef):
|
||||
typedef.setdefault('doctail', '')
|
||||
typedef.setdefault('context_type', typedef['type'])
|
||||
typedef.setdefault('dest', True)
|
||||
typedef.setdefault('value', True)
|
||||
typedef.setdefault('parser', 'f.Value, error(nil)')
|
||||
typedef.setdefault('parser_cast', 'parsed')
|
||||
|
||||
|
||||
def _write_cli_flag_types(outfile, types):
|
||||
_fwrite(outfile, """\
|
||||
package cli
|
||||
|
||||
// WARNING: This file is generated!
|
||||
|
||||
""")
|
||||
|
||||
for typedef in types:
|
||||
_set_typedef_defaults(typedef)
|
||||
|
||||
_fwrite(outfile, """\
|
||||
// {name}Flag is a flag with type {type}{doctail}
|
||||
type {name}Flag struct {{
|
||||
Name string
|
||||
Usage string
|
||||
EnvVar string
|
||||
Hidden bool
|
||||
""".format(**typedef))
|
||||
|
||||
if typedef['value']:
|
||||
_fwrite(outfile, """\
|
||||
Value {type}
|
||||
""".format(**typedef))
|
||||
|
||||
if typedef['dest']:
|
||||
_fwrite(outfile, """\
|
||||
Destination *{type}
|
||||
""".format(**typedef))
|
||||
|
||||
_fwrite(outfile, "\n}\n\n")
|
||||
|
||||
_fwrite(outfile, """\
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f {name}Flag) String() string {{
|
||||
return FlagStringer(f)
|
||||
}}
|
||||
|
||||
// GetName returns the name of the flag
|
||||
func (f {name}Flag) GetName() string {{
|
||||
return f.Name
|
||||
}}
|
||||
|
||||
// {name} looks up the value of a local {name}Flag, returns
|
||||
// {context_default} if not found
|
||||
func (c *Context) {name}(name string) {context_type} {{
|
||||
return lookup{name}(name, c.flagSet)
|
||||
}}
|
||||
|
||||
// Global{name} looks up the value of a global {name}Flag, returns
|
||||
// {context_default} if not found
|
||||
func (c *Context) Global{name}(name string) {context_type} {{
|
||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {{
|
||||
return lookup{name}(name, fs)
|
||||
}}
|
||||
return {context_default}
|
||||
}}
|
||||
|
||||
func lookup{name}(name string, set *flag.FlagSet) {context_type} {{
|
||||
f := set.Lookup(name)
|
||||
if f != nil {{
|
||||
parsed, err := {parser}
|
||||
if err != nil {{
|
||||
return {context_default}
|
||||
}}
|
||||
return {parser_cast}
|
||||
}}
|
||||
return {context_default}
|
||||
}}
|
||||
""".format(**typedef))
|
||||
|
||||
|
||||
def _write_altsrc_flag_types(outfile, types):
|
||||
_fwrite(outfile, """\
|
||||
package altsrc
|
||||
|
||||
import (
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
)
|
||||
|
||||
// WARNING: This file is generated!
|
||||
|
||||
""")
|
||||
|
||||
for typedef in types:
|
||||
_set_typedef_defaults(typedef)
|
||||
|
||||
_fwrite(outfile, """\
|
||||
// {name}Flag is the flag type that wraps cli.{name}Flag to allow
|
||||
// for other values to be specified
|
||||
type {name}Flag struct {{
|
||||
cli.{name}Flag
|
||||
set *flag.FlagSet
|
||||
}}
|
||||
|
||||
// New{name}Flag creates a new {name}Flag
|
||||
func New{name}Flag(fl cli.{name}Flag) *{name}Flag {{
|
||||
return &{name}Flag{{{name}Flag: fl, set: nil}}
|
||||
}}
|
||||
|
||||
// Apply saves the flagSet for later usage calls, then calls the
|
||||
// wrapped {name}Flag.Apply
|
||||
func (f *{name}Flag) Apply(set *flag.FlagSet) {{
|
||||
f.set = set
|
||||
f.{name}Flag.Apply(set)
|
||||
}}
|
||||
""".format(**typedef))
|
||||
|
||||
|
||||
def _fwrite(outfile, text):
|
||||
print(textwrap.dedent(text), end='', file=outfile)
|
||||
|
||||
|
||||
_WRITEFUNCS = {
|
||||
'cli': _write_cli_flag_types,
|
||||
'altsrc': _write_altsrc_flag_types
|
||||
}
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
|
@ -1,122 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
from subprocess import check_call, check_output
|
||||
|
||||
|
||||
PACKAGE_NAME = os.environ.get(
|
||||
'CLI_PACKAGE_NAME', 'github.com/urfave/cli'
|
||||
)
|
||||
|
||||
|
||||
def main(sysargs=sys.argv[:]):
|
||||
targets = {
|
||||
'vet': _vet,
|
||||
'test': _test,
|
||||
'gfmrun': _gfmrun,
|
||||
'toc': _toc,
|
||||
'gen': _gen,
|
||||
}
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
'target', nargs='?', choices=tuple(targets.keys()), default='test'
|
||||
)
|
||||
args = parser.parse_args(sysargs[1:])
|
||||
|
||||
targets[args.target]()
|
||||
return 0
|
||||
|
||||
|
||||
def _test():
|
||||
if check_output('go version'.split()).split()[2] < 'go1.2':
|
||||
_run('go test -v .')
|
||||
return
|
||||
|
||||
coverprofiles = []
|
||||
for subpackage in ['', 'altsrc']:
|
||||
coverprofile = 'cli.coverprofile'
|
||||
if subpackage != '':
|
||||
coverprofile = '{}.coverprofile'.format(subpackage)
|
||||
|
||||
coverprofiles.append(coverprofile)
|
||||
|
||||
_run('go test -v'.split() + [
|
||||
'-coverprofile={}'.format(coverprofile),
|
||||
('{}/{}'.format(PACKAGE_NAME, subpackage)).rstrip('/')
|
||||
])
|
||||
|
||||
combined_name = _combine_coverprofiles(coverprofiles)
|
||||
_run('go tool cover -func={}'.format(combined_name))
|
||||
os.remove(combined_name)
|
||||
|
||||
|
||||
def _gfmrun():
|
||||
go_version = check_output('go version'.split()).split()[2]
|
||||
if go_version < 'go1.3':
|
||||
print('runtests: skip on {}'.format(go_version), file=sys.stderr)
|
||||
return
|
||||
_run(['gfmrun', '-c', str(_gfmrun_count()), '-s', 'README.md'])
|
||||
|
||||
|
||||
def _vet():
|
||||
_run('go vet ./...')
|
||||
|
||||
|
||||
def _toc():
|
||||
_run('node_modules/.bin/markdown-toc -i README.md')
|
||||
_run('git diff --exit-code')
|
||||
|
||||
|
||||
def _gen():
|
||||
go_version = check_output('go version'.split()).split()[2]
|
||||
if go_version < 'go1.5':
|
||||
print('runtests: skip on {}'.format(go_version), file=sys.stderr)
|
||||
return
|
||||
|
||||
_run('go generate ./...')
|
||||
_run('git diff --exit-code')
|
||||
|
||||
|
||||
def _run(command):
|
||||
if hasattr(command, 'split'):
|
||||
command = command.split()
|
||||
print('runtests: {}'.format(' '.join(command)), file=sys.stderr)
|
||||
check_call(command)
|
||||
|
||||
|
||||
def _gfmrun_count():
|
||||
with open('README.md') as infile:
|
||||
lines = infile.read().splitlines()
|
||||
return len(filter(_is_go_runnable, lines))
|
||||
|
||||
|
||||
def _is_go_runnable(line):
|
||||
return line.startswith('package main')
|
||||
|
||||
|
||||
def _combine_coverprofiles(coverprofiles):
|
||||
combined = tempfile.NamedTemporaryFile(
|
||||
suffix='.coverprofile', delete=False
|
||||
)
|
||||
combined.write('mode: set\n')
|
||||
|
||||
for coverprofile in coverprofiles:
|
||||
with open(coverprofile, 'r') as infile:
|
||||
for line in infile.readlines():
|
||||
if not line.startswith('mode: '):
|
||||
combined.write(line)
|
||||
|
||||
combined.flush()
|
||||
name = combined.name
|
||||
combined.close()
|
||||
return name
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
|
@ -1,3 +0,0 @@
|
|||
language: go
|
||||
install:
|
||||
- go get github.com/vishvananda/netns
|
|
@ -1,192 +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
|
||||
|
||||
Copyright 2014 Vishvananda Ishaya.
|
||||
Copyright 2014 Docker, Inc.
|
||||
|
||||
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.
|
|
@ -1,29 +0,0 @@
|
|||
DIRS := \
|
||||
. \
|
||||
nl
|
||||
|
||||
DEPS = \
|
||||
github.com/vishvananda/netns
|
||||
|
||||
uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))
|
||||
testdirs = $(call uniq,$(foreach d,$(1),$(dir $(wildcard $(d)/*_test.go))))
|
||||
goroot = $(addprefix ../../../,$(1))
|
||||
unroot = $(subst ../../../,,$(1))
|
||||
fmt = $(addprefix fmt-,$(1))
|
||||
|
||||
all: fmt
|
||||
|
||||
$(call goroot,$(DEPS)):
|
||||
go get $(call unroot,$@)
|
||||
|
||||
.PHONY: $(call testdirs,$(DIRS))
|
||||
$(call testdirs,$(DIRS)):
|
||||
sudo -E go test -v github.com/vishvananda/netlink/$@
|
||||
|
||||
$(call fmt,$(call testdirs,$(DIRS))):
|
||||
! gofmt -l $(subst fmt-,,$@)/*.go | grep ''
|
||||
|
||||
.PHONY: fmt
|
||||
fmt: $(call fmt,$(call testdirs,$(DIRS)))
|
||||
|
||||
test: fmt $(call goroot,$(DEPS)) $(call testdirs,$(DIRS))
|
28
Makefile
28
Makefile
|
@ -12,8 +12,6 @@ PROJECT := github.com/opencontainers/runc
|
|||
BUILDTAGS := seccomp
|
||||
COMMIT_NO := $(shell git rev-parse HEAD 2> /dev/null || true)
|
||||
COMMIT := $(if $(shell git status --porcelain --untracked-files=no),"${COMMIT_NO}-dirty","${COMMIT_NO}")
|
||||
RUNC_LINK := $(CURDIR)/Godeps/_workspace/src/github.com/opencontainers/runc
|
||||
export GOPATH := $(CURDIR)/Godeps/_workspace
|
||||
|
||||
MAN_DIR := $(CURDIR)/man/man8
|
||||
MAN_PAGES = $(shell ls $(MAN_DIR)/*.8)
|
||||
|
@ -28,21 +26,21 @@ SHELL := $(shell command -v bash 2>/dev/null)
|
|||
|
||||
.DEFAULT: runc
|
||||
|
||||
runc: $(SOURCES) | $(RUNC_LINK)
|
||||
runc: $(SOURCES)
|
||||
go build -i -ldflags "-X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -tags "$(BUILDTAGS)" -o runc .
|
||||
|
||||
all: runc recvtty
|
||||
|
||||
recvtty: contrib/cmd/recvtty/recvtty
|
||||
|
||||
contrib/cmd/recvtty/recvtty: $(SOURCES) | $(RUNC_LINK)
|
||||
contrib/cmd/recvtty/recvtty: $(SOURCES)
|
||||
go build -i -ldflags "-X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -tags "$(BUILDTAGS)" -o contrib/cmd/recvtty/recvtty ./contrib/cmd/recvtty
|
||||
|
||||
static: $(SOURCES) | $(RUNC_LINK)
|
||||
static: $(SOURCES)
|
||||
CGO_ENABLED=1 go build -i -tags "$(BUILDTAGS) cgo static_build" -ldflags "-w -extldflags -static -X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -o runc .
|
||||
CGO_ENABLED=1 go build -i -tags "$(BUILDTAGS) cgo static_build" -ldflags "-w -extldflags -static -X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -o contrib/cmd/recvtty/recvtty ./contrib/cmd/recvtty
|
||||
|
||||
release: $(RUNC_LINK) | $(RUNC_LINK)
|
||||
release:
|
||||
@flag_list=(seccomp selinux apparmor static ambient); \
|
||||
unset expression; \
|
||||
for flag in "$${flag_list[@]}"; do \
|
||||
|
@ -64,19 +62,15 @@ release: $(RUNC_LINK) | $(RUNC_LINK)
|
|||
CGO_ENABLED=1; \
|
||||
}; \
|
||||
echo "Building target: $$output"; \
|
||||
rm -rf "${GOPATH}/pkg"; \
|
||||
go build -i -ldflags "$$ldflags" -tags "$$tags" -o "$$output" .; \
|
||||
done
|
||||
|
||||
$(RUNC_LINK):
|
||||
ln -sfn $(CURDIR) $(RUNC_LINK)
|
||||
|
||||
dbuild: runcimage
|
||||
docker run --rm -v $(CURDIR):/go/src/$(PROJECT) --privileged $(RUNC_IMAGE) make clean all
|
||||
|
||||
lint:
|
||||
go vet ./...
|
||||
go fmt ./...
|
||||
go vet $(allpackages)
|
||||
go fmt $(allpackages)
|
||||
|
||||
man:
|
||||
man/md2man-all.sh
|
||||
|
@ -94,7 +88,7 @@ unittest: runcimage
|
|||
docker run -e TESTFLAGS -t --privileged --rm -v $(CURDIR):/go/src/$(PROJECT) $(RUNC_IMAGE) make localunittest
|
||||
|
||||
localunittest: all
|
||||
go test -timeout 3m -tags "$(BUILDTAGS)" ${TESTFLAGS} -v ./...
|
||||
go test -timeout 3m -tags "$(BUILDTAGS)" ${TESTFLAGS} -v $(allpackages)
|
||||
|
||||
integration: runcimage
|
||||
docker run -e TESTFLAGS -t --privileged --rm -v $(CURDIR):/go/src/$(PROJECT) $(RUNC_IMAGE) make localintegration
|
||||
|
@ -127,14 +121,16 @@ uninstall-man:
|
|||
clean:
|
||||
rm -f runc
|
||||
rm -f contrib/cmd/recvtty/recvtty
|
||||
rm -f $(RUNC_LINK)
|
||||
rm -rf $(GOPATH)/pkg
|
||||
rm -rf $(RELEASE_DIR)
|
||||
rm -rf $(MAN_DIR)
|
||||
|
||||
validate:
|
||||
script/validate-gofmt
|
||||
script/validate-shfmt
|
||||
go vet ./...
|
||||
go vet $(allpackages)
|
||||
|
||||
ci: validate localtest
|
||||
|
||||
# memoize allpackages, so that it's executed only once and only if used
|
||||
_allpackages = $(shell go list ./... | grep -v vendor)
|
||||
allpackages = $(if $(__allpackages),,$(eval __allpackages := $$(_allpackages)))$(__allpackages)
|
||||
|
|
|
@ -77,6 +77,12 @@ You can run a specific test case by setting the `TESTFLAGS` variable.
|
|||
# make test TESTFLAGS="-run=SomeTestFunction"
|
||||
```
|
||||
|
||||
### Dependencies Management
|
||||
|
||||
`runc` uses [vndr](https://github.com/LK4D4/vndr) for dependencies management.
|
||||
Please refer to [vndr](https://github.com/LK4D4/vndr) for how to add or update
|
||||
new dependencies.
|
||||
|
||||
## Using runc
|
||||
|
||||
### Creating an OCI Bundle
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
source "$(dirname "$BASH_SOURCE")/.validate"
|
||||
|
||||
IFS=$'\n'
|
||||
files=($(validate_diff --diff-filter=ACMR --name-only -- '*.go' | grep -v '^Godeps/' || true))
|
||||
files=($(validate_diff --diff-filter=ACMR --name-only -- '*.go' | grep -v '^vendor/' || true))
|
||||
unset IFS
|
||||
|
||||
badFiles=()
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
badFiles=()
|
||||
while read f; do
|
||||
badFiles+=("$f")
|
||||
done < <(shfmt -l . | grep -v Godeps/)
|
||||
done < <(shfmt -l . | grep -v vendor/)
|
||||
|
||||
if [ ${#badFiles[@]} -eq 0 ]; then
|
||||
echo 'Congratulations! All shell source files are properly formatted.'
|
||||
|
|
|
@ -72,11 +72,9 @@ function teardown() {
|
|||
run git clone https://github.com/opencontainers/runtime-spec.git src/runtime-spec
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
SPEC_COMMIT=$(grep runtime-spec ${TESTDIR}/../../Godeps/Godeps.json -A 4 | grep Rev | cut -d":" -f 2 | tr -d ' "')
|
||||
(
|
||||
cd src/runtime-spec &&
|
||||
run git reset --hard "${SPEC_COMMIT}"
|
||||
)
|
||||
SPEC_COMMIT=$(grep runtime-spec ${TESTDIR}/../../vendor.conf | cut -d ' ' -f 2)
|
||||
run git -C src/runtime-spec reset --hard "${SPEC_COMMIT}"
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[ -e src/runtime-spec/schema/config-schema.json ]
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
github.com/Sirupsen/logrus 26709e2714106fb8ad40b773b711ebce25b78914
|
||||
github.com/coreos/go-systemd 48702e0da86bd25e76cfef347e2adeb434a0d0a6
|
||||
github.com/coreos/pkg/dlopen 3ac0863d7acf3bc44daf49afef8919af12f704ef
|
||||
github.com/docker/docker 0f5c9d301b9b1cca66b3ea0f9dec3b5317d3686d
|
||||
github.com/docker/go-units 9b001659dd36225e356b4467c465d732e745f53d
|
||||
github.com/godbus/dbus c7fdd8b5cd55e87b4e1f4e372cdb1db61dd6c66f
|
||||
github.com/golang/protobuf/proto f7137ae6b19afbfd61a94b746fda3b3fe0491874
|
||||
github.com/mrunalp/fileutils ed869b029674c0e9ce4c0dfa781405c2d9946d08
|
||||
github.com/opencontainers/runtime-spec/specs-go 794ca7ac88234607f9d2c76da8a6e9bbbade8cb9
|
||||
github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
|
||||
github.com/syndtr/gocapability/capability e7cb7fa329f456b3855136a2642b197bad7366ba
|
||||
github.com/urfave/cli d53eb991652b1d438abdd34ce4bfa3ef1539108e
|
||||
github.com/vishvananda/netlink 1e2e08e8a2dcdacaae3f14ac44c5cfa31361f270
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue