<commit_before>package mysql

import (
	"context"
	"database/sql"
	"fmt"
	"math"
	"strings"
	"time"

	_ "github.com/go-sql-driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/callbacks"
	"gorm.io/gorm/clause"
	"gorm.io/gorm/logger"
	"gorm.io/gorm/migrator"
	"gorm.io/gorm/schema"
)

type Config struct {
	DriverName                    string
	ServerVersion                 string
	DSN                           string
	Conn                          gorm.ConnPool
	SkipInitializeWithVersion     bool
	DefaultStringSize             uint
	DefaultDatetimePrecision      *int
	DisableDatetimePrecision      bool
	DontSupportRenameIndex        bool
	DontSupportRenameColumn       bool
	DontSupportForShareClause     bool
	DontSupportNullAsDefaultValue bool
}

type Dialector struct {
	*Config
}

var (
	// CreateClauses create clauses
	CreateClauses = []string{"INSERT", "VALUES", "ON CONFLICT"}
	// QueryClauses query clauses
	QueryClauses = []string{}
	// UpdateClauses update clauses
	UpdateClauses = []string{"UPDATE", "SET", "WHERE", "ORDER BY", "LIMIT"}
	// DeleteClauses delete clauses
	DeleteClauses = []string{"DELETE", "FROM", "WHERE", "ORDER BY", "LIMIT"}

	defaultDatetimePrecision = 3
)

func Open(dsn string) gorm.Dialector {
	return &Dialector{Config: &Config{DSN: dsn}}
}

func New(config Config) gorm.Dialector {
	return &Dialector{Config: &config}
}

func (dialector Dialector) Name() string {
	return "mysql"
}

// NowFunc return now func
func (dialector Dialector) NowFunc(n int) func() time.Time {
	return func() time.Time {
		round := time.Second / time.Duration(math.Pow10(n))
		return time.Now().Round(round)
	}
}

func (dialector Dialector) Apply(config *gorm.Config) error {
	if config.NowFunc == nil {
		if dialector.DefaultDatetimePrecision == nil {
			dialector.DefaultDatetimePrecision = &defaultDatetimePrecision
		}

		// while maintaining the readability of the code, separate the business logic from
		// the general part and leave it to the function to do it here.
		config.NowFunc = dialector.NowFunc(*dialector.DefaultDatetimePrecision)
	}

	return nil
}

func (dialector Dialector) Initialize(db *gorm.DB) (err error) {
	ctx := context.Background()

	// register callbacks
	callbacks.RegisterDefaultCallbacks(db, &callbacks.Config{
		CreateClauses: CreateClauses,
		QueryClauses:  QueryClauses,
		UpdateClauses: UpdateClauses,
		DeleteClauses: DeleteClauses,
	})

	if dialector.DriverName == "" {
		dialector.DriverName = "mysql"
	}

	if dialector.DefaultDatetimePrecision == nil {
		dialector.DefaultDatetimePrecision = &defaultDatetimePrecision
	}

	if dialector.Conn != nil {
		db.ConnPool = dialector.Conn
	} else {
		db.ConnPool, err = sql.Open(dialector.DriverName, dialector.DSN)
		if err != nil {
			return err
		}
	}

	if !dialector.Config.SkipInitializeWithVersion {
		err = db.ConnPool.QueryRowContext(ctx, "SELECT VERSION()").Scan(&dialector.ServerVersion)
		if err != nil {
			return err
		}

		if strings.Contains(dialector.ServerVersion, "MariaDB") {
			dialector.Config.DontSupportRenameIndex = true
			dialector.Config.DontSupportRenameColumn = true
			dialector.Config.DontSupportForShareClause = true
			dialector.Config.DontSupportNullAsDefaultValue = true
		} else if strings.HasPrefix(dialector.ServerVersion, "5.6.") {
			dialector.Config.DontSupportRenameIndex = true
			dialector.Config.DontSupportRenameColumn = true
			dialector.Config.DontSupportForShareClause = true
		} else if strings.HasPrefix(dialector.ServerVersion, "5.7.") {
			dialector.Config.DontSupportRenameColumn = true
			dialector.Config.DontSupportForShareClause = true
		} else if strings.HasPrefix(dialector.ServerVersion, "5.") {
			dialector.Config.DisableDatetimePrecision = true
			dialector.Config.DontSupportRenameIndex = true
			dialector.Config.DontSupportRenameColumn = true
			dialector.Config.DontSupportForShareClause = true
		}
	}

	for k, v := range dialector.ClauseBuilders() {
		db.ClauseBuilders[k] = v
	}
	return
}

const (
	// ClauseOnConflict for clause.ClauseBuilder ON CONFLICT key
	ClauseOnConflict = "ON CONFLICT"
	// ClauseValues for clause.ClauseBuilder VALUES key
	ClauseValues = "VALUES"
	// ClauseValues for clause.ClauseBuilder FOR key
	ClauseFor = "FOR"
)

func (dialector Dialector) ClauseBuilders() map[string]clause.ClauseBuilder {
	clauseBuilders := map[string]clause.ClauseBuilder{
		ClauseOnConflict: func(c clause.Clause, builder clause.Builder) {
			onConflict, ok := c.Expression.(clause.OnConflict)
			if !ok {
				c.Build(builder)
				return
			}

			builder.WriteString("ON DUPLICATE KEY UPDATE ")
			if len(onConflict.DoUpdates) == 0 {
				if s := builder.(*gorm.Statement).Schema; s != nil {
					var column clause.Column
					onConflict.DoNothing = false

					if s.PrioritizedPrimaryField != nil {
						column = clause.Column{Name: s.PrioritizedPrimaryField.DBName}
					} else if len(s.DBNames) > 0 {
						column = clause.Column{Name: s.DBNames[0]}
					}

					if column.Name != "" {
						onConflict.DoUpdates = []clause.Assignment{{Column: column, Value: column}}
					}
				}
			}

			for idx, assignment := range onConflict.DoUpdates {
				if idx > 0 {
					builder.WriteByte(',')
				}

				builder.WriteQuoted(assignment.Column)
				builder.WriteByte('=')
				if column, ok := assignment.Value.(clause.Column); ok && column.Table == "excluded" {
					column.Table = ""
					builder.WriteString("VALUES(")
					builder.WriteQuoted(column)
					builder.WriteByte(')')
				} else {
					builder.AddVar(builder, assignment.Value)
				}
			}
		},
		ClauseValues: func(c clause.Clause, builder clause.Builder) {
			if values, ok := c.Expression.(clause.Values); ok && len(values.Columns) == 0 {
				builder.WriteString("VALUES()")
				return
			}
			c.Build(builder)
		},
	}

	if dialector.Config.DontSupportForShareClause {
		clauseBuilders[ClauseFor] = func(c clause.Clause, builder clause.Builder) {
			if values, ok := c.Expression.(clause.Locking); ok && strings.EqualFold(values.Strength, "SHARE") {
				builder.WriteString("LOCK IN SHARE MODE")
				return
			}
			c.Build(builder)
		}
	}

	return clauseBuilders
}

func (dialector Dialector) DefaultValueOf(field *schema.Field) clause.Expression {
	return clause.Expr{SQL: "DEFAULT"}
}

func (dialector Dialector) Migrator(db *gorm.DB) gorm.Migrator {
	return Migrator{
		Migrator: migrator.Migrator{
			Config: migrator.Config{
				DB:        db,
				Dialector: dialector,
			},
		},
		Dialector: dialector,
	}
}

func (dialector Dialector) BindVarTo(writer clause.Writer, stmt *gorm.Statement, v interface{}) {
	writer.WriteByte('?')
}

func (dialector Dialector) QuoteTo(writer clause.Writer, str string) {
	var (
		underQuoted, selfQuoted bool
		continuousBacktick      int8
		shiftDelimiter          int8
	)

	for _, v := range []byte(str) {
		switch v {
		case '`':
			continuousBacktick++
			if continuousBacktick == 2 {
				writer.WriteString("``")
				continuousBacktick = 0
			}
		case '.':
			if continuousBacktick > 0 || !selfQuoted {
				shiftDelimiter = 0
				underQuoted = false
				continuousBacktick = 0
				writer.WriteByte('`')
			}
			writer.WriteByte(v)
			continue
		default:
			if shiftDelimiter-continuousBacktick <= 0 && !underQuoted {
				writer.WriteByte('`')
				underQuoted = true
				if selfQuoted = continuousBacktick > 0; selfQuoted {
					continuousBacktick -= 1
				}
			}

			for ; continuousBacktick > 0; continuousBacktick -= 1 {
				writer.WriteString("``")
			}

			writer.WriteByte(v)
		}
		shiftDelimiter++
	}

	if continuousBacktick > 0 && !selfQuoted {
		writer.WriteString("``")
	}
	writer.WriteByte('`')
}

func (dialector Dialector) Explain(sql string, vars ...interface{}) string {
	return logger.ExplainSQL(sql, nil, `'`, vars...)
}

func (dialector Dialector) DataTypeOf(field *schema.Field) string {
	switch field.DataType {
	case schema.Bool:
		return "boolean"
	case schema.Int, schema.Uint:
		return dialector.getSchemaIntAndUnitType(field)
	case schema.Float:
		return dialector.getSchemaFloatType(field)
	case schema.String:
		return dialector.getSchemaStringType(field)
	case schema.Time:
		return dialector.getSchemaTimeType(field)
	case schema.Bytes:
		return dialector.getSchemaBytesType(field)
	}

	return string(field.DataType)
}

func (dialector Dialector) getSchemaFloatType(field *schema.Field) string {
	if field.Precision > 0 {
		return fmt.Sprintf("decimal(%d, %d)", field.Precision, field.Scale)
	}

	if field.Size <= 32 {
		return "float"
	}

	return "double"
}

func (dialector Dialector) getSchemaStringType(field *schema.Field) string {
	size := field.Size
	if size == 0 {
		if dialector.DefaultStringSize > 0 {
			size = int(dialector.DefaultStringSize)
		} else {
			hasIndex := field.TagSettings["INDEX"] != "" || field.TagSettings["UNIQUE"] != ""
			// TEXT, GEOMETRY or JSON column can't have a default value
			if field.PrimaryKey || field.HasDefaultValue || hasIndex {
				size = 191 // utf8mb4
			}
		}
	}

	if size >= 65536 && size <= int(math.Pow(2, 24)) {
		return "mediumtext"
	}

	if size > int(math.Pow(2, 24)) || size <= 0 {
		return "longtext"
	}

	return fmt.Sprintf("varchar(%d)", size)
}

func (dialector Dialector) getSchemaTimeType(field *schema.Field) string {
	precision := ""
	if !dialector.DisableDatetimePrecision && field.Precision == 0 {
		field.Precision = *dialector.DefaultDatetimePrecision
	}

	if field.Precision > 0 {
		precision = fmt.Sprintf("(%d)", field.Precision)
	}

	if field.NotNull || field.PrimaryKey {
		return "datetime" + precision
	}
	return "datetime" + precision + " NULL"
}

func (dialector Dialector) getSchemaBytesType(field *schema.Field) string {
	if field.Size > 0 && field.Size < 65536 {
		return fmt.Sprintf("varbinary(%d)", field.Size)
	}

	if field.Size >= 65536 && field.Size <= int(math.Pow(2, 24)) {
		return "mediumblob"
	}

	return "longblob"
}

func (dialector Dialector) getSchemaIntAndUnitType(field *schema.Field) string {
	sqlType := "bigint"
	switch {
	case field.Size <= 8:
		sqlType = "tinyint"
	case field.Size <= 16:
		sqlType = "smallint"
	case field.Size <= 24:
		sqlType = "mediumint"
	case field.Size <= 32:
		sqlType = "int"
	}

	if field.DataType == schema.Uint {
		sqlType += " unsigned"
	}

	if field.AutoIncrement {
		sqlType += " AUTO_INCREMENT"
	}

	return sqlType
}

func (dialector Dialector) SavePoint(tx *gorm.DB, name string) error {
	return tx.Exec("SAVEPOINT " + name).Error
}

