<commit_before>// Copyright ©2011-2012 The bíogo 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 pwm implements a position weight matrix search based on an
// algorithm by Deborah Toledo Flores.
package pwm

import (
	"code.google.com/p/biogo/bio"
	"code.google.com/p/biogo/exp/feat"
	"code.google.com/p/biogo/exp/seq"
	"code.google.com/p/biogo/exp/seq/sequtils"
	ofeat "code.google.com/p/biogo/feat"
	"fmt"
	"math"
	"sort"
)

type probs struct {
	score      float64
	freqs      []int
	occurrence int
}

type probTable []*probs

func (m probTable) Len() int           { return len(m) }
func (m probTable) Less(i, j int) bool { return m[i].score > m[j].score }
func (m probTable) Swap(i, j int)      { m[i], m[j] = m[j], m[i] }

type PWM struct {
	matrix    [][]float64
	lookAhead []float64
	table     probTable
	minScore  float64
	Format    string // Format for probability values in attributes.
}

func New(matrix [][]float64) (m *PWM) {
	m = &PWM{
		matrix:    matrix,
		lookAhead: make([]float64, len(matrix)),
		minScore:  math.MaxFloat64,
		Format:    "%e",
	}

	var maxVal, maxScore float64

	for i := len(matrix) - 1; i >= 0; i-- {
		maxVal = 0
		for _, v := range matrix[i] {
			if v > maxVal {
				maxVal = v
			}
		}
		maxScore += maxVal
		m.lookAhead[i] = maxScore
	}

	for i := range matrix {
		for j := range matrix[i] {
			matrix[i][j] /= maxScore
		}
		m.lookAhead[i] /= maxScore
	}

	return
}

func (m *PWM) genTable(minScore, score float64, pos int, motif []byte) {
	for i, s := range m.matrix[pos] {
		motif[pos] = byte(i)
		if pos < len(m.matrix)-1 {
			if minScore-(score+s) > m.lookAhead[pos+1] { // will not be able to achieve minScore
				continue
			}
			m.genTable(minScore, score+s, pos+1, motif)
		} else {
			if score+s < minScore { // will not be able to achieve minScore
				continue
			}
			// count frequencies of states in current motif
			freqs := make([]int, 4)
			for _, j := range motif {
				freqs[j]++
			}
			found := false
			for j := len(m.table) - 1; j >= 0; j-- {
				table := m.table[j]
				if table.score != score+s {
					continue // if using insertion sort, if table.score > score+s then we can found = false and break
				}
				match := true
				for k := range freqs {
					if freqs[k] != table.freqs[k] {
						match = false
						break
					}
				}
				if match {
					table.occurrence++
					found = true
					break
				}
			}

			if !found {
				m.table = append(m.table, &probs{score: score + s, freqs: freqs, occurrence: 1})
			}
		}
	}

}

type Sequence interface {
	seq.Sequence
	Moltype() bio.Moltype
	Orientation() feat.Orientation
}

func (m *PWM) Search(s Sequence, start, end int, minScore float64) []*ofeat.Feature {
	if minScore < m.minScore {
		m.table = make(probTable, 0)
		m.genTable(minScore, 0, 0, make([]byte, len(m.matrix)))
		sort.Sort(m.table)
	}

	var (
		index  = s.Alphabet().LetterIndex()
		length = len(m.matrix)

		freqs = make([]float64, 4)
		zeros = make([]float64, 4)

		diff = 1 / float64(length)

		format = "%-s " + m.Format
		mot    = s.New()
		f      []*ofeat.Feature
	)

LOOP:
	for pos := start; pos+length < end; pos++ {
		// Determine the score for this position.
		var score = 0.
		for i := 0; i < length; i++ {
			base := index[s.At(pos+i).L]
			if base < 0 || minScore-score > m.lookAhead[i] { // not valid base or will not be able to achieve minScore
				continue LOOP
			} else {
				score += m.matrix[i][base]
			}
		}

		if score < minScore {
			continue
		}

		// Calculate base frequencies for window.
		copy(freqs, zeros)
		for i := pos; i < pos+length; i++ {
			base := index[s.At(i).L]
			if base >= 0 {
				freqs[base] += diff
			} else { // Probability for this pos will be meaningless; if N is tolerated, include N in valid alphabet - make special case?
				continue LOOP
			}
		}

		// Descend probability function summing probabilities.
		var (
			prob = 0.
			sp   = 0.
		)
		for _, e := range m.table {
			sp = 1
			if e.score < score {
				break
			}
			for i, f := range freqs {
				sp *= math.Pow(f, float64(e.freqs[i]))
			}
			sp *= float64(e.occurrence)
			prob += sp
		}

		sequtils.Truncate(mot, s, pos, pos+length) // FIXME Should use Slice for non-allocating path.
		f = append(f, &ofeat.Feature{
			Location:   fmt.Sprintf("%s %s", s.Name(), s.Description()),
			Start:      pos,
			End:        pos + length,
			Score:      &score,
			Attributes: fmt.Sprintf(format, mot, prob),
			Strand:     int8(s.Orientation()),
			Moltype:    s.Moltype(),
			Frame:      -1,
		})
	}

	return f
}
<commit_msg>Use new feat type<commit_after>// Copyright ©2011-2013 The bíogo 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 pwm implements a position weight matrix search based on an
// algorithm by Deborah Toledo Flores.
package pwm

import (
	"code.google.com/p/biogo/bio"
	"code.google.com/p/biogo/exp/feat"
	"code.google.com/p/biogo/exp/seq"
	"code.google.com/p/biogo/exp/seq/sequtils"

	"fmt"
	"math"
	"sort"
)

type probs struct {
	score      float64
	freqs      []int
	occurrence int
}

type probTable []*probs

func (m probTable) Len() int           { return len(m) }
func (m probTable) Less(i, j int) bool { return m[i].score > m[j].score }
func (m probTable) Swap(i, j int)      { m[i], m[j] = m[j], m[i] }

type Feature struct {
	MotifLocation feat.Feature
	MotifStart    int
	MotifEnd      int
	MotifScore    float64
	MotifProb     float64
	MotifSeq      seq.Sequence
	MotifOrient   feat.Orientation
	Moltype       bio.Moltype
}

func (f *Feature) Start() int { return f.MotifStart }
func (f *Feature) End() int   { return f.MotifEnd }
func (f *Feature) Len() int   { return f.MotifEnd - f.MotifStart }
func (f *Feature) Name() string {
	return fmt.Sprintf("%s:[%d,%d)", f.Location().Name(), f.MotifStart, f.MotifEnd)
}
func (f *Feature) Description() string           { return "PWM motif" }
func (f *Feature) Location() feat.Feature        { return f.MotifLocation }
func (f *Feature) MolType() bio.Moltype          { return f.Moltype }
func (f *Feature) Orientation() feat.Orientation { return f.MotifOrient }

type PWM struct {
	matrix    [][]float64
	lookAhead []float64
	table     probTable
	minScore  float64
	Format    string // Format for probability values in attributes.
}

func New(matrix [][]float64) (m *PWM) {
	m = &PWM{
		matrix:    matrix,
		lookAhead: make([]float64, len(matrix)),
		minScore:  math.MaxFloat64,
		Format:    "%e",
	}

	var maxVal, maxScore float64

	for i := len(matrix) - 1; i >= 0; i-- {
		maxVal = 0
		for _, v := range matrix[i] {
			if v > maxVal {
				maxVal = v
			}
		}
		maxScore += maxVal
		m.lookAhead[i] = maxScore
	}

	for i := range matrix {
		for j := range matrix[i] {
			matrix[i][j] /= maxScore
		}
		m.lookAhead[i] /= maxScore
	}

	return
}

func (m *PWM) genTable(minScore, score float64, pos int, motif []byte) {
	for i, s := range m.matrix[pos] {
		motif[pos] = byte(i)
		if pos < len(m.matrix)-1 {
			if minScore-(score+s) > m.lookAhead[pos+1] { // will not be able to achieve minScore
				continue
			}
			m.genTable(minScore, score+s, pos+1, motif)
		} else {
			if score+s < minScore { // will not be able to achieve minScore
				continue
			}
			// count frequencies of states in current motif
			freqs := make([]int, 4)
			for _, j := range motif {
				freqs[j]++
			}
			found := false
			for j := len(m.table) - 1; j >= 0; j-- {
				table := m.table[j]
				if table.score != score+s {
					continue // if using insertion sort, if table.score > score+s then we can found = false and break
				}
				match := true
				for k := range freqs {
					if freqs[k] != table.freqs[k] {
						match = false
						break
					}
				}
				if match {
					table.occurrence++
					found = true
					break
				}
			}

			if !found {
				m.table = append(m.table, &probs{score: score + s, freqs: freqs, occurrence: 1})
			}
		}
	}

}

type Sequence interface {
	seq.Sequence
	Moltype() bio.Moltype
	Orientation() feat.Orientation
}

func (m *PWM) Search(s Sequence, start, end int, minScore float64) []feat.Feature {
	if minScore < m.minScore {
		m.table = make(probTable, 0)
		m.genTable(minScore, 0, 0, make([]byte, len(m.matrix)))
		sort.Sort(m.table)
	}

	var (
		index  = s.Alphabet().LetterIndex()
		length = len(m.matrix)

		freqs = make([]float64, 4)
		zeros = make([]float64, 4)

		diff = 1 / float64(length)

		f []feat.Feature
	)

LOOP:
	for pos := start; pos+length < end; pos++ {
		// Determine the score for this position.
		var score = 0.
		for i := 0; i < length; i++ {
			base := index[s.At(pos+i).L]
			if base < 0 || minScore-score > m.lookAhead[i] { // not valid base or will not be able to achieve minScore
				continue LOOP
			} else {
				score += m.matrix[i][base]
			}
		}

		if score < minScore {
			continue
		}

		// Calculate base frequencies for window.
		copy(freqs, zeros)
		for i := pos; i < pos+length; i++ {
			base := index[s.At(i).L]
			if base >= 0 {
				freqs[base] += diff
			} else { // Probability for this pos will be meaningless; if N is tolerated, include N in valid alphabet - make special case?
				continue LOOP
			}
		}

		// Descend probability function summing probabilities.
		var (
			prob = 0.
			sp   = 0.
		)
		for _, e := range m.table {
			sp = 1
			if e.score < score {
				break
			}
			for i, f := range freqs {
				sp *= math.Pow(f, float64(e.freqs[i]))
			}
			sp *= float64(e.occurrence)
			prob += sp
		}

		mot := s.New()
		sequtils.Truncate(mot, s, pos, pos+length)
		f = append(f, &Feature{
			MotifLocation: s,
			MotifStart:    pos,
			MotifEnd:      pos + length,
			MotifScore:    score,
			MotifProb:     prob,
			MotifSeq:      mot,
			MotifOrient:   s.Orientation(),
			Moltype:       s.Moltype(),
		})
	}

	return f
}
<|endoftext|>


