Strips existing code. Refactors directory structure and begins
implementation of version 3.0.1.
This commit is contained in:
parent
79847ab3e9
commit
6187b52beb
|
@ -7,4 +7,5 @@
|
||||||
#
|
#
|
||||||
# Please keep the list sorted.
|
# Please keep the list sorted.
|
||||||
|
|
||||||
|
Alan Shreve <alan@inconshreveable.com>
|
||||||
Jim Teeuwen <jimteeuwen at gmail dot com>
|
Jim Teeuwen <jimteeuwen at gmail dot com>
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
// This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
|
|
||||||
// license. Its contents can be found at:
|
|
||||||
// http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
|
|
||||||
package bindata
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
var newline = []byte{'\n'}
|
|
||||||
|
|
||||||
type ByteWriter struct {
|
|
||||||
io.Writer
|
|
||||||
c int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *ByteWriter) Write(p []byte) (n int, err error) {
|
|
||||||
if len(p) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for n = range p {
|
|
||||||
if w.c%12 == 0 {
|
|
||||||
w.Writer.Write(newline)
|
|
||||||
w.c = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Fprintf(w.Writer, "0x%02x,", p[n])
|
|
||||||
w.c++
|
|
||||||
}
|
|
||||||
|
|
||||||
n++
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
// This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
|
|
||||||
// license. Its contents can be found at:
|
|
||||||
// http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
|
|
||||||
package bindata
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
type StringWriter struct {
|
|
||||||
io.Writer
|
|
||||||
c int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *StringWriter) Write(p []byte) (n int, err error) {
|
|
||||||
if len(p) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for n = range p {
|
|
||||||
fmt.Fprintf(w.Writer, "\\x%02x", p[n])
|
|
||||||
w.c++
|
|
||||||
}
|
|
||||||
|
|
||||||
n++
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
39
lib/toc.go
39
lib/toc.go
|
@ -1,39 +0,0 @@
|
||||||
// This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
|
|
||||||
// license. Its contents can be found at:
|
|
||||||
// http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
|
|
||||||
package bindata
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// createTOC writes a table of contents file to the given location.
|
|
||||||
func CreateTOC(dir, pkgname string) error {
|
|
||||||
file := filepath.Join(dir, "bindata-toc.go")
|
|
||||||
code := fmt.Sprintf(`package %s
|
|
||||||
|
|
||||||
// Global Table of Contents map. Generated by go-bindata.
|
|
||||||
// After startup of the program, all generated data files will
|
|
||||||
// put themselves in this map. The key is the full filename, as
|
|
||||||
// supplied to go-bindata.
|
|
||||||
var go_bindata = make(map[string]func() []byte)`, pkgname)
|
|
||||||
|
|
||||||
return ioutil.WriteFile(file, []byte(code), 0600)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteTOCInit writes the TOC init function for a given data file
|
|
||||||
// replacing the prefix in the filename by "", funcname being the translated function name
|
|
||||||
func WriteTOCInit(output io.Writer, filename, prefix, funcname string) {
|
|
||||||
filename = strings.Replace(filename, prefix, "", 1)
|
|
||||||
fmt.Fprintf(output, `
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
go_bindata[%q] = %s
|
|
||||||
}
|
|
||||||
`, filename, funcname)
|
|
||||||
}
|
|
187
lib/translate.go
187
lib/translate.go
|
@ -1,187 +0,0 @@
|
||||||
// This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
|
|
||||||
// license. Its contents can be found at:
|
|
||||||
// http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
|
|
||||||
package bindata
|
|
||||||
|
|
||||||
import (
|
|
||||||
"compress/gzip"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
"unicode"
|
|
||||||
)
|
|
||||||
|
|
||||||
var regFuncName = regexp.MustCompile(`[^a-zA-Z0-9_]`)
|
|
||||||
|
|
||||||
// translate translates the input file to go source code.
|
|
||||||
func Translate(input io.Reader, output io.Writer, pkgname, funcname string, uncompressed, nomemcpy bool) {
|
|
||||||
if nomemcpy {
|
|
||||||
if uncompressed {
|
|
||||||
translate_nomemcpy_uncomp(input, output, pkgname, funcname)
|
|
||||||
} else {
|
|
||||||
translate_nomemcpy_comp(input, output, pkgname, funcname)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if uncompressed {
|
|
||||||
translate_memcpy_uncomp(input, output, pkgname, funcname)
|
|
||||||
} else {
|
|
||||||
translate_memcpy_comp(input, output, pkgname, funcname)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// input -> gzip -> gowriter -> output.
|
|
||||||
func translate_memcpy_comp(input io.Reader, output io.Writer, pkgname, funcname string) {
|
|
||||||
fmt.Fprintf(output, `package %s
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"compress/gzip"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
// %s returns raw, uncompressed file data.
|
|
||||||
func %s() []byte {
|
|
||||||
gz, err := gzip.NewReader(bytes.NewBuffer([]byte{`, pkgname, funcname, funcname)
|
|
||||||
|
|
||||||
gz := gzip.NewWriter(&ByteWriter{Writer: output})
|
|
||||||
io.Copy(gz, input)
|
|
||||||
gz.Close()
|
|
||||||
|
|
||||||
fmt.Fprint(output, `
|
|
||||||
}))
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
panic("Decompression failed: " + err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
var b bytes.Buffer
|
|
||||||
io.Copy(&b, gz)
|
|
||||||
gz.Close()
|
|
||||||
|
|
||||||
return b.Bytes()
|
|
||||||
}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
// input -> gzip -> gowriter -> output.
|
|
||||||
func translate_memcpy_uncomp(input io.Reader, output io.Writer, pkgname, funcname string) {
|
|
||||||
fmt.Fprintf(output, `package %s
|
|
||||||
|
|
||||||
// %s returns raw file data.
|
|
||||||
func %s() []byte {
|
|
||||||
return []byte{`, pkgname, funcname, funcname)
|
|
||||||
|
|
||||||
io.Copy(&ByteWriter{Writer: output}, input)
|
|
||||||
|
|
||||||
fmt.Fprint(output, `
|
|
||||||
}
|
|
||||||
}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
// input -> gzip -> gowriter -> output.
|
|
||||||
func translate_nomemcpy_comp(input io.Reader, output io.Writer, pkgname, funcname string) {
|
|
||||||
fmt.Fprintf(output, `package %s
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"compress/gzip"
|
|
||||||
"io"
|
|
||||||
"reflect"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _%s = "`, pkgname, funcname)
|
|
||||||
|
|
||||||
gz := gzip.NewWriter(&StringWriter{Writer: output})
|
|
||||||
io.Copy(gz, input)
|
|
||||||
gz.Close()
|
|
||||||
|
|
||||||
fmt.Fprintf(output, `"
|
|
||||||
|
|
||||||
// %s returns raw, uncompressed file data.
|
|
||||||
func %s() []byte {
|
|
||||||
var empty [0]byte
|
|
||||||
sx := (*reflect.StringHeader)(unsafe.Pointer(&_%s))
|
|
||||||
b := empty[:]
|
|
||||||
bx := (*reflect.SliceHeader)(unsafe.Pointer(&b))
|
|
||||||
bx.Data = sx.Data
|
|
||||||
bx.Len = len(_%s)
|
|
||||||
bx.Cap = bx.Len
|
|
||||||
|
|
||||||
gz, err := gzip.NewReader(bytes.NewBuffer(b))
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
panic("Decompression failed: " + err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
var buf bytes.Buffer
|
|
||||||
io.Copy(&buf, gz)
|
|
||||||
gz.Close()
|
|
||||||
|
|
||||||
return buf.Bytes()
|
|
||||||
}
|
|
||||||
`, funcname, funcname, funcname, funcname)
|
|
||||||
}
|
|
||||||
|
|
||||||
// input -> gowriter -> output.
|
|
||||||
func translate_nomemcpy_uncomp(input io.Reader, output io.Writer, pkgname, funcname string) {
|
|
||||||
fmt.Fprintf(output, `package %s
|
|
||||||
|
|
||||||
import (
|
|
||||||
"reflect"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _%s = "`, pkgname, funcname)
|
|
||||||
|
|
||||||
io.Copy(&StringWriter{Writer: output}, input)
|
|
||||||
|
|
||||||
fmt.Fprintf(output, `"
|
|
||||||
|
|
||||||
// %s returns raw file data.
|
|
||||||
//
|
|
||||||
// WARNING: The returned byte slice is READ-ONLY.
|
|
||||||
// Attempting to alter the slice contents will yield a runtime panic.
|
|
||||||
func %s() []byte {
|
|
||||||
var empty [0]byte
|
|
||||||
sx := (*reflect.StringHeader)(unsafe.Pointer(&_%s))
|
|
||||||
b := empty[:]
|
|
||||||
bx := (*reflect.SliceHeader)(unsafe.Pointer(&b))
|
|
||||||
bx.Data = sx.Data
|
|
||||||
bx.Len = len(_%s)
|
|
||||||
bx.Cap = bx.Len
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
`, funcname, funcname, funcname, funcname)
|
|
||||||
}
|
|
||||||
|
|
||||||
// safeFuncname creates a safe function name from the input path.
|
|
||||||
func SafeFuncname(in, prefix string) string {
|
|
||||||
name := strings.Replace(in, prefix, "", 1)
|
|
||||||
|
|
||||||
if len(name) == 0 {
|
|
||||||
name = in
|
|
||||||
}
|
|
||||||
|
|
||||||
name = strings.ToLower(name)
|
|
||||||
name = regFuncName.ReplaceAllString(name, "_")
|
|
||||||
|
|
||||||
if unicode.IsDigit(rune(name[0])) {
|
|
||||||
// Identifier can't start with a digit.
|
|
||||||
name = "_" + name
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get rid of "__" instances for niceness.
|
|
||||||
for strings.Index(name, "__") > -1 {
|
|
||||||
name = strings.Replace(name, "__", "_", -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Leading underscore is silly.
|
|
||||||
if name[0] == '_' {
|
|
||||||
name = name[1:]
|
|
||||||
}
|
|
||||||
|
|
||||||
return name
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
// This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
|
|
||||||
// license. Its contents can be found at:
|
|
||||||
// http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
|
|
||||||
package bindata
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"runtime"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
AppName = "bindata"
|
|
||||||
AppVersionMajor = 2
|
|
||||||
AppVersionMinor = 1
|
|
||||||
)
|
|
||||||
|
|
||||||
// revision part of the program version.
|
|
||||||
// This will be set automatically at build time like so:
|
|
||||||
//
|
|
||||||
// go build -ldflags "-X main.AppVersionRev `date -u +%s`"
|
|
||||||
var AppVersionRev string
|
|
||||||
|
|
||||||
func Version() string {
|
|
||||||
if len(AppVersionRev) == 0 {
|
|
||||||
AppVersionRev = "0"
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("%s %d.%d.%s (Go runtime %s).\nCopyright (c) 2010-2013, Jim Teeuwen.",
|
|
||||||
AppName, AppVersionMajor, AppVersionMinor, AppVersionRev, runtime.Version())
|
|
||||||
}
|
|
157
main.go
157
main.go
|
@ -1,157 +0,0 @@
|
||||||
// This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
|
|
||||||
// license. Its contents can be found at:
|
|
||||||
// http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"github.com/jteeuwen/go-bindata/lib"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"unicode"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
pipe = false
|
|
||||||
in = ""
|
|
||||||
out = flag.String("out", "", "Optional path and name of the output file.")
|
|
||||||
pkgname = flag.String("pkg", "main", "Name of the package to generate.")
|
|
||||||
funcname = flag.String("func", "", "Optional name of the function to generate.")
|
|
||||||
prefix = flag.String("prefix", "", "Optional path prefix to strip off map keys and function names.")
|
|
||||||
uncompressed = flag.Bool("uncompressed", false, "The specified resource will /not/ be GZIP compressed when this flag is specified. This alters the generated output code.")
|
|
||||||
nomemcopy = flag.Bool("nomemcopy", false, "Use a .rodata hack to get rid of unnecessary memcopies. Refer to the documentation to see what implications this carries.")
|
|
||||||
tags = flag.String("tags", "", "Optional build tags")
|
|
||||||
toc = flag.Bool("toc", false, "Generate a table of contents for this and other files. The input filepath becomes the map key. This option is only useable in non-pipe mode.")
|
|
||||||
version = flag.Bool("version", false, "Display version information.")
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
parseArgs()
|
|
||||||
|
|
||||||
if pipe {
|
|
||||||
bindata.Translate(os.Stdin, os.Stdout, *pkgname, *funcname, *uncompressed, *nomemcopy)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fs, err := os.Open(in)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "[e] %s\n", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
defer fs.Close()
|
|
||||||
|
|
||||||
fd, err := os.Create(*out)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "[e] %s\n", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
defer fd.Close()
|
|
||||||
|
|
||||||
if *tags != "" {
|
|
||||||
fmt.Fprintf(fd, "// +build %s\n\n", *tags)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Translate binary to Go code.
|
|
||||||
bindata.Translate(fs, fd, *pkgname, *funcname, *uncompressed, *nomemcopy)
|
|
||||||
|
|
||||||
// Append the TOC init function to the end of the output file and
|
|
||||||
// write the `bindata-toc.go` file, if applicable.
|
|
||||||
if *toc {
|
|
||||||
dir, _ := filepath.Split(*out)
|
|
||||||
err := bindata.CreateTOC(dir, *pkgname)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "[e] %s\n", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
bindata.WriteTOCInit(fd, in, *prefix, *funcname)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseArgs processes and verifies commandline arguments.
|
|
||||||
func parseArgs() {
|
|
||||||
flag.Usage = func() {
|
|
||||||
fmt.Printf("Usage: %s [options] <filename>\n\n", os.Args[0])
|
|
||||||
flag.PrintDefaults()
|
|
||||||
}
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
if *version {
|
|
||||||
fmt.Printf("%s\n", bindata.Version())
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
pipe = flag.NArg() == 0
|
|
||||||
|
|
||||||
if !pipe {
|
|
||||||
*prefix, _ = filepath.Abs(filepath.Clean(*prefix))
|
|
||||||
in, _ = filepath.Abs(filepath.Clean(flag.Args()[0]))
|
|
||||||
*out = safeFilename(*out, in)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(*pkgname) == 0 {
|
|
||||||
fmt.Fprintln(os.Stderr, "[w] No package name specified. Using 'main'.")
|
|
||||||
*pkgname = "main"
|
|
||||||
} else {
|
|
||||||
if unicode.IsDigit(rune((*pkgname)[0])) {
|
|
||||||
// Identifier can't start with a digit.
|
|
||||||
*pkgname = "_" + *pkgname
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(*funcname) == 0 {
|
|
||||||
if pipe {
|
|
||||||
// Can't infer from input file name in this mode.
|
|
||||||
fmt.Fprintln(os.Stderr, "[e] No function name specified.")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
*funcname = bindata.SafeFuncname(in, *prefix)
|
|
||||||
fmt.Fprintf(os.Stderr, "[w] No function name specified. Using %s.\n", *funcname)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// safeFilename creates a safe output filename from the given
|
|
||||||
// output and input paths.
|
|
||||||
func safeFilename(out, in string) string {
|
|
||||||
var filename string
|
|
||||||
|
|
||||||
if len(out) == 0 {
|
|
||||||
filename = in + ".go"
|
|
||||||
|
|
||||||
_, err := os.Lstat(filename)
|
|
||||||
if err == nil {
|
|
||||||
// File already exists. Pad name with a sequential number until we
|
|
||||||
// find a name that is available.
|
|
||||||
count := 0
|
|
||||||
|
|
||||||
for {
|
|
||||||
filename = path.Join(out, fmt.Sprintf("%s.%d.go", in, count))
|
|
||||||
_, err = os.Lstat(filename)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
count++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
filename, _ = filepath.Abs(filepath.Clean(out))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure output directory exists while we're here.
|
|
||||||
dir, _ := filepath.Split(filename)
|
|
||||||
_, err := os.Lstat(dir)
|
|
||||||
if err != nil {
|
|
||||||
os.MkdirAll(dir, 0755)
|
|
||||||
}
|
|
||||||
|
|
||||||
return filename
|
|
||||||
}
|
|
7
testdata/bindata-toc.go
vendored
7
testdata/bindata-toc.go
vendored
|
@ -1,7 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
// Global Table of Contents map. Generated by go-bindata.
|
|
||||||
// After startup of the program, all generated data files will
|
|
||||||
// put themselves in this map. The key is the full filename, as
|
|
||||||
// supplied to go-bindata.
|
|
||||||
var go_bindata = make(map[string]func() []byte)
|
|
1849
testdata/memcpy-compressed.go
vendored
1849
testdata/memcpy-compressed.go
vendored
File diff suppressed because it is too large
Load Diff
1832
testdata/memcpy-uncompressed.go
vendored
1832
testdata/memcpy-uncompressed.go
vendored
File diff suppressed because it is too large
Load Diff
1403
testdata/nomemcpy-compressed.go
vendored
1403
testdata/nomemcpy-compressed.go
vendored
File diff suppressed because it is too large
Load Diff
1392
testdata/nomemcpy-uncompressed.go
vendored
1392
testdata/nomemcpy-uncompressed.go
vendored
File diff suppressed because it is too large
Load Diff
1853
testdata/toc.go
vendored
1853
testdata/toc.go
vendored
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user