1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
|
package main
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"runtime"
"strings"
"sync"
"unicode/utf8"
"go/build"
)
// returns truncated 'data' and amount of bytes skipped (for cursor pos adjustment)
func filter_out_shebang(data []byte) ([]byte, int) {
if len(data) > 2 && data[0] == '#' && data[1] == '!' {
newline := bytes.Index(data, []byte("\n"))
if newline != -1 && len(data) > newline+1 {
return data[newline+1:], newline + 1
}
}
return data, 0
}
func file_exists(filename string) bool {
_, err := os.Stat(filename)
if err != nil {
return false
}
return true
}
func char_to_byte_offset(s []byte, offset_c int) (offset_b int) {
for offset_b = 0; offset_c > 0 && offset_b < len(s); offset_b++ {
if utf8.RuneStart(s[offset_b]) {
offset_c--
}
}
return offset_b
}
func xdg_home_dir() string {
xdghome := os.Getenv("XDG_CONFIG_HOME")
if xdghome == "" {
xdghome = filepath.Join(os.Getenv("HOME"), ".config")
}
return xdghome
}
func has_prefix(s, prefix string, ignorecase bool) bool {
if ignorecase {
s = strings.ToLower(s)
prefix = strings.ToLower(prefix)
}
return strings.HasPrefix(s, prefix)
}
//-------------------------------------------------------------------------
// print_backtrace
//
// a nicer backtrace printer than the default one
//-------------------------------------------------------------------------
var g_backtrace_mutex sync.Mutex
func print_backtrace(err interface{}) {
g_backtrace_mutex.Lock()
defer g_backtrace_mutex.Unlock()
fmt.Printf("panic: %v\n", err)
i := 2
for {
pc, file, line, ok := runtime.Caller(i)
if !ok {
break
}
f := runtime.FuncForPC(pc)
fmt.Printf("%d(%s): %s:%d\n", i-1, f.Name(), file, line)
i++
}
fmt.Println("")
}
//-------------------------------------------------------------------------
// File reader goroutine
//
// It's a bad idea to block multiple goroutines on file I/O. Creates many
// threads which fight for HDD. Therefore only single goroutine should read HDD
// at the same time.
//-------------------------------------------------------------------------
type file_read_request struct {
filename string
out chan file_read_response
}
type file_read_response struct {
data []byte
error error
}
type file_reader_type struct {
in chan file_read_request
}
func new_file_reader() *file_reader_type {
this := new(file_reader_type)
this.in = make(chan file_read_request)
go func() {
var rsp file_read_response
for {
req := <-this.in
rsp.data, rsp.error = ioutil.ReadFile(req.filename)
req.out <- rsp
}
}()
return this
}
func (this *file_reader_type) read_file(filename string) ([]byte, error) {
req := file_read_request{
filename,
make(chan file_read_response),
}
this.in <- req
rsp := <-req.out
return rsp.data, rsp.error
}
var file_reader = new_file_reader()
//-------------------------------------------------------------------------
// copy of the build.Context without func fields
//-------------------------------------------------------------------------
type go_build_context struct {
GOARCH string
GOOS string
GOROOT string
GOPATH string
CgoEnabled bool
UseAllFiles bool
Compiler string
BuildTags []string
ReleaseTags []string
InstallSuffix string
}
func pack_build_context(ctx *build.Context) go_build_context {
return go_build_context{
GOARCH: ctx.GOARCH,
GOOS: ctx.GOOS,
GOROOT: ctx.GOROOT,
GOPATH: ctx.GOPATH,
CgoEnabled: ctx.CgoEnabled,
UseAllFiles: ctx.UseAllFiles,
Compiler: ctx.Compiler,
BuildTags: ctx.BuildTags,
ReleaseTags: ctx.ReleaseTags,
InstallSuffix: ctx.InstallSuffix,
}
}
func unpack_build_context(ctx *go_build_context) build.Context {
return build.Context{
GOARCH: ctx.GOARCH,
GOOS: ctx.GOOS,
GOROOT: ctx.GOROOT,
GOPATH: ctx.GOPATH,
CgoEnabled: ctx.CgoEnabled,
UseAllFiles: ctx.UseAllFiles,
Compiler: ctx.Compiler,
BuildTags: ctx.BuildTags,
ReleaseTags: ctx.ReleaseTags,
InstallSuffix: ctx.InstallSuffix,
}
}
|