Remove non-go option (#682)
This commit is contained in:
parent
2993dcc3db
commit
04d216dcc5
|
@ -3,6 +3,7 @@ ignored = ["github.com/ethereum/go-ethereum/whisper/notifications"]
|
|||
[prune]
|
||||
unused-packages = true
|
||||
go-tests = true
|
||||
non-go = true
|
||||
|
||||
[[prune.project]]
|
||||
name = "github.com/karalabe/hid"
|
||||
|
@ -11,8 +12,8 @@ ignored = ["github.com/ethereum/go-ethereum/whisper/notifications"]
|
|||
|
||||
[[prune.project]]
|
||||
name = "github.com/ethereum/go-ethereum"
|
||||
non-go = false
|
||||
unused-packages = false
|
||||
non-go = false
|
||||
|
||||
# * * * * * constrained `status-go` dependencies * * * * *
|
||||
# (for the full dependency list see `Gopkg.lock`)
|
||||
|
|
|
@ -1,193 +0,0 @@
|
|||
# go-fcm : FCM Library for Go
|
||||
|
||||
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg?style=flat-square)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=MYW4MY786JXFN&lc=GB&item_name=go%2dfcm%20development&item_number=go%2dfcm¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted)
|
||||
[![AUR](https://img.shields.io/aur/license/yaourt.svg?style=flat-square)](https://github.com/NaySoftware/go-fcm/blob/master/LICENSE)
|
||||
|
||||
Firebase Cloud Messaging ( FCM ) Library using golang ( Go )
|
||||
|
||||
This library uses HTTP/JSON Firebase Cloud Messaging connection server protocol
|
||||
|
||||
|
||||
###### Features
|
||||
|
||||
* Send messages to a topic
|
||||
* Send messages to a device list
|
||||
* Message can be a notification or data payload
|
||||
* Supports condition attribute (fcm only)
|
||||
* Instace Id Features
|
||||
- Get info about app Instance
|
||||
- Subscribe app Instance to a topic
|
||||
- Batch Subscribe/Unsubscribe to/from a topic
|
||||
- Create registration tokens for APNs tokens
|
||||
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
go get github.com/NaySoftware/go-fcm
|
||||
```
|
||||
|
||||
## Docs - go-fcm API
|
||||
```
|
||||
https://godoc.org/github.com/NaySoftware/go-fcm
|
||||
```
|
||||
|
||||
#### Firebase Cloud Messaging HTTP Protocol Specs
|
||||
```
|
||||
https://firebase.google.com/docs/cloud-messaging/http-server-ref
|
||||
```
|
||||
|
||||
#### Firebase Cloud Messaging Developer docs
|
||||
```
|
||||
https://firebase.google.com/docs/cloud-messaging/
|
||||
```
|
||||
|
||||
#### (Google) Instance Id Server Reference
|
||||
```
|
||||
https://developers.google.com/instance-id/reference/server
|
||||
```
|
||||
### Notes
|
||||
|
||||
|
||||
|
||||
|
||||
> a note from firebase console
|
||||
|
||||
```
|
||||
Firebase Cloud Messaging tokens have replaced server keys for
|
||||
sending messages. While you may continue to use them, support
|
||||
is being deprecated for server keys.
|
||||
```
|
||||
|
||||
|
||||
###### Firebase Cloud Messaging token ( new token )
|
||||
|
||||
serverKey variable will also hold the new FCM token by Firebase Cloud Messaging
|
||||
|
||||
Firebase Cloud Messaging token can be found in:
|
||||
|
||||
1. Firebase project settings
|
||||
2. Cloud Messaging
|
||||
3. then copy the Firebase Cloud Messaging token
|
||||
|
||||
|
||||
###### Server Key
|
||||
|
||||
serverKey is the server key by Firebase Cloud Messaging
|
||||
|
||||
Server Key can be found in:
|
||||
|
||||
1. Firebase project settings
|
||||
2. Cloud Messaging
|
||||
3. then copy the server key
|
||||
|
||||
[will be deprecated by firabase as mentioned above!]
|
||||
|
||||
###### Retry mechanism
|
||||
|
||||
Retry should be implemented based on the requirements.
|
||||
Sending a request will result with a "FcmResponseStatus" struct, which holds
|
||||
a detailed information based on the Firebase Response, with RetryAfter
|
||||
(response header) if available - with a failed request.
|
||||
its recommended to use a backoff time to retry the request - (if RetryAfter
|
||||
header is not available).
|
||||
|
||||
|
||||
|
||||
|
||||
# Examples
|
||||
|
||||
### Send to A topic
|
||||
|
||||
```go
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/NaySoftware/go-fcm"
|
||||
)
|
||||
|
||||
const (
|
||||
serverKey = "YOUR-KEY"
|
||||
topic = "/topics/someTopic"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
data := map[string]string{
|
||||
"msg": "Hello World1",
|
||||
"sum": "Happy Day",
|
||||
}
|
||||
|
||||
c := fcm.NewFcmClient(serverKey)
|
||||
c.NewFcmMsgTo(topic, data)
|
||||
|
||||
|
||||
status, err := c.Send()
|
||||
|
||||
|
||||
if err == nil {
|
||||
status.PrintResults()
|
||||
} else {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
### Send to a list of Devices (tokens)
|
||||
|
||||
```go
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/NaySoftware/go-fcm"
|
||||
)
|
||||
|
||||
const (
|
||||
serverKey = "YOUR-KEY"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
data := map[string]string{
|
||||
"msg": "Hello World1",
|
||||
"sum": "Happy Day",
|
||||
}
|
||||
|
||||
ids := []string{
|
||||
"token1",
|
||||
}
|
||||
|
||||
|
||||
xds := []string{
|
||||
"token5",
|
||||
"token6",
|
||||
"token7",
|
||||
}
|
||||
|
||||
c := fcm.NewFcmClient(serverKey)
|
||||
c.NewFcmRegIdsMsg(ids, data)
|
||||
c.AppendDevices(xds)
|
||||
|
||||
status, err := c.Send()
|
||||
|
||||
|
||||
if err == nil {
|
||||
status.PrintResults()
|
||||
} else {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
```
|
File diff suppressed because it is too large
Load Diff
|
@ -1,74 +0,0 @@
|
|||
btcec
|
||||
=====
|
||||
|
||||
[![Build Status](https://travis-ci.org/btcsuite/btcd.png?branch=master)]
|
||||
(https://travis-ci.org/btcsuite/btcec) [![ISC License]
|
||||
(http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org)
|
||||
[![GoDoc](https://godoc.org/github.com/btcsuite/btcd/btcec?status.png)]
|
||||
(http://godoc.org/github.com/btcsuite/btcd/btcec)
|
||||
|
||||
Package btcec implements elliptic curve cryptography needed for working with
|
||||
Bitcoin (secp256k1 only for now). It is designed so that it may be used with the
|
||||
standard crypto/ecdsa packages provided with go. A comprehensive suite of test
|
||||
is provided to ensure proper functionality. Package btcec was originally based
|
||||
on work from ThePiachu which is licensed under the same terms as Go, but it has
|
||||
signficantly diverged since then. The btcsuite developers original is licensed
|
||||
under the liberal ISC license.
|
||||
|
||||
Although this package was primarily written for btcd, it has intentionally been
|
||||
designed so it can be used as a standalone package for any projects needing to
|
||||
use secp256k1 elliptic curve cryptography.
|
||||
|
||||
## Installation and Updating
|
||||
|
||||
```bash
|
||||
$ go get -u github.com/btcsuite/btcd/btcec
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
* [Sign Message]
|
||||
(http://godoc.org/github.com/btcsuite/btcd/btcec#example-package--SignMessage)
|
||||
Demonstrates signing a message with a secp256k1 private key that is first
|
||||
parsed form raw bytes and serializing the generated signature.
|
||||
|
||||
* [Verify Signature]
|
||||
(http://godoc.org/github.com/btcsuite/btcd/btcec#example-package--VerifySignature)
|
||||
Demonstrates verifying a secp256k1 signature against a public key that is
|
||||
first parsed from raw bytes. The signature is also parsed from raw bytes.
|
||||
|
||||
* [Encryption]
|
||||
(http://godoc.org/github.com/btcsuite/btcd/btcec#example-package--EncryptMessage)
|
||||
Demonstrates encrypting a message for a public key that is first parsed from
|
||||
raw bytes, then decrypting it using the corresponding private key.
|
||||
|
||||
* [Decryption]
|
||||
(http://godoc.org/github.com/btcsuite/btcd/btcec#example-package--DecryptMessage)
|
||||
Demonstrates decrypting a message using a private key that is first parsed
|
||||
from raw bytes.
|
||||
|
||||
## GPG Verification Key
|
||||
|
||||
All official release tags are signed by Conformal so users can ensure the code
|
||||
has not been tampered with and is coming from the btcsuite developers. To
|
||||
verify the signature perform the following:
|
||||
|
||||
- Download the public key from the Conformal website at
|
||||
https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt
|
||||
|
||||
- Import the public key into your GPG keyring:
|
||||
```bash
|
||||
gpg --import GIT-GPG-KEY-conformal.txt
|
||||
```
|
||||
|
||||
- Verify the release tag with the following command where `TAG_NAME` is a
|
||||
placeholder for the specific tag:
|
||||
```bash
|
||||
git tag -v TAG_NAME
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Package btcec is licensed under the [copyfree](http://copyfree.org) ISC License
|
||||
except for btcec.go and btcec_test.go which is under the same license as Go.
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
chaincfg
|
||||
========
|
||||
|
||||
[![Build Status](http://img.shields.io/travis/btcsuite/btcd.svg)]
|
||||
(https://travis-ci.org/btcsuite/btcd) [![ISC License]
|
||||
(http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org)
|
||||
[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)]
|
||||
(http://godoc.org/github.com/btcsuite/btcd/chaincfg)
|
||||
|
||||
Package chaincfg defines chain configuration parameters for the three standard
|
||||
Bitcoin networks and provides the ability for callers to define their own custom
|
||||
Bitcoin networks.
|
||||
|
||||
Although this package was primarily written for btcd, it has intentionally been
|
||||
designed so it can be used as a standalone package for any projects needing to
|
||||
use parameters for the standard Bitcoin networks or for projects needing to
|
||||
define their own network.
|
||||
|
||||
## Sample Use
|
||||
|
||||
```Go
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/btcsuite/btcd/chaincfg"
|
||||
)
|
||||
|
||||
var testnet = flag.Bool("testnet", false, "operate on the testnet Bitcoin network")
|
||||
|
||||
// By default (without -testnet), use mainnet.
|
||||
var chainParams = &chaincfg.MainNetParams
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
// Modify active network parameters if operating on testnet.
|
||||
if *testnet {
|
||||
chainParams = &chaincfg.TestNet3Params
|
||||
}
|
||||
|
||||
// later...
|
||||
|
||||
// Create and print new payment address, specific to the active network.
|
||||
pubKeyHash := make([]byte, 20)
|
||||
addr, err := btcutil.NewAddressPubKeyHash(pubKeyHash, chainParams)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println(addr)
|
||||
}
|
||||
```
|
||||
|
||||
## Installation and Updating
|
||||
|
||||
```bash
|
||||
$ go get -u github.com/btcsuite/btcd/chaincfg
|
||||
```
|
||||
|
||||
## GPG Verification Key
|
||||
|
||||
All official release tags are signed by Conformal so users can ensure the code
|
||||
has not been tampered with and is coming from the btcsuite developers. To
|
||||
verify the signature perform the following:
|
||||
|
||||
- Download the public key from the Conformal website at
|
||||
https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt
|
||||
|
||||
- Import the public key into your GPG keyring:
|
||||
```bash
|
||||
gpg --import GIT-GPG-KEY-conformal.txt
|
||||
```
|
||||
|
||||
- Verify the release tag with the following command where `TAG_NAME` is a
|
||||
placeholder for the specific tag:
|
||||
```bash
|
||||
git tag -v TAG_NAME
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Package chaincfg is licensed under the [copyfree](http://copyfree.org) ISC
|
||||
License.
|
|
@ -1,42 +0,0 @@
|
|||
chainhash
|
||||
=========
|
||||
|
||||
[![Build Status](http://img.shields.io/travis/btcsuite/btcd.svg)]
|
||||
(https://travis-ci.org/btcsuite/btcd) [![ISC License]
|
||||
(http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org)
|
||||
[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)]
|
||||
(http://godoc.org/github.com/btcsuite/btcd/chaincfg/chainhash)
|
||||
|
||||
chainhash provides a generic hash type and associated functions that allows the
|
||||
specific hash algorithm to be abstracted.
|
||||
|
||||
## Installation and Updating
|
||||
|
||||
```bash
|
||||
$ go get -u github.com/btcsuite/btcd/chaincfg/chainhash
|
||||
```
|
||||
|
||||
## GPG Verification Key
|
||||
|
||||
All official release tags are signed by Conformal so users can ensure the code
|
||||
has not been tampered with and is coming from the btcsuite developers. To
|
||||
verify the signature perform the following:
|
||||
|
||||
- Download the public key from the Conformal website at
|
||||
https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt
|
||||
|
||||
- Import the public key into your GPG keyring:
|
||||
```bash
|
||||
gpg --import GIT-GPG-KEY-conformal.txt
|
||||
```
|
||||
|
||||
- Verify the release tag with the following command where `TAG_NAME` is a
|
||||
placeholder for the specific tag:
|
||||
```bash
|
||||
git tag -v TAG_NAME
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Package chainhash is licensed under the [copyfree](http://copyfree.org) ISC
|
||||
License.
|
|
@ -1,114 +0,0 @@
|
|||
wire
|
||||
====
|
||||
|
||||
[![Build Status](http://img.shields.io/travis/btcsuite/btcd.svg)]
|
||||
(https://travis-ci.org/btcsuite/btcd) [![ISC License]
|
||||
(http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org)
|
||||
[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)]
|
||||
(http://godoc.org/github.com/btcsuite/btcd/wire)
|
||||
|
||||
Package wire implements the bitcoin wire protocol. A comprehensive suite of
|
||||
tests with 100% test coverage is provided to ensure proper functionality.
|
||||
|
||||
There is an associated blog post about the release of this package
|
||||
[here](https://blog.conformal.com/btcwire-the-bitcoin-wire-protocol-package-from-btcd/).
|
||||
|
||||
This package has intentionally been designed so it can be used as a standalone
|
||||
package for any projects needing to interface with bitcoin peers at the wire
|
||||
protocol level.
|
||||
|
||||
## Installation and Updating
|
||||
|
||||
```bash
|
||||
$ go get -u github.com/btcsuite/btcd/wire
|
||||
```
|
||||
|
||||
## Bitcoin Message Overview
|
||||
|
||||
The bitcoin protocol consists of exchanging messages between peers. Each message
|
||||
is preceded by a header which identifies information about it such as which
|
||||
bitcoin network it is a part of, its type, how big it is, and a checksum to
|
||||
verify validity. All encoding and decoding of message headers is handled by this
|
||||
package.
|
||||
|
||||
To accomplish this, there is a generic interface for bitcoin messages named
|
||||
`Message` which allows messages of any type to be read, written, or passed
|
||||
around through channels, functions, etc. In addition, concrete implementations
|
||||
of most of the currently supported bitcoin messages are provided. For these
|
||||
supported messages, all of the details of marshalling and unmarshalling to and
|
||||
from the wire using bitcoin encoding are handled so the caller doesn't have to
|
||||
concern themselves with the specifics.
|
||||
|
||||
## Reading Messages Example
|
||||
|
||||
In order to unmarshal bitcoin messages from the wire, use the `ReadMessage`
|
||||
function. It accepts any `io.Reader`, but typically this will be a `net.Conn`
|
||||
to a remote node running a bitcoin peer. Example syntax is:
|
||||
|
||||
```Go
|
||||
// Use the most recent protocol version supported by the package and the
|
||||
// main bitcoin network.
|
||||
pver := wire.ProtocolVersion
|
||||
btcnet := wire.MainNet
|
||||
|
||||
// Reads and validates the next bitcoin message from conn using the
|
||||
// protocol version pver and the bitcoin network btcnet. The returns
|
||||
// are a wire.Message, a []byte which contains the unmarshalled
|
||||
// raw payload, and a possible error.
|
||||
msg, rawPayload, err := wire.ReadMessage(conn, pver, btcnet)
|
||||
if err != nil {
|
||||
// Log and handle the error
|
||||
}
|
||||
```
|
||||
|
||||
See the package documentation for details on determining the message type.
|
||||
|
||||
## Writing Messages Example
|
||||
|
||||
In order to marshal bitcoin messages to the wire, use the `WriteMessage`
|
||||
function. It accepts any `io.Writer`, but typically this will be a `net.Conn`
|
||||
to a remote node running a bitcoin peer. Example syntax to request addresses
|
||||
from a remote peer is:
|
||||
|
||||
```Go
|
||||
// Use the most recent protocol version supported by the package and the
|
||||
// main bitcoin network.
|
||||
pver := wire.ProtocolVersion
|
||||
btcnet := wire.MainNet
|
||||
|
||||
// Create a new getaddr bitcoin message.
|
||||
msg := wire.NewMsgGetAddr()
|
||||
|
||||
// Writes a bitcoin message msg to conn using the protocol version
|
||||
// pver, and the bitcoin network btcnet. The return is a possible
|
||||
// error.
|
||||
err := wire.WriteMessage(conn, msg, pver, btcnet)
|
||||
if err != nil {
|
||||
// Log and handle the error
|
||||
}
|
||||
```
|
||||
|
||||
## GPG Verification Key
|
||||
|
||||
All official release tags are signed by Conformal so users can ensure the code
|
||||
has not been tampered with and is coming from the btcsuite developers. To
|
||||
verify the signature perform the following:
|
||||
|
||||
- Download the public key from the Conformal website at
|
||||
https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt
|
||||
|
||||
- Import the public key into your GPG keyring:
|
||||
```bash
|
||||
gpg --import GIT-GPG-KEY-conformal.txt
|
||||
```
|
||||
|
||||
- Verify the release tag with the following command where `TAG_NAME` is a
|
||||
placeholder for the specific tag:
|
||||
```bash
|
||||
git tag -v TAG_NAME
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Package wire is licensed under the [copyfree](http://copyfree.org) ISC
|
||||
License.
|
|
@ -1,28 +0,0 @@
|
|||
# Temp files
|
||||
*~
|
||||
|
||||
# Log files
|
||||
*.log
|
||||
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
|
@ -1,15 +0,0 @@
|
|||
language: go
|
||||
go:
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
sudo: false
|
||||
install:
|
||||
- go get -d -t -v ./...
|
||||
- go get -v github.com/alecthomas/gometalinter
|
||||
- gometalinter --install
|
||||
script:
|
||||
- export PATH=$PATH:$HOME/gopath/bin
|
||||
- ./goclean.sh
|
||||
after_success:
|
||||
- go get -v github.com/mattn/goveralls
|
||||
- goveralls -coverprofile=profile.cov -service=travis-ci
|
|
@ -1,53 +0,0 @@
|
|||
btcutil
|
||||
=======
|
||||
|
||||
[![Build Status](http://img.shields.io/travis/btcsuite/btcutil.svg)]
|
||||
(https://travis-ci.org/btcsuite/btcutil) [![Coverage Status]
|
||||
(http://img.shields.io/coveralls/btcsuite/btcutil.svg)]
|
||||
(https://coveralls.io/r/btcsuite/btcutil?branch=master) [![ISC License]
|
||||
(http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org)
|
||||
[![GoDoc](http://img.shields.io/badge/godoc-reference-blue.svg)]
|
||||
(http://godoc.org/github.com/btcsuite/btcutil)
|
||||
|
||||
Package btcutil provides bitcoin-specific convenience functions and types.
|
||||
A comprehensive suite of tests is provided to ensure proper functionality. See
|
||||
`test_coverage.txt` for the gocov coverage report. Alternatively, if you are
|
||||
running a POSIX OS, you can run the `cov_report.sh` script for a real-time
|
||||
report.
|
||||
|
||||
This package was developed for btcd, an alternative full-node implementation of
|
||||
bitcoin which is under active development by Conformal. Although it was
|
||||
primarily written for btcd, this package has intentionally been designed so it
|
||||
can be used as a standalone package for any projects needing the functionality
|
||||
provided.
|
||||
|
||||
## Installation and Updating
|
||||
|
||||
```bash
|
||||
$ go get -u github.com/btcsuite/btcutil
|
||||
```
|
||||
|
||||
## GPG Verification Key
|
||||
|
||||
All official release tags are signed by Conformal so users can ensure the code
|
||||
has not been tampered with and is coming from the btcsuite developers. To
|
||||
verify the signature perform the following:
|
||||
|
||||
- Download the public key from the Conformal website at
|
||||
https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt
|
||||
|
||||
- Import the public key into your GPG keyring:
|
||||
```bash
|
||||
gpg --import GIT-GPG-KEY-conformal.txt
|
||||
```
|
||||
|
||||
- Verify the release tag with the following command where `TAG_NAME` is a
|
||||
placeholder for the specific tag:
|
||||
```bash
|
||||
git tag -v TAG_NAME
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Package btcutil is licensed under the [copyfree](http://copyfree.org) ISC
|
||||
License.
|
|
@ -1,40 +0,0 @@
|
|||
base58
|
||||
==========
|
||||
|
||||
[![Build Status](http://img.shields.io/travis/btcsuite/btcutil.svg)]
|
||||
(https://travis-ci.org/btcsuite/btcutil) [![ISC License]
|
||||
(http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org)
|
||||
[![GoDoc](https://godoc.org/github.com/btcsuite/btcutil/base58?status.png)]
|
||||
(http://godoc.org/github.com/btcsuite/btcutil/base58)
|
||||
|
||||
Package base58 provides an API for encoding and decoding to and from the
|
||||
modified base58 encoding. It also provides an API to do Base58Check encoding,
|
||||
as described [here](https://en.bitcoin.it/wiki/Base58Check_encoding).
|
||||
|
||||
A comprehensive suite of tests is provided to ensure proper functionality.
|
||||
|
||||
## Installation and Updating
|
||||
|
||||
```bash
|
||||
$ go get -u github.com/btcsuite/btcutil/base58
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
* [Decode Example]
|
||||
(http://godoc.org/github.com/btcsuite/btcutil/base58#example-Decode)
|
||||
Demonstrates how to decode modified base58 encoded data.
|
||||
* [Encode Example]
|
||||
(http://godoc.org/github.com/btcsuite/btcutil/base58#example-Encode)
|
||||
Demonstrates how to encode data using the modified base58 encoding scheme.
|
||||
* [CheckDecode Example]
|
||||
(http://godoc.org/github.com/btcsuite/btcutil/base58#example-CheckDecode)
|
||||
Demonstrates how to decode Base58Check encoded data.
|
||||
* [CheckEncode Example]
|
||||
(http://godoc.org/github.com/btcsuite/btcutil/base58#example-CheckEncode)
|
||||
Demonstrates how to encode data using the Base58Check encoding scheme.
|
||||
|
||||
## License
|
||||
|
||||
Package base58 is licensed under the [copyfree](http://copyfree.org) ISC
|
||||
License.
|
|
@ -1,17 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# This script uses gocov to generate a test coverage report.
|
||||
# The gocov tool my be obtained with the following command:
|
||||
# go get github.com/axw/gocov/gocov
|
||||
#
|
||||
# It will be installed to $GOPATH/bin, so ensure that location is in your $PATH.
|
||||
|
||||
# Check for gocov.
|
||||
type gocov >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo >&2 "This script requires the gocov tool."
|
||||
echo >&2 "You may obtain it with the following command:"
|
||||
echo >&2 "go get github.com/axw/gocov/gocov"
|
||||
exit 1
|
||||
fi
|
||||
gocov test | gocov report
|
|
@ -1,17 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# This script uses gocov to generate a test coverage report.
|
||||
# The gocov tool my be obtained with the following command:
|
||||
# go get github.com/axw/gocov/gocov
|
||||
#
|
||||
# It will be installed to $GOPATH/bin, so ensure that location is in your $PATH.
|
||||
|
||||
# Check for gocov.
|
||||
type gocov >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo >&2 "This script requires the gocov tool."
|
||||
echo >&2 "You may obtain it with the following command:"
|
||||
echo >&2 "go get github.com/axw/gocov/gocov"
|
||||
exit 1
|
||||
fi
|
||||
gocov test | gocov report
|
|
@ -1,48 +0,0 @@
|
|||
#!/bin/bash
|
||||
# The script does automatic checking on a Go package and its sub-packages, including:
|
||||
# 1. gofmt (http://golang.org/cmd/gofmt/)
|
||||
# 2. goimports (https://github.com/bradfitz/goimports)
|
||||
# 3. golint (https://github.com/golang/lint)
|
||||
# 4. go vet (http://golang.org/cmd/vet)
|
||||
# 5. gosimple (https://github.com/dominikh/go-simple)
|
||||
# 6. unconvert (https://github.com/mdempsky/unconvert)
|
||||
# 7. race detector (http://blog.golang.org/race-detector)
|
||||
# 8. test coverage (http://blog.golang.org/cover)
|
||||
#
|
||||
# gometalint (github.com/alecthomas/gometalinter) is used to run each each
|
||||
# static checker.
|
||||
|
||||
set -ex
|
||||
|
||||
# Automatic checks
|
||||
test -z "$(gometalinter --disable-all \
|
||||
--enable=gofmt \
|
||||
--enable=goimports \
|
||||
--enable=golint \
|
||||
--enable=vet \
|
||||
--enable=gosimple \
|
||||
--enable=unconvert \
|
||||
--deadline=120s ./... | grep -v 'ExampleNew' 2>&1 | tee /dev/stderr)"
|
||||
env GORACE="halt_on_error=1" go test -race ./...
|
||||
|
||||
# Run test coverage on each subdirectories and merge the coverage profile.
|
||||
|
||||
echo "mode: count" > profile.cov
|
||||
|
||||
# Standard go tooling behavior is to ignore dirs with leading underscores.
|
||||
for dir in $(find . -maxdepth 10 -not -path './.git*' -not -path '*/_*' -type d);
|
||||
do
|
||||
if ls $dir/*.go &> /dev/null; then
|
||||
go test -covermode=count -coverprofile=$dir/profile.tmp $dir
|
||||
if [ -f $dir/profile.tmp ]; then
|
||||
cat $dir/profile.tmp | tail -n +2 >> profile.cov
|
||||
rm $dir/profile.tmp
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
go tool cover -func profile.cov
|
||||
|
||||
# To submit the test coverage result to coveralls.io,
|
||||
# use goveralls (https://github.com/mattn/goveralls)
|
||||
# goveralls -coverprofile=profile.cov -service=travis-ci
|
|
@ -1,72 +0,0 @@
|
|||
|
||||
github.com/conformal/btcutil/base58.go Base58Decode 100.00% (20/20)
|
||||
github.com/conformal/btcutil/base58.go Base58Encode 100.00% (15/15)
|
||||
github.com/conformal/btcutil/block.go Block.Tx 100.00% (12/12)
|
||||
github.com/conformal/btcutil/wif.go WIF.String 100.00% (11/11)
|
||||
github.com/conformal/btcutil/block.go Block.Transactions 100.00% (11/11)
|
||||
github.com/conformal/btcutil/amount.go AmountUnit.String 100.00% (8/8)
|
||||
github.com/conformal/btcutil/tx.go NewTxFromReader 100.00% (6/6)
|
||||
github.com/conformal/btcutil/block.go NewBlockFromBytes 100.00% (6/6)
|
||||
github.com/conformal/btcutil/block.go NewBlockFromReader 100.00% (6/6)
|
||||
github.com/conformal/btcutil/address.go encodeAddress 100.00% (6/6)
|
||||
github.com/conformal/btcutil/address.go newAddressPubKeyHash 100.00% (5/5)
|
||||
github.com/conformal/btcutil/address.go newAddressScriptHashFromHash 100.00% (5/5)
|
||||
github.com/conformal/btcutil/tx.go Tx.Sha 100.00% (5/5)
|
||||
github.com/conformal/btcutil/block.go Block.Sha 100.00% (5/5)
|
||||
github.com/conformal/btcutil/amount.go NewAmount 100.00% (5/5)
|
||||
github.com/conformal/btcutil/amount.go round 100.00% (3/3)
|
||||
github.com/conformal/btcutil/address.go NewAddressScriptHash 100.00% (2/2)
|
||||
github.com/conformal/btcutil/amount.go Amount.Format 100.00% (2/2)
|
||||
github.com/conformal/btcutil/tx.go NewTxFromBytes 100.00% (2/2)
|
||||
github.com/conformal/btcutil/hash160.go calcHash 100.00% (2/2)
|
||||
github.com/conformal/btcutil/address.go AddressPubKeyHash.Hash160 100.00% (1/1)
|
||||
github.com/conformal/btcutil/block.go OutOfRangeError.Error 100.00% (1/1)
|
||||
github.com/conformal/btcutil/block.go Block.MsgBlock 100.00% (1/1)
|
||||
github.com/conformal/btcutil/tx.go Tx.MsgTx 100.00% (1/1)
|
||||
github.com/conformal/btcutil/hash160.go Hash160 100.00% (1/1)
|
||||
github.com/conformal/btcutil/block.go NewBlockFromBlockAndBytes 100.00% (1/1)
|
||||
github.com/conformal/btcutil/block.go Block.Height 100.00% (1/1)
|
||||
github.com/conformal/btcutil/block.go Block.SetHeight 100.00% (1/1)
|
||||
github.com/conformal/btcutil/block.go NewBlock 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKeyHash.IsForNet 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKey.EncodeAddress 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go NewAddressPubKeyHash 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKeyHash.EncodeAddress 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKeyHash.ScriptAddress 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKeyHash.String 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go NewAddressScriptHashFromHash 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressScriptHash.EncodeAddress 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressScriptHash.ScriptAddress 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressScriptHash.IsForNet 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressScriptHash.String 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressScriptHash.Hash160 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKey.ScriptAddress 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKey.IsForNet 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKey.String 100.00% (1/1)
|
||||
github.com/conformal/btcutil/tx.go NewTx 100.00% (1/1)
|
||||
github.com/conformal/btcutil/tx.go Tx.SetIndex 100.00% (1/1)
|
||||
github.com/conformal/btcutil/amount.go Amount.ToUnit 100.00% (1/1)
|
||||
github.com/conformal/btcutil/tx.go Tx.Index 100.00% (1/1)
|
||||
github.com/conformal/btcutil/amount.go Amount.String 100.00% (1/1)
|
||||
github.com/conformal/btcutil/amount.go Amount.MulF64 100.00% (1/1)
|
||||
github.com/conformal/btcutil/appdata.go appDataDir 92.00% (23/25)
|
||||
github.com/conformal/btcutil/block.go Block.TxLoc 88.89% (8/9)
|
||||
github.com/conformal/btcutil/block.go Block.Bytes 88.89% (8/9)
|
||||
github.com/conformal/btcutil/address.go NewAddressPubKey 87.50% (7/8)
|
||||
github.com/conformal/btcutil/address.go DecodeAddress 85.00% (17/20)
|
||||
github.com/conformal/btcutil/wif.go DecodeWIF 85.00% (17/20)
|
||||
github.com/conformal/btcutil/address.go AddressPubKey.serialize 80.00% (4/5)
|
||||
github.com/conformal/btcutil/block.go Block.TxSha 75.00% (3/4)
|
||||
github.com/conformal/btcutil/wif.go paddedAppend 66.67% (2/3)
|
||||
github.com/conformal/btcutil/wif.go NewWIF 66.67% (2/3)
|
||||
github.com/conformal/btcutil/certgen.go NewTLSCertPair 0.00% (0/54)
|
||||
github.com/conformal/btcutil/wif.go WIF.SerializePubKey 0.00% (0/4)
|
||||
github.com/conformal/btcutil/address.go AddressPubKey.AddressPubKeyHash 0.00% (0/3)
|
||||
github.com/conformal/btcutil/address.go AddressPubKey.Format 0.00% (0/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKey.PubKey 0.00% (0/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKey.SetFormat 0.00% (0/1)
|
||||
github.com/conformal/btcutil/wif.go WIF.IsForNet 0.00% (0/1)
|
||||
github.com/conformal/btcutil/appdata.go AppDataDir 0.00% (0/1)
|
||||
github.com/conformal/btcutil/net.go interfaceAddrs 0.00% (0/1)
|
||||
github.com/conformal/btcutil ------------------------------- 75.88% (258/340)
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
*.out
|
||||
*.5
|
||||
*.6
|
||||
*.8
|
||||
*.swp
|
||||
_obj
|
||||
_test
|
||||
testdata
|
|
@ -1,12 +0,0 @@
|
|||
mmap-go
|
||||
=======
|
||||
|
||||
mmap-go is a portable mmap package for the [Go programming language](http://golang.org).
|
||||
It has been tested on Linux (386, amd64), OS X, and Windows (386). It should also
|
||||
work on other Unix-like platforms, but hasn't been tested with them. I'm interested
|
||||
to hear about the results.
|
||||
|
||||
I haven't been able to add more features without adding significant complexity,
|
||||
so mmap-go doesn't support mprotect, mincore, and maybe a few other things.
|
||||
If you're running on a Unix-like platform and need some of these features,
|
||||
I suggest Gustavo Niemeyer's [gommap](http://labix.org/gommap).
|
|
@ -1,24 +0,0 @@
|
|||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
|
@ -1,172 +0,0 @@
|
|||
## locales
|
||||
<img align="right" src="https://raw.githubusercontent.com/go-playground/locales/master/logo.png">![Project status](https://img.shields.io/badge/version-0.11.1-green.svg)
|
||||
[![Build Status](https://semaphoreci.com/api/v1/joeybloggs/locales/branches/master/badge.svg)](https://semaphoreci.com/joeybloggs/locales)
|
||||
[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/locales)](https://goreportcard.com/report/github.com/go-playground/locales)
|
||||
[![GoDoc](https://godoc.org/github.com/go-playground/locales?status.svg)](https://godoc.org/github.com/go-playground/locales)
|
||||
![License](https://img.shields.io/dub/l/vibe-d.svg)
|
||||
[![Gitter](https://badges.gitter.im/go-playground/locales.svg)](https://gitter.im/go-playground/locales?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
Locales is a set of locales generated from the [Unicode CLDR Project](http://cldr.unicode.org/) which can be used independently or within
|
||||
an i18n package; these were built for use with, but not exclusive to, [Universal Translator](https://github.com/go-playground/universal-translator).
|
||||
|
||||
Features
|
||||
--------
|
||||
- [x] Rules generated from the latest [CLDR](http://cldr.unicode.org/index/downloads) data, v31.0.1
|
||||
- [x] Contains Cardinal, Ordinal and Range Plural Rules
|
||||
- [x] Contains Month, Weekday and Timezone translations built in
|
||||
- [x] Contains Date & Time formatting functions
|
||||
- [x] Contains Number, Currency, Accounting and Percent formatting functions
|
||||
- [x] Supports the "Gregorian" calendar only ( my time isn't unlimited, had to draw the line somewhere )
|
||||
|
||||
Full Tests
|
||||
--------------------
|
||||
I could sure use your help adding tests for every locale, it is a huge undertaking and I just don't have the free time to do it all at the moment;
|
||||
any help would be **greatly appreciated!!!!** please see [issue](https://github.com/go-playground/locales/issues/1) for details.
|
||||
|
||||
Installation
|
||||
-----------
|
||||
|
||||
Use go get
|
||||
|
||||
```shell
|
||||
go get github.com/go-playground/locales
|
||||
```
|
||||
|
||||
NOTES
|
||||
--------
|
||||
You'll notice most return types are []byte, this is because most of the time the results will be concatenated with a larger body
|
||||
of text and can avoid some allocations if already appending to a byte array, otherwise just cast as string.
|
||||
|
||||
Usage
|
||||
-------
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/go-playground/locales/currency"
|
||||
"github.com/go-playground/locales/en_CA"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
loc, _ := time.LoadLocation("America/Toronto")
|
||||
datetime := time.Date(2016, 02, 03, 9, 0, 1, 0, loc)
|
||||
|
||||
l := en_CA.New()
|
||||
|
||||
// Dates
|
||||
fmt.Println(l.FmtDateFull(datetime))
|
||||
fmt.Println(l.FmtDateLong(datetime))
|
||||
fmt.Println(l.FmtDateMedium(datetime))
|
||||
fmt.Println(l.FmtDateShort(datetime))
|
||||
|
||||
// Times
|
||||
fmt.Println(l.FmtTimeFull(datetime))
|
||||
fmt.Println(l.FmtTimeLong(datetime))
|
||||
fmt.Println(l.FmtTimeMedium(datetime))
|
||||
fmt.Println(l.FmtTimeShort(datetime))
|
||||
|
||||
// Months Wide
|
||||
fmt.Println(l.MonthWide(time.January))
|
||||
fmt.Println(l.MonthWide(time.February))
|
||||
fmt.Println(l.MonthWide(time.March))
|
||||
// ...
|
||||
|
||||
// Months Abbreviated
|
||||
fmt.Println(l.MonthAbbreviated(time.January))
|
||||
fmt.Println(l.MonthAbbreviated(time.February))
|
||||
fmt.Println(l.MonthAbbreviated(time.March))
|
||||
// ...
|
||||
|
||||
// Months Narrow
|
||||
fmt.Println(l.MonthNarrow(time.January))
|
||||
fmt.Println(l.MonthNarrow(time.February))
|
||||
fmt.Println(l.MonthNarrow(time.March))
|
||||
// ...
|
||||
|
||||
// Weekdays Wide
|
||||
fmt.Println(l.WeekdayWide(time.Sunday))
|
||||
fmt.Println(l.WeekdayWide(time.Monday))
|
||||
fmt.Println(l.WeekdayWide(time.Tuesday))
|
||||
// ...
|
||||
|
||||
// Weekdays Abbreviated
|
||||
fmt.Println(l.WeekdayAbbreviated(time.Sunday))
|
||||
fmt.Println(l.WeekdayAbbreviated(time.Monday))
|
||||
fmt.Println(l.WeekdayAbbreviated(time.Tuesday))
|
||||
// ...
|
||||
|
||||
// Weekdays Short
|
||||
fmt.Println(l.WeekdayShort(time.Sunday))
|
||||
fmt.Println(l.WeekdayShort(time.Monday))
|
||||
fmt.Println(l.WeekdayShort(time.Tuesday))
|
||||
// ...
|
||||
|
||||
// Weekdays Narrow
|
||||
fmt.Println(l.WeekdayNarrow(time.Sunday))
|
||||
fmt.Println(l.WeekdayNarrow(time.Monday))
|
||||
fmt.Println(l.WeekdayNarrow(time.Tuesday))
|
||||
// ...
|
||||
|
||||
var f64 float64
|
||||
|
||||
f64 = -10356.4523
|
||||
|
||||
// Number
|
||||
fmt.Println(l.FmtNumber(f64, 2))
|
||||
|
||||
// Currency
|
||||
fmt.Println(l.FmtCurrency(f64, 2, currency.CAD))
|
||||
fmt.Println(l.FmtCurrency(f64, 2, currency.USD))
|
||||
|
||||
// Accounting
|
||||
fmt.Println(l.FmtAccounting(f64, 2, currency.CAD))
|
||||
fmt.Println(l.FmtAccounting(f64, 2, currency.USD))
|
||||
|
||||
f64 = 78.12
|
||||
|
||||
// Percent
|
||||
fmt.Println(l.FmtPercent(f64, 0))
|
||||
|
||||
// Plural Rules for locale, so you know what rules you must cover
|
||||
fmt.Println(l.PluralsCardinal())
|
||||
fmt.Println(l.PluralsOrdinal())
|
||||
|
||||
// Cardinal Plural Rules
|
||||
fmt.Println(l.CardinalPluralRule(1, 0))
|
||||
fmt.Println(l.CardinalPluralRule(1.0, 0))
|
||||
fmt.Println(l.CardinalPluralRule(1.0, 1))
|
||||
fmt.Println(l.CardinalPluralRule(3, 0))
|
||||
|
||||
// Ordinal Plural Rules
|
||||
fmt.Println(l.OrdinalPluralRule(21, 0)) // 21st
|
||||
fmt.Println(l.OrdinalPluralRule(22, 0)) // 22nd
|
||||
fmt.Println(l.OrdinalPluralRule(33, 0)) // 33rd
|
||||
fmt.Println(l.OrdinalPluralRule(34, 0)) // 34th
|
||||
|
||||
// Range Plural Rules
|
||||
fmt.Println(l.RangePluralRule(1, 0, 1, 0)) // 1-1
|
||||
fmt.Println(l.RangePluralRule(1, 0, 2, 0)) // 1-2
|
||||
fmt.Println(l.RangePluralRule(5, 0, 8, 0)) // 5-8
|
||||
}
|
||||
```
|
||||
|
||||
NOTES:
|
||||
-------
|
||||
These rules were generated from the [Unicode CLDR Project](http://cldr.unicode.org/), if you encounter any issues
|
||||
I strongly encourage contributing to the CLDR project to get the locale information corrected and the next time
|
||||
these locales are regenerated the fix will come with.
|
||||
|
||||
I do however realize that time constraints are often important and so there are two options:
|
||||
|
||||
1. Create your own locale, copy, paste and modify, and ensure it complies with the `Translator` interface.
|
||||
2. Add an exception in the locale generation code directly and once regenerated, fix will be in place.
|
||||
|
||||
Please to not make fixes inside the locale files, they WILL get overwritten when the locales are regenerated.
|
||||
|
||||
License
|
||||
------
|
||||
Distributed under MIT License, please see license file in code for more details.
|
Binary file not shown.
Before Width: | Height: | Size: 36 KiB |
|
@ -1,24 +0,0 @@
|
|||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
|
@ -1,90 +0,0 @@
|
|||
## universal-translator
|
||||
<img align="right" src="https://raw.githubusercontent.com/go-playground/universal-translator/master/logo.png">
|
||||
![Project status](https://img.shields.io/badge/version-0.16.0-green.svg)
|
||||
[![Build Status](https://semaphoreci.com/api/v1/joeybloggs/universal-translator/branches/master/badge.svg)](https://semaphoreci.com/joeybloggs/universal-translator)
|
||||
[![Coverage Status](https://coveralls.io/repos/github/go-playground/universal-translator/badge.svg)](https://coveralls.io/github/go-playground/universal-translator)
|
||||
[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/universal-translator)](https://goreportcard.com/report/github.com/go-playground/universal-translator)
|
||||
[![GoDoc](https://godoc.org/github.com/go-playground/universal-translator?status.svg)](https://godoc.org/github.com/go-playground/universal-translator)
|
||||
![License](https://img.shields.io/dub/l/vibe-d.svg)
|
||||
[![Gitter](https://badges.gitter.im/go-playground/universal-translator.svg)](https://gitter.im/go-playground/universal-translator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
Universal Translator is an i18n Translator for Go/Golang using CLDR data + pluralization rules
|
||||
|
||||
Why another i18n library?
|
||||
--------------------------
|
||||
Because none of the plural rules seem to be correct out there, including the previous implementation of this package,
|
||||
so I took it upon myself to create [locales](https://github.com/go-playground/locales) for everyone to use; this package
|
||||
is a thin wrapper around [locales](https://github.com/go-playground/locales) in order to store and translate text for
|
||||
use in your applications.
|
||||
|
||||
Features
|
||||
--------
|
||||
- [x] Rules generated from the [CLDR](http://cldr.unicode.org/index/downloads) data, v30.0.3
|
||||
- [x] Contains Cardinal, Ordinal and Range Plural Rules
|
||||
- [x] Contains Month, Weekday and Timezone translations built in
|
||||
- [x] Contains Date & Time formatting functions
|
||||
- [x] Contains Number, Currency, Accounting and Percent formatting functions
|
||||
- [x] Supports the "Gregorian" calendar only ( my time isn't unlimited, had to draw the line somewhere )
|
||||
- [x] Support loading translations from files
|
||||
- [x] Exporting translations to file(s), mainly for getting them professionally translated
|
||||
- [ ] Code Generation for translation files -> Go code.. i.e. after it has been professionally translated
|
||||
- [ ] Tests for all languages, I need help with this, please see [here](https://github.com/go-playground/locales/issues/1)
|
||||
|
||||
Installation
|
||||
-----------
|
||||
|
||||
Use go get
|
||||
|
||||
```shell
|
||||
go get github.com/go-playground/universal-translator
|
||||
```
|
||||
|
||||
Usage & Documentation
|
||||
-------
|
||||
|
||||
Please see https://godoc.org/github.com/go-playground/universal-translator for usage docs
|
||||
|
||||
##### Examples:
|
||||
|
||||
- [Basic](https://github.com/go-playground/universal-translator/tree/master/examples/basic)
|
||||
- [Full - no files](https://github.com/go-playground/universal-translator/tree/master/examples/full-no-files)
|
||||
- [Full - with files](https://github.com/go-playground/universal-translator/tree/master/examples/full-with-files)
|
||||
|
||||
File formatting
|
||||
--------------
|
||||
All types, Plain substitution, Cardinal, Ordinal and Range translations can all be contained withing the same file(s);
|
||||
they are only separated for easy viewing.
|
||||
|
||||
##### Examples:
|
||||
|
||||
- [Formats](https://github.com/go-playground/universal-translator/tree/master/examples/file-formats)
|
||||
|
||||
##### Basic Makeup
|
||||
NOTE: not all fields are needed for all translation types, see [examples](https://github.com/go-playground/universal-translator/tree/master/examples/file-formats)
|
||||
```json
|
||||
{
|
||||
"locale": "en",
|
||||
"key": "days-left",
|
||||
"trans": "You have {0} day left.",
|
||||
"type": "Cardinal",
|
||||
"rule": "One",
|
||||
"override": false
|
||||
}
|
||||
```
|
||||
|Field|Description|
|
||||
|---|---|
|
||||
|locale|The locale for which the translation is for.|
|
||||
|key|The translation key that will be used to store and lookup each translation; normally it is a string or integer.|
|
||||
|trans|The actual translation text.|
|
||||
|type|The type of translation Cardinal, Ordinal, Range or "" for a plain substitution(not required to be defined if plain used)|
|
||||
|rule|The plural rule for which the translation is for eg. One, Two, Few, Many or Other.(not required to be defined if plain used)|
|
||||
|override|If you wish to override an existing translation that has already been registered, set this to 'true'. 99% of the time there is no need to define it.|
|
||||
|
||||
Help With Tests
|
||||
---------------
|
||||
To anyone interesting in helping or contributing, I sure could use some help creating tests for each language.
|
||||
Please see issue [here](https://github.com/go-playground/locales/issues/1) for details.
|
||||
|
||||
License
|
||||
------
|
||||
Distributed under MIT License, please see license file in code for more details.
|
Binary file not shown.
Before Width: | Height: | Size: 16 KiB |
|
@ -1,16 +0,0 @@
|
|||
language: go
|
||||
sudo: false
|
||||
go:
|
||||
- 1.2
|
||||
- 1.3
|
||||
- 1.4
|
||||
- 1.5
|
||||
- 1.6
|
||||
- tip
|
||||
|
||||
before_install:
|
||||
- go get github.com/mattn/goveralls
|
||||
- go get golang.org/x/tools/cmd/cover
|
||||
|
||||
script:
|
||||
- goveralls -service=travis-ci
|
|
@ -1,38 +0,0 @@
|
|||
[![GoDoc](https://godoc.org/github.com/go-stack/stack?status.svg)](https://godoc.org/github.com/go-stack/stack)
|
||||
[![Go Report Card](https://goreportcard.com/badge/go-stack/stack)](https://goreportcard.com/report/go-stack/stack)
|
||||
[![TravisCI](https://travis-ci.org/go-stack/stack.svg?branch=master)](https://travis-ci.org/go-stack/stack)
|
||||
[![Coverage Status](https://coveralls.io/repos/github/go-stack/stack/badge.svg?branch=master)](https://coveralls.io/github/go-stack/stack?branch=master)
|
||||
|
||||
# stack
|
||||
|
||||
Package stack implements utilities to capture, manipulate, and format call
|
||||
stacks. It provides a simpler API than package runtime.
|
||||
|
||||
The implementation takes care of the minutia and special cases of interpreting
|
||||
the program counter (pc) values returned by runtime.Callers.
|
||||
|
||||
## Versioning
|
||||
|
||||
Package stack publishes releases via [semver](http://semver.org/) compatible Git
|
||||
tags prefixed with a single 'v'. The master branch always contains the latest
|
||||
release. The develop branch contains unreleased commits.
|
||||
|
||||
## Formatting
|
||||
|
||||
Package stack's types implement fmt.Formatter, which provides a simple and
|
||||
flexible way to declaratively configure formatting when used with logging or
|
||||
error tracking packages.
|
||||
|
||||
```go
|
||||
func DoTheThing() {
|
||||
c := stack.Caller(0)
|
||||
log.Print(c) // "source.go:10"
|
||||
log.Printf("%+v", c) // "pkg/path/source.go:10"
|
||||
log.Printf("%n", c) // "DoTheThing"
|
||||
|
||||
s := stack.Trace().TrimRuntime()
|
||||
log.Print(s) // "[source.go:15 caller.go:42 main.go:14]"
|
||||
}
|
||||
```
|
||||
|
||||
See the docs for all of the supported formatting options.
|
|
@ -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
|
||||
protoc --go_out=Mtestdata/test.proto=github.com/golang/protobuf/proto/testdata,Mgoogle/protobuf/any.proto=github.com/golang/protobuf/ptypes/any:. proto3_proto/proto3.proto
|
||||
make
|
|
@ -1,36 +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.
|
||||
|
||||
# Not stored here, but descriptor.proto is in https://github.com/google/protobuf/
|
||||
# at src/google/protobuf/descriptor.proto
|
||||
regenerate:
|
||||
@echo WARNING! THIS RULE IS PROBABLY NOT RIGHT FOR YOUR INSTALLATION
|
||||
protoc --go_out=../../../../.. -I$(HOME)/src/protobuf/include $(HOME)/src/protobuf/include/google/protobuf/descriptor.proto
|
|
@ -1,16 +0,0 @@
|
|||
cmd/snappytool/snappytool
|
||||
testdata/bench
|
||||
|
||||
# These explicitly listed benchmark data files are for an obsolete version of
|
||||
# snappy_test.go.
|
||||
testdata/alice29.txt
|
||||
testdata/asyoulik.txt
|
||||
testdata/fireworks.jpeg
|
||||
testdata/geo.protodata
|
||||
testdata/html
|
||||
testdata/html_x_4
|
||||
testdata/kppkn.gtb
|
||||
testdata/lcet10.txt
|
||||
testdata/paper-100k.pdf
|
||||
testdata/plrabn12.txt
|
||||
testdata/urls.10K
|
|
@ -1,107 +0,0 @@
|
|||
The Snappy compression format in the Go programming language.
|
||||
|
||||
To download and install from source:
|
||||
$ go get github.com/golang/snappy
|
||||
|
||||
Unless otherwise noted, the Snappy-Go source files are distributed
|
||||
under the BSD-style license found in the LICENSE file.
|
||||
|
||||
|
||||
|
||||
Benchmarks.
|
||||
|
||||
The golang/snappy benchmarks include compressing (Z) and decompressing (U) ten
|
||||
or so files, the same set used by the C++ Snappy code (github.com/google/snappy
|
||||
and note the "google", not "golang"). On an "Intel(R) Core(TM) i7-3770 CPU @
|
||||
3.40GHz", Go's GOARCH=amd64 numbers as of 2016-05-29:
|
||||
|
||||
"go test -test.bench=."
|
||||
|
||||
_UFlat0-8 2.19GB/s ± 0% html
|
||||
_UFlat1-8 1.41GB/s ± 0% urls
|
||||
_UFlat2-8 23.5GB/s ± 2% jpg
|
||||
_UFlat3-8 1.91GB/s ± 0% jpg_200
|
||||
_UFlat4-8 14.0GB/s ± 1% pdf
|
||||
_UFlat5-8 1.97GB/s ± 0% html4
|
||||
_UFlat6-8 814MB/s ± 0% txt1
|
||||
_UFlat7-8 785MB/s ± 0% txt2
|
||||
_UFlat8-8 857MB/s ± 0% txt3
|
||||
_UFlat9-8 719MB/s ± 1% txt4
|
||||
_UFlat10-8 2.84GB/s ± 0% pb
|
||||
_UFlat11-8 1.05GB/s ± 0% gaviota
|
||||
|
||||
_ZFlat0-8 1.04GB/s ± 0% html
|
||||
_ZFlat1-8 534MB/s ± 0% urls
|
||||
_ZFlat2-8 15.7GB/s ± 1% jpg
|
||||
_ZFlat3-8 740MB/s ± 3% jpg_200
|
||||
_ZFlat4-8 9.20GB/s ± 1% pdf
|
||||
_ZFlat5-8 991MB/s ± 0% html4
|
||||
_ZFlat6-8 379MB/s ± 0% txt1
|
||||
_ZFlat7-8 352MB/s ± 0% txt2
|
||||
_ZFlat8-8 396MB/s ± 1% txt3
|
||||
_ZFlat9-8 327MB/s ± 1% txt4
|
||||
_ZFlat10-8 1.33GB/s ± 1% pb
|
||||
_ZFlat11-8 605MB/s ± 1% gaviota
|
||||
|
||||
|
||||
|
||||
"go test -test.bench=. -tags=noasm"
|
||||
|
||||
_UFlat0-8 621MB/s ± 2% html
|
||||
_UFlat1-8 494MB/s ± 1% urls
|
||||
_UFlat2-8 23.2GB/s ± 1% jpg
|
||||
_UFlat3-8 1.12GB/s ± 1% jpg_200
|
||||
_UFlat4-8 4.35GB/s ± 1% pdf
|
||||
_UFlat5-8 609MB/s ± 0% html4
|
||||
_UFlat6-8 296MB/s ± 0% txt1
|
||||
_UFlat7-8 288MB/s ± 0% txt2
|
||||
_UFlat8-8 309MB/s ± 1% txt3
|
||||
_UFlat9-8 280MB/s ± 1% txt4
|
||||
_UFlat10-8 753MB/s ± 0% pb
|
||||
_UFlat11-8 400MB/s ± 0% gaviota
|
||||
|
||||
_ZFlat0-8 409MB/s ± 1% html
|
||||
_ZFlat1-8 250MB/s ± 1% urls
|
||||
_ZFlat2-8 12.3GB/s ± 1% jpg
|
||||
_ZFlat3-8 132MB/s ± 0% jpg_200
|
||||
_ZFlat4-8 2.92GB/s ± 0% pdf
|
||||
_ZFlat5-8 405MB/s ± 1% html4
|
||||
_ZFlat6-8 179MB/s ± 1% txt1
|
||||
_ZFlat7-8 170MB/s ± 1% txt2
|
||||
_ZFlat8-8 189MB/s ± 1% txt3
|
||||
_ZFlat9-8 164MB/s ± 1% txt4
|
||||
_ZFlat10-8 479MB/s ± 1% pb
|
||||
_ZFlat11-8 270MB/s ± 1% gaviota
|
||||
|
||||
|
||||
|
||||
For comparison (Go's encoded output is byte-for-byte identical to C++'s), here
|
||||
are the numbers from C++ Snappy's
|
||||
|
||||
make CXXFLAGS="-O2 -DNDEBUG -g" clean snappy_unittest.log && cat snappy_unittest.log
|
||||
|
||||
BM_UFlat/0 2.4GB/s html
|
||||
BM_UFlat/1 1.4GB/s urls
|
||||
BM_UFlat/2 21.8GB/s jpg
|
||||
BM_UFlat/3 1.5GB/s jpg_200
|
||||
BM_UFlat/4 13.3GB/s pdf
|
||||
BM_UFlat/5 2.1GB/s html4
|
||||
BM_UFlat/6 1.0GB/s txt1
|
||||
BM_UFlat/7 959.4MB/s txt2
|
||||
BM_UFlat/8 1.0GB/s txt3
|
||||
BM_UFlat/9 864.5MB/s txt4
|
||||
BM_UFlat/10 2.9GB/s pb
|
||||
BM_UFlat/11 1.2GB/s gaviota
|
||||
|
||||
BM_ZFlat/0 944.3MB/s html (22.31 %)
|
||||
BM_ZFlat/1 501.6MB/s urls (47.78 %)
|
||||
BM_ZFlat/2 14.3GB/s jpg (99.95 %)
|
||||
BM_ZFlat/3 538.3MB/s jpg_200 (73.00 %)
|
||||
BM_ZFlat/4 8.3GB/s pdf (83.30 %)
|
||||
BM_ZFlat/5 903.5MB/s html4 (22.52 %)
|
||||
BM_ZFlat/6 336.0MB/s txt1 (57.88 %)
|
||||
BM_ZFlat/7 312.3MB/s txt2 (61.91 %)
|
||||
BM_ZFlat/8 353.1MB/s txt3 (54.99 %)
|
||||
BM_ZFlat/9 289.9MB/s txt4 (66.26 %)
|
||||
BM_ZFlat/10 1.2GB/s pb (19.68 %)
|
||||
BM_ZFlat/11 527.4MB/s gaviota (37.72 %)
|
|
@ -1,23 +0,0 @@
|
|||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
|
@ -1,25 +0,0 @@
|
|||
golang-lru
|
||||
==========
|
||||
|
||||
This provides the `lru` package which implements a fixed-size
|
||||
thread safe LRU cache. It is based on the cache in Groupcache.
|
||||
|
||||
Documentation
|
||||
=============
|
||||
|
||||
Full docs are available on [Godoc](http://godoc.org/github.com/hashicorp/golang-lru)
|
||||
|
||||
Example
|
||||
=======
|
||||
|
||||
Using the LRU is very simple:
|
||||
|
||||
```go
|
||||
l, _ := New(128)
|
||||
for i := 0; i < 256; i++ {
|
||||
l.Add(i, nil)
|
||||
}
|
||||
if l.Len() != 128 {
|
||||
panic(fmt.Sprintf("bad len: %v", l.Len()))
|
||||
}
|
||||
```
|
|
@ -1 +0,0 @@
|
|||
/gotasks/specs
|
|
@ -1,44 +0,0 @@
|
|||
goupnp is a UPnP client library for Go
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Run `go get -u github.com/huin/goupnp`.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
Supported DCPs (you probably want to start with one of these):
|
||||
|
||||
* [![GoDoc](https://godoc.org/github.com/huin/goupnp?status.svg) av1](https://godoc.org/github.com/huin/goupnp/dcps/av1) - Client for UPnP Device Control Protocol MediaServer v1 and MediaRenderer v1.
|
||||
* [![GoDoc](https://godoc.org/github.com/huin/goupnp?status.svg) internetgateway1](https://godoc.org/github.com/huin/goupnp/dcps/internetgateway1) - Client for UPnP Device Control Protocol Internet Gateway Device v1.
|
||||
* [![GoDoc](https://godoc.org/github.com/huin/goupnp?status.svg) internetgateway2](https://godoc.org/github.com/huin/goupnp/dcps/internetgateway2) - Client for UPnP Device Control Protocol Internet Gateway Device v2.
|
||||
|
||||
Core components:
|
||||
|
||||
* [![GoDoc](https://godoc.org/github.com/huin/goupnp?status.svg) (goupnp)](https://godoc.org/github.com/huin/goupnp) core library - contains datastructures and utilities typically used by the implemented DCPs.
|
||||
* [![GoDoc](https://godoc.org/github.com/huin/goupnp?status.svg) httpu](https://godoc.org/github.com/huin/goupnp/httpu) HTTPU implementation, underlies SSDP.
|
||||
* [![GoDoc](https://godoc.org/github.com/huin/goupnp?status.svg) ssdp](https://godoc.org/github.com/huin/goupnp/ssdp) SSDP client implementation (simple service discovery protocol) - used to discover UPnP services on a network.
|
||||
* [![GoDoc](https://godoc.org/github.com/huin/goupnp?status.svg) soap](https://godoc.org/github.com/huin/goupnp/soap) SOAP client implementation (simple object access protocol) - used to communicate with discovered services.
|
||||
|
||||
|
||||
Regenerating dcps generated source code:
|
||||
----------------------------------------
|
||||
|
||||
1. Install gotasks: `go get -u github.com/jingweno/gotask`
|
||||
2. Change to the gotasks directory: `cd gotasks`
|
||||
3. Run specgen task: `gotask specgen`
|
||||
|
||||
Supporting additional UPnP devices and services:
|
||||
------------------------------------------------
|
||||
|
||||
Supporting additional services is, in the trivial case, simply a matter of
|
||||
adding the service to the `dcpMetadata` whitelist in `gotasks/specgen_task.go`,
|
||||
regenerating the source code (see above), and committing that source code.
|
||||
|
||||
However, it would be helpful if anyone needing such a service could test the
|
||||
service against the service they have, and then reporting any trouble
|
||||
encountered as an [issue on this
|
||||
project](https://github.com/huin/goupnp/issues/new). If it just works, then
|
||||
please report at least minimal working functionality as an issue, and
|
||||
optionally contribute the metadata upstream.
|
|
@ -1,13 +0,0 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.6.2
|
||||
- tip
|
||||
|
||||
allowed_failures:
|
||||
- go: tip
|
||||
|
||||
install:
|
||||
- go get -d -v ./... && go install -race -v ./...
|
||||
|
||||
script: go test -race -v ./...
|
|
@ -1,52 +0,0 @@
|
|||
go-nat-pmp
|
||||
==========
|
||||
|
||||
A Go language client for the NAT-PMP internet protocol for port mapping and discovering the external
|
||||
IP address of a firewall.
|
||||
|
||||
NAT-PMP is supported by Apple brand routers and open source routers like Tomato and DD-WRT.
|
||||
|
||||
See http://tools.ietf.org/html/draft-cheshire-nat-pmp-03
|
||||
|
||||
|
||||
[![Build Status](https://travis-ci.org/jackpal/go-nat-pmp.svg)](https://travis-ci.org/jackpal/go-nat-pmp)
|
||||
|
||||
Get the package
|
||||
---------------
|
||||
|
||||
go get -u github.com/jackpal/go-nat-pmp
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
import (
|
||||
"github.com/jackpal/gateway"
|
||||
natpmp "github.com/jackpal/go-nat-pmp"
|
||||
)
|
||||
|
||||
gatewayIP, err = gateway.DiscoverGateway()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
client := natpmp.NewClient(gatewayIP)
|
||||
response, err := client.GetExternalAddress()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
print("External IP address:", response.ExternalIPAddress)
|
||||
|
||||
Clients
|
||||
-------
|
||||
|
||||
This library is used in the Taipei Torrent BitTorrent client http://github.com/jackpal/Taipei-Torrent
|
||||
|
||||
Complete documentation
|
||||
----------------------
|
||||
|
||||
http://godoc.org/github.com/jackpal/go-nat-pmp
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
This project is licensed under the Apache License 2.0.
|
|
@ -1,8 +0,0 @@
|
|||
language: go
|
||||
go:
|
||||
- tip
|
||||
|
||||
sudo: false
|
||||
|
||||
script:
|
||||
- go test -v
|
|
@ -1,43 +0,0 @@
|
|||
# go-colorable
|
||||
|
||||
Colorable writer for windows.
|
||||
|
||||
For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.)
|
||||
This package is possible to handle escape sequence for ansi color on windows.
|
||||
|
||||
## Too Bad!
|
||||
|
||||
![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/bad.png)
|
||||
|
||||
|
||||
## So Good!
|
||||
|
||||
![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/good.png)
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true})
|
||||
logrus.SetOutput(colorable.NewColorableStdout())
|
||||
|
||||
logrus.Info("succeeded")
|
||||
logrus.Warn("not correct")
|
||||
logrus.Error("something error")
|
||||
logrus.Fatal("panic")
|
||||
```
|
||||
|
||||
You can compile above code on non-windows OSs.
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
$ go get github.com/mattn/go-colorable
|
||||
```
|
||||
|
||||
# License
|
||||
|
||||
MIT
|
||||
|
||||
# Author
|
||||
|
||||
Yasuhiro Matsumoto (a.k.a mattn)
|
|
@ -1,8 +0,0 @@
|
|||
language: go
|
||||
go:
|
||||
- tip
|
||||
before_install:
|
||||
- go get github.com/mattn/goveralls
|
||||
- go get golang.org/x/tools/cmd/cover
|
||||
script:
|
||||
- $HOME/gopath/bin/goveralls -repotoken 3gHdORO5k5ziZcWMBxnd9LrMZaJs8m9x5
|
|
@ -1,47 +0,0 @@
|
|||
# go-isatty
|
||||
|
||||
[![Build Status](https://travis-ci.org/mattn/go-isatty.svg?branch=master)](https://travis-ci.org/mattn/go-isatty) [![Coverage Status](https://coveralls.io/repos/github/mattn/go-isatty/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-isatty?branch=master)
|
||||
|
||||
isatty for golang
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mattn/go-isatty"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if isatty.IsTerminal(os.Stdout.Fd()) {
|
||||
fmt.Println("Is Terminal")
|
||||
} else if isatty.IsCygwinTerminal(os.Stdout.Fd()) {
|
||||
fmt.Println("Is Cygwin/MSYS2 Terminal")
|
||||
} else {
|
||||
fmt.Println("Is Not Terminal")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
$ go get github.com/mattn/go-isatty
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
## Author
|
||||
|
||||
Yasuhiro Matsumoto (a.k.a mattn)
|
||||
|
||||
## Thanks
|
||||
|
||||
* k-takata: base idea for IsCygwinTerminal
|
||||
|
||||
https://github.com/k-takata/go-iscygpty
|
|
@ -1,9 +0,0 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.4.3
|
||||
- 1.5.3
|
||||
- tip
|
||||
|
||||
script:
|
||||
- go test -v ./...
|
|
@ -1,10 +0,0 @@
|
|||
# How to contribute
|
||||
|
||||
We definitely welcome patches and contribution to this project!
|
||||
|
||||
### Legal requirements
|
||||
|
||||
In order to protect both you and ourselves, you will need to sign the
|
||||
[Contributor License Agreement](https://cla.developers.google.com/clas).
|
||||
|
||||
You may have already signed it for other Google projects.
|
|
@ -1,13 +0,0 @@
|
|||
This project was automatically exported from code.google.com/p/go-uuid
|
||||
|
||||
# uuid ![build status](https://travis-ci.org/pborman/uuid.svg?branch=master)
|
||||
The uuid package generates and inspects UUIDs based on [RFC 4122](http://tools.ietf.org/html/rfc4122) and DCE 1.1: Authentication and Security Services.
|
||||
|
||||
###### Install
|
||||
`go get github.com/pborman/uuid`
|
||||
|
||||
###### Documentation
|
||||
[![GoDoc](https://godoc.org/github.com/pborman/uuid?status.svg)](http://godoc.org/github.com/pborman/uuid)
|
||||
|
||||
Full `go doc` style documentation for the package can be viewed online without installing this package by using the GoDoc site here:
|
||||
http://godoc.org/github.com/pborman/uuid
|
|
@ -1 +0,0 @@
|
|||
command-line-arguments.test
|
|
@ -1 +0,0 @@
|
|||
See [![go-doc](https://godoc.org/github.com/prometheus/client_golang/prometheus?status.svg)](https://godoc.org/github.com/prometheus/client_golang/prometheus).
|
67
vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/README.txt
generated
vendored
67
vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/README.txt
generated
vendored
|
@ -1,67 +0,0 @@
|
|||
PACKAGE
|
||||
|
||||
package goautoneg
|
||||
import "bitbucket.org/ww/goautoneg"
|
||||
|
||||
HTTP Content-Type Autonegotiation.
|
||||
|
||||
The functions in this package implement the behaviour specified in
|
||||
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
|
||||
|
||||
Copyright (c) 2011, Open Knowledge Foundation Ltd.
|
||||
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 the Open Knowledge Foundation Ltd. 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
|
||||
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.
|
||||
|
||||
|
||||
FUNCTIONS
|
||||
|
||||
func Negotiate(header string, alternatives []string) (content_type string)
|
||||
Negotiate the most appropriate content_type given the accept header
|
||||
and a list of alternatives.
|
||||
|
||||
func ParseAccept(header string) (accept []Accept)
|
||||
Parse an Accept Header string returning a sorted list
|
||||
of clauses
|
||||
|
||||
|
||||
TYPES
|
||||
|
||||
type Accept struct {
|
||||
Type, SubType string
|
||||
Q float32
|
||||
Params map[string]string
|
||||
}
|
||||
Structure to represent a clause in an HTTP Accept Header
|
||||
|
||||
|
||||
SUBDIRECTORIES
|
||||
|
||||
.hg
|
|
@ -1,9 +0,0 @@
|
|||
sudo: false
|
||||
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.9.x
|
||||
- 1.x
|
||||
|
||||
go_import_path: github.com/prometheus/procfs
|
|
@ -1,18 +0,0 @@
|
|||
# Contributing
|
||||
|
||||
Prometheus uses GitHub to manage reviews of pull requests.
|
||||
|
||||
* If you have a trivial fix or improvement, go ahead and create a pull request,
|
||||
addressing (with `@...`) the maintainer of this repository (see
|
||||
[MAINTAINERS.md](MAINTAINERS.md)) in the description of the pull request.
|
||||
|
||||
* If you plan to do something more involved, first discuss your ideas
|
||||
on our [mailing list](https://groups.google.com/forum/?fromgroups#!forum/prometheus-developers).
|
||||
This will avoid unnecessary work and surely give you and us a good deal
|
||||
of inspiration.
|
||||
|
||||
* Relevant coding style guidelines are the [Go Code Review
|
||||
Comments](https://code.google.com/p/go-wiki/wiki/CodeReviewComments)
|
||||
and the _Formatting and style_ section of Peter Bourgon's [Go: Best
|
||||
Practices for Production
|
||||
Environments](http://peter.bourgon.org/go-in-production/#formatting-and-style).
|
|
@ -1 +0,0 @@
|
|||
* Tobias Schmidt <tobidt@gmail.com>
|
|
@ -1,18 +0,0 @@
|
|||
ci: fmt lint test
|
||||
|
||||
fmt:
|
||||
! gofmt -l *.go | read nothing
|
||||
go vet
|
||||
|
||||
lint:
|
||||
go get github.com/golang/lint/golint
|
||||
golint *.go
|
||||
|
||||
test: sysfs/fixtures/.unpacked
|
||||
go test -v ./...
|
||||
|
||||
sysfs/fixtures/.unpacked: sysfs/fixtures.ttar
|
||||
./ttar -C sysfs -x -f sysfs/fixtures.ttar
|
||||
touch $@
|
||||
|
||||
.PHONY: fmt lint test ci
|
|
@ -1,11 +0,0 @@
|
|||
# procfs
|
||||
|
||||
This procfs package provides functions to retrieve system, kernel and process
|
||||
metrics from the pseudo-filesystem proc.
|
||||
|
||||
*WARNING*: This package is a work in progress. Its API may still break in
|
||||
backwards-incompatible ways without warnings. Use it at your own risk.
|
||||
|
||||
[![GoDoc](https://godoc.org/github.com/prometheus/procfs?status.png)](https://godoc.org/github.com/prometheus/procfs)
|
||||
[![Build Status](https://travis-ci.org/prometheus/procfs.svg?branch=master)](https://travis-ci.org/prometheus/procfs)
|
||||
[![Go Report Card](https://goreportcard.com/badge/github.com/prometheus/procfs)](https://goreportcard.com/report/github.com/prometheus/procfs)
|
|
@ -1,264 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# Purpose: plain text tar format
|
||||
# Limitations: - only suitable for text files, directories, and symlinks
|
||||
# - stores only filename, content, and mode
|
||||
# - not designed for untrusted input
|
||||
|
||||
# Note: must work with bash version 3.2 (macOS)
|
||||
|
||||
set -o errexit -o nounset
|
||||
|
||||
# Sanitize environment (for instance, standard sorting of glob matches)
|
||||
export LC_ALL=C
|
||||
|
||||
path=""
|
||||
CMD=""
|
||||
|
||||
function usage {
|
||||
bname=$(basename "$0")
|
||||
cat << USAGE
|
||||
Usage: $bname [-C <DIR>] -c -f <ARCHIVE> <FILE...> (create archive)
|
||||
$bname -t -f <ARCHIVE> (list archive contents)
|
||||
$bname [-C <DIR>] -x -f <ARCHIVE> (extract archive)
|
||||
|
||||
Options:
|
||||
-C <DIR> (change directory)
|
||||
|
||||
Example: Change to sysfs directory, create ttar file from fixtures directory
|
||||
$bname -C sysfs -c -f sysfs/fixtures.ttar fixtures/
|
||||
USAGE
|
||||
exit "$1"
|
||||
}
|
||||
|
||||
function vecho {
|
||||
if [ "${VERBOSE:-}" == "yes" ]; then
|
||||
echo >&7 "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
function set_cmd {
|
||||
if [ -n "$CMD" ]; then
|
||||
echo "ERROR: more than one command given"
|
||||
echo
|
||||
usage 2
|
||||
fi
|
||||
CMD=$1
|
||||
}
|
||||
|
||||
while getopts :cf:htxvC: opt; do
|
||||
case $opt in
|
||||
c)
|
||||
set_cmd "create"
|
||||
;;
|
||||
f)
|
||||
ARCHIVE=$OPTARG
|
||||
;;
|
||||
h)
|
||||
usage 0
|
||||
;;
|
||||
t)
|
||||
set_cmd "list"
|
||||
;;
|
||||
x)
|
||||
set_cmd "extract"
|
||||
;;
|
||||
v)
|
||||
VERBOSE=yes
|
||||
exec 7>&1
|
||||
;;
|
||||
C)
|
||||
CDIR=$OPTARG
|
||||
;;
|
||||
*)
|
||||
echo >&2 "ERROR: invalid option -$OPTARG"
|
||||
echo
|
||||
usage 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Remove processed options from arguments
|
||||
shift $(( OPTIND - 1 ));
|
||||
|
||||
if [ "${CMD:-}" == "" ]; then
|
||||
echo >&2 "ERROR: no command given"
|
||||
echo
|
||||
usage 1
|
||||
elif [ "${ARCHIVE:-}" == "" ]; then
|
||||
echo >&2 "ERROR: no archive name given"
|
||||
echo
|
||||
usage 1
|
||||
fi
|
||||
|
||||
function list {
|
||||
local path=""
|
||||
local size=0
|
||||
local line_no=0
|
||||
local ttar_file=$1
|
||||
if [ -n "${2:-}" ]; then
|
||||
echo >&2 "ERROR: too many arguments."
|
||||
echo
|
||||
usage 1
|
||||
fi
|
||||
if [ ! -e "$ttar_file" ]; then
|
||||
echo >&2 "ERROR: file not found ($ttar_file)"
|
||||
echo
|
||||
usage 1
|
||||
fi
|
||||
while read -r line; do
|
||||
line_no=$(( line_no + 1 ))
|
||||
if [ $size -gt 0 ]; then
|
||||
size=$(( size - 1 ))
|
||||
continue
|
||||
fi
|
||||
if [[ $line =~ ^Path:\ (.*)$ ]]; then
|
||||
path=${BASH_REMATCH[1]}
|
||||
elif [[ $line =~ ^Lines:\ (.*)$ ]]; then
|
||||
size=${BASH_REMATCH[1]}
|
||||
echo "$path"
|
||||
elif [[ $line =~ ^Directory:\ (.*)$ ]]; then
|
||||
path=${BASH_REMATCH[1]}
|
||||
echo "$path/"
|
||||
elif [[ $line =~ ^SymlinkTo:\ (.*)$ ]]; then
|
||||
echo "$path -> ${BASH_REMATCH[1]}"
|
||||
fi
|
||||
done < "$ttar_file"
|
||||
}
|
||||
|
||||
function extract {
|
||||
local path=""
|
||||
local size=0
|
||||
local line_no=0
|
||||
local ttar_file=$1
|
||||
if [ -n "${2:-}" ]; then
|
||||
echo >&2 "ERROR: too many arguments."
|
||||
echo
|
||||
usage 1
|
||||
fi
|
||||
if [ ! -e "$ttar_file" ]; then
|
||||
echo >&2 "ERROR: file not found ($ttar_file)"
|
||||
echo
|
||||
usage 1
|
||||
fi
|
||||
while IFS= read -r line; do
|
||||
line_no=$(( line_no + 1 ))
|
||||
if [ "$size" -gt 0 ]; then
|
||||
echo "$line" >> "$path"
|
||||
size=$(( size - 1 ))
|
||||
continue
|
||||
fi
|
||||
if [[ $line =~ ^Path:\ (.*)$ ]]; then
|
||||
path=${BASH_REMATCH[1]}
|
||||
if [ -e "$path" ] || [ -L "$path" ]; then
|
||||
rm "$path"
|
||||
fi
|
||||
elif [[ $line =~ ^Lines:\ (.*)$ ]]; then
|
||||
size=${BASH_REMATCH[1]}
|
||||
# Create file even if it is zero-length.
|
||||
touch "$path"
|
||||
vecho " $path"
|
||||
elif [[ $line =~ ^Mode:\ (.*)$ ]]; then
|
||||
mode=${BASH_REMATCH[1]}
|
||||
chmod "$mode" "$path"
|
||||
vecho "$mode"
|
||||
elif [[ $line =~ ^Directory:\ (.*)$ ]]; then
|
||||
path=${BASH_REMATCH[1]}
|
||||
mkdir -p "$path"
|
||||
vecho " $path/"
|
||||
elif [[ $line =~ ^SymlinkTo:\ (.*)$ ]]; then
|
||||
ln -s "${BASH_REMATCH[1]}" "$path"
|
||||
vecho " $path -> ${BASH_REMATCH[1]}"
|
||||
elif [[ $line =~ ^# ]]; then
|
||||
# Ignore comments between files
|
||||
continue
|
||||
else
|
||||
echo >&2 "ERROR: Unknown keyword on line $line_no: $line"
|
||||
exit 1
|
||||
fi
|
||||
done < "$ttar_file"
|
||||
}
|
||||
|
||||
function div {
|
||||
echo "# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -" \
|
||||
"- - - - - -"
|
||||
}
|
||||
|
||||
function get_mode {
|
||||
local mfile=$1
|
||||
if [ -z "${STAT_OPTION:-}" ]; then
|
||||
if stat -c '%a' "$mfile" >/dev/null 2>&1; then
|
||||
STAT_OPTION='-c'
|
||||
STAT_FORMAT='%a'
|
||||
else
|
||||
STAT_OPTION='-f'
|
||||
STAT_FORMAT='%A'
|
||||
fi
|
||||
fi
|
||||
stat "${STAT_OPTION}" "${STAT_FORMAT}" "$mfile"
|
||||
}
|
||||
|
||||
function _create {
|
||||
shopt -s nullglob
|
||||
local mode
|
||||
while (( "$#" )); do
|
||||
file=$1
|
||||
if [ -L "$file" ]; then
|
||||
echo "Path: $file"
|
||||
symlinkTo=$(readlink "$file")
|
||||
echo "SymlinkTo: $symlinkTo"
|
||||
vecho " $file -> $symlinkTo"
|
||||
div
|
||||
elif [ -d "$file" ]; then
|
||||
# Strip trailing slash (if there is one)
|
||||
file=${file%/}
|
||||
echo "Directory: $file"
|
||||
mode=$(get_mode "$file")
|
||||
echo "Mode: $mode"
|
||||
vecho "$mode $file/"
|
||||
div
|
||||
# Find all files and dirs, including hidden/dot files
|
||||
for x in "$file/"{*,.[^.]*}; do
|
||||
_create "$x"
|
||||
done
|
||||
elif [ -f "$file" ]; then
|
||||
echo "Path: $file"
|
||||
lines=$(wc -l "$file"|awk '{print $1}')
|
||||
echo "Lines: $lines"
|
||||
cat "$file"
|
||||
mode=$(get_mode "$file")
|
||||
echo "Mode: $mode"
|
||||
vecho "$mode $file"
|
||||
div
|
||||
else
|
||||
echo >&2 "ERROR: file not found ($file in $(pwd))"
|
||||
exit 2
|
||||
fi
|
||||
shift
|
||||
done
|
||||
}
|
||||
|
||||
function create {
|
||||
ttar_file=$1
|
||||
shift
|
||||
if [ -z "${1:-}" ]; then
|
||||
echo >&2 "ERROR: missing arguments."
|
||||
echo
|
||||
usage 1
|
||||
fi
|
||||
if [ -e "$ttar_file" ]; then
|
||||
rm "$ttar_file"
|
||||
fi
|
||||
exec > "$ttar_file"
|
||||
_create "$@"
|
||||
}
|
||||
|
||||
if [ -n "${CDIR:-}" ]; then
|
||||
if [[ "$ARCHIVE" != /* ]]; then
|
||||
# Relative path: preserve the archive's location before changing
|
||||
# directory
|
||||
ARCHIVE="$(pwd)/$ARCHIVE"
|
||||
fi
|
||||
cd "$CDIR"
|
||||
fi
|
||||
|
||||
"$CMD" "$ARCHIVE" "$@"
|
|
@ -1,9 +0,0 @@
|
|||
*.[68]
|
||||
*.a
|
||||
*.out
|
||||
*.swp
|
||||
_obj
|
||||
_testmain.go
|
||||
cmd/metrics-bench/metrics-bench
|
||||
cmd/metrics-example/metrics-example
|
||||
cmd/never-read/never-read
|
|
@ -1,14 +0,0 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.2
|
||||
- 1.3
|
||||
- 1.4
|
||||
- 1.5
|
||||
|
||||
script:
|
||||
- ./validate.sh
|
||||
|
||||
# this should give us faster builds according to
|
||||
# http://docs.travis-ci.com/user/migrating-from-legacy/
|
||||
sudo: false
|
|
@ -1,153 +0,0 @@
|
|||
go-metrics
|
||||
==========
|
||||
|
||||
![travis build status](https://travis-ci.org/rcrowley/go-metrics.svg?branch=master)
|
||||
|
||||
Go port of Coda Hale's Metrics library: <https://github.com/dropwizard/metrics>.
|
||||
|
||||
Documentation: <http://godoc.org/github.com/rcrowley/go-metrics>.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Create and update metrics:
|
||||
|
||||
```go
|
||||
c := metrics.NewCounter()
|
||||
metrics.Register("foo", c)
|
||||
c.Inc(47)
|
||||
|
||||
g := metrics.NewGauge()
|
||||
metrics.Register("bar", g)
|
||||
g.Update(47)
|
||||
|
||||
r := NewRegistry()
|
||||
g := metrics.NewRegisteredFunctionalGauge("cache-evictions", r, func() int64 { return cache.getEvictionsCount() })
|
||||
|
||||
s := metrics.NewExpDecaySample(1028, 0.015) // or metrics.NewUniformSample(1028)
|
||||
h := metrics.NewHistogram(s)
|
||||
metrics.Register("baz", h)
|
||||
h.Update(47)
|
||||
|
||||
m := metrics.NewMeter()
|
||||
metrics.Register("quux", m)
|
||||
m.Mark(47)
|
||||
|
||||
t := metrics.NewTimer()
|
||||
metrics.Register("bang", t)
|
||||
t.Time(func() {})
|
||||
t.Update(47)
|
||||
```
|
||||
|
||||
Register() is not threadsafe. For threadsafe metric registration use
|
||||
GetOrRegister:
|
||||
|
||||
```
|
||||
t := metrics.GetOrRegisterTimer("account.create.latency", nil)
|
||||
t.Time(func() {})
|
||||
t.Update(47)
|
||||
```
|
||||
|
||||
Periodically log every metric in human-readable form to standard error:
|
||||
|
||||
```go
|
||||
go metrics.Log(metrics.DefaultRegistry, 5 * time.Second, log.New(os.Stderr, "metrics: ", log.Lmicroseconds))
|
||||
```
|
||||
|
||||
Periodically log every metric in slightly-more-parseable form to syslog:
|
||||
|
||||
```go
|
||||
w, _ := syslog.Dial("unixgram", "/dev/log", syslog.LOG_INFO, "metrics")
|
||||
go metrics.Syslog(metrics.DefaultRegistry, 60e9, w)
|
||||
```
|
||||
|
||||
Periodically emit every metric to Graphite using the [Graphite client](https://github.com/cyberdelia/go-metrics-graphite):
|
||||
|
||||
```go
|
||||
|
||||
import "github.com/cyberdelia/go-metrics-graphite"
|
||||
|
||||
addr, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:2003")
|
||||
go graphite.Graphite(metrics.DefaultRegistry, 10e9, "metrics", addr)
|
||||
```
|
||||
|
||||
Periodically emit every metric into InfluxDB:
|
||||
|
||||
**NOTE:** this has been pulled out of the library due to constant fluctuations
|
||||
in the InfluxDB API. In fact, all client libraries are on their way out. see
|
||||
issues [#121](https://github.com/rcrowley/go-metrics/issues/121) and
|
||||
[#124](https://github.com/rcrowley/go-metrics/issues/124) for progress and details.
|
||||
|
||||
```go
|
||||
import "github.com/vrischmann/go-metrics-influxdb"
|
||||
|
||||
go influxdb.Influxdb(metrics.DefaultRegistry, 10e9, &influxdb.Config{
|
||||
Host: "127.0.0.1:8086",
|
||||
Database: "metrics",
|
||||
Username: "test",
|
||||
Password: "test",
|
||||
})
|
||||
```
|
||||
|
||||
Periodically upload every metric to Librato using the [Librato client](https://github.com/mihasya/go-metrics-librato):
|
||||
|
||||
**Note**: the client included with this repository under the `librato` package
|
||||
has been deprecated and moved to the repository linked above.
|
||||
|
||||
```go
|
||||
import "github.com/mihasya/go-metrics-librato"
|
||||
|
||||
go librato.Librato(metrics.DefaultRegistry,
|
||||
10e9, // interval
|
||||
"example@example.com", // account owner email address
|
||||
"token", // Librato API token
|
||||
"hostname", // source
|
||||
[]float64{0.95}, // percentiles to send
|
||||
time.Millisecond, // time unit
|
||||
)
|
||||
```
|
||||
|
||||
Periodically emit every metric to StatHat:
|
||||
|
||||
```go
|
||||
import "github.com/rcrowley/go-metrics/stathat"
|
||||
|
||||
go stathat.Stathat(metrics.DefaultRegistry, 10e9, "example@example.com")
|
||||
```
|
||||
|
||||
Maintain all metrics along with expvars at `/debug/metrics`:
|
||||
|
||||
This uses the same mechanism as [the official expvar](http://golang.org/pkg/expvar/)
|
||||
but exposed under `/debug/metrics`, which shows a json representation of all your usual expvars
|
||||
as well as all your go-metrics.
|
||||
|
||||
|
||||
```go
|
||||
import "github.com/rcrowley/go-metrics/exp"
|
||||
|
||||
exp.Exp(metrics.DefaultRegistry)
|
||||
```
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
```sh
|
||||
go get github.com/rcrowley/go-metrics
|
||||
```
|
||||
|
||||
StatHat support additionally requires their Go client:
|
||||
|
||||
```sh
|
||||
go get github.com/stathat/go
|
||||
```
|
||||
|
||||
Publishing Metrics
|
||||
------------------
|
||||
|
||||
Clients are available for the following destinations:
|
||||
|
||||
* Librato - [https://github.com/mihasya/go-metrics-librato](https://github.com/mihasya/go-metrics-librato)
|
||||
* Graphite - [https://github.com/cyberdelia/go-metrics-graphite](https://github.com/cyberdelia/go-metrics-graphite)
|
||||
* InfluxDB - [https://github.com/vrischmann/go-metrics-influxdb](https://github.com/vrischmann/go-metrics-influxdb)
|
||||
* Ganglia - [https://github.com/appscode/metlia](https://github.com/appscode/metlia)
|
||||
* Prometheus - [https://github.com/deathowl/go-metrics-prometheus](https://github.com/deathowl/go-metrics-prometheus)
|
|
@ -1,285 +0,0 @@
|
|||
Memory usage
|
||||
============
|
||||
|
||||
(Highly unscientific.)
|
||||
|
||||
Command used to gather static memory usage:
|
||||
|
||||
```sh
|
||||
grep ^Vm "/proc/$(ps fax | grep [m]etrics-bench | awk '{print $1}')/status"
|
||||
```
|
||||
|
||||
Program used to gather baseline memory usage:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "time"
|
||||
|
||||
func main() {
|
||||
time.Sleep(600e9)
|
||||
}
|
||||
```
|
||||
|
||||
Baseline
|
||||
--------
|
||||
|
||||
```
|
||||
VmPeak: 42604 kB
|
||||
VmSize: 42604 kB
|
||||
VmLck: 0 kB
|
||||
VmHWM: 1120 kB
|
||||
VmRSS: 1120 kB
|
||||
VmData: 35460 kB
|
||||
VmStk: 136 kB
|
||||
VmExe: 1020 kB
|
||||
VmLib: 1848 kB
|
||||
VmPTE: 36 kB
|
||||
VmSwap: 0 kB
|
||||
```
|
||||
|
||||
Program used to gather metric memory usage (with other metrics being similar):
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"metrics"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Sprintf("foo")
|
||||
metrics.NewRegistry()
|
||||
time.Sleep(600e9)
|
||||
}
|
||||
```
|
||||
|
||||
1000 counters registered
|
||||
------------------------
|
||||
|
||||
```
|
||||
VmPeak: 44016 kB
|
||||
VmSize: 44016 kB
|
||||
VmLck: 0 kB
|
||||
VmHWM: 1928 kB
|
||||
VmRSS: 1928 kB
|
||||
VmData: 36868 kB
|
||||
VmStk: 136 kB
|
||||
VmExe: 1024 kB
|
||||
VmLib: 1848 kB
|
||||
VmPTE: 40 kB
|
||||
VmSwap: 0 kB
|
||||
```
|
||||
|
||||
**1.412 kB virtual, TODO 0.808 kB resident per counter.**
|
||||
|
||||
100000 counters registered
|
||||
--------------------------
|
||||
|
||||
```
|
||||
VmPeak: 55024 kB
|
||||
VmSize: 55024 kB
|
||||
VmLck: 0 kB
|
||||
VmHWM: 12440 kB
|
||||
VmRSS: 12440 kB
|
||||
VmData: 47876 kB
|
||||
VmStk: 136 kB
|
||||
VmExe: 1024 kB
|
||||
VmLib: 1848 kB
|
||||
VmPTE: 64 kB
|
||||
VmSwap: 0 kB
|
||||
```
|
||||
|
||||
**0.1242 kB virtual, 0.1132 kB resident per counter.**
|
||||
|
||||
1000 gauges registered
|
||||
----------------------
|
||||
|
||||
```
|
||||
VmPeak: 44012 kB
|
||||
VmSize: 44012 kB
|
||||
VmLck: 0 kB
|
||||
VmHWM: 1928 kB
|
||||
VmRSS: 1928 kB
|
||||
VmData: 36868 kB
|
||||
VmStk: 136 kB
|
||||
VmExe: 1020 kB
|
||||
VmLib: 1848 kB
|
||||
VmPTE: 40 kB
|
||||
VmSwap: 0 kB
|
||||
```
|
||||
|
||||
**1.408 kB virtual, 0.808 kB resident per counter.**
|
||||
|
||||
100000 gauges registered
|
||||
------------------------
|
||||
|
||||
```
|
||||
VmPeak: 55020 kB
|
||||
VmSize: 55020 kB
|
||||
VmLck: 0 kB
|
||||
VmHWM: 12432 kB
|
||||
VmRSS: 12432 kB
|
||||
VmData: 47876 kB
|
||||
VmStk: 136 kB
|
||||
VmExe: 1020 kB
|
||||
VmLib: 1848 kB
|
||||
VmPTE: 60 kB
|
||||
VmSwap: 0 kB
|
||||
```
|
||||
|
||||
**0.12416 kB virtual, 0.11312 resident per gauge.**
|
||||
|
||||
1000 histograms with a uniform sample size of 1028
|
||||
--------------------------------------------------
|
||||
|
||||
```
|
||||
VmPeak: 72272 kB
|
||||
VmSize: 72272 kB
|
||||
VmLck: 0 kB
|
||||
VmHWM: 16204 kB
|
||||
VmRSS: 16204 kB
|
||||
VmData: 65100 kB
|
||||
VmStk: 136 kB
|
||||
VmExe: 1048 kB
|
||||
VmLib: 1848 kB
|
||||
VmPTE: 80 kB
|
||||
VmSwap: 0 kB
|
||||
```
|
||||
|
||||
**29.668 kB virtual, TODO 15.084 resident per histogram.**
|
||||
|
||||
10000 histograms with a uniform sample size of 1028
|
||||
---------------------------------------------------
|
||||
|
||||
```
|
||||
VmPeak: 256912 kB
|
||||
VmSize: 256912 kB
|
||||
VmLck: 0 kB
|
||||
VmHWM: 146204 kB
|
||||
VmRSS: 146204 kB
|
||||
VmData: 249740 kB
|
||||
VmStk: 136 kB
|
||||
VmExe: 1048 kB
|
||||
VmLib: 1848 kB
|
||||
VmPTE: 448 kB
|
||||
VmSwap: 0 kB
|
||||
```
|
||||
|
||||
**21.4308 kB virtual, 14.5084 kB resident per histogram.**
|
||||
|
||||
50000 histograms with a uniform sample size of 1028
|
||||
---------------------------------------------------
|
||||
|
||||
```
|
||||
VmPeak: 908112 kB
|
||||
VmSize: 908112 kB
|
||||
VmLck: 0 kB
|
||||
VmHWM: 645832 kB
|
||||
VmRSS: 645588 kB
|
||||
VmData: 900940 kB
|
||||
VmStk: 136 kB
|
||||
VmExe: 1048 kB
|
||||
VmLib: 1848 kB
|
||||
VmPTE: 1716 kB
|
||||
VmSwap: 1544 kB
|
||||
```
|
||||
|
||||
**17.31016 kB virtual, 12.88936 kB resident per histogram.**
|
||||
|
||||
1000 histograms with an exponentially-decaying sample size of 1028 and alpha of 0.015
|
||||
-------------------------------------------------------------------------------------
|
||||
|
||||
```
|
||||
VmPeak: 62480 kB
|
||||
VmSize: 62480 kB
|
||||
VmLck: 0 kB
|
||||
VmHWM: 11572 kB
|
||||
VmRSS: 11572 kB
|
||||
VmData: 55308 kB
|
||||
VmStk: 136 kB
|
||||
VmExe: 1048 kB
|
||||
VmLib: 1848 kB
|
||||
VmPTE: 64 kB
|
||||
VmSwap: 0 kB
|
||||
```
|
||||
|
||||
**19.876 kB virtual, 10.452 kB resident per histogram.**
|
||||
|
||||
10000 histograms with an exponentially-decaying sample size of 1028 and alpha of 0.015
|
||||
--------------------------------------------------------------------------------------
|
||||
|
||||
```
|
||||
VmPeak: 153296 kB
|
||||
VmSize: 153296 kB
|
||||
VmLck: 0 kB
|
||||
VmHWM: 101176 kB
|
||||
VmRSS: 101176 kB
|
||||
VmData: 146124 kB
|
||||
VmStk: 136 kB
|
||||
VmExe: 1048 kB
|
||||
VmLib: 1848 kB
|
||||
VmPTE: 240 kB
|
||||
VmSwap: 0 kB
|
||||
```
|
||||
|
||||
**11.0692 kB virtual, 10.0056 kB resident per histogram.**
|
||||
|
||||
50000 histograms with an exponentially-decaying sample size of 1028 and alpha of 0.015
|
||||
--------------------------------------------------------------------------------------
|
||||
|
||||
```
|
||||
VmPeak: 557264 kB
|
||||
VmSize: 557264 kB
|
||||
VmLck: 0 kB
|
||||
VmHWM: 501056 kB
|
||||
VmRSS: 501056 kB
|
||||
VmData: 550092 kB
|
||||
VmStk: 136 kB
|
||||
VmExe: 1048 kB
|
||||
VmLib: 1848 kB
|
||||
VmPTE: 1032 kB
|
||||
VmSwap: 0 kB
|
||||
```
|
||||
|
||||
**10.2932 kB virtual, 9.99872 kB resident per histogram.**
|
||||
|
||||
1000 meters
|
||||
-----------
|
||||
|
||||
```
|
||||
VmPeak: 74504 kB
|
||||
VmSize: 74504 kB
|
||||
VmLck: 0 kB
|
||||
VmHWM: 24124 kB
|
||||
VmRSS: 24124 kB
|
||||
VmData: 67340 kB
|
||||
VmStk: 136 kB
|
||||
VmExe: 1040 kB
|
||||
VmLib: 1848 kB
|
||||
VmPTE: 92 kB
|
||||
VmSwap: 0 kB
|
||||
```
|
||||
|
||||
**31.9 kB virtual, 23.004 kB resident per meter.**
|
||||
|
||||
10000 meters
|
||||
------------
|
||||
|
||||
```
|
||||
VmPeak: 278920 kB
|
||||
VmSize: 278920 kB
|
||||
VmLck: 0 kB
|
||||
VmHWM: 227300 kB
|
||||
VmRSS: 227300 kB
|
||||
VmData: 271756 kB
|
||||
VmStk: 136 kB
|
||||
VmExe: 1040 kB
|
||||
VmLib: 1848 kB
|
||||
VmPTE: 488 kB
|
||||
VmSwap: 0 kB
|
||||
```
|
||||
|
||||
**23.6316 kB virtual, 22.618 kB resident per meter.**
|
|
@ -1,10 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# check there are no formatting issues
|
||||
GOFMT_LINES=`gofmt -l . | wc -l | xargs`
|
||||
test $GOFMT_LINES -eq 0 || echo "gofmt needs to be run, ${GOFMT_LINES} files have issues"
|
||||
|
||||
# run the tests for the root package
|
||||
go test .
|
|
@ -1,92 +0,0 @@
|
|||
# Created by https://www.gitignore.io
|
||||
|
||||
### OSX ###
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear on external disk
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
|
||||
### Windows ###
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
|
||||
### Linux ###
|
||||
*~
|
||||
|
||||
# KDE directory preferences
|
||||
.directory
|
||||
|
||||
|
||||
### Go ###
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
|
||||
|
||||
### vim ###
|
||||
[._]*.s[a-w][a-z]
|
||||
[._]s[a-w][a-z]
|
||||
*.un~
|
||||
Session.vim
|
||||
.netrwhist
|
||||
*~
|
||||
|
||||
### JetBrains files ###
|
||||
.idea/
|
||||
*.iml
|
|
@ -1,28 +0,0 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.7.5
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: osx
|
||||
go: 1.7.5
|
||||
env:
|
||||
- GOFLAGS="-tags kqueue"
|
||||
|
||||
env:
|
||||
global:
|
||||
- GOBIN=$HOME/bin
|
||||
- PATH=$HOME/bin:$PATH
|
||||
|
||||
install:
|
||||
- go get -t -v ./...
|
||||
|
||||
script:
|
||||
- "(go version | grep -q 1.4) || go tool vet -all ."
|
||||
- go install $GOFLAGS ./...
|
||||
- go test -v -race $GOFLAGS ./...
|
|
@ -1,21 +0,0 @@
|
|||
notify [![GoDoc](https://godoc.org/github.com/rjeczalik/notify?status.svg)](https://godoc.org/github.com/rjeczalik/notify) [![Build Status](https://img.shields.io/travis/rjeczalik/notify/master.svg)](https://travis-ci.org/rjeczalik/notify "inotify + FSEvents + kqueue") [![Build status](https://img.shields.io/appveyor/ci/rjeczalik/notify-246.svg)](https://ci.appveyor.com/project/rjeczalik/notify-246 "ReadDirectoryChangesW") [![Coverage Status](https://img.shields.io/coveralls/rjeczalik/notify/master.svg)](https://coveralls.io/r/rjeczalik/notify?branch=master)
|
||||
======
|
||||
|
||||
Filesystem event notification library on steroids. (under active development)
|
||||
|
||||
*Documentation*
|
||||
|
||||
[godoc.org/github.com/rjeczalik/notify](https://godoc.org/github.com/rjeczalik/notify)
|
||||
|
||||
*Installation*
|
||||
|
||||
```
|
||||
~ $ go get -u github.com/rjeczalik/notify
|
||||
```
|
||||
|
||||
*Projects using notify*
|
||||
|
||||
- [github.com/rjeczalik/cmd/notify](https://godoc.org/github.com/rjeczalik/cmd/notify)
|
||||
- [github.com/cortesi/devd](https://github.com/cortesi/devd)
|
||||
- [github.com/cortesi/modd](https://github.com/cortesi/modd)
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
version: "{build}"
|
||||
|
||||
os: Windows Server 2012 R2
|
||||
|
||||
clone_folder: c:\projects\src\github.com\rjeczalik\notify
|
||||
|
||||
environment:
|
||||
PATH: c:\projects\bin;%PATH%
|
||||
GOPATH: c:\projects
|
||||
NOTIFY_TIMEOUT: 5s
|
||||
|
||||
install:
|
||||
- go version
|
||||
- go get -v -t ./...
|
||||
|
||||
build_script:
|
||||
- go tool vet -all .
|
||||
- go build ./...
|
||||
- go test -v -race ./...
|
||||
|
||||
test: off
|
||||
|
||||
deploy: off
|
|
@ -1,5 +0,0 @@
|
|||
/.test
|
||||
/otto/otto
|
||||
/otto/otto-*
|
||||
/test/test-*.js
|
||||
/test/tester
|
|
@ -1 +0,0 @@
|
|||
* Designate the filename of "anonymous" source code by the hash (md5/sha1, etc.)
|
|
@ -1,63 +0,0 @@
|
|||
.PHONY: test test-race test-release release release-check test-262
|
||||
.PHONY: parser
|
||||
.PHONY: otto assets underscore
|
||||
|
||||
TESTS := \
|
||||
~
|
||||
|
||||
TEST := -v --run
|
||||
TEST := -v
|
||||
TEST := -v --run Test\($(subst $(eval) ,\|,$(TESTS))\)
|
||||
TEST := .
|
||||
|
||||
test: parser inline.go
|
||||
go test -i
|
||||
go test $(TEST)
|
||||
@echo PASS
|
||||
|
||||
parser:
|
||||
$(MAKE) -C parser
|
||||
|
||||
inline.go: inline.pl
|
||||
./$< > $@
|
||||
|
||||
#################
|
||||
# release, test #
|
||||
#################
|
||||
|
||||
release: test-race test-release
|
||||
for package in . parser token ast file underscore registry; do (cd $$package && godocdown --signature > README.markdown); done
|
||||
@echo \*\*\* make release-check
|
||||
@echo PASS
|
||||
|
||||
release-check: .test
|
||||
$(MAKE) -C test build test
|
||||
$(MAKE) -C .test/test262 build test
|
||||
@echo PASS
|
||||
|
||||
test-262: .test
|
||||
$(MAKE) -C .test/test262 build test
|
||||
@echo PASS
|
||||
|
||||
test-release:
|
||||
go test -i
|
||||
go test
|
||||
|
||||
test-race:
|
||||
go test -race -i
|
||||
go test -race
|
||||
|
||||
#################################
|
||||
# otto, assets, underscore, ... #
|
||||
#################################
|
||||
|
||||
otto:
|
||||
$(MAKE) -C otto
|
||||
|
||||
assets:
|
||||
mkdir -p .assets
|
||||
for file in underscore/test/*.js; do tr "\`" "_" < $$file > .assets/`basename $$file`; done
|
||||
|
||||
underscore:
|
||||
$(MAKE) -C $@
|
||||
|
|
@ -1,871 +0,0 @@
|
|||
# otto
|
||||
--
|
||||
```go
|
||||
import "github.com/robertkrimen/otto"
|
||||
```
|
||||
|
||||
Package otto is a JavaScript parser and interpreter written natively in Go.
|
||||
|
||||
http://godoc.org/github.com/robertkrimen/otto
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/robertkrimen/otto"
|
||||
)
|
||||
```
|
||||
|
||||
Run something in the VM
|
||||
|
||||
```go
|
||||
vm := otto.New()
|
||||
vm.Run(`
|
||||
abc = 2 + 2;
|
||||
console.log("The value of abc is " + abc); // 4
|
||||
`)
|
||||
```
|
||||
|
||||
Get a value out of the VM
|
||||
|
||||
```go
|
||||
if value, err := vm.Get("abc"); err == nil {
|
||||
if value_int, err := value.ToInteger(); err == nil {
|
||||
fmt.Printf("", value_int, err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Set a number
|
||||
|
||||
```go
|
||||
vm.Set("def", 11)
|
||||
vm.Run(`
|
||||
console.log("The value of def is " + def);
|
||||
// The value of def is 11
|
||||
`)
|
||||
```
|
||||
|
||||
Set a string
|
||||
|
||||
```go
|
||||
vm.Set("xyzzy", "Nothing happens.")
|
||||
vm.Run(`
|
||||
console.log(xyzzy.length); // 16
|
||||
`)
|
||||
```
|
||||
|
||||
Get the value of an expression
|
||||
|
||||
```go
|
||||
value, _ = vm.Run("xyzzy.length")
|
||||
{
|
||||
// value is an int64 with a value of 16
|
||||
value, _ := value.ToInteger()
|
||||
}
|
||||
```
|
||||
|
||||
An error happens
|
||||
|
||||
```go
|
||||
value, err = vm.Run("abcdefghijlmnopqrstuvwxyz.length")
|
||||
if err != nil {
|
||||
// err = ReferenceError: abcdefghijlmnopqrstuvwxyz is not defined
|
||||
// If there is an error, then value.IsUndefined() is true
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Set a Go function
|
||||
|
||||
```go
|
||||
vm.Set("sayHello", func(call otto.FunctionCall) otto.Value {
|
||||
fmt.Printf("Hello, %s.\n", call.Argument(0).String())
|
||||
return otto.Value{}
|
||||
})
|
||||
```
|
||||
|
||||
Set a Go function that returns something useful
|
||||
|
||||
```go
|
||||
vm.Set("twoPlus", func(call otto.FunctionCall) otto.Value {
|
||||
right, _ := call.Argument(0).ToInteger()
|
||||
result, _ := vm.ToValue(2 + right)
|
||||
return result
|
||||
})
|
||||
```
|
||||
|
||||
Use the functions in JavaScript
|
||||
|
||||
```go
|
||||
result, _ = vm.Run(`
|
||||
sayHello("Xyzzy"); // Hello, Xyzzy.
|
||||
sayHello(); // Hello, undefined
|
||||
|
||||
result = twoPlus(2.0); // 4
|
||||
`)
|
||||
```
|
||||
|
||||
### Parser
|
||||
|
||||
A separate parser is available in the parser package if you're just interested
|
||||
in building an AST.
|
||||
|
||||
http://godoc.org/github.com/robertkrimen/otto/parser
|
||||
|
||||
Parse and return an AST
|
||||
|
||||
```go
|
||||
filename := "" // A filename is optional
|
||||
src := `
|
||||
// Sample xyzzy example
|
||||
(function(){
|
||||
if (3.14159 > 0) {
|
||||
console.log("Hello, World.");
|
||||
return;
|
||||
}
|
||||
|
||||
var xyzzy = NaN;
|
||||
console.log("Nothing happens.");
|
||||
return xyzzy;
|
||||
})();
|
||||
`
|
||||
|
||||
// Parse some JavaScript, yielding a *ast.Program and/or an ErrorList
|
||||
program, err := parser.ParseFile(nil, filename, src, 0)
|
||||
```
|
||||
|
||||
### otto
|
||||
|
||||
You can run (Go) JavaScript from the commandline with:
|
||||
http://github.com/robertkrimen/otto/tree/master/otto
|
||||
|
||||
$ go get -v github.com/robertkrimen/otto/otto
|
||||
|
||||
Run JavaScript by entering some source on stdin or by giving otto a filename:
|
||||
|
||||
$ otto example.js
|
||||
|
||||
### underscore
|
||||
|
||||
Optionally include the JavaScript utility-belt library, underscore, with this
|
||||
import:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/robertkrimen/otto"
|
||||
_ "github.com/robertkrimen/otto/underscore"
|
||||
)
|
||||
|
||||
// Now every otto runtime will come loaded with underscore
|
||||
```
|
||||
|
||||
For more information: http://github.com/robertkrimen/otto/tree/master/underscore
|
||||
|
||||
|
||||
### Caveat Emptor
|
||||
|
||||
The following are some limitations with otto:
|
||||
|
||||
* "use strict" will parse, but does nothing.
|
||||
* The regular expression engine (re2/regexp) is not fully compatible with the ECMA5 specification.
|
||||
* Otto targets ES5. ES6 features (eg: Typed Arrays) are not supported.
|
||||
|
||||
|
||||
### Regular Expression Incompatibility
|
||||
|
||||
Go translates JavaScript-style regular expressions into something that is
|
||||
"regexp" compatible via `parser.TransformRegExp`. Unfortunately, RegExp requires
|
||||
backtracking for some patterns, and backtracking is not supported by the
|
||||
standard Go engine: https://code.google.com/p/re2/wiki/Syntax
|
||||
|
||||
Therefore, the following syntax is incompatible:
|
||||
|
||||
(?=) // Lookahead (positive), currently a parsing error
|
||||
(?!) // Lookahead (backhead), currently a parsing error
|
||||
\1 // Backreference (\1, \2, \3, ...), currently a parsing error
|
||||
|
||||
A brief discussion of these limitations: "Regexp (?!re)"
|
||||
https://groups.google.com/forum/?fromgroups=#%21topic/golang-nuts/7qgSDWPIh_E
|
||||
|
||||
More information about re2: https://code.google.com/p/re2/
|
||||
|
||||
In addition to the above, re2 (Go) has a different definition for \s: [\t\n\f\r
|
||||
]. The JavaScript definition, on the other hand, also includes \v, Unicode
|
||||
"Separator, Space", etc.
|
||||
|
||||
|
||||
### Halting Problem
|
||||
|
||||
If you want to stop long running executions (like third-party code), you can use
|
||||
the interrupt channel to do this:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/robertkrimen/otto"
|
||||
)
|
||||
|
||||
var halt = errors.New("Stahp")
|
||||
|
||||
func main() {
|
||||
runUnsafe(`var abc = [];`)
|
||||
runUnsafe(`
|
||||
while (true) {
|
||||
// Loop forever
|
||||
}`)
|
||||
}
|
||||
|
||||
func runUnsafe(unsafe string) {
|
||||
start := time.Now()
|
||||
defer func() {
|
||||
duration := time.Since(start)
|
||||
if caught := recover(); caught != nil {
|
||||
if caught == halt {
|
||||
fmt.Fprintf(os.Stderr, "Some code took to long! Stopping after: %v\n", duration)
|
||||
return
|
||||
}
|
||||
panic(caught) // Something else happened, repanic!
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "Ran code successfully: %v\n", duration)
|
||||
}()
|
||||
|
||||
vm := otto.New()
|
||||
vm.Interrupt = make(chan func(), 1) // The buffer prevents blocking
|
||||
|
||||
go func() {
|
||||
time.Sleep(2 * time.Second) // Stop after two seconds
|
||||
vm.Interrupt <- func() {
|
||||
panic(halt)
|
||||
}
|
||||
}()
|
||||
|
||||
vm.Run(unsafe) // Here be dragons (risky code)
|
||||
}
|
||||
```
|
||||
|
||||
Where is setTimeout/setInterval?
|
||||
|
||||
These timing functions are not actually part of the ECMA-262 specification.
|
||||
Typically, they belong to the `window` object (in the browser). It would not be
|
||||
difficult to provide something like these via Go, but you probably want to wrap
|
||||
otto in an event loop in that case.
|
||||
|
||||
For an example of how this could be done in Go with otto, see natto:
|
||||
|
||||
http://github.com/robertkrimen/natto
|
||||
|
||||
Here is some more discussion of the issue:
|
||||
|
||||
* http://book.mixu.net/node/ch2.html
|
||||
|
||||
* http://en.wikipedia.org/wiki/Reentrancy_%28computing%29
|
||||
|
||||
* http://aaroncrane.co.uk/2009/02/perl_safe_signals/
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
var ErrVersion = errors.New("version mismatch")
|
||||
```
|
||||
|
||||
#### type Error
|
||||
|
||||
```go
|
||||
type Error struct {
|
||||
}
|
||||
```
|
||||
|
||||
An Error represents a runtime error, e.g. a TypeError, a ReferenceError, etc.
|
||||
|
||||
#### func (Error) Error
|
||||
|
||||
```go
|
||||
func (err Error) Error() string
|
||||
```
|
||||
Error returns a description of the error
|
||||
|
||||
TypeError: 'def' is not a function
|
||||
|
||||
#### func (Error) String
|
||||
|
||||
```go
|
||||
func (err Error) String() string
|
||||
```
|
||||
String returns a description of the error and a trace of where the error
|
||||
occurred.
|
||||
|
||||
TypeError: 'def' is not a function
|
||||
at xyz (<anonymous>:3:9)
|
||||
at <anonymous>:7:1/
|
||||
|
||||
#### type FunctionCall
|
||||
|
||||
```go
|
||||
type FunctionCall struct {
|
||||
This Value
|
||||
ArgumentList []Value
|
||||
Otto *Otto
|
||||
}
|
||||
```
|
||||
|
||||
FunctionCall is an encapsulation of a JavaScript function call.
|
||||
|
||||
#### func (FunctionCall) Argument
|
||||
|
||||
```go
|
||||
func (self FunctionCall) Argument(index int) Value
|
||||
```
|
||||
Argument will return the value of the argument at the given index.
|
||||
|
||||
If no such argument exists, undefined is returned.
|
||||
|
||||
#### type Object
|
||||
|
||||
```go
|
||||
type Object struct {
|
||||
}
|
||||
```
|
||||
|
||||
Object is the representation of a JavaScript object.
|
||||
|
||||
#### func (Object) Call
|
||||
|
||||
```go
|
||||
func (self Object) Call(name string, argumentList ...interface{}) (Value, error)
|
||||
```
|
||||
Call a method on the object.
|
||||
|
||||
It is essentially equivalent to:
|
||||
|
||||
var method, _ := object.Get(name)
|
||||
method.Call(object, argumentList...)
|
||||
|
||||
An undefined value and an error will result if:
|
||||
|
||||
1. There is an error during conversion of the argument list
|
||||
2. The property is not actually a function
|
||||
3. An (uncaught) exception is thrown
|
||||
|
||||
#### func (Object) Class
|
||||
|
||||
```go
|
||||
func (self Object) Class() string
|
||||
```
|
||||
Class will return the class string of the object.
|
||||
|
||||
The return value will (generally) be one of:
|
||||
|
||||
Object
|
||||
Function
|
||||
Array
|
||||
String
|
||||
Number
|
||||
Boolean
|
||||
Date
|
||||
RegExp
|
||||
|
||||
#### func (Object) Get
|
||||
|
||||
```go
|
||||
func (self Object) Get(name string) (Value, error)
|
||||
```
|
||||
Get the value of the property with the given name.
|
||||
|
||||
#### func (Object) Keys
|
||||
|
||||
```go
|
||||
func (self Object) Keys() []string
|
||||
```
|
||||
Get the keys for the object
|
||||
|
||||
Equivalent to calling Object.keys on the object
|
||||
|
||||
#### func (Object) Set
|
||||
|
||||
```go
|
||||
func (self Object) Set(name string, value interface{}) error
|
||||
```
|
||||
Set the property of the given name to the given value.
|
||||
|
||||
An error will result if the setting the property triggers an exception (i.e.
|
||||
read-only), or there is an error during conversion of the given value.
|
||||
|
||||
#### func (Object) Value
|
||||
|
||||
```go
|
||||
func (self Object) Value() Value
|
||||
```
|
||||
Value will return self as a value.
|
||||
|
||||
#### type Otto
|
||||
|
||||
```go
|
||||
type Otto struct {
|
||||
// Interrupt is a channel for interrupting the runtime. You can use this to halt a long running execution, for example.
|
||||
// See "Halting Problem" for more information.
|
||||
Interrupt chan func()
|
||||
}
|
||||
```
|
||||
|
||||
Otto is the representation of the JavaScript runtime. Each instance of Otto has
|
||||
a self-contained namespace.
|
||||
|
||||
#### func New
|
||||
|
||||
```go
|
||||
func New() *Otto
|
||||
```
|
||||
New will allocate a new JavaScript runtime
|
||||
|
||||
#### func Run
|
||||
|
||||
```go
|
||||
func Run(src interface{}) (*Otto, Value, error)
|
||||
```
|
||||
Run will allocate a new JavaScript runtime, run the given source on the
|
||||
allocated runtime, and return the runtime, resulting value, and error (if any).
|
||||
|
||||
src may be a string, a byte slice, a bytes.Buffer, or an io.Reader, but it MUST
|
||||
always be in UTF-8.
|
||||
|
||||
src may also be a Script.
|
||||
|
||||
src may also be a Program, but if the AST has been modified, then runtime
|
||||
behavior is undefined.
|
||||
|
||||
#### func (Otto) Call
|
||||
|
||||
```go
|
||||
func (self Otto) Call(source string, this interface{}, argumentList ...interface{}) (Value, error)
|
||||
```
|
||||
Call the given JavaScript with a given this and arguments.
|
||||
|
||||
If this is nil, then some special handling takes place to determine the proper
|
||||
this value, falling back to a "standard" invocation if necessary (where this is
|
||||
undefined).
|
||||
|
||||
If source begins with "new " (A lowercase new followed by a space), then Call
|
||||
will invoke the function constructor rather than performing a function call. In
|
||||
this case, the this argument has no effect.
|
||||
|
||||
```go
|
||||
// value is a String object
|
||||
value, _ := vm.Call("Object", nil, "Hello, World.")
|
||||
|
||||
// Likewise...
|
||||
value, _ := vm.Call("new Object", nil, "Hello, World.")
|
||||
|
||||
// This will perform a concat on the given array and return the result
|
||||
// value is [ 1, 2, 3, undefined, 4, 5, 6, 7, "abc" ]
|
||||
value, _ := vm.Call(`[ 1, 2, 3, undefined, 4 ].concat`, nil, 5, 6, 7, "abc")
|
||||
```
|
||||
|
||||
#### func (*Otto) Compile
|
||||
|
||||
```go
|
||||
func (self *Otto) Compile(filename string, src interface{}) (*Script, error)
|
||||
```
|
||||
Compile will parse the given source and return a Script value or nil and an
|
||||
error if there was a problem during compilation.
|
||||
|
||||
```go
|
||||
script, err := vm.Compile("", `var abc; if (!abc) abc = 0; abc += 2; abc;`)
|
||||
vm.Run(script)
|
||||
```
|
||||
|
||||
#### func (*Otto) Copy
|
||||
|
||||
```go
|
||||
func (in *Otto) Copy() *Otto
|
||||
```
|
||||
Copy will create a copy/clone of the runtime.
|
||||
|
||||
Copy is useful for saving some time when creating many similar runtimes.
|
||||
|
||||
This method works by walking the original runtime and cloning each object,
|
||||
scope, stash, etc. into a new runtime.
|
||||
|
||||
Be on the lookout for memory leaks or inadvertent sharing of resources.
|
||||
|
||||
#### func (Otto) Get
|
||||
|
||||
```go
|
||||
func (self Otto) Get(name string) (Value, error)
|
||||
```
|
||||
Get the value of the top-level binding of the given name.
|
||||
|
||||
If there is an error (like the binding does not exist), then the value will be
|
||||
undefined.
|
||||
|
||||
#### func (Otto) Object
|
||||
|
||||
```go
|
||||
func (self Otto) Object(source string) (*Object, error)
|
||||
```
|
||||
Object will run the given source and return the result as an object.
|
||||
|
||||
For example, accessing an existing object:
|
||||
|
||||
```go
|
||||
object, _ := vm.Object(`Number`)
|
||||
```
|
||||
|
||||
Or, creating a new object:
|
||||
|
||||
```go
|
||||
object, _ := vm.Object(`({ xyzzy: "Nothing happens." })`)
|
||||
```
|
||||
|
||||
Or, creating and assigning an object:
|
||||
|
||||
```go
|
||||
object, _ := vm.Object(`xyzzy = {}`)
|
||||
object.Set("volume", 11)
|
||||
```
|
||||
|
||||
If there is an error (like the source does not result in an object), then nil
|
||||
and an error is returned.
|
||||
|
||||
#### func (Otto) Run
|
||||
|
||||
```go
|
||||
func (self Otto) Run(src interface{}) (Value, error)
|
||||
```
|
||||
Run will run the given source (parsing it first if necessary), returning the
|
||||
resulting value and error (if any)
|
||||
|
||||
src may be a string, a byte slice, a bytes.Buffer, or an io.Reader, but it MUST
|
||||
always be in UTF-8.
|
||||
|
||||
If the runtime is unable to parse source, then this function will return
|
||||
undefined and the parse error (nothing will be evaluated in this case).
|
||||
|
||||
src may also be a Script.
|
||||
|
||||
src may also be a Program, but if the AST has been modified, then runtime
|
||||
behavior is undefined.
|
||||
|
||||
#### func (Otto) Set
|
||||
|
||||
```go
|
||||
func (self Otto) Set(name string, value interface{}) error
|
||||
```
|
||||
Set the top-level binding of the given name to the given value.
|
||||
|
||||
Set will automatically apply ToValue to the given value in order to convert it
|
||||
to a JavaScript value (type Value).
|
||||
|
||||
If there is an error (like the binding is read-only, or the ToValue conversion
|
||||
fails), then an error is returned.
|
||||
|
||||
If the top-level binding does not exist, it will be created.
|
||||
|
||||
#### func (Otto) ToValue
|
||||
|
||||
```go
|
||||
func (self Otto) ToValue(value interface{}) (Value, error)
|
||||
```
|
||||
ToValue will convert an interface{} value to a value digestible by
|
||||
otto/JavaScript.
|
||||
|
||||
#### type Script
|
||||
|
||||
```go
|
||||
type Script struct {
|
||||
}
|
||||
```
|
||||
|
||||
Script is a handle for some (reusable) JavaScript. Passing a Script value to a
|
||||
run method will evaluate the JavaScript.
|
||||
|
||||
#### func (*Script) String
|
||||
|
||||
```go
|
||||
func (self *Script) String() string
|
||||
```
|
||||
|
||||
#### type Value
|
||||
|
||||
```go
|
||||
type Value struct {
|
||||
}
|
||||
```
|
||||
|
||||
Value is the representation of a JavaScript value.
|
||||
|
||||
#### func FalseValue
|
||||
|
||||
```go
|
||||
func FalseValue() Value
|
||||
```
|
||||
FalseValue will return a value representing false.
|
||||
|
||||
It is equivalent to:
|
||||
|
||||
```go
|
||||
ToValue(false)
|
||||
```
|
||||
|
||||
#### func NaNValue
|
||||
|
||||
```go
|
||||
func NaNValue() Value
|
||||
```
|
||||
NaNValue will return a value representing NaN.
|
||||
|
||||
It is equivalent to:
|
||||
|
||||
```go
|
||||
ToValue(math.NaN())
|
||||
```
|
||||
|
||||
#### func NullValue
|
||||
|
||||
```go
|
||||
func NullValue() Value
|
||||
```
|
||||
NullValue will return a Value representing null.
|
||||
|
||||
#### func ToValue
|
||||
|
||||
```go
|
||||
func ToValue(value interface{}) (Value, error)
|
||||
```
|
||||
ToValue will convert an interface{} value to a value digestible by
|
||||
otto/JavaScript
|
||||
|
||||
This function will not work for advanced types (struct, map, slice/array, etc.)
|
||||
and you should use Otto.ToValue instead.
|
||||
|
||||
#### func TrueValue
|
||||
|
||||
```go
|
||||
func TrueValue() Value
|
||||
```
|
||||
TrueValue will return a value representing true.
|
||||
|
||||
It is equivalent to:
|
||||
|
||||
```go
|
||||
ToValue(true)
|
||||
```
|
||||
|
||||
#### func UndefinedValue
|
||||
|
||||
```go
|
||||
func UndefinedValue() Value
|
||||
```
|
||||
UndefinedValue will return a Value representing undefined.
|
||||
|
||||
#### func (Value) Call
|
||||
|
||||
```go
|
||||
func (value Value) Call(this Value, argumentList ...interface{}) (Value, error)
|
||||
```
|
||||
Call the value as a function with the given this value and argument list and
|
||||
return the result of invocation. It is essentially equivalent to:
|
||||
|
||||
value.apply(thisValue, argumentList)
|
||||
|
||||
An undefined value and an error will result if:
|
||||
|
||||
1. There is an error during conversion of the argument list
|
||||
2. The value is not actually a function
|
||||
3. An (uncaught) exception is thrown
|
||||
|
||||
#### func (Value) Class
|
||||
|
||||
```go
|
||||
func (value Value) Class() string
|
||||
```
|
||||
Class will return the class string of the value or the empty string if value is
|
||||
not an object.
|
||||
|
||||
The return value will (generally) be one of:
|
||||
|
||||
Object
|
||||
Function
|
||||
Array
|
||||
String
|
||||
Number
|
||||
Boolean
|
||||
Date
|
||||
RegExp
|
||||
|
||||
#### func (Value) Export
|
||||
|
||||
```go
|
||||
func (self Value) Export() (interface{}, error)
|
||||
```
|
||||
Export will attempt to convert the value to a Go representation and return it
|
||||
via an interface{} kind.
|
||||
|
||||
Export returns an error, but it will always be nil. It is present for backwards
|
||||
compatibility.
|
||||
|
||||
If a reasonable conversion is not possible, then the original value is returned.
|
||||
|
||||
undefined -> nil (FIXME?: Should be Value{})
|
||||
null -> nil
|
||||
boolean -> bool
|
||||
number -> A number type (int, float32, uint64, ...)
|
||||
string -> string
|
||||
Array -> []interface{}
|
||||
Object -> map[string]interface{}
|
||||
|
||||
#### func (Value) IsBoolean
|
||||
|
||||
```go
|
||||
func (value Value) IsBoolean() bool
|
||||
```
|
||||
IsBoolean will return true if value is a boolean (primitive).
|
||||
|
||||
#### func (Value) IsDefined
|
||||
|
||||
```go
|
||||
func (value Value) IsDefined() bool
|
||||
```
|
||||
IsDefined will return false if the value is undefined, and true otherwise.
|
||||
|
||||
#### func (Value) IsFunction
|
||||
|
||||
```go
|
||||
func (value Value) IsFunction() bool
|
||||
```
|
||||
IsFunction will return true if value is a function.
|
||||
|
||||
#### func (Value) IsNaN
|
||||
|
||||
```go
|
||||
func (value Value) IsNaN() bool
|
||||
```
|
||||
IsNaN will return true if value is NaN (or would convert to NaN).
|
||||
|
||||
#### func (Value) IsNull
|
||||
|
||||
```go
|
||||
func (value Value) IsNull() bool
|
||||
```
|
||||
IsNull will return true if the value is null, and false otherwise.
|
||||
|
||||
#### func (Value) IsNumber
|
||||
|
||||
```go
|
||||
func (value Value) IsNumber() bool
|
||||
```
|
||||
IsNumber will return true if value is a number (primitive).
|
||||
|
||||
#### func (Value) IsObject
|
||||
|
||||
```go
|
||||
func (value Value) IsObject() bool
|
||||
```
|
||||
IsObject will return true if value is an object.
|
||||
|
||||
#### func (Value) IsPrimitive
|
||||
|
||||
```go
|
||||
func (value Value) IsPrimitive() bool
|
||||
```
|
||||
IsPrimitive will return true if value is a primitive (any kind of primitive).
|
||||
|
||||
#### func (Value) IsString
|
||||
|
||||
```go
|
||||
func (value Value) IsString() bool
|
||||
```
|
||||
IsString will return true if value is a string (primitive).
|
||||
|
||||
#### func (Value) IsUndefined
|
||||
|
||||
```go
|
||||
func (value Value) IsUndefined() bool
|
||||
```
|
||||
IsUndefined will return true if the value is undefined, and false otherwise.
|
||||
|
||||
#### func (Value) Object
|
||||
|
||||
```go
|
||||
func (value Value) Object() *Object
|
||||
```
|
||||
Object will return the object of the value, or nil if value is not an object.
|
||||
|
||||
This method will not do any implicit conversion. For example, calling this
|
||||
method on a string primitive value will not return a String object.
|
||||
|
||||
#### func (Value) String
|
||||
|
||||
```go
|
||||
func (value Value) String() string
|
||||
```
|
||||
String will return the value as a string.
|
||||
|
||||
This method will make return the empty string if there is an error.
|
||||
|
||||
#### func (Value) ToBoolean
|
||||
|
||||
```go
|
||||
func (value Value) ToBoolean() (bool, error)
|
||||
```
|
||||
ToBoolean will convert the value to a boolean (bool).
|
||||
|
||||
ToValue(0).ToBoolean() => false
|
||||
ToValue("").ToBoolean() => false
|
||||
ToValue(true).ToBoolean() => true
|
||||
ToValue(1).ToBoolean() => true
|
||||
ToValue("Nothing happens").ToBoolean() => true
|
||||
|
||||
If there is an error during the conversion process (like an uncaught exception),
|
||||
then the result will be false and an error.
|
||||
|
||||
#### func (Value) ToFloat
|
||||
|
||||
```go
|
||||
func (value Value) ToFloat() (float64, error)
|
||||
```
|
||||
ToFloat will convert the value to a number (float64).
|
||||
|
||||
ToValue(0).ToFloat() => 0.
|
||||
ToValue(1.1).ToFloat() => 1.1
|
||||
ToValue("11").ToFloat() => 11.
|
||||
|
||||
If there is an error during the conversion process (like an uncaught exception),
|
||||
then the result will be 0 and an error.
|
||||
|
||||
#### func (Value) ToInteger
|
||||
|
||||
```go
|
||||
func (value Value) ToInteger() (int64, error)
|
||||
```
|
||||
ToInteger will convert the value to a number (int64).
|
||||
|
||||
ToValue(0).ToInteger() => 0
|
||||
ToValue(1.1).ToInteger() => 1
|
||||
ToValue("11").ToInteger() => 11
|
||||
|
||||
If there is an error during the conversion process (like an uncaught exception),
|
||||
then the result will be 0 and an error.
|
||||
|
||||
#### func (Value) ToString
|
||||
|
||||
```go
|
||||
func (value Value) ToString() (string, error)
|
||||
```
|
||||
ToString will convert the value to a string (string).
|
||||
|
||||
ToValue(0).ToString() => "0"
|
||||
ToValue(false).ToString() => "false"
|
||||
ToValue(1.1).ToString() => "1.1"
|
||||
ToValue("11").ToString() => "11"
|
||||
ToValue('Nothing happens.').ToString() => "Nothing happens."
|
||||
|
||||
If there is an error during the conversion process (like an uncaught exception),
|
||||
then the result will be the empty string ("") and an error.
|
||||
|
||||
--
|
||||
**godocdown** http://github.com/robertkrimen/godocdown
|
File diff suppressed because it is too large
Load Diff
|
@ -1,110 +0,0 @@
|
|||
# file
|
||||
--
|
||||
import "github.com/robertkrimen/otto/file"
|
||||
|
||||
Package file encapsulates the file abstractions used by the ast & parser.
|
||||
|
||||
## Usage
|
||||
|
||||
#### type File
|
||||
|
||||
```go
|
||||
type File struct {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### func NewFile
|
||||
|
||||
```go
|
||||
func NewFile(filename, src string, base int) *File
|
||||
```
|
||||
|
||||
#### func (*File) Base
|
||||
|
||||
```go
|
||||
func (fl *File) Base() int
|
||||
```
|
||||
|
||||
#### func (*File) Name
|
||||
|
||||
```go
|
||||
func (fl *File) Name() string
|
||||
```
|
||||
|
||||
#### func (*File) Source
|
||||
|
||||
```go
|
||||
func (fl *File) Source() string
|
||||
```
|
||||
|
||||
#### type FileSet
|
||||
|
||||
```go
|
||||
type FileSet struct {
|
||||
}
|
||||
```
|
||||
|
||||
A FileSet represents a set of source files.
|
||||
|
||||
#### func (*FileSet) AddFile
|
||||
|
||||
```go
|
||||
func (self *FileSet) AddFile(filename, src string) int
|
||||
```
|
||||
AddFile adds a new file with the given filename and src.
|
||||
|
||||
This an internal method, but exported for cross-package use.
|
||||
|
||||
#### func (*FileSet) File
|
||||
|
||||
```go
|
||||
func (self *FileSet) File(idx Idx) *File
|
||||
```
|
||||
|
||||
#### func (*FileSet) Position
|
||||
|
||||
```go
|
||||
func (self *FileSet) Position(idx Idx) *Position
|
||||
```
|
||||
Position converts an Idx in the FileSet into a Position.
|
||||
|
||||
#### type Idx
|
||||
|
||||
```go
|
||||
type Idx int
|
||||
```
|
||||
|
||||
Idx is a compact encoding of a source position within a file set. It can be
|
||||
converted into a Position for a more convenient, but much larger,
|
||||
representation.
|
||||
|
||||
#### type Position
|
||||
|
||||
```go
|
||||
type Position struct {
|
||||
Filename string // The filename where the error occurred, if any
|
||||
Offset int // The src offset
|
||||
Line int // The line number, starting at 1
|
||||
Column int // The column number, starting at 1 (The character count)
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Position describes an arbitrary source position including the filename, line,
|
||||
and column location.
|
||||
|
||||
#### func (*Position) String
|
||||
|
||||
```go
|
||||
func (self *Position) String() string
|
||||
```
|
||||
String returns a string in one of several forms:
|
||||
|
||||
file:line:column A valid position with filename
|
||||
line:column A valid position without filename
|
||||
file An invalid position with filename
|
||||
- An invalid position without filename
|
||||
|
||||
--
|
||||
**godocdown** http://github.com/robertkrimen/godocdown
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +0,0 @@
|
|||
.PHONY: test
|
||||
|
||||
test:
|
||||
go test
|
|
@ -1,190 +0,0 @@
|
|||
# parser
|
||||
--
|
||||
import "github.com/robertkrimen/otto/parser"
|
||||
|
||||
Package parser implements a parser for JavaScript.
|
||||
|
||||
import (
|
||||
"github.com/robertkrimen/otto/parser"
|
||||
)
|
||||
|
||||
Parse and return an AST
|
||||
|
||||
filename := "" // A filename is optional
|
||||
src := `
|
||||
// Sample xyzzy example
|
||||
(function(){
|
||||
if (3.14159 > 0) {
|
||||
console.log("Hello, World.");
|
||||
return;
|
||||
}
|
||||
|
||||
var xyzzy = NaN;
|
||||
console.log("Nothing happens.");
|
||||
return xyzzy;
|
||||
})();
|
||||
`
|
||||
|
||||
// Parse some JavaScript, yielding a *ast.Program and/or an ErrorList
|
||||
program, err := parser.ParseFile(nil, filename, src, 0)
|
||||
|
||||
|
||||
### Warning
|
||||
|
||||
The parser and AST interfaces are still works-in-progress (particularly where
|
||||
node types are concerned) and may change in the future.
|
||||
|
||||
## Usage
|
||||
|
||||
#### func ParseFile
|
||||
|
||||
```go
|
||||
func ParseFile(fileSet *file.FileSet, filename string, src interface{}, mode Mode) (*ast.Program, error)
|
||||
```
|
||||
ParseFile parses the source code of a single JavaScript/ECMAScript source file
|
||||
and returns the corresponding ast.Program node.
|
||||
|
||||
If fileSet == nil, ParseFile parses source without a FileSet. If fileSet != nil,
|
||||
ParseFile first adds filename and src to fileSet.
|
||||
|
||||
The filename argument is optional and is used for labelling errors, etc.
|
||||
|
||||
src may be a string, a byte slice, a bytes.Buffer, or an io.Reader, but it MUST
|
||||
always be in UTF-8.
|
||||
|
||||
// Parse some JavaScript, yielding a *ast.Program and/or an ErrorList
|
||||
program, err := parser.ParseFile(nil, "", `if (abc > 1) {}`, 0)
|
||||
|
||||
#### func ParseFunction
|
||||
|
||||
```go
|
||||
func ParseFunction(parameterList, body string) (*ast.FunctionLiteral, error)
|
||||
```
|
||||
ParseFunction parses a given parameter list and body as a function and returns
|
||||
the corresponding ast.FunctionLiteral node.
|
||||
|
||||
The parameter list, if any, should be a comma-separated list of identifiers.
|
||||
|
||||
#### func ReadSource
|
||||
|
||||
```go
|
||||
func ReadSource(filename string, src interface{}) ([]byte, error)
|
||||
```
|
||||
|
||||
#### func TransformRegExp
|
||||
|
||||
```go
|
||||
func TransformRegExp(pattern string) (string, error)
|
||||
```
|
||||
TransformRegExp transforms a JavaScript pattern into a Go "regexp" pattern.
|
||||
|
||||
re2 (Go) cannot do backtracking, so the presence of a lookahead (?=) (?!) or
|
||||
backreference (\1, \2, ...) will cause an error.
|
||||
|
||||
re2 (Go) has a different definition for \s: [\t\n\f\r ]. The JavaScript
|
||||
definition, on the other hand, also includes \v, Unicode "Separator, Space",
|
||||
etc.
|
||||
|
||||
If the pattern is invalid (not valid even in JavaScript), then this function
|
||||
returns the empty string and an error.
|
||||
|
||||
If the pattern is valid, but incompatible (contains a lookahead or
|
||||
backreference), then this function returns the transformation (a non-empty
|
||||
string) AND an error.
|
||||
|
||||
#### type Error
|
||||
|
||||
```go
|
||||
type Error struct {
|
||||
Position file.Position
|
||||
Message string
|
||||
}
|
||||
```
|
||||
|
||||
An Error represents a parsing error. It includes the position where the error
|
||||
occurred and a message/description.
|
||||
|
||||
#### func (Error) Error
|
||||
|
||||
```go
|
||||
func (self Error) Error() string
|
||||
```
|
||||
|
||||
#### type ErrorList
|
||||
|
||||
```go
|
||||
type ErrorList []*Error
|
||||
```
|
||||
|
||||
ErrorList is a list of *Errors.
|
||||
|
||||
#### func (*ErrorList) Add
|
||||
|
||||
```go
|
||||
func (self *ErrorList) Add(position file.Position, msg string)
|
||||
```
|
||||
Add adds an Error with given position and message to an ErrorList.
|
||||
|
||||
#### func (ErrorList) Err
|
||||
|
||||
```go
|
||||
func (self ErrorList) Err() error
|
||||
```
|
||||
Err returns an error equivalent to this ErrorList. If the list is empty, Err
|
||||
returns nil.
|
||||
|
||||
#### func (ErrorList) Error
|
||||
|
||||
```go
|
||||
func (self ErrorList) Error() string
|
||||
```
|
||||
Error implements the Error interface.
|
||||
|
||||
#### func (ErrorList) Len
|
||||
|
||||
```go
|
||||
func (self ErrorList) Len() int
|
||||
```
|
||||
|
||||
#### func (ErrorList) Less
|
||||
|
||||
```go
|
||||
func (self ErrorList) Less(i, j int) bool
|
||||
```
|
||||
|
||||
#### func (*ErrorList) Reset
|
||||
|
||||
```go
|
||||
func (self *ErrorList) Reset()
|
||||
```
|
||||
Reset resets an ErrorList to no errors.
|
||||
|
||||
#### func (ErrorList) Sort
|
||||
|
||||
```go
|
||||
func (self ErrorList) Sort()
|
||||
```
|
||||
|
||||
#### func (ErrorList) Swap
|
||||
|
||||
```go
|
||||
func (self ErrorList) Swap(i, j int)
|
||||
```
|
||||
|
||||
#### type Mode
|
||||
|
||||
```go
|
||||
type Mode uint
|
||||
```
|
||||
|
||||
A Mode value is a set of flags (or 0). They control optional parser
|
||||
functionality.
|
||||
|
||||
```go
|
||||
const (
|
||||
IgnoreRegExpErrors Mode = 1 << iota // Ignore RegExp compatibility errors (allow backtracking)
|
||||
)
|
||||
```
|
||||
|
||||
--
|
||||
**godocdown** http://github.com/robertkrimen/godocdown
|
|
@ -1,51 +0,0 @@
|
|||
# registry
|
||||
--
|
||||
import "github.com/robertkrimen/otto/registry"
|
||||
|
||||
Package registry is an expirmental package to facillitate altering the otto
|
||||
runtime via import.
|
||||
|
||||
This interface can change at any time.
|
||||
|
||||
## Usage
|
||||
|
||||
#### func Apply
|
||||
|
||||
```go
|
||||
func Apply(callback func(Entry))
|
||||
```
|
||||
|
||||
#### type Entry
|
||||
|
||||
```go
|
||||
type Entry struct {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### func Register
|
||||
|
||||
```go
|
||||
func Register(source func() string) *Entry
|
||||
```
|
||||
|
||||
#### func (*Entry) Disable
|
||||
|
||||
```go
|
||||
func (self *Entry) Disable()
|
||||
```
|
||||
|
||||
#### func (*Entry) Enable
|
||||
|
||||
```go
|
||||
func (self *Entry) Enable()
|
||||
```
|
||||
|
||||
#### func (Entry) Source
|
||||
|
||||
```go
|
||||
func (self Entry) Source() string
|
||||
```
|
||||
|
||||
--
|
||||
**godocdown** http://github.com/robertkrimen/godocdown
|
|
@ -1,2 +0,0 @@
|
|||
token_const.go: tokenfmt
|
||||
./$^ | gofmt > $@
|
|
@ -1,171 +0,0 @@
|
|||
# token
|
||||
--
|
||||
import "github.com/robertkrimen/otto/token"
|
||||
|
||||
Package token defines constants representing the lexical tokens of JavaScript
|
||||
(ECMA5).
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
const (
|
||||
ILLEGAL
|
||||
EOF
|
||||
COMMENT
|
||||
KEYWORD
|
||||
|
||||
STRING
|
||||
BOOLEAN
|
||||
NULL
|
||||
NUMBER
|
||||
IDENTIFIER
|
||||
|
||||
PLUS // +
|
||||
MINUS // -
|
||||
MULTIPLY // *
|
||||
SLASH // /
|
||||
REMAINDER // %
|
||||
|
||||
AND // &
|
||||
OR // |
|
||||
EXCLUSIVE_OR // ^
|
||||
SHIFT_LEFT // <<
|
||||
SHIFT_RIGHT // >>
|
||||
UNSIGNED_SHIFT_RIGHT // >>>
|
||||
AND_NOT // &^
|
||||
|
||||
ADD_ASSIGN // +=
|
||||
SUBTRACT_ASSIGN // -=
|
||||
MULTIPLY_ASSIGN // *=
|
||||
QUOTIENT_ASSIGN // /=
|
||||
REMAINDER_ASSIGN // %=
|
||||
|
||||
AND_ASSIGN // &=
|
||||
OR_ASSIGN // |=
|
||||
EXCLUSIVE_OR_ASSIGN // ^=
|
||||
SHIFT_LEFT_ASSIGN // <<=
|
||||
SHIFT_RIGHT_ASSIGN // >>=
|
||||
UNSIGNED_SHIFT_RIGHT_ASSIGN // >>>=
|
||||
AND_NOT_ASSIGN // &^=
|
||||
|
||||
LOGICAL_AND // &&
|
||||
LOGICAL_OR // ||
|
||||
INCREMENT // ++
|
||||
DECREMENT // --
|
||||
|
||||
EQUAL // ==
|
||||
STRICT_EQUAL // ===
|
||||
LESS // <
|
||||
GREATER // >
|
||||
ASSIGN // =
|
||||
NOT // !
|
||||
|
||||
BITWISE_NOT // ~
|
||||
|
||||
NOT_EQUAL // !=
|
||||
STRICT_NOT_EQUAL // !==
|
||||
LESS_OR_EQUAL // <=
|
||||
GREATER_OR_EQUAL // >=
|
||||
|
||||
LEFT_PARENTHESIS // (
|
||||
LEFT_BRACKET // [
|
||||
LEFT_BRACE // {
|
||||
COMMA // ,
|
||||
PERIOD // .
|
||||
|
||||
RIGHT_PARENTHESIS // )
|
||||
RIGHT_BRACKET // ]
|
||||
RIGHT_BRACE // }
|
||||
SEMICOLON // ;
|
||||
COLON // :
|
||||
QUESTION_MARK // ?
|
||||
|
||||
IF
|
||||
IN
|
||||
DO
|
||||
|
||||
VAR
|
||||
FOR
|
||||
NEW
|
||||
TRY
|
||||
|
||||
THIS
|
||||
ELSE
|
||||
CASE
|
||||
VOID
|
||||
WITH
|
||||
|
||||
WHILE
|
||||
BREAK
|
||||
CATCH
|
||||
THROW
|
||||
|
||||
RETURN
|
||||
TYPEOF
|
||||
DELETE
|
||||
SWITCH
|
||||
|
||||
DEFAULT
|
||||
FINALLY
|
||||
|
||||
FUNCTION
|
||||
CONTINUE
|
||||
DEBUGGER
|
||||
|
||||
INSTANCEOF
|
||||
)
|
||||
```
|
||||
|
||||
#### type Token
|
||||
|
||||
```go
|
||||
type Token int
|
||||
```
|
||||
|
||||
Token is the set of lexical tokens in JavaScript (ECMA5).
|
||||
|
||||
#### func IsKeyword
|
||||
|
||||
```go
|
||||
func IsKeyword(literal string) (Token, bool)
|
||||
```
|
||||
IsKeyword returns the keyword token if literal is a keyword, a KEYWORD token if
|
||||
the literal is a future keyword (const, let, class, super, ...), or 0 if the
|
||||
literal is not a keyword.
|
||||
|
||||
If the literal is a keyword, IsKeyword returns a second value indicating if the
|
||||
literal is considered a future keyword in strict-mode only.
|
||||
|
||||
7.6.1.2 Future Reserved Words:
|
||||
|
||||
const
|
||||
class
|
||||
enum
|
||||
export
|
||||
extends
|
||||
import
|
||||
super
|
||||
|
||||
7.6.1.2 Future Reserved Words (strict):
|
||||
|
||||
implements
|
||||
interface
|
||||
let
|
||||
package
|
||||
private
|
||||
protected
|
||||
public
|
||||
static
|
||||
|
||||
#### func (Token) String
|
||||
|
||||
```go
|
||||
func (tkn Token) String() string
|
||||
```
|
||||
String returns the string corresponding to the token. For operators, delimiters,
|
||||
and keywords the string is the actual token string (e.g., for the token PLUS,
|
||||
the String() is "+"). For all other tokens the string corresponds to the token
|
||||
name (e.g. for the token IDENTIFIER, the string is "IDENTIFIER").
|
||||
|
||||
--
|
||||
**godocdown** http://github.com/robertkrimen/godocdown
|
|
@ -1,222 +0,0 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my (%token, @order, @keywords);
|
||||
|
||||
{
|
||||
my $keywords;
|
||||
my @const;
|
||||
push @const, <<_END_;
|
||||
package token
|
||||
|
||||
const(
|
||||
_ Token = iota
|
||||
_END_
|
||||
|
||||
for (split m/\n/, <<_END_) {
|
||||
ILLEGAL
|
||||
EOF
|
||||
COMMENT
|
||||
KEYWORD
|
||||
|
||||
STRING
|
||||
BOOLEAN
|
||||
NULL
|
||||
NUMBER
|
||||
IDENTIFIER
|
||||
|
||||
PLUS +
|
||||
MINUS -
|
||||
MULTIPLY *
|
||||
SLASH /
|
||||
REMAINDER %
|
||||
|
||||
AND &
|
||||
OR |
|
||||
EXCLUSIVE_OR ^
|
||||
SHIFT_LEFT <<
|
||||
SHIFT_RIGHT >>
|
||||
UNSIGNED_SHIFT_RIGHT >>>
|
||||
AND_NOT &^
|
||||
|
||||
ADD_ASSIGN +=
|
||||
SUBTRACT_ASSIGN -=
|
||||
MULTIPLY_ASSIGN *=
|
||||
QUOTIENT_ASSIGN /=
|
||||
REMAINDER_ASSIGN %=
|
||||
|
||||
AND_ASSIGN &=
|
||||
OR_ASSIGN |=
|
||||
EXCLUSIVE_OR_ASSIGN ^=
|
||||
SHIFT_LEFT_ASSIGN <<=
|
||||
SHIFT_RIGHT_ASSIGN >>=
|
||||
UNSIGNED_SHIFT_RIGHT_ASSIGN >>>=
|
||||
AND_NOT_ASSIGN &^=
|
||||
|
||||
LOGICAL_AND &&
|
||||
LOGICAL_OR ||
|
||||
INCREMENT ++
|
||||
DECREMENT --
|
||||
|
||||
EQUAL ==
|
||||
STRICT_EQUAL ===
|
||||
LESS <
|
||||
GREATER >
|
||||
ASSIGN =
|
||||
NOT !
|
||||
|
||||
BITWISE_NOT ~
|
||||
|
||||
NOT_EQUAL !=
|
||||
STRICT_NOT_EQUAL !==
|
||||
LESS_OR_EQUAL <=
|
||||
GREATER_OR_EQUAL <=
|
||||
|
||||
LEFT_PARENTHESIS (
|
||||
LEFT_BRACKET [
|
||||
LEFT_BRACE {
|
||||
COMMA ,
|
||||
PERIOD .
|
||||
|
||||
RIGHT_PARENTHESIS )
|
||||
RIGHT_BRACKET ]
|
||||
RIGHT_BRACE }
|
||||
SEMICOLON ;
|
||||
COLON :
|
||||
QUESTION_MARK ?
|
||||
|
||||
firstKeyword
|
||||
IF
|
||||
IN
|
||||
DO
|
||||
|
||||
VAR
|
||||
FOR
|
||||
NEW
|
||||
TRY
|
||||
|
||||
THIS
|
||||
ELSE
|
||||
CASE
|
||||
VOID
|
||||
WITH
|
||||
|
||||
WHILE
|
||||
BREAK
|
||||
CATCH
|
||||
THROW
|
||||
|
||||
RETURN
|
||||
TYPEOF
|
||||
DELETE
|
||||
SWITCH
|
||||
|
||||
DEFAULT
|
||||
FINALLY
|
||||
|
||||
FUNCTION
|
||||
CONTINUE
|
||||
DEBUGGER
|
||||
|
||||
INSTANCEOF
|
||||
lastKeyword
|
||||
_END_
|
||||
chomp;
|
||||
|
||||
next if m/^\s*#/;
|
||||
|
||||
my ($name, $symbol) = m/(\w+)\s*(\S+)?/;
|
||||
|
||||
if (defined $symbol) {
|
||||
push @order, $name;
|
||||
push @const, "$name // $symbol";
|
||||
$token{$name} = $symbol;
|
||||
} elsif (defined $name) {
|
||||
$keywords ||= $name eq 'firstKeyword';
|
||||
|
||||
push @const, $name;
|
||||
#$const[-1] .= " Token = iota" if 2 == @const;
|
||||
if ($name =~ m/^([A-Z]+)/) {
|
||||
push @keywords, $name if $keywords;
|
||||
push @order, $name;
|
||||
if ($token{SEMICOLON}) {
|
||||
$token{$name} = lc $1;
|
||||
} else {
|
||||
$token{$name} = $name;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
push @const, "";
|
||||
}
|
||||
|
||||
}
|
||||
push @const, ")";
|
||||
print join "\n", @const, "";
|
||||
}
|
||||
|
||||
{
|
||||
print <<_END_;
|
||||
|
||||
var token2string = [...]string{
|
||||
_END_
|
||||
for my $name (@order) {
|
||||
print "$name: \"$token{$name}\",\n";
|
||||
}
|
||||
print <<_END_;
|
||||
}
|
||||
_END_
|
||||
|
||||
print <<_END_;
|
||||
|
||||
var keywordTable = map[string]_keyword{
|
||||
_END_
|
||||
for my $name (@keywords) {
|
||||
print <<_END_
|
||||
"@{[ lc $name ]}": _keyword{
|
||||
token: $name,
|
||||
},
|
||||
_END_
|
||||
}
|
||||
|
||||
for my $name (qw/
|
||||
const
|
||||
class
|
||||
enum
|
||||
export
|
||||
extends
|
||||
import
|
||||
super
|
||||
/) {
|
||||
print <<_END_
|
||||
"$name": _keyword{
|
||||
token: KEYWORD,
|
||||
futureKeyword: true,
|
||||
},
|
||||
_END_
|
||||
}
|
||||
|
||||
for my $name (qw/
|
||||
implements
|
||||
interface
|
||||
let
|
||||
package
|
||||
private
|
||||
protected
|
||||
public
|
||||
static
|
||||
/) {
|
||||
print <<_END_
|
||||
"$name": _keyword{
|
||||
token: KEYWORD,
|
||||
futureKeyword: true,
|
||||
strict: true,
|
||||
},
|
||||
_END_
|
||||
}
|
||||
|
||||
print <<_END_;
|
||||
}
|
||||
_END_
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
language: go
|
||||
go:
|
||||
- 1.3
|
||||
- 1.4
|
|
@ -1,99 +0,0 @@
|
|||
# Go CORS handler [![godoc](http://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://godoc.org/github.com/rs/cors) [![license](http://img.shields.io/badge/license-MIT-red.svg?style=flat)](https://raw.githubusercontent.com/rs/cors/master/LICENSE) [![build](https://img.shields.io/travis/rs/cors.svg?style=flat)](https://travis-ci.org/rs/cors) [![Coverage](http://gocover.io/_badge/github.com/rs/cors)](http://gocover.io/github.com/rs/cors)
|
||||
|
||||
CORS is a `net/http` handler implementing [Cross Origin Resource Sharing W3 specification](http://www.w3.org/TR/cors/) in Golang.
|
||||
|
||||
## Getting Started
|
||||
|
||||
After installing Go and setting up your [GOPATH](http://golang.org/doc/code.html#GOPATH), create your first `.go` file. We'll call it `server.go`.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/rs/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write([]byte("{\"hello\": \"world\"}"))
|
||||
})
|
||||
|
||||
// cors.Default() setup the middleware with default options being
|
||||
// all origins accepted with simple methods (GET, POST). See
|
||||
// documentation below for more options.
|
||||
handler := cors.Default().Handler(mux)
|
||||
http.ListenAndServe(":8080", handler)
|
||||
}
|
||||
```
|
||||
|
||||
Install `cors`:
|
||||
|
||||
go get github.com/rs/cors
|
||||
|
||||
Then run your server:
|
||||
|
||||
go run server.go
|
||||
|
||||
The server now runs on `localhost:8080`:
|
||||
|
||||
$ curl -D - -H 'Origin: http://foo.com' http://localhost:8080/
|
||||
HTTP/1.1 200 OK
|
||||
Access-Control-Allow-Origin: foo.com
|
||||
Content-Type: application/json
|
||||
Date: Sat, 25 Oct 2014 03:43:57 GMT
|
||||
Content-Length: 18
|
||||
|
||||
{"hello": "world"}
|
||||
|
||||
### More Examples
|
||||
|
||||
* `net/http`: [examples/nethttp/server.go](https://github.com/rs/cors/blob/master/examples/nethttp/server.go)
|
||||
* [Goji](https://goji.io): [examples/goji/server.go](https://github.com/rs/cors/blob/master/examples/goji/server.go)
|
||||
* [Martini](http://martini.codegangsta.io): [examples/martini/server.go](https://github.com/rs/cors/blob/master/examples/martini/server.go)
|
||||
* [Negroni](https://github.com/codegangsta/negroni): [examples/negroni/server.go](https://github.com/rs/cors/blob/master/examples/negroni/server.go)
|
||||
* [Alice](https://github.com/justinas/alice): [examples/alice/server.go](https://github.com/rs/cors/blob/master/examples/alice/server.go)
|
||||
|
||||
## Parameters
|
||||
|
||||
Parameters are passed to the middleware thru the `cors.New` method as follow:
|
||||
|
||||
```go
|
||||
c := cors.New(cors.Options{
|
||||
AllowedOrigins: []string{"http://foo.com"},
|
||||
AllowCredentials: true,
|
||||
})
|
||||
|
||||
// Insert the middleware
|
||||
handler = c.Handler(handler)
|
||||
```
|
||||
|
||||
* **AllowedOrigins** `[]string`: A list of origins a cross-domain request can be executed from. If the special `*` value is present in the list, all origins will be allowed. An origin may contain a wildcard (`*`) to replace 0 or more characters (i.e.: `http://*.domain.com`). Usage of wildcards implies a small performance penality. Only one wildcard can be used per origin. The default value is `*`.
|
||||
* **AllowOriginFunc** `func (origin string) bool`: A custom function to validate the origin. It take the origin as argument and returns true if allowed or false otherwise. If this option is set, the content of `AllowedOrigins` is ignored
|
||||
* **AllowedMethods** `[]string`: A list of methods the client is allowed to use with cross-domain requests. Default value is simple methods (`GET` and `POST`).
|
||||
* **AllowedHeaders** `[]string`: A list of non simple headers the client is allowed to use with cross-domain requests.
|
||||
* **ExposedHeaders** `[]string`: Indicates which headers are safe to expose to the API of a CORS API specification
|
||||
* **AllowCredentials** `bool`: Indicates whether the request can include user credentials like cookies, HTTP authentication or client side SSL certificates. The default is `false`.
|
||||
* **MaxAge** `int`: Indicates how long (in seconds) the results of a preflight request can be cached. The default is `0` which stands for no max age.
|
||||
* **OptionsPassthrough** `bool`: Instructs preflight to let other potential next handlers to process the `OPTIONS` method. Turn this on if your application handles `OPTIONS`.
|
||||
* **Debug** `bool`: Debugging flag adds additional output to debug server side CORS issues.
|
||||
|
||||
See [API documentation](http://godoc.org/github.com/rs/cors) for more info.
|
||||
|
||||
## Benchmarks
|
||||
|
||||
BenchmarkWithout 20000000 64.6 ns/op 8 B/op 1 allocs/op
|
||||
BenchmarkDefault 3000000 469 ns/op 114 B/op 2 allocs/op
|
||||
BenchmarkAllowedOrigin 3000000 608 ns/op 114 B/op 2 allocs/op
|
||||
BenchmarkPreflight 20000000 73.2 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkPreflightHeader 20000000 73.6 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkParseHeaderList 2000000 847 ns/op 184 B/op 6 allocs/op
|
||||
BenchmarkParse…Single 5000000 290 ns/op 32 B/op 3 allocs/op
|
||||
BenchmarkParse…Normalized 2000000 776 ns/op 160 B/op 6 allocs/op
|
||||
|
||||
## Licenses
|
||||
|
||||
All source code is licensed under the [MIT License](https://raw.github.com/rs/cors/master/LICENSE).
|
|
@ -1,7 +0,0 @@
|
|||
language: go
|
||||
go:
|
||||
- 1.5
|
||||
- tip
|
||||
matrix:
|
||||
allow_failures:
|
||||
- go: tip
|
|
@ -1,134 +0,0 @@
|
|||
# XHandler
|
||||
|
||||
[![godoc](http://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://godoc.org/github.com/rs/xhandler) [![license](http://img.shields.io/badge/license-MIT-red.svg?style=flat)](https://raw.githubusercontent.com/rs/xhandler/master/LICENSE) [![Build Status](https://travis-ci.org/rs/xhandler.svg?branch=master)](https://travis-ci.org/rs/xhandler) [![Coverage](http://gocover.io/_badge/github.com/rs/xhandler)](http://gocover.io/github.com/rs/xhandler)
|
||||
|
||||
XHandler is a bridge between [net/context](https://godoc.org/golang.org/x/net/context) and `http.Handler`.
|
||||
|
||||
It lets you enforce `net/context` in your handlers without sacrificing compatibility with existing `http.Handlers` nor imposing a specific router.
|
||||
|
||||
Thanks to `net/context` deadline management, `xhandler` is able to enforce a per request deadline and will cancel the context when the client closes the connection unexpectedly.
|
||||
|
||||
You may create your own `net/context` aware handler pretty much the same way as you would do with http.Handler.
|
||||
|
||||
Read more about xhandler on [Dailymotion engineering blog](http://engineering.dailymotion.com/our-way-to-go/).
|
||||
|
||||
## Installing
|
||||
|
||||
go get -u github.com/rs/xhandler
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/rs/cors"
|
||||
"github.com/rs/xhandler"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type myMiddleware struct {
|
||||
next xhandler.HandlerC
|
||||
}
|
||||
|
||||
func (h myMiddleware) ServeHTTPC(ctx context.Context, w http.ResponseWriter, r *http.Request) {
|
||||
ctx = context.WithValue(ctx, "test", "World")
|
||||
h.next.ServeHTTPC(ctx, w, r)
|
||||
}
|
||||
|
||||
func main() {
|
||||
c := xhandler.Chain{}
|
||||
|
||||
// Add close notifier handler so context is cancelled when the client closes
|
||||
// the connection
|
||||
c.UseC(xhandler.CloseHandler)
|
||||
|
||||
// Add timeout handler
|
||||
c.UseC(xhandler.TimeoutHandler(2 * time.Second))
|
||||
|
||||
// Middleware putting something in the context
|
||||
c.UseC(func(next xhandler.HandlerC) xhandler.HandlerC {
|
||||
return myMiddleware{next: next}
|
||||
})
|
||||
|
||||
// Mix it with a non-context-aware middleware handler
|
||||
c.Use(cors.Default().Handler)
|
||||
|
||||
// Final handler (using handlerFuncC), reading from the context
|
||||
xh := xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
|
||||
value := ctx.Value("test").(string)
|
||||
w.Write([]byte("Hello " + value))
|
||||
})
|
||||
|
||||
// Bridge context aware handlers with http.Handler using xhandler.Handle()
|
||||
http.Handle("/test", c.Handler(xh))
|
||||
|
||||
if err := http.ListenAndServe(":8080", nil); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Using xmux
|
||||
|
||||
Xhandler comes with an optional context aware [muxer](https://github.com/rs/xmux) forked from [httprouter](https://github.com/julienschmidt/httprouter):
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/rs/xhandler"
|
||||
"github.com/rs/xmux"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
func main() {
|
||||
c := xhandler.Chain{}
|
||||
|
||||
// Append a context-aware middleware handler
|
||||
c.UseC(xhandler.CloseHandler)
|
||||
|
||||
// Another context-aware middleware handler
|
||||
c.UseC(xhandler.TimeoutHandler(2 * time.Second))
|
||||
|
||||
mux := xmux.New()
|
||||
|
||||
// Use c.Handler to terminate the chain with your final handler
|
||||
mux.GET("/welcome/:name", xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
|
||||
fmt.Fprintf(w, "Welcome %s!", xmux.Params(ctx).Get("name"))
|
||||
}))
|
||||
|
||||
if err := http.ListenAndServe(":8080", c.Handler(mux)); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See [xmux](https://github.com/rs/xmux) for more examples.
|
||||
|
||||
## Context Aware Middleware
|
||||
|
||||
Here is a list of `net/context` aware middleware handlers implementing `xhandler.HandlerC` interface.
|
||||
|
||||
Feel free to put up a PR linking your middleware if you have built one:
|
||||
|
||||
| Middleware | Author | Description |
|
||||
| ---------- | ------ | ----------- |
|
||||
| [xmux](https://github.com/rs/xmux) | [Olivier Poitrey](https://github.com/rs) | HTTP request muxer |
|
||||
| [xlog](https://github.com/rs/xlog) | [Olivier Poitrey](https://github.com/rs) | HTTP handler logger |
|
||||
| [xstats](https://github.com/rs/xstats) | [Olivier Poitrey](https://github.com/rs) | A generic client for service instrumentation |
|
||||
| [xaccess](https://github.com/rs/xaccess) | [Olivier Poitrey](https://github.com/rs) | HTTP handler access logger with [xlog](https://github.com/rs/xlog) and [xstats](https://github.com/rs/xstats) |
|
||||
| [cors](https://github.com/rs/cors) | [Olivier Poitrey](https://github.com/rs) | [Cross Origin Resource Sharing](http://www.w3.org/TR/cors/) (CORS) support |
|
||||
|
||||
## Licenses
|
||||
|
||||
All source code is licensed under the [MIT License](https://raw.github.com/rs/xhandler/master/LICENSE).
|
|
@ -1,4 +0,0 @@
|
|||
{{.CommentFormat}}
|
||||
func {{.DocInfo.Name}}f(t TestingT, {{.ParamsFormat}}) bool {
|
||||
return {{.DocInfo.Name}}(t, {{.ForwardedParamsFormat}})
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
{{.CommentWithoutT "a"}}
|
||||
func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) bool {
|
||||
return {{.DocInfo.Name}}(a.t, {{.ForwardedParams}})
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
{{.Comment}}
|
||||
func {{.DocInfo.Name}}(t TestingT, {{.Params}}) {
|
||||
if !assert.{{.DocInfo.Name}}(t, {{.ForwardedParams}}) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
{{.CommentWithoutT "a"}}
|
||||
func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) {
|
||||
{{.DocInfo.Name}}(a.t, {{.ForwardedParams}})
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
language: go
|
||||
before_script:
|
||||
# make sure we keep path in tact when we sudo
|
||||
- sudo sed -i -e 's/^Defaults\tsecure_path.*$//' /etc/sudoers
|
||||
# modprobe ip_gre or else the first gre device can't be deleted
|
||||
- sudo modprobe ip_gre
|
||||
# modprobe nf_conntrack for the conntrack testing
|
||||
- sudo modprobe nf_conntrack
|
||||
- sudo modprobe nf_conntrack_netlink
|
||||
- sudo modprobe nf_conntrack_ipv4
|
||||
- sudo modprobe nf_conntrack_ipv6
|
||||
install:
|
||||
- go get github.com/vishvananda/netns
|
|
@ -1,30 +0,0 @@
|
|||
DIRS := \
|
||||
. \
|
||||
nl
|
||||
|
||||
DEPS = \
|
||||
github.com/vishvananda/netns \
|
||||
golang.org/x/sys/unix
|
||||
|
||||
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: test
|
||||
|
||||
$(call goroot,$(DEPS)):
|
||||
go get $(call unroot,$@)
|
||||
|
||||
.PHONY: $(call testdirs,$(DIRS))
|
||||
$(call testdirs,$(DIRS)):
|
||||
go test -test.exec sudo -test.parallel 4 -timeout 60s -test.v github.com/vishvananda/netlink/$@
|
||||
|
||||
$(call fmt,$(call testdirs,$(DIRS))):
|
||||
! gofmt -l $(subst fmt-,,$@)/*.go | grep -q .
|
||||
|
||||
.PHONY: fmt
|
||||
fmt: $(call fmt,$(call testdirs,$(DIRS)))
|
||||
|
||||
test: fmt $(call goroot,$(DEPS)) $(call testdirs,$(DIRS))
|
|
@ -1,92 +0,0 @@
|
|||
# netlink - netlink library for go #
|
||||
|
||||
[![Build Status](https://travis-ci.org/vishvananda/netlink.png?branch=master)](https://travis-ci.org/vishvananda/netlink) [![GoDoc](https://godoc.org/github.com/vishvananda/netlink?status.svg)](https://godoc.org/github.com/vishvananda/netlink)
|
||||
|
||||
The netlink package provides a simple netlink library for go. Netlink
|
||||
is the interface a user-space program in linux uses to communicate with
|
||||
the kernel. It can be used to add and remove interfaces, set ip addresses
|
||||
and routes, and configure ipsec. Netlink communication requires elevated
|
||||
privileges, so in most cases this code needs to be run as root. Since
|
||||
low-level netlink messages are inscrutable at best, the library attempts
|
||||
to provide an api that is loosely modeled on the CLI provided by iproute2.
|
||||
Actions like `ip link add` will be accomplished via a similarly named
|
||||
function like AddLink(). This library began its life as a fork of the
|
||||
netlink functionality in
|
||||
[docker/libcontainer](https://github.com/docker/libcontainer) but was
|
||||
heavily rewritten to improve testability, performance, and to add new
|
||||
functionality like ipsec xfrm handling.
|
||||
|
||||
## Local Build and Test ##
|
||||
|
||||
You can use go get command:
|
||||
|
||||
go get github.com/vishvananda/netlink
|
||||
|
||||
Testing dependencies:
|
||||
|
||||
go get github.com/vishvananda/netns
|
||||
|
||||
Testing (requires root):
|
||||
|
||||
sudo -E go test github.com/vishvananda/netlink
|
||||
|
||||
## Examples ##
|
||||
|
||||
Add a new bridge and add eth1 into it:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/vishvananda/netlink"
|
||||
)
|
||||
|
||||
func main() {
|
||||
la := netlink.NewLinkAttrs()
|
||||
la.Name = "foo"
|
||||
mybridge := &netlink.Bridge{LinkAttrs: la}
|
||||
err := netlink.LinkAdd(mybridge)
|
||||
if err != nil {
|
||||
fmt.Printf("could not add %s: %v\n", la.Name, err)
|
||||
}
|
||||
eth1, _ := netlink.LinkByName("eth1")
|
||||
netlink.LinkSetMaster(eth1, mybridge)
|
||||
}
|
||||
|
||||
```
|
||||
Note `NewLinkAttrs` constructor, it sets default values in structure. For now
|
||||
it sets only `TxQLen` to `-1`, so kernel will set default by itself. If you're
|
||||
using simple initialization(`LinkAttrs{Name: "foo"}`) `TxQLen` will be set to
|
||||
`0` unless you specify it like `LinkAttrs{Name: "foo", TxQLen: 1000}`.
|
||||
|
||||
Add a new ip address to loopback:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/vishvananda/netlink"
|
||||
)
|
||||
|
||||
func main() {
|
||||
lo, _ := netlink.LinkByName("lo")
|
||||
addr, _ := netlink.ParseAddr("169.254.169.254/32")
|
||||
netlink.AddrAdd(lo, addr)
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Future Work ##
|
||||
|
||||
Many pieces of netlink are not yet fully supported in the high-level
|
||||
interface. Aspects of virtually all of the high-level objects don't exist.
|
||||
Many of the underlying primitives are there, so its a matter of putting
|
||||
the right fields into the high-level objects and making sure that they
|
||||
are serialized and deserialized correctly in the Add and List methods.
|
||||
|
||||
There are also a few pieces of low level netlink functionality that still
|
||||
need to be implemented. Routing rules are not in place and some of the
|
||||
more advanced link types. Hopefully there is decent structure and testing
|
||||
in place to make these fairly straightforward to add.
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
# netns - network namespaces in go #
|
||||
|
||||
The netns package provides an ultra-simple interface for handling
|
||||
network namespaces in go. Changing namespaces requires elevated
|
||||
privileges, so in most cases this code needs to be run as root.
|
||||
|
||||
## Local Build and Test ##
|
||||
|
||||
You can use go get command:
|
||||
|
||||
go get github.com/vishvananda/netns
|
||||
|
||||
Testing (requires root):
|
||||
|
||||
sudo -E go test github.com/vishvananda/netns
|
||||
|
||||
## Example ##
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"runtime"
|
||||
"github.com/vishvananda/netns"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Lock the OS Thread so we don't accidentally switch namespaces
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
// Save the current network namespace
|
||||
origns, _ := netns.Get()
|
||||
defer origns.Close()
|
||||
|
||||
// Create a new network namespace
|
||||
newns, _ := netns.New()
|
||||
netns.Set(newns)
|
||||
defer newns.Close()
|
||||
|
||||
// Do something with the network namespace
|
||||
ifaces, _ := net.Interfaces()
|
||||
fmt.Printf("Interfaces: %v\n", ifaces)
|
||||
|
||||
// Switch back to the original namespace
|
||||
netns.Set(origns)
|
||||
}
|
||||
|
||||
```
|
|
@ -1,2 +0,0 @@
|
|||
_obj/
|
||||
unix.test
|
|
@ -1,173 +0,0 @@
|
|||
# Building `sys/unix`
|
||||
|
||||
The sys/unix package provides access to the raw system call interface of the
|
||||
underlying operating system. See: https://godoc.org/golang.org/x/sys/unix
|
||||
|
||||
Porting Go to a new architecture/OS combination or adding syscalls, types, or
|
||||
constants to an existing architecture/OS pair requires some manual effort;
|
||||
however, there are tools that automate much of the process.
|
||||
|
||||
## Build Systems
|
||||
|
||||
There are currently two ways we generate the necessary files. We are currently
|
||||
migrating the build system to use containers so the builds are reproducible.
|
||||
This is being done on an OS-by-OS basis. Please update this documentation as
|
||||
components of the build system change.
|
||||
|
||||
### Old Build System (currently for `GOOS != "Linux" || GOARCH == "sparc64"`)
|
||||
|
||||
The old build system generates the Go files based on the C header files
|
||||
present on your system. This means that files
|
||||
for a given GOOS/GOARCH pair must be generated on a system with that OS and
|
||||
architecture. This also means that the generated code can differ from system
|
||||
to system, based on differences in the header files.
|
||||
|
||||
To avoid this, if you are using the old build system, only generate the Go
|
||||
files on an installation with unmodified header files. It is also important to
|
||||
keep track of which version of the OS the files were generated from (ex.
|
||||
Darwin 14 vs Darwin 15). This makes it easier to track the progress of changes
|
||||
and have each OS upgrade correspond to a single change.
|
||||
|
||||
To build the files for your current OS and architecture, make sure GOOS and
|
||||
GOARCH are set correctly and run `mkall.sh`. This will generate the files for
|
||||
your specific system. Running `mkall.sh -n` shows the commands that will be run.
|
||||
|
||||
Requirements: bash, perl, go
|
||||
|
||||
### New Build System (currently for `GOOS == "Linux" && GOARCH != "sparc64"`)
|
||||
|
||||
The new build system uses a Docker container to generate the go files directly
|
||||
from source checkouts of the kernel and various system libraries. This means
|
||||
that on any platform that supports Docker, all the files using the new build
|
||||
system can be generated at once, and generated files will not change based on
|
||||
what the person running the scripts has installed on their computer.
|
||||
|
||||
The OS specific files for the new build system are located in the `${GOOS}`
|
||||
directory, and the build is coordinated by the `${GOOS}/mkall.go` program. When
|
||||
the kernel or system library updates, modify the Dockerfile at
|
||||
`${GOOS}/Dockerfile` to checkout the new release of the source.
|
||||
|
||||
To build all the files under the new build system, you must be on an amd64/Linux
|
||||
system and have your GOOS and GOARCH set accordingly. Running `mkall.sh` will
|
||||
then generate all of the files for all of the GOOS/GOARCH pairs in the new build
|
||||
system. Running `mkall.sh -n` shows the commands that will be run.
|
||||
|
||||
Requirements: bash, perl, go, docker
|
||||
|
||||
## Component files
|
||||
|
||||
This section describes the various files used in the code generation process.
|
||||
It also contains instructions on how to modify these files to add a new
|
||||
architecture/OS or to add additional syscalls, types, or constants. Note that
|
||||
if you are using the new build system, the scripts cannot be called normally.
|
||||
They must be called from within the docker container.
|
||||
|
||||
### asm files
|
||||
|
||||
The hand-written assembly file at `asm_${GOOS}_${GOARCH}.s` implements system
|
||||
call dispatch. There are three entry points:
|
||||
```
|
||||
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
|
||||
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
|
||||
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
|
||||
```
|
||||
The first and second are the standard ones; they differ only in how many
|
||||
arguments can be passed to the kernel. The third is for low-level use by the
|
||||
ForkExec wrapper. Unlike the first two, it does not call into the scheduler to
|
||||
let it know that a system call is running.
|
||||
|
||||
When porting Go to an new architecture/OS, this file must be implemented for
|
||||
each GOOS/GOARCH pair.
|
||||
|
||||
### mksysnum
|
||||
|
||||
Mksysnum is a script located at `${GOOS}/mksysnum.pl` (or `mksysnum_${GOOS}.pl`
|
||||
for the old system). This script takes in a list of header files containing the
|
||||
syscall number declarations and parses them to produce the corresponding list of
|
||||
Go numeric constants. See `zsysnum_${GOOS}_${GOARCH}.go` for the generated
|
||||
constants.
|
||||
|
||||
Adding new syscall numbers is mostly done by running the build on a sufficiently
|
||||
new installation of the target OS (or updating the source checkouts for the
|
||||
new build system). However, depending on the OS, you make need to update the
|
||||
parsing in mksysnum.
|
||||
|
||||
### mksyscall.pl
|
||||
|
||||
The `syscall.go`, `syscall_${GOOS}.go`, `syscall_${GOOS}_${GOARCH}.go` are
|
||||
hand-written Go files which implement system calls (for unix, the specific OS,
|
||||
or the specific OS/Architecture pair respectively) that need special handling
|
||||
and list `//sys` comments giving prototypes for ones that can be generated.
|
||||
|
||||
The mksyscall.pl script takes the `//sys` and `//sysnb` comments and converts
|
||||
them into syscalls. This requires the name of the prototype in the comment to
|
||||
match a syscall number in the `zsysnum_${GOOS}_${GOARCH}.go` file. The function
|
||||
prototype can be exported (capitalized) or not.
|
||||
|
||||
Adding a new syscall often just requires adding a new `//sys` function prototype
|
||||
with the desired arguments and a capitalized name so it is exported. However, if
|
||||
you want the interface to the syscall to be different, often one will make an
|
||||
unexported `//sys` prototype, an then write a custom wrapper in
|
||||
`syscall_${GOOS}.go`.
|
||||
|
||||
### types files
|
||||
|
||||
For each OS, there is a hand-written Go file at `${GOOS}/types.go` (or
|
||||
`types_${GOOS}.go` on the old system). This file includes standard C headers and
|
||||
creates Go type aliases to the corresponding C types. The file is then fed
|
||||
through godef to get the Go compatible definitions. Finally, the generated code
|
||||
is fed though mkpost.go to format the code correctly and remove any hidden or
|
||||
private identifiers. This cleaned-up code is written to
|
||||
`ztypes_${GOOS}_${GOARCH}.go`.
|
||||
|
||||
The hardest part about preparing this file is figuring out which headers to
|
||||
include and which symbols need to be `#define`d to get the actual data
|
||||
structures that pass through to the kernel system calls. Some C libraries
|
||||
preset alternate versions for binary compatibility and translate them on the
|
||||
way in and out of system calls, but there is almost always a `#define` that can
|
||||
get the real ones.
|
||||
See `types_darwin.go` and `linux/types.go` for examples.
|
||||
|
||||
To add a new type, add in the necessary include statement at the top of the
|
||||
file (if it is not already there) and add in a type alias line. Note that if
|
||||
your type is significantly different on different architectures, you may need
|
||||
some `#if/#elif` macros in your include statements.
|
||||
|
||||
### mkerrors.sh
|
||||
|
||||
This script is used to generate the system's various constants. This doesn't
|
||||
just include the error numbers and error strings, but also the signal numbers
|
||||
an a wide variety of miscellaneous constants. The constants come from the list
|
||||
of include files in the `includes_${uname}` variable. A regex then picks out
|
||||
the desired `#define` statements, and generates the corresponding Go constants.
|
||||
The error numbers and strings are generated from `#include <errno.h>`, and the
|
||||
signal numbers and strings are generated from `#include <signal.h>`. All of
|
||||
these constants are written to `zerrors_${GOOS}_${GOARCH}.go` via a C program,
|
||||
`_errors.c`, which prints out all the constants.
|
||||
|
||||
To add a constant, add the header that includes it to the appropriate variable.
|
||||
Then, edit the regex (if necessary) to match the desired constant. Avoid making
|
||||
the regex too broad to avoid matching unintended constants.
|
||||
|
||||
|
||||
## Generated files
|
||||
|
||||
### `zerror_${GOOS}_${GOARCH}.go`
|
||||
|
||||
A file containing all of the system's generated error numbers, error strings,
|
||||
signal numbers, and constants. Generated by `mkerrors.sh` (see above).
|
||||
|
||||
### `zsyscall_${GOOS}_${GOARCH}.go`
|
||||
|
||||
A file containing all the generated syscalls for a specific GOOS and GOARCH.
|
||||
Generated by `mksyscall.pl` (see above).
|
||||
|
||||
### `zsysnum_${GOOS}_${GOARCH}.go`
|
||||
|
||||
A list of numeric constants for all the syscall number of the specific GOOS
|
||||
and GOARCH. Generated by mksysnum (see above).
|
||||
|
||||
### `ztypes_${GOOS}_${GOARCH}.go`
|
||||
|
||||
A file containing Go types for passing into (or returning from) syscalls.
|
||||
Generated by godefs and the types file (see above).
|
|
@ -1,188 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# 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.
|
||||
|
||||
# This script runs or (given -n) prints suggested commands to generate files for
|
||||
# the Architecture/OS specified by the GOARCH and GOOS environment variables.
|
||||
# See README.md for more information about how the build system works.
|
||||
|
||||
GOOSARCH="${GOOS}_${GOARCH}"
|
||||
|
||||
# defaults
|
||||
mksyscall="./mksyscall.pl"
|
||||
mkerrors="./mkerrors.sh"
|
||||
zerrors="zerrors_$GOOSARCH.go"
|
||||
mksysctl=""
|
||||
zsysctl="zsysctl_$GOOSARCH.go"
|
||||
mksysnum=
|
||||
mktypes=
|
||||
run="sh"
|
||||
cmd=""
|
||||
|
||||
case "$1" in
|
||||
-syscalls)
|
||||
for i in zsyscall*go
|
||||
do
|
||||
# Run the command line that appears in the first line
|
||||
# of the generated file to regenerate it.
|
||||
sed 1q $i | sed 's;^// ;;' | sh > _$i && gofmt < _$i > $i
|
||||
rm _$i
|
||||
done
|
||||
exit 0
|
||||
;;
|
||||
-n)
|
||||
run="cat"
|
||||
cmd="echo"
|
||||
shift
|
||||
esac
|
||||
|
||||
case "$#" in
|
||||
0)
|
||||
;;
|
||||
*)
|
||||
echo 'usage: mkall.sh [-n]' 1>&2
|
||||
exit 2
|
||||
esac
|
||||
|
||||
if [[ "$GOOS" = "linux" ]] && [[ "$GOARCH" != "sparc64" ]]; then
|
||||
# Use then new build system
|
||||
# Files generated through docker (use $cmd so you can Ctl-C the build or run)
|
||||
$cmd docker build --tag generate:$GOOS $GOOS
|
||||
$cmd docker run --interactive --tty --volume $(dirname "$(readlink -f "$0")"):/build generate:$GOOS
|
||||
exit
|
||||
fi
|
||||
|
||||
GOOSARCH_in=syscall_$GOOSARCH.go
|
||||
case "$GOOSARCH" in
|
||||
_* | *_ | _)
|
||||
echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
darwin_386)
|
||||
mkerrors="$mkerrors -m32"
|
||||
mksyscall="./mksyscall.pl -l32"
|
||||
mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
darwin_amd64)
|
||||
mkerrors="$mkerrors -m64"
|
||||
mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
darwin_arm)
|
||||
mkerrors="$mkerrors"
|
||||
mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
darwin_arm64)
|
||||
mkerrors="$mkerrors -m64"
|
||||
mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
dragonfly_amd64)
|
||||
mkerrors="$mkerrors -m64"
|
||||
mksyscall="./mksyscall.pl -dragonfly"
|
||||
mksysnum="curl -s 'http://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master' | ./mksysnum_dragonfly.pl"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
freebsd_386)
|
||||
mkerrors="$mkerrors -m32"
|
||||
mksyscall="./mksyscall.pl -l32"
|
||||
mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
freebsd_amd64)
|
||||
mkerrors="$mkerrors -m64"
|
||||
mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
freebsd_arm)
|
||||
mkerrors="$mkerrors"
|
||||
mksyscall="./mksyscall.pl -l32 -arm"
|
||||
mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
|
||||
# Let the type of C char be signed for making the bare syscall
|
||||
# API consistent across platforms.
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
||||
;;
|
||||
linux_sparc64)
|
||||
GOOSARCH_in=syscall_linux_sparc64.go
|
||||
unistd_h=/usr/include/sparc64-linux-gnu/asm/unistd.h
|
||||
mkerrors="$mkerrors -m64"
|
||||
mksysnum="./mksysnum_linux.pl $unistd_h"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
netbsd_386)
|
||||
mkerrors="$mkerrors -m32"
|
||||
mksyscall="./mksyscall.pl -l32 -netbsd"
|
||||
mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
netbsd_amd64)
|
||||
mkerrors="$mkerrors -m64"
|
||||
mksyscall="./mksyscall.pl -netbsd"
|
||||
mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
netbsd_arm)
|
||||
mkerrors="$mkerrors"
|
||||
mksyscall="./mksyscall.pl -l32 -netbsd -arm"
|
||||
mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
|
||||
# Let the type of C char be signed for making the bare syscall
|
||||
# API consistent across platforms.
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
||||
;;
|
||||
openbsd_386)
|
||||
mkerrors="$mkerrors -m32"
|
||||
mksyscall="./mksyscall.pl -l32 -openbsd"
|
||||
mksysctl="./mksysctl_openbsd.pl"
|
||||
mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
openbsd_amd64)
|
||||
mkerrors="$mkerrors -m64"
|
||||
mksyscall="./mksyscall.pl -openbsd"
|
||||
mksysctl="./mksysctl_openbsd.pl"
|
||||
mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
openbsd_arm)
|
||||
mkerrors="$mkerrors"
|
||||
mksyscall="./mksyscall.pl -l32 -openbsd -arm"
|
||||
mksysctl="./mksysctl_openbsd.pl"
|
||||
mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
|
||||
# Let the type of C char be signed for making the bare syscall
|
||||
# API consistent across platforms.
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
||||
;;
|
||||
solaris_amd64)
|
||||
mksyscall="./mksyscall_solaris.pl"
|
||||
mkerrors="$mkerrors -m64"
|
||||
mksysnum=
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
*)
|
||||
echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
(
|
||||
if [ -n "$mkerrors" ]; then echo "$mkerrors |gofmt >$zerrors"; fi
|
||||
case "$GOOS" in
|
||||
*)
|
||||
syscall_goos="syscall_$GOOS.go"
|
||||
case "$GOOS" in
|
||||
darwin | dragonfly | freebsd | netbsd | openbsd)
|
||||
syscall_goos="syscall_bsd.go $syscall_goos"
|
||||
;;
|
||||
esac
|
||||
if [ -n "$mksyscall" ]; then echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go"; fi
|
||||
;;
|
||||
esac
|
||||
if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
|
||||
if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
|
||||
if [ -n "$mktypes" ]; then
|
||||
echo "$mktypes types_$GOOS.go | go run mkpost.go > ztypes_$GOOSARCH.go";
|
||||
fi
|
||||
) | $run
|
|
@ -1,580 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# 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.
|
||||
|
||||
# Generate Go code listing errors and other #defined constant
|
||||
# values (ENAMETOOLONG etc.), by asking the preprocessor
|
||||
# about the definitions.
|
||||
|
||||
unset LANG
|
||||
export LC_ALL=C
|
||||
export LC_CTYPE=C
|
||||
|
||||
if test -z "$GOARCH" -o -z "$GOOS"; then
|
||||
echo 1>&2 "GOARCH or GOOS not defined in environment"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check that we are using the new build system if we should
|
||||
if [[ "$GOOS" = "linux" ]] && [[ "$GOARCH" != "sparc64" ]]; then
|
||||
if [[ "$GOLANG_SYS_BUILD" != "docker" ]]; then
|
||||
echo 1>&2 "In the new build system, mkerrors should not be called directly."
|
||||
echo 1>&2 "See README.md"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
CC=${CC:-cc}
|
||||
|
||||
if [[ "$GOOS" = "solaris" ]]; then
|
||||
# Assumes GNU versions of utilities in PATH.
|
||||
export PATH=/usr/gnu/bin:$PATH
|
||||
fi
|
||||
|
||||
uname=$(uname)
|
||||
|
||||
includes_Darwin='
|
||||
#define _DARWIN_C_SOURCE
|
||||
#define KERNEL
|
||||
#define _DARWIN_USE_64_BIT_INODE
|
||||
#include <stdint.h>
|
||||
#include <sys/attr.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/wait.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <termios.h>
|
||||
'
|
||||
|
||||
includes_DragonFly='
|
||||
#include <sys/types.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <termios.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <net/ip_mroute/ip_mroute.h>
|
||||
'
|
||||
|
||||
includes_FreeBSD='
|
||||
#include <sys/capability.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <termios.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_mroute.h>
|
||||
#include <sys/extattr.h>
|
||||
|
||||
#if __FreeBSD__ >= 10
|
||||
#define IFT_CARP 0xf8 // IFT_CARP is deprecated in FreeBSD 10
|
||||
#undef SIOCAIFADDR
|
||||
#define SIOCAIFADDR _IOW(105, 26, struct oifaliasreq) // ifaliasreq contains if_data
|
||||
#undef SIOCSIFPHYADDR
|
||||
#define SIOCSIFPHYADDR _IOW(105, 70, struct oifaliasreq) // ifaliasreq contains if_data
|
||||
#endif
|
||||
'
|
||||
|
||||
includes_Linux='
|
||||
#define _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#ifndef __LP64__
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#endif
|
||||
#define _GNU_SOURCE
|
||||
|
||||
// <sys/ioctl.h> is broken on powerpc64, as it fails to include definitions of
|
||||
// these structures. We just include them copied from <bits/termios.h>.
|
||||
#if defined(__powerpc__)
|
||||
struct sgttyb {
|
||||
char sg_ispeed;
|
||||
char sg_ospeed;
|
||||
char sg_erase;
|
||||
char sg_kill;
|
||||
short sg_flags;
|
||||
};
|
||||
|
||||
struct tchars {
|
||||
char t_intrc;
|
||||
char t_quitc;
|
||||
char t_startc;
|
||||
char t_stopc;
|
||||
char t_eofc;
|
||||
char t_brkc;
|
||||
};
|
||||
|
||||
struct ltchars {
|
||||
char t_suspc;
|
||||
char t_dsuspc;
|
||||
char t_rprntc;
|
||||
char t_flushc;
|
||||
char t_werasc;
|
||||
char t_lnextc;
|
||||
};
|
||||
#endif
|
||||
|
||||
#include <bits/sockaddr.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/eventfd.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/xattr.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_alg.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/if_tun.h>
|
||||
#include <linux/if_packet.h>
|
||||
#include <linux/if_addr.h>
|
||||
#include <linux/falloc.h>
|
||||
#include <linux/filter.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/keyctl.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/perf_event.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/seccomp.h>
|
||||
#include <linux/sockios.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/icmpv6.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/can.h>
|
||||
#include <linux/vm_sockets.h>
|
||||
#include <linux/taskstats.h>
|
||||
#include <linux/genetlink.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/watchdog.h>
|
||||
#include <net/route.h>
|
||||
#include <asm/termbits.h>
|
||||
|
||||
#ifndef MSG_FASTOPEN
|
||||
#define MSG_FASTOPEN 0x20000000
|
||||
#endif
|
||||
|
||||
#ifndef PTRACE_GETREGS
|
||||
#define PTRACE_GETREGS 0xc
|
||||
#endif
|
||||
|
||||
#ifndef PTRACE_SETREGS
|
||||
#define PTRACE_SETREGS 0xd
|
||||
#endif
|
||||
|
||||
#ifndef SOL_NETLINK
|
||||
#define SOL_NETLINK 270
|
||||
#endif
|
||||
|
||||
#ifdef SOL_BLUETOOTH
|
||||
// SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h
|
||||
// but it is already in bluetooth_linux.go
|
||||
#undef SOL_BLUETOOTH
|
||||
#endif
|
||||
|
||||
// Certain constants are missing from the fs/crypto UAPI
|
||||
#define FS_KEY_DESC_PREFIX "fscrypt:"
|
||||
#define FS_KEY_DESC_PREFIX_SIZE 8
|
||||
#define FS_MAX_KEY_SIZE 64
|
||||
'
|
||||
|
||||
includes_NetBSD='
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/termios.h>
|
||||
#include <sys/ttycom.h>
|
||||
#include <sys/wait.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_mroute.h>
|
||||
#include <netinet/if_ether.h>
|
||||
|
||||
// Needed since <sys/param.h> refers to it...
|
||||
#define schedppq 1
|
||||
'
|
||||
|
||||
includes_OpenBSD='
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/termios.h>
|
||||
#include <sys/ttycom.h>
|
||||
#include <sys/wait.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_mroute.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <net/if_bridge.h>
|
||||
|
||||
// We keep some constants not supported in OpenBSD 5.5 and beyond for
|
||||
// the promise of compatibility.
|
||||
#define EMUL_ENABLED 0x1
|
||||
#define EMUL_NATIVE 0x2
|
||||
#define IPV6_FAITH 0x1d
|
||||
#define IPV6_OPTIONS 0x1
|
||||
#define IPV6_RTHDR_STRICT 0x1
|
||||
#define IPV6_SOCKOPT_RESERVED1 0x3
|
||||
#define SIOCGIFGENERIC 0xc020693a
|
||||
#define SIOCSIFGENERIC 0x80206939
|
||||
#define WALTSIG 0x4
|
||||
'
|
||||
|
||||
includes_SunOS='
|
||||
#include <limits.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mkdev.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <termios.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_mroute.h>
|
||||
'
|
||||
|
||||
|
||||
includes='
|
||||
#include <sys/types.h>
|
||||
#include <sys/file.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <errno.h>
|
||||
#include <sys/signal.h>
|
||||
#include <signal.h>
|
||||
#include <sys/resource.h>
|
||||
#include <time.h>
|
||||
'
|
||||
ccflags="$@"
|
||||
|
||||
# Write go tool cgo -godefs input.
|
||||
(
|
||||
echo package unix
|
||||
echo
|
||||
echo '/*'
|
||||
indirect="includes_$(uname)"
|
||||
echo "${!indirect} $includes"
|
||||
echo '*/'
|
||||
echo 'import "C"'
|
||||
echo 'import "syscall"'
|
||||
echo
|
||||
echo 'const ('
|
||||
|
||||
# The gcc command line prints all the #defines
|
||||
# it encounters while processing the input
|
||||
echo "${!indirect} $includes" | $CC -x c - -E -dM $ccflags |
|
||||
awk '
|
||||
$1 != "#define" || $2 ~ /\(/ || $3 == "" {next}
|
||||
|
||||
$2 ~ /^E([ABCD]X|[BIS]P|[SD]I|S|FL)$/ {next} # 386 registers
|
||||
$2 ~ /^(SIGEV_|SIGSTKSZ|SIGRT(MIN|MAX))/ {next}
|
||||
$2 ~ /^(SCM_SRCRT)$/ {next}
|
||||
$2 ~ /^(MAP_FAILED)$/ {next}
|
||||
$2 ~ /^ELF_.*$/ {next}# <asm/elf.h> contains ELF_ARCH, etc.
|
||||
|
||||
$2 ~ /^EXTATTR_NAMESPACE_NAMES/ ||
|
||||
$2 ~ /^EXTATTR_NAMESPACE_[A-Z]+_STRING/ {next}
|
||||
|
||||
$2 !~ /^ETH_/ &&
|
||||
$2 !~ /^EPROC_/ &&
|
||||
$2 !~ /^EQUIV_/ &&
|
||||
$2 !~ /^EXPR_/ &&
|
||||
$2 ~ /^E[A-Z0-9_]+$/ ||
|
||||
$2 ~ /^B[0-9_]+$/ ||
|
||||
$2 ~ /^(OLD|NEW)DEV$/ ||
|
||||
$2 == "BOTHER" ||
|
||||
$2 ~ /^CI?BAUD(EX)?$/ ||
|
||||
$2 == "IBSHIFT" ||
|
||||
$2 ~ /^V[A-Z0-9]+$/ ||
|
||||
$2 ~ /^CS[A-Z0-9]/ ||
|
||||
$2 ~ /^I(SIG|CANON|CRNL|UCLC|EXTEN|MAXBEL|STRIP|UTF8)$/ ||
|
||||
$2 ~ /^IGN/ ||
|
||||
$2 ~ /^IX(ON|ANY|OFF)$/ ||
|
||||
$2 ~ /^IN(LCR|PCK)$/ ||
|
||||
$2 ~ /(^FLU?SH)|(FLU?SH$)/ ||
|
||||
$2 ~ /^C(LOCAL|READ|MSPAR|RTSCTS)$/ ||
|
||||
$2 == "BRKINT" ||
|
||||
$2 == "HUPCL" ||
|
||||
$2 == "PENDIN" ||
|
||||
$2 == "TOSTOP" ||
|
||||
$2 == "XCASE" ||
|
||||
$2 == "ALTWERASE" ||
|
||||
$2 == "NOKERNINFO" ||
|
||||
$2 ~ /^PAR/ ||
|
||||
$2 ~ /^SIG[^_]/ ||
|
||||
$2 ~ /^O[CNPFPL][A-Z]+[^_][A-Z]+$/ ||
|
||||
$2 ~ /^(NL|CR|TAB|BS|VT|FF)DLY$/ ||
|
||||
$2 ~ /^(NL|CR|TAB|BS|VT|FF)[0-9]$/ ||
|
||||
$2 ~ /^O?XTABS$/ ||
|
||||
$2 ~ /^TC[IO](ON|OFF)$/ ||
|
||||
$2 ~ /^IN_/ ||
|
||||
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
|
||||
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|EVFILT|NOTE|EV|SHUT|PROT|MAP|PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ ||
|
||||
$2 ~ /^FALLOC_/ ||
|
||||
$2 == "ICMPV6_FILTER" ||
|
||||
$2 == "SOMAXCONN" ||
|
||||
$2 == "NAME_MAX" ||
|
||||
$2 == "IFNAMSIZ" ||
|
||||
$2 ~ /^CTL_(HW|KERN|MAXNAME|NET|QUERY)$/ ||
|
||||
$2 ~ /^KERN_(HOSTNAME|OS(RELEASE|TYPE)|VERSION)$/ ||
|
||||
$2 ~ /^HW_MACHINE$/ ||
|
||||
$2 ~ /^SYSCTL_VERS/ ||
|
||||
$2 ~ /^(MS|MNT|UMOUNT)_/ ||
|
||||
$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
|
||||
$2 ~ /^(O|F|E?FD|NAME|S|PTRACE|PT)_/ ||
|
||||
$2 ~ /^LINUX_REBOOT_CMD_/ ||
|
||||
$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
|
||||
$2 !~ "NLA_TYPE_MASK" &&
|
||||
$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P)_/ ||
|
||||
$2 ~ /^SIOC/ ||
|
||||
$2 ~ /^TIOC/ ||
|
||||
$2 ~ /^TCGET/ ||
|
||||
$2 ~ /^TCSET/ ||
|
||||
$2 ~ /^TC(FLSH|SBRKP?|XONC)$/ ||
|
||||
$2 !~ "RTF_BITS" &&
|
||||
$2 ~ /^(IFF|IFT|NET_RT|RTM|RTF|RTV|RTA|RTAX)_/ ||
|
||||
$2 ~ /^BIOC/ ||
|
||||
$2 ~ /^RUSAGE_(SELF|CHILDREN|THREAD)/ ||
|
||||
$2 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|LOCKS|MEMLOCK|MSGQUEUE|NICE|NOFILE|NPROC|RSS|RTPRIO|RTTIME|SIGPENDING|STACK)|RLIM_INFINITY/ ||
|
||||
$2 ~ /^PRIO_(PROCESS|PGRP|USER)/ ||
|
||||
$2 ~ /^CLONE_[A-Z_]+/ ||
|
||||
$2 !~ /^(BPF_TIMEVAL)$/ &&
|
||||
$2 ~ /^(BPF|DLT)_/ ||
|
||||
$2 ~ /^CLOCK_/ ||
|
||||
$2 ~ /^CAN_/ ||
|
||||
$2 ~ /^CAP_/ ||
|
||||
$2 ~ /^ALG_/ ||
|
||||
$2 ~ /^FS_(POLICY_FLAGS|KEY_DESC|ENCRYPTION_MODE|[A-Z0-9_]+_KEY_SIZE|IOC_(GET|SET)_ENCRYPTION)/ ||
|
||||
$2 ~ /^GRND_/ ||
|
||||
$2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ ||
|
||||
$2 ~ /^KEYCTL_/ ||
|
||||
$2 ~ /^PERF_EVENT_IOC_/ ||
|
||||
$2 ~ /^SECCOMP_MODE_/ ||
|
||||
$2 ~ /^SPLICE_/ ||
|
||||
$2 ~ /^(VM|VMADDR)_/ ||
|
||||
$2 ~ /^IOCTL_VM_SOCKETS_/ ||
|
||||
$2 ~ /^(TASKSTATS|TS)_/ ||
|
||||
$2 ~ /^CGROUPSTATS_/ ||
|
||||
$2 ~ /^GENL_/ ||
|
||||
$2 ~ /^STATX_/ ||
|
||||
$2 ~ /^UTIME_/ ||
|
||||
$2 ~ /^XATTR_(CREATE|REPLACE)/ ||
|
||||
$2 ~ /^ATTR_(BIT_MAP_COUNT|(CMN|VOL|FILE)_)/ ||
|
||||
$2 ~ /^FSOPT_/ ||
|
||||
$2 ~ /^WDIOC_/ ||
|
||||
$2 !~ "WMESGLEN" &&
|
||||
$2 ~ /^W[A-Z0-9]+$/ ||
|
||||
$2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)}
|
||||
$2 ~ /^__WCOREFLAG$/ {next}
|
||||
$2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)}
|
||||
|
||||
{next}
|
||||
' | sort
|
||||
|
||||
echo ')'
|
||||
) >_const.go
|
||||
|
||||
# Pull out the error names for later.
|
||||
errors=$(
|
||||
echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
|
||||
awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print $2 }' |
|
||||
sort
|
||||
)
|
||||
|
||||
# Pull out the signal names for later.
|
||||
signals=$(
|
||||
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
|
||||
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
|
||||
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
|
||||
sort
|
||||
)
|
||||
|
||||
# Again, writing regexps to a file.
|
||||
echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
|
||||
awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print "^\t" $2 "[ \t]*=" }' |
|
||||
sort >_error.grep
|
||||
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
|
||||
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
|
||||
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
|
||||
sort >_signal.grep
|
||||
|
||||
echo '// mkerrors.sh' "$@"
|
||||
echo '// Code generated by the command above; see README.md. DO NOT EDIT.'
|
||||
echo
|
||||
echo "// +build ${GOARCH},${GOOS}"
|
||||
echo
|
||||
go tool cgo -godefs -- "$@" _const.go >_error.out
|
||||
cat _error.out | grep -vf _error.grep | grep -vf _signal.grep
|
||||
echo
|
||||
echo '// Errors'
|
||||
echo 'const ('
|
||||
cat _error.out | grep -f _error.grep | sed 's/=\(.*\)/= syscall.Errno(\1)/'
|
||||
echo ')'
|
||||
|
||||
echo
|
||||
echo '// Signals'
|
||||
echo 'const ('
|
||||
cat _error.out | grep -f _signal.grep | sed 's/=\(.*\)/= syscall.Signal(\1)/'
|
||||
echo ')'
|
||||
|
||||
# Run C program to print error and syscall strings.
|
||||
(
|
||||
echo -E "
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#define nelem(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
||||
enum { A = 'A', Z = 'Z', a = 'a', z = 'z' }; // avoid need for single quotes below
|
||||
|
||||
int errors[] = {
|
||||
"
|
||||
for i in $errors
|
||||
do
|
||||
echo -E ' '$i,
|
||||
done
|
||||
|
||||
echo -E "
|
||||
};
|
||||
|
||||
int signals[] = {
|
||||
"
|
||||
for i in $signals
|
||||
do
|
||||
echo -E ' '$i,
|
||||
done
|
||||
|
||||
# Use -E because on some systems bash builtin interprets \n itself.
|
||||
echo -E '
|
||||
};
|
||||
|
||||
static int
|
||||
intcmp(const void *a, const void *b)
|
||||
{
|
||||
return *(int*)a - *(int*)b;
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
int i, e;
|
||||
char buf[1024], *p;
|
||||
|
||||
printf("\n\n// Error table\n");
|
||||
printf("var errors = [...]string {\n");
|
||||
qsort(errors, nelem(errors), sizeof errors[0], intcmp);
|
||||
for(i=0; i<nelem(errors); i++) {
|
||||
e = errors[i];
|
||||
if(i > 0 && errors[i-1] == e)
|
||||
continue;
|
||||
strcpy(buf, strerror(e));
|
||||
// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
|
||||
if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
|
||||
buf[0] += a - A;
|
||||
printf("\t%d: \"%s\",\n", e, buf);
|
||||
}
|
||||
printf("}\n\n");
|
||||
|
||||
printf("\n\n// Signal table\n");
|
||||
printf("var signals = [...]string {\n");
|
||||
qsort(signals, nelem(signals), sizeof signals[0], intcmp);
|
||||
for(i=0; i<nelem(signals); i++) {
|
||||
e = signals[i];
|
||||
if(i > 0 && signals[i-1] == e)
|
||||
continue;
|
||||
strcpy(buf, strsignal(e));
|
||||
// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
|
||||
if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
|
||||
buf[0] += a - A;
|
||||
// cut trailing : number.
|
||||
p = strrchr(buf, ":"[0]);
|
||||
if(p)
|
||||
*p = '\0';
|
||||
printf("\t%d: \"%s\",\n", e, buf);
|
||||
}
|
||||
printf("}\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
'
|
||||
) >_errors.c
|
||||
|
||||
$CC $ccflags -o _errors _errors.c && $GORUN ./_errors && rm -f _errors.c _errors _const.go _error.grep _signal.grep _error.out
|
|
@ -1,340 +0,0 @@
|
|||
#!/usr/bin/env perl
|
||||
# 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.
|
||||
|
||||
# This program reads a file containing function prototypes
|
||||
# (like syscall_darwin.go) and generates system call bodies.
|
||||
# The prototypes are marked by lines beginning with "//sys"
|
||||
# and read like func declarations if //sys is replaced by func, but:
|
||||
# * The parameter lists must give a name for each argument.
|
||||
# This includes return parameters.
|
||||
# * The parameter lists must give a type for each argument:
|
||||
# the (x, y, z int) shorthand is not allowed.
|
||||
# * If the return parameter is an error number, it must be named errno.
|
||||
|
||||
# A line beginning with //sysnb is like //sys, except that the
|
||||
# goroutine will not be suspended during the execution of the system
|
||||
# call. This must only be used for system calls which can never
|
||||
# block, as otherwise the system call could cause all goroutines to
|
||||
# hang.
|
||||
|
||||
use strict;
|
||||
|
||||
my $cmdline = "mksyscall.pl " . join(' ', @ARGV);
|
||||
my $errors = 0;
|
||||
my $_32bit = "";
|
||||
my $plan9 = 0;
|
||||
my $openbsd = 0;
|
||||
my $netbsd = 0;
|
||||
my $dragonfly = 0;
|
||||
my $arm = 0; # 64-bit value should use (even, odd)-pair
|
||||
my $tags = ""; # build tags
|
||||
|
||||
if($ARGV[0] eq "-b32") {
|
||||
$_32bit = "big-endian";
|
||||
shift;
|
||||
} elsif($ARGV[0] eq "-l32") {
|
||||
$_32bit = "little-endian";
|
||||
shift;
|
||||
}
|
||||
if($ARGV[0] eq "-plan9") {
|
||||
$plan9 = 1;
|
||||
shift;
|
||||
}
|
||||
if($ARGV[0] eq "-openbsd") {
|
||||
$openbsd = 1;
|
||||
shift;
|
||||
}
|
||||
if($ARGV[0] eq "-netbsd") {
|
||||
$netbsd = 1;
|
||||
shift;
|
||||
}
|
||||
if($ARGV[0] eq "-dragonfly") {
|
||||
$dragonfly = 1;
|
||||
shift;
|
||||
}
|
||||
if($ARGV[0] eq "-arm") {
|
||||
$arm = 1;
|
||||
shift;
|
||||
}
|
||||
if($ARGV[0] eq "-tags") {
|
||||
shift;
|
||||
$tags = $ARGV[0];
|
||||
shift;
|
||||
}
|
||||
|
||||
if($ARGV[0] =~ /^-/) {
|
||||
print STDERR "usage: mksyscall.pl [-b32 | -l32] [-tags x,y] [file ...]\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
# Check that we are using the new build system if we should
|
||||
if($ENV{'GOOS'} eq "linux" && $ENV{'GOARCH'} ne "sparc64") {
|
||||
if($ENV{'GOLANG_SYS_BUILD'} ne "docker") {
|
||||
print STDERR "In the new build system, mksyscall should not be called directly.\n";
|
||||
print STDERR "See README.md\n";
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub parseparamlist($) {
|
||||
my ($list) = @_;
|
||||
$list =~ s/^\s*//;
|
||||
$list =~ s/\s*$//;
|
||||
if($list eq "") {
|
||||
return ();
|
||||
}
|
||||
return split(/\s*,\s*/, $list);
|
||||
}
|
||||
|
||||
sub parseparam($) {
|
||||
my ($p) = @_;
|
||||
if($p !~ /^(\S*) (\S*)$/) {
|
||||
print STDERR "$ARGV:$.: malformed parameter: $p\n";
|
||||
$errors = 1;
|
||||
return ("xx", "int");
|
||||
}
|
||||
return ($1, $2);
|
||||
}
|
||||
|
||||
my $text = "";
|
||||
while(<>) {
|
||||
chomp;
|
||||
s/\s+/ /g;
|
||||
s/^\s+//;
|
||||
s/\s+$//;
|
||||
my $nonblock = /^\/\/sysnb /;
|
||||
next if !/^\/\/sys / && !$nonblock;
|
||||
|
||||
# Line must be of the form
|
||||
# func Open(path string, mode int, perm int) (fd int, errno error)
|
||||
# Split into name, in params, out params.
|
||||
if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*((?i)SYS_[A-Z0-9_]+))?$/) {
|
||||
print STDERR "$ARGV:$.: malformed //sys declaration\n";
|
||||
$errors = 1;
|
||||
next;
|
||||
}
|
||||
my ($func, $in, $out, $sysname) = ($2, $3, $4, $5);
|
||||
|
||||
# Split argument lists on comma.
|
||||
my @in = parseparamlist($in);
|
||||
my @out = parseparamlist($out);
|
||||
|
||||
# Try in vain to keep people from editing this file.
|
||||
# The theory is that they jump into the middle of the file
|
||||
# without reading the header.
|
||||
$text .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
|
||||
|
||||
# Go function header.
|
||||
my $out_decl = @out ? sprintf(" (%s)", join(', ', @out)) : "";
|
||||
$text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out_decl;
|
||||
|
||||
# Check if err return available
|
||||
my $errvar = "";
|
||||
foreach my $p (@out) {
|
||||
my ($name, $type) = parseparam($p);
|
||||
if($type eq "error") {
|
||||
$errvar = $name;
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
# Prepare arguments to Syscall.
|
||||
my @args = ();
|
||||
my $n = 0;
|
||||
foreach my $p (@in) {
|
||||
my ($name, $type) = parseparam($p);
|
||||
if($type =~ /^\*/) {
|
||||
push @args, "uintptr(unsafe.Pointer($name))";
|
||||
} elsif($type eq "string" && $errvar ne "") {
|
||||
$text .= "\tvar _p$n *byte\n";
|
||||
$text .= "\t_p$n, $errvar = BytePtrFromString($name)\n";
|
||||
$text .= "\tif $errvar != nil {\n\t\treturn\n\t}\n";
|
||||
push @args, "uintptr(unsafe.Pointer(_p$n))";
|
||||
$n++;
|
||||
} elsif($type eq "string") {
|
||||
print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n";
|
||||
$text .= "\tvar _p$n *byte\n";
|
||||
$text .= "\t_p$n, _ = BytePtrFromString($name)\n";
|
||||
push @args, "uintptr(unsafe.Pointer(_p$n))";
|
||||
$n++;
|
||||
} elsif($type =~ /^\[\](.*)/) {
|
||||
# Convert slice into pointer, length.
|
||||
# Have to be careful not to take address of &a[0] if len == 0:
|
||||
# pass dummy pointer in that case.
|
||||
# Used to pass nil, but some OSes or simulators reject write(fd, nil, 0).
|
||||
$text .= "\tvar _p$n unsafe.Pointer\n";
|
||||
$text .= "\tif len($name) > 0 {\n\t\t_p$n = unsafe.Pointer(\&${name}[0])\n\t}";
|
||||
$text .= " else {\n\t\t_p$n = unsafe.Pointer(&_zero)\n\t}";
|
||||
$text .= "\n";
|
||||
push @args, "uintptr(_p$n)", "uintptr(len($name))";
|
||||
$n++;
|
||||
} elsif($type eq "int64" && ($openbsd || $netbsd)) {
|
||||
push @args, "0";
|
||||
if($_32bit eq "big-endian") {
|
||||
push @args, "uintptr($name>>32)", "uintptr($name)";
|
||||
} elsif($_32bit eq "little-endian") {
|
||||
push @args, "uintptr($name)", "uintptr($name>>32)";
|
||||
} else {
|
||||
push @args, "uintptr($name)";
|
||||
}
|
||||
} elsif($type eq "int64" && $dragonfly) {
|
||||
if ($func !~ /^extp(read|write)/i) {
|
||||
push @args, "0";
|
||||
}
|
||||
if($_32bit eq "big-endian") {
|
||||
push @args, "uintptr($name>>32)", "uintptr($name)";
|
||||
} elsif($_32bit eq "little-endian") {
|
||||
push @args, "uintptr($name)", "uintptr($name>>32)";
|
||||
} else {
|
||||
push @args, "uintptr($name)";
|
||||
}
|
||||
} elsif($type eq "int64" && $_32bit ne "") {
|
||||
if(@args % 2 && $arm) {
|
||||
# arm abi specifies 64-bit argument uses
|
||||
# (even, odd) pair
|
||||
push @args, "0"
|
||||
}
|
||||
if($_32bit eq "big-endian") {
|
||||
push @args, "uintptr($name>>32)", "uintptr($name)";
|
||||
} else {
|
||||
push @args, "uintptr($name)", "uintptr($name>>32)";
|
||||
}
|
||||
} else {
|
||||
push @args, "uintptr($name)";
|
||||
}
|
||||
}
|
||||
|
||||
# Determine which form to use; pad args with zeros.
|
||||
my $asm = "Syscall";
|
||||
if ($nonblock) {
|
||||
if ($errvar ne "") {
|
||||
$asm = "RawSyscall";
|
||||
} else {
|
||||
$asm = "RawSyscallNoError";
|
||||
}
|
||||
} else {
|
||||
if ($errvar eq "") {
|
||||
$asm = "SyscallNoError";
|
||||
}
|
||||
}
|
||||
if(@args <= 3) {
|
||||
while(@args < 3) {
|
||||
push @args, "0";
|
||||
}
|
||||
} elsif(@args <= 6) {
|
||||
$asm .= "6";
|
||||
while(@args < 6) {
|
||||
push @args, "0";
|
||||
}
|
||||
} elsif(@args <= 9) {
|
||||
$asm .= "9";
|
||||
while(@args < 9) {
|
||||
push @args, "0";
|
||||
}
|
||||
} else {
|
||||
print STDERR "$ARGV:$.: too many arguments to system call\n";
|
||||
}
|
||||
|
||||
# System call number.
|
||||
if($sysname eq "") {
|
||||
$sysname = "SYS_$func";
|
||||
$sysname =~ s/([a-z])([A-Z])/${1}_$2/g; # turn FooBar into Foo_Bar
|
||||
$sysname =~ y/a-z/A-Z/;
|
||||
}
|
||||
|
||||
# Actual call.
|
||||
my $args = join(', ', @args);
|
||||
my $call = "$asm($sysname, $args)";
|
||||
|
||||
# Assign return values.
|
||||
my $body = "";
|
||||
my @ret = ("_", "_", "_");
|
||||
my $do_errno = 0;
|
||||
for(my $i=0; $i<@out; $i++) {
|
||||
my $p = $out[$i];
|
||||
my ($name, $type) = parseparam($p);
|
||||
my $reg = "";
|
||||
if($name eq "err" && !$plan9) {
|
||||
$reg = "e1";
|
||||
$ret[2] = $reg;
|
||||
$do_errno = 1;
|
||||
} elsif($name eq "err" && $plan9) {
|
||||
$ret[0] = "r0";
|
||||
$ret[2] = "e1";
|
||||
next;
|
||||
} else {
|
||||
$reg = sprintf("r%d", $i);
|
||||
$ret[$i] = $reg;
|
||||
}
|
||||
if($type eq "bool") {
|
||||
$reg = "$reg != 0";
|
||||
}
|
||||
if($type eq "int64" && $_32bit ne "") {
|
||||
# 64-bit number in r1:r0 or r0:r1.
|
||||
if($i+2 > @out) {
|
||||
print STDERR "$ARGV:$.: not enough registers for int64 return\n";
|
||||
}
|
||||
if($_32bit eq "big-endian") {
|
||||
$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i, $i+1);
|
||||
} else {
|
||||
$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i+1, $i);
|
||||
}
|
||||
$ret[$i] = sprintf("r%d", $i);
|
||||
$ret[$i+1] = sprintf("r%d", $i+1);
|
||||
}
|
||||
if($reg ne "e1" || $plan9) {
|
||||
$body .= "\t$name = $type($reg)\n";
|
||||
}
|
||||
}
|
||||
if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") {
|
||||
$text .= "\t$call\n";
|
||||
} else {
|
||||
if ($errvar ne "") {
|
||||
$text .= "\t$ret[0], $ret[1], $ret[2] := $call\n";
|
||||
} else {
|
||||
$text .= "\t$ret[0], $ret[1] := $call\n";
|
||||
}
|
||||
}
|
||||
$text .= $body;
|
||||
|
||||
if ($plan9 && $ret[2] eq "e1") {
|
||||
$text .= "\tif int32(r0) == -1 {\n";
|
||||
$text .= "\t\terr = e1\n";
|
||||
$text .= "\t}\n";
|
||||
} elsif ($do_errno) {
|
||||
$text .= "\tif e1 != 0 {\n";
|
||||
$text .= "\t\terr = errnoErr(e1)\n";
|
||||
$text .= "\t}\n";
|
||||
}
|
||||
$text .= "\treturn\n";
|
||||
$text .= "}\n\n";
|
||||
}
|
||||
|
||||
chomp $text;
|
||||
chomp $text;
|
||||
|
||||
if($errors) {
|
||||
exit 1;
|
||||
}
|
||||
|
||||
print <<EOF;
|
||||
// $cmdline
|
||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||
|
||||
// +build $tags
|
||||
|
||||
package unix
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var _ syscall.Errno
|
||||
|
||||
$text
|
||||
EOF
|
||||
exit 0;
|
|
@ -1,289 +0,0 @@
|
|||
#!/usr/bin/env perl
|
||||
# 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.
|
||||
|
||||
# This program reads a file containing function prototypes
|
||||
# (like syscall_solaris.go) and generates system call bodies.
|
||||
# The prototypes are marked by lines beginning with "//sys"
|
||||
# and read like func declarations if //sys is replaced by func, but:
|
||||
# * The parameter lists must give a name for each argument.
|
||||
# This includes return parameters.
|
||||
# * The parameter lists must give a type for each argument:
|
||||
# the (x, y, z int) shorthand is not allowed.
|
||||
# * If the return parameter is an error number, it must be named err.
|
||||
# * If go func name needs to be different than its libc name,
|
||||
# * or the function is not in libc, name could be specified
|
||||
# * at the end, after "=" sign, like
|
||||
# //sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt
|
||||
|
||||
use strict;
|
||||
|
||||
my $cmdline = "mksyscall_solaris.pl " . join(' ', @ARGV);
|
||||
my $errors = 0;
|
||||
my $_32bit = "";
|
||||
my $tags = ""; # build tags
|
||||
|
||||
binmode STDOUT;
|
||||
|
||||
if($ARGV[0] eq "-b32") {
|
||||
$_32bit = "big-endian";
|
||||
shift;
|
||||
} elsif($ARGV[0] eq "-l32") {
|
||||
$_32bit = "little-endian";
|
||||
shift;
|
||||
}
|
||||
if($ARGV[0] eq "-tags") {
|
||||
shift;
|
||||
$tags = $ARGV[0];
|
||||
shift;
|
||||
}
|
||||
|
||||
if($ARGV[0] =~ /^-/) {
|
||||
print STDERR "usage: mksyscall_solaris.pl [-b32 | -l32] [-tags x,y] [file ...]\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
sub parseparamlist($) {
|
||||
my ($list) = @_;
|
||||
$list =~ s/^\s*//;
|
||||
$list =~ s/\s*$//;
|
||||
if($list eq "") {
|
||||
return ();
|
||||
}
|
||||
return split(/\s*,\s*/, $list);
|
||||
}
|
||||
|
||||
sub parseparam($) {
|
||||
my ($p) = @_;
|
||||
if($p !~ /^(\S*) (\S*)$/) {
|
||||
print STDERR "$ARGV:$.: malformed parameter: $p\n";
|
||||
$errors = 1;
|
||||
return ("xx", "int");
|
||||
}
|
||||
return ($1, $2);
|
||||
}
|
||||
|
||||
my $package = "";
|
||||
my $text = "";
|
||||
my $dynimports = "";
|
||||
my $linknames = "";
|
||||
my @vars = ();
|
||||
while(<>) {
|
||||
chomp;
|
||||
s/\s+/ /g;
|
||||
s/^\s+//;
|
||||
s/\s+$//;
|
||||
$package = $1 if !$package && /^package (\S+)$/;
|
||||
my $nonblock = /^\/\/sysnb /;
|
||||
next if !/^\/\/sys / && !$nonblock;
|
||||
|
||||
# Line must be of the form
|
||||
# func Open(path string, mode int, perm int) (fd int, err error)
|
||||
# Split into name, in params, out params.
|
||||
if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$/) {
|
||||
print STDERR "$ARGV:$.: malformed //sys declaration\n";
|
||||
$errors = 1;
|
||||
next;
|
||||
}
|
||||
my ($nb, $func, $in, $out, $modname, $sysname) = ($1, $2, $3, $4, $5, $6);
|
||||
|
||||
# Split argument lists on comma.
|
||||
my @in = parseparamlist($in);
|
||||
my @out = parseparamlist($out);
|
||||
|
||||
# So file name.
|
||||
if($modname eq "") {
|
||||
$modname = "libc";
|
||||
}
|
||||
|
||||
# System call name.
|
||||
if($sysname eq "") {
|
||||
$sysname = "$func";
|
||||
}
|
||||
|
||||
# System call pointer variable name.
|
||||
my $sysvarname = "proc$sysname";
|
||||
|
||||
my $strconvfunc = "BytePtrFromString";
|
||||
my $strconvtype = "*byte";
|
||||
|
||||
$sysname =~ y/A-Z/a-z/; # All libc functions are lowercase.
|
||||
|
||||
# Runtime import of function to allow cross-platform builds.
|
||||
$dynimports .= "//go:cgo_import_dynamic libc_${sysname} ${sysname} \"$modname.so\"\n";
|
||||
# Link symbol to proc address variable.
|
||||
$linknames .= "//go:linkname ${sysvarname} libc_${sysname}\n";
|
||||
# Library proc address variable.
|
||||
push @vars, $sysvarname;
|
||||
|
||||
# Go function header.
|
||||
$out = join(', ', @out);
|
||||
if($out ne "") {
|
||||
$out = " ($out)";
|
||||
}
|
||||
if($text ne "") {
|
||||
$text .= "\n"
|
||||
}
|
||||
$text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out;
|
||||
|
||||
# Check if err return available
|
||||
my $errvar = "";
|
||||
foreach my $p (@out) {
|
||||
my ($name, $type) = parseparam($p);
|
||||
if($type eq "error") {
|
||||
$errvar = $name;
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
# Prepare arguments to Syscall.
|
||||
my @args = ();
|
||||
my $n = 0;
|
||||
foreach my $p (@in) {
|
||||
my ($name, $type) = parseparam($p);
|
||||
if($type =~ /^\*/) {
|
||||
push @args, "uintptr(unsafe.Pointer($name))";
|
||||
} elsif($type eq "string" && $errvar ne "") {
|
||||
$text .= "\tvar _p$n $strconvtype\n";
|
||||
$text .= "\t_p$n, $errvar = $strconvfunc($name)\n";
|
||||
$text .= "\tif $errvar != nil {\n\t\treturn\n\t}\n";
|
||||
push @args, "uintptr(unsafe.Pointer(_p$n))";
|
||||
$n++;
|
||||
} elsif($type eq "string") {
|
||||
print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n";
|
||||
$text .= "\tvar _p$n $strconvtype\n";
|
||||
$text .= "\t_p$n, _ = $strconvfunc($name)\n";
|
||||
push @args, "uintptr(unsafe.Pointer(_p$n))";
|
||||
$n++;
|
||||
} elsif($type =~ /^\[\](.*)/) {
|
||||
# Convert slice into pointer, length.
|
||||
# Have to be careful not to take address of &a[0] if len == 0:
|
||||
# pass nil in that case.
|
||||
$text .= "\tvar _p$n *$1\n";
|
||||
$text .= "\tif len($name) > 0 {\n\t\t_p$n = \&$name\[0]\n\t}\n";
|
||||
push @args, "uintptr(unsafe.Pointer(_p$n))", "uintptr(len($name))";
|
||||
$n++;
|
||||
} elsif($type eq "int64" && $_32bit ne "") {
|
||||
if($_32bit eq "big-endian") {
|
||||
push @args, "uintptr($name >> 32)", "uintptr($name)";
|
||||
} else {
|
||||
push @args, "uintptr($name)", "uintptr($name >> 32)";
|
||||
}
|
||||
} elsif($type eq "bool") {
|
||||
$text .= "\tvar _p$n uint32\n";
|
||||
$text .= "\tif $name {\n\t\t_p$n = 1\n\t} else {\n\t\t_p$n = 0\n\t}\n";
|
||||
push @args, "uintptr(_p$n)";
|
||||
$n++;
|
||||
} else {
|
||||
push @args, "uintptr($name)";
|
||||
}
|
||||
}
|
||||
my $nargs = @args;
|
||||
|
||||
# Determine which form to use; pad args with zeros.
|
||||
my $asm = "sysvicall6";
|
||||
if ($nonblock) {
|
||||
$asm = "rawSysvicall6";
|
||||
}
|
||||
if(@args <= 6) {
|
||||
while(@args < 6) {
|
||||
push @args, "0";
|
||||
}
|
||||
} else {
|
||||
print STDERR "$ARGV:$.: too many arguments to system call\n";
|
||||
}
|
||||
|
||||
# Actual call.
|
||||
my $args = join(', ', @args);
|
||||
my $call = "$asm(uintptr(unsafe.Pointer(&$sysvarname)), $nargs, $args)";
|
||||
|
||||
# Assign return values.
|
||||
my $body = "";
|
||||
my $failexpr = "";
|
||||
my @ret = ("_", "_", "_");
|
||||
my @pout= ();
|
||||
my $do_errno = 0;
|
||||
for(my $i=0; $i<@out; $i++) {
|
||||
my $p = $out[$i];
|
||||
my ($name, $type) = parseparam($p);
|
||||
my $reg = "";
|
||||
if($name eq "err") {
|
||||
$reg = "e1";
|
||||
$ret[2] = $reg;
|
||||
$do_errno = 1;
|
||||
} else {
|
||||
$reg = sprintf("r%d", $i);
|
||||
$ret[$i] = $reg;
|
||||
}
|
||||
if($type eq "bool") {
|
||||
$reg = "$reg != 0";
|
||||
}
|
||||
if($type eq "int64" && $_32bit ne "") {
|
||||
# 64-bit number in r1:r0 or r0:r1.
|
||||
if($i+2 > @out) {
|
||||
print STDERR "$ARGV:$.: not enough registers for int64 return\n";
|
||||
}
|
||||
if($_32bit eq "big-endian") {
|
||||
$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i, $i+1);
|
||||
} else {
|
||||
$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i+1, $i);
|
||||
}
|
||||
$ret[$i] = sprintf("r%d", $i);
|
||||
$ret[$i+1] = sprintf("r%d", $i+1);
|
||||
}
|
||||
if($reg ne "e1") {
|
||||
$body .= "\t$name = $type($reg)\n";
|
||||
}
|
||||
}
|
||||
if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") {
|
||||
$text .= "\t$call\n";
|
||||
} else {
|
||||
$text .= "\t$ret[0], $ret[1], $ret[2] := $call\n";
|
||||
}
|
||||
$text .= $body;
|
||||
|
||||
if ($do_errno) {
|
||||
$text .= "\tif e1 != 0 {\n";
|
||||
$text .= "\t\terr = e1\n";
|
||||
$text .= "\t}\n";
|
||||
}
|
||||
$text .= "\treturn\n";
|
||||
$text .= "}\n";
|
||||
}
|
||||
|
||||
if($errors) {
|
||||
exit 1;
|
||||
}
|
||||
|
||||
print <<EOF;
|
||||
// $cmdline
|
||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||
|
||||
// +build $tags
|
||||
|
||||
package $package
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
EOF
|
||||
|
||||
print "import \"golang.org/x/sys/unix\"\n" if $package ne "unix";
|
||||
|
||||
my $vardecls = "\t" . join(",\n\t", @vars);
|
||||
$vardecls .= " syscallFunc";
|
||||
|
||||
chomp($_=<<EOF);
|
||||
|
||||
$dynimports
|
||||
$linknames
|
||||
var (
|
||||
$vardecls
|
||||
)
|
||||
|
||||
$text
|
||||
EOF
|
||||
print $_;
|
||||
exit 0;
|
|
@ -1,264 +0,0 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
# 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.
|
||||
|
||||
#
|
||||
# Parse the header files for OpenBSD and generate a Go usable sysctl MIB.
|
||||
#
|
||||
# Build a MIB with each entry being an array containing the level, type and
|
||||
# a hash that will contain additional entries if the current entry is a node.
|
||||
# We then walk this MIB and create a flattened sysctl name to OID hash.
|
||||
#
|
||||
|
||||
use strict;
|
||||
|
||||
if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") {
|
||||
print STDERR "GOARCH or GOOS not defined in environment\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my $debug = 0;
|
||||
my %ctls = ();
|
||||
|
||||
my @headers = qw (
|
||||
sys/sysctl.h
|
||||
sys/socket.h
|
||||
sys/tty.h
|
||||
sys/malloc.h
|
||||
sys/mount.h
|
||||
sys/namei.h
|
||||
sys/sem.h
|
||||
sys/shm.h
|
||||
sys/vmmeter.h
|
||||
uvm/uvm_param.h
|
||||
uvm/uvm_swap_encrypt.h
|
||||
ddb/db_var.h
|
||||
net/if.h
|
||||
net/if_pfsync.h
|
||||
net/pipex.h
|
||||
netinet/in.h
|
||||
netinet/icmp_var.h
|
||||
netinet/igmp_var.h
|
||||
netinet/ip_ah.h
|
||||
netinet/ip_carp.h
|
||||
netinet/ip_divert.h
|
||||
netinet/ip_esp.h
|
||||
netinet/ip_ether.h
|
||||
netinet/ip_gre.h
|
||||
netinet/ip_ipcomp.h
|
||||
netinet/ip_ipip.h
|
||||
netinet/pim_var.h
|
||||
netinet/tcp_var.h
|
||||
netinet/udp_var.h
|
||||
netinet6/in6.h
|
||||
netinet6/ip6_divert.h
|
||||
netinet6/pim6_var.h
|
||||
netinet/icmp6.h
|
||||
netmpls/mpls.h
|
||||
);
|
||||
|
||||
my @ctls = qw (
|
||||
kern
|
||||
vm
|
||||
fs
|
||||
net
|
||||
#debug # Special handling required
|
||||
hw
|
||||
#machdep # Arch specific
|
||||
user
|
||||
ddb
|
||||
#vfs # Special handling required
|
||||
fs.posix
|
||||
kern.forkstat
|
||||
kern.intrcnt
|
||||
kern.malloc
|
||||
kern.nchstats
|
||||
kern.seminfo
|
||||
kern.shminfo
|
||||
kern.timecounter
|
||||
kern.tty
|
||||
kern.watchdog
|
||||
net.bpf
|
||||
net.ifq
|
||||
net.inet
|
||||
net.inet.ah
|
||||
net.inet.carp
|
||||
net.inet.divert
|
||||
net.inet.esp
|
||||
net.inet.etherip
|
||||
net.inet.gre
|
||||
net.inet.icmp
|
||||
net.inet.igmp
|
||||
net.inet.ip
|
||||
net.inet.ip.ifq
|
||||
net.inet.ipcomp
|
||||
net.inet.ipip
|
||||
net.inet.mobileip
|
||||
net.inet.pfsync
|
||||
net.inet.pim
|
||||
net.inet.tcp
|
||||
net.inet.udp
|
||||
net.inet6
|
||||
net.inet6.divert
|
||||
net.inet6.ip6
|
||||
net.inet6.icmp6
|
||||
net.inet6.pim6
|
||||
net.inet6.tcp6
|
||||
net.inet6.udp6
|
||||
net.mpls
|
||||
net.mpls.ifq
|
||||
net.key
|
||||
net.pflow
|
||||
net.pfsync
|
||||
net.pipex
|
||||
net.rt
|
||||
vm.swapencrypt
|
||||
#vfsgenctl # Special handling required
|
||||
);
|
||||
|
||||
# Node name "fixups"
|
||||
my %ctl_map = (
|
||||
"ipproto" => "net.inet",
|
||||
"net.inet.ipproto" => "net.inet",
|
||||
"net.inet6.ipv6proto" => "net.inet6",
|
||||
"net.inet6.ipv6" => "net.inet6.ip6",
|
||||
"net.inet.icmpv6" => "net.inet6.icmp6",
|
||||
"net.inet6.divert6" => "net.inet6.divert",
|
||||
"net.inet6.tcp6" => "net.inet.tcp",
|
||||
"net.inet6.udp6" => "net.inet.udp",
|
||||
"mpls" => "net.mpls",
|
||||
"swpenc" => "vm.swapencrypt"
|
||||
);
|
||||
|
||||
# Node mappings
|
||||
my %node_map = (
|
||||
"net.inet.ip.ifq" => "net.ifq",
|
||||
"net.inet.pfsync" => "net.pfsync",
|
||||
"net.mpls.ifq" => "net.ifq"
|
||||
);
|
||||
|
||||
my $ctlname;
|
||||
my %mib = ();
|
||||
my %sysctl = ();
|
||||
my $node;
|
||||
|
||||
sub debug() {
|
||||
print STDERR "$_[0]\n" if $debug;
|
||||
}
|
||||
|
||||
# Walk the MIB and build a sysctl name to OID mapping.
|
||||
sub build_sysctl() {
|
||||
my ($node, $name, $oid) = @_;
|
||||
my %node = %{$node};
|
||||
my @oid = @{$oid};
|
||||
|
||||
foreach my $key (sort keys %node) {
|
||||
my @node = @{$node{$key}};
|
||||
my $nodename = $name.($name ne '' ? '.' : '').$key;
|
||||
my @nodeoid = (@oid, $node[0]);
|
||||
if ($node[1] eq 'CTLTYPE_NODE') {
|
||||
if (exists $node_map{$nodename}) {
|
||||
$node = \%mib;
|
||||
$ctlname = $node_map{$nodename};
|
||||
foreach my $part (split /\./, $ctlname) {
|
||||
$node = \%{@{$$node{$part}}[2]};
|
||||
}
|
||||
} else {
|
||||
$node = $node[2];
|
||||
}
|
||||
&build_sysctl($node, $nodename, \@nodeoid);
|
||||
} elsif ($node[1] ne '') {
|
||||
$sysctl{$nodename} = \@nodeoid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $ctl (@ctls) {
|
||||
$ctls{$ctl} = $ctl;
|
||||
}
|
||||
|
||||
# Build MIB
|
||||
foreach my $header (@headers) {
|
||||
&debug("Processing $header...");
|
||||
open HEADER, "/usr/include/$header" ||
|
||||
print STDERR "Failed to open $header\n";
|
||||
while (<HEADER>) {
|
||||
if ($_ =~ /^#define\s+(CTL_NAMES)\s+{/ ||
|
||||
$_ =~ /^#define\s+(CTL_(.*)_NAMES)\s+{/ ||
|
||||
$_ =~ /^#define\s+((.*)CTL_NAMES)\s+{/) {
|
||||
if ($1 eq 'CTL_NAMES') {
|
||||
# Top level.
|
||||
$node = \%mib;
|
||||
} else {
|
||||
# Node.
|
||||
my $nodename = lc($2);
|
||||
if ($header =~ /^netinet\//) {
|
||||
$ctlname = "net.inet.$nodename";
|
||||
} elsif ($header =~ /^netinet6\//) {
|
||||
$ctlname = "net.inet6.$nodename";
|
||||
} elsif ($header =~ /^net\//) {
|
||||
$ctlname = "net.$nodename";
|
||||
} else {
|
||||
$ctlname = "$nodename";
|
||||
$ctlname =~ s/^(fs|net|kern)_/$1\./;
|
||||
}
|
||||
if (exists $ctl_map{$ctlname}) {
|
||||
$ctlname = $ctl_map{$ctlname};
|
||||
}
|
||||
if (not exists $ctls{$ctlname}) {
|
||||
&debug("Ignoring $ctlname...");
|
||||
next;
|
||||
}
|
||||
|
||||
# Walk down from the top of the MIB.
|
||||
$node = \%mib;
|
||||
foreach my $part (split /\./, $ctlname) {
|
||||
if (not exists $$node{$part}) {
|
||||
&debug("Missing node $part");
|
||||
$$node{$part} = [ 0, '', {} ];
|
||||
}
|
||||
$node = \%{@{$$node{$part}}[2]};
|
||||
}
|
||||
}
|
||||
|
||||
# Populate current node with entries.
|
||||
my $i = -1;
|
||||
while (defined($_) && $_ !~ /^}/) {
|
||||
$_ = <HEADER>;
|
||||
$i++ if $_ =~ /{.*}/;
|
||||
next if $_ !~ /{\s+"(\w+)",\s+(CTLTYPE_[A-Z]+)\s+}/;
|
||||
$$node{$1} = [ $i, $2, {} ];
|
||||
}
|
||||
}
|
||||
}
|
||||
close HEADER;
|
||||
}
|
||||
|
||||
&build_sysctl(\%mib, "", []);
|
||||
|
||||
print <<EOF;
|
||||
// mksysctl_openbsd.pl
|
||||
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
|
||||
|
||||
// +build $ENV{'GOARCH'},$ENV{'GOOS'}
|
||||
|
||||
package unix;
|
||||
|
||||
type mibentry struct {
|
||||
ctlname string
|
||||
ctloid []_C_int
|
||||
}
|
||||
|
||||
var sysctlMib = []mibentry {
|
||||
EOF
|
||||
|
||||
foreach my $name (sort keys %sysctl) {
|
||||
my @oid = @{$sysctl{$name}};
|
||||
print "\t{ \"$name\", []_C_int{ ", join(', ', @oid), " } }, \n";
|
||||
}
|
||||
|
||||
print <<EOF;
|
||||
}
|
||||
EOF
|
|
@ -1,39 +0,0 @@
|
|||
#!/usr/bin/env perl
|
||||
# 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.
|
||||
#
|
||||
# Generate system call table for Darwin from sys/syscall.h
|
||||
|
||||
use strict;
|
||||
|
||||
if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") {
|
||||
print STDERR "GOARCH or GOOS not defined in environment\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my $command = "mksysnum_darwin.pl " . join(' ', @ARGV);
|
||||
|
||||
print <<EOF;
|
||||
// $command
|
||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||
|
||||
// +build $ENV{'GOARCH'},$ENV{'GOOS'}
|
||||
|
||||
package unix
|
||||
|
||||
const (
|
||||
EOF
|
||||
|
||||
while(<>){
|
||||
if(/^#define\s+SYS_(\w+)\s+([0-9]+)/){
|
||||
my $name = $1;
|
||||
my $num = $2;
|
||||
$name =~ y/a-z/A-Z/;
|
||||
print " SYS_$name = $num;"
|
||||
}
|
||||
}
|
||||
|
||||
print <<EOF;
|
||||
)
|
||||
EOF
|
|
@ -1,50 +0,0 @@
|
|||
#!/usr/bin/env perl
|
||||
# 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.
|
||||
#
|
||||
# Generate system call table for DragonFly from master list
|
||||
# (for example, /usr/src/sys/kern/syscalls.master).
|
||||
|
||||
use strict;
|
||||
|
||||
if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") {
|
||||
print STDERR "GOARCH or GOOS not defined in environment\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my $command = "mksysnum_dragonfly.pl " . join(' ', @ARGV);
|
||||
|
||||
print <<EOF;
|
||||
// $command
|
||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||
|
||||
// +build $ENV{'GOARCH'},$ENV{'GOOS'}
|
||||
|
||||
package unix
|
||||
|
||||
const (
|
||||
EOF
|
||||
|
||||
while(<>){
|
||||
if(/^([0-9]+)\s+STD\s+({ \S+\s+(\w+).*)$/){
|
||||
my $num = $1;
|
||||
my $proto = $2;
|
||||
my $name = "SYS_$3";
|
||||
$name =~ y/a-z/A-Z/;
|
||||
|
||||
# There are multiple entries for enosys and nosys, so comment them out.
|
||||
if($name =~ /^SYS_E?NOSYS$/){
|
||||
$name = "// $name";
|
||||
}
|
||||
if($name eq 'SYS_SYS_EXIT'){
|
||||
$name = 'SYS_EXIT';
|
||||
}
|
||||
|
||||
print " $name = $num; // $proto\n";
|
||||
}
|
||||
}
|
||||
|
||||
print <<EOF;
|
||||
)
|
||||
EOF
|
|
@ -1,50 +0,0 @@
|
|||
#!/usr/bin/env perl
|
||||
# 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.
|
||||
#
|
||||
# Generate system call table for FreeBSD from master list
|
||||
# (for example, /usr/src/sys/kern/syscalls.master).
|
||||
|
||||
use strict;
|
||||
|
||||
if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") {
|
||||
print STDERR "GOARCH or GOOS not defined in environment\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my $command = "mksysnum_freebsd.pl " . join(' ', @ARGV);
|
||||
|
||||
print <<EOF;
|
||||
// $command
|
||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||
|
||||
// +build $ENV{'GOARCH'},$ENV{'GOOS'}
|
||||
|
||||
package unix
|
||||
|
||||
const (
|
||||
EOF
|
||||
|
||||
while(<>){
|
||||
if(/^([0-9]+)\s+\S+\s+STD\s+({ \S+\s+(\w+).*)$/){
|
||||
my $num = $1;
|
||||
my $proto = $2;
|
||||
my $name = "SYS_$3";
|
||||
$name =~ y/a-z/A-Z/;
|
||||
|
||||
# There are multiple entries for enosys and nosys, so comment them out.
|
||||
if($name =~ /^SYS_E?NOSYS$/){
|
||||
$name = "// $name";
|
||||
}
|
||||
if($name eq 'SYS_SYS_EXIT'){
|
||||
$name = 'SYS_EXIT';
|
||||
}
|
||||
|
||||
print " $name = $num; // $proto\n";
|
||||
}
|
||||
}
|
||||
|
||||
print <<EOF;
|
||||
)
|
||||
EOF
|
|
@ -1,58 +0,0 @@
|
|||
#!/usr/bin/env perl
|
||||
# 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.
|
||||
#
|
||||
# Generate system call table for OpenBSD from master list
|
||||
# (for example, /usr/src/sys/kern/syscalls.master).
|
||||
|
||||
use strict;
|
||||
|
||||
if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") {
|
||||
print STDERR "GOARCH or GOOS not defined in environment\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my $command = "mksysnum_netbsd.pl " . join(' ', @ARGV);
|
||||
|
||||
print <<EOF;
|
||||
// $command
|
||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||
|
||||
// +build $ENV{'GOARCH'},$ENV{'GOOS'}
|
||||
|
||||
package unix
|
||||
|
||||
const (
|
||||
EOF
|
||||
|
||||
my $line = '';
|
||||
while(<>){
|
||||
if($line =~ /^(.*)\\$/) {
|
||||
# Handle continuation
|
||||
$line = $1;
|
||||
$_ =~ s/^\s+//;
|
||||
$line .= $_;
|
||||
} else {
|
||||
# New line
|
||||
$line = $_;
|
||||
}
|
||||
next if $line =~ /\\$/;
|
||||
if($line =~ /^([0-9]+)\s+((STD)|(NOERR))\s+(RUMP\s+)?({\s+\S+\s*\*?\s*\|(\S+)\|(\S*)\|(\w+).*\s+})(\s+(\S+))?$/) {
|
||||
my $num = $1;
|
||||
my $proto = $6;
|
||||
my $compat = $8;
|
||||
my $name = "$7_$9";
|
||||
|
||||
$name = "$7_$11" if $11 ne '';
|
||||
$name =~ y/a-z/A-Z/;
|
||||
|
||||
if($compat eq '' || $compat eq '13' || $compat eq '30' || $compat eq '50') {
|
||||
print " $name = $num; // $proto\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print <<EOF;
|
||||
)
|
||||
EOF
|
|
@ -1,50 +0,0 @@
|
|||
#!/usr/bin/env perl
|
||||
# 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.
|
||||
#
|
||||
# Generate system call table for OpenBSD from master list
|
||||
# (for example, /usr/src/sys/kern/syscalls.master).
|
||||
|
||||
use strict;
|
||||
|
||||
if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") {
|
||||
print STDERR "GOARCH or GOOS not defined in environment\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my $command = "mksysnum_openbsd.pl " . join(' ', @ARGV);
|
||||
|
||||
print <<EOF;
|
||||
// $command
|
||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||
|
||||
// +build $ENV{'GOARCH'},$ENV{'GOOS'}
|
||||
|
||||
package unix
|
||||
|
||||
const (
|
||||
EOF
|
||||
|
||||
while(<>){
|
||||
if(/^([0-9]+)\s+STD\s+(NOLOCK\s+)?({ \S+\s+\*?(\w+).*)$/){
|
||||
my $num = $1;
|
||||
my $proto = $3;
|
||||
my $name = $4;
|
||||
$name =~ y/a-z/A-Z/;
|
||||
|
||||
# There are multiple entries for enosys and nosys, so comment them out.
|
||||
if($name =~ /^SYS_E?NOSYS$/){
|
||||
$name = "// $name";
|
||||
}
|
||||
if($name eq 'SYS_SYS_EXIT'){
|
||||
$name = 'SYS_EXIT';
|
||||
}
|
||||
|
||||
print " $name = $num; // $proto\n";
|
||||
}
|
||||
}
|
||||
|
||||
print <<EOF;
|
||||
)
|
||||
EOF
|
|
@ -1,16 +0,0 @@
|
|||
# Copyright 2013 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.
|
||||
|
||||
CLEANFILES+=maketables
|
||||
|
||||
maketables: maketables.go
|
||||
go build $^
|
||||
|
||||
tables: maketables
|
||||
./maketables > tables.go
|
||||
gofmt -w -s tables.go
|
||||
|
||||
# Build (but do not run) maketables during testing,
|
||||
# just to make sure it still compiles.
|
||||
testshort: maketables
|
|
@ -1,3 +0,0 @@
|
|||
language: go
|
||||
go: 1.2
|
||||
|
|
@ -1,245 +0,0 @@
|
|||
# Set [![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](https://godoc.org/gopkg.in/fatih/set.v0) [![Build Status](http://img.shields.io/travis/fatih/set.svg?style=flat-square)](https://travis-ci.org/fatih/set)
|
||||
|
||||
Set is a basic and simple, hash-based, **Set** data structure implementation
|
||||
in Go (Golang).
|
||||
|
||||
Set provides both threadsafe and non-threadsafe implementations of a generic
|
||||
set data structure. The thread safety encompasses all operations on one set.
|
||||
Operations on multiple sets are consistent in that the elements of each set
|
||||
used was valid at exactly one point in time between the start and the end of
|
||||
the operation. Because it's thread safe, you can use it concurrently with your
|
||||
goroutines.
|
||||
|
||||
For usage see examples below or click on the godoc badge.
|
||||
|
||||
## Install and Usage
|
||||
|
||||
Install the package with:
|
||||
|
||||
```bash
|
||||
go get gopkg.in/fatih/set.v0
|
||||
```
|
||||
|
||||
Import it with:
|
||||
|
||||
```go
|
||||
import "gopkg.in/fatih/set.v0"
|
||||
```
|
||||
|
||||
and use `set` as the package name inside the code.
|
||||
|
||||
## Examples
|
||||
|
||||
#### Initialization of a new Set
|
||||
|
||||
```go
|
||||
|
||||
// create a set with zero items
|
||||
s := set.New()
|
||||
s := set.NewNonTS() // non thread-safe version
|
||||
|
||||
// ... or with some initial values
|
||||
s := set.New("istanbul", "frankfurt", 30.123, "san francisco", 1234)
|
||||
s := set.NewNonTS("kenya", "ethiopia", "sumatra")
|
||||
|
||||
```
|
||||
|
||||
#### Basic Operations
|
||||
|
||||
```go
|
||||
// add items
|
||||
s.Add("istanbul")
|
||||
s.Add("istanbul") // nothing happens if you add duplicate item
|
||||
|
||||
// add multiple items
|
||||
s.Add("ankara", "san francisco", 3.14)
|
||||
|
||||
// remove item
|
||||
s.Remove("frankfurt")
|
||||
s.Remove("frankfurt") // nothing happes if you remove a nonexisting item
|
||||
|
||||
// remove multiple items
|
||||
s.Remove("barcelona", 3.14, "ankara")
|
||||
|
||||
// removes an arbitary item and return it
|
||||
item := s.Pop()
|
||||
|
||||
// create a new copy
|
||||
other := s.Copy()
|
||||
|
||||
// remove all items
|
||||
s.Clear()
|
||||
|
||||
// number of items in the set
|
||||
len := s.Size()
|
||||
|
||||
// return a list of items
|
||||
items := s.List()
|
||||
|
||||
// string representation of set
|
||||
fmt.Printf("set is %s", s.String())
|
||||
|
||||
```
|
||||
|
||||
#### Check Operations
|
||||
|
||||
```go
|
||||
// check for set emptiness, returns true if set is empty
|
||||
s.IsEmpty()
|
||||
|
||||
// check for a single item exist
|
||||
s.Has("istanbul")
|
||||
|
||||
// ... or for multiple items. This will return true if all of the items exist.
|
||||
s.Has("istanbul", "san francisco", 3.14)
|
||||
|
||||
// create two sets for the following checks...
|
||||
s := s.New("1", "2", "3", "4", "5")
|
||||
t := s.New("1", "2", "3")
|
||||
|
||||
|
||||
// check if they are the same
|
||||
if !s.IsEqual(t) {
|
||||
fmt.Println("s is not equal to t")
|
||||
}
|
||||
|
||||
// if s contains all elements of t
|
||||
if s.IsSubset(t) {
|
||||
fmt.Println("t is a subset of s")
|
||||
}
|
||||
|
||||
// ... or if s is a superset of t
|
||||
if t.IsSuperset(s) {
|
||||
fmt.Println("s is a superset of t")
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
#### Set Operations
|
||||
|
||||
|
||||
```go
|
||||
// let us initialize two sets with some values
|
||||
a := set.New("ankara", "berlin", "san francisco")
|
||||
b := set.New("frankfurt", "berlin")
|
||||
|
||||
// creates a new set with the items in a and b combined.
|
||||
// [frankfurt, berlin, ankara, san francisco]
|
||||
c := set.Union(a, b)
|
||||
|
||||
// contains items which is in both a and b
|
||||
// [berlin]
|
||||
c := set.Intersection(a, b)
|
||||
|
||||
// contains items which are in a but not in b
|
||||
// [ankara, san francisco]
|
||||
c := set.Difference(a, b)
|
||||
|
||||
// contains items which are in one of either, but not in both.
|
||||
// [frankfurt, ankara, san francisco]
|
||||
c := set.SymmetricDifference(a, b)
|
||||
|
||||
```
|
||||
|
||||
```go
|
||||
// like Union but saves the result back into a.
|
||||
a.Merge(b)
|
||||
|
||||
// removes the set items which are in b from a and saves the result back into a.
|
||||
a.Separate(b)
|
||||
|
||||
```
|
||||
|
||||
#### Multiple Set Operations
|
||||
|
||||
```go
|
||||
a := set.New("1", "3", "4", "5")
|
||||
b := set.New("2", "3", "4", "5")
|
||||
c := set.New("4", "5", "6", "7")
|
||||
|
||||
// creates a new set with items in a, b and c
|
||||
// [1 2 3 4 5 6 7]
|
||||
u := set.Union(a, b, c)
|
||||
|
||||
// creates a new set with items in a but not in b and c
|
||||
// [1]
|
||||
u := set.Difference(a, b, c)
|
||||
|
||||
// creates a new set with items that are common to a, b and c
|
||||
// [5]
|
||||
u := set.Intersection(a, b, c)
|
||||
```
|
||||
|
||||
#### Helper methods
|
||||
|
||||
The Slice functions below are a convenient way to extract or convert your Set data
|
||||
into basic data types.
|
||||
|
||||
|
||||
```go
|
||||
// create a set of mixed types
|
||||
s := set.New("ankara", "5", "8", "san francisco", 13, 21)
|
||||
|
||||
|
||||
// convert s into a slice of strings (type is []string)
|
||||
// [ankara 5 8 san francisco]
|
||||
t := set.StringSlice(s)
|
||||
|
||||
|
||||
// u contains a slice of ints (type is []int)
|
||||
// [13, 21]
|
||||
u := set.IntSlice(s)
|
||||
|
||||
```
|
||||
|
||||
#### Concurrent safe usage
|
||||
|
||||
Below is an example of a concurrent way that uses set. We call ten functions
|
||||
concurrently and wait until they are finished. It basically creates a new
|
||||
string for each goroutine and adds it to our set.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/fatih/set"
|
||||
"strconv"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var wg sync.WaitGroup // this is just for waiting until all goroutines finish
|
||||
|
||||
// Initialize our thread safe Set
|
||||
s := set.New()
|
||||
|
||||
// Add items concurrently (item1, item2, and so on)
|
||||
for i := 0; i < 10; i++ {
|
||||
wg.Add(1)
|
||||
go func(i int) {
|
||||
item := "item" + strconv.Itoa(i)
|
||||
fmt.Println("adding", item)
|
||||
s.Add(item)
|
||||
wg.Done()
|
||||
}(i)
|
||||
}
|
||||
|
||||
// Wait until all concurrent calls finished and print our set
|
||||
wg.Wait()
|
||||
fmt.Println(s)
|
||||
}
|
||||
```
|
||||
|
||||
## Credits
|
||||
|
||||
* [Fatih Arslan](https://github.com/fatih)
|
||||
* [Arne Hormann](https://github.com/arnehormann)
|
||||
* [Sam Boyer](https://github.com/sdboyer)
|
||||
* [Ralph Loizzo](https://github.com/friartech)
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT) - see LICENSE.md for more details
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue