#136: Start working on database persistence
This commit is contained in:
27
vendor/modernc.org/ccgo/v3/LICENSE
generated
vendored
Normal file
27
vendor/modernc.org/ccgo/v3/LICENSE
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
Copyright (c) 2017 The CCGO Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the names of the authors nor the names of the
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
129
vendor/modernc.org/ccgo/v3/lib/Makefile
generated
vendored
Normal file
129
vendor/modernc.org/ccgo/v3/lib/Makefile
generated
vendored
Normal file
@ -0,0 +1,129 @@
|
||||
# Copyright 2019 The CCGO Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
.PHONY: all bench clean cover cpu editor internalError later mem nuke todo edit devbench
|
||||
|
||||
grep=--include=*.go
|
||||
ngrep='TODOOK\|internalError\|testdata'
|
||||
testlog=testdata/testlog-$(shell echo $$GOOS)-$(shell echo $$GOARCH)-on-$(shell go env GOOS)-$(shell go env GOARCH)
|
||||
|
||||
all:
|
||||
LC_ALL=C make all_log 2>&1 | tee log
|
||||
|
||||
all_log:
|
||||
date
|
||||
go version
|
||||
uname -a
|
||||
./unconvert.sh
|
||||
gofmt -l -s -w *.go
|
||||
GOOS=darwin GOARCH=amd64 go build -o /dev/null
|
||||
GOOS=linux GOARCH=386 go build -o /dev/null
|
||||
GOOS=linux GOARCH=amd64 go build -o /dev/null
|
||||
GOOS=linux GOARCH=arm go build -o /dev/null
|
||||
GOOS=windows GOARCH=386 go build -o /dev/null
|
||||
GOOS=windows GOARCH=amd64 go build -o /dev/null
|
||||
go vet 2>&1 | grep -v $(ngrep) || true
|
||||
golint 2>&1 | grep -v $(ngrep) || true
|
||||
make todo
|
||||
misspell *.go
|
||||
staticcheck | grep -v 'lexer\.go' || true
|
||||
maligned || true
|
||||
grep -n 'files.*, ok' log
|
||||
@grep -n --color=never 'FAIL\|PASS' log
|
||||
@grep -n --color=always 'FAIL' log
|
||||
grep -n --color=always 'nil pointer' log
|
||||
grep -c 'exit status 1' log || true
|
||||
grep -c 'exit status 2' log || true
|
||||
LC_ALL=C date 2>&1 | tee -a log
|
||||
|
||||
test:
|
||||
LC_ALL=C make test_log 2>&1 | tee $(testlog)
|
||||
grep -ni --color=always fail $(testlog) || true
|
||||
|
||||
test_log:
|
||||
go version
|
||||
uname -a
|
||||
go test -v -timeout 24h
|
||||
date | tee -a $(testlog)
|
||||
|
||||
test_linux_amd64:
|
||||
GOOS=linux GOARCH=amd64 make test
|
||||
|
||||
test_linux_386:
|
||||
GOOS=linux GOARCH=386 make test
|
||||
|
||||
test_linux_arm:
|
||||
GOOS=linux GOARCH=arm make test
|
||||
|
||||
test_linux_arm64:
|
||||
GOOS=linux GOARCH=arm64 make test
|
||||
|
||||
test_windows_386:
|
||||
go version | tee %TEMP%\testlog-windows-386
|
||||
go test -v -timeout 24h | tee -a %TEMP%\testlog-windows-386
|
||||
date /T | tee -a %TEMP%\testlog-windows-386
|
||||
time /T | tee -a %TEMP%\testlog-windows-386
|
||||
|
||||
test_windows_amd64:
|
||||
go version | tee %TEMP%\testlog-windows-amd64
|
||||
go test -v -timeout 24h | tee -a %TEMP%\testlog-windows-amd64
|
||||
date /T | tee -a %TEMP%\testlog-windows-amd64
|
||||
time /T | tee -a %TEMP%\testlog-windows-amd64
|
||||
|
||||
build_all_targets:
|
||||
GOOS=darwin GOARCH=amd64 go build -v ./...
|
||||
GOOS=linux GOARCH=386 go build -v ./...
|
||||
GOOS=linux GOARCH=amd64 go build -v ./...
|
||||
GOOS=linux GOARCH=arm go build -v ./...
|
||||
GOOS=linux GOARCH=arm64 go build -v ./...
|
||||
GOOS=windows GOARCH=386 go build -v ./...
|
||||
GOOS=windows GOARCH=amd64 go build -v ./...
|
||||
|
||||
devbench:
|
||||
date 2>&1 | tee log-devbench
|
||||
go test -timeout 24h -dev -run @ -bench . 2>&1 | tee -a log-devbench
|
||||
grep -n 'FAIL\|SKIP' log-devbench || true
|
||||
|
||||
bench:
|
||||
date 2>&1 | tee log-bench
|
||||
go test -timeout 24h -v -run '^[^E]' -bench . 2>&1 | tee -a log-bench
|
||||
grep -n 'FAIL\|SKIP' log-bench || true
|
||||
|
||||
clean:
|
||||
go clean
|
||||
rm -f *~ *.test *.out
|
||||
|
||||
cover:
|
||||
t=$(shell mktemp) ; go test -coverprofile $$t && go tool cover -html $$t && unlink $$t
|
||||
|
||||
cpu: clean
|
||||
go test -run @ -bench . -cpuprofile cpu.out
|
||||
go tool pprof -lines *.test cpu.out
|
||||
|
||||
edit:
|
||||
@touch log
|
||||
@if [ -f "Session.vim" ]; then gvim -S & else gvim -p Makefile *.go & fi
|
||||
|
||||
|
||||
editor:
|
||||
gofmt -l -s -w *.go
|
||||
GO111MODULE=off go build -v -o $(GOPATH)/bin/ccgo modernc.org/ccgo/v3
|
||||
|
||||
later:
|
||||
@grep -n $(grep) LATER * || true
|
||||
@grep -n $(grep) MAYBE * || true
|
||||
|
||||
mem: clean
|
||||
go test -run Mem -mem -memprofile mem.out -timeout 24h
|
||||
go tool pprof -lines -web -alloc_space *.test mem.out
|
||||
|
||||
nuke: clean
|
||||
go clean -i
|
||||
|
||||
todo:
|
||||
@grep -nr $(grep) ^[[:space:]]*_[[:space:]]*=[[:space:]][[:alpha:]][[:alnum:]]* * | grep -v $(ngrep) || true
|
||||
@grep -nr $(grep) 'TODO\|panic' * | grep -v $(ngrep) || true
|
||||
@grep -nr $(grep) BUG * | grep -v $(ngrep) || true
|
||||
@grep -nr $(grep) [^[:alpha:]]println * | grep -v $(ngrep) || true
|
||||
@grep -nir $(grep) 'work.*progress' || true
|
1737
vendor/modernc.org/ccgo/v3/lib/ccgo.go
generated
vendored
Normal file
1737
vendor/modernc.org/ccgo/v3/lib/ccgo.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
39
vendor/modernc.org/ccgo/v3/lib/cover.go
generated
vendored
Normal file
39
vendor/modernc.org/ccgo/v3/lib/cover.go
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright 2020 The CCGO 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 ccgo // import "modernc.org/ccgo/v3/lib"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
coverMap = map[uintptr]struct{}{}
|
||||
)
|
||||
|
||||
func pc2origin(pc uintptr) string {
|
||||
f := runtime.FuncForPC(pc)
|
||||
var fn, fns string
|
||||
var fl int
|
||||
if f != nil {
|
||||
fn, fl = f.FileLine(pc)
|
||||
fns = f.Name()
|
||||
if x := strings.LastIndex(fns, "."); x > 0 {
|
||||
fns = fns[x+1:]
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("%s:%d:%s", fn, fl, fns)
|
||||
}
|
||||
|
||||
func coverReport() string {
|
||||
var a []string
|
||||
for pc := range coverMap {
|
||||
a = append(a, pc2origin(pc))
|
||||
}
|
||||
sort.Strings(a)
|
||||
return strings.Join(a, "\n")
|
||||
}
|
91
vendor/modernc.org/ccgo/v3/lib/design-notes.adoc
generated
vendored
Normal file
91
vendor/modernc.org/ccgo/v3/lib/design-notes.adoc
generated
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
= Design Notes
|
||||
|
||||
== Problems:
|
||||
|
||||
Translating C to Go is harder than it looks.
|
||||
|
||||
Jan says: It's impossible in the general case to turn C char* into Go
|
||||
[]byte. It's possible to do it probably often for concrete C code
|
||||
cases - based also on author's C coding style. The first problem this
|
||||
runs into is that Go does not guarantee that the backing array will
|
||||
keep its address stable due to Go movable stacks. C expects the
|
||||
opposite, a pointer never magically modifies itself, so some code will
|
||||
fail.
|
||||
|
||||
INSERT CODE EXAMPLES ILLUSTRATING THE PROBLEM HERE
|
||||
|
||||
== How the parser works
|
||||
|
||||
There are no comment nodes in the C AST. Instead every cc.Token has a
|
||||
Sep field: https://godoc.org/modernc.org/cc/v3#Token
|
||||
|
||||
It captures, when configured to do so, all white space preceding the
|
||||
token, combined, including comments, if any. So we have all white
|
||||
space/comments information for every token in the AST. A final white
|
||||
space/comment, preceding EOF, is available as field TrailingSeperator
|
||||
in the AST: https://godoc.org/modernc.org/cc/v3#AST.
|
||||
|
||||
To get the lexically first white space/comment for any node, use
|
||||
tokenSeparator():
|
||||
https://gitlab.com/cznic/ccgo/-/blob/6551e2544a758fdc265c8fac71fb2587fb3e1042/v3/go.go#L1476
|
||||
|
||||
The same with a default value is comment():
|
||||
https://gitlab.com/cznic/ccgo/-/blob/6551e2544a758fdc265c8fac71fb2587fb3e1042/v3/go.go#L1467
|
||||
|
||||
== Looking forward
|
||||
|
||||
Eric says: In my visualization of how the translator would work, the
|
||||
output of a ccgo translation of a module at any given time is a file
|
||||
of pseudo-Go code in which some sections may be enclosed by a Unicode
|
||||
bracketing character (presently using the guillemot quotes U+ab and
|
||||
U+bb) meaning "this is not Go yet" that intentionally makes the Go
|
||||
compiler barf. This expresses a color on the AST nodes.
|
||||
|
||||
So, for example, if I'm translating hello.c with a ruleset that does not
|
||||
include print -> fmt.Printf, this:
|
||||
|
||||
---------------------------------------------------------
|
||||
#include <stdio>
|
||||
|
||||
/* an example comment */
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
printf("Hello, World")
|
||||
}
|
||||
---------------------------------------------------------
|
||||
|
||||
becomes this without any explicit rules at all:
|
||||
|
||||
---------------------------------------------------------
|
||||
«#include <stdio>»
|
||||
|
||||
/* an example comment */
|
||||
|
||||
func main
|
||||
{
|
||||
«printf(»"Hello, World"!\n"«)»
|
||||
}
|
||||
---------------------------------------------------------
|
||||
|
||||
Then, when the rule print -> fmt.Printf is added, it becomes
|
||||
|
||||
---------------------------------------------------------
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
/* an example comment */
|
||||
|
||||
func main
|
||||
{
|
||||
fmt.Printf("Hello, World"!\n")
|
||||
}
|
||||
---------------------------------------------------------
|
||||
|
||||
because with that rule the AST node corresponding to the printf
|
||||
call can be translated and colored "Go". This implies an import
|
||||
of fmt. We observe that there are no longer C-colored spans
|
||||
and drop the #includes.
|
||||
|
||||
// end
|
41
vendor/modernc.org/ccgo/v3/lib/dmesg.go
generated
vendored
Normal file
41
vendor/modernc.org/ccgo/v3/lib/dmesg.go
generated
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright 2021 The CCGO 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 ccgo.dmesg
|
||||
|
||||
package ccgo // import "modernc.org/ccgo/v3/lib"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const dmesgs = true
|
||||
|
||||
var (
|
||||
pid = fmt.Sprintf("[%v %v] ", os.Getpid(), filepath.Base(os.Args[0]))
|
||||
logf *os.File
|
||||
)
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
if logf, err = os.OpenFile("/tmp/ccgo.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY|os.O_SYNC, 0644); err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func dmesg(s string, args ...interface{}) {
|
||||
if s == "" {
|
||||
s = strings.Repeat("%v ", len(args))
|
||||
}
|
||||
s = fmt.Sprintf(pid+s, args...)
|
||||
switch {
|
||||
case len(s) != 0 && s[len(s)-1] == '\n':
|
||||
fmt.Fprint(logf, s)
|
||||
default:
|
||||
fmt.Fprintln(logf, s)
|
||||
}
|
||||
}
|
110
vendor/modernc.org/ccgo/v3/lib/etc.go
generated
vendored
Normal file
110
vendor/modernc.org/ccgo/v3/lib/etc.go
generated
vendored
Normal file
@ -0,0 +1,110 @@
|
||||
// Copyright 2020 The CCGO 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 ccgo // import "modernc.org/ccgo/v3/lib"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
|
||||
"modernc.org/cc/v3"
|
||||
)
|
||||
|
||||
var (
|
||||
reservedNames = map[string]bool{
|
||||
"bool": false, // ccgo can use
|
||||
"break": true, // keyword
|
||||
"case": true, // keyword
|
||||
"chan": true, // keyword
|
||||
"const": true, // keyword
|
||||
"continue": true, // keyword
|
||||
"default": true, // keyword
|
||||
"defer": true, // keyword
|
||||
"else": true, // keyword
|
||||
"fallthrough": true, // keyword
|
||||
"false": false, // ccgo can use
|
||||
"float32": false, // ccgo can use
|
||||
"float64": false, // ccgo can use
|
||||
"for": true, // keyword
|
||||
"func": true, // keyword
|
||||
"go": true, // keyword
|
||||
"goto": true, // keyword
|
||||
"if": true, // keyword
|
||||
"import": true, // keyword
|
||||
"init": false, // special name
|
||||
"int16": false, // ccgo can use
|
||||
"int32": false, // ccgo can use
|
||||
"int64": false, // ccgo can use
|
||||
"int8": false, // ccgo can use
|
||||
"interface": true, // keyword
|
||||
"map": true, // keyword
|
||||
"math": false, // package name
|
||||
"nil": false, // ccgo can use
|
||||
"package": true, // keyword
|
||||
"range": true, // keyword
|
||||
"return": true, // keyword
|
||||
"select": true, // keyword
|
||||
"struct": true, // keyword
|
||||
"switch": true, // keyword
|
||||
"true": false, // ccgo can use
|
||||
"type": true, // keyword
|
||||
"types": false, // package name
|
||||
"uint16": false, // ccgo can use
|
||||
"uint32": false, // ccgo can use
|
||||
"uint64": false, // ccgo can use
|
||||
"uint8": false, // ccgo can use
|
||||
"uintptr": false, // ccgo can use
|
||||
"unsafe": false, // package name
|
||||
"var": true, // keyword
|
||||
}
|
||||
|
||||
reservedIds []cc.StringID
|
||||
|
||||
maxInt32 = big.NewInt(math.MaxInt32)
|
||||
maxInt64 = big.NewInt(math.MaxInt64)
|
||||
maxUint32 = big.NewInt(math.MaxUint32)
|
||||
maxUint64 = big.NewInt(0).SetUint64(math.MaxUint64)
|
||||
minInt32 = big.NewInt(math.MinInt32)
|
||||
minInt64 = big.NewInt(math.MinInt64)
|
||||
)
|
||||
|
||||
func init() {
|
||||
for k := range reservedNames {
|
||||
reservedIds = append(reservedIds, cc.String(k))
|
||||
}
|
||||
}
|
||||
|
||||
type scope map[cc.StringID]int32
|
||||
|
||||
func newScope() scope {
|
||||
s := scope{}
|
||||
for _, k := range reservedIds {
|
||||
s[k] = 0
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (s scope) take(t cc.StringID) string {
|
||||
if t == 0 {
|
||||
panic(todo("internal error"))
|
||||
}
|
||||
|
||||
n, ok := s[t]
|
||||
if !ok {
|
||||
s[t] = 0
|
||||
return t.String()
|
||||
}
|
||||
|
||||
for {
|
||||
n++
|
||||
s[t] = n
|
||||
r := fmt.Sprintf("%s%d", t, n)
|
||||
id := cc.String(r)
|
||||
if _, ok := s[id]; !ok {
|
||||
s[id] = 0
|
||||
return r
|
||||
}
|
||||
}
|
||||
}
|
12856
vendor/modernc.org/ccgo/v3/lib/go.go
generated
vendored
Normal file
12856
vendor/modernc.org/ccgo/v3/lib/go.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
568
vendor/modernc.org/ccgo/v3/lib/init.go
generated
vendored
Normal file
568
vendor/modernc.org/ccgo/v3/lib/init.go
generated
vendored
Normal file
@ -0,0 +1,568 @@
|
||||
// Copyright 2020 The CCGO 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 ccgo // import "modernc.org/ccgo/v3/lib"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"modernc.org/cc/v3"
|
||||
)
|
||||
|
||||
func isAggregateTypeOrUnion(t cc.Type) bool {
|
||||
switch t.Kind() {
|
||||
case cc.Struct, cc.Union, cc.Array:
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// 6.7.8 Initialization
|
||||
func (p *project) initializer(f *function, n *cc.Initializer, t cc.Type, sc cc.StorageClass, tld *tld) {
|
||||
lm := map[*cc.Initializer][]cc.StringID{}
|
||||
tm := map[*cc.Initializer][]cc.StringID{}
|
||||
s := p.initializerFlatten(n, lm, tm)
|
||||
sort.Slice(s, func(i, j int) bool {
|
||||
a := s[i]
|
||||
b := s[j]
|
||||
if a.Offset < b.Offset {
|
||||
return true
|
||||
}
|
||||
|
||||
if a.Offset > b.Offset {
|
||||
return false
|
||||
}
|
||||
|
||||
if a.Field == nil || b.Field == nil || !a.Field.IsBitField() || !b.Field.IsBitField() {
|
||||
panic(todo("%v: internal error: %#x, %v: %#x", a.Position(), a.Offset, b.Position(), b.Offset))
|
||||
}
|
||||
|
||||
return a.Field.BitFieldOffset() < b.Field.BitFieldOffset()
|
||||
})
|
||||
p.initializerInner("", 0, f, s, t, sc, tld, nil, lm, tm)
|
||||
}
|
||||
|
||||
func (p *project) initializerInner(tag string, off uintptr, f *function, s []*cc.Initializer, t cc.Type, sc cc.StorageClass, tld *tld, patchField cc.Field, lm, tm map[*cc.Initializer][]cc.StringID) {
|
||||
// 11: The initializer for a scalar shall be a single expression, optionally
|
||||
// enclosed in braces. The initial value of the object is that of the
|
||||
// expression (after conversion); the same type constraints and conversions as
|
||||
// for simple assignment apply, taking the type of the scalar to be the
|
||||
// unqualified version of its declared type.
|
||||
if t.IsScalarType() && len(s) == 1 {
|
||||
p.w("%s%s", tidyComment("", s[0]), tag)
|
||||
switch {
|
||||
case tld != nil && t.Kind() == cc.Ptr && s[0].AssignmentExpression.Operand.Value() == nil:
|
||||
tld.patches = append(tld.patches, initPatch{t, s[0], patchField})
|
||||
p.w(" 0 ")
|
||||
default:
|
||||
p.assignmentExpression(f, s[0].AssignmentExpression, t, exprValue, fOutermost)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 12: The rest of this subclause deals with initializers for objects that have
|
||||
// aggregate or union type.
|
||||
|
||||
k := t.Kind()
|
||||
|
||||
// 13: The initializer for a structure or union object that has automatic
|
||||
// storage duration shall be either an initializer list as described below, or
|
||||
// a single expression that has compatible structure or union type. In the
|
||||
// latter case, the initial value of the object, including unnamed members, is
|
||||
// that of the expression.
|
||||
if sc == cc.Automatic && len(s) == 1 {
|
||||
switch k {
|
||||
case cc.Struct, cc.Union:
|
||||
if compatibleStructOrUnion(t, s[0].AssignmentExpression.Operand.Type()) {
|
||||
p.w("%s%s", tidyComment("", s[0]), tag)
|
||||
p.assignmentExpression(f, s[0].AssignmentExpression, t, exprValue, fOutermost)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if k == cc.Array && len(s) == 1 {
|
||||
et := t.Elem()
|
||||
if dmesgs { //TODO-
|
||||
dmesg("%v: %v", s[0].Position(), et)
|
||||
}
|
||||
switch {
|
||||
case isCharType(et):
|
||||
// 14: An array of character type may be initialized by a character string
|
||||
// literal, optionally enclosed in braces. Successive characters of the
|
||||
// character string literal (including the terminating null character if there
|
||||
// is room or if the array is of unknown size) initialize the elements of the
|
||||
// array.
|
||||
if x, ok := s[0].AssignmentExpression.Operand.Value().(cc.StringValue); ok {
|
||||
p.w("%s%s", tidyComment("", s[0]), tag)
|
||||
str := cc.StringID(x).String()
|
||||
slen := uintptr(len(str)) + 1
|
||||
alen := t.Len()
|
||||
switch {
|
||||
case alen < slen-1:
|
||||
p.w("*(*%s)(unsafe.Pointer(%s))", p.typ(s[0], t), p.stringLiteralString(str[:alen]))
|
||||
case alen < slen:
|
||||
p.w("*(*%s)(unsafe.Pointer(%s))", p.typ(s[0], t), p.stringLiteralString(str))
|
||||
default: // alen >= slen
|
||||
p.w("*(*%s)(unsafe.Pointer(%s))", p.typ(s[0], t), p.stringLiteralString(str+strings.Repeat("\x00", int(alen-slen))))
|
||||
}
|
||||
return
|
||||
}
|
||||
case p.isWCharType(et):
|
||||
// 15: An array with element type compatible with wchar_t may be initialized by
|
||||
// a wide string literal, optionally enclosed in braces. Successive wide
|
||||
// characters of the wide string literal (including the terminating null wide
|
||||
// character if there is room or if the array is of unknown size) initialize
|
||||
// the elements of the array.
|
||||
if x, ok := s[0].AssignmentExpression.Operand.Value().(cc.WideStringValue); ok {
|
||||
p.w("%s%s", tidyComment("", s[0]), tag)
|
||||
str := []rune(cc.StringID(x).String())
|
||||
slen := uintptr(len(str)) + 1
|
||||
alen := t.Len()
|
||||
switch {
|
||||
case alen < slen-1:
|
||||
panic(todo("", p.pos(s[0])))
|
||||
case alen < slen:
|
||||
p.w("*(*%s)(unsafe.Pointer(%s))", p.typ(s[0], t), p.wideStringLiteral(x, 0))
|
||||
default: // alen >= slen
|
||||
p.w("*(*%s)(unsafe.Pointer(%s))", p.typ(s[0], t), p.wideStringLiteral(x, int(alen-slen)))
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 16: Otherwise, the initializer for an object that has aggregate or union
|
||||
// type shall be a brace-enclosed list of initializers for the elements or
|
||||
// named members.
|
||||
switch k {
|
||||
case cc.Array:
|
||||
p.initializerArray(tag, off, f, s, t, sc, tld, lm, tm)
|
||||
case cc.Struct:
|
||||
p.initializerStruct(tag, off, f, s, t, sc, tld, lm, tm)
|
||||
case cc.Union:
|
||||
p.initializerUnion(tag, off, f, s, t, sc, tld, lm, tm)
|
||||
default:
|
||||
panic(todo("%v: internal error: %v %v", s[0].Position(), t, len(s)))
|
||||
}
|
||||
}
|
||||
|
||||
func (p *project) initializerArray(tag string, off uintptr, f *function, s []*cc.Initializer, t cc.Type, sc cc.StorageClass, tld *tld, lm, tm map[*cc.Initializer][]cc.StringID) {
|
||||
if len(s) == 0 {
|
||||
p.w("%s{}", p.typ(nil, t))
|
||||
return
|
||||
}
|
||||
|
||||
et := t.Elem()
|
||||
esz := et.Size()
|
||||
s0 := s[0]
|
||||
p.w("%s%s%s{", initComment(s0, lm), tag, p.typ(s0, t))
|
||||
var a [][]*cc.Initializer
|
||||
for len(s) != 0 {
|
||||
s2, parts, _ := p.initializerArrayElement(off, s, esz)
|
||||
s = s2
|
||||
a = append(a, parts)
|
||||
}
|
||||
mustIndex := uintptr(len(a)) != t.Len()
|
||||
var parts []*cc.Initializer
|
||||
for _, parts = range a {
|
||||
var comma *cc.Token
|
||||
comma = parts[len(parts)-1].TrailingComma()
|
||||
elemOff := parts[0].Offset - off
|
||||
tag = ""
|
||||
if mustIndex {
|
||||
tag = fmt.Sprintf("%d:", elemOff/esz)
|
||||
}
|
||||
p.initializerInner(tag, off+elemOff, f, parts, et, sc, tld, nil, lm, tm)
|
||||
p.preCommaSep(comma)
|
||||
p.w(",")
|
||||
}
|
||||
p.w("%s}", initComment(parts[len(parts)-1], tm))
|
||||
}
|
||||
|
||||
func initComment(n *cc.Initializer, m map[*cc.Initializer][]cc.StringID) string {
|
||||
a := m[n]
|
||||
if len(a) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
m[n] = a[1:]
|
||||
return tidyCommentString(a[0].String())
|
||||
}
|
||||
|
||||
func (p *project) initializerArrayElement(off uintptr, s []*cc.Initializer, elemSize uintptr) (r []*cc.Initializer, parts []*cc.Initializer, isZero bool) {
|
||||
r = s
|
||||
isZero = true
|
||||
valueOff := s[0].Offset - off
|
||||
elemOff := valueOff - valueOff%elemSize
|
||||
nextOff := elemOff + elemSize
|
||||
for len(s) != 0 {
|
||||
if v := s[0]; v.Offset-off < nextOff {
|
||||
s = s[1:]
|
||||
parts = append(parts, v)
|
||||
if !v.AssignmentExpression.Operand.IsZero() {
|
||||
isZero = false
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
return r[len(parts):], parts, isZero
|
||||
}
|
||||
|
||||
func (p *project) initializerStruct(tag string, off uintptr, f *function, s []*cc.Initializer, t cc.Type, sc cc.StorageClass, tld *tld, lm, tm map[*cc.Initializer][]cc.StringID) {
|
||||
if len(s) == 0 {
|
||||
p.w("%s{}", p.typ(nil, t))
|
||||
return
|
||||
}
|
||||
|
||||
if t.HasFlexibleMember() {
|
||||
p.err(s[0], "flexible array members not supported")
|
||||
return
|
||||
}
|
||||
|
||||
p.w("%s%s%s{", initComment(s[0], lm), tag, p.typ(s[0], t))
|
||||
var parts []*cc.Initializer
|
||||
var isZero bool
|
||||
var fld cc.Field
|
||||
for len(s) != 0 {
|
||||
var comma *cc.Token
|
||||
s, fld, parts, isZero = p.initializerStructField(off, s, t)
|
||||
if isZero {
|
||||
continue
|
||||
}
|
||||
|
||||
if fld.Type().IsIncomplete() {
|
||||
panic(todo(""))
|
||||
}
|
||||
|
||||
comma = parts[len(parts)-1].TrailingComma()
|
||||
tag = fmt.Sprintf("%s:", p.fieldName2(parts[0], fld))
|
||||
ft := fld.Type()
|
||||
switch {
|
||||
case fld.IsBitField():
|
||||
first := true
|
||||
for _, v := range parts {
|
||||
if v.AssignmentExpression.Operand.IsZero() {
|
||||
continue
|
||||
}
|
||||
|
||||
if !first {
|
||||
p.w("|")
|
||||
}
|
||||
first = false
|
||||
bitFld := v.Field
|
||||
bft := p.bitFileType(bitFld.BitFieldBlockWidth())
|
||||
p.w("%s%s", tidyComment("", v.AssignmentExpression), tag)
|
||||
tag = ""
|
||||
p.assignmentExpression(f, v.AssignmentExpression, bft, exprValue, fOutermost)
|
||||
p.w("&%#x", uint64(1)<<uint64(bitFld.BitFieldWidth())-1)
|
||||
if o := bitFld.BitFieldOffset(); o != 0 {
|
||||
p.w("<<%d", o)
|
||||
}
|
||||
}
|
||||
default:
|
||||
p.initializerInner(tag, off+fld.Offset(), f, parts, ft, sc, tld, fld, lm, tm)
|
||||
}
|
||||
p.preCommaSep(comma)
|
||||
p.w(",")
|
||||
}
|
||||
p.w("%s}", initComment(parts[len(parts)-1], tm))
|
||||
}
|
||||
|
||||
func (p *project) preCommaSep(comma *cc.Token) {
|
||||
if comma == nil {
|
||||
return
|
||||
}
|
||||
|
||||
p.w("%s", strings.TrimSpace(comma.Sep.String()))
|
||||
}
|
||||
|
||||
func (p *project) initializerStructField(off uintptr, s []*cc.Initializer, t cc.Type) (r []*cc.Initializer, fld cc.Field, parts []*cc.Initializer, isZero bool) {
|
||||
r = s
|
||||
isZero = true
|
||||
valueOff := s[0].Offset
|
||||
nf := t.NumField()
|
||||
nextOff := off + t.Size()
|
||||
bits := false
|
||||
for i := []int{0}; i[0] < nf; i[0]++ {
|
||||
fld2 := t.FieldByIndex(i)
|
||||
if fld2.Name() == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if fld == nil {
|
||||
fld = fld2
|
||||
}
|
||||
if fld2.Offset()+off > valueOff {
|
||||
nextOff = off + fld2.Offset()
|
||||
break
|
||||
}
|
||||
|
||||
if !fld2.IsBitField() {
|
||||
fld = fld2
|
||||
continue
|
||||
}
|
||||
|
||||
fld = fld2.BitFieldBlockFirst()
|
||||
}
|
||||
for len(s) != 0 {
|
||||
if v := s[0]; v.Offset < nextOff || v.Type().Size() == 0 {
|
||||
if v.Field != nil && v.Field.IsBitField() {
|
||||
bits = true
|
||||
}
|
||||
s = s[1:]
|
||||
parts = append(parts, v)
|
||||
if !v.AssignmentExpression.Operand.IsZero() {
|
||||
isZero = false
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
if bits && fld.Name() == 0 {
|
||||
for _, v := range parts {
|
||||
if v.Field != nil && v.Field.Name() != 0 {
|
||||
fld = v.Field
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return r[len(parts):], fld, parts, isZero
|
||||
}
|
||||
|
||||
func (p *project) initializerUnion(tag string, off uintptr, f *function, s []*cc.Initializer, t cc.Type, sc cc.StorageClass, tld *tld, lm, tm map[*cc.Initializer][]cc.StringID) {
|
||||
if len(s) == 0 {
|
||||
p.w("%s{}", p.typ(nil, t))
|
||||
return
|
||||
}
|
||||
|
||||
s0 := s[0]
|
||||
var parts []*cc.Initializer
|
||||
var isZero bool
|
||||
var fld cc.Field
|
||||
s, fld, parts, isZero = p.initializerUnionField(off, s, t)
|
||||
if len(s) != 0 {
|
||||
panic(todo("%v: internal error: %v", s0.Position(), t))
|
||||
}
|
||||
|
||||
if isZero {
|
||||
p.w("%s%s%s{", initComment(s0, lm), tag, p.typ(s0, t))
|
||||
p.w("%s}", initComment(parts[len(parts)-1], tm))
|
||||
return
|
||||
}
|
||||
|
||||
if fld0 := parts[0].FirstDesignatorField(); fld0 != nil && fld0.Index() != 0 {
|
||||
if fld0.IsBitField() || fld.IsBitField() {
|
||||
panic(todo(""))
|
||||
}
|
||||
|
||||
fld := parts[0].Field
|
||||
if fld.IsBitField() {
|
||||
panic(todo(""))
|
||||
}
|
||||
|
||||
// tag: *(*T)(unsafe.Pointer(&struct{f: ft; pad _[n]byte}{f: expr}))
|
||||
p.w("%s *(*%s)(unsafe.Pointer(&struct{f %s", tag, p.typ(s0, t), p.typ(s0, fld.Type()))
|
||||
if pad := t.Size() - fld.Type().Size(); pad != 0 {
|
||||
p.w("; _ [%v]byte", pad)
|
||||
}
|
||||
p.w("}{")
|
||||
p.initializerInner("f:", off+fld.Offset(), f, parts, fld.Type(), sc, tld, fld, lm, tm)
|
||||
p.w("}))")
|
||||
return
|
||||
}
|
||||
|
||||
p.w("%s%s%s{", initComment(s0, lm), tag, p.typ(s0, t))
|
||||
ft := fld.Type()
|
||||
tag = fmt.Sprintf("%s:", p.fieldName2(parts[0], fld))
|
||||
switch {
|
||||
case fld.IsBitField():
|
||||
first := true
|
||||
for _, v := range parts {
|
||||
if v.AssignmentExpression.Operand.IsZero() {
|
||||
continue
|
||||
}
|
||||
|
||||
if !first {
|
||||
p.w("|")
|
||||
}
|
||||
first = false
|
||||
bitFld := v.Field
|
||||
bft := p.bitFileType(bitFld.BitFieldBlockWidth())
|
||||
p.w("%s%s", tidyComment("", v.AssignmentExpression), tag)
|
||||
tag = ""
|
||||
p.assignmentExpression(f, v.AssignmentExpression, bft, exprValue, fOutermost)
|
||||
p.w("&%#x", uint64(1)<<uint64(bitFld.BitFieldWidth())-1)
|
||||
if o := bitFld.BitFieldOffset(); o != 0 {
|
||||
p.w("<<%d", o)
|
||||
}
|
||||
}
|
||||
default:
|
||||
p.initializerInner(tag, off+fld.Offset(), f, parts, ft, sc, tld, fld, lm, tm)
|
||||
}
|
||||
comma := parts[len(parts)-1].TrailingComma()
|
||||
p.preCommaSep(comma)
|
||||
p.w(",")
|
||||
p.w("%s}", initComment(parts[len(parts)-1], tm))
|
||||
}
|
||||
|
||||
func (p *project) initializerUnionField(off uintptr, s []*cc.Initializer, t cc.Type) (r []*cc.Initializer, fld cc.Field, parts []*cc.Initializer, isZero bool) {
|
||||
r = s
|
||||
isZero = true
|
||||
fld = t.FieldByIndex([]int{0})
|
||||
nextOff := off + t.Size()
|
||||
for len(s) != 0 {
|
||||
if v := s[0]; v.Offset < nextOff {
|
||||
s = s[1:]
|
||||
parts = append(parts, v)
|
||||
if !v.AssignmentExpression.Operand.IsZero() {
|
||||
isZero = false
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
return r[len(parts):], fld, parts, isZero
|
||||
}
|
||||
|
||||
func compatibleStructOrUnion(t1, t2 cc.Type) bool {
|
||||
switch t1.Kind() {
|
||||
case cc.Struct:
|
||||
if t2.Kind() != cc.Struct {
|
||||
return false
|
||||
}
|
||||
case cc.Union:
|
||||
if t2.Kind() != cc.Union {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
if tag := t1.Tag(); tag != 0 && t2.Tag() != tag {
|
||||
return false
|
||||
}
|
||||
|
||||
nf := t1.NumField()
|
||||
if t2.NumField() != nf {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := []int{0}; i[0] < nf; i[0]++ {
|
||||
f1 := t1.FieldByIndex(i)
|
||||
f2 := t2.FieldByIndex(i)
|
||||
nm := f1.Name()
|
||||
if f2.Name() != nm {
|
||||
return false
|
||||
}
|
||||
|
||||
ft1 := f1.Type()
|
||||
ft2 := f2.Type()
|
||||
if ft1.Size() != ft2.Size() ||
|
||||
f1.IsBitField() != f2.IsBitField() ||
|
||||
f1.BitFieldOffset() != f2.BitFieldOffset() ||
|
||||
f1.BitFieldWidth() != f2.BitFieldWidth() {
|
||||
return false
|
||||
}
|
||||
|
||||
if !compatibleType(ft1, ft2) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func compatibleType(t1, t2 cc.Type) bool {
|
||||
if t1.Kind() != t2.Kind() {
|
||||
return false
|
||||
}
|
||||
|
||||
switch t1.Kind() {
|
||||
case cc.Array:
|
||||
if t1.Len() != t2.Len() || !compatibleType(t1.Elem(), t2.Elem()) {
|
||||
return false
|
||||
}
|
||||
case cc.Struct, cc.Union:
|
||||
if !compatibleStructOrUnion(t1, t2) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *project) bitFileType(bits int) cc.Type {
|
||||
switch bits {
|
||||
case 8:
|
||||
return p.task.cfg.ABI.Type(cc.UChar)
|
||||
case 16:
|
||||
return p.task.cfg.ABI.Type(cc.UShort)
|
||||
case 32:
|
||||
return p.task.cfg.ABI.Type(cc.UInt)
|
||||
case 64:
|
||||
return p.task.cfg.ABI.Type(cc.ULongLong)
|
||||
default:
|
||||
panic(todo("%v: internal error: %v", bits))
|
||||
}
|
||||
}
|
||||
|
||||
func (p *project) isWCharType(t cc.Type) bool {
|
||||
if t.IsAliasType() {
|
||||
if id := t.AliasDeclarator().Name(); id == idWcharT ||
|
||||
p.task.goos == "windows" && id == idWinWchar {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func isCharType(t cc.Type) bool {
|
||||
switch t.Kind() {
|
||||
case cc.Char, cc.SChar, cc.UChar:
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *project) initializerFlatten(n *cc.Initializer, lm, tm map[*cc.Initializer][]cc.StringID) (s []*cc.Initializer) {
|
||||
switch n.Case {
|
||||
case cc.InitializerExpr: // AssignmentExpression
|
||||
return append(s, n)
|
||||
case cc.InitializerInitList: // '{' InitializerList ',' '}'
|
||||
first := true
|
||||
for list := n.InitializerList; list != nil; list = list.InitializerList {
|
||||
in := list.Initializer
|
||||
k := in
|
||||
if in.Case != cc.InitializerExpr {
|
||||
k = nil
|
||||
}
|
||||
if first {
|
||||
lm[k] = append(lm[k], append(lm[nil], n.Token.Sep)...)
|
||||
if k != nil {
|
||||
delete(lm, nil)
|
||||
}
|
||||
first = false
|
||||
}
|
||||
if list.InitializerList == nil {
|
||||
tm[k] = append([]cc.StringID{n.Token3.Sep}, append(tm[nil], tm[k]...)...)
|
||||
tm[k] = append(tm[k], append(tm[nil], n.Token3.Sep)...)
|
||||
if k != nil {
|
||||
delete(tm, nil)
|
||||
}
|
||||
}
|
||||
s = append(s, p.initializerFlatten(in, lm, tm)...)
|
||||
}
|
||||
return s
|
||||
default:
|
||||
panic(todo("%v: internal error: %v", n.Position(), n.Case))
|
||||
}
|
||||
}
|
9
vendor/modernc.org/ccgo/v3/lib/mem.go
generated
vendored
Normal file
9
vendor/modernc.org/ccgo/v3/lib/mem.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
// Copyright 2020 The CCGO 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 !linux
|
||||
|
||||
package ccgo // import "modernc.org/ccgo/v3/lib"
|
||||
|
||||
var totalRam uint64
|
20
vendor/modernc.org/ccgo/v3/lib/mem_linux.go
generated
vendored
Normal file
20
vendor/modernc.org/ccgo/v3/lib/mem_linux.go
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright 2020 The CCGO 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 ccgo // import "modernc.org/ccgo/v3/lib"
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
var totalRam uint64
|
||||
|
||||
func init() {
|
||||
var si unix.Sysinfo_t
|
||||
if unix.Sysinfo(&si) != nil {
|
||||
return
|
||||
}
|
||||
|
||||
totalRam = uint64(si.Totalram)
|
||||
}
|
11
vendor/modernc.org/ccgo/v3/lib/nodmesg.go
generated
vendored
Normal file
11
vendor/modernc.org/ccgo/v3/lib/nodmesg.go
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright 2020 The Libc 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 !ccgo.dmesg
|
||||
|
||||
package ccgo // import "modernc.org/ccgo/v3/lib"
|
||||
|
||||
const dmesgs = false
|
||||
|
||||
func dmesg(s string, args ...interface{}) {}
|
57
vendor/modernc.org/ccgo/v3/lib/stringer.go
generated
vendored
Normal file
57
vendor/modernc.org/ccgo/v3/lib/stringer.go
generated
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
// Code generated by "stringer -output stringer.go -type=exprMode,opKind"; DO NOT EDIT.
|
||||
|
||||
package ccgo
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[exprAddrOf-1]
|
||||
_ = x[exprBool-2]
|
||||
_ = x[exprCondInit-3]
|
||||
_ = x[exprCondReturn-4]
|
||||
_ = x[exprDecay-5]
|
||||
_ = x[exprFunc-6]
|
||||
_ = x[exprLValue-7]
|
||||
_ = x[exprPSelect-8]
|
||||
_ = x[exprSelect-9]
|
||||
_ = x[exprValue-10]
|
||||
_ = x[exprVoid-11]
|
||||
}
|
||||
|
||||
const _exprMode_name = "exprAddrOfexprBoolexprCondInitexprCondReturnexprDecayexprFuncexprLValueexprPSelectexprSelectexprValueexprVoid"
|
||||
|
||||
var _exprMode_index = [...]uint8{0, 10, 18, 30, 44, 53, 61, 71, 82, 92, 101, 109}
|
||||
|
||||
func (i exprMode) String() string {
|
||||
i -= 1
|
||||
if i < 0 || i >= exprMode(len(_exprMode_index)-1) {
|
||||
return "exprMode(" + strconv.FormatInt(int64(i+1), 10) + ")"
|
||||
}
|
||||
return _exprMode_name[_exprMode_index[i]:_exprMode_index[i+1]]
|
||||
}
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[opNormal-0]
|
||||
_ = x[opArray-1]
|
||||
_ = x[opArrayParameter-2]
|
||||
_ = x[opFunction-3]
|
||||
_ = x[opUnion-4]
|
||||
_ = x[opBitfield-5]
|
||||
_ = x[opStruct-6]
|
||||
}
|
||||
|
||||
const _opKind_name = "opNormalopArrayopArrayParameteropFunctionopUnionopBitfieldopStruct"
|
||||
|
||||
var _opKind_index = [...]uint8{0, 8, 15, 31, 41, 48, 58, 66}
|
||||
|
||||
func (i opKind) String() string {
|
||||
if i < 0 || i >= opKind(len(_opKind_index)-1) {
|
||||
return "opKind(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _opKind_name[_opKind_index[i]:_opKind_index[i+1]]
|
||||
}
|
4
vendor/modernc.org/ccgo/v3/lib/unconvert.sh
generated
vendored
Normal file
4
vendor/modernc.org/ccgo/v3/lib/unconvert.sh
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
until unconvert -fastmath . &> /dev/null
|
||||
do
|
||||
unconvert -fastmath -apply . &> /dev/null
|
||||
done
|
438
vendor/modernc.org/ccgo/v3/lib/util.go
generated
vendored
Normal file
438
vendor/modernc.org/ccgo/v3/lib/util.go
generated
vendored
Normal file
@ -0,0 +1,438 @@
|
||||
// Copyright 2020 The CCGO Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// generator.go helpers
|
||||
|
||||
package ccgo // import "modernc.org/ccgo/v3/lib"
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bufio"
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// CopyFile copies src to dest, preserving permissions and times where/when
|
||||
// possible. If canOverwrite is not nil, it is consulted whether a destination
|
||||
// file can be overwritten. If canOverwrite is nil then destination is
|
||||
// overwritten if permissions allow that, otherwise the function fails.
|
||||
//
|
||||
// Src and dst must be in the slash form.
|
||||
func CopyFile(dst, src string, canOverwrite func(fn string, fi os.FileInfo) bool) (n int64, rerr error) {
|
||||
dst = filepath.FromSlash(dst)
|
||||
dstDir := filepath.Dir(dst)
|
||||
di, err := os.Stat(dstDir)
|
||||
switch {
|
||||
case err != nil:
|
||||
if !os.IsNotExist(err) {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(dstDir, 0770); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
case err == nil:
|
||||
if !di.IsDir() {
|
||||
return 0, fmt.Errorf("cannot create directory, file exists: %s", dst)
|
||||
}
|
||||
}
|
||||
|
||||
src = filepath.FromSlash(src)
|
||||
si, err := os.Stat(src)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if si.IsDir() {
|
||||
return 0, fmt.Errorf("cannot copy a directory: %s", src)
|
||||
}
|
||||
|
||||
di, err = os.Stat(dst)
|
||||
switch {
|
||||
case err != nil && !os.IsNotExist(err):
|
||||
return 0, err
|
||||
case err == nil:
|
||||
if di.IsDir() {
|
||||
return 0, fmt.Errorf("cannot overwite a directory: %s", dst)
|
||||
}
|
||||
|
||||
if canOverwrite != nil && !canOverwrite(dst, di) {
|
||||
return 0, fmt.Errorf("cannot overwite: %s", dst)
|
||||
}
|
||||
}
|
||||
|
||||
s, err := os.Open(src)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
defer s.Close()
|
||||
r := bufio.NewReader(s)
|
||||
|
||||
d, err := os.Create(dst)
|
||||
|
||||
defer func() {
|
||||
if err := d.Close(); err != nil && rerr == nil {
|
||||
rerr = err
|
||||
return
|
||||
}
|
||||
|
||||
if err := os.Chmod(dst, si.Mode()); err != nil && rerr == nil {
|
||||
rerr = err
|
||||
return
|
||||
}
|
||||
|
||||
if err := os.Chtimes(dst, si.ModTime(), si.ModTime()); err != nil && rerr == nil {
|
||||
rerr = err
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
w := bufio.NewWriter(d)
|
||||
|
||||
defer func() {
|
||||
if err := w.Flush(); err != nil && rerr == nil {
|
||||
rerr = err
|
||||
}
|
||||
}()
|
||||
|
||||
return io.Copy(w, r)
|
||||
}
|
||||
|
||||
// MustCopyFile is like CopyFile but it executes Fatal(stackTrace, err) if it fails.
|
||||
func MustCopyFile(stackTrace bool, dst, src string, canOverwrite func(fn string, fi os.FileInfo) bool) int64 {
|
||||
n, err := CopyFile(dst, src, canOverwrite)
|
||||
if err != nil {
|
||||
Fatal(stackTrace, err)
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
// CopyDir recursively copies src to dest, preserving permissions and times
|
||||
// where/when possible. If canOverwrite is not nil, it is consulted whether a
|
||||
// destination file can be overwritten. If canOverwrite is nil then destination
|
||||
// is overwritten if permissions allow that, otherwise the function fails.
|
||||
//
|
||||
// Src and dst must be in the slash form.
|
||||
func CopyDir(dst, src string, canOverwrite func(fn string, fi os.FileInfo) bool) (files int, bytes int64, rerr error) {
|
||||
dst = filepath.FromSlash(dst)
|
||||
src = filepath.FromSlash(src)
|
||||
si, err := os.Stat(src)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
if !si.IsDir() {
|
||||
return 0, 0, fmt.Errorf("cannot copy a file: %s", src)
|
||||
}
|
||||
|
||||
return files, bytes, filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rel, err := filepath.Rel(src, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if info.IsDir() {
|
||||
return os.MkdirAll(filepath.Join(dst, rel), 0770)
|
||||
}
|
||||
|
||||
n, err := CopyFile(filepath.Join(dst, rel), path, canOverwrite)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
files++
|
||||
bytes += n
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// MustCopyDir is like CopyDir, but it executes Fatal(stackTrace, errú if it fails.
|
||||
func MustCopyDir(stackTrace bool, dst, src string, canOverwrite func(fn string, fi os.FileInfo) bool) (files int, bytes int64) {
|
||||
file, bytes, err := CopyDir(dst, src, canOverwrite)
|
||||
if err != nil {
|
||||
Fatal(stackTrace, err)
|
||||
}
|
||||
|
||||
return file, bytes
|
||||
}
|
||||
|
||||
// UntarFile extracts a named tar.gz archive into dst. If canOverwrite is not
|
||||
// nil, it is consulted whether a destination file can be overwritten. If
|
||||
// canOverwrite is nil then destination is overwritten if permissions allow
|
||||
// that, otherwise the function fails.
|
||||
//
|
||||
// Src and dst must be in the slash form.
|
||||
func UntarFile(dst, src string, canOverwrite func(fn string, fi os.FileInfo) bool) error {
|
||||
f, err := os.Open(filepath.FromSlash(src))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
|
||||
return Untar(dst, bufio.NewReader(f), canOverwrite)
|
||||
}
|
||||
|
||||
// MustUntarFile is like UntarFile but it executes Fatal(stackTrace, err) if it fails.
|
||||
func MustUntarFile(stackTrace bool, dst, src string, canOverwrite func(fn string, fi os.FileInfo) bool) {
|
||||
if err := UntarFile(dst, src, canOverwrite); err != nil {
|
||||
Fatal(stackTrace, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Untar extracts a tar.gz archive into dst. If canOverwrite is not nil, it is
|
||||
// consulted whether a destination file can be overwritten. If canOverwrite is
|
||||
// nil then destination is overwritten if permissions allow that, otherwise the
|
||||
// function fails.
|
||||
//
|
||||
// Dst must be in the slash form.
|
||||
func Untar(dst string, r io.Reader, canOverwrite func(fn string, fi os.FileInfo) bool) error {
|
||||
dst = filepath.FromSlash(dst)
|
||||
gr, err := gzip.NewReader(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tr := tar.NewReader(gr)
|
||||
for {
|
||||
hdr, err := tr.Next()
|
||||
if err != nil {
|
||||
if err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
switch hdr.Typeflag {
|
||||
case tar.TypeDir:
|
||||
dir := filepath.Join(dst, hdr.Name)
|
||||
if err = os.MkdirAll(dir, 0770); err != nil {
|
||||
return err
|
||||
}
|
||||
case tar.TypeSymlink, tar.TypeXGlobalHeader:
|
||||
// skip
|
||||
case tar.TypeReg, tar.TypeRegA:
|
||||
dir := filepath.Dir(filepath.Join(dst, hdr.Name))
|
||||
if _, err := os.Stat(dir); err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = os.MkdirAll(dir, 0770); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
fn := filepath.Join(dst, hdr.Name)
|
||||
f, err := os.OpenFile(fn, os.O_CREATE|os.O_WRONLY, os.FileMode(hdr.Mode))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w := bufio.NewWriter(f)
|
||||
if _, err = io.Copy(w, tr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := w.Flush(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := f.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.Chtimes(fn, hdr.AccessTime, hdr.ModTime); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unexpected tar header typeflag %#02x", hdr.Typeflag)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MustUntar is like Untar but it executes Fatal(stackTrace, err) if it fails.
|
||||
func MustUntar(stackTrace bool, dst string, r io.Reader, canOverwrite func(fn string, fi os.FileInfo) bool) {
|
||||
if err := Untar(dst, r, canOverwrite); err != nil {
|
||||
Fatal(stackTrace, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Fatalf prints a formatted message to os.Stderr and performs os.Exit(1). A
|
||||
// stack trace is added if stackTrace is true.
|
||||
func Fatalf(stackTrace bool, s string, args ...interface{}) {
|
||||
if stackTrace {
|
||||
fmt.Fprintf(os.Stderr, "%s\n", debug.Stack())
|
||||
}
|
||||
fmt.Fprintln(os.Stderr, strings.TrimSpace(fmt.Sprintf(s, args...)))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Fatal prints its argumenst to os.Stderr and performs os.Exit(1). A
|
||||
// stack trace is added if stackTrace is true.
|
||||
func Fatal(stackTrace bool, args ...interface{}) {
|
||||
if stackTrace {
|
||||
fmt.Fprintf(os.Stderr, "%s\n", debug.Stack())
|
||||
}
|
||||
fmt.Fprintln(os.Stderr, strings.TrimSpace(fmt.Sprint(args...)))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Mkdirs will create all paths. Paths must be in slash form.
|
||||
func Mkdirs(paths ...string) error {
|
||||
for _, path := range paths {
|
||||
path = filepath.FromSlash(path)
|
||||
if err := os.MkdirAll(path, 0770); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MustMkdirs is like Mkdir but if executes Fatal(stackTrace, err) if it fails.
|
||||
func MustMkdirs(stackTrace bool, paths ...string) {
|
||||
if err := Mkdirs(paths...); err != nil {
|
||||
Fatal(stackTrace, err)
|
||||
}
|
||||
}
|
||||
|
||||
// InDir executes f in dir. Dir must be in slash form.
|
||||
func InDir(dir string, f func() error) (err error) {
|
||||
var cwd string
|
||||
if cwd, err = os.Getwd(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err2 := os.Chdir(cwd); err2 != nil {
|
||||
err = err2
|
||||
}
|
||||
}()
|
||||
|
||||
if err = os.Chdir(filepath.FromSlash(dir)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return f()
|
||||
}
|
||||
|
||||
// MustInDir is like InDir but it executes Fatal(stackTrace, err) if it fails.
|
||||
func MustInDir(stackTrace bool, dir string, f func() error) {
|
||||
if err := InDir(dir, f); err != nil {
|
||||
Fatal(stackTrace, err)
|
||||
}
|
||||
}
|
||||
|
||||
type echoWriter struct {
|
||||
w bytes.Buffer
|
||||
}
|
||||
|
||||
func (w *echoWriter) Write(b []byte) (int, error) {
|
||||
os.Stdout.Write(b)
|
||||
return w.w.Write(b)
|
||||
}
|
||||
|
||||
// Shell echoes and executes cmd with args and returns the combined output if the command.
|
||||
func Shell(cmd string, args ...string) ([]byte, error) {
|
||||
cmd, err := exec.LookPath(cmd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
wd, err := AbsCwd()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmt.Printf("execute %s %q in %s\n", cmd, args, wd)
|
||||
var b echoWriter
|
||||
c := exec.Command(cmd, args...)
|
||||
c.Stdout = &b
|
||||
c.Stderr = &b
|
||||
err = c.Run()
|
||||
return b.w.Bytes(), err
|
||||
}
|
||||
|
||||
// MustShell is like Shell but it executes Fatal(stackTrace, err) if it fails.
|
||||
func MustShell(stackTrace bool, cmd string, args ...string) []byte {
|
||||
b, err := Shell(cmd, args...)
|
||||
if err != nil {
|
||||
Fatalf(stackTrace, "%s\n%s", b, err)
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
// Compile executes Shell with cmd set to "ccgo".
|
||||
func Compile(args ...string) ([]byte, error) { return Shell("ccgo", args...) }
|
||||
|
||||
// MustCompile is like Compile but if executes Fatal(stackTrace, err) if it fails.
|
||||
func MustCompile(stackTrace bool, args ...string) []byte {
|
||||
return MustShell(stackTrace, "ccgo", args...)
|
||||
}
|
||||
|
||||
// AbsCwd returns the absolute working directory.
|
||||
func AbsCwd() (string, error) {
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if wd, err = filepath.Abs(wd); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return wd, nil
|
||||
}
|
||||
|
||||
// MustAbsCwd is like AbsCwd but executes Fatal(stackTrace, err) if it fails.
|
||||
func MustAbsCwd(stackTrace bool) string {
|
||||
s, err := AbsCwd()
|
||||
if err != nil {
|
||||
Fatal(stackTrace, err)
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// Env returns the value of environmental variable key of dflt otherwise.
|
||||
func Env(key, dflt string) string {
|
||||
if s := os.Getenv(key); s != "" {
|
||||
return s
|
||||
}
|
||||
|
||||
return dflt
|
||||
}
|
||||
|
||||
// MustTempDir is like ioutil.TempDir but executes Fatal(stackTrace, err) if it
|
||||
// fails. The returned path is absolute.
|
||||
func MustTempDir(stackTrace bool, dir, name string) string {
|
||||
s, err := ioutil.TempDir(dir, name)
|
||||
if err != nil {
|
||||
Fatal(stackTrace, err)
|
||||
}
|
||||
|
||||
if s, err = filepath.Abs(s); err != nil {
|
||||
Fatal(stackTrace, err)
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
Reference in New Issue
Block a user