summaryrefslogtreecommitdiffstats
path: root/vendor/modernc.org/ccgo/v3/lib/util.go
diff options
context:
space:
mode:
authorWim <wim@42.be>2022-01-31 00:27:37 +0100
committerWim <wim@42.be>2022-03-20 14:57:48 +0100
commite3cafeaf9292f67459ff1d186f68283bfaedf2ae (patch)
treeb69c39620aa91dba695b3b935c6651c0fb37ce75 /vendor/modernc.org/ccgo/v3/lib/util.go
parente7b193788a56ee7cdb02a87a9db0ad6724ef66d5 (diff)
downloadmatterbridge-msglm-e3cafeaf9292f67459ff1d186f68283bfaedf2ae.tar.gz
matterbridge-msglm-e3cafeaf9292f67459ff1d186f68283bfaedf2ae.tar.bz2
matterbridge-msglm-e3cafeaf9292f67459ff1d186f68283bfaedf2ae.zip
Add dependencies/vendor (whatsapp)
Diffstat (limited to 'vendor/modernc.org/ccgo/v3/lib/util.go')
-rw-r--r--vendor/modernc.org/ccgo/v3/lib/util.go458
1 files changed, 458 insertions, 0 deletions
diff --git a/vendor/modernc.org/ccgo/v3/lib/util.go b/vendor/modernc.org/ccgo/v3/lib/util.go
new file mode 100644
index 00000000..f11e439c
--- /dev/null
+++ b/vendor/modernc.org/ccgo/v3/lib/util.go
@@ -0,0 +1,458 @@
+// 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, "%v %s\noutput: %s\nerr: %s", cmd, args, 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...)
+}
+
+// Run is like Compile, but executes in-process.
+func Run(args ...string) ([]byte, error) {
+ var b bytes.Buffer
+ t := NewTask(append([]string{"ccgo"}, args...), &b, &b)
+ err := t.Main()
+ return b.Bytes(), err
+}
+
+// MustRun is like Run but if executes Fatal(stackTrace, err) if it fails.
+func MustRun(stackTrace bool, args ...string) []byte {
+ var b bytes.Buffer
+ args = append([]string{"ccgo"}, args...)
+ t := NewTask(args, &b, &b)
+ if err := t.Main(); err != nil {
+ Fatalf(stackTrace, "%v\noutput: %s\nerr: %s", args, b.Bytes(), err)
+ }
+
+ return b.Bytes()
+}
+
+// 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
+}