#136: Start working on database persistence

This commit is contained in:
TwinProduction
2021-07-12 00:56:30 -04:00
committed by Chris
parent e6335da94f
commit bd1eb7c61b
657 changed files with 2190821 additions and 82 deletions

27
vendor/modernc.org/ccgo/v3/LICENSE generated vendored Normal file
View 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
View 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

File diff suppressed because it is too large Load Diff

39
vendor/modernc.org/ccgo/v3/lib/cover.go generated vendored Normal file
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

568
vendor/modernc.org/ccgo/v3/lib/init.go generated vendored Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
}