<commit_before>//  Copyright (c) 2014 Couchbase, 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 upsidedown

import (
	"github.com/blevesearch/bleve/document"
	"github.com/blevesearch/bleve/index"
	"github.com/blevesearch/bleve/index/store"
)

type IndexReader struct {
	index    *UpsideDownCouch
	kvreader store.KVReader
	docCount uint64
}

func (i *IndexReader) TermFieldReader(term []byte, fieldName string, includeFreq, includeNorm, includeTermVectors bool) (index.TermFieldReader, error) {
	fieldIndex, fieldExists := i.index.fieldCache.FieldNamed(fieldName, false)
	if fieldExists {
		return newUpsideDownCouchTermFieldReader(i, term, uint16(fieldIndex), includeFreq, includeNorm, includeTermVectors)
	}
	return newUpsideDownCouchTermFieldReader(i, []byte{ByteSeparator}, ^uint16(0), includeFreq, includeNorm, includeTermVectors)
}

func (i *IndexReader) FieldDict(fieldName string) (index.FieldDict, error) {
	return i.FieldDictRange(fieldName, nil, nil)
}

func (i *IndexReader) FieldDictRange(fieldName string, startTerm []byte, endTerm []byte) (index.FieldDict, error) {
	fieldIndex, fieldExists := i.index.fieldCache.FieldNamed(fieldName, false)
	if fieldExists {
		return newUpsideDownCouchFieldDict(i, uint16(fieldIndex), startTerm, endTerm)
	}
	return newUpsideDownCouchFieldDict(i, ^uint16(0), []byte{ByteSeparator}, []byte{})
}

func (i *IndexReader) FieldDictPrefix(fieldName string, termPrefix []byte) (index.FieldDict, error) {
	return i.FieldDictRange(fieldName, termPrefix, termPrefix)
}

func (i *IndexReader) DocIDReaderAll() (index.DocIDReader, error) {
	return newUpsideDownCouchDocIDReader(i)
}

func (i *IndexReader) DocIDReaderOnly(ids []string) (index.DocIDReader, error) {
	return newUpsideDownCouchDocIDReaderOnly(i, ids)
}

func (i *IndexReader) Document(id string) (doc *document.Document, err error) {
	// first hit the back index to confirm doc exists
	var backIndexRow *BackIndexRow
	backIndexRow, err = backIndexRowForDoc(i.kvreader, []byte(id))
	if err != nil {
		return
	}
	if backIndexRow == nil {
		return
	}
	doc = document.NewDocument(id)
	storedRow := NewStoredRow([]byte(id), 0, []uint64{}, 'x', nil)
	storedRowScanPrefix := storedRow.ScanPrefixForDoc()
	it := i.kvreader.PrefixIterator(storedRowScanPrefix)
	defer func() {
		if cerr := it.Close(); err == nil && cerr != nil {
			err = cerr
		}
	}()
	key, val, valid := it.Current()
	for valid {
		safeVal := make([]byte, len(val))
		copy(safeVal, val)
		var row *StoredRow
		row, err = NewStoredRowKV(key, safeVal)
		if err != nil {
			doc = nil
			return
		}
		if row != nil {
			fieldName := i.index.fieldCache.FieldIndexed(row.field)
			field := decodeFieldType(row.typ, fieldName, row.arrayPositions, row.value)
			if field != nil {
				doc.AddField(field)
			}
		}

		it.Next()
		key, val, valid = it.Current()
	}
	return
}

func (i *IndexReader) DocumentFieldTerms(id index.IndexInternalID, fields []string) (index.FieldTerms, error) {
	back, err := backIndexRowForDoc(i.kvreader, id)
	if err != nil {
		return nil, err
	}
	if back == nil {
		return nil, nil
	}
	rv := make(index.FieldTerms, len(fields))
	fieldsMap := make(map[uint16]string, len(fields))
	for _, f := range fields {
		id, ok := i.index.fieldCache.FieldNamed(f, false)
		if ok {
			fieldsMap[id] = f
		}
	}
	for _, entry := range back.termEntries {
		if field, ok := fieldsMap[uint16(*entry.Field)]; ok {
			terms, ok := rv[field]
			if !ok {
				terms = make([]string, 0)
			}
			terms = append(terms, *entry.Term)
			rv[field] = terms
		}
	}
	return rv, nil
}

func (i *IndexReader) Fields() (fields []string, err error) {
	fields = make([]string, 0)
	it := i.kvreader.PrefixIterator([]byte{'f'})
	defer func() {
		if cerr := it.Close(); err == nil && cerr != nil {
			err = cerr
		}
	}()
	key, val, valid := it.Current()
	for valid {
		var row UpsideDownCouchRow
		row, err = ParseFromKeyValue(key, val)
		if err != nil {
			fields = nil
			return
		}
		if row != nil {
			fieldRow, ok := row.(*FieldRow)
			if ok {
				fields = append(fields, fieldRow.name)
			}
		}

		it.Next()
		key, val, valid = it.Current()
	}
	return
}

func (i *IndexReader) GetInternal(key []byte) ([]byte, error) {
	internalRow := NewInternalRow(key, nil)
	return i.kvreader.Get(internalRow.Key())
}

func (i *IndexReader) DocCount() (uint64, error) {
	return i.docCount, nil
}

func (i *IndexReader) Close() error {
	return i.kvreader.Close()
}

func (i *IndexReader) ExternalID(id index.IndexInternalID) (string, error) {
	return string(id), nil
}

func (i *IndexReader) InternalID(id string) (index.IndexInternalID, error) {
	return index.IndexInternalID(id), nil
}

func incrementBytes(in []byte) []byte {
	rv := make([]byte, len(in))
	copy(rv, in)
	for i := len(rv) - 1; i >= 0; i-- {
		rv[i] = rv[i] + 1
		if rv[i] != 0 {
			// didn't overflow, so stop
			break
		}
	}
	return rv
}
<commit_msg>simplify DocumentFieldTerms append() usage<commit_after>//  Copyright (c) 2014 Couchbase, 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 upsidedown

import (
	"github.com/blevesearch/bleve/document"
	"github.com/blevesearch/bleve/index"
	"github.com/blevesearch/bleve/index/store"
)

type IndexReader struct {
	index    *UpsideDownCouch
	kvreader store.KVReader
	docCount uint64
}

func (i *IndexReader) TermFieldReader(term []byte, fieldName string, includeFreq, includeNorm, includeTermVectors bool) (index.TermFieldReader, error) {
	fieldIndex, fieldExists := i.index.fieldCache.FieldNamed(fieldName, false)
	if fieldExists {
		return newUpsideDownCouchTermFieldReader(i, term, uint16(fieldIndex), includeFreq, includeNorm, includeTermVectors)
	}
	return newUpsideDownCouchTermFieldReader(i, []byte{ByteSeparator}, ^uint16(0), includeFreq, includeNorm, includeTermVectors)
}

func (i *IndexReader) FieldDict(fieldName string) (index.FieldDict, error) {
	return i.FieldDictRange(fieldName, nil, nil)
}

func (i *IndexReader) FieldDictRange(fieldName string, startTerm []byte, endTerm []byte) (index.FieldDict, error) {
	fieldIndex, fieldExists := i.index.fieldCache.FieldNamed(fieldName, false)
	if fieldExists {
		return newUpsideDownCouchFieldDict(i, uint16(fieldIndex), startTerm, endTerm)
	}
	return newUpsideDownCouchFieldDict(i, ^uint16(0), []byte{ByteSeparator}, []byte{})
}

func (i *IndexReader) FieldDictPrefix(fieldName string, termPrefix []byte) (index.FieldDict, error) {
	return i.FieldDictRange(fieldName, termPrefix, termPrefix)
}

func (i *IndexReader) DocIDReaderAll() (index.DocIDReader, error) {
	return newUpsideDownCouchDocIDReader(i)
}

func (i *IndexReader) DocIDReaderOnly(ids []string) (index.DocIDReader, error) {
	return newUpsideDownCouchDocIDReaderOnly(i, ids)
}

func (i *IndexReader) Document(id string) (doc *document.Document, err error) {
	// first hit the back index to confirm doc exists
	var backIndexRow *BackIndexRow
	backIndexRow, err = backIndexRowForDoc(i.kvreader, []byte(id))
	if err != nil {
		return
	}
	if backIndexRow == nil {
		return
	}
	doc = document.NewDocument(id)
	storedRow := NewStoredRow([]byte(id), 0, []uint64{}, 'x', nil)
	storedRowScanPrefix := storedRow.ScanPrefixForDoc()
	it := i.kvreader.PrefixIterator(storedRowScanPrefix)
	defer func() {
		if cerr := it.Close(); err == nil && cerr != nil {
			err = cerr
		}
	}()
	key, val, valid := it.Current()
	for valid {
		safeVal := make([]byte, len(val))
		copy(safeVal, val)
		var row *StoredRow
		row, err = NewStoredRowKV(key, safeVal)
		if err != nil {
			doc = nil
			return
		}
		if row != nil {
			fieldName := i.index.fieldCache.FieldIndexed(row.field)
			field := decodeFieldType(row.typ, fieldName, row.arrayPositions, row.value)
			if field != nil {
				doc.AddField(field)
			}
		}

		it.Next()
		key, val, valid = it.Current()
	}
	return
}

func (i *IndexReader) DocumentFieldTerms(id index.IndexInternalID, fields []string) (index.FieldTerms, error) {
	back, err := backIndexRowForDoc(i.kvreader, id)
	if err != nil {
		return nil, err
	}
	if back == nil {
		return nil, nil
	}
	rv := make(index.FieldTerms, len(fields))
	fieldsMap := make(map[uint16]string, len(fields))
	for _, f := range fields {
		id, ok := i.index.fieldCache.FieldNamed(f, false)
		if ok {
			fieldsMap[id] = f
		}
	}
	for _, entry := range back.termEntries {
		if field, ok := fieldsMap[uint16(*entry.Field)]; ok {
			rv[field] = append(rv[field], *entry.Term)
		}
	}
	return rv, nil
}

func (i *IndexReader) Fields() (fields []string, err error) {
	fields = make([]string, 0)
	it := i.kvreader.PrefixIterator([]byte{'f'})
	defer func() {
		if cerr := it.Close(); err == nil && cerr != nil {
			err = cerr
		}
	}()
	key, val, valid := it.Current()
	for valid {
		var row UpsideDownCouchRow
		row, err = ParseFromKeyValue(key, val)
		if err != nil {
			fields = nil
			return
		}
		if row != nil {
			fieldRow, ok := row.(*FieldRow)
			if ok {
				fields = append(fields, fieldRow.name)
			}
		}

		it.Next()
		key, val, valid = it.Current()
	}
	return
}

func (i *IndexReader) GetInternal(key []byte) ([]byte, error) {
	internalRow := NewInternalRow(key, nil)
	return i.kvreader.Get(internalRow.Key())
}

func (i *IndexReader) DocCount() (uint64, error) {
	return i.docCount, nil
}

func (i *IndexReader) Close() error {
	return i.kvreader.Close()
}

func (i *IndexReader) ExternalID(id index.IndexInternalID) (string, error) {
	return string(id), nil
}

func (i *IndexReader) InternalID(id string) (index.IndexInternalID, error) {
	return index.IndexInternalID(id), nil
}

func incrementBytes(in []byte) []byte {
	rv := make([]byte, len(in))
	copy(rv, in)
	for i := len(rv) - 1; i >= 0; i-- {
		rv[i] = rv[i] + 1
		if rv[i] != 0 {
			// didn't overflow, so stop
			break
		}
	}
	return rv
}
<|endoftext|>


<commit_before>/*!
 * Copyright 2014 Docker, Inc.
 * Licensed under the Apache License, Version 2.0
 * github.com/docker/docker/LICENSE
 *
 * github.com/docker/docker/api/client/commands.go
 * github.com/docker/docker/pkg/archive/archive.go
 * github.com/docker/docker/pkg/fileutils/fileutils.go
 */

package api

import (
	"archive/tar"
	"bufio"
	"fmt"
	"io"
	"io/ioutil"
	"net/url"
	"os"
	"path/filepath"
	"strings"

	log "github.com/sirupsen/logrus"
)

const (
	DOCKERFILE   = "Dockerfile"
	DOCKERIGNORE = ".dockerignore"
)