func (dialector Dialector) RollbackTo(tx *gorm.DB, name string) error {
	return tx.Exec("ROLLBACK TO SAVEPOINT " + name).Error
}
<commit_msg>feat: custom type implements autoIncrement (#83)<commit_after>package mysql

import (
	"context"
	"database/sql"
	"fmt"
	"math"
	"strings"
	"time"

	_ "github.com/go-sql-driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/callbacks"
	"gorm.io/gorm/clause"
	"gorm.io/gorm/logger"
	"gorm.io/gorm/migrator"
	"gorm.io/gorm/schema"
)

type Config struct {
	DriverName                    string
	ServerVersion                 string
	DSN                           string
	Conn                          gorm.ConnPool
	SkipInitializeWithVersion     bool
	DefaultStringSize             uint
	DefaultDatetimePrecision      *int
	DisableDatetimePrecision      bool
	DontSupportRenameIndex        bool
	DontSupportRenameColumn       bool
	DontSupportForShareClause     bool
	DontSupportNullAsDefaultValue bool
}

type Dialector struct {
	*Config
}

var (
	// CreateClauses create clauses
	CreateClauses = []string{"INSERT", "VALUES", "ON CONFLICT"}
	// QueryClauses query clauses
	QueryClauses = []string{}
	// UpdateClauses update clauses
	UpdateClauses = []string{"UPDATE", "SET", "WHERE", "ORDER BY", "LIMIT"}
	// DeleteClauses delete clauses
	DeleteClauses = []string{"DELETE", "FROM", "WHERE", "ORDER BY", "LIMIT"}

	defaultDatetimePrecision = 3
)

func Open(dsn string) gorm.Dialector {
	return &Dialector{Config: &Config{DSN: dsn}}
}

func New(config Config) gorm.Dialector {
	return &Dialector{Config: &config}
}

func (dialector Dialector) Name() string {
	return "mysql"
}

// NowFunc return now func
func (dialector Dialector) NowFunc(n int) func() time.Time {
	return func() time.Time {
		round := time.Second / time.Duration(math.Pow10(n))
		return time.Now().Round(round)
	}
}

func (dialector Dialector) Apply(config *gorm.Config) error {
	if config.NowFunc == nil {
		if dialector.DefaultDatetimePrecision == nil {
			dialector.DefaultDatetimePrecision = &defaultDatetimePrecision
		}

		// while maintaining the readability of the code, separate the business logic from
		// the general part and leave it to the function to do it here.
		config.NowFunc = dialector.NowFunc(*dialector.DefaultDatetimePrecision)
	}

	return nil
}

func (dialector Dialector) Initialize(db *gorm.DB) (err error) {
	ctx := context.Background()

	// register callbacks
	callbacks.RegisterDefaultCallbacks(db, &callbacks.Config{
		CreateClauses: CreateClauses,
		QueryClauses:  QueryClauses,
		UpdateClauses: UpdateClauses,
		DeleteClauses: DeleteClauses,
	})

	if dialector.DriverName == "" {
		dialector.DriverName = "mysql"
	}

	if dialector.DefaultDatetimePrecision == nil {
		dialector.DefaultDatetimePrecision = &defaultDatetimePrecision
	}

	if dialector.Conn != nil {
		db.ConnPool = dialector.Conn
	} else {
		db.ConnPool, err = sql.Open(dialector.DriverName, dialector.DSN)
		if err != nil {
			return err
		}
	}

	if !dialector.Config.SkipInitializeWithVersion {
		err = db.ConnPool.QueryRowContext(ctx, "SELECT VERSION()").Scan(&dialector.ServerVersion)
		if err != nil {
			return err
		}

		if strings.Contains(dialector.ServerVersion, "MariaDB") {
			dialector.Config.DontSupportRenameIndex = true
			dialector.Config.DontSupportRenameColumn = true
			dialector.Config.DontSupportForShareClause = true
			dialector.Config.DontSupportNullAsDefaultValue = true
		} else if strings.HasPrefix(dialector.ServerVersion, "5.6.") {
			dialector.Config.DontSupportRenameIndex = true
			dialector.Config.DontSupportRenameColumn = true
			dialector.Config.DontSupportForShareClause = true
		} else if strings.HasPrefix(dialector.ServerVersion, "5.7.") {
			dialector.Config.DontSupportRenameColumn = true
			dialector.Config.DontSupportForShareClause = true
		} else if strings.HasPrefix(dialector.ServerVersion, "5.") {
			dialector.Config.DisableDatetimePrecision = true
			dialector.Config.DontSupportRenameIndex = true
			dialector.Config.DontSupportRenameColumn = true
			dialector.Config.DontSupportForShareClause = true
		}
	}

	for k, v := range dialector.ClauseBuilders() {
		db.ClauseBuilders[k] = v
	}
	return
}

const (
	// ClauseOnConflict for clause.ClauseBuilder ON CONFLICT key
	ClauseOnConflict = "ON CONFLICT"
	// ClauseValues for clause.ClauseBuilder VALUES key
	ClauseValues = "VALUES"
	// ClauseValues for clause.ClauseBuilder FOR key
	ClauseFor = "FOR"
)

func (dialector Dialector) ClauseBuilders() map[string]clause.ClauseBuilder {
	clauseBuilders := map[string]clause.ClauseBuilder{
		ClauseOnConflict: func(c clause.Clause, builder clause.Builder) {
			onConflict, ok := c.Expression.(clause.OnConflict)
			if !ok {
				c.Build(builder)
				return
			}

			builder.WriteString("ON DUPLICATE KEY UPDATE ")
			if len(onConflict.DoUpdates) == 0 {
				if s := builder.(*gorm.Statement).Schema; s != nil {
					var column clause.Column
					onConflict.DoNothing = false

					if s.PrioritizedPrimaryField != nil {
						column = clause.Column{Name: s.PrioritizedPrimaryField.DBName}
					} else if len(s.DBNames) > 0 {
						column = clause.Column{Name: s.DBNames[0]}
					}

					if column.Name != "" {
						onConflict.DoUpdates = []clause.Assignment{{Column: column, Value: column}}
					}
				}
			}

			for idx, assignment := range onConflict.DoUpdates {
				if idx > 0 {
					builder.WriteByte(',')
				}

				builder.WriteQuoted(assignment.Column)
				builder.WriteByte('=')
				if column, ok := assignment.Value.(clause.Column); ok && column.Table == "excluded" {
					column.Table = ""
					builder.WriteString("VALUES(")
					builder.WriteQuoted(column)
					builder.WriteByte(')')
				} else {
					builder.AddVar(builder, assignment.Value)
				}
			}
		},
		ClauseValues: func(c clause.Clause, builder clause.Builder) {
			if values, ok := c.Expression.(clause.Values); ok && len(values.Columns) == 0 {
				builder.WriteString("VALUES()")
				return
			}
			c.Build(builder)
		},
	}

	if dialector.Config.DontSupportForShareClause {
		clauseBuilders[ClauseFor] = func(c clause.Clause, builder clause.Builder) {
			if values, ok := c.Expression.(clause.Locking); ok && strings.EqualFold(values.Strength, "SHARE") {
				builder.WriteString("LOCK IN SHARE MODE")
				return
			}
			c.Build(builder)
		}
	}

	return clauseBuilders
}

func (dialector Dialector) DefaultValueOf(field *schema.Field) clause.Expression {
	return clause.Expr{SQL: "DEFAULT"}
}

func (dialector Dialector) Migrator(db *gorm.DB) gorm.Migrator {
	return Migrator{
		Migrator: migrator.Migrator{
			Config: migrator.Config{
				DB:        db,
				Dialector: dialector,
			},
		},
		Dialector: dialector,
	}
}

func (dialector Dialector) BindVarTo(writer clause.Writer, stmt *gorm.Statement, v interface{}) {
	writer.WriteByte('?')
}

func (dialector Dialector) QuoteTo(writer clause.Writer, str string) {
	var (
		underQuoted, selfQuoted bool
		continuousBacktick      int8
		shiftDelimiter          int8
	)

	for _, v := range []byte(str) {
		switch v {
		case '`':
			continuousBacktick++
			if continuousBacktick == 2 {
				writer.WriteString("``")
				continuousBacktick = 0
			}
		case '.':
			if continuousBacktick > 0 || !selfQuoted {
				shiftDelimiter = 0
				underQuoted = false
				continuousBacktick = 0
				writer.WriteByte('`')
			}
			writer.WriteByte(v)
			continue
		default:
			if shiftDelimiter-continuousBacktick <= 0 && !underQuoted {
				writer.WriteByte('`')
				underQuoted = true
				if selfQuoted = continuousBacktick > 0; selfQuoted {
					continuousBacktick -= 1
				}
			}

			for ; continuousBacktick > 0; continuousBacktick -= 1 {
				writer.WriteString("``")
			}

			writer.WriteByte(v)
		}
		shiftDelimiter++
	}

	if continuousBacktick > 0 && !selfQuoted {
		writer.WriteString("``")
	}
	writer.WriteByte('`')
}

func (dialector Dialector) Explain(sql string, vars ...interface{}) string {
	return logger.ExplainSQL(sql, nil, `'`, vars...)
}

func (dialector Dialector) DataTypeOf(field *schema.Field) string {
	switch field.DataType {
	case schema.Bool:
		return "boolean"
	case schema.Int, schema.Uint:
		return dialector.getSchemaIntAndUnitType(field)
	case schema.Float:
		return dialector.getSchemaFloatType(field)
	case schema.String:
		return dialector.getSchemaStringType(field)
	case schema.Time:
		return dialector.getSchemaTimeType(field)
	case schema.Bytes:
		return dialector.getSchemaBytesType(field)
	default:
		return dialector.getSchemaCustomType(field)
	}
}

func (dialector Dialector) getSchemaFloatType(field *schema.Field) string {
	if field.Precision > 0 {
		return fmt.Sprintf("decimal(%d, %d)", field.Precision, field.Scale)
	}

	if field.Size <= 32 {
		return "float"
	}

	return "double"
}

func (dialector Dialector) getSchemaStringType(field *schema.Field) string {
	size := field.Size
	if size == 0 {
		if dialector.DefaultStringSize > 0 {
			size = int(dialector.DefaultStringSize)
		} else {
			hasIndex := field.TagSettings["INDEX"] != "" || field.TagSettings["UNIQUE"] != ""
			// TEXT, GEOMETRY or JSON column can't have a default value
			if field.PrimaryKey || field.HasDefaultValue || hasIndex {
				size = 191 // utf8mb4
			}
		}
	}

	if size >= 65536 && size <= int(math.Pow(2, 24)) {
		return "mediumtext"
	}

	if size > int(math.Pow(2, 24)) || size <= 0 {
		return "longtext"
	}

	return fmt.Sprintf("varchar(%d)", size)
}

func (dialector Dialector) getSchemaTimeType(field *schema.Field) string {
	precision := ""
	if !dialector.DisableDatetimePrecision && field.Precision == 0 {
		field.Precision = *dialector.DefaultDatetimePrecision
	}

	if field.Precision > 0 {
		precision = fmt.Sprintf("(%d)", field.Precision)
	}

	if field.NotNull || field.PrimaryKey {
		return "datetime" + precision
	}
	return "datetime" + precision + " NULL"
}

func (dialector Dialector) getSchemaBytesType(field *schema.Field) string {
	if field.Size > 0 && field.Size < 65536 {
		return fmt.Sprintf("varbinary(%d)", field.Size)
	}

	if field.Size >= 65536 && field.Size <= int(math.Pow(2, 24)) {
		return "mediumblob"
	}

	return "longblob"
}

func (dialector Dialector) getSchemaIntAndUnitType(field *schema.Field) string {
	sqlType := "bigint"
	switch {
	case field.Size <= 8:
		sqlType = "tinyint"
	case field.Size <= 16:
		sqlType = "smallint"
	case field.Size <= 24:
		sqlType = "mediumint"
	case field.Size <= 32:
		sqlType = "int"
	}

	if field.DataType == schema.Uint {
		sqlType += " unsigned"
	}

	if field.AutoIncrement {
		sqlType += " AUTO_INCREMENT"
	}

	return sqlType
}

func (dialector Dialector) getSchemaCustomType(field *schema.Field) string {
	sqlType := string(field.DataType)

	if field.AutoIncrement && !strings.Contains(strings.ToLower(sqlType), " auto_increment") {
		sqlType += " AUTO_INCREMENT"
	}

	return sqlType
}

func (dialector Dialector) SavePoint(tx *gorm.DB, name string) error {
	return tx.Exec("SAVEPOINT " + name).Error
}

func (dialector Dialector) RollbackTo(tx *gorm.DB, name string) error {
	return tx.Exec("ROLLBACK TO SAVEPOINT " + name).Error
}
<|endoftext|>


<commit_before>package participle

import (
	"errors"
	"fmt"
	"reflect"
	"strconv"
	"strings"

	"github.com/alecthomas/participle/lexer"
)

var (
	positionType  = reflect.TypeOf(lexer.Position{})
	captureType   = reflect.TypeOf((*Capture)(nil)).Elem()
	parseableType = reflect.TypeOf((*Parseable)(nil)).Elem()

	// NextMatch should be returned by Parseable.Parse() method implementations to indicate
	// that the node did not match and that other matches should be attempted, if appropriate.
	NextMatch = errors.New("no match") // nolint: golint
)

// A node in the grammar.
type node interface {
	// Parse from scanner into value.
	// Nodes should panic if parsing fails.
	Parse(lex lexer.PeekingLexer, parent reflect.Value) []reflect.Value
	String() string
}

func decorate(name func() string) {
	if msg := recover(); msg != nil {
		switch msg := msg.(type) {
		case Error:
			panicf("%s: %s", name(), msg)
		case *lexer.Error:
			panic(&lexer.Error{Message: name() + ": " + msg.Message, Pos: msg.Pos})
		default:
			panic(msg)
		}
	}
}

func recoverToError(err *error) {
	if msg := recover(); msg != nil {
		switch msg := msg.(type) {
		case Error:
			*err = msg
		case *lexer.Error:
			*err = msg
		default:
			panic(msg)
		}
	}
}

// A node that proxies to an implementation that implements the Parseable interface.
type parseable struct {
	t reflect.Type
}

func (p *parseable) String() string { return stringer(p) }

func (p *parseable) Parse(lex lexer.PeekingLexer, parent reflect.Value) (out []reflect.Value) {
	rv := reflect.New(p.t)
	v := rv.Interface().(Parseable)
	err := v.Parse(lex)
	if err != nil {
		if err == NextMatch {
			return nil
		}
		panic(err)
	}
	return []reflect.Value{rv.Elem()}
}

type strct struct {
	typ  reflect.Type
	expr node
}

func (s *strct) String() string { return stringer(s) }

func (s *strct) maybeInjectPos(pos lexer.Position, v reflect.Value) {
	if f := v.FieldByName("Pos"); f.IsValid() && f.Type() == positionType {
		f.Set(reflect.ValueOf(pos))
	}
}

func (s *strct) Parse(lex lexer.PeekingLexer, parent reflect.Value) (out []reflect.Value) {
	sv := reflect.New(s.typ).Elem()
	s.maybeInjectPos(lex.Peek(0).Pos, sv)
	if s.expr.Parse(lex, sv) == nil {
		return nil
	}
	return []reflect.Value{sv}
}

// <expr> {"|" <expr>}
type disjunction struct {
	nodes     []node
	lookahead lookaheadTable
}

func (d *disjunction) String() string { return stringer(d) }

func (e *disjunction) Parse(lex lexer.PeekingLexer, parent reflect.Value) (out []reflect.Value) {
	if selected := e.lookahead.Select(lex, parent); selected != -2 {
		if selected == -1 {
			return nil
		}
		return e.nodes[selected].Parse(lex, parent)
	}

	// Same logic without lookahead.
	for _, a := range e.nodes {
		if value := a.Parse(lex, parent); value != nil {
			return value
		}
	}
	return nil
}

// <node> ...
type sequence struct {
	head bool
	node node
	next *sequence
}

func (s *sequence) String() string { return stringer(s) }

func (s *sequence) Parse(lex lexer.PeekingLexer, parent reflect.Value) (out []reflect.Value) {
	for n := s; n != nil; n = n.next {
		child := n.node.Parse(lex, parent)
		if child == nil {
			// Early exit if first value doesn't match, otherwise all values must match.
			if n == s {
				return nil
			}
			lexer.Panicf(lex.Peek(0).Pos, "unexpected %q (expected %s)", lex.Peek(0), n)
		}
		out = append(out, child...)
	}
	return out
}

// @<expr>
type capture struct {
	field structLexerField
	node  node
}

func (c *capture) String() string { return stringer(c) }

func (c *capture) Parse(lex lexer.PeekingLexer, parent reflect.Value) (out []reflect.Value) {
	pos := lex.Peek(0).Pos
	v := c.node.Parse(lex, parent)
	if v == nil {
		return nil
	}
	setField(pos, parent, c.field, v)
	return []reflect.Value{parent}
}

// <identifier> - named lexer token reference
type reference struct {
	typ        rune
	identifier string // Used for informational purposes.
}

func (r *reference) String() string { return stringer(r) }

func (r *reference) Parse(lex lexer.PeekingLexer, parent reflect.Value) (out []reflect.Value) {
	token := lex.Peek(0)
	if token.Type != r.typ {
		return nil
	}
	return []reflect.Value{reflect.ValueOf(lex.Next().Value)}
}

// [ <expr> ] <sequence>
type optional struct {
	node      node
	next      node
	lookahead lookaheadTable
}

func (o *optional) String() string { return stringer(o) }

func (o *optional) Parse(lex lexer.PeekingLexer, parent reflect.Value) (out []reflect.Value) {
	switch o.lookahead.Select(lex, parent) {
	case -2: // No lookahead table
		fallthrough
	case 0:
		out = o.node.Parse(lex, parent)
		if out == nil {
			out = []reflect.Value{}
		}
		fallthrough
	case 1:
		if o.next != nil {
			out = append(out, o.next.Parse(lex, parent)...)
		}
		return out
	case -1:
		// We have a next node but neither it or the optional matched the lookahead, so it's a complete mismatch.
		if o.next != nil {
			return nil
		}
		return []reflect.Value{}
	default:
		panic("unexpected selection")
	}
}

// { <expr> } <sequence>
type repetition struct {
	node      node
	next      node
	lookahead lookaheadTable
}

func (r *repetition) String() string { return stringer(r) }

// Parse a repetition. Once a repetition is encountered it will always match, so grammars
// should ensure that branches are differentiated prior to the repetition.
func (r *repetition) Parse(lex lexer.PeekingLexer, parent reflect.Value) (out []reflect.Value) {
	switch r.lookahead.Select(lex, parent) {
	case -2: // No lookahead table
		fallthrough
	case 0:
		for {
			v := r.node.Parse(lex, parent)
			if v == nil {
				break
			}
			out = append(out, v...)
		}
		if out == nil {
			out = []reflect.Value{}
		}
		fallthrough
	case 1:
		if r.next != nil {
			out = append(out, r.next.Parse(lex, parent)...)
		}
		return out
	case -1:
		// We have a next node but neither it or the optional matched the lookahead, so it's a complete mismatch.
		if r.next != nil {
			panicf("expected %s", r.next)
		}
		return []reflect.Value{}
	default:
		panic("unexpected selection")
	}
}

// Match a token literal exactly "..."[:<type>].
type literal struct {
	s  string
	t  rune
	tt string // Used for display purposes - symbolic name of t.
}

func (l *literal) String() string { return stringer(l) }

func (l *literal) Parse(lex lexer.PeekingLexer, parent reflect.Value) (out []reflect.Value) {
	token := lex.Peek(0)
	if token.Value == l.s && (l.t == -1 || l.t == token.Type) {
		return []reflect.Value{reflect.ValueOf(lex.Next().Value)}
	}
	return nil
}

// Attempt to transform values to given type.
//
// This will dereference pointers, and attempt to parse strings into integer values, floats, etc.
func conform(t reflect.Type, values []reflect.Value) (out []reflect.Value) {
	for _, v := range values {
		for t != v.Type() && t.Kind() == reflect.Ptr && v.Kind() != reflect.Ptr {
			v = v.Addr()
		}

		switch t.Kind() {
		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			n, err := strconv.ParseInt(v.String(), 0, 64)
			if err == nil {
				v = reflect.New(t).Elem()
				v.SetInt(n)
			}

		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
			n, err := strconv.ParseUint(v.String(), 0, 64)
			if err == nil {
				v = reflect.New(t).Elem()
				v.SetUint(n)
			}

		case reflect.Bool:
			v = reflect.ValueOf(true)

		case reflect.Float32, reflect.Float64:
			n, err := strconv.ParseFloat(v.String(), 64)
			if err == nil {
				v = reflect.New(t).Elem()
				v.SetFloat(n)
			}
		}

		out = append(out, v)
	}
	return out
}

// Set field.
//
// If field is a pointer the pointer will be set to the value. If field is a string, value will be
// appended. If field is a slice, value will be appended to slice.
//
// For all other types, an attempt will be made to convert the string to the corresponding
// type (int, float32, etc.).
func setField(pos lexer.Position, strct reflect.Value, field structLexerField, fieldValue []reflect.Value) { // nolint: gocyclo
	defer decorate(func() string { return strct.Type().String() + "." + field.Name })

	f := strct.FieldByIndex(field.Index)
	switch f.Kind() {
	case reflect.Slice:
		fieldValue = conform(f.Type().Elem(), fieldValue)
		f.Set(reflect.Append(f, fieldValue...))
		return

	case reflect.Ptr:
		if f.IsNil() {
			fv := reflect.New(f.Type().Elem()).Elem()
			f.Set(fv.Addr())
			f = fv
		} else {
			f = f.Elem()
		}
	}

	if f.CanAddr() {
		if d, ok := f.Addr().Interface().(Capture); ok {
			ifv := []string{}
			for _, v := range fieldValue {
				ifv = append(ifv, v.Interface().(string))
			}
			err := d.Capture(ifv)
			if err != nil {
				lexer.Panic(pos, err.Error())
			}
			return
		}
	}

	// Strings concatenate all captured tokens.
	if f.Kind() == reflect.String {
		fieldValue = conform(f.Type(), fieldValue)
		for _, v := range fieldValue {
			f.Set(reflect.ValueOf(f.String() + v.String()).Convert(f.Type()))
		}
		return
	}

	// Coalesce multiple tokens into one. This allow eg. ["-", "10"] to be captured as separate tokens but
	// parsed as a single string "-10".
	if len(fieldValue) > 1 {
		out := []string{}
		for _, v := range fieldValue {
			out = append(out, v.String())
		}
		fieldValue = []reflect.Value{reflect.ValueOf(strings.Join(out, ""))}
	}

	fieldValue = conform(f.Type(), fieldValue)

	fv := fieldValue[0]

	switch f.Kind() {
	// Numeric types will increment if the token can not be coerced.
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		if fv.Type() != f.Type() {
			f.SetInt(f.Int() + 1)
		} else {
			f.Set(fv)
		}
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		if fv.Type() != f.Type() {
			f.SetUint(f.Uint() + 1)
		} else {
			f.Set(fv)
		}

	case reflect.Float32, reflect.Float64:
		if fv.Type() != f.Type() {
			f.SetFloat(f.Float() + 1)
		} else {
			f.Set(fv)
		}

	case reflect.Bool, reflect.Struct:
		if fv.Type() != f.Type() {
			panicf("value %q is not correct type %s", fv, f.Type())
		}
		f.Set(fv)

	default:
		panicf("unsupported field type %s for field %s", f.Type(), field.Name)
	}
}

func indirectType(t reflect.Type) reflect.Type {
	if t.Kind() == reflect.Ptr || t.Kind() == reflect.Slice {
		return indirectType(t.Elem())
	}
	return t
}

func panicf(f string, args ...interface{}) {
	panic(Error(fmt.Sprintf(f, args...)))
}

type Error string

func (e Error) Error() string { return string(e) }
<commit_msg>Linter fixes.<commit_after>package participle

import (
	"errors"
	"fmt"
	"reflect"
	"strconv"
	"strings"

	"github.com/alecthomas/participle/lexer"
)

var (
	positionType  = reflect.TypeOf(lexer.Position{})
	captureType   = reflect.TypeOf((*Capture)(nil)).Elem()
	parseableType = reflect.TypeOf((*Parseable)(nil)).Elem()

	// NextMatch should be returned by Parseable.Parse() method implementations to indicate
	// that the node did not match and that other matches should be attempted, if appropriate.
	NextMatch = errors.New("no match") // nolint: golint
)

// A node in the grammar.
type node interface {
	// Parse from scanner into value.
	// Nodes should panic if parsing fails.
	Parse(lex lexer.PeekingLexer, parent reflect.Value) []reflect.Value
	String() string
}

func decorate(name func() string) {
	if msg := recover(); msg != nil {
		switch msg := msg.(type) {
		case Error:
			panicf("%s: %s", name(), msg)
		case *lexer.Error:
			panic(&lexer.Error{Message: name() + ": " + msg.Message, Pos: msg.Pos})
		default:
			panic(msg)
		}
	}
}

func recoverToError(err *error) {
	if msg := recover(); msg != nil {
		switch msg := msg.(type) {
		case Error:
			*err = msg
		case *lexer.Error:
			*err = msg
		default:
			panic(msg)
		}
	}
}

// A node that proxies to an implementation that implements the Parseable interface.
type parseable struct {
	t reflect.Type
}

func (p *parseable) String() string { return stringer(p) }

func (p *parseable) Parse(lex lexer.PeekingLexer, parent reflect.Value) (out []reflect.Value) {
	rv := reflect.New(p.t)
	v := rv.Interface().(Parseable)
	err := v.Parse(lex)
	if err != nil {
		if err == NextMatch {
			return nil
		}
		panic(err)
	}
	return []reflect.Value{rv.Elem()}
}

type strct struct {
	typ  reflect.Type
	expr node
}

func (s *strct) String() string { return stringer(s) }

func (s *strct) maybeInjectPos(pos lexer.Position, v reflect.Value) {
	if f := v.FieldByName("Pos"); f.IsValid() && f.Type() == positionType {
		f.Set(reflect.ValueOf(pos))
	}
}

func (s *strct) Parse(lex lexer.PeekingLexer, parent reflect.Value) (out []reflect.Value) {
	sv := reflect.New(s.typ).Elem()
	s.maybeInjectPos(lex.Peek(0).Pos, sv)
	if s.expr.Parse(lex, sv) == nil {
		return nil
	}
	return []reflect.Value{sv}
}

// <expr> {"|" <expr>}
type disjunction struct {
	nodes     []node
	lookahead lookaheadTable
}

func (d *disjunction) String() string { return stringer(d) }

func (d *disjunction) Parse(lex lexer.PeekingLexer, parent reflect.Value) (out []reflect.Value) {
	if selected := d.lookahead.Select(lex, parent); selected != -2 {
		if selected == -1 {
			return nil
		}
		return d.nodes[selected].Parse(lex, parent)
	}

	// Same logic without lookahead.
	for _, a := range d.nodes {
		if value := a.Parse(lex, parent); value != nil {
			return value
		}
	}
	return nil
}

// <node> ...
type sequence struct {
	head bool
	node node
	next *sequence
}

func (s *sequence) String() string { return stringer(s) }

func (s *sequence) Parse(lex lexer.PeekingLexer, parent reflect.Value) (out []reflect.Value) {
	for n := s; n != nil; n = n.next {
		child := n.node.Parse(lex, parent)
		if child == nil {
			// Early exit if first value doesn't match, otherwise all values must match.
			if n == s {
				return nil
			}
			lexer.Panicf(lex.Peek(0).Pos, "unexpected %q (expected %s)", lex.Peek(0), n)
		}
		out = append(out, child...)
	}
	return out
}

// @<expr>
type capture struct {
	field structLexerField
	node  node
}

func (c *capture) String() string { return stringer(c) }

func (c *capture) Parse(lex lexer.PeekingLexer, parent reflect.Value) (out []reflect.Value) {
	pos := lex.Peek(0).Pos
	v := c.node.Parse(lex, parent)
	if v == nil {
		return nil
	}
	setField(pos, parent, c.field, v)
	return []reflect.Value{parent}
}

// <identifier> - named lexer token reference
type reference struct {
	typ        rune
	identifier string // Used for informational purposes.
}

func (r *reference) String() string { return stringer(r) }

func (r *reference) Parse(lex lexer.PeekingLexer, parent reflect.Value) (out []reflect.Value) {
	token := lex.Peek(0)
	if token.Type != r.typ {
		return nil
	}
	return []reflect.Value{reflect.ValueOf(lex.Next().Value)}
}

// [ <expr> ] <sequence>
type optional struct {
	node      node
	next      node
	lookahead lookaheadTable
}

func (o *optional) String() string { return stringer(o) }

func (o *optional) Parse(lex lexer.PeekingLexer, parent reflect.Value) (out []reflect.Value) {
	switch o.lookahead.Select(lex, parent) {
	case -2: // No lookahead table
		fallthrough
	case 0:
		out = o.node.Parse(lex, parent)
		if out == nil {
			out = []reflect.Value{}
		}
		fallthrough
	case 1:
		if o.next != nil {
			out = append(out, o.next.Parse(lex, parent)...)
		}
		return out
	case -1:
		// We have a next node but neither it or the optional matched the lookahead, so it's a complete mismatch.
		if o.next != nil {
			return nil
		}
		return []reflect.Value{}
	default:
		panic("unexpected selection")
	}
}

// { <expr> } <sequence>
type repetition struct {
	node      node
	next      node
	lookahead lookaheadTable
}

func (r *repetition) String() string { return stringer(r) }

// Parse a repetition. Once a repetition is encountered it will always match, so grammars
// should ensure that branches are differentiated prior to the repetition.
func (r *repetition) Parse(lex lexer.PeekingLexer, parent reflect.Value) (out []reflect.Value) {
	switch r.lookahead.Select(lex, parent) {
	case -2: // No lookahead table
		fallthrough
	case 0:
		for {
			v := r.node.Parse(lex, parent)
			if v == nil {
				break
			}
			out = append(out, v...)
		}
		if out == nil {
			out = []reflect.Value{}
		}
		fallthrough
	case 1:
		if r.next != nil {
			out = append(out, r.next.Parse(lex, parent)...)
		}
		return out
	case -1:
		// We have a next node but neither it or the optional matched the lookahead, so it's a complete mismatch.
		if r.next != nil {
			panicf("expected %s", r.next)
		}
		return []reflect.Value{}
	default:
		panic("unexpected selection")
	}
}

// Match a token literal exactly "..."[:<type>].
type literal struct {
	s  string
	t  rune
	tt string // Used for display purposes - symbolic name of t.
}

func (l *literal) String() string { return stringer(l) }

func (l *literal) Parse(lex lexer.PeekingLexer, parent reflect.Value) (out []reflect.Value) {
	token := lex.Peek(0)
	if token.Value == l.s && (l.t == -1 || l.t == token.Type) {
		return []reflect.Value{reflect.ValueOf(lex.Next().Value)}
	}
	return nil
}

// Attempt to transform values to given type.
//
// This will dereference pointers, and attempt to parse strings into integer values, floats, etc.
func conform(t reflect.Type, values []reflect.Value) (out []reflect.Value) {
	for _, v := range values {
		for t != v.Type() && t.Kind() == reflect.Ptr && v.Kind() != reflect.Ptr {
			v = v.Addr()
		}

		switch t.Kind() {
		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			n, err := strconv.ParseInt(v.String(), 0, 64)
			if err == nil {
				v = reflect.New(t).Elem()
				v.SetInt(n)
			}

		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
			n, err := strconv.ParseUint(v.String(), 0, 64)
			if err == nil {
				v = reflect.New(t).Elem()
				v.SetUint(n)
			}

		case reflect.Bool:
			v = reflect.ValueOf(true)

		case reflect.Float32, reflect.Float64:
			n, err := strconv.ParseFloat(v.String(), 64)
			if err == nil {
				v = reflect.New(t).Elem()
				v.SetFloat(n)
			}
		}

		out = append(out, v)
	}
	return out
}

// Set field.
//
// If field is a pointer the pointer will be set to the value. If field is a string, value will be
// appended. If field is a slice, value will be appended to slice.
//
// For all other types, an attempt will be made to convert the string to the corresponding
// type (int, float32, etc.).
func setField(pos lexer.Position, strct reflect.Value, field structLexerField, fieldValue []reflect.Value) { // nolint: gocyclo
	defer decorate(func() string { return strct.Type().String() + "." + field.Name })

	f := strct.FieldByIndex(field.Index)
	switch f.Kind() {
	case reflect.Slice:
		fieldValue = conform(f.Type().Elem(), fieldValue)
		f.Set(reflect.Append(f, fieldValue...))
		return

	case reflect.Ptr:
		if f.IsNil() {
			fv := reflect.New(f.Type().Elem()).Elem()
			f.Set(fv.Addr())
			f = fv
		} else {
			f = f.Elem()
		}
	}

	if f.CanAddr() {
		if d, ok := f.Addr().Interface().(Capture); ok {
			ifv := []string{}
			for _, v := range fieldValue {
				ifv = append(ifv, v.Interface().(string))
			}
			err := d.Capture(ifv)
			if err != nil {
				lexer.Panic(pos, err.Error())
			}
			return
		}
	}

	// Strings concatenate all captured tokens.
	if f.Kind() == reflect.String {
		fieldValue = conform(f.Type(), fieldValue)
		for _, v := range fieldValue {
			f.Set(reflect.ValueOf(f.String() + v.String()).Convert(f.Type()))
		}
		return
	}

	// Coalesce multiple tokens into one. This allow eg. ["-", "10"] to be captured as separate tokens but
	// parsed as a single string "-10".
	if len(fieldValue) > 1 {
		out := []string{}
		for _, v := range fieldValue {
			out = append(out, v.String())
		}
		fieldValue = []reflect.Value{reflect.ValueOf(strings.Join(out, ""))}
	}

	fieldValue = conform(f.Type(), fieldValue)

	fv := fieldValue[0]

	switch f.Kind() {
	// Numeric types will increment if the token can not be coerced.
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		if fv.Type() != f.Type() {
			f.SetInt(f.Int() + 1)
		} else {
			f.Set(fv)
		}
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		if fv.Type() != f.Type() {
			f.SetUint(f.Uint() + 1)
		} else {
			f.Set(fv)
		}

	case reflect.Float32, reflect.Float64:
		if fv.Type() != f.Type() {
			f.SetFloat(f.Float() + 1)
		} else {
			f.Set(fv)
		}

	case reflect.Bool, reflect.Struct:
		if fv.Type() != f.Type() {
			panicf("value %q is not correct type %s", fv, f.Type())
		}
		f.Set(fv)

	default:
		panicf("unsupported field type %s for field %s", f.Type(), field.Name)
	}
}

func indirectType(t reflect.Type) reflect.Type {
	if t.Kind() == reflect.Ptr || t.Kind() == reflect.Slice {
		return indirectType(t.Elem())
	}
	return t
}

func panicf(f string, args ...interface{}) {
	panic(Error(fmt.Sprintf(f, args...)))
}

type Error string

func (e Error) Error() string { return string(e) }
<|endoftext|>


<commit_before>// +build !windows

package singleinstance

import (
    "os"
    "syscall"
)

// CreateLockFile try to create a file with given name
// and acquire an exclusive lock on it
// if the file already exists AND is still locked, it will fail
func CreateLockFile(filename string) (*os.File, error) {
    file, err := os.OpenFile("plop", os.O_WRONLY, 0666)
    if err != nil {
        return nil, err
    }
    err = syscall.Flock(int(file.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
    if err != nil {
        return nil, err
    }
    return file, nil
}
<commit_msg>Use filename instead of hardcoded string<commit_after>// +build !windows

package singleinstance

import (
	"os"
	"syscall"
)

// CreateLockFile try to create a file with given name
// and acquire an exclusive lock on it
// if the file already exists AND is still locked, it will fail
func CreateLockFile(filename string) (*os.File, error) {
	file, err := os.OpenFile(filename, os.O_WRONLY, 0666)
	if err != nil {
		return nil, err
	}
	err = syscall.Flock(int(file.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
	if err != nil {
		return nil, err
	}
	return file, nil
}
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// 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 log

import (
	l "log"
	"strings"
)

// Level is a level of logging
type Level int

const (
	// Error log level
	Error Level = iota
	// Warn log level
	Warn
	// Info log level
	Info
	// Debug log level
	Debug
)

var levels = [...]Level{Error, Warn, Info, Debug}
var stringLevels = [...]string{"ERROR", "WARN", "INFO", "DEBUG"}

func (l Level) String() string {
	return stringLevels[l]
}

// ParseLevel parses the log level, returns Info level if not found
func ParseLevel(lvl string) Level {
	lvl = strings.ToUpper(lvl)
	for i, l := range stringLevels {
		if l == lvl {
			return levels[i]
		}
	}
	return Info
}

// Log is the global logger
var Log Logger = &defaultLogger{
	level: Info,
}

// Infof logs at the info level
func Infof(format string, args ...interface{}) {
	if InfoEnabled() {
		Log.Infof(format, args...)
	}
}

// Warnf logs suspect situations and recoverable errors
func Warnf(format string, args ...interface{}) {
	if WarnEnabled() {
		Log.Warnf(format, args...)
	}
}

// Errorf logs error conditions.
func Errorf(format string, args ...interface{}) {
	if ErrorEnabled() {
		Log.Errorf(format, args...)
	}
}

// Debugf logs potentially verbose debug-time data
func Debugf(format string, args ...interface{}) {
	if DebugEnabled() {
		Log.Debugf(format, args...)
	}
}

// InfoEnabled returns whether output of messages at the info level is currently enabled.
func InfoEnabled() bool {
	return Log.InfoEnabled()
}

// WarnEnabled returns whether output of messages at the warn level is currently enabled.
func WarnEnabled() bool {
	return Log.WarnEnabled()
}

// ErrorEnabled returns whether output of messages at the wanr level is currently enabled.
func ErrorEnabled() bool {
	return Log.ErrorEnabled()
}

// DebugEnabled returns whether output of messages at the debug level is currently enabled.
func DebugEnabled() bool {
	return Log.DebugEnabled()
}

// Logger is a logging interface
type Logger interface {
	// Debugf logs potentially verbose debug-time data
	Debugf(format string, args ...interface{})
	// Infof logs informational data
	Infof(format string, args ...interface{})
	// Warnf logs suspect situations and recoverable errors
	Warnf(format string, args ...interface{})
	// Errorf logs error conditions.
	Errorf(format string, args ...interface{})

	// Level gets the current logging level
	Level() Level
	// SetLevel set the current logging level
	SetLevel(level Level)

	// DebugEnabled returns whether output of messages at the debug level is currently enabled.
	DebugEnabled() bool
	// InfoEnabled returns whether output of messages at the info level is currently enabled.
	InfoEnabled() bool
	// WarnEnabled returns whether output of messages at the warn level is currently enabled.
	WarnEnabled() bool
	// ErrorEnabled returns whether output of messages at the error level is currently enabled.
	ErrorEnabled() bool
}

type defaultLogger struct {
	level Level
}

func (d *defaultLogger) Infof(format string, args ...interface{}) {
	if d.InfoEnabled() {
		d.printf(format, args...)
	}
}

// Warnf logs suspect situations and recoverable errors
func (d *defaultLogger) Warnf(format string, args ...interface{}) {
	if d.WarnEnabled() {
		d.printf(format, args...)
	}
}

// Errorf logs error conditions.
func (d *defaultLogger) Errorf(format string, args ...interface{}) {
	if d.ErrorEnabled() {
		d.printf(format, args...)
	}
}

// Debugf logs potentially verbose debug-time data
func (d *defaultLogger) Debugf(format string, args ...interface{}) {
	if d.DebugEnabled() {
		d.printf(format, args...)
	}
}

// formatted logging
func (d *defaultLogger) printf(format string, args ...interface{}) {
	format = d.level.String() + " " + format
	l.Printf(format, args...)
}

// InfoEnabled returns whether output of messages at the info level is currently enabled.
func (d *defaultLogger) InfoEnabled() bool {
	return d.level >= Info
}

// InfoEnabled returns whether output of messages at the warn level is currently enabled.
func (d *defaultLogger) WarnEnabled() bool {
	return d.level >= Warn
}

// ErrorEnabled returns whether output of messages at the wanr level is currently enabled.
func (d *defaultLogger) ErrorEnabled() bool {
	return d.level >= Error
}

// DebugEnabled returns whether output of messages at the debug level is currently enabled.
func (d *defaultLogger) DebugEnabled() bool {
	return d.level >= Debug
}

// DebugEnabled returns whether output of messages at the debug level is currently enabled.
func (d *defaultLogger) SetLevel(level Level) {
	d.level = level
}

// DebugEnabled returns whether output of messages at the debug level is currently enabled.
func (d *defaultLogger) Level() Level {
	return d.level
}

// 2020-03-10T20:51:11.261002Z	error
<commit_msg>fix logging<commit_after>// Copyright 2020 Google LLC
//
// 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 log

import (
	l "log"
	"strings"
)

// Level is a level of logging
type Level int

const (
	// Error log level
	Error Level = iota
	// Warn log level
	Warn
	// Info log level
	Info
	// Debug log level
	Debug
)

var levels = [...]Level{Error, Warn, Info, Debug}
var stringLevels = [...]string{"ERROR", "WARN", "INFO", "DEBUG"}

func (l Level) String() string {
	return stringLevels[l]
}

// ParseLevel parses the log level, returns Info level if not found
func ParseLevel(lvl string) Level {
	lvl = strings.ToUpper(lvl)
	for i, l := range stringLevels {
		if l == lvl {
			return levels[i]
		}
	}
	return Info
}

// Log is the global logger
var Log Logger = &defaultLogger{
	level: Info,
}

// Infof logs at the info level
func Infof(format string, args ...interface{}) {
	if InfoEnabled() {
		Log.Infof(format, args...)
	}
}

// Warnf logs suspect situations and recoverable errors
func Warnf(format string, args ...interface{}) {
	if WarnEnabled() {
		Log.Warnf(format, args...)
	}
}

// Errorf logs error conditions.
func Errorf(format string, args ...interface{}) {
	if ErrorEnabled() {
		Log.Errorf(format, args...)
	}
}

// Debugf logs potentially verbose debug-time data
func Debugf(format string, args ...interface{}) {
	if DebugEnabled() {
		Log.Debugf(format, args...)
	}
}

// InfoEnabled returns whether output of messages at the info level is currently enabled.
func InfoEnabled() bool {
	return Log.InfoEnabled()
}

// WarnEnabled returns whether output of messages at the warn level is currently enabled.
func WarnEnabled() bool {
	return Log.WarnEnabled()
}

// ErrorEnabled returns whether output of messages at the wanr level is currently enabled.
func ErrorEnabled() bool {
	return Log.ErrorEnabled()
}

// DebugEnabled returns whether output of messages at the debug level is currently enabled.
func DebugEnabled() bool {
	return Log.DebugEnabled()
}

// Logger is a logging interface
type Logger interface {
	// Debugf logs potentially verbose debug-time data
	Debugf(format string, args ...interface{})
	// Infof logs informational data
	Infof(format string, args ...interface{})
	// Warnf logs suspect situations and recoverable errors
	Warnf(format string, args ...interface{})
	// Errorf logs error conditions.
	Errorf(format string, args ...interface{})

	// Level gets the current logging level
	Level() Level
	// SetLevel set the current logging level
	SetLevel(level Level)

	// DebugEnabled returns whether output of messages at the debug level is currently enabled.
	DebugEnabled() bool
	// InfoEnabled returns whether output of messages at the info level is currently enabled.
	InfoEnabled() bool
	// WarnEnabled returns whether output of messages at the warn level is currently enabled.
	WarnEnabled() bool
	// ErrorEnabled returns whether output of messages at the error level is currently enabled.
	ErrorEnabled() bool
}

type defaultLogger struct {
	level Level
}

func (d *defaultLogger) Infof(format string, args ...interface{}) {
	if d.InfoEnabled() {
		d.printf(Info, format, args...)
	}
}

// Warnf logs suspect situations and recoverable errors
func (d *defaultLogger) Warnf(format string, args ...interface{}) {
	if d.WarnEnabled() {
		d.printf(Warn, format, args...)
	}
}

// Errorf logs error conditions.
func (d *defaultLogger) Errorf(format string, args ...interface{}) {
	if d.ErrorEnabled() {
		d.printf(Error, format, args...)
	}
}

// Debugf logs potentially verbose debug-time data
func (d *defaultLogger) Debugf(format string, args ...interface{}) {
	if d.DebugEnabled() {
		d.printf(Debug, format, args...)
	}
}

// formatted logging
func (d *defaultLogger) printf(lvl Level, format string, args ...interface{}) {
	format = lvl.String() + " " + format
	l.Printf(format, args...)
}

// InfoEnabled returns whether output of messages at the info level is currently enabled.
func (d *defaultLogger) InfoEnabled() bool {
	return d.level >= Info
}

// InfoEnabled returns whether output of messages at the warn level is currently enabled.
func (d *defaultLogger) WarnEnabled() bool {
	return d.level >= Warn
}

// ErrorEnabled returns whether output of messages at the wanr level is currently enabled.
func (d *defaultLogger) ErrorEnabled() bool {
	return d.level >= Error
}

// DebugEnabled returns whether output of messages at the debug level is currently enabled.
func (d *defaultLogger) DebugEnabled() bool {
	return d.level >= Debug
}

// DebugEnabled returns whether output of messages at the debug level is currently enabled.
func (d *defaultLogger) SetLevel(level Level) {
	d.level = level
}

// DebugEnabled returns whether output of messages at the debug level is currently enabled.
func (d *defaultLogger) Level() Level {
	return d.level
}
<|endoftext|>


<commit_before>package log

import (
	"fmt"
	"log"
	"os"
	"sync"
)

type Level string

var (
	logger = newDefaultLogger()
	mutex  = &sync.Mutex{}
)

const (
	DebugLevel Level = "DEBUG"
	InfoLevel  Level = "INFO"
	WarnLevel  Level = "WARN"
	ErrorLevel Level = "ERROR"
)

func (level Level) String() string {
	return string(level)
}

type Logger interface {
	Debug(args ...interface{})
	Debugf(format string, args ...interface{})

	Info(args ...interface{})
	Infof(format string, args ...interface{})

	Warn(args ...interface{})
	Warnf(format string, args ...interface{})

	Error(args ...interface{})
	Errorf(format string, args ...interface{})
}

type defaultLogger struct {
	logger *log.Logger
}

func (l *defaultLogger) Debug(args ...interface{}) {
	l.out(DebugLevel, args...)
}

func (l *defaultLogger) Debugf(format string, args ...interface{}) {
	l.outf(DebugLevel, format, args...)
}

func (l *defaultLogger) Info(args ...interface{}) {
	l.out(InfoLevel, args...)
}

func (l *defaultLogger) Infof(format string, args ...interface{}) {
	l.outf(InfoLevel, format, args...)
}

func (l *defaultLogger) Warn(args ...interface{}) {
	l.out(WarnLevel, args...)
}

func (l *defaultLogger) Warnf(format string, args ...interface{}) {
	l.outf(WarnLevel, format, args...)
}
func (l *defaultLogger) Error(args ...interface{}) {
	l.out(ErrorLevel, args...)
}

func (l *defaultLogger) Errorf(format string, args ...interface{}) {
	l.outf(ErrorLevel, format, args...)
}

func (l *defaultLogger) out(level Level, args ...interface{}) {
	// combine level identifier and given arguments for variadic function call
	leveledArgs := append([]interface{}{"[" + level.String() + "]"}, args...)
	l.logger.Output(4, fmt.Sprintln(leveledArgs...))
}

func (l *defaultLogger) outf(level Level, format string, args ...interface{}) {
	// combine level identifier and given arguments for variadic function call
	leveledArgs := append([]interface{}{level}, args...)
	l.logger.Output(4, fmt.Sprintf("[%s] "+format, leveledArgs...))
}

func newDefaultLogger() Logger {
	return &defaultLogger{
		logger: log.New(os.Stdout, "sarah ", log.LstdFlags|log.Llongfile),
	}
}

func SetLogger(l Logger) {
	mutex.Lock()
	defer mutex.Unlock()
	logger = l
}

func Debug(args ...interface{}) {
	logger.Debug(args...)
}

func Debugf(format string, args ...interface{}) {
	logger.Debugf(format, args...)
}

func Info(args ...interface{}) {
	logger.Info(args...)
}

func Infof(format string, args ...interface{}) {
	logger.Infof(format, args...)
}

func Warn(args ...interface{}) {
	logger.Warn(args...)
}

func Warnf(format string, args ...interface{}) {
	logger.Warnf(format, args...)
}

func Error(args ...interface{}) {
	logger.Error(args...)
}

func Errorf(format string, args ...interface{}) {
	logger.Errorf(format, args...)
}
<commit_msg>add comments<commit_after>package log

import (
	"fmt"
	"log"
	"os"
	"sync"
)

// Level indicates what logging level the output is representing.
// This typically indicates the severity of particular logging event.
type Level string

var (
	logger = newDefaultLogger()
	mutex  = &sync.Mutex{}
)

const (
	// DebugLevel indicates the output is logged for debugging purpose.
	DebugLevel Level = "DEBUG"

	// InfoLevel is used to inform what is happening inside the application.
	InfoLevel Level = "INFO"

	// WarnLevel represents those events that are not critical, but deserves to note.
	WarnLevel Level = "WARN"

	// ErrorLevel indicates the error state of events. This must be noted and be fixed.
	// In practical situation, fix may include lowering of the log level.
	ErrorLevel Level = "ERROR"
)

// String returns the stringified representation of log level.
func (level Level) String() string {
	return string(level)
}

// Logger defines the interface that can be used as logging tool in this application.
// Developer may provide a customized logger via SetLogger to modify behavior.
// By default, instance of defaultLogger is set as default Logger just like http's DefaultClient.
type Logger interface {
	Debug(args ...interface{})
	Debugf(format string, args ...interface{})

	Info(args ...interface{})
	Infof(format string, args ...interface{})

	Warn(args ...interface{})
	Warnf(format string, args ...interface{})

	Error(args ...interface{})
	Errorf(format string, args ...interface{})
}

type defaultLogger struct {
	logger *log.Logger
}

func (l *defaultLogger) Debug(args ...interface{}) {
	l.out(DebugLevel, args...)
}

func (l *defaultLogger) Debugf(format string, args ...interface{}) {
	l.outf(DebugLevel, format, args...)
}

func (l *defaultLogger) Info(args ...interface{}) {
	l.out(InfoLevel, args...)
}

func (l *defaultLogger) Infof(format string, args ...interface{}) {
	l.outf(InfoLevel, format, args...)
}

func (l *defaultLogger) Warn(args ...interface{}) {
	l.out(WarnLevel, args...)
}

func (l *defaultLogger) Warnf(format string, args ...interface{}) {
	l.outf(WarnLevel, format, args...)
}
func (l *defaultLogger) Error(args ...interface{}) {
	l.out(ErrorLevel, args...)
}

func (l *defaultLogger) Errorf(format string, args ...interface{}) {
	l.outf(ErrorLevel, format, args...)
}

func (l *defaultLogger) out(level Level, args ...interface{}) {
	// combine level identifier and given arguments for variadic function call
	leveledArgs := append([]interface{}{"[" + level.String() + "]"}, args...)
	l.logger.Output(4, fmt.Sprintln(leveledArgs...))
}

func (l *defaultLogger) outf(level Level, format string, args ...interface{}) {
	// combine level identifier and given arguments for variadic function call
	leveledArgs := append([]interface{}{level}, args...)
	l.logger.Output(4, fmt.Sprintf("[%s] "+format, leveledArgs...))
}

func newDefaultLogger() Logger {
	return &defaultLogger{
		logger: log.New(os.Stdout, "sarah ", log.LstdFlags|log.Llongfile),
	}
}

// SetLogger receives struct that satisfies Logger interface, and set this as logger.
// From this call forward, any call to logging method proxies arguments to corresponding logging method of given Logger.
// e.g. call to log.Info points to Logger.Info.
//
// This method is "thread-safe."
func SetLogger(l Logger) {
	mutex.Lock()
	defer mutex.Unlock()
	logger = l
}

func Debug(args ...interface{}) {
	logger.Debug(args...)
}

func Debugf(format string, args ...interface{}) {
	logger.Debugf(format, args...)
}

func Info(args ...interface{}) {
	logger.Info(args...)
}

func Infof(format string, args ...interface{}) {
	logger.Infof(format, args...)
}

func Warn(args ...interface{}) {
	logger.Warn(args...)
}

func Warnf(format string, args ...interface{}) {
	logger.Warnf(format, args...)
}

func Error(args ...interface{}) {
	logger.Error(args...)
}

func Errorf(format string, args ...interface{}) {
	logger.Errorf(format, args...)
}
<|endoftext|>


<commit_before>package dexcom

import (
	"bytes"
	"fmt"
	"log"
	"time"

	"github.com/ecc1/ble"
)

type bleConn struct {
	tx ble.Characteristic
	rx chan byte
}

// Dexcom G4 Share expects each BLE message to start with two 01 bytes.
func (conn *bleConn) Frame(data []byte) []byte {
	return append([]byte{1, 1}, data...)
}

const (
	// maximum size of writes to GATT characteristics
	gattMTU = 20
)

func (conn *bleConn) Send(data []byte) error {
	for {
		n := len(data)
		if n == 0 {
			return nil
		}
		if n > gattMTU {
			n = gattMTU
		}
		err := conn.tx.WriteValue(data[:n])
		if err != nil {
			return err
		}
		data = data[n:]
	}
}

func (conn *bleConn) Receive(data []byte) error {
	for i := 0; i < len(data); i++ {
		b, ok := <-conn.rx
		if !ok {
			return fmt.Errorf("input channel closed")
		}
		data[i] = b
	}
	return nil
}

var (
	receiverService = dexcomUUID(0xa0b1)
)

func connect() error {
	device, err := ble.Discover(time.Minute, receiverService)
	if err != nil {
		return err
	}
	if !device.Connected() {
		err = device.Connect()
		if err != nil {
			return err
		}
		log.Printf("%s: connected\n", device.Name())
	} else {
		log.Printf("%s: already connected\n", device.Name())
	}
	if !device.Paired() {
		err = device.Pair()
		if err != nil {
			return err
		}
		log.Printf("%s: paired\n", device.Name())
	} else {
		log.Printf("%s: already paired\n", device.Name())
	}
	err = ble.Update()
	if err != nil {
		return err
	}
	return authenticate(device)
}

var (
	authentication = dexcomUUID(0xacac)
	authCode       = []byte(serialNumber + "000000")
)

func authenticate(device ble.Device) error {
	auth, err := ble.GetCharacteristic(authentication)
	if err != nil {
		return err
	}
	data, err := auth.ReadValue()
	if err != nil {
		return err
	}
	if bytes.Equal(data, authCode) {
		log.Printf("%s: already authenticated\n", device.Name())
		return nil
	}
	err = auth.WriteValue(authCode)
	if err != nil {
		return err
	}
	log.Printf("%s: authenticated\n", device.Name())
	return nil
}

var (
	heartbeat   = dexcomUUID(0x2b18)
	sendData    = dexcomUUID(0xb20a)
	receiveData = dexcomUUID(0xb20b)
)

func OpenBLE() (Connection, error) {
	err := connect()
	if err != nil {
		return nil, err
	}

	// We need to enable heartbeat notifications
	// or else we won't get any receiveData responses.
	err = ble.HandleNotify(heartbeat, func(data []byte) {})
	if err != nil {
		return nil, err
	}

	rx := make(chan byte, 1600)
	err = ble.HandleNotify(receiveData, func(data []byte) {
		for _, b := range data {
			rx <- b
		}
	})
	if err != nil {
		return nil, err
	}

	tx, err := ble.GetCharacteristic(sendData)
	if err != nil {
		return nil, err
	}

	return &bleConn{
		tx: tx,
		rx: rx,
	}, nil
}

func dexcomUUID(id uint16) string {
	return "f0ac" + fmt.Sprintf("%04x", id) + "-ebfa-f96f-28da-076c35a521db"
}
<commit_msg>Improve dexcomUUID function<commit_after>package dexcom

import (
	"bytes"
	"fmt"
	"log"
	"time"

	"github.com/ecc1/ble"
)

type bleConn struct {
	tx ble.Characteristic
	rx chan byte
}

// Dexcom G4 Share expects each BLE message to start with two 01 bytes.
func (conn *bleConn) Frame(data []byte) []byte {
	return append([]byte{1, 1}, data...)
}

const (
	// maximum size of writes to GATT characteristics
	gattMTU = 20
)

func (conn *bleConn) Send(data []byte) error {
	for {
		n := len(data)
		if n == 0 {
			return nil
		}
		if n > gattMTU {
			n = gattMTU
		}
		err := conn.tx.WriteValue(data[:n])
		if err != nil {
			return err
		}
		data = data[n:]
	}
}

func (conn *bleConn) Receive(data []byte) error {
	for i := 0; i < len(data); i++ {
		b, ok := <-conn.rx
		if !ok {
			return fmt.Errorf("input channel closed")
		}
		data[i] = b
	}
	return nil
}

var (
	receiverService = dexcomUUID(0xa0b1)
)

func connect() error {
	device, err := ble.Discover(time.Minute, receiverService)
	if err != nil {
		return err
	}
	if !device.Connected() {
		err = device.Connect()
		if err != nil {
			return err
		}
		log.Printf("%s: connected\n", device.Name())
	} else {
		log.Printf("%s: already connected\n", device.Name())
	}
	if !device.Paired() {
		err = device.Pair()
		if err != nil {
			return err
		}
		log.Printf("%s: paired\n", device.Name())
	} else {
		log.Printf("%s: already paired\n", device.Name())
	}
	err = ble.Update()
	if err != nil {
		return err
	}
	return authenticate(device)
}

var (
	authentication = dexcomUUID(0xacac)
	authCode       = []byte(serialNumber + "000000")
)

func authenticate(device ble.Device) error {
	auth, err := ble.GetCharacteristic(authentication)
	if err != nil {
		return err
	}
	data, err := auth.ReadValue()
	if err != nil {
		return err
	}
	if bytes.Equal(data, authCode) {
		log.Printf("%s: already authenticated\n", device.Name())
		return nil
	}
	err = auth.WriteValue(authCode)
	if err != nil {
		return err
	}
	log.Printf("%s: authenticated\n", device.Name())
	return nil
}

var (
	heartbeat   = dexcomUUID(0x2b18)
	sendData    = dexcomUUID(0xb20a)
	receiveData = dexcomUUID(0xb20b)
)

func OpenBLE() (Connection, error) {
	err := connect()
	if err != nil {
		return nil, err
	}

	// We need to enable heartbeat notifications
	// or else we won't get any receiveData responses.
	err = ble.HandleNotify(heartbeat, func(data []byte) {})
	if err != nil {
		return nil, err
	}

	rx := make(chan byte, 1600)
	err = ble.HandleNotify(receiveData, func(data []byte) {
		for _, b := range data {
			rx <- b
		}
	})
	if err != nil {
		return nil, err
	}

	tx, err := ble.GetCharacteristic(sendData)
	if err != nil {
		return nil, err
	}

	return &bleConn{
		tx: tx,
		rx: rx,
	}, nil
}

func dexcomUUID(id uint16) string {
	return fmt.Sprintf("f0ac%04x-ebfa-f96f-28da-076c35a521db", id)
}
<|endoftext|>


<commit_before>package xlsx

import (
	"fmt"
	"strconv"
)

// Sheet is a high level structure intended to provide user access to
// the contents of a particular sheet within an XLSX file.
type Sheet struct {
	Name        string
	File        *File
	Rows        []*Row
	Cols        []*Col
	MaxRow      int
	MaxCol      int
	Hidden      bool
	SheetViews  []SheetView
	SheetFormat SheetFormat
}

type SheetView struct {
	Pane *Pane
}

type Pane struct {
	XSplit      float64
	YSplit      float64
	TopLeftCell string
	ActivePane  string
	State       string // Either "split" or "frozen"
}

type SheetFormat struct {
	DefaultColWidth  float64
	DefaultRowHeight float64
}

// Add a new Row to a Sheet
func (s *Sheet) AddRow() *Row {
	row := &Row{Sheet: s}
	s.Rows = append(s.Rows, row)
	if len(s.Rows) > s.MaxRow {
		s.MaxRow = len(s.Rows)
	}
	return row
}

// Make sure we always have as many Cols as we do cells.
func (s *Sheet) maybeAddCol(cellCount int) {
	if cellCount > s.MaxCol {
		col := &Col{
			style:     NewStyle(),
			Min:       cellCount,
			Max:       cellCount,
			Hidden:    false,
			Collapsed: false,
			Width:     ColWidth}
		s.Cols = append(s.Cols, col)
		s.MaxCol = cellCount
	}
}

// Make sure we always have as many Cols as we do cells.
func (s *Sheet) Col(idx int) *Col {
	s.maybeAddCol(idx + 1)
	return s.Cols[idx]
}

// Get a Cell by passing it's cartesian coordinates (zero based) as
// row and column integer indexes.
//
// For example:
//
//    cell := sheet.Cell(0,0)
//
// ... would set the variable "cell" to contain a Cell struct
// containing the data from the field "A1" on the spreadsheet.
func (sh *Sheet) Cell(row, col int) *Cell {

	if len(sh.Rows) > row && sh.Rows[row] != nil && len(sh.Rows[row].Cells) > col {
		return sh.Rows[row].Cells[col]
	}
	return new(Cell)
}

//Set the width of a single column or multiple columns.
func (s *Sheet) SetColWidth(startcol, endcol int, width float64) error {
	if startcol > endcol {
		return fmt.Errorf("Could not set width for range %d-%d: startcol must be less than endcol.", startcol, endcol)
	}
	col := &Col{
		style:     NewStyle(),
		Min:       startcol + 1,
		Max:       endcol + 1,
		Hidden:    false,
		Collapsed: false,
		Width:     width}
	s.Cols = append(s.Cols, col)
	if endcol+1 > s.MaxCol {
		s.MaxCol = endcol + 1
	}
	return nil
}

// Dump sheet to its XML representation, intended for internal use only
func (s *Sheet) makeXLSXSheet(refTable *RefTable, styles *xlsxStyleSheet) *xlsxWorksheet {
	worksheet := newXlsxWorksheet()
	xSheet := xlsxSheetData{}
	maxRow := 0
	maxCell := 0

	colsXfIdList := make([]int, len(s.Cols))
	worksheet.Cols = xlsxCols{Col: []xlsxCol{}}
	for c, col := range s.Cols {
		XfId := 0

		style := col.GetStyle()
		//col's style always not nil
		if style != nil {
			xNumFmt := styles.newNumFmt(col.numFmt)
			XfId = handleStyleForXLSX(style, xNumFmt.NumFmtId, styles)
		}
		colsXfIdList[c] = XfId

		if col.Width == 0 {
			col.Width = ColWidth
		}
		worksheet.Cols.Col = append(worksheet.Cols.Col,
			xlsxCol{Min: col.Min,
				Max:       col.Max,
				Hidden:    col.Hidden,
				Width:     col.Width,
				Collapsed: col.Collapsed,
				Style:     XfId,
			})
	}

	for r, row := range s.Rows {
		if r > maxRow {
			maxRow = r
		}
		xRow := xlsxRow{}
		xRow.R = r + 1
		if row.isCustom {
			xRow.CustomHeight = true
			xRow.Ht = fmt.Sprintf("%g", row.Height)
		}
		for c, cell := range row.Cells {
			XfId := colsXfIdList[c]

			// generate NumFmtId and add new NumFmt
			xNumFmt := styles.newNumFmt(cell.numFmt)

			style := cell.style
			if style != nil {
				XfId = handleStyleForXLSX(style, xNumFmt.NumFmtId, styles)
			} else if len(cell.numFmt) > 0 && s.Cols[c].numFmt != cell.numFmt {
				XfId = handleNumFmtIdForXLSX(xNumFmt.NumFmtId, styles)
			}

			if c > maxCell {
				maxCell = c
			}
			xC := xlsxC{}
			xC.R = fmt.Sprintf("%s%d", numericToLetters(c), r+1)
			switch cell.cellType {
			case CellTypeString:
				xC.V = strconv.Itoa(refTable.AddString(cell.Value))
				xC.T = "s"
				xC.S = XfId
			case CellTypeBool:
				xC.V = cell.Value
				xC.T = "b"
				xC.S = XfId
			case CellTypeNumeric:
				xC.V = cell.Value
				xC.S = XfId
			case CellTypeDate:
				xC.V = cell.Value
				xC.S = XfId
			case CellTypeFormula:
				xC.V = cell.Value
				xC.F = &xlsxF{Content: cell.formula}
				xC.S = XfId
			case CellTypeError:
				xC.V = cell.Value
				xC.F = &xlsxF{Content: cell.formula}
				xC.T = "e"
				xC.S = XfId
			case CellTypeGeneral:
				xC.V = cell.Value
				xC.S = XfId
			}
			xRow.C = append(xRow.C, xC)

			if cell.HMerge > 0 || cell.VMerge > 0 {
				// r == rownum, c == colnum
				mc := xlsxMergeCell{}
				start := fmt.Sprintf("%s%d", numericToLetters(c), r+1)
				endcol := c + cell.HMerge
				endrow := r + cell.VMerge + 1
				end := fmt.Sprintf("%s%d", numericToLetters(endcol), endrow)
				mc.Ref = start + ":" + end
				if worksheet.MergeCells == nil {
					worksheet.MergeCells = &xlsxMergeCells{}
				}
				worksheet.MergeCells.Cells = append(worksheet.MergeCells.Cells, mc)
			}
		}
		xSheet.Row = append(xSheet.Row, xRow)
	}

	if worksheet.MergeCells != nil {
		worksheet.MergeCells.Count = len(worksheet.MergeCells.Cells)
	}

	worksheet.SheetData = xSheet
	dimension := xlsxDimension{}
	dimension.Ref = fmt.Sprintf("A1:%s%d",
		numericToLetters(maxCell), maxRow+1)
	if dimension.Ref == "A1:A1" {
		dimension.Ref = "A1"
	}
	worksheet.Dimension = dimension
	return worksheet
}

func handleStyleForXLSX(style *Style, NumFmtId int, styles *xlsxStyleSheet) (XfId int) {
	xFont, xFill, xBorder, xCellStyleXf, xCellXf := style.makeXLSXStyleElements()
	fontId := styles.addFont(xFont)
	fillId := styles.addFill(xFill)

	// HACK - adding light grey fill, as in OO and Google
	greyfill := xlsxFill{}
	greyfill.PatternFill.PatternType = "lightGrey"
	styles.addFill(greyfill)

	borderId := styles.addBorder(xBorder)
	xCellStyleXf.FontId = fontId
	xCellStyleXf.FillId = fillId
	xCellStyleXf.BorderId = borderId
	xCellStyleXf.NumFmtId = builtInNumFmtIndex_GENERAL
	xCellXf.FontId = fontId
	xCellXf.FillId = fillId
	xCellXf.BorderId = borderId
	xCellXf.NumFmtId = NumFmtId
	// apply the numFmtId when it is not the default cellxf
	if xCellXf.NumFmtId > 0 {
		xCellXf.ApplyNumberFormat = true
	}

	xCellStyleXf.Alignment.Horizontal = style.Alignment.Horizontal
	xCellStyleXf.Alignment.Vertical = style.Alignment.Vertical
	xCellXf.Alignment.Horizontal = style.Alignment.Horizontal
	xCellXf.Alignment.Vertical = style.Alignment.Vertical

	styles.addCellStyleXf(xCellStyleXf)
	XfId = styles.addCellXf(xCellXf)
	return
}

func handleNumFmtIdForXLSX(NumFmtId int, styles *xlsxStyleSheet) (XfId int) {
	xCellXf := makeXLSXCellElement()
	xCellXf.NumFmtId = NumFmtId
	XfId = styles.addCellXf(xCellXf)
	return
}
<commit_msg>Enable modification of sheet DefaultRowHeight and DefaultColWidth<commit_after>package xlsx

import (
	"fmt"
	"strconv"
)

// Sheet is a high level structure intended to provide user access to
// the contents of a particular sheet within an XLSX file.
type Sheet struct {
	Name        string
	File        *File
	Rows        []*Row
	Cols        []*Col
	MaxRow      int
	MaxCol      int
	Hidden      bool
	SheetViews  []SheetView
	SheetFormat SheetFormat
}

type SheetView struct {
	Pane *Pane
}

type Pane struct {
	XSplit      float64
	YSplit      float64
	TopLeftCell string
	ActivePane  string
	State       string // Either "split" or "frozen"
}

type SheetFormat struct {
	DefaultColWidth  float64
	DefaultRowHeight float64
}

// Add a new Row to a Sheet
func (s *Sheet) AddRow() *Row {
	row := &Row{Sheet: s}
	s.Rows = append(s.Rows, row)
	if len(s.Rows) > s.MaxRow {
		s.MaxRow = len(s.Rows)
	}
	return row
}

// Make sure we always have as many Cols as we do cells.
func (s *Sheet) maybeAddCol(cellCount int) {
	if cellCount > s.MaxCol {
		col := &Col{
			style:     NewStyle(),
			Min:       cellCount,
			Max:       cellCount,
			Hidden:    false,
			Collapsed: false,
			Width:     ColWidth}
		s.Cols = append(s.Cols, col)
		s.MaxCol = cellCount
	}
}

// Make sure we always have as many Cols as we do cells.
func (s *Sheet) Col(idx int) *Col {
	s.maybeAddCol(idx + 1)
	return s.Cols[idx]
}

// Get a Cell by passing it's cartesian coordinates (zero based) as
// row and column integer indexes.
//
// For example:
//
//    cell := sheet.Cell(0,0)
//
// ... would set the variable "cell" to contain a Cell struct
// containing the data from the field "A1" on the spreadsheet.
func (sh *Sheet) Cell(row, col int) *Cell {

	if len(sh.Rows) > row && sh.Rows[row] != nil && len(sh.Rows[row].Cells) > col {
		return sh.Rows[row].Cells[col]
	}
	return new(Cell)
}

//Set the width of a single column or multiple columns.
func (s *Sheet) SetColWidth(startcol, endcol int, width float64) error {
	if startcol > endcol {
		return fmt.Errorf("Could not set width for range %d-%d: startcol must be less than endcol.", startcol, endcol)
	}
	col := &Col{
		style:     NewStyle(),
		Min:       startcol + 1,
		Max:       endcol + 1,
		Hidden:    false,
		Collapsed: false,
		Width:     width}
	s.Cols = append(s.Cols, col)
	if endcol+1 > s.MaxCol {
		s.MaxCol = endcol + 1
	}
	return nil
}

// Dump sheet to its XML representation, intended for internal use only
func (s *Sheet) makeXLSXSheet(refTable *RefTable, styles *xlsxStyleSheet) *xlsxWorksheet {
	worksheet := newXlsxWorksheet()
	xSheet := xlsxSheetData{}
	maxRow := 0
	maxCell := 0

	if s.SheetFormat.DefaultRowHeight != 0 {
		worksheet.SheetFormatPr.DefaultRowHeight = s.SheetFormat.DefaultRowHeight
	}
	worksheet.SheetFormatPr.DefaultColWidth = s.SheetFormat.DefaultColWidth

	colsXfIdList := make([]int, len(s.Cols))
	worksheet.Cols = xlsxCols{Col: []xlsxCol{}}
	for c, col := range s.Cols {
		XfId := 0

		style := col.GetStyle()
		//col's style always not nil
		if style != nil {
			xNumFmt := styles.newNumFmt(col.numFmt)
			XfId = handleStyleForXLSX(style, xNumFmt.NumFmtId, styles)
		}
		colsXfIdList[c] = XfId

		if col.Width == 0 {
			col.Width = ColWidth
		}
		worksheet.Cols.Col = append(worksheet.Cols.Col,
			xlsxCol{Min: col.Min,
				Max:       col.Max,
				Hidden:    col.Hidden,
				Width:     col.Width,
				Collapsed: col.Collapsed,
				Style:     XfId,
			})
	}

	for r, row := range s.Rows {
		if r > maxRow {
			maxRow = r
		}
		xRow := xlsxRow{}
		xRow.R = r + 1
		if row.isCustom {
			xRow.CustomHeight = true
			xRow.Ht = fmt.Sprintf("%g", row.Height)
		}
		for c, cell := range row.Cells {
			XfId := colsXfIdList[c]

			// generate NumFmtId and add new NumFmt
			xNumFmt := styles.newNumFmt(cell.numFmt)

			style := cell.style
			if style != nil {
				XfId = handleStyleForXLSX(style, xNumFmt.NumFmtId, styles)
			} else if len(cell.numFmt) > 0 && s.Cols[c].numFmt != cell.numFmt {
				XfId = handleNumFmtIdForXLSX(xNumFmt.NumFmtId, styles)
			}

			if c > maxCell {
				maxCell = c
			}
			xC := xlsxC{}
			xC.R = fmt.Sprintf("%s%d", numericToLetters(c), r+1)
			switch cell.cellType {
			case CellTypeString:
				xC.V = strconv.Itoa(refTable.AddString(cell.Value))
				xC.T = "s"
				xC.S = XfId
			case CellTypeBool:
				xC.V = cell.Value
				xC.T = "b"
				xC.S = XfId
			case CellTypeNumeric:
				xC.V = cell.Value
				xC.S = XfId
			case CellTypeDate:
				xC.V = cell.Value
				xC.S = XfId
			case CellTypeFormula:
				xC.V = cell.Value
				xC.F = &xlsxF{Content: cell.formula}
				xC.S = XfId
			case CellTypeError:
				xC.V = cell.Value
				xC.F = &xlsxF{Content: cell.formula}
				xC.T = "e"
				xC.S = XfId
			case CellTypeGeneral:
				xC.V = cell.Value
				xC.S = XfId
			}
			xRow.C = append(xRow.C, xC)

			if cell.HMerge > 0 || cell.VMerge > 0 {
				// r == rownum, c == colnum
				mc := xlsxMergeCell{}
				start := fmt.Sprintf("%s%d", numericToLetters(c), r+1)
				endcol := c + cell.HMerge
				endrow := r + cell.VMerge + 1
				end := fmt.Sprintf("%s%d", numericToLetters(endcol), endrow)
				mc.Ref = start + ":" + end
				if worksheet.MergeCells == nil {
					worksheet.MergeCells = &xlsxMergeCells{}
				}
				worksheet.MergeCells.Cells = append(worksheet.MergeCells.Cells, mc)
			}
		}
		xSheet.Row = append(xSheet.Row, xRow)
	}

	if worksheet.MergeCells != nil {
		worksheet.MergeCells.Count = len(worksheet.MergeCells.Cells)
	}

	worksheet.SheetData = xSheet
	dimension := xlsxDimension{}
	dimension.Ref = fmt.Sprintf("A1:%s%d",
		numericToLetters(maxCell), maxRow+1)
	if dimension.Ref == "A1:A1" {
		dimension.Ref = "A1"
	}
	worksheet.Dimension = dimension
	return worksheet
}

func handleStyleForXLSX(style *Style, NumFmtId int, styles *xlsxStyleSheet) (XfId int) {
	xFont, xFill, xBorder, xCellStyleXf, xCellXf := style.makeXLSXStyleElements()
	fontId := styles.addFont(xFont)
	fillId := styles.addFill(xFill)

	// HACK - adding light grey fill, as in OO and Google
	greyfill := xlsxFill{}
	greyfill.PatternFill.PatternType = "lightGrey"
	styles.addFill(greyfill)

	borderId := styles.addBorder(xBorder)
	xCellStyleXf.FontId = fontId
	xCellStyleXf.FillId = fillId
	xCellStyleXf.BorderId = borderId
	xCellStyleXf.NumFmtId = builtInNumFmtIndex_GENERAL
	xCellXf.FontId = fontId
	xCellXf.FillId = fillId
	xCellXf.BorderId = borderId
	xCellXf.NumFmtId = NumFmtId
	// apply the numFmtId when it is not the default cellxf
	if xCellXf.NumFmtId > 0 {
		xCellXf.ApplyNumberFormat = true
	}

	xCellStyleXf.Alignment.Horizontal = style.Alignment.Horizontal
	xCellStyleXf.Alignment.Vertical = style.Alignment.Vertical
	xCellXf.Alignment.Horizontal = style.Alignment.Horizontal
	xCellXf.Alignment.Vertical = style.Alignment.Vertical

	styles.addCellStyleXf(xCellStyleXf)
	XfId = styles.addCellXf(xCellXf)
	return
}

func handleNumFmtIdForXLSX(NumFmtId int, styles *xlsxStyleSheet) (XfId int) {
	xCellXf := makeXLSXCellElement()
	xCellXf.NumFmtId = NumFmtId
	XfId = styles.addCellXf(xCellXf)
	return
}
<|endoftext|>


<commit_before>package main

var deployment_script string = `
#!/bin/bash
# comment line below if you want quiet output
set -x

DEPLOYMENT_PATH=$1
REPOSITORY=$2
KEEP_RELEASES=$3
# variable init
CUR_TIMESTAMP="$(date +'%Y%m%d%H%M%S')"

# update code base with remote_cache strategy
if [ -d "$DEPLOYMENT_PATH/shared/cached-copy" ]
then
  cd "$DEPLOYMENT_PATH/shared/cached-copy"
  git fetch -q origin
  git fetch --tags -q origin
  git rev-list --max-count=1 HEAD | xargs git reset -q --hard
  git clean -q -d -x -f;
else
  git clone -q $REPOSITORY "$DEPLOYMENT_PATH/shared/cached-copy"
  cd "$DEPLOYMENT_PATH/shared/cached-copy"
  git rev-list --max-count=1 HEAD | xargs git checkout -q -b deploy
fi
cp -RPp "$DEPLOYMENT_PATH/shared/cached-copy" "$DEPLOYMENT_PATH/releases/$CUR_TIMESTAMP"
git rev-list --max-count=1 HEAD > "$DEPLOYMENT_PATH/releases/$CUR_TIMESTAMP/REVISION"
chmod -R g+w "$DEPLOYMENT_PATH/releases/$CUR_TIMESTAMP"

rm -f "$DEPLOYMENT_PATH/current" &&  ln -s "$DEPLOYMENT_PATH/releases/$CUR_TIMESTAMP" "$DEPLOYMENT_PATH/current"
ls -1dt "$DEPLOYMENT_PATH/releases/*" | tail -n +$KEEP_RELEASES |  xargs rm -rf
`
<commit_msg>remove beginning newline, comment set -x<commit_after>package main

var deployment_script string = `#!/bin/bash
# comment line below if you want quiet output
#set -x

DEPLOYMENT_PATH=$1
REPOSITORY=$2
KEEP_RELEASES=$3
# variable init
CUR_TIMESTAMP="$(date +'%Y%m%d%H%M%S')"

# update code base with remote_cache strategy
if [ -d "$DEPLOYMENT_PATH/shared/cached-copy" ]
then
  cd "$DEPLOYMENT_PATH/shared/cached-copy"
  git fetch -q origin
  git fetch --tags -q origin
  git rev-list --max-count=1 HEAD | xargs git reset -q --hard
  git clean -q -d -x -f;
else
  git clone -q $REPOSITORY "$DEPLOYMENT_PATH/shared/cached-copy"
  cd "$DEPLOYMENT_PATH/shared/cached-copy"
  git rev-list --max-count=1 HEAD | xargs git checkout -q -b deploy
fi
cp -RPp "$DEPLOYMENT_PATH/shared/cached-copy" "$DEPLOYMENT_PATH/releases/$CUR_TIMESTAMP"
git rev-list --max-count=1 HEAD > "$DEPLOYMENT_PATH/releases/$CUR_TIMESTAMP/REVISION"
chmod -R g+w "$DEPLOYMENT_PATH/releases/$CUR_TIMESTAMP"

rm -f "$DEPLOYMENT_PATH/current" &&  ln -s "$DEPLOYMENT_PATH/releases/$CUR_TIMESTAMP" "$DEPLOYMENT_PATH/current"
ls -1dt "$DEPLOYMENT_PATH/releases/*" | tail -n +$KEEP_RELEASES |  xargs rm -rf
`
<|endoftext|>


<commit_before>// Copyright 2013 com 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 com

import (
	"math/rand"
	"strings"
	"time"
)

// AppendStr appends string to slice with no duplicates.
func AppendStr(strs []string, str string) []string {
	for _, s := range strs {
		if s == str {
			return strs
		}
	}
	return append(strs, str)
}

// CompareSliceStr compares two 'string' type slices.
// It returns true if elements and order are both the same.
func CompareSliceStr(s1, s2 []string) bool {
	if len(s1) != len(s2) {
		return false
	}

	for i := range s1 {
		if s1[i] != s2[i] {
			return false
		}
	}

	return true
}

// CompareSliceStr compares two 'string' type slices.
// It returns true if elements are the same, and ignores the order.
func CompareSliceStrU(s1, s2 []string) bool {
	if len(s1) != len(s2) {
		return false
	}

	for i := range s1 {
		for j := len(s2) - 1; j >= 0; j-- {
			if s1[i] == s2[j] {
				s2 = append(s2[:j], s2[j+1:]...)
				break
			}
		}
	}
	if len(s2) > 0 {
		return false
	}
	return true
}

// IsSliceContainsStr returns true if the string exists in given slice.
func IsSliceContainsStr(sl []string, str string) bool {
	str = strings.ToLower(str)
	for _, s := range sl {
		if strings.ToLower(s) == str {
			return true
		}
	}
	return false
}

// IsSliceContainsInt64 returns true if the int64 exists in given slice.
func IsSliceContainsInt64(sl []int64, i int64) bool {
	for _, s := range sl {
		if s == i {
			return true
		}
	}
	return false
}

// ==============================
type reducetype func(interface{}) interface{}
type filtertype func(interface{}) bool

func InSlice(v string, sl []string) bool {
	for _, vv := range sl {
		if vv == v {
			return true
		}
	}
	return false
}

func InSliceIface(v interface{}, sl []interface{}) bool {
	for _, vv := range sl {
		if vv == v {
			return true
		}
	}
	return false
}

func SliceRandList(min, max int) []int {
	if max < min {
		min, max = max, min
	}
	length := max - min + 1
	t0 := time.Now()
	rand.Seed(int64(t0.Nanosecond()))
	list := rand.Perm(length)
	for index := range list {
		list[index] += min
	}
	return list
}

func SliceMerge(slice1, slice2 []interface{}) (c []interface{}) {
	c = append(slice1, slice2...)
	return
}

func SliceReduce(slice []interface{}, a reducetype) (dslice []interface{}) {
	for _, v := range slice {
		dslice = append(dslice, a(v))
	}
	return
}

func SliceRand(a []interface{}) (b interface{}) {
	randnum := rand.Intn(len(a))
	b = a[randnum]
	return
}

func SliceSum(intslice []int64) (sum int64) {
	for _, v := range intslice {
		sum += v
	}
	return
}

func SliceFilter(slice []interface{}, a filtertype) (ftslice []interface{}) {
	for _, v := range slice {
		if a(v) {
			ftslice = append(ftslice, v)
		}
	}
	return
}

func SliceDiff(slice1, slice2 []interface{}) (diffslice []interface{}) {
	for _, v := range slice1 {
		if !InSliceIface(v, slice2) {
			diffslice = append(diffslice, v)
		}
	}
	return
}

func SliceIntersect(slice1, slice2 []interface{}) (diffslice []interface{}) {
	for _, v := range slice1 {
		if !InSliceIface(v, slice2) {
			diffslice = append(diffslice, v)
		}
	}
	return
}

func SliceChunk(slice []interface{}, size int) (chunkslice [][]interface{}) {
	if size >= len(slice) {
		chunkslice = append(chunkslice, slice)
		return
	}
	end := size
	for i := 0; i <= (len(slice) - size); i += size {
		chunkslice = append(chunkslice, slice[i:end])
		end += size
	}
	return
}

func SliceRange(start, end, step int64) (intslice []int64) {
	for i := start; i <= end; i += step {
		intslice = append(intslice, i)
	}
	return
}

func SlicePad(slice []interface{}, size int, val interface{}) []interface{} {
	if size <= len(slice) {
		return slice
	}
	for i := 0; i < (size - len(slice)); i++ {
		slice = append(slice, val)
	}
	return slice
}

func SliceUnique(slice []interface{}) (uniqueslice []interface{}) {
	for _, v := range slice {
		if !InSliceIface(v, uniqueslice) {
			uniqueslice = append(uniqueslice, v)
		}
	}
	return
}

func SliceShuffle(slice []interface{}) []interface{} {
	for i := 0; i < len(slice); i++ {
		a := rand.Intn(len(slice))
		b := rand.Intn(len(slice))
		slice[a], slice[b] = slice[b], slice[a]
	}
	return slice
}

func SliceInsert(slice, insertion []interface{}, index int) []interface{} {
	result := make([]interface{}, len(slice)+len(insertion))
	at := copy(result, slice[:index])
	at += copy(result[at:], insertion)
	copy(result[at:], slice[index:])
	return result
}

//SliceRomove(a,4,5) //a[4]
func SliceRemove(slice []interface{}, start int, args ...int) []interface{} {
	var end int
	if len(args) == 0 {
		end = start + 1
	} else {
		end = args[0]
	}
	if end > len(slice)-1 {
		return slice[:start]
	}
	return append(slice[:start], slice[end:]...)
}
<commit_msg>add SliceRemoveCallback<commit_after>// Copyright 2013 com 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 com

import (
	"math/rand"
	"strings"
	"time"
)

// AppendStr appends string to slice with no duplicates.
func AppendStr(strs []string, str string) []string {
	for _, s := range strs {
		if s == str {
			return strs
		}
	}
	return append(strs, str)
}

// CompareSliceStr compares two 'string' type slices.
// It returns true if elements and order are both the same.
func CompareSliceStr(s1, s2 []string) bool {
	if len(s1) != len(s2) {
		return false
	}

	for i := range s1 {
		if s1[i] != s2[i] {
			return false
		}
	}

	return true
}

// CompareSliceStr compares two 'string' type slices.
// It returns true if elements are the same, and ignores the order.
func CompareSliceStrU(s1, s2 []string) bool {
	if len(s1) != len(s2) {
		return false
	}

	for i := range s1 {
		for j := len(s2) - 1; j >= 0; j-- {
			if s1[i] == s2[j] {
				s2 = append(s2[:j], s2[j+1:]...)
				break
			}
		}
	}
	if len(s2) > 0 {
		return false
	}
	return true
}

// IsSliceContainsStr returns true if the string exists in given slice.
func IsSliceContainsStr(sl []string, str string) bool {
	str = strings.ToLower(str)
	for _, s := range sl {
		if strings.ToLower(s) == str {
			return true
		}
	}
	return false
}

// IsSliceContainsInt64 returns true if the int64 exists in given slice.
func IsSliceContainsInt64(sl []int64, i int64) bool {
	for _, s := range sl {
		if s == i {
			return true
		}
	}
	return false
}

// ==============================
type reducetype func(interface{}) interface{}
type filtertype func(interface{}) bool

func InSlice(v string, sl []string) bool {
	for _, vv := range sl {
		if vv == v {
			return true
		}
	}
	return false
}

func InSliceIface(v interface{}, sl []interface{}) bool {
	for _, vv := range sl {
		if vv == v {
			return true
		}
	}
	return false
}

func SliceRandList(min, max int) []int {
	if max < min {
		min, max = max, min
	}
	length := max - min + 1
	t0 := time.Now()
	rand.Seed(int64(t0.Nanosecond()))
	list := rand.Perm(length)
	for index := range list {
		list[index] += min
	}
	return list
}

func SliceMerge(slice1, slice2 []interface{}) (c []interface{}) {
	c = append(slice1, slice2...)
	return
}

func SliceReduce(slice []interface{}, a reducetype) (dslice []interface{}) {
	for _, v := range slice {
		dslice = append(dslice, a(v))
	}
	return
}

func SliceRand(a []interface{}) (b interface{}) {
	randnum := rand.Intn(len(a))
	b = a[randnum]
	return
}

func SliceSum(intslice []int64) (sum int64) {
	for _, v := range intslice {
		sum += v
	}
	return
}

func SliceFilter(slice []interface{}, a filtertype) (ftslice []interface{}) {
	for _, v := range slice {
		if a(v) {
			ftslice = append(ftslice, v)
		}
	}
	return
}

func SliceDiff(slice1, slice2 []interface{}) (diffslice []interface{}) {
	for _, v := range slice1 {
		if !InSliceIface(v, slice2) {
			diffslice = append(diffslice, v)
		}
	}
	return
}

func SliceIntersect(slice1, slice2 []interface{}) (diffslice []interface{}) {
	for _, v := range slice1 {
		if !InSliceIface(v, slice2) {
			diffslice = append(diffslice, v)
		}
	}
	return
}

func SliceChunk(slice []interface{}, size int) (chunkslice [][]interface{}) {
	if size >= len(slice) {
		chunkslice = append(chunkslice, slice)
		return
	}
	end := size
	for i := 0; i <= (len(slice) - size); i += size {
		chunkslice = append(chunkslice, slice[i:end])
		end += size
	}
	return
}

func SliceRange(start, end, step int64) (intslice []int64) {
	for i := start; i <= end; i += step {
		intslice = append(intslice, i)
	}
	return
}

func SlicePad(slice []interface{}, size int, val interface{}) []interface{} {
	if size <= len(slice) {
		return slice
	}
	for i := 0; i < (size - len(slice)); i++ {
		slice = append(slice, val)
	}
	return slice
}

func SliceUnique(slice []interface{}) (uniqueslice []interface{}) {
	for _, v := range slice {
		if !InSliceIface(v, uniqueslice) {
			uniqueslice = append(uniqueslice, v)
		}
	}
	return
}

func SliceShuffle(slice []interface{}) []interface{} {
	for i := 0; i < len(slice); i++ {
		a := rand.Intn(len(slice))
		b := rand.Intn(len(slice))
		slice[a], slice[b] = slice[b], slice[a]
	}
	return slice
}

func SliceInsert(slice, insertion []interface{}, index int) []interface{} {
	result := make([]interface{}, len(slice)+len(insertion))
	at := copy(result, slice[:index])
	at += copy(result[at:], insertion)
	copy(result[at:], slice[index:])
	return result
}

//SliceRomove SliceRomove(a,4,5) //a[4]
func SliceRemove(slice []interface{}, start int, args ...int) []interface{} {
	var end int
	if len(args) == 0 {
		end = start + 1
	} else {
		end = args[0]
	}
	if end > len(slice)-1 {
		return slice[:start]
	}
	return append(slice[:start], slice[end:]...)
}

// SliceRemoveCallback : 根据条件删除
// a=[]int{1,2,3,4,5,6}
// SliceRemoveCallback(50, func(i int) func(bool)error{
//	if a[i]!=4 {
//	 	return nil
// 	}
// 	return func(inside bool)error{
//		if inside {
//			a=append(a[0:i],a[i+1:]...)
// 		}else{
//			a=a[0:i]
//		}
//		return 1,nil
// 	}
//})
func SliceRemoveCallback(length int, callback func(int) func(bool) error) error {
	for i, j := 0, length-1; i <= j; i++ {
		if removeFunc := callback(i); removeFunc != nil {
			var err error
			if i+1 <= j {
				err = removeFunc(true)
			} else {
				err = removeFunc(false)
			}
			if err != nil {
				return err
			}
			i--
			j--
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package space

import (
	"fmt"
	"math"
)

func main() {
	fmt.Println("hello world")
	fmt.Println(math.Pi)
}
<commit_msg>strating the space module<commit_after>package space

import (
	"container/list"
	"fmt"
	"math"
)

type Space struct {
	vectors *List
}

const g_dimention = 2
const g_width = 400
const g_hight = 400

func (s *Space) AddVector(v Vector) {

}

func (s *Space) Init() {
	vectors := list.New()
	s.vectors = vectors
	return s
}
func New() *Space {
	fmt.Println("creating a world")
	fmt.Println(math.Pi)
	return new(Space).Init()
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"strings"
)

func Command(cmd string) (output *exec.Cmd) {
	output = exec.Command("bash", "-c", cmd)
	return output
}

func Run(file string) (exitStatus int) {
	cmd := fmt.Sprintf(`go run %s`, file)
	command := Command(cmd)
	out, err := command.CombinedOutput()

	fmt.Println(string(out))
	if err != nil {
		return 1
	}
	return 0
}

func ExecuteCommands(commands string) (status int) {
	filename := "test-123.go"
	ioutil.WriteFile(filename, []byte(commands), os.ModeTemporary|os.ModePerm)
	return Run(filename)
}

func main() {
	commands := []string{`package main`, `import "fmt"`, `func main() {`}

	var cmd string

	fmt.Println("Go in the Shell (type `exit` to finish)")
	reader := bufio.NewReader(os.Stdin)

	for cmd != "exit" {
		if cmd != "" {
			status := ExecuteCommands(strings.Join(commands, "\n") + "\n" + cmd + "\n}")
			if status == 0 {
				commands = append(commands, cmd)
			}
		}
		fmt.Print(">>> ")
		cmd, _ = reader.ReadString('\n')
		cmd = strings.TrimSpace(cmd)
	}
}
<commit_msg>Start work on separate imports and functions<commit_after>package main

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"strings"
)

type Func struct {
	name string
	body []string
}

func Command(cmd string) (output *exec.Cmd) {
	output = exec.Command("bash", "-c", cmd)
	return output
}

func Run(file string) (exitStatus int) {
	cmd := fmt.Sprintf(`go run %s`, file)
	command := Command(cmd)
	out, err := command.CombinedOutput()

	fmt.Println(string(out))
	if err != nil {
		return 1
	}
	return 0
}

func ExecuteCommands(commands string) (status int) {
	filename := "test-123.go"
	ioutil.WriteFile(filename, []byte(commands), os.ModeTemporary|os.ModePerm)
	return Run(filename)
}

func buildFile(packageName, imports []string, funcs []Func) {

}

func main() {
	package_name := []string{`package main`}
	imports := []string{`import "fmt"`}
	funcs := []Func{}
	commands := []string{`func main() {`}

	var cmd string

	fmt.Println("Go in the Shell (type `exit` to finish)")
	reader := bufio.NewReader(os.Stdin)

	for cmd != "exit" {
		if cmd != "" {

			status := ExecuteCommands(strings.Join(commands, "\n") + "\n" + cmd + "\n}")
			if status == 0 {
				commands = append(commands, cmd)
			}
		}
		fmt.Print(">>> ")
		cmd, _ = reader.ReadString('\n')
		cmd = strings.TrimSpace(cmd)
	}
}
<|endoftext|>