pax_global_header00006660000000000000000000000064145363126260014522gustar00rootroot0000000000000052 comment=2c88e7f58ae1ca6f811b818d0d985b4622556532 go-internal-1.12.0/000077500000000000000000000000001453631262600140225ustar00rootroot00000000000000go-internal-1.12.0/.gitattributes000066400000000000000000000005671453631262600167250ustar00rootroot00000000000000# By default, do not attempt to do any end-of-line conversion upon # checkin or checkout. * -text # For specific file-types, force conversion to LF line endings. This # can be overridden below or in a more specific .gitattributes if, for # example, we want to allow a .txt file to contain a CRLF line ending *.go text eol=lf *.txt text eol=lf *.txtar text eol=lf go-internal-1.12.0/.github/000077500000000000000000000000001453631262600153625ustar00rootroot00000000000000go-internal-1.12.0/.github/workflows/000077500000000000000000000000001453631262600174175ustar00rootroot00000000000000go-internal-1.12.0/.github/workflows/test.yml000066400000000000000000000016471453631262600211310ustar00rootroot00000000000000on: push: branches: - master pull_request: branches: - '**' name: Test jobs: test: strategy: fail-fast: false matrix: go-version: - '1.20.x' - '1.21.x' os: - ubuntu-latest - macos-latest - windows-latest runs-on: ${{ matrix.os }} steps: - name: Checkout code uses: actions/checkout@v4 - name: Install Go uses: actions/setup-go@v4 with: go-version: ${{ matrix.go-version }} cache: false # our tests are quick enough - name: Test run: | go test ./... go test -race ./... - name: Tidy if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.21.x' # no need to do this everywhere run: | go mod tidy test -z "$(gofmt -d .)" || (gofmt -d . && false) test -z "$(git status --porcelain)" || (git status; git diff && false) go-internal-1.12.0/LICENSE000066400000000000000000000027071453631262600150350ustar00rootroot00000000000000Copyright (c) 2018 The Go 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 name of Google Inc. nor the names of its 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. go-internal-1.12.0/README.md000066400000000000000000000053711453631262600153070ustar00rootroot00000000000000This repository factors out an opinionated selection of internal packages and functionality from the Go standard library. Currently this consists mostly of packages and testing code from within the Go tool implementation. This repo is [primarily maintained](https://github.com/rogpeppe/go-internal/graphs/contributors) by long-time [Go contributors](https://github.com/golang/go/contributors) who are also currently [maintaining CUE](https://github.com/cue-lang/cue/graphs/contributors) (which is primarily written in Go and which relies upon several of the packages here). Contributions are welcome, but please open an issue for discussion first. ## Packages Included are the following: - dirhash: calculate hashes over directory trees the same way that the Go tool does. - goproxytest: a GOPROXY implementation designed for test use. - gotooltest: Use the Go tool inside test scripts (see testscript below) - imports: list of known architectures and OSs, and support for reading import statements. - modfile: read and write `go.mod` files while preserving formatting and comments. - module: module paths and versions. - par: do work in parallel. - semver: semantic version parsing. - testenv: information on the current testing environment. - testscript: script-based testing based on txtar files - txtar: simple text-based file archives for testing. ### testscript The most popular package here is the [testscript](https://pkg.go.dev/github.com/rogpeppe/go-internal/testscript) package: * Provides a shell-like test environment that is very nicely tuned for testing Go CLI commands. * Extracted from the core Go team's internal testscript package ([cmd/go/internal/script](https://github.com/golang/go/tree/master/src/cmd/go/internal/script)), which is [heavily used](https://github.com/golang/go/tree/master/src/cmd/go/testdata/script) to test the `go` command. * Supports patterns for checking stderr/stdout, command pass/fail assertions, and so on. * Integrates well with `go test`, including coverage support. * Inputs and sample output files can use the simple [txtar](https://pkg.go.dev/golang.org/x/tools/txtar) text archive format, also used by the Go playground. * Allows [automatically updating](https://pkg.go.dev/github.com/rogpeppe/go-internal/testscript#Params) golden files. * Built-in support for Go concepts like build tags. * Accompanied by a [testscript](https://github.com/rogpeppe/go-internal/tree/master/cmd/testscript) command for running standalone scripts with files embedded in txtar format. A nice introduction to using testscripts is this [blog post](https://bitfieldconsulting.com/golang/test-scripts) series. Both testscript and txtar were [originally created](https://github.com/golang/go/commit/5890e25b7ccb2d2249b2f8a02ef5dbc36047868b) by Russ Cox. go-internal-1.12.0/cache/000077500000000000000000000000001453631262600150655ustar00rootroot00000000000000go-internal-1.12.0/cache/cache.go000066400000000000000000000437441453631262600164730ustar00rootroot00000000000000// Copyright 2017 The Go 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 cache implements a build artifact cache. package cache import ( "bytes" "crypto/sha256" "encoding/hex" "errors" "fmt" "io" "io/fs" "os" "path/filepath" "strconv" "strings" "time" "github.com/rogpeppe/go-internal/lockedfile" ) // An ActionID is a cache action key, the hash of a complete description of a // repeatable computation (command line, environment variables, // input file contents, executable contents). type ActionID [HashSize]byte // An OutputID is a cache output key, the hash of an output of a computation. type OutputID [HashSize]byte // A Cache is a package cache, backed by a file system directory tree. type Cache struct { dir string now func() time.Time } // Open opens and returns the cache in the given directory. // // It is safe for multiple processes on a single machine to use the // same cache directory in a local file system simultaneously. // They will coordinate using operating system file locks and may // duplicate effort but will not corrupt the cache. // // However, it is NOT safe for multiple processes on different machines // to share a cache directory (for example, if the directory were stored // in a network file system). File locking is notoriously unreliable in // network file systems and may not suffice to protect the cache. func Open(dir string) (*Cache, error) { info, err := os.Stat(dir) if err != nil { return nil, err } if !info.IsDir() { return nil, &fs.PathError{Op: "open", Path: dir, Err: fmt.Errorf("not a directory")} } for i := 0; i < 256; i++ { name := filepath.Join(dir, fmt.Sprintf("%02x", i)) if err := os.MkdirAll(name, 0777); err != nil { return nil, err } } c := &Cache{ dir: dir, now: time.Now, } return c, nil } // fileName returns the name of the file corresponding to the given id. func (c *Cache) fileName(id [HashSize]byte, key string) string { return filepath.Join(c.dir, fmt.Sprintf("%02x", id[0]), fmt.Sprintf("%x", id)+"-"+key) } // An entryNotFoundError indicates that a cache entry was not found, with an // optional underlying reason. type entryNotFoundError struct { Err error } func (e *entryNotFoundError) Error() string { if e.Err == nil { return "cache entry not found" } return fmt.Sprintf("cache entry not found: %v", e.Err) } func (e *entryNotFoundError) Unwrap() error { return e.Err } const ( // action entry file is "v1 \n" hexSize = HashSize * 2 entrySize = 2 + 1 + hexSize + 1 + hexSize + 1 + 20 + 1 + 20 + 1 ) // verify controls whether to run the cache in verify mode. // In verify mode, the cache always returns errMissing from Get // but then double-checks in Put that the data being written // exactly matches any existing entry. This provides an easy // way to detect program behavior that would have been different // had the cache entry been returned from Get. // // verify is enabled by setting the environment variable // GODEBUG=gocacheverify=1. var verify = false var errVerifyMode = errors.New("gocacheverify=1") // DebugTest is set when GODEBUG=gocachetest=1 is in the environment. var DebugTest = false func init() { initEnv() } func initEnv() { verify = false debugHash = false debug := strings.Split(os.Getenv("GODEBUG"), ",") for _, f := range debug { if f == "gocacheverify=1" { verify = true } if f == "gocachehash=1" { debugHash = true } if f == "gocachetest=1" { DebugTest = true } } } // Get looks up the action ID in the cache, // returning the corresponding output ID and file size, if any. // Note that finding an output ID does not guarantee that the // saved file for that output ID is still available. func (c *Cache) Get(id ActionID) (Entry, error) { if verify { return Entry{}, &entryNotFoundError{Err: errVerifyMode} } return c.get(id) } type Entry struct { OutputID OutputID Size int64 Time time.Time } // get is Get but does not respect verify mode, so that Put can use it. func (c *Cache) get(id ActionID) (Entry, error) { missing := func(reason error) (Entry, error) { return Entry{}, &entryNotFoundError{Err: reason} } f, err := os.Open(c.fileName(id, "a")) if err != nil { return missing(err) } defer f.Close() entry := make([]byte, entrySize+1) // +1 to detect whether f is too long if n, err := io.ReadFull(f, entry); n > entrySize { return missing(errors.New("too long")) } else if err != io.ErrUnexpectedEOF { if err == io.EOF { return missing(errors.New("file is empty")) } return missing(err) } else if n < entrySize { return missing(errors.New("entry file incomplete")) } if entry[0] != 'v' || entry[1] != '1' || entry[2] != ' ' || entry[3+hexSize] != ' ' || entry[3+hexSize+1+hexSize] != ' ' || entry[3+hexSize+1+hexSize+1+20] != ' ' || entry[entrySize-1] != '\n' { return missing(errors.New("invalid header")) } eid, entry := entry[3:3+hexSize], entry[3+hexSize:] eout, entry := entry[1:1+hexSize], entry[1+hexSize:] esize, entry := entry[1:1+20], entry[1+20:] etime, entry := entry[1:1+20], entry[1+20:] var buf [HashSize]byte if _, err := hex.Decode(buf[:], eid); err != nil { return missing(fmt.Errorf("decoding ID: %v", err)) } else if buf != id { return missing(errors.New("mismatched ID")) } if _, err := hex.Decode(buf[:], eout); err != nil { return missing(fmt.Errorf("decoding output ID: %v", err)) } i := 0 for i < len(esize) && esize[i] == ' ' { i++ } size, err := strconv.ParseInt(string(esize[i:]), 10, 64) if err != nil { return missing(fmt.Errorf("parsing size: %v", err)) } else if size < 0 { return missing(errors.New("negative size")) } i = 0 for i < len(etime) && etime[i] == ' ' { i++ } tm, err := strconv.ParseInt(string(etime[i:]), 10, 64) if err != nil { return missing(fmt.Errorf("parsing timestamp: %v", err)) } else if tm < 0 { return missing(errors.New("negative timestamp")) } c.used(c.fileName(id, "a")) return Entry{buf, size, time.Unix(0, tm)}, nil } // GetFile looks up the action ID in the cache and returns // the name of the corresponding data file. func (c *Cache) GetFile(id ActionID) (file string, entry Entry, err error) { entry, err = c.Get(id) if err != nil { return "", Entry{}, err } file = c.OutputFile(entry.OutputID) info, err := os.Stat(file) if err != nil { return "", Entry{}, &entryNotFoundError{Err: err} } if info.Size() != entry.Size { return "", Entry{}, &entryNotFoundError{Err: errors.New("file incomplete")} } return file, entry, nil } // GetBytes looks up the action ID in the cache and returns // the corresponding output bytes. // GetBytes should only be used for data that can be expected to fit in memory. func (c *Cache) GetBytes(id ActionID) ([]byte, Entry, error) { entry, err := c.Get(id) if err != nil { return nil, entry, err } data, _ := os.ReadFile(c.OutputFile(entry.OutputID)) if sha256.Sum256(data) != entry.OutputID { return nil, entry, &entryNotFoundError{Err: errors.New("bad checksum")} } return data, entry, nil } /* TODO: consider copying cmd/go/internal/mmap over for this method // GetMmap looks up the action ID in the cache and returns // the corresponding output bytes. // GetMmap should only be used for data that can be expected to fit in memory. func (c *Cache) GetMmap(id ActionID) ([]byte, Entry, error) { entry, err := c.Get(id) if err != nil { return nil, entry, err } md, err := mmap.Mmap(c.OutputFile(entry.OutputID)) if err != nil { return nil, Entry{}, err } if int64(len(md.Data)) != entry.Size { return nil, Entry{}, &entryNotFoundError{Err: errors.New("file incomplete")} } return md.Data, entry, nil } */ // OutputFile returns the name of the cache file storing output with the given OutputID. func (c *Cache) OutputFile(out OutputID) string { file := c.fileName(out, "d") c.used(file) return file } // Time constants for cache expiration. // // We set the mtime on a cache file on each use, but at most one per mtimeInterval (1 hour), // to avoid causing many unnecessary inode updates. The mtimes therefore // roughly reflect "time of last use" but may in fact be older by at most an hour. // // We scan the cache for entries to delete at most once per trimInterval (1 day). // // When we do scan the cache, we delete entries that have not been used for // at least trimLimit (5 days). Statistics gathered from a month of usage by // Go developers found that essentially all reuse of cached entries happened // within 5 days of the previous reuse. See golang.org/issue/22990. const ( mtimeInterval = 1 * time.Hour trimInterval = 24 * time.Hour trimLimit = 5 * 24 * time.Hour ) // used makes a best-effort attempt to update mtime on file, // so that mtime reflects cache access time. // // Because the reflection only needs to be approximate, // and to reduce the amount of disk activity caused by using // cache entries, used only updates the mtime if the current // mtime is more than an hour old. This heuristic eliminates // nearly all of the mtime updates that would otherwise happen, // while still keeping the mtimes useful for cache trimming. func (c *Cache) used(file string) { info, err := os.Stat(file) if err == nil && c.now().Sub(info.ModTime()) < mtimeInterval { return } os.Chtimes(file, c.now(), c.now()) } // Trim removes old cache entries that are likely not to be reused. func (c *Cache) Trim() error { now := c.now() // We maintain in dir/trim.txt the time of the last completed cache trim. // If the cache has been trimmed recently enough, do nothing. // This is the common case. // If the trim file is corrupt, detected if the file can't be parsed, or the // trim time is too far in the future, attempt the trim anyway. It's possible that // the cache was full when the corruption happened. Attempting a trim on // an empty cache is cheap, so there wouldn't be a big performance hit in that case. if data, err := lockedfile.Read(filepath.Join(c.dir, "trim.txt")); err == nil { if t, err := strconv.ParseInt(strings.TrimSpace(string(data)), 10, 64); err == nil { lastTrim := time.Unix(t, 0) if d := now.Sub(lastTrim); d < trimInterval && d > -mtimeInterval { return nil } } } // Trim each of the 256 subdirectories. // We subtract an additional mtimeInterval // to account for the imprecision of our "last used" mtimes. cutoff := now.Add(-trimLimit - mtimeInterval) for i := 0; i < 256; i++ { subdir := filepath.Join(c.dir, fmt.Sprintf("%02x", i)) c.trimSubdir(subdir, cutoff) } // Ignore errors from here: if we don't write the complete timestamp, the // cache will appear older than it is, and we'll trim it again next time. var b bytes.Buffer fmt.Fprintf(&b, "%d", now.Unix()) if err := lockedfile.Write(filepath.Join(c.dir, "trim.txt"), &b, 0666); err != nil { return err } return nil } // trimSubdir trims a single cache subdirectory. func (c *Cache) trimSubdir(subdir string, cutoff time.Time) { // Read all directory entries from subdir before removing // any files, in case removing files invalidates the file offset // in the directory scan. Also, ignore error from f.Readdirnames, // because we don't care about reporting the error and we still // want to process any entries found before the error. f, err := os.Open(subdir) if err != nil { return } names, _ := f.Readdirnames(-1) f.Close() for _, name := range names { // Remove only cache entries (xxxx-a and xxxx-d). if !strings.HasSuffix(name, "-a") && !strings.HasSuffix(name, "-d") { continue } entry := filepath.Join(subdir, name) info, err := os.Stat(entry) if err == nil && info.ModTime().Before(cutoff) { os.Remove(entry) } } } // putIndexEntry adds an entry to the cache recording that executing the action // with the given id produces an output with the given output id (hash) and size. func (c *Cache) putIndexEntry(id ActionID, out OutputID, size int64, allowVerify bool) error { // Note: We expect that for one reason or another it may happen // that repeating an action produces a different output hash // (for example, if the output contains a time stamp or temp dir name). // While not ideal, this is also not a correctness problem, so we // don't make a big deal about it. In particular, we leave the action // cache entries writable specifically so that they can be overwritten. // // Setting GODEBUG=gocacheverify=1 does make a big deal: // in verify mode we are double-checking that the cache entries // are entirely reproducible. As just noted, this may be unrealistic // in some cases but the check is also useful for shaking out real bugs. entry := fmt.Sprintf("v1 %x %x %20d %20d\n", id, out, size, time.Now().UnixNano()) if verify && allowVerify { old, err := c.get(id) if err == nil && (old.OutputID != out || old.Size != size) { // panic to show stack trace, so we can see what code is generating this cache entry. msg := fmt.Sprintf("go: internal cache error: cache verify failed: id=%x changed:<<<\n%s\n>>>\nold: %x %d\nnew: %x %d", id, reverseHash(id), out, size, old.OutputID, old.Size) panic(msg) } } file := c.fileName(id, "a") // Copy file to cache directory. mode := os.O_WRONLY | os.O_CREATE f, err := os.OpenFile(file, mode, 0666) if err != nil { return err } _, err = f.WriteString(entry) if err == nil { // Truncate the file only *after* writing it. // (This should be a no-op, but truncate just in case of previous corruption.) // // This differs from os.WriteFile, which truncates to 0 *before* writing // via os.O_TRUNC. Truncating only after writing ensures that a second write // of the same content to the same file is idempotent, and does not — even // temporarily! — undo the effect of the first write. err = f.Truncate(int64(len(entry))) } if closeErr := f.Close(); err == nil { err = closeErr } if err != nil { // TODO(bcmills): This Remove potentially races with another go command writing to file. // Can we eliminate it? os.Remove(file) return err } os.Chtimes(file, c.now(), c.now()) // mainly for tests return nil } // Put stores the given output in the cache as the output for the action ID. // It may read file twice. The content of file must not change between the two passes. func (c *Cache) Put(id ActionID, file io.ReadSeeker) (OutputID, int64, error) { return c.put(id, file, true) } // PutNoVerify is like Put but disables the verify check // when GODEBUG=goverifycache=1 is set. // It is meant for data that is OK to cache but that we expect to vary slightly from run to run, // like test output containing times and the like. func (c *Cache) PutNoVerify(id ActionID, file io.ReadSeeker) (OutputID, int64, error) { return c.put(id, file, false) } func (c *Cache) put(id ActionID, file io.ReadSeeker, allowVerify bool) (OutputID, int64, error) { // Compute output ID. h := sha256.New() if _, err := file.Seek(0, 0); err != nil { return OutputID{}, 0, err } size, err := io.Copy(h, file) if err != nil { return OutputID{}, 0, err } var out OutputID h.Sum(out[:0]) // Copy to cached output file (if not already present). if err := c.copyFile(file, out, size); err != nil { return out, size, err } // Add to cache index. return out, size, c.putIndexEntry(id, out, size, allowVerify) } // PutBytes stores the given bytes in the cache as the output for the action ID. func (c *Cache) PutBytes(id ActionID, data []byte) error { _, _, err := c.Put(id, bytes.NewReader(data)) return err } // copyFile copies file into the cache, expecting it to have the given // output ID and size, if that file is not present already. func (c *Cache) copyFile(file io.ReadSeeker, out OutputID, size int64) error { name := c.fileName(out, "d") info, err := os.Stat(name) if err == nil && info.Size() == size { // Check hash. if f, err := os.Open(name); err == nil { h := sha256.New() io.Copy(h, f) f.Close() var out2 OutputID h.Sum(out2[:0]) if out == out2 { return nil } } // Hash did not match. Fall through and rewrite file. } // Copy file to cache directory. mode := os.O_RDWR | os.O_CREATE if err == nil && info.Size() > size { // shouldn't happen but fix in case mode |= os.O_TRUNC } f, err := os.OpenFile(name, mode, 0666) if err != nil { return err } defer f.Close() if size == 0 { // File now exists with correct size. // Only one possible zero-length file, so contents are OK too. // Early return here makes sure there's a "last byte" for code below. return nil } // From here on, if any of the I/O writing the file fails, // we make a best-effort attempt to truncate the file f // before returning, to avoid leaving bad bytes in the file. // Copy file to f, but also into h to double-check hash. if _, err := file.Seek(0, 0); err != nil { f.Truncate(0) return err } h := sha256.New() w := io.MultiWriter(f, h) if _, err := io.CopyN(w, file, size-1); err != nil { f.Truncate(0) return err } // Check last byte before writing it; writing it will make the size match // what other processes expect to find and might cause them to start // using the file. buf := make([]byte, 1) if _, err := file.Read(buf); err != nil { f.Truncate(0) return err } h.Write(buf) sum := h.Sum(nil) if !bytes.Equal(sum, out[:]) { f.Truncate(0) return fmt.Errorf("file content changed underfoot") } // Commit cache file entry. if _, err := f.Write(buf); err != nil { f.Truncate(0) return err } if err := f.Close(); err != nil { // Data might not have been written, // but file may look like it is the right size. // To be extra careful, remove cached file. os.Remove(name) return err } os.Chtimes(name, c.now(), c.now()) // mainly for tests return nil } // FuzzDir returns a subdirectory within the cache for storing fuzzing data. // The subdirectory may not exist. // // This directory is managed by the internal/fuzz package. Files in this // directory aren't removed by the 'go clean -cache' command or by Trim. // They may be removed with 'go clean -fuzzcache'. // // TODO(#48526): make Trim remove unused files from this directory. func (c *Cache) FuzzDir() string { return filepath.Join(c.dir, "fuzz") } go-internal-1.12.0/cache/cache_test.go000066400000000000000000000165551453631262600175320ustar00rootroot00000000000000// Copyright 2017 The Go 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 cache import ( "bytes" "encoding/binary" "fmt" "os" "path/filepath" "testing" "time" ) func init() { verify = false // even if GODEBUG is set } func TestBasic(t *testing.T) { dir, err := os.MkdirTemp("", "cachetest-") if err != nil { t.Fatal(err) } defer os.RemoveAll(dir) _, err = Open(filepath.Join(dir, "notexist")) if err == nil { t.Fatal(`Open("tmp/notexist") succeeded, want failure`) } cdir := filepath.Join(dir, "c1") if err := os.Mkdir(cdir, 0777); err != nil { t.Fatal(err) } c1, err := Open(cdir) if err != nil { t.Fatalf("Open(c1) (create): %v", err) } if err := c1.putIndexEntry(dummyID(1), dummyID(12), 13, true); err != nil { t.Fatalf("addIndexEntry: %v", err) } if err := c1.putIndexEntry(dummyID(1), dummyID(2), 3, true); err != nil { // overwrite entry t.Fatalf("addIndexEntry: %v", err) } if entry, err := c1.Get(dummyID(1)); err != nil || entry.OutputID != dummyID(2) || entry.Size != 3 { t.Fatalf("c1.Get(1) = %x, %v, %v, want %x, %v, nil", entry.OutputID, entry.Size, err, dummyID(2), 3) } c2, err := Open(cdir) if err != nil { t.Fatalf("Open(c2) (reuse): %v", err) } if entry, err := c2.Get(dummyID(1)); err != nil || entry.OutputID != dummyID(2) || entry.Size != 3 { t.Fatalf("c2.Get(1) = %x, %v, %v, want %x, %v, nil", entry.OutputID, entry.Size, err, dummyID(2), 3) } if err := c2.putIndexEntry(dummyID(2), dummyID(3), 4, true); err != nil { t.Fatalf("addIndexEntry: %v", err) } if entry, err := c1.Get(dummyID(2)); err != nil || entry.OutputID != dummyID(3) || entry.Size != 4 { t.Fatalf("c1.Get(2) = %x, %v, %v, want %x, %v, nil", entry.OutputID, entry.Size, err, dummyID(3), 4) } } func TestGrowth(t *testing.T) { dir, err := os.MkdirTemp("", "cachetest-") if err != nil { t.Fatal(err) } defer os.RemoveAll(dir) c, err := Open(dir) if err != nil { t.Fatalf("Open: %v", err) } n := 10000 if testing.Short() { n = 10 } for i := 0; i < n; i++ { if err := c.putIndexEntry(dummyID(i), dummyID(i*99), int64(i)*101, true); err != nil { t.Fatalf("addIndexEntry: %v", err) } id := ActionID(dummyID(i)) entry, err := c.Get(id) if err != nil { t.Fatalf("Get(%x): %v", id, err) } if entry.OutputID != dummyID(i*99) || entry.Size != int64(i)*101 { t.Errorf("Get(%x) = %x, %d, want %x, %d", id, entry.OutputID, entry.Size, dummyID(i*99), int64(i)*101) } } for i := 0; i < n; i++ { id := ActionID(dummyID(i)) entry, err := c.Get(id) if err != nil { t.Fatalf("Get2(%x): %v", id, err) } if entry.OutputID != dummyID(i*99) || entry.Size != int64(i)*101 { t.Errorf("Get2(%x) = %x, %d, want %x, %d", id, entry.OutputID, entry.Size, dummyID(i*99), int64(i)*101) } } } func TestVerifyPanic(t *testing.T) { os.Setenv("GODEBUG", "gocacheverify=1") initEnv() defer func() { os.Unsetenv("GODEBUG") verify = false }() if !verify { t.Fatal("initEnv did not set verify") } dir, err := os.MkdirTemp("", "cachetest-") if err != nil { t.Fatal(err) } defer os.RemoveAll(dir) c, err := Open(dir) if err != nil { t.Fatalf("Open: %v", err) } id := ActionID(dummyID(1)) if err := c.PutBytes(id, []byte("abc")); err != nil { t.Fatal(err) } defer func() { if err := recover(); err != nil { t.Log(err) return } }() c.PutBytes(id, []byte("def")) t.Fatal("mismatched Put did not panic in verify mode") } func dummyID(x int) [HashSize]byte { var out [HashSize]byte binary.LittleEndian.PutUint64(out[:], uint64(x)) return out } func TestCacheTrim(t *testing.T) { dir, err := os.MkdirTemp("", "cachetest-") if err != nil { t.Fatal(err) } defer os.RemoveAll(dir) c, err := Open(dir) if err != nil { t.Fatalf("Open: %v", err) } const start = 1000000000 now := int64(start) c.now = func() time.Time { return time.Unix(now, 0) } checkTime := func(name string, mtime int64) { t.Helper() file := filepath.Join(c.dir, name[:2], name) info, err := os.Stat(file) if err != nil { t.Fatal(err) } if info.ModTime().Unix() != mtime { t.Fatalf("%s mtime = %d, want %d", name, info.ModTime().Unix(), mtime) } } id := ActionID(dummyID(1)) c.PutBytes(id, []byte("abc")) entry, _ := c.Get(id) c.PutBytes(ActionID(dummyID(2)), []byte("def")) mtime := now checkTime(fmt.Sprintf("%x-a", id), mtime) checkTime(fmt.Sprintf("%x-d", entry.OutputID), mtime) // Get should not change recent mtimes. now = start + 10 c.Get(id) checkTime(fmt.Sprintf("%x-a", id), mtime) checkTime(fmt.Sprintf("%x-d", entry.OutputID), mtime) // Get should change distant mtimes. now = start + 5000 mtime2 := now if _, err := c.Get(id); err != nil { t.Fatal(err) } c.OutputFile(entry.OutputID) checkTime(fmt.Sprintf("%x-a", id), mtime2) checkTime(fmt.Sprintf("%x-d", entry.OutputID), mtime2) // Trim should leave everything alone: it's all too new. if err := c.Trim(); err != nil { // if testenv.SyscallIsNotSupported(err) { if true { t.Skipf("skipping: Trim is unsupported (%v)", err) } t.Fatal(err) } if _, err := c.Get(id); err != nil { t.Fatal(err) } c.OutputFile(entry.OutputID) data, err := os.ReadFile(filepath.Join(dir, "trim.txt")) if err != nil { t.Fatal(err) } checkTime(fmt.Sprintf("%x-a", dummyID(2)), start) // Trim less than a day later should not do any work at all. now = start + 80000 if err := c.Trim(); err != nil { t.Fatal(err) } if _, err := c.Get(id); err != nil { t.Fatal(err) } c.OutputFile(entry.OutputID) data2, err := os.ReadFile(filepath.Join(dir, "trim.txt")) if err != nil { t.Fatal(err) } if !bytes.Equal(data, data2) { t.Fatalf("second trim did work: %q -> %q", data, data2) } // Fast forward and do another trim just before the 5 day cutoff. // Note that because of usedQuantum the cutoff is actually 5 days + 1 hour. // We used c.Get(id) just now, so 5 days later it should still be kept. // On the other hand almost a full day has gone by since we wrote dummyID(2) // and we haven't looked at it since, so 5 days later it should be gone. now += 5 * 86400 checkTime(fmt.Sprintf("%x-a", dummyID(2)), start) if err := c.Trim(); err != nil { t.Fatal(err) } if _, err := c.Get(id); err != nil { t.Fatal(err) } c.OutputFile(entry.OutputID) mtime3 := now if _, err := c.Get(dummyID(2)); err == nil { // haven't done a Get for this since original write above t.Fatalf("Trim did not remove dummyID(2)") } // The c.Get(id) refreshed id's mtime again. // Check that another 5 days later it is still not gone, // but check by using checkTime, which doesn't bring mtime forward. now += 5 * 86400 if err := c.Trim(); err != nil { t.Fatal(err) } checkTime(fmt.Sprintf("%x-a", id), mtime3) checkTime(fmt.Sprintf("%x-d", entry.OutputID), mtime3) // Half a day later Trim should still be a no-op, because there was a Trim recently. // Even though the entry for id is now old enough to be trimmed, // it gets a reprieve until the time comes for a new Trim scan. now += 86400 / 2 if err := c.Trim(); err != nil { t.Fatal(err) } checkTime(fmt.Sprintf("%x-a", id), mtime3) checkTime(fmt.Sprintf("%x-d", entry.OutputID), mtime3) // Another half a day later, Trim should actually run, and it should remove id. now += 86400/2 + 1 if err := c.Trim(); err != nil { t.Fatal(err) } if _, err := c.Get(dummyID(1)); err == nil { t.Fatal("Trim did not remove dummyID(1)") } } go-internal-1.12.0/cache/default.go000066400000000000000000000054061453631262600170450ustar00rootroot00000000000000// Copyright 2017 The Go 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 cache import ( "fmt" "log" "os" "path/filepath" "sync" ) // Default returns the default cache to use. // It never returns nil. func Default() *Cache { defaultOnce.Do(initDefaultCache) return defaultCache } var ( defaultOnce sync.Once defaultCache *Cache ) // cacheREADME is a message stored in a README in the cache directory. // Because the cache lives outside the normal Go trees, we leave the // README as a courtesy to explain where it came from. const cacheREADME = `This directory holds cached build artifacts from the Go build system. Run "go clean -cache" if the directory is getting too large. Run "go clean -fuzzcache" to delete the fuzz cache. See golang.org to learn more about Go. ` // initDefaultCache does the work of finding the default cache // the first time Default is called. func initDefaultCache() { dir := DefaultDir() if dir == "off" { if defaultDirErr != nil { log.Fatalf("build cache is required, but could not be located: %v", defaultDirErr) } log.Fatalf("build cache is disabled by GOCACHE=off, but required as of Go 1.12") } if err := os.MkdirAll(dir, 0777); err != nil { log.Fatalf("failed to initialize build cache at %s: %s\n", dir, err) } if _, err := os.Stat(filepath.Join(dir, "README")); err != nil { // Best effort. os.WriteFile(filepath.Join(dir, "README"), []byte(cacheREADME), 0666) } c, err := Open(dir) if err != nil { log.Fatalf("failed to initialize build cache at %s: %s\n", dir, err) } defaultCache = c } var ( defaultDirOnce sync.Once defaultDir string defaultDirErr error ) // DefaultDir returns the effective GOCACHE setting. // It returns "off" if the cache is disabled. func DefaultDir() string { // Save the result of the first call to DefaultDir for later use in // initDefaultCache. cmd/go/main.go explicitly sets GOCACHE so that // subprocesses will inherit it, but that means initDefaultCache can't // otherwise distinguish between an explicit "off" and a UserCacheDir error. defaultDirOnce.Do(func() { // NOTE: changed from upstream's cfg.Getenv, so it will ignore "go env -w". // Consider calling "go env" or copying the cfg package instead. defaultDir = os.Getenv("GOCACHE") if filepath.IsAbs(defaultDir) || defaultDir == "off" { return } if defaultDir != "" { defaultDir = "off" defaultDirErr = fmt.Errorf("GOCACHE is not an absolute path") return } // Compute default location. dir, err := os.UserCacheDir() if err != nil { defaultDir = "off" defaultDirErr = fmt.Errorf("GOCACHE is not defined and %v", err) return } defaultDir = filepath.Join(dir, "go-build") }) return defaultDir } go-internal-1.12.0/cache/hash.go000066400000000000000000000115601453631262600163420ustar00rootroot00000000000000// Copyright 2017 The Go 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 cache import ( "bytes" "crypto/sha256" "fmt" "hash" "io" "os" "runtime" "strings" "sync" ) var debugHash = false // set when GODEBUG=gocachehash=1 // HashSize is the number of bytes in a hash. const HashSize = 32 // A Hash provides access to the canonical hash function used to index the cache. // The current implementation uses salted SHA256, but clients must not assume this. type Hash struct { h hash.Hash name string // for debugging buf *bytes.Buffer // for verify } // hashSalt is a salt string added to the beginning of every hash // created by NewHash. Using the Go version makes sure that different // versions of the go command (or even different Git commits during // work on the development branch) do not address the same cache // entries, so that a bug in one version does not affect the execution // of other versions. This salt will result in additional ActionID files // in the cache, but not additional copies of the large output files, // which are still addressed by unsalted SHA256. // // We strip any GOEXPERIMENTs the go tool was built with from this // version string on the assumption that they shouldn't affect go tool // execution. This allows bootstrapping to converge faster: dist builds // go_bootstrap without any experiments, so by stripping experiments // go_bootstrap and the final go binary will use the same salt. var hashSalt = []byte(stripExperiment(runtime.Version())) // stripExperiment strips any GOEXPERIMENT configuration from the Go // version string. func stripExperiment(version string) string { if i := strings.Index(version, " X:"); i >= 0 { return version[:i] } return version } // Subkey returns an action ID corresponding to mixing a parent // action ID with a string description of the subkey. func Subkey(parent ActionID, desc string) ActionID { h := sha256.New() h.Write([]byte("subkey:")) h.Write(parent[:]) h.Write([]byte(desc)) var out ActionID h.Sum(out[:0]) if debugHash { fmt.Fprintf(os.Stderr, "HASH subkey %x %q = %x\n", parent, desc, out) } if verify { hashDebug.Lock() hashDebug.m[out] = fmt.Sprintf("subkey %x %q", parent, desc) hashDebug.Unlock() } return out } // NewHash returns a new Hash. // The caller is expected to Write data to it and then call Sum. func NewHash(name string) *Hash { h := &Hash{h: sha256.New(), name: name} if debugHash { fmt.Fprintf(os.Stderr, "HASH[%s]\n", h.name) } h.Write(hashSalt) if verify { h.buf = new(bytes.Buffer) } return h } // Write writes data to the running hash. func (h *Hash) Write(b []byte) (int, error) { if debugHash { fmt.Fprintf(os.Stderr, "HASH[%s]: %q\n", h.name, b) } if h.buf != nil { h.buf.Write(b) } return h.h.Write(b) } // Sum returns the hash of the data written previously. func (h *Hash) Sum() [HashSize]byte { var out [HashSize]byte h.h.Sum(out[:0]) if debugHash { fmt.Fprintf(os.Stderr, "HASH[%s]: %x\n", h.name, out) } if h.buf != nil { hashDebug.Lock() if hashDebug.m == nil { hashDebug.m = make(map[[HashSize]byte]string) } hashDebug.m[out] = h.buf.String() hashDebug.Unlock() } return out } // In GODEBUG=gocacheverify=1 mode, // hashDebug holds the input to every computed hash ID, // so that we can work backward from the ID involved in a // cache entry mismatch to a description of what should be there. var hashDebug struct { sync.Mutex m map[[HashSize]byte]string } // reverseHash returns the input used to compute the hash id. func reverseHash(id [HashSize]byte) string { hashDebug.Lock() s := hashDebug.m[id] hashDebug.Unlock() return s } var hashFileCache struct { sync.Mutex m map[string][HashSize]byte } // FileHash returns the hash of the named file. // It caches repeated lookups for a given file, // and the cache entry for a file can be initialized // using SetFileHash. // The hash used by FileHash is not the same as // the hash used by NewHash. func FileHash(file string) ([HashSize]byte, error) { hashFileCache.Lock() out, ok := hashFileCache.m[file] hashFileCache.Unlock() if ok { return out, nil } h := sha256.New() f, err := os.Open(file) if err != nil { if debugHash { fmt.Fprintf(os.Stderr, "HASH %s: %v\n", file, err) } return [HashSize]byte{}, err } _, err = io.Copy(h, f) f.Close() if err != nil { if debugHash { fmt.Fprintf(os.Stderr, "HASH %s: %v\n", file, err) } return [HashSize]byte{}, err } h.Sum(out[:0]) if debugHash { fmt.Fprintf(os.Stderr, "HASH %s: %x\n", file, out) } SetFileHash(file, out) return out, nil } // SetFileHash sets the hash returned by FileHash for file. func SetFileHash(file string, sum [HashSize]byte) { hashFileCache.Lock() if hashFileCache.m == nil { hashFileCache.m = make(map[string][HashSize]byte) } hashFileCache.m[file] = sum hashFileCache.Unlock() } go-internal-1.12.0/cache/hash_test.go000066400000000000000000000021401453631262600173730ustar00rootroot00000000000000// Copyright 2017 The Go 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 cache import ( "fmt" "os" "testing" ) func TestHash(t *testing.T) { oldSalt := hashSalt hashSalt = nil defer func() { hashSalt = oldSalt }() h := NewHash("alice") h.Write([]byte("hello world")) sum := fmt.Sprintf("%x", h.Sum()) want := "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9" if sum != want { t.Errorf("hash(hello world) = %v, want %v", sum, want) } } func TestHashFile(t *testing.T) { f, err := os.CreateTemp("", "cmd-go-test-") if err != nil { t.Fatal(err) } name := f.Name() fmt.Fprintf(f, "hello world") defer os.Remove(name) if err := f.Close(); err != nil { t.Fatal(err) } var h ActionID // make sure hash result is assignable to ActionID h, err = FileHash(name) if err != nil { t.Fatal(err) } sum := fmt.Sprintf("%x", h) want := "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9" if sum != want { t.Errorf("hash(hello world) = %v, want %v", sum, want) } } go-internal-1.12.0/cmd/000077500000000000000000000000001453631262600145655ustar00rootroot00000000000000go-internal-1.12.0/cmd/testscript/000077500000000000000000000000001453631262600167715ustar00rootroot00000000000000go-internal-1.12.0/cmd/testscript/README.md000066400000000000000000000066751453631262600202660ustar00rootroot00000000000000``` The testscript command runs github.com/rogpeppe/go-internal/testscript scripts in a fresh temporary work directory tree. Usage: testscript [-v] [-e VAR[=value]]... [-u] [-work] files... The testscript command is designed to make it easy to create self-contained reproductions of command sequences. Each file is opened as a script and run as described in the documentation for github.com/rogpeppe/go-internal/testscript. The special filename "-" is interpreted as the standard input. As a special case, supporting files/directories in the .gomodproxy subdirectory will be served via a github.com/rogpeppe/go-internal/goproxytest server which is available to each script via the GOPROXY environment variable. The contents of the .gomodproxy subdirectory are not available to the script except via the proxy server. See the documentation for github.com/rogpeppe/go-internal/goproxytest for details on the format of these files/directories. Environment variables can be passed through to each script with the -e flag, where VAR is the name of the variable. Variables override testscript-defined values, with the exception of WORK which cannot be overridden. The -e flag can appear multiple times to specify multiple variables. The -u flag specifies that if a cmp command within a testscript fails and its second argument refers to a file inside the testscript file, the command will succeed and the testscript file will be updated to reflect the actual content. As such, this is the cmd/testcript equivalent of testscript.Params.UpdateScripts. The -work flag prints the temporary work directory path before running each script, and does not remove that directory when testscript exits. Examples ======== The following example, fruit.txtar, shows a simple reproduction that includes .gomodproxy supporting files: go get -m fruit.com go list fruit.com/... stdout 'fruit.com/fruit' -- go.mod -- module mod -- .gomodproxy/fruit.com_v1.0.0/.mod -- module fruit.com -- .gomodproxy/fruit.com_v1.0.0/.info -- {"Version":"v1.0.0","Time":"2018-10-22T18:45:39Z"} -- .gomodproxy/fruit.com_v1.0.0/fruit/fruit.go -- package fruit const Name = "Apple" Running testscript -v fruit.txtar we get: ... > go get -m fruit.com [stderr] go: finding fruit.com v1.0.0 > go list fruit.com/... [stdout] fruit.com/fruit [stderr] go: downloading fruit.com v1.0.0 > stdout 'fruit.com/fruit' PASS The following example, goimports.txtar, shows a simple reproduction involving goimports: go install golang.org/x/tools/cmd/goimports # check goimports help information exec goimports -d main.go stdout 'import "math"' -- go.mod -- module mod require golang.org/x/tools v0.0.0-20181221235234-d00ac6d27372 -- main.go -- package mod const Pi = math.Pi Running testscript -v goimports.txtar we get: ... > go install golang.org/x/tools/cmd/goimports [stderr] go: finding golang.org/x/tools v0.0.0-20181221235234-d00ac6d27372 go: downloading golang.org/x/tools v0.0.0-20181221235234-d00ac6d27372 # check goimports help information (0.015s) > exec goimports -d main.go [stdout] diff -u main.go.orig main.go --- main.go.orig 2019-01-08 16:03:35.861907738 +0000 +++ main.go 2019-01-08 16:03:35.861907738 +0000 @@ -1,3 +1,5 @@ package mod +import "math" + const Pi = math.Pi > stdout 'import "math"' PASS ``` go-internal-1.12.0/cmd/testscript/help.go000066400000000000000000000073201453631262600202520ustar00rootroot00000000000000package main import ( "fmt" "io" ) func mainUsage(f io.Writer) { fmt.Fprint(f, mainHelp) } var mainHelp = ` The testscript command runs github.com/rogpeppe/go-internal/testscript scripts in a fresh temporary work directory tree. Usage: testscript [-v] [-e VAR[=value]]... [-u] [-continue] [-work] files... The testscript command is designed to make it easy to create self-contained reproductions of command sequences. Each file is opened as a script and run as described in the documentation for github.com/rogpeppe/go-internal/testscript. The special filename "-" is interpreted as the standard input. As a special case, supporting files/directories in the .gomodproxy subdirectory will be served via a github.com/rogpeppe/go-internal/goproxytest server which is available to each script via the GOPROXY environment variable. The contents of the .gomodproxy subdirectory are not available to the script except via the proxy server. See the documentation for github.com/rogpeppe/go-internal/goproxytest for details on the format of these files/directories. Environment variables can be passed through to each script with the -e flag, where VAR is the name of the variable. Variables override testscript-defined values, with the exception of WORK which cannot be overridden. The -e flag can appear multiple times to specify multiple variables. The -u flag specifies that if a cmp command within a testscript fails and its second argument refers to a file inside the testscript file, the command will succeed and the testscript file will be updated to reflect the actual content. As such, this is the cmd/testcript equivalent of testscript.Params.UpdateScripts. The -continue flag specifies that if an error occurs, the script will continue running. All errors will be printed and the exit status will be false. The -work flag prints the temporary work directory path before running each script, and does not remove that directory when testscript exits. Examples ======== The following example, fruit.txtar, shows a simple reproduction that includes .gomodproxy supporting files: go get -m fruit.com go list fruit.com/... stdout 'fruit.com/fruit' -- go.mod -- module mod -- .gomodproxy/fruit.com_v1.0.0/.mod -- module fruit.com -- .gomodproxy/fruit.com_v1.0.0/.info -- {"Version":"v1.0.0","Time":"2018-10-22T18:45:39Z"} -- .gomodproxy/fruit.com_v1.0.0/fruit/fruit.go -- package fruit const Name = "Apple" Running testscript -v fruit.txtar we get: ... > go get -m fruit.com [stderr] go: finding fruit.com v1.0.0 > go list fruit.com/... [stdout] fruit.com/fruit [stderr] go: downloading fruit.com v1.0.0 > stdout 'fruit.com/fruit' PASS The following example, goimports.txtar, shows a simple reproduction involving goimports: go install golang.org/x/tools/cmd/goimports # check goimports help information exec goimports -d main.go stdout 'import "math"' -- go.mod -- module mod require golang.org/x/tools v0.0.0-20181221235234-d00ac6d27372 -- main.go -- package mod const Pi = math.Pi Running testscript -v goimports.txtar we get: ... > go install golang.org/x/tools/cmd/goimports [stderr] go: finding golang.org/x/tools v0.0.0-20181221235234-d00ac6d27372 go: downloading golang.org/x/tools v0.0.0-20181221235234-d00ac6d27372 # check goimports help information (0.015s) > exec goimports -d main.go [stdout] diff -u main.go.orig main.go --- main.go.orig 2019-01-08 16:03:35.861907738 +0000 +++ main.go 2019-01-08 16:03:35.861907738 +0000 @@ -1,3 +1,5 @@ package mod +import "math" + const Pi = math.Pi > stdout 'import "math"' PASS `[1:] go-internal-1.12.0/cmd/testscript/main.go000066400000000000000000000234231453631262600202500ustar00rootroot00000000000000// Copyright 2018 The Go 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 main import ( "errors" "flag" "fmt" "io/ioutil" "os" "os/exec" "path/filepath" "strings" "sync/atomic" "github.com/rogpeppe/go-internal/goproxytest" "github.com/rogpeppe/go-internal/gotooltest" "github.com/rogpeppe/go-internal/testscript" "github.com/rogpeppe/go-internal/txtar" ) const ( // goModProxyDir is the special subdirectory in a txtar script's supporting files // within which we expect to find github.com/rogpeppe/go-internal/goproxytest // directories. goModProxyDir = ".gomodproxy" ) type envVarsFlag struct { vals []string } func (e *envVarsFlag) String() string { return fmt.Sprintf("%v", e.vals) } func (e *envVarsFlag) Set(v string) error { e.vals = append(e.vals, v) return nil } func main() { os.Exit(main1()) } func main1() int { switch err := mainerr(); err { case nil: return 0 case flag.ErrHelp: return 2 default: fmt.Fprintln(os.Stderr, err) return 1 } } func mainerr() (retErr error) { fs := flag.NewFlagSet(os.Args[0], flag.ContinueOnError) fs.Usage = func() { mainUsage(os.Stderr) } var envVars envVarsFlag fUpdate := fs.Bool("u", false, "update archive file if a cmp fails") fWork := fs.Bool("work", false, "print temporary work directory and do not remove when done") fContinue := fs.Bool("continue", false, "continue running the script if an error occurs") fVerbose := fs.Bool("v", false, "run tests verbosely") fs.Var(&envVars, "e", "pass through environment variable to script (can appear multiple times)") if err := fs.Parse(os.Args[1:]); err != nil { return err } td, err := ioutil.TempDir("", "testscript") if err != nil { return fmt.Errorf("unable to create temp dir: %v", err) } if *fWork { fmt.Fprintf(os.Stderr, "temporary work directory: %v\n", td) } else { defer os.RemoveAll(td) } files := fs.Args() if len(files) == 0 { files = []string{"-"} } // If we are only reading from stdin, -u cannot be specified. It seems a bit // bizarre to invoke testscript with '-' and a regular file, but hey. In // that case the -u flag will only apply to the regular file and we assume // the user knows it. onlyReadFromStdin := true for _, f := range files { if f != "-" { onlyReadFromStdin = false } } if onlyReadFromStdin && *fUpdate { return fmt.Errorf("cannot use -u when reading from stdin") } tr := testRunner{ update: *fUpdate, continueOnError: *fContinue, verbose: *fVerbose, env: envVars.vals, testWork: *fWork, } dirNames := make(map[string]int) for _, filename := range files { // TODO make running files concurrent by default? If we do, note we'll need to do // something smarter with the runner stdout and stderr below // Derive a name for the directory from the basename of file, making // uniq by adding a numeric suffix in the case we otherwise end // up with multiple files with the same basename dirName := filepath.Base(filename) count := dirNames[dirName] dirNames[dirName] = count + 1 if count != 0 { dirName = fmt.Sprintf("%s%d", dirName, count) } runDir := filepath.Join(td, dirName) if err := os.Mkdir(runDir, 0o777); err != nil { return fmt.Errorf("failed to create a run directory within %v for %v: %v", td, renderFilename(filename), err) } if err := tr.run(runDir, filename); err != nil { return err } } return nil } type testRunner struct { // update denotes that the source testscript archive filename should be // updated in the case of any cmp failures. update bool // continueOnError indicates that T.FailNow should not panic, allowing the // test script to continue running. Note that T is still marked as failed. continueOnError bool // verbose indicates the running of the script should be noisy. verbose bool // env is the environment that should be set on top of the base // testscript-defined minimal environment. env []string // testWork indicates whether or not temporary working directory trees // should be left behind. Corresponds exactly to the // testscript.Params.TestWork field. testWork bool } // run runs the testscript archive located at the path filename, within the // working directory runDir. filename could be "-" in the case of stdin func (tr *testRunner) run(runDir, filename string) error { var ar *txtar.Archive var err error mods := filepath.Join(runDir, goModProxyDir) if err := os.MkdirAll(mods, 0o777); err != nil { return fmt.Errorf("failed to create goModProxy dir: %v", err) } if filename == "-" { byts, err := ioutil.ReadAll(os.Stdin) if err != nil { return fmt.Errorf("failed to read from stdin: %v", err) } ar = txtar.Parse(byts) } else { ar, err = txtar.ParseFile(filename) } if err != nil { return fmt.Errorf("failed to txtar parse %v: %v", renderFilename(filename), err) } var script, gomodProxy txtar.Archive script.Comment = ar.Comment for _, f := range ar.Files { fp := filepath.Clean(filepath.FromSlash(f.Name)) parts := strings.Split(fp, string(os.PathSeparator)) if len(parts) > 1 && parts[0] == goModProxyDir { gomodProxy.Files = append(gomodProxy.Files, f) } else { script.Files = append(script.Files, f) } } if txtar.Write(&gomodProxy, runDir); err != nil { return fmt.Errorf("failed to write .gomodproxy files: %v", err) } scriptFile := filepath.Join(runDir, "script.txtar") if err := ioutil.WriteFile(scriptFile, txtar.Format(&script), 0o666); err != nil { return fmt.Errorf("failed to write script for %v: %v", renderFilename(filename), err) } p := testscript.Params{ Dir: runDir, UpdateScripts: tr.update, ContinueOnError: tr.continueOnError, } if _, err := exec.LookPath("go"); err == nil { if err := gotooltest.Setup(&p); err != nil { return fmt.Errorf("failed to setup go tool for %v run: %v", renderFilename(filename), err) } } addSetup := func(f func(env *testscript.Env) error) { origSetup := p.Setup p.Setup = func(env *testscript.Env) error { if origSetup != nil { if err := origSetup(env); err != nil { return err } } return f(env) } } if tr.testWork { addSetup(func(env *testscript.Env) error { fmt.Fprintf(os.Stderr, "temporary work directory for %s: %s\n", renderFilename(filename), env.WorkDir) return nil }) } if len(gomodProxy.Files) > 0 { srv, err := goproxytest.NewServer(mods, "") if err != nil { return fmt.Errorf("cannot start proxy for %v: %v", renderFilename(filename), err) } defer srv.Close() addSetup(func(env *testscript.Env) error { // Add GOPROXY after calling the original setup // so that it overrides any GOPROXY set there. env.Vars = append(env.Vars, "GOPROXY="+srv.URL, "GONOSUMDB=*", ) return nil }) } if len(tr.env) > 0 { addSetup(func(env *testscript.Env) error { for _, v := range tr.env { varName := v if i := strings.Index(v, "="); i >= 0 { varName = v[:i] } else { v = fmt.Sprintf("%s=%s", v, os.Getenv(v)) } switch varName { case "": return fmt.Errorf("invalid variable name %q", varName) case "WORK": return fmt.Errorf("cannot override WORK variable") } env.Vars = append(env.Vars, v) } return nil }) } r := &runT{ verbose: tr.verbose, } func() { defer func() { switch recover() { case nil, skipRun: case failedRun: err = failedRun default: panic(fmt.Errorf("unexpected panic: %v [%T]", err, err)) } }() testscript.RunT(r, p) // When continueOnError is true, FailNow does not call panic(failedRun). // We still want err to be set, as the script resulted in a failure. if r.Failed() { err = failedRun } }() if err != nil { return fmt.Errorf("error running %v in %v\n", renderFilename(filename), runDir) } if tr.update && filename != "-" { // Parse the (potentially) updated scriptFile as an archive, then merge // with the original archive, retaining order. Then write the archive // back to the source file source, err := ioutil.ReadFile(scriptFile) if err != nil { return fmt.Errorf("failed to read from script file %v for -update: %v", scriptFile, err) } updatedAr := txtar.Parse(source) updatedFiles := make(map[string]txtar.File) for _, f := range updatedAr.Files { updatedFiles[f.Name] = f } for i, f := range ar.Files { if newF, ok := updatedFiles[f.Name]; ok { ar.Files[i] = newF } } if err := ioutil.WriteFile(filename, txtar.Format(ar), 0o666); err != nil { return fmt.Errorf("failed to write script back to %v for -update: %v", renderFilename(filename), err) } } return nil } var ( failedRun = errors.New("failed run") skipRun = errors.New("skip") ) // renderFilename renders filename in error messages, taking into account // the filename could be the special "-" (stdin) func renderFilename(filename string) string { if filename == "-" { return "" } return filename } // runT implements testscript.T and is used in the call to testscript.Run type runT struct { verbose bool failed int32 } func (r *runT) Skip(is ...interface{}) { panic(skipRun) } func (r *runT) Fatal(is ...interface{}) { r.Log(is...) r.FailNow() } func (r *runT) Parallel() { // No-op for now; we are currently only running a single script in a // testscript instance. } func (r *runT) Log(is ...interface{}) { fmt.Print(is...) } func (r *runT) FailNow() { atomic.StoreInt32(&r.failed, 1) panic(failedRun) } func (r *runT) Failed() bool { return atomic.LoadInt32(&r.failed) != 0 } func (r *runT) Run(n string, f func(t testscript.T)) { // For now we we don't top/tail the run of a subtest. We are currently only // running a single script in a testscript instance, which means that we // will only have a single subtest. f(r) } func (r *runT) Verbose() bool { return r.verbose } go-internal-1.12.0/cmd/testscript/main_test.go000066400000000000000000000056201453631262600213060ustar00rootroot00000000000000// Copyright 2018 The Go 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 main import ( "bytes" "os" "os/exec" "path/filepath" "runtime" "strings" "testing" "github.com/rogpeppe/go-internal/gotooltest" "github.com/rogpeppe/go-internal/internal/os/execpath" "github.com/rogpeppe/go-internal/testscript" ) func TestMain(m *testing.M) { os.Exit(testscript.RunMain(m, map[string]func() int{ "testscript": main1, })) } func TestScripts(t *testing.T) { if _, err := exec.LookPath("go"); err != nil { t.Fatalf("need go in PATH for these tests") } var stderr bytes.Buffer cmd := exec.Command("go", "env", "GOMOD") cmd.Stderr = &stderr out, err := cmd.Output() if err != nil { t.Fatalf("failed to run %v: %v\n%s", strings.Join(cmd.Args, " "), err, stderr.String()) } gomod := string(out) if gomod == "" { t.Fatalf("apparently we are not running in module mode?") } p := testscript.Params{ Dir: "testdata", Setup: func(env *testscript.Env) error { env.Vars = append(env.Vars, "GOINTERNALMODPATH="+filepath.Dir(gomod), "GONOSUMDB=*", ) return nil }, Cmds: map[string]func(ts *testscript.TestScript, neg bool, args []string){ "dropgofrompath": dropgofrompath, "setfilegoproxy": setfilegoproxy, "expandone": expandone, }, } if err := gotooltest.Setup(&p); err != nil { t.Fatal(err) } testscript.Run(t, p) } func dropgofrompath(ts *testscript.TestScript, neg bool, args []string) { if neg { ts.Fatalf("unsupported: ! dropgofrompath") } var newPath []string for _, d := range filepath.SplitList(ts.Getenv("PATH")) { getenv := func(k string) string { // Note that Windows and Plan9 use lowercase "path". if strings.ToUpper(k) == "PATH" { return d } return ts.Getenv(k) } if _, err := execpath.Look("go", getenv); err != nil { newPath = append(newPath, d) } } ts.Setenv("PATH", strings.Join(newPath, string(filepath.ListSeparator))) } func setfilegoproxy(ts *testscript.TestScript, neg bool, args []string) { if neg { ts.Fatalf("unsupported: ! setfilegoproxy") } path := args[0] path = filepath.ToSlash(path) // probably sufficient to just handle spaces path = strings.Replace(path, " ", "%20", -1) if runtime.GOOS == "windows" { path = "/" + path } ts.Setenv("GOPROXY", "file://"+path) } // expandone takes a single glob-style argument that should expand to // a single file, otherwise the command fails func expandone(ts *testscript.TestScript, neg bool, args []string) { if len(args) != 1 { ts.Fatalf("expandone: expected a single argument") } if neg { ts.Fatalf("unsupported: ! expandone") } glob := ts.MkAbs(args[0]) matches, err := filepath.Glob(glob) if err != nil { ts.Fatalf("expandone: failed to glob %q: %v", glob, err) } if n := len(matches); n != 1 { ts.Fatalf("expandone: %q matched %v files, not 1", glob, n) } } go-internal-1.12.0/cmd/testscript/testdata/000077500000000000000000000000001453631262600206025ustar00rootroot00000000000000go-internal-1.12.0/cmd/testscript/testdata/continue.txt000066400000000000000000000005511453631262600231700ustar00rootroot00000000000000# should support -continue unquote file.txt # Running with continue, the testscript command itself # should fail, but we should see the results of executing # both commands. ! testscript -continue file.txt stdout 'grep banana in' stdout 'no match for `banana` found in in' stdout 'grep apple in' -- file.txt -- >grep banana in >grep apple in >-- in -- >apple go-internal-1.12.0/cmd/testscript/testdata/env_values.txt000066400000000000000000000011231453631262600235070ustar00rootroot00000000000000# Test that passing env values, e.g. ENV1=val, works unquote test.txt env BLAH1= env BLAH2=junk # Normal operation testscript -e BLAH1=rubbish -e BLAH2 test.txt # It is an error to specify WORK. Note the error message # appears on stdout because it is written to the log output # of testscript, which has no concept of stderr. ! testscript -e BLAH1=rubbish -e BLAH2 -e WORK test.txt stdout 'cannot override WORK variable' -- test.txt -- >exec printf $BLAH1'\n' >cmp stdout stdout1.txt > >exec printf $BLAH2'\n' >cmp stdout stdout2.txt > >-- stdout1.txt -- >rubbish >-- stdout2.txt -- >junk go-internal-1.12.0/cmd/testscript/testdata/env_var_no_go.txt000066400000000000000000000043151453631262600241670ustar00rootroot00000000000000# Test passing environment variables to scripts with no go command on PATH # # This is the counterpart to env_var_with_go.txt unquote noproxy.txt unquote withproxy.txt dropgofrompath env BANANA=banana env GOPATH=$WORK/ourgopath env GOPROXY= # no GOPROXY, no pass-through, no proxy testscript -v noproxy.txt stdout ^BANANA=$ stdout ^GOPATH=$ stdout ^GOPROXY=$ ! stderr .+ # no GOPROXY, no pass-through, with proxy testscript -v withproxy.txt stdout ^BANANA=$ stdout ^GOPATH=$ stdout ^GOPROXY=http://.*/mod$ ! stderr .+ # no GOPROXY, with pass-through, no proxy testscript -v -e BANANA -e GOPATH -e GOPROXY noproxy.txt stdout ^BANANA=banana$ stdout ^GOPATH=${WORK@R}[/\\]ourgopath$ stdout ^GOPROXY=$ ! stderr .+ # no GOPROXY, with pass-through, with proxy testscript -v -e BANANA -e GOPATH -e GOPROXY withproxy.txt stdout ^BANANA=banana$ stdout ^GOPATH=${WORK@R}[/\\]ourgopath$ stdout ^GOPROXY=$ ! stderr .+ setfilegoproxy $WORK/proxy # with GOPROXY, no pass-through, no proxy testscript -v noproxy.txt stdout ^BANANA=$ stdout ^GOPATH=$ stdout ^GOPROXY=$ ! stderr .+ # with GOPROXY, no pass-through, with proxy testscript -v withproxy.txt stdout ^BANANA=$ stdout ^GOPATH=$ stdout ^GOPROXY=http://.*/mod$ ! stderr .+ # with GOPROXY, with pass-through, no proxy testscript -v -e BANANA -e GOPATH -e GOPROXY noproxy.txt stdout ^BANANA=banana$ stdout ^GOPATH=${WORK@R}[/\\]ourgopath$ stdout ^GOPROXY=$GOPROXY$ ! stderr .+ # with GOPROXY, with pass-through, with proxy testscript -v -e BANANA -e GOPATH -e GOPROXY withproxy.txt stdout ^BANANA=banana$ stdout ^GOPATH=${WORK@R}[/\\]ourgopath$ stdout ^GOPROXY=$GOPROXY$ ! stderr .+ -- noproxy.txt -- >env BANANA >env GOPATH >env GOPROXY -- withproxy.txt -- >env BANANA >env GOPATH >env GOPROXY >-- .gomodproxy/fruit.com_v1.0.0/.mod -- >module fruit.com > >-- .gomodproxy/fruit.com_v1.0.0/.info -- >{"Version":"v1.0.0","Time":"2018-10-22T18:45:39Z"} > >-- .gomodproxy/fruit.com_v1.0.0/go.mod -- >module fruit.com > >-- .gomodproxy/fruit.com_v1.0.0/fruit/fruit.go -- >package fruit > >const Apple = "apple" >-- .gomodproxy/fruit.com_v1.0.0/coretest/coretest.go -- >// package coretest becomes a candidate for the missing >// core import in main above >package coretest > >const Mandarin = "mandarin" go-internal-1.12.0/cmd/testscript/testdata/env_var_with_go.txt000066400000000000000000000053011453631262600245220ustar00rootroot00000000000000# Test passing environment variables to scripts with the go command on PATH # # Below where we check the output of testscript -v, we have to match against # the string literal $WORK because testscript rewrites the actual directory # to $WORK. Hence we don't want to expand this script's $WORK in such a comparison. # # This is the counterpart to env_var_no_go.txt unquote noproxy.txt unquote withproxy.txt # Baseline testscript -v noproxy.txt stdout ^BANANA=$ stdout '^GOPATH=\$WORK[/\\]\.gopath'$ stdout ^GOPROXY=https://proxy.golang.org,direct$ ! stderr .+ env BANANA=banana env GOPATH=$WORK/ourgopath env GOPROXY= # no GOPROXY, no pass-through, no proxy testscript -v noproxy.txt stdout ^BANANA=$ stdout '^GOPATH=\$WORK[/\\]\.gopath'$ stdout ^GOPROXY=https://proxy.golang.org,direct$ ! stderr .+ # no GOPROXY, no pass-through, with proxy testscript -v withproxy.txt stdout ^BANANA=$ stdout '^GOPATH=\$WORK[/\\]\.gopath'$ stdout ^GOPROXY=http://.*/mod$ ! stderr .+ # no GOPROXY, with pass-through, no proxy testscript -v -e BANANA -e GOPATH -e GOPROXY noproxy.txt stdout ^BANANA=banana$ stdout ^GOPATH=${WORK@R}[/\\]ourgopath$ stdout ^GOPROXY=$ ! stderr .+ # no GOPROXY, with pass-through, with proxy testscript -v -e BANANA -e GOPATH -e GOPROXY withproxy.txt stdout ^BANANA=banana$ stdout ^GOPATH=${WORK@R}[/\\]ourgopath$ stdout ^GOPROXY=$ ! stderr .+ setfilegoproxy $WORK/proxy # with GOPROXY, no pass-through, no proxy testscript -v noproxy.txt stdout ^BANANA=$ stdout '^GOPATH=\$WORK[/\\]\.gopath'$ stdout ^GOPROXY=$GOPROXY$ ! stderr .+ # with GOPROXY, no pass-through, with proxy testscript -v withproxy.txt stdout ^BANANA=$ stdout '^GOPATH=\$WORK[/\\]\.gopath'$ stdout ^GOPROXY=http://.*/mod$ ! stderr .+ # with GOPROXY, with pass-through, no proxy testscript -v -e BANANA -e GOPATH -e GOPROXY noproxy.txt stdout ^BANANA=banana$ stdout ^GOPATH=${WORK@R}[/\\]ourgopath$ stdout ^GOPROXY=$GOPROXY$ ! stderr .+ # with GOPROXY, with pass-through, with proxy testscript -v -e BANANA -e GOPATH -e GOPROXY withproxy.txt stdout ^BANANA=banana$ stdout ^GOPATH=${WORK@R}[/\\]ourgopath$ stdout ^GOPROXY=$GOPROXY$ ! stderr .+ -- noproxy.txt -- >env BANANA >env GOPATH >env GOPROXY -- withproxy.txt -- >env BANANA >env GOPATH >env GOPROXY >-- .gomodproxy/fruit.com_v1.0.0/.mod -- >module fruit.com > >-- .gomodproxy/fruit.com_v1.0.0/.info -- >{"Version":"v1.0.0","Time":"2018-10-22T18:45:39Z"} > >-- .gomodproxy/fruit.com_v1.0.0/go.mod -- >module fruit.com > >-- .gomodproxy/fruit.com_v1.0.0/fruit/fruit.go -- >package fruit > >const Apple = "apple" >-- .gomodproxy/fruit.com_v1.0.0/coretest/coretest.go -- >// package coretest becomes a candidate for the missing >// core import in main above >package coretest > >const Mandarin = "mandarin" go-internal-1.12.0/cmd/testscript/testdata/error.txt000066400000000000000000000003271453631262600224760ustar00rootroot00000000000000# should support skip unquote file.txt # stdin stdin file.txt ! testscript -v stderr 'error running in' # file-based ! testscript -v file.txt stderr 'error running file.txt in' -- file.txt -- >exec false go-internal-1.12.0/cmd/testscript/testdata/help.txt000066400000000000000000000001661453631262600222760ustar00rootroot00000000000000# Simply sanity check on help output ! testscript -help ! stdout .+ stderr 'The testscript command' stderr 'Examples' go-internal-1.12.0/cmd/testscript/testdata/nogo.txt000066400000000000000000000004601453631262600223050ustar00rootroot00000000000000# should support skip unquote file.txt # We can't just set PATH to empty because we need the part of it that # contains the command names, so use a special builtin instead. dropgofrompath ! testscript -v file.txt stdout 'unknown command "go"' stderr 'error running file.txt in' -- file.txt -- >go env go-internal-1.12.0/cmd/testscript/testdata/noproxy.txt000066400000000000000000000005611453631262600230630ustar00rootroot00000000000000# With no .gomodproxy supporting files, we use the GOPROXY from # the environment. # Note that Go 1.21 started quoting with single quotes in "go env", # where older versions used double quotes. env GOPROXY=0.1.2.3 unquote file.txt testscript -v file.txt -- file.txt -- >go env >[!windows] stdout '^GOPROXY=[''"]0.1.2.3[''"]$' >[windows] stdout '^set GOPROXY=0.1.2.3$' go-internal-1.12.0/cmd/testscript/testdata/simple.txt000066400000000000000000000016471453631262600226440ustar00rootroot00000000000000# With .gomodproxy supporting files, any GOPROXY from the # environment should be overridden by the test proxy. env GOPROXY=0.1.2.3 unquote file.txt testscript -v file.txt stdout 'example.com/mod' ! stderr .+ -- file.txt -- >go get -d fruit.com >go list -m >stdout 'example.com/mod' >go list fruit.com/... >stdout 'fruit.com/fruit' >stdout 'fruit.com/coretest' >-- go.mod -- >module example.com/mod > >require fruit.com v1.0.0 >-- .gomodproxy/fruit.com_v1.0.0/.mod -- >module fruit.com > >-- .gomodproxy/fruit.com_v1.0.0/.info -- >{"Version":"v1.0.0","Time":"2018-10-22T18:45:39Z"} > >-- .gomodproxy/fruit.com_v1.0.0/go.mod -- >module fruit.com > >-- .gomodproxy/fruit.com_v1.0.0/fruit/fruit.go -- >package fruit > >const Apple = "apple" >-- .gomodproxy/fruit.com_v1.0.0/coretest/coretest.go -- >// package coretest becomes a candidate for the missing >// core import in main above >package coretest > >const Mandarin = "mandarin" go-internal-1.12.0/cmd/testscript/testdata/skip.txt000066400000000000000000000002001453631262600223010ustar00rootroot00000000000000# should support skip unquote file.txt testscript -v file.txt stdout 'go version' ! stderr .+ -- file.txt -- >go version >skip go-internal-1.12.0/cmd/testscript/testdata/update.txt000066400000000000000000000027031453631262600226270ustar00rootroot00000000000000# should support the -update flag unquote in.txt res.txt # Should be an error to use -u with only stdin stdin in.txt ! testscript -u stderr 'cannot use -u when reading from stdin' # It is ok to use -u when reading from stdin and # a regular file testscript -u - in.txt cmp in.txt res.txt -- in.txt -- >exec printf 'hello\n' >cmp stdout stdout.txt > >-- .gomodproxy/fruit.com_v1.0.0/.mod -- >module fruit.com > >-- .gomodproxy/fruit.com_v1.0.0/.info -- >{"Version":"v1.0.0","Time":"2018-10-22T18:45:39Z"} > >-- .gomodproxy/fruit.com_v1.0.0/go.mod -- >module fruit.com > >-- stdout.txt -- >goodbye >-- .gomodproxy/fruit.com_v1.0.0/fruit/fruit.go -- >package fruit > >const Apple = "apple" >-- .gomodproxy/fruit.com_v1.0.0/coretest/coretest.go -- >// package coretest becomes a candidate for the missing >// core import in main above >package coretest > >const Mandarin = "mandarin" -- res.txt -- >exec printf 'hello\n' >cmp stdout stdout.txt > >-- .gomodproxy/fruit.com_v1.0.0/.mod -- >module fruit.com > >-- .gomodproxy/fruit.com_v1.0.0/.info -- >{"Version":"v1.0.0","Time":"2018-10-22T18:45:39Z"} > >-- .gomodproxy/fruit.com_v1.0.0/go.mod -- >module fruit.com > >-- stdout.txt -- >hello >-- .gomodproxy/fruit.com_v1.0.0/fruit/fruit.go -- >package fruit > >const Apple = "apple" >-- .gomodproxy/fruit.com_v1.0.0/coretest/coretest.go -- >// package coretest becomes a candidate for the missing >// core import in main above >package coretest > >const Mandarin = "mandarin" go-internal-1.12.0/cmd/testscript/testdata/work.txt000066400000000000000000000014161453631262600223270ustar00rootroot00000000000000# Test that passing -work leaves behind the working directory # that contains the temporary directories within which the # script arguments are expanded. # # This test also covers the use of multiple scripts which share # the same basename, ensuring that the naming of the directories # within the working directory. unquote file.txt dir/file.txt testscript -v -work file.txt dir/file.txt stderr '^temporary work directory: \Q'$WORK'\E[/\\]\.tmp[/\\]' stderr '^temporary work directory for file.txt: \Q'$WORK'\E[/\\]\.tmp[/\\]' stderr '^temporary work directory for dir[/\\]file.txt: \Q'$WORK'\E[/\\]\.tmp[/\\]' expandone $WORK/.tmp/testscript*/file.txt/script.txtar expandone $WORK/.tmp/testscript*/file.txt1/script.txtar -- file.txt -- >exec true -- dir/file.txt -- >exec true go-internal-1.12.0/cmd/txtar-addmod/000077500000000000000000000000001453631262600171555ustar00rootroot00000000000000go-internal-1.12.0/cmd/txtar-addmod/addmod.go000066400000000000000000000125151453631262600207400ustar00rootroot00000000000000// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // The txtar-addmod command adds a module as a txtar archive to the a testdata module directory // as understood by the goproxytest package (see https://godoc.org/github.com/rogpeppe/go-internal/goproxytest). // // Usage: // // txtar-addmod dir path@version... // // where dir is the directory to add the module to. // // In general, it's intended to be used only for very small modules - we do not want to check // very large files into testdata/mod. // // It is acceptable to edit the archive afterward to remove or shorten files. package main import ( "bytes" "flag" "fmt" "log" "os" "os/exec" "path/filepath" "strings" "golang.org/x/mod/module" "golang.org/x/tools/txtar" ) func usage() { fmt.Fprintf(os.Stderr, "usage: txtar-addmod dir path@version...\n") flag.PrintDefaults() fmt.Fprintf(os.Stderr, ` The txtar-addmod command adds a module as a txtar archive to the testdata module directory as understood by the goproxytest package (see https://godoc.org/github.com/rogpeppe/go-internal/goproxytest). The dir argument names to directory to add the module to. If dir is "-", the result will instead be written to the standard output in a form suitable for embedding directly into a testscript txtar file, with each file prefixed with the ".gomodproxy" directory. In general, txtar-addmod is intended to be used only for very small modules - we do not want to check very large files into testdata/mod. It is acceptable to edit the archive afterward to remove or shorten files. `) os.Exit(2) } var tmpdir string func fatalf(format string, args ...interface{}) { os.RemoveAll(tmpdir) log.Fatalf(format, args...) } const goCmd = "go" func main() { os.Exit(main1()) } var allFiles = flag.Bool("all", false, "include all source files") func main1() int { flag.Usage = usage flag.Parse() if flag.NArg() < 2 { usage() } targetDir := flag.Arg(0) modules := flag.Args()[1:] log.SetPrefix("txtar-addmod: ") log.SetFlags(0) var err error tmpdir, err = os.MkdirTemp("", "txtar-addmod-") if err != nil { log.Fatal(err) } run := func(command string, args ...string) string { cmd := exec.Command(command, args...) cmd.Dir = tmpdir var stderr bytes.Buffer cmd.Stderr = &stderr out, err := cmd.Output() if err != nil { fatalf("%s %s: %v\n%s", command, strings.Join(args, " "), err, stderr.Bytes()) } return string(out) } gopath := strings.TrimSpace(run("go", "env", "GOPATH")) if gopath == "" { fatalf("cannot find GOPATH") } exitCode := 0 for _, arg := range modules { if err := os.WriteFile(filepath.Join(tmpdir, "go.mod"), []byte("module m\n"), 0o666); err != nil { fatalf("%v", err) } run(goCmd, "get", "-d", arg) path := arg if i := strings.Index(path, "@"); i >= 0 { path = path[:i] } out := run(goCmd, "list", "-m", "-f={{.Path}} {{.Version}} {{.Dir}}", path) f := strings.Fields(out) if len(f) != 3 { log.Printf("go list -m %s: unexpected output %q", arg, out) exitCode = 1 continue } path, vers, dir := f[0], f[1], f[2] encpath, err := module.EscapePath(path) if err != nil { log.Printf("failed to encode path %q: %v", path, err) continue } path = encpath mod, err := os.ReadFile(filepath.Join(gopath, "pkg/mod/cache/download", path, "@v", vers+".mod")) if err != nil { log.Printf("%s: %v", arg, err) exitCode = 1 continue } info, err := os.ReadFile(filepath.Join(gopath, "pkg/mod/cache/download", path, "@v", vers+".info")) if err != nil { log.Printf("%s: %v", arg, err) exitCode = 1 continue } a := new(txtar.Archive) title := arg if !strings.Contains(arg, "@") { title += "@" + vers } dir = filepath.Clean(dir) modDir := strings.ReplaceAll(path, "/", "_") + "_" + vers filePrefix := "" if targetDir == "-" { filePrefix = ".gomodproxy/" + modDir + "/" } else { // No comment if we're writing to stdout. a.Comment = []byte(fmt.Sprintf("module %s\n\n", title)) } a.Files = []txtar.File{ {Name: filePrefix + ".mod", Data: mod}, {Name: filePrefix + ".info", Data: info}, } err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { if err != nil { return err } if !info.Mode().IsRegular() { return nil } // TODO: skip dirs like "testdata" or "_foo" unless -all // is given? name := info.Name() switch { case *allFiles: case name == "go.mod": case strings.HasSuffix(name, ".go"): default: // the name is not in the whitelist, and we're // not including all files via -all return nil } data, err := os.ReadFile(path) if err != nil { return err } a.Files = append(a.Files, txtar.File{ Name: filePrefix + strings.TrimPrefix(path, dir+string(filepath.Separator)), Data: data, }) return nil }) if err != nil { log.Printf("%s: %v", arg, err) exitCode = 1 continue } data := txtar.Format(a) if targetDir == "-" { if _, err := os.Stdout.Write(data); err != nil { log.Printf("cannot write output: %v", err) exitCode = 1 break } } else { if err := os.WriteFile(filepath.Join(targetDir, modDir+".txtar"), data, 0o666); err != nil { log.Printf("%s: %v", arg, err) exitCode = 1 continue } } } os.RemoveAll(tmpdir) return exitCode } go-internal-1.12.0/cmd/txtar-addmod/script_test.go000066400000000000000000000021301453631262600220430ustar00rootroot00000000000000// Copyright 2018 The Go 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 main import ( "fmt" "os" "testing" "github.com/rogpeppe/go-internal/goproxytest" "github.com/rogpeppe/go-internal/gotooltest" "github.com/rogpeppe/go-internal/testscript" ) var proxyURL string func TestMain(m *testing.M) { os.Exit(testscript.RunMain(gobinMain{m}, map[string]func() int{ "txtar-addmod": main1, })) } type gobinMain struct { m *testing.M } func (m gobinMain) Run() int { // Start the Go proxy server running for all tests. srv, err := goproxytest.NewServer("testdata/mod", "") if err != nil { fmt.Fprintf(os.Stderr, "cannot start proxy: %v", err) return 1 } proxyURL = srv.URL return m.m.Run() } func TestScripts(t *testing.T) { p := testscript.Params{ Dir: "testdata", Setup: func(e *testscript.Env) error { e.Vars = append(e.Vars, "GOPROXY="+proxyURL, "GONOSUMDB=*", ) return nil }, } if err := gotooltest.Setup(&p); err != nil { t.Fatal(err) } testscript.Run(t, p) } go-internal-1.12.0/cmd/txtar-addmod/testdata/000077500000000000000000000000001453631262600207665ustar00rootroot00000000000000go-internal-1.12.0/cmd/txtar-addmod/testdata/encode.txt000066400000000000000000000003231453631262600227620ustar00rootroot00000000000000mkdir $WORK/out txtar-addmod $WORK/out github.com/shurcooL/httpfs@v0.0.0-20171119174359-809beceb2371 ! stdout .+ ! stderr .+ exists $WORK/out/github.com_shurcoo!l_httpfs_v0.0.0-20171119174359-809beceb2371.txtar go-internal-1.12.0/cmd/txtar-addmod/testdata/mod/000077500000000000000000000000001453631262600215455ustar00rootroot00000000000000go-internal-1.12.0/cmd/txtar-addmod/testdata/mod/github.com_gobin-testrepos_simple-main_v1.0.0.txt000066400000000000000000000007031453631262600327460ustar00rootroot00000000000000module github.com/gobin-testrepos/simple-main@v1.0.0 -- .mod -- module github.com/gobin-testrepos/simple-main -- .info -- {"Version":"v1.0.0","Time":"2018-10-22T18:45:39Z"} -- go.mod -- module github.com/gobin-testrepos/simple-main -- main.go -- package main import "fmt" func main() { fmt.Println("I am a simple module-based main") } -- foobar -- This is an extra file that can't be imported with the Go package, but may still be used in a test. github.com_shurcoo!l_httpfs_v0.0.0-20171119174359-809beceb2371.txt000066400000000000000000000003161453631262600337520ustar00rootroot00000000000000go-internal-1.12.0/cmd/txtar-addmod/testdata/modmodule github.com/shurcooL/httpfs@v0.0.0-20171119174359-809beceb2371 -- .mod -- module github.com/shurcooL/httpfs -- .info -- {"Version":"v0.0.0-20171119174359-809beceb2371","Time":"2017-11-19T17:43:59Z"} go-internal-1.12.0/cmd/txtar-addmod/testdata/to_stdout.txt000066400000000000000000000012031453631262600235470ustar00rootroot00000000000000unquote expect txtar-addmod - github.com/gobin-testrepos/simple-main cmp stdout expect ! stderr .+ -- expect -- >-- .gomodproxy/github.com_gobin-testrepos_simple-main_v1.0.0/.mod -- >module github.com/gobin-testrepos/simple-main >-- .gomodproxy/github.com_gobin-testrepos_simple-main_v1.0.0/.info -- >{"Version":"v1.0.0","Time":"2018-10-22T18:45:39Z"} >-- .gomodproxy/github.com_gobin-testrepos_simple-main_v1.0.0/go.mod -- >module github.com/gobin-testrepos/simple-main >-- .gomodproxy/github.com_gobin-testrepos_simple-main_v1.0.0/main.go -- >package main > >import "fmt" > >func main() { > fmt.Println("I am a simple module-based main") >} go-internal-1.12.0/cmd/txtar-addmod/testdata/txtar-addmod-self.txt000066400000000000000000000006151453631262600250500ustar00rootroot00000000000000mkdir $WORK/out txtar-addmod $WORK/out github.com/gobin-testrepos/simple-main ! stdout .+ ! stderr .+ exists $WORK/out/github.com_gobin-testrepos_simple-main_v1.0.0.txtar ! grep foobar $WORK/out/github.com_gobin-testrepos_simple-main_v1.0.0.txtar txtar-addmod -all $WORK/out github.com/gobin-testrepos/simple-main grep '-- foobar --' $WORK/out/github.com_gobin-testrepos_simple-main_v1.0.0.txtar go-internal-1.12.0/cmd/txtar-c/000077500000000000000000000000001453631262600161475ustar00rootroot00000000000000go-internal-1.12.0/cmd/txtar-c/savedir.go000066400000000000000000000047121453631262600201370ustar00rootroot00000000000000// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // The txtar-c command archives a directory tree as a txtar archive printed to standard output. // // Usage: // // txtar-c /path/to/dir >saved.txtar // // See https://godoc.org/golang.org/x/tools/txtar for details of the format // and how to parse a txtar file. package main import ( "bytes" stdflag "flag" "fmt" "log" "os" "path/filepath" "strings" "unicode/utf8" "github.com/rogpeppe/go-internal/txtar" ) var flag = stdflag.NewFlagSet(os.Args[0], stdflag.ContinueOnError) func usage() { fmt.Fprintf(os.Stderr, "usage: txtar-c dir >saved.txtar\n") flag.PrintDefaults() } var ( quoteFlag = flag.Bool("quote", false, "quote files that contain txtar file markers instead of failing") allFlag = flag.Bool("a", false, "include dot files too") ) func main() { os.Exit(main1()) } func main1() int { flag.Usage = usage if flag.Parse(os.Args[1:]) != nil { return 2 } if flag.NArg() != 1 { usage() return 2 } log.SetPrefix("txtar-c: ") log.SetFlags(0) dir := flag.Arg(0) a := new(txtar.Archive) dir = filepath.Clean(dir) if err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { if err != nil { return err } if path == dir { return nil } name := info.Name() if strings.HasPrefix(name, ".") && !*allFlag { if info.IsDir() { return filepath.SkipDir } return nil } if !info.Mode().IsRegular() { return nil } data, err := os.ReadFile(path) if err != nil { return err } if !utf8.Valid(data) { log.Printf("%s: ignoring file with invalid UTF-8 data", path) return nil } if len(data) > 0 && !bytes.HasSuffix(data, []byte("\n")) { log.Printf("%s: adding final newline", path) data = append(data, '\n') } filename := strings.TrimPrefix(path, dir+string(filepath.Separator)) if txtar.NeedsQuote(data) { if !*quoteFlag { log.Printf("%s: ignoring file with txtar marker in", path) return nil } data, err = txtar.Quote(data) if err != nil { log.Printf("%s: ignoring unquotable file: %v", path, err) return nil } a.Comment = append(a.Comment, []byte("unquote "+filename+"\n")...) } a.Files = append(a.Files, txtar.File{ Name: filepath.ToSlash(filename), Data: data, }) return nil }); err != nil { log.Fatal(err) } data := txtar.Format(a) os.Stdout.Write(data) return 0 } go-internal-1.12.0/cmd/txtar-c/script_test.go000066400000000000000000000007121453631262600210410ustar00rootroot00000000000000// Copyright 2018 The Go 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 main import ( "os" "testing" "github.com/rogpeppe/go-internal/testscript" ) func TestMain(m *testing.M) { os.Exit(testscript.RunMain(m, map[string]func() int{ "txtar-c": main1, })) } func TestScripts(t *testing.T) { testscript.Run(t, testscript.Params{ Dir: "testdata", }) } go-internal-1.12.0/cmd/txtar-c/testdata/000077500000000000000000000000001453631262600177605ustar00rootroot00000000000000go-internal-1.12.0/cmd/txtar-c/testdata/all.txt000066400000000000000000000014111453631262600212660ustar00rootroot00000000000000unquote expect-all unquote expect-no-all # Without the -a flag, it should ignore . files. txtar-c blah ! stderr .+ cmp stdout expect-no-all # With the -a flag, it should include them. txtar-c -a blah ! stderr .+ cmp stdout expect-all -- blah/.foo/foo -- foo -- blah/.other -- other -- blah/go.mod -- module example.com/blah -- blah/main.go -- package main import "fmt" func main() { fmt.Println("Hello, world!") } -- expect-all -- >-- .foo/foo -- >foo >-- .other -- >other >-- go.mod -- >module example.com/blah > >-- main.go -- >package main > >import "fmt" > >func main() { > fmt.Println("Hello, world!") >} -- expect-no-all -- >-- go.mod -- >module example.com/blah > >-- main.go -- >package main > >import "fmt" > >func main() { > fmt.Println("Hello, world!") >} go-internal-1.12.0/cmd/txtar-c/testdata/needquote.txt000066400000000000000000000003441453631262600225130ustar00rootroot00000000000000unquote blah/withsep unquote expect txtar-c blah stderr 'txtar-c: blah.withsep: ignoring file with txtar marker in' cmp stdout expect -- blah/withsep -- >-- separator -- >foo -- blah/nosep -- bar -- expect -- >-- nosep -- >bar go-internal-1.12.0/cmd/txtar-c/testdata/quote.txt000066400000000000000000000003051453631262600216540ustar00rootroot00000000000000unquote blah/withsep unquote expect txtar-c -quote blah ! stderr .+ cmp stdout expect -- blah/withsep -- >-- separator -- >foo -- expect -- >unquote withsep >-- withsep -- >>-- separator -- >>foo go-internal-1.12.0/cmd/txtar-c/testdata/txtar-savedir-self.txt000066400000000000000000000006261453631262600242510ustar00rootroot00000000000000unquote expect txtar-c blah ! stderr .+ cmp stdout expect -- blah/go.mod -- module example.com/blah -- blah/main.go -- package main import "fmt" func main() { fmt.Println("Hello, world!") } -- blah/subdir/x -- x contents -- expect -- >-- go.mod -- >module example.com/blah > >-- main.go -- >package main > >import "fmt" > >func main() { > fmt.Println("Hello, world!") >} >-- subdir/x -- >x contents go-internal-1.12.0/cmd/txtar-goproxy/000077500000000000000000000000001453631262600174345ustar00rootroot00000000000000go-internal-1.12.0/cmd/txtar-goproxy/main.go000066400000000000000000000020361453631262600207100ustar00rootroot00000000000000// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // The txtar-goproxy command runs a Go module proxy from a txtar module // directory (as manipulated by the txtar-addmod command). // // This allows interactive experimentation with the set of proxied modules. // For example: // // cd cmd/go // go test -proxy=localhost:1234 & // export GOPROXY=http://localhost:1234/mod // // and then run go commands as usual. package main import ( "flag" "fmt" "log" "os" "github.com/rogpeppe/go-internal/goproxytest" ) var proxyAddr = flag.String("addr", "", "run proxy on this network address") func usage() { fmt.Fprintf(os.Stderr, "usage: txtar-goproxy [flags] dir\n") flag.PrintDefaults() os.Exit(2) } func main() { flag.Usage = usage flag.Parse() if flag.NArg() != 1 { usage() } srv, err := goproxytest.NewServer(flag.Arg(0), *proxyAddr) if err != nil { log.Fatal(err) } fmt.Printf("export GOPROXY=%s\n", srv.URL) select {} } go-internal-1.12.0/cmd/txtar-x/000077500000000000000000000000001453631262600161745ustar00rootroot00000000000000go-internal-1.12.0/cmd/txtar-x/extract.go000066400000000000000000000023351453631262600202000ustar00rootroot00000000000000// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // The txtar-x command extracts a txtar archive to a filesystem. // // Usage: // // txtar-x [-C root-dir] saved.txt // // See https://godoc.org/golang.org/x/tools/txtar for details of the format // and how to parse a txtar file. package main import ( "flag" "fmt" "io" "log" "os" "github.com/rogpeppe/go-internal/txtar" ) var ( extractDir = flag.String("C", ".", "directory to extract files into") ) func usage() { fmt.Fprintf(os.Stderr, "usage: txtar-x [flags] [file]\n") flag.PrintDefaults() } func main() { os.Exit(main1()) } func main1() int { flag.Usage = usage flag.Parse() if flag.NArg() > 1 { usage() return 2 } log.SetPrefix("txtar-x: ") log.SetFlags(0) var a *txtar.Archive if flag.NArg() == 0 { data, err := io.ReadAll(os.Stdin) if err != nil { log.Printf("cannot read stdin: %v", err) return 1 } a = txtar.Parse(data) } else { a1, err := txtar.ParseFile(flag.Arg(0)) if err != nil { log.Print(err) return 1 } a = a1 } if err := txtar.Write(a, *extractDir); err != nil { log.Print(err) return 1 } return 0 } go-internal-1.12.0/cmd/txtar-x/extract_test.go000066400000000000000000000017001453631262600212320ustar00rootroot00000000000000// Copyright 2018 The Go 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 main import ( "bytes" "os" "testing" "github.com/rogpeppe/go-internal/testscript" ) func TestMain(m *testing.M) { os.Exit(testscript.RunMain(m, map[string]func() int{ "txtar-x": main1, })) } func TestScripts(t *testing.T) { testscript.Run(t, testscript.Params{ Dir: "testdata", Cmds: map[string]func(ts *testscript.TestScript, neg bool, args []string){ "unquote": unquote, }, }) } func unquote(ts *testscript.TestScript, neg bool, args []string) { if neg { ts.Fatalf("unsupported: ! unquote") } for _, arg := range args { file := ts.MkAbs(arg) data, err := os.ReadFile(file) ts.Check(err) data = bytes.Replace(data, []byte("\n>"), []byte("\n"), -1) data = bytes.TrimPrefix(data, []byte(">")) err = os.WriteFile(file, data, 0o666) ts.Check(err) } } go-internal-1.12.0/cmd/txtar-x/testdata/000077500000000000000000000000001453631262600200055ustar00rootroot00000000000000go-internal-1.12.0/cmd/txtar-x/testdata/extract-dir.txt000066400000000000000000000003271453631262600227760ustar00rootroot00000000000000unquote file.txtar txtar-x -C x/y file.txtar cmp x/y/foo expect/foo cmp x/y/a/b/bar expect/a/b/bar -- file.txtar -- >some comment > >-- foo -- >foo >-- a/b/bar -- >bar -- expect/foo -- foo -- expect/a/b/bar -- bar go-internal-1.12.0/cmd/txtar-x/testdata/extract-out-of-bounds.txt000066400000000000000000000003561453631262600247230ustar00rootroot00000000000000unquote file1.txtar file2.txtar ! txtar-x file1.txtar stderr '"\.\./foo": outside parent directory' ! txtar-x file2.txtar stderr '"/foo": outside parent directory' -- file1.txtar -- >-- ../foo -- >foo -- file2.txtar -- >-- /foo -- >foo go-internal-1.12.0/cmd/txtar-x/testdata/extract-stdin.txt000066400000000000000000000003161453631262600233370ustar00rootroot00000000000000unquote file.txtar stdin file.txtar txtar-x cmp foo expect/foo cmp a/b/bar expect/a/b/bar -- file.txtar -- >some comment > >-- foo -- >foo >-- a/b/bar -- >bar -- expect/foo -- foo -- expect/a/b/bar -- bar go-internal-1.12.0/cmd/txtar-x/testdata/extract.txt000066400000000000000000000003101453631262600222120ustar00rootroot00000000000000unquote file.txtar txtar-x file.txtar cmp foo expect/foo cmp a/b/bar expect/a/b/bar -- file.txtar -- >some comment > >-- foo -- >foo >-- a/b/bar -- >bar -- expect/foo -- foo -- expect/a/b/bar -- bar go-internal-1.12.0/diff/000077500000000000000000000000001453631262600147325ustar00rootroot00000000000000go-internal-1.12.0/diff/diff.go000066400000000000000000000170521453631262600161760ustar00rootroot00000000000000// Copyright 2022 The Go 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 diff import ( "bytes" "fmt" "sort" "strings" ) // A pair is a pair of values tracked for both the x and y side of a diff. // It is typically a pair of line indexes. type pair struct{ x, y int } // Diff returns an anchored diff of the two texts old and new // in the “unified diff” format. If old and new are identical, // Diff returns a nil slice (no output). // // Unix diff implementations typically look for a diff with // the smallest number of lines inserted and removed, // which can in the worst case take time quadratic in the // number of lines in the texts. As a result, many implementations // either can be made to run for a long time or cut off the search // after a predetermined amount of work. // // In contrast, this implementation looks for a diff with the // smallest number of “unique” lines inserted and removed, // where unique means a line that appears just once in both old and new. // We call this an “anchored diff” because the unique lines anchor // the chosen matching regions. An anchored diff is usually clearer // than a standard diff, because the algorithm does not try to // reuse unrelated blank lines or closing braces. // The algorithm also guarantees to run in O(n log n) time // instead of the standard O(n²) time. // // Some systems call this approach a “patience diff,” named for // the “patience sorting” algorithm, itself named for a solitaire card game. // We avoid that name for two reasons. First, the name has been used // for a few different variants of the algorithm, so it is imprecise. // Second, the name is frequently interpreted as meaning that you have // to wait longer (to be patient) for the diff, meaning that it is a slower algorithm, // when in fact the algorithm is faster than the standard one. func Diff(oldName string, old []byte, newName string, new []byte) []byte { if bytes.Equal(old, new) { return nil } x := lines(old) y := lines(new) // Print diff header. var out bytes.Buffer fmt.Fprintf(&out, "diff %s %s\n", oldName, newName) fmt.Fprintf(&out, "--- %s\n", oldName) fmt.Fprintf(&out, "+++ %s\n", newName) // Loop over matches to consider, // expanding each match to include surrounding lines, // and then printing diff chunks. // To avoid setup/teardown cases outside the loop, // tgs returns a leading {0,0} and trailing {len(x), len(y)} pair // in the sequence of matches. var ( done pair // printed up to x[:done.x] and y[:done.y] chunk pair // start lines of current chunk count pair // number of lines from each side in current chunk ctext []string // lines for current chunk ) for _, m := range tgs(x, y) { if m.x < done.x { // Already handled scanning forward from earlier match. continue } // Expand matching lines as far possible, // establishing that x[start.x:end.x] == y[start.y:end.y]. // Note that on the first (or last) iteration we may (or definitey do) // have an empty match: start.x==end.x and start.y==end.y. start := m for start.x > done.x && start.y > done.y && x[start.x-1] == y[start.y-1] { start.x-- start.y-- } end := m for end.x < len(x) && end.y < len(y) && x[end.x] == y[end.y] { end.x++ end.y++ } // Emit the mismatched lines before start into this chunk. // (No effect on first sentinel iteration, when start = {0,0}.) for _, s := range x[done.x:start.x] { ctext = append(ctext, "-"+s) count.x++ } for _, s := range y[done.y:start.y] { ctext = append(ctext, "+"+s) count.y++ } // If we're not at EOF and have too few common lines, // the chunk includes all the common lines and continues. const C = 3 // number of context lines if (end.x < len(x) || end.y < len(y)) && (end.x-start.x < C || (len(ctext) > 0 && end.x-start.x < 2*C)) { for _, s := range x[start.x:end.x] { ctext = append(ctext, " "+s) count.x++ count.y++ } done = end continue } // End chunk with common lines for context. if len(ctext) > 0 { n := end.x - start.x if n > C { n = C } for _, s := range x[start.x : start.x+n] { ctext = append(ctext, " "+s) count.x++ count.y++ } done = pair{start.x + n, start.y + n} // Format and emit chunk. // Convert line numbers to 1-indexed. // Special case: empty file shows up as 0,0 not 1,0. if count.x > 0 { chunk.x++ } if count.y > 0 { chunk.y++ } fmt.Fprintf(&out, "@@ -%d,%d +%d,%d @@\n", chunk.x, count.x, chunk.y, count.y) for _, s := range ctext { out.WriteString(s) } count.x = 0 count.y = 0 ctext = ctext[:0] } // If we reached EOF, we're done. if end.x >= len(x) && end.y >= len(y) { break } // Otherwise start a new chunk. chunk = pair{end.x - C, end.y - C} for _, s := range x[chunk.x:end.x] { ctext = append(ctext, " "+s) count.x++ count.y++ } done = end } return out.Bytes() } // lines returns the lines in the file x, including newlines. // If the file does not end in a newline, one is supplied // along with a warning about the missing newline. func lines(x []byte) []string { l := strings.SplitAfter(string(x), "\n") if l[len(l)-1] == "" { l = l[:len(l)-1] } else { // Treat last line as having a message about the missing newline attached, // using the same text as BSD/GNU diff (including the leading backslash). l[len(l)-1] += "\n\\ No newline at end of file\n" } return l } // tgs returns the pairs of indexes of the longest common subsequence // of unique lines in x and y, where a unique line is one that appears // once in x and once in y. // // The longest common subsequence algorithm is as described in // Thomas G. Szymanski, “A Special Case of the Maximal Common // Subsequence Problem,” Princeton TR #170 (January 1975), // available at https://research.swtch.com/tgs170.pdf. func tgs(x, y []string) []pair { // Count the number of times each string appears in a and b. // We only care about 0, 1, many, counted as 0, -1, -2 // for the x side and 0, -4, -8 for the y side. // Using negative numbers now lets us distinguish positive line numbers later. m := make(map[string]int) for _, s := range x { if c := m[s]; c > -2 { m[s] = c - 1 } } for _, s := range y { if c := m[s]; c > -8 { m[s] = c - 4 } } // Now unique strings can be identified by m[s] = -1+-4. // // Gather the indexes of those strings in x and y, building: // xi[i] = increasing indexes of unique strings in x. // yi[i] = increasing indexes of unique strings in y. // inv[i] = index j such that x[xi[i]] = y[yi[j]]. var xi, yi, inv []int for i, s := range y { if m[s] == -1+-4 { m[s] = len(yi) yi = append(yi, i) } } for i, s := range x { if j, ok := m[s]; ok && j >= 0 { xi = append(xi, i) inv = append(inv, j) } } // Apply Algorithm A from Szymanski's paper. // In those terms, A = J = inv and B = [0, n). // We add sentinel pairs {0,0}, and {len(x),len(y)} // to the returned sequence, to help the processing loop. J := inv n := len(xi) T := make([]int, n) L := make([]int, n) for i := range T { T[i] = n + 1 } for i := 0; i < n; i++ { k := sort.Search(n, func(k int) bool { return T[k] >= J[i] }) T[k] = J[i] L[i] = k + 1 } k := 0 for _, v := range L { if k < v { k = v } } seq := make([]pair, 2+k) seq[1+k] = pair{len(x), len(y)} // sentinel at end lastj := n for i := n - 1; i >= 0; i-- { if L[i] == k && J[i] < lastj { seq[k] = pair{xi[i], yi[J[i]]} k-- } } seq[0] = pair{0, 0} // sentinel at start return seq } go-internal-1.12.0/diff/diff_test.go000066400000000000000000000021121453631262600172240ustar00rootroot00000000000000// Copyright 2022 The Go 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 diff import ( "bytes" "path/filepath" "testing" "golang.org/x/tools/txtar" ) func clean(text []byte) []byte { text = bytes.ReplaceAll(text, []byte("$\n"), []byte("\n")) text = bytes.TrimSuffix(text, []byte("^D\n")) return text } func Test(t *testing.T) { files, _ := filepath.Glob("testdata/*.txt") if len(files) == 0 { t.Fatalf("no testdata") } for _, file := range files { t.Run(filepath.Base(file), func(t *testing.T) { a, err := txtar.ParseFile(file) if err != nil { t.Fatal(err) } if len(a.Files) != 3 || a.Files[2].Name != "diff" { t.Fatalf("%s: want three files, third named \"diff\"", file) } diffs := Diff(a.Files[0].Name, clean(a.Files[0].Data), a.Files[1].Name, clean(a.Files[1].Data)) want := clean(a.Files[2].Data) if !bytes.Equal(diffs, want) { t.Fatalf("%s: have:\n%s\nwant:\n%s\n%s", file, diffs, want, Diff("have", diffs, "want", want)) } }) } } go-internal-1.12.0/diff/testdata/000077500000000000000000000000001453631262600165435ustar00rootroot00000000000000go-internal-1.12.0/diff/testdata/allnew.txt000066400000000000000000000001331453631262600205630ustar00rootroot00000000000000-- old -- -- new -- a b c -- diff -- diff old new --- old +++ new @@ -0,0 +1,3 @@ +a +b +c go-internal-1.12.0/diff/testdata/allold.txt000066400000000000000000000001331453631262600205500ustar00rootroot00000000000000-- old -- a b c -- new -- -- diff -- diff old new --- old +++ new @@ -1,3 +0,0 @@ -a -b -c go-internal-1.12.0/diff/testdata/basic.txt000066400000000000000000000004121453631262600203620ustar00rootroot00000000000000Example from Hunt and McIlroy, “An Algorithm for Differential File Comparison.” https://www.cs.dartmouth.edu/~doug/diff.pdf -- old -- a b c d e f g -- new -- w a b x y z e -- diff -- diff old new --- old +++ new @@ -1,7 +1,7 @@ +w a b -c -d +x +y +z e -f -g go-internal-1.12.0/diff/testdata/dups.txt000066400000000000000000000002151453631262600202550ustar00rootroot00000000000000-- old -- a b c d e f -- new -- a B C d e f -- diff -- diff old new --- old +++ new @@ -1,8 +1,8 @@ a $ -b - -c +B + +C $ d $ go-internal-1.12.0/diff/testdata/end.txt000066400000000000000000000002621453631262600200520ustar00rootroot00000000000000-- old -- 1 2 3 4 5 6 7 eight nine ten eleven -- new -- 1 2 3 4 5 6 7 8 9 10 -- diff -- diff old new --- old +++ new @@ -5,7 +5,6 @@ 5 6 7 -eight -nine -ten -eleven +8 +9 +10 go-internal-1.12.0/diff/testdata/eof.txt000066400000000000000000000000571453631262600200570ustar00rootroot00000000000000-- old -- a b c^D -- new -- a b c^D -- diff -- go-internal-1.12.0/diff/testdata/eof1.txt000066400000000000000000000002021453631262600201300ustar00rootroot00000000000000-- old -- a b c -- new -- a b c^D -- diff -- diff old new --- old +++ new @@ -1,3 +1,3 @@ a b -c +c \ No newline at end of file go-internal-1.12.0/diff/testdata/eof2.txt000066400000000000000000000002021453631262600201310ustar00rootroot00000000000000-- old -- a b c^D -- new -- a b c -- diff -- diff old new --- old +++ new @@ -1,3 +1,3 @@ a b -c \ No newline at end of file +c go-internal-1.12.0/diff/testdata/long.txt000066400000000000000000000003751453631262600202500ustar00rootroot00000000000000-- old -- 1 2 3 4 5 6 7 8 9 10 11 12 13 14 14½ 15 16 17 18 19 20 -- new -- 1 2 3 4 5 6 8 9 10 11 12 13 14 17 18 19 20 -- diff -- diff old new --- old +++ new @@ -4,7 +4,6 @@ 4 5 6 -7 8 9 10 @@ -12,9 +11,6 @@ 12 13 14 -14½ -15 -16 17 18 19 go-internal-1.12.0/diff/testdata/same.txt000066400000000000000000000000671453631262600202340ustar00rootroot00000000000000-- old -- hello world -- new -- hello world -- diff -- go-internal-1.12.0/diff/testdata/start.txt000066400000000000000000000002161453631262600204400ustar00rootroot00000000000000-- old -- e pi 4 5 6 7 8 9 10 -- new -- 1 2 3 4 5 6 7 8 9 10 -- diff -- diff old new --- old +++ new @@ -1,5 +1,6 @@ -e -pi +1 +2 +3 4 5 6 go-internal-1.12.0/diff/testdata/triv.txt000066400000000000000000000005441453631262600202730ustar00rootroot00000000000000Another example from Hunt and McIlroy, “An Algorithm for Differential File Comparison.” https://www.cs.dartmouth.edu/~doug/diff.pdf Anchored diff gives up on finding anything, since there are no unique lines. -- old -- a b c a b b a -- new -- c a b a b c -- diff -- diff old new --- old +++ new @@ -1,7 +1,6 @@ -a -b -c -a -b -b -a +c +a +b +a +b +c go-internal-1.12.0/dirhash/000077500000000000000000000000001453631262600154445ustar00rootroot00000000000000go-internal-1.12.0/dirhash/hash.go000066400000000000000000000045011453631262600167160ustar00rootroot00000000000000// Copyright 2018 The Go 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 dirhash defines hashes over directory trees. package dirhash import ( "archive/zip" "crypto/sha256" "encoding/base64" "errors" "fmt" "io" "os" "path/filepath" "sort" "strings" ) var DefaultHash = Hash1 type Hash func(files []string, open func(string) (io.ReadCloser, error)) (string, error) func Hash1(files []string, open func(string) (io.ReadCloser, error)) (string, error) { h := sha256.New() files = append([]string(nil), files...) sort.Strings(files) for _, file := range files { if strings.Contains(file, "\n") { return "", errors.New("filenames with newlines are not supported") } r, err := open(file) if err != nil { return "", err } hf := sha256.New() _, err = io.Copy(hf, r) r.Close() if err != nil { return "", err } fmt.Fprintf(h, "%x %s\n", hf.Sum(nil), file) } return "h1:" + base64.StdEncoding.EncodeToString(h.Sum(nil)), nil } func HashDir(dir, prefix string, hash Hash) (string, error) { files, err := DirFiles(dir, prefix) if err != nil { return "", err } osOpen := func(name string) (io.ReadCloser, error) { return os.Open(filepath.Join(dir, strings.TrimPrefix(name, prefix))) } return hash(files, osOpen) } func DirFiles(dir, prefix string) ([]string, error) { var files []string dir = filepath.Clean(dir) err := filepath.Walk(dir, func(file string, info os.FileInfo, err error) error { if err != nil { return err } if info.IsDir() { return nil } rel := file if dir != "." { rel = file[len(dir)+1:] } f := filepath.Join(prefix, rel) files = append(files, filepath.ToSlash(f)) return nil }) if err != nil { return nil, err } return files, nil } func HashZip(zipfile string, hash Hash) (string, error) { z, err := zip.OpenReader(zipfile) if err != nil { return "", err } defer z.Close() var files []string zfiles := make(map[string]*zip.File) for _, file := range z.File { files = append(files, file.Name) zfiles[file.Name] = file } zipOpen := func(name string) (io.ReadCloser, error) { f := zfiles[name] if f == nil { return nil, fmt.Errorf("file %q not found in zip", name) // should never happen } return f.Open() } return hash(files, zipOpen) } go-internal-1.12.0/dirhash/hash_test.go000066400000000000000000000064761453631262600177720ustar00rootroot00000000000000// Copyright 2018 The Go 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 dirhash import ( "archive/zip" "crypto/sha256" "encoding/base64" "fmt" "io" "io/ioutil" "os" "path/filepath" "strings" "testing" ) func h(s string) string { return fmt.Sprintf("%x", sha256.Sum256([]byte(s))) } func htop(k string, s string) string { sum := sha256.Sum256([]byte(s)) return k + ":" + base64.StdEncoding.EncodeToString(sum[:]) } func TestHash1(t *testing.T) { files := []string{"xyz", "abc"} open := func(name string) (io.ReadCloser, error) { return ioutil.NopCloser(strings.NewReader("data for " + name)), nil } want := htop("h1", fmt.Sprintf("%s %s\n%s %s\n", h("data for abc"), "abc", h("data for xyz"), "xyz")) out, err := Hash1(files, open) if err != nil { t.Fatal(err) } if out != want { t.Errorf("Hash1(...) = %s, want %s", out, want) } _, err = Hash1([]string{"xyz", "a\nbc"}, open) if err == nil { t.Error("Hash1: expected error on newline in filenames") } } func TestHashDir(t *testing.T) { dir, err := ioutil.TempDir("", "dirhash-test-") if err != nil { t.Fatal(err) } defer os.RemoveAll(dir) if err := ioutil.WriteFile(filepath.Join(dir, "xyz"), []byte("data for xyz"), 0o666); err != nil { t.Fatal(err) } if err := ioutil.WriteFile(filepath.Join(dir, "abc"), []byte("data for abc"), 0o666); err != nil { t.Fatal(err) } want := htop("h1", fmt.Sprintf("%s %s\n%s %s\n", h("data for abc"), "prefix/abc", h("data for xyz"), "prefix/xyz")) out, err := HashDir(dir, "prefix", Hash1) if err != nil { t.Fatalf("HashDir: %v", err) } if out != want { t.Errorf("HashDir(...) = %s, want %s", out, want) } } func TestHashZip(t *testing.T) { f, err := ioutil.TempFile("", "dirhash-test-") if err != nil { t.Fatal(err) } defer os.Remove(f.Name()) defer f.Close() z := zip.NewWriter(f) w, err := z.Create("prefix/xyz") if err != nil { t.Fatal(err) } w.Write([]byte("data for xyz")) w, err = z.Create("prefix/abc") if err != nil { t.Fatal(err) } w.Write([]byte("data for abc")) if err := z.Close(); err != nil { t.Fatal(err) } if err := f.Close(); err != nil { t.Fatal(err) } want := htop("h1", fmt.Sprintf("%s %s\n%s %s\n", h("data for abc"), "prefix/abc", h("data for xyz"), "prefix/xyz")) out, err := HashZip(f.Name(), Hash1) if err != nil { t.Fatalf("HashDir: %v", err) } if out != want { t.Errorf("HashDir(...) = %s, want %s", out, want) } } func TestDirFiles(t *testing.T) { dir, err := ioutil.TempDir("", "dirfiles-test-") if err != nil { t.Fatal(err) } defer os.RemoveAll(dir) if err := ioutil.WriteFile(filepath.Join(dir, "xyz"), []byte("data for xyz"), 0o666); err != nil { t.Fatal(err) } if err := ioutil.WriteFile(filepath.Join(dir, "abc"), []byte("data for abc"), 0o666); err != nil { t.Fatal(err) } if err := os.Mkdir(filepath.Join(dir, "subdir"), 0o777); err != nil { t.Fatal(err) } if err := ioutil.WriteFile(filepath.Join(dir, "subdir", "xyz"), []byte("data for subdir xyz"), 0o666); err != nil { t.Fatal(err) } prefix := "foo/bar@v2.3.4" out, err := DirFiles(dir, prefix) if err != nil { t.Fatalf("DirFiles: %v", err) } for _, file := range out { if !strings.HasPrefix(file, prefix) { t.Errorf("Dir file = %s, want prefix %s", file, prefix) } } } go-internal-1.12.0/fmtsort/000077500000000000000000000000001453631262600155205ustar00rootroot00000000000000go-internal-1.12.0/fmtsort/export_test.go000066400000000000000000000004411453631262600204260ustar00rootroot00000000000000// Copyright 2018 The Go 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 fmtsort import "reflect" func Compare(a, b reflect.Value) int { return compare(a, b) } const BrokenNaNs = brokenNaNs go-internal-1.12.0/fmtsort/mapelem.go000066400000000000000000000010531453631262600174660ustar00rootroot00000000000000package fmtsort import "reflect" const brokenNaNs = false func mapElems(mapValue reflect.Value) ([]reflect.Value, []reflect.Value) { // Note: this code is arranged to not panic even in the presence // of a concurrent map update. The runtime is responsible for // yelling loudly if that happens. See issue 33275. n := mapValue.Len() key := make([]reflect.Value, 0, n) value := make([]reflect.Value, 0, n) iter := mapValue.MapRange() for iter.Next() { key = append(key, iter.Key()) value = append(value, iter.Value()) } return key, value } go-internal-1.12.0/fmtsort/sort.go000066400000000000000000000127301453631262600170410ustar00rootroot00000000000000// Copyright 2018 The Go 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 fmtsort provides a general stable ordering mechanism // for maps, on behalf of the fmt and text/template packages. // It is not guaranteed to be efficient and works only for types // that are valid map keys. package fmtsort import ( "reflect" "sort" ) // Note: Throughout this package we avoid calling reflect.Value.Interface as // it is not always legal to do so and it's easier to avoid the issue than to face it. // SortedMap represents a map's keys and values. The keys and values are // aligned in index order: Value[i] is the value in the map corresponding to Key[i]. type SortedMap struct { Key []reflect.Value Value []reflect.Value } func (o *SortedMap) Len() int { return len(o.Key) } func (o *SortedMap) Less(i, j int) bool { return compare(o.Key[i], o.Key[j]) < 0 } func (o *SortedMap) Swap(i, j int) { o.Key[i], o.Key[j] = o.Key[j], o.Key[i] o.Value[i], o.Value[j] = o.Value[j], o.Value[i] } // Sort accepts a map and returns a SortedMap that has the same keys and // values but in a stable sorted order according to the keys, modulo issues // raised by unorderable key values such as NaNs. // // The ordering rules are more general than with Go's < operator: // // - when applicable, nil compares low // - ints, floats, and strings order by < // - NaN compares less than non-NaN floats // - bool compares false before true // - complex compares real, then imag // - pointers compare by machine address // - channel values compare by machine address // - structs compare each field in turn // - arrays compare each element in turn. // Otherwise identical arrays compare by length. // - interface values compare first by reflect.Type describing the concrete type // and then by concrete value as described in the previous rules. func Sort(mapValue reflect.Value) *SortedMap { if mapValue.Type().Kind() != reflect.Map { return nil } key, value := mapElems(mapValue) sorted := &SortedMap{ Key: key, Value: value, } sort.Stable(sorted) return sorted } // compare compares two values of the same type. It returns -1, 0, 1 // according to whether a > b (1), a == b (0), or a < b (-1). // If the types differ, it returns -1. // See the comment on Sort for the comparison rules. func compare(aVal, bVal reflect.Value) int { aType, bType := aVal.Type(), bVal.Type() if aType != bType { return -1 // No good answer possible, but don't return 0: they're not equal. } switch aVal.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: a, b := aVal.Int(), bVal.Int() switch { case a < b: return -1 case a > b: return 1 default: return 0 } case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: a, b := aVal.Uint(), bVal.Uint() switch { case a < b: return -1 case a > b: return 1 default: return 0 } case reflect.String: a, b := aVal.String(), bVal.String() switch { case a < b: return -1 case a > b: return 1 default: return 0 } case reflect.Float32, reflect.Float64: return floatCompare(aVal.Float(), bVal.Float()) case reflect.Complex64, reflect.Complex128: a, b := aVal.Complex(), bVal.Complex() if c := floatCompare(real(a), real(b)); c != 0 { return c } return floatCompare(imag(a), imag(b)) case reflect.Bool: a, b := aVal.Bool(), bVal.Bool() switch { case a == b: return 0 case a: return 1 default: return -1 } case reflect.Ptr: a, b := aVal.Pointer(), bVal.Pointer() switch { case a < b: return -1 case a > b: return 1 default: return 0 } case reflect.Chan: if c, ok := nilCompare(aVal, bVal); ok { return c } ap, bp := aVal.Pointer(), bVal.Pointer() switch { case ap < bp: return -1 case ap > bp: return 1 default: return 0 } case reflect.Struct: for i := 0; i < aVal.NumField(); i++ { if c := compare(aVal.Field(i), bVal.Field(i)); c != 0 { return c } } return 0 case reflect.Array: for i := 0; i < aVal.Len(); i++ { if c := compare(aVal.Index(i), bVal.Index(i)); c != 0 { return c } } return 0 case reflect.Interface: if c, ok := nilCompare(aVal, bVal); ok { return c } c := compare(reflect.ValueOf(aVal.Elem().Type()), reflect.ValueOf(bVal.Elem().Type())) if c != 0 { return c } return compare(aVal.Elem(), bVal.Elem()) default: // Certain types cannot appear as keys (maps, funcs, slices), but be explicit. panic("bad type in compare: " + aType.String()) } } // nilCompare checks whether either value is nil. If not, the boolean is false. // If either value is nil, the boolean is true and the integer is the comparison // value. The comparison is defined to be 0 if both are nil, otherwise the one // nil value compares low. Both arguments must represent a chan, func, // interface, map, pointer, or slice. func nilCompare(aVal, bVal reflect.Value) (int, bool) { if aVal.IsNil() { if bVal.IsNil() { return 0, true } return -1, true } if bVal.IsNil() { return 1, true } return 0, false } // floatCompare compares two floating-point values. NaNs compare low. func floatCompare(a, b float64) int { switch { case isNaN(a): return -1 // No good answer if b is a NaN so don't bother checking. case isNaN(b): return 1 case a < b: return -1 case a > b: return 1 } return 0 } func isNaN(a float64) bool { return a != a } go-internal-1.12.0/fmtsort/sort_test.go000066400000000000000000000153551453631262600201060ustar00rootroot00000000000000// Copyright 2018 The Go 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 fmtsort_test import ( "fmt" "math" "reflect" "strings" "testing" "github.com/rogpeppe/go-internal/fmtsort" ) var compareTests = [][]reflect.Value{ ct(reflect.TypeOf(int(0)), -1, 0, 1), ct(reflect.TypeOf(int8(0)), -1, 0, 1), ct(reflect.TypeOf(int16(0)), -1, 0, 1), ct(reflect.TypeOf(int32(0)), -1, 0, 1), ct(reflect.TypeOf(int64(0)), -1, 0, 1), ct(reflect.TypeOf(uint(0)), 0, 1, 5), ct(reflect.TypeOf(uint8(0)), 0, 1, 5), ct(reflect.TypeOf(uint16(0)), 0, 1, 5), ct(reflect.TypeOf(uint32(0)), 0, 1, 5), ct(reflect.TypeOf(uint64(0)), 0, 1, 5), ct(reflect.TypeOf(uintptr(0)), 0, 1, 5), ct(reflect.TypeOf(string("")), "", "a", "ab"), ct(reflect.TypeOf(float32(0)), math.NaN(), math.Inf(-1), -1e10, 0, 1e10, math.Inf(1)), ct(reflect.TypeOf(float64(0)), math.NaN(), math.Inf(-1), -1e10, 0, 1e10, math.Inf(1)), ct(reflect.TypeOf(complex64(0+1i)), -1-1i, -1+0i, -1+1i, 0-1i, 0+0i, 0+1i, 1-1i, 1+0i, 1+1i), ct(reflect.TypeOf(complex128(0+1i)), -1-1i, -1+0i, -1+1i, 0-1i, 0+0i, 0+1i, 1-1i, 1+0i, 1+1i), ct(reflect.TypeOf(false), false, true), ct(reflect.TypeOf(&ints[0]), &ints[0], &ints[1], &ints[2]), ct(reflect.TypeOf(chans[0]), chans[0], chans[1], chans[2]), ct(reflect.TypeOf(toy{}), toy{0, 1}, toy{0, 2}, toy{1, -1}, toy{1, 1}), ct(reflect.TypeOf([2]int{}), [2]int{1, 1}, [2]int{1, 2}, [2]int{2, 0}), ct(reflect.TypeOf(interface{}(interface{}(0))), iFace, 1, 2, 3), } var iFace interface{} func ct(typ reflect.Type, args ...interface{}) []reflect.Value { value := make([]reflect.Value, len(args)) for i, v := range args { x := reflect.ValueOf(v) if !x.IsValid() { // Make it a typed nil. x = reflect.Zero(typ) } else { x = x.Convert(typ) } value[i] = x } return value } func TestCompare(t *testing.T) { for _, test := range compareTests { for i, v0 := range test { for j, v1 := range test { c := fmtsort.Compare(v0, v1) var expect int switch { case i == j: expect = 0 // NaNs are tricky. if typ := v0.Type(); (typ.Kind() == reflect.Float32 || typ.Kind() == reflect.Float64) && math.IsNaN(v0.Float()) { expect = -1 } case i < j: expect = -1 case i > j: expect = 1 } if c != expect { t.Errorf("%s: compare(%v,%v)=%d; expect %d", v0.Type(), v0, v1, c, expect) } } } } } type sortTest struct { data interface{} // Always a map. print string // Printed result using our custom printer. printBrokenNaNs string // Printed result when NaN support is broken (pre Go1.12). } var sortTests = []sortTest{ { data: map[int]string{7: "bar", -3: "foo"}, print: "-3:foo 7:bar", }, { data: map[uint8]string{7: "bar", 3: "foo"}, print: "3:foo 7:bar", }, { data: map[string]string{"7": "bar", "3": "foo"}, print: "3:foo 7:bar", }, { data: map[float64]string{7: "bar", -3: "foo", math.NaN(): "nan", math.Inf(0): "inf"}, print: "NaN:nan -3:foo 7:bar +Inf:inf", printBrokenNaNs: "NaN: -3:foo 7:bar +Inf:inf", }, { data: map[complex128]string{7 + 2i: "bar2", 7 + 1i: "bar", -3: "foo", complex(math.NaN(), 0i): "nan", complex(math.Inf(0), 0i): "inf"}, print: "(NaN+0i):nan (-3+0i):foo (7+1i):bar (7+2i):bar2 (+Inf+0i):inf", printBrokenNaNs: "(NaN+0i): (-3+0i):foo (7+1i):bar (7+2i):bar2 (+Inf+0i):inf", }, { data: map[bool]string{true: "true", false: "false"}, print: "false:false true:true", }, { data: chanMap(), print: "CHAN0:0 CHAN1:1 CHAN2:2", }, { data: pointerMap(), print: "PTR0:0 PTR1:1 PTR2:2", }, { data: map[toy]string{toy{7, 2}: "72", toy{7, 1}: "71", toy{3, 4}: "34"}, print: "{3 4}:34 {7 1}:71 {7 2}:72", }, { data: map[[2]int]string{{7, 2}: "72", {7, 1}: "71", {3, 4}: "34"}, print: "[3 4]:34 [7 1]:71 [7 2]:72", }, } func sprint(data interface{}) string { om := fmtsort.Sort(reflect.ValueOf(data)) if om == nil { return "nil" } b := new(strings.Builder) for i, key := range om.Key { if i > 0 { b.WriteRune(' ') } b.WriteString(sprintKey(key)) b.WriteRune(':') b.WriteString(fmt.Sprint(om.Value[i])) } return b.String() } // sprintKey formats a reflect.Value but gives reproducible values for some // problematic types such as pointers. Note that it only does special handling // for the troublesome types used in the test cases; it is not a general // printer. func sprintKey(key reflect.Value) string { switch str := key.Type().String(); str { case "*int": ptr := key.Interface().(*int) for i := range ints { if ptr == &ints[i] { return fmt.Sprintf("PTR%d", i) } } return "PTR???" case "chan int": c := key.Interface().(chan int) for i := range chans { if c == chans[i] { return fmt.Sprintf("CHAN%d", i) } } return "CHAN???" default: return fmt.Sprint(key) } } var ( ints [3]int chans = [3]chan int{make(chan int), make(chan int), make(chan int)} ) func pointerMap() map[*int]string { m := make(map[*int]string) for i := 2; i >= 0; i-- { m[&ints[i]] = fmt.Sprint(i) } return m } func chanMap() map[chan int]string { m := make(map[chan int]string) for i := 2; i >= 0; i-- { m[chans[i]] = fmt.Sprint(i) } return m } type toy struct { A int // Exported. b int // Unexported. } func TestOrder(t *testing.T) { for _, test := range sortTests { got := sprint(test.data) want := test.print if fmtsort.BrokenNaNs && test.printBrokenNaNs != "" { want = test.printBrokenNaNs } if got != want { t.Errorf("%s: got %q, want %q", reflect.TypeOf(test.data), got, want) } } } func TestInterface(t *testing.T) { // A map containing multiple concrete types should be sorted by type, // then value. However, the relative ordering of types is unspecified, // so test this by checking the presence of sorted subgroups. m := map[interface{}]string{ [2]int{1, 0}: "", [2]int{0, 1}: "", true: "", false: "", 3.1: "", 2.1: "", 1.1: "", math.NaN(): "", 3: "", 2: "", 1: "", "c": "", "b": "", "a": "", struct{ x, y int }{1, 0}: "", struct{ x, y int }{0, 1}: "", } got := sprint(m) typeGroups := []string{ "NaN: 1.1: 2.1: 3.1:", // float64 "false: true:", // bool "1: 2: 3:", // int "a: b: c:", // string "[0 1]: [1 0]:", // [2]int "{0 1}: {1 0}:", // struct{ x int; y int } } for _, g := range typeGroups { if !strings.Contains(got, g) { t.Errorf("sorted map should contain %q", g) } } } go-internal-1.12.0/go.mod000066400000000000000000000002471453631262600151330ustar00rootroot00000000000000module github.com/rogpeppe/go-internal go 1.20 require ( golang.org/x/mod v0.9.0 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f golang.org/x/tools v0.1.12 ) go-internal-1.12.0/go.sum000066400000000000000000000010031453631262600151470ustar00rootroot00000000000000golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= go-internal-1.12.0/goproxytest/000077500000000000000000000000001453631262600164315ustar00rootroot00000000000000go-internal-1.12.0/goproxytest/allhex.go000066400000000000000000000010021453631262600202260ustar00rootroot00000000000000// Copyright 2018 The Go 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 goproxytest // This code was taken from src/cmd/go/internal/modfetch/codehost. // allHex reports whether the revision rev is entirely lower-case hexadecimal digits. func allHex(rev string) bool { for i := 0; i < len(rev); i++ { c := rev[i] if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' { continue } return false } return true } go-internal-1.12.0/goproxytest/proxy.go000066400000000000000000000204301453631262600201400ustar00rootroot00000000000000// Copyright 2018 The Go 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 goproxytest serves Go modules from a proxy server designed to run on localhost during tests, both to make tests avoid requiring specific network servers and also to make them significantly faster. Each module archive is either a file named path_vers.txtar or path_vers.txt, or a directory named path_vers, where slashes in path have been replaced with underscores. The archive or directory must contain two files ".info" and ".mod", to be served as the info and mod files in the proxy protocol (see https://research.swtch.com/vgo-module). The remaining files are served as the content of the module zip file. The path@vers prefix required of files in the zip file is added automatically by the proxy: the files in the archive have names without the prefix, like plain "go.mod", "x.go", and so on. See ../cmd/txtar-addmod and ../cmd/txtar-c for tools generate txtar files, although it's fine to write them by hand. */ package goproxytest import ( "archive/zip" "bytes" "encoding/json" "fmt" "io/fs" "log" "net" "net/http" "os" "path/filepath" "strings" "golang.org/x/mod/module" "golang.org/x/mod/semver" "golang.org/x/tools/txtar" "github.com/rogpeppe/go-internal/par" ) type Server struct { server *http.Server URL string dir string modList []module.Version zipCache par.Cache archiveCache par.Cache } // StartProxy starts the Go module proxy listening on the given // network address. It serves modules taken from the given directory // name. If addr is empty, it will listen on an arbitrary // localhost port. If dir is empty, "testmod" will be used. // // The returned Server should be closed after use. func NewServer(dir, addr string) (*Server, error) { var srv Server if addr == "" { addr = "localhost:0" } if dir == "" { dir = "testmod" } srv.dir = dir if err := srv.readModList(); err != nil { return nil, fmt.Errorf("cannot read modules: %v", err) } l, err := net.Listen("tcp", addr) if err != nil { return nil, fmt.Errorf("cannot listen on %q: %v", addr, err) } srv.server = &http.Server{ Handler: http.HandlerFunc(srv.handler), } addr = l.Addr().String() srv.URL = "http://" + addr + "/mod" go func() { if err := srv.server.Serve(l); err != nil && err != http.ErrServerClosed { log.Printf("go proxy: http.Serve: %v", err) } }() return &srv, nil } // Close shuts down the proxy. func (srv *Server) Close() { srv.server.Close() } func (srv *Server) readModList() error { entries, err := os.ReadDir(srv.dir) if err != nil { return err } for _, entry := range entries { name := entry.Name() switch { case strings.HasSuffix(name, ".txt"): name = strings.TrimSuffix(name, ".txt") case strings.HasSuffix(name, ".txtar"): name = strings.TrimSuffix(name, ".txtar") case entry.IsDir(): default: continue } i := strings.LastIndex(name, "_v") if i < 0 { continue } encPath := strings.ReplaceAll(name[:i], "_", "/") path, err := module.UnescapePath(encPath) if err != nil { return fmt.Errorf("cannot decode module path in %q: %v", name, err) } encVers := name[i+1:] vers, err := module.UnescapeVersion(encVers) if err != nil { return fmt.Errorf("cannot decode module version in %q: %v", name, err) } srv.modList = append(srv.modList, module.Version{Path: path, Version: vers}) } return nil } // handler serves the Go module proxy protocol. // See the proxy section of https://research.swtch.com/vgo-module. func (srv *Server) handler(w http.ResponseWriter, r *http.Request) { if !strings.HasPrefix(r.URL.Path, "/mod/") { http.NotFound(w, r) return } path := strings.TrimPrefix(r.URL.Path, "/mod/") i := strings.Index(path, "/@v/") if i < 0 { http.NotFound(w, r) return } enc, file := path[:i], path[i+len("/@v/"):] path, err := module.UnescapePath(enc) if err != nil { fmt.Fprintf(os.Stderr, "go proxy_test: %v\n", err) http.NotFound(w, r) return } if file == "list" { n := 0 for _, m := range srv.modList { if m.Path == path && !isPseudoVersion(m.Version) { if err := module.Check(m.Path, m.Version); err == nil { fmt.Fprintf(w, "%s\n", m.Version) n++ } } } if n == 0 { http.NotFound(w, r) } return } i = strings.LastIndex(file, ".") if i < 0 { http.NotFound(w, r) return } encVers, ext := file[:i], file[i+1:] vers, err := module.UnescapeVersion(encVers) if err != nil { fmt.Fprintf(os.Stderr, "go proxy_test: %v\n", err) http.NotFound(w, r) return } if allHex(vers) { var best string // Convert commit hash (only) to known version. // Use latest version in semver priority, to match similar logic // in the repo-based module server (see modfetch.(*codeRepo).convert). for _, m := range srv.modList { if m.Path == path && semver.Compare(best, m.Version) < 0 { var hash string if isPseudoVersion(m.Version) { hash = m.Version[strings.LastIndex(m.Version, "-")+1:] } else { hash = srv.findHash(m) } if strings.HasPrefix(hash, vers) || strings.HasPrefix(vers, hash) { best = m.Version } } } if best != "" { vers = best } } a := srv.readArchive(path, vers) if a == nil { // As of https://go-review.googlesource.com/c/go/+/189517, cmd/go // resolves all paths. i.e. for github.com/hello/world, cmd/go attempts // to resolve github.com, github.com/hello and github.com/hello/world. // cmd/go expects a 404/410 response if there is nothing there. Hence we // cannot return with a 500. fmt.Fprintf(os.Stderr, "go proxy: no archive %s %s\n", path, vers) http.NotFound(w, r) return } switch ext { case "info", "mod": want := "." + ext for _, f := range a.Files { if f.Name == want { w.Write(f.Data) return } } case "zip": type cached struct { zip []byte err error } c := srv.zipCache.Do(a, func() interface{} { var buf bytes.Buffer z := zip.NewWriter(&buf) for _, f := range a.Files { if strings.HasPrefix(f.Name, ".") { continue } zf, err := z.Create(path + "@" + vers + "/" + f.Name) if err != nil { return cached{nil, err} } if _, err := zf.Write(f.Data); err != nil { return cached{nil, err} } } if err := z.Close(); err != nil { return cached{nil, err} } return cached{buf.Bytes(), nil} }).(cached) if c.err != nil { fmt.Fprintf(os.Stderr, "go proxy: %v\n", c.err) http.Error(w, c.err.Error(), 500) return } w.Write(c.zip) return } http.NotFound(w, r) } func (srv *Server) findHash(m module.Version) string { a := srv.readArchive(m.Path, m.Version) if a == nil { return "" } var data []byte for _, f := range a.Files { if f.Name == ".info" { data = f.Data break } } var info struct{ Short string } json.Unmarshal(data, &info) return info.Short } func (srv *Server) readArchive(path, vers string) *txtar.Archive { enc, err := module.EscapePath(path) if err != nil { fmt.Fprintf(os.Stderr, "go proxy: %v\n", err) return nil } encVers, err := module.EscapeVersion(vers) if err != nil { fmt.Fprintf(os.Stderr, "go proxy: %v\n", err) return nil } prefix := strings.ReplaceAll(enc, "/", "_") name := filepath.Join(srv.dir, prefix+"_"+encVers) txtName := name + ".txt" txtarName := name + ".txtar" a := srv.archiveCache.Do(name, func() interface{} { a, err := txtar.ParseFile(txtarName) if os.IsNotExist(err) { // fall back to trying with the .txt extension a, err = txtar.ParseFile(txtName) } if os.IsNotExist(err) { // fall back to trying a directory a = new(txtar.Archive) err = filepath.WalkDir(name, func(path string, entry fs.DirEntry, err error) error { if err != nil { return err } if path == name && !entry.IsDir() { return fmt.Errorf("expected a directory root") } if entry.IsDir() { return nil } arpath := filepath.ToSlash(strings.TrimPrefix(path, name+string(os.PathSeparator))) data, err := os.ReadFile(path) if err != nil { return err } a.Files = append(a.Files, txtar.File{ Name: arpath, Data: data, }) return nil }) } if err != nil { if !os.IsNotExist(err) { fmt.Fprintf(os.Stderr, "go proxy: %v\n", err) } a = nil } return a }).(*txtar.Archive) return a } go-internal-1.12.0/goproxytest/proxy_test.go000066400000000000000000000014441453631262600212030ustar00rootroot00000000000000// Copyright 2018 The Go 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 goproxytest_test import ( "path/filepath" "testing" "github.com/rogpeppe/go-internal/goproxytest" "github.com/rogpeppe/go-internal/gotooltest" "github.com/rogpeppe/go-internal/testscript" ) func TestScripts(t *testing.T) { srv, err := goproxytest.NewServer(filepath.Join("testdata", "mod"), "") if err != nil { t.Fatalf("cannot start proxy: %v", err) } p := testscript.Params{ Dir: "testdata", Setup: func(e *testscript.Env) error { e.Vars = append(e.Vars, "GOPROXY="+srv.URL, "GONOSUMDB=*", ) return nil }, } if err := gotooltest.Setup(&p); err != nil { t.Fatal(err) } testscript.Run(t, p) } go-internal-1.12.0/goproxytest/pseudo.go000066400000000000000000000011511453631262600202550ustar00rootroot00000000000000// Copyright 2018 The Go 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 goproxytest import ( "regexp" "strings" "golang.org/x/mod/semver" ) // This code was taken from cmd/go/internal/modfetch/pseudo.go var pseudoVersionRE = regexp.MustCompile(`^v[0-9]+\.(0\.0-|\d+\.\d+-([^+]*\.)?0\.)\d{14}-[A-Za-z0-9]+(\+incompatible)?$`) // isPseudoVersion reports whether v is a pseudo-version. func isPseudoVersion(v string) bool { return strings.Count(v, "-") >= 2 && semver.IsValid(v) && pseudoVersionRE.MatchString(v) } go-internal-1.12.0/goproxytest/testdata/000077500000000000000000000000001453631262600202425ustar00rootroot00000000000000go-internal-1.12.0/goproxytest/testdata/list.txt000066400000000000000000000007411453631262600217600ustar00rootroot00000000000000go list -m -versions fruit.com stdout 'v1.0.0 v1.1.0' go get -d fruit.com@v1.0.0 go get -d fruit.com@v1.1.0 # On Go 1.18 and later, this will error out if GOPATH is ${WORK}/gopath, # as that places GOMODCACHE inside the Go module and "mod tidy" walks it. # "mod tidy" then complains about invalid import paths such as # "mod/gopath/pkg/mod/fruit.com@v1.1.0/fruit". # It's for that reason that we moved the default GOPATH to ${WORK}/.gopath. go mod tidy -- go.mod -- module mod go-internal-1.12.0/goproxytest/testdata/mod/000077500000000000000000000000001453631262600210215ustar00rootroot00000000000000go-internal-1.12.0/goproxytest/testdata/mod/fruit.com_v1.0.0.txt000066400000000000000000000002651453631262600243750ustar00rootroot00000000000000-- .mod -- module fruit.com -- .info -- {"Version":"v1.0.0","Time":"2018-10-22T18:45:39Z"} -- go.mod -- module fruit.com -- fruit/fruit.go -- package main const Name = "Orange" go-internal-1.12.0/goproxytest/testdata/mod/fruit.com_v1.1.0/000077500000000000000000000000001453631262600236325ustar00rootroot00000000000000go-internal-1.12.0/goproxytest/testdata/mod/fruit.com_v1.1.0/.info000066400000000000000000000000631453631262600245650ustar00rootroot00000000000000{"Version":"v1.1.0","Time":"2018-10-22T18:45:39Z"} go-internal-1.12.0/goproxytest/testdata/mod/fruit.com_v1.1.0/.mod000066400000000000000000000000211453631262600244030ustar00rootroot00000000000000module fruit.com go-internal-1.12.0/goproxytest/testdata/mod/fruit.com_v1.1.0/fruit/000077500000000000000000000000001453631262600247635ustar00rootroot00000000000000go-internal-1.12.0/goproxytest/testdata/mod/fruit.com_v1.1.0/fruit/main.go000066400000000000000000000000441453631262600262340ustar00rootroot00000000000000package fruit const Name = "Apple" go-internal-1.12.0/gotooltest/000077500000000000000000000000001453631262600162255ustar00rootroot00000000000000go-internal-1.12.0/gotooltest/script_test.go000066400000000000000000000014441453631262600211220ustar00rootroot00000000000000// Copyright 2018 The Go 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 gotooltest_test import ( "os" "path/filepath" "testing" "github.com/rogpeppe/go-internal/gotooltest" "github.com/rogpeppe/go-internal/testscript" ) func TestSimple(t *testing.T) { p := testscript.Params{ Dir: "testdata", Setup: func(env *testscript.Env) error { // cover.txt will need testscript as a dependency. // Tell it where our module is, via an absolute path. wd, err := os.Getwd() if err != nil { return err } modPath := filepath.Dir(wd) env.Setenv("GOINTERNAL_MODULE", modPath) return nil }, } if err := gotooltest.Setup(&p); err != nil { t.Fatal(err) } testscript.Run(t, p) } go-internal-1.12.0/gotooltest/setup.go000066400000000000000000000107661453631262600177260ustar00rootroot00000000000000// Copyright 2015 The Go 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 gotooltest implements functionality useful for testing // tools that use the go command. package gotooltest import ( "bytes" "encoding/json" "fmt" "os" "os/exec" "path/filepath" "regexp" "runtime" "strings" "sync" "github.com/rogpeppe/go-internal/testscript" ) var ( goVersionRegex = regexp.MustCompile(`^go([1-9][0-9]*)\.([1-9][0-9]*)$`) goEnv struct { GOROOT string GOCACHE string GOPROXY string goversion string releaseTags []string once sync.Once err error } ) // initGoEnv initialises goEnv. It should only be called using goEnv.once.Do, // as in Setup. // // Run all of these probe commands in a temporary directory, so as not to make // any assumptions about the caller's working directory. func initGoEnv() (err error) { td, err := os.MkdirTemp("", "gotooltest-initGoEnv") if err != nil { return fmt.Errorf("failed to create temporary directory for go command tests: %w", err) } defer func() { if rerr := os.RemoveAll(td); rerr != nil && err == nil { err = fmt.Errorf("failed to remove temporary directory for go command tests: %w", rerr) } }() // Write a temporary go.mod file in td. This ensures that we create // a porcelain environment in which to run these probe commands. if err := os.WriteFile(filepath.Join(td, "go.mod"), []byte("module gotooltest"), 0600); err != nil { return fmt.Errorf("failed to write temporary go.mod file: %w", err) } run := func(args ...string) (*bytes.Buffer, *bytes.Buffer, error) { var stdout, stderr bytes.Buffer cmd := exec.Command(args[0], args[1:]...) cmd.Dir = td cmd.Stdout = &stdout cmd.Stderr = &stderr return &stdout, &stderr, cmd.Run() } lout, stderr, err := run("go", "list", "-f={{context.ReleaseTags}}", "runtime") if err != nil { return fmt.Errorf("failed to determine release tags from go command: %v\n%v", err, stderr.String()) } tagStr := strings.TrimSpace(lout.String()) tagStr = strings.Trim(tagStr, "[]") goEnv.releaseTags = strings.Split(tagStr, " ") eout, stderr, err := run("go", "env", "-json", "GOROOT", "GOCACHE", "GOPROXY", ) if err != nil { return fmt.Errorf("failed to determine environment from go command: %v\n%v", err, stderr) } if err := json.Unmarshal(eout.Bytes(), &goEnv); err != nil { return fmt.Errorf("failed to unmarshal GOROOT and GOCACHE tags from go command out: %v\n%v", err, eout) } version := goEnv.releaseTags[len(goEnv.releaseTags)-1] if !goVersionRegex.MatchString(version) { return fmt.Errorf("invalid go version %q", version) } goEnv.goversion = version[2:] return nil } // Setup sets up the given test environment for tests that use the go // command. It adds support for go tags to p.Condition and adds the go // command to p.Cmds. It also wraps p.Setup to set up the environment // variables for running the go command appropriately. // // It checks go command can run, but not that it can build or run // binaries. func Setup(p *testscript.Params) error { goEnv.once.Do(func() { goEnv.err = initGoEnv() }) if goEnv.err != nil { return goEnv.err } origSetup := p.Setup p.Setup = func(e *testscript.Env) error { e.Vars = goEnviron(e.Vars) if origSetup != nil { return origSetup(e) } return nil } if p.Cmds == nil { p.Cmds = make(map[string]func(ts *testscript.TestScript, neg bool, args []string)) } p.Cmds["go"] = cmdGo return nil } func goEnviron(env0 []string) []string { env := environ(env0) workdir := env.get("WORK") return append(env, []string{ "GOPATH=" + filepath.Join(workdir, ".gopath"), "CCACHE_DISABLE=1", // ccache breaks with non-existent HOME "GOARCH=" + runtime.GOARCH, "GOOS=" + runtime.GOOS, "GOROOT=" + goEnv.GOROOT, "GOCACHE=" + goEnv.GOCACHE, "GOPROXY=" + goEnv.GOPROXY, "goversion=" + goEnv.goversion, }...) } func cmdGo(ts *testscript.TestScript, neg bool, args []string) { if len(args) < 1 { ts.Fatalf("usage: go subcommand ...") } err := ts.Exec("go", args...) if err != nil { ts.Logf("[%v]\n", err) if !neg { ts.Fatalf("unexpected go command failure") } } else { if neg { ts.Fatalf("unexpected go command success") } } } type environ []string func (e0 *environ) get(name string) string { e := *e0 for i := len(e) - 1; i >= 0; i-- { v := e[i] if len(v) <= len(name) { continue } if strings.HasPrefix(v, name) && v[len(name)] == '=' { return v[len(name)+1:] } } return "" } go-internal-1.12.0/gotooltest/setup_test.go000066400000000000000000000010611453631262600207510ustar00rootroot00000000000000package gotooltest import ( "os" "testing" ) func TestInitGoEnv(t *testing.T) { // Set up a temp directory containing a bad go.mod file to // ensure the working directory does not influence the probe // commands run during initGoEnv td := t.TempDir() // If these commands fail we are in bigger trouble wd, _ := os.Getwd() os.Chdir(td) t.Cleanup(func() { os.Chdir(wd) os.Remove(td) }) if err := os.WriteFile("go.mod", []byte("this is rubbish"), 0600); err != nil { t.Fatal(err) } if err := initGoEnv(); err != nil { t.Fatal(err) } } go-internal-1.12.0/gotooltest/testdata/000077500000000000000000000000001453631262600200365ustar00rootroot00000000000000go-internal-1.12.0/gotooltest/testdata/cover.txt000066400000000000000000000032241453631262600217160ustar00rootroot00000000000000unquote scripts/exec.txt # The module uses testscript itself. # Use the checked out module, based on where the test binary ran. go mod edit -replace=github.com/rogpeppe/go-internal=${GOINTERNAL_MODULE} go mod tidy # First, a 'go test' run without coverage. go test -vet=off stdout 'PASS' ! stdout 'coverage' # Then, a 'go test' run with -coverprofile. # The total coverage after merging profiles should end up being 100%. # Marking all printlns as covered requires all edge cases to work well. go test -vet=off -coverprofile=cover.out -v stdout 'PASS' stdout 'coverage: 100\.0%' ! stdout 'malformed coverage' # written by "go test" if cover.out is invalid exists cover.out -- go.mod -- module test go 1.15 -- foo.go -- package foo import "os" func foo1() int { switch os.Args[1] { case "1": println("first path") case "2": println("second path") default: println("third path") } return 1 } -- foo_test.go -- package foo import ( "os" "testing" "github.com/rogpeppe/go-internal/gotooltest" "github.com/rogpeppe/go-internal/testscript" ) func TestMain(m *testing.M) { os.Exit(testscript.RunMain(m, map[string] func() int{ "foo": foo1, })) } func TestFoo(t *testing.T) { p := testscript.Params{ Dir: "scripts", } if err := gotooltest.Setup(&p); err != nil { t.Fatal(err) } testscript.Run(t, p) } -- scripts/exec.txt -- ># Note that foo always fails, to prevent "go build" from doing anything. > ># Running the command directly; trigger the first path. >! foo 1 > ># Running the command via exec; trigger the second path. >! exec foo 2 > ># Running the command indirectly, via toolexec; trigger the third path. >! go build -a -toolexec=foo runtime go-internal-1.12.0/gotooltest/testdata/env.txt000066400000000000000000000002441453631262600213670ustar00rootroot00000000000000# GOPATH and GOMODCACHE are not shared with the host, # but GOCACHE is. go env stdout GOPATH=.*${WORK@R} stdout GOMODCACHE=.*${WORK@R} ! stdout GOCACHE=.*${WORK@R} go-internal-1.12.0/gotooltest/testdata/version.txt000066400000000000000000000002131453631262600222600ustar00rootroot00000000000000go list -f '{{context.ReleaseTags}}' runtime [go1.11] [!go1.12] stdout go1\.11 [go1.11] [!go1.12] ! stdout go1\.12 [go1.12] stdout go1\.12 go-internal-1.12.0/imports/000077500000000000000000000000001453631262600155175ustar00rootroot00000000000000go-internal-1.12.0/imports/build.go000066400000000000000000000140771453631262600171560ustar00rootroot00000000000000// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Copied from Go distribution src/go/build/build.go, syslist.go package imports import ( "bytes" "strings" "unicode" ) var slashslash = []byte("//") // ShouldBuild reports whether it is okay to use this file, // The rule is that in the file's leading run of // comments // and blank lines, which must be followed by a blank line // (to avoid including a Go package clause doc comment), // lines beginning with '// +build' are taken as build directives. // // The file is accepted only if each such line lists something // matching the file. For example: // // // +build windows linux // // marks the file as applicable only on Windows and Linux. // // If tags["*"] is true, then ShouldBuild will consider every // build tag except "ignore" to be both true and false for // the purpose of satisfying build tags, in order to estimate // (conservatively) whether a file could ever possibly be used // in any build. func ShouldBuild(content []byte, tags map[string]bool) bool { // Pass 1. Identify leading run of // comments and blank lines, // which must be followed by a blank line. end := 0 p := content for len(p) > 0 { line := p if i := bytes.IndexByte(line, '\n'); i >= 0 { line, p = line[:i], p[i+1:] } else { p = p[len(p):] } line = bytes.TrimSpace(line) if len(line) == 0 { // Blank line end = len(content) - len(p) continue } if !bytes.HasPrefix(line, slashslash) { // Not comment line break } } content = content[:end] // Pass 2. Process each line in the run. p = content allok := true for len(p) > 0 { line := p if i := bytes.IndexByte(line, '\n'); i >= 0 { line, p = line[:i], p[i+1:] } else { p = p[len(p):] } line = bytes.TrimSpace(line) if !bytes.HasPrefix(line, slashslash) { continue } line = bytes.TrimSpace(line[len(slashslash):]) if len(line) > 0 && line[0] == '+' { // Looks like a comment +line. f := strings.Fields(string(line)) if f[0] == "+build" { ok := false for _, tok := range f[1:] { if matchTags(tok, tags) { ok = true } } if !ok { allok = false } } } } return allok } // matchTags reports whether the name is one of: // // tag (if tags[tag] is true) // !tag (if tags[tag] is false) // a comma-separated list of any of these func matchTags(name string, tags map[string]bool) bool { if name == "" { return false } if i := strings.Index(name, ","); i >= 0 { // comma-separated list ok1 := matchTags(name[:i], tags) ok2 := matchTags(name[i+1:], tags) return ok1 && ok2 } if strings.HasPrefix(name, "!!") { // bad syntax, reject always return false } if strings.HasPrefix(name, "!") { // negation return len(name) > 1 && matchTag(name[1:], tags, false) } return matchTag(name, tags, true) } // matchTag reports whether the tag name is valid and satisfied by tags[name]==want. func matchTag(name string, tags map[string]bool, want bool) bool { // Tags must be letters, digits, underscores or dots. // Unlike in Go identifiers, all digits are fine (e.g., "386"). for _, c := range name { if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' { return false } } if tags["*"] && name != "" && name != "ignore" { // Special case for gathering all possible imports: // if we put * in the tags map then all tags // except "ignore" are considered both present and not // (so we return true no matter how 'want' is set). return true } have := tags[name] if name == "linux" { have = have || tags["android"] } return have == want } // MatchFile returns false if the name contains a $GOOS or $GOARCH // suffix which does not match the current system. // The recognized name formats are: // // name_$(GOOS).* // name_$(GOARCH).* // name_$(GOOS)_$(GOARCH).* // name_$(GOOS)_test.* // name_$(GOARCH)_test.* // name_$(GOOS)_$(GOARCH)_test.* // // An exception: if GOOS=android, then files with GOOS=linux are also matched. // // If tags["*"] is true, then MatchFile will consider all possible // GOOS and GOARCH to be available and will consequently // always return true. func MatchFile(name string, tags map[string]bool) bool { if tags["*"] { return true } if dot := strings.Index(name, "."); dot != -1 { name = name[:dot] } // Before Go 1.4, a file called "linux.go" would be equivalent to having a // build tag "linux" in that file. For Go 1.4 and beyond, we require this // auto-tagging to apply only to files with a non-empty prefix, so // "foo_linux.go" is tagged but "linux.go" is not. This allows new operating // systems, such as android, to arrive without breaking existing code with // innocuous source code in "android.go". The easiest fix: cut everything // in the name before the initial _. i := strings.Index(name, "_") if i < 0 { return true } name = name[i:] // ignore everything before first _ l := strings.Split(name, "_") if n := len(l); n > 0 && l[n-1] == "test" { l = l[:n-1] } n := len(l) if n >= 2 && KnownOS[l[n-2]] && KnownArch[l[n-1]] { return tags[l[n-2]] && tags[l[n-1]] } if n >= 1 && KnownOS[l[n-1]] { return tags[l[n-1]] } if n >= 1 && KnownArch[l[n-1]] { return tags[l[n-1]] } return true } var ( KnownOS = make(map[string]bool) UnixOS = make(map[string]bool) KnownArch = make(map[string]bool) ) func init() { for _, v := range strings.Fields(goosList) { KnownOS[v] = true } for _, v := range strings.Fields(unixList) { UnixOS[v] = true } for _, v := range strings.Fields(goarchList) { KnownArch[v] = true } } // These values come from Go's src/go/build/syslist.go and should be kept in // sync with that file. const ( goosList = "aix android darwin dragonfly freebsd hurd illumos ios js linux nacl netbsd openbsd plan9 solaris windows zos " unixList = "aix android darwin dragonfly freebsd hurd illumos ios linux netbsd openbsd solaris " goarchList = "386 amd64 amd64p32 arm armbe arm64 arm64be loong64 mips mipsle mips64 mips64le mips64p32 mips64p32le ppc ppc64 ppc64le riscv riscv64 s390 s390x sparc sparc64 wasm " ) go-internal-1.12.0/imports/read.go000066400000000000000000000132311453631262600167610ustar00rootroot00000000000000// Copyright 2012 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Copied from Go distribution src/go/build/read.go. package imports import ( "bufio" "errors" "io" "unicode/utf8" ) type importReader struct { b *bufio.Reader buf []byte peek byte err error eof bool nerr int } func isIdent(c byte) bool { return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '_' || c >= utf8.RuneSelf } var ( errSyntax = errors.New("syntax error") errNUL = errors.New("unexpected NUL in input") ) // syntaxError records a syntax error, but only if an I/O error has not already been recorded. func (r *importReader) syntaxError() { if r.err == nil { r.err = errSyntax } } // readByte reads the next byte from the input, saves it in buf, and returns it. // If an error occurs, readByte records the error in r.err and returns 0. func (r *importReader) readByte() byte { c, err := r.b.ReadByte() if err == nil { r.buf = append(r.buf, c) if c == 0 { err = errNUL } } if err != nil { if err == io.EOF { r.eof = true } else if r.err == nil { r.err = err } c = 0 } return c } // peekByte returns the next byte from the input reader but does not advance beyond it. // If skipSpace is set, peekByte skips leading spaces and comments. func (r *importReader) peekByte(skipSpace bool) byte { if r.err != nil { if r.nerr++; r.nerr > 10000 { panic("go/build: import reader looping") } return 0 } // Use r.peek as first input byte. // Don't just return r.peek here: it might have been left by peekByte(false) // and this might be peekByte(true). c := r.peek if c == 0 { c = r.readByte() } for r.err == nil && !r.eof { if skipSpace { // For the purposes of this reader, semicolons are never necessary to // understand the input and are treated as spaces. switch c { case ' ', '\f', '\t', '\r', '\n', ';': c = r.readByte() continue case '/': c = r.readByte() if c == '/' { for c != '\n' && r.err == nil && !r.eof { c = r.readByte() } } else if c == '*' { var c1 byte for (c != '*' || c1 != '/') && r.err == nil { if r.eof { r.syntaxError() } c, c1 = c1, r.readByte() } } else { r.syntaxError() } c = r.readByte() continue } } break } r.peek = c return r.peek } // nextByte is like peekByte but advances beyond the returned byte. func (r *importReader) nextByte(skipSpace bool) byte { c := r.peekByte(skipSpace) r.peek = 0 return c } // readKeyword reads the given keyword from the input. // If the keyword is not present, readKeyword records a syntax error. func (r *importReader) readKeyword(kw string) { r.peekByte(true) for i := 0; i < len(kw); i++ { if r.nextByte(false) != kw[i] { r.syntaxError() return } } if isIdent(r.peekByte(false)) { r.syntaxError() } } // readIdent reads an identifier from the input. // If an identifier is not present, readIdent records a syntax error. func (r *importReader) readIdent() { c := r.peekByte(true) if !isIdent(c) { r.syntaxError() return } for isIdent(r.peekByte(false)) { r.peek = 0 } } // readString reads a quoted string literal from the input. // If an identifier is not present, readString records a syntax error. func (r *importReader) readString(save *[]string) { switch r.nextByte(true) { case '`': start := len(r.buf) - 1 for r.err == nil { if r.nextByte(false) == '`' { if save != nil { *save = append(*save, string(r.buf[start:])) } break } if r.eof { r.syntaxError() } } case '"': start := len(r.buf) - 1 for r.err == nil { c := r.nextByte(false) if c == '"' { if save != nil { *save = append(*save, string(r.buf[start:])) } break } if r.eof || c == '\n' { r.syntaxError() } if c == '\\' { r.nextByte(false) } } default: r.syntaxError() } } // readImport reads an import clause - optional identifier followed by quoted string - // from the input. func (r *importReader) readImport(imports *[]string) { c := r.peekByte(true) if c == '.' { r.peek = 0 } else if isIdent(c) { r.readIdent() } r.readString(imports) } // ReadComments is like ioutil.ReadAll, except that it only reads the leading // block of comments in the file. func ReadComments(f io.Reader) ([]byte, error) { r := &importReader{b: bufio.NewReader(f)} r.peekByte(true) if r.err == nil && !r.eof { // Didn't reach EOF, so must have found a non-space byte. Remove it. r.buf = r.buf[:len(r.buf)-1] } return r.buf, r.err } // ReadImports is like ioutil.ReadAll, except that it expects a Go file as input // and stops reading the input once the imports have completed. func ReadImports(f io.Reader, reportSyntaxError bool, imports *[]string) ([]byte, error) { r := &importReader{b: bufio.NewReader(f)} r.readKeyword("package") r.readIdent() for r.peekByte(true) == 'i' { r.readKeyword("import") if r.peekByte(true) == '(' { r.nextByte(false) for r.peekByte(true) != ')' && r.err == nil { r.readImport(imports) } r.nextByte(false) } else { r.readImport(imports) } } // If we stopped successfully before EOF, we read a byte that told us we were done. // Return all but that last byte, which would cause a syntax error if we let it through. if r.err == nil && !r.eof { return r.buf[:len(r.buf)-1], nil } // If we stopped for a syntax error, consume the whole file so that // we are sure we don't change the errors that go/parser returns. if r.err == errSyntax && !reportSyntaxError { r.err = nil for r.err == nil && !r.eof { r.readByte() } } return r.buf, r.err } go-internal-1.12.0/imports/read_test.go000066400000000000000000000074761453631262600200360ustar00rootroot00000000000000// Copyright 2012 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Copied from Go distribution src/go/build/read.go. package imports import ( "io" "strings" "testing" ) const quote = "`" type readTest struct { // Test input contains ℙ where readImports should stop. in string err string } var readImportsTests = []readTest{ { `package p`, "", }, { `package p; import "x"`, "", }, { `package p; import . "x"`, "", }, { `package p; import "x";ℙvar x = 1`, "", }, { `package p // comment import "x" import _ "x" import a "x" /* comment */ import ( "x" /* comment */ _ "x" a "x" // comment ` + quote + `x` + quote + ` _ /*comment*/ ` + quote + `x` + quote + ` a ` + quote + `x` + quote + ` ) import ( ) import () import()import()import() import();import();import() ℙvar x = 1 `, "", }, } var readCommentsTests = []readTest{ { `ℙpackage p`, "", }, { `ℙpackage p; import "x"`, "", }, { `ℙpackage p; import . "x"`, "", }, { `// foo /* bar */ /* quux */ // baz /*/ zot */ // asdf ℙHello, world`, "", }, } func testRead(t *testing.T, tests []readTest, read func(io.Reader) ([]byte, error)) { for i, tt := range tests { var in, testOut string j := strings.Index(tt.in, "ℙ") if j < 0 { in = tt.in testOut = tt.in } else { in = tt.in[:j] + tt.in[j+len("ℙ"):] testOut = tt.in[:j] } r := strings.NewReader(in) buf, err := read(r) if err != nil { if tt.err == "" { t.Errorf("#%d: err=%q, expected success (%q)", i, err, string(buf)) continue } if !strings.Contains(err.Error(), tt.err) { t.Errorf("#%d: err=%q, expected %q", i, err, tt.err) continue } continue } if err == nil && tt.err != "" { t.Errorf("#%d: success, expected %q", i, tt.err) continue } out := string(buf) if out != testOut { t.Errorf("#%d: wrong output:\nhave %q\nwant %q\n", i, out, testOut) } } } func TestReadImports(t *testing.T) { testRead(t, readImportsTests, func(r io.Reader) ([]byte, error) { return ReadImports(r, true, nil) }) } func TestReadComments(t *testing.T) { testRead(t, readCommentsTests, ReadComments) } var readFailuresTests = []readTest{ { `package`, "syntax error", }, { "package p\n\x00\nimport `math`\n", "unexpected NUL in input", }, { `package p; import`, "syntax error", }, { `package p; import "`, "syntax error", }, { "package p; import ` \n\n", "syntax error", }, { `package p; import "x`, "syntax error", }, { `package p; import _`, "syntax error", }, { `package p; import _ "`, "syntax error", }, { `package p; import _ "x`, "syntax error", }, { `package p; import .`, "syntax error", }, { `package p; import . "`, "syntax error", }, { `package p; import . "x`, "syntax error", }, { `package p; import (`, "syntax error", }, { `package p; import ("`, "syntax error", }, { `package p; import ("x`, "syntax error", }, { `package p; import ("x"`, "syntax error", }, } func TestReadFailures(t *testing.T) { // Errors should be reported (true arg to readImports). testRead(t, readFailuresTests, func(r io.Reader) ([]byte, error) { return ReadImports(r, true, nil) }) } func TestReadFailuresIgnored(t *testing.T) { // Syntax errors should not be reported (false arg to readImports). // Instead, entire file should be the output and no error. // Convert tests not to return syntax errors. tests := make([]readTest, len(readFailuresTests)) copy(tests, readFailuresTests) for i := range tests { tt := &tests[i] if !strings.Contains(tt.err, "NUL") { tt.err = "" } } testRead(t, tests, func(r io.Reader) ([]byte, error) { return ReadImports(r, false, nil) }) } go-internal-1.12.0/imports/scan.go000066400000000000000000000043601453631262600167750ustar00rootroot00000000000000// Copyright 2018 The Go 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 imports import ( "fmt" "io/ioutil" "os" "path/filepath" "sort" "strconv" "strings" ) func ScanDir(dir string, tags map[string]bool) ([]string, []string, error) { infos, err := ioutil.ReadDir(dir) if err != nil { return nil, nil, err } var files []string for _, info := range infos { name := info.Name() if info.Mode().IsRegular() && !strings.HasPrefix(name, "_") && strings.HasSuffix(name, ".go") && MatchFile(name, tags) { files = append(files, filepath.Join(dir, name)) } } return scanFiles(files, tags, false) } func ScanFiles(files []string, tags map[string]bool) ([]string, []string, error) { return scanFiles(files, tags, true) } func scanFiles(files []string, tags map[string]bool, explicitFiles bool) ([]string, []string, error) { imports := make(map[string]bool) testImports := make(map[string]bool) numFiles := 0 Files: for _, name := range files { r, err := os.Open(name) if err != nil { return nil, nil, err } var list []string data, err := ReadImports(r, false, &list) r.Close() if err != nil { return nil, nil, fmt.Errorf("reading %s: %v", name, err) } // import "C" is implicit requirement of cgo tag. // When listing files on the command line (explicitFiles=true) // we do not apply build tag filtering but we still do apply // cgo filtering, so no explicitFiles check here. // Why? Because we always have, and it's not worth breaking // that behavior now. for _, path := range list { if path == `"C"` && !tags["cgo"] && !tags["*"] { continue Files } } if !explicitFiles && !ShouldBuild(data, tags) { continue } numFiles++ m := imports if strings.HasSuffix(name, "_test.go") { m = testImports } for _, p := range list { q, err := strconv.Unquote(p) if err != nil { continue } m[q] = true } } if numFiles == 0 { return nil, nil, ErrNoGo } return keys(imports), keys(testImports), nil } var ErrNoGo = fmt.Errorf("no Go source files") func keys(m map[string]bool) []string { var list []string for k := range m { list = append(list, k) } sort.Strings(list) return list } go-internal-1.12.0/imports/scan_test.go000066400000000000000000000031601453631262600200310ustar00rootroot00000000000000// Copyright 2018 The Go 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 imports import ( "path/filepath" "reflect" "runtime" "testing" "github.com/rogpeppe/go-internal/testenv" ) func TestScan(t *testing.T) { testenv.MustHaveGoBuild(t) imports, testImports, err := ScanDir(filepath.Join(runtime.GOROOT(), "src/encoding/json"), nil) if err != nil { t.Fatal(err) } foundBase64 := false for _, p := range imports { if p == "encoding/base64" { foundBase64 = true } if p == "encoding/binary" { // A dependency but not an import t.Errorf("json reported as importing encoding/binary but does not") } if p == "net/http" { // A test import but not an import t.Errorf("json reported as importing encoding/binary but does not") } } if !foundBase64 { t.Errorf("json missing import encoding/base64 (%q)", imports) } foundHTTP := false for _, p := range testImports { if p == "net/http" { foundHTTP = true } if p == "unicode/utf16" { // A package import but not a test import t.Errorf("json reported as test-importing unicode/utf16 but does not") } } if !foundHTTP { t.Errorf("json missing test import net/http (%q)", testImports) } } func TestScanStar(t *testing.T) { testenv.MustHaveGoBuild(t) imports, _, err := ScanDir("testdata/import1", map[string]bool{"*": true}) if err != nil { t.Fatal(err) } want := []string{"import1", "import2", "import3", "import4"} if !reflect.DeepEqual(imports, want) { t.Errorf("ScanDir testdata/import1:\nhave %v\nwant %v", imports, want) } } go-internal-1.12.0/imports/testdata/000077500000000000000000000000001453631262600173305ustar00rootroot00000000000000go-internal-1.12.0/imports/testdata/import1/000077500000000000000000000000001453631262600207235ustar00rootroot00000000000000go-internal-1.12.0/imports/testdata/import1/x.go000066400000000000000000000000341453631262600215160ustar00rootroot00000000000000package x import "import1" go-internal-1.12.0/imports/testdata/import1/x1.go000066400000000000000000000002061453631262600216000ustar00rootroot00000000000000//go:build blahblh && linux && !linux && windows && darwin // +build blahblh,linux,!linux,windows,darwin package x import "import4" go-internal-1.12.0/imports/testdata/import1/x_darwin.go000066400000000000000000000000371453631262600230650ustar00rootroot00000000000000package xxxx import "import3" go-internal-1.12.0/imports/testdata/import1/x_windows.go000066400000000000000000000000341453631262600232700ustar00rootroot00000000000000package x import "import2" go-internal-1.12.0/internal/000077500000000000000000000000001453631262600156365ustar00rootroot00000000000000go-internal-1.12.0/internal/misspell/000077500000000000000000000000001453631262600174665ustar00rootroot00000000000000go-internal-1.12.0/internal/misspell/misspell.go000066400000000000000000000033761453631262600216560ustar00rootroot00000000000000// Package misspell impements utilities for basic spelling correction. package misspell import ( "unicode/utf8" ) // AlmostEqual reports whether a and b have Damerau-Levenshtein distance of at // most 1. That is, it reports whether a can be transformed into b by adding, // removing or substituting a single rune, or by swapping two adjacent runes. // Invalid runes are considered equal. // // It runs in O(len(a)+len(b)) time. func AlmostEqual(a, b string) bool { for len(a) > 0 && len(b) > 0 { ra, tailA := shiftRune(a) rb, tailB := shiftRune(b) if ra == rb { a, b = tailA, tailB continue } // check for addition/deletion/substitution if equalValid(a, tailB) || equalValid(tailA, b) || equalValid(tailA, tailB) { return true } if len(tailA) == 0 || len(tailB) == 0 { return false } // check for swap a, b = tailA, tailB Ra, tailA := shiftRune(tailA) Rb, tailB := shiftRune(tailB) return ra == Rb && Ra == rb && equalValid(tailA, tailB) } if len(a) == 0 { return len(b) == 0 || singleRune(b) } return singleRune(a) } // singleRune reports whether s consists of a single UTF-8 codepoint. func singleRune(s string) bool { _, n := utf8.DecodeRuneInString(s) return n == len(s) } // shiftRune splits off the first UTF-8 codepoint from s and returns it and the // rest of the string. It panics if s is empty. func shiftRune(s string) (rune, string) { if len(s) == 0 { panic(s) } r, n := utf8.DecodeRuneInString(s) return r, s[n:] } // equalValid reports whether a and b are equal, if invalid code points are considered equal. func equalValid(a, b string) bool { var ra, rb rune for len(a) > 0 && len(b) > 0 { ra, a = shiftRune(a) rb, b = shiftRune(b) if ra != rb { return false } } return len(a) == 0 && len(b) == 0 } go-internal-1.12.0/internal/misspell/misspell_test.go000066400000000000000000000042331453631262600227060ustar00rootroot00000000000000package misspell import ( "math" "testing" ) func TestAlmostEqual(t *testing.T) { t.Parallel() tcs := []struct { inA string inB string want bool }{ {"", "", true}, {"", "a", true}, {"a", "a", true}, {"a", "b", true}, {"hello", "hell", true}, {"hello", "jello", true}, {"hello", "helol", true}, {"hello", "jelol", false}, } for _, tc := range tcs { got := AlmostEqual(tc.inA, tc.inB) if got != tc.want { t.Errorf("AlmostEqual(%q, %q) = %v, want %v", tc.inA, tc.inB, got, tc.want) } // two tests for the price of one \o/ if got != AlmostEqual(tc.inB, tc.inA) { t.Errorf("AlmostEqual(%q, %q) == %v != AlmostEqual(%q, %q)", tc.inA, tc.inB, got, tc.inB, tc.inA) } } } func FuzzAlmostEqual(f *testing.F) { f.Add("", "") f.Add("", "a") f.Add("a", "a") f.Add("a", "b") f.Add("hello", "hell") f.Add("hello", "jello") f.Add("hello", "helol") f.Add("hello", "jelol") f.Fuzz(func(t *testing.T, a, b string) { if len(a) > 10 || len(b) > 10 { // longer strings won't add coverage, but take longer to check return } d := editDistance([]rune(a), []rune(b)) got := AlmostEqual(a, b) if want := d <= 1; got != want { t.Errorf("AlmostEqual(%q, %q) = %v, editDistance(%q, %q) = %d", a, b, got, a, b, d) } if got != AlmostEqual(b, a) { t.Errorf("AlmostEqual(%q, %q) == %v != AlmostEqual(%q, %q)", a, b, got, b, a) } }) } // editDistance returns the Damerau-Levenshtein distance between a and b. It is // inefficient, but by keeping almost verbatim to the recursive definition from // Wikipedia, hopefully "obviously correct" and thus suitable for the fuzzing // test of AlmostEqual. func editDistance(a, b []rune) int { i, j := len(a), len(b) m := math.MaxInt if i == 0 && j == 0 { return 0 } if i > 0 { m = min(m, editDistance(a[1:], b)+1) } if j > 0 { m = min(m, editDistance(a, b[1:])+1) } if i > 0 && j > 0 { d := editDistance(a[1:], b[1:]) if a[0] != b[0] { d += 1 } m = min(m, d) } if i > 1 && j > 1 && a[0] == b[1] && a[1] == b[0] { d := editDistance(a[2:], b[2:]) if a[0] != b[0] { d += 1 } m = min(m, d) } return m } func min(a, b int) int { if a < b { return a } return b } go-internal-1.12.0/internal/misspell/testdata/000077500000000000000000000000001453631262600212775ustar00rootroot00000000000000go-internal-1.12.0/internal/misspell/testdata/fuzz/000077500000000000000000000000001453631262600222755ustar00rootroot00000000000000go-internal-1.12.0/internal/misspell/testdata/fuzz/FuzzAlmostEqual/000077500000000000000000000000001453631262600254035ustar00rootroot00000000000000go-internal-1.12.0/internal/misspell/testdata/fuzz/FuzzAlmostEqual/295b316649ae86dd000066400000000000000000000000501453631262600274730ustar00rootroot00000000000000go test fuzz v1 string("") string("00") go-internal-1.12.0/internal/misspell/testdata/fuzz/FuzzAlmostEqual/5bd9cd4e8c887808000066400000000000000000000000611453631262600275700ustar00rootroot00000000000000go test fuzz v1 string("\x980") string("0\xb70") go-internal-1.12.0/internal/misspell/testdata/fuzz/FuzzAlmostEqual/b323cef1fc26e507000066400000000000000000000000761453631262600276230ustar00rootroot00000000000000go test fuzz v1 string("OOOOOOOO000") string("0000000000000") go-internal-1.12.0/internal/misspell/testdata/fuzz/FuzzAlmostEqual/c6edde4256d6f5eb000066400000000000000000000001011453631262600277650ustar00rootroot00000000000000go test fuzz v1 string("OOOOOOOO000") string("0000000000\x1000") go-internal-1.12.0/internal/os/000077500000000000000000000000001453631262600162575ustar00rootroot00000000000000go-internal-1.12.0/internal/os/execpath/000077500000000000000000000000001453631262600200605ustar00rootroot00000000000000go-internal-1.12.0/internal/os/execpath/exec.go000066400000000000000000000002721453631262600213340ustar00rootroot00000000000000package execpath import "os/exec" type Error = exec.Error // ErrNotFound is the error resulting if a path search failed to find an executable file. var ErrNotFound = exec.ErrNotFound go-internal-1.12.0/internal/os/execpath/lp_js.go000066400000000000000000000012701453631262600215160ustar00rootroot00000000000000// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. //go:build js && wasm package execpath // Look searches for an executable named file, using getenv to look up // environment variables. If getenv is nil, os.Getenv will be used. If file // contains a slash, it is tried directly and getenv will not be called. The // result may be an absolute path or a path relative to the current directory. func Look(file string, getenv func(string) string) (string, error) { // Wasm can not execute processes, so act as if there are no executables at all. return "", &Error{file, ErrNotFound} } go-internal-1.12.0/internal/os/execpath/lp_plan9.go000066400000000000000000000024431453631262600221300ustar00rootroot00000000000000// Copyright 2011 The Go 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 execpath import ( "os" "path/filepath" "strings" ) func findExecutable(file string) error { d, err := os.Stat(file) if err != nil { return err } if m := d.Mode(); !m.IsDir() && m&0111 != 0 { return nil } return os.ErrPermission } // Look searches for an executable named file, using getenv to look up // environment variables. If getenv is nil, os.Getenv will be used. If file // contains a slash, it is tried directly and getenv will not be called. The // result may be an absolute path or a path relative to the current directory. func Look(file string, getenv func(string) string) (string, error) { if getenv == nil { getenv = os.Getenv } // skip the path lookup for these prefixes skip := []string{"/", "#", "./", "../"} for _, p := range skip { if strings.HasPrefix(file, p) { err := findExecutable(file) if err == nil { return file, nil } return "", &Error{file, err} } } path := getenv("path") for _, dir := range filepath.SplitList(path) { path := filepath.Join(dir, file) if err := findExecutable(path); err == nil { return path, nil } } return "", &Error{file, ErrNotFound} } go-internal-1.12.0/internal/os/execpath/lp_unix.go000066400000000000000000000030211453631262600220610ustar00rootroot00000000000000// Copyright 2010 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. //go:build aix || darwin || dragonfly || freebsd || linux || nacl || netbsd || openbsd || solaris package execpath import ( "os" "path/filepath" "strings" ) func findExecutable(file string) error { d, err := os.Stat(file) if err != nil { return err } if m := d.Mode(); !m.IsDir() && m&0111 != 0 { return nil } return os.ErrPermission } // Look searches for an executable named file, using getenv to look up // environment variables. If getenv is nil, os.Getenv will be used. If file // contains a slash, it is tried directly and getenv will not be called. The // result may be an absolute path or a path relative to the current directory. func Look(file string, getenv func(string) string) (string, error) { if getenv == nil { getenv = os.Getenv } // NOTE(rsc): I wish we could use the Plan 9 behavior here // (only bypass the path if file begins with / or ./ or ../) // but that would not match all the Unix shells. if strings.Contains(file, "/") { err := findExecutable(file) if err == nil { return file, nil } return "", &Error{file, err} } path := getenv("PATH") for _, dir := range filepath.SplitList(path) { if dir == "" { // Unix shell semantics: path element "" means "." dir = "." } path := filepath.Join(dir, file) if err := findExecutable(path); err == nil { return path, nil } } return "", &Error{file, ErrNotFound} } go-internal-1.12.0/internal/os/execpath/lp_windows.go000066400000000000000000000040471453631262600226010ustar00rootroot00000000000000// Copyright 2010 The Go 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 execpath import ( "os" "path/filepath" "strings" ) func chkStat(file string) error { d, err := os.Stat(file) if err != nil { return err } if d.IsDir() { return os.ErrPermission } return nil } func hasExt(file string) bool { i := strings.LastIndex(file, ".") if i < 0 { return false } return strings.LastIndexAny(file, `:\/`) < i } func findExecutable(file string, exts []string) (string, error) { if len(exts) == 0 { return file, chkStat(file) } if hasExt(file) { if chkStat(file) == nil { return file, nil } } for _, e := range exts { if f := file + e; chkStat(f) == nil { return f, nil } } return "", os.ErrNotExist } // Look searches for an executable named file, using getenv to look up // environment variables. If getenv is nil, os.Getenv will be used. If file // contains a slash, it is tried directly and getenv will not be called. The // result may be an absolute path or a path relative to the current directory. // Look also uses PATHEXT environment variable to match // a suitable candidate. func Look(file string, getenv func(string) string) (string, error) { if getenv == nil { getenv = os.Getenv } var exts []string x := getenv(`PATHEXT`) if x != "" { for _, e := range strings.Split(strings.ToLower(x), `;`) { if e == "" { continue } if e[0] != '.' { e = "." + e } exts = append(exts, e) } } else { exts = []string{".com", ".exe", ".bat", ".cmd"} } if strings.ContainsAny(file, `:\/`) { if f, err := findExecutable(file, exts); err == nil { return f, nil } else { return "", &Error{file, err} } } if f, err := findExecutable(filepath.Join(".", file), exts); err == nil { return f, nil } path := getenv("path") for _, dir := range filepath.SplitList(path) { if f, err := findExecutable(filepath.Join(dir, file), exts); err == nil { return f, nil } } return "", &Error{file, ErrNotFound} } go-internal-1.12.0/internal/syscall/000077500000000000000000000000001453631262600173105ustar00rootroot00000000000000go-internal-1.12.0/internal/syscall/windows/000077500000000000000000000000001453631262600210025ustar00rootroot00000000000000go-internal-1.12.0/internal/syscall/windows/mksyscall.go000066400000000000000000000005261453631262600233360ustar00rootroot00000000000000// Copyright 2016 The Go 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 windows //go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go syscall_windows.go security_windows.go psapi_windows.go symlink_windows.go go-internal-1.12.0/internal/syscall/windows/psapi_windows.go000066400000000000000000000013141453631262600242160ustar00rootroot00000000000000// Copyright 2017 The Go 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 windows type PROCESS_MEMORY_COUNTERS struct { CB uint32 PageFaultCount uint32 PeakWorkingSetSize uintptr WorkingSetSize uintptr QuotaPeakPagedPoolUsage uintptr QuotaPagedPoolUsage uintptr QuotaPeakNonPagedPoolUsage uintptr QuotaNonPagedPoolUsage uintptr PagefileUsage uintptr PeakPagefileUsage uintptr } //sys GetProcessMemoryInfo(handle syscall.Handle, memCounters *PROCESS_MEMORY_COUNTERS, cb uint32) (err error) = psapi.GetProcessMemoryInfo go-internal-1.12.0/internal/syscall/windows/reparse_windows.go000066400000000000000000000046121453631262600245470ustar00rootroot00000000000000// Copyright 2016 The Go 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 windows const ( FSCTL_SET_REPARSE_POINT = 0x000900A4 IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003 SYMLINK_FLAG_RELATIVE = 1 ) // These structures are described // in https://msdn.microsoft.com/en-us/library/cc232007.aspx // and https://msdn.microsoft.com/en-us/library/cc232006.aspx. // REPARSE_DATA_BUFFER_HEADER is a common part of REPARSE_DATA_BUFFER structure. type REPARSE_DATA_BUFFER_HEADER struct { ReparseTag uint32 // The size, in bytes, of the reparse data that follows // the common portion of the REPARSE_DATA_BUFFER element. // This value is the length of the data starting at the // SubstituteNameOffset field. ReparseDataLength uint16 Reserved uint16 } type SymbolicLinkReparseBuffer struct { // The integer that contains the offset, in bytes, // of the substitute name string in the PathBuffer array, // computed as an offset from byte 0 of PathBuffer. Note that // this offset must be divided by 2 to get the array index. SubstituteNameOffset uint16 // The integer that contains the length, in bytes, of the // substitute name string. If this string is null-terminated, // SubstituteNameLength does not include the Unicode null character. SubstituteNameLength uint16 // PrintNameOffset is similar to SubstituteNameOffset. PrintNameOffset uint16 // PrintNameLength is similar to SubstituteNameLength. PrintNameLength uint16 // Flags specifies whether the substitute name is a full path name or // a path name relative to the directory containing the symbolic link. Flags uint32 PathBuffer [1]uint16 } type MountPointReparseBuffer struct { // The integer that contains the offset, in bytes, // of the substitute name string in the PathBuffer array, // computed as an offset from byte 0 of PathBuffer. Note that // this offset must be divided by 2 to get the array index. SubstituteNameOffset uint16 // The integer that contains the length, in bytes, of the // substitute name string. If this string is null-terminated, // SubstituteNameLength does not include the Unicode null character. SubstituteNameLength uint16 // PrintNameOffset is similar to SubstituteNameOffset. PrintNameOffset uint16 // PrintNameLength is similar to SubstituteNameLength. PrintNameLength uint16 PathBuffer [1]uint16 } go-internal-1.12.0/internal/syscall/windows/security_windows.go000066400000000000000000000073231453631262600247570ustar00rootroot00000000000000// Copyright 2016 The Go 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 windows import ( "syscall" "unsafe" ) const ( SecurityAnonymous = 0 SecurityIdentification = 1 SecurityImpersonation = 2 SecurityDelegation = 3 ) //sys ImpersonateSelf(impersonationlevel uint32) (err error) = advapi32.ImpersonateSelf //sys RevertToSelf() (err error) = advapi32.RevertToSelf const ( TOKEN_ADJUST_PRIVILEGES = 0x0020 SE_PRIVILEGE_ENABLED = 0x00000002 ) type LUID struct { LowPart uint32 HighPart int32 } type LUID_AND_ATTRIBUTES struct { Luid LUID Attributes uint32 } type TOKEN_PRIVILEGES struct { PrivilegeCount uint32 Privileges [1]LUID_AND_ATTRIBUTES } //sys OpenThreadToken(h syscall.Handle, access uint32, openasself bool, token *syscall.Token) (err error) = advapi32.OpenThreadToken //sys LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err error) = advapi32.LookupPrivilegeValueW //sys adjustTokenPrivileges(token syscall.Token, disableAllPrivileges bool, newstate *TOKEN_PRIVILEGES, buflen uint32, prevstate *TOKEN_PRIVILEGES, returnlen *uint32) (ret uint32, err error) [true] = advapi32.AdjustTokenPrivileges func AdjustTokenPrivileges(token syscall.Token, disableAllPrivileges bool, newstate *TOKEN_PRIVILEGES, buflen uint32, prevstate *TOKEN_PRIVILEGES, returnlen *uint32) error { ret, err := adjustTokenPrivileges(token, disableAllPrivileges, newstate, buflen, prevstate, returnlen) if ret == 0 { // AdjustTokenPrivileges call failed return err } // AdjustTokenPrivileges call succeeded if err == syscall.EINVAL { // GetLastError returned ERROR_SUCCESS return nil } return err } //sys DuplicateTokenEx(hExistingToken syscall.Token, dwDesiredAccess uint32, lpTokenAttributes *syscall.SecurityAttributes, impersonationLevel uint32, tokenType TokenType, phNewToken *syscall.Token) (err error) = advapi32.DuplicateTokenEx //sys SetTokenInformation(tokenHandle syscall.Token, tokenInformationClass uint32, tokenInformation uintptr, tokenInformationLength uint32) (err error) = advapi32.SetTokenInformation type SID_AND_ATTRIBUTES struct { Sid *syscall.SID Attributes uint32 } type TOKEN_MANDATORY_LABEL struct { Label SID_AND_ATTRIBUTES } func (tml *TOKEN_MANDATORY_LABEL) Size() uint32 { return uint32(unsafe.Sizeof(TOKEN_MANDATORY_LABEL{})) + syscall.GetLengthSid(tml.Label.Sid) } const SE_GROUP_INTEGRITY = 0x00000020 type TokenType uint32 const ( TokenPrimary TokenType = 1 TokenImpersonation TokenType = 2 ) //sys GetProfilesDirectory(dir *uint16, dirLen *uint32) (err error) = userenv.GetProfilesDirectoryW const ( LG_INCLUDE_INDIRECT = 0x1 MAX_PREFERRED_LENGTH = 0xFFFFFFFF ) type LocalGroupUserInfo0 struct { Name *uint16 } type UserInfo4 struct { Name *uint16 Password *uint16 PasswordAge uint32 Priv uint32 HomeDir *uint16 Comment *uint16 Flags uint32 ScriptPath *uint16 AuthFlags uint32 FullName *uint16 UsrComment *uint16 Parms *uint16 Workstations *uint16 LastLogon uint32 LastLogoff uint32 AcctExpires uint32 MaxStorage uint32 UnitsPerWeek uint32 LogonHours *byte BadPwCount uint32 NumLogons uint32 LogonServer *uint16 CountryCode uint32 CodePage uint32 UserSid *syscall.SID PrimaryGroupID uint32 Profile *uint16 HomeDirDrive *uint16 PasswordExpired uint32 } //sys NetUserGetLocalGroups(serverName *uint16, userName *uint16, level uint32, flags uint32, buf **byte, prefMaxLen uint32, entriesRead *uint32, totalEntries *uint32) (neterr error) = netapi32.NetUserGetLocalGroups go-internal-1.12.0/internal/syscall/windows/symlink_windows.go000066400000000000000000000031151453631262600245710ustar00rootroot00000000000000// Copyright 2018 The Go 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 windows import "syscall" const ( ERROR_INVALID_PARAMETER syscall.Errno = 87 // symlink support for CreateSymbolicLink() starting with Windows 10 (1703, v10.0.14972) SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE = 0x2 // FileInformationClass values FileBasicInfo = 0 // FILE_BASIC_INFO FileStandardInfo = 1 // FILE_STANDARD_INFO FileNameInfo = 2 // FILE_NAME_INFO FileStreamInfo = 7 // FILE_STREAM_INFO FileCompressionInfo = 8 // FILE_COMPRESSION_INFO FileAttributeTagInfo = 9 // FILE_ATTRIBUTE_TAG_INFO FileIdBothDirectoryInfo = 0xa // FILE_ID_BOTH_DIR_INFO FileIdBothDirectoryRestartInfo = 0xb // FILE_ID_BOTH_DIR_INFO FileRemoteProtocolInfo = 0xd // FILE_REMOTE_PROTOCOL_INFO FileFullDirectoryInfo = 0xe // FILE_FULL_DIR_INFO FileFullDirectoryRestartInfo = 0xf // FILE_FULL_DIR_INFO FileStorageInfo = 0x10 // FILE_STORAGE_INFO FileAlignmentInfo = 0x11 // FILE_ALIGNMENT_INFO FileIdInfo = 0x12 // FILE_ID_INFO FileIdExtdDirectoryInfo = 0x13 // FILE_ID_EXTD_DIR_INFO FileIdExtdDirectoryRestartInfo = 0x14 // FILE_ID_EXTD_DIR_INFO ) type FILE_ATTRIBUTE_TAG_INFO struct { FileAttributes uint32 ReparseTag uint32 } //sys GetFileInformationByHandleEx(handle syscall.Handle, class uint32, info *byte, bufsize uint32) (err error) go-internal-1.12.0/internal/syscall/windows/syscall_windows.go000066400000000000000000000216561453631262600245670ustar00rootroot00000000000000// Copyright 2014 The Go 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 windows import ( "sync" "syscall" "unsafe" ) const ( ERROR_SHARING_VIOLATION syscall.Errno = 32 ERROR_LOCK_VIOLATION syscall.Errno = 33 ERROR_NOT_SUPPORTED syscall.Errno = 50 ERROR_CALL_NOT_IMPLEMENTED syscall.Errno = 120 ERROR_INVALID_NAME syscall.Errno = 123 ERROR_LOCK_FAILED syscall.Errno = 167 ERROR_NO_UNICODE_TRANSLATION syscall.Errno = 1113 ) const GAA_FLAG_INCLUDE_PREFIX = 0x00000010 const ( IF_TYPE_OTHER = 1 IF_TYPE_ETHERNET_CSMACD = 6 IF_TYPE_ISO88025_TOKENRING = 9 IF_TYPE_PPP = 23 IF_TYPE_SOFTWARE_LOOPBACK = 24 IF_TYPE_ATM = 37 IF_TYPE_IEEE80211 = 71 IF_TYPE_TUNNEL = 131 IF_TYPE_IEEE1394 = 144 ) type SocketAddress struct { Sockaddr *syscall.RawSockaddrAny SockaddrLength int32 } type IpAdapterUnicastAddress struct { Length uint32 Flags uint32 Next *IpAdapterUnicastAddress Address SocketAddress PrefixOrigin int32 SuffixOrigin int32 DadState int32 ValidLifetime uint32 PreferredLifetime uint32 LeaseLifetime uint32 OnLinkPrefixLength uint8 } type IpAdapterAnycastAddress struct { Length uint32 Flags uint32 Next *IpAdapterAnycastAddress Address SocketAddress } type IpAdapterMulticastAddress struct { Length uint32 Flags uint32 Next *IpAdapterMulticastAddress Address SocketAddress } type IpAdapterDnsServerAdapter struct { Length uint32 Reserved uint32 Next *IpAdapterDnsServerAdapter Address SocketAddress } type IpAdapterPrefix struct { Length uint32 Flags uint32 Next *IpAdapterPrefix Address SocketAddress PrefixLength uint32 } type IpAdapterAddresses struct { Length uint32 IfIndex uint32 Next *IpAdapterAddresses AdapterName *byte FirstUnicastAddress *IpAdapterUnicastAddress FirstAnycastAddress *IpAdapterAnycastAddress FirstMulticastAddress *IpAdapterMulticastAddress FirstDnsServerAddress *IpAdapterDnsServerAdapter DnsSuffix *uint16 Description *uint16 FriendlyName *uint16 PhysicalAddress [syscall.MAX_ADAPTER_ADDRESS_LENGTH]byte PhysicalAddressLength uint32 Flags uint32 Mtu uint32 IfType uint32 OperStatus uint32 Ipv6IfIndex uint32 ZoneIndices [16]uint32 FirstPrefix *IpAdapterPrefix /* more fields might be present here. */ } const ( IfOperStatusUp = 1 IfOperStatusDown = 2 IfOperStatusTesting = 3 IfOperStatusUnknown = 4 IfOperStatusDormant = 5 IfOperStatusNotPresent = 6 IfOperStatusLowerLayerDown = 7 ) //sys GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) = iphlpapi.GetAdaptersAddresses //sys GetComputerNameEx(nameformat uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW //sys MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) = MoveFileExW //sys GetModuleFileName(module syscall.Handle, fn *uint16, len uint32) (n uint32, err error) = kernel32.GetModuleFileNameW const ( WSA_FLAG_OVERLAPPED = 0x01 WSA_FLAG_NO_HANDLE_INHERIT = 0x80 WSAEMSGSIZE syscall.Errno = 10040 MSG_PEEK = 0x2 MSG_TRUNC = 0x0100 MSG_CTRUNC = 0x0200 socket_error = uintptr(^uint32(0)) ) var WSAID_WSASENDMSG = syscall.GUID{ Data1: 0xa441e712, Data2: 0x754f, Data3: 0x43ca, Data4: [8]byte{0x84, 0xa7, 0x0d, 0xee, 0x44, 0xcf, 0x60, 0x6d}, } var WSAID_WSARECVMSG = syscall.GUID{ Data1: 0xf689d7c8, Data2: 0x6f1f, Data3: 0x436b, Data4: [8]byte{0x8a, 0x53, 0xe5, 0x4f, 0xe3, 0x51, 0xc3, 0x22}, } var sendRecvMsgFunc struct { once sync.Once sendAddr uintptr recvAddr uintptr err error } type WSAMsg struct { Name *syscall.RawSockaddrAny Namelen int32 Buffers *syscall.WSABuf BufferCount uint32 Control syscall.WSABuf Flags uint32 } //sys WSASocket(af int32, typ int32, protocol int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = ws2_32.WSASocketW func loadWSASendRecvMsg() error { sendRecvMsgFunc.once.Do(func() { var s syscall.Handle s, sendRecvMsgFunc.err = syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP) if sendRecvMsgFunc.err != nil { return } defer syscall.CloseHandle(s) var n uint32 sendRecvMsgFunc.err = syscall.WSAIoctl(s, syscall.SIO_GET_EXTENSION_FUNCTION_POINTER, (*byte)(unsafe.Pointer(&WSAID_WSARECVMSG)), uint32(unsafe.Sizeof(WSAID_WSARECVMSG)), (*byte)(unsafe.Pointer(&sendRecvMsgFunc.recvAddr)), uint32(unsafe.Sizeof(sendRecvMsgFunc.recvAddr)), &n, nil, 0) if sendRecvMsgFunc.err != nil { return } sendRecvMsgFunc.err = syscall.WSAIoctl(s, syscall.SIO_GET_EXTENSION_FUNCTION_POINTER, (*byte)(unsafe.Pointer(&WSAID_WSASENDMSG)), uint32(unsafe.Sizeof(WSAID_WSASENDMSG)), (*byte)(unsafe.Pointer(&sendRecvMsgFunc.sendAddr)), uint32(unsafe.Sizeof(sendRecvMsgFunc.sendAddr)), &n, nil, 0) }) return sendRecvMsgFunc.err } func WSASendMsg(fd syscall.Handle, msg *WSAMsg, flags uint32, bytesSent *uint32, overlapped *syscall.Overlapped, croutine *byte) error { err := loadWSASendRecvMsg() if err != nil { return err } r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.sendAddr, 6, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(flags), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) if r1 == socket_error { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return err } func WSARecvMsg(fd syscall.Handle, msg *WSAMsg, bytesReceived *uint32, overlapped *syscall.Overlapped, croutine *byte) error { err := loadWSASendRecvMsg() if err != nil { return err } r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.recvAddr, 5, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(bytesReceived)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0) if r1 == socket_error { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return err } const ( ComputerNameNetBIOS = 0 ComputerNameDnsHostname = 1 ComputerNameDnsDomain = 2 ComputerNameDnsFullyQualified = 3 ComputerNamePhysicalNetBIOS = 4 ComputerNamePhysicalDnsHostname = 5 ComputerNamePhysicalDnsDomain = 6 ComputerNamePhysicalDnsFullyQualified = 7 ComputerNameMax = 8 MOVEFILE_REPLACE_EXISTING = 0x1 MOVEFILE_COPY_ALLOWED = 0x2 MOVEFILE_DELAY_UNTIL_REBOOT = 0x4 MOVEFILE_WRITE_THROUGH = 0x8 MOVEFILE_CREATE_HARDLINK = 0x10 MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20 ) func Rename(oldpath, newpath string) error { from, err := syscall.UTF16PtrFromString(oldpath) if err != nil { return err } to, err := syscall.UTF16PtrFromString(newpath) if err != nil { return err } return MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING) } //sys LockFileEx(file syscall.Handle, flags uint32, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) = kernel32.LockFileEx //sys UnlockFileEx(file syscall.Handle, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) = kernel32.UnlockFileEx const ( LOCKFILE_FAIL_IMMEDIATELY = 0x00000001 LOCKFILE_EXCLUSIVE_LOCK = 0x00000002 ) const MB_ERR_INVALID_CHARS = 8 //sys GetACP() (acp uint32) = kernel32.GetACP //sys GetConsoleCP() (ccp uint32) = kernel32.GetConsoleCP //sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar //sys GetCurrentThread() (pseudoHandle syscall.Handle, err error) = kernel32.GetCurrentThread const STYPE_DISKTREE = 0x00 type SHARE_INFO_2 struct { Netname *uint16 Type uint32 Remark *uint16 Permissions uint32 MaxUses uint32 CurrentUses uint32 Path *uint16 Passwd *uint16 } //sys NetShareAdd(serverName *uint16, level uint32, buf *byte, parmErr *uint16) (neterr error) = netapi32.NetShareAdd //sys NetShareDel(serverName *uint16, netName *uint16, reserved uint32) (neterr error) = netapi32.NetShareDel const ( FILE_NAME_NORMALIZED = 0x0 FILE_NAME_OPENED = 0x8 VOLUME_NAME_DOS = 0x0 VOLUME_NAME_GUID = 0x1 VOLUME_NAME_NONE = 0x4 VOLUME_NAME_NT = 0x2 ) //sys GetFinalPathNameByHandle(file syscall.Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) = kernel32.GetFinalPathNameByHandleW func LoadGetFinalPathNameByHandle() error { return procGetFinalPathNameByHandleW.Find() } go-internal-1.12.0/internal/syscall/windows/sysdll/000077500000000000000000000000001453631262600223145ustar00rootroot00000000000000go-internal-1.12.0/internal/syscall/windows/sysdll/sysdll.go000066400000000000000000000021271453631262600241570ustar00rootroot00000000000000// Copyright 2016 The Go 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 sysdll is an internal leaf package that records and reports // which Windows DLL names are used by Go itself. These DLLs are then // only loaded from the System32 directory. See Issue 14959. package sysdll // IsSystemDLL reports whether the named dll key (a base name, like // "foo.dll") is a system DLL which should only be loaded from the // Windows SYSTEM32 directory. // // Filenames are case sensitive, but that doesn't matter because // the case registered with Add is also the same case used with // LoadDLL later. // // It has no associated mutex and should only be mutated serially // (currently: during init), and not concurrent with DLL loading. var IsSystemDLL = map[string]bool{} // Add notes that dll is a system32 DLL which should only be loaded // from the Windows SYSTEM32 directory. It returns its argument back, // for ease of use in generated code. func Add(dll string) string { IsSystemDLL[dll] = true return dll } go-internal-1.12.0/internal/syscall/windows/zsyscall_windows.go000066400000000000000000000277371453631262600247670ustar00rootroot00000000000000// Code generated by 'go generate'; DO NOT EDIT. package windows import ( "syscall" "unsafe" "github.com/rogpeppe/go-internal/internal/syscall/windows/sysdll" ) var _ unsafe.Pointer // Do the interface allocations only once for common // Errno values. const ( errnoERROR_IO_PENDING = 997 ) var ( errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) ) // errnoErr returns common boxed Errno values, to prevent // allocations at runtime. func errnoErr(e syscall.Errno) error { switch e { case 0: return nil case errnoERROR_IO_PENDING: return errERROR_IO_PENDING } // TODO: add more here, after collecting data on the common // error values see on Windows. (perhaps when running // all.bat?) return e } var ( modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll")) modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll")) modws2_32 = syscall.NewLazyDLL(sysdll.Add("ws2_32.dll")) modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll")) modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll")) moduserenv = syscall.NewLazyDLL(sysdll.Add("userenv.dll")) modpsapi = syscall.NewLazyDLL(sysdll.Add("psapi.dll")) procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW") procMoveFileExW = modkernel32.NewProc("MoveFileExW") procGetModuleFileNameW = modkernel32.NewProc("GetModuleFileNameW") procWSASocketW = modws2_32.NewProc("WSASocketW") procLockFileEx = modkernel32.NewProc("LockFileEx") procUnlockFileEx = modkernel32.NewProc("UnlockFileEx") procGetACP = modkernel32.NewProc("GetACP") procGetConsoleCP = modkernel32.NewProc("GetConsoleCP") procMultiByteToWideChar = modkernel32.NewProc("MultiByteToWideChar") procGetCurrentThread = modkernel32.NewProc("GetCurrentThread") procNetShareAdd = modnetapi32.NewProc("NetShareAdd") procNetShareDel = modnetapi32.NewProc("NetShareDel") procGetFinalPathNameByHandleW = modkernel32.NewProc("GetFinalPathNameByHandleW") procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf") procRevertToSelf = modadvapi32.NewProc("RevertToSelf") procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken") procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW") procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") procDuplicateTokenEx = modadvapi32.NewProc("DuplicateTokenEx") procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation") procGetProfilesDirectoryW = moduserenv.NewProc("GetProfilesDirectoryW") procNetUserGetLocalGroups = modnetapi32.NewProc("NetUserGetLocalGroups") procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo") procGetFileInformationByHandleEx = modkernel32.NewProc("GetFileInformationByHandleEx") ) func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) { r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0) if r0 != 0 { errcode = syscall.Errno(r0) } return } func GetComputerNameEx(nameformat uint32, buf *uint16, n *uint32) (err error) { r1, _, e1 := syscall.Syscall(procGetComputerNameExW.Addr(), 3, uintptr(nameformat), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n))) if r1 == 0 { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return } func MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) { r1, _, e1 := syscall.Syscall(procMoveFileExW.Addr(), 3, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), uintptr(flags)) if r1 == 0 { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return } func GetModuleFileName(module syscall.Handle, fn *uint16, len uint32) (n uint32, err error) { r0, _, e1 := syscall.Syscall(procGetModuleFileNameW.Addr(), 3, uintptr(module), uintptr(unsafe.Pointer(fn)), uintptr(len)) n = uint32(r0) if n == 0 { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return } func WSASocket(af int32, typ int32, protocol int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (handle syscall.Handle, err error) { r0, _, e1 := syscall.Syscall6(procWSASocketW.Addr(), 6, uintptr(af), uintptr(typ), uintptr(protocol), uintptr(unsafe.Pointer(protinfo)), uintptr(group), uintptr(flags)) handle = syscall.Handle(r0) if handle == syscall.InvalidHandle { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return } func LockFileEx(file syscall.Handle, flags uint32, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) { r1, _, e1 := syscall.Syscall6(procLockFileEx.Addr(), 6, uintptr(file), uintptr(flags), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped))) if r1 == 0 { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return } func UnlockFileEx(file syscall.Handle, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) { r1, _, e1 := syscall.Syscall6(procUnlockFileEx.Addr(), 5, uintptr(file), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped)), 0) if r1 == 0 { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return } func GetACP() (acp uint32) { r0, _, _ := syscall.Syscall(procGetACP.Addr(), 0, 0, 0, 0) acp = uint32(r0) return } func GetConsoleCP() (ccp uint32) { r0, _, _ := syscall.Syscall(procGetConsoleCP.Addr(), 0, 0, 0, 0) ccp = uint32(r0) return } func MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) { r0, _, e1 := syscall.Syscall6(procMultiByteToWideChar.Addr(), 6, uintptr(codePage), uintptr(dwFlags), uintptr(unsafe.Pointer(str)), uintptr(nstr), uintptr(unsafe.Pointer(wchar)), uintptr(nwchar)) nwrite = int32(r0) if nwrite == 0 { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return } func GetCurrentThread() (pseudoHandle syscall.Handle, err error) { r0, _, e1 := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0) pseudoHandle = syscall.Handle(r0) if pseudoHandle == 0 { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return } func NetShareAdd(serverName *uint16, level uint32, buf *byte, parmErr *uint16) (neterr error) { r0, _, _ := syscall.Syscall6(procNetShareAdd.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(level), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(parmErr)), 0, 0) if r0 != 0 { neterr = syscall.Errno(r0) } return } func NetShareDel(serverName *uint16, netName *uint16, reserved uint32) (neterr error) { r0, _, _ := syscall.Syscall(procNetShareDel.Addr(), 3, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(netName)), uintptr(reserved)) if r0 != 0 { neterr = syscall.Errno(r0) } return } func GetFinalPathNameByHandle(file syscall.Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) { r0, _, e1 := syscall.Syscall6(procGetFinalPathNameByHandleW.Addr(), 4, uintptr(file), uintptr(unsafe.Pointer(filePath)), uintptr(filePathSize), uintptr(flags), 0, 0) n = uint32(r0) if n == 0 { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return } func ImpersonateSelf(impersonationlevel uint32) (err error) { r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(impersonationlevel), 0, 0) if r1 == 0 { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return } func RevertToSelf() (err error) { r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0) if r1 == 0 { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return } func OpenThreadToken(h syscall.Handle, access uint32, openasself bool, token *syscall.Token) (err error) { var _p0 uint32 if openasself { _p0 = 1 } else { _p0 = 0 } r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(h), uintptr(access), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0) if r1 == 0 { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return } func LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err error) { r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemname)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) if r1 == 0 { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return } func adjustTokenPrivileges(token syscall.Token, disableAllPrivileges bool, newstate *TOKEN_PRIVILEGES, buflen uint32, prevstate *TOKEN_PRIVILEGES, returnlen *uint32) (ret uint32, err error) { var _p0 uint32 if disableAllPrivileges { _p0 = 1 } else { _p0 = 0 } r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(newstate)), uintptr(buflen), uintptr(unsafe.Pointer(prevstate)), uintptr(unsafe.Pointer(returnlen))) ret = uint32(r0) if true { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return } func DuplicateTokenEx(hExistingToken syscall.Token, dwDesiredAccess uint32, lpTokenAttributes *syscall.SecurityAttributes, impersonationLevel uint32, tokenType TokenType, phNewToken *syscall.Token) (err error) { r1, _, e1 := syscall.Syscall6(procDuplicateTokenEx.Addr(), 6, uintptr(hExistingToken), uintptr(dwDesiredAccess), uintptr(unsafe.Pointer(lpTokenAttributes)), uintptr(impersonationLevel), uintptr(tokenType), uintptr(unsafe.Pointer(phNewToken))) if r1 == 0 { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return } func SetTokenInformation(tokenHandle syscall.Token, tokenInformationClass uint32, tokenInformation uintptr, tokenInformationLength uint32) (err error) { r1, _, e1 := syscall.Syscall6(procSetTokenInformation.Addr(), 4, uintptr(tokenHandle), uintptr(tokenInformationClass), uintptr(tokenInformation), uintptr(tokenInformationLength), 0, 0) if r1 == 0 { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return } func GetProfilesDirectory(dir *uint16, dirLen *uint32) (err error) { r1, _, e1 := syscall.Syscall(procGetProfilesDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(dir)), uintptr(unsafe.Pointer(dirLen)), 0) if r1 == 0 { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return } func NetUserGetLocalGroups(serverName *uint16, userName *uint16, level uint32, flags uint32, buf **byte, prefMaxLen uint32, entriesRead *uint32, totalEntries *uint32) (neterr error) { r0, _, _ := syscall.Syscall9(procNetUserGetLocalGroups.Addr(), 8, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(flags), uintptr(unsafe.Pointer(buf)), uintptr(prefMaxLen), uintptr(unsafe.Pointer(entriesRead)), uintptr(unsafe.Pointer(totalEntries)), 0) if r0 != 0 { neterr = syscall.Errno(r0) } return } func GetProcessMemoryInfo(handle syscall.Handle, memCounters *PROCESS_MEMORY_COUNTERS, cb uint32) (err error) { r1, _, e1 := syscall.Syscall(procGetProcessMemoryInfo.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(memCounters)), uintptr(cb)) if r1 == 0 { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return } func GetFileInformationByHandleEx(handle syscall.Handle, class uint32, info *byte, bufsize uint32) (err error) { r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(handle), uintptr(class), uintptr(unsafe.Pointer(info)), uintptr(bufsize), 0, 0) if r1 == 0 { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return } go-internal-1.12.0/lockedfile/000077500000000000000000000000001453631262600161235ustar00rootroot00000000000000go-internal-1.12.0/lockedfile/internal/000077500000000000000000000000001453631262600177375ustar00rootroot00000000000000go-internal-1.12.0/lockedfile/internal/filelock/000077500000000000000000000000001453631262600215275ustar00rootroot00000000000000go-internal-1.12.0/lockedfile/internal/filelock/filelock.go000066400000000000000000000057151453631262600236560ustar00rootroot00000000000000// Copyright 2018 The Go 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 filelock provides a platform-independent API for advisory file // locking. Calls to functions in this package on platforms that do not support // advisory locks will return errors for which IsNotSupported returns true. package filelock import ( "errors" "io/fs" "os" ) // A File provides the minimal set of methods required to lock an open file. // File implementations must be usable as map keys. // The usual implementation is *os.File. type File interface { // Name returns the name of the file. Name() string // Fd returns a valid file descriptor. // (If the File is an *os.File, it must not be closed.) Fd() uintptr // Stat returns the FileInfo structure describing file. Stat() (fs.FileInfo, error) } // Lock places an advisory write lock on the file, blocking until it can be // locked. // // If Lock returns nil, no other process will be able to place a read or write // lock on the file until this process exits, closes f, or calls Unlock on it. // // If f's descriptor is already read- or write-locked, the behavior of Lock is // unspecified. // // Closing the file may or may not release the lock promptly. Callers should // ensure that Unlock is always called when Lock succeeds. func Lock(f File) error { return lock(f, writeLock) } // RLock places an advisory read lock on the file, blocking until it can be locked. // // If RLock returns nil, no other process will be able to place a write lock on // the file until this process exits, closes f, or calls Unlock on it. // // If f is already read- or write-locked, the behavior of RLock is unspecified. // // Closing the file may or may not release the lock promptly. Callers should // ensure that Unlock is always called if RLock succeeds. func RLock(f File) error { return lock(f, readLock) } // Unlock removes an advisory lock placed on f by this process. // // The caller must not attempt to unlock a file that is not locked. func Unlock(f File) error { return unlock(f) } // String returns the name of the function corresponding to lt // (Lock, RLock, or Unlock). func (lt lockType) String() string { switch lt { case readLock: return "RLock" case writeLock: return "Lock" default: return "Unlock" } } // IsNotSupported returns a boolean indicating whether the error is known to // report that a function is not supported (possibly for a specific input). // It is satisfied by ErrNotSupported as well as some syscall errors. func IsNotSupported(err error) bool { return isNotSupported(underlyingError(err)) } var ErrNotSupported = errors.New("operation not supported") // underlyingError returns the underlying error for known os error types. func underlyingError(err error) error { switch err := err.(type) { case *fs.PathError: return err.Err case *os.LinkError: return err.Err case *os.SyscallError: return err.Err } return err } go-internal-1.12.0/lockedfile/internal/filelock/filelock_fcntl.go000066400000000000000000000132711453631262600250400ustar00rootroot00000000000000// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. //go:build aix || (solaris && !illumos) // This code implements the filelock API using POSIX 'fcntl' locks, which attach // to an (inode, process) pair rather than a file descriptor. To avoid unlocking // files prematurely when the same file is opened through different descriptors, // we allow only one read-lock at a time. // // Most platforms provide some alternative API, such as an 'flock' system call // or an F_OFD_SETLK command for 'fcntl', that allows for better concurrency and // does not require per-inode bookkeeping in the application. package filelock import ( "errors" "io" "io/fs" "math/rand" "sync" "syscall" "time" ) type lockType int16 const ( readLock lockType = syscall.F_RDLCK writeLock lockType = syscall.F_WRLCK ) type inode = uint64 // type of syscall.Stat_t.Ino type inodeLock struct { owner File queue []<-chan File } var ( mu sync.Mutex inodes = map[File]inode{} locks = map[inode]inodeLock{} ) func lock(f File, lt lockType) (err error) { // POSIX locks apply per inode and process, and the lock for an inode is // released when *any* descriptor for that inode is closed. So we need to // synchronize access to each inode internally, and must serialize lock and // unlock calls that refer to the same inode through different descriptors. fi, err := f.Stat() if err != nil { return err } ino := fi.Sys().(*syscall.Stat_t).Ino mu.Lock() if i, dup := inodes[f]; dup && i != ino { mu.Unlock() return &fs.PathError{ Op: lt.String(), Path: f.Name(), Err: errors.New("inode for file changed since last Lock or RLock"), } } inodes[f] = ino var wait chan File l := locks[ino] if l.owner == f { // This file already owns the lock, but the call may change its lock type. } else if l.owner == nil { // No owner: it's ours now. l.owner = f } else { // Already owned: add a channel to wait on. wait = make(chan File) l.queue = append(l.queue, wait) } locks[ino] = l mu.Unlock() if wait != nil { wait <- f } // Spurious EDEADLK errors arise on platforms that compute deadlock graphs at // the process, rather than thread, level. Consider processes P and Q, with // threads P.1, P.2, and Q.3. The following trace is NOT a deadlock, but will be // reported as a deadlock on systems that consider only process granularity: // // P.1 locks file A. // Q.3 locks file B. // Q.3 blocks on file A. // P.2 blocks on file B. (This is erroneously reported as a deadlock.) // P.1 unlocks file A. // Q.3 unblocks and locks file A. // Q.3 unlocks files A and B. // P.2 unblocks and locks file B. // P.2 unlocks file B. // // These spurious errors were observed in practice on AIX and Solaris in // cmd/go: see https://golang.org/issue/32817. // // We work around this bug by treating EDEADLK as always spurious. If there // really is a lock-ordering bug between the interacting processes, it will // become a livelock instead, but that's not appreciably worse than if we had // a proper flock implementation (which generally does not even attempt to // diagnose deadlocks). // // In the above example, that changes the trace to: // // P.1 locks file A. // Q.3 locks file B. // Q.3 blocks on file A. // P.2 spuriously fails to lock file B and goes to sleep. // P.1 unlocks file A. // Q.3 unblocks and locks file A. // Q.3 unlocks files A and B. // P.2 wakes up and locks file B. // P.2 unlocks file B. // // We know that the retry loop will not introduce a *spurious* livelock // because, according to the POSIX specification, EDEADLK is only to be // returned when “the lock is blocked by a lock from another process”. // If that process is blocked on some lock that we are holding, then the // resulting livelock is due to a real deadlock (and would manifest as such // when using, for example, the flock implementation of this package). // If the other process is *not* blocked on some other lock that we are // holding, then it will eventually release the requested lock. nextSleep := 1 * time.Millisecond const maxSleep = 500 * time.Millisecond for { err = setlkw(f.Fd(), lt) if err != syscall.EDEADLK { break } time.Sleep(nextSleep) nextSleep += nextSleep if nextSleep > maxSleep { nextSleep = maxSleep } // Apply 10% jitter to avoid synchronizing collisions when we finally unblock. nextSleep += time.Duration((0.1*rand.Float64() - 0.05) * float64(nextSleep)) } if err != nil { unlock(f) return &fs.PathError{ Op: lt.String(), Path: f.Name(), Err: err, } } return nil } func unlock(f File) error { var owner File mu.Lock() ino, ok := inodes[f] if ok { owner = locks[ino].owner } mu.Unlock() if owner != f { panic("unlock called on a file that is not locked") } err := setlkw(f.Fd(), syscall.F_UNLCK) mu.Lock() l := locks[ino] if len(l.queue) == 0 { // No waiters: remove the map entry. delete(locks, ino) } else { // The first waiter is sending us their file now. // Receive it and update the queue. l.owner = <-l.queue[0] l.queue = l.queue[1:] locks[ino] = l } delete(inodes, f) mu.Unlock() return err } // setlkw calls FcntlFlock with F_SETLKW for the entire file indicated by fd. func setlkw(fd uintptr, lt lockType) error { for { err := syscall.FcntlFlock(fd, syscall.F_SETLKW, &syscall.Flock_t{ Type: int16(lt), Whence: io.SeekStart, Start: 0, Len: 0, // All bytes. }) if err != syscall.EINTR { return err } } } func isNotSupported(err error) bool { return err == syscall.ENOSYS || err == syscall.ENOTSUP || err == syscall.EOPNOTSUPP || err == ErrNotSupported } go-internal-1.12.0/lockedfile/internal/filelock/filelock_other.go000066400000000000000000000011401453631262600250430ustar00rootroot00000000000000// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. //go:build !unix && !windows package filelock import "io/fs" type lockType int8 const ( readLock = iota + 1 writeLock ) func lock(f File, lt lockType) error { return &fs.PathError{ Op: lt.String(), Path: f.Name(), Err: ErrNotSupported, } } func unlock(f File) error { return &fs.PathError{ Op: "Unlock", Path: f.Name(), Err: ErrNotSupported, } } func isNotSupported(err error) bool { return err == ErrNotSupported } go-internal-1.12.0/lockedfile/internal/filelock/filelock_test.go000066400000000000000000000077531453631262600247210ustar00rootroot00000000000000// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. //go:build !js && !plan9 package filelock_test import ( "fmt" "os" "os/exec" "path/filepath" "runtime" "testing" "time" "github.com/rogpeppe/go-internal/lockedfile/internal/filelock" ) func lock(t *testing.T, f *os.File) { t.Helper() err := filelock.Lock(f) t.Logf("Lock(fd %d) = %v", f.Fd(), err) if err != nil { t.Fail() } } func rLock(t *testing.T, f *os.File) { t.Helper() err := filelock.RLock(f) t.Logf("RLock(fd %d) = %v", f.Fd(), err) if err != nil { t.Fail() } } func unlock(t *testing.T, f *os.File) { t.Helper() err := filelock.Unlock(f) t.Logf("Unlock(fd %d) = %v", f.Fd(), err) if err != nil { t.Fail() } } func mustTempFile(t *testing.T) (f *os.File, remove func()) { t.Helper() base := filepath.Base(t.Name()) f, err := os.CreateTemp("", base) if err != nil { t.Fatalf(`os.CreateTemp("", %q) = %v`, base, err) } t.Logf("fd %d = %s", f.Fd(), f.Name()) return f, func() { f.Close() os.Remove(f.Name()) } } func mustOpen(t *testing.T, name string) *os.File { t.Helper() f, err := os.OpenFile(name, os.O_RDWR, 0) if err != nil { t.Fatalf("os.Open(%q) = %v", name, err) } t.Logf("fd %d = os.Open(%q)", f.Fd(), name) return f } const ( quiescent = 10 * time.Millisecond probablyStillBlocked = 10 * time.Second ) func mustBlock(t *testing.T, op string, f *os.File) (wait func(*testing.T)) { t.Helper() desc := fmt.Sprintf("%s(fd %d)", op, f.Fd()) done := make(chan struct{}) go func() { t.Helper() switch op { case "Lock": lock(t, f) case "RLock": rLock(t, f) default: panic("invalid op: " + op) } close(done) }() select { case <-done: t.Fatalf("%s unexpectedly did not block", desc) return nil case <-time.After(quiescent): t.Logf("%s is blocked (as expected)", desc) return func(t *testing.T) { t.Helper() select { case <-time.After(probablyStillBlocked): t.Fatalf("%s is unexpectedly still blocked", desc) case <-done: } } } } func TestLockExcludesLock(t *testing.T) { t.Parallel() f, remove := mustTempFile(t) defer remove() other := mustOpen(t, f.Name()) defer other.Close() lock(t, f) lockOther := mustBlock(t, "Lock", other) unlock(t, f) lockOther(t) unlock(t, other) } func TestLockExcludesRLock(t *testing.T) { t.Parallel() f, remove := mustTempFile(t) defer remove() other := mustOpen(t, f.Name()) defer other.Close() lock(t, f) rLockOther := mustBlock(t, "RLock", other) unlock(t, f) rLockOther(t) unlock(t, other) } func TestRLockExcludesOnlyLock(t *testing.T) { t.Parallel() f, remove := mustTempFile(t) defer remove() rLock(t, f) f2 := mustOpen(t, f.Name()) defer f2.Close() doUnlockTF := false switch runtime.GOOS { case "aix", "solaris": // When using POSIX locks (as on Solaris), we can't safely read-lock the // same inode through two different descriptors at the same time: when the // first descriptor is closed, the second descriptor would still be open but // silently unlocked. So a second RLock must block instead of proceeding. lockF2 := mustBlock(t, "RLock", f2) unlock(t, f) lockF2(t) default: rLock(t, f2) doUnlockTF = true } other := mustOpen(t, f.Name()) defer other.Close() lockOther := mustBlock(t, "Lock", other) unlock(t, f2) if doUnlockTF { unlock(t, f) } lockOther(t) unlock(t, other) } func TestLockNotDroppedByExecCommand(t *testing.T) { f, remove := mustTempFile(t) defer remove() lock(t, f) other := mustOpen(t, f.Name()) defer other.Close() // Some kinds of file locks are dropped when a duplicated or forked file // descriptor is unlocked. Double-check that the approach used by os/exec does // not accidentally drop locks. cmd := exec.Command(os.Args[0], "-test.run=^$") if err := cmd.Run(); err != nil { t.Fatalf("exec failed: %v", err) } lockOther := mustBlock(t, "Lock", other) unlock(t, f) lockOther(t) unlock(t, other) } go-internal-1.12.0/lockedfile/internal/filelock/filelock_unix.go000066400000000000000000000015531453631262600247150ustar00rootroot00000000000000// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. //go:build darwin || dragonfly || freebsd || illumos || linux || netbsd || openbsd package filelock import ( "io/fs" "syscall" ) type lockType int16 const ( readLock lockType = syscall.LOCK_SH writeLock lockType = syscall.LOCK_EX ) func lock(f File, lt lockType) (err error) { for { err = syscall.Flock(int(f.Fd()), int(lt)) if err != syscall.EINTR { break } } if err != nil { return &fs.PathError{ Op: lt.String(), Path: f.Name(), Err: err, } } return nil } func unlock(f File) error { return lock(f, syscall.LOCK_UN) } func isNotSupported(err error) bool { return err == syscall.ENOSYS || err == syscall.ENOTSUP || err == syscall.EOPNOTSUPP || err == ErrNotSupported } go-internal-1.12.0/lockedfile/internal/filelock/filelock_windows.go000066400000000000000000000027721453631262600254300ustar00rootroot00000000000000// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. //go:build windows package filelock import ( "io/fs" "syscall" "github.com/rogpeppe/go-internal/internal/syscall/windows" ) type lockType uint32 const ( readLock lockType = 0 writeLock lockType = windows.LOCKFILE_EXCLUSIVE_LOCK ) const ( reserved = 0 allBytes = ^uint32(0) ) func lock(f File, lt lockType) error { // Per https://golang.org/issue/19098, “Programs currently expect the Fd // method to return a handle that uses ordinary synchronous I/O.” // However, LockFileEx still requires an OVERLAPPED structure, // which contains the file offset of the beginning of the lock range. // We want to lock the entire file, so we leave the offset as zero. ol := new(syscall.Overlapped) err := windows.LockFileEx(syscall.Handle(f.Fd()), uint32(lt), reserved, allBytes, allBytes, ol) if err != nil { return &fs.PathError{ Op: lt.String(), Path: f.Name(), Err: err, } } return nil } func unlock(f File) error { ol := new(syscall.Overlapped) err := windows.UnlockFileEx(syscall.Handle(f.Fd()), reserved, allBytes, allBytes, ol) if err != nil { return &fs.PathError{ Op: "Unlock", Path: f.Name(), Err: err, } } return nil } func isNotSupported(err error) bool { switch err { case windows.ERROR_NOT_SUPPORTED, windows.ERROR_CALL_NOT_IMPLEMENTED, ErrNotSupported: return true default: return false } } go-internal-1.12.0/lockedfile/lockedfile.go000066400000000000000000000120731453631262600205560ustar00rootroot00000000000000// Copyright 2018 The Go 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 lockedfile creates and manipulates files whose contents should only // change atomically. package lockedfile import ( "fmt" "io" "io/fs" "os" "runtime" ) // A File is a locked *os.File. // // Closing the file releases the lock. // // If the program exits while a file is locked, the operating system releases // the lock but may not do so promptly: callers must ensure that all locked // files are closed before exiting. type File struct { osFile closed bool } // osFile embeds a *os.File while keeping the pointer itself unexported. // (When we close a File, it must be the same file descriptor that we opened!) type osFile struct { *os.File } // OpenFile is like os.OpenFile, but returns a locked file. // If flag includes os.O_WRONLY or os.O_RDWR, the file is write-locked; // otherwise, it is read-locked. func OpenFile(name string, flag int, perm fs.FileMode) (*File, error) { var ( f = new(File) err error ) f.osFile.File, err = openFile(name, flag, perm) if err != nil { return nil, err } // Although the operating system will drop locks for open files when the go // command exits, we want to hold locks for as little time as possible, and we // especially don't want to leave a file locked after we're done with it. Our // Close method is what releases the locks, so use a finalizer to report // missing Close calls on a best-effort basis. runtime.SetFinalizer(f, func(f *File) { panic(fmt.Sprintf("lockedfile.File %s became unreachable without a call to Close", f.Name())) }) return f, nil } // Open is like os.Open, but returns a read-locked file. func Open(name string) (*File, error) { return OpenFile(name, os.O_RDONLY, 0) } // Create is like os.Create, but returns a write-locked file. func Create(name string) (*File, error) { return OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) } // Edit creates the named file with mode 0666 (before umask), // but does not truncate existing contents. // // If Edit succeeds, methods on the returned File can be used for I/O. // The associated file descriptor has mode O_RDWR and the file is write-locked. func Edit(name string) (*File, error) { return OpenFile(name, os.O_RDWR|os.O_CREATE, 0666) } // Close unlocks and closes the underlying file. // // Close may be called multiple times; all calls after the first will return a // non-nil error. func (f *File) Close() error { if f.closed { return &fs.PathError{ Op: "close", Path: f.Name(), Err: fs.ErrClosed, } } f.closed = true err := closeFile(f.osFile.File) runtime.SetFinalizer(f, nil) return err } // Read opens the named file with a read-lock and returns its contents. func Read(name string) ([]byte, error) { f, err := Open(name) if err != nil { return nil, err } defer f.Close() return io.ReadAll(f) } // Write opens the named file (creating it with the given permissions if needed), // then write-locks it and overwrites it with the given content. func Write(name string, content io.Reader, perm fs.FileMode) (err error) { f, err := OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm) if err != nil { return err } _, err = io.Copy(f, content) if closeErr := f.Close(); err == nil { err = closeErr } return err } // Transform invokes t with the result of reading the named file, with its lock // still held. // // If t returns a nil error, Transform then writes the returned contents back to // the file, making a best effort to preserve existing contents on error. // // t must not modify the slice passed to it. func Transform(name string, t func([]byte) ([]byte, error)) (err error) { f, err := Edit(name) if err != nil { return err } defer f.Close() old, err := io.ReadAll(f) if err != nil { return err } new, err := t(old) if err != nil { return err } if len(new) > len(old) { // The overall file size is increasing, so write the tail first: if we're // about to run out of space on the disk, we would rather detect that // failure before we have overwritten the original contents. if _, err := f.WriteAt(new[len(old):], int64(len(old))); err != nil { // Make a best effort to remove the incomplete tail. f.Truncate(int64(len(old))) return err } } // We're about to overwrite the old contents. In case of failure, make a best // effort to roll back before we close the file. defer func() { if err != nil { if _, err := f.WriteAt(old, 0); err == nil { f.Truncate(int64(len(old))) } } }() if len(new) >= len(old) { if _, err := f.WriteAt(new[:len(old)], 0); err != nil { return err } } else { if _, err := f.WriteAt(new, 0); err != nil { return err } // The overall file size is decreasing, so shrink the file to its final size // after writing. We do this after writing (instead of before) so that if // the write fails, enough filesystem space will likely still be reserved // to contain the previous contents. if err := f.Truncate(int64(len(new))); err != nil { return err } } return nil } go-internal-1.12.0/lockedfile/lockedfile_filelock.go000066400000000000000000000033671453631262600224340ustar00rootroot00000000000000// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. //go:build !plan9 package lockedfile import ( "io/fs" "os" "github.com/rogpeppe/go-internal/lockedfile/internal/filelock" ) func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) { // On BSD systems, we could add the O_SHLOCK or O_EXLOCK flag to the OpenFile // call instead of locking separately, but we have to support separate locking // calls for Linux and Windows anyway, so it's simpler to use that approach // consistently. f, err := os.OpenFile(name, flag&^os.O_TRUNC, perm) if err != nil { return nil, err } switch flag & (os.O_RDONLY | os.O_WRONLY | os.O_RDWR) { case os.O_WRONLY, os.O_RDWR: err = filelock.Lock(f) default: err = filelock.RLock(f) } if err != nil { f.Close() return nil, err } if flag&os.O_TRUNC == os.O_TRUNC { if err := f.Truncate(0); err != nil { // The documentation for os.O_TRUNC says “if possible, truncate file when // opened”, but doesn't define “possible” (golang.org/issue/28699). // We'll treat regular files (and symlinks to regular files) as “possible” // and ignore errors for the rest. if fi, statErr := f.Stat(); statErr != nil || fi.Mode().IsRegular() { filelock.Unlock(f) f.Close() return nil, err } } } return f, nil } func closeFile(f *os.File) error { // Since locking syscalls operate on file descriptors, we must unlock the file // while the descriptor is still valid — that is, before the file is closed — // and avoid unlocking files that are already closed. err := filelock.Unlock(f) if closeErr := f.Close(); err == nil { err = closeErr } return err } go-internal-1.12.0/lockedfile/lockedfile_plan9.go000066400000000000000000000050071453631262600216600ustar00rootroot00000000000000// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. //go:build plan9 package lockedfile import ( "io/fs" "math/rand" "os" "strings" "time" ) // Opening an exclusive-use file returns an error. // The expected error strings are: // // - "open/create -- file is locked" (cwfs, kfs) // - "exclusive lock" (fossil) // - "exclusive use file already open" (ramfs) var lockedErrStrings = [...]string{ "file is locked", "exclusive lock", "exclusive use file already open", } // Even though plan9 doesn't support the Lock/RLock/Unlock functions to // manipulate already-open files, IsLocked is still meaningful: os.OpenFile // itself may return errors that indicate that a file with the ModeExclusive bit // set is already open. func isLocked(err error) bool { s := err.Error() for _, frag := range lockedErrStrings { if strings.Contains(s, frag) { return true } } return false } func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) { // Plan 9 uses a mode bit instead of explicit lock/unlock syscalls. // // Per http://man.cat-v.org/plan_9/5/stat: “Exclusive use files may be open // for I/O by only one fid at a time across all clients of the server. If a // second open is attempted, it draws an error.” // // So we can try to open a locked file, but if it fails we're on our own to // figure out when it becomes available. We'll use exponential backoff with // some jitter and an arbitrary limit of 500ms. // If the file was unpacked or created by some other program, it might not // have the ModeExclusive bit set. Set it before we call OpenFile, so that we // can be confident that a successful OpenFile implies exclusive use. if fi, err := os.Stat(name); err == nil { if fi.Mode()&fs.ModeExclusive == 0 { if err := os.Chmod(name, fi.Mode()|fs.ModeExclusive); err != nil { return nil, err } } } else if !os.IsNotExist(err) { return nil, err } nextSleep := 1 * time.Millisecond const maxSleep = 500 * time.Millisecond for { f, err := os.OpenFile(name, flag, perm|fs.ModeExclusive) if err == nil { return f, nil } if !isLocked(err) { return nil, err } time.Sleep(nextSleep) nextSleep += nextSleep if nextSleep > maxSleep { nextSleep = maxSleep } // Apply 10% jitter to avoid synchronizing collisions. nextSleep += time.Duration((0.1*rand.Float64() - 0.05) * float64(nextSleep)) } } func closeFile(f *os.File) error { return f.Close() } go-internal-1.12.0/lockedfile/lockedfile_test.go000066400000000000000000000132701453631262600216150ustar00rootroot00000000000000// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // js does not support inter-process file locking. // //go:build !js package lockedfile_test import ( "fmt" "os" "os/exec" "path/filepath" "testing" "time" "github.com/rogpeppe/go-internal/lockedfile" ) func mustTempDir(t *testing.T) (dir string, remove func()) { t.Helper() dir, err := os.MkdirTemp("", filepath.Base(t.Name())) if err != nil { t.Fatal(err) } return dir, func() { os.RemoveAll(dir) } } const ( quiescent = 10 * time.Millisecond probablyStillBlocked = 10 * time.Second ) func mustBlock(t *testing.T, desc string, f func()) (wait func(*testing.T)) { t.Helper() done := make(chan struct{}) go func() { f() close(done) }() timer := time.NewTimer(quiescent) defer timer.Stop() select { case <-done: t.Fatalf("%s unexpectedly did not block", desc) case <-timer.C: } return func(t *testing.T) { logTimer := time.NewTimer(quiescent) defer logTimer.Stop() select { case <-logTimer.C: // We expect the operation to have unblocked by now, // but maybe it's just slow. Write to the test log // in case the test times out, but don't fail it. t.Helper() t.Logf("%s is unexpectedly still blocked after %v", desc, quiescent) // Wait for the operation to actually complete, no matter how long it // takes. If the test has deadlocked, this will cause the test to time out // and dump goroutines. <-done case <-done: } } } func TestMutexExcludes(t *testing.T) { t.Parallel() dir, remove := mustTempDir(t) defer remove() path := filepath.Join(dir, "lock") mu := lockedfile.MutexAt(path) t.Logf("mu := MutexAt(_)") unlock, err := mu.Lock() if err != nil { t.Fatalf("mu.Lock: %v", err) } t.Logf("unlock, _ := mu.Lock()") mu2 := lockedfile.MutexAt(mu.Path) t.Logf("mu2 := MutexAt(mu.Path)") wait := mustBlock(t, "mu2.Lock()", func() { unlock2, err := mu2.Lock() if err != nil { t.Errorf("mu2.Lock: %v", err) return } t.Logf("unlock2, _ := mu2.Lock()") t.Logf("unlock2()") unlock2() }) t.Logf("unlock()") unlock() wait(t) } func TestReadWaitsForLock(t *testing.T) { t.Parallel() dir, remove := mustTempDir(t) defer remove() path := filepath.Join(dir, "timestamp.txt") f, err := lockedfile.Create(path) if err != nil { t.Fatalf("Create: %v", err) } defer f.Close() const ( part1 = "part 1\n" part2 = "part 2\n" ) _, err = f.WriteString(part1) if err != nil { t.Fatalf("WriteString: %v", err) } t.Logf("WriteString(%q) = ", part1) wait := mustBlock(t, "Read", func() { b, err := lockedfile.Read(path) if err != nil { t.Errorf("Read: %v", err) return } const want = part1 + part2 got := string(b) if got == want { t.Logf("Read(_) = %q", got) } else { t.Errorf("Read(_) = %q, _; want %q", got, want) } }) _, err = f.WriteString(part2) if err != nil { t.Errorf("WriteString: %v", err) } else { t.Logf("WriteString(%q) = ", part2) } f.Close() wait(t) } func TestCanLockExistingFile(t *testing.T) { t.Parallel() dir, remove := mustTempDir(t) defer remove() path := filepath.Join(dir, "existing.txt") if err := os.WriteFile(path, []byte("ok"), 0777); err != nil { t.Fatalf("os.WriteFile: %v", err) } f, err := lockedfile.Edit(path) if err != nil { t.Fatalf("first Edit: %v", err) } wait := mustBlock(t, "Edit", func() { other, err := lockedfile.Edit(path) if err != nil { t.Errorf("second Edit: %v", err) } other.Close() }) f.Close() wait(t) } // TestSpuriousEDEADLK verifies that the spurious EDEADLK reported in // https://golang.org/issue/32817 no longer occurs. func TestSpuriousEDEADLK(t *testing.T) { // P.1 locks file A. // Q.3 locks file B. // Q.3 blocks on file A. // P.2 blocks on file B. (Spurious EDEADLK occurs here.) // P.1 unlocks file A. // Q.3 unblocks and locks file A. // Q.3 unlocks files A and B. // P.2 unblocks and locks file B. // P.2 unlocks file B. dirVar := t.Name() + "DIR" if dir := os.Getenv(dirVar); dir != "" { // Q.3 locks file B. b, err := lockedfile.Edit(filepath.Join(dir, "B")) if err != nil { t.Fatal(err) } defer b.Close() if err := os.WriteFile(filepath.Join(dir, "locked"), []byte("ok"), 0666); err != nil { t.Fatal(err) } // Q.3 blocks on file A. a, err := lockedfile.Edit(filepath.Join(dir, "A")) // Q.3 unblocks and locks file A. if err != nil { t.Fatal(err) } defer a.Close() // Q.3 unlocks files A and B. return } dir, remove := mustTempDir(t) defer remove() // P.1 locks file A. a, err := lockedfile.Edit(filepath.Join(dir, "A")) if err != nil { t.Fatal(err) } cmd := exec.Command(os.Args[0], "-test.run="+t.Name()) cmd.Env = append(os.Environ(), fmt.Sprintf("%s=%s", dirVar, dir)) qDone := make(chan struct{}) waitQ := mustBlock(t, "Edit A and B in subprocess", func() { out, err := cmd.CombinedOutput() if err != nil { t.Errorf("%v:\n%s", err, out) } close(qDone) }) // Wait until process Q has either failed or locked file B. // Otherwise, P.2 might not block on file B as intended. locked: for { if _, err := os.Stat(filepath.Join(dir, "locked")); !os.IsNotExist(err) { break locked } timer := time.NewTimer(1 * time.Millisecond) select { case <-qDone: timer.Stop() break locked case <-timer.C: } } waitP2 := mustBlock(t, "Edit B", func() { // P.2 blocks on file B. (Spurious EDEADLK occurs here.) b, err := lockedfile.Edit(filepath.Join(dir, "B")) // P.2 unblocks and locks file B. if err != nil { t.Error(err) return } // P.2 unlocks file B. b.Close() }) // P.1 unlocks file A. a.Close() waitQ(t) waitP2(t) } go-internal-1.12.0/lockedfile/mutex.go000066400000000000000000000045351453631262600176230ustar00rootroot00000000000000// Copyright 2018 The Go 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 lockedfile import ( "fmt" "os" "sync" ) // A Mutex provides mutual exclusion within and across processes by locking a // well-known file. Such a file generally guards some other part of the // filesystem: for example, a Mutex file in a directory might guard access to // the entire tree rooted in that directory. // // Mutex does not implement sync.Locker: unlike a sync.Mutex, a lockedfile.Mutex // can fail to lock (e.g. if there is a permission error in the filesystem). // // Like a sync.Mutex, a Mutex may be included as a field of a larger struct but // must not be copied after first use. The Path field must be set before first // use and must not be change thereafter. type Mutex struct { Path string // The path to the well-known lock file. Must be non-empty. mu sync.Mutex // A redundant mutex. The race detector doesn't know about file locking, so in tests we may need to lock something that it understands. } // MutexAt returns a new Mutex with Path set to the given non-empty path. func MutexAt(path string) *Mutex { if path == "" { panic("lockedfile.MutexAt: path must be non-empty") } return &Mutex{Path: path} } func (mu *Mutex) String() string { return fmt.Sprintf("lockedfile.Mutex(%s)", mu.Path) } // Lock attempts to lock the Mutex. // // If successful, Lock returns a non-nil unlock function: it is provided as a // return-value instead of a separate method to remind the caller to check the // accompanying error. (See https://golang.org/issue/20803.) func (mu *Mutex) Lock() (unlock func(), err error) { if mu.Path == "" { panic("lockedfile.Mutex: missing Path during Lock") } // We could use either O_RDWR or O_WRONLY here. If we choose O_RDWR and the // file at mu.Path is write-only, the call to OpenFile will fail with a // permission error. That's actually what we want: if we add an RLock method // in the future, it should call OpenFile with O_RDONLY and will require the // files must be readable, so we should not let the caller make any // assumptions about Mutex working with write-only files. f, err := OpenFile(mu.Path, os.O_RDWR|os.O_CREATE, 0666) if err != nil { return nil, err } mu.mu.Lock() return func() { mu.mu.Unlock() f.Close() }, nil } go-internal-1.12.0/lockedfile/transform_test.go000066400000000000000000000044121453631262600215250ustar00rootroot00000000000000// Copyright 2019 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // js does not support inter-process file locking. // //go:build !js package lockedfile_test import ( "bytes" "encoding/binary" "math/rand" "path/filepath" "testing" "time" "github.com/rogpeppe/go-internal/lockedfile" ) func isPowerOf2(x int) bool { return x > 0 && x&(x-1) == 0 } func roundDownToPowerOf2(x int) int { if x <= 0 { panic("nonpositive x") } bit := 1 for x != bit { x = x &^ bit bit <<= 1 } return x } func TestTransform(t *testing.T) { dir, remove := mustTempDir(t) defer remove() path := filepath.Join(dir, "blob.bin") const maxChunkWords = 8 << 10 buf := make([]byte, 2*maxChunkWords*8) for i := uint64(0); i < 2*maxChunkWords; i++ { binary.LittleEndian.PutUint64(buf[i*8:], i) } if err := lockedfile.Write(path, bytes.NewReader(buf[:8]), 0666); err != nil { t.Fatal(err) } var attempts int64 = 128 if !testing.Short() { attempts *= 16 } const parallel = 32 var sem = make(chan bool, parallel) for n := attempts; n > 0; n-- { sem <- true go func() { defer func() { <-sem }() time.Sleep(time.Duration(rand.Intn(100)) * time.Microsecond) chunkWords := roundDownToPowerOf2(rand.Intn(maxChunkWords) + 1) offset := rand.Intn(chunkWords) err := lockedfile.Transform(path, func(data []byte) (chunk []byte, err error) { chunk = buf[offset*8 : (offset+chunkWords)*8] if len(data)&^7 != len(data) { t.Errorf("read %d bytes, but each write is an integer multiple of 8 bytes", len(data)) return chunk, nil } words := len(data) / 8 if !isPowerOf2(words) { t.Errorf("read %d 8-byte words, but each write is a power-of-2 number of words", words) return chunk, nil } u := binary.LittleEndian.Uint64(data) for i := 1; i < words; i++ { next := binary.LittleEndian.Uint64(data[i*8:]) if next != u+1 { t.Errorf("wrote sequential integers, but read integer out of sequence at offset %d", i) return chunk, nil } u = next } return chunk, nil }) if err != nil { t.Errorf("unexpected error from Transform: %v", err) } }() } for n := parallel; n > 0; n-- { sem <- true } } go-internal-1.12.0/modfile/000077500000000000000000000000001453631262600154415ustar00rootroot00000000000000go-internal-1.12.0/modfile/forward.go000066400000000000000000000027101453631262600174340ustar00rootroot00000000000000// Package modfile implements parsing and formatting for go.mod files. // // This is now just a simple forwarding layer over golang.org/x/mod/modfile // apart from the ParseGopkgIn function which doesn't exist there. // // See that package for documentation. // // Deprecated: use [golang.org/x/mod/modfile] instead. package modfile import ( "golang.org/x/mod/modfile" ) type Position = modfile.Position type Expr = modfile.Expr type Comment = modfile.Comment type Comments = modfile.Comments type FileSyntax = modfile.FileSyntax type CommentBlock = modfile.CommentBlock type Line = modfile.Line type LineBlock = modfile.LineBlock type LParen = modfile.LParen type RParen = modfile.RParen type File = modfile.File type Module = modfile.Module type Go = modfile.Go type Require = modfile.Require type Exclude = modfile.Exclude type Replace = modfile.Replace type VersionFixer = modfile.VersionFixer func Format(f *FileSyntax) []byte { return modfile.Format(f) } func ModulePath(mod []byte) string { return modfile.ModulePath(mod) } func Parse(file string, data []byte, fix VersionFixer) (*File, error) { return modfile.Parse(file, data, fix) } func ParseLax(file string, data []byte, fix VersionFixer) (*File, error) { return modfile.ParseLax(file, data, fix) } func IsDirectoryPath(ns string) bool { return modfile.IsDirectoryPath(ns) } func MustQuote(s string) bool { return modfile.MustQuote(s) } func AutoQuote(s string) string { return modfile.AutoQuote(s) } go-internal-1.12.0/modfile/gopkgin.go000066400000000000000000000023571453631262600174350ustar00rootroot00000000000000// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // TODO: Figure out what gopkg.in should do. package modfile import "strings" // ParseGopkgIn splits gopkg.in import paths into their constituent parts func ParseGopkgIn(path string) (root, repo, major, subdir string, ok bool) { if !strings.HasPrefix(path, "gopkg.in/") { return } f := strings.Split(path, "/") if len(f) >= 2 { if elem, v, ok := dotV(f[1]); ok { root = strings.Join(f[:2], "/") repo = "github.com/go-" + elem + "/" + elem major = v subdir = strings.Join(f[2:], "/") return root, repo, major, subdir, true } } if len(f) >= 3 { if elem, v, ok := dotV(f[2]); ok { root = strings.Join(f[:3], "/") repo = "github.com/" + f[1] + "/" + elem major = v subdir = strings.Join(f[3:], "/") return root, repo, major, subdir, true } } return } func dotV(name string) (elem, v string, ok bool) { i := len(name) - 1 for i >= 0 && '0' <= name[i] && name[i] <= '9' { i-- } if i <= 2 || i+1 >= len(name) || name[i-1] != '.' || name[i] != 'v' || name[i+1] == '0' && len(name) != i+2 { return "", "", false } return name[:i-1], name[i:], true } go-internal-1.12.0/module/000077500000000000000000000000001453631262600153075ustar00rootroot00000000000000go-internal-1.12.0/module/forward.go000066400000000000000000000026161453631262600173070ustar00rootroot00000000000000// Package module is a thin forwarding layer on top of // [golang.org/x/mod/module]. Note that the Encode* and // Decode* functions map to Escape* and Unescape* // in that package. // // See that package for documentation on everything else. // // Deprecated: use [golang.org/x/mod/module] instead. package module import "golang.org/x/mod/module" type Version = module.Version func Check(path, version string) error { return module.Check(path, version) } func CheckPath(path string) error { return module.CheckPath(path) } func CheckImportPath(path string) error { return module.CheckImportPath(path) } func CheckFilePath(path string) error { return module.CheckFilePath(path) } func SplitPathVersion(path string) (prefix, pathMajor string, ok bool) { return module.SplitPathVersion(path) } func MatchPathMajor(v, pathMajor string) bool { return module.MatchPathMajor(v, pathMajor) } func CanonicalVersion(v string) string { return module.CanonicalVersion(v) } func Sort(list []Version) { module.Sort(list) } func EncodePath(path string) (encoding string, err error) { return module.EscapePath(path) } func EncodeVersion(v string) (encoding string, err error) { return module.EscapeVersion(v) } func DecodePath(encoding string) (path string, err error) { return module.UnescapePath(encoding) } func DecodeVersion(encoding string) (v string, err error) { return module.UnescapeVersion(encoding) } go-internal-1.12.0/par/000077500000000000000000000000001453631262600146045ustar00rootroot00000000000000go-internal-1.12.0/par/work.go000066400000000000000000000072431453631262600161230ustar00rootroot00000000000000// Copyright 2018 The Go 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 par implements parallel execution helpers. package par import ( "math/rand" "sync" "sync/atomic" ) // Work manages a set of work items to be executed in parallel, at most once each. // The items in the set must all be valid map keys. type Work struct { f func(interface{}) // function to run for each item running int // total number of runners mu sync.Mutex added map[interface{}]bool // items added to set todo []interface{} // items yet to be run wait sync.Cond // wait when todo is empty waiting int // number of runners waiting for todo } func (w *Work) init() { if w.added == nil { w.added = make(map[interface{}]bool) } } // Add adds item to the work set, if it hasn't already been added. func (w *Work) Add(item interface{}) { w.mu.Lock() w.init() if !w.added[item] { w.added[item] = true w.todo = append(w.todo, item) if w.waiting > 0 { w.wait.Signal() } } w.mu.Unlock() } // Do runs f in parallel on items from the work set, // with at most n invocations of f running at a time. // It returns when everything added to the work set has been processed. // At least one item should have been added to the work set // before calling Do (or else Do returns immediately), // but it is allowed for f(item) to add new items to the set. // Do should only be used once on a given Work. func (w *Work) Do(n int, f func(item interface{})) { if n < 1 { panic("par.Work.Do: n < 1") } if w.running >= 1 { panic("par.Work.Do: already called Do") } w.running = n w.f = f w.wait.L = &w.mu for i := 0; i < n-1; i++ { go w.runner() } w.runner() } // runner executes work in w until both nothing is left to do // and all the runners are waiting for work. // (Then all the runners return.) func (w *Work) runner() { for { // Wait for something to do. w.mu.Lock() for len(w.todo) == 0 { w.waiting++ if w.waiting == w.running { // All done. w.wait.Broadcast() w.mu.Unlock() return } w.wait.Wait() w.waiting-- } // Pick something to do at random, // to eliminate pathological contention // in case items added at about the same time // are most likely to contend. i := rand.Intn(len(w.todo)) item := w.todo[i] w.todo[i] = w.todo[len(w.todo)-1] w.todo = w.todo[:len(w.todo)-1] w.mu.Unlock() w.f(item) } } // Cache runs an action once per key and caches the result. type Cache struct { m sync.Map } type cacheEntry struct { done uint32 mu sync.Mutex result interface{} } // Do calls the function f if and only if Do is being called for the first time with this key. // No call to Do with a given key returns until the one call to f returns. // Do returns the value returned by the one call to f. func (c *Cache) Do(key interface{}, f func() interface{}) interface{} { entryIface, ok := c.m.Load(key) if !ok { entryIface, _ = c.m.LoadOrStore(key, new(cacheEntry)) } e := entryIface.(*cacheEntry) if atomic.LoadUint32(&e.done) == 0 { e.mu.Lock() if atomic.LoadUint32(&e.done) == 0 { e.result = f() atomic.StoreUint32(&e.done, 1) } e.mu.Unlock() } return e.result } // Get returns the cached result associated with key. // It returns nil if there is no such result. // If the result for key is being computed, Get does not wait for the computation to finish. func (c *Cache) Get(key interface{}) interface{} { entryIface, ok := c.m.Load(key) if !ok { return nil } e := entryIface.(*cacheEntry) if atomic.LoadUint32(&e.done) == 0 { return nil } return e.result } go-internal-1.12.0/par/work_test.go000066400000000000000000000030261453631262600171550ustar00rootroot00000000000000// Copyright 2018 The Go 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 par import ( "sync/atomic" "testing" "time" ) func TestWork(t *testing.T) { var w Work const N = 10000 n := int32(0) w.Add(N) w.Do(100, func(x interface{}) { atomic.AddInt32(&n, 1) i := x.(int) if i >= 2 { w.Add(i - 1) w.Add(i - 2) } w.Add(i >> 1) w.Add((i >> 1) ^ 1) }) if n != N+1 { t.Fatalf("ran %d items, expected %d", n, N+1) } } func TestWorkParallel(t *testing.T) { for tries := 0; tries < 10; tries++ { var w Work const N = 100 for i := 0; i < N; i++ { w.Add(i) } start := time.Now() var n int32 w.Do(N, func(x interface{}) { time.Sleep(1 * time.Millisecond) atomic.AddInt32(&n, +1) }) if n != N { t.Fatalf("par.Work.Do did not do all the work") } if time.Since(start) < N/2*time.Millisecond { return } } t.Fatalf("par.Work.Do does not seem to be parallel") } func TestCache(t *testing.T) { var cache Cache n := 1 v := cache.Do(1, func() interface{} { n++; return n }) if v != 2 { t.Fatalf("cache.Do(1) did not run f") } v = cache.Do(1, func() interface{} { n++; return n }) if v != 2 { t.Fatalf("cache.Do(1) ran f again!") } v = cache.Do(2, func() interface{} { n++; return n }) if v != 3 { t.Fatalf("cache.Do(2) did not run f") } v = cache.Do(1, func() interface{} { n++; return n }) if v != 2 { t.Fatalf("cache.Do(1) did not returned saved value from original cache.Do(1)") } } go-internal-1.12.0/renameio/000077500000000000000000000000001453631262600156215ustar00rootroot00000000000000go-internal-1.12.0/renameio/renameio.go000066400000000000000000000036411453631262600177530ustar00rootroot00000000000000// Copyright 2018 The Go 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 renameio writes files atomically by renaming temporary files. // // Deprecated: Use [github.com/google/renameio/v2] instead. package renameio import ( "bytes" "io" "io/ioutil" "os" "path/filepath" ) const patternSuffix = "*.tmp" // Pattern returns a glob pattern that matches the unrenamed temporary files // created when writing to filename. func Pattern(filename string) string { return filepath.Join(filepath.Dir(filename), filepath.Base(filename)+patternSuffix) } // WriteFile is like ioutil.WriteFile, but first writes data to an arbitrary // file in the same directory as filename, then renames it atomically to the // final name. // // That ensures that the final location, if it exists, is always a complete file. func WriteFile(filename string, data []byte) (err error) { return WriteToFile(filename, bytes.NewReader(data)) } // WriteToFile is a variant of WriteFile that accepts the data as an io.Reader // instead of a slice. func WriteToFile(filename string, data io.Reader) (err error) { f, err := ioutil.TempFile(filepath.Dir(filename), filepath.Base(filename)+patternSuffix) if err != nil { return err } defer func() { // Only call os.Remove on f.Name() if we failed to rename it: otherwise, // some other process may have created a new file with the same name after // that. if err != nil { f.Close() os.Remove(f.Name()) } }() if _, err := io.Copy(f, data); err != nil { return err } // Sync the file before renaming it: otherwise, after a crash the reader may // observe a 0-length file instead of the actual contents. // See https://golang.org/issue/22397#issuecomment-380831736. if err := f.Sync(); err != nil { return err } if err := f.Close(); err != nil { return err } return os.Rename(f.Name(), filename) } go-internal-1.12.0/robustio/000077500000000000000000000000001453631262600156705ustar00rootroot00000000000000go-internal-1.12.0/robustio/robustio.go000066400000000000000000000037051453631262600200720ustar00rootroot00000000000000// Copyright 2019 The Go 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 robustio wraps I/O functions that are prone to failure on Windows, // transparently retrying errors up to an arbitrary timeout. // // Errors are classified heuristically and retries are bounded, so the functions // in this package do not completely eliminate spurious errors. However, they do // significantly reduce the rate of failure in practice. // // If so, the error will likely wrap one of: // The functions in this package do not completely eliminate spurious errors, // but substantially reduce their rate of occurrence in practice. package robustio // Rename is like os.Rename, but on Windows retries errors that may occur if the // file is concurrently read or overwritten. // // (See golang.org/issue/31247 and golang.org/issue/32188.) func Rename(oldpath, newpath string) error { return rename(oldpath, newpath) } // ReadFile is like os.ReadFile, but on Windows retries errors that may // occur if the file is concurrently replaced. // // (See golang.org/issue/31247 and golang.org/issue/32188.) func ReadFile(filename string) ([]byte, error) { return readFile(filename) } // RemoveAll is like os.RemoveAll, but on Windows retries errors that may occur // if an executable file in the directory has recently been executed. // // (See golang.org/issue/19491.) func RemoveAll(path string) error { return removeAll(path) } // IsEphemeralError reports whether err is one of the errors that the functions // in this package attempt to mitigate. // // Errors considered ephemeral include: // - syscall.ERROR_ACCESS_DENIED // - syscall.ERROR_FILE_NOT_FOUND // - internal/syscall/windows.ERROR_SHARING_VIOLATION // // This set may be expanded in the future; programs must not rely on the // non-ephemerality of any given error. func IsEphemeralError(err error) bool { return isEphemeralError(err) } go-internal-1.12.0/robustio/robustio_darwin.go000066400000000000000000000007221453631262600214320ustar00rootroot00000000000000// Copyright 2019 The Go 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 robustio import ( "errors" "syscall" ) const errFileNotFound = syscall.ENOENT // isEphemeralError returns true if err may be resolved by waiting. func isEphemeralError(err error) bool { var errno syscall.Errno if errors.As(err, &errno) { return errno == errFileNotFound } return false } go-internal-1.12.0/robustio/robustio_flaky.go000066400000000000000000000047541453631262600212650ustar00rootroot00000000000000// Copyright 2019 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. //go:build windows || darwin package robustio import ( "errors" "math/rand" "os" "syscall" "time" ) const arbitraryTimeout = 2000 * time.Millisecond // retry retries ephemeral errors from f up to an arbitrary timeout // to work around filesystem flakiness on Windows and Darwin. func retry(f func() (err error, mayRetry bool)) error { var ( bestErr error lowestErrno syscall.Errno start time.Time nextSleep time.Duration = 1 * time.Millisecond ) for { err, mayRetry := f() if err == nil || !mayRetry { return err } var errno syscall.Errno if errors.As(err, &errno) && (lowestErrno == 0 || errno < lowestErrno) { bestErr = err lowestErrno = errno } else if bestErr == nil { bestErr = err } if start.IsZero() { start = time.Now() } else if d := time.Since(start) + nextSleep; d >= arbitraryTimeout { break } time.Sleep(nextSleep) nextSleep += time.Duration(rand.Int63n(int64(nextSleep))) } return bestErr } // rename is like os.Rename, but retries ephemeral errors. // // On Windows it wraps os.Rename, which (as of 2019-06-04) uses MoveFileEx with // MOVEFILE_REPLACE_EXISTING. // // Windows also provides a different system call, ReplaceFile, // that provides similar semantics, but perhaps preserves more metadata. (The // documentation on the differences between the two is very sparse.) // // Empirical error rates with MoveFileEx are lower under modest concurrency, so // for now we're sticking with what the os package already provides. func rename(oldpath, newpath string) (err error) { return retry(func() (err error, mayRetry bool) { err = os.Rename(oldpath, newpath) return err, isEphemeralError(err) }) } // readFile is like os.ReadFile, but retries ephemeral errors. func readFile(filename string) ([]byte, error) { var b []byte err := retry(func() (err error, mayRetry bool) { b, err = os.ReadFile(filename) // Unlike in rename, we do not retry errFileNotFound here: it can occur // as a spurious error, but the file may also genuinely not exist, so the // increase in robustness is probably not worth the extra latency. return err, isEphemeralError(err) && !errors.Is(err, errFileNotFound) }) return b, err } func removeAll(path string) error { return retry(func() (err error, mayRetry bool) { err = os.RemoveAll(path) return err, isEphemeralError(err) }) } go-internal-1.12.0/robustio/robustio_other.go000066400000000000000000000010041453631262600212610ustar00rootroot00000000000000// Copyright 2019 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. //go:build !windows && !darwin package robustio import ( "os" ) func rename(oldpath, newpath string) error { return os.Rename(oldpath, newpath) } func readFile(filename string) ([]byte, error) { return os.ReadFile(filename) } func removeAll(path string) error { return os.RemoveAll(path) } func isEphemeralError(err error) bool { return false } go-internal-1.12.0/robustio/robustio_windows.go000066400000000000000000000012101453631262600216310ustar00rootroot00000000000000// Copyright 2019 The Go 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 robustio import ( "errors" "syscall" "github.com/rogpeppe/go-internal/internal/syscall/windows" ) const errFileNotFound = syscall.ERROR_FILE_NOT_FOUND // isEphemeralError returns true if err may be resolved by waiting. func isEphemeralError(err error) bool { var errno syscall.Errno if errors.As(err, &errno) { switch errno { case syscall.ERROR_ACCESS_DENIED, syscall.ERROR_FILE_NOT_FOUND, windows.ERROR_SHARING_VIOLATION: return true } } return false } go-internal-1.12.0/semver/000077500000000000000000000000001453631262600153235ustar00rootroot00000000000000go-internal-1.12.0/semver/forward.go000066400000000000000000000013221453631262600173140ustar00rootroot00000000000000// Package semver is a thin forwarding layer on top of // [golang.org/x/mod/semver]. See that package for documentation. // // Deprecated: use [golang.org/x/mod/semver] instead. package semver import "golang.org/x/mod/semver" func IsValid(v string) bool { return semver.IsValid(v) } func Canonical(v string) string { return semver.Canonical(v) } func Major(v string) string { return semver.Major(v) } func MajorMinor(v string) string { return semver.MajorMinor(v) } func Prerelease(v string) string { return semver.Prerelease(v) } func Build(v string) string { return semver.Build(v) } func Compare(v, w string) int { return semver.Compare(v, w) } func Max(v, w string) string { return semver.Max(v, w) } go-internal-1.12.0/testenv/000077500000000000000000000000001453631262600155125ustar00rootroot00000000000000go-internal-1.12.0/testenv/testenv.go000066400000000000000000000161561453631262600175420ustar00rootroot00000000000000// Copyright 2015 The Go 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 testenv provides information about what functionality // is available in different testing environments run by the Go team. // // It is an internal package because these details are specific // to the Go team's test setup (on build.golang.org) and not // fundamental to tests in general. package testenv import ( "errors" "flag" "os" "os/exec" "path/filepath" "runtime" "strconv" "strings" "testing" ) // Builder reports the name of the builder running this test // (for example, "linux-amd64" or "windows-386-gce"). // If the test is not running on the build infrastructure, // Builder returns the empty string. func Builder() string { return os.Getenv("GO_BUILDER_NAME") } // HasGoBuild reports whether the current system can build programs with “go build” // and then run them with os.StartProcess or exec.Command. func HasGoBuild() bool { if os.Getenv("GO_GCFLAGS") != "" { // It's too much work to require every caller of the go command // to pass along "-gcflags="+os.Getenv("GO_GCFLAGS"). // For now, if $GO_GCFLAGS is set, report that we simply can't // run go build. return false } switch runtime.GOOS { case "android", "nacl", "js": return false case "darwin": if strings.HasPrefix(runtime.GOARCH, "arm") { return false } } return true } // MustHaveGoBuild checks that the current system can build programs with “go build” // and then run them with os.StartProcess or exec.Command. // If not, MustHaveGoBuild calls t.Skip with an explanation. func MustHaveGoBuild(t testing.TB) { if os.Getenv("GO_GCFLAGS") != "" { t.Skipf("skipping test: 'go build' not compatible with setting $GO_GCFLAGS") } if !HasGoBuild() { t.Skipf("skipping test: 'go build' not available on %s/%s", runtime.GOOS, runtime.GOARCH) } } // HasGoRun reports whether the current system can run programs with “go run.” func HasGoRun() bool { // For now, having go run and having go build are the same. return HasGoBuild() } // MustHaveGoRun checks that the current system can run programs with “go run.” // If not, MustHaveGoRun calls t.Skip with an explanation. func MustHaveGoRun(t testing.TB) { if !HasGoRun() { t.Skipf("skipping test: 'go run' not available on %s/%s", runtime.GOOS, runtime.GOARCH) } } // GoToolPath reports the path to the Go tool. // It is a convenience wrapper around GoTool. // If the tool is unavailable GoToolPath calls t.Skip. // If the tool should be available and isn't, GoToolPath calls t.Fatal. func GoToolPath(t testing.TB) string { MustHaveGoBuild(t) path, err := GoTool() if err != nil { t.Fatal(err) } return path } // GoTool reports the path to the Go tool. func GoTool() (string, error) { if !HasGoBuild() { return "", errors.New("platform cannot run go tool") } var exeSuffix string if runtime.GOOS == "windows" { exeSuffix = ".exe" } path := filepath.Join(runtime.GOROOT(), "bin", "go"+exeSuffix) if _, err := os.Stat(path); err == nil { return path, nil } goBin, err := exec.LookPath("go" + exeSuffix) if err != nil { return "", errors.New("cannot find go tool: " + err.Error()) } return goBin, nil } // HasExec reports whether the current system can start new processes // using os.StartProcess or (more commonly) exec.Command. func HasExec() bool { switch runtime.GOOS { case "nacl", "js": return false case "darwin": if strings.HasPrefix(runtime.GOARCH, "arm") { return false } } return true } // HasSrc reports whether the entire source tree is available under GOROOT. func HasSrc() bool { switch runtime.GOOS { case "nacl": return false case "darwin": if strings.HasPrefix(runtime.GOARCH, "arm") { return false } } return true } // MustHaveExec checks that the current system can start new processes // using os.StartProcess or (more commonly) exec.Command. // If not, MustHaveExec calls t.Skip with an explanation. func MustHaveExec(t testing.TB) { if !HasExec() { t.Skipf("skipping test: cannot exec subprocess on %s/%s", runtime.GOOS, runtime.GOARCH) } } // HasExternalNetwork reports whether the current system can use // external (non-localhost) networks. func HasExternalNetwork() bool { return !testing.Short() && runtime.GOOS != "nacl" && runtime.GOOS != "js" } // MustHaveExternalNetwork checks that the current system can use // external (non-localhost) networks. // If not, MustHaveExternalNetwork calls t.Skip with an explanation. func MustHaveExternalNetwork(t testing.TB) { if runtime.GOOS == "nacl" || runtime.GOOS == "js" { t.Skipf("skipping test: no external network on %s", runtime.GOOS) } if testing.Short() { t.Skipf("skipping test: no external network in -short mode") } } var haveCGO bool // HasCGO reports whether the current system can use cgo. func HasCGO() bool { return haveCGO } // MustHaveCGO calls t.Skip if cgo is not available. func MustHaveCGO(t testing.TB) { if !haveCGO { t.Skipf("skipping test: no cgo") } } // HasSymlink reports whether the current system can use os.Symlink. func HasSymlink() bool { ok, _ := hasSymlink() return ok } // MustHaveSymlink reports whether the current system can use os.Symlink. // If not, MustHaveSymlink calls t.Skip with an explanation. func MustHaveSymlink(t testing.TB) { ok, reason := hasSymlink() if !ok { t.Skipf("skipping test: cannot make symlinks on %s/%s%s", runtime.GOOS, runtime.GOARCH, reason) } } // HasLink reports whether the current system can use os.Link. func HasLink() bool { // From Android release M (Marshmallow), hard linking files is blocked // and an attempt to call link() on a file will return EACCES. // - https://code.google.com/p/android-developer-preview/issues/detail?id=3150 return runtime.GOOS != "plan9" && runtime.GOOS != "android" } // MustHaveLink reports whether the current system can use os.Link. // If not, MustHaveLink calls t.Skip with an explanation. func MustHaveLink(t testing.TB) { if !HasLink() { t.Skipf("skipping test: hardlinks are not supported on %s/%s", runtime.GOOS, runtime.GOARCH) } } var flaky = flag.Bool("flaky", false, "run known-flaky tests too") func SkipFlaky(t testing.TB, issue int) { t.Helper() if !*flaky { t.Skipf("skipping known flaky test without the -flaky flag; see golang.org/issue/%d", issue) } } func SkipFlakyNet(t testing.TB) { t.Helper() if v, _ := strconv.ParseBool(os.Getenv("GO_BUILDER_FLAKY_NET")); v { t.Skip("skipping test on builder known to have frequent network failures") } } // CleanCmdEnv will fill cmd.Env with the environment, excluding certain // variables that could modify the behavior of the Go tools such as // GODEBUG and GOTRACEBACK. func CleanCmdEnv(cmd *exec.Cmd) *exec.Cmd { if cmd.Env != nil { panic("environment already set") } for _, env := range os.Environ() { // Exclude GODEBUG from the environment to prevent its output // from breaking tests that are trying to parse other command output. if strings.HasPrefix(env, "GODEBUG=") { continue } // Exclude GOTRACEBACK for the same reason. if strings.HasPrefix(env, "GOTRACEBACK=") { continue } cmd.Env = append(cmd.Env, env) } return cmd } go-internal-1.12.0/testenv/testenv_cgo.go000066400000000000000000000003411453631262600203570ustar00rootroot00000000000000// Copyright 2017 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. //go:build cgo package testenv func init() { haveCGO = true } go-internal-1.12.0/testenv/testenv_notwin.go000066400000000000000000000005551453631262600211340ustar00rootroot00000000000000// Copyright 2016 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. //go:build !windows package testenv import ( "runtime" ) func hasSymlink() (ok bool, reason string) { switch runtime.GOOS { case "android", "nacl", "plan9": return false, "" } return true, "" } go-internal-1.12.0/testenv/testenv_windows.go000066400000000000000000000020461453631262600213050ustar00rootroot00000000000000// Copyright 2016 The Go 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 testenv import ( "io/ioutil" "os" "path/filepath" "sync" "syscall" ) var symlinkOnce sync.Once var winSymlinkErr error func initWinHasSymlink() { tmpdir, err := ioutil.TempDir("", "symtest") if err != nil { panic("failed to create temp directory: " + err.Error()) } defer os.RemoveAll(tmpdir) err = os.Symlink("target", filepath.Join(tmpdir, "symlink")) if err != nil { err = err.(*os.LinkError).Err switch err { case syscall.EWINDOWS, syscall.ERROR_PRIVILEGE_NOT_HELD: winSymlinkErr = err } } } func hasSymlink() (ok bool, reason string) { symlinkOnce.Do(initWinHasSymlink) switch winSymlinkErr { case nil: return true, "" case syscall.EWINDOWS: return false, ": symlinks are not supported on your version of Windows" case syscall.ERROR_PRIVILEGE_NOT_HELD: return false, ": you don't have enough privileges to create symlinks" } return false, "" } go-internal-1.12.0/testscript/000077500000000000000000000000001453631262600162265ustar00rootroot00000000000000go-internal-1.12.0/testscript/clonefile.go000066400000000000000000000002671453631262600205220ustar00rootroot00000000000000//go:build unix && !darwin package testscript import "os" // cloneFile makes a clone of a file via a hard link. func cloneFile(from, to string) error { return os.Link(from, to) } go-internal-1.12.0/testscript/clonefile_darwin.go000066400000000000000000000003101453631262600220530ustar00rootroot00000000000000package testscript import "golang.org/x/sys/unix" // cloneFile makes a clone of a file via MacOS's `clonefile` syscall. func cloneFile(from, to string) error { return unix.Clonefile(from, to, 0) } go-internal-1.12.0/testscript/clonefile_other.go000066400000000000000000000005171453631262600217210ustar00rootroot00000000000000//go:build !unix package testscript import "fmt" // cloneFile does not attempt anything on Windows, as hard links on it have // led to "access denied" errors when deleting files at the end of a test. // We haven't tested platforms like plan9 or wasm/wasi. func cloneFile(from, to string) error { return fmt.Errorf("unavailable") } go-internal-1.12.0/testscript/cmd.go000066400000000000000000000405661453631262600173330ustar00rootroot00000000000000// Copyright 2018 The Go 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 testscript import ( "bufio" "bytes" "fmt" "io/ioutil" "os" "os/exec" "path/filepath" "regexp" "runtime" "strconv" "strings" "github.com/rogpeppe/go-internal/diff" "github.com/rogpeppe/go-internal/testscript/internal/pty" "github.com/rogpeppe/go-internal/txtar" ) // scriptCmds are the script command implementations. // Keep list and the implementations below sorted by name. // // NOTE: If you make changes here, update doc.go. var scriptCmds = map[string]func(*TestScript, bool, []string){ "cd": (*TestScript).cmdCd, "chmod": (*TestScript).cmdChmod, "cmp": (*TestScript).cmdCmp, "cmpenv": (*TestScript).cmdCmpenv, "cp": (*TestScript).cmdCp, "env": (*TestScript).cmdEnv, "exec": (*TestScript).cmdExec, "exists": (*TestScript).cmdExists, "grep": (*TestScript).cmdGrep, "mkdir": (*TestScript).cmdMkdir, "mv": (*TestScript).cmdMv, "rm": (*TestScript).cmdRm, "skip": (*TestScript).cmdSkip, "stderr": (*TestScript).cmdStderr, "stdin": (*TestScript).cmdStdin, "stdout": (*TestScript).cmdStdout, "ttyin": (*TestScript).cmdTtyin, "ttyout": (*TestScript).cmdTtyout, "stop": (*TestScript).cmdStop, "symlink": (*TestScript).cmdSymlink, "unix2dos": (*TestScript).cmdUNIX2DOS, "unquote": (*TestScript).cmdUnquote, "wait": (*TestScript).cmdWait, } // cd changes to a different directory. func (ts *TestScript) cmdCd(neg bool, args []string) { if neg { ts.Fatalf("unsupported: ! cd") } if len(args) != 1 { ts.Fatalf("usage: cd dir") } dir := args[0] if !filepath.IsAbs(dir) { dir = filepath.Join(ts.cd, dir) } info, err := os.Stat(dir) if os.IsNotExist(err) { ts.Fatalf("directory %s does not exist", dir) } ts.Check(err) if !info.IsDir() { ts.Fatalf("%s is not a directory", dir) } ts.cd = dir ts.Logf("%s\n", ts.cd) } func (ts *TestScript) cmdChmod(neg bool, args []string) { if neg { ts.Fatalf("unsupported: ! chmod") } if len(args) != 2 { ts.Fatalf("usage: chmod perm paths...") } perm, err := strconv.ParseUint(args[0], 8, 32) if err != nil || perm&uint64(os.ModePerm) != perm { ts.Fatalf("invalid mode: %s", args[0]) } for _, arg := range args[1:] { path := arg if !filepath.IsAbs(path) { path = filepath.Join(ts.cd, arg) } err := os.Chmod(path, os.FileMode(perm)) ts.Check(err) } } // cmp compares two files. func (ts *TestScript) cmdCmp(neg bool, args []string) { if len(args) != 2 { ts.Fatalf("usage: cmp file1 file2") } ts.doCmdCmp(neg, args, false) } // cmpenv compares two files with environment variable substitution. func (ts *TestScript) cmdCmpenv(neg bool, args []string) { if len(args) != 2 { ts.Fatalf("usage: cmpenv file1 file2") } ts.doCmdCmp(neg, args, true) } func (ts *TestScript) doCmdCmp(neg bool, args []string, env bool) { name1, name2 := args[0], args[1] text1 := ts.ReadFile(name1) absName2 := ts.MkAbs(name2) data, err := ioutil.ReadFile(absName2) ts.Check(err) text2 := string(data) if env { text2 = ts.expand(text2) } eq := text1 == text2 if neg { if eq { ts.Fatalf("%s and %s do not differ", name1, name2) } return // they differ, as expected } if eq { return // they are equal, as expected } if ts.params.UpdateScripts && !env { if scriptFile, ok := ts.scriptFiles[absName2]; ok { ts.scriptUpdates[scriptFile] = text1 return } // The file being compared against isn't in the txtar archive, so don't // update the script. } unifiedDiff := diff.Diff(name1, []byte(text1), name2, []byte(text2)) ts.Logf("%s", unifiedDiff) ts.Fatalf("%s and %s differ", name1, name2) } // cp copies files, maybe eventually directories. func (ts *TestScript) cmdCp(neg bool, args []string) { if neg { ts.Fatalf("unsupported: ! cp") } if len(args) < 2 { ts.Fatalf("usage: cp src... dst") } dst := ts.MkAbs(args[len(args)-1]) info, err := os.Stat(dst) dstDir := err == nil && info.IsDir() if len(args) > 2 && !dstDir { ts.Fatalf("cp: destination %s is not a directory", dst) } for _, arg := range args[:len(args)-1] { var ( src string data []byte mode os.FileMode ) switch arg { case "stdout": src = arg data = []byte(ts.stdout) mode = 0o666 case "stderr": src = arg data = []byte(ts.stderr) mode = 0o666 case "ttyout": src = arg data = []byte(ts.ttyout) mode = 0o666 default: src = ts.MkAbs(arg) info, err := os.Stat(src) ts.Check(err) mode = info.Mode() & 0o777 data, err = ioutil.ReadFile(src) ts.Check(err) } targ := dst if dstDir { targ = filepath.Join(dst, filepath.Base(src)) } ts.Check(ioutil.WriteFile(targ, data, mode)) } } // env displays or adds to the environment. func (ts *TestScript) cmdEnv(neg bool, args []string) { if neg { ts.Fatalf("unsupported: ! env") } if len(args) == 0 { printed := make(map[string]bool) // env list can have duplicates; only print effective value (from envMap) once for _, kv := range ts.env { k := envvarname(kv[:strings.Index(kv, "=")]) if !printed[k] { printed[k] = true ts.Logf("%s=%s\n", k, ts.envMap[k]) } } return } for _, env := range args { i := strings.Index(env, "=") if i < 0 { // Display value instead of setting it. ts.Logf("%s=%s\n", env, ts.Getenv(env)) continue } ts.Setenv(env[:i], env[i+1:]) } } var backgroundSpecifier = regexp.MustCompile(`^&([a-zA-Z_0-9]+&)?$`) // exec runs the given command. func (ts *TestScript) cmdExec(neg bool, args []string) { if len(args) < 1 || (len(args) == 1 && args[0] == "&") { ts.Fatalf("usage: exec program [args...] [&]") } var err error if len(args) > 0 && backgroundSpecifier.MatchString(args[len(args)-1]) { bgName := strings.TrimSuffix(strings.TrimPrefix(args[len(args)-1], "&"), "&") if ts.findBackground(bgName) != nil { ts.Fatalf("duplicate background process name %q", bgName) } var cmd *exec.Cmd cmd, err = ts.execBackground(args[0], args[1:len(args)-1]...) if err == nil { wait := make(chan struct{}) go func() { waitOrStop(ts.ctxt, cmd, -1) close(wait) }() ts.background = append(ts.background, backgroundCmd{bgName, cmd, wait, neg}) } ts.stdout, ts.stderr = "", "" } else { ts.stdout, ts.stderr, err = ts.exec(args[0], args[1:]...) if ts.stdout != "" { fmt.Fprintf(&ts.log, "[stdout]\n%s", ts.stdout) } if ts.stderr != "" { fmt.Fprintf(&ts.log, "[stderr]\n%s", ts.stderr) } if err == nil && neg { ts.Fatalf("unexpected command success") } } if err != nil { fmt.Fprintf(&ts.log, "[%v]\n", err) if ts.ctxt.Err() != nil { ts.Fatalf("test timed out while running command") } else if !neg { ts.Fatalf("unexpected command failure") } } } // exists checks that the list of files exists. func (ts *TestScript) cmdExists(neg bool, args []string) { var readonly bool if len(args) > 0 && args[0] == "-readonly" { readonly = true args = args[1:] } if len(args) == 0 { ts.Fatalf("usage: exists [-readonly] file...") } for _, file := range args { file = ts.MkAbs(file) info, err := os.Stat(file) if err == nil && neg { what := "file" if info.IsDir() { what = "directory" } ts.Fatalf("%s %s unexpectedly exists", what, file) } if err != nil && !neg { ts.Fatalf("%s does not exist", file) } if err == nil && !neg && readonly && info.Mode()&0o222 != 0 { ts.Fatalf("%s exists but is writable", file) } } } // mkdir creates directories. func (ts *TestScript) cmdMkdir(neg bool, args []string) { if neg { ts.Fatalf("unsupported: ! mkdir") } if len(args) < 1 { ts.Fatalf("usage: mkdir dir...") } for _, arg := range args { ts.Check(os.MkdirAll(ts.MkAbs(arg), 0o777)) } } func (ts *TestScript) cmdMv(neg bool, args []string) { if neg { ts.Fatalf("unsupported: ! mv") } if len(args) != 2 { ts.Fatalf("usage: mv old new") } ts.Check(os.Rename(ts.MkAbs(args[0]), ts.MkAbs(args[1]))) } // unquote unquotes files. func (ts *TestScript) cmdUnquote(neg bool, args []string) { if neg { ts.Fatalf("unsupported: ! unquote") } for _, arg := range args { file := ts.MkAbs(arg) data, err := ioutil.ReadFile(file) ts.Check(err) data, err = txtar.Unquote(data) ts.Check(err) err = ioutil.WriteFile(file, data, 0o666) ts.Check(err) } } // rm removes files or directories. func (ts *TestScript) cmdRm(neg bool, args []string) { if neg { ts.Fatalf("unsupported: ! rm") } if len(args) < 1 { ts.Fatalf("usage: rm file...") } for _, arg := range args { file := ts.MkAbs(arg) removeAll(file) // does chmod and then attempts rm ts.Check(os.RemoveAll(file)) // report error } } // skip marks the test skipped. func (ts *TestScript) cmdSkip(neg bool, args []string) { if len(args) > 1 { ts.Fatalf("usage: skip [msg]") } if neg { ts.Fatalf("unsupported: ! skip") } // Before we mark the test as skipped, shut down any background processes and // make sure they have returned the correct status. for _, bg := range ts.background { interruptProcess(bg.cmd.Process) } ts.cmdWait(false, nil) if len(args) == 1 { ts.t.Skip(args[0]) } ts.t.Skip() } func (ts *TestScript) cmdStdin(neg bool, args []string) { if neg { ts.Fatalf("unsupported: ! stdin") } if len(args) != 1 { ts.Fatalf("usage: stdin filename") } if ts.stdinPty { ts.Fatalf("conflicting use of 'stdin' and 'ttyin -stdin'") } ts.stdin = ts.ReadFile(args[0]) } // stdout checks that the last go command standard output matches a regexp. func (ts *TestScript) cmdStdout(neg bool, args []string) { scriptMatch(ts, neg, args, ts.stdout, "stdout") } // stderr checks that the last go command standard output matches a regexp. func (ts *TestScript) cmdStderr(neg bool, args []string) { scriptMatch(ts, neg, args, ts.stderr, "stderr") } // grep checks that file content matches a regexp. // Like stdout/stderr and unlike Unix grep, it accepts Go regexp syntax. func (ts *TestScript) cmdGrep(neg bool, args []string) { scriptMatch(ts, neg, args, "", "grep") } func (ts *TestScript) cmdTtyin(neg bool, args []string) { if !pty.Supported { ts.Fatalf("unsupported: ttyin on %s", runtime.GOOS) } if neg { ts.Fatalf("unsupported: ! ttyin") } switch len(args) { case 1: ts.ttyin = ts.ReadFile(args[0]) case 2: if args[0] != "-stdin" { ts.Fatalf("usage: ttyin [-stdin] filename") } if ts.stdin != "" { ts.Fatalf("conflicting use of 'stdin' and 'ttyin -stdin'") } ts.stdinPty = true ts.ttyin = ts.ReadFile(args[1]) default: ts.Fatalf("usage: ttyin [-stdin] filename") } if ts.ttyin == "" { ts.Fatalf("tty input file is empty") } } func (ts *TestScript) cmdTtyout(neg bool, args []string) { scriptMatch(ts, neg, args, ts.ttyout, "ttyout") } // stop stops execution of the test (marking it passed). func (ts *TestScript) cmdStop(neg bool, args []string) { if neg { ts.Fatalf("unsupported: ! stop") } if len(args) > 1 { ts.Fatalf("usage: stop [msg]") } if len(args) == 1 { ts.Logf("stop: %s\n", args[0]) } else { ts.Logf("stop\n") } ts.stopped = true } // symlink creates a symbolic link. func (ts *TestScript) cmdSymlink(neg bool, args []string) { if neg { ts.Fatalf("unsupported: ! symlink") } if len(args) != 3 || args[1] != "->" { ts.Fatalf("usage: symlink file -> target") } // Note that the link target args[2] is not interpreted with MkAbs: // it will be interpreted relative to the directory file is in. ts.Check(os.Symlink(args[2], ts.MkAbs(args[0]))) } // cmdUNIX2DOS converts files from UNIX line endings to DOS line endings. func (ts *TestScript) cmdUNIX2DOS(neg bool, args []string) { if neg { ts.Fatalf("unsupported: ! unix2dos") } if len(args) < 1 { ts.Fatalf("usage: unix2dos paths...") } for _, arg := range args { filename := ts.MkAbs(arg) data, err := ioutil.ReadFile(filename) ts.Check(err) dosData, err := unix2DOS(data) ts.Check(err) if err := ioutil.WriteFile(filename, dosData, 0o666); err != nil { ts.Fatalf("%s: %v", filename, err) } } } // Tait waits for background commands to exit, setting stderr and stdout to their result. func (ts *TestScript) cmdWait(neg bool, args []string) { if len(args) > 1 { ts.Fatalf("usage: wait [name]") } if neg { ts.Fatalf("unsupported: ! wait") } if len(args) > 0 { ts.waitBackgroundOne(args[0]) } else { ts.waitBackground(true) } } func (ts *TestScript) waitBackgroundOne(bgName string) { bg := ts.findBackground(bgName) if bg == nil { ts.Fatalf("unknown background process %q", bgName) } <-bg.wait ts.stdout = bg.cmd.Stdout.(*strings.Builder).String() ts.stderr = bg.cmd.Stderr.(*strings.Builder).String() if ts.stdout != "" { fmt.Fprintf(&ts.log, "[stdout]\n%s", ts.stdout) } if ts.stderr != "" { fmt.Fprintf(&ts.log, "[stderr]\n%s", ts.stderr) } // Note: ignore bg.neg, which only takes effect on the non-specific // wait command. if bg.cmd.ProcessState.Success() { if bg.neg { ts.Fatalf("unexpected command success") } } else { if ts.ctxt.Err() != nil { ts.Fatalf("test timed out while running command") } else if !bg.neg { ts.Fatalf("unexpected command failure") } } // Remove this process from the list of running background processes. for i := range ts.background { if bg == &ts.background[i] { ts.background = append(ts.background[:i], ts.background[i+1:]...) break } } } func (ts *TestScript) findBackground(bgName string) *backgroundCmd { if bgName == "" { return nil } for i := range ts.background { bg := &ts.background[i] if bg.name == bgName { return bg } } return nil } func (ts *TestScript) waitBackground(checkStatus bool) { var stdouts, stderrs []string for _, bg := range ts.background { <-bg.wait args := append([]string{filepath.Base(bg.cmd.Args[0])}, bg.cmd.Args[1:]...) fmt.Fprintf(&ts.log, "[background] %s: %v\n", strings.Join(args, " "), bg.cmd.ProcessState) cmdStdout := bg.cmd.Stdout.(*strings.Builder).String() if cmdStdout != "" { fmt.Fprintf(&ts.log, "[stdout]\n%s", cmdStdout) stdouts = append(stdouts, cmdStdout) } cmdStderr := bg.cmd.Stderr.(*strings.Builder).String() if cmdStderr != "" { fmt.Fprintf(&ts.log, "[stderr]\n%s", cmdStderr) stderrs = append(stderrs, cmdStderr) } if !checkStatus { continue } if bg.cmd.ProcessState.Success() { if bg.neg { ts.Fatalf("unexpected command success") } } else { if ts.ctxt.Err() != nil { ts.Fatalf("test timed out while running command") } else if !bg.neg { ts.Fatalf("unexpected command failure") } } } ts.stdout = strings.Join(stdouts, "") ts.stderr = strings.Join(stderrs, "") ts.background = nil } // scriptMatch implements both stdout and stderr. func scriptMatch(ts *TestScript, neg bool, args []string, text, name string) { n := 0 if len(args) >= 1 && strings.HasPrefix(args[0], "-count=") { if neg { ts.Fatalf("cannot use -count= with negated match") } var err error n, err = strconv.Atoi(args[0][len("-count="):]) if err != nil { ts.Fatalf("bad -count=: %v", err) } if n < 1 { ts.Fatalf("bad -count=: must be at least 1") } args = args[1:] } extraUsage := "" want := 1 if name == "grep" { extraUsage = " file" want = 2 } if len(args) != want { ts.Fatalf("usage: %s [-count=N] 'pattern'%s", name, extraUsage) } pattern := args[0] re, err := regexp.Compile(`(?m)` + pattern) ts.Check(err) isGrep := name == "grep" if isGrep { name = args[1] // for error messages data, err := ioutil.ReadFile(ts.MkAbs(args[1])) ts.Check(err) text = string(data) } if neg { if re.MatchString(text) { if isGrep { ts.Logf("[%s]\n%s\n", name, text) } ts.Fatalf("unexpected match for %#q found in %s: %s", pattern, name, re.FindString(text)) } } else { if !re.MatchString(text) { if isGrep { ts.Logf("[%s]\n%s\n", name, text) } ts.Fatalf("no match for %#q found in %s", pattern, name) } if n > 0 { count := len(re.FindAllString(text, -1)) if count != n { if isGrep { ts.Logf("[%s]\n%s\n", name, text) } ts.Fatalf("have %d matches for %#q, want %d", count, pattern, n) } } } } // unix2DOS returns data with UNIX line endings converted to DOS line endings. func unix2DOS(data []byte) ([]byte, error) { sb := &strings.Builder{} s := bufio.NewScanner(bytes.NewReader(data)) for s.Scan() { if _, err := sb.Write(s.Bytes()); err != nil { return nil, err } if _, err := sb.WriteString("\r\n"); err != nil { return nil, err } } if err := s.Err(); err != nil { return nil, err } return []byte(sb.String()), nil } go-internal-1.12.0/testscript/doc.go000066400000000000000000000321411453631262600173230ustar00rootroot00000000000000// Copyright 2018 The Go 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 testscript provides support for defining filesystem-based tests by creating scripts in a directory. To invoke the tests, call testscript.Run. For example: func TestFoo(t *testing.T) { testscript.Run(t, testscript.Params{ Dir: "testdata", }) } A testscript directory holds test scripts with extension txtar or txt run during 'go test'. Each script defines a subtest; the exact set of allowable commands in a script are defined by the parameters passed to the Run function. To run a specific script foo.txtar or foo.txt, run go test cmd/go -run=TestName/^foo$ where TestName is the name of the test that Run is called from. To define an executable command (or several) that can be run as part of the script, call RunMain with the functions that implement the command's functionality. The command functions will be called in a separate process, so are free to mutate global variables without polluting the top level test binary. func TestMain(m *testing.M) { os.Exit(testscript.RunMain(m, map[string] func() int{ "testscript": testscriptMain, })) } In general script files should have short names: a few words, not whole sentences. The first word should be the general category of behavior being tested, often the name of a subcommand to be tested or a concept (vendor, pattern). Each script is a text archive (go doc golang.org/x/tools/txtar). The script begins with an actual command script to run followed by the content of zero or more supporting files to create in the script's temporary file system before it starts executing. As an example: # hello world exec cat hello.text stdout 'hello world\n' ! stderr . -- hello.text -- hello world Each script runs in a fresh temporary work directory tree, available to scripts as $WORK. Scripts also have access to these other environment variables: PATH= HOME=/no-home TMPDIR=$WORK/.tmp devnull= /= := $=$ The environment variable $exe (lowercase) is an empty string on most systems, ".exe" on Windows. The script's supporting files are unpacked relative to $WORK and then the script begins execution in that directory as well. Thus the example above runs in $WORK with $WORK/hello.txtar containing the listed contents. The lines at the top of the script are a sequence of commands to be executed by a small script engine in the testscript package (not the system shell). The script stops and the overall test fails if any particular command fails. Each line is parsed into a sequence of space-separated command words, with environment variable expansion and # marking an end-of-line comment. Adding single quotes around text keeps spaces in that text from being treated as word separators and also disables environment variable expansion. Inside a single-quoted block of text, a repeated single quote indicates a literal single quote, as in: 'Don''t communicate by sharing memory.' A line beginning with # is a comment and conventionally explains what is being done or tested at the start of a new phase in the script. A special form of environment variable syntax can be used to quote regexp metacharacters inside environment variables. The "@R" suffix is special, and indicates that the variable should be quoted. ${VAR@R} The command prefix ! indicates that the command on the rest of the line (typically go or a matching predicate) must fail, not succeed. Only certain commands support this prefix. They are indicated below by [!] in the synopsis. The command prefix [cond] indicates that the command on the rest of the line should only run when the condition is satisfied. The predefined conditions are: - [short] for testing.Short() - [net] for whether the external network can be used - [link] for whether the OS has hard link support - [symlink] for whether the OS has symbolic link support - [exec:prog] for whether prog is available for execution (found by exec.LookPath) - [gc] for whether Go was built with gc - [gccgo] for whether Go was built with gccgo - [go1.x] for whether the Go version is 1.x or later - [unix] for whether the OS is Unix-like (that is, would match the 'unix' build constraint) Any known values of GOOS and GOARCH can also be used as conditions. They will be satisfied if the target OS or architecture match the specified value. For example, the condition [darwin] is true if GOOS=darwin, and [amd64] is true if GOARCH=amd64. A condition can be negated: [!short] means to run the rest of the line when testing.Short() is false. Additional conditions can be added by passing a function to Params.Condition. The predefined commands are: - cd dir Change to the given directory for future commands. - chmod perm path... Change the permissions of the files or directories named by the path arguments to the given octal mode (000 to 777). - [!] cmp file1 file2 Check that the named files have (or do not have) the same content. By convention, file1 is the actual data and file2 the expected data. File1 can be "stdout" or "stderr" to use the standard output or standard error from the most recent exec or wait command. (If the files have differing content and the command is not negated, the failure prints a diff.) - [!] cmpenv file1 file2 Like cmp, but environment variables in file2 are substituted before the comparison. For example, $GOOS is replaced by the target GOOS. - cp src... dst Copy the listed files to the target file or existing directory. src can include "stdout" or "stderr" to use the standard output or standard error from the most recent exec or go command. - env [key=value...] With no arguments, print the environment (useful for debugging). Otherwise add the listed key=value pairs to the environment. - [!] exec program [args...] [&] Run the given executable program with the arguments. It must (or must not) succeed. Note that 'exec' does not terminate the script (unlike in Unix shells). If the last token is '&', the program executes in the background. The standard output and standard error of the previous command is cleared, but the output of the background process is buffered — and checking of its exit status is delayed — until the next call to 'wait', 'skip', or 'stop' or the end of the test. At the end of the test, any remaining background processes are terminated using os.Interrupt (if supported) or os.Kill. If the last token is '&word&` (where "word" is alphanumeric), the command runs in the background but has a name, and can be waited for specifically by passing the word to 'wait'. Standard input can be provided using the stdin command; this will be cleared after exec has been called. - [!] exists [-readonly] file... Each of the listed files or directories must (or must not) exist. If -readonly is given, the files or directories must be unwritable. - [!] grep [-count=N] pattern file The file's content must (or must not) match the regular expression pattern. For positive matches, -count=N specifies an exact number of matches to require. - mkdir path... Create the listed directories, if they do not already exists. - mv path1 path2 Rename path1 to path2. OS-specific restrictions may apply when path1 and path2 are in different directories. - rm file... Remove the listed files or directories. - skip [message] Mark the test skipped, including the message if given. - [!] stderr [-count=N] pattern Apply the grep command (see above) to the standard error from the most recent exec or wait command. - stdin file Set the standard input for the next exec command to the contents of the given file. File can be "stdout" or "stderr" to use the standard output or standard error from the most recent exec or wait command. - [!] stdout [-count=N] pattern Apply the grep command (see above) to the standard output from the most recent exec or wait command. - ttyin [-stdin] file Attach the next exec command to a controlling pseudo-terminal, and use the contents of the given file as the raw terminal input. If -stdin is specified, also attach the terminal to standard input. Note that this does not attach the terminal to standard output/error. - [!] ttyout [-count=N] pattern Apply the grep command (see above) to the raw controlling terminal output from the most recent exec command. - stop [message] Stop the test early (marking it as passing), including the message if given. - symlink file -> target Create file as a symlink to target. The -> (like in ls -l output) is required. - unquote file... Rewrite each file by replacing any leading ">" characters from each line. This enables a file to contain substrings that look like txtar file markers. See also https://godoc.org/github.com/rogpeppe/go-internal/txtar#Unquote - wait [command] Wait for all 'exec' and 'go' commands started in the background (with the '&' token) to exit, and display success or failure status for them. After a call to wait, the 'stderr' and 'stdout' commands will apply to the concatenation of the corresponding streams of the background commands, in the order in which those commands were started. If an argument is specified, it waits for just that command. When TestScript runs a script and the script fails, by default TestScript shows the execution of the most recent phase of the script (since the last # comment) and only shows the # comments for earlier phases. For example, here is a multi-phase script with a bug in it (TODO: make this example less go-command specific): # GOPATH with p1 in d2, p2 in d2 env GOPATH=$WORK/d1${:}$WORK/d2 # build & install p1 env go install -i p1 ! stale p1 ! stale p2 # modify p2 - p1 should appear stale cp $WORK/p2x.go $WORK/d2/src/p2/p2.go stale p1 p2 # build & install p1 again go install -i p11 ! stale p1 ! stale p2 -- $WORK/d1/src/p1/p1.go -- package p1 import "p2" func F() { p2.F() } -- $WORK/d2/src/p2/p2.go -- package p2 func F() {} -- $WORK/p2x.go -- package p2 func F() {} func G() {} The bug is that the final phase installs p11 instead of p1. The test failure looks like: $ go test -run=Script --- FAIL: TestScript (3.75s) --- FAIL: TestScript/install_rebuild_gopath (0.16s) script_test.go:223: # GOPATH with p1 in d2, p2 in d2 (0.000s) # build & install p1 (0.087s) # modify p2 - p1 should appear stale (0.029s) # build & install p1 again (0.022s) > go install -i p11 [stderr] can't load package: package p11: cannot find package "p11" in any of: /Users/rsc/go/src/p11 (from $GOROOT) $WORK/d1/src/p11 (from $GOPATH) $WORK/d2/src/p11 [exit status 1] FAIL: unexpected go command failure script_test.go:73: failed at testdata/script/install_rebuild_gopath.txt:15 in $WORK/gopath/src FAIL exit status 1 FAIL cmd/go 4.875s $ Note that the commands in earlier phases have been hidden, so that the relevant commands are more easily found, and the elapsed time for a completed phase is shown next to the phase heading. To see the entire execution, use "go test -v", which also adds an initial environment dump to the beginning of the log. Note also that in reported output, the actual name of the per-script temporary directory has been consistently replaced with the literal string $WORK. If Params.TestWork is true, it causes each test to log the name of its $WORK directory and other environment variable settings and also to leave that directory behind when it exits, for manual debugging of failing tests: $ go test -run=Script -testwork --- FAIL: TestScript (3.75s) --- FAIL: TestScript/install_rebuild_gopath (0.16s) script_test.go:223: WORK=/tmp/cmd-go-test-745953508/script-install_rebuild_gopath GOARCH= GOCACHE=/Users/rsc/Library/Caches/go-build GOOS= GOPATH=$WORK/gopath GOROOT=/Users/rsc/go HOME=/no-home TMPDIR=$WORK/tmp exe= # GOPATH with p1 in d2, p2 in d2 (0.000s) # build & install p1 (0.085s) # modify p2 - p1 should appear stale (0.030s) # build & install p1 again (0.019s) > go install -i p11 [stderr] can't load package: package p11: cannot find package "p11" in any of: /Users/rsc/go/src/p11 (from $GOROOT) $WORK/d1/src/p11 (from $GOPATH) $WORK/d2/src/p11 [exit status 1] FAIL: unexpected go command failure script_test.go:73: failed at testdata/script/install_rebuild_gopath.txt:15 in $WORK/gopath/src FAIL exit status 1 FAIL cmd/go 4.875s $ $ WORK=/tmp/cmd-go-test-745953508/script-install_rebuild_gopath $ cd $WORK/d1/src/p1 $ cat p1.go package p1 import "p2" func F() { p2.F() } $ */ package testscript go-internal-1.12.0/testscript/exe.go000066400000000000000000000107711453631262600173440ustar00rootroot00000000000000// Copyright 2018 The Go 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 testscript import ( "io" "io/ioutil" "log" "os" "path/filepath" "runtime" "strings" ) // TestingM is implemented by *testing.M. It's defined as an interface // to allow testscript to co-exist with other testing frameworks // that might also wish to call M.Run. type TestingM interface { Run() int } // Deprecated: this option is no longer used. func IgnoreMissedCoverage() {} // RunMain should be called within a TestMain function to allow // subcommands to be run in the testscript context. // // The commands map holds the set of command names, each // with an associated run function which should return the // code to pass to os.Exit. It's OK for a command function to // exit itself, but this may result in loss of coverage information. // // When Run is called, these commands are installed as regular commands in the shell // path, so can be invoked with "exec" or via any other command (for example a shell script). // // For backwards compatibility, the commands declared in the map can be run // without "exec" - that is, "foo" will behave like "exec foo". // This can be disabled with Params.RequireExplicitExec to keep consistency // across test scripts, and to keep separate process executions explicit. // // This function returns an exit code to pass to os.Exit, after calling m.Run. func RunMain(m TestingM, commands map[string]func() int) (exitCode int) { // Depending on os.Args[0], this is either the top-level execution of // the test binary by "go test", or the execution of one of the provided // commands via "foo" or "exec foo". cmdName := filepath.Base(os.Args[0]) if runtime.GOOS == "windows" { cmdName = strings.TrimSuffix(cmdName, ".exe") } mainf := commands[cmdName] if mainf == nil { // Unknown command; this is just the top-level execution of the // test binary by "go test". // Set up all commands in a directory, added in $PATH. tmpdir, err := ioutil.TempDir("", "testscript-main") if err != nil { log.Printf("could not set up temporary directory: %v", err) return 2 } defer func() { if err := os.RemoveAll(tmpdir); err != nil { log.Printf("cannot delete temporary directory: %v", err) exitCode = 2 } }() bindir := filepath.Join(tmpdir, "bin") if err := os.MkdirAll(bindir, 0o777); err != nil { log.Printf("could not set up PATH binary directory: %v", err) return 2 } os.Setenv("PATH", bindir+string(filepath.ListSeparator)+os.Getenv("PATH")) // We're not in a subcommand. for name := range commands { name := name // Set up this command in the directory we added to $PATH. binfile := filepath.Join(bindir, name) if runtime.GOOS == "windows" { binfile += ".exe" } binpath, err := os.Executable() if err == nil { err = copyBinary(binpath, binfile) } if err != nil { log.Printf("could not set up %s in $PATH: %v", name, err) return 2 } scriptCmds[name] = func(ts *TestScript, neg bool, args []string) { if ts.params.RequireExplicitExec { ts.Fatalf("use 'exec %s' rather than '%s' (because RequireExplicitExec is enabled)", name, name) } ts.cmdExec(neg, append([]string{name}, args...)) } } return m.Run() } // The command being registered is being invoked, so run it, then exit. os.Args[0] = cmdName return mainf() } // copyBinary makes a copy of a binary to a new location. It is used as part of // setting up top-level commands in $PATH. // // It does not attempt to use symlinks for two reasons: // // First, some tools like cmd/go's -toolexec will be clever enough to realise // when they're given a symlink, and they will use the symlink target for // executing the program. This breaks testscript, as we depend on os.Args[0] to // know what command to run. // // Second, symlinks might not be available on some environments, so we have to // implement a "full copy" fallback anyway. // // However, we do try to use cloneFile, since that will probably work on most // unix-like setups. Note that "go test" also places test binaries in the // system's temporary directory, like we do. func copyBinary(from, to string) error { if err := cloneFile(from, to); err == nil { return nil } writer, err := os.OpenFile(to, os.O_WRONLY|os.O_CREATE, 0o777) if err != nil { return err } defer writer.Close() reader, err := os.Open(from) if err != nil { return err } defer reader.Close() _, err = io.Copy(writer, reader) return err } go-internal-1.12.0/testscript/internal/000077500000000000000000000000001453631262600200425ustar00rootroot00000000000000go-internal-1.12.0/testscript/internal/pty/000077500000000000000000000000001453631262600206565ustar00rootroot00000000000000go-internal-1.12.0/testscript/internal/pty/pty.go000066400000000000000000000023451453631262600220250ustar00rootroot00000000000000//go:build linux || darwin // +build linux darwin package pty import ( "fmt" "os" "os/exec" "syscall" ) const Supported = true func SetCtty(cmd *exec.Cmd, tty *os.File) { cmd.SysProcAttr = &syscall.SysProcAttr{ Setctty: true, Setsid: true, Ctty: 3, } cmd.ExtraFiles = []*os.File{tty} } func Open() (pty, tty *os.File, err error) { p, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0) if err != nil { return nil, nil, fmt.Errorf("failed to open pty multiplexer: %v", err) } defer func() { if err != nil { p.Close() } }() name, err := ptyName(p) if err != nil { return nil, nil, fmt.Errorf("failed to obtain tty name: %v", err) } if err := ptyGrant(p); err != nil { return nil, nil, fmt.Errorf("failed to grant pty: %v", err) } if err := ptyUnlock(p); err != nil { return nil, nil, fmt.Errorf("failed to unlock pty: %v", err) } t, err := os.OpenFile(name, os.O_RDWR|syscall.O_NOCTTY, 0) if err != nil { return nil, nil, fmt.Errorf("failed to open TTY: %v", err) } return p, t, nil } func ioctl(f *os.File, name string, cmd, ptr uintptr) error { _, _, err := syscall.Syscall(syscall.SYS_IOCTL, f.Fd(), cmd, ptr) if err != 0 { return fmt.Errorf("%s ioctl failed: %v", name, err) } return nil } go-internal-1.12.0/testscript/internal/pty/pty_darwin.go000066400000000000000000000014221453631262600233640ustar00rootroot00000000000000package pty import ( "bytes" "os" "syscall" "unsafe" ) func ptyName(f *os.File) (string, error) { // Parameter length is encoded in the low 13 bits of the top word. // See https://github.com/apple/darwin-xnu/blob/2ff845c2e0/bsd/sys/ioccom.h#L69-L77 const IOCPARM_MASK = 0x1fff const TIOCPTYGNAME_PARM_LEN = (syscall.TIOCPTYGNAME >> 16) & IOCPARM_MASK out := make([]byte, TIOCPTYGNAME_PARM_LEN) err := ioctl(f, "TIOCPTYGNAME", syscall.TIOCPTYGNAME, uintptr(unsafe.Pointer(&out[0]))) if err != nil { return "", err } i := bytes.IndexByte(out, 0x00) return string(out[:i]), nil } func ptyGrant(f *os.File) error { return ioctl(f, "TIOCPTYGRANT", syscall.TIOCPTYGRANT, 0) } func ptyUnlock(f *os.File) error { return ioctl(f, "TIOCPTYUNLK", syscall.TIOCPTYUNLK, 0) } go-internal-1.12.0/testscript/internal/pty/pty_linux.go000066400000000000000000000007271453631262600232460ustar00rootroot00000000000000package pty import ( "os" "strconv" "syscall" "unsafe" ) func ptyName(f *os.File) (string, error) { var out uint err := ioctl(f, "TIOCGPTN", syscall.TIOCGPTN, uintptr(unsafe.Pointer(&out))) if err != nil { return "", err } return "/dev/pts/" + strconv.Itoa(int(out)), nil } func ptyGrant(f *os.File) error { return nil } func ptyUnlock(f *os.File) error { var zero int return ioctl(f, "TIOCSPTLCK", syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&zero))) } go-internal-1.12.0/testscript/internal/pty/pty_unsupported.go000066400000000000000000000005451453631262600244750ustar00rootroot00000000000000//go:build !linux && !darwin // +build !linux,!darwin package pty import ( "fmt" "os" "os/exec" "runtime" ) const Supported = false func SetCtty(cmd *exec.Cmd, tty *os.File) error { panic("SetCtty called on unsupported platform") } func Open() (pty, tty *os.File, err error) { return nil, nil, fmt.Errorf("pty unsupported on %s", runtime.GOOS) } go-internal-1.12.0/testscript/testdata/000077500000000000000000000000001453631262600200375ustar00rootroot00000000000000go-internal-1.12.0/testscript/testdata/big_diff.txt000066400000000000000000004212161453631262600223370ustar00rootroot00000000000000# Verify the behaviour of cmp in the case of a diff between two # large files (with a large diff) unquote dir/script.txt ! testscript dir env cmpenv stdout stdout.golden -- stdout.golden -- > cmp a b diff a b --- a +++ b @@ -1,1017 +1,1036 @@ 0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 -E07BDA2D3E411F8AE1E2B2F3A7D95342 -840F2018A642B9956896793DE31E7059 -9D8DCB6C73C034185419A3CA355ABEDA -13A225190669971F58E1B97AC92D8701 -A7361785190939C924748BD5AAD2C38D -0A846FFACD16E92D74B1CFC38263DAED -5A85FE36ECB3B9369E03465338F1D2F4 -80D3C2C75E495EFFAEA9E56FA262D1C8 -CD5206C016A0CC44CCE3187A128B0654 -18A23CE2287673019BE407FB31A4A0C2 -BD5C67BC3D29256E1BDEB78F5A43DF46 -336B82DE9B7BE168E8DFCE82310613AE -51C1CCA42F66F5B1F4C17396DE8EDAA7 -402A9501F16DE1B9FA81CFCDF3F54392 +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +0A846FFACD16E92D74B1CFC38263DAED +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +13A225190669971F58E1B97AC92D8701 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +18A23CE2287673019BE407FB31A4A0C2 +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +336B82DE9B7BE168E8DFCE82310613AE +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +402A9501F16DE1B9FA81CFCDF3F54392 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +51C1CCA42F66F5B1F4C17396DE8EDAA7 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +5A85FE36ECB3B9369E03465338F1D2F4 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +80D3C2C75E495EFFAEA9E56FA262D1C8 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +840F2018A642B9956896793DE31E7059 +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +9D8DCB6C73C034185419A3CA355ABEDA +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +A7361785190939C924748BD5AAD2C38D +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +BD5C67BC3D29256E1BDEB78F5A43DF46 +CD5206C016A0CC44CCE3187A128B0654 +CD5206C016A0CC44CCE3187A128B0654 +CD5206C016A0CC44CCE3187A128B0654 +CD5206C016A0CC44CCE3187A128B0654 +CD5206C016A0CC44CCE3187A128B0654 +CD5206C016A0CC44CCE3187A128B0654 +CD5206C016A0CC44CCE3187A128B0654 +CD5206C016A0CC44CCE3187A128B0654 +CD5206C016A0CC44CCE3187A128B0654 +CD5206C016A0CC44CCE3187A128B0654 +CD5206C016A0CC44CCE3187A128B0654 +CD5206C016A0CC44CCE3187A128B0654 +CD5206C016A0CC44CCE3187A128B0654 +CD5206C016A0CC44CCE3187A128B0654 +CD5206C016A0CC44CCE3187A128B0654 +CD5206C016A0CC44CCE3187A128B0654 FAIL: $$WORK${/}dir${/}script.txt:1: a and b differ -- dir/script.txt -- >cmp a b > >-- a -- >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >E07BDA2D3E411F8AE1E2B2F3A7D95342 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >13A225190669971F58E1B97AC92D8701 >A7361785190939C924748BD5AAD2C38D >0A846FFACD16E92D74B1CFC38263DAED >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >CD5206C016A0CC44CCE3187A128B0654 >18A23CE2287673019BE407FB31A4A0C2 >BD5C67BC3D29256E1BDEB78F5A43DF46 >336B82DE9B7BE168E8DFCE82310613AE >51C1CCA42F66F5B1F4C17396DE8EDAA7 >402A9501F16DE1B9FA81CFCDF3F54392 >-- b -- >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >0A846FFACD16E92D74B1CFC38263DAED >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >13A225190669971F58E1B97AC92D8701 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >18A23CE2287673019BE407FB31A4A0C2 >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >336B82DE9B7BE168E8DFCE82310613AE >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >402A9501F16DE1B9FA81CFCDF3F54392 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >51C1CCA42F66F5B1F4C17396DE8EDAA7 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >5A85FE36ECB3B9369E03465338F1D2F4 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >80D3C2C75E495EFFAEA9E56FA262D1C8 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >840F2018A642B9956896793DE31E7059 >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >9D8DCB6C73C034185419A3CA355ABEDA >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >A7361785190939C924748BD5AAD2C38D >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >BD5C67BC3D29256E1BDEB78F5A43DF46 >CD5206C016A0CC44CCE3187A128B0654 >CD5206C016A0CC44CCE3187A128B0654 >CD5206C016A0CC44CCE3187A128B0654 >CD5206C016A0CC44CCE3187A128B0654 >CD5206C016A0CC44CCE3187A128B0654 >CD5206C016A0CC44CCE3187A128B0654 >CD5206C016A0CC44CCE3187A128B0654 >CD5206C016A0CC44CCE3187A128B0654 >CD5206C016A0CC44CCE3187A128B0654 >CD5206C016A0CC44CCE3187A128B0654 >CD5206C016A0CC44CCE3187A128B0654 >CD5206C016A0CC44CCE3187A128B0654 >CD5206C016A0CC44CCE3187A128B0654 >CD5206C016A0CC44CCE3187A128B0654 >CD5206C016A0CC44CCE3187A128B0654 >CD5206C016A0CC44CCE3187A128B0654 go-internal-1.12.0/testscript/testdata/cmd_stdout_stderr.txt000066400000000000000000000025671453631262600243420ustar00rootroot00000000000000# Verify that when we don't update stdout when we don't attempt to write via Stdout() fprintargs stdout hello stdout from fprintargs stdout 'hello stdout from fprintargs' echoandexit 0 stdout 'hello stdout from fprintargs' # Verify that when we don't update stderr when we don't attempt to write via Stderr() fprintargs stderr hello stderr from fprintargs stderr 'hello stderr from fprintargs' echoandexit 0 stderr 'hello stderr from fprintargs' # Verify that we do update stdout when we attempt to write via Stdout() or Stderr() fprintargs stdout hello stdout from fprintargs stdout 'hello stdout from fprintargs' ! stderr .+ echoandexit 0 'hello stdout from echoandexit' stdout 'hello stdout from echoandexit' ! stderr .+ fprintargs stdout hello stdout from fprintargs stdout 'hello stdout from fprintargs' ! stderr .+ echoandexit 0 '' 'hello stderr from echoandexit' ! stdout .+ stderr 'hello stderr from echoandexit' # Verify that we do update stderr when we attempt to write via Stdout() or Stderr() fprintargs stderr hello stderr from fprintargs ! stdout .+ stderr 'hello stderr from fprintargs' echoandexit 0 'hello stdout from echoandexit' stdout 'hello stdout from echoandexit' ! stderr .+ fprintargs stdout hello stdout from fprintargs stdout 'hello stdout from fprintargs' ! stderr .+ echoandexit 0 '' 'hello stderr from echoandexit' ! stdout .+ stderr 'hello stderr from echoandexit' go-internal-1.12.0/testscript/testdata/cmpenv.txt000066400000000000000000000000731453631262600220700ustar00rootroot00000000000000env $=$ cmpenv file1 file2 -- file1 -- $i -- file2 -- $$i go-internal-1.12.0/testscript/testdata/command.txt000066400000000000000000000000751453631262600222200ustar00rootroot00000000000000printargs a b 'c d' stdout '\["printargs" "a" "b" "c d"\]\n' go-internal-1.12.0/testscript/testdata/commandstatus.txt000066400000000000000000000000371453631262600234620ustar00rootroot00000000000000! status 1 ! status 2 status 0 go-internal-1.12.0/testscript/testdata/cond.txt000066400000000000000000000007701453631262600215270ustar00rootroot00000000000000# test that exactly one of gc and gccgo is set [gc] mkdir gc_true [gccgo] mkdir gccgo_true [gc] ! exists gccgo_true [!gc] exists gccgo_true [gccgo] ! exists gc_true [!gccgo] exists gc_true # test that go version build tags are set [go1.1] mkdir go1.x [go2.1] mkdir go2.x exists go1.x ! exists go2.x # unix should be true on Linux and MacOS, but not on Windows. # Both platforms are tested on CI. [unix] mkdir unix_true [linux] exists unix_true [darwin] exists unix_true [windows] ! exists unix_true go-internal-1.12.0/testscript/testdata/cpstdout.txt000066400000000000000000000003401453631262600224420ustar00rootroot00000000000000[!exec:cat] stop # hello world exec cat hello.text cp stdout got cmp got hello.text ! cmp got different.text exists got mv got new ! exists got cmp new hello.text -- hello.text -- hello world -- different.text -- goodbye go-internal-1.12.0/testscript/testdata/defer.txt000066400000000000000000000000361453631262600216640ustar00rootroot00000000000000testdefer testdefer testdefer go-internal-1.12.0/testscript/testdata/evalsymlink.txt000066400000000000000000000004671453631262600231450ustar00rootroot00000000000000# If ioutil.TempDir returns a sym linked dir (default behaviour in macOS for example) the # matcher will have problems with external programs that uses the real path. # This script tests that $WORK is matched in a consistent way (also see #79). [windows] skip exec pwd stdout ^$WORK$ exec pwd -P stdout ^$WORK$ go-internal-1.12.0/testscript/testdata/exec_path_change.txt000066400000000000000000000010251453631262600240430ustar00rootroot00000000000000# If the PATH environment variable is set in the testscript.Params.Setup phase # or set directly within a script, exec should honour that PATH [!exec:go] skip env HOME=$WORK${/}home [windows] env USERPROFILE=$WORK\home [windows] env LOCALAPPDATA=$WORK\appdata cd go exec go$exe version stdout 'go version' exec go$exe build env PATH=$WORK${/}go${:}$PATH exec go$exe version stdout 'This is not go' -- go/go.mod -- module example.com/go -- go/main.go -- package main import "fmt" func main() { fmt.Println("This is not go") } go-internal-1.12.0/testscript/testdata/execguard.txt000066400000000000000000000001441453631262600225460ustar00rootroot00000000000000[exec:nosuchcommand] exec nosuchcommand [!exec:cat] stop exec cat foo stdout 'foo\n' -- foo -- foo go-internal-1.12.0/testscript/testdata/exists.txt000066400000000000000000000002741453631262600221220ustar00rootroot00000000000000chmod 444 foo_r exists foo ! exists unfoo # TODO The following line fails but probably should not. # ! exists -readonly foo exists foo_r exists -readonly foo_r -- foo -- foo -- foo_r -- go-internal-1.12.0/testscript/testdata/hello.txt000066400000000000000000000001641453631262600217040ustar00rootroot00000000000000[!exec:cat] stop # hello world exec cat hello.text stdout 'hello world\n' ! stderr . -- hello.text -- hello world go-internal-1.12.0/testscript/testdata/interrupt.txt000066400000000000000000000001361453631262600226340ustar00rootroot00000000000000[windows] skip signalcatcher & waitfile catchsignal interrupt wait stdout 'caught interrupt' go-internal-1.12.0/testscript/testdata/long_diff.txt000066400000000000000000000011751453631262600225330ustar00rootroot00000000000000# Verify the behaviour of cmp in the case of a small diff between # two large files unquote dir/script.txt ! testscript dir env cmpenv stdout stdout.golden -- dir/script.txt -- >cmp a b > >-- a -- >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >-- b -- >b >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a >a -- stdout.golden -- > cmp a b diff a b --- a +++ b @@ -1,4 +1,4 @@ -a +b a a a FAIL: $$WORK${/}dir${/}script.txt:1: a and b differ go-internal-1.12.0/testscript/testdata/nothing.txtar000066400000000000000000000001331453631262600225660ustar00rootroot00000000000000# Intentionally blank file, used to test that -testwork doesn't remove the work directory go-internal-1.12.0/testscript/testdata/nothing/000077500000000000000000000000001453631262600215055ustar00rootroot00000000000000go-internal-1.12.0/testscript/testdata/nothing/nothing.txtar000066400000000000000000000003541453631262600242410ustar00rootroot00000000000000# Intentionally empty test script; used to test Params.WorkdirRoot -- README.md -- This file exists so that a test for Params.WorkdirRoot can verify the existence of a file within WorkdirRoot/script-nothing once scripts have finished. go-internal-1.12.0/testscript/testdata/pty.txt000066400000000000000000000002761453631262600214210ustar00rootroot00000000000000[!linux] [!darwin] skip [darwin] skip # https://go.dev/issue/61779 ttyin secretwords.txt terminalprompt ttyout 'magic words' ! stderr . ! stdout . -- secretwords.txt -- SQUEAMISHOSSIFRAGE go-internal-1.12.0/testscript/testdata/readfile.txt000066400000000000000000000002211453631262600223460ustar00rootroot00000000000000fprintargs stdout stdout testreadfile stdout fprintargs stderr stderr testreadfile stderr testreadfile x/somefile -- x/somefile -- x/somefile go-internal-1.12.0/testscript/testdata/regexpquote.txt000066400000000000000000000001011453631262600231400ustar00rootroot00000000000000env XXX='hello)' grep ^${XXX@R}$ file.txt -- file.txt -- hello) go-internal-1.12.0/testscript/testdata/setenv.txt000066400000000000000000000001221453631262600220770ustar00rootroot00000000000000setSpecialVal exists $SPECIALVAL.txt ensureSpecialVal -- 42.txt -- Douglas Adams go-internal-1.12.0/testscript/testdata/setupfiles.txt000066400000000000000000000002341453631262600227620ustar00rootroot00000000000000# check that the Setup function saw the unarchived files, # including the temp directory that's always created. setup-filenames .tmp a b -- a -- -- b/c -- go-internal-1.12.0/testscript/testdata/stdin.txt000066400000000000000000000003251453631262600217210ustar00rootroot00000000000000[!exec:cat] skip stdin hello.txt exec cat stdout hello exec cat ! stdout hello [!exec:cat] stop # Check that 'stdin stdout' works. exec cat hello.txt stdin stdout exec cat stdout hello -- hello.txt -- hello go-internal-1.12.0/testscript/testdata/testscript_duplicate_name.txt000066400000000000000000000006051453631262600260370ustar00rootroot00000000000000# Check that RequireUniqueNames works; # it should reject txtar archives with duplicate names as defined by the host system. unquote scripts-normalized/testscript.txt testscript scripts-normalized ! testscript -unique-names scripts-normalized stdout '.* would overwrite .* \(because RequireUniqueNames is enabled\)' -- scripts-normalized/testscript.txt -- >-- file -- >-- dir/../file --go-internal-1.12.0/testscript/testdata/testscript_explicit_exec.txt000066400000000000000000000013521453631262600257120ustar00rootroot00000000000000# Check that RequireExplicitExec works; # it should reject `fprintargs` in favor of `exec fprintargs`, # but it shouldn't complain about `some-param-cmd`, # as that Params.Cmds entry won't work via `exec some-param-cmd`. unquote scripts-implicit/testscript.txt unquote scripts-explicit/testscript.txt testscript scripts-implicit testscript scripts-explicit ! testscript -explicit-exec scripts-implicit testscript -explicit-exec scripts-explicit -- scripts-implicit/testscript.txt -- >fprintargs stdout right >cmp stdout expect > >some-param-cmd >! exec some-param-cmd > >-- expect -- >right -- scripts-explicit/testscript.txt -- >exec fprintargs stdout right >cmp stdout expect > >some-param-cmd >! exec some-param-cmd > >-- expect -- >right go-internal-1.12.0/testscript/testdata/testscript_logging.txt000066400000000000000000000042541453631262600245170ustar00rootroot00000000000000# non-verbose, non-continue ! testscript scripts cmpenv stdout expect-stdout.txt # verbose ! testscript -v scripts cmpenv stdout expect-stdout-v.txt # continue ! testscript -continue scripts cmpenv stdout expect-stdout-c.txt # verbose, continue ! testscript -v -continue scripts cmpenv stdout expect-stdout-vc.txt -- scripts/testscript.txt -- # comment 1 printargs section1 # comment 2 printargs section2 # comment 3 printargs section3 status 1 # comment 4 printargs section3 # comment 5 printargs section5 status 1 -- expect-stdout.txt -- # comment 1 (0.000s) # comment 2 (0.000s) # comment 3 (0.000s) > printargs section3 [stdout] ["printargs" "section3"] > status 1 [exit status 1] FAIL: $$WORK${/}scripts${/}testscript.txt:9: unexpected command failure -- expect-stdout-v.txt -- # comment 1 (0.000s) > printargs section1 [stdout] ["printargs" "section1"] # comment 2 (0.000s) > printargs section2 [stdout] ["printargs" "section2"] # comment 3 (0.000s) > printargs section3 [stdout] ["printargs" "section3"] > status 1 [exit status 1] FAIL: $$WORK${/}scripts${/}testscript.txt:9: unexpected command failure -- expect-stdout-c.txt -- # comment 1 (0.000s) # comment 2 (0.000s) # comment 3 (0.000s) > printargs section3 [stdout] ["printargs" "section3"] > status 1 [exit status 1] FAIL: $$WORK${/}scripts${/}testscript.txt:9: unexpected command failure # comment 4 (0.000s) > printargs section3 [stdout] ["printargs" "section3"] # comment 5 (0.000s) > printargs section5 [stdout] ["printargs" "section5"] > status 1 [exit status 1] FAIL: $$WORK${/}scripts${/}testscript.txt:16: unexpected command failure -- expect-stdout-vc.txt -- # comment 1 (0.000s) > printargs section1 [stdout] ["printargs" "section1"] # comment 2 (0.000s) > printargs section2 [stdout] ["printargs" "section2"] # comment 3 (0.000s) > printargs section3 [stdout] ["printargs" "section3"] > status 1 [exit status 1] FAIL: $$WORK${/}scripts${/}testscript.txt:9: unexpected command failure # comment 4 (0.000s) > printargs section3 [stdout] ["printargs" "section3"] # comment 5 (0.000s) > printargs section5 [stdout] ["printargs" "section5"] > status 1 [exit status 1] FAIL: $$WORK${/}scripts${/}testscript.txt:16: unexpected command failure go-internal-1.12.0/testscript/testdata/testscript_notfound.txt000066400000000000000000000006271453631262600247250ustar00rootroot00000000000000# Check that unknown commands output a useful error message ! testscript notfound stdout 'unknown command "notexist"' ! testscript negation stdout 'unknown command "!exists" \(did you mean "! exists"\?\)' ! testscript misspelled stdout 'unknown command "exits" \(did you mean "exists"\?\)' -- notfound/script.txt -- notexist -- negation/script.txt -- !exists file -- misspelled/script.txt -- exits file go-internal-1.12.0/testscript/testdata/testscript_stdout_stderr_error.txt000066400000000000000000000011671453631262600272070ustar00rootroot00000000000000# Verify that stdout and stderr get set event when a user-builtin # command aborts. Note that we need to assert against stdout # because our meta testscript command sees only a single log. unquote scripts/testscript.txt ! testscript -v scripts cmpenv stdout stdout.golden -- scripts/testscript.txt -- > printargs hello world > echoandexit 1 'this is stdout' 'this is stderr' -- stdout.golden -- > printargs hello world [stdout] ["printargs" "hello" "world"] > echoandexit 1 'this is stdout' 'this is stderr' [stdout] this is stdout [stderr] this is stderr FAIL: ${$}WORK${/}scripts${/}testscript.txt:2: told to exit with code 1 go-internal-1.12.0/testscript/testdata/testscript_update_script.txt000066400000000000000000000007371453631262600257410ustar00rootroot00000000000000# Check that we support both txt and txtar extensions. unquote scripts/testscript.txt unquote testscript-new.txt cp scripts/testscript.txt scripts/testscript2.txtar testscript -update scripts cmp scripts/testscript.txt testscript-new.txt cmp scripts/testscript2.txtar testscript-new.txt -- scripts/testscript.txt -- >fprintargs stdout right >cmp stdout expect > >-- expect -- >wrong -- testscript-new.txt -- >fprintargs stdout right >cmp stdout expect > >-- expect -- >right go-internal-1.12.0/testscript/testdata/testscript_update_script_actual_is_file.txt000066400000000000000000000004441453631262600307570ustar00rootroot00000000000000unquote scripts/testscript.txt unquote testscript-new.txt testscript -update scripts cmp scripts/testscript.txt testscript-new.txt -- scripts/testscript.txt -- >cmp got want > >-- got -- >right >-- want -- >wrong -- testscript-new.txt -- >cmp got want > >-- got -- >right >-- want -- >right go-internal-1.12.0/testscript/testdata/testscript_update_script_expected_not_in_archive.txt000066400000000000000000000005031453631262600326600ustar00rootroot00000000000000# Verify that comparing stdout against a file not in the archive does nothing unquote scripts/testscript.txt cp scripts/testscript.txt unchanged ! testscript -update scripts cmp scripts/testscript.txt unchanged -- scripts/testscript.txt -- >fprintargs stdout right >cp file expect >cmp stdout expect > >-- file -- >wrong go-internal-1.12.0/testscript/testdata/testscript_update_script_quote.txt000066400000000000000000000005431453631262600271510ustar00rootroot00000000000000unquote scripts/testscript.txt unquote testscript-new.txt testscript -update scripts cmp scripts/testscript.txt testscript-new.txt -- scripts/testscript.txt -- >fprintargs stdout '-- lookalike --' >cmp stdout expect > >-- expect -- >wrong -- testscript-new.txt -- >fprintargs stdout '-- lookalike --' >cmp stdout expect > >-- expect -- >>-- lookalike -- go-internal-1.12.0/testscript/testdata/testscript_update_script_stderr.txt000066400000000000000000000005001453631262600273100ustar00rootroot00000000000000unquote scripts/testscript.txt unquote testscript-new.txt testscript -update scripts cmp scripts/testscript.txt testscript-new.txt -- scripts/testscript.txt -- >fprintargs stderr right >cmp stderr expect > >-- expect -- >wrong -- testscript-new.txt -- >fprintargs stderr right >cmp stderr expect > >-- expect -- >right go-internal-1.12.0/testscript/testdata/values.txt000066400000000000000000000000141453631262600220720ustar00rootroot00000000000000test-values go-internal-1.12.0/testscript/testdata/wait.txt000066400000000000000000000015251453631262600215470ustar00rootroot00000000000000[!exec:echo] skip [!exec:false] skip # TODO: the '\n' below doesn't work on Windows on Github Actions, which does # have coreutils like "echo" installed. Perhaps they emit CRLF? [windows] skip exec echo foo stdout foo exec echo foo & exec echo bar & ! exec false & # Starting a background process should clear previous output. ! stdout foo # Wait should set the output to the concatenated outputs of the background # programs, in the order in which they were started. wait stdout 'foo\nbar' exec echo bg1 &b1& exec echo bg2 &b2& exec echo bg3 &b3& exec echo bg4 &b4& wait b3 stdout bg3 wait b2 stdout bg2 wait stdout 'bg1\nbg4' # We should be able to start several background processes and wait for them # individually. # The end of the test should interrupt or kill any remaining background # programs. [!exec:sleep] skip ! exec sleep 86400 & go-internal-1.12.0/testscript/testscript.go000066400000000000000000001141671453631262600207730ustar00rootroot00000000000000// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Script-driven tests. // See testdata/script/README for an overview. package testscript import ( "bytes" "context" "errors" "flag" "fmt" "go/build" "io" "io/fs" "os" "os/exec" "path/filepath" "regexp" "runtime" "sort" "strings" "sync/atomic" "syscall" "testing" "time" "github.com/rogpeppe/go-internal/imports" "github.com/rogpeppe/go-internal/internal/misspell" "github.com/rogpeppe/go-internal/internal/os/execpath" "github.com/rogpeppe/go-internal/par" "github.com/rogpeppe/go-internal/testenv" "github.com/rogpeppe/go-internal/testscript/internal/pty" "github.com/rogpeppe/go-internal/txtar" ) var goVersionRegex = regexp.MustCompile(`^go([1-9][0-9]*)\.([1-9][0-9]*)$`) var execCache par.Cache // If -testwork is specified, the test prints the name of the temp directory // and does not remove it when done, so that a programmer can // poke at the test file tree afterward. var testWork = flag.Bool("testwork", false, "") // timeSince is defined as a variable so that it can be overridden // for the local testscript tests so that we can test against predictable // output. var timeSince = time.Since // showVerboseEnv specifies whether the environment should be displayed // automatically when in verbose mode. This is set to false for the local testscript tests so we // can test against predictable output. var showVerboseEnv = true // Env holds the environment to use at the start of a test script invocation. type Env struct { // WorkDir holds the path to the root directory of the // extracted files. WorkDir string // Vars holds the initial set environment variables that will be passed to the // testscript commands. Vars []string // Cd holds the initial current working directory. Cd string // Values holds a map of arbitrary values for use by custom // testscript commands. This enables Setup to pass arbitrary // values (not just strings) through to custom commands. Values map[interface{}]interface{} ts *TestScript } // Value returns a value from Env.Values, or nil if no // value was set by Setup. func (ts *TestScript) Value(key interface{}) interface{} { return ts.values[key] } // Defer arranges for f to be called at the end // of the test. If Defer is called multiple times, the // defers are executed in reverse order (similar // to Go's defer statement) func (e *Env) Defer(f func()) { e.ts.Defer(f) } // Getenv retrieves the value of the environment variable named by the key. It // returns the value, which will be empty if the variable is not present. func (e *Env) Getenv(key string) string { key = envvarname(key) for i := len(e.Vars) - 1; i >= 0; i-- { if pair := strings.SplitN(e.Vars[i], "=", 2); len(pair) == 2 && envvarname(pair[0]) == key { return pair[1] } } return "" } func envvarname(k string) string { if runtime.GOOS == "windows" { return strings.ToLower(k) } return k } // Setenv sets the value of the environment variable named by the key. It // panics if key is invalid. func (e *Env) Setenv(key, value string) { if key == "" || strings.IndexByte(key, '=') != -1 { panic(fmt.Errorf("invalid environment variable key %q", key)) } e.Vars = append(e.Vars, key+"="+value) } // T returns the t argument passed to the current test by the T.Run method. // Note that if the tests were started by calling Run, // the returned value will implement testing.TB. // Note that, despite that, the underlying value will not be of type // *testing.T because *testing.T does not implement T. // // If Cleanup is called on the returned value, the function will run // after any functions passed to Env.Defer. func (e *Env) T() T { return e.ts.t } // Params holds parameters for a call to Run. type Params struct { // Dir holds the name of the directory holding the scripts. // All files in the directory with a .txtar or .txt suffix will be // considered as test scripts. By default the current directory is used. // Dir is interpreted relative to the current test directory. Dir string // Setup is called, if not nil, to complete any setup required // for a test. The WorkDir and Vars fields will have already // been initialized and all the files extracted into WorkDir, // and Cd will be the same as WorkDir. // The Setup function may modify Vars and Cd as it wishes. Setup func(*Env) error // Condition is called, if not nil, to determine whether a particular // condition is true. It's called only for conditions not in the // standard set, and may be nil. Condition func(cond string) (bool, error) // Cmds holds a map of commands available to the script. // It will only be consulted for commands not part of the standard set. Cmds map[string]func(ts *TestScript, neg bool, args []string) // TestWork specifies that working directories should be // left intact for later inspection. TestWork bool // WorkdirRoot specifies the directory within which scripts' work // directories will be created. Setting WorkdirRoot implies TestWork=true. // If empty, the work directories will be created inside // $GOTMPDIR/go-test-script*, where $GOTMPDIR defaults to os.TempDir(). WorkdirRoot string // Deprecated: this option is no longer used. IgnoreMissedCoverage bool // UpdateScripts specifies that if a `cmp` command fails and its second // argument refers to a file inside the testscript file, the command will // succeed and the testscript file will be updated to reflect the actual // content (which could be stdout, stderr or a real file). // // The content will be quoted with txtar.Quote if needed; // a manual change will be needed if it is not unquoted in the // script. UpdateScripts bool // RequireExplicitExec requires that commands passed to RunMain must be used // in test scripts via `exec cmd` and not simply `cmd`. This can help keep // consistency across test scripts as well as keep separate process // executions explicit. RequireExplicitExec bool // RequireUniqueNames requires that names in the txtar archive are unique. // By default, later entries silently overwrite earlier ones. RequireUniqueNames bool // ContinueOnError causes a testscript to try to continue in // the face of errors. Once an error has occurred, the script // will continue as if in verbose mode. ContinueOnError bool // Deadline, if not zero, specifies the time at which the test run will have // exceeded the timeout. It is equivalent to testing.T's Deadline method, // and Run will set it to the method's return value if this field is zero. Deadline time.Time } // RunDir runs the tests in the given directory. All files in dir with a ".txt" // or ".txtar" extension are considered to be test files. func Run(t *testing.T, p Params) { if deadline, ok := t.Deadline(); ok && p.Deadline.IsZero() { p.Deadline = deadline } RunT(tshim{t}, p) } // T holds all the methods of the *testing.T type that // are used by testscript. type T interface { Skip(...interface{}) Fatal(...interface{}) Parallel() Log(...interface{}) FailNow() Run(string, func(T)) // Verbose is usually implemented by the testing package // directly rather than on the *testing.T type. Verbose() bool } // TFailed holds optional extra methods implemented on T. // It's defined as a separate type for backward compatibility reasons. type TFailed interface { Failed() bool } type tshim struct { *testing.T } func (t tshim) Run(name string, f func(T)) { t.T.Run(name, func(t *testing.T) { f(tshim{t}) }) } func (t tshim) Verbose() bool { return testing.Verbose() } // RunT is like Run but uses an interface type instead of the concrete *testing.T // type to make it possible to use testscript functionality outside of go test. func RunT(t T, p Params) { entries, err := os.ReadDir(p.Dir) if os.IsNotExist(err) { // Continue so we give a helpful error on len(files)==0 below. } else if err != nil { t.Fatal(err) } var files []string for _, entry := range entries { name := entry.Name() if strings.HasSuffix(name, ".txtar") || strings.HasSuffix(name, ".txt") { files = append(files, filepath.Join(p.Dir, name)) } } if len(files) == 0 { t.Fatal(fmt.Sprintf("no txtar nor txt scripts found in dir %s", p.Dir)) } testTempDir := p.WorkdirRoot if testTempDir == "" { testTempDir, err = os.MkdirTemp(os.Getenv("GOTMPDIR"), "go-test-script") if err != nil { t.Fatal(err) } } else { p.TestWork = true } // The temp dir returned by os.MkdirTemp might be a sym linked dir (default // behaviour in macOS). That could mess up matching that includes $WORK if, // for example, an external program outputs resolved paths. Evaluating the // dir here will ensure consistency. testTempDir, err = filepath.EvalSymlinks(testTempDir) if err != nil { t.Fatal(err) } var ( ctx = context.Background() gracePeriod = 100 * time.Millisecond cancel context.CancelFunc ) if !p.Deadline.IsZero() { timeout := time.Until(p.Deadline) // If time allows, increase the termination grace period to 5% of the // remaining time. if gp := timeout / 20; gp > gracePeriod { gracePeriod = gp } // When we run commands that execute subprocesses, we want to reserve two // grace periods to clean up. We will send the first termination signal when // the context expires, then wait one grace period for the process to // produce whatever useful output it can (such as a stack trace). After the // first grace period expires, we'll escalate to os.Kill, leaving the second // grace period for the test function to record its output before the test // process itself terminates. timeout -= 2 * gracePeriod ctx, cancel = context.WithTimeout(ctx, timeout) // We don't defer cancel() because RunT returns before the sub-tests, // and we don't have access to Cleanup due to the T interface. Instead, // we call it after the refCount goes to zero below. _ = cancel } refCount := int32(len(files)) for _, file := range files { file := file name := strings.TrimSuffix(filepath.Base(file), ".txt") name = strings.TrimSuffix(name, ".txtar") t.Run(name, func(t T) { t.Parallel() ts := &TestScript{ t: t, testTempDir: testTempDir, name: name, file: file, params: p, ctxt: ctx, gracePeriod: gracePeriod, deferred: func() {}, scriptFiles: make(map[string]string), scriptUpdates: make(map[string]string), } defer func() { if p.TestWork || *testWork { return } removeAll(ts.workdir) if atomic.AddInt32(&refCount, -1) == 0 { // This is the last subtest to finish. Remove the // parent directory too, and cancel the context. os.Remove(testTempDir) if cancel != nil { cancel() } } }() ts.run() }) } } // A TestScript holds execution state for a single test script. type TestScript struct { params Params t T testTempDir string workdir string // temporary work dir ($WORK) log bytes.Buffer // test execution log (printed at end of test) mark int // offset of next log truncation cd string // current directory during test execution; initially $WORK/gopath/src name string // short name of test ("foo") file string // full file name ("testdata/script/foo.txt") lineno int // line number currently executing line string // line currently executing env []string // environment list (for os/exec) envMap map[string]string // environment mapping (matches env; on Windows keys are lowercase) values map[interface{}]interface{} // values for custom commands stdin string // standard input to next 'go' command; set by 'stdin' command. stdout string // standard output from last 'go' command; for 'stdout' command stderr string // standard error from last 'go' command; for 'stderr' command ttyin string // terminal input; set by 'ttyin' command stdinPty bool // connect pty to standard input; set by 'ttyin -stdin' command ttyout string // terminal output; for 'ttyout' command stopped bool // test wants to stop early start time.Time // time phase started background []backgroundCmd // backgrounded 'exec' and 'go' commands deferred func() // deferred cleanup actions. archive *txtar.Archive // the testscript being run. scriptFiles map[string]string // files stored in the txtar archive (absolute paths -> path in script) scriptUpdates map[string]string // updates to testscript files via UpdateScripts. // runningBuiltin indicates if we are running a user-supplied builtin // command. These commands are specified via Params.Cmds. runningBuiltin bool // builtinStd(out|err) are established if a user-supplied builtin command // requests Stdout() or Stderr(). Either both are non-nil, or both are nil. // This invariant is maintained by both setBuiltinStd() and // clearBuiltinStd(). builtinStdout *strings.Builder builtinStderr *strings.Builder ctxt context.Context // per TestScript context gracePeriod time.Duration // time between SIGQUIT and SIGKILL } type backgroundCmd struct { name string cmd *exec.Cmd wait <-chan struct{} neg bool // if true, cmd should fail } func writeFile(name string, data []byte, perm fs.FileMode, excl bool) error { oflags := os.O_WRONLY | os.O_CREATE | os.O_TRUNC if excl { oflags |= os.O_EXCL } f, err := os.OpenFile(name, oflags, perm) if err != nil { return err } defer f.Close() if _, err := f.Write(data); err != nil { return fmt.Errorf("cannot write file contents: %v", err) } return nil } // Name returns the short name or basename of the test script. func (ts *TestScript) Name() string { return ts.name } // setup sets up the test execution temporary directory and environment. // It returns the comment section of the txtar archive. func (ts *TestScript) setup() string { defer catchFailNow(func() { // There's been a failure in setup; fail immediately regardless // of the ContinueOnError flag. ts.t.FailNow() }) ts.workdir = filepath.Join(ts.testTempDir, "script-"+ts.name) // Establish a temporary directory in workdir, but use a prefix that ensures // this directory will not be walked when resolving the ./... pattern from // workdir. This is important because when resolving a ./... pattern, cmd/go // (which is used by go/packages) creates temporary build files and // directories. This can, and does, therefore interfere with the ./... // pattern when used from workdir and can lead to race conditions within // cmd/go as it walks directories to match the ./... pattern. tmpDir := filepath.Join(ts.workdir, ".tmp") ts.Check(os.MkdirAll(tmpDir, 0o777)) env := &Env{ Vars: []string{ "WORK=" + ts.workdir, // must be first for ts.abbrev "PATH=" + os.Getenv("PATH"), "GOTRACEBACK=system", homeEnvName() + "=/no-home", tempEnvName() + "=" + tmpDir, "devnull=" + os.DevNull, "/=" + string(os.PathSeparator), ":=" + string(os.PathListSeparator), "$=$", }, WorkDir: ts.workdir, Values: make(map[interface{}]interface{}), Cd: ts.workdir, ts: ts, } // These env vars affect how a Go program behaves at run-time; // If the user or `go test` wrapper set them, we should propagate them // so that sub-process commands run via the test binary see them as well. for _, name := range []string{ // If we are collecting coverage profiles, e.g. `go test -coverprofile`. "GOCOVERDIR", // If the user set GORACE when running a command like `go test -race`, // such as GORACE=atexit_sleep_ms=10 to avoid the default 1s sleeps. "GORACE", } { if val := os.Getenv(name); val != "" { env.Vars = append(env.Vars, name+"="+val) } } // Must preserve SYSTEMROOT on Windows: https://github.com/golang/go/issues/25513 et al if runtime.GOOS == "windows" { env.Vars = append(env.Vars, "SYSTEMROOT="+os.Getenv("SYSTEMROOT"), "exe=.exe", ) } else { env.Vars = append(env.Vars, "exe=", ) } ts.cd = env.Cd // Unpack archive. a, err := txtar.ParseFile(ts.file) ts.Check(err) ts.archive = a for _, f := range a.Files { name := ts.MkAbs(ts.expand(f.Name)) ts.scriptFiles[name] = f.Name ts.Check(os.MkdirAll(filepath.Dir(name), 0o777)) switch err := writeFile(name, f.Data, 0o666, ts.params.RequireUniqueNames); { case ts.params.RequireUniqueNames && errors.Is(err, fs.ErrExist): ts.Check(fmt.Errorf("%s would overwrite %s (because RequireUniqueNames is enabled)", f.Name, name)) default: ts.Check(err) } } // Run any user-defined setup. if ts.params.Setup != nil { ts.Check(ts.params.Setup(env)) } ts.cd = env.Cd ts.env = env.Vars ts.values = env.Values ts.envMap = make(map[string]string) for _, kv := range ts.env { if i := strings.Index(kv, "="); i >= 0 { ts.envMap[envvarname(kv[:i])] = kv[i+1:] } } return string(a.Comment) } // run runs the test script. func (ts *TestScript) run() { // Truncate log at end of last phase marker, // discarding details of successful phase. verbose := ts.t.Verbose() rewind := func() { if !verbose { ts.log.Truncate(ts.mark) } } // Insert elapsed time for phase at end of phase marker markTime := func() { if ts.mark > 0 && !ts.start.IsZero() { afterMark := append([]byte{}, ts.log.Bytes()[ts.mark:]...) ts.log.Truncate(ts.mark - 1) // cut \n and afterMark fmt.Fprintf(&ts.log, " (%.3fs)\n", timeSince(ts.start).Seconds()) ts.log.Write(afterMark) } ts.start = time.Time{} } failed := false defer func() { // On a normal exit from the test loop, background processes are cleaned up // before we print PASS. If we return early (e.g., due to a test failure), // don't print anything about the processes that were still running. for _, bg := range ts.background { interruptProcess(bg.cmd.Process) } if ts.t.Verbose() || failed { // In verbose mode or on test failure, we want to see what happened in the background // processes too. ts.waitBackground(false) } else { for _, bg := range ts.background { <-bg.wait } ts.background = nil } markTime() // Flush testScript log to testing.T log. ts.t.Log(ts.abbrev(ts.log.String())) }() defer func() { ts.deferred() }() script := ts.setup() // With -v or -testwork, start log with full environment. if *testWork || (showVerboseEnv && ts.t.Verbose()) { // Display environment. ts.cmdEnv(false, nil) fmt.Fprintf(&ts.log, "\n") ts.mark = ts.log.Len() } defer ts.applyScriptUpdates() // Run script. // See testdata/script/README for documentation of script form. for script != "" { // Extract next line. ts.lineno++ var line string if i := strings.Index(script, "\n"); i >= 0 { line, script = script[:i], script[i+1:] } else { line, script = script, "" } // # is a comment indicating the start of new phase. if strings.HasPrefix(line, "#") { // If there was a previous phase, it succeeded, // so rewind the log to delete its details (unless -v is in use or // ContinueOnError was enabled and there was a previous error, // causing verbose to be set to true). // If nothing has happened at all since the mark, // rewinding is a no-op and adding elapsed time // for doing nothing is meaningless, so don't. if ts.log.Len() > ts.mark { rewind() markTime() } // Print phase heading and mark start of phase output. fmt.Fprintf(&ts.log, "%s\n", line) ts.mark = ts.log.Len() ts.start = time.Now() continue } ok := ts.runLine(line) if !ok { failed = true if ts.params.ContinueOnError { verbose = true } else { ts.t.FailNow() } } // Command can ask script to stop early. if ts.stopped { // Break instead of returning, so that we check the status of any // background processes and print PASS. break } } for _, bg := range ts.background { interruptProcess(bg.cmd.Process) } ts.cmdWait(false, nil) // If we reached here but we've failed (probably because ContinueOnError // was set), don't wipe the log and print "PASS". if failed { ts.t.FailNow() } // Final phase ended. rewind() markTime() if !ts.stopped { fmt.Fprintf(&ts.log, "PASS\n") } } func (ts *TestScript) runLine(line string) (runOK bool) { defer catchFailNow(func() { runOK = false }) // Parse input line. Ignore blanks entirely. args := ts.parse(line) if len(args) == 0 { return true } // Echo command to log. fmt.Fprintf(&ts.log, "> %s\n", line) // Command prefix [cond] means only run this command if cond is satisfied. for strings.HasPrefix(args[0], "[") && strings.HasSuffix(args[0], "]") { cond := args[0] cond = cond[1 : len(cond)-1] cond = strings.TrimSpace(cond) args = args[1:] if len(args) == 0 { ts.Fatalf("missing command after condition") } want := true if strings.HasPrefix(cond, "!") { want = false cond = strings.TrimSpace(cond[1:]) } ok, err := ts.condition(cond) if err != nil { ts.Fatalf("bad condition %q: %v", cond, err) } if ok != want { // Don't run rest of line. return true } } // Command prefix ! means negate the expectations about this command: // go command should fail, match should not be found, etc. neg := false if args[0] == "!" { neg = true args = args[1:] if len(args) == 0 { ts.Fatalf("! on line by itself") } } // Run command. cmd := scriptCmds[args[0]] if cmd == nil { cmd = ts.params.Cmds[args[0]] } if cmd == nil { // try to find spelling corrections. We arbitrarily limit the number of // corrections, to not be too noisy. switch c := ts.cmdSuggestions(args[0]); len(c) { case 1: ts.Fatalf("unknown command %q (did you mean %q?)", args[0], c[0]) case 2, 3, 4: ts.Fatalf("unknown command %q (did you mean one of %q?)", args[0], c) default: ts.Fatalf("unknown command %q", args[0]) } } ts.callBuiltinCmd(args[0], func() { cmd(ts, neg, args[1:]) }) return true } func (ts *TestScript) callBuiltinCmd(cmd string, runCmd func()) { ts.runningBuiltin = true defer func() { r := recover() ts.runningBuiltin = false ts.clearBuiltinStd() switch r { case nil: // we did not panic default: // re-"throw" the panic panic(r) } }() runCmd() } func (ts *TestScript) cmdSuggestions(name string) []string { // special case: spell-correct `!cmd` to `! cmd` if strings.HasPrefix(name, "!") { if _, ok := scriptCmds[name[1:]]; ok { return []string{"! " + name[1:]} } if _, ok := ts.params.Cmds[name[1:]]; ok { return []string{"! " + name[1:]} } } var candidates []string for c := range scriptCmds { if misspell.AlmostEqual(name, c) { candidates = append(candidates, c) } } for c := range ts.params.Cmds { if misspell.AlmostEqual(name, c) { candidates = append(candidates, c) } } if len(candidates) == 0 { return nil } // deduplicate candidates // TODO: Use slices.Compact (and maybe slices.Sort) once we can use Go 1.21 sort.Strings(candidates) out := candidates[:1] for _, c := range candidates[1:] { if out[len(out)-1] == c { out = append(out, c) } } return out } func (ts *TestScript) applyScriptUpdates() { if len(ts.scriptUpdates) == 0 { return } for name, content := range ts.scriptUpdates { found := false for i := range ts.archive.Files { f := &ts.archive.Files[i] if f.Name != name { continue } data := []byte(content) if txtar.NeedsQuote(data) { data1, err := txtar.Quote(data) if err != nil { ts.Fatalf("cannot update script file %q: %v", f.Name, err) continue } data = data1 } f.Data = data found = true } // Sanity check. if !found { panic("script update file not found") } } if err := os.WriteFile(ts.file, txtar.Format(ts.archive), 0o666); err != nil { ts.t.Fatal("cannot update script: ", err) } ts.Logf("%s updated", ts.file) } var failNow = errors.New("fail now!") // catchFailNow catches any panic from Fatalf and calls // f if it did so. It must be called in a defer. func catchFailNow(f func()) { e := recover() if e == nil { return } if e != failNow { panic(e) } f() } // condition reports whether the given condition is satisfied. func (ts *TestScript) condition(cond string) (bool, error) { switch { case cond == "short": return testing.Short(), nil case cond == "net": return testenv.HasExternalNetwork(), nil case cond == "link": return testenv.HasLink(), nil case cond == "symlink": return testenv.HasSymlink(), nil case imports.KnownOS[cond]: return cond == runtime.GOOS, nil case cond == "unix": return imports.UnixOS[runtime.GOOS], nil case imports.KnownArch[cond]: return cond == runtime.GOARCH, nil case strings.HasPrefix(cond, "exec:"): prog := cond[len("exec:"):] ok := execCache.Do(prog, func() interface{} { _, err := execpath.Look(prog, ts.Getenv) return err == nil }).(bool) return ok, nil case cond == "gc" || cond == "gccgo": // TODO this reflects the compiler that the current // binary was built with but not necessarily the compiler // that will be used. return cond == runtime.Compiler, nil case goVersionRegex.MatchString(cond): for _, v := range build.Default.ReleaseTags { if cond == v { return true, nil } } return false, nil case ts.params.Condition != nil: return ts.params.Condition(cond) default: ts.Fatalf("unknown condition %q", cond) panic("unreachable") } } // Helpers for command implementations. // abbrev abbreviates the actual work directory in the string s to the literal string "$WORK". func (ts *TestScript) abbrev(s string) string { s = strings.Replace(s, ts.workdir, "$WORK", -1) if *testWork || ts.params.TestWork { // Expose actual $WORK value in environment dump on first line of work script, // so that the user can find out what directory -testwork left behind. s = "WORK=" + ts.workdir + "\n" + strings.TrimPrefix(s, "WORK=$WORK\n") } return s } // Defer arranges for f to be called at the end // of the test. If Defer is called multiple times, the // defers are executed in reverse order (similar // to Go's defer statement) func (ts *TestScript) Defer(f func()) { old := ts.deferred ts.deferred = func() { defer old() f() } } // Check calls ts.Fatalf if err != nil. func (ts *TestScript) Check(err error) { if err != nil { ts.Fatalf("%v", err) } } // Stdout returns an io.Writer that can be used by a user-supplied builtin // command (delcared via Params.Cmds) to write to stdout. If this method is // called outside of the execution of a user-supplied builtin command, the // call panics. func (ts *TestScript) Stdout() io.Writer { if !ts.runningBuiltin { panic("can only call TestScript.Stdout when running a builtin command") } ts.setBuiltinStd() return ts.builtinStdout } // Stderr returns an io.Writer that can be used by a user-supplied builtin // command (delcared via Params.Cmds) to write to stderr. If this method is // called outside of the execution of a user-supplied builtin command, the // call panics. func (ts *TestScript) Stderr() io.Writer { if !ts.runningBuiltin { panic("can only call TestScript.Stderr when running a builtin command") } ts.setBuiltinStd() return ts.builtinStderr } // setBuiltinStd ensures that builtinStdout and builtinStderr are non nil. func (ts *TestScript) setBuiltinStd() { // This method must maintain the invariant that both builtinStdout and // builtinStderr are set or neither are set // If both are set, nothing to do if ts.builtinStdout != nil && ts.builtinStderr != nil { return } ts.builtinStdout = new(strings.Builder) ts.builtinStderr = new(strings.Builder) } // clearBuiltinStd sets ts.stdout and ts.stderr from the builtin command // buffers, logs both, and resets both builtinStdout and builtinStderr to nil. func (ts *TestScript) clearBuiltinStd() { // This method must maintain the invariant that both builtinStdout and // builtinStderr are set or neither are set // If neither set, nothing to do if ts.builtinStdout == nil && ts.builtinStderr == nil { return } ts.stdout = ts.builtinStdout.String() ts.builtinStdout = nil ts.stderr = ts.builtinStderr.String() ts.builtinStderr = nil ts.logStd() } // Logf appends the given formatted message to the test log transcript. func (ts *TestScript) Logf(format string, args ...interface{}) { format = strings.TrimSuffix(format, "\n") fmt.Fprintf(&ts.log, format, args...) ts.log.WriteByte('\n') } // exec runs the given command line (an actual subprocess, not simulated) // in ts.cd with environment ts.env and then returns collected standard output and standard error. func (ts *TestScript) exec(command string, args ...string) (stdout, stderr string, err error) { cmd, err := ts.buildExecCmd(command, args...) if err != nil { return "", "", err } cmd.Dir = ts.cd cmd.Env = append(ts.env, "PWD="+ts.cd) cmd.Stdin = strings.NewReader(ts.stdin) var stdoutBuf, stderrBuf strings.Builder cmd.Stdout = &stdoutBuf cmd.Stderr = &stderrBuf if ts.ttyin != "" { ctrl, tty, err := pty.Open() if err != nil { return "", "", err } doneR, doneW := make(chan struct{}), make(chan struct{}) var ptyBuf strings.Builder go func() { io.Copy(ctrl, strings.NewReader(ts.ttyin)) ctrl.Write([]byte{4 /* EOT */}) close(doneW) }() go func() { io.Copy(&ptyBuf, ctrl) close(doneR) }() defer func() { tty.Close() ctrl.Close() <-doneR <-doneW ts.ttyin = "" ts.ttyout = ptyBuf.String() }() pty.SetCtty(cmd, tty) if ts.stdinPty { cmd.Stdin = tty } } if err = cmd.Start(); err == nil { err = waitOrStop(ts.ctxt, cmd, ts.gracePeriod) } ts.stdin = "" ts.stdinPty = false return stdoutBuf.String(), stderrBuf.String(), err } // execBackground starts the given command line (an actual subprocess, not simulated) // in ts.cd with environment ts.env. func (ts *TestScript) execBackground(command string, args ...string) (*exec.Cmd, error) { if ts.ttyin != "" { return nil, errors.New("ttyin is not supported by background commands") } cmd, err := ts.buildExecCmd(command, args...) if err != nil { return nil, err } cmd.Dir = ts.cd cmd.Env = append(ts.env, "PWD="+ts.cd) var stdoutBuf, stderrBuf strings.Builder cmd.Stdin = strings.NewReader(ts.stdin) cmd.Stdout = &stdoutBuf cmd.Stderr = &stderrBuf ts.stdin = "" return cmd, cmd.Start() } func (ts *TestScript) buildExecCmd(command string, args ...string) (*exec.Cmd, error) { if filepath.Base(command) == command { if lp, err := execpath.Look(command, ts.Getenv); err != nil { return nil, err } else { command = lp } } return exec.Command(command, args...), nil } // BackgroundCmds returns a slice containing all the commands that have // been started in the background since the most recent wait command, or // the start of the script if wait has not been called. func (ts *TestScript) BackgroundCmds() []*exec.Cmd { cmds := make([]*exec.Cmd, len(ts.background)) for i, b := range ts.background { cmds[i] = b.cmd } return cmds } // waitOrStop waits for the already-started command cmd by calling its Wait method. // // If cmd does not return before ctx is done, waitOrStop sends it an interrupt // signal. If killDelay is positive, waitOrStop waits that additional period for // Wait to return before sending os.Kill. func waitOrStop(ctx context.Context, cmd *exec.Cmd, killDelay time.Duration) error { if cmd.Process == nil { panic("waitOrStop called with a nil cmd.Process — missing Start call?") } errc := make(chan error) go func() { select { case errc <- nil: return case <-ctx.Done(): } var interrupt os.Signal = syscall.SIGQUIT if runtime.GOOS == "windows" { // Per https://golang.org/pkg/os/#Signal, “Interrupt is not implemented on // Windows; using it with os.Process.Signal will return an error.” // Fall back directly to Kill instead. interrupt = os.Kill } err := cmd.Process.Signal(interrupt) if err == nil { err = ctx.Err() // Report ctx.Err() as the reason we interrupted. } else if err == os.ErrProcessDone { errc <- nil return } if killDelay > 0 { timer := time.NewTimer(killDelay) select { // Report ctx.Err() as the reason we interrupted the process... case errc <- ctx.Err(): timer.Stop() return // ...but after killDelay has elapsed, fall back to a stronger signal. case <-timer.C: } // Wait still hasn't returned. // Kill the process harder to make sure that it exits. // // Ignore any error: if cmd.Process has already terminated, we still // want to send ctx.Err() (or the error from the Interrupt call) // to properly attribute the signal that may have terminated it. _ = cmd.Process.Kill() } errc <- err }() waitErr := cmd.Wait() if interruptErr := <-errc; interruptErr != nil { return interruptErr } return waitErr } // interruptProcess sends os.Interrupt to p if supported, or os.Kill otherwise. func interruptProcess(p *os.Process) { if err := p.Signal(os.Interrupt); err != nil { // Per https://golang.org/pkg/os/#Signal, “Interrupt is not implemented on // Windows; using it with os.Process.Signal will return an error.” // Fall back to Kill instead. p.Kill() } } // Exec runs the given command and saves its stdout and stderr so // they can be inspected by subsequent script commands. func (ts *TestScript) Exec(command string, args ...string) error { var err error ts.stdout, ts.stderr, err = ts.exec(command, args...) ts.logStd() return err } // logStd logs the current non-empty values of stdout and stderr. func (ts *TestScript) logStd() { if ts.stdout != "" { ts.Logf("[stdout]\n%s", ts.stdout) } if ts.stderr != "" { ts.Logf("[stderr]\n%s", ts.stderr) } } // expand applies environment variable expansion to the string s. func (ts *TestScript) expand(s string) string { return os.Expand(s, func(key string) string { if key1 := strings.TrimSuffix(key, "@R"); len(key1) != len(key) { return regexp.QuoteMeta(ts.Getenv(key1)) } return ts.Getenv(key) }) } // fatalf aborts the test with the given failure message. func (ts *TestScript) Fatalf(format string, args ...interface{}) { // In user-supplied builtins, the only way we have of aborting // is via Fatalf. Hence if we are aborting from a user-supplied // builtin, it's important we first log stdout and stderr. If // we are not, the following call is a no-op. ts.clearBuiltinStd() fmt.Fprintf(&ts.log, "FAIL: %s:%d: %s\n", ts.file, ts.lineno, fmt.Sprintf(format, args...)) // This should be caught by the defer inside the TestScript.runLine method. // We do this rather than calling ts.t.FailNow directly because we want to // be able to continue on error when Params.ContinueOnError is set. panic(failNow) } // MkAbs interprets file relative to the test script's current directory // and returns the corresponding absolute path. func (ts *TestScript) MkAbs(file string) string { if filepath.IsAbs(file) { return file } return filepath.Join(ts.cd, file) } // ReadFile returns the contents of the file with the // given name, intepreted relative to the test script's // current directory. It interprets "stdout" and "stderr" to // mean the standard output or standard error from // the most recent exec or wait command respectively. // // If the file cannot be read, the script fails. func (ts *TestScript) ReadFile(file string) string { switch file { case "stdout": return ts.stdout case "stderr": return ts.stderr case "ttyout": return ts.ttyout default: file = ts.MkAbs(file) data, err := os.ReadFile(file) ts.Check(err) return string(data) } } // Setenv sets the value of the environment variable named by the key. func (ts *TestScript) Setenv(key, value string) { ts.env = append(ts.env, key+"="+value) ts.envMap[envvarname(key)] = value } // Getenv gets the value of the environment variable named by the key. func (ts *TestScript) Getenv(key string) string { return ts.envMap[envvarname(key)] } // parse parses a single line as a list of space-separated arguments // subject to environment variable expansion (but not resplitting). // Single quotes around text disable splitting and expansion. // To embed a single quote, double it: 'Don”t communicate by sharing memory.' func (ts *TestScript) parse(line string) []string { ts.line = line var ( args []string arg string // text of current arg so far (need to add line[start:i]) start = -1 // if >= 0, position where current arg text chunk starts quoted = false // currently processing quoted text ) for i := 0; ; i++ { if !quoted && (i >= len(line) || line[i] == ' ' || line[i] == '\t' || line[i] == '\r' || line[i] == '#') { // Found arg-separating space. if start >= 0 { arg += ts.expand(line[start:i]) args = append(args, arg) start = -1 arg = "" } if i >= len(line) || line[i] == '#' { break } continue } if i >= len(line) { ts.Fatalf("unterminated quoted argument") } if line[i] == '\'' { if !quoted { // starting a quoted chunk if start >= 0 { arg += ts.expand(line[start:i]) } start = i + 1 quoted = true continue } // 'foo''bar' means foo'bar, like in rc shell and Pascal. if i+1 < len(line) && line[i+1] == '\'' { arg += line[start:i] start = i + 1 i++ // skip over second ' before next iteration continue } // ending a quoted chunk arg += line[start:i] start = i + 1 quoted = false continue } // found character worth saving; make sure we're saving if start < 0 { start = i } } return args } func removeAll(dir string) error { // module cache has 0o444 directories; // make them writable in order to remove content. filepath.WalkDir(dir, func(path string, entry fs.DirEntry, err error) error { if err != nil { return nil // ignore errors walking in file system } if entry.IsDir() { os.Chmod(path, 0o777) } return nil }) return os.RemoveAll(dir) } func homeEnvName() string { switch runtime.GOOS { case "windows": return "USERPROFILE" case "plan9": return "home" default: return "HOME" } } func tempEnvName() string { switch runtime.GOOS { case "windows": return "TMP" case "plan9": return "TMPDIR" // actually plan 9 doesn't have one at all but this is fine default: return "TMPDIR" } } go-internal-1.12.0/testscript/testscript_test.go000066400000000000000000000324201453631262600220210ustar00rootroot00000000000000// Copyright 2018 The Go 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 testscript import ( "bytes" "errors" "flag" "fmt" "io/ioutil" "os" "os/exec" "os/signal" "path/filepath" "reflect" "regexp" "strconv" "strings" "testing" "time" ) func printArgs() int { fmt.Printf("%q\n", os.Args) return 0 } func fprintArgs() int { s := strings.Join(os.Args[2:], " ") switch os.Args[1] { case "stdout": fmt.Println(s) case "stderr": fmt.Fprintln(os.Stderr, s) } return 0 } func exitWithStatus() int { n, _ := strconv.Atoi(os.Args[1]) return n } func signalCatcher() int { // Note: won't work under Windows. c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt) // Create a file so that the test can know that // we will catch the signal. if err := ioutil.WriteFile("catchsignal", nil, 0o666); err != nil { fmt.Println(err) return 1 } <-c fmt.Println("caught interrupt") return 0 } func terminalPrompt() int { tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0) if err != nil { fmt.Println(err) return 1 } tty.WriteString("The magic words are: ") var words string fmt.Fscanln(tty, &words) if words != "SQUEAMISHOSSIFRAGE" { fmt.Println(words) return 42 } return 0 } func TestMain(m *testing.M) { timeSince = func(t time.Time) time.Duration { return 0 } showVerboseEnv = false os.Exit(RunMain(m, map[string]func() int{ "printargs": printArgs, "fprintargs": fprintArgs, "status": exitWithStatus, "signalcatcher": signalCatcher, "terminalprompt": terminalPrompt, })) } func TestCRLFInput(t *testing.T) { td, err := ioutil.TempDir("", "") if err != nil { t.Fatalf("failed to create TempDir: %v", err) } defer func() { os.RemoveAll(td) }() tf := filepath.Join(td, "script.txt") contents := []byte("exists output.txt\r\n-- output.txt --\r\noutput contents") if err := ioutil.WriteFile(tf, contents, 0o644); err != nil { t.Fatalf("failed to write to %v: %v", tf, err) } t.Run("_", func(t *testing.T) { Run(t, Params{Dir: td}) }) } func TestEnv(t *testing.T) { e := &Env{ Vars: []string{ "HOME=/no-home", "PATH=/usr/bin", "PATH=/usr/bin:/usr/local/bin", "INVALID", }, } if got, want := e.Getenv("HOME"), "/no-home"; got != want { t.Errorf("e.Getenv(\"HOME\") == %q, want %q", got, want) } e.Setenv("HOME", "/home/user") if got, want := e.Getenv("HOME"), "/home/user"; got != want { t.Errorf(`e.Getenv("HOME") == %q, want %q`, got, want) } if got, want := e.Getenv("PATH"), "/usr/bin:/usr/local/bin"; got != want { t.Errorf(`e.Getenv("PATH") == %q, want %q`, got, want) } if got, want := e.Getenv("INVALID"), ""; got != want { t.Errorf(`e.Getenv("INVALID") == %q, want %q`, got, want) } for _, key := range []string{ "", "=", "key=invalid", } { var panicValue interface{} func() { defer func() { panicValue = recover() }() e.Setenv(key, "") }() if panicValue == nil { t.Errorf("e.Setenv(%q) did not panic, want panic", key) } } } func TestSetupFailure(t *testing.T) { dir := t.TempDir() if err := os.WriteFile(filepath.Join(dir, "foo.txt"), nil, 0o666); err != nil { t.Fatal(err) } ft := &fakeT{} func() { defer catchAbort() RunT(ft, Params{ Dir: dir, Setup: func(*Env) error { return fmt.Errorf("some failure") }, }) }() if !ft.failed { t.Fatal("test should have failed because of setup failure") } want := regexp.MustCompile(`^FAIL: .*: some failure\n$`) if got := ft.log.String(); !want.MatchString(got) { t.Fatalf("expected msg to match `%v`; got:\n%q", want, got) } } func TestScripts(t *testing.T) { // TODO set temp directory. testDeferCount := 0 Run(t, Params{ UpdateScripts: os.Getenv("TESTSCRIPT_UPDATE") != "", Dir: "testdata", Cmds: map[string]func(ts *TestScript, neg bool, args []string){ "setSpecialVal": setSpecialVal, "ensureSpecialVal": ensureSpecialVal, "interrupt": interrupt, "waitfile": waitFile, "testdefer": func(ts *TestScript, neg bool, args []string) { testDeferCount++ n := testDeferCount ts.Defer(func() { if testDeferCount != n { t.Errorf("defers not run in reverse order; got %d want %d", testDeferCount, n) } testDeferCount-- }) }, "setup-filenames": func(ts *TestScript, neg bool, want []string) { got := ts.Value("setupFilenames") if !reflect.DeepEqual(want, got) { ts.Fatalf("setup did not see expected files; got %q want %q", got, want) } }, "test-values": func(ts *TestScript, neg bool, args []string) { if ts.Value("somekey") != 1234 { ts.Fatalf("test-values did not see expected value") } if ts.Value("t").(T) != ts.t { ts.Fatalf("test-values did not see expected t") } if _, ok := ts.Value("t").(testing.TB); !ok { ts.Fatalf("test-values t does not implement testing.TB") } }, "testreadfile": func(ts *TestScript, neg bool, args []string) { if len(args) != 1 { ts.Fatalf("testreadfile ") } got := ts.ReadFile(args[0]) want := args[0] + "\n" if got != want { ts.Fatalf("reading %q; got %q want %q", args[0], got, want) } }, "testscript": func(ts *TestScript, neg bool, args []string) { // Run testscript in testscript. Oooh! Meta! fset := flag.NewFlagSet("testscript", flag.ContinueOnError) fUpdate := fset.Bool("update", false, "update scripts when cmp fails") fExplicitExec := fset.Bool("explicit-exec", false, "require explicit use of exec for commands") fUniqueNames := fset.Bool("unique-names", false, "require unique names in txtar archive") fVerbose := fset.Bool("v", false, "be verbose with output") fContinue := fset.Bool("continue", false, "continue on error") if err := fset.Parse(args); err != nil { ts.Fatalf("failed to parse args for testscript: %v", err) } if fset.NArg() != 1 { ts.Fatalf("testscript [-v] [-continue] [-update] [-explicit-exec] ") } dir := fset.Arg(0) t := &fakeT{verbose: *fVerbose} func() { defer catchAbort() RunT(t, Params{ Dir: ts.MkAbs(dir), UpdateScripts: *fUpdate, RequireExplicitExec: *fExplicitExec, RequireUniqueNames: *fUniqueNames, Cmds: map[string]func(ts *TestScript, neg bool, args []string){ "some-param-cmd": func(ts *TestScript, neg bool, args []string) { }, "echoandexit": echoandexit, }, ContinueOnError: *fContinue, }) }() stdout := t.log.String() stdout = strings.ReplaceAll(stdout, ts.workdir, "$WORK") fmt.Fprint(ts.Stdout(), stdout) if neg { if !t.failed { ts.Fatalf("testscript unexpectedly succeeded") } return } if t.failed { ts.Fatalf("testscript unexpectedly failed with errors: %q", &t.log) } }, "echoandexit": echoandexit, }, Setup: func(env *Env) error { infos, err := ioutil.ReadDir(env.WorkDir) if err != nil { return fmt.Errorf("cannot read workdir: %v", err) } var setupFilenames []string for _, info := range infos { setupFilenames = append(setupFilenames, info.Name()) } env.Values["setupFilenames"] = setupFilenames env.Values["somekey"] = 1234 env.Values["t"] = env.T() env.Vars = append(env.Vars, "GONOSUMDB=*", ) return nil }, }) if testDeferCount != 0 { t.Fatalf("defer mismatch; got %d want 0", testDeferCount) } // TODO check that the temp directory has been removed. } func echoandexit(ts *TestScript, neg bool, args []string) { // Takes at least one argument // // args[0] - int that indicates the exit code of the command // args[1] - the string to echo to stdout if non-empty // args[2] - the string to echo to stderr if non-empty if len(args) == 0 || len(args) > 3 { ts.Fatalf("echoandexit takes at least one and at most three arguments") } if neg { ts.Fatalf("neg means nothing for echoandexit") } exitCode, err := strconv.ParseInt(args[0], 10, 64) if err != nil { ts.Fatalf("failed to parse exit code from %q: %v", args[0], err) } if len(args) > 1 && args[1] != "" { fmt.Fprint(ts.Stdout(), args[1]) } if len(args) > 2 && args[2] != "" { fmt.Fprint(ts.Stderr(), args[2]) } if exitCode != 0 { ts.Fatalf("told to exit with code %d", exitCode) } } // TestTestwork tests that using the flag -testwork will make sure the work dir isn't removed // after the test is done. It uses an empty testscript file that doesn't do anything. func TestTestwork(t *testing.T) { out, err := exec.Command("go", "test", ".", "-testwork", "-v", "-run", "TestScripts/^nothing$").CombinedOutput() if err != nil { t.Fatal(err) } re := regexp.MustCompile(`\s+WORK=(\S+)`) match := re.FindAllStringSubmatch(string(out), -1) // Ensure that there is only one line with one match if len(match) != 1 || len(match[0]) != 2 { t.Fatalf("failed to extract WORK directory") } var fi os.FileInfo if fi, err = os.Stat(match[0][1]); err != nil { t.Fatalf("failed to stat expected work directory %v: %v", match[0][1], err) } if !fi.IsDir() { t.Fatalf("expected persisted workdir is not a directory: %v", match[0][1]) } } // TestWorkdirRoot tests that a non zero value in Params.WorkdirRoot is honoured func TestWorkdirRoot(t *testing.T) { td, err := ioutil.TempDir("", "") if err != nil { t.Fatalf("failed to create temp dir: %v", err) } defer os.RemoveAll(td) params := Params{ Dir: filepath.Join("testdata", "nothing"), WorkdirRoot: td, } // Run as a sub-test so that this call blocks until the sub-tests created by // calling Run (which themselves call t.Parallel) complete. t.Run("run tests", func(t *testing.T) { Run(t, params) }) // Verify that we have a single go-test-script-* named directory files, err := filepath.Glob(filepath.Join(td, "script-nothing", "README.md")) if err != nil { t.Fatal(err) } if len(files) != 1 { t.Fatalf("unexpected files found for kept files; got %q", files) } } // TestBadDir verifies that invoking testscript with a directory that either // does not exist or that contains no *.txt scripts fails the test func TestBadDir(t *testing.T) { ft := new(fakeT) func() { defer catchAbort() RunT(ft, Params{ Dir: "thiswillnevermatch", }) }() want := regexp.MustCompile(`no txtar nor txt scripts found in dir thiswillnevermatch`) if got := ft.log.String(); !want.MatchString(got) { t.Fatalf("expected msg to match `%v`; got:\n%v", want, got) } } // catchAbort catches the panic raised by fakeT.FailNow. func catchAbort() { if err := recover(); err != nil && err != errAbort { panic(err) } } func TestUNIX2DOS(t *testing.T) { for data, want := range map[string]string{ "": "", // Preserve empty files. "\n": "\r\n", // Convert LF to CRLF in a file containing a single empty line. "\r\n": "\r\n", // Preserve CRLF in a single line file. "a": "a\r\n", // Append CRLF to a single line file with no line terminator. "a\n": "a\r\n", // Convert LF to CRLF in a file containing a single non-empty line. "a\r\n": "a\r\n", // Preserve CRLF in a file containing a single non-empty line. "a\nb\n": "a\r\nb\r\n", // Convert LF to CRLF in multiline UNIX file. "a\r\nb\n": "a\r\nb\r\n", // Convert LF to CRLF in a file containing a mix of UNIX and DOS lines. "a\nb\r\n": "a\r\nb\r\n", // Convert LF to CRLF in a file containing a mix of UNIX and DOS lines. } { if got, err := unix2DOS([]byte(data)); err != nil || !bytes.Equal(got, []byte(want)) { t.Errorf("unix2DOS(%q) == %q, %v, want %q, nil", data, got, err, want) } } } func setSpecialVal(ts *TestScript, neg bool, args []string) { ts.Setenv("SPECIALVAL", "42") } func ensureSpecialVal(ts *TestScript, neg bool, args []string) { want := "42" if got := ts.Getenv("SPECIALVAL"); got != want { ts.Fatalf("expected SPECIALVAL to be %q; got %q", want, got) } } // interrupt interrupts the current background command. // Note that this will not work under Windows. func interrupt(ts *TestScript, neg bool, args []string) { if neg { ts.Fatalf("interrupt does not support neg") } if len(args) > 0 { ts.Fatalf("unexpected args found") } bg := ts.BackgroundCmds() if got, want := len(bg), 1; got != want { ts.Fatalf("unexpected background cmd count; got %d want %d", got, want) } bg[0].Process.Signal(os.Interrupt) } func waitFile(ts *TestScript, neg bool, args []string) { if neg { ts.Fatalf("waitfile does not support neg") } if len(args) != 1 { ts.Fatalf("usage: waitfile file") } path := ts.MkAbs(args[0]) for i := 0; i < 100; i++ { _, err := os.Stat(path) if err == nil { return } if !os.IsNotExist(err) { ts.Fatalf("unexpected stat error: %v", err) } time.Sleep(10 * time.Millisecond) } ts.Fatalf("timed out waiting for %q to be created", path) } type fakeT struct { log strings.Builder verbose bool failed bool } var errAbort = errors.New("abort test") func (t *fakeT) Skip(args ...interface{}) { panic(errAbort) } func (t *fakeT) Fatal(args ...interface{}) { t.Log(args...) t.FailNow() } func (t *fakeT) Parallel() {} func (t *fakeT) Log(args ...interface{}) { fmt.Fprint(&t.log, args...) } func (t *fakeT) FailNow() { t.failed = true panic(errAbort) } func (t *fakeT) Run(name string, f func(T)) { f(t) } func (t *fakeT) Verbose() bool { return t.verbose } func (t *fakeT) Failed() bool { return t.failed } go-internal-1.12.0/txtar/000077500000000000000000000000001453631262600151645ustar00rootroot00000000000000go-internal-1.12.0/txtar/archive.go000066400000000000000000000150121453631262600171330ustar00rootroot00000000000000// Copyright 2018 The Go 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 txtar implements a trivial text-based file archive format. // // The goals for the format are: // // - be trivial enough to create and edit by hand. // - be able to store trees of text files describing go command test cases. // - diff nicely in git history and code reviews. // // Non-goals include being a completely general archive format, // storing binary data, storing file modes, storing special files like // symbolic links, and so on. // // # Txtar format // // A txtar archive is zero or more comment lines and then a sequence of file entries. // Each file entry begins with a file marker line of the form "-- FILENAME --" // and is followed by zero or more file content lines making up the file data. // The comment or file content ends at the next file marker line. // The file marker line must begin with the three-byte sequence "-- " // and end with the three-byte sequence " --", but the enclosed // file name can be surrounding by additional white space, // all of which is stripped. // // If the txtar file is missing a trailing newline on the final line, // parsers should consider a final newline to be present anyway. // // There are no possible syntax errors in a txtar archive. package txtar import ( "bytes" "errors" "fmt" "io/ioutil" "os" "path/filepath" "strings" "unicode/utf8" "golang.org/x/tools/txtar" ) // An Archive is a collection of files. type Archive = txtar.Archive // A File is a single file in an archive. type File = txtar.File // Format returns the serialized form of an Archive. // It is assumed that the Archive data structure is well-formed: // a.Comment and all a.File[i].Data contain no file marker lines, // and all a.File[i].Name is non-empty. func Format(a *Archive) []byte { return txtar.Format(a) } // ParseFile parses the named file as an archive. func ParseFile(file string) (*Archive, error) { data, err := ioutil.ReadFile(file) if err != nil { return nil, err } return Parse(data), nil } // Parse parses the serialized form of an Archive. // The returned Archive holds slices of data. // // TODO use golang.org/x/tools/txtar.Parse when https://github.com/golang/go/issues/59264 // is fixed. func Parse(data []byte) *Archive { a := new(Archive) var name string a.Comment, name, data = findFileMarker(data) for name != "" { f := File{name, nil} f.Data, name, data = findFileMarker(data) a.Files = append(a.Files, f) } return a } // NeedsQuote reports whether the given data needs to // be quoted before it's included as a txtar file. func NeedsQuote(data []byte) bool { _, _, after := findFileMarker(data) return after != nil } // Quote quotes the data so that it can be safely stored in a txtar // file. This copes with files that contain lines that look like txtar // separators. // // The original data can be recovered with Unquote. It returns an error // if the data cannot be quoted (for example because it has no final // newline or it holds unprintable characters) func Quote(data []byte) ([]byte, error) { if len(data) == 0 { return nil, nil } if data[len(data)-1] != '\n' { return nil, errors.New("data has no final newline") } if !utf8.Valid(data) { return nil, fmt.Errorf("data contains non-UTF-8 characters") } var nd []byte prev := byte('\n') for _, b := range data { if prev == '\n' { nd = append(nd, '>') } nd = append(nd, b) prev = b } return nd, nil } // Unquote unquotes data as quoted by Quote. func Unquote(data []byte) ([]byte, error) { if len(data) == 0 { return nil, nil } if data[0] != '>' || data[len(data)-1] != '\n' { return nil, errors.New("data does not appear to be quoted") } data = bytes.Replace(data, []byte("\n>"), []byte("\n"), -1) data = bytes.TrimPrefix(data, []byte(">")) return data, nil } var ( newlineMarker = []byte("\n-- ") marker = []byte("-- ") markerEnd = []byte(" --") ) // findFileMarker finds the next file marker in data, // extracts the file name, and returns the data before the marker, // the file name, and the data after the marker. // If there is no next marker, findFileMarker returns before = fixNL(data), name = "", after = nil. func findFileMarker(data []byte) (before []byte, name string, after []byte) { var i int for { if name, after = isMarker(data[i:]); name != "" { return data[:i], name, after } j := bytes.Index(data[i:], newlineMarker) if j < 0 { return fixNL(data), "", nil } i += j + 1 // positioned at start of new possible marker } } // isMarker checks whether data begins with a file marker line. // If so, it returns the name from the line and the data after the line. // Otherwise it returns name == "" with an unspecified after. func isMarker(data []byte) (name string, after []byte) { if !bytes.HasPrefix(data, marker) { return "", nil } if i := bytes.IndexByte(data, '\n'); i >= 0 { data, after = data[:i], data[i+1:] if data[i-1] == '\r' { data = data[:len(data)-1] } } if !bytes.HasSuffix(data, markerEnd) { return "", nil } return strings.TrimSpace(string(data[len(marker) : len(data)-len(markerEnd)])), after } // If data is empty or ends in \n, fixNL returns data. // Otherwise fixNL returns a new slice consisting of data with a final \n added. func fixNL(data []byte) []byte { if len(data) == 0 || data[len(data)-1] == '\n' { return data } d := make([]byte, len(data)+1) copy(d, data) d[len(data)] = '\n' return d } // Write writes each File in an Archive to the given directory, returning any // errors encountered. An error is also returned in the event a file would be // written outside of dir. func Write(a *Archive, dir string) error { for _, f := range a.Files { fp := filepath.Clean(filepath.FromSlash(f.Name)) if isAbs(fp) || strings.HasPrefix(fp, ".."+string(filepath.Separator)) { return fmt.Errorf("%q: outside parent directory", f.Name) } fp = filepath.Join(dir, fp) if err := os.MkdirAll(filepath.Dir(fp), 0o777); err != nil { return err } // Avoid overwriting existing files by using O_EXCL. out, err := os.OpenFile(fp, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o666) if err != nil { return err } _, err = out.Write(f.Data) cerr := out.Close() if err != nil { return err } if cerr != nil { return cerr } } return nil } func isAbs(p string) bool { // Note: under Windows, filepath.IsAbs(`\foo`) returns false, // so we need to check for that case specifically. return filepath.IsAbs(p) || strings.HasPrefix(p, string(filepath.Separator)) } go-internal-1.12.0/txtar/archive_test.go000066400000000000000000000104561453631262600202010ustar00rootroot00000000000000// Copyright 2018 The Go 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 txtar import ( "bytes" "fmt" "io/ioutil" "os" "reflect" "testing" ) var tests = []struct { name string text string parsed *Archive }{ // General test { name: "basic", text: `comment1 comment2 -- file1 -- File 1 text. -- foo --- More file 1 text. -- file 2 -- File 2 text. -- empty -- -- noNL -- hello world`, parsed: &Archive{ Comment: []byte("comment1\ncomment2\n"), Files: []File{ {"file1", []byte("File 1 text.\n-- foo ---\nMore file 1 text.\n")}, {"file 2", []byte("File 2 text.\n")}, {"empty", []byte{}}, {"noNL", []byte("hello world\n")}, }, }, }, // Test CRLF input { name: "basicCRLF", text: "blah\r\n-- hello --\r\nhello\r\n", parsed: &Archive{ Comment: []byte("blah\r\n"), Files: []File{ {"hello", []byte("hello\r\n")}, }, }, }, } func Test(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { a := Parse([]byte(tt.text)) if !reflect.DeepEqual(a, tt.parsed) { t.Fatalf("Parse: wrong output:\nhave:\n%s\nwant:\n%s", shortArchive(a), shortArchive(tt.parsed)) } text := Format(a) a = Parse(text) if !reflect.DeepEqual(a, tt.parsed) { t.Fatalf("Parse after Format: wrong output:\nhave:\n%s\nwant:\n%s", shortArchive(a), shortArchive(tt.parsed)) } }) } } func shortArchive(a *Archive) string { var buf bytes.Buffer fmt.Fprintf(&buf, "comment: %q\n", a.Comment) for _, f := range a.Files { fmt.Fprintf(&buf, "file %q: %q\n", f.Name, f.Data) } return buf.String() } func TestWrite(t *testing.T) { td, err := ioutil.TempDir("", "") if err != nil { t.Fatalf("failed to create temp dir: %v", err) } defer os.RemoveAll(td) good := &Archive{Files: []File{File{Name: "good.txt"}}} if err := Write(good, td); err != nil { t.Fatalf("expected no error; got %v", err) } badRel := &Archive{Files: []File{File{Name: "../bad.txt"}}} want := `"../bad.txt": outside parent directory` if err := Write(badRel, td); err == nil || err.Error() != want { t.Fatalf("expected %v; got %v", want, err) } badAbs := &Archive{Files: []File{File{Name: "/bad.txt"}}} want = `"/bad.txt": outside parent directory` if err := Write(badAbs, td); err == nil || err.Error() != want { t.Fatalf("expected %v; got %v", want, err) } } var unquoteErrorTests = []struct { testName string data string expectError string }{{ testName: "no final newline", data: ">hello", expectError: `data does not appear to be quoted`, }, { testName: "no initial >", data: "hello\n", expectError: `data does not appear to be quoted`, }} func TestUnquote(t *testing.T) { for _, test := range unquoteErrorTests { t.Run(test.testName, func(t *testing.T) { _, err := Unquote([]byte(test.data)) if err == nil { t.Fatalf("unexpected success") } if err.Error() != test.expectError { t.Fatalf("unexpected error; got %q want %q", err, test.expectError) } }) } } var quoteTests = []struct { testName string data string expect string expectError string }{{ testName: "empty", data: "", expect: "", }, { testName: "one line", data: "foo\n", expect: ">foo\n", }, { testName: "several lines", data: "foo\nbar\n-- baz --\n", expect: ">foo\n>bar\n>-- baz --\n", }, { testName: "bad data", data: "foo\xff\n", expectError: `data contains non-UTF-8 characters`, }, { testName: "no final newline", data: "foo", expectError: `data has no final newline`, }} func TestQuote(t *testing.T) { for _, test := range quoteTests { t.Run(test.testName, func(t *testing.T) { got, err := Quote([]byte(test.data)) if test.expectError != "" { if err == nil { t.Fatalf("unexpected success") } if err.Error() != test.expectError { t.Fatalf("unexpected error; got %q want %q", err, test.expectError) } return } if err != nil { t.Fatalf("quote error: %v", err) } if string(got) != test.expect { t.Fatalf("unexpected result; got %q want %q", got, test.expect) } orig, err := Unquote(got) if err != nil { t.Fatal(err) } if string(orig) != test.data { t.Fatalf("round trip failed; got %q want %q", orig, test.data) } }) } }