<commit_before>/*
 * Minio Client (C) 2014, 2015 Minio, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package main

import (
	"encoding/json"

	"github.com/fatih/color"
	"github.com/minio/cli"
	"github.com/minio/mc/pkg/console"
	"github.com/minio/minio/pkg/probe"
)

var (
	mbFlags = []cli.Flag{
		cli.BoolFlag{
			Name:  "help, h",
			Usage: "Help of mb.",
		},
		cli.StringFlag{
			Name:  "region",
			Value: "us-east-1",
			Usage: "Specify bucket region. Defaults to ‘us-east-1’.",
		},
	}
)

// make a bucket or folder.
var mbCmd = cli.Command{
	Name:   "mb",
	Usage:  "Make a bucket or folder.",
	Action: mainMakeBucket,
	Flags:  append(mbFlags, globalFlags...),
	CustomHelpTemplate: `NAME:
   mc {{.Name}} - {{.Usage}}

USAGE:
   mc {{.Name}} [FLAGS] TARGET [TARGET...]

FLAGS:
  {{range .Flags}}{{.}}
  {{end}}
EXAMPLES:
   1. Create a bucket on Amazon S3 cloud storage.
      $ mc {{.Name}} s3/mynewbucket

   2. Create a new bucket on Google Cloud Storage.
      $ mc {{.Name}} gcs/miniocloud

   4. Create a new bucket on Amazon S3 cloud storage in region ‘us-west-2’.
      $ mc {{.Name}} --region=us-west-2 s3/myregionbucket

   5. Create a new directory including its missing parents (equivalent to ‘mkdir -p’).
      $ mc {{.Name}} /tmp/this/new/dir1

   6. Create multiple directories including its missing parents (behavior similar to ‘mkdir -p’).
      $ mc {{.Name}} /mnt/sdb/mydisk /mnt/sdc/mydisk /mnt/sdd/mydisk
`,
}

// makeBucketMessage is container for make bucket success and failure messages.
type makeBucketMessage struct {
	Status string `json:"status"`
	Bucket string `json:"bucket"`
	Region string `json:"region"`
}

// String colorized make bucket message.
func (s makeBucketMessage) String() string {
	return console.Colorize("MakeBucket", "Bucket created successfully ‘"+s.Bucket+"’.")
}

// JSON jsonified make bucket message.
func (s makeBucketMessage) JSON() string {
	makeBucketJSONBytes, e := json.Marshal(s)
	fatalIf(probe.NewError(e), "Unable to marshal into JSON.")

	return string(makeBucketJSONBytes)
}

// Validate command line arguments.
func checkMakeBucketSyntax(ctx *cli.Context) {
	if !ctx.Args().Present() {
		cli.ShowCommandHelpAndExit(ctx, "mb", 1) // last argument is exit code
	}
}

// mainMakeBucket is entry point for mb command.
func mainMakeBucket(ctx *cli.Context) {
	// Set global flags from context.
	setGlobalsFromContext(ctx)

	// check 'mb' cli arguments.
	checkMakeBucketSyntax(ctx)

	// Additional command speific theme customization.
	console.SetColor("MakeBucket", color.New(color.FgGreen, color.Bold))

	// Save region.
	region := ctx.String("region")

	for i := range ctx.Args() {
		targetURL := ctx.Args().Get(i)
		// Instantiate client for URL.
		clnt, err := newClient(targetURL)
		errorIf(err.Trace(targetURL), "Invalid target ‘"+targetURL+"’.")

		// Make bucket.
		err = clnt.MakeBucket(region)
		errorIf(err.Trace(targetURL), "Unable to make bucket ‘"+targetURL+"’.")

		// Successfully created a bucket.
		printMsg(makeBucketMessage{Status: "success", Bucket: targetURL})
	}
}
<commit_msg>Do not show successful msg in mb command when the latter actually fails (#1761)<commit_after>/*
 * Minio Client (C) 2014, 2015 Minio, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package main

import (
	"encoding/json"

	"github.com/fatih/color"
	"github.com/minio/cli"
	"github.com/minio/mc/pkg/console"
	"github.com/minio/minio/pkg/probe"
)

var (
	mbFlags = []cli.Flag{
		cli.BoolFlag{
			Name:  "help, h",
			Usage: "Help of mb.",
		},
		cli.StringFlag{
			Name:  "region",
			Value: "us-east-1",
			Usage: "Specify bucket region. Defaults to ‘us-east-1’.",
		},
	}
)

// make a bucket or folder.
var mbCmd = cli.Command{
	Name:   "mb",
	Usage:  "Make a bucket or folder.",
	Action: mainMakeBucket,
	Flags:  append(mbFlags, globalFlags...),
	CustomHelpTemplate: `NAME:
   mc {{.Name}} - {{.Usage}}

USAGE:
   mc {{.Name}} [FLAGS] TARGET [TARGET...]

FLAGS:
  {{range .Flags}}{{.}}
  {{end}}
EXAMPLES:
   1. Create a bucket on Amazon S3 cloud storage.
      $ mc {{.Name}} s3/mynewbucket

   2. Create a new bucket on Google Cloud Storage.
      $ mc {{.Name}} gcs/miniocloud

   4. Create a new bucket on Amazon S3 cloud storage in region ‘us-west-2’.
      $ mc {{.Name}} --region=us-west-2 s3/myregionbucket

   5. Create a new directory including its missing parents (equivalent to ‘mkdir -p’).
      $ mc {{.Name}} /tmp/this/new/dir1

   6. Create multiple directories including its missing parents (behavior similar to ‘mkdir -p’).
      $ mc {{.Name}} /mnt/sdb/mydisk /mnt/sdc/mydisk /mnt/sdd/mydisk
`,
}

// makeBucketMessage is container for make bucket success and failure messages.
type makeBucketMessage struct {
	Status string `json:"status"`
	Bucket string `json:"bucket"`
	Region string `json:"region"`
}

// String colorized make bucket message.
func (s makeBucketMessage) String() string {
	return console.Colorize("MakeBucket", "Bucket created successfully ‘"+s.Bucket+"’.")
}

// JSON jsonified make bucket message.
func (s makeBucketMessage) JSON() string {
	makeBucketJSONBytes, e := json.Marshal(s)
	fatalIf(probe.NewError(e), "Unable to marshal into JSON.")

	return string(makeBucketJSONBytes)
}

// Validate command line arguments.
func checkMakeBucketSyntax(ctx *cli.Context) {
	if !ctx.Args().Present() {
		cli.ShowCommandHelpAndExit(ctx, "mb", 1) // last argument is exit code
	}
}

// mainMakeBucket is entry point for mb command.
func mainMakeBucket(ctx *cli.Context) {
	// Set global flags from context.
	setGlobalsFromContext(ctx)

	// check 'mb' cli arguments.
	checkMakeBucketSyntax(ctx)

	// Additional command speific theme customization.
	console.SetColor("MakeBucket", color.New(color.FgGreen, color.Bold))

	// Save region.
	region := ctx.String("region")

	for i := range ctx.Args() {
		targetURL := ctx.Args().Get(i)
		// Instantiate client for URL.
		clnt, err := newClient(targetURL)
		if err != nil {
			errorIf(err.Trace(targetURL), "Invalid target ‘"+targetURL+"’.")
			continue
		}

		// Make bucket.
		err = clnt.MakeBucket(region)
		if err != nil {
			errorIf(err.Trace(targetURL), "Unable to make bucket ‘"+targetURL+"’.")
			continue
		}

		// Successfully created a bucket.
		printMsg(makeBucketMessage{Status: "success", Bucket: targetURL})
	}
}
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package thrift

import (
	"compress/gzip"
	"io"
	"net/http"
	"strings"
)

// NewThriftHandlerFunc is a function that create a ready to use Apache Thrift Handler function
func NewThriftHandlerFunc(processor TProcessor,
	inPfactory, outPfactory TProtocolFactory) func(w http.ResponseWriter, r *http.Request) {

	return gz(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Add("Content-Type", "application/x-thrift")

		transport := NewStreamTransport(r.Body, w)
		processor.Process(r.Context(), inPfactory.GetProtocol(transport), outPfactory.GetProtocol(transport))
	})
}

// gz transparently compresses the HTTP response if the client supports it.
func gz(handler http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
			handler(w, r)
			return
		}
		w.Header().Set("Content-Encoding", "gzip")
		gz := gzip.NewWriter(w)
		defer gz.Close()
		gzw := gzipResponseWriter{Writer: gz, ResponseWriter: w}
		handler(gzw, r)
	}
}

type gzipResponseWriter struct {
	io.Writer
	http.ResponseWriter
}

func (w gzipResponseWriter) Write(b []byte) (int, error) {
	return w.Writer.Write(b)
}
<commit_msg>go: Use sync.Pool for gzip in HTTP transport<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package thrift

import (
	"compress/gzip"
	"io"
	"net/http"
	"strings"
	"sync"
)

// NewThriftHandlerFunc is a function that create a ready to use Apache Thrift Handler function
func NewThriftHandlerFunc(processor TProcessor,
	inPfactory, outPfactory TProtocolFactory) func(w http.ResponseWriter, r *http.Request) {

	return gz(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Add("Content-Type", "application/x-thrift")

		transport := NewStreamTransport(r.Body, w)
		processor.Process(r.Context(), inPfactory.GetProtocol(transport), outPfactory.GetProtocol(transport))
	})
}

// gz transparently compresses the HTTP response if the client supports it.
func gz(handler http.HandlerFunc) http.HandlerFunc {
	sp := &sync.Pool{
		New: func() interface{} {
			return gzip.NewWriter(nil)
		},
	}

	return func(w http.ResponseWriter, r *http.Request) {
		if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
			handler(w, r)
			return
		}
		w.Header().Set("Content-Encoding", "gzip")
		gz := sp.Get().(*gzip.Writer)
		gz.Reset(w)
		defer func() {
			_ = gz.Close()
			sp.Put(gz)
		}()
		gzw := gzipResponseWriter{Writer: gz, ResponseWriter: w}
		handler(gzw, r)
	}
}

type gzipResponseWriter struct {
	io.Writer
	http.ResponseWriter
}

func (w gzipResponseWriter) Write(b []byte) (int, error) {
	return w.Writer.Write(b)
}
<|endoftext|>


<commit_before>package main

// NOTE: Only annotation rules targeting tests implemented in origin
// should be added to this file.
//
// Rules defined here are additive to the rules already defined for
// kube e2e tests in openshift/kubernetes. The kube rules are
// vendored via the following file:
//
//   vendor/k8s.io/kubernetes/openshift-hack/e2e/annotate/rules.go
//
// Changes to rules for kube e2e tests should be proposed to
// openshift/kubernetes and vendored back into origin.

var (
	testMaps = map[string][]string{
		// tests that require a local host
		"[Local]": {
			// Doesn't work on scaled up clusters
			`\[Feature:ImagePrune\]`,
		},
		// alpha features that are not gated
		"[Disabled:Alpha]": {},
		// tests for features that are not implemented in openshift
		"[Disabled:Unimplemented]": {},
		// tests that rely on special configuration that we do not yet support
		"[Disabled:SpecialConfig]": {},
		// tests that rely on special configuration that we do not yet support
		// tests that are known broken and need to be fixed upstream or in openshift
		// always add an issue here
		"[Disabled:Broken]": {
			`should idle the service and DeploymentConfig properly`,       // idling with a single service and DeploymentConfig
			`should answer endpoint and wildcard queries for the cluster`, // currently not supported by dns operator https://github.com/openshift/cluster-dns-operator/issues/43
		},
		// tests that may work, but we don't support them
		"[Disabled:Unsupported]": {},
		// tests too slow to be part of conformance
		"[Slow]": {},
		// tests that are known flaky
		"[Flaky]": {
			`openshift mongodb replication creating from a template`, // flaking on deployment
		},
		// tests that must be run without competition
		"[Serial]":        {},
		"[Skipped:azure]": {},
		"[Skipped:ovirt]": {
			// https://bugzilla.redhat.com/show_bug.cgi?id=1838751
			`\[sig-network\] Networking Granular Checks: Services should function for endpoint-Service`,
			`\[sig-network\] Networking Granular Checks: Services should function for node-Service`,
			`\[sig-network\] Networking Granular Checks: Services should function for pod-Service`,
		},
		"[Skipped:gce]": {},
		// tests that don't pass under openshift-sdn multitenant mode
		"[Skipped:Network/OpenShiftSDN/Multitenant]": {
			`\[Feature:NetworkPolicy\]`, // not compatible with multitenant mode
			`\[sig-network\] Services should preserve source pod IP for traffic thru service cluster IP`, // known bug, not planned to be fixed
		},
		// tests that don't pass under OVN Kubernetes
		"[Skipped:Network/OVNKubernetes]": {
			// https://jira.coreos.com/browse/SDN-510: OVN-K doesn't support session affinity
			`\[sig-network\] Networking Granular Checks: Services should function for client IP based session affinity: http`,
			`\[sig-network\] Networking Granular Checks: Services should function for client IP based session affinity: udp`,
			`\[sig-network\] Services should be able to switch session affinity for NodePort service`,
			`\[sig-network\] Services should be able to switch session affinity for service with type clusterIP`,
			`\[sig-network\] Services should have session affinity work for NodePort service`,
			`\[sig-network\] Services should have session affinity work for service with type clusterIP`,
			`\[sig-network\] Services should have session affinity timeout work for NodePort service`,
			`\[sig-network\] Services should have session affinity timeout work for service with type clusterIP`,
			// https://github.com/kubernetes/kubernetes/pull/93597: upstream is flaky
			`\[sig-network\] Conntrack should be able to preserve UDP traffic when server pod cycles for a NodePort service`,

			// ovn-kubernetes does not support named ports
			`NetworkPolicy.*named port`,
		},
		"[Skipped:ibmcloud]": {
			// skip Gluster tests (not supported on ROKS worker nodes)
			// https://bugzilla.redhat.com/show_bug.cgi?id=1825009 - e2e: skip Glusterfs-related tests upstream for rhel7 worker nodes
			`\[Driver: gluster\]`,
			`GlusterFS`,
			`GlusterDynamicProvisioner`,

			// Nodes in ROKS have access to secrets in the cluster to handle encryption
			// https://bugzilla.redhat.com/show_bug.cgi?id=1825013 - ROKS: worker nodes have access to secrets in the cluster
			`\[sig-auth\] \[Feature:NodeAuthorizer\] Getting a non-existent configmap should exit with the Forbidden error, not a NotFound error`,
			`\[sig-auth\] \[Feature:NodeAuthorizer\] Getting a non-existent secret should exit with the Forbidden error, not a NotFound error`,
			`\[sig-auth\] \[Feature:NodeAuthorizer\] Getting a secret for a workload the node has access to should succeed`,
			`\[sig-auth\] \[Feature:NodeAuthorizer\] Getting an existing configmap should exit with the Forbidden error`,
			`\[sig-auth\] \[Feature:NodeAuthorizer\] Getting an existing secret should exit with the Forbidden error`,

			// Access to node external address is blocked from pods within a ROKS cluster by Calico
			// https://bugzilla.redhat.com/show_bug.cgi?id=1825016 - e2e: NodeAuthenticator tests use both external and internal addresses for node
			`\[sig-auth\] \[Feature:NodeAuthenticator\] The kubelet's main port 10250 should reject requests with no credentials`,
			`\[sig-auth\] \[Feature:NodeAuthenticator\] The kubelet can delegate ServiceAccount tokens to the API server`,

			// Calico is allowing the request to timeout instead of returning 'REFUSED'
			// https://bugzilla.redhat.com/show_bug.cgi?id=1825021 - ROKS: calico SDN results in a request timeout when accessing services with no endpoints
			`\[sig-network\] Services should be rejected when no endpoints exist`,

			// Mode returned by RHEL7 worker contains an extra character not expected by the test: dgtrwx vs dtrwx
			// https://bugzilla.redhat.com/show_bug.cgi?id=1825024 - e2e: Failing test - HostPath should give a volume the correct mode
			`\[sig-storage\] HostPath should give a volume the correct mode`,

			// Currently ibm-master-proxy-static and imbcloud-block-storage-plugin tolerate all taints
			// https://bugzilla.redhat.com/show_bug.cgi?id=1825027
			`\[Feature:Platform\] Managed cluster should ensure control plane operators do not make themselves unevictable`,
		},
	}

	// labelExcludes temporarily block tests out of a specific suite
	labelExcludes = map[string][]string{}
)
<commit_msg>Clarify the split between o/k and o/o e2e test annotations.<commit_after>package main

// Rules defined here are additive to the rules already defined for
// kube e2e tests in openshift/kubernetes. The kube rules are
// vendored via the following file:
//
//   vendor/k8s.io/kubernetes/openshift-hack/e2e/annotate/rules.go
//
// Rules that are needed to pass the upstream e2e test suite in a
// "default OCP CI" configuration (eg, AWS or GCP, openshift-sdn) must
// be added to openshift/kubernetes to allow CI to pass there, and
// then vendored back into origin. Rules that only apply to
// "non-default" configurations (other clouds, other network
// providers) should be added here.

var (
	testMaps = map[string][]string{
		// tests that require a local host
		"[Local]": {
			// Doesn't work on scaled up clusters
			`\[Feature:ImagePrune\]`,
		},
		// alpha features that are not gated
		"[Disabled:Alpha]": {},
		// tests for features that are not implemented in openshift
		"[Disabled:Unimplemented]": {},
		// tests that rely on special configuration that we do not yet support
		"[Disabled:SpecialConfig]": {},
		// tests that rely on special configuration that we do not yet support
		// tests that are known broken and need to be fixed upstream or in openshift
		// always add an issue here
		"[Disabled:Broken]": {
			`should idle the service and DeploymentConfig properly`,       // idling with a single service and DeploymentConfig
			`should answer endpoint and wildcard queries for the cluster`, // currently not supported by dns operator https://github.com/openshift/cluster-dns-operator/issues/43
		},
		// tests that may work, but we don't support them
		"[Disabled:Unsupported]": {},
		// tests too slow to be part of conformance
		"[Slow]": {},
		// tests that are known flaky
		"[Flaky]": {
			`openshift mongodb replication creating from a template`, // flaking on deployment
		},
		// tests that must be run without competition
		"[Serial]":        {},
		"[Skipped:azure]": {},
		"[Skipped:ovirt]": {
			// https://bugzilla.redhat.com/show_bug.cgi?id=1838751
			`\[sig-network\] Networking Granular Checks: Services should function for endpoint-Service`,
			`\[sig-network\] Networking Granular Checks: Services should function for node-Service`,
			`\[sig-network\] Networking Granular Checks: Services should function for pod-Service`,
		},
		"[Skipped:gce]": {},

		// tests that don't pass under openshift-sdn NetworkPolicy mode are specified
		// in the rules file in openshift/kubernetes, not here.

		// tests that don't pass under openshift-sdn multitenant mode
		"[Skipped:Network/OpenShiftSDN/Multitenant]": {
			`\[Feature:NetworkPolicy\]`, // not compatible with multitenant mode
			`\[sig-network\] Services should preserve source pod IP for traffic thru service cluster IP`, // known bug, not planned to be fixed
		},
		// tests that don't pass under OVN Kubernetes
		"[Skipped:Network/OVNKubernetes]": {
			// https://jira.coreos.com/browse/SDN-510: OVN-K doesn't support session affinity
			`\[sig-network\] Networking Granular Checks: Services should function for client IP based session affinity: http`,
			`\[sig-network\] Networking Granular Checks: Services should function for client IP based session affinity: udp`,
			`\[sig-network\] Services should be able to switch session affinity for NodePort service`,
			`\[sig-network\] Services should be able to switch session affinity for service with type clusterIP`,
			`\[sig-network\] Services should have session affinity work for NodePort service`,
			`\[sig-network\] Services should have session affinity work for service with type clusterIP`,
			`\[sig-network\] Services should have session affinity timeout work for NodePort service`,
			`\[sig-network\] Services should have session affinity timeout work for service with type clusterIP`,
			// https://github.com/kubernetes/kubernetes/pull/93597: upstream is flaky
			`\[sig-network\] Conntrack should be able to preserve UDP traffic when server pod cycles for a NodePort service`,

			// ovn-kubernetes does not support named ports
			`NetworkPolicy.*named port`,
		},
		"[Skipped:ibmcloud]": {
			// skip Gluster tests (not supported on ROKS worker nodes)
			// https://bugzilla.redhat.com/show_bug.cgi?id=1825009 - e2e: skip Glusterfs-related tests upstream for rhel7 worker nodes
			`\[Driver: gluster\]`,
			`GlusterFS`,
			`GlusterDynamicProvisioner`,

			// Nodes in ROKS have access to secrets in the cluster to handle encryption
			// https://bugzilla.redhat.com/show_bug.cgi?id=1825013 - ROKS: worker nodes have access to secrets in the cluster
			`\[sig-auth\] \[Feature:NodeAuthorizer\] Getting a non-existent configmap should exit with the Forbidden error, not a NotFound error`,
			`\[sig-auth\] \[Feature:NodeAuthorizer\] Getting a non-existent secret should exit with the Forbidden error, not a NotFound error`,
			`\[sig-auth\] \[Feature:NodeAuthorizer\] Getting a secret for a workload the node has access to should succeed`,
			`\[sig-auth\] \[Feature:NodeAuthorizer\] Getting an existing configmap should exit with the Forbidden error`,
			`\[sig-auth\] \[Feature:NodeAuthorizer\] Getting an existing secret should exit with the Forbidden error`,

			// Access to node external address is blocked from pods within a ROKS cluster by Calico
			// https://bugzilla.redhat.com/show_bug.cgi?id=1825016 - e2e: NodeAuthenticator tests use both external and internal addresses for node
			`\[sig-auth\] \[Feature:NodeAuthenticator\] The kubelet's main port 10250 should reject requests with no credentials`,
			`\[sig-auth\] \[Feature:NodeAuthenticator\] The kubelet can delegate ServiceAccount tokens to the API server`,

			// Calico is allowing the request to timeout instead of returning 'REFUSED'
			// https://bugzilla.redhat.com/show_bug.cgi?id=1825021 - ROKS: calico SDN results in a request timeout when accessing services with no endpoints
			`\[sig-network\] Services should be rejected when no endpoints exist`,

			// Mode returned by RHEL7 worker contains an extra character not expected by the test: dgtrwx vs dtrwx
			// https://bugzilla.redhat.com/show_bug.cgi?id=1825024 - e2e: Failing test - HostPath should give a volume the correct mode
			`\[sig-storage\] HostPath should give a volume the correct mode`,

			// Currently ibm-master-proxy-static and imbcloud-block-storage-plugin tolerate all taints
			// https://bugzilla.redhat.com/show_bug.cgi?id=1825027
			`\[Feature:Platform\] Managed cluster should ensure control plane operators do not make themselves unevictable`,
		},
	}

	// labelExcludes temporarily block tests out of a specific suite
	labelExcludes = map[string][]string{}
)
<|endoftext|>


<commit_before>package sdl

// #cgo linux freebsd darwin windows pkg-config: sdl2
// #cgo linux freebsd darwin windows LDFLAGS: -lSDL2_ttf -lSDL2_mixer -lSDL2_image
// #include "wrapper.h"
import "C"
import (
	"errors"
	"runtime"
	"unsafe"
)

func init() {
	initTTF()
	initMix()
	initImg()
}

// Point is a structure that defines a two demensional point.
// (https://wiki.libsdl.org/SDL_Point)
type point struct {
	X int32
	Y int32
}

func (p *point) cptr() *C.SDL_Point {
	return (*C.SDL_Point)(unsafe.Pointer(p))
}

// Rect is a structure that defines a rectangle, with the origin at the upper
// left.
// (https://wiki.libsdl.org/SDL_Rect)
type rect struct {
	X int32
	Y int32
	W int32
	H int32
}

func (a *rect) cptr() *C.SDL_Rect {
	return (*C.SDL_Rect)(unsafe.Pointer(a))
}

// Color defines a color using r, g, b, a values from 0-255
// (https://wiki.libsdl.org/SDL_Color)
type color struct {
	R uint8
	G uint8
	B uint8
	A uint8
}

func (a *color) cptr() *C.SDL_Color {
	return (*C.SDL_Color)(unsafe.Pointer(a))
}

// Surface SDL Surface (https://wiki.libsdl.org/SDL_Surface)
type surface C.SDL_Surface

func (a *surface) cptr() *C.SDL_Surface {
	return (*C.SDL_Surface)(unsafe.Pointer(a))
}

// mainThread manages the thread that SDL calls execute on
var mainThread = make(chan func())
var mainDone = make(chan struct{})

type callback func()

// lockMain calls runtime.LockOSThread on the calling thread.  This is intended to be the main thread since SDL on some platforms requires the main thread.  Use the MainThread channel to execute SDL calls.
// https://github.com/golang/go/wiki/LockOSThread
func lockMain(cb callback) {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	go cb()
	for {
		select {
		case f := <-mainThread:
			f()
		case <-mainDone:
			return
		}
	}
}

// GetTicks (https://wiki.libsdl.org/SDL_GetTicks)
func getTicks() uint32 {
	return uint32(C.SDL_GetTicks())
}

// Delay (https://wiki.libsdl.org/SDL_Delay)
func delay(ms uint32) {
	C.SDL_Delay(C.Uint32(ms))
}

// GetError (https://wiki.libsdl.org/SDL_GetError)
func getError() error {
	if err := C.SDL_GetError(); err != nil {
		return errors.New(C.GoString(err))
	}
	return nil
}

// getVersion gets the current SDL version (https://wiki.libsdl.org/SDL_GetVersion) return values are major, minor, patch
func getVersion() (int, int, int) {
	var version C.SDL_version
	C.SDL_GetVersion(&version)

	return int(version.major), int(version.minor), int(version.patch)
}

// ClearError (https://wiki.libsdl.org/SDL_ClearError)
func clearError() {
	C.SDL_ClearError()
}

// FreeSurface (https://wiki.libsdl.org/SDL_FreeSurface)
func freeSurface(s *surface) {
	C.SDL_FreeSurface(s.cptr())
}

func quit() {
	C.Mix_Quit()
	C.TTF_Quit()
	C.IMG_Quit()
	C.SDL_Quit()
}
<commit_msg>Added flags for the min macosx version flag<commit_after>package sdl

// #cgo darwin CFLAGS: -mmacosx-version-min=10.7
// #cgo linux freebsd darwin windows pkg-config: sdl2
// #cgo linux freebsd darwin windows LDFLAGS: -lSDL2_ttf -lSDL2_mixer -lSDL2_image -mmacosx-version-min=10.7
// #include "wrapper.h"
import "C"
import (
	"errors"
	"runtime"
	"unsafe"
)

func init() {
	initTTF()
	initMix()
	initImg()
}

// Point is a structure that defines a two demensional point.
// (https://wiki.libsdl.org/SDL_Point)
type point struct {
	X int32
	Y int32
}

func (p *point) cptr() *C.SDL_Point {
	return (*C.SDL_Point)(unsafe.Pointer(p))
}

// Rect is a structure that defines a rectangle, with the origin at the upper
// left.
// (https://wiki.libsdl.org/SDL_Rect)
type rect struct {
	X int32
	Y int32
	W int32
	H int32
}

func (a *rect) cptr() *C.SDL_Rect {
	return (*C.SDL_Rect)(unsafe.Pointer(a))
}

// Color defines a color using r, g, b, a values from 0-255
// (https://wiki.libsdl.org/SDL_Color)
type color struct {
	R uint8
	G uint8
	B uint8
	A uint8
}

func (a *color) cptr() *C.SDL_Color {
	return (*C.SDL_Color)(unsafe.Pointer(a))
}

// Surface SDL Surface (https://wiki.libsdl.org/SDL_Surface)
type surface C.SDL_Surface

func (a *surface) cptr() *C.SDL_Surface {
	return (*C.SDL_Surface)(unsafe.Pointer(a))
}

// mainThread manages the thread that SDL calls execute on
var mainThread = make(chan func())
var mainDone = make(chan struct{})

type callback func()

// lockMain calls runtime.LockOSThread on the calling thread.  This is intended to be the main thread since SDL on some platforms requires the main thread.  Use the MainThread channel to execute SDL calls.
// https://github.com/golang/go/wiki/LockOSThread
func lockMain(cb callback) {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	go cb()
	for {
		select {
		case f := <-mainThread:
			f()
		case <-mainDone:
			return
		}
	}
}

// GetTicks (https://wiki.libsdl.org/SDL_GetTicks)
func getTicks() uint32 {
	return uint32(C.SDL_GetTicks())
}

// Delay (https://wiki.libsdl.org/SDL_Delay)
func delay(ms uint32) {
	C.SDL_Delay(C.Uint32(ms))
}

// GetError (https://wiki.libsdl.org/SDL_GetError)
func getError() error {
	if err := C.SDL_GetError(); err != nil {
		return errors.New(C.GoString(err))
	}
	return nil
}

// getVersion gets the current SDL version (https://wiki.libsdl.org/SDL_GetVersion) return values are major, minor, patch
func getVersion() (int, int, int) {
	var version C.SDL_version
	C.SDL_GetVersion(&version)

	return int(version.major), int(version.minor), int(version.patch)
}

// ClearError (https://wiki.libsdl.org/SDL_ClearError)
func clearError() {
	C.SDL_ClearError()
}

// FreeSurface (https://wiki.libsdl.org/SDL_FreeSurface)
func freeSurface(s *surface) {
	C.SDL_FreeSurface(s.cptr())
}

func quit() {
	C.Mix_Quit()
	C.TTF_Quit()
	C.IMG_Quit()
	C.SDL_Quit()
}
<|endoftext|>


<commit_before>package main

import "os"
import "log"
import "fmt"
import "flag"
import "os/exec"
import "strings"
import "syscall"
import "net/url"
import "io/ioutil"

func main() {
	status := run()
	os.Exit(status)
}

func run() int {
	// Parse command line flags (we will forward these to the
	// underlying docker process
	flag.Parse()

	// Get the existing value for DOCKER_HOST
	dh := os.Getenv("DOCKER_HOST")

	// Check if it is empty
	if dh != "" {
		// ...and if it as URL
		dhurl, err := url.Parse(dh)
		// ...and if uses the ssh scheme (otherwise, we do absolutely nothing)
		if err == nil && dhurl.Scheme == "ssh" {
			hostname := strings.Split(dhurl.Host, ":")

			host := hostname[0]
			rport := "4243"
			if len(hostname) == 2 {
				host = hostname[0]
				rport = hostname[1]
			} else if len(hostname) > 2 {
				log.Fatalf("Unable to determine hostname and port from '%s'", dhurl.Host)
			}

			lport := "4243"
			if dhurl.Path != "" {
				lport = dhurl.Path[1:]
			}

			user := ""
			if dhurl.User != nil {
				user = dhurl.User.Username()
			}

			dest := host
			if user != "" {
				dest = fmt.Sprintf("%s@%s", user, host)
			}

			tmp, err := ioutil.TempFile("", "sdocker_")
			log.Printf("tmp = %s", tmp)
			if err != nil {
				log.Fatal(err.Error())
			}

			log.Printf("Tunnel from localhost:%s to %s:%s", lport, dest, rport)

			start := exec.Command("ssh", "-M", "-S", tmp.Name(),
				"-fnNT", "-L", fmt.Sprintf("%s:localhost:%s", lport, rport), dest)
			terr := start.Run()
			if terr != nil {
				log.Fatalf("Unable to open tunnel: %v", terr)
			}

			log.Printf("Tunnel started: %v", start)

			defer func() {
				// Close ssh tunnel
				stop := exec.Command("ssh", "-S", tmp.Name(),
					"-O", "exit", dest)
				// This exist with status code 255, but as far as I can tell,
				// that is normal.  So I ignore the error (nothing I could
				// do about it anyway really.
				stop.Run()

				// Remove temporary file
				os.Remove(tmp.Name())
			}()

			os.Setenv("DOCKER_HOST", fmt.Sprintf("tcp://localhost:%s", lport))
		}
	}
	cmd := exec.Command("docker", flag.Args()...)
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	cmd.Env = os.Environ()

	if err := cmd.Run(); err != nil {
		if exitError, ok := err.(*exec.ExitError); ok {
			waitStatus := exitError.Sys().(syscall.WaitStatus)
			return waitStatus.ExitStatus()
		}
	}
	waitStatus := cmd.ProcessState.Sys().(syscall.WaitStatus)
	return waitStatus.ExitStatus()
}
<commit_msg>OK, I think this includes everything<commit_after>package main

import "os"
import "log"
import "fmt"
import "flag"
import "os/exec"
import "strings"
import "syscall"
import "net/url"
import "io/ioutil"

func main() {
	// Run a nested docker command and return its exit status
	status := run()
	os.Exit(status)
}

func run() int {
	// Used to turn on debugging output
	verbose := false

	// Parse command line flags (we will forward these to the
	// underlying docker process)
	flag.Parse()

	// Get the existing value for DOCKER_HOST
	dh := os.Getenv("DOCKER_HOST")

	// Check if it is empty
	if dh != "" {
		// ...and if it as URL
		dhurl, err := url.Parse(dh)
		// ...and if uses the ssh scheme (otherwise, we do absolutely nothing)
		if err == nil && dhurl.Scheme == "ssh" {
			// Get hostname information and split it at the ":" if present
			hostname := strings.Split(dhurl.Host, ":")

			// Now extract out the remote host and remote port number
			host := hostname[0]
			rport := "4243" // This is the default if no remote port is specified

			if len(hostname) == 2 {
				host = hostname[0]
				rport = hostname[1]
			} else if len(hostname) > 2 {
				log.Fatalf("Unable to determine hostname and port from '%s'", dhurl.Host)
			}

			// Now assume the (same) default to open here on the localhost
			lport := "4243"
			if dhurl.Path != "" {
				// Unless there is a path component in the DOCKER_HOST.  In that
				// case, use the path as the port number.  Odd choice for a port
				// number, but nothing else seems better.
				lport = dhurl.Path[1:]
			}

			// Finally, see if they specified a user
			user := ""
			if dhurl.User != nil {
				user = dhurl.User.Username()
			}

			// Now, we need to start building args for the call to 'ssh'
			dest := host
			if user != "" {
				dest = fmt.Sprintf("%s@%s", user, host)
			}

			// Create a temporary file to use as the socket control file
			tmp, err := ioutil.TempFile("", "sdocker_")
			if err != nil {
				log.Fatal(err.Error())
			}

			if verbose {
				log.Printf("Tunnel from localhost:%s to %s:%s", lport, dest, rport)
			}

			// This command starts the socket
			start := exec.Command("ssh", "-M", "-S", tmp.Name(),
				"-fnNT", "-L", fmt.Sprintf("%s:localhost:%s", lport, rport), dest)
			terr := start.Run()

			// If it fails, we exit
			if terr != nil {
				log.Fatalf("Unable to open tunnel: %v", terr)
			}

			// This will clean everything up when we are done
			defer func() {
				// Close ssh tunnel
				stop := exec.Command("ssh", "-S", tmp.Name(),
					"-O", "exit", dest)
				// This exits with status code 255, but as far as I can tell,
				// that is normal.  So I ignore the error (nothing I could
				// do about it anyway really.
				stop.Run()

				// Remove temporary file
				os.Remove(tmp.Name())
				if verbose {
					log.Printf("Tunnel closed and control socket file removed")
				}
			}()

			// Now formulate the value of DOCKER_HOST to pass to our nested
			// invocation of docker
			ndh := fmt.Sprintf("tcp://localhost:%s", lport)
			if verbose {
				log.Printf("Running nested docker command with DOCKER_HOST='%s'", ndh)
			}

			// ...and assign it to the environment
			os.Setenv("DOCKER_HOST", ndh)
		}
	}

	// Here is where we call the nested docker command
	cmd := exec.Command("docker", flag.Args()...)

	// We completely connect stdin, stdout and stderr error so this
	// command looks just like the nested docker process
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout

	// We need to set the environment in case it has changed
	cmd.Env = os.Environ()

	// Now run the command and extract the exit status one way...
	if err := cmd.Run(); err != nil {
		if exitError, ok := err.(*exec.ExitError); ok {
			waitStatus := exitError.Sys().(syscall.WaitStatus)
			return waitStatus.ExitStatus()
		}
	}

	// ...or another.
	waitStatus := cmd.ProcessState.Sys().(syscall.WaitStatus)
	return waitStatus.ExitStatus()
}
<|endoftext|>


<commit_before>package booklit

import (
	"fmt"
	"regexp"
	"strings"

	"github.com/agext/levenshtein"
	"github.com/vito/booklit/ast"
)

type Section struct {
	Path string

	Title Content
	Body  Content

	PrimaryTag Tag
	Tags       []Tag

	Parent   *Section
	Children []*Section

	Style    string
	Partials Partials

	SplitSections        bool
	PreventSplitSections bool

	ResetDepth bool

	OmitChildrenFromTableOfContents bool

	Processor       SectionProcessor
	PluginFactories []PluginFactory
	Plugins         []Plugin

	Location       ast.Location
	InvokeLocation ast.Location
}

type Partials map[string]Content

type SectionProcessor interface {
	EvaluateFile(*Section, string, []PluginFactory) (*Section, error)
	EvaluateNode(*Section, ast.Node, []PluginFactory) (*Section, error)
}

type Tag struct {
	Name  string
	Title Content

	Section  *Section
	Location ast.Location
	Anchor   string

	Content Content
}

func (con *Section) String() string {
	return fmt.Sprintf("{section (%s): %s}", con.Path, con.Title)
}

func (con *Section) FilePath() string {
	if con.Path != "" {
		return con.Path
	}

	if con.Parent != nil {
		return con.Parent.FilePath()
	}

	return ""
}

func (con *Section) IsFlow() bool {
	if false {
		println("sup")
	}

	return false
}

func (con *Section) Visit(visitor Visitor) error {
	return visitor.VisitSection(con)
}

func (con *Section) SetTitle(title Content, loc ast.Location, tags ...string) {
	if len(tags) == 0 {
		tags = []string{con.defaultTag(title)}
	}

	con.Tags = []Tag{}
	for _, name := range tags {
		con.SetTag(name, title, loc)
	}

	con.Title = title
	con.PrimaryTag = con.Tags[0]
}

func (con *Section) SetTag(name string, title Content, loc ast.Location, optionalAnchor ...string) {
	anchor := ""
	if len(optionalAnchor) > 0 {
		anchor = optionalAnchor[0]
	}

	con.Tags = append(con.Tags, Tag{
		Section:  con,
		Location: loc,

		Name:   name,
		Title:  title,
		Anchor: anchor,
	})
}

func (con *Section) SetTagAnchored(name string, title Content, loc ast.Location, content Content, anchor string) {
	con.Tags = append(con.Tags, Tag{
		Section:  con,
		Location: loc,

		Name:   name,
		Title:  title,
		Anchor: anchor,

		Content: content,
	})
}

func (con *Section) Number() string {
	if con.Parent == nil {
		return ""
	}

	parentNumber := con.Parent.Number()
	selfIndex := 1
	for _, child := range con.Parent.Children {
		if child == con {
			break
		}

		selfIndex++
	}

	if parentNumber == "" {
		return fmt.Sprintf("%d", selfIndex)
	}

	return fmt.Sprintf("%s.%d", parentNumber, selfIndex)
}

func (con *Section) HasAnchors() bool {
	for _, tag := range con.Tags {
		if tag.Anchor != "" {
			return true
		}
	}

	if con.SplitSections {
		return false
	}

	for _, child := range con.Children {
		if child.HasAnchors() {
			return true
		}
	}

	return false
}

func (con *Section) AnchorTags() []Tag {
	tags := []Tag{}

	for _, tag := range con.Tags {
		if tag.Anchor == "" {
			continue
		}

		tags = append(tags, tag)
	}

	return tags
}

func (con *Section) Top() *Section {
	if con.Parent != nil {
		return con.Parent.Top()
	}

	return con
}

func (con *Section) Contains(sub *Section) bool {
	if con == sub {
		return true
	}

	for _, child := range con.Children {
		if child.Contains(sub) {
			return true
		}
	}

	return false
}

func (con *Section) IsOrHasChild(sub *Section) bool {
	if con == sub {
		return true
	}

	for _, child := range con.Children {
		if child == sub {
			return true
		}
	}

	return false
}

func (con *Section) Prev() *Section {
	if con.Parent == nil {
		return nil
	}

	var lastChild *Section
	for _, child := range con.Parent.Children {
		if lastChild != nil && child == con {
			return lastChild
		}

		lastChild = child
	}

	return con.Parent
}

func (con *Section) Next() *Section {
	if con.SplitSections {
		if len(con.Children) > 0 {
			return con.Children[0]
		}
	}

	return con.NextSibling()
}

func (con *Section) NextSibling() *Section {
	if con.Parent == nil {
		return nil
	}

	var sawSelf bool
	for _, child := range con.Parent.Children {
		if sawSelf {
			return child
		}

		if child == con {
			sawSelf = true
		}
	}

	return con.Parent.NextSibling()
}

func (con *Section) FindTag(tagName string) []Tag {
	return con.filterTags(true, nil, func(other string) bool {
		return other == tagName
	})
}

func (con *Section) SimilarTags(tagName string) []Tag {
	return con.filterTags(true, nil, func(other string) bool {
		return levenshtein.Match(tagName, other, nil) > 0.5
	})
}

func (con *Section) SetPartial(name string, value Content) {
	if con.Partials == nil {
		con.Partials = Partials{}
	}

	con.Partials[name] = value
}

func (con *Section) Partial(name string) Content {
	return con.Partials[name]
}

func (con *Section) UsePlugin(pf PluginFactory) {
	con.PluginFactories = append(con.PluginFactories, pf)
	con.Plugins = append(con.Plugins, pf(con))
}

func (con *Section) Depth() int {
	if con.Parent == nil {
		return 0
	}

	return con.Parent.Depth() + 1
}

func (con *Section) PageDepth() int {
	if con.Parent == nil || con.Parent.ResetDepth {
		return 0
	}

	return con.Parent.PageDepth() + 1
}

func (con *Section) SplitSectionsPrevented() bool {
	if con.PreventSplitSections {
		return true
	}

	if con.Parent != nil && con.Parent.SplitSectionsPrevented() {
		return true
	}

	return false
}

func (con *Section) filterTags(up bool, exclude *Section, match func(string) bool) []Tag {
	tags := []Tag{}

	if match(con.Title.String()) {
		tags = append(tags, con.PrimaryTag)
	}

	for _, t := range con.Tags {
		if match(t.Name) {
			tags = append(tags, t)
		}
	}

	for _, sub := range con.Children {
		if sub != exclude {
			tags = append(tags, sub.filterTags(false, nil, match)...)
		}
	}

	if up && con.Parent != nil {
		tags = append(tags, con.Parent.filterTags(true, con, match)...)
	}

	return tags
}

var whitespaceRegexp = regexp.MustCompile(`\s+`)
var specialCharsRegexp = regexp.MustCompile(`[^[:alnum:]_\-]`)

func (con *Section) defaultTag(title Content) string {
	return strings.ToLower(
		specialCharsRegexp.ReplaceAllString(
			whitespaceRegexp.ReplaceAllString(
				strings.Replace(
					StripAux(title).String(),
					" & ",
					" and ",
					-1,
				),
				"-",
			),
			"",
		),
	)
}
<commit_msg>Revert "one last attempt to get failed test coverage check"<commit_after>package booklit

import (
	"fmt"
	"regexp"
	"strings"

	"github.com/agext/levenshtein"
	"github.com/vito/booklit/ast"
)

type Section struct {
	Path string

	Title Content
	Body  Content

	PrimaryTag Tag
	Tags       []Tag

	Parent   *Section
	Children []*Section

	Style    string
	Partials Partials

	SplitSections        bool
	PreventSplitSections bool

	ResetDepth bool

	OmitChildrenFromTableOfContents bool

	Processor       SectionProcessor
	PluginFactories []PluginFactory
	Plugins         []Plugin

	Location       ast.Location
	InvokeLocation ast.Location
}

type Partials map[string]Content

type SectionProcessor interface {
	EvaluateFile(*Section, string, []PluginFactory) (*Section, error)
	EvaluateNode(*Section, ast.Node, []PluginFactory) (*Section, error)
}

type Tag struct {
	Name  string
	Title Content

	Section  *Section
	Location ast.Location
	Anchor   string

	Content Content
}

func (con *Section) String() string {
	return fmt.Sprintf("{section (%s): %s}", con.Path, con.Title)
}

func (con *Section) FilePath() string {
	if con.Path != "" {
		return con.Path
	}

	if con.Parent != nil {
		return con.Parent.FilePath()
	}

	return ""
}

func (con *Section) IsFlow() bool {
	return false
}

func (con *Section) Visit(visitor Visitor) error {
	return visitor.VisitSection(con)
}

func (con *Section) SetTitle(title Content, loc ast.Location, tags ...string) {
	if len(tags) == 0 {
		tags = []string{con.defaultTag(title)}
	}

	con.Tags = []Tag{}
	for _, name := range tags {
		con.SetTag(name, title, loc)
	}

	con.Title = title
	con.PrimaryTag = con.Tags[0]
}

func (con *Section) SetTag(name string, title Content, loc ast.Location, optionalAnchor ...string) {
	anchor := ""
	if len(optionalAnchor) > 0 {
		anchor = optionalAnchor[0]
	}

	con.Tags = append(con.Tags, Tag{
		Section:  con,
		Location: loc,

		Name:   name,
		Title:  title,
		Anchor: anchor,
	})
}

func (con *Section) SetTagAnchored(name string, title Content, loc ast.Location, content Content, anchor string) {
	con.Tags = append(con.Tags, Tag{
		Section:  con,
		Location: loc,

		Name:   name,
		Title:  title,
		Anchor: anchor,

		Content: content,
	})
}

func (con *Section) Number() string {
	if con.Parent == nil {
		return ""
	}

	parentNumber := con.Parent.Number()
	selfIndex := 1
	for _, child := range con.Parent.Children {
		if child == con {
			break
		}

		selfIndex++
	}

	if parentNumber == "" {
		return fmt.Sprintf("%d", selfIndex)
	}

	return fmt.Sprintf("%s.%d", parentNumber, selfIndex)
}

func (con *Section) HasAnchors() bool {
	for _, tag := range con.Tags {
		if tag.Anchor != "" {
			return true
		}
	}

	if con.SplitSections {
		return false
	}

	for _, child := range con.Children {
		if child.HasAnchors() {
			return true
		}
	}

	return false
}

func (con *Section) AnchorTags() []Tag {
	tags := []Tag{}

	for _, tag := range con.Tags {
		if tag.Anchor == "" {
			continue
		}

		tags = append(tags, tag)
	}

	return tags
}

func (con *Section) Top() *Section {
	if con.Parent != nil {
		return con.Parent.Top()
	}

	return con
}

func (con *Section) Contains(sub *Section) bool {
	if con == sub {
		return true
	}

	for _, child := range con.Children {
		if child.Contains(sub) {
			return true
		}
	}

	return false
}

func (con *Section) IsOrHasChild(sub *Section) bool {
	if con == sub {
		return true
	}

	for _, child := range con.Children {
		if child == sub {
			return true
		}
	}

	return false
}

func (con *Section) Prev() *Section {
	if con.Parent == nil {
		return nil
	}

	var lastChild *Section
	for _, child := range con.Parent.Children {
		if lastChild != nil && child == con {
			return lastChild
		}

		lastChild = child
	}

	return con.Parent
}

func (con *Section) Next() *Section {
	if con.SplitSections {
		if len(con.Children) > 0 {
			return con.Children[0]
		}
	}

	return con.NextSibling()
}

func (con *Section) NextSibling() *Section {
	if con.Parent == nil {
		return nil
	}

	var sawSelf bool
	for _, child := range con.Parent.Children {
		if sawSelf {
			return child
		}

		if child == con {
			sawSelf = true
		}
	}

	return con.Parent.NextSibling()
}

func (con *Section) FindTag(tagName string) []Tag {
	return con.filterTags(true, nil, func(other string) bool {
		return other == tagName
	})
}

func (con *Section) SimilarTags(tagName string) []Tag {
	return con.filterTags(true, nil, func(other string) bool {
		return levenshtein.Match(tagName, other, nil) > 0.5
	})
}

func (con *Section) SetPartial(name string, value Content) {
	if con.Partials == nil {
		con.Partials = Partials{}
	}

	con.Partials[name] = value
}

func (con *Section) Partial(name string) Content {
	return con.Partials[name]
}

func (con *Section) UsePlugin(pf PluginFactory) {
	con.PluginFactories = append(con.PluginFactories, pf)
	con.Plugins = append(con.Plugins, pf(con))
}

func (con *Section) Depth() int {
	if con.Parent == nil {
		return 0
	}

	return con.Parent.Depth() + 1
}

func (con *Section) PageDepth() int {
	if con.Parent == nil || con.Parent.ResetDepth {
		return 0
	}

	return con.Parent.PageDepth() + 1
}

func (con *Section) SplitSectionsPrevented() bool {
	if con.PreventSplitSections {
		return true
	}

	if con.Parent != nil && con.Parent.SplitSectionsPrevented() {
		return true
	}

	return false
}

func (con *Section) filterTags(up bool, exclude *Section, match func(string) bool) []Tag {
	tags := []Tag{}

	if match(con.Title.String()) {
		tags = append(tags, con.PrimaryTag)
	}

	for _, t := range con.Tags {
		if match(t.Name) {
			tags = append(tags, t)
		}
	}

	for _, sub := range con.Children {
		if sub != exclude {
			tags = append(tags, sub.filterTags(false, nil, match)...)
		}
	}

	if up && con.Parent != nil {
		tags = append(tags, con.Parent.filterTags(true, con, match)...)
	}

	return tags
}

var whitespaceRegexp = regexp.MustCompile(`\s+`)
var specialCharsRegexp = regexp.MustCompile(`[^[:alnum:]_\-]`)

func (con *Section) defaultTag(title Content) string {
	return strings.ToLower(
		specialCharsRegexp.ReplaceAllString(
			whitespaceRegexp.ReplaceAllString(
				strings.Replace(
					StripAux(title).String(),
					" & ",
					" and ",
					-1,
				),
				"-",
			),
			"",
		),
	)
}
<|endoftext|>


<commit_before>// Copyright 2015, Joe Tsai. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE.md file.

// Package meta implements the XFLATE meta encoding scheme.
//
// The XFLATE meta encoding is a method of encoding arbitrary data into one
// or more RFC 1951 compliant DEFLATE blocks. This encoding has the special
// property that when the blocks are decoded by a RFC 1951 compliant
// decompressor, they produce absolutely no output. However, when decoded with
// the XFLATE meta decoder, it losslessly produces the encoded input.
//
// The meta encoding works by encoding arbitrary data into the Huffman tree
// definition of dynamic DEFLATE blocks. These blocks have an empty data section
// and produce no output. Due to the Huffman definition overhead, the encoded
// output is usually larger than the input. However, for most input datasets,
// this encoding scheme is able to achieve an efficiency of at least 50%.
package meta

import (
	"fmt"

	"github.com/dsnet/compress/internal/errors"
	"github.com/dsnet/compress/internal/prefix"
)

// These are the magic values that begin every single meta block.
const (
	magicVals uint32 = 0x05860004
	magicMask uint32 = 0xfffe3fc6
)

// ReverseSearch searches for a meta header in reverse. This returns the last
// index where the header was found. If not found, it returns -1.
func ReverseSearch(data []byte) int {
	var magic uint32
	for i := len(data) - 1; i >= 0; i-- {
		magic = (magic << 8) | uint32(data[i])
		if magic&magicMask == magicVals {
			return i
		}
	}
	return -1
}

const (
	maxSyms    = 257 // Maximum number of literal codes (with EOM marker)
	minHuffLen = 1   // Minimum number of bits for each Huffman code
	maxHuffLen = 7   // Maximum number of bits for each Huffman code
	minRepLast = 3   // Minimum number of repeated codes (clen: 16)
	maxRepLast = 6   // Maximum number of repeated codes (clen: 16)
	minRepZero = 11  // Minimum number of repeated zeros (clen: 18)
	maxRepZero = 138 // Maximum number of repeated zeros (clen: 18)
)

// These are some constants regarding the theoretical and practical limits for
// the meta encoding of a single block.
const (
	// MinRawBytes and MaxRawBytes are the theoretical minimum and maximum
	// number of bytes a block can encode.
	MinRawBytes = 0
	MaxRawBytes = 31

	// MinEncBytes and MaxEncBytes are the theoretical minimum and maximum
	// number of bytes an encoded block will occupy.
	MinEncBytes = 12
	MaxEncBytes = 64

	// EnsureRawBytes is the maximum number of bytes that a single block is
	// ensured to encode (computed using brute force).
	EnsureRawBytes = 22
)

// FinalMode controls or indicates which final bits are set in the last block
// in the meta stream. In the meta encoding, there are 2 final bits:
//
//	Stream: This is the final bit from DEFLATE (as defined in RFC 1951).
//	and indicates that the entire compression stream has come to an end.
//	This bit indicate absolute termination of the stream.
//
//	Meta: This final bit indicates that the current sequence of meta blocks has
//	terminated. The decoded data from those blocks form a single stream.
//	This bit is used as a form of message framing for the meta encoding format.
//
// It invalid for the stream final bit to be set, while the meta final bit is
// not set. All other combinations are legal.
type FinalMode int

const (
	// FinalNil has neither the stream nor meta final bits set.
	FinalNil FinalMode = iota

	// FinalMeta has the final bit set, but not stream final bit.
	FinalMeta

	// FinalStream has both the meta and stream final bits set.
	FinalStream
)

// The Huffman encoding used by the XFLATE meta encoding uses a partially
// pre-determined HCLEN table. The symbols are 0, 16, 18, and another symbol
// between minHuffLen and maxHuffLen, inclusively. The 0 symbol represents a
// logical zero in the meta encoding, and the symbol between minHuffLen and
// maxHuffLen represents a logical one. Symbols 16 and 18 are used to provide a
// primitive form of run-length encoding. The codes that these symbols map to
// are fixed and are shown below.
//
//	Code      Symbol
//	0    <=>  0                      (symZero)
//	10   <=>  minHuffLen..maxHuffLen (symOne)
//	110  <=>  16                     (symRepLast)
//	111  <=>  18                     (symRepZero)
//
// The symZero symbol occupies 1 bit since it is the most commonly needed bit,
// while symOne occupies 2 bits. Thus, it is cheaper to encode logical zeros
// than it is to encode logical ones. The invert bit in the meta encoding takes
// advantage of this fact and allows all data bits to be inverted so that the
// number zero bits is greater than the number of one bits.
const (
	symZero    = iota // Symbol to encode a input zero (clen: 0)
	symOne            // Symbol to encode a input one  (clen: minHuffLen..maxHuffLen)
	symRepLast        // Symbol to repeat last symbol  (clen: 16)
	symRepZero        // Symbol to repeat zero symbol  (clen: 18)
)

var encHuff, decHuff = func() (enc prefix.Encoder, dec prefix.Decoder) {
	codes := [4]prefix.PrefixCode{
		{Sym: symZero, Len: 1},
		{Sym: symOne, Len: 2},
		{Sym: symRepLast, Len: 3},
		{Sym: symRepZero, Len: 3},
	}
	prefix.GeneratePrefixes(codes[:])
	enc.Init(codes[:])
	dec.Init(codes[:])
	return
}()

func errorf(c int, f string, a ...interface{}) error {
	return errors.Error{Code: c, Pkg: "meta", Msg: fmt.Sprintf(f, a...)}
}

var (
	errCorrupted = errorf(errors.Corrupted, "")
	errClosed    = errorf(errors.Closed, "")
)

// oneBitsLUT reports the number of set bits in the input byte.
var oneBitsLUT = func() (lut [256]byte) {
	for i := range lut[:] {
		for b := byte(i); b > 0; b >>= 1 {
			lut[i] += b & 1
		}
	}
	return
}()

// numBits counts the number of zero and one bits in the byte.
func numBits(b byte) (zeros, ones int) {
	ones = int(oneBitsLUT[b])
	zeros = 8 - ones
	return
}

// numPads computes number of bits needed to pad n-bits to a byte alignment.
func numPads(n uint) uint {
	return -n & 7
}

// btoi converts a bool to a integer 0 or 1.
func btoi(b bool) int {
	if b {
		return 1
	}
	return 0
}
<commit_msg>xflate/internal/meta: minor documentation changes<commit_after>// Copyright 2015, Joe Tsai. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE.md file.

// Package meta implements the XFLATE meta encoding scheme.
//
// The XFLATE meta encoding is a method of encoding arbitrary data into one
// or more RFC 1951 compliant DEFLATE blocks. This encoding has the special
// property that when the blocks are decoded by a RFC 1951 compliant
// decompressor, they produce absolutely no output. However, when decoded with
// the XFLATE meta decoder, it losslessly produces the original input.
//
// The meta encoding works by encoding arbitrary data into the Huffman tree
// definition of dynamic DEFLATE blocks. These blocks have an empty data section
// and produce no output. Due to the Huffman definition overhead, the encoded
// output is usually larger than the input. However, for most input datasets,
// this encoding scheme is able to achieve an efficiency of at least 50%.
package meta

import (
	"fmt"

	"github.com/dsnet/compress/internal/errors"
	"github.com/dsnet/compress/internal/prefix"
)

// These are the magic values that begin every single meta block.
const (
	magicVals uint32 = 0x05860004
	magicMask uint32 = 0xfffe3fc6
)

// ReverseSearch searches for a meta header in reverse. This returns the last
// index where the header was found. If not found, it returns -1.
func ReverseSearch(data []byte) int {
	var magic uint32
	for i := len(data) - 1; i >= 0; i-- {
		magic = (magic << 8) | uint32(data[i])
		if magic&magicMask == magicVals {
			return i
		}
	}
	return -1
}

const (
	maxSyms    = 257 // Maximum number of literal codes (with EOM marker)
	minHuffLen = 1   // Minimum number of bits for each Huffman code
	maxHuffLen = 7   // Maximum number of bits for each Huffman code
	minRepLast = 3   // Minimum number of repeated codes (clen: 16)
	maxRepLast = 6   // Maximum number of repeated codes (clen: 16)
	minRepZero = 11  // Minimum number of repeated zeros (clen: 18)
	maxRepZero = 138 // Maximum number of repeated zeros (clen: 18)
)

// These are some constants regarding the theoretical and practical limits for
// the meta encoding of a single block.
const (
	// MinRawBytes and MaxRawBytes are the theoretical minimum and maximum
	// number of bytes a block can encode.
	MinRawBytes = 0
	MaxRawBytes = 31

	// MinEncBytes and MaxEncBytes are the theoretical minimum and maximum
	// number of bytes an encoded block will occupy.
	MinEncBytes = 12
	MaxEncBytes = 64

	// EnsureRawBytes is the maximum number of bytes that a single block is
	// ensured to encode (computed using brute force).
	EnsureRawBytes = 22
)

// FinalMode controls or indicates which final bits are set in the last block
// in the meta stream. In the meta encoding, there are 2 final bits:
//
//	Stream: This is the final bit from DEFLATE (as defined in RFC 1951).
//	and indicates that the entire compression stream has come to an end.
//	This bit indicate absolute termination of the stream.
//
//	Meta: This final bit indicates that the current sequence of meta blocks has
//	terminated. The decoded data from those blocks form a meta substream.
//	This bit is used as a form of message framing for the meta encoding format.
//
// It invalid for the stream final bit to be set, while the meta final bit is
// not set. All other combinations are legal.
type FinalMode int

const (
	// FinalNil has neither the stream nor meta final bits set.
	FinalNil FinalMode = iota

	// FinalMeta has the final bit set, but not stream final bit.
	FinalMeta

	// FinalStream has both the meta and stream final bits set.
	FinalStream
)

// The Huffman encoding used by the XFLATE meta encoding uses a partially
// pre-determined HCLEN table. The symbols are 0, 16, 18, and another symbol
// between minHuffLen and maxHuffLen, inclusively. The 0 symbol represents a
// logical zero in the meta encoding, and the symbol between minHuffLen and
// maxHuffLen represents a logical one. Symbols 16 and 18 are used to provide a
// primitive form of run-length encoding. The codes that these symbols map to
// are fixed and are shown below.
//
//	Code      Symbol
//	0    <=>  0                      (symZero)
//	10   <=>  minHuffLen..maxHuffLen (symOne)
//	110  <=>  16                     (symRepLast)
//	111  <=>  18                     (symRepZero)
//
// The symZero symbol occupies 1 bit since it is the most commonly needed bit,
// while symOne occupies 2 bits. Thus, it is cheaper to encode logical zeros
// than it is to encode logical ones. The invert bit in the meta encoding takes
// advantage of this fact and allows all data bits to be inverted so that the
// number zero bits is greater than the number of one bits.
const (
	symZero    = iota // Symbol to encode a input zero (clen: 0)
	symOne            // Symbol to encode a input one  (clen: minHuffLen..maxHuffLen)
	symRepLast        // Symbol to repeat last symbol  (clen: 16)
	symRepZero        // Symbol to repeat zero symbol  (clen: 18)
)

var encHuff, decHuff = func() (enc prefix.Encoder, dec prefix.Decoder) {
	codes := [4]prefix.PrefixCode{
		{Sym: symZero, Len: 1},
		{Sym: symOne, Len: 2},
		{Sym: symRepLast, Len: 3},
		{Sym: symRepZero, Len: 3},
	}
	prefix.GeneratePrefixes(codes[:])
	enc.Init(codes[:])
	dec.Init(codes[:])
	return
}()

func errorf(c int, f string, a ...interface{}) error {
	return errors.Error{Code: c, Pkg: "meta", Msg: fmt.Sprintf(f, a...)}
}

var (
	errCorrupted = errorf(errors.Corrupted, "")
	errClosed    = errorf(errors.Closed, "")
)

// oneBitsLUT reports the number of set bits in the input byte.
var oneBitsLUT = func() (lut [256]byte) {
	for i := range lut[:] {
		for b := byte(i); b > 0; b >>= 1 {
			lut[i] += b & 1
		}
	}
	return
}()

// numBits counts the number of zero and one bits in the byte.
func numBits(b byte) (zeros, ones int) {
	ones = int(oneBitsLUT[b])
	zeros = 8 - ones
	return
}

// numPads computes number of bits needed to pad n-bits to a byte alignment.
func numPads(n uint) uint {
	return -n & 7
}

// btoi converts a bool to a integer 0 or 1.
func btoi(b bool) int {
	if b {
		return 1
	}
	return 0
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"sort"
	"strings"
	"time"

	"github.com/Sirupsen/logrus"

	"github.com/NetSys/quilt/stitch"
)

const (
	testRoot           = "/tests"
	quiltPath          = "/.quilt"
	infrastructureSpec = quiltPath + "/github.com/NetSys/quilt/quilt-tester/" +
		"config/infrastructure-runner.js"
	slackEndpoint = "https://hooks.slack.com/services/T04Q3TL41/B0M25TWP5/" +
		"soKJeP5HbWcjkUJzEHh7ylYm"
	testerImport = "github.com/NetSys/quilt"
	webRoot      = "/var/www/quilt-tester"
)

// The global logger for this CI run.
var log logger

func main() {
	myIP := os.Getenv("MY_IP")
	if myIP == "" {
		logrus.Error("IP of tester machine unknown.")
		os.Exit(1)
	}

	var err error
	if log, err = newLogger(myIP); err != nil {
		logrus.WithError(err).Error("Failed to create logger.")
		os.Exit(1)
	}

	tester, err := newTester(testRoot, myIP)
	if err != nil {
		logrus.WithError(err).Error("Failed to create tester instance.")
		os.Exit(1)
	}

	if err := tester.run(); err != nil {
		logrus.WithError(err).Error("Test execution failed.")
		os.Exit(1)
	}
}

type tester struct {
	preserveFailed bool

	testSuites  []*testSuite
	initialized bool
	ip          string
}

func newTester(testRoot, myIP string) (tester, error) {
	t := tester{
		ip: myIP,
	}

	flag.BoolVar(&t.preserveFailed, "preserve-failed", false,
		"don't destroy machines on failed tests")
	flag.Parse()

	err := t.generateTestSuites(testRoot)
	if err != nil {
		return tester{}, err
	}

	return t, nil
}

func (t *tester) generateTestSuites(testRoot string) error {
	namespace := t.namespace()
	l := log.testerLogger

	// First, we need to ls the testRoot, and find all of the folders. Then we can
	// generate a testSuite for each folder.
	testSuiteFolders, err := filepath.Glob(filepath.Join(testRoot, "*"))
	if err != nil {
		l.infoln("Could not access test suite folders")
		l.errorln(err.Error())
		return err
	}

	sort.Sort(byPriorityPrefix(testSuiteFolders))
	for _, testSuiteFolder := range testSuiteFolders {
		files, err := ioutil.ReadDir(testSuiteFolder)
		if err != nil {
			l.infoln(fmt.Sprintf(
				"Error reading test suite %s", testSuiteFolder))
			l.errorln(err.Error())
			return err
		}

		var spec string
		var tests []string
		for _, file := range files {
			path := filepath.Join(testSuiteFolder, file.Name())
			switch {
			case strings.HasSuffix(file.Name(), ".js"):
				spec = path
				if err := updateNamespace(spec, namespace); err != nil {
					l.infoln(fmt.Sprintf(
						"Error updating namespace for %s.", spec))
					l.errorln(err.Error())
					return err
				}
			// If the file is executable by everyone, and is not a directory.
			case (file.Mode()&1 != 0) && !file.IsDir():
				tests = append(tests, path)
			}
		}
		newSuite := testSuite{
			name:  filepath.Base(testSuiteFolder),
			spec:  spec,
			tests: tests,
		}
		t.testSuites = append(t.testSuites, &newSuite)
	}

	return nil
}

func (t tester) run() error {
	defer func() {
		failed := false
		for _, suite := range t.testSuites {
			if suite.failed != 0 {
				failed = true
				break
			}
		}

		if failed && t.preserveFailed {
			return
		}

		cleanupMachines(t.namespace())
	}()

	if err := t.setup(); err != nil {
		log.testerLogger.errorln("Unable to setup the tests, bailing.")
		t.slack(false)
		return err
	}

	err := t.runTestSuites()
	t.slack(true)
	return err
}

func (t *tester) setup() error {
	namespace := t.namespace()
	l := log.testerLogger

	l.infoln("Starting the Quilt daemon.")
	go runQuiltDaemon()

	// Get our specs
	os.Setenv(stitch.QuiltPathKey, quiltPath)
	l.infoln(fmt.Sprintf("Downloading %s into %s", testerImport, quiltPath))
	_, _, err := downloadSpecs(testerImport)
	if err != nil {
		l.infoln(fmt.Sprintf("Could not download %s", testerImport))
		l.errorln(err.Error())
		return err
	}

	// Do a preliminary quilt stop.
	l.infoln(fmt.Sprintf("Preliminary `quilt stop %s`", namespace))
	_, _, err = stop(namespace)
	if err != nil {
		l.infoln(fmt.Sprintf("Error stopping: %s", err.Error()))
		return err
	}

	// Setup infrastructure.
	l.infoln("Booting the machines the test suites will run on, and waiting " +
		"for them to connect back.")
	l.infoln("Begin " + infrastructureSpec)
	if err := updateNamespace(infrastructureSpec, namespace); err != nil {
		l.infoln(fmt.Sprintf("Error updating namespace for %s.",
			infrastructureSpec))
		l.errorln(err.Error())
		return err
	}
	contents, _ := fileContents(infrastructureSpec)
	l.println(contents)
	l.infoln("End " + infrastructureSpec)

	_, _, err = runSpecUntilConnected(infrastructureSpec)
	if err != nil {
		l.infoln("Failed to setup infrastructure")
		l.errorln(err.Error())
		return err
	}

	l.infoln("Booted Quilt")
	l.infoln("Machines")
	machines, _ := queryMachines()
	l.println(fmt.Sprintf("%v", machines))

	return nil
}

func (t tester) runTestSuites() error {
	l := log.testerLogger

	l.infoln("Wait 5 minutes for containers to start up")
	time.Sleep(5 * time.Minute)

	var err error
	for _, suite := range t.testSuites {
		if e := suite.run(); e != nil && err == nil {
			err = e
		}
	}
	return err
}

func (t tester) namespace() string {
	sanitizedIP := strings.Replace(t.ip, ".", "-", -1)
	return fmt.Sprintf("tester-%s", sanitizedIP)
}

func toPost(failed bool, pretext string, text string) slackPost {
	iconemoji := ":confetti_ball:"
	color := "#009900" // Green
	if failed {
		iconemoji = ":oncoming_police_car:"
		color = "#D00000" // Red
	}

	return slackPost{
		Channel:   os.Getenv("SLACK_CHANNEL"),
		Color:     color,
		Pretext:   pretext,
		Username:  "quilt-bot",
		Iconemoji: iconemoji,
		Fields: []message{
			{
				Title: "Continuous Integration",
				Short: false,
				Value: text,
			},
		},
	}
}

func (t tester) slack(initialized bool) {
	log.testerLogger.infoln("Posting to slack.")

	var suitesPassed []string
	var suitesFailed []string
	for _, suite := range t.testSuites {
		if suite.failed != 0 {
			suitesFailed = append(suitesFailed, suite.name)
		} else {
			suitesPassed = append(suitesPassed, suite.name)
		}
	}

	var failed bool
	var pretext, text string
	if !initialized {
		failed = true
		text = "Didn't run tests"
		pretext = fmt.Sprintf("<!channel> Initialization <%s|failed>.",
			log.url())
	} else {
		// The tests passed.
		failed = false
		pretext = fmt.Sprintf("All tests <%s|passed>!", log.url())
		text = fmt.Sprintf("Test Suites Passed: %s",
			strings.Join(suitesPassed, ", "))

		// Some tests failed.
		if len(suitesFailed) > 0 {
			failed = true
			text += fmt.Sprintf("\nTest Suites Failed: %s",
				strings.Join(suitesFailed, ", "))
			pretext = fmt.Sprintf("<!channel> Some tests <%s|failed>",
				log.url())
		}
	}

	err := slack(slackEndpoint, toPost(failed, pretext, text))
	if err != nil {
		l := log.testerLogger
		l.infoln("Error posting to Slack.")
		l.errorln(err.Error())
	}
}

type testSuite struct {
	name   string
	spec   string
	tests  []string
	passed int
	failed int
}

func (ts *testSuite) run() error {
	l := log.testerLogger

	l.infoln(fmt.Sprintf("Test Suite: %s", ts.name))
	l.infoln("Start " + ts.name + ".js")
	contents, _ := fileContents(ts.spec)
	l.println(contents)
	l.infoln("End " + ts.name + ".js")

	runSpec(ts.spec)

	// Wait for the containers to start
	l.infoln("Waiting 5 minutes for containers to start up")
	time.Sleep(5 * time.Minute)
	l.infoln("Starting Tests")
	var err error
	for _, test := range ts.tests {
		l.println(".. " + filepath.Base(test))
		if e := runTest(test); e == nil {
			l.println(".... Passed")
			ts.passed++
		} else {
			l.println(".... Failed")
			ts.failed++

			if err == nil {
				err = e
			}
		}
	}

	l.infoln("Finished Tests")
	l.infoln(fmt.Sprintf("Finished Test Suite: %s", ts.name))

	return err
}

func runTest(testPath string) error {
	testPassed := true

	output, err := exec.Command(testPath).CombinedOutput()
	if err != nil || !strings.Contains(string(output), "PASSED") {
		testPassed = false
	}

	_, testName := filepath.Split(testPath)
	l := log.testLogger(testPassed, testName)
	if !testPassed {
		l.infoln("Failed!")
	}

	if contents, err := fileContents(testPath + ".go"); err == nil {
		l.infoln("Begin test source")
		l.println(contents)
		l.infoln("End test source")
	} else {
		l.infoln(fmt.Sprintf("Could not read test source for %s", testName))
		l.errorln(err.Error())
	}

	l.infoln("Begin test output")
	l.println(string(output))
	l.infoln("End test output")

	if !testPassed {
		return fmt.Errorf("test failed: %s", testName)
	}
	return nil
}
<commit_msg>quilt-tester: Preserve machines that failed to initialize<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"sort"
	"strings"
	"time"

	"github.com/Sirupsen/logrus"

	"github.com/NetSys/quilt/stitch"
)

const (
	testRoot           = "/tests"
	quiltPath          = "/.quilt"
	infrastructureSpec = quiltPath + "/github.com/NetSys/quilt/quilt-tester/" +
		"config/infrastructure-runner.js"
	slackEndpoint = "https://hooks.slack.com/services/T04Q3TL41/B0M25TWP5/" +
		"soKJeP5HbWcjkUJzEHh7ylYm"
	testerImport = "github.com/NetSys/quilt"
	webRoot      = "/var/www/quilt-tester"
)

// The global logger for this CI run.
var log logger

func main() {
	myIP := os.Getenv("MY_IP")
	if myIP == "" {
		logrus.Error("IP of tester machine unknown.")
		os.Exit(1)
	}

	var err error
	if log, err = newLogger(myIP); err != nil {
		logrus.WithError(err).Error("Failed to create logger.")
		os.Exit(1)
	}

	tester, err := newTester(testRoot, myIP)
	if err != nil {
		logrus.WithError(err).Error("Failed to create tester instance.")
		os.Exit(1)
	}

	if err := tester.run(); err != nil {
		logrus.WithError(err).Error("Test execution failed.")
		os.Exit(1)
	}
}

type tester struct {
	preserveFailed bool

	testSuites  []*testSuite
	initialized bool
	ip          string
}

func newTester(testRoot, myIP string) (tester, error) {
	t := tester{
		ip: myIP,
	}

	flag.BoolVar(&t.preserveFailed, "preserve-failed", false,
		"don't destroy machines on failed tests")
	flag.Parse()

	err := t.generateTestSuites(testRoot)
	if err != nil {
		return tester{}, err
	}

	return t, nil
}

func (t *tester) generateTestSuites(testRoot string) error {
	namespace := t.namespace()
	l := log.testerLogger

	// First, we need to ls the testRoot, and find all of the folders. Then we can
	// generate a testSuite for each folder.
	testSuiteFolders, err := filepath.Glob(filepath.Join(testRoot, "*"))
	if err != nil {
		l.infoln("Could not access test suite folders")
		l.errorln(err.Error())
		return err
	}

	sort.Sort(byPriorityPrefix(testSuiteFolders))
	for _, testSuiteFolder := range testSuiteFolders {
		files, err := ioutil.ReadDir(testSuiteFolder)
		if err != nil {
			l.infoln(fmt.Sprintf(
				"Error reading test suite %s", testSuiteFolder))
			l.errorln(err.Error())
			return err
		}

		var spec string
		var tests []string
		for _, file := range files {
			path := filepath.Join(testSuiteFolder, file.Name())
			switch {
			case strings.HasSuffix(file.Name(), ".js"):
				spec = path
				if err := updateNamespace(spec, namespace); err != nil {
					l.infoln(fmt.Sprintf(
						"Error updating namespace for %s.", spec))
					l.errorln(err.Error())
					return err
				}
			// If the file is executable by everyone, and is not a directory.
			case (file.Mode()&1 != 0) && !file.IsDir():
				tests = append(tests, path)
			}
		}
		newSuite := testSuite{
			name:  filepath.Base(testSuiteFolder),
			spec:  spec,
			tests: tests,
		}
		t.testSuites = append(t.testSuites, &newSuite)
	}

	return nil
}

func (t tester) run() error {
	defer func() {
		failed := false
		for _, suite := range t.testSuites {
			if suite.failed != 0 {
				failed = true
				break
			}
		}

		if failed && t.preserveFailed {
			return
		}

		cleanupMachines(t.namespace())
	}()

	if err := t.setup(); err != nil {
		log.testerLogger.errorln("Unable to setup the tests, bailing.")
		// All suites failed if we didn't run them.
		for _, suite := range t.testSuites {
			suite.failed = 1
		}
		t.slack(false)
		return err
	}

	err := t.runTestSuites()
	t.slack(true)
	return err
}

func (t *tester) setup() error {
	namespace := t.namespace()
	l := log.testerLogger

	l.infoln("Starting the Quilt daemon.")
	go runQuiltDaemon()

	// Get our specs
	os.Setenv(stitch.QuiltPathKey, quiltPath)
	l.infoln(fmt.Sprintf("Downloading %s into %s", testerImport, quiltPath))
	_, _, err := downloadSpecs(testerImport)
	if err != nil {
		l.infoln(fmt.Sprintf("Could not download %s", testerImport))
		l.errorln(err.Error())
		return err
	}

	// Do a preliminary quilt stop.
	l.infoln(fmt.Sprintf("Preliminary `quilt stop %s`", namespace))
	_, _, err = stop(namespace)
	if err != nil {
		l.infoln(fmt.Sprintf("Error stopping: %s", err.Error()))
		return err
	}

	// Setup infrastructure.
	l.infoln("Booting the machines the test suites will run on, and waiting " +
		"for them to connect back.")
	l.infoln("Begin " + infrastructureSpec)
	if err := updateNamespace(infrastructureSpec, namespace); err != nil {
		l.infoln(fmt.Sprintf("Error updating namespace for %s.",
			infrastructureSpec))
		l.errorln(err.Error())
		return err
	}
	contents, _ := fileContents(infrastructureSpec)
	l.println(contents)
	l.infoln("End " + infrastructureSpec)

	_, _, err = runSpecUntilConnected(infrastructureSpec)
	if err != nil {
		l.infoln("Failed to setup infrastructure")
		l.errorln(err.Error())
		return err
	}

	l.infoln("Booted Quilt")
	l.infoln("Machines")
	machines, _ := queryMachines()
	l.println(fmt.Sprintf("%v", machines))

	return nil
}

func (t tester) runTestSuites() error {
	l := log.testerLogger

	l.infoln("Wait 5 minutes for containers to start up")
	time.Sleep(5 * time.Minute)

	var err error
	for _, suite := range t.testSuites {
		if e := suite.run(); e != nil && err == nil {
			err = e
		}
	}
	return err
}

func (t tester) namespace() string {
	sanitizedIP := strings.Replace(t.ip, ".", "-", -1)
	return fmt.Sprintf("tester-%s", sanitizedIP)
}

func toPost(failed bool, pretext string, text string) slackPost {
	iconemoji := ":confetti_ball:"
	color := "#009900" // Green
	if failed {
		iconemoji = ":oncoming_police_car:"
		color = "#D00000" // Red
	}

	return slackPost{
		Channel:   os.Getenv("SLACK_CHANNEL"),
		Color:     color,
		Pretext:   pretext,
		Username:  "quilt-bot",
		Iconemoji: iconemoji,
		Fields: []message{
			{
				Title: "Continuous Integration",
				Short: false,
				Value: text,
			},
		},
	}
}

func (t tester) slack(initialized bool) {
	log.testerLogger.infoln("Posting to slack.")

	var suitesPassed []string
	var suitesFailed []string
	for _, suite := range t.testSuites {
		if suite.failed != 0 {
			suitesFailed = append(suitesFailed, suite.name)
		} else {
			suitesPassed = append(suitesPassed, suite.name)
		}
	}

	var failed bool
	var pretext, text string
	if !initialized {
		failed = true
		text = "Didn't run tests"
		pretext = fmt.Sprintf("<!channel> Initialization <%s|failed>.",
			log.url())
	} else {
		// The tests passed.
		failed = false
		pretext = fmt.Sprintf("All tests <%s|passed>!", log.url())
		text = fmt.Sprintf("Test Suites Passed: %s",
			strings.Join(suitesPassed, ", "))

		// Some tests failed.
		if len(suitesFailed) > 0 {
			failed = true
			text += fmt.Sprintf("\nTest Suites Failed: %s",
				strings.Join(suitesFailed, ", "))
			pretext = fmt.Sprintf("<!channel> Some tests <%s|failed>",
				log.url())
		}
	}

	err := slack(slackEndpoint, toPost(failed, pretext, text))
	if err != nil {
		l := log.testerLogger
		l.infoln("Error posting to Slack.")
		l.errorln(err.Error())
	}
}

type testSuite struct {
	name   string
	spec   string
	tests  []string
	passed int
	failed int
}

func (ts *testSuite) run() error {
	l := log.testerLogger

	l.infoln(fmt.Sprintf("Test Suite: %s", ts.name))
	l.infoln("Start " + ts.name + ".js")
	contents, _ := fileContents(ts.spec)
	l.println(contents)
	l.infoln("End " + ts.name + ".js")

	runSpec(ts.spec)

	// Wait for the containers to start
	l.infoln("Waiting 5 minutes for containers to start up")
	time.Sleep(5 * time.Minute)
	l.infoln("Starting Tests")
	var err error
	for _, test := range ts.tests {
		l.println(".. " + filepath.Base(test))
		if e := runTest(test); e == nil {
			l.println(".... Passed")
			ts.passed++
		} else {
			l.println(".... Failed")
			ts.failed++

			if err == nil {
				err = e
			}
		}
	}

	l.infoln("Finished Tests")
	l.infoln(fmt.Sprintf("Finished Test Suite: %s", ts.name))

	return err
}

func runTest(testPath string) error {
	testPassed := true

	output, err := exec.Command(testPath).CombinedOutput()
	if err != nil || !strings.Contains(string(output), "PASSED") {
		testPassed = false
	}

	_, testName := filepath.Split(testPath)
	l := log.testLogger(testPassed, testName)
	if !testPassed {
		l.infoln("Failed!")
	}

	if contents, err := fileContents(testPath + ".go"); err == nil {
		l.infoln("Begin test source")
		l.println(contents)
		l.infoln("End test source")
	} else {
		l.infoln(fmt.Sprintf("Could not read test source for %s", testName))
		l.errorln(err.Error())
	}

	l.infoln("Begin test output")
	l.println(string(output))
	l.infoln("End test output")

	if !testPassed {
		return fmt.Errorf("test failed: %s", testName)
	}
	return nil
}
<|endoftext|>


<commit_before>
package dirscanner

import (
    "fmt"
    "io/ioutil"
    "path"
)

func ScanDir(a_path string, a_fileMsgs chan FileMsg,
    a_events chan Event) {

    if files, err := ioutil.ReadDir(a_path); err == nil {
        for _, file := range files {
            if file.IsDir() {
                ScanDir(path.Join(a_path, file.Name()), a_fileMsgs, a_events)
            } else {
                a_fileMsgs <- FileMsg{a_path, file.Name(), CREATED}
                a_events <- Event{DEBUG, fmt.Sprintf("Found file %s",
                    path.Join(a_path, file.Name())), nil}
            }
        }
    } else {
        a_events <- Event{ERROR,
            fmt.Sprintf("Failed to scan path %s", a_path), err}
    }
}
<commit_msg>Send events for dirs to...<commit_after>
package dirscanner

import (
    "fmt"
    "io/ioutil"
    "path"
)

func ScanDir(a_path string, a_fileMsgs chan FileMsg,
    a_events chan Event) {

    if files, err := ioutil.ReadDir(a_path); err == nil {
        for _, file := range files {
            if file.IsDir() {
                a_fileMsgs <- FileMsg{a_path, file.Name(), CREATED}
                a_events <- Event{DEBUG, fmt.Sprintf("Found dir %s",
                    path.Join(a_path, file.Name())), nil}
                ScanDir(path.Join(a_path, file.Name()), a_fileMsgs, a_events)
            } else {
                a_fileMsgs <- FileMsg{a_path, file.Name(), CREATED}
                a_events <- Event{DEBUG, fmt.Sprintf("Found file %s",
                    path.Join(a_path, file.Name())), nil}
            }
        }
    } else {
        a_events <- Event{ERROR,
            fmt.Sprintf("Failed to scan path %s", a_path), err}
    }
}
<|endoftext|>


<commit_before>package sqlread

import (
	"io"
)

type lexItemType uint8

//go:generate stringer -type=lexItemType
const (
	TIllegal lexItemType = iota

	TEof
	TSemi
	TComma

	TComment

	TNull
	TString
	TNumber
	TIdentifier

	TDropTableFullStmt
	TLockTableFullStmt
	TUnlockTablesFullStmt
	TSetFullStmt

	TLParen
	TRParen

	TCreateTable
	TCreateTableDetail

	TColumnType
	TColumnSize
	TColumnEnumVal
	TColumnDetails

	TInsertInto
	TInsertValues

	// Values Below Are Specific to the interpreter
	TIntpSelect
	TIntpStar
	TIntpFrom
	TIntpIntoOutfile
	TIntpShowTables

	TIntpQuit
)

type LexItem struct {
	Type lexItemType
	Val  string
	Pos  int64
}

type lexer struct {
	input io.ReaderAt
	start int64
	pos   int64
	// width int
	items chan LexItem
}

const (
	eof  = byte(0)  // null
	lf   = byte(10) // \n
	semi = byte(59) // semicolon ;
	bs   = byte(92) // backslash \
	bt   = byte(96) // backtick `
	dot  = byte(46) // period .

	lprn = byte(40) // (
	rprn = byte(41) // )
	coma = byte(44) // ,

	sq = byte(39) // '
	dq = byte(34) // "

	letN = byte(78) // N
	// letn = byte(39)
)

func (l *lexer) next() byte {
	i, b := l.peek(1)
	if i != 1 {
		return eof
	}

	l.pos++

	return b[0]
}

func (l *lexer) rewind() {
	l.pos--
}

func (l *lexer) peek(s int) (int, []byte) {
	b := make([]byte, s)

	n, err := l.input.ReadAt(b, l.pos)
	if err == io.EOF {
		return n, b
	} else if err != nil {
		panic(err)
	}

	return n, b
}

func (l *lexer) hasPrefix(s string) bool {
	x := []byte(s)
	_, y := l.peek(len(x))

	return string(x) == string(y)
}

type state func(*lexer) state

var (
	whitespace = []byte(" \t\r\n")
	sep        = []byte(" \t\r\n;")
	numbers    = []byte("0123456789")
)

func (l *lexer) Run() {
	for state := startState; state != nil; {
		state = state(l)
	}
	close(l.items)
}

func (l *lexer) accept(bs []byte) (c int) {
	for {
		n := l.next()

		found := false
		for _, b := range bs {
			if b == n {
				found = true
				break
			}
		}

		if !found {
			l.rewind()
			return c
		}
		c++
	}
}

func (l *lexer) until(b byte) bool {
	for {
		n := l.next()
		if n == eof {
			return false
		}

		if n == b {
			return true
		}
	}
}

func Lex(input io.ReaderAt) (*lexer, chan LexItem) {
	l := &lexer{
		input: input,
		items: make(chan LexItem, 2000000),
	}

	return l, l.items
}

func LexSection(input io.ReaderAt, off, n int64) (*lexer, chan LexItem) {
	l := &lexer{
		input: io.NewSectionReader(input, off, n),
		items: make(chan LexItem, 2000000),
	}

	return l, l.items
}

func (l *lexer) emit(t lexItemType) LexItem {
	b := make([]byte, l.pos-l.start)
	l.input.ReadAt(b, l.start)

	li := LexItem{
		Type: t,
		Val:  string(b),
		Pos:  l.start,
	}

	l.items <- li

	return li
}

func in(b byte, bs []byte) bool {
	for _, bb := range bs {
		if b == bb {
			return true
		}
	}

	return false
}
<commit_msg>Adds case insensitive hasPrefixI for human friendlier parsing<commit_after>package sqlread

import (
	"io"
	"strings"
)

type lexItemType uint8

//go:generate stringer -type=lexItemType
const (
	TIllegal lexItemType = iota

	TEof
	TSemi
	TComma

	TComment

	TNull
	TString
	TNumber
	TIdentifier

	TDropTableFullStmt
	TLockTableFullStmt
	TUnlockTablesFullStmt
	TSetFullStmt

	TLParen
	TRParen

	TCreateTable
	TCreateTableDetail

	TColumnType
	TColumnSize
	TColumnEnumVal
	TColumnDetails

	TInsertInto
	TInsertValues

	// Values Below Are Specific to the interpreter
	TIntpSelect
	TIntpStar
	TIntpFrom
	TIntpIntoOutfile
	TIntpShowTables

	TIntpQuit
)

type LexItem struct {
	Type lexItemType
	Val  string
	Pos  int64
}

type lexer struct {
	input io.ReaderAt
	start int64
	pos   int64
	// width int
	items chan LexItem
}

const (
	eof  = byte(0)  // null
	lf   = byte(10) // \n
	semi = byte(59) // semicolon ;
	bs   = byte(92) // backslash \
	bt   = byte(96) // backtick `
	dot  = byte(46) // period .

	lprn = byte(40) // (
	rprn = byte(41) // )
	coma = byte(44) // ,

	sq = byte(39) // '
	dq = byte(34) // "

	letN = byte(78) // N
	// letn = byte(39)
)

func (l *lexer) next() byte {
	i, b := l.peek(1)
	if i != 1 {
		return eof
	}

	l.pos++

	return b[0]
}

func (l *lexer) rewind() {
	l.pos--
}

func (l *lexer) peek(s int) (int, []byte) {
	b := make([]byte, s)

	n, err := l.input.ReadAt(b, l.pos)
	if err == io.EOF {
		return n, b
	} else if err != nil {
		panic(err)
	}

	return n, b
}

func (l *lexer) hasPrefix(s string) bool {
	x := []byte(s)
	_, y := l.peek(len(x))

	return string(x) == string(y)
}

func (l *lexer) hasPrefixI(s string) bool {
	x := []byte(s)
	_, y := l.peek(len(x))

	return strings.EqualFold(string(x), string(y))
}

type state func(*lexer) state

var (
	whitespace = []byte(" \t\r\n")
	sep        = []byte(" \t\r\n;")
	numbers    = []byte("0123456789")
)

func (l *lexer) Run() {
	for state := startState; state != nil; {
		state = state(l)
	}
	close(l.items)
}

func (l *lexer) accept(bs []byte) (c int) {
	for {
		n := l.next()

		found := false
		for _, b := range bs {
			if b == n {
				found = true
				break
			}
		}

		if !found {
			l.rewind()
			return c
		}
		c++
	}
}

func (l *lexer) until(b byte) bool {
	for {
		n := l.next()
		if n == eof {
			return false
		}

		if n == b {
			return true
		}
	}
}

func Lex(input io.ReaderAt) (*lexer, chan LexItem) {
	l := &lexer{
		input: input,
		items: make(chan LexItem, 2000000),
	}

	return l, l.items
}

func LexSection(input io.ReaderAt, off, n int64) (*lexer, chan LexItem) {
	l := &lexer{
		input: io.NewSectionReader(input, off, n),
		items: make(chan LexItem, 2000000),
	}

	return l, l.items
}

func (l *lexer) emit(t lexItemType) LexItem {
	b := make([]byte, l.pos-l.start)
	l.input.ReadAt(b, l.start)

	li := LexItem{
		Type: t,
		Val:  string(b),
		Pos:  l.start,
	}

	l.items <- li

	return li
}

func in(b byte, bs []byte) bool {
	for _, bb := range bs {
		if b == bb {
			return true
		}
	}

	return false
}
<|endoftext|>