func (client *DockerClient) BuildImage(path, tag string) (string, error) {
	v := url.Values{}
	v.Set("rm", "1")
	if tag != "" {
		v.Set("t", tag)
	}

	uri := fmt.Sprintf("/v%s/build?%s", API_VERSION, v.Encode())

	dockerfile := path

	fi, err := os.Lstat(dockerfile)
	if err != nil {
		return "", err
	}

	fm := fi.Mode()
	if fm.IsDir() {
		dockerfile = filepath.Join(dockerfile, DOCKERFILE)
		if _, err := os.Stat(dockerfile); os.IsNotExist(err) {
			return "", fmt.Errorf("No Dockerfile found in %s", path)
		}
	}

	var (
		root     = filepath.Dir(dockerfile)
		filename = filepath.Base(dockerfile)
	)

	ignore, err := ioutil.ReadFile(filepath.Join(root, DOCKERIGNORE))
	if err != nil && !os.IsNotExist(err) {
		return "", fmt.Errorf("Error reading .dockerignore: %s", err)
	}

	var excludes []string
	for _, pattern := range strings.Split(string(ignore), "\n") {
		pattern = strings.TrimSpace(pattern)
		if pattern == "" {
			continue
		}
		pattern = filepath.Clean(pattern)
		excludes = append(excludes, pattern)
	}

	fmt.Fprintf(client.out, "Sending build context to Docker daemon\n")
	if log.GetLevel() < log.InfoLevel {
		fmt.Fprintf(client.out, "---> ")
	}

	pipeReader, pipeWriter := io.Pipe()

	go func() {
		var (
			files int64 = 0
			total int64 = 0
		)

		bufWriter := bufio.NewWriterSize(pipeWriter, 32*1024)
		tarWriter := tar.NewWriter(bufWriter)
		tmpWriter := bufio.NewWriterSize(nil, 32*1024)
		defer tmpWriter.Reset(nil)

		seen := make(map[string]bool)

		filepath.Walk(filepath.Join(root, "."), func(filePath string, f os.FileInfo, err error) error {
			if err != nil {
				log.Debugf("Can't stat file %s, error: %s", filePath, err)
				return nil
			}

			relFilePath, err := filepath.Rel(root, filePath)
			if err != nil || (relFilePath == "." && f.IsDir()) {
				return nil
			}

			skip := false

			switch relFilePath {
			default:
				skip, err = func() (bool, error) { // Excluding
					for _, exclude := range excludes {
						matched, err := filepath.Match(exclude, relFilePath)
						if err != nil {
							log.Errorf("Error matching: %s, pattern: %s", relFilePath, exclude)
							return false, err
						}
						if matched {
							if filepath.Clean(relFilePath) == "." {
								log.Errorf("Can't exclude whole path, excluding pattern: %s", exclude)
								continue
							}
							return true, nil
						}
					}
					return false, nil
				}()
				if err != nil {
					log.Debugf("Error matching: %s, %s", relFilePath, err)
					return err
				}
			case DOCKERFILE:
				if filename != DOCKERFILE {
					skip = true
				}
			case DOCKERIGNORE:
			case filename:
			}

			if skip {
				log.WithField("", " Skipped").Debugf("---> %s", relFilePath)
				if f.IsDir() {
					return filepath.SkipDir
				}
				return nil
			}

			if seen[relFilePath] {
				return nil
			}
			seen[relFilePath] = true

			var size int64

			if err := func() error { // Adding a file to tar
				fi, err := os.Lstat(filePath)
				if err != nil {
					log.Errorf("Can't get file info: %s, error: %s", filePath, err)
					return err
				}

				size = fi.Size()

				link := ""
				if (fi.Mode() & os.ModeSymlink) != 0 {
					if link, err = os.Readlink(filePath); err != nil {
						log.Errorf("Can't read link to tar: %s, error: %s", filePath, err)
						return err
					}
				}

				hdr, err := tar.FileInfoHeader(fi, link)
				if err != nil {
					log.Errorf("Can't get file info header to tar: %s, error: %s", filePath, err)
					return err
				}

				name := relFilePath
				if fi.IsDir() && !strings.HasSuffix(name, "/") {
					name = name + "/"
				}
				hdr.Name = name

				if name == filename {
					hdr.Name = DOCKERFILE
				}

				if err := tarWriter.WriteHeader(hdr); err != nil {
					log.Errorf("Can't write tar header, error: %s", err)
					return err
				}

				if hdr.Typeflag == tar.TypeReg {
					file, err := os.Open(filePath)
					if err != nil {
						log.Errorf("Can't open file: %s, error: %s", filePath, err)
						return err
					}

					tmpWriter.Reset(tarWriter)
					defer tmpWriter.Reset(nil)
					_, err = io.Copy(tmpWriter, file)
					file.Close()
					if err != nil {
						log.Errorf("Can't write file to tar: %s, error: %s", filePath, err)
						return err
					}
					err = tmpWriter.Flush()
					if err != nil {
						log.Errorf("Can't flush file to tar, error: %s", err)
						return err
					}
				}

				return nil
			}(); err != nil {
				log.Debugf("Can't add file %s to tar, error: %s", filePath, err)
			}

			files++
			total += size

			if log.GetLevel() < log.InfoLevel {
				fmt.Fprintf(client.out, ".")
			}
			log.WithFields(log.Fields{
				"": fmt.Sprintf(" %7.2f KB", float64(size)/1000),
			}).Infof("---> %s", relFilePath)

			return nil
		})

		if err := tarWriter.Close(); err != nil {
			log.Debugf("Can't close tar writer: %s", err)
		}

		bufWriter.Flush()
		if err := pipeWriter.Close(); err != nil {
			log.Debugf("Can't close pipe writer: %s", err)
		}

		if log.GetLevel() < log.InfoLevel {
			fmt.Fprintf(client.out, "\n")
		}
		fmt.Fprintf(client.out, "---> Sent %d file(s), %.2f KB\n", files, float64(total)/1000)
	}()

	headers := map[string]string{}
	headers["Content-type"] = "application/tar"

	return client.doStreamRequest("POST", uri, pipeReader, headers)
}
<commit_msg>Make sure the absolute path<commit_after>/*!
 * Copyright 2014 Docker, Inc.
 * Licensed under the Apache License, Version 2.0
 * github.com/docker/docker/LICENSE
 *
 * github.com/docker/docker/api/client/commands.go
 * github.com/docker/docker/pkg/archive/archive.go
 * github.com/docker/docker/pkg/fileutils/fileutils.go
 */

package api

import (
	"archive/tar"
	"bufio"
	"fmt"
	"io"
	"io/ioutil"
	"net/url"
	"os"
	"path/filepath"
	"strings"

	log "github.com/sirupsen/logrus"
)

const (
	DOCKERFILE   = "Dockerfile"
	DOCKERIGNORE = ".dockerignore"
)

func (client *DockerClient) BuildImage(path, tag string) (string, error) {
	v := url.Values{}
	v.Set("rm", "1")
	if tag != "" {
		v.Set("t", tag)
	}

	uri := fmt.Sprintf("/v%s/build?%s", API_VERSION, v.Encode())

	dockerfile := os.ExpandEnv(path)

	fi, err := os.Lstat(dockerfile)
	if err != nil {
		return "", err
	}

	fm := fi.Mode()
	if fm.IsDir() {
		dockerfile = filepath.Join(dockerfile, DOCKERFILE)
		if _, err := os.Stat(dockerfile); os.IsNotExist(err) {
			return "", fmt.Errorf("No Dockerfile found in %s", path)
		}
	}

	var (
		root     = filepath.Dir(dockerfile)
		filename = filepath.Base(dockerfile)
	)

	ignore, err := ioutil.ReadFile(filepath.Join(root, DOCKERIGNORE))
	if err != nil && !os.IsNotExist(err) {
		return "", fmt.Errorf("Error reading .dockerignore: %s", err)
	}

	var excludes []string
	for _, pattern := range strings.Split(string(ignore), "\n") {
		pattern = strings.TrimSpace(pattern)
		if pattern == "" {
			continue
		}
		pattern = filepath.Clean(pattern)
		excludes = append(excludes, pattern)
	}

	fmt.Fprintf(client.out, "Sending build context to Docker daemon\n")
	if log.GetLevel() < log.InfoLevel {
		fmt.Fprintf(client.out, "---> ")
	}

	pipeReader, pipeWriter := io.Pipe()

	go func() {
		var (
			files int64 = 0
			total int64 = 0
		)

		bufWriter := bufio.NewWriterSize(pipeWriter, 32*1024)
		tarWriter := tar.NewWriter(bufWriter)
		tmpWriter := bufio.NewWriterSize(nil, 32*1024)
		defer tmpWriter.Reset(nil)

		seen := make(map[string]bool)

		filepath.Walk(filepath.Join(root, "."), func(filePath string, f os.FileInfo, err error) error {
			if err != nil {
				log.Debugf("Can't stat file %s, error: %s", filePath, err)
				return nil
			}

			relFilePath, err := filepath.Rel(root, filePath)
			if err != nil || (relFilePath == "." && f.IsDir()) {
				return nil
			}

			skip := false

			switch relFilePath {
			default:
				skip, err = func() (bool, error) { // Excluding
					for _, exclude := range excludes {
						matched, err := filepath.Match(exclude, relFilePath)
						if err != nil {
							log.Errorf("Error matching: %s, pattern: %s", relFilePath, exclude)
							return false, err
						}
						if matched {
							if filepath.Clean(relFilePath) == "." {
								log.Errorf("Can't exclude whole path, excluding pattern: %s", exclude)
								continue
							}
							return true, nil
						}
					}
					return false, nil
				}()
				if err != nil {
					log.Debugf("Error matching: %s, %s", relFilePath, err)
					return err
				}
			case DOCKERFILE:
				if filename != DOCKERFILE {
					skip = true
				}
			case DOCKERIGNORE:
			case filename:
			}

			if skip {
				log.WithField("", " Skipped").Debugf("---> %s", relFilePath)
				if f.IsDir() {
					return filepath.SkipDir
				}
				return nil
			}

			if seen[relFilePath] {
				return nil
			}
			seen[relFilePath] = true

			var size int64

			if err := func() error { // Adding a file to tar
				fi, err := os.Lstat(filePath)
				if err != nil {
					log.Errorf("Can't get file info: %s, error: %s", filePath, err)
					return err
				}

				size = fi.Size()

				link := ""
				if (fi.Mode() & os.ModeSymlink) != 0 {
					if link, err = os.Readlink(filePath); err != nil {
						log.Errorf("Can't read link to tar: %s, error: %s", filePath, err)
						return err
					}
				}

				hdr, err := tar.FileInfoHeader(fi, link)
				if err != nil {
					log.Errorf("Can't get file info header to tar: %s, error: %s", filePath, err)
					return err
				}

				name := relFilePath
				if fi.IsDir() && !strings.HasSuffix(name, "/") {
					name = name + "/"
				}
				hdr.Name = name

				if name == filename {
					hdr.Name = DOCKERFILE
				}

				if err := tarWriter.WriteHeader(hdr); err != nil {
					log.Errorf("Can't write tar header, error: %s", err)
					return err
				}

				if hdr.Typeflag == tar.TypeReg {
					file, err := os.Open(filePath)
					if err != nil {
						log.Errorf("Can't open file: %s, error: %s", filePath, err)
						return err
					}

					tmpWriter.Reset(tarWriter)
					defer tmpWriter.Reset(nil)
					_, err = io.Copy(tmpWriter, file)
					file.Close()
					if err != nil {
						log.Errorf("Can't write file to tar: %s, error: %s", filePath, err)
						return err
					}
					err = tmpWriter.Flush()
					if err != nil {
						log.Errorf("Can't flush file to tar, error: %s", err)
						return err
					}
				}

				return nil
			}(); err != nil {
				log.Debugf("Can't add file %s to tar, error: %s", filePath, err)
			}

			files++
			total += size

			if log.GetLevel() < log.InfoLevel {
				fmt.Fprintf(client.out, ".")
			}
			log.WithFields(log.Fields{
				"": fmt.Sprintf(" %7.2f KB", float64(size)/1000),
			}).Infof("---> %s", relFilePath)

			return nil
		})

		if err := tarWriter.Close(); err != nil {
			log.Debugf("Can't close tar writer: %s", err)
		}

		bufWriter.Flush()
		if err := pipeWriter.Close(); err != nil {
			log.Debugf("Can't close pipe writer: %s", err)
		}

		if log.GetLevel() < log.InfoLevel {
			fmt.Fprintf(client.out, "\n")
		}
		fmt.Fprintf(client.out, "---> Sent %d file(s), %.2f KB\n", files, float64(total)/1000)
	}()

	headers := map[string]string{}
	headers["Content-type"] = "application/tar"

	return client.doStreamRequest("POST", uri, pipeReader, headers)
}
<|endoftext|>


