Vendoring updates
This commit is contained in:
parent
16f7ddcd58
commit
8b0c907c3d
7
go.mod
7
go.mod
|
@ -3,11 +3,12 @@ module git.kemonine.info/PiFrame
|
||||||
go 1.15
|
go 1.15
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/d2r2/go-bh1750 v0.0.0-20181222061755-1195122364ab
|
github.com/d2r2/go-bh1750 v0.0.0-20181222061755-1195122364ab // indirect
|
||||||
github.com/d2r2/go-i2c v0.0.0-20191123181816-73a8a799d6bc
|
github.com/d2r2/go-i2c v0.0.0-20191123181816-73a8a799d6bc // indirect
|
||||||
github.com/d2r2/go-logger v0.0.0-20181221090742-9998a510495e
|
github.com/d2r2/go-logger v0.0.0-20181221090742-9998a510495e // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/dietsche/rfsnotify v0.0.0-20200716145600-b37be6e4177f
|
github.com/dietsche/rfsnotify v0.0.0-20200716145600-b37be6e4177f
|
||||||
|
github.com/eiannone/keyboard v0.0.0-20200508000154-caf4b762e807
|
||||||
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||||
github.com/gdamore/tcell v1.4.0
|
github.com/gdamore/tcell v1.4.0
|
||||||
github.com/rivo/tview v0.0.0-20200818120338-53d50e499bf9
|
github.com/rivo/tview v0.0.0-20200818120338-53d50e499bf9
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -9,6 +9,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dietsche/rfsnotify v0.0.0-20200716145600-b37be6e4177f h1:b3QvpXLSx1U13VM79rSkA+6Xv4lmT/urEMzA36Yma0U=
|
github.com/dietsche/rfsnotify v0.0.0-20200716145600-b37be6e4177f h1:b3QvpXLSx1U13VM79rSkA+6Xv4lmT/urEMzA36Yma0U=
|
||||||
github.com/dietsche/rfsnotify v0.0.0-20200716145600-b37be6e4177f/go.mod h1:ztitxkMUaBsHRey1tS5xFCd4gm/zAQwA9yfCP5y4cAA=
|
github.com/dietsche/rfsnotify v0.0.0-20200716145600-b37be6e4177f/go.mod h1:ztitxkMUaBsHRey1tS5xFCd4gm/zAQwA9yfCP5y4cAA=
|
||||||
|
github.com/eiannone/keyboard v0.0.0-20200508000154-caf4b762e807 h1:jdjd5e68T4R/j4PWxfZqcKY8KtT9oo8IPNVuV4bSXDQ=
|
||||||
|
github.com/eiannone/keyboard v0.0.0-20200508000154-caf4b762e807/go.mod h1:Xoiu5VdKMvbRgHuY7+z64lhu/7lvax/22nzASF6GrO8=
|
||||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
|
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
|
||||||
|
|
25
vendor/github.com/d2r2/go-bh1750/.travis.yml
generated
vendored
25
vendor/github.com/d2r2/go-bh1750/.travis.yml
generated
vendored
|
@ -1,25 +0,0 @@
|
||||||
language: go
|
|
||||||
go:
|
|
||||||
# - "1.10"
|
|
||||||
- "tip"
|
|
||||||
|
|
||||||
# first part of the GOARCH workaround
|
|
||||||
# setting the GOARCH directly doesn't work, since the value will be overwritten later
|
|
||||||
# so set it to a temporary environment variable first
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
TRAVIS_CGO_ENABLED=1
|
|
||||||
TRAVIS_GOOS=linux
|
|
||||||
matrix:
|
|
||||||
- TRAVIS_GOARCH=amd64
|
|
||||||
- TRAVIS_GOARCH=arm TRAVIS_CC=arm-linux-gnueabi-gcc TRAVIS_GOARM=6
|
|
||||||
|
|
||||||
# second part of the GOARCH workaround
|
|
||||||
# now actually set the GOARCH env variable to the value of the temporary variable set earlier
|
|
||||||
before_install:
|
|
||||||
- sudo apt-get install gcc-arm-linux-gnueabi # for CGO cross compile to ARM
|
|
||||||
- export CGO_ENABLED=$TRAVIS_CGO_ENABLED GOARCH=$TRAVIS_GOARCH GOARM=$TRAVIS_GOARM GOOS=$TRAVIS_GOOS CC=$TRAVIS_CC
|
|
||||||
- go env # for debugging
|
|
||||||
- go tool dist env # for debugging
|
|
||||||
|
|
||||||
|
|
91
vendor/github.com/d2r2/go-bh1750/README.md
generated
vendored
91
vendor/github.com/d2r2/go-bh1750/README.md
generated
vendored
|
@ -1,91 +0,0 @@
|
||||||
|
|
||||||
BH1750 ambient light sensor
|
|
||||||
=====================
|
|
||||||
|
|
||||||
[![Build Status](https://travis-ci.org/d2r2/go-bh1750.svg?branch=master)](https://travis-ci.org/d2r2/go-bh1750)
|
|
||||||
[![Go Report Card](https://goreportcard.com/badge/github.com/d2r2/go-bh1750)](https://goreportcard.com/report/github.com/d2r2/go-bh1750)
|
|
||||||
[![GoDoc](https://godoc.org/github.com/d2r2/go-bh1750?status.svg)](https://godoc.org/github.com/d2r2/go-bh1750)
|
|
||||||
[![MIT License](http://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
|
|
||||||
|
|
||||||
BH1750 ([general specification](https://raw.github.com/d2r2/go-bh1750/master/docs/bh1750fvi-e-186247.pdf)) is a power effective ambient light sensor with spectral response close to human eye. Sensor returns measured ambient light value in lux units. Easily integrated with Arduino and Raspberry PI via i2c communication interface:
|
|
||||||
![image](https://raw.github.com/d2r2/go-bh1750/master/docs/bh1750.jpg)
|
|
||||||
|
|
||||||
Here is a library written in [Go programming language](https://golang.org/) for Raspberry PI and counterparts, which gives you in the output ambient light value (making all necessary i2c-bus interacting and values computing).
|
|
||||||
|
|
||||||
Golang usage
|
|
||||||
------------
|
|
||||||
|
|
||||||
|
|
||||||
```go
|
|
||||||
func main() {
|
|
||||||
// Create new connection to i2c-bus on 0 line with address 0x23.
|
|
||||||
// Use i2cdetect utility to find device address over the i2c-bus
|
|
||||||
i2c, err := i2c.NewI2C(0x23, 0)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
defer i2c.Close()
|
|
||||||
|
|
||||||
sensor := bh1750.NewBH1750()
|
|
||||||
|
|
||||||
resolution := bh1750.HighResolution
|
|
||||||
amb, err := sensor.MeasureAmbientLight(i2c, resolution)
|
|
||||||
if err != nil {
|
|
||||||
lg.Fatal(err)
|
|
||||||
}
|
|
||||||
log.Printf("Ambient light (%s) = %v lx", resolution, amb)
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Getting help
|
|
||||||
------------
|
|
||||||
|
|
||||||
GoDoc [documentation](http://godoc.org/github.com/d2r2/go-bh1750)
|
|
||||||
|
|
||||||
Installation
|
|
||||||
------------
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ go get -u github.com/d2r2/go-bh1750
|
|
||||||
```
|
|
||||||
|
|
||||||
Troubleshooting
|
|
||||||
--------------
|
|
||||||
|
|
||||||
- *How to obtain fresh Golang installation to RPi device (either any RPi clone):*
|
|
||||||
If your RaspberryPI golang installation taken by default from repository is outdated, you may consider
|
|
||||||
to install actual golang manually from official Golang [site](https://golang.org/dl/). Download
|
|
||||||
tar.gz file containing armv6l in the name. Follow installation instructions.
|
|
||||||
|
|
||||||
- *How to enable I2C bus on RPi device:*
|
|
||||||
If you employ RaspberryPI, use raspi-config utility to activate i2c-bus on the OS level.
|
|
||||||
Go to "Interfacing Options" menu, to active I2C bus.
|
|
||||||
Probably you will need to reboot to load i2c kernel module.
|
|
||||||
Finally you should have device like /dev/i2c-1 present in the system.
|
|
||||||
|
|
||||||
- *How to find I2C bus allocation and device address:*
|
|
||||||
Use i2cdetect utility in format "i2cdetect -y X", where X may vary from 0 to 5 or more,
|
|
||||||
to discover address occupied by peripheral device. To install utility you should run
|
|
||||||
`apt install i2c-tools` on debian-kind system. `i2cdetect -y 1` sample output:
|
|
||||||
```
|
|
||||||
0 1 2 3 4 5 6 7 8 9 a b c d e f
|
|
||||||
00: -- -- -- -- -- -- -- -- -- -- -- -- --
|
|
||||||
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
|
||||||
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
|
||||||
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
|
||||||
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
|
||||||
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
|
||||||
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
|
||||||
70: -- -- -- -- -- -- 76 --
|
|
||||||
```
|
|
||||||
|
|
||||||
Contact
|
|
||||||
-------
|
|
||||||
|
|
||||||
Please use [Github issue tracker](https://github.com/d2r2/go-bh1750/issues) for filing bugs or feature requests.
|
|
||||||
|
|
||||||
|
|
||||||
License
|
|
||||||
-------
|
|
||||||
|
|
||||||
Go-bh1750 is licensed under MIT License.
|
|
323
vendor/github.com/d2r2/go-bh1750/bh1750.go
generated
vendored
323
vendor/github.com/d2r2/go-bh1750/bh1750.go
generated
vendored
|
@ -1,323 +0,0 @@
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Denis Dyakov
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
|
||||||
// associated documentation files (the "Software"), to deal in the Software without restriction,
|
|
||||||
// including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
// and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
|
||||||
// subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all copies or substantial
|
|
||||||
// portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
|
||||||
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
||||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
//
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
package bh1750
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"errors"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
i2c "github.com/d2r2/go-i2c"
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Command bytes
|
|
||||||
const (
|
|
||||||
// No active state.
|
|
||||||
CMD_POWER_DOWN = 0x00
|
|
||||||
|
|
||||||
// Waiting for measurement command.
|
|
||||||
CMD_POWER_ON = 0x01
|
|
||||||
|
|
||||||
// Reset Data register value.
|
|
||||||
// Reset command is not acceptable in Power Down mode.
|
|
||||||
CMD_RESET = 0x07
|
|
||||||
|
|
||||||
// Start measurement at 1lx resolution.
|
|
||||||
// Measurement Time is typically 120ms.
|
|
||||||
CMD_CONTINUOUSLY_H_RES_MODE = 0x10
|
|
||||||
|
|
||||||
// Start measurement at 0.5lx resolution.
|
|
||||||
// Measurement Time is typically 120ms.
|
|
||||||
CMD_CONTINUOUSLY_H_RES_MODE2 = 0x11
|
|
||||||
|
|
||||||
// Start measurement at 4lx resolution.
|
|
||||||
// Measurement Time is typically 16ms.
|
|
||||||
CMD_CONTINUOUSLY_L_RES_MODE = 0x13
|
|
||||||
|
|
||||||
// Start measurement at 1lx resolution.
|
|
||||||
// Measurement Time is typically 120ms.
|
|
||||||
// It is automatically set to Power Down mode after measurement
|
|
||||||
CMD_ONE_TIME_H_RES_MODE = 0x20
|
|
||||||
|
|
||||||
// Start measurement at 0.5lx resolution.
|
|
||||||
// Measurement Time is typically 120ms.
|
|
||||||
// It is automatically set to Power Down mode after measurement.
|
|
||||||
CMD_ONE_TIME_H_RES_MODE2 = 0x21
|
|
||||||
|
|
||||||
// Start measurement at 4lx resolution.
|
|
||||||
// Measurement Time is typically 16ms.
|
|
||||||
// It is automatically set to Power Down mode after measurement.
|
|
||||||
CMD_ONE_TIME_L_RES_MODE = 0x23
|
|
||||||
|
|
||||||
// Change measurement time. 01000_MT[7,6,5]
|
|
||||||
CMD_CHANGE_MEAS_TIME_HIGH = 0x40
|
|
||||||
|
|
||||||
// Change measurement time. 011_MT[4,3,2,1,0]
|
|
||||||
CMD_CHANGE_MEAS_TIME_LOW = 0x60
|
|
||||||
)
|
|
||||||
|
|
||||||
// ResolutionMode define sensor sensitivity
|
|
||||||
// and measure time. Be aware, that improving
|
|
||||||
// sensitivity lead to increasing of measurement time.
|
|
||||||
type ResolutionMode int
|
|
||||||
|
|
||||||
const (
|
|
||||||
// LowResolution precision 4 lx, 16 ms measurement time
|
|
||||||
LowResolution ResolutionMode = iota + 1
|
|
||||||
// HighResolution precision 1 lx, 120 ms measurement time
|
|
||||||
HighResolution
|
|
||||||
// HighestResolution precision 0.5 lx, 120 ms measurement time
|
|
||||||
HighestResolution
|
|
||||||
)
|
|
||||||
|
|
||||||
// String define stringer interface.
|
|
||||||
func (v ResolutionMode) String() string {
|
|
||||||
switch v {
|
|
||||||
case LowResolution:
|
|
||||||
return "Low Resolution"
|
|
||||||
case HighResolution:
|
|
||||||
return "High Resolution"
|
|
||||||
case HighestResolution:
|
|
||||||
return "Highest Resolution"
|
|
||||||
default:
|
|
||||||
return "<unknown>"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// BH1750 it's a sensor itself.
|
|
||||||
type BH1750 struct {
|
|
||||||
// Since sensor have no register
|
|
||||||
// to report current state, we save
|
|
||||||
// last issued command to fill this gap.
|
|
||||||
lastCmd byte
|
|
||||||
lastResolution ResolutionMode
|
|
||||||
factor byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBH1750 return new sensor instance.
|
|
||||||
func NewBH1750() *BH1750 {
|
|
||||||
v := &BH1750{}
|
|
||||||
v.factor = v.GetDefaultSensivityFactor()
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset clear ambient light register value.
|
|
||||||
func (v *BH1750) Reset(i2c *i2c.I2C) error {
|
|
||||||
lg.Debug("Reset sensor...")
|
|
||||||
_, err := i2c.WriteBytes([]byte{CMD_RESET})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
v.lastCmd = CMD_RESET
|
|
||||||
time.Sleep(time.Microsecond * 3)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// PowerDown return register to idle state.
|
|
||||||
func (v *BH1750) PowerDown(i2c *i2c.I2C) error {
|
|
||||||
lg.Debug("Power down sensor...")
|
|
||||||
_, err := i2c.WriteBytes([]byte{CMD_POWER_DOWN})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
v.lastCmd = CMD_POWER_DOWN
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// PowerOn activate sensor.
|
|
||||||
func (v *BH1750) PowerOn(i2c *i2c.I2C) error {
|
|
||||||
lg.Debug("Power on sensor...")
|
|
||||||
_, err := i2c.WriteBytes([]byte{CMD_POWER_ON})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
v.lastCmd = CMD_POWER_ON
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get internal parameters used to program sensor.
|
|
||||||
func (v *BH1750) getResolutionData(resolution ResolutionMode) (cmd byte,
|
|
||||||
wait time.Duration, divider uint32) {
|
|
||||||
|
|
||||||
switch resolution {
|
|
||||||
case LowResolution:
|
|
||||||
cmd = CMD_ONE_TIME_L_RES_MODE
|
|
||||||
divider = 1
|
|
||||||
// typical measure time is 16 ms,
|
|
||||||
// but as it was found 24 ms max time
|
|
||||||
// gives better results
|
|
||||||
wait = time.Millisecond * 24
|
|
||||||
case HighResolution:
|
|
||||||
cmd = CMD_ONE_TIME_H_RES_MODE
|
|
||||||
divider = 1
|
|
||||||
// typical measure time
|
|
||||||
wait = time.Millisecond * 120
|
|
||||||
case HighestResolution:
|
|
||||||
cmd = CMD_ONE_TIME_H_RES_MODE2
|
|
||||||
divider = 2
|
|
||||||
// typical measure time
|
|
||||||
wait = time.Millisecond * 120
|
|
||||||
}
|
|
||||||
wait = wait * time.Duration(v.factor) /
|
|
||||||
time.Duration(v.GetDefaultSensivityFactor())
|
|
||||||
|
|
||||||
return cmd, wait, divider
|
|
||||||
}
|
|
||||||
|
|
||||||
// MeasureAmbientLight measure and return ambient light once in lux.
|
|
||||||
func (v *BH1750) MeasureAmbientLight(i2c *i2c.I2C,
|
|
||||||
resolution ResolutionMode) (uint16, error) {
|
|
||||||
|
|
||||||
lg.Debug("Run one time measure...")
|
|
||||||
|
|
||||||
cmd, wait, divider := v.getResolutionData(resolution)
|
|
||||||
|
|
||||||
v.lastCmd = cmd
|
|
||||||
v.lastResolution = resolution
|
|
||||||
|
|
||||||
_, err := i2c.WriteBytes([]byte{cmd})
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
time.Sleep(wait)
|
|
||||||
|
|
||||||
var data struct {
|
|
||||||
Data [2]byte
|
|
||||||
}
|
|
||||||
err = readDataToStruct(i2c, 2, binary.BigEndian, &data)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
amb := uint16(uint32(uint16(data.Data[0])<<8|uint16(data.Data[1])) *
|
|
||||||
5 / 6 / divider)
|
|
||||||
|
|
||||||
return amb, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// StartMeasureAmbientLightContinuously start continuous
|
|
||||||
// measurement process. Use FetchMeasuredAmbientLight to get
|
|
||||||
// average ambient light amount collected and calculated over a time.
|
|
||||||
// Use PowerDown to stop measurements and return sensor to idle state.
|
|
||||||
func (v *BH1750) StartMeasureAmbientLightContinuously(i2c *i2c.I2C,
|
|
||||||
resolution ResolutionMode) (wait time.Duration, err error) {
|
|
||||||
|
|
||||||
lg.Debug("Start measures continuously...")
|
|
||||||
|
|
||||||
cmd, wait, _ := v.getResolutionData(resolution)
|
|
||||||
|
|
||||||
v.lastCmd = cmd
|
|
||||||
v.lastResolution = resolution
|
|
||||||
|
|
||||||
_, err = i2c.WriteBytes([]byte{cmd})
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait first time to collect necessary
|
|
||||||
// amount of light for correct results.
|
|
||||||
// It's not necessary to wait next time
|
|
||||||
// same amount of time, because
|
|
||||||
// sensor accumulate average lux amount
|
|
||||||
// without any overwrite old value.
|
|
||||||
time.Sleep(wait)
|
|
||||||
|
|
||||||
// In any case we are returning same
|
|
||||||
// recommended amount of time to wait
|
|
||||||
// between measures.
|
|
||||||
return wait, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FetchMeasuredAmbientLight return current average ambient light in lux.
|
|
||||||
// Previous command should be any continuous measurement initiation,
|
|
||||||
// otherwise error will be reported.
|
|
||||||
func (v *BH1750) FetchMeasuredAmbientLight(i2c *i2c.I2C) (uint16, error) {
|
|
||||||
|
|
||||||
lg.Debug("Fetch measured data...")
|
|
||||||
|
|
||||||
cmd, _, divider := v.getResolutionData(v.lastResolution)
|
|
||||||
|
|
||||||
if v.lastCmd != cmd {
|
|
||||||
return 0, errors.New(
|
|
||||||
"can't fetch measured ambient light, since last command doesn't match")
|
|
||||||
}
|
|
||||||
|
|
||||||
var data struct {
|
|
||||||
Data [2]byte
|
|
||||||
}
|
|
||||||
err := readDataToStruct(i2c, 2, binary.BigEndian, &data)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
amb := uint16(uint32(uint16(data.Data[0])<<8|uint16(data.Data[1])) *
|
|
||||||
5 / 6 / divider)
|
|
||||||
|
|
||||||
return amb, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetDefaultSensivityFactor return factor value
|
|
||||||
// used when your sensor have no any protection cover.
|
|
||||||
// This is default setting according to specification.
|
|
||||||
func (v *BH1750) GetDefaultSensivityFactor() byte {
|
|
||||||
return 69
|
|
||||||
}
|
|
||||||
|
|
||||||
// ChangeSensivityFactor used when you close sensor
|
|
||||||
// with protection cover, which change (ordinary decrease)
|
|
||||||
// expected amount of light falling on the sensor.
|
|
||||||
// In this case you should calibrate you sensor and find
|
|
||||||
// appropriate factor to get in output correct ambient light value.
|
|
||||||
// Be aware, that improving sensitivity will increase
|
|
||||||
// measurement time.
|
|
||||||
func (v *BH1750) ChangeSensivityFactor(i2c *i2c.I2C, factor byte) error {
|
|
||||||
|
|
||||||
lg.Debug("Change sensitivity factor...")
|
|
||||||
|
|
||||||
// minimum limit
|
|
||||||
const minValue = 31
|
|
||||||
// maximum limit
|
|
||||||
const maxValue = 254
|
|
||||||
|
|
||||||
if factor < minValue || factor > maxValue {
|
|
||||||
return errors.New(spew.Sprintf("sensitivity factor value exceed range [%d..%d]",
|
|
||||||
minValue, maxValue))
|
|
||||||
}
|
|
||||||
|
|
||||||
high := (factor & 0xE0) >> 5
|
|
||||||
_, err := i2c.WriteBytes([]byte{CMD_CHANGE_MEAS_TIME_HIGH | high})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
low := (factor & 0x1F)
|
|
||||||
_, err = i2c.WriteBytes([]byte{CMD_CHANGE_MEAS_TIME_LOW | low})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
v.factor = factor
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
10
vendor/github.com/d2r2/go-bh1750/logger.go
generated
vendored
10
vendor/github.com/d2r2/go-bh1750/logger.go
generated
vendored
|
@ -1,10 +0,0 @@
|
||||||
package bh1750
|
|
||||||
|
|
||||||
import logger "github.com/d2r2/go-logger"
|
|
||||||
|
|
||||||
// You can manage verbosity of log output
|
|
||||||
// in the package by changing last parameter value.
|
|
||||||
var lg = logger.NewPackageLogger("bh1750",
|
|
||||||
logger.DebugLevel,
|
|
||||||
// logger.InfoLevel,
|
|
||||||
)
|
|
106
vendor/github.com/d2r2/go-bh1750/utils.go
generated
vendored
106
vendor/github.com/d2r2/go-bh1750/utils.go
generated
vendored
|
@ -1,106 +0,0 @@
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Denis Dyakov
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
|
||||||
// associated documentation files (the "Software"), to deal in the Software without restriction,
|
|
||||||
// including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
// and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
|
||||||
// subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all copies or substantial
|
|
||||||
// portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
|
||||||
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
||||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
//
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
package bh1750
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/binary"
|
|
||||||
"math"
|
|
||||||
|
|
||||||
i2c "github.com/d2r2/go-i2c"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Utility functions
|
|
||||||
|
|
||||||
// getS16BE extract 2-byte integer as signed big-endian.
|
|
||||||
func getS16BE(buf []byte) int16 {
|
|
||||||
v := int16(buf[0])<<8 + int16(buf[1])
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// getS16LE extract 2-byte integer as signed little-endian.
|
|
||||||
func getS16LE(buf []byte) int16 {
|
|
||||||
w := getS16BE(buf)
|
|
||||||
// exchange bytes
|
|
||||||
v := (w&0xFF)<<8 + w>>8
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// getU16BE extract 2-byte integer as unsigned big-endian.
|
|
||||||
func getU16BE(buf []byte) uint16 {
|
|
||||||
v := uint16(buf[0])<<8 + uint16(buf[1])
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// getU16LE extract 2-byte integer as unsigned little-endian.
|
|
||||||
func getU16LE(buf []byte) uint16 {
|
|
||||||
w := getU16BE(buf)
|
|
||||||
// exchange bytes
|
|
||||||
v := (w&0xFF)<<8 + w>>8
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func calcCRC1(seed byte, buf []byte) byte {
|
|
||||||
for i := 0; i < len(buf); i++ {
|
|
||||||
b := buf[ /*len(buf)-1-*/ i]
|
|
||||||
for j := 0; j < 8; j++ {
|
|
||||||
if (seed^b)&0x01 != 0 {
|
|
||||||
seed ^= 0x18
|
|
||||||
seed >>= 1
|
|
||||||
seed |= 0x80
|
|
||||||
// crc = crc ^ 0x8c
|
|
||||||
} else {
|
|
||||||
seed >>= 1
|
|
||||||
}
|
|
||||||
b >>= 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return seed
|
|
||||||
}
|
|
||||||
|
|
||||||
// Round float amount to certain precision.
|
|
||||||
func round64(value float64, precision int) float64 {
|
|
||||||
value2 := math.Round(value*math.Pow10(precision)) /
|
|
||||||
math.Pow10(precision)
|
|
||||||
return value2
|
|
||||||
}
|
|
||||||
|
|
||||||
// Round float amount to certain precision.
|
|
||||||
func round32(value float32, precision int) float32 {
|
|
||||||
return float32(round64(float64(value), precision))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read byte block from i2c device to struct object.
|
|
||||||
func readDataToStruct(i2c *i2c.I2C, byteCount int,
|
|
||||||
byteOrder binary.ByteOrder, obj interface{}) error {
|
|
||||||
buf1 := make([]byte, byteCount)
|
|
||||||
_, err := i2c.ReadBytes(buf1)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
buf := bytes.NewBuffer(buf1)
|
|
||||||
err = binary.Read(buf, byteOrder, obj)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
25
vendor/github.com/d2r2/go-i2c/.travis.yml
generated
vendored
25
vendor/github.com/d2r2/go-i2c/.travis.yml
generated
vendored
|
@ -1,25 +0,0 @@
|
||||||
language: go
|
|
||||||
go:
|
|
||||||
- "1.10"
|
|
||||||
# - "tip"
|
|
||||||
|
|
||||||
# first part of the GOARCH workaround
|
|
||||||
# setting the GOARCH directly doesn't work, since the value will be overwritten later
|
|
||||||
# so set it to a temporary environment variable first
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
TRAVIS_CGO_ENABLED=1
|
|
||||||
TRAVIS_GOOS=linux
|
|
||||||
matrix:
|
|
||||||
- TRAVIS_GOARCH=amd64
|
|
||||||
- TRAVIS_GOARCH=arm TRAVIS_CC=arm-linux-gnueabi-gcc TRAVIS_GOARM=6
|
|
||||||
|
|
||||||
# second part of the GOARCH workaround
|
|
||||||
# now actually set the GOARCH env variable to the value of the temporary variable set earlier
|
|
||||||
before_install:
|
|
||||||
- sudo apt-get install gcc-arm-linux-gnueabi crossbuild-essential-armel # for CGO cross compile to ARM
|
|
||||||
- export CGO_ENABLED=$TRAVIS_CGO_ENABLED GOARCH=$TRAVIS_GOARCH GOARM=$TRAVIS_GOARM GOOS=$TRAVIS_GOOS CC=$TRAVIS_CC
|
|
||||||
- go env # for debugging
|
|
||||||
- go tool dist env # for debugging
|
|
||||||
|
|
||||||
|
|
22
vendor/github.com/d2r2/go-i2c/LICENSE
generated
vendored
22
vendor/github.com/d2r2/go-i2c/LICENSE
generated
vendored
|
@ -1,22 +0,0 @@
|
||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2016 Denis Dyakov
|
|
||||||
Copyright (c) 2013 Dave Cheney
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
97
vendor/github.com/d2r2/go-i2c/README.md
generated
vendored
97
vendor/github.com/d2r2/go-i2c/README.md
generated
vendored
|
@ -1,97 +0,0 @@
|
||||||
I2C-bus interaction of peripheral sensors with Raspberry PI embedded linux or respective clones
|
|
||||||
==============================================================================================
|
|
||||||
|
|
||||||
[![Build Status](https://travis-ci.org/d2r2/go-i2c.svg?branch=master)](https://travis-ci.org/d2r2/go-i2c)
|
|
||||||
[![Go Report Card](https://goreportcard.com/badge/github.com/d2r2/go-i2c)](https://goreportcard.com/report/github.com/d2r2/go-i2c)
|
|
||||||
[![GoDoc](https://godoc.org/github.com/d2r2/go-i2c?status.svg)](https://godoc.org/github.com/d2r2/go-i2c)
|
|
||||||
[![MIT License](http://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
|
|
||||||
|
|
||||||
This library written in [Go programming language](https://golang.org/) intended to activate and interact with the I2C bus by reading and writing data.
|
|
||||||
|
|
||||||
Compatibility
|
|
||||||
-------------
|
|
||||||
|
|
||||||
Tested on Raspberry Pi 1 (model B), Raspberry Pi 3 B+, Banana Pi (model M1), Orange Pi Zero, Orange Pi One.
|
|
||||||
|
|
||||||
Golang usage
|
|
||||||
------------
|
|
||||||
|
|
||||||
```go
|
|
||||||
func main() {
|
|
||||||
// Create new connection to I2C bus on 2 line with address 0x27
|
|
||||||
i2c, err := i2c.NewI2C(0x27, 2)
|
|
||||||
if err != nil { log.Fatal(err) }
|
|
||||||
// Free I2C connection on exit
|
|
||||||
defer i2c.Close()
|
|
||||||
....
|
|
||||||
// Here goes code specific for sending and reading data
|
|
||||||
// to and from device connected via I2C bus, like:
|
|
||||||
_, err := i2c.Write([]byte{0x1, 0xF3})
|
|
||||||
if err != nil { log.Fatal(err) }
|
|
||||||
....
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Tutorial
|
|
||||||
--------
|
|
||||||
|
|
||||||
My [repositories](https://github.com/d2r2?tab=repositories) contain quite a lot projects, which use i2c library as a starting point to interact with various peripheral devices and sensors for use on embedded Linux devices. All these libraries start with a standard call to open I2C-connection to specific bus line and address, than pass i2c instance to device.
|
|
||||||
|
|
||||||
In its turn, go-i2c use [go-logger](https://github.com/d2r2/go-logger) library to output debug and other notification's lines which produce all necessary levels of logging. You can manage what level of verbosity you would like to see, by adding call:
|
|
||||||
```go
|
|
||||||
// Uncomment/comment next line to suppress/increase verbosity of output
|
|
||||||
logger.ChangePackageLogLevel("i2c", logger.InfoLevel)
|
|
||||||
```
|
|
||||||
Once you put this call, it will decrease verbosity from default "Debug" up to next "Info" level, reducing the number of low-level console outputs that occur during interaction with the I2C bus. Please, find examples in corresponding I2C-driven sensors among my projects.
|
|
||||||
|
|
||||||
You will find here the list of all devices and sensors supported by me, that reference this library:
|
|
||||||
|
|
||||||
- [Liquid-crystal display driven by Hitachi HD44780 IC](https://github.com/d2r2/go-hd44780).
|
|
||||||
- [BMP180/BMP280/BME280 temperature and pressure sensors](https://github.com/d2r2/go-bsbmp).
|
|
||||||
- [DHT12/AM2320 humidity and temperature sensors](https://github.com/d2r2/go-aosong).
|
|
||||||
- [Si7021 relative humidity and temperature sensor](https://github.com/d2r2/go-si7021).
|
|
||||||
- [SHT3x humidity and temperature sensor](https://github.com/d2r2/go-sht3x).
|
|
||||||
- [VL53L0X time-of-flight ranging sensor](https://github.com/d2r2/go-vl53l0x).
|
|
||||||
- [BH1750 ambient light sensor](https://github.com/d2r2/go-bh1750).
|
|
||||||
- [MPL3115A2 pressure and temperature sensor](https://github.com/d2r2/go-mpl3115a2).
|
|
||||||
|
|
||||||
|
|
||||||
Getting help
|
|
||||||
------------
|
|
||||||
|
|
||||||
GoDoc [documentation](http://godoc.org/github.com/d2r2/go-i2c)
|
|
||||||
|
|
||||||
Troubleshooting
|
|
||||||
--------------
|
|
||||||
|
|
||||||
- *How to obtain fresh Golang installation to RPi device (either any RPi clone):*
|
|
||||||
If your RaspberryPI golang installation taken by default from repository is outdated, you may consider
|
|
||||||
to install actual golang manually from official Golang [site](https://golang.org/dl/). Download
|
|
||||||
tar.gz file containing armv6l in the name. Follow installation instructions.
|
|
||||||
|
|
||||||
- *How to enable I2C bus on RPi device:*
|
|
||||||
If you employ RaspberryPI, use raspi-config utility to activate i2c-bus on the OS level.
|
|
||||||
Go to "Interfacing Options" menu, to active I2C bus.
|
|
||||||
Probably you will need to reboot to load i2c kernel module.
|
|
||||||
Finally you should have device like /dev/i2c-1 present in the system.
|
|
||||||
|
|
||||||
- *How to find I2C bus allocation and device address:*
|
|
||||||
Use i2cdetect utility in format "i2cdetect -y X", where X may vary from 0 to 5 or more,
|
|
||||||
to discover address occupied by peripheral device. To install utility you should run
|
|
||||||
`apt install i2c-tools` on debian-kind system. `i2cdetect -y 1` sample output:
|
|
||||||
```
|
|
||||||
0 1 2 3 4 5 6 7 8 9 a b c d e f
|
|
||||||
00: -- -- -- -- -- -- -- -- -- -- -- -- --
|
|
||||||
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
|
||||||
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
|
||||||
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
|
||||||
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
|
||||||
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
|
||||||
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
|
||||||
70: -- -- -- -- -- -- 76 --
|
|
||||||
```
|
|
||||||
|
|
||||||
License
|
|
||||||
-------
|
|
||||||
|
|
||||||
Go-i2c is licensed under MIT License.
|
|
12
vendor/github.com/d2r2/go-i2c/cgo.go
generated
vendored
12
vendor/github.com/d2r2/go-i2c/cgo.go
generated
vendored
|
@ -1,12 +0,0 @@
|
||||||
// +build linux,cgo
|
|
||||||
|
|
||||||
package i2c
|
|
||||||
|
|
||||||
// #include <linux/i2c-dev.h>
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
// Get I2C_SLAVE constant value from
|
|
||||||
// Linux OS I2C declaration file.
|
|
||||||
const (
|
|
||||||
I2C_SLAVE = C.I2C_SLAVE
|
|
||||||
)
|
|
241
vendor/github.com/d2r2/go-i2c/i2c.go
generated
vendored
241
vendor/github.com/d2r2/go-i2c/i2c.go
generated
vendored
|
@ -1,241 +0,0 @@
|
||||||
// Package i2c provides low level control over the Linux i2c bus.
|
|
||||||
//
|
|
||||||
// Before usage you should load the i2c-dev kernel module
|
|
||||||
//
|
|
||||||
// sudo modprobe i2c-dev
|
|
||||||
//
|
|
||||||
// Each i2c bus can address 127 independent i2c devices, and most
|
|
||||||
// Linux systems contain several buses.
|
|
||||||
|
|
||||||
package i2c
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
// I2C represents a connection to I2C-device.
|
|
||||||
type I2C struct {
|
|
||||||
addr uint8
|
|
||||||
bus int
|
|
||||||
rc *os.File
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewI2C opens a connection for I2C-device.
|
|
||||||
// SMBus (System Management Bus) protocol over I2C
|
|
||||||
// supported as well: you should preliminary specify
|
|
||||||
// register address to read from, either write register
|
|
||||||
// together with the data in case of write operations.
|
|
||||||
func NewI2C(addr uint8, bus int) (*I2C, error) {
|
|
||||||
f, err := os.OpenFile(fmt.Sprintf("/dev/i2c-%d", bus), os.O_RDWR, 0600)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := ioctl(f.Fd(), I2C_SLAVE, uintptr(addr)); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
v := &I2C{rc: f, bus: bus, addr: addr}
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetBus return bus line, where I2C-device is allocated.
|
|
||||||
func (v *I2C) GetBus() int {
|
|
||||||
return v.bus
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAddr return device occupied address in the bus.
|
|
||||||
func (v *I2C) GetAddr() uint8 {
|
|
||||||
return v.addr
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *I2C) write(buf []byte) (int, error) {
|
|
||||||
return v.rc.Write(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteBytes send bytes to the remote I2C-device. The interpretation of
|
|
||||||
// the message is implementation-dependent.
|
|
||||||
func (v *I2C) WriteBytes(buf []byte) (int, error) {
|
|
||||||
lg.Debugf("Write %d hex bytes: [%+v]", len(buf), hex.EncodeToString(buf))
|
|
||||||
return v.write(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *I2C) read(buf []byte) (int, error) {
|
|
||||||
return v.rc.Read(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadBytes read bytes from I2C-device.
|
|
||||||
// Number of bytes read correspond to buf parameter length.
|
|
||||||
func (v *I2C) ReadBytes(buf []byte) (int, error) {
|
|
||||||
n, err := v.read(buf)
|
|
||||||
if err != nil {
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
lg.Debugf("Read %d hex bytes: [%+v]", len(buf), hex.EncodeToString(buf))
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close I2C-connection.
|
|
||||||
func (v *I2C) Close() error {
|
|
||||||
return v.rc.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadRegBytes read count of n byte's sequence from I2C-device
|
|
||||||
// starting from reg address.
|
|
||||||
// SMBus (System Management Bus) protocol over I2C.
|
|
||||||
func (v *I2C) ReadRegBytes(reg byte, n int) ([]byte, int, error) {
|
|
||||||
lg.Debugf("Read %d bytes starting from reg 0x%0X...", n, reg)
|
|
||||||
_, err := v.WriteBytes([]byte{reg})
|
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
buf := make([]byte, n)
|
|
||||||
c, err := v.ReadBytes(buf)
|
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
return buf, c, nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadRegU8 reads byte from I2C-device register specified in reg.
|
|
||||||
// SMBus (System Management Bus) protocol over I2C.
|
|
||||||
func (v *I2C) ReadRegU8(reg byte) (byte, error) {
|
|
||||||
_, err := v.WriteBytes([]byte{reg})
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
buf := make([]byte, 1)
|
|
||||||
_, err = v.ReadBytes(buf)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
lg.Debugf("Read U8 %d from reg 0x%0X", buf[0], reg)
|
|
||||||
return buf[0], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteRegU8 writes byte to I2C-device register specified in reg.
|
|
||||||
// SMBus (System Management Bus) protocol over I2C.
|
|
||||||
func (v *I2C) WriteRegU8(reg byte, value byte) error {
|
|
||||||
buf := []byte{reg, value}
|
|
||||||
_, err := v.WriteBytes(buf)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
lg.Debugf("Write U8 %d to reg 0x%0X", value, reg)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadRegU16BE reads unsigned big endian word (16 bits)
|
|
||||||
// from I2C-device starting from address specified in reg.
|
|
||||||
// SMBus (System Management Bus) protocol over I2C.
|
|
||||||
func (v *I2C) ReadRegU16BE(reg byte) (uint16, error) {
|
|
||||||
_, err := v.WriteBytes([]byte{reg})
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
buf := make([]byte, 2)
|
|
||||||
_, err = v.ReadBytes(buf)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
w := uint16(buf[0])<<8 + uint16(buf[1])
|
|
||||||
lg.Debugf("Read U16 %d from reg 0x%0X", w, reg)
|
|
||||||
return w, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadRegU16LE reads unsigned little endian word (16 bits)
|
|
||||||
// from I2C-device starting from address specified in reg.
|
|
||||||
// SMBus (System Management Bus) protocol over I2C.
|
|
||||||
func (v *I2C) ReadRegU16LE(reg byte) (uint16, error) {
|
|
||||||
w, err := v.ReadRegU16BE(reg)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
// exchange bytes
|
|
||||||
w = (w&0xFF)<<8 + w>>8
|
|
||||||
return w, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadRegS16BE reads signed big endian word (16 bits)
|
|
||||||
// from I2C-device starting from address specified in reg.
|
|
||||||
// SMBus (System Management Bus) protocol over I2C.
|
|
||||||
func (v *I2C) ReadRegS16BE(reg byte) (int16, error) {
|
|
||||||
_, err := v.WriteBytes([]byte{reg})
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
buf := make([]byte, 2)
|
|
||||||
_, err = v.ReadBytes(buf)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
w := int16(buf[0])<<8 + int16(buf[1])
|
|
||||||
lg.Debugf("Read S16 %d from reg 0x%0X", w, reg)
|
|
||||||
return w, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadRegS16LE reads signed little endian word (16 bits)
|
|
||||||
// from I2C-device starting from address specified in reg.
|
|
||||||
// SMBus (System Management Bus) protocol over I2C.
|
|
||||||
func (v *I2C) ReadRegS16LE(reg byte) (int16, error) {
|
|
||||||
w, err := v.ReadRegS16BE(reg)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
// exchange bytes
|
|
||||||
w = (w&0xFF)<<8 + w>>8
|
|
||||||
return w, nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteRegU16BE writes unsigned big endian word (16 bits)
|
|
||||||
// value to I2C-device starting from address specified in reg.
|
|
||||||
// SMBus (System Management Bus) protocol over I2C.
|
|
||||||
func (v *I2C) WriteRegU16BE(reg byte, value uint16) error {
|
|
||||||
buf := []byte{reg, byte((value & 0xFF00) >> 8), byte(value & 0xFF)}
|
|
||||||
_, err := v.WriteBytes(buf)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
lg.Debugf("Write U16 %d to reg 0x%0X", value, reg)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteRegU16LE writes unsigned little endian word (16 bits)
|
|
||||||
// value to I2C-device starting from address specified in reg.
|
|
||||||
// SMBus (System Management Bus) protocol over I2C.
|
|
||||||
func (v *I2C) WriteRegU16LE(reg byte, value uint16) error {
|
|
||||||
w := (value*0xFF00)>>8 + value<<8
|
|
||||||
return v.WriteRegU16BE(reg, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteRegS16BE writes signed big endian word (16 bits)
|
|
||||||
// value to I2C-device starting from address specified in reg.
|
|
||||||
// SMBus (System Management Bus) protocol over I2C.
|
|
||||||
func (v *I2C) WriteRegS16BE(reg byte, value int16) error {
|
|
||||||
buf := []byte{reg, byte((uint16(value) & 0xFF00) >> 8), byte(value & 0xFF)}
|
|
||||||
_, err := v.WriteBytes(buf)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
lg.Debugf("Write S16 %d to reg 0x%0X", value, reg)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteRegS16LE writes signed little endian word (16 bits)
|
|
||||||
// value to I2C-device starting from address specified in reg.
|
|
||||||
// SMBus (System Management Bus) protocol over I2C.
|
|
||||||
func (v *I2C) WriteRegS16LE(reg byte, value int16) error {
|
|
||||||
w := int16((uint16(value)*0xFF00)>>8) + value<<8
|
|
||||||
return v.WriteRegS16BE(reg, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ioctl(fd, cmd, arg uintptr) error {
|
|
||||||
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, cmd, arg, 0, 0, 0)
|
|
||||||
if err != 0 {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
11
vendor/github.com/d2r2/go-i2c/logger.go
generated
vendored
11
vendor/github.com/d2r2/go-i2c/logger.go
generated
vendored
|
@ -1,11 +0,0 @@
|
||||||
package i2c
|
|
||||||
|
|
||||||
import logger "github.com/d2r2/go-logger"
|
|
||||||
|
|
||||||
// You can manage verbosity of log output
|
|
||||||
// in the package by changing last parameter value
|
|
||||||
// (comment/uncomment corresponding lines).
|
|
||||||
var lg = logger.NewPackageLogger("i2c",
|
|
||||||
logger.DebugLevel,
|
|
||||||
// logger.InfoLevel,
|
|
||||||
)
|
|
11
vendor/github.com/d2r2/go-i2c/noncgo.go
generated
vendored
11
vendor/github.com/d2r2/go-i2c/noncgo.go
generated
vendored
|
@ -1,11 +0,0 @@
|
||||||
// +build !cgo
|
|
||||||
|
|
||||||
package i2c
|
|
||||||
|
|
||||||
// Use hard-coded value for system I2C_SLAVE
|
|
||||||
// constant, if OS not Linux or CGO disabled.
|
|
||||||
// This is not a good approach, but
|
|
||||||
// can be used as a last resort.
|
|
||||||
const (
|
|
||||||
I2C_SLAVE = 0x0703
|
|
||||||
)
|
|
2
vendor/github.com/d2r2/go-logger/README.md
generated
vendored
2
vendor/github.com/d2r2/go-logger/README.md
generated
vendored
|
@ -1,2 +0,0 @@
|
||||||
Golang logger functionality with logging separation by package to improve debug process
|
|
||||||
|
|
161
vendor/github.com/d2r2/go-logger/file.go
generated
vendored
161
vendor/github.com/d2r2/go-logger/file.go
generated
vendored
|
@ -1,161 +0,0 @@
|
||||||
package logger
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"sort"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
type File struct {
|
|
||||||
sync.RWMutex
|
|
||||||
Path string
|
|
||||||
File *os.File
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *File) Flush() error {
|
|
||||||
v.Lock()
|
|
||||||
defer v.Unlock()
|
|
||||||
if v.File != nil {
|
|
||||||
err := v.File.Sync()
|
|
||||||
v.File = nil
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *File) Close() error {
|
|
||||||
v.Lock()
|
|
||||||
defer v.Unlock()
|
|
||||||
if v.File != nil {
|
|
||||||
err := v.File.Close()
|
|
||||||
v.File = nil
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *File) getRotatedFileList() ([]logFile, error) {
|
|
||||||
var list []logFile
|
|
||||||
err := filepath.Walk(path.Dir(v.Path), func(p string,
|
|
||||||
info os.FileInfo, err error) error {
|
|
||||||
pattern := "*" + path.Base(v.Path) + "*"
|
|
||||||
if ok, err := path.Match(pattern, path.Base(p)); ok && err == nil {
|
|
||||||
i := extractIndex(info)
|
|
||||||
list = append(list, logFile{FileInfo: info, Index: i})
|
|
||||||
} else if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
s := &sortLogFiles{Items: list}
|
|
||||||
sort.Sort(s)
|
|
||||||
return s.Items, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *File) doRotate(items []logFile, rotateMaxCount int) error {
|
|
||||||
if len(items) > 0 {
|
|
||||||
// delete last files
|
|
||||||
deleteCount := len(items) - rotateMaxCount + 1
|
|
||||||
if deleteCount > 0 {
|
|
||||||
for i := 0; i < deleteCount; i++ {
|
|
||||||
err := os.Remove(items[i].FileInfo.Name())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
items = items[deleteCount:]
|
|
||||||
}
|
|
||||||
// change names of rest files
|
|
||||||
baseFilePath := items[len(items)-1].FileInfo.Name()
|
|
||||||
movs := make([]int, len(items))
|
|
||||||
// 1st round to change names
|
|
||||||
for i, item := range items {
|
|
||||||
movs[i] = i + 100000
|
|
||||||
err := os.Rename(item.FileInfo.Name(),
|
|
||||||
fmt.Sprintf("%s.%d", baseFilePath, movs[i]))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 2nd round to change names
|
|
||||||
for i, item := range movs {
|
|
||||||
err := os.Rename(fmt.Sprintf("%s.%d", baseFilePath, item),
|
|
||||||
fmt.Sprintf("%s.%d", baseFilePath, len(items)-i))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *File) rotateFiles(rotateMaxSize int64, rotateMaxCount int) error {
|
|
||||||
fs, err := v.File.Stat()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if fs.Size() > rotateMaxSize {
|
|
||||||
if v.File != nil {
|
|
||||||
err := v.File.Close()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
v.File = nil
|
|
||||||
}
|
|
||||||
list, err := v.getRotatedFileList()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err = v.doRotate(list, rotateMaxCount); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *File) getFile() (*os.File, error) {
|
|
||||||
v.Lock()
|
|
||||||
defer v.Unlock()
|
|
||||||
if v.File == nil {
|
|
||||||
file, err := os.OpenFile(v.Path, os.O_RDWR|os.O_APPEND, 0660)
|
|
||||||
if err != nil {
|
|
||||||
file, err = os.Create(v.Path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
v.File = file
|
|
||||||
}
|
|
||||||
return v.File, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *File) writeToFile(msg string, rotateMaxSize int64, rotateMaxCount int) error {
|
|
||||||
file, err := v.getFile()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
v.Lock()
|
|
||||||
defer v.Unlock()
|
|
||||||
var buf bytes.Buffer
|
|
||||||
buf.WriteString(msg)
|
|
||||||
buf.WriteString(fmt.Sprintln())
|
|
||||||
if _, err := io.Copy(file, &buf); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// if err = file.Sync(); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
if err := v.rotateFiles(rotateMaxSize, rotateMaxCount); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
31
vendor/github.com/d2r2/go-logger/format.go
generated
vendored
31
vendor/github.com/d2r2/go-logger/format.go
generated
vendored
|
@ -1,31 +0,0 @@
|
||||||
package logger
|
|
||||||
|
|
||||||
import "os"
|
|
||||||
|
|
||||||
type LevelLength int
|
|
||||||
|
|
||||||
const (
|
|
||||||
LevelShort LevelLength = iota
|
|
||||||
LevelLong
|
|
||||||
)
|
|
||||||
|
|
||||||
type FormatOptions struct {
|
|
||||||
TimeFormat string
|
|
||||||
PackageLength int
|
|
||||||
LevelLength LevelLength
|
|
||||||
}
|
|
||||||
|
|
||||||
func FormatMessage(options FormatOptions, level LogLevel, packageName, msg string, colored bool) string {
|
|
||||||
appName := os.Args[0]
|
|
||||||
out := metaFmtStr(colored, level, options, appName,
|
|
||||||
packageName, msg, "%[1]s [%[3]s] %[4]s %[5]s")
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
func (options FormatOptions) GetLevelStr(level LogLevel) string {
|
|
||||||
if options.LevelLength == LevelLong {
|
|
||||||
return level.LongStr()
|
|
||||||
} else {
|
|
||||||
return level.ShortStr()
|
|
||||||
}
|
|
||||||
}
|
|
309
vendor/github.com/d2r2/go-logger/logger.go
generated
vendored
309
vendor/github.com/d2r2/go-logger/logger.go
generated
vendored
|
@ -1,309 +0,0 @@
|
||||||
package logger
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
type LogLevel int
|
|
||||||
|
|
||||||
const (
|
|
||||||
FatalLevel LogLevel = iota
|
|
||||||
PanicLevel
|
|
||||||
ErrorLevel
|
|
||||||
WarnLevel
|
|
||||||
NotifyLevel
|
|
||||||
InfoLevel
|
|
||||||
DebugLevel
|
|
||||||
)
|
|
||||||
|
|
||||||
func (v LogLevel) String() string {
|
|
||||||
switch v {
|
|
||||||
case FatalLevel:
|
|
||||||
return "Fatal"
|
|
||||||
case PanicLevel:
|
|
||||||
return "Panic"
|
|
||||||
case ErrorLevel:
|
|
||||||
return "Error"
|
|
||||||
case WarnLevel:
|
|
||||||
return "Warning"
|
|
||||||
case NotifyLevel:
|
|
||||||
return "Notice"
|
|
||||||
case InfoLevel:
|
|
||||||
return "Information"
|
|
||||||
case DebugLevel:
|
|
||||||
return "Debug"
|
|
||||||
default:
|
|
||||||
return "<undef>"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v LogLevel) LongStr() string {
|
|
||||||
return v.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v LogLevel) ShortStr() string {
|
|
||||||
switch v {
|
|
||||||
case FatalLevel:
|
|
||||||
return "Fatal"
|
|
||||||
case PanicLevel:
|
|
||||||
return "Panic"
|
|
||||||
case ErrorLevel:
|
|
||||||
return "Error"
|
|
||||||
case WarnLevel:
|
|
||||||
return "Warn"
|
|
||||||
case NotifyLevel:
|
|
||||||
return "Notice"
|
|
||||||
case InfoLevel:
|
|
||||||
return "Info"
|
|
||||||
case DebugLevel:
|
|
||||||
return "Debug"
|
|
||||||
default:
|
|
||||||
return "<undef>"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Log struct {
|
|
||||||
log *log.Logger
|
|
||||||
colored bool
|
|
||||||
level LogLevel
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewLog(log *log.Logger, colored bool, level LogLevel) *Log {
|
|
||||||
v := &Log{log: log, colored: colored, level: level}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
type Logger struct {
|
|
||||||
sync.RWMutex
|
|
||||||
logs []*Log
|
|
||||||
packages []*Package
|
|
||||||
options FormatOptions
|
|
||||||
logFile *File
|
|
||||||
rotateMaxSize int64
|
|
||||||
rotateMaxCount int
|
|
||||||
enableSyslog bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewLogger() *Logger {
|
|
||||||
stdout := NewLog(log.New(os.Stdout, "", 0), true, DebugLevel)
|
|
||||||
logs := []*Log{stdout}
|
|
||||||
options := FormatOptions{TimeFormat: "2006-01-02T15:04:05.000", LevelLength: LevelShort, PackageLength: 8}
|
|
||||||
l := &Logger{
|
|
||||||
logs: logs,
|
|
||||||
options: options,
|
|
||||||
rotateMaxSize: 1024 * 1024 * 512,
|
|
||||||
rotateMaxCount: 3,
|
|
||||||
}
|
|
||||||
return l
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Logger) Close() error {
|
|
||||||
v.Lock()
|
|
||||||
defer v.Unlock()
|
|
||||||
|
|
||||||
for _, pack := range v.packages {
|
|
||||||
pack.Close()
|
|
||||||
}
|
|
||||||
v.packages = nil
|
|
||||||
|
|
||||||
if v.logFile != nil {
|
|
||||||
v.logFile.Close()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Logger) SetRotateParams(rotateMaxSize int64, rotateMaxCount int) {
|
|
||||||
v.Lock()
|
|
||||||
defer v.Unlock()
|
|
||||||
v.rotateMaxSize = rotateMaxSize
|
|
||||||
v.rotateMaxCount = rotateMaxCount
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Logger) GetRotateMaxSize() int64 {
|
|
||||||
v.Lock()
|
|
||||||
defer v.Unlock()
|
|
||||||
return v.rotateMaxSize
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Logger) GetRotateMaxCount() int {
|
|
||||||
v.Lock()
|
|
||||||
defer v.Unlock()
|
|
||||||
return v.rotateMaxCount
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
func (v *Logger) SetApplicationName(appName string) {
|
|
||||||
v.Lock()
|
|
||||||
defer v.Unlock()
|
|
||||||
v.appName = appName
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Logger) GetApplicationName() string {
|
|
||||||
v.RLock()
|
|
||||||
defer v.RUnlock()
|
|
||||||
return v.appName
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
func (v *Logger) EnableSyslog(enable bool) {
|
|
||||||
v.Lock()
|
|
||||||
defer v.Unlock()
|
|
||||||
v.enableSyslog = enable
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Logger) GetSyslogEnabled() bool {
|
|
||||||
v.RLock()
|
|
||||||
defer v.RUnlock()
|
|
||||||
return v.enableSyslog
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Logger) SetFormatOptions(options FormatOptions) {
|
|
||||||
v.Lock()
|
|
||||||
defer v.Unlock()
|
|
||||||
v.options = options
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Logger) GetFormatOptions() FormatOptions {
|
|
||||||
v.RLock()
|
|
||||||
defer v.RUnlock()
|
|
||||||
return v.options
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Logger) SetLogFileName(logFilePath string) error {
|
|
||||||
if path.Ext(logFilePath) == "" {
|
|
||||||
logFilePath += ".log"
|
|
||||||
}
|
|
||||||
fp, err := filepath.Abs(logFilePath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
v.Lock()
|
|
||||||
defer v.Unlock()
|
|
||||||
lf := &File{Path: fp}
|
|
||||||
v.logFile = lf
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Logger) GetLogFileInfo() *File {
|
|
||||||
v.RLock()
|
|
||||||
defer v.RUnlock()
|
|
||||||
return v.logFile
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Logger) NewPackageLogger(packageName string, level LogLevel) PackageLog {
|
|
||||||
v.Lock()
|
|
||||||
defer v.Unlock()
|
|
||||||
p := &Package{parent: v, packageName: packageName, level: level}
|
|
||||||
v.packages = append(v.packages, p)
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Logger) ChangePackageLogLevel(packageName string, level LogLevel) error {
|
|
||||||
var p *Package
|
|
||||||
for _, item := range v.packages {
|
|
||||||
if item.packageName == packageName {
|
|
||||||
p = item
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if p != nil {
|
|
||||||
p.SetLogLevel(level)
|
|
||||||
} else {
|
|
||||||
err := fmt.Errorf("Package log %q is not found", packageName)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Logger) AddCustomLog(writer io.Writer, colored bool, level LogLevel) {
|
|
||||||
v.Lock()
|
|
||||||
defer v.Unlock()
|
|
||||||
log := NewLog(log.New(writer, "", 0), colored, level)
|
|
||||||
v.logs = append(v.logs, log)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Logger) getLogs() []*Log {
|
|
||||||
v.RLock()
|
|
||||||
defer v.RUnlock()
|
|
||||||
lst := []*Log{}
|
|
||||||
for _, item := range v.logs {
|
|
||||||
lst = append(lst, item)
|
|
||||||
}
|
|
||||||
return lst
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
globalLock sync.RWMutex
|
|
||||||
lgr *Logger
|
|
||||||
)
|
|
||||||
|
|
||||||
func SetFormatOptions(format FormatOptions) {
|
|
||||||
globalLock.RLock()
|
|
||||||
defer globalLock.RUnlock()
|
|
||||||
lgr.SetFormatOptions(format)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetRotateParams(rotateMaxSize int64, rotateMaxCount int) {
|
|
||||||
globalLock.RLock()
|
|
||||||
defer globalLock.RUnlock()
|
|
||||||
lgr.SetRotateParams(rotateMaxSize, rotateMaxCount)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPackageLogger(module string, level LogLevel) PackageLog {
|
|
||||||
globalLock.RLock()
|
|
||||||
defer globalLock.RUnlock()
|
|
||||||
return lgr.NewPackageLogger(module, level)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ChangePackageLogLevel(packageName string, level LogLevel) error {
|
|
||||||
globalLock.RLock()
|
|
||||||
defer globalLock.RUnlock()
|
|
||||||
return lgr.ChangePackageLogLevel(packageName, level)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetLogFileName(logFilePath string) error {
|
|
||||||
globalLock.RLock()
|
|
||||||
defer globalLock.RUnlock()
|
|
||||||
return lgr.SetLogFileName(logFilePath)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
func SetApplicationName(appName string) {
|
|
||||||
globalLock.RLock()
|
|
||||||
defer globalLock.RUnlock()
|
|
||||||
lgr.SetApplicationName(appName)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
func EnableSyslog(enable bool) {
|
|
||||||
globalLock.RLock()
|
|
||||||
defer globalLock.RUnlock()
|
|
||||||
lgr.EnableSyslog(enable)
|
|
||||||
}
|
|
||||||
|
|
||||||
func AddCustomLog(writer io.Writer, colored bool, level LogLevel) {
|
|
||||||
globalLock.RLock()
|
|
||||||
defer globalLock.RUnlock()
|
|
||||||
lgr.AddCustomLog(writer, colored, level)
|
|
||||||
}
|
|
||||||
|
|
||||||
func FinalizeLogger() error {
|
|
||||||
var err error
|
|
||||||
if lgr != nil {
|
|
||||||
err = lgr.Close()
|
|
||||||
}
|
|
||||||
globalLock.Lock()
|
|
||||||
defer globalLock.Unlock()
|
|
||||||
lgr = nil
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
lgr = NewLogger()
|
|
||||||
}
|
|
258
vendor/github.com/d2r2/go-logger/package.go
generated
vendored
258
vendor/github.com/d2r2/go-logger/package.go
generated
vendored
|
@ -1,258 +0,0 @@
|
||||||
package logger
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log/syslog"
|
|
||||||
"os"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
)
|
|
||||||
|
|
||||||
type PackageLog interface {
|
|
||||||
Printf(level LogLevel, format string, args ...interface{})
|
|
||||||
Print(level LogLevel, args ...interface{})
|
|
||||||
Debugf(format string, args ...interface{})
|
|
||||||
Debug(args ...interface{})
|
|
||||||
Infof(format string, args ...interface{})
|
|
||||||
Info(args ...interface{})
|
|
||||||
Notifyf(format string, args ...interface{})
|
|
||||||
Notify(args ...interface{})
|
|
||||||
Warningf(format string, args ...interface{})
|
|
||||||
Warnf(format string, args ...interface{})
|
|
||||||
Warning(args ...interface{})
|
|
||||||
Warn(args ...interface{})
|
|
||||||
Errorf(format string, args ...interface{})
|
|
||||||
Error(args ...interface{})
|
|
||||||
Panicf(format string, args ...interface{})
|
|
||||||
Panic(args ...interface{})
|
|
||||||
Fatalf(format string, args ...interface{})
|
|
||||||
Fatal(args ...interface{})
|
|
||||||
}
|
|
||||||
|
|
||||||
type Package struct {
|
|
||||||
sync.RWMutex
|
|
||||||
parent *Logger
|
|
||||||
packageName string
|
|
||||||
level LogLevel
|
|
||||||
syslog *syslog.Writer
|
|
||||||
}
|
|
||||||
|
|
||||||
// Static cast to verify that object implement interface.
|
|
||||||
var _ PackageLog = &Package{}
|
|
||||||
|
|
||||||
func (v *Package) Close() error {
|
|
||||||
v.Lock()
|
|
||||||
defer v.Unlock()
|
|
||||||
if v.syslog != nil {
|
|
||||||
err := v.syslog.Close()
|
|
||||||
v.syslog = nil
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Package) SetLogLevel(level LogLevel) {
|
|
||||||
v.Lock()
|
|
||||||
defer v.Unlock()
|
|
||||||
v.level = level
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Package) GetLogLevel() LogLevel {
|
|
||||||
v.RLock()
|
|
||||||
defer v.RUnlock()
|
|
||||||
return v.level
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Package) getSyslog(level LogLevel, options FormatOptions,
|
|
||||||
appName string) (*syslog.Writer, error) {
|
|
||||||
v.Lock()
|
|
||||||
defer v.Unlock()
|
|
||||||
if v.syslog == nil {
|
|
||||||
tag := metaFmtStr(false, level, options, appName,
|
|
||||||
v.packageName, "", "%[2]s-%[3]s")
|
|
||||||
sl, err := syslog.New(syslog.LOG_DEBUG, tag)
|
|
||||||
if err != nil {
|
|
||||||
err = spew.Errorf("Failed to connect to syslog: %v\n", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
v.syslog = sl
|
|
||||||
}
|
|
||||||
return v.syslog, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Package) writeToSyslog(options FormatOptions,
|
|
||||||
level LogLevel, appName string, msg string) error {
|
|
||||||
|
|
||||||
sl, err := v.getSyslog(level, options, appName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
switch level {
|
|
||||||
case DebugLevel:
|
|
||||||
return sl.Debug(msg)
|
|
||||||
case InfoLevel:
|
|
||||||
return sl.Info(msg)
|
|
||||||
case WarnLevel:
|
|
||||||
return sl.Warning(msg)
|
|
||||||
case ErrorLevel:
|
|
||||||
return sl.Err(msg)
|
|
||||||
case PanicLevel:
|
|
||||||
return sl.Crit(msg)
|
|
||||||
case FatalLevel:
|
|
||||||
return sl.Emerg(msg)
|
|
||||||
default:
|
|
||||||
return sl.Debug(msg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type printLog func(log *Log, msg interface{})
|
|
||||||
type getMessage func(colored bool) interface{}
|
|
||||||
|
|
||||||
func printLogs(logs []*Log, level LogLevel, prnt printLog, getMsg getMessage) {
|
|
||||||
// Console and custom logs output
|
|
||||||
for _, log := range logs {
|
|
||||||
if log.level >= level {
|
|
||||||
prnt(log, getMsg(log.colored))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Package) print(level LogLevel, msg string) {
|
|
||||||
lvl := v.GetLogLevel()
|
|
||||||
if lvl >= level {
|
|
||||||
appName := getApplicationName()
|
|
||||||
logs := v.parent.getLogs()
|
|
||||||
options := v.parent.GetFormatOptions()
|
|
||||||
out1 := FormatMessage(options, level, v.packageName, msg, false)
|
|
||||||
// File output
|
|
||||||
if lf := v.parent.GetLogFileInfo(); lf != nil {
|
|
||||||
rotateMaxSize := v.parent.GetRotateMaxSize()
|
|
||||||
rotateMaxCount := v.parent.GetRotateMaxCount()
|
|
||||||
if err := lf.writeToFile(out1, rotateMaxSize, rotateMaxCount); err != nil {
|
|
||||||
err = spew.Errorf("Failed to report syslog message %q: %v\n", out1, err)
|
|
||||||
printLogs(logs, FatalLevel,
|
|
||||||
func(log *Log, msg interface{}) {
|
|
||||||
log.log.Fatal(msg)
|
|
||||||
},
|
|
||||||
func(colored bool) interface{} {
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Syslog output
|
|
||||||
if v.parent.GetSyslogEnabled() {
|
|
||||||
if err := v.writeToSyslog(options, level, appName, msg); err != nil {
|
|
||||||
err = spew.Errorf("Failed to report syslog message %q: %v\n", msg, err)
|
|
||||||
printLogs(logs, FatalLevel,
|
|
||||||
func(log *Log, msg interface{}) {
|
|
||||||
log.log.Fatal(msg)
|
|
||||||
},
|
|
||||||
func(colored bool) interface{} {
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Console and custom logs output
|
|
||||||
outColored1 := FormatMessage(options, level, v.packageName, msg, true)
|
|
||||||
printLogs(logs, level,
|
|
||||||
func(log *Log, msg interface{}) {
|
|
||||||
log.log.Print(msg)
|
|
||||||
},
|
|
||||||
func(colored bool) interface{} {
|
|
||||||
if colored {
|
|
||||||
return outColored1 + fmt.Sprintln()
|
|
||||||
} else {
|
|
||||||
return out1 + fmt.Sprintln()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// Check critical events
|
|
||||||
if level == PanicLevel {
|
|
||||||
panic(out1)
|
|
||||||
} else if level == FatalLevel {
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Package) Printf(level LogLevel, format string, args ...interface{}) {
|
|
||||||
lvl := v.GetLogLevel()
|
|
||||||
if lvl >= level {
|
|
||||||
msg := spew.Sprintf(format, args...)
|
|
||||||
v.print(level, msg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Package) Print(level LogLevel, args ...interface{}) {
|
|
||||||
lvl := v.GetLogLevel()
|
|
||||||
if lvl >= level {
|
|
||||||
msg := fmt.Sprint(args...)
|
|
||||||
v.print(level, msg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Package) Debugf(format string, args ...interface{}) {
|
|
||||||
v.Printf(DebugLevel, format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Package) Debug(args ...interface{}) {
|
|
||||||
v.Print(DebugLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Package) Infof(format string, args ...interface{}) {
|
|
||||||
v.Printf(InfoLevel, format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Package) Info(args ...interface{}) {
|
|
||||||
v.Print(InfoLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Package) Notifyf(format string, args ...interface{}) {
|
|
||||||
v.Printf(NotifyLevel, format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Package) Notify(args ...interface{}) {
|
|
||||||
v.Print(NotifyLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Package) Warningf(format string, args ...interface{}) {
|
|
||||||
v.Printf(WarnLevel, format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Package) Warnf(format string, args ...interface{}) {
|
|
||||||
v.Printf(WarnLevel, format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Package) Warning(args ...interface{}) {
|
|
||||||
v.Print(WarnLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Package) Warn(args ...interface{}) {
|
|
||||||
v.Print(WarnLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Package) Errorf(format string, args ...interface{}) {
|
|
||||||
v.Printf(ErrorLevel, format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Package) Error(args ...interface{}) {
|
|
||||||
v.Print(ErrorLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Package) Panicf(format string, args ...interface{}) {
|
|
||||||
v.Printf(PanicLevel, format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Package) Panic(args ...interface{}) {
|
|
||||||
v.Print(PanicLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Package) Fatalf(format string, args ...interface{}) {
|
|
||||||
v.Printf(FatalLevel, format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Package) Fatal(args ...interface{}) {
|
|
||||||
v.Print(FatalLevel, args...)
|
|
||||||
}
|
|
133
vendor/github.com/d2r2/go-logger/utils.go
generated
vendored
133
vendor/github.com/d2r2/go-logger/utils.go
generated
vendored
|
@ -1,133 +0,0 @@
|
||||||
package logger
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type logFile struct {
|
|
||||||
FileInfo os.FileInfo
|
|
||||||
Index int
|
|
||||||
}
|
|
||||||
|
|
||||||
type sortLogFiles struct {
|
|
||||||
Items []logFile
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sf *sortLogFiles) Len() int {
|
|
||||||
return len(sf.Items)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sf *sortLogFiles) Less(i, j int) bool {
|
|
||||||
return sf.Items[j].Index < sf.Items[i].Index
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sf *sortLogFiles) Swap(i, j int) {
|
|
||||||
item := sf.Items[i]
|
|
||||||
sf.Items[i] = sf.Items[j]
|
|
||||||
sf.Items[j] = item
|
|
||||||
}
|
|
||||||
|
|
||||||
func findStringSubmatchIndexes(r *regexp.Regexp, s string) map[string][2]int {
|
|
||||||
captures := make(map[string][2]int)
|
|
||||||
ind := r.FindStringSubmatchIndex(s)
|
|
||||||
names := r.SubexpNames()
|
|
||||||
for i, name := range names {
|
|
||||||
if name != "" && i < len(ind)/2 {
|
|
||||||
if ind[i*2] != -1 && ind[i*2+1] != -1 {
|
|
||||||
captures[name] = [2]int{ind[i*2], ind[i*2+1]}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return captures
|
|
||||||
}
|
|
||||||
|
|
||||||
func extractIndex(item os.FileInfo) int {
|
|
||||||
r := regexp.MustCompile(`.+\.log(\.(?P<index>\d+))?`)
|
|
||||||
fileName := path.Base(item.Name())
|
|
||||||
m := findStringSubmatchIndexes(r, fileName)
|
|
||||||
if v, ok := m["index"]; ok {
|
|
||||||
i, _ := strconv.Atoi(fileName[v[0]:v[1]])
|
|
||||||
return i
|
|
||||||
} else {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
nocolor = 0
|
|
||||||
red = 31
|
|
||||||
green = 32
|
|
||||||
yellow = 33
|
|
||||||
blue = 34
|
|
||||||
gray = 37
|
|
||||||
)
|
|
||||||
|
|
||||||
type IndentKind int
|
|
||||||
|
|
||||||
const (
|
|
||||||
LeftIndent = iota
|
|
||||||
CenterIndent
|
|
||||||
RightIndent
|
|
||||||
)
|
|
||||||
|
|
||||||
func cutOrIndentText(text string, length int, indent IndentKind) string {
|
|
||||||
if length < 0 {
|
|
||||||
return text
|
|
||||||
} else if len(text) > length {
|
|
||||||
text = text[:length]
|
|
||||||
} else {
|
|
||||||
switch indent {
|
|
||||||
case LeftIndent:
|
|
||||||
text = text + strings.Repeat(" ", length-len(text))
|
|
||||||
case RightIndent:
|
|
||||||
text = strings.Repeat(" ", length-len(text)) + text
|
|
||||||
case CenterIndent:
|
|
||||||
text = strings.Repeat(" ", (length-len(text))/2) + text +
|
|
||||||
strings.Repeat(" ", length-len(text)-(length-len(text))/2)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return text
|
|
||||||
}
|
|
||||||
|
|
||||||
func metaFmtStr(colored bool, level LogLevel, options FormatOptions, appName string,
|
|
||||||
packageName string, message string, format string) string {
|
|
||||||
var colorPfx, colorSfx string
|
|
||||||
if colored {
|
|
||||||
var levelColor int
|
|
||||||
switch level {
|
|
||||||
case DebugLevel:
|
|
||||||
levelColor = gray
|
|
||||||
case InfoLevel:
|
|
||||||
levelColor = blue
|
|
||||||
case NotifyLevel, WarnLevel:
|
|
||||||
levelColor = yellow
|
|
||||||
case ErrorLevel, PanicLevel, FatalLevel:
|
|
||||||
levelColor = red
|
|
||||||
default:
|
|
||||||
levelColor = nocolor
|
|
||||||
}
|
|
||||||
colorPfx = "\x1b[" + strconv.Itoa(levelColor) + "m"
|
|
||||||
colorSfx = "\x1b[0m"
|
|
||||||
}
|
|
||||||
arg1 := time.Now().Format(options.TimeFormat)
|
|
||||||
arg2 := appName
|
|
||||||
arg3 := cutOrIndentText(packageName, options.PackageLength, RightIndent)
|
|
||||||
lvlStr := options.GetLevelStr(level)
|
|
||||||
lvlLen := len([]rune(lvlStr))
|
|
||||||
arg4 := colorPfx + cutOrIndentText(strings.ToUpper(lvlStr), lvlLen, LeftIndent) + colorSfx
|
|
||||||
arg5 := message
|
|
||||||
out := fmt.Sprintf(format, arg1, arg2, arg3, arg4, arg5)
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
func getApplicationName() string {
|
|
||||||
appName := os.Args[0]
|
|
||||||
return appName
|
|
||||||
}
|
|
15
vendor/github.com/davecgh/go-spew/LICENSE
generated
vendored
15
vendor/github.com/davecgh/go-spew/LICENSE
generated
vendored
|
@ -1,15 +0,0 @@
|
||||||
ISC License
|
|
||||||
|
|
||||||
Copyright (c) 2012-2016 Dave Collins <dave@davec.name>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
145
vendor/github.com/davecgh/go-spew/spew/bypass.go
generated
vendored
145
vendor/github.com/davecgh/go-spew/spew/bypass.go
generated
vendored
|
@ -1,145 +0,0 @@
|
||||||
// Copyright (c) 2015-2016 Dave Collins <dave@davec.name>
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, and distribute this software for any
|
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||||
// copyright notice and this permission notice appear in all copies.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
// NOTE: Due to the following build constraints, this file will only be compiled
|
|
||||||
// when the code is not running on Google App Engine, compiled by GopherJS, and
|
|
||||||
// "-tags safe" is not added to the go build command line. The "disableunsafe"
|
|
||||||
// tag is deprecated and thus should not be used.
|
|
||||||
// Go versions prior to 1.4 are disabled because they use a different layout
|
|
||||||
// for interfaces which make the implementation of unsafeReflectValue more complex.
|
|
||||||
// +build !js,!appengine,!safe,!disableunsafe,go1.4
|
|
||||||
|
|
||||||
package spew
|
|
||||||
|
|
||||||
import (
|
|
||||||
"reflect"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// UnsafeDisabled is a build-time constant which specifies whether or
|
|
||||||
// not access to the unsafe package is available.
|
|
||||||
UnsafeDisabled = false
|
|
||||||
|
|
||||||
// ptrSize is the size of a pointer on the current arch.
|
|
||||||
ptrSize = unsafe.Sizeof((*byte)(nil))
|
|
||||||
)
|
|
||||||
|
|
||||||
type flag uintptr
|
|
||||||
|
|
||||||
var (
|
|
||||||
// flagRO indicates whether the value field of a reflect.Value
|
|
||||||
// is read-only.
|
|
||||||
flagRO flag
|
|
||||||
|
|
||||||
// flagAddr indicates whether the address of the reflect.Value's
|
|
||||||
// value may be taken.
|
|
||||||
flagAddr flag
|
|
||||||
)
|
|
||||||
|
|
||||||
// flagKindMask holds the bits that make up the kind
|
|
||||||
// part of the flags field. In all the supported versions,
|
|
||||||
// it is in the lower 5 bits.
|
|
||||||
const flagKindMask = flag(0x1f)
|
|
||||||
|
|
||||||
// Different versions of Go have used different
|
|
||||||
// bit layouts for the flags type. This table
|
|
||||||
// records the known combinations.
|
|
||||||
var okFlags = []struct {
|
|
||||||
ro, addr flag
|
|
||||||
}{{
|
|
||||||
// From Go 1.4 to 1.5
|
|
||||||
ro: 1 << 5,
|
|
||||||
addr: 1 << 7,
|
|
||||||
}, {
|
|
||||||
// Up to Go tip.
|
|
||||||
ro: 1<<5 | 1<<6,
|
|
||||||
addr: 1 << 8,
|
|
||||||
}}
|
|
||||||
|
|
||||||
var flagValOffset = func() uintptr {
|
|
||||||
field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
|
|
||||||
if !ok {
|
|
||||||
panic("reflect.Value has no flag field")
|
|
||||||
}
|
|
||||||
return field.Offset
|
|
||||||
}()
|
|
||||||
|
|
||||||
// flagField returns a pointer to the flag field of a reflect.Value.
|
|
||||||
func flagField(v *reflect.Value) *flag {
|
|
||||||
return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset))
|
|
||||||
}
|
|
||||||
|
|
||||||
// unsafeReflectValue converts the passed reflect.Value into a one that bypasses
|
|
||||||
// the typical safety restrictions preventing access to unaddressable and
|
|
||||||
// unexported data. It works by digging the raw pointer to the underlying
|
|
||||||
// value out of the protected value and generating a new unprotected (unsafe)
|
|
||||||
// reflect.Value to it.
|
|
||||||
//
|
|
||||||
// This allows us to check for implementations of the Stringer and error
|
|
||||||
// interfaces to be used for pretty printing ordinarily unaddressable and
|
|
||||||
// inaccessible values such as unexported struct fields.
|
|
||||||
func unsafeReflectValue(v reflect.Value) reflect.Value {
|
|
||||||
if !v.IsValid() || (v.CanInterface() && v.CanAddr()) {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
flagFieldPtr := flagField(&v)
|
|
||||||
*flagFieldPtr &^= flagRO
|
|
||||||
*flagFieldPtr |= flagAddr
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sanity checks against future reflect package changes
|
|
||||||
// to the type or semantics of the Value.flag field.
|
|
||||||
func init() {
|
|
||||||
field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
|
|
||||||
if !ok {
|
|
||||||
panic("reflect.Value has no flag field")
|
|
||||||
}
|
|
||||||
if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() {
|
|
||||||
panic("reflect.Value flag field has changed kind")
|
|
||||||
}
|
|
||||||
type t0 int
|
|
||||||
var t struct {
|
|
||||||
A t0
|
|
||||||
// t0 will have flagEmbedRO set.
|
|
||||||
t0
|
|
||||||
// a will have flagStickyRO set
|
|
||||||
a t0
|
|
||||||
}
|
|
||||||
vA := reflect.ValueOf(t).FieldByName("A")
|
|
||||||
va := reflect.ValueOf(t).FieldByName("a")
|
|
||||||
vt0 := reflect.ValueOf(t).FieldByName("t0")
|
|
||||||
|
|
||||||
// Infer flagRO from the difference between the flags
|
|
||||||
// for the (otherwise identical) fields in t.
|
|
||||||
flagPublic := *flagField(&vA)
|
|
||||||
flagWithRO := *flagField(&va) | *flagField(&vt0)
|
|
||||||
flagRO = flagPublic ^ flagWithRO
|
|
||||||
|
|
||||||
// Infer flagAddr from the difference between a value
|
|
||||||
// taken from a pointer and not.
|
|
||||||
vPtrA := reflect.ValueOf(&t).Elem().FieldByName("A")
|
|
||||||
flagNoPtr := *flagField(&vA)
|
|
||||||
flagPtr := *flagField(&vPtrA)
|
|
||||||
flagAddr = flagNoPtr ^ flagPtr
|
|
||||||
|
|
||||||
// Check that the inferred flags tally with one of the known versions.
|
|
||||||
for _, f := range okFlags {
|
|
||||||
if flagRO == f.ro && flagAddr == f.addr {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
panic("reflect.Value read-only flag has changed semantics")
|
|
||||||
}
|
|
38
vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
generated
vendored
38
vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
generated
vendored
|
@ -1,38 +0,0 @@
|
||||||
// Copyright (c) 2015-2016 Dave Collins <dave@davec.name>
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, and distribute this software for any
|
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||||
// copyright notice and this permission notice appear in all copies.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
// NOTE: Due to the following build constraints, this file will only be compiled
|
|
||||||
// when the code is running on Google App Engine, compiled by GopherJS, or
|
|
||||||
// "-tags safe" is added to the go build command line. The "disableunsafe"
|
|
||||||
// tag is deprecated and thus should not be used.
|
|
||||||
// +build js appengine safe disableunsafe !go1.4
|
|
||||||
|
|
||||||
package spew
|
|
||||||
|
|
||||||
import "reflect"
|
|
||||||
|
|
||||||
const (
|
|
||||||
// UnsafeDisabled is a build-time constant which specifies whether or
|
|
||||||
// not access to the unsafe package is available.
|
|
||||||
UnsafeDisabled = true
|
|
||||||
)
|
|
||||||
|
|
||||||
// unsafeReflectValue typically converts the passed reflect.Value into a one
|
|
||||||
// that bypasses the typical safety restrictions preventing access to
|
|
||||||
// unaddressable and unexported data. However, doing this relies on access to
|
|
||||||
// the unsafe package. This is a stub version which simply returns the passed
|
|
||||||
// reflect.Value when the unsafe package is not available.
|
|
||||||
func unsafeReflectValue(v reflect.Value) reflect.Value {
|
|
||||||
return v
|
|
||||||
}
|
|
341
vendor/github.com/davecgh/go-spew/spew/common.go
generated
vendored
341
vendor/github.com/davecgh/go-spew/spew/common.go
generated
vendored
|
@ -1,341 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2013-2016 Dave Collins <dave@davec.name>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package spew
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"reflect"
|
|
||||||
"sort"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Some constants in the form of bytes to avoid string overhead. This mirrors
|
|
||||||
// the technique used in the fmt package.
|
|
||||||
var (
|
|
||||||
panicBytes = []byte("(PANIC=")
|
|
||||||
plusBytes = []byte("+")
|
|
||||||
iBytes = []byte("i")
|
|
||||||
trueBytes = []byte("true")
|
|
||||||
falseBytes = []byte("false")
|
|
||||||
interfaceBytes = []byte("(interface {})")
|
|
||||||
commaNewlineBytes = []byte(",\n")
|
|
||||||
newlineBytes = []byte("\n")
|
|
||||||
openBraceBytes = []byte("{")
|
|
||||||
openBraceNewlineBytes = []byte("{\n")
|
|
||||||
closeBraceBytes = []byte("}")
|
|
||||||
asteriskBytes = []byte("*")
|
|
||||||
colonBytes = []byte(":")
|
|
||||||
colonSpaceBytes = []byte(": ")
|
|
||||||
openParenBytes = []byte("(")
|
|
||||||
closeParenBytes = []byte(")")
|
|
||||||
spaceBytes = []byte(" ")
|
|
||||||
pointerChainBytes = []byte("->")
|
|
||||||
nilAngleBytes = []byte("<nil>")
|
|
||||||
maxNewlineBytes = []byte("<max depth reached>\n")
|
|
||||||
maxShortBytes = []byte("<max>")
|
|
||||||
circularBytes = []byte("<already shown>")
|
|
||||||
circularShortBytes = []byte("<shown>")
|
|
||||||
invalidAngleBytes = []byte("<invalid>")
|
|
||||||
openBracketBytes = []byte("[")
|
|
||||||
closeBracketBytes = []byte("]")
|
|
||||||
percentBytes = []byte("%")
|
|
||||||
precisionBytes = []byte(".")
|
|
||||||
openAngleBytes = []byte("<")
|
|
||||||
closeAngleBytes = []byte(">")
|
|
||||||
openMapBytes = []byte("map[")
|
|
||||||
closeMapBytes = []byte("]")
|
|
||||||
lenEqualsBytes = []byte("len=")
|
|
||||||
capEqualsBytes = []byte("cap=")
|
|
||||||
)
|
|
||||||
|
|
||||||
// hexDigits is used to map a decimal value to a hex digit.
|
|
||||||
var hexDigits = "0123456789abcdef"
|
|
||||||
|
|
||||||
// catchPanic handles any panics that might occur during the handleMethods
|
|
||||||
// calls.
|
|
||||||
func catchPanic(w io.Writer, v reflect.Value) {
|
|
||||||
if err := recover(); err != nil {
|
|
||||||
w.Write(panicBytes)
|
|
||||||
fmt.Fprintf(w, "%v", err)
|
|
||||||
w.Write(closeParenBytes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleMethods attempts to call the Error and String methods on the underlying
|
|
||||||
// type the passed reflect.Value represents and outputes the result to Writer w.
|
|
||||||
//
|
|
||||||
// It handles panics in any called methods by catching and displaying the error
|
|
||||||
// as the formatted value.
|
|
||||||
func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) {
|
|
||||||
// We need an interface to check if the type implements the error or
|
|
||||||
// Stringer interface. However, the reflect package won't give us an
|
|
||||||
// interface on certain things like unexported struct fields in order
|
|
||||||
// to enforce visibility rules. We use unsafe, when it's available,
|
|
||||||
// to bypass these restrictions since this package does not mutate the
|
|
||||||
// values.
|
|
||||||
if !v.CanInterface() {
|
|
||||||
if UnsafeDisabled {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
v = unsafeReflectValue(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Choose whether or not to do error and Stringer interface lookups against
|
|
||||||
// the base type or a pointer to the base type depending on settings.
|
|
||||||
// Technically calling one of these methods with a pointer receiver can
|
|
||||||
// mutate the value, however, types which choose to satisify an error or
|
|
||||||
// Stringer interface with a pointer receiver should not be mutating their
|
|
||||||
// state inside these interface methods.
|
|
||||||
if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() {
|
|
||||||
v = unsafeReflectValue(v)
|
|
||||||
}
|
|
||||||
if v.CanAddr() {
|
|
||||||
v = v.Addr()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is it an error or Stringer?
|
|
||||||
switch iface := v.Interface().(type) {
|
|
||||||
case error:
|
|
||||||
defer catchPanic(w, v)
|
|
||||||
if cs.ContinueOnMethod {
|
|
||||||
w.Write(openParenBytes)
|
|
||||||
w.Write([]byte(iface.Error()))
|
|
||||||
w.Write(closeParenBytes)
|
|
||||||
w.Write(spaceBytes)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Write([]byte(iface.Error()))
|
|
||||||
return true
|
|
||||||
|
|
||||||
case fmt.Stringer:
|
|
||||||
defer catchPanic(w, v)
|
|
||||||
if cs.ContinueOnMethod {
|
|
||||||
w.Write(openParenBytes)
|
|
||||||
w.Write([]byte(iface.String()))
|
|
||||||
w.Write(closeParenBytes)
|
|
||||||
w.Write(spaceBytes)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
w.Write([]byte(iface.String()))
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// printBool outputs a boolean value as true or false to Writer w.
|
|
||||||
func printBool(w io.Writer, val bool) {
|
|
||||||
if val {
|
|
||||||
w.Write(trueBytes)
|
|
||||||
} else {
|
|
||||||
w.Write(falseBytes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// printInt outputs a signed integer value to Writer w.
|
|
||||||
func printInt(w io.Writer, val int64, base int) {
|
|
||||||
w.Write([]byte(strconv.FormatInt(val, base)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// printUint outputs an unsigned integer value to Writer w.
|
|
||||||
func printUint(w io.Writer, val uint64, base int) {
|
|
||||||
w.Write([]byte(strconv.FormatUint(val, base)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// printFloat outputs a floating point value using the specified precision,
|
|
||||||
// which is expected to be 32 or 64bit, to Writer w.
|
|
||||||
func printFloat(w io.Writer, val float64, precision int) {
|
|
||||||
w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// printComplex outputs a complex value using the specified float precision
|
|
||||||
// for the real and imaginary parts to Writer w.
|
|
||||||
func printComplex(w io.Writer, c complex128, floatPrecision int) {
|
|
||||||
r := real(c)
|
|
||||||
w.Write(openParenBytes)
|
|
||||||
w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision)))
|
|
||||||
i := imag(c)
|
|
||||||
if i >= 0 {
|
|
||||||
w.Write(plusBytes)
|
|
||||||
}
|
|
||||||
w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision)))
|
|
||||||
w.Write(iBytes)
|
|
||||||
w.Write(closeParenBytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
// printHexPtr outputs a uintptr formatted as hexadecimal with a leading '0x'
|
|
||||||
// prefix to Writer w.
|
|
||||||
func printHexPtr(w io.Writer, p uintptr) {
|
|
||||||
// Null pointer.
|
|
||||||
num := uint64(p)
|
|
||||||
if num == 0 {
|
|
||||||
w.Write(nilAngleBytes)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix
|
|
||||||
buf := make([]byte, 18)
|
|
||||||
|
|
||||||
// It's simpler to construct the hex string right to left.
|
|
||||||
base := uint64(16)
|
|
||||||
i := len(buf) - 1
|
|
||||||
for num >= base {
|
|
||||||
buf[i] = hexDigits[num%base]
|
|
||||||
num /= base
|
|
||||||
i--
|
|
||||||
}
|
|
||||||
buf[i] = hexDigits[num]
|
|
||||||
|
|
||||||
// Add '0x' prefix.
|
|
||||||
i--
|
|
||||||
buf[i] = 'x'
|
|
||||||
i--
|
|
||||||
buf[i] = '0'
|
|
||||||
|
|
||||||
// Strip unused leading bytes.
|
|
||||||
buf = buf[i:]
|
|
||||||
w.Write(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// valuesSorter implements sort.Interface to allow a slice of reflect.Value
|
|
||||||
// elements to be sorted.
|
|
||||||
type valuesSorter struct {
|
|
||||||
values []reflect.Value
|
|
||||||
strings []string // either nil or same len and values
|
|
||||||
cs *ConfigState
|
|
||||||
}
|
|
||||||
|
|
||||||
// newValuesSorter initializes a valuesSorter instance, which holds a set of
|
|
||||||
// surrogate keys on which the data should be sorted. It uses flags in
|
|
||||||
// ConfigState to decide if and how to populate those surrogate keys.
|
|
||||||
func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface {
|
|
||||||
vs := &valuesSorter{values: values, cs: cs}
|
|
||||||
if canSortSimply(vs.values[0].Kind()) {
|
|
||||||
return vs
|
|
||||||
}
|
|
||||||
if !cs.DisableMethods {
|
|
||||||
vs.strings = make([]string, len(values))
|
|
||||||
for i := range vs.values {
|
|
||||||
b := bytes.Buffer{}
|
|
||||||
if !handleMethods(cs, &b, vs.values[i]) {
|
|
||||||
vs.strings = nil
|
|
||||||
break
|
|
||||||
}
|
|
||||||
vs.strings[i] = b.String()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if vs.strings == nil && cs.SpewKeys {
|
|
||||||
vs.strings = make([]string, len(values))
|
|
||||||
for i := range vs.values {
|
|
||||||
vs.strings[i] = Sprintf("%#v", vs.values[i].Interface())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return vs
|
|
||||||
}
|
|
||||||
|
|
||||||
// canSortSimply tests whether a reflect.Kind is a primitive that can be sorted
|
|
||||||
// directly, or whether it should be considered for sorting by surrogate keys
|
|
||||||
// (if the ConfigState allows it).
|
|
||||||
func canSortSimply(kind reflect.Kind) bool {
|
|
||||||
// This switch parallels valueSortLess, except for the default case.
|
|
||||||
switch kind {
|
|
||||||
case reflect.Bool:
|
|
||||||
return true
|
|
||||||
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
|
||||||
return true
|
|
||||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
|
||||||
return true
|
|
||||||
case reflect.Float32, reflect.Float64:
|
|
||||||
return true
|
|
||||||
case reflect.String:
|
|
||||||
return true
|
|
||||||
case reflect.Uintptr:
|
|
||||||
return true
|
|
||||||
case reflect.Array:
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Len returns the number of values in the slice. It is part of the
|
|
||||||
// sort.Interface implementation.
|
|
||||||
func (s *valuesSorter) Len() int {
|
|
||||||
return len(s.values)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap swaps the values at the passed indices. It is part of the
|
|
||||||
// sort.Interface implementation.
|
|
||||||
func (s *valuesSorter) Swap(i, j int) {
|
|
||||||
s.values[i], s.values[j] = s.values[j], s.values[i]
|
|
||||||
if s.strings != nil {
|
|
||||||
s.strings[i], s.strings[j] = s.strings[j], s.strings[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// valueSortLess returns whether the first value should sort before the second
|
|
||||||
// value. It is used by valueSorter.Less as part of the sort.Interface
|
|
||||||
// implementation.
|
|
||||||
func valueSortLess(a, b reflect.Value) bool {
|
|
||||||
switch a.Kind() {
|
|
||||||
case reflect.Bool:
|
|
||||||
return !a.Bool() && b.Bool()
|
|
||||||
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
|
||||||
return a.Int() < b.Int()
|
|
||||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
|
||||||
return a.Uint() < b.Uint()
|
|
||||||
case reflect.Float32, reflect.Float64:
|
|
||||||
return a.Float() < b.Float()
|
|
||||||
case reflect.String:
|
|
||||||
return a.String() < b.String()
|
|
||||||
case reflect.Uintptr:
|
|
||||||
return a.Uint() < b.Uint()
|
|
||||||
case reflect.Array:
|
|
||||||
// Compare the contents of both arrays.
|
|
||||||
l := a.Len()
|
|
||||||
for i := 0; i < l; i++ {
|
|
||||||
av := a.Index(i)
|
|
||||||
bv := b.Index(i)
|
|
||||||
if av.Interface() == bv.Interface() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return valueSortLess(av, bv)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return a.String() < b.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Less returns whether the value at index i should sort before the
|
|
||||||
// value at index j. It is part of the sort.Interface implementation.
|
|
||||||
func (s *valuesSorter) Less(i, j int) bool {
|
|
||||||
if s.strings == nil {
|
|
||||||
return valueSortLess(s.values[i], s.values[j])
|
|
||||||
}
|
|
||||||
return s.strings[i] < s.strings[j]
|
|
||||||
}
|
|
||||||
|
|
||||||
// sortValues is a sort function that handles both native types and any type that
|
|
||||||
// can be converted to error or Stringer. Other inputs are sorted according to
|
|
||||||
// their Value.String() value to ensure display stability.
|
|
||||||
func sortValues(values []reflect.Value, cs *ConfigState) {
|
|
||||||
if len(values) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
sort.Sort(newValuesSorter(values, cs))
|
|
||||||
}
|
|
306
vendor/github.com/davecgh/go-spew/spew/config.go
generated
vendored
306
vendor/github.com/davecgh/go-spew/spew/config.go
generated
vendored
|
@ -1,306 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2013-2016 Dave Collins <dave@davec.name>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package spew
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ConfigState houses the configuration options used by spew to format and
|
|
||||||
// display values. There is a global instance, Config, that is used to control
|
|
||||||
// all top-level Formatter and Dump functionality. Each ConfigState instance
|
|
||||||
// provides methods equivalent to the top-level functions.
|
|
||||||
//
|
|
||||||
// The zero value for ConfigState provides no indentation. You would typically
|
|
||||||
// want to set it to a space or a tab.
|
|
||||||
//
|
|
||||||
// Alternatively, you can use NewDefaultConfig to get a ConfigState instance
|
|
||||||
// with default settings. See the documentation of NewDefaultConfig for default
|
|
||||||
// values.
|
|
||||||
type ConfigState struct {
|
|
||||||
// Indent specifies the string to use for each indentation level. The
|
|
||||||
// global config instance that all top-level functions use set this to a
|
|
||||||
// single space by default. If you would like more indentation, you might
|
|
||||||
// set this to a tab with "\t" or perhaps two spaces with " ".
|
|
||||||
Indent string
|
|
||||||
|
|
||||||
// MaxDepth controls the maximum number of levels to descend into nested
|
|
||||||
// data structures. The default, 0, means there is no limit.
|
|
||||||
//
|
|
||||||
// NOTE: Circular data structures are properly detected, so it is not
|
|
||||||
// necessary to set this value unless you specifically want to limit deeply
|
|
||||||
// nested data structures.
|
|
||||||
MaxDepth int
|
|
||||||
|
|
||||||
// DisableMethods specifies whether or not error and Stringer interfaces are
|
|
||||||
// invoked for types that implement them.
|
|
||||||
DisableMethods bool
|
|
||||||
|
|
||||||
// DisablePointerMethods specifies whether or not to check for and invoke
|
|
||||||
// error and Stringer interfaces on types which only accept a pointer
|
|
||||||
// receiver when the current type is not a pointer.
|
|
||||||
//
|
|
||||||
// NOTE: This might be an unsafe action since calling one of these methods
|
|
||||||
// with a pointer receiver could technically mutate the value, however,
|
|
||||||
// in practice, types which choose to satisify an error or Stringer
|
|
||||||
// interface with a pointer receiver should not be mutating their state
|
|
||||||
// inside these interface methods. As a result, this option relies on
|
|
||||||
// access to the unsafe package, so it will not have any effect when
|
|
||||||
// running in environments without access to the unsafe package such as
|
|
||||||
// Google App Engine or with the "safe" build tag specified.
|
|
||||||
DisablePointerMethods bool
|
|
||||||
|
|
||||||
// DisablePointerAddresses specifies whether to disable the printing of
|
|
||||||
// pointer addresses. This is useful when diffing data structures in tests.
|
|
||||||
DisablePointerAddresses bool
|
|
||||||
|
|
||||||
// DisableCapacities specifies whether to disable the printing of capacities
|
|
||||||
// for arrays, slices, maps and channels. This is useful when diffing
|
|
||||||
// data structures in tests.
|
|
||||||
DisableCapacities bool
|
|
||||||
|
|
||||||
// ContinueOnMethod specifies whether or not recursion should continue once
|
|
||||||
// a custom error or Stringer interface is invoked. The default, false,
|
|
||||||
// means it will print the results of invoking the custom error or Stringer
|
|
||||||
// interface and return immediately instead of continuing to recurse into
|
|
||||||
// the internals of the data type.
|
|
||||||
//
|
|
||||||
// NOTE: This flag does not have any effect if method invocation is disabled
|
|
||||||
// via the DisableMethods or DisablePointerMethods options.
|
|
||||||
ContinueOnMethod bool
|
|
||||||
|
|
||||||
// SortKeys specifies map keys should be sorted before being printed. Use
|
|
||||||
// this to have a more deterministic, diffable output. Note that only
|
|
||||||
// native types (bool, int, uint, floats, uintptr and string) and types
|
|
||||||
// that support the error or Stringer interfaces (if methods are
|
|
||||||
// enabled) are supported, with other types sorted according to the
|
|
||||||
// reflect.Value.String() output which guarantees display stability.
|
|
||||||
SortKeys bool
|
|
||||||
|
|
||||||
// SpewKeys specifies that, as a last resort attempt, map keys should
|
|
||||||
// be spewed to strings and sorted by those strings. This is only
|
|
||||||
// considered if SortKeys is true.
|
|
||||||
SpewKeys bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Config is the active configuration of the top-level functions.
|
|
||||||
// The configuration can be changed by modifying the contents of spew.Config.
|
|
||||||
var Config = ConfigState{Indent: " "}
|
|
||||||
|
|
||||||
// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
|
|
||||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
|
||||||
// the formatted string as a value that satisfies error. See NewFormatter
|
|
||||||
// for formatting details.
|
|
||||||
//
|
|
||||||
// This function is shorthand for the following syntax:
|
|
||||||
//
|
|
||||||
// fmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b))
|
|
||||||
func (c *ConfigState) Errorf(format string, a ...interface{}) (err error) {
|
|
||||||
return fmt.Errorf(format, c.convertArgs(a)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
|
|
||||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
|
||||||
// the number of bytes written and any write error encountered. See
|
|
||||||
// NewFormatter for formatting details.
|
|
||||||
//
|
|
||||||
// This function is shorthand for the following syntax:
|
|
||||||
//
|
|
||||||
// fmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b))
|
|
||||||
func (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, err error) {
|
|
||||||
return fmt.Fprint(w, c.convertArgs(a)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
|
|
||||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
|
||||||
// the number of bytes written and any write error encountered. See
|
|
||||||
// NewFormatter for formatting details.
|
|
||||||
//
|
|
||||||
// This function is shorthand for the following syntax:
|
|
||||||
//
|
|
||||||
// fmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b))
|
|
||||||
func (c *ConfigState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
|
|
||||||
return fmt.Fprintf(w, format, c.convertArgs(a)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
|
|
||||||
// passed with a Formatter interface returned by c.NewFormatter. See
|
|
||||||
// NewFormatter for formatting details.
|
|
||||||
//
|
|
||||||
// This function is shorthand for the following syntax:
|
|
||||||
//
|
|
||||||
// fmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b))
|
|
||||||
func (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
|
|
||||||
return fmt.Fprintln(w, c.convertArgs(a)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print is a wrapper for fmt.Print that treats each argument as if it were
|
|
||||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
|
||||||
// the number of bytes written and any write error encountered. See
|
|
||||||
// NewFormatter for formatting details.
|
|
||||||
//
|
|
||||||
// This function is shorthand for the following syntax:
|
|
||||||
//
|
|
||||||
// fmt.Print(c.NewFormatter(a), c.NewFormatter(b))
|
|
||||||
func (c *ConfigState) Print(a ...interface{}) (n int, err error) {
|
|
||||||
return fmt.Print(c.convertArgs(a)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Printf is a wrapper for fmt.Printf that treats each argument as if it were
|
|
||||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
|
||||||
// the number of bytes written and any write error encountered. See
|
|
||||||
// NewFormatter for formatting details.
|
|
||||||
//
|
|
||||||
// This function is shorthand for the following syntax:
|
|
||||||
//
|
|
||||||
// fmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b))
|
|
||||||
func (c *ConfigState) Printf(format string, a ...interface{}) (n int, err error) {
|
|
||||||
return fmt.Printf(format, c.convertArgs(a)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Println is a wrapper for fmt.Println that treats each argument as if it were
|
|
||||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
|
||||||
// the number of bytes written and any write error encountered. See
|
|
||||||
// NewFormatter for formatting details.
|
|
||||||
//
|
|
||||||
// This function is shorthand for the following syntax:
|
|
||||||
//
|
|
||||||
// fmt.Println(c.NewFormatter(a), c.NewFormatter(b))
|
|
||||||
func (c *ConfigState) Println(a ...interface{}) (n int, err error) {
|
|
||||||
return fmt.Println(c.convertArgs(a)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were
|
|
||||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
|
||||||
// the resulting string. See NewFormatter for formatting details.
|
|
||||||
//
|
|
||||||
// This function is shorthand for the following syntax:
|
|
||||||
//
|
|
||||||
// fmt.Sprint(c.NewFormatter(a), c.NewFormatter(b))
|
|
||||||
func (c *ConfigState) Sprint(a ...interface{}) string {
|
|
||||||
return fmt.Sprint(c.convertArgs(a)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were
|
|
||||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
|
||||||
// the resulting string. See NewFormatter for formatting details.
|
|
||||||
//
|
|
||||||
// This function is shorthand for the following syntax:
|
|
||||||
//
|
|
||||||
// fmt.Sprintf(format, c.NewFormatter(a), c.NewFormatter(b))
|
|
||||||
func (c *ConfigState) Sprintf(format string, a ...interface{}) string {
|
|
||||||
return fmt.Sprintf(format, c.convertArgs(a)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it
|
|
||||||
// were passed with a Formatter interface returned by c.NewFormatter. It
|
|
||||||
// returns the resulting string. See NewFormatter for formatting details.
|
|
||||||
//
|
|
||||||
// This function is shorthand for the following syntax:
|
|
||||||
//
|
|
||||||
// fmt.Sprintln(c.NewFormatter(a), c.NewFormatter(b))
|
|
||||||
func (c *ConfigState) Sprintln(a ...interface{}) string {
|
|
||||||
return fmt.Sprintln(c.convertArgs(a)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
NewFormatter returns a custom formatter that satisfies the fmt.Formatter
|
|
||||||
interface. As a result, it integrates cleanly with standard fmt package
|
|
||||||
printing functions. The formatter is useful for inline printing of smaller data
|
|
||||||
types similar to the standard %v format specifier.
|
|
||||||
|
|
||||||
The custom formatter only responds to the %v (most compact), %+v (adds pointer
|
|
||||||
addresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb
|
|
||||||
combinations. Any other verbs such as %x and %q will be sent to the the
|
|
||||||
standard fmt package for formatting. In addition, the custom formatter ignores
|
|
||||||
the width and precision arguments (however they will still work on the format
|
|
||||||
specifiers not handled by the custom formatter).
|
|
||||||
|
|
||||||
Typically this function shouldn't be called directly. It is much easier to make
|
|
||||||
use of the custom formatter by calling one of the convenience functions such as
|
|
||||||
c.Printf, c.Println, or c.Printf.
|
|
||||||
*/
|
|
||||||
func (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter {
|
|
||||||
return newFormatter(c, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fdump formats and displays the passed arguments to io.Writer w. It formats
|
|
||||||
// exactly the same as Dump.
|
|
||||||
func (c *ConfigState) Fdump(w io.Writer, a ...interface{}) {
|
|
||||||
fdump(c, w, a...)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Dump displays the passed parameters to standard out with newlines, customizable
|
|
||||||
indentation, and additional debug information such as complete types and all
|
|
||||||
pointer addresses used to indirect to the final value. It provides the
|
|
||||||
following features over the built-in printing facilities provided by the fmt
|
|
||||||
package:
|
|
||||||
|
|
||||||
* Pointers are dereferenced and followed
|
|
||||||
* Circular data structures are detected and handled properly
|
|
||||||
* Custom Stringer/error interfaces are optionally invoked, including
|
|
||||||
on unexported types
|
|
||||||
* Custom types which only implement the Stringer/error interfaces via
|
|
||||||
a pointer receiver are optionally invoked when passing non-pointer
|
|
||||||
variables
|
|
||||||
* Byte arrays and slices are dumped like the hexdump -C command which
|
|
||||||
includes offsets, byte values in hex, and ASCII output
|
|
||||||
|
|
||||||
The configuration options are controlled by modifying the public members
|
|
||||||
of c. See ConfigState for options documentation.
|
|
||||||
|
|
||||||
See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to
|
|
||||||
get the formatted result as a string.
|
|
||||||
*/
|
|
||||||
func (c *ConfigState) Dump(a ...interface{}) {
|
|
||||||
fdump(c, os.Stdout, a...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sdump returns a string with the passed arguments formatted exactly the same
|
|
||||||
// as Dump.
|
|
||||||
func (c *ConfigState) Sdump(a ...interface{}) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
fdump(c, &buf, a...)
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// convertArgs accepts a slice of arguments and returns a slice of the same
|
|
||||||
// length with each argument converted to a spew Formatter interface using
|
|
||||||
// the ConfigState associated with s.
|
|
||||||
func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) {
|
|
||||||
formatters = make([]interface{}, len(args))
|
|
||||||
for index, arg := range args {
|
|
||||||
formatters[index] = newFormatter(c, arg)
|
|
||||||
}
|
|
||||||
return formatters
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDefaultConfig returns a ConfigState with the following default settings.
|
|
||||||
//
|
|
||||||
// Indent: " "
|
|
||||||
// MaxDepth: 0
|
|
||||||
// DisableMethods: false
|
|
||||||
// DisablePointerMethods: false
|
|
||||||
// ContinueOnMethod: false
|
|
||||||
// SortKeys: false
|
|
||||||
func NewDefaultConfig() *ConfigState {
|
|
||||||
return &ConfigState{Indent: " "}
|
|
||||||
}
|
|
211
vendor/github.com/davecgh/go-spew/spew/doc.go
generated
vendored
211
vendor/github.com/davecgh/go-spew/spew/doc.go
generated
vendored
|
@ -1,211 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2013-2016 Dave Collins <dave@davec.name>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Package spew implements a deep pretty printer for Go data structures to aid in
|
|
||||||
debugging.
|
|
||||||
|
|
||||||
A quick overview of the additional features spew provides over the built-in
|
|
||||||
printing facilities for Go data types are as follows:
|
|
||||||
|
|
||||||
* Pointers are dereferenced and followed
|
|
||||||
* Circular data structures are detected and handled properly
|
|
||||||
* Custom Stringer/error interfaces are optionally invoked, including
|
|
||||||
on unexported types
|
|
||||||
* Custom types which only implement the Stringer/error interfaces via
|
|
||||||
a pointer receiver are optionally invoked when passing non-pointer
|
|
||||||
variables
|
|
||||||
* Byte arrays and slices are dumped like the hexdump -C command which
|
|
||||||
includes offsets, byte values in hex, and ASCII output (only when using
|
|
||||||
Dump style)
|
|
||||||
|
|
||||||
There are two different approaches spew allows for dumping Go data structures:
|
|
||||||
|
|
||||||
* Dump style which prints with newlines, customizable indentation,
|
|
||||||
and additional debug information such as types and all pointer addresses
|
|
||||||
used to indirect to the final value
|
|
||||||
* A custom Formatter interface that integrates cleanly with the standard fmt
|
|
||||||
package and replaces %v, %+v, %#v, and %#+v to provide inline printing
|
|
||||||
similar to the default %v while providing the additional functionality
|
|
||||||
outlined above and passing unsupported format verbs such as %x and %q
|
|
||||||
along to fmt
|
|
||||||
|
|
||||||
Quick Start
|
|
||||||
|
|
||||||
This section demonstrates how to quickly get started with spew. See the
|
|
||||||
sections below for further details on formatting and configuration options.
|
|
||||||
|
|
||||||
To dump a variable with full newlines, indentation, type, and pointer
|
|
||||||
information use Dump, Fdump, or Sdump:
|
|
||||||
spew.Dump(myVar1, myVar2, ...)
|
|
||||||
spew.Fdump(someWriter, myVar1, myVar2, ...)
|
|
||||||
str := spew.Sdump(myVar1, myVar2, ...)
|
|
||||||
|
|
||||||
Alternatively, if you would prefer to use format strings with a compacted inline
|
|
||||||
printing style, use the convenience wrappers Printf, Fprintf, etc with
|
|
||||||
%v (most compact), %+v (adds pointer addresses), %#v (adds types), or
|
|
||||||
%#+v (adds types and pointer addresses):
|
|
||||||
spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
|
|
||||||
spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
|
|
||||||
spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
|
|
||||||
spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
|
|
||||||
|
|
||||||
Configuration Options
|
|
||||||
|
|
||||||
Configuration of spew is handled by fields in the ConfigState type. For
|
|
||||||
convenience, all of the top-level functions use a global state available
|
|
||||||
via the spew.Config global.
|
|
||||||
|
|
||||||
It is also possible to create a ConfigState instance that provides methods
|
|
||||||
equivalent to the top-level functions. This allows concurrent configuration
|
|
||||||
options. See the ConfigState documentation for more details.
|
|
||||||
|
|
||||||
The following configuration options are available:
|
|
||||||
* Indent
|
|
||||||
String to use for each indentation level for Dump functions.
|
|
||||||
It is a single space by default. A popular alternative is "\t".
|
|
||||||
|
|
||||||
* MaxDepth
|
|
||||||
Maximum number of levels to descend into nested data structures.
|
|
||||||
There is no limit by default.
|
|
||||||
|
|
||||||
* DisableMethods
|
|
||||||
Disables invocation of error and Stringer interface methods.
|
|
||||||
Method invocation is enabled by default.
|
|
||||||
|
|
||||||
* DisablePointerMethods
|
|
||||||
Disables invocation of error and Stringer interface methods on types
|
|
||||||
which only accept pointer receivers from non-pointer variables.
|
|
||||||
Pointer method invocation is enabled by default.
|
|
||||||
|
|
||||||
* DisablePointerAddresses
|
|
||||||
DisablePointerAddresses specifies whether to disable the printing of
|
|
||||||
pointer addresses. This is useful when diffing data structures in tests.
|
|
||||||
|
|
||||||
* DisableCapacities
|
|
||||||
DisableCapacities specifies whether to disable the printing of
|
|
||||||
capacities for arrays, slices, maps and channels. This is useful when
|
|
||||||
diffing data structures in tests.
|
|
||||||
|
|
||||||
* ContinueOnMethod
|
|
||||||
Enables recursion into types after invoking error and Stringer interface
|
|
||||||
methods. Recursion after method invocation is disabled by default.
|
|
||||||
|
|
||||||
* SortKeys
|
|
||||||
Specifies map keys should be sorted before being printed. Use
|
|
||||||
this to have a more deterministic, diffable output. Note that
|
|
||||||
only native types (bool, int, uint, floats, uintptr and string)
|
|
||||||
and types which implement error or Stringer interfaces are
|
|
||||||
supported with other types sorted according to the
|
|
||||||
reflect.Value.String() output which guarantees display
|
|
||||||
stability. Natural map order is used by default.
|
|
||||||
|
|
||||||
* SpewKeys
|
|
||||||
Specifies that, as a last resort attempt, map keys should be
|
|
||||||
spewed to strings and sorted by those strings. This is only
|
|
||||||
considered if SortKeys is true.
|
|
||||||
|
|
||||||
Dump Usage
|
|
||||||
|
|
||||||
Simply call spew.Dump with a list of variables you want to dump:
|
|
||||||
|
|
||||||
spew.Dump(myVar1, myVar2, ...)
|
|
||||||
|
|
||||||
You may also call spew.Fdump if you would prefer to output to an arbitrary
|
|
||||||
io.Writer. For example, to dump to standard error:
|
|
||||||
|
|
||||||
spew.Fdump(os.Stderr, myVar1, myVar2, ...)
|
|
||||||
|
|
||||||
A third option is to call spew.Sdump to get the formatted output as a string:
|
|
||||||
|
|
||||||
str := spew.Sdump(myVar1, myVar2, ...)
|
|
||||||
|
|
||||||
Sample Dump Output
|
|
||||||
|
|
||||||
See the Dump example for details on the setup of the types and variables being
|
|
||||||
shown here.
|
|
||||||
|
|
||||||
(main.Foo) {
|
|
||||||
unexportedField: (*main.Bar)(0xf84002e210)({
|
|
||||||
flag: (main.Flag) flagTwo,
|
|
||||||
data: (uintptr) <nil>
|
|
||||||
}),
|
|
||||||
ExportedField: (map[interface {}]interface {}) (len=1) {
|
|
||||||
(string) (len=3) "one": (bool) true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C
|
|
||||||
command as shown.
|
|
||||||
([]uint8) (len=32 cap=32) {
|
|
||||||
00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... |
|
|
||||||
00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0|
|
|
||||||
00000020 31 32 |12|
|
|
||||||
}
|
|
||||||
|
|
||||||
Custom Formatter
|
|
||||||
|
|
||||||
Spew provides a custom formatter that implements the fmt.Formatter interface
|
|
||||||
so that it integrates cleanly with standard fmt package printing functions. The
|
|
||||||
formatter is useful for inline printing of smaller data types similar to the
|
|
||||||
standard %v format specifier.
|
|
||||||
|
|
||||||
The custom formatter only responds to the %v (most compact), %+v (adds pointer
|
|
||||||
addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb
|
|
||||||
combinations. Any other verbs such as %x and %q will be sent to the the
|
|
||||||
standard fmt package for formatting. In addition, the custom formatter ignores
|
|
||||||
the width and precision arguments (however they will still work on the format
|
|
||||||
specifiers not handled by the custom formatter).
|
|
||||||
|
|
||||||
Custom Formatter Usage
|
|
||||||
|
|
||||||
The simplest way to make use of the spew custom formatter is to call one of the
|
|
||||||
convenience functions such as spew.Printf, spew.Println, or spew.Printf. The
|
|
||||||
functions have syntax you are most likely already familiar with:
|
|
||||||
|
|
||||||
spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
|
|
||||||
spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
|
|
||||||
spew.Println(myVar, myVar2)
|
|
||||||
spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
|
|
||||||
spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
|
|
||||||
|
|
||||||
See the Index for the full list convenience functions.
|
|
||||||
|
|
||||||
Sample Formatter Output
|
|
||||||
|
|
||||||
Double pointer to a uint8:
|
|
||||||
%v: <**>5
|
|
||||||
%+v: <**>(0xf8400420d0->0xf8400420c8)5
|
|
||||||
%#v: (**uint8)5
|
|
||||||
%#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5
|
|
||||||
|
|
||||||
Pointer to circular struct with a uint8 field and a pointer to itself:
|
|
||||||
%v: <*>{1 <*><shown>}
|
|
||||||
%+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)<shown>}
|
|
||||||
%#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)<shown>}
|
|
||||||
%#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)<shown>}
|
|
||||||
|
|
||||||
See the Printf example for details on the setup of variables being shown
|
|
||||||
here.
|
|
||||||
|
|
||||||
Errors
|
|
||||||
|
|
||||||
Since it is possible for custom Stringer/error interfaces to panic, spew
|
|
||||||
detects them and handles them internally by printing the panic information
|
|
||||||
inline with the output. Since spew is intended to provide deep pretty printing
|
|
||||||
capabilities on structures, it intentionally does not return any errors.
|
|
||||||
*/
|
|
||||||
package spew
|
|
509
vendor/github.com/davecgh/go-spew/spew/dump.go
generated
vendored
509
vendor/github.com/davecgh/go-spew/spew/dump.go
generated
vendored
|
@ -1,509 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2013-2016 Dave Collins <dave@davec.name>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package spew
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"reflect"
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// uint8Type is a reflect.Type representing a uint8. It is used to
|
|
||||||
// convert cgo types to uint8 slices for hexdumping.
|
|
||||||
uint8Type = reflect.TypeOf(uint8(0))
|
|
||||||
|
|
||||||
// cCharRE is a regular expression that matches a cgo char.
|
|
||||||
// It is used to detect character arrays to hexdump them.
|
|
||||||
cCharRE = regexp.MustCompile(`^.*\._Ctype_char$`)
|
|
||||||
|
|
||||||
// cUnsignedCharRE is a regular expression that matches a cgo unsigned
|
|
||||||
// char. It is used to detect unsigned character arrays to hexdump
|
|
||||||
// them.
|
|
||||||
cUnsignedCharRE = regexp.MustCompile(`^.*\._Ctype_unsignedchar$`)
|
|
||||||
|
|
||||||
// cUint8tCharRE is a regular expression that matches a cgo uint8_t.
|
|
||||||
// It is used to detect uint8_t arrays to hexdump them.
|
|
||||||
cUint8tCharRE = regexp.MustCompile(`^.*\._Ctype_uint8_t$`)
|
|
||||||
)
|
|
||||||
|
|
||||||
// dumpState contains information about the state of a dump operation.
|
|
||||||
type dumpState struct {
|
|
||||||
w io.Writer
|
|
||||||
depth int
|
|
||||||
pointers map[uintptr]int
|
|
||||||
ignoreNextType bool
|
|
||||||
ignoreNextIndent bool
|
|
||||||
cs *ConfigState
|
|
||||||
}
|
|
||||||
|
|
||||||
// indent performs indentation according to the depth level and cs.Indent
|
|
||||||
// option.
|
|
||||||
func (d *dumpState) indent() {
|
|
||||||
if d.ignoreNextIndent {
|
|
||||||
d.ignoreNextIndent = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
d.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth))
|
|
||||||
}
|
|
||||||
|
|
||||||
// unpackValue returns values inside of non-nil interfaces when possible.
|
|
||||||
// This is useful for data types like structs, arrays, slices, and maps which
|
|
||||||
// can contain varying types packed inside an interface.
|
|
||||||
func (d *dumpState) unpackValue(v reflect.Value) reflect.Value {
|
|
||||||
if v.Kind() == reflect.Interface && !v.IsNil() {
|
|
||||||
v = v.Elem()
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// dumpPtr handles formatting of pointers by indirecting them as necessary.
|
|
||||||
func (d *dumpState) dumpPtr(v reflect.Value) {
|
|
||||||
// Remove pointers at or below the current depth from map used to detect
|
|
||||||
// circular refs.
|
|
||||||
for k, depth := range d.pointers {
|
|
||||||
if depth >= d.depth {
|
|
||||||
delete(d.pointers, k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep list of all dereferenced pointers to show later.
|
|
||||||
pointerChain := make([]uintptr, 0)
|
|
||||||
|
|
||||||
// Figure out how many levels of indirection there are by dereferencing
|
|
||||||
// pointers and unpacking interfaces down the chain while detecting circular
|
|
||||||
// references.
|
|
||||||
nilFound := false
|
|
||||||
cycleFound := false
|
|
||||||
indirects := 0
|
|
||||||
ve := v
|
|
||||||
for ve.Kind() == reflect.Ptr {
|
|
||||||
if ve.IsNil() {
|
|
||||||
nilFound = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
indirects++
|
|
||||||
addr := ve.Pointer()
|
|
||||||
pointerChain = append(pointerChain, addr)
|
|
||||||
if pd, ok := d.pointers[addr]; ok && pd < d.depth {
|
|
||||||
cycleFound = true
|
|
||||||
indirects--
|
|
||||||
break
|
|
||||||
}
|
|
||||||
d.pointers[addr] = d.depth
|
|
||||||
|
|
||||||
ve = ve.Elem()
|
|
||||||
if ve.Kind() == reflect.Interface {
|
|
||||||
if ve.IsNil() {
|
|
||||||
nilFound = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
ve = ve.Elem()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display type information.
|
|
||||||
d.w.Write(openParenBytes)
|
|
||||||
d.w.Write(bytes.Repeat(asteriskBytes, indirects))
|
|
||||||
d.w.Write([]byte(ve.Type().String()))
|
|
||||||
d.w.Write(closeParenBytes)
|
|
||||||
|
|
||||||
// Display pointer information.
|
|
||||||
if !d.cs.DisablePointerAddresses && len(pointerChain) > 0 {
|
|
||||||
d.w.Write(openParenBytes)
|
|
||||||
for i, addr := range pointerChain {
|
|
||||||
if i > 0 {
|
|
||||||
d.w.Write(pointerChainBytes)
|
|
||||||
}
|
|
||||||
printHexPtr(d.w, addr)
|
|
||||||
}
|
|
||||||
d.w.Write(closeParenBytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display dereferenced value.
|
|
||||||
d.w.Write(openParenBytes)
|
|
||||||
switch {
|
|
||||||
case nilFound:
|
|
||||||
d.w.Write(nilAngleBytes)
|
|
||||||
|
|
||||||
case cycleFound:
|
|
||||||
d.w.Write(circularBytes)
|
|
||||||
|
|
||||||
default:
|
|
||||||
d.ignoreNextType = true
|
|
||||||
d.dump(ve)
|
|
||||||
}
|
|
||||||
d.w.Write(closeParenBytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
// dumpSlice handles formatting of arrays and slices. Byte (uint8 under
|
|
||||||
// reflection) arrays and slices are dumped in hexdump -C fashion.
|
|
||||||
func (d *dumpState) dumpSlice(v reflect.Value) {
|
|
||||||
// Determine whether this type should be hex dumped or not. Also,
|
|
||||||
// for types which should be hexdumped, try to use the underlying data
|
|
||||||
// first, then fall back to trying to convert them to a uint8 slice.
|
|
||||||
var buf []uint8
|
|
||||||
doConvert := false
|
|
||||||
doHexDump := false
|
|
||||||
numEntries := v.Len()
|
|
||||||
if numEntries > 0 {
|
|
||||||
vt := v.Index(0).Type()
|
|
||||||
vts := vt.String()
|
|
||||||
switch {
|
|
||||||
// C types that need to be converted.
|
|
||||||
case cCharRE.MatchString(vts):
|
|
||||||
fallthrough
|
|
||||||
case cUnsignedCharRE.MatchString(vts):
|
|
||||||
fallthrough
|
|
||||||
case cUint8tCharRE.MatchString(vts):
|
|
||||||
doConvert = true
|
|
||||||
|
|
||||||
// Try to use existing uint8 slices and fall back to converting
|
|
||||||
// and copying if that fails.
|
|
||||||
case vt.Kind() == reflect.Uint8:
|
|
||||||
// We need an addressable interface to convert the type
|
|
||||||
// to a byte slice. However, the reflect package won't
|
|
||||||
// give us an interface on certain things like
|
|
||||||
// unexported struct fields in order to enforce
|
|
||||||
// visibility rules. We use unsafe, when available, to
|
|
||||||
// bypass these restrictions since this package does not
|
|
||||||
// mutate the values.
|
|
||||||
vs := v
|
|
||||||
if !vs.CanInterface() || !vs.CanAddr() {
|
|
||||||
vs = unsafeReflectValue(vs)
|
|
||||||
}
|
|
||||||
if !UnsafeDisabled {
|
|
||||||
vs = vs.Slice(0, numEntries)
|
|
||||||
|
|
||||||
// Use the existing uint8 slice if it can be
|
|
||||||
// type asserted.
|
|
||||||
iface := vs.Interface()
|
|
||||||
if slice, ok := iface.([]uint8); ok {
|
|
||||||
buf = slice
|
|
||||||
doHexDump = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The underlying data needs to be converted if it can't
|
|
||||||
// be type asserted to a uint8 slice.
|
|
||||||
doConvert = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy and convert the underlying type if needed.
|
|
||||||
if doConvert && vt.ConvertibleTo(uint8Type) {
|
|
||||||
// Convert and copy each element into a uint8 byte
|
|
||||||
// slice.
|
|
||||||
buf = make([]uint8, numEntries)
|
|
||||||
for i := 0; i < numEntries; i++ {
|
|
||||||
vv := v.Index(i)
|
|
||||||
buf[i] = uint8(vv.Convert(uint8Type).Uint())
|
|
||||||
}
|
|
||||||
doHexDump = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hexdump the entire slice as needed.
|
|
||||||
if doHexDump {
|
|
||||||
indent := strings.Repeat(d.cs.Indent, d.depth)
|
|
||||||
str := indent + hex.Dump(buf)
|
|
||||||
str = strings.Replace(str, "\n", "\n"+indent, -1)
|
|
||||||
str = strings.TrimRight(str, d.cs.Indent)
|
|
||||||
d.w.Write([]byte(str))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recursively call dump for each item.
|
|
||||||
for i := 0; i < numEntries; i++ {
|
|
||||||
d.dump(d.unpackValue(v.Index(i)))
|
|
||||||
if i < (numEntries - 1) {
|
|
||||||
d.w.Write(commaNewlineBytes)
|
|
||||||
} else {
|
|
||||||
d.w.Write(newlineBytes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// dump is the main workhorse for dumping a value. It uses the passed reflect
|
|
||||||
// value to figure out what kind of object we are dealing with and formats it
|
|
||||||
// appropriately. It is a recursive function, however circular data structures
|
|
||||||
// are detected and handled properly.
|
|
||||||
func (d *dumpState) dump(v reflect.Value) {
|
|
||||||
// Handle invalid reflect values immediately.
|
|
||||||
kind := v.Kind()
|
|
||||||
if kind == reflect.Invalid {
|
|
||||||
d.w.Write(invalidAngleBytes)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle pointers specially.
|
|
||||||
if kind == reflect.Ptr {
|
|
||||||
d.indent()
|
|
||||||
d.dumpPtr(v)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print type information unless already handled elsewhere.
|
|
||||||
if !d.ignoreNextType {
|
|
||||||
d.indent()
|
|
||||||
d.w.Write(openParenBytes)
|
|
||||||
d.w.Write([]byte(v.Type().String()))
|
|
||||||
d.w.Write(closeParenBytes)
|
|
||||||
d.w.Write(spaceBytes)
|
|
||||||
}
|
|
||||||
d.ignoreNextType = false
|
|
||||||
|
|
||||||
// Display length and capacity if the built-in len and cap functions
|
|
||||||
// work with the value's kind and the len/cap itself is non-zero.
|
|
||||||
valueLen, valueCap := 0, 0
|
|
||||||
switch v.Kind() {
|
|
||||||
case reflect.Array, reflect.Slice, reflect.Chan:
|
|
||||||
valueLen, valueCap = v.Len(), v.Cap()
|
|
||||||
case reflect.Map, reflect.String:
|
|
||||||
valueLen = v.Len()
|
|
||||||
}
|
|
||||||
if valueLen != 0 || !d.cs.DisableCapacities && valueCap != 0 {
|
|
||||||
d.w.Write(openParenBytes)
|
|
||||||
if valueLen != 0 {
|
|
||||||
d.w.Write(lenEqualsBytes)
|
|
||||||
printInt(d.w, int64(valueLen), 10)
|
|
||||||
}
|
|
||||||
if !d.cs.DisableCapacities && valueCap != 0 {
|
|
||||||
if valueLen != 0 {
|
|
||||||
d.w.Write(spaceBytes)
|
|
||||||
}
|
|
||||||
d.w.Write(capEqualsBytes)
|
|
||||||
printInt(d.w, int64(valueCap), 10)
|
|
||||||
}
|
|
||||||
d.w.Write(closeParenBytes)
|
|
||||||
d.w.Write(spaceBytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call Stringer/error interfaces if they exist and the handle methods flag
|
|
||||||
// is enabled
|
|
||||||
if !d.cs.DisableMethods {
|
|
||||||
if (kind != reflect.Invalid) && (kind != reflect.Interface) {
|
|
||||||
if handled := handleMethods(d.cs, d.w, v); handled {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch kind {
|
|
||||||
case reflect.Invalid:
|
|
||||||
// Do nothing. We should never get here since invalid has already
|
|
||||||
// been handled above.
|
|
||||||
|
|
||||||
case reflect.Bool:
|
|
||||||
printBool(d.w, v.Bool())
|
|
||||||
|
|
||||||
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
|
||||||
printInt(d.w, v.Int(), 10)
|
|
||||||
|
|
||||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
|
||||||
printUint(d.w, v.Uint(), 10)
|
|
||||||
|
|
||||||
case reflect.Float32:
|
|
||||||
printFloat(d.w, v.Float(), 32)
|
|
||||||
|
|
||||||
case reflect.Float64:
|
|
||||||
printFloat(d.w, v.Float(), 64)
|
|
||||||
|
|
||||||
case reflect.Complex64:
|
|
||||||
printComplex(d.w, v.Complex(), 32)
|
|
||||||
|
|
||||||
case reflect.Complex128:
|
|
||||||
printComplex(d.w, v.Complex(), 64)
|
|
||||||
|
|
||||||
case reflect.Slice:
|
|
||||||
if v.IsNil() {
|
|
||||||
d.w.Write(nilAngleBytes)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
fallthrough
|
|
||||||
|
|
||||||
case reflect.Array:
|
|
||||||
d.w.Write(openBraceNewlineBytes)
|
|
||||||
d.depth++
|
|
||||||
if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
|
|
||||||
d.indent()
|
|
||||||
d.w.Write(maxNewlineBytes)
|
|
||||||
} else {
|
|
||||||
d.dumpSlice(v)
|
|
||||||
}
|
|
||||||
d.depth--
|
|
||||||
d.indent()
|
|
||||||
d.w.Write(closeBraceBytes)
|
|
||||||
|
|
||||||
case reflect.String:
|
|
||||||
d.w.Write([]byte(strconv.Quote(v.String())))
|
|
||||||
|
|
||||||
case reflect.Interface:
|
|
||||||
// The only time we should get here is for nil interfaces due to
|
|
||||||
// unpackValue calls.
|
|
||||||
if v.IsNil() {
|
|
||||||
d.w.Write(nilAngleBytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
case reflect.Ptr:
|
|
||||||
// Do nothing. We should never get here since pointers have already
|
|
||||||
// been handled above.
|
|
||||||
|
|
||||||
case reflect.Map:
|
|
||||||
// nil maps should be indicated as different than empty maps
|
|
||||||
if v.IsNil() {
|
|
||||||
d.w.Write(nilAngleBytes)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
d.w.Write(openBraceNewlineBytes)
|
|
||||||
d.depth++
|
|
||||||
if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
|
|
||||||
d.indent()
|
|
||||||
d.w.Write(maxNewlineBytes)
|
|
||||||
} else {
|
|
||||||
numEntries := v.Len()
|
|
||||||
keys := v.MapKeys()
|
|
||||||
if d.cs.SortKeys {
|
|
||||||
sortValues(keys, d.cs)
|
|
||||||
}
|
|
||||||
for i, key := range keys {
|
|
||||||
d.dump(d.unpackValue(key))
|
|
||||||
d.w.Write(colonSpaceBytes)
|
|
||||||
d.ignoreNextIndent = true
|
|
||||||
d.dump(d.unpackValue(v.MapIndex(key)))
|
|
||||||
if i < (numEntries - 1) {
|
|
||||||
d.w.Write(commaNewlineBytes)
|
|
||||||
} else {
|
|
||||||
d.w.Write(newlineBytes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
d.depth--
|
|
||||||
d.indent()
|
|
||||||
d.w.Write(closeBraceBytes)
|
|
||||||
|
|
||||||
case reflect.Struct:
|
|
||||||
d.w.Write(openBraceNewlineBytes)
|
|
||||||
d.depth++
|
|
||||||
if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
|
|
||||||
d.indent()
|
|
||||||
d.w.Write(maxNewlineBytes)
|
|
||||||
} else {
|
|
||||||
vt := v.Type()
|
|
||||||
numFields := v.NumField()
|
|
||||||
for i := 0; i < numFields; i++ {
|
|
||||||
d.indent()
|
|
||||||
vtf := vt.Field(i)
|
|
||||||
d.w.Write([]byte(vtf.Name))
|
|
||||||
d.w.Write(colonSpaceBytes)
|
|
||||||
d.ignoreNextIndent = true
|
|
||||||
d.dump(d.unpackValue(v.Field(i)))
|
|
||||||
if i < (numFields - 1) {
|
|
||||||
d.w.Write(commaNewlineBytes)
|
|
||||||
} else {
|
|
||||||
d.w.Write(newlineBytes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
d.depth--
|
|
||||||
d.indent()
|
|
||||||
d.w.Write(closeBraceBytes)
|
|
||||||
|
|
||||||
case reflect.Uintptr:
|
|
||||||
printHexPtr(d.w, uintptr(v.Uint()))
|
|
||||||
|
|
||||||
case reflect.UnsafePointer, reflect.Chan, reflect.Func:
|
|
||||||
printHexPtr(d.w, v.Pointer())
|
|
||||||
|
|
||||||
// There were not any other types at the time this code was written, but
|
|
||||||
// fall back to letting the default fmt package handle it in case any new
|
|
||||||
// types are added.
|
|
||||||
default:
|
|
||||||
if v.CanInterface() {
|
|
||||||
fmt.Fprintf(d.w, "%v", v.Interface())
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(d.w, "%v", v.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// fdump is a helper function to consolidate the logic from the various public
|
|
||||||
// methods which take varying writers and config states.
|
|
||||||
func fdump(cs *ConfigState, w io.Writer, a ...interface{}) {
|
|
||||||
for _, arg := range a {
|
|
||||||
if arg == nil {
|
|
||||||
w.Write(interfaceBytes)
|
|
||||||
w.Write(spaceBytes)
|
|
||||||
w.Write(nilAngleBytes)
|
|
||||||
w.Write(newlineBytes)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
d := dumpState{w: w, cs: cs}
|
|
||||||
d.pointers = make(map[uintptr]int)
|
|
||||||
d.dump(reflect.ValueOf(arg))
|
|
||||||
d.w.Write(newlineBytes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fdump formats and displays the passed arguments to io.Writer w. It formats
|
|
||||||
// exactly the same as Dump.
|
|
||||||
func Fdump(w io.Writer, a ...interface{}) {
|
|
||||||
fdump(&Config, w, a...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sdump returns a string with the passed arguments formatted exactly the same
|
|
||||||
// as Dump.
|
|
||||||
func Sdump(a ...interface{}) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
fdump(&Config, &buf, a...)
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Dump displays the passed parameters to standard out with newlines, customizable
|
|
||||||
indentation, and additional debug information such as complete types and all
|
|
||||||
pointer addresses used to indirect to the final value. It provides the
|
|
||||||
following features over the built-in printing facilities provided by the fmt
|
|
||||||
package:
|
|
||||||
|
|
||||||
* Pointers are dereferenced and followed
|
|
||||||
* Circular data structures are detected and handled properly
|
|
||||||
* Custom Stringer/error interfaces are optionally invoked, including
|
|
||||||
on unexported types
|
|
||||||
* Custom types which only implement the Stringer/error interfaces via
|
|
||||||
a pointer receiver are optionally invoked when passing non-pointer
|
|
||||||
variables
|
|
||||||
* Byte arrays and slices are dumped like the hexdump -C command which
|
|
||||||
includes offsets, byte values in hex, and ASCII output
|
|
||||||
|
|
||||||
The configuration options are controlled by an exported package global,
|
|
||||||
spew.Config. See ConfigState for options documentation.
|
|
||||||
|
|
||||||
See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to
|
|
||||||
get the formatted result as a string.
|
|
||||||
*/
|
|
||||||
func Dump(a ...interface{}) {
|
|
||||||
fdump(&Config, os.Stdout, a...)
|
|
||||||
}
|
|
419
vendor/github.com/davecgh/go-spew/spew/format.go
generated
vendored
419
vendor/github.com/davecgh/go-spew/spew/format.go
generated
vendored
|
@ -1,419 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2013-2016 Dave Collins <dave@davec.name>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package spew
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// supportedFlags is a list of all the character flags supported by fmt package.
|
|
||||||
const supportedFlags = "0-+# "
|
|
||||||
|
|
||||||
// formatState implements the fmt.Formatter interface and contains information
|
|
||||||
// about the state of a formatting operation. The NewFormatter function can
|
|
||||||
// be used to get a new Formatter which can be used directly as arguments
|
|
||||||
// in standard fmt package printing calls.
|
|
||||||
type formatState struct {
|
|
||||||
value interface{}
|
|
||||||
fs fmt.State
|
|
||||||
depth int
|
|
||||||
pointers map[uintptr]int
|
|
||||||
ignoreNextType bool
|
|
||||||
cs *ConfigState
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildDefaultFormat recreates the original format string without precision
|
|
||||||
// and width information to pass in to fmt.Sprintf in the case of an
|
|
||||||
// unrecognized type. Unless new types are added to the language, this
|
|
||||||
// function won't ever be called.
|
|
||||||
func (f *formatState) buildDefaultFormat() (format string) {
|
|
||||||
buf := bytes.NewBuffer(percentBytes)
|
|
||||||
|
|
||||||
for _, flag := range supportedFlags {
|
|
||||||
if f.fs.Flag(int(flag)) {
|
|
||||||
buf.WriteRune(flag)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.WriteRune('v')
|
|
||||||
|
|
||||||
format = buf.String()
|
|
||||||
return format
|
|
||||||
}
|
|
||||||
|
|
||||||
// constructOrigFormat recreates the original format string including precision
|
|
||||||
// and width information to pass along to the standard fmt package. This allows
|
|
||||||
// automatic deferral of all format strings this package doesn't support.
|
|
||||||
func (f *formatState) constructOrigFormat(verb rune) (format string) {
|
|
||||||
buf := bytes.NewBuffer(percentBytes)
|
|
||||||
|
|
||||||
for _, flag := range supportedFlags {
|
|
||||||
if f.fs.Flag(int(flag)) {
|
|
||||||
buf.WriteRune(flag)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if width, ok := f.fs.Width(); ok {
|
|
||||||
buf.WriteString(strconv.Itoa(width))
|
|
||||||
}
|
|
||||||
|
|
||||||
if precision, ok := f.fs.Precision(); ok {
|
|
||||||
buf.Write(precisionBytes)
|
|
||||||
buf.WriteString(strconv.Itoa(precision))
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.WriteRune(verb)
|
|
||||||
|
|
||||||
format = buf.String()
|
|
||||||
return format
|
|
||||||
}
|
|
||||||
|
|
||||||
// unpackValue returns values inside of non-nil interfaces when possible and
|
|
||||||
// ensures that types for values which have been unpacked from an interface
|
|
||||||
// are displayed when the show types flag is also set.
|
|
||||||
// This is useful for data types like structs, arrays, slices, and maps which
|
|
||||||
// can contain varying types packed inside an interface.
|
|
||||||
func (f *formatState) unpackValue(v reflect.Value) reflect.Value {
|
|
||||||
if v.Kind() == reflect.Interface {
|
|
||||||
f.ignoreNextType = false
|
|
||||||
if !v.IsNil() {
|
|
||||||
v = v.Elem()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// formatPtr handles formatting of pointers by indirecting them as necessary.
|
|
||||||
func (f *formatState) formatPtr(v reflect.Value) {
|
|
||||||
// Display nil if top level pointer is nil.
|
|
||||||
showTypes := f.fs.Flag('#')
|
|
||||||
if v.IsNil() && (!showTypes || f.ignoreNextType) {
|
|
||||||
f.fs.Write(nilAngleBytes)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove pointers at or below the current depth from map used to detect
|
|
||||||
// circular refs.
|
|
||||||
for k, depth := range f.pointers {
|
|
||||||
if depth >= f.depth {
|
|
||||||
delete(f.pointers, k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep list of all dereferenced pointers to possibly show later.
|
|
||||||
pointerChain := make([]uintptr, 0)
|
|
||||||
|
|
||||||
// Figure out how many levels of indirection there are by derferencing
|
|
||||||
// pointers and unpacking interfaces down the chain while detecting circular
|
|
||||||
// references.
|
|
||||||
nilFound := false
|
|
||||||
cycleFound := false
|
|
||||||
indirects := 0
|
|
||||||
ve := v
|
|
||||||
for ve.Kind() == reflect.Ptr {
|
|
||||||
if ve.IsNil() {
|
|
||||||
nilFound = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
indirects++
|
|
||||||
addr := ve.Pointer()
|
|
||||||
pointerChain = append(pointerChain, addr)
|
|
||||||
if pd, ok := f.pointers[addr]; ok && pd < f.depth {
|
|
||||||
cycleFound = true
|
|
||||||
indirects--
|
|
||||||
break
|
|
||||||
}
|
|
||||||
f.pointers[addr] = f.depth
|
|
||||||
|
|
||||||
ve = ve.Elem()
|
|
||||||
if ve.Kind() == reflect.Interface {
|
|
||||||
if ve.IsNil() {
|
|
||||||
nilFound = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
ve = ve.Elem()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display type or indirection level depending on flags.
|
|
||||||
if showTypes && !f.ignoreNextType {
|
|
||||||
f.fs.Write(openParenBytes)
|
|
||||||
f.fs.Write(bytes.Repeat(asteriskBytes, indirects))
|
|
||||||
f.fs.Write([]byte(ve.Type().String()))
|
|
||||||
f.fs.Write(closeParenBytes)
|
|
||||||
} else {
|
|
||||||
if nilFound || cycleFound {
|
|
||||||
indirects += strings.Count(ve.Type().String(), "*")
|
|
||||||
}
|
|
||||||
f.fs.Write(openAngleBytes)
|
|
||||||
f.fs.Write([]byte(strings.Repeat("*", indirects)))
|
|
||||||
f.fs.Write(closeAngleBytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display pointer information depending on flags.
|
|
||||||
if f.fs.Flag('+') && (len(pointerChain) > 0) {
|
|
||||||
f.fs.Write(openParenBytes)
|
|
||||||
for i, addr := range pointerChain {
|
|
||||||
if i > 0 {
|
|
||||||
f.fs.Write(pointerChainBytes)
|
|
||||||
}
|
|
||||||
printHexPtr(f.fs, addr)
|
|
||||||
}
|
|
||||||
f.fs.Write(closeParenBytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display dereferenced value.
|
|
||||||
switch {
|
|
||||||
case nilFound:
|
|
||||||
f.fs.Write(nilAngleBytes)
|
|
||||||
|
|
||||||
case cycleFound:
|
|
||||||
f.fs.Write(circularShortBytes)
|
|
||||||
|
|
||||||
default:
|
|
||||||
f.ignoreNextType = true
|
|
||||||
f.format(ve)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// format is the main workhorse for providing the Formatter interface. It
|
|
||||||
// uses the passed reflect value to figure out what kind of object we are
|
|
||||||
// dealing with and formats it appropriately. It is a recursive function,
|
|
||||||
// however circular data structures are detected and handled properly.
|
|
||||||
func (f *formatState) format(v reflect.Value) {
|
|
||||||
// Handle invalid reflect values immediately.
|
|
||||||
kind := v.Kind()
|
|
||||||
if kind == reflect.Invalid {
|
|
||||||
f.fs.Write(invalidAngleBytes)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle pointers specially.
|
|
||||||
if kind == reflect.Ptr {
|
|
||||||
f.formatPtr(v)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print type information unless already handled elsewhere.
|
|
||||||
if !f.ignoreNextType && f.fs.Flag('#') {
|
|
||||||
f.fs.Write(openParenBytes)
|
|
||||||
f.fs.Write([]byte(v.Type().String()))
|
|
||||||
f.fs.Write(closeParenBytes)
|
|
||||||
}
|
|
||||||
f.ignoreNextType = false
|
|
||||||
|
|
||||||
// Call Stringer/error interfaces if they exist and the handle methods
|
|
||||||
// flag is enabled.
|
|
||||||
if !f.cs.DisableMethods {
|
|
||||||
if (kind != reflect.Invalid) && (kind != reflect.Interface) {
|
|
||||||
if handled := handleMethods(f.cs, f.fs, v); handled {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch kind {
|
|
||||||
case reflect.Invalid:
|
|
||||||
// Do nothing. We should never get here since invalid has already
|
|
||||||
// been handled above.
|
|
||||||
|
|
||||||
case reflect.Bool:
|
|
||||||
printBool(f.fs, v.Bool())
|
|
||||||
|
|
||||||
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
|
||||||
printInt(f.fs, v.Int(), 10)
|
|
||||||
|
|
||||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
|
||||||
printUint(f.fs, v.Uint(), 10)
|
|
||||||
|
|
||||||
case reflect.Float32:
|
|
||||||
printFloat(f.fs, v.Float(), 32)
|
|
||||||
|
|
||||||
case reflect.Float64:
|
|
||||||
printFloat(f.fs, v.Float(), 64)
|
|
||||||
|
|
||||||
case reflect.Complex64:
|
|
||||||
printComplex(f.fs, v.Complex(), 32)
|
|
||||||
|
|
||||||
case reflect.Complex128:
|
|
||||||
printComplex(f.fs, v.Complex(), 64)
|
|
||||||
|
|
||||||
case reflect.Slice:
|
|
||||||
if v.IsNil() {
|
|
||||||
f.fs.Write(nilAngleBytes)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
fallthrough
|
|
||||||
|
|
||||||
case reflect.Array:
|
|
||||||
f.fs.Write(openBracketBytes)
|
|
||||||
f.depth++
|
|
||||||
if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
|
|
||||||
f.fs.Write(maxShortBytes)
|
|
||||||
} else {
|
|
||||||
numEntries := v.Len()
|
|
||||||
for i := 0; i < numEntries; i++ {
|
|
||||||
if i > 0 {
|
|
||||||
f.fs.Write(spaceBytes)
|
|
||||||
}
|
|
||||||
f.ignoreNextType = true
|
|
||||||
f.format(f.unpackValue(v.Index(i)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f.depth--
|
|
||||||
f.fs.Write(closeBracketBytes)
|
|
||||||
|
|
||||||
case reflect.String:
|
|
||||||
f.fs.Write([]byte(v.String()))
|
|
||||||
|
|
||||||
case reflect.Interface:
|
|
||||||
// The only time we should get here is for nil interfaces due to
|
|
||||||
// unpackValue calls.
|
|
||||||
if v.IsNil() {
|
|
||||||
f.fs.Write(nilAngleBytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
case reflect.Ptr:
|
|
||||||
// Do nothing. We should never get here since pointers have already
|
|
||||||
// been handled above.
|
|
||||||
|
|
||||||
case reflect.Map:
|
|
||||||
// nil maps should be indicated as different than empty maps
|
|
||||||
if v.IsNil() {
|
|
||||||
f.fs.Write(nilAngleBytes)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
f.fs.Write(openMapBytes)
|
|
||||||
f.depth++
|
|
||||||
if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
|
|
||||||
f.fs.Write(maxShortBytes)
|
|
||||||
} else {
|
|
||||||
keys := v.MapKeys()
|
|
||||||
if f.cs.SortKeys {
|
|
||||||
sortValues(keys, f.cs)
|
|
||||||
}
|
|
||||||
for i, key := range keys {
|
|
||||||
if i > 0 {
|
|
||||||
f.fs.Write(spaceBytes)
|
|
||||||
}
|
|
||||||
f.ignoreNextType = true
|
|
||||||
f.format(f.unpackValue(key))
|
|
||||||
f.fs.Write(colonBytes)
|
|
||||||
f.ignoreNextType = true
|
|
||||||
f.format(f.unpackValue(v.MapIndex(key)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f.depth--
|
|
||||||
f.fs.Write(closeMapBytes)
|
|
||||||
|
|
||||||
case reflect.Struct:
|
|
||||||
numFields := v.NumField()
|
|
||||||
f.fs.Write(openBraceBytes)
|
|
||||||
f.depth++
|
|
||||||
if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
|
|
||||||
f.fs.Write(maxShortBytes)
|
|
||||||
} else {
|
|
||||||
vt := v.Type()
|
|
||||||
for i := 0; i < numFields; i++ {
|
|
||||||
if i > 0 {
|
|
||||||
f.fs.Write(spaceBytes)
|
|
||||||
}
|
|
||||||
vtf := vt.Field(i)
|
|
||||||
if f.fs.Flag('+') || f.fs.Flag('#') {
|
|
||||||
f.fs.Write([]byte(vtf.Name))
|
|
||||||
f.fs.Write(colonBytes)
|
|
||||||
}
|
|
||||||
f.format(f.unpackValue(v.Field(i)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f.depth--
|
|
||||||
f.fs.Write(closeBraceBytes)
|
|
||||||
|
|
||||||
case reflect.Uintptr:
|
|
||||||
printHexPtr(f.fs, uintptr(v.Uint()))
|
|
||||||
|
|
||||||
case reflect.UnsafePointer, reflect.Chan, reflect.Func:
|
|
||||||
printHexPtr(f.fs, v.Pointer())
|
|
||||||
|
|
||||||
// There were not any other types at the time this code was written, but
|
|
||||||
// fall back to letting the default fmt package handle it if any get added.
|
|
||||||
default:
|
|
||||||
format := f.buildDefaultFormat()
|
|
||||||
if v.CanInterface() {
|
|
||||||
fmt.Fprintf(f.fs, format, v.Interface())
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(f.fs, format, v.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Format satisfies the fmt.Formatter interface. See NewFormatter for usage
|
|
||||||
// details.
|
|
||||||
func (f *formatState) Format(fs fmt.State, verb rune) {
|
|
||||||
f.fs = fs
|
|
||||||
|
|
||||||
// Use standard formatting for verbs that are not v.
|
|
||||||
if verb != 'v' {
|
|
||||||
format := f.constructOrigFormat(verb)
|
|
||||||
fmt.Fprintf(fs, format, f.value)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if f.value == nil {
|
|
||||||
if fs.Flag('#') {
|
|
||||||
fs.Write(interfaceBytes)
|
|
||||||
}
|
|
||||||
fs.Write(nilAngleBytes)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
f.format(reflect.ValueOf(f.value))
|
|
||||||
}
|
|
||||||
|
|
||||||
// newFormatter is a helper function to consolidate the logic from the various
|
|
||||||
// public methods which take varying config states.
|
|
||||||
func newFormatter(cs *ConfigState, v interface{}) fmt.Formatter {
|
|
||||||
fs := &formatState{value: v, cs: cs}
|
|
||||||
fs.pointers = make(map[uintptr]int)
|
|
||||||
return fs
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
NewFormatter returns a custom formatter that satisfies the fmt.Formatter
|
|
||||||
interface. As a result, it integrates cleanly with standard fmt package
|
|
||||||
printing functions. The formatter is useful for inline printing of smaller data
|
|
||||||
types similar to the standard %v format specifier.
|
|
||||||
|
|
||||||
The custom formatter only responds to the %v (most compact), %+v (adds pointer
|
|
||||||
addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb
|
|
||||||
combinations. Any other verbs such as %x and %q will be sent to the the
|
|
||||||
standard fmt package for formatting. In addition, the custom formatter ignores
|
|
||||||
the width and precision arguments (however they will still work on the format
|
|
||||||
specifiers not handled by the custom formatter).
|
|
||||||
|
|
||||||
Typically this function shouldn't be called directly. It is much easier to make
|
|
||||||
use of the custom formatter by calling one of the convenience functions such as
|
|
||||||
Printf, Println, or Fprintf.
|
|
||||||
*/
|
|
||||||
func NewFormatter(v interface{}) fmt.Formatter {
|
|
||||||
return newFormatter(&Config, v)
|
|
||||||
}
|
|
148
vendor/github.com/davecgh/go-spew/spew/spew.go
generated
vendored
148
vendor/github.com/davecgh/go-spew/spew/spew.go
generated
vendored
|
@ -1,148 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2013-2016 Dave Collins <dave@davec.name>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package spew
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
|
|
||||||
// passed with a default Formatter interface returned by NewFormatter. It
|
|
||||||
// returns the formatted string as a value that satisfies error. See
|
|
||||||
// NewFormatter for formatting details.
|
|
||||||
//
|
|
||||||
// This function is shorthand for the following syntax:
|
|
||||||
//
|
|
||||||
// fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b))
|
|
||||||
func Errorf(format string, a ...interface{}) (err error) {
|
|
||||||
return fmt.Errorf(format, convertArgs(a)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
|
|
||||||
// passed with a default Formatter interface returned by NewFormatter. It
|
|
||||||
// returns the number of bytes written and any write error encountered. See
|
|
||||||
// NewFormatter for formatting details.
|
|
||||||
//
|
|
||||||
// This function is shorthand for the following syntax:
|
|
||||||
//
|
|
||||||
// fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b))
|
|
||||||
func Fprint(w io.Writer, a ...interface{}) (n int, err error) {
|
|
||||||
return fmt.Fprint(w, convertArgs(a)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
|
|
||||||
// passed with a default Formatter interface returned by NewFormatter. It
|
|
||||||
// returns the number of bytes written and any write error encountered. See
|
|
||||||
// NewFormatter for formatting details.
|
|
||||||
//
|
|
||||||
// This function is shorthand for the following syntax:
|
|
||||||
//
|
|
||||||
// fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b))
|
|
||||||
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
|
|
||||||
return fmt.Fprintf(w, format, convertArgs(a)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
|
|
||||||
// passed with a default Formatter interface returned by NewFormatter. See
|
|
||||||
// NewFormatter for formatting details.
|
|
||||||
//
|
|
||||||
// This function is shorthand for the following syntax:
|
|
||||||
//
|
|
||||||
// fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b))
|
|
||||||
func Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
|
|
||||||
return fmt.Fprintln(w, convertArgs(a)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print is a wrapper for fmt.Print that treats each argument as if it were
|
|
||||||
// passed with a default Formatter interface returned by NewFormatter. It
|
|
||||||
// returns the number of bytes written and any write error encountered. See
|
|
||||||
// NewFormatter for formatting details.
|
|
||||||
//
|
|
||||||
// This function is shorthand for the following syntax:
|
|
||||||
//
|
|
||||||
// fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b))
|
|
||||||
func Print(a ...interface{}) (n int, err error) {
|
|
||||||
return fmt.Print(convertArgs(a)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Printf is a wrapper for fmt.Printf that treats each argument as if it were
|
|
||||||
// passed with a default Formatter interface returned by NewFormatter. It
|
|
||||||
// returns the number of bytes written and any write error encountered. See
|
|
||||||
// NewFormatter for formatting details.
|
|
||||||
//
|
|
||||||
// This function is shorthand for the following syntax:
|
|
||||||
//
|
|
||||||
// fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b))
|
|
||||||
func Printf(format string, a ...interface{}) (n int, err error) {
|
|
||||||
return fmt.Printf(format, convertArgs(a)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Println is a wrapper for fmt.Println that treats each argument as if it were
|
|
||||||
// passed with a default Formatter interface returned by NewFormatter. It
|
|
||||||
// returns the number of bytes written and any write error encountered. See
|
|
||||||
// NewFormatter for formatting details.
|
|
||||||
//
|
|
||||||
// This function is shorthand for the following syntax:
|
|
||||||
//
|
|
||||||
// fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b))
|
|
||||||
func Println(a ...interface{}) (n int, err error) {
|
|
||||||
return fmt.Println(convertArgs(a)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were
|
|
||||||
// passed with a default Formatter interface returned by NewFormatter. It
|
|
||||||
// returns the resulting string. See NewFormatter for formatting details.
|
|
||||||
//
|
|
||||||
// This function is shorthand for the following syntax:
|
|
||||||
//
|
|
||||||
// fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b))
|
|
||||||
func Sprint(a ...interface{}) string {
|
|
||||||
return fmt.Sprint(convertArgs(a)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were
|
|
||||||
// passed with a default Formatter interface returned by NewFormatter. It
|
|
||||||
// returns the resulting string. See NewFormatter for formatting details.
|
|
||||||
//
|
|
||||||
// This function is shorthand for the following syntax:
|
|
||||||
//
|
|
||||||
// fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b))
|
|
||||||
func Sprintf(format string, a ...interface{}) string {
|
|
||||||
return fmt.Sprintf(format, convertArgs(a)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it
|
|
||||||
// were passed with a default Formatter interface returned by NewFormatter. It
|
|
||||||
// returns the resulting string. See NewFormatter for formatting details.
|
|
||||||
//
|
|
||||||
// This function is shorthand for the following syntax:
|
|
||||||
//
|
|
||||||
// fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b))
|
|
||||||
func Sprintln(a ...interface{}) string {
|
|
||||||
return fmt.Sprintln(convertArgs(a)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// convertArgs accepts a slice of arguments and returns a slice of the same
|
|
||||||
// length with each argument converted to a default spew Formatter interface.
|
|
||||||
func convertArgs(args []interface{}) (formatters []interface{}) {
|
|
||||||
formatters = make([]interface{}, len(args))
|
|
||||||
for index, arg := range args {
|
|
||||||
formatters[index] = NewFormatter(arg)
|
|
||||||
}
|
|
||||||
return formatters
|
|
||||||
}
|
|
28
vendor/github.com/eiannone/keyboard/.gitignore
generated
vendored
Normal file
28
vendor/github.com/eiannone/keyboard/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# JetBrains IntelliJIdea
|
||||||
|
*.iml
|
||||||
|
.idea/
|
5
vendor/github.com/eiannone/keyboard/AUTHORS
generated
vendored
Normal file
5
vendor/github.com/eiannone/keyboard/AUTHORS
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# Please keep this file sorted.
|
||||||
|
|
||||||
|
Emanuele Iannone <emanuele@fondani.it>
|
||||||
|
Georg Reinke <guelfey@googlemail.com>
|
||||||
|
nsf <no.smile.face@gmail.com>
|
|
@ -1,6 +1,7 @@
|
||||||
MIT License
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2018 Denis Dyakov
|
Copyright (C) 2012 termbox-go authors
|
||||||
|
Copyright (c) 2015 Emanuele Iannone
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -19,3 +20,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
|
|
81
vendor/github.com/eiannone/keyboard/README.md
generated
vendored
Normal file
81
vendor/github.com/eiannone/keyboard/README.md
generated
vendored
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
# Keyboard
|
||||||
|
Simple library to listen for keystrokes from the keyboard
|
||||||
|
|
||||||
|
The code is inspired by [termbox-go](https://github.com/nsf/termbox-go) library.
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
Install and update this go package with `go get -u github.com/eiannone/keyboard`
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
Example of getting a single keystroke:
|
||||||
|
|
||||||
|
```go
|
||||||
|
char, _, err := keyboard.GetSingleKey()
|
||||||
|
if (err != nil) {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("You pressed: %q\r\n", char)
|
||||||
|
```
|
||||||
|
|
||||||
|
Example of getting a series of keystrokes with a blocking `GetKey()` function:
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/eiannone/keyboard"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if err := keyboard.Open(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
_ = keyboard.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
fmt.Println("Press ESC to quit")
|
||||||
|
for {
|
||||||
|
char, key, err := keyboard.GetKey()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("You pressed: rune %q, key %X\r\n", char, key)
|
||||||
|
if key == keyboard.KeyEsc {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Example of getting a series of keystrokes using a channel:
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/eiannone/keyboard"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
keysEvents, err := keyboard.GetKeys(10)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
_ = keyboard.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
fmt.Println("Press ESC to quit")
|
||||||
|
for {
|
||||||
|
event := <-keysEvents
|
||||||
|
if event.Err != nil {
|
||||||
|
panic(event.Err)
|
||||||
|
}
|
||||||
|
fmt.Printf("You pressed: rune %q, key %X\r\n", event.Rune, event.Key)
|
||||||
|
if event.Key == keyboard.KeyEsc {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
207
vendor/github.com/eiannone/keyboard/keyboard.go
generated
vendored
Normal file
207
vendor/github.com/eiannone/keyboard/keyboard.go
generated
vendored
Normal file
|
@ -0,0 +1,207 @@
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package keyboard
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
"unicode/utf8"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
input_event struct {
|
||||||
|
data []byte
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
out *os.File
|
||||||
|
in int
|
||||||
|
|
||||||
|
// term specific keys
|
||||||
|
keys []string
|
||||||
|
|
||||||
|
// termbox inner state
|
||||||
|
orig_tios unix.Termios
|
||||||
|
|
||||||
|
sigio = make(chan os.Signal, 1)
|
||||||
|
quitEvProd = make(chan bool)
|
||||||
|
quitConsole = make(chan bool)
|
||||||
|
inbuf = make([]byte, 0, 128)
|
||||||
|
input_buf = make(chan input_event)
|
||||||
|
)
|
||||||
|
|
||||||
|
func parse_escape_sequence(buf []byte) (size int, event KeyEvent) {
|
||||||
|
bufstr := string(buf)
|
||||||
|
for i, key := range keys {
|
||||||
|
if strings.HasPrefix(bufstr, key) {
|
||||||
|
event.Rune = 0
|
||||||
|
event.Key = Key(0xFFFF - i)
|
||||||
|
size = len(key)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, event
|
||||||
|
}
|
||||||
|
|
||||||
|
func extract_event(inbuf []byte) (int, KeyEvent) {
|
||||||
|
if len(inbuf) == 0 {
|
||||||
|
return 0, KeyEvent{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if inbuf[0] == '\033' {
|
||||||
|
if len(inbuf) == 1 {
|
||||||
|
return 1, KeyEvent{Key: KeyEsc}
|
||||||
|
}
|
||||||
|
// possible escape sequence
|
||||||
|
if size, event := parse_escape_sequence(inbuf); size != 0 {
|
||||||
|
return size, event
|
||||||
|
} else {
|
||||||
|
// it's not a recognized escape sequence, return error
|
||||||
|
i := 1 // check for multiple sequences in the buffer
|
||||||
|
for ; i < len(inbuf) && inbuf[i] != '\033'; i++ {
|
||||||
|
}
|
||||||
|
return i, KeyEvent{Key: KeyEsc, Err: errors.New("Unrecognized escape sequence")}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we're here, this is not an escape sequence and not an alt sequence
|
||||||
|
// so, it's a FUNCTIONAL KEY or a UNICODE character
|
||||||
|
|
||||||
|
// first of all check if it's a functional key
|
||||||
|
if Key(inbuf[0]) <= KeySpace || Key(inbuf[0]) == KeyBackspace2 {
|
||||||
|
return 1, KeyEvent{Key: Key(inbuf[0])}
|
||||||
|
}
|
||||||
|
|
||||||
|
// the only possible option is utf8 rune
|
||||||
|
if r, n := utf8.DecodeRune(inbuf); r != utf8.RuneError {
|
||||||
|
return n, KeyEvent{Rune: r}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, KeyEvent{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for an event and return it. This is a blocking function call.
|
||||||
|
func inputEventsProducer() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-quitEvProd:
|
||||||
|
return
|
||||||
|
case ev := <-input_buf:
|
||||||
|
if ev.err != nil {
|
||||||
|
select {
|
||||||
|
case <-quitEvProd:
|
||||||
|
return
|
||||||
|
case inputComm <- KeyEvent{Err: ev.err}:
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
inbuf = append(inbuf, ev.data...)
|
||||||
|
for {
|
||||||
|
size, event := extract_event(inbuf)
|
||||||
|
if size > 0 {
|
||||||
|
select {
|
||||||
|
case <-quitEvProd:
|
||||||
|
return
|
||||||
|
case inputComm <- event:
|
||||||
|
}
|
||||||
|
copy(inbuf, inbuf[size:])
|
||||||
|
inbuf = inbuf[:len(inbuf)-size]
|
||||||
|
}
|
||||||
|
if size == 0 || len(inbuf) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func initConsole() (err error) {
|
||||||
|
out, err = os.OpenFile("/dev/tty", unix.O_WRONLY, 0)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
in, err = syscall.Open("/dev/tty", unix.O_RDONLY, 0)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = setup_term()
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("Error while reading terminfo data:" + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
signal.Notify(sigio, unix.SIGIO)
|
||||||
|
|
||||||
|
if _, err = unix.FcntlInt(uintptr(in), unix.F_SETFL, unix.O_ASYNC|unix.O_NONBLOCK); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = unix.FcntlInt(uintptr(in), unix.F_SETOWN, unix.Getpid())
|
||||||
|
if runtime.GOOS != "darwin" && err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = unix.IoctlSetTermios(int(out.Fd()), ioctl_GETATTR, &orig_tios); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tios := orig_tios
|
||||||
|
tios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK |
|
||||||
|
unix.ISTRIP | unix.INLCR | unix.IGNCR |
|
||||||
|
unix.ICRNL | unix.IXON
|
||||||
|
tios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON |
|
||||||
|
unix.ISIG | unix.IEXTEN
|
||||||
|
tios.Cflag &^= unix.CSIZE | unix.PARENB
|
||||||
|
tios.Cflag |= unix.CS8
|
||||||
|
tios.Cc[unix.VMIN] = 1
|
||||||
|
tios.Cc[unix.VTIME] = 0
|
||||||
|
|
||||||
|
if err = unix.IoctlSetTermios(int(out.Fd()), ioctl_SETATTR, &tios); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
buf := make([]byte, 128)
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-quitConsole:
|
||||||
|
return
|
||||||
|
case <-sigio:
|
||||||
|
for {
|
||||||
|
bytesRead, err := syscall.Read(in, buf)
|
||||||
|
if err == unix.EAGAIN || err == unix.EWOULDBLOCK {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
bytesRead = 0
|
||||||
|
}
|
||||||
|
data := make([]byte, bytesRead)
|
||||||
|
copy(data, buf)
|
||||||
|
select {
|
||||||
|
case <-quitConsole:
|
||||||
|
return
|
||||||
|
case input_buf <- input_event{data, err}:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
go inputEventsProducer()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func releaseConsole() {
|
||||||
|
quitConsole <- true
|
||||||
|
quitEvProd <- true
|
||||||
|
unix.IoctlSetTermios(int(out.Fd()), ioctl_SETATTR, &orig_tios)
|
||||||
|
out.Close()
|
||||||
|
unix.Close(in)
|
||||||
|
}
|
231
vendor/github.com/eiannone/keyboard/keyboard_common.go
generated
vendored
Normal file
231
vendor/github.com/eiannone/keyboard/keyboard_common.go
generated
vendored
Normal file
|
@ -0,0 +1,231 @@
|
||||||
|
package keyboard
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
Key uint16
|
||||||
|
|
||||||
|
KeyEvent struct {
|
||||||
|
Key Key // One of Key* constants, invalid if 'Ch' is not 0
|
||||||
|
Rune rune // A unicode character
|
||||||
|
Err error // Error in case if input failed
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Key constants, see GetKey() function.
|
||||||
|
const (
|
||||||
|
KeyF1 Key = 0xFFFF - iota
|
||||||
|
KeyF2
|
||||||
|
KeyF3
|
||||||
|
KeyF4
|
||||||
|
KeyF5
|
||||||
|
KeyF6
|
||||||
|
KeyF7
|
||||||
|
KeyF8
|
||||||
|
KeyF9
|
||||||
|
KeyF10
|
||||||
|
KeyF11
|
||||||
|
KeyF12
|
||||||
|
KeyInsert
|
||||||
|
KeyDelete
|
||||||
|
KeyHome
|
||||||
|
KeyEnd
|
||||||
|
KeyPgup
|
||||||
|
KeyPgdn
|
||||||
|
KeyArrowUp
|
||||||
|
KeyArrowDown
|
||||||
|
KeyArrowLeft
|
||||||
|
KeyArrowRight
|
||||||
|
key_min // see terminfo
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
KeyCtrlTilde Key = 0x00
|
||||||
|
KeyCtrl2 Key = 0x00
|
||||||
|
KeyCtrlSpace Key = 0x00
|
||||||
|
KeyCtrlA Key = 0x01
|
||||||
|
KeyCtrlB Key = 0x02
|
||||||
|
KeyCtrlC Key = 0x03
|
||||||
|
KeyCtrlD Key = 0x04
|
||||||
|
KeyCtrlE Key = 0x05
|
||||||
|
KeyCtrlF Key = 0x06
|
||||||
|
KeyCtrlG Key = 0x07
|
||||||
|
KeyBackspace Key = 0x08
|
||||||
|
KeyCtrlH Key = 0x08
|
||||||
|
KeyTab Key = 0x09
|
||||||
|
KeyCtrlI Key = 0x09
|
||||||
|
KeyCtrlJ Key = 0x0A
|
||||||
|
KeyCtrlK Key = 0x0B
|
||||||
|
KeyCtrlL Key = 0x0C
|
||||||
|
KeyEnter Key = 0x0D
|
||||||
|
KeyCtrlM Key = 0x0D
|
||||||
|
KeyCtrlN Key = 0x0E
|
||||||
|
KeyCtrlO Key = 0x0F
|
||||||
|
KeyCtrlP Key = 0x10
|
||||||
|
KeyCtrlQ Key = 0x11
|
||||||
|
KeyCtrlR Key = 0x12
|
||||||
|
KeyCtrlS Key = 0x13
|
||||||
|
KeyCtrlT Key = 0x14
|
||||||
|
KeyCtrlU Key = 0x15
|
||||||
|
KeyCtrlV Key = 0x16
|
||||||
|
KeyCtrlW Key = 0x17
|
||||||
|
KeyCtrlX Key = 0x18
|
||||||
|
KeyCtrlY Key = 0x19
|
||||||
|
KeyCtrlZ Key = 0x1A
|
||||||
|
KeyEsc Key = 0x1B
|
||||||
|
KeyCtrlLsqBracket Key = 0x1B
|
||||||
|
KeyCtrl3 Key = 0x1B
|
||||||
|
KeyCtrl4 Key = 0x1C
|
||||||
|
KeyCtrlBackslash Key = 0x1C
|
||||||
|
KeyCtrl5 Key = 0x1D
|
||||||
|
KeyCtrlRsqBracket Key = 0x1D
|
||||||
|
KeyCtrl6 Key = 0x1E
|
||||||
|
KeyCtrl7 Key = 0x1F
|
||||||
|
KeyCtrlSlash Key = 0x1F
|
||||||
|
KeyCtrlUnderscore Key = 0x1F
|
||||||
|
KeySpace Key = 0x20
|
||||||
|
KeyBackspace2 Key = 0x7F
|
||||||
|
KeyCtrl8 Key = 0x7F
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
inputComm chan KeyEvent
|
||||||
|
|
||||||
|
ping = make(chan bool)
|
||||||
|
doneClosing = make(chan bool, 1)
|
||||||
|
busy = make(chan bool)
|
||||||
|
waitingForKey = make(chan bool)
|
||||||
|
)
|
||||||
|
|
||||||
|
func IsStarted(timeout time.Duration) bool {
|
||||||
|
select {
|
||||||
|
case ping <- true:
|
||||||
|
return true
|
||||||
|
case <-time.After(timeout):
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetKeys(bufferSize int) (<-chan KeyEvent, error) {
|
||||||
|
if IsStarted(time.Millisecond * 1) {
|
||||||
|
if cap(inputComm) == bufferSize {
|
||||||
|
return inputComm, nil
|
||||||
|
}
|
||||||
|
return nil, errors.New("channel already started with a different capacity")
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case busy <- true:
|
||||||
|
return nil, errors.New("cannot open keyboard because program is busy")
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
// Signal busy operation
|
||||||
|
go func() {
|
||||||
|
for <-busy {
|
||||||
|
} // Close the routine when busy is false
|
||||||
|
}()
|
||||||
|
|
||||||
|
inputComm = make(chan KeyEvent, bufferSize)
|
||||||
|
err := initConsole()
|
||||||
|
if err != nil {
|
||||||
|
close(inputComm)
|
||||||
|
busy <- false
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signal ping subroutine started
|
||||||
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
releaseConsole()
|
||||||
|
close(inputComm)
|
||||||
|
doneClosing <- true
|
||||||
|
}()
|
||||||
|
for <-ping {
|
||||||
|
} // Close the routine when ping is false
|
||||||
|
}()
|
||||||
|
busy <- false
|
||||||
|
// Wait for ping subroutine to start
|
||||||
|
ping <- true
|
||||||
|
|
||||||
|
return inputComm, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Open() (err error) {
|
||||||
|
_, err = GetKeys(10)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should be called after successful initialization when functionality isn't required anymore.
|
||||||
|
func Close() (err error) {
|
||||||
|
// Checks if already closing
|
||||||
|
select {
|
||||||
|
case busy <- true:
|
||||||
|
return errors.New("cannot close keyboard because program is busy")
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
// Checks if already closed
|
||||||
|
if !IsStarted(time.Millisecond * 1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signal busy operation
|
||||||
|
go func() {
|
||||||
|
for <-busy {
|
||||||
|
} // Close the routine when busy is false
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Stop responding to ping and closes initial subroutine
|
||||||
|
ping <- false
|
||||||
|
|
||||||
|
// Cancel GetKey() operations
|
||||||
|
select {
|
||||||
|
case waitingForKey <- false:
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for closing finished
|
||||||
|
<-doneClosing
|
||||||
|
|
||||||
|
busy <- false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetKey() (rune, Key, error) {
|
||||||
|
// Check if opened
|
||||||
|
if !IsStarted(time.Millisecond * 50) {
|
||||||
|
return 0, 0, errors.New("keyboard not opened")
|
||||||
|
}
|
||||||
|
// Check if already waiting for key
|
||||||
|
select {
|
||||||
|
case waitingForKey <- true:
|
||||||
|
return 0, 0, errors.New("already waiting for key")
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case ev := <-inputComm:
|
||||||
|
return ev.Rune, ev.Key, ev.Err
|
||||||
|
|
||||||
|
case keepAlive := <-waitingForKey:
|
||||||
|
if !keepAlive {
|
||||||
|
return 0, 0, errors.New("operation canceled")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetSingleKey() (ch rune, key Key, err error) {
|
||||||
|
err = Open()
|
||||||
|
if err == nil {
|
||||||
|
ch, key, err = GetKey()
|
||||||
|
errClosing := Close()
|
||||||
|
if err == nil {
|
||||||
|
err = errClosing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
285
vendor/github.com/eiannone/keyboard/keyboard_windows.go
generated
vendored
Normal file
285
vendor/github.com/eiannone/keyboard/keyboard_windows.go
generated
vendored
Normal file
|
@ -0,0 +1,285 @@
|
||||||
|
package keyboard
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
vk_backspace = 0x8
|
||||||
|
vk_tab = 0x9
|
||||||
|
vk_enter = 0xd
|
||||||
|
vk_esc = 0x1b
|
||||||
|
vk_space = 0x20
|
||||||
|
vk_pgup = 0x21
|
||||||
|
vk_pgdn = 0x22
|
||||||
|
vk_end = 0x23
|
||||||
|
vk_home = 0x24
|
||||||
|
vk_arrow_left = 0x25
|
||||||
|
vk_arrow_up = 0x26
|
||||||
|
vk_arrow_right = 0x27
|
||||||
|
vk_arrow_down = 0x28
|
||||||
|
vk_insert = 0x2d
|
||||||
|
vk_delete = 0x2e
|
||||||
|
|
||||||
|
vk_f1 = 0x70
|
||||||
|
vk_f2 = 0x71
|
||||||
|
vk_f3 = 0x72
|
||||||
|
vk_f4 = 0x73
|
||||||
|
vk_f5 = 0x74
|
||||||
|
vk_f6 = 0x75
|
||||||
|
vk_f7 = 0x76
|
||||||
|
vk_f8 = 0x77
|
||||||
|
vk_f9 = 0x78
|
||||||
|
vk_f10 = 0x79
|
||||||
|
vk_f11 = 0x7a
|
||||||
|
vk_f12 = 0x7b
|
||||||
|
|
||||||
|
right_alt_pressed = 0x1
|
||||||
|
left_alt_pressed = 0x2
|
||||||
|
right_ctrl_pressed = 0x4
|
||||||
|
left_ctrl_pressed = 0x8
|
||||||
|
shift_pressed = 0x10
|
||||||
|
|
||||||
|
k32_keyEvent = 0x1
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
wchar uint16
|
||||||
|
dword uint32
|
||||||
|
word uint16
|
||||||
|
|
||||||
|
k32_event struct {
|
||||||
|
key_down int32
|
||||||
|
repeat_count word
|
||||||
|
virtual_key_code word
|
||||||
|
virtual_scan_code word
|
||||||
|
unicode_char wchar
|
||||||
|
control_key_state dword
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||||
|
|
||||||
|
k32_WaitForMultipleObjects = kernel32.NewProc("WaitForMultipleObjects")
|
||||||
|
k32_ReadConsoleInputW = kernel32.NewProc("ReadConsoleInputW")
|
||||||
|
|
||||||
|
hConsoleIn syscall.Handle
|
||||||
|
hInterrupt windows.Handle
|
||||||
|
|
||||||
|
quit = make(chan bool)
|
||||||
|
|
||||||
|
// This is just to prevent heap allocs at all costs
|
||||||
|
tmpArg dword
|
||||||
|
)
|
||||||
|
|
||||||
|
func getError(errno syscall.Errno) error {
|
||||||
|
if errno != 0 {
|
||||||
|
return error(errno)
|
||||||
|
} else {
|
||||||
|
return syscall.EINVAL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getKeyEvent(r *k32_event) (KeyEvent, bool) {
|
||||||
|
e := KeyEvent{}
|
||||||
|
|
||||||
|
if r.key_down == 0 {
|
||||||
|
return e, false
|
||||||
|
}
|
||||||
|
|
||||||
|
ctrlPressed := r.control_key_state&(left_ctrl_pressed|right_ctrl_pressed) != 0
|
||||||
|
|
||||||
|
if r.virtual_key_code >= vk_f1 && r.virtual_key_code <= vk_f12 {
|
||||||
|
switch r.virtual_key_code {
|
||||||
|
case vk_f1:
|
||||||
|
e.Key = KeyF1
|
||||||
|
case vk_f2:
|
||||||
|
e.Key = KeyF2
|
||||||
|
case vk_f3:
|
||||||
|
e.Key = KeyF3
|
||||||
|
case vk_f4:
|
||||||
|
e.Key = KeyF4
|
||||||
|
case vk_f5:
|
||||||
|
e.Key = KeyF5
|
||||||
|
case vk_f6:
|
||||||
|
e.Key = KeyF6
|
||||||
|
case vk_f7:
|
||||||
|
e.Key = KeyF7
|
||||||
|
case vk_f8:
|
||||||
|
e.Key = KeyF8
|
||||||
|
case vk_f9:
|
||||||
|
e.Key = KeyF9
|
||||||
|
case vk_f10:
|
||||||
|
e.Key = KeyF10
|
||||||
|
case vk_f11:
|
||||||
|
e.Key = KeyF11
|
||||||
|
case vk_f12:
|
||||||
|
e.Key = KeyF12
|
||||||
|
default:
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
return e, true
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.virtual_key_code <= vk_delete {
|
||||||
|
switch r.virtual_key_code {
|
||||||
|
case vk_insert:
|
||||||
|
e.Key = KeyInsert
|
||||||
|
case vk_delete:
|
||||||
|
e.Key = KeyDelete
|
||||||
|
case vk_home:
|
||||||
|
e.Key = KeyHome
|
||||||
|
case vk_end:
|
||||||
|
e.Key = KeyEnd
|
||||||
|
case vk_pgup:
|
||||||
|
e.Key = KeyPgup
|
||||||
|
case vk_pgdn:
|
||||||
|
e.Key = KeyPgdn
|
||||||
|
case vk_arrow_up:
|
||||||
|
e.Key = KeyArrowUp
|
||||||
|
case vk_arrow_down:
|
||||||
|
e.Key = KeyArrowDown
|
||||||
|
case vk_arrow_left:
|
||||||
|
e.Key = KeyArrowLeft
|
||||||
|
case vk_arrow_right:
|
||||||
|
e.Key = KeyArrowRight
|
||||||
|
case vk_backspace:
|
||||||
|
if ctrlPressed {
|
||||||
|
e.Key = KeyBackspace2
|
||||||
|
} else {
|
||||||
|
e.Key = KeyBackspace
|
||||||
|
}
|
||||||
|
case vk_tab:
|
||||||
|
e.Key = KeyTab
|
||||||
|
case vk_enter:
|
||||||
|
e.Key = KeyEnter
|
||||||
|
case vk_esc:
|
||||||
|
e.Key = KeyEsc
|
||||||
|
case vk_space:
|
||||||
|
if ctrlPressed {
|
||||||
|
// manual return here, because KeyCtrlSpace is zero
|
||||||
|
e.Key = KeyCtrlSpace
|
||||||
|
return e, true
|
||||||
|
} else {
|
||||||
|
e.Key = KeySpace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if e.Key != 0 {
|
||||||
|
return e, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctrlPressed {
|
||||||
|
if Key(r.unicode_char) >= KeyCtrlA && Key(r.unicode_char) <= KeyCtrlRsqBracket {
|
||||||
|
e.Key = Key(r.unicode_char)
|
||||||
|
return e, true
|
||||||
|
}
|
||||||
|
switch r.virtual_key_code {
|
||||||
|
case 192, 50:
|
||||||
|
// manual return here, because KeyCtrl2 is zero
|
||||||
|
e.Key = KeyCtrl2
|
||||||
|
return e, true
|
||||||
|
case 51:
|
||||||
|
e.Key = KeyCtrl3
|
||||||
|
case 52:
|
||||||
|
e.Key = KeyCtrl4
|
||||||
|
case 53:
|
||||||
|
e.Key = KeyCtrl5
|
||||||
|
case 54:
|
||||||
|
e.Key = KeyCtrl6
|
||||||
|
case 189, 191, 55:
|
||||||
|
e.Key = KeyCtrl7
|
||||||
|
case 8, 56:
|
||||||
|
e.Key = KeyCtrl8
|
||||||
|
}
|
||||||
|
|
||||||
|
if e.Key != 0 {
|
||||||
|
return e, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.unicode_char != 0 {
|
||||||
|
e.Rune = rune(r.unicode_char)
|
||||||
|
return e, true
|
||||||
|
}
|
||||||
|
|
||||||
|
return e, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func produceEvent(event KeyEvent) bool {
|
||||||
|
select {
|
||||||
|
case <-quit:
|
||||||
|
return false
|
||||||
|
case inputComm <- event:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func inputEventsProducer() {
|
||||||
|
var input [20]uint16
|
||||||
|
for {
|
||||||
|
// Wait for events
|
||||||
|
// https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitformultipleobjects
|
||||||
|
r0, _, e1 := syscall.Syscall6(k32_WaitForMultipleObjects.Addr(), 4,
|
||||||
|
uintptr(2), uintptr(unsafe.Pointer(&hConsoleIn)), 0, windows.INFINITE, 0, 0)
|
||||||
|
if uint32(r0) == windows.WAIT_FAILED && false == produceEvent(KeyEvent{Err: getError(e1)}) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case <-quit:
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get console input
|
||||||
|
r0, _, e1 = syscall.Syscall6(k32_ReadConsoleInputW.Addr(), 4,
|
||||||
|
uintptr(hConsoleIn), uintptr(unsafe.Pointer(&input[0])), 1, uintptr(unsafe.Pointer(&tmpArg)), 0, 0)
|
||||||
|
if int(r0) == 0 {
|
||||||
|
if false == produceEvent(KeyEvent{Err: getError(e1)}) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else if input[0] == k32_keyEvent {
|
||||||
|
kEvent := (*k32_event)(unsafe.Pointer(&input[2]))
|
||||||
|
ev, ok := getKeyEvent(kEvent)
|
||||||
|
if ok {
|
||||||
|
for i := 0; i < int(kEvent.repeat_count); i++ {
|
||||||
|
if false == produceEvent(ev) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func initConsole() (err error) {
|
||||||
|
// Create an interrupt event
|
||||||
|
hInterrupt, err = windows.CreateEvent(nil, 0, 0, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
hConsoleIn, err = syscall.Open("CONIN$", windows.O_RDWR, 0)
|
||||||
|
if err != nil {
|
||||||
|
windows.Close(hInterrupt)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
go inputEventsProducer()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func releaseConsole() {
|
||||||
|
// Stop events producer
|
||||||
|
windows.SetEvent(hInterrupt)
|
||||||
|
quit <- true
|
||||||
|
|
||||||
|
syscall.Close(hConsoleIn)
|
||||||
|
windows.Close(hInterrupt)
|
||||||
|
}
|
12
vendor/github.com/eiannone/keyboard/syscalls.go
generated
vendored
Normal file
12
vendor/github.com/eiannone/keyboard/syscalls.go
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
// +build !windows,!linux
|
||||||
|
|
||||||
|
package keyboard
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ioctl_GETATTR = unix.TIOCGETA
|
||||||
|
ioctl_SETATTR = unix.TIOCSETA
|
||||||
|
)
|
10
vendor/github.com/eiannone/keyboard/syscalls_linux.go
generated
vendored
Normal file
10
vendor/github.com/eiannone/keyboard/syscalls_linux.go
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package keyboard
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ioctl_GETATTR = unix.TCGETS
|
||||||
|
ioctl_SETATTR = unix.TCSETS
|
||||||
|
)
|
257
vendor/github.com/eiannone/keyboard/terminfo.go
generated
vendored
Normal file
257
vendor/github.com/eiannone/keyboard/terminfo.go
generated
vendored
Normal file
|
@ -0,0 +1,257 @@
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
// This file is imported from https://github.com/nsf/termbox-go
|
||||||
|
// Last update: 2020-04-30
|
||||||
|
|
||||||
|
// This file contains a simple and incomplete implementation of the terminfo
|
||||||
|
// database. Information was taken from the ncurses manpages term(5) and
|
||||||
|
// terminfo(5). Currently, only the string capabilities for special keys and for
|
||||||
|
// functions without parameters are actually used. Colors are still done with
|
||||||
|
// ANSI escape sequences. Other special features that are not (yet?) supported
|
||||||
|
// are reading from ~/.terminfo, the TERMINFO_DIRS variable, Berkeley database
|
||||||
|
// format and extended capabilities.
|
||||||
|
|
||||||
|
package keyboard
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
"encoding/hex"
|
||||||
|
"errors"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ti_header_length = 12
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
eterm_keys = []string{
|
||||||
|
"\x1b[11~", "\x1b[12~", "\x1b[13~", "\x1b[14~", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[7~", "\x1b[8~", "\x1b[5~", "\x1b[6~", "\x1b[A", "\x1b[B", "\x1b[D", "\x1b[C",
|
||||||
|
}
|
||||||
|
screen_keys = []string{
|
||||||
|
"\x1bOP", "\x1bOQ", "\x1bOR", "\x1bOS", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[1~", "\x1b[4~", "\x1b[5~", "\x1b[6~", "\x1bOA", "\x1bOB", "\x1bOD", "\x1bOC",
|
||||||
|
}
|
||||||
|
xterm_keys = []string{
|
||||||
|
"\x1bOP", "\x1bOQ", "\x1bOR", "\x1bOS", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[H", "\x1b[F", "\x1b[5~", "\x1b[6~", "\x1b[A", "\x1b[B", "\x1b[D", "\x1b[C",
|
||||||
|
}
|
||||||
|
rxvt_keys = []string{
|
||||||
|
"\x1b[11~", "\x1b[12~", "\x1b[13~", "\x1b[14~", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[7~", "\x1b[8~", "\x1b[5~", "\x1b[6~", "\x1b[A", "\x1b[B", "\x1b[D", "\x1b[C",
|
||||||
|
}
|
||||||
|
linux_keys = []string{
|
||||||
|
"\x1b[[A", "\x1b[[B", "\x1b[[C", "\x1b[[D", "\x1b[[E", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[1~", "\x1b[4~", "\x1b[5~", "\x1b[6~", "\x1b[A", "\x1b[B", "\x1b[D", "\x1b[C",
|
||||||
|
}
|
||||||
|
|
||||||
|
terms = []struct {
|
||||||
|
name string
|
||||||
|
keys []string
|
||||||
|
}{
|
||||||
|
{"Eterm", eterm_keys},
|
||||||
|
{"screen", screen_keys},
|
||||||
|
{"xterm", xterm_keys},
|
||||||
|
{"xterm-256color", xterm_keys},
|
||||||
|
{"rxvt-unicode", rxvt_keys},
|
||||||
|
{"rxvt-256color", rxvt_keys},
|
||||||
|
{"linux", linux_keys},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func load_terminfo() ([]byte, error) {
|
||||||
|
var data []byte
|
||||||
|
var err error
|
||||||
|
|
||||||
|
term := os.Getenv("TERM")
|
||||||
|
if term == "" {
|
||||||
|
return nil, errors.New("terminfo: TERM not set")
|
||||||
|
}
|
||||||
|
// Check if is a builtin terminal
|
||||||
|
for _, t := range terms {
|
||||||
|
if t.name == term {
|
||||||
|
return nil, errors.New("use built in!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following behaviour follows the one described in terminfo(5) as
|
||||||
|
// distributed by ncurses.
|
||||||
|
|
||||||
|
terminfo := os.Getenv("TERMINFO")
|
||||||
|
if terminfo != "" {
|
||||||
|
// if TERMINFO is set, no other directory should be searched
|
||||||
|
return ti_try_path(terminfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
// next, consider ~/.terminfo
|
||||||
|
home := os.Getenv("HOME")
|
||||||
|
if home != "" {
|
||||||
|
data, err = ti_try_path(home + "/.terminfo")
|
||||||
|
if err == nil {
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// next, TERMINFO_DIRS
|
||||||
|
dirs := os.Getenv("TERMINFO_DIRS")
|
||||||
|
if dirs != "" {
|
||||||
|
for _, dir := range strings.Split(dirs, ":") {
|
||||||
|
if dir == "" {
|
||||||
|
// "" -> "/usr/share/terminfo"
|
||||||
|
dir = "/usr/share/terminfo"
|
||||||
|
}
|
||||||
|
data, err = ti_try_path(dir)
|
||||||
|
if err == nil {
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// next, /lib/terminfo
|
||||||
|
data, err = ti_try_path("/lib/terminfo")
|
||||||
|
if err == nil {
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// fall back to /usr/share/terminfo
|
||||||
|
return ti_try_path("/usr/share/terminfo")
|
||||||
|
}
|
||||||
|
|
||||||
|
func ti_try_path(path string) (data []byte, err error) {
|
||||||
|
// load_terminfo already made sure it is set
|
||||||
|
term := os.Getenv("TERM")
|
||||||
|
|
||||||
|
// first try, the typical *nix path
|
||||||
|
terminfo := path + "/" + term[0:1] + "/" + term
|
||||||
|
data, err = ioutil.ReadFile(terminfo)
|
||||||
|
if err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback to darwin specific dirs structure
|
||||||
|
terminfo = path + "/" + hex.EncodeToString([]byte(term[:1])) + "/" + term
|
||||||
|
data, err = ioutil.ReadFile(terminfo)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func setup_term_builtin() error {
|
||||||
|
name := os.Getenv("TERM")
|
||||||
|
if name == "" {
|
||||||
|
return errors.New("terminfo: TERM environment variable not set")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, t := range terms {
|
||||||
|
if t.name == name {
|
||||||
|
keys = t.keys
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compat_table := []struct {
|
||||||
|
partial string
|
||||||
|
keys []string
|
||||||
|
}{
|
||||||
|
{"xterm", xterm_keys},
|
||||||
|
{"xterm-256color", xterm_keys},
|
||||||
|
{"rxvt", rxvt_keys},
|
||||||
|
{"rxvt-unicode", rxvt_keys},
|
||||||
|
{"rxvt-256color", rxvt_keys},
|
||||||
|
{"linux", linux_keys},
|
||||||
|
{"Eterm", eterm_keys},
|
||||||
|
{"screen", screen_keys},
|
||||||
|
// let's assume that 'cygwin' is xterm compatible
|
||||||
|
{"cygwin", xterm_keys},
|
||||||
|
{"st", xterm_keys},
|
||||||
|
}
|
||||||
|
|
||||||
|
// try compatibility variants
|
||||||
|
for _, it := range compat_table {
|
||||||
|
if strings.Contains(name, it.partial) {
|
||||||
|
keys = it.keys
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors.New("termbox: unsupported terminal")
|
||||||
|
}
|
||||||
|
|
||||||
|
func setup_term() (err error) {
|
||||||
|
var data []byte
|
||||||
|
var header [6]int16
|
||||||
|
var str_offset, table_offset int16
|
||||||
|
|
||||||
|
data, err = load_terminfo()
|
||||||
|
if err != nil {
|
||||||
|
return setup_term_builtin()
|
||||||
|
}
|
||||||
|
|
||||||
|
rd := bytes.NewReader(data)
|
||||||
|
// 0: magic number, 1: size of names section, 2: size of boolean section, 3:
|
||||||
|
// size of numbers section (in integers), 4: size of the strings section (in
|
||||||
|
// integers), 5: size of the string table
|
||||||
|
|
||||||
|
err = binary.Read(rd, binary.LittleEndian, header[:])
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if header[0] != 542 && header[0] != 282 {
|
||||||
|
return setup_term_builtin()
|
||||||
|
}
|
||||||
|
|
||||||
|
number_sec_len := int16(2)
|
||||||
|
if header[0] == 542 { // doc says it should be octal 0542, but what I see it terminfo files is 542, learn to program please... thank you..
|
||||||
|
number_sec_len = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header[1]+header[2])%2 != 0 {
|
||||||
|
// old quirk to align everything on word boundaries
|
||||||
|
header[2] += 1
|
||||||
|
}
|
||||||
|
str_offset = ti_header_length + header[1] + header[2] + number_sec_len*header[3]
|
||||||
|
table_offset = str_offset + 2*header[4]
|
||||||
|
|
||||||
|
keys = make([]string, 0xFFFF-key_min)
|
||||||
|
for i := range keys {
|
||||||
|
keys[i], err = ti_read_string(rd, str_offset+2*ti_keys[i], table_offset)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ti_read_string(rd *bytes.Reader, str_off, table int16) (string, error) {
|
||||||
|
var off int16
|
||||||
|
|
||||||
|
_, err := rd.Seek(int64(str_off), 0)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
err = binary.Read(rd, binary.LittleEndian, &off)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
_, err = rd.Seek(int64(table+off), 0)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
var bs []byte
|
||||||
|
for {
|
||||||
|
b, err := rd.ReadByte()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if b == byte(0x00) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
bs = append(bs, b)
|
||||||
|
}
|
||||||
|
return string(bs), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// "Maps" special keys constants from termbox.go to the number of the respective
|
||||||
|
// string capability in the terminfo file. Taken from (ncurses) term.h.
|
||||||
|
var ti_keys = []int16{
|
||||||
|
66, 68 /* apparently not a typo; 67 is F10 for whatever reason */, 69, 70,
|
||||||
|
71, 72, 73, 74, 75, 67, 216, 217, 77, 59, 76, 164, 82, 81, 87, 61, 79, 83,
|
||||||
|
}
|
13
vendor/golang.org/x/sys/windows/aliases.go
generated
vendored
Normal file
13
vendor/golang.org/x/sys/windows/aliases.go
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build windows
|
||||||
|
// +build go1.9
|
||||||
|
|
||||||
|
package windows
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
type Errno = syscall.Errno
|
||||||
|
type SysProcAttr = syscall.SysProcAttr
|
415
vendor/golang.org/x/sys/windows/dll_windows.go
generated
vendored
Normal file
415
vendor/golang.org/x/sys/windows/dll_windows.go
generated
vendored
Normal file
|
@ -0,0 +1,415 @@
|
||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package windows
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// We need to use LoadLibrary and GetProcAddress from the Go runtime, because
|
||||||
|
// the these symbols are loaded by the system linker and are required to
|
||||||
|
// dynamically load additional symbols. Note that in the Go runtime, these
|
||||||
|
// return syscall.Handle and syscall.Errno, but these are the same, in fact,
|
||||||
|
// as windows.Handle and windows.Errno, and we intend to keep these the same.
|
||||||
|
|
||||||
|
//go:linkname syscall_loadlibrary syscall.loadlibrary
|
||||||
|
func syscall_loadlibrary(filename *uint16) (handle Handle, err Errno)
|
||||||
|
|
||||||
|
//go:linkname syscall_getprocaddress syscall.getprocaddress
|
||||||
|
func syscall_getprocaddress(handle Handle, procname *uint8) (proc uintptr, err Errno)
|
||||||
|
|
||||||
|
// DLLError describes reasons for DLL load failures.
|
||||||
|
type DLLError struct {
|
||||||
|
Err error
|
||||||
|
ObjName string
|
||||||
|
Msg string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *DLLError) Error() string { return e.Msg }
|
||||||
|
|
||||||
|
// A DLL implements access to a single DLL.
|
||||||
|
type DLL struct {
|
||||||
|
Name string
|
||||||
|
Handle Handle
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadDLL loads DLL file into memory.
|
||||||
|
//
|
||||||
|
// Warning: using LoadDLL without an absolute path name is subject to
|
||||||
|
// DLL preloading attacks. To safely load a system DLL, use LazyDLL
|
||||||
|
// with System set to true, or use LoadLibraryEx directly.
|
||||||
|
func LoadDLL(name string) (dll *DLL, err error) {
|
||||||
|
namep, err := UTF16PtrFromString(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
h, e := syscall_loadlibrary(namep)
|
||||||
|
if e != 0 {
|
||||||
|
return nil, &DLLError{
|
||||||
|
Err: e,
|
||||||
|
ObjName: name,
|
||||||
|
Msg: "Failed to load " + name + ": " + e.Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d := &DLL{
|
||||||
|
Name: name,
|
||||||
|
Handle: h,
|
||||||
|
}
|
||||||
|
return d, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MustLoadDLL is like LoadDLL but panics if load operation failes.
|
||||||
|
func MustLoadDLL(name string) *DLL {
|
||||||
|
d, e := LoadDLL(name)
|
||||||
|
if e != nil {
|
||||||
|
panic(e)
|
||||||
|
}
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindProc searches DLL d for procedure named name and returns *Proc
|
||||||
|
// if found. It returns an error if search fails.
|
||||||
|
func (d *DLL) FindProc(name string) (proc *Proc, err error) {
|
||||||
|
namep, err := BytePtrFromString(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
a, e := syscall_getprocaddress(d.Handle, namep)
|
||||||
|
if e != 0 {
|
||||||
|
return nil, &DLLError{
|
||||||
|
Err: e,
|
||||||
|
ObjName: name,
|
||||||
|
Msg: "Failed to find " + name + " procedure in " + d.Name + ": " + e.Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p := &Proc{
|
||||||
|
Dll: d,
|
||||||
|
Name: name,
|
||||||
|
addr: a,
|
||||||
|
}
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MustFindProc is like FindProc but panics if search fails.
|
||||||
|
func (d *DLL) MustFindProc(name string) *Proc {
|
||||||
|
p, e := d.FindProc(name)
|
||||||
|
if e != nil {
|
||||||
|
panic(e)
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindProcByOrdinal searches DLL d for procedure by ordinal and returns *Proc
|
||||||
|
// if found. It returns an error if search fails.
|
||||||
|
func (d *DLL) FindProcByOrdinal(ordinal uintptr) (proc *Proc, err error) {
|
||||||
|
a, e := GetProcAddressByOrdinal(d.Handle, ordinal)
|
||||||
|
name := "#" + itoa(int(ordinal))
|
||||||
|
if e != nil {
|
||||||
|
return nil, &DLLError{
|
||||||
|
Err: e,
|
||||||
|
ObjName: name,
|
||||||
|
Msg: "Failed to find " + name + " procedure in " + d.Name + ": " + e.Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p := &Proc{
|
||||||
|
Dll: d,
|
||||||
|
Name: name,
|
||||||
|
addr: a,
|
||||||
|
}
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MustFindProcByOrdinal is like FindProcByOrdinal but panics if search fails.
|
||||||
|
func (d *DLL) MustFindProcByOrdinal(ordinal uintptr) *Proc {
|
||||||
|
p, e := d.FindProcByOrdinal(ordinal)
|
||||||
|
if e != nil {
|
||||||
|
panic(e)
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release unloads DLL d from memory.
|
||||||
|
func (d *DLL) Release() (err error) {
|
||||||
|
return FreeLibrary(d.Handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Proc implements access to a procedure inside a DLL.
|
||||||
|
type Proc struct {
|
||||||
|
Dll *DLL
|
||||||
|
Name string
|
||||||
|
addr uintptr
|
||||||
|
}
|
||||||
|
|
||||||
|
// Addr returns the address of the procedure represented by p.
|
||||||
|
// The return value can be passed to Syscall to run the procedure.
|
||||||
|
func (p *Proc) Addr() uintptr {
|
||||||
|
return p.addr
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:uintptrescapes
|
||||||
|
|
||||||
|
// Call executes procedure p with arguments a. It will panic, if more than 15 arguments
|
||||||
|
// are supplied.
|
||||||
|
//
|
||||||
|
// The returned error is always non-nil, constructed from the result of GetLastError.
|
||||||
|
// Callers must inspect the primary return value to decide whether an error occurred
|
||||||
|
// (according to the semantics of the specific function being called) before consulting
|
||||||
|
// the error. The error will be guaranteed to contain windows.Errno.
|
||||||
|
func (p *Proc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) {
|
||||||
|
switch len(a) {
|
||||||
|
case 0:
|
||||||
|
return syscall.Syscall(p.Addr(), uintptr(len(a)), 0, 0, 0)
|
||||||
|
case 1:
|
||||||
|
return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], 0, 0)
|
||||||
|
case 2:
|
||||||
|
return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], 0)
|
||||||
|
case 3:
|
||||||
|
return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], a[2])
|
||||||
|
case 4:
|
||||||
|
return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], 0, 0)
|
||||||
|
case 5:
|
||||||
|
return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], 0)
|
||||||
|
case 6:
|
||||||
|
return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5])
|
||||||
|
case 7:
|
||||||
|
return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], 0, 0)
|
||||||
|
case 8:
|
||||||
|
return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], 0)
|
||||||
|
case 9:
|
||||||
|
return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8])
|
||||||
|
case 10:
|
||||||
|
return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], 0, 0)
|
||||||
|
case 11:
|
||||||
|
return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], 0)
|
||||||
|
case 12:
|
||||||
|
return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11])
|
||||||
|
case 13:
|
||||||
|
return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], 0, 0)
|
||||||
|
case 14:
|
||||||
|
return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], 0)
|
||||||
|
case 15:
|
||||||
|
return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14])
|
||||||
|
default:
|
||||||
|
panic("Call " + p.Name + " with too many arguments " + itoa(len(a)) + ".")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A LazyDLL implements access to a single DLL.
|
||||||
|
// It will delay the load of the DLL until the first
|
||||||
|
// call to its Handle method or to one of its
|
||||||
|
// LazyProc's Addr method.
|
||||||
|
type LazyDLL struct {
|
||||||
|
Name string
|
||||||
|
|
||||||
|
// System determines whether the DLL must be loaded from the
|
||||||
|
// Windows System directory, bypassing the normal DLL search
|
||||||
|
// path.
|
||||||
|
System bool
|
||||||
|
|
||||||
|
mu sync.Mutex
|
||||||
|
dll *DLL // non nil once DLL is loaded
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load loads DLL file d.Name into memory. It returns an error if fails.
|
||||||
|
// Load will not try to load DLL, if it is already loaded into memory.
|
||||||
|
func (d *LazyDLL) Load() error {
|
||||||
|
// Non-racy version of:
|
||||||
|
// if d.dll != nil {
|
||||||
|
if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll))) != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
d.mu.Lock()
|
||||||
|
defer d.mu.Unlock()
|
||||||
|
if d.dll != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// kernel32.dll is special, since it's where LoadLibraryEx comes from.
|
||||||
|
// The kernel already special-cases its name, so it's always
|
||||||
|
// loaded from system32.
|
||||||
|
var dll *DLL
|
||||||
|
var err error
|
||||||
|
if d.Name == "kernel32.dll" {
|
||||||
|
dll, err = LoadDLL(d.Name)
|
||||||
|
} else {
|
||||||
|
dll, err = loadLibraryEx(d.Name, d.System)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-racy version of:
|
||||||
|
// d.dll = dll
|
||||||
|
atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll)), unsafe.Pointer(dll))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// mustLoad is like Load but panics if search fails.
|
||||||
|
func (d *LazyDLL) mustLoad() {
|
||||||
|
e := d.Load()
|
||||||
|
if e != nil {
|
||||||
|
panic(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle returns d's module handle.
|
||||||
|
func (d *LazyDLL) Handle() uintptr {
|
||||||
|
d.mustLoad()
|
||||||
|
return uintptr(d.dll.Handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewProc returns a LazyProc for accessing the named procedure in the DLL d.
|
||||||
|
func (d *LazyDLL) NewProc(name string) *LazyProc {
|
||||||
|
return &LazyProc{l: d, Name: name}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLazyDLL creates new LazyDLL associated with DLL file.
|
||||||
|
func NewLazyDLL(name string) *LazyDLL {
|
||||||
|
return &LazyDLL{Name: name}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLazySystemDLL is like NewLazyDLL, but will only
|
||||||
|
// search Windows System directory for the DLL if name is
|
||||||
|
// a base name (like "advapi32.dll").
|
||||||
|
func NewLazySystemDLL(name string) *LazyDLL {
|
||||||
|
return &LazyDLL{Name: name, System: true}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A LazyProc implements access to a procedure inside a LazyDLL.
|
||||||
|
// It delays the lookup until the Addr method is called.
|
||||||
|
type LazyProc struct {
|
||||||
|
Name string
|
||||||
|
|
||||||
|
mu sync.Mutex
|
||||||
|
l *LazyDLL
|
||||||
|
proc *Proc
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find searches DLL for procedure named p.Name. It returns
|
||||||
|
// an error if search fails. Find will not search procedure,
|
||||||
|
// if it is already found and loaded into memory.
|
||||||
|
func (p *LazyProc) Find() error {
|
||||||
|
// Non-racy version of:
|
||||||
|
// if p.proc == nil {
|
||||||
|
if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc))) == nil {
|
||||||
|
p.mu.Lock()
|
||||||
|
defer p.mu.Unlock()
|
||||||
|
if p.proc == nil {
|
||||||
|
e := p.l.Load()
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
proc, e := p.l.dll.FindProc(p.Name)
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
// Non-racy version of:
|
||||||
|
// p.proc = proc
|
||||||
|
atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc)), unsafe.Pointer(proc))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// mustFind is like Find but panics if search fails.
|
||||||
|
func (p *LazyProc) mustFind() {
|
||||||
|
e := p.Find()
|
||||||
|
if e != nil {
|
||||||
|
panic(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Addr returns the address of the procedure represented by p.
|
||||||
|
// The return value can be passed to Syscall to run the procedure.
|
||||||
|
// It will panic if the procedure cannot be found.
|
||||||
|
func (p *LazyProc) Addr() uintptr {
|
||||||
|
p.mustFind()
|
||||||
|
return p.proc.Addr()
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:uintptrescapes
|
||||||
|
|
||||||
|
// Call executes procedure p with arguments a. It will panic, if more than 15 arguments
|
||||||
|
// are supplied. It will also panic if the procedure cannot be found.
|
||||||
|
//
|
||||||
|
// The returned error is always non-nil, constructed from the result of GetLastError.
|
||||||
|
// Callers must inspect the primary return value to decide whether an error occurred
|
||||||
|
// (according to the semantics of the specific function being called) before consulting
|
||||||
|
// the error. The error will be guaranteed to contain windows.Errno.
|
||||||
|
func (p *LazyProc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) {
|
||||||
|
p.mustFind()
|
||||||
|
return p.proc.Call(a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
var canDoSearchSystem32Once struct {
|
||||||
|
sync.Once
|
||||||
|
v bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func initCanDoSearchSystem32() {
|
||||||
|
// https://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx says:
|
||||||
|
// "Windows 7, Windows Server 2008 R2, Windows Vista, and Windows
|
||||||
|
// Server 2008: The LOAD_LIBRARY_SEARCH_* flags are available on
|
||||||
|
// systems that have KB2533623 installed. To determine whether the
|
||||||
|
// flags are available, use GetProcAddress to get the address of the
|
||||||
|
// AddDllDirectory, RemoveDllDirectory, or SetDefaultDllDirectories
|
||||||
|
// function. If GetProcAddress succeeds, the LOAD_LIBRARY_SEARCH_*
|
||||||
|
// flags can be used with LoadLibraryEx."
|
||||||
|
canDoSearchSystem32Once.v = (modkernel32.NewProc("AddDllDirectory").Find() == nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func canDoSearchSystem32() bool {
|
||||||
|
canDoSearchSystem32Once.Do(initCanDoSearchSystem32)
|
||||||
|
return canDoSearchSystem32Once.v
|
||||||
|
}
|
||||||
|
|
||||||
|
func isBaseName(name string) bool {
|
||||||
|
for _, c := range name {
|
||||||
|
if c == ':' || c == '/' || c == '\\' {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// loadLibraryEx wraps the Windows LoadLibraryEx function.
|
||||||
|
//
|
||||||
|
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v=vs.85).aspx
|
||||||
|
//
|
||||||
|
// If name is not an absolute path, LoadLibraryEx searches for the DLL
|
||||||
|
// in a variety of automatic locations unless constrained by flags.
|
||||||
|
// See: https://msdn.microsoft.com/en-us/library/ff919712%28VS.85%29.aspx
|
||||||
|
func loadLibraryEx(name string, system bool) (*DLL, error) {
|
||||||
|
loadDLL := name
|
||||||
|
var flags uintptr
|
||||||
|
if system {
|
||||||
|
if canDoSearchSystem32() {
|
||||||
|
const LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800
|
||||||
|
flags = LOAD_LIBRARY_SEARCH_SYSTEM32
|
||||||
|
} else if isBaseName(name) {
|
||||||
|
// WindowsXP or unpatched Windows machine
|
||||||
|
// trying to load "foo.dll" out of the system
|
||||||
|
// folder, but LoadLibraryEx doesn't support
|
||||||
|
// that yet on their system, so emulate it.
|
||||||
|
systemdir, err := GetSystemDirectory()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
loadDLL = systemdir + "\\" + name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
h, err := LoadLibraryEx(loadDLL, 0, flags)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &DLL{Name: name, Handle: h}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type errString string
|
||||||
|
|
||||||
|
func (s errString) Error() string { return string(s) }
|
8
vendor/golang.org/x/sys/windows/empty.s
generated
vendored
Normal file
8
vendor/golang.org/x/sys/windows/empty.s
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !go1.12
|
||||||
|
|
||||||
|
// This file is here to allow bodyless functions with go:linkname for Go 1.11
|
||||||
|
// and earlier (see https://golang.org/issue/23311).
|
54
vendor/golang.org/x/sys/windows/env_windows.go
generated
vendored
Normal file
54
vendor/golang.org/x/sys/windows/env_windows.go
generated
vendored
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Windows environment variables.
|
||||||
|
|
||||||
|
package windows
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Getenv(key string) (value string, found bool) {
|
||||||
|
return syscall.Getenv(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Setenv(key, value string) error {
|
||||||
|
return syscall.Setenv(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Clearenv() {
|
||||||
|
syscall.Clearenv()
|
||||||
|
}
|
||||||
|
|
||||||
|
func Environ() []string {
|
||||||
|
return syscall.Environ()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a default environment associated with the token, rather than the current
|
||||||
|
// process. If inheritExisting is true, then this environment also inherits the
|
||||||
|
// environment of the current process.
|
||||||
|
func (token Token) Environ(inheritExisting bool) (env []string, err error) {
|
||||||
|
var block *uint16
|
||||||
|
err = CreateEnvironmentBlock(&block, token, inheritExisting)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer DestroyEnvironmentBlock(block)
|
||||||
|
blockp := uintptr(unsafe.Pointer(block))
|
||||||
|
for {
|
||||||
|
entry := UTF16PtrToString((*uint16)(unsafe.Pointer(blockp)))
|
||||||
|
if len(entry) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
env = append(env, entry)
|
||||||
|
blockp += 2 * (uintptr(len(entry)) + 1)
|
||||||
|
}
|
||||||
|
return env, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Unsetenv(key string) error {
|
||||||
|
return syscall.Unsetenv(key)
|
||||||
|
}
|
20
vendor/golang.org/x/sys/windows/eventlog.go
generated
vendored
Normal file
20
vendor/golang.org/x/sys/windows/eventlog.go
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package windows
|
||||||
|
|
||||||
|
const (
|
||||||
|
EVENTLOG_SUCCESS = 0
|
||||||
|
EVENTLOG_ERROR_TYPE = 1
|
||||||
|
EVENTLOG_WARNING_TYPE = 2
|
||||||
|
EVENTLOG_INFORMATION_TYPE = 4
|
||||||
|
EVENTLOG_AUDIT_SUCCESS = 8
|
||||||
|
EVENTLOG_AUDIT_FAILURE = 16
|
||||||
|
)
|
||||||
|
|
||||||
|
//sys RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Handle, err error) [failretval==0] = advapi32.RegisterEventSourceW
|
||||||
|
//sys DeregisterEventSource(handle Handle) (err error) = advapi32.DeregisterEventSource
|
||||||
|
//sys ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrSId uintptr, numStrings uint16, dataSize uint32, strings **uint16, rawData *byte) (err error) = advapi32.ReportEventW
|
97
vendor/golang.org/x/sys/windows/exec_windows.go
generated
vendored
Normal file
97
vendor/golang.org/x/sys/windows/exec_windows.go
generated
vendored
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// Fork, exec, wait, etc.
|
||||||
|
|
||||||
|
package windows
|
||||||
|
|
||||||
|
// EscapeArg rewrites command line argument s as prescribed
|
||||||
|
// in http://msdn.microsoft.com/en-us/library/ms880421.
|
||||||
|
// This function returns "" (2 double quotes) if s is empty.
|
||||||
|
// Alternatively, these transformations are done:
|
||||||
|
// - every back slash (\) is doubled, but only if immediately
|
||||||
|
// followed by double quote (");
|
||||||
|
// - every double quote (") is escaped by back slash (\);
|
||||||
|
// - finally, s is wrapped with double quotes (arg -> "arg"),
|
||||||
|
// but only if there is space or tab inside s.
|
||||||
|
func EscapeArg(s string) string {
|
||||||
|
if len(s) == 0 {
|
||||||
|
return "\"\""
|
||||||
|
}
|
||||||
|
n := len(s)
|
||||||
|
hasSpace := false
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
switch s[i] {
|
||||||
|
case '"', '\\':
|
||||||
|
n++
|
||||||
|
case ' ', '\t':
|
||||||
|
hasSpace = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if hasSpace {
|
||||||
|
n += 2
|
||||||
|
}
|
||||||
|
if n == len(s) {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
qs := make([]byte, n)
|
||||||
|
j := 0
|
||||||
|
if hasSpace {
|
||||||
|
qs[j] = '"'
|
||||||
|
j++
|
||||||
|
}
|
||||||
|
slashes := 0
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
switch s[i] {
|
||||||
|
default:
|
||||||
|
slashes = 0
|
||||||
|
qs[j] = s[i]
|
||||||
|
case '\\':
|
||||||
|
slashes++
|
||||||
|
qs[j] = s[i]
|
||||||
|
case '"':
|
||||||
|
for ; slashes > 0; slashes-- {
|
||||||
|
qs[j] = '\\'
|
||||||
|
j++
|
||||||
|
}
|
||||||
|
qs[j] = '\\'
|
||||||
|
j++
|
||||||
|
qs[j] = s[i]
|
||||||
|
}
|
||||||
|
j++
|
||||||
|
}
|
||||||
|
if hasSpace {
|
||||||
|
for ; slashes > 0; slashes-- {
|
||||||
|
qs[j] = '\\'
|
||||||
|
j++
|
||||||
|
}
|
||||||
|
qs[j] = '"'
|
||||||
|
j++
|
||||||
|
}
|
||||||
|
return string(qs[:j])
|
||||||
|
}
|
||||||
|
|
||||||
|
func CloseOnExec(fd Handle) {
|
||||||
|
SetHandleInformation(Handle(fd), HANDLE_FLAG_INHERIT, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FullPath retrieves the full path of the specified file.
|
||||||
|
func FullPath(name string) (path string, err error) {
|
||||||
|
p, err := UTF16PtrFromString(name)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
n := uint32(100)
|
||||||
|
for {
|
||||||
|
buf := make([]uint16, n)
|
||||||
|
n, err = GetFullPathName(p, uint32(len(buf)), &buf[0], nil)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if n <= uint32(len(buf)) {
|
||||||
|
return UTF16ToString(buf[:n]), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
31
vendor/golang.org/x/sys/windows/memory_windows.go
generated
vendored
Normal file
31
vendor/golang.org/x/sys/windows/memory_windows.go
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package windows
|
||||||
|
|
||||||
|
const (
|
||||||
|
MEM_COMMIT = 0x00001000
|
||||||
|
MEM_RESERVE = 0x00002000
|
||||||
|
MEM_DECOMMIT = 0x00004000
|
||||||
|
MEM_RELEASE = 0x00008000
|
||||||
|
MEM_RESET = 0x00080000
|
||||||
|
MEM_TOP_DOWN = 0x00100000
|
||||||
|
MEM_WRITE_WATCH = 0x00200000
|
||||||
|
MEM_PHYSICAL = 0x00400000
|
||||||
|
MEM_RESET_UNDO = 0x01000000
|
||||||
|
MEM_LARGE_PAGES = 0x20000000
|
||||||
|
|
||||||
|
PAGE_NOACCESS = 0x01
|
||||||
|
PAGE_READONLY = 0x02
|
||||||
|
PAGE_READWRITE = 0x04
|
||||||
|
PAGE_WRITECOPY = 0x08
|
||||||
|
PAGE_EXECUTE_READ = 0x20
|
||||||
|
PAGE_EXECUTE_READWRITE = 0x40
|
||||||
|
PAGE_EXECUTE_WRITECOPY = 0x80
|
||||||
|
|
||||||
|
QUOTA_LIMITS_HARDWS_MIN_DISABLE = 0x00000002
|
||||||
|
QUOTA_LIMITS_HARDWS_MIN_ENABLE = 0x00000001
|
||||||
|
QUOTA_LIMITS_HARDWS_MAX_DISABLE = 0x00000008
|
||||||
|
QUOTA_LIMITS_HARDWS_MAX_ENABLE = 0x00000004
|
||||||
|
)
|
63
vendor/golang.org/x/sys/windows/mkerrors.bash
generated
vendored
Normal file
63
vendor/golang.org/x/sys/windows/mkerrors.bash
generated
vendored
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Copyright 2019 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.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
shopt -s nullglob
|
||||||
|
|
||||||
|
winerror="$(printf '%s\n' "/mnt/c/Program Files (x86)/Windows Kits/"/*/Include/*/shared/winerror.h | sort -Vr | head -n 1)"
|
||||||
|
[[ -n $winerror ]] || { echo "Unable to find winerror.h" >&2; exit 1; }
|
||||||
|
|
||||||
|
declare -A errors
|
||||||
|
|
||||||
|
{
|
||||||
|
echo "// Code generated by 'mkerrors.bash'; DO NOT EDIT."
|
||||||
|
echo
|
||||||
|
echo "package windows"
|
||||||
|
echo "import \"syscall\""
|
||||||
|
echo "const ("
|
||||||
|
|
||||||
|
while read -r line; do
|
||||||
|
unset vtype
|
||||||
|
if [[ $line =~ ^#define\ +([A-Z0-9_]+k?)\ +([A-Z0-9_]+\()?([A-Z][A-Z0-9_]+k?)\)? ]]; then
|
||||||
|
key="${BASH_REMATCH[1]}"
|
||||||
|
value="${BASH_REMATCH[3]}"
|
||||||
|
elif [[ $line =~ ^#define\ +([A-Z0-9_]+k?)\ +([A-Z0-9_]+\()?((0x)?[0-9A-Fa-f]+)L?\)? ]]; then
|
||||||
|
key="${BASH_REMATCH[1]}"
|
||||||
|
value="${BASH_REMATCH[3]}"
|
||||||
|
vtype="${BASH_REMATCH[2]}"
|
||||||
|
elif [[ $line =~ ^#define\ +([A-Z0-9_]+k?)\ +\(\(([A-Z]+)\)((0x)?[0-9A-Fa-f]+)L?\) ]]; then
|
||||||
|
key="${BASH_REMATCH[1]}"
|
||||||
|
value="${BASH_REMATCH[3]}"
|
||||||
|
vtype="${BASH_REMATCH[2]}"
|
||||||
|
else
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
[[ -n $key && -n $value ]] || continue
|
||||||
|
[[ -z ${errors["$key"]} ]] || continue
|
||||||
|
errors["$key"]="$value"
|
||||||
|
if [[ -v vtype ]]; then
|
||||||
|
if [[ $key == FACILITY_* || $key == NO_ERROR ]]; then
|
||||||
|
vtype=""
|
||||||
|
elif [[ $vtype == *HANDLE* || $vtype == *HRESULT* ]]; then
|
||||||
|
vtype="Handle"
|
||||||
|
else
|
||||||
|
vtype="syscall.Errno"
|
||||||
|
fi
|
||||||
|
last_vtype="$vtype"
|
||||||
|
else
|
||||||
|
vtype=""
|
||||||
|
if [[ $last_vtype == Handle && $value == NO_ERROR ]]; then
|
||||||
|
value="S_OK"
|
||||||
|
elif [[ $last_vtype == syscall.Errno && $value == NO_ERROR ]]; then
|
||||||
|
value="ERROR_SUCCESS"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$key $vtype = $value"
|
||||||
|
done < "$winerror"
|
||||||
|
|
||||||
|
echo ")"
|
||||||
|
} | gofmt > "zerrors_windows.go"
|
27
vendor/golang.org/x/sys/windows/mkknownfolderids.bash
generated
vendored
Normal file
27
vendor/golang.org/x/sys/windows/mkknownfolderids.bash
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Copyright 2019 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.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
shopt -s nullglob
|
||||||
|
|
||||||
|
knownfolders="$(printf '%s\n' "/mnt/c/Program Files (x86)/Windows Kits/"/*/Include/*/um/KnownFolders.h | sort -Vr | head -n 1)"
|
||||||
|
[[ -n $knownfolders ]] || { echo "Unable to find KnownFolders.h" >&2; exit 1; }
|
||||||
|
|
||||||
|
{
|
||||||
|
echo "// Code generated by 'mkknownfolderids.bash'; DO NOT EDIT."
|
||||||
|
echo
|
||||||
|
echo "package windows"
|
||||||
|
echo "type KNOWNFOLDERID GUID"
|
||||||
|
echo "var ("
|
||||||
|
while read -r line; do
|
||||||
|
[[ $line =~ DEFINE_KNOWN_FOLDER\((FOLDERID_[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+)\) ]] || continue
|
||||||
|
printf "%s = &KNOWNFOLDERID{0x%08x, 0x%04x, 0x%04x, [8]byte{0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x}}\n" \
|
||||||
|
"${BASH_REMATCH[1]}" $(( "${BASH_REMATCH[2]}" )) $(( "${BASH_REMATCH[3]}" )) $(( "${BASH_REMATCH[4]}" )) \
|
||||||
|
$(( "${BASH_REMATCH[5]}" )) $(( "${BASH_REMATCH[6]}" )) $(( "${BASH_REMATCH[7]}" )) $(( "${BASH_REMATCH[8]}" )) \
|
||||||
|
$(( "${BASH_REMATCH[9]}" )) $(( "${BASH_REMATCH[10]}" )) $(( "${BASH_REMATCH[11]}" )) $(( "${BASH_REMATCH[12]}" ))
|
||||||
|
done < "$knownfolders"
|
||||||
|
echo ")"
|
||||||
|
} | gofmt > "zknownfolderids_windows.go"
|
9
vendor/golang.org/x/sys/windows/mksyscall.go
generated
vendored
Normal file
9
vendor/golang.org/x/sys/windows/mksyscall.go
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build generate
|
||||||
|
|
||||||
|
package windows
|
||||||
|
|
||||||
|
//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go eventlog.go service.go syscall_windows.go security_windows.go
|
30
vendor/golang.org/x/sys/windows/race.go
generated
vendored
Normal file
30
vendor/golang.org/x/sys/windows/race.go
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build windows,race
|
||||||
|
|
||||||
|
package windows
|
||||||
|
|
||||||
|
import (
|
||||||
|
"runtime"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const raceenabled = true
|
||||||
|
|
||||||
|
func raceAcquire(addr unsafe.Pointer) {
|
||||||
|
runtime.RaceAcquire(addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func raceReleaseMerge(addr unsafe.Pointer) {
|
||||||
|
runtime.RaceReleaseMerge(addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func raceReadRange(addr unsafe.Pointer, len int) {
|
||||||
|
runtime.RaceReadRange(addr, len)
|
||||||
|
}
|
||||||
|
|
||||||
|
func raceWriteRange(addr unsafe.Pointer, len int) {
|
||||||
|
runtime.RaceWriteRange(addr, len)
|
||||||
|
}
|
25
vendor/golang.org/x/sys/windows/race0.go
generated
vendored
Normal file
25
vendor/golang.org/x/sys/windows/race0.go
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build windows,!race
|
||||||
|
|
||||||
|
package windows
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const raceenabled = false
|
||||||
|
|
||||||
|
func raceAcquire(addr unsafe.Pointer) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func raceReleaseMerge(addr unsafe.Pointer) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func raceReadRange(addr unsafe.Pointer, len int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func raceWriteRange(addr unsafe.Pointer, len int) {
|
||||||
|
}
|
1406
vendor/golang.org/x/sys/windows/security_windows.go
generated
vendored
Normal file
1406
vendor/golang.org/x/sys/windows/security_windows.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
229
vendor/golang.org/x/sys/windows/service.go
generated
vendored
Normal file
229
vendor/golang.org/x/sys/windows/service.go
generated
vendored
Normal file
|
@ -0,0 +1,229 @@
|
||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package windows
|
||||||
|
|
||||||
|
const (
|
||||||
|
SC_MANAGER_CONNECT = 1
|
||||||
|
SC_MANAGER_CREATE_SERVICE = 2
|
||||||
|
SC_MANAGER_ENUMERATE_SERVICE = 4
|
||||||
|
SC_MANAGER_LOCK = 8
|
||||||
|
SC_MANAGER_QUERY_LOCK_STATUS = 16
|
||||||
|
SC_MANAGER_MODIFY_BOOT_CONFIG = 32
|
||||||
|
SC_MANAGER_ALL_ACCESS = 0xf003f
|
||||||
|
)
|
||||||
|
|
||||||
|
//sys OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle Handle, err error) [failretval==0] = advapi32.OpenSCManagerW
|
||||||
|
|
||||||
|
const (
|
||||||
|
SERVICE_KERNEL_DRIVER = 1
|
||||||
|
SERVICE_FILE_SYSTEM_DRIVER = 2
|
||||||
|
SERVICE_ADAPTER = 4
|
||||||
|
SERVICE_RECOGNIZER_DRIVER = 8
|
||||||
|
SERVICE_WIN32_OWN_PROCESS = 16
|
||||||
|
SERVICE_WIN32_SHARE_PROCESS = 32
|
||||||
|
SERVICE_WIN32 = SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS
|
||||||
|
SERVICE_INTERACTIVE_PROCESS = 256
|
||||||
|
SERVICE_DRIVER = SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_RECOGNIZER_DRIVER
|
||||||
|
SERVICE_TYPE_ALL = SERVICE_WIN32 | SERVICE_ADAPTER | SERVICE_DRIVER | SERVICE_INTERACTIVE_PROCESS
|
||||||
|
|
||||||
|
SERVICE_BOOT_START = 0
|
||||||
|
SERVICE_SYSTEM_START = 1
|
||||||
|
SERVICE_AUTO_START = 2
|
||||||
|
SERVICE_DEMAND_START = 3
|
||||||
|
SERVICE_DISABLED = 4
|
||||||
|
|
||||||
|
SERVICE_ERROR_IGNORE = 0
|
||||||
|
SERVICE_ERROR_NORMAL = 1
|
||||||
|
SERVICE_ERROR_SEVERE = 2
|
||||||
|
SERVICE_ERROR_CRITICAL = 3
|
||||||
|
|
||||||
|
SC_STATUS_PROCESS_INFO = 0
|
||||||
|
|
||||||
|
SC_ACTION_NONE = 0
|
||||||
|
SC_ACTION_RESTART = 1
|
||||||
|
SC_ACTION_REBOOT = 2
|
||||||
|
SC_ACTION_RUN_COMMAND = 3
|
||||||
|
|
||||||
|
SERVICE_STOPPED = 1
|
||||||
|
SERVICE_START_PENDING = 2
|
||||||
|
SERVICE_STOP_PENDING = 3
|
||||||
|
SERVICE_RUNNING = 4
|
||||||
|
SERVICE_CONTINUE_PENDING = 5
|
||||||
|
SERVICE_PAUSE_PENDING = 6
|
||||||
|
SERVICE_PAUSED = 7
|
||||||
|
SERVICE_NO_CHANGE = 0xffffffff
|
||||||
|
|
||||||
|
SERVICE_ACCEPT_STOP = 1
|
||||||
|
SERVICE_ACCEPT_PAUSE_CONTINUE = 2
|
||||||
|
SERVICE_ACCEPT_SHUTDOWN = 4
|
||||||
|
SERVICE_ACCEPT_PARAMCHANGE = 8
|
||||||
|
SERVICE_ACCEPT_NETBINDCHANGE = 16
|
||||||
|
SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 32
|
||||||
|
SERVICE_ACCEPT_POWEREVENT = 64
|
||||||
|
SERVICE_ACCEPT_SESSIONCHANGE = 128
|
||||||
|
|
||||||
|
SERVICE_CONTROL_STOP = 1
|
||||||
|
SERVICE_CONTROL_PAUSE = 2
|
||||||
|
SERVICE_CONTROL_CONTINUE = 3
|
||||||
|
SERVICE_CONTROL_INTERROGATE = 4
|
||||||
|
SERVICE_CONTROL_SHUTDOWN = 5
|
||||||
|
SERVICE_CONTROL_PARAMCHANGE = 6
|
||||||
|
SERVICE_CONTROL_NETBINDADD = 7
|
||||||
|
SERVICE_CONTROL_NETBINDREMOVE = 8
|
||||||
|
SERVICE_CONTROL_NETBINDENABLE = 9
|
||||||
|
SERVICE_CONTROL_NETBINDDISABLE = 10
|
||||||
|
SERVICE_CONTROL_DEVICEEVENT = 11
|
||||||
|
SERVICE_CONTROL_HARDWAREPROFILECHANGE = 12
|
||||||
|
SERVICE_CONTROL_POWEREVENT = 13
|
||||||
|
SERVICE_CONTROL_SESSIONCHANGE = 14
|
||||||
|
|
||||||
|
SERVICE_ACTIVE = 1
|
||||||
|
SERVICE_INACTIVE = 2
|
||||||
|
SERVICE_STATE_ALL = 3
|
||||||
|
|
||||||
|
SERVICE_QUERY_CONFIG = 1
|
||||||
|
SERVICE_CHANGE_CONFIG = 2
|
||||||
|
SERVICE_QUERY_STATUS = 4
|
||||||
|
SERVICE_ENUMERATE_DEPENDENTS = 8
|
||||||
|
SERVICE_START = 16
|
||||||
|
SERVICE_STOP = 32
|
||||||
|
SERVICE_PAUSE_CONTINUE = 64
|
||||||
|
SERVICE_INTERROGATE = 128
|
||||||
|
SERVICE_USER_DEFINED_CONTROL = 256
|
||||||
|
SERVICE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_START | SERVICE_STOP | SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE | SERVICE_USER_DEFINED_CONTROL
|
||||||
|
|
||||||
|
SERVICE_RUNS_IN_SYSTEM_PROCESS = 1
|
||||||
|
|
||||||
|
SERVICE_CONFIG_DESCRIPTION = 1
|
||||||
|
SERVICE_CONFIG_FAILURE_ACTIONS = 2
|
||||||
|
SERVICE_CONFIG_DELAYED_AUTO_START_INFO = 3
|
||||||
|
SERVICE_CONFIG_FAILURE_ACTIONS_FLAG = 4
|
||||||
|
SERVICE_CONFIG_SERVICE_SID_INFO = 5
|
||||||
|
SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO = 6
|
||||||
|
SERVICE_CONFIG_PRESHUTDOWN_INFO = 7
|
||||||
|
SERVICE_CONFIG_TRIGGER_INFO = 8
|
||||||
|
SERVICE_CONFIG_PREFERRED_NODE = 9
|
||||||
|
SERVICE_CONFIG_LAUNCH_PROTECTED = 12
|
||||||
|
|
||||||
|
SERVICE_SID_TYPE_NONE = 0
|
||||||
|
SERVICE_SID_TYPE_UNRESTRICTED = 1
|
||||||
|
SERVICE_SID_TYPE_RESTRICTED = 2 | SERVICE_SID_TYPE_UNRESTRICTED
|
||||||
|
|
||||||
|
SC_ENUM_PROCESS_INFO = 0
|
||||||
|
|
||||||
|
SERVICE_NOTIFY_STATUS_CHANGE = 2
|
||||||
|
SERVICE_NOTIFY_STOPPED = 0x00000001
|
||||||
|
SERVICE_NOTIFY_START_PENDING = 0x00000002
|
||||||
|
SERVICE_NOTIFY_STOP_PENDING = 0x00000004
|
||||||
|
SERVICE_NOTIFY_RUNNING = 0x00000008
|
||||||
|
SERVICE_NOTIFY_CONTINUE_PENDING = 0x00000010
|
||||||
|
SERVICE_NOTIFY_PAUSE_PENDING = 0x00000020
|
||||||
|
SERVICE_NOTIFY_PAUSED = 0x00000040
|
||||||
|
SERVICE_NOTIFY_CREATED = 0x00000080
|
||||||
|
SERVICE_NOTIFY_DELETED = 0x00000100
|
||||||
|
SERVICE_NOTIFY_DELETE_PENDING = 0x00000200
|
||||||
|
)
|
||||||
|
|
||||||
|
type SERVICE_STATUS struct {
|
||||||
|
ServiceType uint32
|
||||||
|
CurrentState uint32
|
||||||
|
ControlsAccepted uint32
|
||||||
|
Win32ExitCode uint32
|
||||||
|
ServiceSpecificExitCode uint32
|
||||||
|
CheckPoint uint32
|
||||||
|
WaitHint uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type SERVICE_TABLE_ENTRY struct {
|
||||||
|
ServiceName *uint16
|
||||||
|
ServiceProc uintptr
|
||||||
|
}
|
||||||
|
|
||||||
|
type QUERY_SERVICE_CONFIG struct {
|
||||||
|
ServiceType uint32
|
||||||
|
StartType uint32
|
||||||
|
ErrorControl uint32
|
||||||
|
BinaryPathName *uint16
|
||||||
|
LoadOrderGroup *uint16
|
||||||
|
TagId uint32
|
||||||
|
Dependencies *uint16
|
||||||
|
ServiceStartName *uint16
|
||||||
|
DisplayName *uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
type SERVICE_DESCRIPTION struct {
|
||||||
|
Description *uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
type SERVICE_DELAYED_AUTO_START_INFO struct {
|
||||||
|
IsDelayedAutoStartUp uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type SERVICE_STATUS_PROCESS struct {
|
||||||
|
ServiceType uint32
|
||||||
|
CurrentState uint32
|
||||||
|
ControlsAccepted uint32
|
||||||
|
Win32ExitCode uint32
|
||||||
|
ServiceSpecificExitCode uint32
|
||||||
|
CheckPoint uint32
|
||||||
|
WaitHint uint32
|
||||||
|
ProcessId uint32
|
||||||
|
ServiceFlags uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type ENUM_SERVICE_STATUS_PROCESS struct {
|
||||||
|
ServiceName *uint16
|
||||||
|
DisplayName *uint16
|
||||||
|
ServiceStatusProcess SERVICE_STATUS_PROCESS
|
||||||
|
}
|
||||||
|
|
||||||
|
type SERVICE_NOTIFY struct {
|
||||||
|
Version uint32
|
||||||
|
NotifyCallback uintptr
|
||||||
|
Context uintptr
|
||||||
|
NotificationStatus uint32
|
||||||
|
ServiceStatus SERVICE_STATUS_PROCESS
|
||||||
|
NotificationTriggered uint32
|
||||||
|
ServiceNames *uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
type SERVICE_FAILURE_ACTIONS struct {
|
||||||
|
ResetPeriod uint32
|
||||||
|
RebootMsg *uint16
|
||||||
|
Command *uint16
|
||||||
|
ActionsCount uint32
|
||||||
|
Actions *SC_ACTION
|
||||||
|
}
|
||||||
|
|
||||||
|
type SC_ACTION struct {
|
||||||
|
Type uint32
|
||||||
|
Delay uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type QUERY_SERVICE_LOCK_STATUS struct {
|
||||||
|
IsLocked uint32
|
||||||
|
LockOwner *uint16
|
||||||
|
LockDuration uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys CloseServiceHandle(handle Handle) (err error) = advapi32.CloseServiceHandle
|
||||||
|
//sys CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) [failretval==0] = advapi32.CreateServiceW
|
||||||
|
//sys OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) [failretval==0] = advapi32.OpenServiceW
|
||||||
|
//sys DeleteService(service Handle) (err error) = advapi32.DeleteService
|
||||||
|
//sys StartService(service Handle, numArgs uint32, argVectors **uint16) (err error) = advapi32.StartServiceW
|
||||||
|
//sys QueryServiceStatus(service Handle, status *SERVICE_STATUS) (err error) = advapi32.QueryServiceStatus
|
||||||
|
//sys QueryServiceLockStatus(mgr Handle, lockStatus *QUERY_SERVICE_LOCK_STATUS, bufSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceLockStatusW
|
||||||
|
//sys ControlService(service Handle, control uint32, status *SERVICE_STATUS) (err error) = advapi32.ControlService
|
||||||
|
//sys StartServiceCtrlDispatcher(serviceTable *SERVICE_TABLE_ENTRY) (err error) = advapi32.StartServiceCtrlDispatcherW
|
||||||
|
//sys SetServiceStatus(service Handle, serviceStatus *SERVICE_STATUS) (err error) = advapi32.SetServiceStatus
|
||||||
|
//sys ChangeServiceConfig(service Handle, serviceType uint32, startType uint32, errorControl uint32, binaryPathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16, displayName *uint16) (err error) = advapi32.ChangeServiceConfigW
|
||||||
|
//sys QueryServiceConfig(service Handle, serviceConfig *QUERY_SERVICE_CONFIG, bufSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceConfigW
|
||||||
|
//sys ChangeServiceConfig2(service Handle, infoLevel uint32, info *byte) (err error) = advapi32.ChangeServiceConfig2W
|
||||||
|
//sys QueryServiceConfig2(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceConfig2W
|
||||||
|
//sys EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serviceState uint32, services *byte, bufSize uint32, bytesNeeded *uint32, servicesReturned *uint32, resumeHandle *uint32, groupName *uint16) (err error) = advapi32.EnumServicesStatusExW
|
||||||
|
//sys QueryServiceStatusEx(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceStatusEx
|
||||||
|
//sys NotifyServiceStatusChange(service Handle, notifyMask uint32, notifier *SERVICE_NOTIFY) (ret error) = advapi32.NotifyServiceStatusChangeW
|
22
vendor/golang.org/x/sys/windows/str.go
generated
vendored
Normal file
22
vendor/golang.org/x/sys/windows/str.go
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package windows
|
||||||
|
|
||||||
|
func itoa(val int) string { // do it here rather than with fmt to avoid dependency
|
||||||
|
if val < 0 {
|
||||||
|
return "-" + itoa(-val)
|
||||||
|
}
|
||||||
|
var buf [32]byte // big enough for int64
|
||||||
|
i := len(buf) - 1
|
||||||
|
for val >= 10 {
|
||||||
|
buf[i] = byte(val%10 + '0')
|
||||||
|
i--
|
||||||
|
val /= 10
|
||||||
|
}
|
||||||
|
buf[i] = byte(val + '0')
|
||||||
|
return string(buf[i:])
|
||||||
|
}
|
74
vendor/golang.org/x/sys/windows/syscall.go
generated
vendored
Normal file
74
vendor/golang.org/x/sys/windows/syscall.go
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
// Package windows contains an interface to the low-level operating system
|
||||||
|
// primitives. OS details vary depending on the underlying system, and
|
||||||
|
// by default, godoc will display the OS-specific documentation for the current
|
||||||
|
// system. If you want godoc to display syscall documentation for another
|
||||||
|
// system, set $GOOS and $GOARCH to the desired system. For example, if
|
||||||
|
// you want to view documentation for freebsd/arm on linux/amd64, set $GOOS
|
||||||
|
// to freebsd and $GOARCH to arm.
|
||||||
|
//
|
||||||
|
// The primary use of this package is inside other packages that provide a more
|
||||||
|
// portable interface to the system, such as "os", "time" and "net". Use
|
||||||
|
// those packages rather than this one if you can.
|
||||||
|
//
|
||||||
|
// For details of the functions and data types in this package consult
|
||||||
|
// the manuals for the appropriate operating system.
|
||||||
|
//
|
||||||
|
// These calls return err == nil to indicate success; otherwise
|
||||||
|
// err represents an operating system error describing the failure and
|
||||||
|
// holds a value of type syscall.Errno.
|
||||||
|
package windows // import "golang.org/x/sys/windows"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ByteSliceFromString returns a NUL-terminated slice of bytes
|
||||||
|
// containing the text of s. If s contains a NUL byte at any
|
||||||
|
// location, it returns (nil, syscall.EINVAL).
|
||||||
|
func ByteSliceFromString(s string) ([]byte, error) {
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
if s[i] == 0 {
|
||||||
|
return nil, syscall.EINVAL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a := make([]byte, len(s)+1)
|
||||||
|
copy(a, s)
|
||||||
|
return a, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BytePtrFromString returns a pointer to a NUL-terminated array of
|
||||||
|
// bytes containing the text of s. If s contains a NUL byte at any
|
||||||
|
// location, it returns (nil, syscall.EINVAL).
|
||||||
|
func BytePtrFromString(s string) (*byte, error) {
|
||||||
|
a, err := ByteSliceFromString(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &a[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Single-word zero for use when we need a valid pointer to 0 bytes.
|
||||||
|
// See mksyscall.pl.
|
||||||
|
var _zero uintptr
|
||||||
|
|
||||||
|
func (ts *Timespec) Unix() (sec int64, nsec int64) {
|
||||||
|
return int64(ts.Sec), int64(ts.Nsec)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tv *Timeval) Unix() (sec int64, nsec int64) {
|
||||||
|
return int64(tv.Sec), int64(tv.Usec) * 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts *Timespec) Nano() int64 {
|
||||||
|
return int64(ts.Sec)*1e9 + int64(ts.Nsec)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tv *Timeval) Nano() int64 {
|
||||||
|
return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000
|
||||||
|
}
|
1489
vendor/golang.org/x/sys/windows/syscall_windows.go
generated
vendored
Normal file
1489
vendor/golang.org/x/sys/windows/syscall_windows.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
1786
vendor/golang.org/x/sys/windows/types_windows.go
generated
vendored
Normal file
1786
vendor/golang.org/x/sys/windows/types_windows.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
22
vendor/golang.org/x/sys/windows/types_windows_386.go
generated
vendored
Normal file
22
vendor/golang.org/x/sys/windows/types_windows_386.go
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package windows
|
||||||
|
|
||||||
|
type WSAData struct {
|
||||||
|
Version uint16
|
||||||
|
HighVersion uint16
|
||||||
|
Description [WSADESCRIPTION_LEN + 1]byte
|
||||||
|
SystemStatus [WSASYS_STATUS_LEN + 1]byte
|
||||||
|
MaxSockets uint16
|
||||||
|
MaxUdpDg uint16
|
||||||
|
VendorInfo *byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type Servent struct {
|
||||||
|
Name *byte
|
||||||
|
Aliases **byte
|
||||||
|
Port uint16
|
||||||
|
Proto *byte
|
||||||
|
}
|
22
vendor/golang.org/x/sys/windows/types_windows_amd64.go
generated
vendored
Normal file
22
vendor/golang.org/x/sys/windows/types_windows_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package windows
|
||||||
|
|
||||||
|
type WSAData struct {
|
||||||
|
Version uint16
|
||||||
|
HighVersion uint16
|
||||||
|
MaxSockets uint16
|
||||||
|
MaxUdpDg uint16
|
||||||
|
VendorInfo *byte
|
||||||
|
Description [WSADESCRIPTION_LEN + 1]byte
|
||||||
|
SystemStatus [WSASYS_STATUS_LEN + 1]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type Servent struct {
|
||||||
|
Name *byte
|
||||||
|
Aliases **byte
|
||||||
|
Proto *byte
|
||||||
|
Port uint16
|
||||||
|
}
|
22
vendor/golang.org/x/sys/windows/types_windows_arm.go
generated
vendored
Normal file
22
vendor/golang.org/x/sys/windows/types_windows_arm.go
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package windows
|
||||||
|
|
||||||
|
type WSAData struct {
|
||||||
|
Version uint16
|
||||||
|
HighVersion uint16
|
||||||
|
Description [WSADESCRIPTION_LEN + 1]byte
|
||||||
|
SystemStatus [WSASYS_STATUS_LEN + 1]byte
|
||||||
|
MaxSockets uint16
|
||||||
|
MaxUdpDg uint16
|
||||||
|
VendorInfo *byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type Servent struct {
|
||||||
|
Name *byte
|
||||||
|
Aliases **byte
|
||||||
|
Port uint16
|
||||||
|
Proto *byte
|
||||||
|
}
|
6853
vendor/golang.org/x/sys/windows/zerrors_windows.go
generated
vendored
Normal file
6853
vendor/golang.org/x/sys/windows/zerrors_windows.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
149
vendor/golang.org/x/sys/windows/zknownfolderids_windows.go
generated
vendored
Normal file
149
vendor/golang.org/x/sys/windows/zknownfolderids_windows.go
generated
vendored
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
// Code generated by 'mkknownfolderids.bash'; DO NOT EDIT.
|
||||||
|
|
||||||
|
package windows
|
||||||
|
|
||||||
|
type KNOWNFOLDERID GUID
|
||||||
|
|
||||||
|
var (
|
||||||
|
FOLDERID_NetworkFolder = &KNOWNFOLDERID{0xd20beec4, 0x5ca8, 0x4905, [8]byte{0xae, 0x3b, 0xbf, 0x25, 0x1e, 0xa0, 0x9b, 0x53}}
|
||||||
|
FOLDERID_ComputerFolder = &KNOWNFOLDERID{0x0ac0837c, 0xbbf8, 0x452a, [8]byte{0x85, 0x0d, 0x79, 0xd0, 0x8e, 0x66, 0x7c, 0xa7}}
|
||||||
|
FOLDERID_InternetFolder = &KNOWNFOLDERID{0x4d9f7874, 0x4e0c, 0x4904, [8]byte{0x96, 0x7b, 0x40, 0xb0, 0xd2, 0x0c, 0x3e, 0x4b}}
|
||||||
|
FOLDERID_ControlPanelFolder = &KNOWNFOLDERID{0x82a74aeb, 0xaeb4, 0x465c, [8]byte{0xa0, 0x14, 0xd0, 0x97, 0xee, 0x34, 0x6d, 0x63}}
|
||||||
|
FOLDERID_PrintersFolder = &KNOWNFOLDERID{0x76fc4e2d, 0xd6ad, 0x4519, [8]byte{0xa6, 0x63, 0x37, 0xbd, 0x56, 0x06, 0x81, 0x85}}
|
||||||
|
FOLDERID_SyncManagerFolder = &KNOWNFOLDERID{0x43668bf8, 0xc14e, 0x49b2, [8]byte{0x97, 0xc9, 0x74, 0x77, 0x84, 0xd7, 0x84, 0xb7}}
|
||||||
|
FOLDERID_SyncSetupFolder = &KNOWNFOLDERID{0x0f214138, 0xb1d3, 0x4a90, [8]byte{0xbb, 0xa9, 0x27, 0xcb, 0xc0, 0xc5, 0x38, 0x9a}}
|
||||||
|
FOLDERID_ConflictFolder = &KNOWNFOLDERID{0x4bfefb45, 0x347d, 0x4006, [8]byte{0xa5, 0xbe, 0xac, 0x0c, 0xb0, 0x56, 0x71, 0x92}}
|
||||||
|
FOLDERID_SyncResultsFolder = &KNOWNFOLDERID{0x289a9a43, 0xbe44, 0x4057, [8]byte{0xa4, 0x1b, 0x58, 0x7a, 0x76, 0xd7, 0xe7, 0xf9}}
|
||||||
|
FOLDERID_RecycleBinFolder = &KNOWNFOLDERID{0xb7534046, 0x3ecb, 0x4c18, [8]byte{0xbe, 0x4e, 0x64, 0xcd, 0x4c, 0xb7, 0xd6, 0xac}}
|
||||||
|
FOLDERID_ConnectionsFolder = &KNOWNFOLDERID{0x6f0cd92b, 0x2e97, 0x45d1, [8]byte{0x88, 0xff, 0xb0, 0xd1, 0x86, 0xb8, 0xde, 0xdd}}
|
||||||
|
FOLDERID_Fonts = &KNOWNFOLDERID{0xfd228cb7, 0xae11, 0x4ae3, [8]byte{0x86, 0x4c, 0x16, 0xf3, 0x91, 0x0a, 0xb8, 0xfe}}
|
||||||
|
FOLDERID_Desktop = &KNOWNFOLDERID{0xb4bfcc3a, 0xdb2c, 0x424c, [8]byte{0xb0, 0x29, 0x7f, 0xe9, 0x9a, 0x87, 0xc6, 0x41}}
|
||||||
|
FOLDERID_Startup = &KNOWNFOLDERID{0xb97d20bb, 0xf46a, 0x4c97, [8]byte{0xba, 0x10, 0x5e, 0x36, 0x08, 0x43, 0x08, 0x54}}
|
||||||
|
FOLDERID_Programs = &KNOWNFOLDERID{0xa77f5d77, 0x2e2b, 0x44c3, [8]byte{0xa6, 0xa2, 0xab, 0xa6, 0x01, 0x05, 0x4a, 0x51}}
|
||||||
|
FOLDERID_StartMenu = &KNOWNFOLDERID{0x625b53c3, 0xab48, 0x4ec1, [8]byte{0xba, 0x1f, 0xa1, 0xef, 0x41, 0x46, 0xfc, 0x19}}
|
||||||
|
FOLDERID_Recent = &KNOWNFOLDERID{0xae50c081, 0xebd2, 0x438a, [8]byte{0x86, 0x55, 0x8a, 0x09, 0x2e, 0x34, 0x98, 0x7a}}
|
||||||
|
FOLDERID_SendTo = &KNOWNFOLDERID{0x8983036c, 0x27c0, 0x404b, [8]byte{0x8f, 0x08, 0x10, 0x2d, 0x10, 0xdc, 0xfd, 0x74}}
|
||||||
|
FOLDERID_Documents = &KNOWNFOLDERID{0xfdd39ad0, 0x238f, 0x46af, [8]byte{0xad, 0xb4, 0x6c, 0x85, 0x48, 0x03, 0x69, 0xc7}}
|
||||||
|
FOLDERID_Favorites = &KNOWNFOLDERID{0x1777f761, 0x68ad, 0x4d8a, [8]byte{0x87, 0xbd, 0x30, 0xb7, 0x59, 0xfa, 0x33, 0xdd}}
|
||||||
|
FOLDERID_NetHood = &KNOWNFOLDERID{0xc5abbf53, 0xe17f, 0x4121, [8]byte{0x89, 0x00, 0x86, 0x62, 0x6f, 0xc2, 0xc9, 0x73}}
|
||||||
|
FOLDERID_PrintHood = &KNOWNFOLDERID{0x9274bd8d, 0xcfd1, 0x41c3, [8]byte{0xb3, 0x5e, 0xb1, 0x3f, 0x55, 0xa7, 0x58, 0xf4}}
|
||||||
|
FOLDERID_Templates = &KNOWNFOLDERID{0xa63293e8, 0x664e, 0x48db, [8]byte{0xa0, 0x79, 0xdf, 0x75, 0x9e, 0x05, 0x09, 0xf7}}
|
||||||
|
FOLDERID_CommonStartup = &KNOWNFOLDERID{0x82a5ea35, 0xd9cd, 0x47c5, [8]byte{0x96, 0x29, 0xe1, 0x5d, 0x2f, 0x71, 0x4e, 0x6e}}
|
||||||
|
FOLDERID_CommonPrograms = &KNOWNFOLDERID{0x0139d44e, 0x6afe, 0x49f2, [8]byte{0x86, 0x90, 0x3d, 0xaf, 0xca, 0xe6, 0xff, 0xb8}}
|
||||||
|
FOLDERID_CommonStartMenu = &KNOWNFOLDERID{0xa4115719, 0xd62e, 0x491d, [8]byte{0xaa, 0x7c, 0xe7, 0x4b, 0x8b, 0xe3, 0xb0, 0x67}}
|
||||||
|
FOLDERID_PublicDesktop = &KNOWNFOLDERID{0xc4aa340d, 0xf20f, 0x4863, [8]byte{0xaf, 0xef, 0xf8, 0x7e, 0xf2, 0xe6, 0xba, 0x25}}
|
||||||
|
FOLDERID_ProgramData = &KNOWNFOLDERID{0x62ab5d82, 0xfdc1, 0x4dc3, [8]byte{0xa9, 0xdd, 0x07, 0x0d, 0x1d, 0x49, 0x5d, 0x97}}
|
||||||
|
FOLDERID_CommonTemplates = &KNOWNFOLDERID{0xb94237e7, 0x57ac, 0x4347, [8]byte{0x91, 0x51, 0xb0, 0x8c, 0x6c, 0x32, 0xd1, 0xf7}}
|
||||||
|
FOLDERID_PublicDocuments = &KNOWNFOLDERID{0xed4824af, 0xdce4, 0x45a8, [8]byte{0x81, 0xe2, 0xfc, 0x79, 0x65, 0x08, 0x36, 0x34}}
|
||||||
|
FOLDERID_RoamingAppData = &KNOWNFOLDERID{0x3eb685db, 0x65f9, 0x4cf6, [8]byte{0xa0, 0x3a, 0xe3, 0xef, 0x65, 0x72, 0x9f, 0x3d}}
|
||||||
|
FOLDERID_LocalAppData = &KNOWNFOLDERID{0xf1b32785, 0x6fba, 0x4fcf, [8]byte{0x9d, 0x55, 0x7b, 0x8e, 0x7f, 0x15, 0x70, 0x91}}
|
||||||
|
FOLDERID_LocalAppDataLow = &KNOWNFOLDERID{0xa520a1a4, 0x1780, 0x4ff6, [8]byte{0xbd, 0x18, 0x16, 0x73, 0x43, 0xc5, 0xaf, 0x16}}
|
||||||
|
FOLDERID_InternetCache = &KNOWNFOLDERID{0x352481e8, 0x33be, 0x4251, [8]byte{0xba, 0x85, 0x60, 0x07, 0xca, 0xed, 0xcf, 0x9d}}
|
||||||
|
FOLDERID_Cookies = &KNOWNFOLDERID{0x2b0f765d, 0xc0e9, 0x4171, [8]byte{0x90, 0x8e, 0x08, 0xa6, 0x11, 0xb8, 0x4f, 0xf6}}
|
||||||
|
FOLDERID_History = &KNOWNFOLDERID{0xd9dc8a3b, 0xb784, 0x432e, [8]byte{0xa7, 0x81, 0x5a, 0x11, 0x30, 0xa7, 0x59, 0x63}}
|
||||||
|
FOLDERID_System = &KNOWNFOLDERID{0x1ac14e77, 0x02e7, 0x4e5d, [8]byte{0xb7, 0x44, 0x2e, 0xb1, 0xae, 0x51, 0x98, 0xb7}}
|
||||||
|
FOLDERID_SystemX86 = &KNOWNFOLDERID{0xd65231b0, 0xb2f1, 0x4857, [8]byte{0xa4, 0xce, 0xa8, 0xe7, 0xc6, 0xea, 0x7d, 0x27}}
|
||||||
|
FOLDERID_Windows = &KNOWNFOLDERID{0xf38bf404, 0x1d43, 0x42f2, [8]byte{0x93, 0x05, 0x67, 0xde, 0x0b, 0x28, 0xfc, 0x23}}
|
||||||
|
FOLDERID_Profile = &KNOWNFOLDERID{0x5e6c858f, 0x0e22, 0x4760, [8]byte{0x9a, 0xfe, 0xea, 0x33, 0x17, 0xb6, 0x71, 0x73}}
|
||||||
|
FOLDERID_Pictures = &KNOWNFOLDERID{0x33e28130, 0x4e1e, 0x4676, [8]byte{0x83, 0x5a, 0x98, 0x39, 0x5c, 0x3b, 0xc3, 0xbb}}
|
||||||
|
FOLDERID_ProgramFilesX86 = &KNOWNFOLDERID{0x7c5a40ef, 0xa0fb, 0x4bfc, [8]byte{0x87, 0x4a, 0xc0, 0xf2, 0xe0, 0xb9, 0xfa, 0x8e}}
|
||||||
|
FOLDERID_ProgramFilesCommonX86 = &KNOWNFOLDERID{0xde974d24, 0xd9c6, 0x4d3e, [8]byte{0xbf, 0x91, 0xf4, 0x45, 0x51, 0x20, 0xb9, 0x17}}
|
||||||
|
FOLDERID_ProgramFilesX64 = &KNOWNFOLDERID{0x6d809377, 0x6af0, 0x444b, [8]byte{0x89, 0x57, 0xa3, 0x77, 0x3f, 0x02, 0x20, 0x0e}}
|
||||||
|
FOLDERID_ProgramFilesCommonX64 = &KNOWNFOLDERID{0x6365d5a7, 0x0f0d, 0x45e5, [8]byte{0x87, 0xf6, 0x0d, 0xa5, 0x6b, 0x6a, 0x4f, 0x7d}}
|
||||||
|
FOLDERID_ProgramFiles = &KNOWNFOLDERID{0x905e63b6, 0xc1bf, 0x494e, [8]byte{0xb2, 0x9c, 0x65, 0xb7, 0x32, 0xd3, 0xd2, 0x1a}}
|
||||||
|
FOLDERID_ProgramFilesCommon = &KNOWNFOLDERID{0xf7f1ed05, 0x9f6d, 0x47a2, [8]byte{0xaa, 0xae, 0x29, 0xd3, 0x17, 0xc6, 0xf0, 0x66}}
|
||||||
|
FOLDERID_UserProgramFiles = &KNOWNFOLDERID{0x5cd7aee2, 0x2219, 0x4a67, [8]byte{0xb8, 0x5d, 0x6c, 0x9c, 0xe1, 0x56, 0x60, 0xcb}}
|
||||||
|
FOLDERID_UserProgramFilesCommon = &KNOWNFOLDERID{0xbcbd3057, 0xca5c, 0x4622, [8]byte{0xb4, 0x2d, 0xbc, 0x56, 0xdb, 0x0a, 0xe5, 0x16}}
|
||||||
|
FOLDERID_AdminTools = &KNOWNFOLDERID{0x724ef170, 0xa42d, 0x4fef, [8]byte{0x9f, 0x26, 0xb6, 0x0e, 0x84, 0x6f, 0xba, 0x4f}}
|
||||||
|
FOLDERID_CommonAdminTools = &KNOWNFOLDERID{0xd0384e7d, 0xbac3, 0x4797, [8]byte{0x8f, 0x14, 0xcb, 0xa2, 0x29, 0xb3, 0x92, 0xb5}}
|
||||||
|
FOLDERID_Music = &KNOWNFOLDERID{0x4bd8d571, 0x6d19, 0x48d3, [8]byte{0xbe, 0x97, 0x42, 0x22, 0x20, 0x08, 0x0e, 0x43}}
|
||||||
|
FOLDERID_Videos = &KNOWNFOLDERID{0x18989b1d, 0x99b5, 0x455b, [8]byte{0x84, 0x1c, 0xab, 0x7c, 0x74, 0xe4, 0xdd, 0xfc}}
|
||||||
|
FOLDERID_Ringtones = &KNOWNFOLDERID{0xc870044b, 0xf49e, 0x4126, [8]byte{0xa9, 0xc3, 0xb5, 0x2a, 0x1f, 0xf4, 0x11, 0xe8}}
|
||||||
|
FOLDERID_PublicPictures = &KNOWNFOLDERID{0xb6ebfb86, 0x6907, 0x413c, [8]byte{0x9a, 0xf7, 0x4f, 0xc2, 0xab, 0xf0, 0x7c, 0xc5}}
|
||||||
|
FOLDERID_PublicMusic = &KNOWNFOLDERID{0x3214fab5, 0x9757, 0x4298, [8]byte{0xbb, 0x61, 0x92, 0xa9, 0xde, 0xaa, 0x44, 0xff}}
|
||||||
|
FOLDERID_PublicVideos = &KNOWNFOLDERID{0x2400183a, 0x6185, 0x49fb, [8]byte{0xa2, 0xd8, 0x4a, 0x39, 0x2a, 0x60, 0x2b, 0xa3}}
|
||||||
|
FOLDERID_PublicRingtones = &KNOWNFOLDERID{0xe555ab60, 0x153b, 0x4d17, [8]byte{0x9f, 0x04, 0xa5, 0xfe, 0x99, 0xfc, 0x15, 0xec}}
|
||||||
|
FOLDERID_ResourceDir = &KNOWNFOLDERID{0x8ad10c31, 0x2adb, 0x4296, [8]byte{0xa8, 0xf7, 0xe4, 0x70, 0x12, 0x32, 0xc9, 0x72}}
|
||||||
|
FOLDERID_LocalizedResourcesDir = &KNOWNFOLDERID{0x2a00375e, 0x224c, 0x49de, [8]byte{0xb8, 0xd1, 0x44, 0x0d, 0xf7, 0xef, 0x3d, 0xdc}}
|
||||||
|
FOLDERID_CommonOEMLinks = &KNOWNFOLDERID{0xc1bae2d0, 0x10df, 0x4334, [8]byte{0xbe, 0xdd, 0x7a, 0xa2, 0x0b, 0x22, 0x7a, 0x9d}}
|
||||||
|
FOLDERID_CDBurning = &KNOWNFOLDERID{0x9e52ab10, 0xf80d, 0x49df, [8]byte{0xac, 0xb8, 0x43, 0x30, 0xf5, 0x68, 0x78, 0x55}}
|
||||||
|
FOLDERID_UserProfiles = &KNOWNFOLDERID{0x0762d272, 0xc50a, 0x4bb0, [8]byte{0xa3, 0x82, 0x69, 0x7d, 0xcd, 0x72, 0x9b, 0x80}}
|
||||||
|
FOLDERID_Playlists = &KNOWNFOLDERID{0xde92c1c7, 0x837f, 0x4f69, [8]byte{0xa3, 0xbb, 0x86, 0xe6, 0x31, 0x20, 0x4a, 0x23}}
|
||||||
|
FOLDERID_SamplePlaylists = &KNOWNFOLDERID{0x15ca69b3, 0x30ee, 0x49c1, [8]byte{0xac, 0xe1, 0x6b, 0x5e, 0xc3, 0x72, 0xaf, 0xb5}}
|
||||||
|
FOLDERID_SampleMusic = &KNOWNFOLDERID{0xb250c668, 0xf57d, 0x4ee1, [8]byte{0xa6, 0x3c, 0x29, 0x0e, 0xe7, 0xd1, 0xaa, 0x1f}}
|
||||||
|
FOLDERID_SamplePictures = &KNOWNFOLDERID{0xc4900540, 0x2379, 0x4c75, [8]byte{0x84, 0x4b, 0x64, 0xe6, 0xfa, 0xf8, 0x71, 0x6b}}
|
||||||
|
FOLDERID_SampleVideos = &KNOWNFOLDERID{0x859ead94, 0x2e85, 0x48ad, [8]byte{0xa7, 0x1a, 0x09, 0x69, 0xcb, 0x56, 0xa6, 0xcd}}
|
||||||
|
FOLDERID_PhotoAlbums = &KNOWNFOLDERID{0x69d2cf90, 0xfc33, 0x4fb7, [8]byte{0x9a, 0x0c, 0xeb, 0xb0, 0xf0, 0xfc, 0xb4, 0x3c}}
|
||||||
|
FOLDERID_Public = &KNOWNFOLDERID{0xdfdf76a2, 0xc82a, 0x4d63, [8]byte{0x90, 0x6a, 0x56, 0x44, 0xac, 0x45, 0x73, 0x85}}
|
||||||
|
FOLDERID_ChangeRemovePrograms = &KNOWNFOLDERID{0xdf7266ac, 0x9274, 0x4867, [8]byte{0x8d, 0x55, 0x3b, 0xd6, 0x61, 0xde, 0x87, 0x2d}}
|
||||||
|
FOLDERID_AppUpdates = &KNOWNFOLDERID{0xa305ce99, 0xf527, 0x492b, [8]byte{0x8b, 0x1a, 0x7e, 0x76, 0xfa, 0x98, 0xd6, 0xe4}}
|
||||||
|
FOLDERID_AddNewPrograms = &KNOWNFOLDERID{0xde61d971, 0x5ebc, 0x4f02, [8]byte{0xa3, 0xa9, 0x6c, 0x82, 0x89, 0x5e, 0x5c, 0x04}}
|
||||||
|
FOLDERID_Downloads = &KNOWNFOLDERID{0x374de290, 0x123f, 0x4565, [8]byte{0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b}}
|
||||||
|
FOLDERID_PublicDownloads = &KNOWNFOLDERID{0x3d644c9b, 0x1fb8, 0x4f30, [8]byte{0x9b, 0x45, 0xf6, 0x70, 0x23, 0x5f, 0x79, 0xc0}}
|
||||||
|
FOLDERID_SavedSearches = &KNOWNFOLDERID{0x7d1d3a04, 0xdebb, 0x4115, [8]byte{0x95, 0xcf, 0x2f, 0x29, 0xda, 0x29, 0x20, 0xda}}
|
||||||
|
FOLDERID_QuickLaunch = &KNOWNFOLDERID{0x52a4f021, 0x7b75, 0x48a9, [8]byte{0x9f, 0x6b, 0x4b, 0x87, 0xa2, 0x10, 0xbc, 0x8f}}
|
||||||
|
FOLDERID_Contacts = &KNOWNFOLDERID{0x56784854, 0xc6cb, 0x462b, [8]byte{0x81, 0x69, 0x88, 0xe3, 0x50, 0xac, 0xb8, 0x82}}
|
||||||
|
FOLDERID_SidebarParts = &KNOWNFOLDERID{0xa75d362e, 0x50fc, 0x4fb7, [8]byte{0xac, 0x2c, 0xa8, 0xbe, 0xaa, 0x31, 0x44, 0x93}}
|
||||||
|
FOLDERID_SidebarDefaultParts = &KNOWNFOLDERID{0x7b396e54, 0x9ec5, 0x4300, [8]byte{0xbe, 0x0a, 0x24, 0x82, 0xeb, 0xae, 0x1a, 0x26}}
|
||||||
|
FOLDERID_PublicGameTasks = &KNOWNFOLDERID{0xdebf2536, 0xe1a8, 0x4c59, [8]byte{0xb6, 0xa2, 0x41, 0x45, 0x86, 0x47, 0x6a, 0xea}}
|
||||||
|
FOLDERID_GameTasks = &KNOWNFOLDERID{0x054fae61, 0x4dd8, 0x4787, [8]byte{0x80, 0xb6, 0x09, 0x02, 0x20, 0xc4, 0xb7, 0x00}}
|
||||||
|
FOLDERID_SavedGames = &KNOWNFOLDERID{0x4c5c32ff, 0xbb9d, 0x43b0, [8]byte{0xb5, 0xb4, 0x2d, 0x72, 0xe5, 0x4e, 0xaa, 0xa4}}
|
||||||
|
FOLDERID_Games = &KNOWNFOLDERID{0xcac52c1a, 0xb53d, 0x4edc, [8]byte{0x92, 0xd7, 0x6b, 0x2e, 0x8a, 0xc1, 0x94, 0x34}}
|
||||||
|
FOLDERID_SEARCH_MAPI = &KNOWNFOLDERID{0x98ec0e18, 0x2098, 0x4d44, [8]byte{0x86, 0x44, 0x66, 0x97, 0x93, 0x15, 0xa2, 0x81}}
|
||||||
|
FOLDERID_SEARCH_CSC = &KNOWNFOLDERID{0xee32e446, 0x31ca, 0x4aba, [8]byte{0x81, 0x4f, 0xa5, 0xeb, 0xd2, 0xfd, 0x6d, 0x5e}}
|
||||||
|
FOLDERID_Links = &KNOWNFOLDERID{0xbfb9d5e0, 0xc6a9, 0x404c, [8]byte{0xb2, 0xb2, 0xae, 0x6d, 0xb6, 0xaf, 0x49, 0x68}}
|
||||||
|
FOLDERID_UsersFiles = &KNOWNFOLDERID{0xf3ce0f7c, 0x4901, 0x4acc, [8]byte{0x86, 0x48, 0xd5, 0xd4, 0x4b, 0x04, 0xef, 0x8f}}
|
||||||
|
FOLDERID_UsersLibraries = &KNOWNFOLDERID{0xa302545d, 0xdeff, 0x464b, [8]byte{0xab, 0xe8, 0x61, 0xc8, 0x64, 0x8d, 0x93, 0x9b}}
|
||||||
|
FOLDERID_SearchHome = &KNOWNFOLDERID{0x190337d1, 0xb8ca, 0x4121, [8]byte{0xa6, 0x39, 0x6d, 0x47, 0x2d, 0x16, 0x97, 0x2a}}
|
||||||
|
FOLDERID_OriginalImages = &KNOWNFOLDERID{0x2c36c0aa, 0x5812, 0x4b87, [8]byte{0xbf, 0xd0, 0x4c, 0xd0, 0xdf, 0xb1, 0x9b, 0x39}}
|
||||||
|
FOLDERID_DocumentsLibrary = &KNOWNFOLDERID{0x7b0db17d, 0x9cd2, 0x4a93, [8]byte{0x97, 0x33, 0x46, 0xcc, 0x89, 0x02, 0x2e, 0x7c}}
|
||||||
|
FOLDERID_MusicLibrary = &KNOWNFOLDERID{0x2112ab0a, 0xc86a, 0x4ffe, [8]byte{0xa3, 0x68, 0x0d, 0xe9, 0x6e, 0x47, 0x01, 0x2e}}
|
||||||
|
FOLDERID_PicturesLibrary = &KNOWNFOLDERID{0xa990ae9f, 0xa03b, 0x4e80, [8]byte{0x94, 0xbc, 0x99, 0x12, 0xd7, 0x50, 0x41, 0x04}}
|
||||||
|
FOLDERID_VideosLibrary = &KNOWNFOLDERID{0x491e922f, 0x5643, 0x4af4, [8]byte{0xa7, 0xeb, 0x4e, 0x7a, 0x13, 0x8d, 0x81, 0x74}}
|
||||||
|
FOLDERID_RecordedTVLibrary = &KNOWNFOLDERID{0x1a6fdba2, 0xf42d, 0x4358, [8]byte{0xa7, 0x98, 0xb7, 0x4d, 0x74, 0x59, 0x26, 0xc5}}
|
||||||
|
FOLDERID_HomeGroup = &KNOWNFOLDERID{0x52528a6b, 0xb9e3, 0x4add, [8]byte{0xb6, 0x0d, 0x58, 0x8c, 0x2d, 0xba, 0x84, 0x2d}}
|
||||||
|
FOLDERID_HomeGroupCurrentUser = &KNOWNFOLDERID{0x9b74b6a3, 0x0dfd, 0x4f11, [8]byte{0x9e, 0x78, 0x5f, 0x78, 0x00, 0xf2, 0xe7, 0x72}}
|
||||||
|
FOLDERID_DeviceMetadataStore = &KNOWNFOLDERID{0x5ce4a5e9, 0xe4eb, 0x479d, [8]byte{0xb8, 0x9f, 0x13, 0x0c, 0x02, 0x88, 0x61, 0x55}}
|
||||||
|
FOLDERID_Libraries = &KNOWNFOLDERID{0x1b3ea5dc, 0xb587, 0x4786, [8]byte{0xb4, 0xef, 0xbd, 0x1d, 0xc3, 0x32, 0xae, 0xae}}
|
||||||
|
FOLDERID_PublicLibraries = &KNOWNFOLDERID{0x48daf80b, 0xe6cf, 0x4f4e, [8]byte{0xb8, 0x00, 0x0e, 0x69, 0xd8, 0x4e, 0xe3, 0x84}}
|
||||||
|
FOLDERID_UserPinned = &KNOWNFOLDERID{0x9e3995ab, 0x1f9c, 0x4f13, [8]byte{0xb8, 0x27, 0x48, 0xb2, 0x4b, 0x6c, 0x71, 0x74}}
|
||||||
|
FOLDERID_ImplicitAppShortcuts = &KNOWNFOLDERID{0xbcb5256f, 0x79f6, 0x4cee, [8]byte{0xb7, 0x25, 0xdc, 0x34, 0xe4, 0x02, 0xfd, 0x46}}
|
||||||
|
FOLDERID_AccountPictures = &KNOWNFOLDERID{0x008ca0b1, 0x55b4, 0x4c56, [8]byte{0xb8, 0xa8, 0x4d, 0xe4, 0xb2, 0x99, 0xd3, 0xbe}}
|
||||||
|
FOLDERID_PublicUserTiles = &KNOWNFOLDERID{0x0482af6c, 0x08f1, 0x4c34, [8]byte{0x8c, 0x90, 0xe1, 0x7e, 0xc9, 0x8b, 0x1e, 0x17}}
|
||||||
|
FOLDERID_AppsFolder = &KNOWNFOLDERID{0x1e87508d, 0x89c2, 0x42f0, [8]byte{0x8a, 0x7e, 0x64, 0x5a, 0x0f, 0x50, 0xca, 0x58}}
|
||||||
|
FOLDERID_StartMenuAllPrograms = &KNOWNFOLDERID{0xf26305ef, 0x6948, 0x40b9, [8]byte{0xb2, 0x55, 0x81, 0x45, 0x3d, 0x09, 0xc7, 0x85}}
|
||||||
|
FOLDERID_CommonStartMenuPlaces = &KNOWNFOLDERID{0xa440879f, 0x87a0, 0x4f7d, [8]byte{0xb7, 0x00, 0x02, 0x07, 0xb9, 0x66, 0x19, 0x4a}}
|
||||||
|
FOLDERID_ApplicationShortcuts = &KNOWNFOLDERID{0xa3918781, 0xe5f2, 0x4890, [8]byte{0xb3, 0xd9, 0xa7, 0xe5, 0x43, 0x32, 0x32, 0x8c}}
|
||||||
|
FOLDERID_RoamingTiles = &KNOWNFOLDERID{0x00bcfc5a, 0xed94, 0x4e48, [8]byte{0x96, 0xa1, 0x3f, 0x62, 0x17, 0xf2, 0x19, 0x90}}
|
||||||
|
FOLDERID_RoamedTileImages = &KNOWNFOLDERID{0xaaa8d5a5, 0xf1d6, 0x4259, [8]byte{0xba, 0xa8, 0x78, 0xe7, 0xef, 0x60, 0x83, 0x5e}}
|
||||||
|
FOLDERID_Screenshots = &KNOWNFOLDERID{0xb7bede81, 0xdf94, 0x4682, [8]byte{0xa7, 0xd8, 0x57, 0xa5, 0x26, 0x20, 0xb8, 0x6f}}
|
||||||
|
FOLDERID_CameraRoll = &KNOWNFOLDERID{0xab5fb87b, 0x7ce2, 0x4f83, [8]byte{0x91, 0x5d, 0x55, 0x08, 0x46, 0xc9, 0x53, 0x7b}}
|
||||||
|
FOLDERID_SkyDrive = &KNOWNFOLDERID{0xa52bba46, 0xe9e1, 0x435f, [8]byte{0xb3, 0xd9, 0x28, 0xda, 0xa6, 0x48, 0xc0, 0xf6}}
|
||||||
|
FOLDERID_OneDrive = &KNOWNFOLDERID{0xa52bba46, 0xe9e1, 0x435f, [8]byte{0xb3, 0xd9, 0x28, 0xda, 0xa6, 0x48, 0xc0, 0xf6}}
|
||||||
|
FOLDERID_SkyDriveDocuments = &KNOWNFOLDERID{0x24d89e24, 0x2f19, 0x4534, [8]byte{0x9d, 0xde, 0x6a, 0x66, 0x71, 0xfb, 0xb8, 0xfe}}
|
||||||
|
FOLDERID_SkyDrivePictures = &KNOWNFOLDERID{0x339719b5, 0x8c47, 0x4894, [8]byte{0x94, 0xc2, 0xd8, 0xf7, 0x7a, 0xdd, 0x44, 0xa6}}
|
||||||
|
FOLDERID_SkyDriveMusic = &KNOWNFOLDERID{0xc3f2459e, 0x80d6, 0x45dc, [8]byte{0xbf, 0xef, 0x1f, 0x76, 0x9f, 0x2b, 0xe7, 0x30}}
|
||||||
|
FOLDERID_SkyDriveCameraRoll = &KNOWNFOLDERID{0x767e6811, 0x49cb, 0x4273, [8]byte{0x87, 0xc2, 0x20, 0xf3, 0x55, 0xe1, 0x08, 0x5b}}
|
||||||
|
FOLDERID_SearchHistory = &KNOWNFOLDERID{0x0d4c3db6, 0x03a3, 0x462f, [8]byte{0xa0, 0xe6, 0x08, 0x92, 0x4c, 0x41, 0xb5, 0xd4}}
|
||||||
|
FOLDERID_SearchTemplates = &KNOWNFOLDERID{0x7e636bfe, 0xdfa9, 0x4d5e, [8]byte{0xb4, 0x56, 0xd7, 0xb3, 0x98, 0x51, 0xd8, 0xa9}}
|
||||||
|
FOLDERID_CameraRollLibrary = &KNOWNFOLDERID{0x2b20df75, 0x1eda, 0x4039, [8]byte{0x80, 0x97, 0x38, 0x79, 0x82, 0x27, 0xd5, 0xb7}}
|
||||||
|
FOLDERID_SavedPictures = &KNOWNFOLDERID{0x3b193882, 0xd3ad, 0x4eab, [8]byte{0x96, 0x5a, 0x69, 0x82, 0x9d, 0x1f, 0xb5, 0x9f}}
|
||||||
|
FOLDERID_SavedPicturesLibrary = &KNOWNFOLDERID{0xe25b5812, 0xbe88, 0x4bd9, [8]byte{0x94, 0xb0, 0x29, 0x23, 0x34, 0x77, 0xb6, 0xc3}}
|
||||||
|
FOLDERID_RetailDemo = &KNOWNFOLDERID{0x12d4c69e, 0x24ad, 0x4923, [8]byte{0xbe, 0x19, 0x31, 0x32, 0x1c, 0x43, 0xa7, 0x67}}
|
||||||
|
FOLDERID_Device = &KNOWNFOLDERID{0x1c2ac1dc, 0x4358, 0x4b6c, [8]byte{0x97, 0x33, 0xaf, 0x21, 0x15, 0x65, 0x76, 0xf0}}
|
||||||
|
FOLDERID_DevelopmentFiles = &KNOWNFOLDERID{0xdbe8e08e, 0x3053, 0x4bbc, [8]byte{0xb1, 0x83, 0x2a, 0x7b, 0x2b, 0x19, 0x1e, 0x59}}
|
||||||
|
FOLDERID_Objects3D = &KNOWNFOLDERID{0x31c0dd25, 0x9439, 0x4f12, [8]byte{0xbf, 0x41, 0x7f, 0xf4, 0xed, 0xa3, 0x87, 0x22}}
|
||||||
|
FOLDERID_AppCaptures = &KNOWNFOLDERID{0xedc0fe71, 0x98d8, 0x4f4a, [8]byte{0xb9, 0x20, 0xc8, 0xdc, 0x13, 0x3c, 0xb1, 0x65}}
|
||||||
|
FOLDERID_LocalDocuments = &KNOWNFOLDERID{0xf42ee2d3, 0x909f, 0x4907, [8]byte{0x88, 0x71, 0x4c, 0x22, 0xfc, 0x0b, 0xf7, 0x56}}
|
||||||
|
FOLDERID_LocalPictures = &KNOWNFOLDERID{0x0ddd015d, 0xb06c, 0x45d5, [8]byte{0x8c, 0x4c, 0xf5, 0x97, 0x13, 0x85, 0x46, 0x39}}
|
||||||
|
FOLDERID_LocalVideos = &KNOWNFOLDERID{0x35286a68, 0x3c57, 0x41a1, [8]byte{0xbb, 0xb1, 0x0e, 0xae, 0x73, 0xd7, 0x6c, 0x95}}
|
||||||
|
FOLDERID_LocalMusic = &KNOWNFOLDERID{0xa0c69a99, 0x21c8, 0x4671, [8]byte{0x87, 0x03, 0x79, 0x34, 0x16, 0x2f, 0xcf, 0x1d}}
|
||||||
|
FOLDERID_LocalDownloads = &KNOWNFOLDERID{0x7d83ee9b, 0x2244, 0x4e70, [8]byte{0xb1, 0xf5, 0x53, 0x93, 0x04, 0x2a, 0xf1, 0xe4}}
|
||||||
|
FOLDERID_RecordedCalls = &KNOWNFOLDERID{0x2f8b40c2, 0x83ed, 0x48ee, [8]byte{0xb3, 0x83, 0xa1, 0xf1, 0x57, 0xec, 0x6f, 0x9a}}
|
||||||
|
FOLDERID_AllAppMods = &KNOWNFOLDERID{0x7ad67899, 0x66af, 0x43ba, [8]byte{0x91, 0x56, 0x6a, 0xad, 0x42, 0xe6, 0xc5, 0x96}}
|
||||||
|
FOLDERID_CurrentAppMods = &KNOWNFOLDERID{0x3db40b20, 0x2a30, 0x4dbe, [8]byte{0x91, 0x7e, 0x77, 0x1d, 0xd2, 0x1d, 0xd0, 0x99}}
|
||||||
|
FOLDERID_AppDataDesktop = &KNOWNFOLDERID{0xb2c5e279, 0x7add, 0x439f, [8]byte{0xb2, 0x8c, 0xc4, 0x1f, 0xe1, 0xbb, 0xf6, 0x72}}
|
||||||
|
FOLDERID_AppDataDocuments = &KNOWNFOLDERID{0x7be16610, 0x1f7f, 0x44ac, [8]byte{0xbf, 0xf0, 0x83, 0xe1, 0x5f, 0x2f, 0xfc, 0xa1}}
|
||||||
|
FOLDERID_AppDataFavorites = &KNOWNFOLDERID{0x7cfbefbc, 0xde1f, 0x45aa, [8]byte{0xb8, 0x43, 0xa5, 0x42, 0xac, 0x53, 0x6c, 0xc9}}
|
||||||
|
FOLDERID_AppDataProgramData = &KNOWNFOLDERID{0x559d40a3, 0xa036, 0x40fa, [8]byte{0xaf, 0x61, 0x84, 0xcb, 0x43, 0x0a, 0x4d, 0x34}}
|
||||||
|
)
|
4070
vendor/golang.org/x/sys/windows/zsyscall_windows.go
generated
vendored
Normal file
4070
vendor/golang.org/x/sys/windows/zsyscall_windows.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
8
vendor/modules.txt
vendored
8
vendor/modules.txt
vendored
|
@ -1,18 +1,17 @@
|
||||||
# github.com/d2r2/go-bh1750 v0.0.0-20181222061755-1195122364ab
|
# github.com/d2r2/go-bh1750 v0.0.0-20181222061755-1195122364ab
|
||||||
## explicit
|
## explicit
|
||||||
github.com/d2r2/go-bh1750
|
|
||||||
# github.com/d2r2/go-i2c v0.0.0-20191123181816-73a8a799d6bc
|
# github.com/d2r2/go-i2c v0.0.0-20191123181816-73a8a799d6bc
|
||||||
## explicit
|
## explicit
|
||||||
github.com/d2r2/go-i2c
|
|
||||||
# github.com/d2r2/go-logger v0.0.0-20181221090742-9998a510495e
|
# github.com/d2r2/go-logger v0.0.0-20181221090742-9998a510495e
|
||||||
## explicit
|
## explicit
|
||||||
github.com/d2r2/go-logger
|
|
||||||
# github.com/davecgh/go-spew v1.1.1
|
# github.com/davecgh/go-spew v1.1.1
|
||||||
## explicit
|
## explicit
|
||||||
github.com/davecgh/go-spew/spew
|
|
||||||
# github.com/dietsche/rfsnotify v0.0.0-20200716145600-b37be6e4177f
|
# github.com/dietsche/rfsnotify v0.0.0-20200716145600-b37be6e4177f
|
||||||
## explicit
|
## explicit
|
||||||
github.com/dietsche/rfsnotify
|
github.com/dietsche/rfsnotify
|
||||||
|
# github.com/eiannone/keyboard v0.0.0-20200508000154-caf4b762e807
|
||||||
|
## explicit
|
||||||
|
github.com/eiannone/keyboard
|
||||||
# github.com/fsnotify/fsnotify v1.4.9
|
# github.com/fsnotify/fsnotify v1.4.9
|
||||||
## explicit
|
## explicit
|
||||||
# github.com/gdamore/encoding v1.0.0
|
# github.com/gdamore/encoding v1.0.0
|
||||||
|
@ -81,6 +80,7 @@ github.com/rivo/uniseg
|
||||||
# golang.org/x/sys v0.0.0-20200817155316-9781c653f443
|
# golang.org/x/sys v0.0.0-20200817155316-9781c653f443
|
||||||
golang.org/x/sys/internal/unsafeheader
|
golang.org/x/sys/internal/unsafeheader
|
||||||
golang.org/x/sys/unix
|
golang.org/x/sys/unix
|
||||||
|
golang.org/x/sys/windows
|
||||||
# golang.org/x/text v0.3.2
|
# golang.org/x/text v0.3.2
|
||||||
golang.org/x/text/encoding
|
golang.org/x/text/encoding
|
||||||
golang.org/x/text/encoding/internal/identifier
|
golang.org/x/text/encoding/internal/identifier
|
||||||
|
|
Loading…
Reference in a new issue