<commit_before>/*
Copyright 2017 The Kubernetes Authors.

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 benchmark

import (
	"testing"

	"k8s.io/kubernetes/test/integration/framework"
)

func TestMain(m *testing.M) {
	framework.EtcdMain(m.Run)
}
<commit_msg>Respect flags of testing package<commit_after>/*
Copyright 2017 The Kubernetes Authors.

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 benchmark

import (
	"flag"
	"testing"

	"k8s.io/kubernetes/test/integration/framework"
)

func TestMain(m *testing.M) {
	flag.Parse()
	framework.EtcdMain(m.Run)
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"net/http"
	"regexp"
	"time"

	"github.com/go-gorp/gorp"
	"github.com/gorilla/mux"

	"github.com/ovh/cds/engine/api/context"
	"github.com/ovh/cds/engine/api/group"
	"github.com/ovh/cds/engine/api/project"
	"github.com/ovh/cds/engine/log"
	"github.com/ovh/cds/sdk"
)

func getProjectsHandler(w http.ResponseWriter, r *http.Request, db *gorp.DbMap, c *context.Ctx) error {
	projects, err := project.LoadAll(db, c.User)
	if err != nil {
		return sdk.WrapError(err, "getProjectsHandler")
	}
	return WriteJSON(w, r, projects, http.StatusOK)
}

func updateProjectHandler(w http.ResponseWriter, r *http.Request, db *gorp.DbMap, c *context.Ctx) error {
	// Get project name in URL
	vars := mux.Vars(r)
	key := vars["permProjectKey"]

	proj := &sdk.Project{}
	if err := UnmarshalBody(r, proj); err != nil {
		return err
	}

	if proj.Name == "" {
		log.Warning("updateProject: Project name must no be empty")
		return sdk.ErrInvalidProjectName
	}

	// Check Request
	if key != proj.Key {
		log.Warning("updateProject: bad Project key %s/%s \n", key, proj.Key)
		return sdk.ErrWrongRequest
	}

	// Check is project exist
	p, errProj := project.Load(db, key, c.User)
	if errProj != nil {
		log.Warning("updateProject: Cannot load project from db: %s\n", errProj)
		return errProj
	}
	// Update in DB is made given the primary key
	proj.ID = p.ID
	if errUp := project.Update(db, proj); errUp != nil {
		log.Warning("updateProject: Cannot update project %s : %s\n", key, errUp)
		return errUp
	}

	return WriteJSON(w, r, p, http.StatusOK)
}

func getProjectHandler(w http.ResponseWriter, r *http.Request, db *gorp.DbMap, c *context.Ctx) error {
	// Get project name in URL
	vars := mux.Vars(r)
	key := vars["permProjectKey"]

	p, errProj := project.Load(db, key, c.User,
		project.LoadOptions.WithVariables,
		project.LoadOptions.WithApplications,
		project.LoadOptions.WithApplicationPipelines,
		project.LoadOptions.WithEnvironments,
		project.LoadOptions.WithGroups,
		project.LoadOptions.WithPermission,
		project.LoadOptions.WithPipelines,
		project.LoadOptions.WithRepositoriesManagers,
	)
	if errProj != nil {
		return sdk.WrapError(errProj, "getProjectHandler (%s)", key)
	}

	return WriteJSON(w, r, p, http.StatusOK)
}

func addProjectHandler(w http.ResponseWriter, r *http.Request, db *gorp.DbMap, c *context.Ctx) error {
	//Unmarshal data
	p := &sdk.Project{}
	if err := UnmarshalBody(r, p); err != nil {
		return err
	}

	// check projectKey pattern
	if rgxp := regexp.MustCompile(sdk.ProjectKeyPattern); !rgxp.MatchString(p.Key) {
		log.Warning("AddProject: Project key %s do not respect pattern %s", p.Key, sdk.ProjectKeyPattern)
		return sdk.ErrInvalidProjectKey
	}

	//check project Name
	if p.Name == "" {
		log.Warning("AddProject: Project name must no be empty")
		return sdk.ErrInvalidProjectName

	}

	// Check that project does not already exists
	exist, errExist := project.Exist(db, p.Key)
	if errExist != nil {
		log.Warning("AddProject: Cannot check if project %s exist: %s\n", p.Key, errExist)
		return errExist
	}

	if exist {
		log.Warning("AddProject: Project %s already exists\n", p.Key)
		// Write nice error message here
		return sdk.ErrConflict

	}

	//Create a project within a transaction
	tx, errBegin := db.Begin()
	defer tx.Rollback()
	if errBegin != nil {
		log.Warning("AddProject: Cannot start transaction: %s\n", errBegin)
		return errBegin

	}

	if err := project.Insert(tx, p); err != nil {
		log.Warning("AddProject: Cannot insert project: %s\n", err)
		return err

	}

	// Add group
	for i := range p.ProjectGroups {
		groupPermission := &p.ProjectGroups[i]

		// Insert group
		groupID, new, errGroup := group.AddGroup(tx, &groupPermission.Group)
		if groupID == 0 {
			return errGroup
		}
		groupPermission.Group.ID = groupID

		// Add group on project
		if err := group.InsertGroupInProject(tx, p.ID, groupPermission.Group.ID, groupPermission.Permission); err != nil {
			log.Warning("addProject: Cannot add group %s in project %s:  %s\n", groupPermission.Group.Name, p.Name, err)
			return err

		}

		// Add user in group
		if new {
			if err := group.InsertUserInGroup(tx, groupPermission.Group.ID, c.User.ID, true); err != nil {
				log.Warning("addProject: Cannot add user %s in group %s:  %s\n", c.User.Username, groupPermission.Group.Name, err)
				return err

			}
		}
	}

	for _, v := range p.Variable {
		var errVar error
		switch v.Type {
		case sdk.KeyVariable:
			errVar = project.AddKeyPair(tx, p, v.Name)
		default:
			errVar = project.InsertVariable(tx, p, v)
		}
		if errVar != nil {
			log.Warning("addProject: Cannot add variable %s in project %s:  %s\n", v.Name, p.Name, errVar)
			return errVar
		}
	}

	if err := project.UpdateLastModified(tx, c.User, p); err != nil {
		log.Warning("addProject: Cannot update last modified:  %s\n", err)
		return err
	}

	if err := tx.Commit(); err != nil {
		log.Warning("addProject: Cannot commit transaction:  %s\n", err)
		return err
	}

	return WriteJSON(w, r, p, http.StatusCreated)
}

func deleteProjectHandler(w http.ResponseWriter, r *http.Request, db *gorp.DbMap, c *context.Ctx) error {
	// Get project name in URL
	vars := mux.Vars(r)
	key := vars["permProjectKey"]

	p, errProj := project.Load(db, key, c.User, project.LoadOptions.WithPipelines)
	if errProj != nil {
		if errProj != sdk.ErrNoProject {
			log.Warning("deleteProject: load project '%s' from db: %s\n", key, errProj)
		}
		return errProj
	}

	if len(p.Pipelines) > 0 {
		log.Warning("deleteProject> Project '%s' still used by %d pipelines\n", key, len(p.Pipelines))
		return sdk.ErrProjectHasPipeline
	}

	if len(p.Applications) > 0 {
		log.Warning("deleteProject> Project '%s' still used by %d applications\n", key, len(p.Applications))
		return sdk.ErrProjectHasApplication
	}

	tx, errBegin := db.Begin()
	if errBegin != nil {
		log.Warning("deleteProject: Cannot start transaction: %s\n", errBegin)
		return errBegin
	}
	defer tx.Rollback()

	if err := project.Delete(tx, p.Key); err != nil {
		log.Warning("deleteProject: cannot delete project %s: %s\n", err)
		return err

	}
	if err := tx.Commit(); err != nil {
		log.Warning("deleteProject: Cannot commit transaction: %s\n", err)
		return err
	}
	log.Notice("Project %s deleted.\n", p.Name)

	return nil

}

func getUserLastUpdates(w http.ResponseWriter, r *http.Request, db *gorp.DbMap, c *context.Ctx) error {
	sinceHeader := r.Header.Get("If-Modified-Since")
	since := time.Unix(0, 0)
	if sinceHeader != "" {
		since, _ = time.Parse(time.RFC1123, sinceHeader)
	}

	lastUpdates, errUp := project.LastUpdates(db, c.User, since)
	if errUp != nil {
		if errUp == sql.ErrNoRows {
			w.WriteHeader(http.StatusNotModified)
			return nil
		}
		return errUp
	}
	if len(lastUpdates) == 0 {
		w.WriteHeader(http.StatusNotModified)
		return nil
	}

	return WriteJSON(w, r, lastUpdates, http.StatusOK)
}
<commit_msg>fix (api): getProjectsHandler load projects with applications (#315)<commit_after>package main

import (
	"database/sql"
	"net/http"
	"regexp"
	"time"

	"github.com/go-gorp/gorp"
	"github.com/gorilla/mux"

	"github.com/ovh/cds/engine/api/context"
	"github.com/ovh/cds/engine/api/group"
	"github.com/ovh/cds/engine/api/project"
	"github.com/ovh/cds/engine/log"
	"github.com/ovh/cds/sdk"
)

func getProjectsHandler(w http.ResponseWriter, r *http.Request, db *gorp.DbMap, c *context.Ctx) error {
	projects, err := project.LoadAll(db, c.User, project.LoadOptions.WithApplications)
	if err != nil {
		return sdk.WrapError(err, "getProjectsHandler")
	}
	return WriteJSON(w, r, projects, http.StatusOK)
}

func updateProjectHandler(w http.ResponseWriter, r *http.Request, db *gorp.DbMap, c *context.Ctx) error {
	// Get project name in URL
	vars := mux.Vars(r)
	key := vars["permProjectKey"]

	proj := &sdk.Project{}
	if err := UnmarshalBody(r, proj); err != nil {
		return err
	}

	if proj.Name == "" {
		log.Warning("updateProject: Project name must no be empty")
		return sdk.ErrInvalidProjectName
	}

	// Check Request
	if key != proj.Key {
		log.Warning("updateProject: bad Project key %s/%s \n", key, proj.Key)
		return sdk.ErrWrongRequest
	}

	// Check is project exist
	p, errProj := project.Load(db, key, c.User)
	if errProj != nil {
		log.Warning("updateProject: Cannot load project from db: %s\n", errProj)
		return errProj
	}
	// Update in DB is made given the primary key
	proj.ID = p.ID
	if errUp := project.Update(db, proj); errUp != nil {
		log.Warning("updateProject: Cannot update project %s : %s\n", key, errUp)
		return errUp
	}

	return WriteJSON(w, r, p, http.StatusOK)
}

func getProjectHandler(w http.ResponseWriter, r *http.Request, db *gorp.DbMap, c *context.Ctx) error {
	// Get project name in URL
	vars := mux.Vars(r)
	key := vars["permProjectKey"]

	p, errProj := project.Load(db, key, c.User,
		project.LoadOptions.WithVariables,
		project.LoadOptions.WithApplications,
		project.LoadOptions.WithApplicationPipelines,
		project.LoadOptions.WithEnvironments,
		project.LoadOptions.WithGroups,
		project.LoadOptions.WithPermission,
		project.LoadOptions.WithPipelines,
		project.LoadOptions.WithRepositoriesManagers,
	)
	if errProj != nil {
		return sdk.WrapError(errProj, "getProjectHandler (%s)", key)
	}

	return WriteJSON(w, r, p, http.StatusOK)
}

func addProjectHandler(w http.ResponseWriter, r *http.Request, db *gorp.DbMap, c *context.Ctx) error {
	//Unmarshal data
	p := &sdk.Project{}
	if err := UnmarshalBody(r, p); err != nil {
		return err
	}

	// check projectKey pattern
	if rgxp := regexp.MustCompile(sdk.ProjectKeyPattern); !rgxp.MatchString(p.Key) {
		log.Warning("AddProject: Project key %s do not respect pattern %s", p.Key, sdk.ProjectKeyPattern)
		return sdk.ErrInvalidProjectKey
	}

	//check project Name
	if p.Name == "" {
		log.Warning("AddProject: Project name must no be empty")
		return sdk.ErrInvalidProjectName

	}

	// Check that project does not already exists
	exist, errExist := project.Exist(db, p.Key)
	if errExist != nil {
		log.Warning("AddProject: Cannot check if project %s exist: %s\n", p.Key, errExist)
		return errExist
	}

	if exist {
		log.Warning("AddProject: Project %s already exists\n", p.Key)
		// Write nice error message here
		return sdk.ErrConflict

	}

	//Create a project within a transaction
	tx, errBegin := db.Begin()
	defer tx.Rollback()
	if errBegin != nil {
		log.Warning("AddProject: Cannot start transaction: %s\n", errBegin)
		return errBegin

	}

	if err := project.Insert(tx, p); err != nil {
		log.Warning("AddProject: Cannot insert project: %s\n", err)
		return err

	}

	// Add group
	for i := range p.ProjectGroups {
		groupPermission := &p.ProjectGroups[i]

		// Insert group
		groupID, new, errGroup := group.AddGroup(tx, &groupPermission.Group)
		if groupID == 0 {
			return errGroup
		}
		groupPermission.Group.ID = groupID

		// Add group on project
		if err := group.InsertGroupInProject(tx, p.ID, groupPermission.Group.ID, groupPermission.Permission); err != nil {
			log.Warning("addProject: Cannot add group %s in project %s:  %s\n", groupPermission.Group.Name, p.Name, err)
			return err

		}

		// Add user in group
		if new {
			if err := group.InsertUserInGroup(tx, groupPermission.Group.ID, c.User.ID, true); err != nil {
				log.Warning("addProject: Cannot add user %s in group %s:  %s\n", c.User.Username, groupPermission.Group.Name, err)
				return err

			}
		}
	}

	for _, v := range p.Variable {
		var errVar error
		switch v.Type {
		case sdk.KeyVariable:
			errVar = project.AddKeyPair(tx, p, v.Name)
		default:
			errVar = project.InsertVariable(tx, p, v)
		}
		if errVar != nil {
			log.Warning("addProject: Cannot add variable %s in project %s:  %s\n", v.Name, p.Name, errVar)
			return errVar
		}
	}

	if err := project.UpdateLastModified(tx, c.User, p); err != nil {
		log.Warning("addProject: Cannot update last modified:  %s\n", err)
		return err
	}

	if err := tx.Commit(); err != nil {
		log.Warning("addProject: Cannot commit transaction:  %s\n", err)
		return err
	}

	return WriteJSON(w, r, p, http.StatusCreated)
}

func deleteProjectHandler(w http.ResponseWriter, r *http.Request, db *gorp.DbMap, c *context.Ctx) error {
	// Get project name in URL
	vars := mux.Vars(r)
	key := vars["permProjectKey"]

	p, errProj := project.Load(db, key, c.User, project.LoadOptions.WithPipelines)
	if errProj != nil {
		if errProj != sdk.ErrNoProject {
			log.Warning("deleteProject: load project '%s' from db: %s\n", key, errProj)
		}
		return errProj
	}

	if len(p.Pipelines) > 0 {
		log.Warning("deleteProject> Project '%s' still used by %d pipelines\n", key, len(p.Pipelines))
		return sdk.ErrProjectHasPipeline
	}

	if len(p.Applications) > 0 {
		log.Warning("deleteProject> Project '%s' still used by %d applications\n", key, len(p.Applications))
		return sdk.ErrProjectHasApplication
	}

	tx, errBegin := db.Begin()
	if errBegin != nil {
		log.Warning("deleteProject: Cannot start transaction: %s\n", errBegin)
		return errBegin
	}
	defer tx.Rollback()

	if err := project.Delete(tx, p.Key); err != nil {
		log.Warning("deleteProject: cannot delete project %s: %s\n", err)
		return err

	}
	if err := tx.Commit(); err != nil {
		log.Warning("deleteProject: Cannot commit transaction: %s\n", err)
		return err
	}
	log.Notice("Project %s deleted.\n", p.Name)

	return nil

}

func getUserLastUpdates(w http.ResponseWriter, r *http.Request, db *gorp.DbMap, c *context.Ctx) error {
	sinceHeader := r.Header.Get("If-Modified-Since")
	since := time.Unix(0, 0)
	if sinceHeader != "" {
		since, _ = time.Parse(time.RFC1123, sinceHeader)
	}

	lastUpdates, errUp := project.LastUpdates(db, c.User, since)
	if errUp != nil {
		if errUp == sql.ErrNoRows {
			w.WriteHeader(http.StatusNotModified)
			return nil
		}
		return errUp
	}
	if len(lastUpdates) == 0 {
		w.WriteHeader(http.StatusNotModified)
		return nil
	}

	return WriteJSON(w, r, lastUpdates, http.StatusOK)
}
<|endoftext|>


<commit_before>// Copyright 2017 The Wuffs Authors.
//
// 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
//
//    https://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.

//go:generate go run gen.go

package check

import (
	"fmt"

	"github.com/google/wuffs/lang/builtin"
	"github.com/google/wuffs/lang/parse"

	a "github.com/google/wuffs/lang/ast"
	t "github.com/google/wuffs/lang/token"
)

var (
	exprArgs    = a.NewExpr(0, 0, 0, t.IDArgs, nil, nil, nil, nil)
	exprNullptr = a.NewExpr(0, 0, 0, t.IDNullptr, nil, nil, nil, nil)
	exprThis    = a.NewExpr(0, 0, 0, t.IDThis, nil, nil, nil, nil)
)

var (
	typeExprGeneric1    = a.NewTypeExpr(0, t.IDBase, t.IDDagger1, nil, nil, nil)
	typeExprGeneric2    = a.NewTypeExpr(0, t.IDBase, t.IDDagger2, nil, nil, nil)
	typeExprIdeal       = a.NewTypeExpr(0, t.IDBase, t.IDQIdeal, nil, nil, nil)
	typeExprList        = a.NewTypeExpr(0, t.IDBase, t.IDComma, nil, nil, nil)
	typeExprNullptr     = a.NewTypeExpr(0, t.IDBase, t.IDQNullptr, nil, nil, nil)
	typeExprPlaceholder = a.NewTypeExpr(0, t.IDBase, t.IDQPlaceholder, nil, nil, nil)
	typeExprTypeExpr    = a.NewTypeExpr(0, t.IDBase, t.IDQTypeExpr, nil, nil, nil)

	typeExprU8  = a.NewTypeExpr(0, t.IDBase, t.IDU8, nil, nil, nil)
	typeExprU16 = a.NewTypeExpr(0, t.IDBase, t.IDU16, nil, nil, nil)
	typeExprU32 = a.NewTypeExpr(0, t.IDBase, t.IDU32, nil, nil, nil)
	typeExprU64 = a.NewTypeExpr(0, t.IDBase, t.IDU64, nil, nil, nil)

	typeExprEmptyStruct = a.NewTypeExpr(0, t.IDBase, t.IDEmptyStruct, nil, nil, nil)
	typeExprBool        = a.NewTypeExpr(0, t.IDBase, t.IDBool, nil, nil, nil)
	typeExprUtility     = a.NewTypeExpr(0, t.IDBase, t.IDUtility, nil, nil, nil)

	typeExprRangeIEU32 = a.NewTypeExpr(0, t.IDBase, t.IDRangeIEU32, nil, nil, nil)
	typeExprRangeIIU32 = a.NewTypeExpr(0, t.IDBase, t.IDRangeIIU32, nil, nil, nil)
	typeExprRangeIEU64 = a.NewTypeExpr(0, t.IDBase, t.IDRangeIEU64, nil, nil, nil)
	typeExprRangeIIU64 = a.NewTypeExpr(0, t.IDBase, t.IDRangeIIU64, nil, nil, nil)
	typeExprRectIEU32  = a.NewTypeExpr(0, t.IDBase, t.IDRectIEU32, nil, nil, nil)
	typeExprRectIIU32  = a.NewTypeExpr(0, t.IDBase, t.IDRectIIU32, nil, nil, nil)

	typeExprIOReader = a.NewTypeExpr(0, t.IDBase, t.IDIOReader, nil, nil, nil)
	typeExprIOWriter = a.NewTypeExpr(0, t.IDBase, t.IDIOWriter, nil, nil, nil)
	typeExprStatus   = a.NewTypeExpr(0, t.IDBase, t.IDStatus, nil, nil, nil)

	typeExprFrameConfig   = a.NewTypeExpr(0, t.IDBase, t.IDFrameConfig, nil, nil, nil)
	typeExprImageConfig   = a.NewTypeExpr(0, t.IDBase, t.IDImageConfig, nil, nil, nil)
	typeExprPixelBuffer   = a.NewTypeExpr(0, t.IDBase, t.IDPixelBuffer, nil, nil, nil)
	typeExprPixelConfig   = a.NewTypeExpr(0, t.IDBase, t.IDPixelConfig, nil, nil, nil)
	typeExprPixelSwizzler = a.NewTypeExpr(0, t.IDBase, t.IDPixelSwizzler, nil, nil, nil)

	typeExprDecodeFrameOptions = a.NewTypeExpr(0, t.IDBase, t.IDDecodeFrameOptions, nil, nil, nil)

	typeExprSliceU8 = a.NewTypeExpr(t.IDSlice, 0, 0, nil, nil, typeExprU8)
	typeExprTableU8 = a.NewTypeExpr(t.IDTable, 0, 0, nil, nil, typeExprU8)
)

func setPlaceholderMBoundsMType(n *a.Node) {
	n.SetMBounds(bounds{zero, zero})
	n.SetMType(typeExprPlaceholder)
}

// typeMap maps from variable names (as token IDs) to types.
type typeMap map[t.ID]*a.TypeExpr

var builtInTypeMap = typeMap{
	t.IDU8:  typeExprU8,
	t.IDU16: typeExprU16,
	t.IDU32: typeExprU32,
	t.IDU64: typeExprU64,

	t.IDEmptyStruct: typeExprEmptyStruct,
	t.IDBool:        typeExprBool,
	t.IDUtility:     typeExprUtility,

	t.IDRangeIEU32: typeExprRangeIEU32,
	t.IDRangeIIU32: typeExprRangeIIU32,
	t.IDRangeIEU64: typeExprRangeIEU64,
	t.IDRangeIIU64: typeExprRangeIIU64,
	t.IDRectIEU32:  typeExprRectIEU32,
	t.IDRectIIU32:  typeExprRectIIU32,

	t.IDIOReader: typeExprIOReader,
	t.IDIOWriter: typeExprIOWriter,
	t.IDStatus:   typeExprStatus,

	t.IDFrameConfig:   typeExprFrameConfig,
	t.IDImageConfig:   typeExprImageConfig,
	t.IDPixelBuffer:   typeExprPixelBuffer,
	t.IDPixelConfig:   typeExprPixelConfig,
	t.IDPixelSwizzler: typeExprPixelSwizzler,

	t.IDDecodeFrameOptions: typeExprDecodeFrameOptions,
}

func (c *Checker) parseBuiltInFuncs(ss []string, generic bool) (map[t.QQID]*a.Func, error) {
	m := map[t.QQID]*a.Func(nil)
	if generic {
		m = map[t.QQID]*a.Func{}
	}

	buf := []byte(nil)
	for _, s := range ss {
		buf = buf[:0]
		buf = append(buf, "pub func "...)
		buf = append(buf, s...)
		buf = append(buf, "{}\n"...)

		const filename = "builtin.wuffs"
		tokens, _, err := t.Tokenize(c.tm, filename, buf)
		if err != nil {
			return nil, fmt.Errorf("check: parsing %q: could not tokenize built-in funcs: %v", s, err)
		}
		if generic {
			for i := range tokens {
				if tokens[i].ID == builtin.GenericOldName1 {
					tokens[i].ID = builtin.GenericNewName1
				} else if tokens[i].ID == builtin.GenericOldName2 {
					tokens[i].ID = builtin.GenericNewName2
				}
			}
		}
		file, err := parse.Parse(c.tm, filename, tokens, &parse.Options{
			AllowBuiltInNames: true,
		})
		if err != nil {
			return nil, fmt.Errorf("check: parsing %q: could not parse built-in funcs: %v", s, err)
		}

		tlds := file.TopLevelDecls()
		if len(tlds) != 1 || tlds[0].Kind() != a.KFunc {
			return nil, fmt.Errorf("check: parsing %q: got %d top level decls, want %d", s, len(tlds), 1)
		}
		f := tlds[0].AsFunc()
		f.AsNode().AsRaw().SetPackage(c.tm, t.IDBase)
		if err := c.checkFuncSignature(f.AsNode()); err != nil {
			return nil, err
		}

		if m != nil {
			m[f.QQID()] = f
		}
	}
	return m, nil
}

func (c *Checker) resolveFunc(typ *a.TypeExpr) (*a.Func, error) {
	if typ.Decorator() != t.IDFunc {
		return nil, fmt.Errorf("check: resolveFunc cannot look up non-func TypeExpr %q", typ.Str(c.tm))
	}
	lTyp := typ.Receiver()
	lQID := lTyp.QID()
	qqid := t.QQID{lQID[0], lQID[1], typ.FuncName()}

	if lTyp.IsSliceType() {
		qqid[0] = t.IDBase
		qqid[1] = t.IDDagger1
		if f := c.builtInSliceFuncs[qqid]; f != nil {
			return f, nil
		}

	} else if lTyp.IsTableType() {
		qqid[0] = t.IDBase
		qqid[1] = t.IDDagger2
		if f := c.builtInTableFuncs[qqid]; f != nil {
			return f, nil
		}

	} else if f := c.funcs[qqid]; f != nil {
		return f, nil
	}
	return nil, fmt.Errorf("check: resolveFunc cannot look up %q", typ.Str(c.tm))
}
<commit_msg>Remove redundant "go generate" line<commit_after>// Copyright 2017 The Wuffs Authors.
//
// 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
//
//    https://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 check

import (
	"fmt"

	"github.com/google/wuffs/lang/builtin"
	"github.com/google/wuffs/lang/parse"

	a "github.com/google/wuffs/lang/ast"
	t "github.com/google/wuffs/lang/token"
)

var (
	exprArgs    = a.NewExpr(0, 0, 0, t.IDArgs, nil, nil, nil, nil)
	exprNullptr = a.NewExpr(0, 0, 0, t.IDNullptr, nil, nil, nil, nil)
	exprThis    = a.NewExpr(0, 0, 0, t.IDThis, nil, nil, nil, nil)
)

var (
	typeExprGeneric1    = a.NewTypeExpr(0, t.IDBase, t.IDDagger1, nil, nil, nil)
	typeExprGeneric2    = a.NewTypeExpr(0, t.IDBase, t.IDDagger2, nil, nil, nil)
	typeExprIdeal       = a.NewTypeExpr(0, t.IDBase, t.IDQIdeal, nil, nil, nil)
	typeExprList        = a.NewTypeExpr(0, t.IDBase, t.IDComma, nil, nil, nil)
	typeExprNullptr     = a.NewTypeExpr(0, t.IDBase, t.IDQNullptr, nil, nil, nil)
	typeExprPlaceholder = a.NewTypeExpr(0, t.IDBase, t.IDQPlaceholder, nil, nil, nil)
	typeExprTypeExpr    = a.NewTypeExpr(0, t.IDBase, t.IDQTypeExpr, nil, nil, nil)

	typeExprU8  = a.NewTypeExpr(0, t.IDBase, t.IDU8, nil, nil, nil)
	typeExprU16 = a.NewTypeExpr(0, t.IDBase, t.IDU16, nil, nil, nil)
	typeExprU32 = a.NewTypeExpr(0, t.IDBase, t.IDU32, nil, nil, nil)
	typeExprU64 = a.NewTypeExpr(0, t.IDBase, t.IDU64, nil, nil, nil)

	typeExprEmptyStruct = a.NewTypeExpr(0, t.IDBase, t.IDEmptyStruct, nil, nil, nil)
	typeExprBool        = a.NewTypeExpr(0, t.IDBase, t.IDBool, nil, nil, nil)
	typeExprUtility     = a.NewTypeExpr(0, t.IDBase, t.IDUtility, nil, nil, nil)

	typeExprRangeIEU32 = a.NewTypeExpr(0, t.IDBase, t.IDRangeIEU32, nil, nil, nil)
	typeExprRangeIIU32 = a.NewTypeExpr(0, t.IDBase, t.IDRangeIIU32, nil, nil, nil)
	typeExprRangeIEU64 = a.NewTypeExpr(0, t.IDBase, t.IDRangeIEU64, nil, nil, nil)
	typeExprRangeIIU64 = a.NewTypeExpr(0, t.IDBase, t.IDRangeIIU64, nil, nil, nil)
	typeExprRectIEU32  = a.NewTypeExpr(0, t.IDBase, t.IDRectIEU32, nil, nil, nil)
	typeExprRectIIU32  = a.NewTypeExpr(0, t.IDBase, t.IDRectIIU32, nil, nil, nil)

	typeExprIOReader = a.NewTypeExpr(0, t.IDBase, t.IDIOReader, nil, nil, nil)
	typeExprIOWriter = a.NewTypeExpr(0, t.IDBase, t.IDIOWriter, nil, nil, nil)
	typeExprStatus   = a.NewTypeExpr(0, t.IDBase, t.IDStatus, nil, nil, nil)

	typeExprFrameConfig   = a.NewTypeExpr(0, t.IDBase, t.IDFrameConfig, nil, nil, nil)
	typeExprImageConfig   = a.NewTypeExpr(0, t.IDBase, t.IDImageConfig, nil, nil, nil)
	typeExprPixelBuffer   = a.NewTypeExpr(0, t.IDBase, t.IDPixelBuffer, nil, nil, nil)
	typeExprPixelConfig   = a.NewTypeExpr(0, t.IDBase, t.IDPixelConfig, nil, nil, nil)
	typeExprPixelSwizzler = a.NewTypeExpr(0, t.IDBase, t.IDPixelSwizzler, nil, nil, nil)

	typeExprDecodeFrameOptions = a.NewTypeExpr(0, t.IDBase, t.IDDecodeFrameOptions, nil, nil, nil)

	typeExprSliceU8 = a.NewTypeExpr(t.IDSlice, 0, 0, nil, nil, typeExprU8)
	typeExprTableU8 = a.NewTypeExpr(t.IDTable, 0, 0, nil, nil, typeExprU8)
)

func setPlaceholderMBoundsMType(n *a.Node) {
	n.SetMBounds(bounds{zero, zero})
	n.SetMType(typeExprPlaceholder)
}

// typeMap maps from variable names (as token IDs) to types.
type typeMap map[t.ID]*a.TypeExpr

var builtInTypeMap = typeMap{
	t.IDU8:  typeExprU8,
	t.IDU16: typeExprU16,
	t.IDU32: typeExprU32,
	t.IDU64: typeExprU64,

	t.IDEmptyStruct: typeExprEmptyStruct,
	t.IDBool:        typeExprBool,
	t.IDUtility:     typeExprUtility,

	t.IDRangeIEU32: typeExprRangeIEU32,
	t.IDRangeIIU32: typeExprRangeIIU32,
	t.IDRangeIEU64: typeExprRangeIEU64,
	t.IDRangeIIU64: typeExprRangeIIU64,
	t.IDRectIEU32:  typeExprRectIEU32,
	t.IDRectIIU32:  typeExprRectIIU32,

	t.IDIOReader: typeExprIOReader,
	t.IDIOWriter: typeExprIOWriter,
	t.IDStatus:   typeExprStatus,

	t.IDFrameConfig:   typeExprFrameConfig,
	t.IDImageConfig:   typeExprImageConfig,
	t.IDPixelBuffer:   typeExprPixelBuffer,
	t.IDPixelConfig:   typeExprPixelConfig,
	t.IDPixelSwizzler: typeExprPixelSwizzler,

	t.IDDecodeFrameOptions: typeExprDecodeFrameOptions,
}

func (c *Checker) parseBuiltInFuncs(ss []string, generic bool) (map[t.QQID]*a.Func, error) {
	m := map[t.QQID]*a.Func(nil)
	if generic {
		m = map[t.QQID]*a.Func{}
	}

	buf := []byte(nil)
	for _, s := range ss {
		buf = buf[:0]
		buf = append(buf, "pub func "...)
		buf = append(buf, s...)
		buf = append(buf, "{}\n"...)

		const filename = "builtin.wuffs"
		tokens, _, err := t.Tokenize(c.tm, filename, buf)
		if err != nil {
			return nil, fmt.Errorf("check: parsing %q: could not tokenize built-in funcs: %v", s, err)
		}
		if generic {
			for i := range tokens {
				if tokens[i].ID == builtin.GenericOldName1 {
					tokens[i].ID = builtin.GenericNewName1
				} else if tokens[i].ID == builtin.GenericOldName2 {
					tokens[i].ID = builtin.GenericNewName2
				}
			}
		}
		file, err := parse.Parse(c.tm, filename, tokens, &parse.Options{
			AllowBuiltInNames: true,
		})
		if err != nil {
			return nil, fmt.Errorf("check: parsing %q: could not parse built-in funcs: %v", s, err)
		}

		tlds := file.TopLevelDecls()
		if len(tlds) != 1 || tlds[0].Kind() != a.KFunc {
			return nil, fmt.Errorf("check: parsing %q: got %d top level decls, want %d", s, len(tlds), 1)
		}
		f := tlds[0].AsFunc()
		f.AsNode().AsRaw().SetPackage(c.tm, t.IDBase)
		if err := c.checkFuncSignature(f.AsNode()); err != nil {
			return nil, err
		}

		if m != nil {
			m[f.QQID()] = f
		}
	}
	return m, nil
}

func (c *Checker) resolveFunc(typ *a.TypeExpr) (*a.Func, error) {
	if typ.Decorator() != t.IDFunc {
		return nil, fmt.Errorf("check: resolveFunc cannot look up non-func TypeExpr %q", typ.Str(c.tm))
	}
	lTyp := typ.Receiver()
	lQID := lTyp.QID()
	qqid := t.QQID{lQID[0], lQID[1], typ.FuncName()}

	if lTyp.IsSliceType() {
		qqid[0] = t.IDBase
		qqid[1] = t.IDDagger1
		if f := c.builtInSliceFuncs[qqid]; f != nil {
			return f, nil
		}

	} else if lTyp.IsTableType() {
		qqid[0] = t.IDBase
		qqid[1] = t.IDDagger2
		if f := c.builtInTableFuncs[qqid]; f != nil {
			return f, nil
		}

	} else if f := c.funcs[qqid]; f != nil {
		return f, nil
	}
	return nil, fmt.Errorf("check: resolveFunc cannot look up %q", typ.Str(c.tm))
}
<|endoftext|>


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

package sparc64

import "cmd/internal/obj"

// General purpose registers, kept in the low bits of Prog.Reg.
const (
	// integer
	REG_R0 = obj.RBaseSPARC64 + iota
	REG_R1
	REG_R2
	REG_R3
	REG_R4
	REG_R5
	REG_R6
	REG_R7
	REG_R8
	REG_R9
	REG_R10
	REG_R11
	REG_R12
	REG_R13
	REG_R14
	REG_R15
	REG_R16
	REG_R17
	REG_R18
	REG_R19
	REG_R20
	REG_R21
	REG_R22
	REG_R23
	REG_R24
	REG_R25
	REG_R26
	REG_R27
	REG_R28
	REG_R29
	REG_R30
	REG_R31

	// single-precision floating point
	REG_F0
	REG_F1
	REG_F2
	REG_F3
	REG_F4
	REG_F5
	REG_F6
	REG_F7
	REG_F8
	REG_F9
	REG_F10
	REG_F11
	REG_F12
	REG_F13
	REG_F14
	REG_F15
	REG_F16
	REG_F17
	REG_F18
	REG_F19
	REG_F20
	REG_F21
	REG_F22
	REG_F23
	REG_F24
	REG_F25
	REG_F26
	REG_F27
	REG_F28
	REG_F29
	REG_F30
	REG_F31

	// double-precision floating point; the first half is aliased to
	// single-precision registers, that is: Dn is aliased to Fn, Fn+1,
	// where n ≤ 30.
	REG_D0
	REG_D32
	REG_D2
	REG_D34
	REG_D4
	REG_D36
	REG_D6
	REG_D38
	REG_D8
	REG_D40
	REG_D10
	REG_D42
	REG_D12
	REG_D44
	REG_D14
	REG_D46
	REG_D16
	REG_D48
	REG_D18
	REG_D50
	REG_D20
	REG_D52
	REG_D22
	REG_D54
	REG_D24
	REG_D56
	REG_D26
	REG_D58
	REG_D28
	REG_D60
	REG_D30
	REG_D62

	// common single/double-precision virtualized registers.
	// Yn is aliased to F2n, F2n+1, D2n.
	REG_Y0
	REG_Y1
	REG_Y2
	REG_Y3
	REG_Y4
	REG_Y5
	REG_Y6
	REG_Y7
	REG_Y8
	REG_Y9
	REG_Y10
	REG_Y11
	REG_Y12
	REG_Y13
	REG_Y14
	REG_Y15
)

const (
	// floating-point condition-code registers
	REG_FCC0 = REG_R0 + 256 + iota
	REG_FCC1
	REG_FCC2
	REG_FCC3
)

const (
	// integer condition-code flags
	REG_ICC = REG_R0 + 384
	REG_XCC = REG_R0 + 384 + 2
)

const (
	REG_SPECIAL = REG_R0 + 512

	REG_CCR  = REG_SPECIAL + 2
	REG_TICK = REG_SPECIAL + 4
	REG_RPC  = REG_SPECIAL + 5

	REG_BSP = REG_RSP + 256
	REG_BFP = REG_RFP + 256

	REG_LAST = REG_R0 + 1024
)

// Register assignments:
const (
	REG_ZR   = REG_R0
	REG_TLS  = REG_R7
	REG_RSP  = REG_R14
	REG_LR   = REG_R15
	REG_G    = REG_R22
	REG_TMP2 = REG_R23
	REG_TMP  = REG_R26
	REG_RT1  = REG_R27
	REG_RT2  = REG_R28
	REG_CTXT = REG_R29
	REG_RFP  = REG_R30
	REG_OLR  = REG_R31
	REG_FTMP = REG_F0
	REG_DTMP = REG_D0
	REG_YTMP = REG_Y0
)

const (
	REG_MIN = REG_R0
	REG_MAX = REG_R25
)

const (
	StackAlign            = 8      // ABI says 16
	StackBias             = 0x7ff  // craziness
	WindowSaveAreaSize    = 16 * 8 // only slots for RFP and PLR used
	ArgumentsSaveAreaSize = 0      // unused, normally 6 * 8
	MinStackFrameSize     = WindowSaveAreaSize + ArgumentsSaveAreaSize
)

const (
	BIG = 1<<12 - 1 // magnitude of smallest negative immediate
)

// Prog.mark
const (
	FOLL = 1 << iota
	LABEL
	LEAF
)

const (
	ClassUnknown = iota

	ClassReg    // R1..R31
	ClassFReg   // F0..F31
	ClassDReg   // D0..D62
	ClassCond   // ICC, XCC
	ClassFCond  // FCC0..FCC3
	ClassSpcReg // TICK, CCR, etc

	ClassZero     // $0 or ZR
	ClassConst5   // unsigned 5-bit constant
	ClassConst6   // unsigned 6-bit constant
	ClassConst10  // signed 10-bit constant
	ClassConst11  // signed 11-bit constant
	ClassConst13  // signed 13-bit constant
	ClassConst31_ // signed 32-bit constant, negative
	ClassConst31  // signed 32-bit constant, positive or zero
	ClassConst32  // 32-bit constant
	ClassConst    // 64-bit constant
	ClassFConst   // floating-point constant

	ClassRegReg     // $(Rn+Rm) or $(Rn)(Rm*1)
	ClassRegConst13 // $n(R), n is 13-bit signed
	ClassRegConst   // $n(R), n large

	ClassIndirRegReg // (Rn+Rm) or (Rn)(Rm*1)
	ClassIndir0      // (R)
	ClassIndir13     // n(R), n is 13-bit signed
	ClassIndir       // n(R), n large

	ClassBranch // n(PC) branch target, n is 21-bit signed, mod 4

	ClassAddr    // $sym(SB)
	ClassMem     // sym(SB)
	ClassTLSAddr // $tlssym(SB)
	ClassTLSMem  // tlssym(SB)

	ClassTextSize
	ClassNone

	ClassBias = 64 // BFP or BSP present in Addr, bitwise OR with classes above
)

var cnames = []string{
	ClassUnknown:     "ClassUnknown",
	ClassReg:         "ClassReg",
	ClassFReg:        "ClassFReg",
	ClassDReg:        "ClassDReg",
	ClassCond:        "ClassCond",
	ClassFCond:       "ClassFCond",
	ClassSpcReg:      "ClassSpcReg",
	ClassZero:        "ClassZero",
	ClassConst5:      "ClassConst5",
	ClassConst6:      "ClassConst6",
	ClassConst10:     "ClassConst10",
	ClassConst11:     "ClassConst11",
	ClassConst13:     "ClassConst13",
	ClassConst31_:    "ClassConst31-",
	ClassConst31:     "ClassConst31+",
	ClassConst32:     "ClassConst32",
	ClassConst:       "ClassConst",
	ClassFConst:      "ClassFConst",
	ClassRegReg:      "ClassRegReg",
	ClassRegConst13:  "ClassRegConst13",
	ClassRegConst:    "ClassRegConst",
	ClassIndirRegReg: "ClassIndirRegReg",
	ClassIndir0:      "ClassIndir0",
	ClassIndir13:     "ClassIndir13",
	ClassIndir:       "ClassIndir",
	ClassBranch:      "ClassBranch",
	ClassAddr:        "ClassAddr",
	ClassMem:         "ClassMem",
	ClassTLSAddr:     "ClassTLSAddr",
	ClassTLSMem:      "ClassTLSMem",
	ClassTextSize:    "ClassTextSize",
	ClassNone:        "ClassNone",
	ClassBias:        "ClassBias",
}

//go:generate go run ../stringer.go -i $GOFILE -o anames.go -p sparc64

const (
	AADD = obj.ABaseSPARC64 + obj.A_ARCHSPECIFIC + iota
	AADDCC
	AADDC
	AADDCCC
	AAND
	AANDCC
	AANDN
	AANDNCC

	// These are the two-operand SPARCv9 32-, and 64-bit, branch
	// on integer condition codes with prediction (BPcc), not the
	// single-operand SPARCv8 32-bit branch on integer condition
	// codes (Bicc).
	ABN
	ABNE
	ABE
	ABG
	ABLE
	ABGE
	ABL
	ABGU
	ABLEU
	ABCC
	ABCS
	ABPOS
	ABNEG
	ABVC
	ABVS

	ABRZ
	ABRLEZ
	ABRLZ
	ABRNZ
	ABRGZ
	ABRGEZ
	ACASW
	ACASD
	AFABSS
	AFABSD
	AFADDS
	AFADDD
	AFBA
	AFBN
	AFBU
	AFBG
	AFBUG
	AFBL
	AFBUL
	AFBLG
	AFBNE
	AFBE
	AFBUE
	AFBGE
	AFBUGE
	AFBLE
	AFBULE
	AFBO
	AFCMPS
	AFCMPD
	AFDIVS
	AFDIVD
	AFITOS
	AFITOD
	AFLUSH
	AFMOVS // the SPARC64 instruction, and alias for loads and stores
	AFMOVD // the SPARC64 instruction, and alias for loads and stores
	AFMULS
	AFMULD
	AFSMULD
	AFNEGS
	AFNEGD
	AFSQRTS
	AFSQRTD
	AFSTOX
	AFDTOX
	AFSTOI
	AFDTOI
	AFSTOD
	AFDTOS
	AFSUBS
	AFSUBD
	AFXTOS
	AFXTOD
	AJMPL
	ALDSB
	ALDSH
	ALDSW
	ALDUB
	ALDD
	ALDDF
	ALDSF
	ALDUH
	ALDUW
	AMEMBAR
	AMOVA
	AMOVCC
	AMOVCS
	AMOVE
	AMOVG
	AMOVGE
	AMOVGU
	AMOVL
	AMOVLE
	AMOVLEU
	AMOVN
	AMOVNE
	AMOVNEG
	AMOVPOS
	AMOVRGEZ
	AMOVRGZ
	AMOVRLEZ
	AMOVRLZ
	AMOVRNZ
	AMOVRZ
	AMOVVC
	AMOVVS
	AMULD
	AOR
	AORCC
	AORN
	AORNCC
	ARD
	ASDIVD
	ASETHI
	AUDIVD
	ASLLW
	ASRLW
	ASRAW
	ASLLD
	ASRLD
	ASRAD
	ASTB
	ASTH
	ASTW
	ASTD
	ASTSF
	ASTDF
	ASUB
	ASUBCC
	ASUBC
	ASUBCCC
	ATA
	AXOR
	AXORCC
	AXNOR
	AXNORCC

	// Pseudo-instructions, aliases to SPARC64 instructions and
	// synthetic instructions.
	ACMP // SUBCC R1, R2, ZR
	ANEG
	AMOVUB
	AMOVB
	AMOVUH
	AMOVH
	AMOVUW
	AMOVW
	AMOVD // also the SPARC64 synthetic instruction
	ARNOP // SETHI $0, ZR

	// These are aliases to two-operand SPARCv9 32-, and 64-bit,
	// branch on integer condition codes with prediction (BPcc),
	// with ICC implied.
	ABNW
	ABNEW
	ABEW
	ABGW
	ABLEW
	ABGEW
	ABLW
	ABGUW
	ABLEUW
	ABCCW
	ABCSW
	ABPOSW
	ABNEGW
	ABVCW
	ABVSW

	// These are aliases to two-operand SPARCv9 32-, and 64-bit,
	// branch on integer condition codes with prediction (BPcc),
	// with XCC implied.
	ABND
	ABNED
	ABED
	ABGD
	ABLED
	ABGED
	ABLD
	ABGUD
	ABLEUD
	ABCCD
	ABCSD
	ABPOSD
	ABNEGD
	ABVCD
	ABVSD

	AWORD
	ADWORD

	ALAST
)
<commit_msg>cmd/internal/obj/sparc64: make ArgumentsSaveAreaSize=6*8<commit_after>// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package sparc64

import "cmd/internal/obj"

// General purpose registers, kept in the low bits of Prog.Reg.
const (
	// integer
	REG_R0 = obj.RBaseSPARC64 + iota
	REG_R1
	REG_R2
	REG_R3
	REG_R4
	REG_R5
	REG_R6
	REG_R7
	REG_R8
	REG_R9
	REG_R10
	REG_R11
	REG_R12
	REG_R13
	REG_R14
	REG_R15
	REG_R16
	REG_R17
	REG_R18
	REG_R19
	REG_R20
	REG_R21
	REG_R22
	REG_R23
	REG_R24
	REG_R25
	REG_R26
	REG_R27
	REG_R28
	REG_R29
	REG_R30
	REG_R31

	// single-precision floating point
	REG_F0
	REG_F1
	REG_F2
	REG_F3
	REG_F4
	REG_F5
	REG_F6
	REG_F7
	REG_F8
	REG_F9
	REG_F10
	REG_F11
	REG_F12
	REG_F13
	REG_F14
	REG_F15
	REG_F16
	REG_F17
	REG_F18
	REG_F19
	REG_F20
	REG_F21
	REG_F22
	REG_F23
	REG_F24
	REG_F25
	REG_F26
	REG_F27
	REG_F28
	REG_F29
	REG_F30
	REG_F31

	// double-precision floating point; the first half is aliased to
	// single-precision registers, that is: Dn is aliased to Fn, Fn+1,
	// where n ≤ 30.
	REG_D0
	REG_D32
	REG_D2
	REG_D34
	REG_D4
	REG_D36
	REG_D6
	REG_D38
	REG_D8
	REG_D40
	REG_D10
	REG_D42
	REG_D12
	REG_D44
	REG_D14
	REG_D46
	REG_D16
	REG_D48
	REG_D18
	REG_D50
	REG_D20
	REG_D52
	REG_D22
	REG_D54
	REG_D24
	REG_D56
	REG_D26
	REG_D58
	REG_D28
	REG_D60
	REG_D30
	REG_D62

	// common single/double-precision virtualized registers.
	// Yn is aliased to F2n, F2n+1, D2n.
	REG_Y0
	REG_Y1
	REG_Y2
	REG_Y3
	REG_Y4
	REG_Y5
	REG_Y6
	REG_Y7
	REG_Y8
	REG_Y9
	REG_Y10
	REG_Y11
	REG_Y12
	REG_Y13
	REG_Y14
	REG_Y15
)

const (
	// floating-point condition-code registers
	REG_FCC0 = REG_R0 + 256 + iota
	REG_FCC1
	REG_FCC2
	REG_FCC3
)

const (
	// integer condition-code flags
	REG_ICC = REG_R0 + 384
	REG_XCC = REG_R0 + 384 + 2
)

const (
	REG_SPECIAL = REG_R0 + 512

	REG_CCR  = REG_SPECIAL + 2
	REG_TICK = REG_SPECIAL + 4
	REG_RPC  = REG_SPECIAL + 5

	REG_BSP = REG_RSP + 256
	REG_BFP = REG_RFP + 256

	REG_LAST = REG_R0 + 1024
)

// Register assignments:
const (
	REG_ZR   = REG_R0
	REG_TLS  = REG_R7
	REG_RSP  = REG_R14
	REG_LR   = REG_R15
	REG_G    = REG_R22
	REG_TMP2 = REG_R23
	REG_TMP  = REG_R26
	REG_RT1  = REG_R27
	REG_RT2  = REG_R28
	REG_CTXT = REG_R29
	REG_RFP  = REG_R30
	REG_OLR  = REG_R31
	REG_FTMP = REG_F0
	REG_DTMP = REG_D0
	REG_YTMP = REG_Y0
)

const (
	REG_MIN = REG_R0
	REG_MAX = REG_R25
)

const (
	StackAlign            = 8      // ABI says 16
	StackBias             = 0x7ff  // craziness
	WindowSaveAreaSize    = 16 * 8 // only slots for RFP and PLR used
	ArgumentsSaveAreaSize = 6 * 8  // unused
	MinStackFrameSize     = WindowSaveAreaSize + ArgumentsSaveAreaSize
)

const (
	BIG = 1<<12 - 1 // magnitude of smallest negative immediate
)

// Prog.mark
const (
	FOLL = 1 << iota
	LABEL
	LEAF
)

const (
	ClassUnknown = iota

	ClassReg    // R1..R31
	ClassFReg   // F0..F31
	ClassDReg   // D0..D62
	ClassCond   // ICC, XCC
	ClassFCond  // FCC0..FCC3
	ClassSpcReg // TICK, CCR, etc

	ClassZero     // $0 or ZR
	ClassConst5   // unsigned 5-bit constant
	ClassConst6   // unsigned 6-bit constant
	ClassConst10  // signed 10-bit constant
	ClassConst11  // signed 11-bit constant
	ClassConst13  // signed 13-bit constant
	ClassConst31_ // signed 32-bit constant, negative
	ClassConst31  // signed 32-bit constant, positive or zero
	ClassConst32  // 32-bit constant
	ClassConst    // 64-bit constant
	ClassFConst   // floating-point constant

	ClassRegReg     // $(Rn+Rm) or $(Rn)(Rm*1)
	ClassRegConst13 // $n(R), n is 13-bit signed
	ClassRegConst   // $n(R), n large

	ClassIndirRegReg // (Rn+Rm) or (Rn)(Rm*1)
	ClassIndir0      // (R)
	ClassIndir13     // n(R), n is 13-bit signed
	ClassIndir       // n(R), n large

	ClassBranch // n(PC) branch target, n is 21-bit signed, mod 4

	ClassAddr    // $sym(SB)
	ClassMem     // sym(SB)
	ClassTLSAddr // $tlssym(SB)
	ClassTLSMem  // tlssym(SB)

	ClassTextSize
	ClassNone

	ClassBias = 64 // BFP or BSP present in Addr, bitwise OR with classes above
)

var cnames = []string{
	ClassUnknown:     "ClassUnknown",
	ClassReg:         "ClassReg",
	ClassFReg:        "ClassFReg",
	ClassDReg:        "ClassDReg",
	ClassCond:        "ClassCond",
	ClassFCond:       "ClassFCond",
	ClassSpcReg:      "ClassSpcReg",
	ClassZero:        "ClassZero",
	ClassConst5:      "ClassConst5",
	ClassConst6:      "ClassConst6",
	ClassConst10:     "ClassConst10",
	ClassConst11:     "ClassConst11",
	ClassConst13:     "ClassConst13",
	ClassConst31_:    "ClassConst31-",
	ClassConst31:     "ClassConst31+",
	ClassConst32:     "ClassConst32",
	ClassConst:       "ClassConst",
	ClassFConst:      "ClassFConst",
	ClassRegReg:      "ClassRegReg",
	ClassRegConst13:  "ClassRegConst13",
	ClassRegConst:    "ClassRegConst",
	ClassIndirRegReg: "ClassIndirRegReg",
	ClassIndir0:      "ClassIndir0",
	ClassIndir13:     "ClassIndir13",
	ClassIndir:       "ClassIndir",
	ClassBranch:      "ClassBranch",
	ClassAddr:        "ClassAddr",
	ClassMem:         "ClassMem",
	ClassTLSAddr:     "ClassTLSAddr",
	ClassTLSMem:      "ClassTLSMem",
	ClassTextSize:    "ClassTextSize",
	ClassNone:        "ClassNone",
	ClassBias:        "ClassBias",
}

//go:generate go run ../stringer.go -i $GOFILE -o anames.go -p sparc64

const (
	AADD = obj.ABaseSPARC64 + obj.A_ARCHSPECIFIC + iota
	AADDCC
	AADDC
	AADDCCC
	AAND
	AANDCC
	AANDN
	AANDNCC

	// These are the two-operand SPARCv9 32-, and 64-bit, branch
	// on integer condition codes with prediction (BPcc), not the
	// single-operand SPARCv8 32-bit branch on integer condition
	// codes (Bicc).
	ABN
	ABNE
	ABE
	ABG
	ABLE
	ABGE
	ABL
	ABGU
	ABLEU
	ABCC
	ABCS
	ABPOS
	ABNEG
	ABVC
	ABVS

	ABRZ
	ABRLEZ
	ABRLZ
	ABRNZ
	ABRGZ
	ABRGEZ
	ACASW
	ACASD
	AFABSS
	AFABSD
	AFADDS
	AFADDD
	AFBA
	AFBN
	AFBU
	AFBG
	AFBUG
	AFBL
	AFBUL
	AFBLG
	AFBNE
	AFBE
	AFBUE
	AFBGE
	AFBUGE
	AFBLE
	AFBULE
	AFBO
	AFCMPS
	AFCMPD
	AFDIVS
	AFDIVD
	AFITOS
	AFITOD
	AFLUSH
	AFMOVS // the SPARC64 instruction, and alias for loads and stores
	AFMOVD // the SPARC64 instruction, and alias for loads and stores
	AFMULS
	AFMULD
	AFSMULD
	AFNEGS
	AFNEGD
	AFSQRTS
	AFSQRTD
	AFSTOX
	AFDTOX
	AFSTOI
	AFDTOI
	AFSTOD
	AFDTOS
	AFSUBS
	AFSUBD
	AFXTOS
	AFXTOD
	AJMPL
	ALDSB
	ALDSH
	ALDSW
	ALDUB
	ALDD
	ALDDF
	ALDSF
	ALDUH
	ALDUW
	AMEMBAR
	AMOVA
	AMOVCC
	AMOVCS
	AMOVE
	AMOVG
	AMOVGE
	AMOVGU
	AMOVL
	AMOVLE
	AMOVLEU
	AMOVN
	AMOVNE
	AMOVNEG
	AMOVPOS
	AMOVRGEZ
	AMOVRGZ
	AMOVRLEZ
	AMOVRLZ
	AMOVRNZ
	AMOVRZ
	AMOVVC
	AMOVVS
	AMULD
	AOR
	AORCC
	AORN
	AORNCC
	ARD
	ASDIVD
	ASETHI
	AUDIVD
	ASLLW
	ASRLW
	ASRAW
	ASLLD
	ASRLD
	ASRAD
	ASTB
	ASTH
	ASTW
	ASTD
	ASTSF
	ASTDF
	ASUB
	ASUBCC
	ASUBC
	ASUBCCC
	ATA
	AXOR
	AXORCC
	AXNOR
	AXNORCC

	// Pseudo-instructions, aliases to SPARC64 instructions and
	// synthetic instructions.
	ACMP // SUBCC R1, R2, ZR
	ANEG
	AMOVUB
	AMOVB
	AMOVUH
	AMOVH
	AMOVUW
	AMOVW
	AMOVD // also the SPARC64 synthetic instruction
	ARNOP // SETHI $0, ZR

	// These are aliases to two-operand SPARCv9 32-, and 64-bit,
	// branch on integer condition codes with prediction (BPcc),
	// with ICC implied.
	ABNW
	ABNEW
	ABEW
	ABGW
	ABLEW
	ABGEW
	ABLW
	ABGUW
	ABLEUW
	ABCCW
	ABCSW
	ABPOSW
	ABNEGW
	ABVCW
	ABVSW

	// These are aliases to two-operand SPARCv9 32-, and 64-bit,
	// branch on integer condition codes with prediction (BPcc),
	// with XCC implied.
	ABND
	ABNED
	ABED
	ABGD
	ABLED
	ABGED
	ABLD
	ABGUD
	ABLEUD
	ABCCD
	ABCSD
	ABPOSD
	ABNEGD
	ABVCD
	ABVSD

	AWORD
	ADWORD

	ALAST
)
<|endoftext|>


<commit_before>package wmi

import (
	"encoding/json"
	"fmt"
	"reflect"
	"strconv"
	"time"

	"github.com/mattn/go-ole"
	"github.com/mattn/go-ole/oleutil"
)

func LoadJSON(data []byte, dst interface{}) error {
	var r Response
	if err := json.Unmarshal(data, &r); err != nil {
		return err
	}
	if len(r.Error) > 0 {
		return fmt.Errorf(r.Error)
	}
	m := r.Response
	dv := reflect.ValueOf(dst)
	if dv.Kind() != reflect.Ptr || dv.IsNil() {
		return ErrInvalidEntityType
	}
	dv = dv.Elem()
	mat, elemType := checkMultiArg(dv)
	if mat == multiArgTypeInvalid {
		return ErrInvalidEntityType
	}
	var errFieldMismatch error
	for _, v := range m {
		ev := reflect.New(elemType)
		if err := loadMap(ev.Interface(), v); err != nil {
			if _, ok := err.(*ErrFieldMismatch); ok {
				// We continue loading entities even in the face of field mismatch errors.
				// If we encounter any other error, that other error is returned. Otherwise,
				// an ErrFieldMismatch is returned.
				errFieldMismatch = err
			} else {
				return err
			}
		}
		if mat != multiArgTypeStructPtr {
			ev = ev.Elem()
		}
		dv.Set(reflect.Append(dv, ev))
	}
	return errFieldMismatch
}

// loadMap loads a map[string]interface{} into a struct pointer.
func loadMap(dst interface{}, src map[string]interface{}) (errFieldMismatch error) {
	v := reflect.ValueOf(dst).Elem()
	for i := 0; i < v.NumField(); i++ {
		f := v.Field(i)
		isPtr := f.Kind() == reflect.Ptr
		if isPtr {
			ptr := reflect.New(f.Type().Elem())
			f.Set(ptr)
			f = f.Elem()
		}
		n := v.Type().Field(i).Name
		if !f.CanSet() {
			return &ErrFieldMismatch{
				StructType: f.Type(),
				FieldName:  n,
				Reason:     "CanSet() is false",
			}
		}
		val, present := src[n]
		if !present {
			errFieldMismatch = &ErrFieldMismatch{
				StructType: f.Type(),
				FieldName:  n,
				Reason:     "no such struct field",
			}
			continue
		}
		switch reflect.ValueOf(val).Kind() {
		case reflect.Int64:
			iv := val.(int64)
			switch f.Kind() {
			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
				f.SetInt(iv)
			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
				f.SetUint(uint64(iv))
			default:
				return &ErrFieldMismatch{
					StructType: f.Type(),
					FieldName:  n,
					Reason:     "not an integer class",
				}
			}
		case reflect.Float64:
			iv := val.(float64)
			switch f.Kind() {
			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
				f.SetInt(int64(iv))
			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
				f.SetUint(uint64(iv))
			case reflect.Float32, reflect.Float64:
				f.SetFloat(iv)
			default:
				return &ErrFieldMismatch{
					StructType: f.Type(),
					FieldName:  n,
					Reason:     "not a number class",
				}
			}
		case reflect.String:
			sv := val.(string)
			iv, err := strconv.ParseInt(sv, 10, 64)
			switch f.Kind() {
			case reflect.String:
				f.SetString(sv)
			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
				if err != nil {
					return err
				}
				f.SetInt(iv)
			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
				if err != nil {
					return err
				}
				f.SetUint(uint64(iv))
			case reflect.Struct:
				switch f.Type() {
				case timeType:
					if len(sv) == 25 {
						sv = sv[:22] + "0" + sv[22:]
					}
					t, err := time.Parse("20060102150405.000000-0700", sv)
					if err != nil {
						return err
					}
					f.Set(reflect.ValueOf(t))
				}
			}
		case reflect.Bool:
			bv := val.(bool)
			switch f.Kind() {
			case reflect.Bool:
				f.SetBool(bv)
			default:
				return &ErrFieldMismatch{
					StructType: f.Type(),
					FieldName:  n,
					Reason:     "not a bool",
				}
			}
		default:
			typeof := reflect.TypeOf(val)
			if isPtr && typeof == nil {
				break
			}
			return fmt.Errorf("wmi: could not unmarshal %v with type %v", n, typeof)
		}
	}
	return errFieldMismatch
}

func QueryGen(query string, columns []string, connectServerArgs ...interface{}) ([]map[string]interface{}, error) {
	var res []map[string]interface{}
	ole.CoInitializeEx(0, 0)
	unknown, err := oleutil.CreateObject("WbemScripting.SWbemLocator")
	if err != nil {
		return nil, err
	}
	defer unknown.Release()

	wmi, err := unknown.QueryInterface(ole.IID_IDispatch)
	if err != nil {
		return nil, err
	}
	defer wmi.Release()

	// service is a SWbemServices
	serviceRaw, err := oleutil.CallMethod(wmi, "ConnectServer", connectServerArgs...)
	if err != nil {
		return nil, err
	}

	service := serviceRaw.ToIDispatch()
	defer service.Release()

	// result is a SWBemObjectSet
	resultRaw, err := oleutil.CallMethod(service, "ExecQuery", query)
	if err != nil {
		return nil, err
	}
	result := resultRaw.ToIDispatch()
	defer result.Release()

	count, err := oleInt64(result, "Count")
	if err != nil {
		return nil, err
	}

	for i := int64(0); i < count; i++ {
		// item is a SWbemObject, but really a Win32_Process
		itemRaw, err := oleutil.CallMethod(result, "ItemIndex", i)
		if err != nil {
			return nil, err
		}
		item := itemRaw.ToIDispatch()
		defer item.Release()
		m := make(map[string]interface{})
		for _, c := range columns {
			prop, err := oleutil.GetProperty(item, c)
			if err != nil {
				return nil, err
			}
			m[c] = prop.Value()
		}
		res = append(res, m)
	}
	return res, nil
}

type WmiQuery struct {
	Query     string
	Namespace string
}

type Response struct {
	Error    string `json:",omitempty"`
	Response []map[string]interface{}
}
<commit_msg>Document the JSON funcs<commit_after>package wmi

import (
	"encoding/json"
	"fmt"
	"reflect"
	"strconv"
	"time"

	"github.com/mattn/go-ole"
	"github.com/mattn/go-ole/oleutil"
)

// LoadJSON loads JSON data into dst
func LoadJSON(data []byte, dst interface{}) error {
	var r Response
	if err := json.Unmarshal(data, &r); err != nil {
		return err
	}
	if len(r.Error) > 0 {
		return fmt.Errorf(r.Error)
	}
	m := r.Response
	dv := reflect.ValueOf(dst)
	if dv.Kind() != reflect.Ptr || dv.IsNil() {
		return ErrInvalidEntityType
	}
	dv = dv.Elem()
	mat, elemType := checkMultiArg(dv)
	if mat == multiArgTypeInvalid {
		return ErrInvalidEntityType
	}
	var errFieldMismatch error
	for _, v := range m {
		ev := reflect.New(elemType)
		if err := loadMap(ev.Interface(), v); err != nil {
			if _, ok := err.(*ErrFieldMismatch); ok {
				// We continue loading entities even in the face of field mismatch errors.
				// If we encounter any other error, that other error is returned. Otherwise,
				// an ErrFieldMismatch is returned.
				errFieldMismatch = err
			} else {
				return err
			}
		}
		if mat != multiArgTypeStructPtr {
			ev = ev.Elem()
		}
		dv.Set(reflect.Append(dv, ev))
	}
	return errFieldMismatch
}

// loadMap loads a map[string]interface{} into a struct pointer.
func loadMap(dst interface{}, src map[string]interface{}) (errFieldMismatch error) {
	v := reflect.ValueOf(dst).Elem()
	for i := 0; i < v.NumField(); i++ {
		f := v.Field(i)
		isPtr := f.Kind() == reflect.Ptr
		if isPtr {
			ptr := reflect.New(f.Type().Elem())
			f.Set(ptr)
			f = f.Elem()
		}
		n := v.Type().Field(i).Name
		if !f.CanSet() {
			return &ErrFieldMismatch{
				StructType: f.Type(),
				FieldName:  n,
				Reason:     "CanSet() is false",
			}
		}
		val, present := src[n]
		if !present {
			errFieldMismatch = &ErrFieldMismatch{
				StructType: f.Type(),
				FieldName:  n,
				Reason:     "no such struct field",
			}
			continue
		}
		switch reflect.ValueOf(val).Kind() {
		case reflect.Int64:
			iv := val.(int64)
			switch f.Kind() {
			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
				f.SetInt(iv)
			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
				f.SetUint(uint64(iv))
			default:
				return &ErrFieldMismatch{
					StructType: f.Type(),
					FieldName:  n,
					Reason:     "not an integer class",
				}
			}
		case reflect.Float64:
			iv := val.(float64)
			switch f.Kind() {
			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
				f.SetInt(int64(iv))
			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
				f.SetUint(uint64(iv))
			case reflect.Float32, reflect.Float64:
				f.SetFloat(iv)
			default:
				return &ErrFieldMismatch{
					StructType: f.Type(),
					FieldName:  n,
					Reason:     "not a number class",
				}
			}
		case reflect.String:
			sv := val.(string)
			iv, err := strconv.ParseInt(sv, 10, 64)
			switch f.Kind() {
			case reflect.String:
				f.SetString(sv)
			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
				if err != nil {
					return err
				}
				f.SetInt(iv)
			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
				if err != nil {
					return err
				}
				f.SetUint(uint64(iv))
			case reflect.Struct:
				switch f.Type() {
				case timeType:
					if len(sv) == 25 {
						sv = sv[:22] + "0" + sv[22:]
					}
					t, err := time.Parse("20060102150405.000000-0700", sv)
					if err != nil {
						return err
					}
					f.Set(reflect.ValueOf(t))
				}
			}
		case reflect.Bool:
			bv := val.(bool)
			switch f.Kind() {
			case reflect.Bool:
				f.SetBool(bv)
			default:
				return &ErrFieldMismatch{
					StructType: f.Type(),
					FieldName:  n,
					Reason:     "not a bool",
				}
			}
		default:
			typeof := reflect.TypeOf(val)
			if isPtr && typeof == nil {
				break
			}
			return fmt.Errorf("wmi: could not unmarshal %v with type %v", n, typeof)
		}
	}
	return errFieldMismatch
}

// QueryGen executes query and returns a map with keys of the columns slice.
func QueryGen(query string, columns []string, connectServerArgs ...interface{}) ([]map[string]interface{}, error) {
	var res []map[string]interface{}
	ole.CoInitializeEx(0, 0)
	unknown, err := oleutil.CreateObject("WbemScripting.SWbemLocator")
	if err != nil {
		return nil, err
	}
	defer unknown.Release()

	wmi, err := unknown.QueryInterface(ole.IID_IDispatch)
	if err != nil {
		return nil, err
	}
	defer wmi.Release()

	// service is a SWbemServices
	serviceRaw, err := oleutil.CallMethod(wmi, "ConnectServer", connectServerArgs...)
	if err != nil {
		return nil, err
	}

	service := serviceRaw.ToIDispatch()
	defer service.Release()

	// result is a SWBemObjectSet
	resultRaw, err := oleutil.CallMethod(service, "ExecQuery", query)
	if err != nil {
		return nil, err
	}
	result := resultRaw.ToIDispatch()
	defer result.Release()

	count, err := oleInt64(result, "Count")
	if err != nil {
		return nil, err
	}

	for i := int64(0); i < count; i++ {
		// item is a SWbemObject, but really a Win32_Process
		itemRaw, err := oleutil.CallMethod(result, "ItemIndex", i)
		if err != nil {
			return nil, err
		}
		item := itemRaw.ToIDispatch()
		defer item.Release()
		m := make(map[string]interface{})
		for _, c := range columns {
			prop, err := oleutil.GetProperty(item, c)
			if err != nil {
				return nil, err
			}
			m[c] = prop.Value()
		}
		res = append(res, m)
	}
	return res, nil
}

type WmiQuery struct {
	Query     string
	Namespace string
}

type Response struct {
	Error    string `json:",omitempty"`
	Response []map[string]interface{}
}
<|endoftext|>


<commit_before>package data

import (
	"encoding/xml"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strings"
)

const (
	// DiscoveryQueryParam is the query parameter that is appended to URLs to signal the request is looking for
	// repository information.
	DiscoveryQueryParam = "spread-get=1"

	// DiscoveryMetaName is the the 'name' of the <meta> tag that contains Spread package information.
	DiscoveryMetaName = "spread-ref"
)

// httpClient is a copy of DefaultClient for testing purposes.
var httpClient = http.DefaultClient

// packageInfo contains the data retrieved in the discovery process.
type packageInfo struct {
	// prefix is the package contained in the repo. It should be an exact match or prefix to the requested package name.
	prefix string
	// repoURL is the location of the repository where package data is stored.
	repoURL string
}

// DiscoverPackage uses the package name to fetch a Spread URL to the repository. Set insecure when HTTP is allowed.
// Verbose will print information to STDOUT.
func DiscoverPackage(packageName string, insecure, verbose bool) (packageInfo, error) {
	// first try HTTPS
	urlStr, res, err := fetch("https", packageName, verbose)
	if err != nil || res.StatusCode != 200 {
		if verbose {
			if err != nil {
				fmt.Fprint(Out, "https fetch failed")
			} else {
				fmt.Fprintf(Out, "ignoring https fetch with status code %d", res.StatusCode)
			}
		}
		// fallback to HTTP if insecure is allowed
		if insecure {
			urlStr, res, err = fetch("http", packageName, verbose)
		}
	}
	if err != nil {
		return packageInfo{}, err
	}

	// close body when done
	if res != nil {
		defer res.Body.Close()
	}

	if verbose {
		fmt.Fprintf(Out, "Parsing meta information from '%s' (status code %d)", urlStr, res.StatusCode)
	}

	pkgs, err := parseSpreadRefs(res.Body)
	if err != nil {
		return packageInfo{}, fmt.Errorf("could not parse for Spread references: %v", err)
	} else if len(pkgs) < 1 {
		return packageInfo{}, fmt.Errorf("no reference found at '%s'", urlStr)
	} else if len(pkgs) > 1 && verbose {
		fmt.Fprintf(Out, "found more than one reference at '%s', using first found", urlStr)
	}
	return pkgs[0], nil
}

// fetch retrieves the package using the given scheme and returns the response and a string of the URL of the fetch.
func fetch(scheme, packageName string, verbose bool) (string, *http.Response, error) {
	u, err := url.Parse(scheme + "://" + packageName)
	if err != nil {
		return "", nil, err
	}
	u.RawQuery = DiscoveryQueryParam
	urlStr := u.String()
	if verbose {
		fmt.Fprintf(Out, "fetching %s", urlStr)
	}

	res, err := httpClient.Get(urlStr)
	return urlStr, res, err
}

// parseSpreadRefs reads an HTML document from r and uses it to return information about the package.
// Information is currently stored in a <meta> tag with the name "spread-ref". Based on Go Get parsing code.
func parseSpreadRefs(r io.Reader) (pkgs []packageInfo, err error) {
	d := xml.NewDecoder(r)
	// only support documents encoded with ASCII
	d.CharsetReader = func(charset string, in io.Reader) (io.Reader, error) {
		switch strings.ToLower(charset) {
		case "ascii":
			return in, nil
		default:
			return nil, fmt.Errorf("cannot decode Spread package information encoded in %q", charset)
		}
	}
	d.Strict = false
	var t xml.Token
	for {
		if t, err = d.Token(); err != nil {
			if err == io.EOF {
				err = nil
			}
			return
		}
		if e, ok := t.(xml.StartElement); ok && strings.EqualFold(e.Name.Local, "body") {
			return
		}
		if e, ok := t.(xml.EndElement); ok && strings.EqualFold(e.Name.Local, "head") {
			return
		}
		e, ok := t.(xml.StartElement)
		if !ok || !strings.EqualFold(e.Name.Local, "meta") {
			continue
		}
		if attrValue(e.Attr, "name") != DiscoveryMetaName {
			continue
		}

		if f := strings.Fields(attrValue(e.Attr, "content")); len(f) == 2 {
			pkgs = append(pkgs, packageInfo{
				prefix:  f[0],
				repoURL: f[1],
			})
		}
	}
}

// attrValue returns the attribute value for the case-insensitive key
// `name', or the empty string if nothing is found.
func attrValue(attrs []xml.Attr, name string) string {
	for _, a := range attrs {
		if strings.EqualFold(a.Name.Local, name) {
			return a.Value
		}
	}
	return ""
}
<commit_msg>close body of failed HTTPS discovery requests<commit_after>package data

import (
	"encoding/xml"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strings"
)

const (
	// DiscoveryQueryParam is the query parameter that is appended to URLs to signal the request is looking for
	// repository information.
	DiscoveryQueryParam = "spread-get=1"

	// DiscoveryMetaName is the the 'name' of the <meta> tag that contains Spread package information.
	DiscoveryMetaName = "spread-ref"
)

// httpClient is a copy of DefaultClient for testing purposes.
var httpClient = http.DefaultClient

// packageInfo contains the data retrieved in the discovery process.
type packageInfo struct {
	// prefix is the package contained in the repo. It should be an exact match or prefix to the requested package name.
	prefix string
	// repoURL is the location of the repository where package data is stored.
	repoURL string
}

// DiscoverPackage uses the package name to fetch a Spread URL to the repository. Set insecure when HTTP is allowed.
// Verbose will print information to STDOUT.
func DiscoverPackage(packageName string, insecure, verbose bool) (packageInfo, error) {
	// first try HTTPS
	urlStr, res, err := fetch("https", packageName, verbose)
	if err != nil || res.StatusCode != 200 {
		if verbose {
			if err != nil {
				fmt.Fprint(Out, "https fetch failed")
			} else {
				fmt.Fprintf(Out, "ignoring https fetch with status code %d", res.StatusCode)
			}
		}
		// fallback to HTTP if insecure is allowed
		if insecure {
			if res != nil {
				res.Body.Close()
			}
			urlStr, res, err = fetch("http", packageName, verbose)
		}
	}
	if err != nil {
		return packageInfo{}, err
	}

	// close body when done
	if res != nil {
		defer res.Body.Close()
	}

	if verbose {
		fmt.Fprintf(Out, "Parsing meta information from '%s' (status code %d)", urlStr, res.StatusCode)
	}

	pkgs, err := parseSpreadRefs(res.Body)
	if err != nil {
		return packageInfo{}, fmt.Errorf("could not parse for Spread references: %v", err)
	} else if len(pkgs) < 1 {
		return packageInfo{}, fmt.Errorf("no reference found at '%s'", urlStr)
	} else if len(pkgs) > 1 && verbose {
		fmt.Fprintf(Out, "found more than one reference at '%s', using first found", urlStr)
	}
	return pkgs[0], nil
}

// fetch retrieves the package using the given scheme and returns the response and a string of the URL of the fetch.
func fetch(scheme, packageName string, verbose bool) (string, *http.Response, error) {
	u, err := url.Parse(scheme + "://" + packageName)
	if err != nil {
		return "", nil, err
	}
	u.RawQuery = DiscoveryQueryParam
	urlStr := u.String()
	if verbose {
		fmt.Fprintf(Out, "fetching %s", urlStr)
	}

	res, err := httpClient.Get(urlStr)
	return urlStr, res, err
}

// parseSpreadRefs reads an HTML document from r and uses it to return information about the package.
// Information is currently stored in a <meta> tag with the name "spread-ref". Based on Go Get parsing code.
func parseSpreadRefs(r io.Reader) (pkgs []packageInfo, err error) {
	d := xml.NewDecoder(r)
	// only support documents encoded with ASCII
	d.CharsetReader = func(charset string, in io.Reader) (io.Reader, error) {
		switch strings.ToLower(charset) {
		case "ascii":
			return in, nil
		default:
			return nil, fmt.Errorf("cannot decode Spread package information encoded in %q", charset)
		}
	}
	d.Strict = false
	var t xml.Token
	for {
		if t, err = d.Token(); err != nil {
			if err == io.EOF {
				err = nil
			}
			return
		}
		if e, ok := t.(xml.StartElement); ok && strings.EqualFold(e.Name.Local, "body") {
			return
		}
		if e, ok := t.(xml.EndElement); ok && strings.EqualFold(e.Name.Local, "head") {
			return
		}
		e, ok := t.(xml.StartElement)
		if !ok || !strings.EqualFold(e.Name.Local, "meta") {
			continue
		}
		if attrValue(e.Attr, "name") != DiscoveryMetaName {
			continue
		}

		if f := strings.Fields(attrValue(e.Attr, "content")); len(f) == 2 {
			pkgs = append(pkgs, packageInfo{
				prefix:  f[0],
				repoURL: f[1],
			})
		}
	}
}

// attrValue returns the attribute value for the case-insensitive key
// `name', or the empty string if nothing is found.
func attrValue(attrs []xml.Attr, name string) string {
	for _, a := range attrs {
		if strings.EqualFold(a.Name.Local, name) {
			return a.Value
		}
	}
	return ""
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	"log"

	"github.com/dmnlk/gomadare"
	"github.com/dmnlk/stringUtils"
	"github.com/rem7/goprowl"
	"strings"
)

var (
	CONSUMER_KEY        string
	CONSUMER_KEY_SECRET string
	ACCESS_TOKEN        string
	ACCESS_TOKEN_SECRET string
	SCREEN_NAME			string
	PROWL_API_KEY       string
	PROWL               goprowl.Goprowl
)

func main() {
	err := configureToken()
	if err != nil {
		fmt.Println(err)
		return
	}
	err = PROWL.RegisterKey(PROWL_API_KEY)
	if err != nil {
		fmt.Println(err)
		return
	}

	SCREEN_NAME = os.Getenv("SCREEN_NAME")

	if len(SCREEN_NAME) < 0 {
		return
	}

	client := gomadare.NewClient(CONSUMER_KEY, CONSUMER_KEY_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET)

	client.GetUserStream(nil, func(s gomadare.Status, e gomadare.Event) {
		if &s != nil {
			go sendReplyAndRetweetToProwl(s)
		}
		if &e != nil {
			go sendEventToProwl(e)
		}
	})
}

func configureToken() error {
	CONSUMER_KEY = os.Getenv("CONSUMER_KEY")
	CONSUMER_KEY_SECRET = os.Getenv("CONSUMER_KEY_SECRET")
	ACCESS_TOKEN = os.Getenv("ACCESS_TOKEN")
	ACCESS_TOKEN_SECRET = os.Getenv("ACCESS_TOKEN_SECRET")
	PROWL_API_KEY = os.Getenv("PROWL_API_KEY")
	if ng := stringUtils.IsAnyEmpty(CONSUMER_KEY, CONSUMER_KEY_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET, PROWL_API_KEY); ng {
		return fmt.Errorf("some key invalid")
	}

	return nil
}

func sendEventToProwl(e gomadare.Event) {
	if stringUtils.IsEmpty(e.Event) {
		return
	}

	if (e.Event == "favorite" || e.Event == "unfavorite") && e.Source.ScreenName == SCREEN_NAME {
		return
	}

	emoji := getEventEmoji(e)
	n := &goprowl.Notification{
		Application: "yggdrasill",
		Description: emoji + " " + e.TargetObject.Text,
		Event:       e.Event + " by " + e.Source.ScreenName,
		Priority:    "1",
	}

	PROWL.Push(n)
}

func getEventEmoji(event gomadare.Event) string {
	if event.Event == "favorite" {
		return "\u2b50"
	}
	if event.Event == "unfavorite" {
		return "\U0001f44e"
	}
	if event.Event == "list_member_removed" {
		return "\u274c"
	}
	if event.Event == "list_member_added" {
		return "\u2755"
	}
	if event.Event == "follow" {
		return "\u2661"
	}
	log.Println("unknown event:" + event.Event)
	return event.Event
}

func getProwlNotification(event gomadare.Event) goprowl.Notification {
	n := &goprowl.Notification{
		Application: "Yggdrsill",
		Priority: "1",
	}

	return *n
}

func sendReplyAndRetweetToProwl(s gomadare.Status) {
	// reply Event
	if len(s.Entities.UserMentions) > 0 {
		for _, mention := range s.Entities.UserMentions {
			if mention.ScreenName == "dmnlk" {
				var n *goprowl.Notification
				if strings.Contains(s.Text, "RT") {
					n = &goprowl.Notification{
						Application: "yggdrasill",
						Description: "\U0001f4a1" + " " + s.Text,
						Event:       "RT by " + s.User.ScreenName,
						Priority:    "1",
					}
				} else {
					n = &goprowl.Notification{
						Application: "yggdrasill",
						Description: "\U0001f4a1" + " " + s.Text,
						Event:       "Mentioned by " + s.User.ScreenName,
						Priority:    "1",
					}
				}

				PROWL.Push(n)
			}
		}
	}

	//RTイベント
	if s.RetweetedStatus.User.ScreenName == "dmnlk" {
		n := &goprowl.Notification{
			Application: "yggdrasill",
			Description: "\U0001f4a1" + " " + s.Text,
			Event:       "RT by " + s.User.ScreenName,
			Priority:    "1",
		}

		PROWL.Push(n)
	}
}
<commit_msg>fix wrong notify, when you retweet other account<commit_after>package main

import (
	"fmt"
	"os"

	"log"

	"github.com/dmnlk/gomadare"
	"github.com/dmnlk/stringUtils"
	"github.com/rem7/goprowl"
	"strings"
)

var (
	CONSUMER_KEY        string
	CONSUMER_KEY_SECRET string
	ACCESS_TOKEN        string
	ACCESS_TOKEN_SECRET string
	SCREEN_NAME			string
	PROWL_API_KEY       string
	PROWL               goprowl.Goprowl
)

func main() {
	err := configureToken()
	if err != nil {
		fmt.Println(err)
		return
	}
	err = PROWL.RegisterKey(PROWL_API_KEY)
	if err != nil {
		fmt.Println(err)
		return
	}

	SCREEN_NAME = os.Getenv("SCREEN_NAME")

	if len(SCREEN_NAME) < 0 {
		return
	}

	client := gomadare.NewClient(CONSUMER_KEY, CONSUMER_KEY_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET)

	client.GetUserStream(nil, func(s gomadare.Status, e gomadare.Event) {
		if &s != nil {
			go sendReplyAndRetweetToProwl(s)
		}
		if &e != nil {
			go sendEventToProwl(e)
		}
	})
}

func configureToken() error {
	CONSUMER_KEY = os.Getenv("CONSUMER_KEY")
	CONSUMER_KEY_SECRET = os.Getenv("CONSUMER_KEY_SECRET")
	ACCESS_TOKEN = os.Getenv("ACCESS_TOKEN")
	ACCESS_TOKEN_SECRET = os.Getenv("ACCESS_TOKEN_SECRET")
	PROWL_API_KEY = os.Getenv("PROWL_API_KEY")
	if ng := stringUtils.IsAnyEmpty(CONSUMER_KEY, CONSUMER_KEY_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET, PROWL_API_KEY); ng {
		return fmt.Errorf("some key invalid")
	}

	return nil
}

func sendEventToProwl(e gomadare.Event) {
	if stringUtils.IsEmpty(e.Event) {
		return
	}

	if (e.Event == "favorite" || e.Event == "unfavorite" || e.Event == "retweeted_retweet") && e.Source.ScreenName == SCREEN_NAME {
		return
	}

	emoji := getEventEmoji(e)
	n := &goprowl.Notification{
		Application: "yggdrasill",
		Description: emoji + " " + e.TargetObject.Text,
		Event:       e.Event + " by " + e.Source.ScreenName,
		Priority:    "1",
	}

	PROWL.Push(n)
}

func getEventEmoji(event gomadare.Event) string {
	if event.Event == "favorite" {
		return "\u2b50"
	}
	if event.Event == "unfavorite" {
		return "\U0001f44e"
	}
	if event.Event == "list_member_removed" {
		return "\u274c"
	}
	if event.Event == "list_member_added" {
		return "\u2755"
	}
	if event.Event == "follow" {
		return "\u2661"
	}
	log.Println("unknown event:" + event.Event)
	return event.Event
}

func getProwlNotification(event gomadare.Event) goprowl.Notification {
	n := &goprowl.Notification{
		Application: "Yggdrsill",
		Priority: "1",
	}

	return *n
}

func sendReplyAndRetweetToProwl(s gomadare.Status) {
	// reply Event
	if len(s.Entities.UserMentions) > 0 {
		for _, mention := range s.Entities.UserMentions {
			if mention.ScreenName == "dmnlk" {
				var n *goprowl.Notification
				if strings.Contains(s.Text, "RT") {
					n = &goprowl.Notification{
						Application: "yggdrasill",
						Description: "\U0001f4a1" + " " + s.Text,
						Event:       "RT by " + s.User.ScreenName,
						Priority:    "1",
					}
				} else {
					n = &goprowl.Notification{
						Application: "yggdrasill",
						Description: "\U0001f4a1" + " " + s.Text,
						Event:       "Mentioned by " + s.User.ScreenName,
						Priority:    "1",
					}
				}

				PROWL.Push(n)
			}
		}
	}

	//RTイベント
	if s.RetweetedStatus.User.ScreenName == "dmnlk" {
		n := &goprowl.Notification{
			Application: "yggdrasill",
			Description: "\U0001f4a1" + " " + s.Text,
			Event:       "RT by " + s.User.ScreenName,
			Priority:    "1",
		}

		PROWL.Push(n)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"launchpad.net/gnuflag"
	"launchpad.net/juju-core/juju/cmd"
	"launchpad.net/juju-core/juju/environs"
	"launchpad.net/juju-core/juju/log"
	"launchpad.net/juju-core/juju/state"
	"launchpad.net/tomb"

	// register providers
	_ "launchpad.net/juju-core/juju/environs/dummy"
	_ "launchpad.net/juju-core/juju/environs/ec2"
)

// ProvisioningAgent is a cmd.Command responsible for running a provisioning agent.
type ProvisioningAgent struct {
	Conf AgentConf
}

// Info returns usage information for the command.
func (a *ProvisioningAgent) Info() *cmd.Info {
	return &cmd.Info{"provisioning", "", "run a juju provisioning agent", ""}
}

// Init initializes the command for running.
func (a *ProvisioningAgent) Init(f *gnuflag.FlagSet, args []string) error {
	a.Conf.addFlags(f)
	if err := f.Parse(true, args); err != nil {
		return err
	}
	return a.Conf.checkArgs(f.Args())
}

// Run runs a provisioning agent.
func (a *ProvisioningAgent) Run(_ *cmd.Context) error {
	// TODO(dfc) place the logic in a loop with a suitable delay
	p, err := NewProvisioner(&a.Conf.StateInfo)
	if err != nil {
		return err
	}
	return p.Wait()
}

type Provisioner struct {
	st      *state.State
	environ environs.Environ
	tomb    tomb.Tomb

	environWatcher  *state.ConfigWatcher
	machinesWatcher *state.MachinesWatcher
}

// NewProvisioner returns a Provisioner.
func NewProvisioner(info *state.Info) (*Provisioner, error) {
	st, err := state.Open(info)
	if err != nil {
		return nil, err
	}
	p := &Provisioner{
		st: st,
	}
	go p.loop()
	return p, nil
}

func (p *Provisioner) loop() {
	defer p.tomb.Done()

	p.environWatcher = p.st.WatchEnvironConfig()
	// TODO(dfc) we need a method like state.IsConnected() here to exit cleanly if
	// there is a connection problem.
	for {
		select {
		case <-p.tomb.Dying():
			return
		case config, ok := <-p.environWatcher.Changes():
			if !ok {
				err := p.environWatcher.Stop()
				if err != nil {
					p.tomb.Kill(err)
				}
				return
			}
			var err error
			p.environ, err = environs.NewEnviron(config.Map())
			if err != nil {
				log.Printf("provisioner loaded invalid environment configuration: %v", err)
				continue
			}
			log.Printf("provisioner loaded new environment configuration")
			p.innerLoop()
		}
	}
}

func (p *Provisioner) innerLoop() {
	p.machinesWatcher = p.st.WatchMachines()
	// TODO(dfc) we need a method like state.IsConnected() here to exit cleanly if
	// there is a connection problem.
	for {
		select {
		case <-p.tomb.Dying():
			return
		case change, ok := <-p.environWatcher.Changes():
			if !ok {
				err := p.environWatcher.Stop()
				if err != nil {
					p.tomb.Kill(err)
				}
				return
			}
			config, err := environs.NewConfig(change.Map())
			if err != nil {
				log.Printf("provisioner loaded invalid environment configuration: %v", err)
				continue
			}
			p.environ.SetConfig(config)
			log.Printf("provisioner loaded new environment configuration")
		case machines, ok := <-p.machinesWatcher.Changes():
			if !ok {
				err := p.machinesWatcher.Stop()
				if err != nil {
					p.tomb.Kill(err)
				}
				return
			}
			p.processMachines(machines)
		}
	}
}

// Wait waits for the Provisioner to exit.
func (p *Provisioner) Wait() error {
	return p.tomb.Wait()
}

// Stop stops the Provisioner and returns any error encountered while
// provisioning.
func (p *Provisioner) Stop() error {
	p.tomb.Kill(nil)
	return p.tomb.Wait()
}

func (p *Provisioner) processMachines(changes *state.MachinesChange) {}
<commit_msg>improved tests<commit_after>package main

import (
	"launchpad.net/gnuflag"
	"launchpad.net/juju-core/juju/cmd"
	"launchpad.net/juju-core/juju/environs"
	"launchpad.net/juju-core/juju/log"
	"launchpad.net/juju-core/juju/state"
	"launchpad.net/tomb"

	// register providers
	_ "launchpad.net/juju-core/juju/environs/dummy"
	_ "launchpad.net/juju-core/juju/environs/ec2"
)

// ProvisioningAgent is a cmd.Command responsible for running a provisioning agent.
type ProvisioningAgent struct {
	Conf AgentConf
}

// Info returns usage information for the command.
func (a *ProvisioningAgent) Info() *cmd.Info {
	return &cmd.Info{"provisioning", "", "run a juju provisioning agent", ""}
}

// Init initializes the command for running.
func (a *ProvisioningAgent) Init(f *gnuflag.FlagSet, args []string) error {
	a.Conf.addFlags(f)
	if err := f.Parse(true, args); err != nil {
		return err
	}
	return a.Conf.checkArgs(f.Args())
}

// Run runs a provisioning agent.
func (a *ProvisioningAgent) Run(_ *cmd.Context) error {
	// TODO(dfc) place the logic in a loop with a suitable delay
	p, err := NewProvisioner(&a.Conf.StateInfo)
	if err != nil {
		return err
	}
	return p.Wait()
}

type Provisioner struct {
	st      *state.State
	environ environs.Environ
	tomb    tomb.Tomb

	environWatcher  *state.ConfigWatcher
	machinesWatcher *state.MachinesWatcher
}

// NewProvisioner returns a Provisioner.
func NewProvisioner(info *state.Info) (*Provisioner, error) {
	st, err := state.Open(info)
	if err != nil {
		return nil, err
	}
	p := &Provisioner{
		st: st,
	}
	go p.loop()
	return p, nil
}

func (p *Provisioner) loop() {
	defer p.tomb.Done()
	defer p.st.Close()

	p.environWatcher = p.st.WatchEnvironConfig()
	// TODO(dfc) we need a method like state.IsConnected() here to exit cleanly if
	// there is a connection problem.
	for {
		select {
		case <-p.tomb.Dying():
			return
		case config, ok := <-p.environWatcher.Changes():
			if !ok {
				err := p.environWatcher.Stop()
				if err != nil {
					p.tomb.Kill(err)
				}
				return
			}
			var err error
			p.environ, err = environs.NewEnviron(config.Map())
			if err != nil {
				log.Printf("provisioner loaded invalid environment configuration: %v", err)
				continue
			}
			log.Printf("provisioner loaded new environment configuration")
			p.innerLoop()
		}
	}
}

func (p *Provisioner) innerLoop() {
	p.machinesWatcher = p.st.WatchMachines()
	// TODO(dfc) we need a method like state.IsConnected() here to exit cleanly if
	// there is a connection problem.
	for {
		select {
		case <-p.tomb.Dying():
			return
		case change, ok := <-p.environWatcher.Changes():
			if !ok {
				err := p.environWatcher.Stop()
				if err != nil {
					p.tomb.Kill(err)
				}
				return
			}
			config, err := environs.NewConfig(change.Map())
			if err != nil {
				log.Printf("provisioner loaded invalid environment configuration: %v", err)
				continue
			}
			p.environ.SetConfig(config)
			log.Printf("provisioner loaded new environment configuration")
		case machines, ok := <-p.machinesWatcher.Changes():
			if !ok {
				err := p.machinesWatcher.Stop()
				if err != nil {
					p.tomb.Kill(err)
				}
				return
			}
			p.processMachines(machines)
		}
	}
}

// Wait waits for the Provisioner to exit.
func (p *Provisioner) Wait() error {
	return p.tomb.Wait()
}

// Stop stops the Provisioner and returns any error encountered while
// provisioning.
func (p *Provisioner) Stop() error {
	p.tomb.Kill(nil)
	return p.tomb.Wait()
}

func (p *Provisioner) processMachines(changes *state.MachinesChange) {}
<|endoftext|>