<commit_before>package xlsx

import (
	"fmt"
	"regexp"
	"text/template"
	"time"
)

// Templates for the various XML content in XLST files
var (
	TemplateContentTypes          *template.Template
	TemplateRelationships         *template.Template
	TemplateWorkbook              *template.Template
	TemplateWorkbookRelationships *template.Template
	TemplateStyles                *template.Template
	TemplateStringLookups         *template.Template
	TemplateSheetStart            *template.Template
	TemplateSheetEnd              *template.Template
	TemplateCellNumber            *template.Template
	TemplateCellString            *template.Template
	TemplateCellDateTime          *template.Template
	TemplateCellInlineString      *template.Template
	TemplateApp                   *template.Template
	TemplateCore                  *template.Template
)

// Template function for integer addition. This is useful to convert between
// zero-based and one-based array offsets within templates
func plus(i int, n int) string {
	return fmt.Sprintf("%d", i+n)
}

// Template function for time formatting
func timeFormat(t time.Time) string {
	return t.Format(time.RFC3339)
}

func init() {
	re := regexp.MustCompile("\n[\t\n\f\r ]*")
	funcMap := template.FuncMap{"plus": plus, "timeFormat": timeFormat}

	TemplateContentTypes = template.Must(template.New("templateContentTypes").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateContentTypes, "")))
	TemplateRelationships = template.Must(template.New("templateRelationships").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateRelationships, "")))
	TemplateWorkbook = template.Must(template.New("templateWorkbook").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateWorkbook, "")))
	TemplateWorkbookRelationships = template.Must(template.New("templateWorkbookRelationships").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateWorkbookRelationships, "")))
	TemplateStyles = template.Must(template.New("templateStyles").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateStyles, "")))
	TemplateStringLookups = template.Must(template.New("templateStringLookups").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateStringLookups, "")))
	TemplateSheetStart = template.Must(template.New("templateSheetStart").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateSheetStart, "")))
	TemplateSheetEnd = template.Must(template.New("templateSheetEnd").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateSheetEnd, "")))
	TemplateCellNumber = template.Must(template.New("templateCellNumber").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateCellNumber, "")))
	TemplateCellString = template.Must(template.New("templateCellString").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateCellString, "")))
	TemplateCellDateTime = template.Must(template.New("templateCellDateTime").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateCellDateTime, "")))
	TemplateCellInlineString = template.Must(template.New("templateCellInlineString").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateCellInlineString, "")))
	TemplateApp = template.Must(template.New("templateApp").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateApp, "")))
	TemplateCore = template.Must(template.New("templateCore").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateCore, "")))
}

const templateContentTypes = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
      <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
      <Default Extension="xml" ContentType="application/xml"/>
      <Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>
      <Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>
      <Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>
      <Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/>
      <Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>
      <Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>
  </Types>`

const templateRelationships = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
      <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>
      <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
      <Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
  </Relationships>`

const templateWorkbook = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
      <fileVersion appName="xl" lastEdited="5" lowestEdited="5" rupBuild="9303"/>
      <workbookPr defaultThemeVersion="124226"/>
      <bookViews>
          <workbookView xWindow="480" yWindow="60" windowWidth="18195" windowHeight="8505"/>
      </bookViews>
      <sheets>
          <sheet name="{{.Title}}" sheetId="1" r:id="rId1"/>
      </sheets>
      <calcPr calcId="145621"/>
  </workbook>`

const templateWorkbookRelationships = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
      <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/>
      <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" Target="sharedStrings.xml"/>
      <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
  </Relationships>`

const templateStyles = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  `

const templateStringLookups = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="{{len .}}" uniqueCount="{{len .}}">
{{range .}}<si><t>{{.}}</t></si>{{end}}
</sst>`

const templateSheetStart = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">
            <sheetViews>
        <sheetView workbookViewId="0"/>
      </sheetViews>
      <sheetFormatPr defaultRowHeight="15" x14ac:dyDescent="0.25"/>
        <cols>
          {{range $i, $e := .Cols}}
          <col min="{{plus $i 1}}" max="{{plus $i 1}}" width="{{$e.Width}}" customWidth="1" style="1"/>
          {{end}}
        </cols>
      <sheetData>`

const templateSheetEnd = `
 <dimension ref="{{.Start}}:{{.End}}"/>
 </sheetData>
   </worksheet>`

const templateCellNumber = `<c r="{{.CellIndex}}" t="n" s="1"><v>{{.Value}}</v></c>`
const templateCellString = `<c r="{{.CellIndex}}" t="s" s="1"><v>{{.Value}}</v></c>`
const templateCellDateTime = `<c r="{{.CellIndex}}" s="2"><v>{{.Value}}</v></c>`
const templateCellInlineString = `<c r="{{.CellIndex}}" t="inlineStr"><is><t>{{.Value}}</t></is></c>`

const templateApp = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes">
  <Application>None</Application>
  <DocSecurity>0</DocSecurity>
  <ScaleCrop>false</ScaleCrop>
  <HeadingPairs>
    <vt:vector size="2" baseType="variant">
      <vt:variant>
        <vt:lpstr>Worksheets</vt:lpstr>
      </vt:variant>
      <vt:variant>
        <vt:i4>1</vt:i4>
      </vt:variant>
    </vt:vector>
  </HeadingPairs>
  <TitlesOfParts>
    <vt:vector size="1" baseType="lpstr">
      <vt:lpstr>{{.Title}}</vt:lpstr>
    </vt:vector>
  </TitlesOfParts>
  <LinksUpToDate>false</LinksUpToDate>
  <SharedDoc>false</SharedDoc>
  <HyperlinksChanged>false</HyperlinksChanged>
</Properties>`

const templateCore = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <dc:creator>{{.CreatedBy}}</dc:creator>
    <cp:lastModifiedBy>{{.ModifiedBy}}</cp:lastModifiedBy>
    <dcterms:created xsi:type="dcterms:W3CDTF">{{timeFormat .CreatedAt}}</dcterms:created>
    <dcterms:modified xsi:type="dcterms:W3CDTF">{{timeFormat .ModifiedAt}}</dcterms:modified>
  </cp:coreProperties>`
<commit_msg>Remove slicer style (xref sean-duffy/sqlite2xlsx#1)<commit_after>package xlsx

import (
	"fmt"
	"regexp"
	"text/template"
	"time"
)

// Templates for the various XML content in XLST files
var (
	TemplateContentTypes          *template.Template
	TemplateRelationships         *template.Template
	TemplateWorkbook              *template.Template
	TemplateWorkbookRelationships *template.Template
	TemplateStyles                *template.Template
	TemplateStringLookups         *template.Template
	TemplateSheetStart            *template.Template
	TemplateSheetEnd              *template.Template
	TemplateCellNumber            *template.Template
	TemplateCellString            *template.Template
	TemplateCellDateTime          *template.Template
	TemplateCellInlineString      *template.Template
	TemplateApp                   *template.Template
	TemplateCore                  *template.Template
)

// Template function for integer addition. This is useful to convert between
// zero-based and one-based array offsets within templates
func plus(i int, n int) string {
	return fmt.Sprintf("%d", i+n)
}

// Template function for time formatting
func timeFormat(t time.Time) string {
	return t.Format(time.RFC3339)
}

func init() {
	re := regexp.MustCompile("\n[\t\n\f\r ]*")
	funcMap := template.FuncMap{"plus": plus, "timeFormat": timeFormat}

	TemplateContentTypes = template.Must(template.New("templateContentTypes").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateContentTypes, "")))
	TemplateRelationships = template.Must(template.New("templateRelationships").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateRelationships, "")))
	TemplateWorkbook = template.Must(template.New("templateWorkbook").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateWorkbook, "")))
	TemplateWorkbookRelationships = template.Must(template.New("templateWorkbookRelationships").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateWorkbookRelationships, "")))
	TemplateStyles = template.Must(template.New("templateStyles").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateStyles, "")))
	TemplateStringLookups = template.Must(template.New("templateStringLookups").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateStringLookups, "")))
	TemplateSheetStart = template.Must(template.New("templateSheetStart").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateSheetStart, "")))
	TemplateSheetEnd = template.Must(template.New("templateSheetEnd").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateSheetEnd, "")))
	TemplateCellNumber = template.Must(template.New("templateCellNumber").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateCellNumber, "")))
	TemplateCellString = template.Must(template.New("templateCellString").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateCellString, "")))
	TemplateCellDateTime = template.Must(template.New("templateCellDateTime").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateCellDateTime, "")))
	TemplateCellInlineString = template.Must(template.New("templateCellInlineString").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateCellInlineString, "")))
	TemplateApp = template.Must(template.New("templateApp").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateApp, "")))
	TemplateCore = template.Must(template.New("templateCore").Funcs(funcMap).Parse(re.ReplaceAllLiteralString(templateCore, "")))
}

const templateContentTypes = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
      <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
      <Default Extension="xml" ContentType="application/xml"/>
      <Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>
      <Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>
      <Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>
      <Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/>
      <Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>
      <Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>
  </Types>`

const templateRelationships = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
      <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>
      <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
      <Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
  </Relationships>`

const templateWorkbook = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
      <fileVersion appName="xl" lastEdited="5" lowestEdited="5" rupBuild="9303"/>
      <workbookPr defaultThemeVersion="124226"/>
      <bookViews>
          <workbookView xWindow="480" yWindow="60" windowWidth="18195" windowHeight="8505"/>
      </bookViews>
      <sheets>
          <sheet name="{{.Title}}" sheetId="1" r:id="rId1"/>
      </sheets>
      <calcPr calcId="145621"/>
  </workbook>`

const templateWorkbookRelationships = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
      <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/>
      <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" Target="sharedStrings.xml"/>
      <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
  </Relationships>`

const templateStyles = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  `

const templateStringLookups = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="{{len .}}" uniqueCount="{{len .}}">
{{range .}}<si><t>{{.}}</t></si>{{end}}
</sst>`

const templateSheetStart = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">
            <sheetViews>
        <sheetView workbookViewId="0"/>
      </sheetViews>
      <sheetFormatPr defaultRowHeight="15" x14ac:dyDescent="0.25"/>
        <cols>
          {{range $i, $e := .Cols}}
          <col min="{{plus $i 1}}" max="{{plus $i 1}}" width="{{$e.Width}}" customWidth="1" style="1"/>
          {{end}}
        </cols>
      <sheetData>`

const templateSheetEnd = `
 <dimension ref="{{.Start}}:{{.End}}"/>
 </sheetData>
   </worksheet>`

const templateCellNumber = `<c r="{{.CellIndex}}" t="n" s="1"><v>{{.Value}}</v></c>`
const templateCellString = `<c r="{{.CellIndex}}" t="s" s="1"><v>{{.Value}}</v></c>`
const templateCellDateTime = `<c r="{{.CellIndex}}" s="2"><v>{{.Value}}</v></c>`
const templateCellInlineString = `<c r="{{.CellIndex}}" t="inlineStr"><is><t>{{.Value}}</t></is></c>`

const templateApp = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes">
  <Application>None</Application>
  <DocSecurity>0</DocSecurity>
  <ScaleCrop>false</ScaleCrop>
  <HeadingPairs>
    <vt:vector size="2" baseType="variant">
      <vt:variant>
        <vt:lpstr>Worksheets</vt:lpstr>
      </vt:variant>
      <vt:variant>
        <vt:i4>1</vt:i4>
      </vt:variant>
    </vt:vector>
  </HeadingPairs>
  <TitlesOfParts>
    <vt:vector size="1" baseType="lpstr">
      <vt:lpstr>{{.Title}}</vt:lpstr>
    </vt:vector>
  </TitlesOfParts>
  <LinksUpToDate>false</LinksUpToDate>
  <SharedDoc>false</SharedDoc>
  <HyperlinksChanged>false</HyperlinksChanged>
</Properties>`

const templateCore = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <dc:creator>{{.CreatedBy}}</dc:creator>
    <cp:lastModifiedBy>{{.ModifiedBy}}</cp:lastModifiedBy>
    <dcterms:created xsi:type="dcterms:W3CDTF">{{timeFormat .CreatedAt}}</dcterms:created>
    <dcterms:modified xsi:type="dcterms:W3CDTF">{{timeFormat .ModifiedAt}}</dcterms:modified>
  </cp:coreProperties>`
<|endoftext|>


<commit_before>/*
Copyright 2017 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package status defines a few useful functions for our binaries,
// mainly to link the status page with a vtctld instance.
package status

import (
	"flag"
	"fmt"
	"html/template"
	"net/url"
	"strings"

	"github.com/youtube/vitess/go/vt/servenv"
)

var (
	vtctldAddr = flag.String("vtctld_addr", "", "address of a vtctld instance")
)

// MakeVtctldRedirect returns an absolute vtctld url that will
// redirect to the page for the topology object specified in q.
func MakeVtctldRedirect(text string, q map[string]string) template.HTML {
	query := url.Values{}
	for k, v := range q {
		query.Set(k, v)
	}
	url := "/explorers/redirect" + "?" + query.Encode()
	return VtctldLink(text, url)
}

// VtctldLink returns the HTML to display a link to the fully
// qualified vtctld url whose path is given as parameter.
// If no vtctld_addr flag was passed in, we just return the text with no link.
func VtctldLink(text, urlPath string) template.HTML {
	if *vtctldAddr == "" {
		return template.HTML(text)
	}
	var fullURL string
	if strings.HasSuffix(*vtctldAddr, "/") {
		fullURL = *vtctldAddr + urlPath
	} else {
		fullURL = *vtctldAddr + "/" + urlPath
	}

	return template.HTML(fmt.Sprintf(`<a href="%v">%v</a>`, fullURL, text))
}

// VtctldKeyspace returns the keyspace name, possibly linked to the
// keyspace page in vtctld.
func VtctldKeyspace(keyspace string) template.HTML {
	return MakeVtctldRedirect(keyspace,
		map[string]string{
			"type":     "keyspace",
			"keyspace": keyspace,
		})
}

// VtctldShard returns the shard name, possibly linked to the shard
// page in vtctld.
func VtctldShard(keyspace, shard string) template.HTML {
	return MakeVtctldRedirect(shard, map[string]string{
		"type":     "shard",
		"keyspace": keyspace,
		"shard":    shard,
	})
}

// VtctldSrvCell returns the cell name, possibly linked to the
// serving graph page in vtctld for that page.
func VtctldSrvCell(cell string) template.HTML {
	return VtctldLink(cell, "/serving_graph/"+cell)
}

// VtctldSrvKeyspace returns the keyspace name, possibly linked to the
// SrvKeyspace page in vtctld.
func VtctldSrvKeyspace(cell, keyspace string) template.HTML {
	return MakeVtctldRedirect(keyspace, map[string]string{
		"type":     "srv_keyspace",
		"cell":     cell,
		"keyspace": keyspace,
	})
}

// VtctldReplication returns 'cell/keyspace/shard', possibly linked to the
// ShardReplication page in vtctld.
func VtctldReplication(cell, keyspace, shard string) template.HTML {
	return MakeVtctldRedirect(fmt.Sprintf("%v/%v/%v", cell, keyspace, shard),
		map[string]string{
			"type":     "replication",
			"keyspace": keyspace,
			"shard":    shard,
			"cell":     cell,
		})
}

// VtctldTablet returns the tablet alias, possibly linked to the
// Tablet page in vtctld.
func VtctldTablet(aliasName string) template.HTML {
	return MakeVtctldRedirect(aliasName, map[string]string{
		"type":  "tablet",
		"alias": aliasName,
	})
}

// StatusFuncs returns a FuncMap that contains all of our methods here.
// It is exported so tests can use them.
var StatusFuncs = template.FuncMap{
	"github_com_youtube_vitess_vtctld_keyspace":     VtctldKeyspace,
	"github_com_youtube_vitess_vtctld_shard":        VtctldShard,
	"github_com_youtube_vitess_vtctld_srv_cell":     VtctldSrvCell,
	"github_com_youtube_vitess_vtctld_srv_keyspace": VtctldSrvKeyspace,
	"github_com_youtube_vitess_vtctld_replication":  VtctldReplication,
	"github_com_youtube_vitess_vtctld_tablet":       VtctldTablet,
}

func init() {
	servenv.AddStatusFuncs(StatusFuncs)
}
<commit_msg>Removing double slashes in vtctld urls.<commit_after>/*
Copyright 2017 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package status defines a few useful functions for our binaries,
// mainly to link the status page with a vtctld instance.
package status

import (
	"flag"
	"fmt"
	"html/template"
	"net/url"
	"strings"

	"github.com/youtube/vitess/go/vt/servenv"
)

var (
	vtctldAddr = flag.String("vtctld_addr", "", "address of a vtctld instance")
)

// MakeVtctldRedirect returns an absolute vtctld url that will
// redirect to the page for the topology object specified in q.
func MakeVtctldRedirect(text string, q map[string]string) template.HTML {
	query := url.Values{}
	for k, v := range q {
		query.Set(k, v)
	}
	url := "explorers/redirect" + "?" + query.Encode()
	return VtctldLink(text, url)
}

// VtctldLink returns the HTML to display a link to the fully
// qualified vtctld url whose path is given as parameter.
// If no vtctld_addr flag was passed in, we just return the text with no link.
func VtctldLink(text, urlPath string) template.HTML {
	if *vtctldAddr == "" {
		return template.HTML(text)
	}
	var fullURL string
	if strings.HasSuffix(*vtctldAddr, "/") {
		fullURL = *vtctldAddr + urlPath
	} else {
		fullURL = *vtctldAddr + "/" + urlPath
	}

	return template.HTML(fmt.Sprintf(`<a href="%v">%v</a>`, fullURL, text))
}

// VtctldKeyspace returns the keyspace name, possibly linked to the
// keyspace page in vtctld.
func VtctldKeyspace(keyspace string) template.HTML {
	return MakeVtctldRedirect(keyspace,
		map[string]string{
			"type":     "keyspace",
			"keyspace": keyspace,
		})
}

// VtctldShard returns the shard name, possibly linked to the shard
// page in vtctld.
func VtctldShard(keyspace, shard string) template.HTML {
	return MakeVtctldRedirect(shard, map[string]string{
		"type":     "shard",
		"keyspace": keyspace,
		"shard":    shard,
	})
}

// VtctldSrvCell returns the cell name, possibly linked to the
// serving graph page in vtctld for that page.
func VtctldSrvCell(cell string) template.HTML {
	return VtctldLink(cell, "serving_graph/"+cell)
}

// VtctldSrvKeyspace returns the keyspace name, possibly linked to the
// SrvKeyspace page in vtctld.
func VtctldSrvKeyspace(cell, keyspace string) template.HTML {
	return MakeVtctldRedirect(keyspace, map[string]string{
		"type":     "srv_keyspace",
		"cell":     cell,
		"keyspace": keyspace,
	})
}

// VtctldReplication returns 'cell/keyspace/shard', possibly linked to the
// ShardReplication page in vtctld.
func VtctldReplication(cell, keyspace, shard string) template.HTML {
	return MakeVtctldRedirect(fmt.Sprintf("%v/%v/%v", cell, keyspace, shard),
		map[string]string{
			"type":     "replication",
			"keyspace": keyspace,
			"shard":    shard,
			"cell":     cell,
		})
}

// VtctldTablet returns the tablet alias, possibly linked to the
// Tablet page in vtctld.
func VtctldTablet(aliasName string) template.HTML {
	return MakeVtctldRedirect(aliasName, map[string]string{
		"type":  "tablet",
		"alias": aliasName,
	})
}

// StatusFuncs returns a FuncMap that contains all of our methods here.
// It is exported so tests can use them.
var StatusFuncs = template.FuncMap{
	"github_com_youtube_vitess_vtctld_keyspace":     VtctldKeyspace,
	"github_com_youtube_vitess_vtctld_shard":        VtctldShard,
	"github_com_youtube_vitess_vtctld_srv_cell":     VtctldSrvCell,
	"github_com_youtube_vitess_vtctld_srv_keyspace": VtctldSrvKeyspace,
	"github_com_youtube_vitess_vtctld_replication":  VtctldReplication,
	"github_com_youtube_vitess_vtctld_tablet":       VtctldTablet,
}

func init() {
	servenv.AddStatusFuncs(StatusFuncs)
}
<|endoftext|>


<commit_before>// Package main is complete tool for the go command line
package main

import "github.com/posener/complete"

var (
	ellipsis   = complete.PredictSet("./...")
	anyPackage = predictPackages("")
	goFiles    = complete.PredictFiles("*.go")
	anyFile    = complete.PredictFiles("*")
	anyGo      = complete.PredictOr(goFiles, anyPackage, ellipsis)
)

func main() {
	build := complete.Command{
		Flags: complete.Flags{
			"-o": anyFile,
			"-i": complete.PredictNothing,

			"-a":             complete.PredictNothing,
			"-n":             complete.PredictNothing,
			"-p":             complete.PredictAnything,
			"-race":          complete.PredictNothing,
			"-msan":          complete.PredictNothing,
			"-v":             complete.PredictNothing,
			"-work":          complete.PredictNothing,
			"-x":             complete.PredictNothing,
			"-asmflags":      complete.PredictAnything,
			"-buildmode":     complete.PredictAnything,
			"-compiler":      complete.PredictAnything,
			"-gccgoflags":    complete.PredictAnything,
			"-gcflags":       complete.PredictAnything,
			"-installsuffix": complete.PredictAnything,
			"-ldflags":       complete.PredictAnything,
			"-linkshared":    complete.PredictNothing,
			"-pkgdir":        anyPackage,
			"-tags":          complete.PredictAnything,
			"-toolexec":      complete.PredictAnything,
		},
		Args: anyGo,
	}

	run := complete.Command{
		Flags: complete.Flags{
			"-exec": complete.PredictAnything,
		},
		Args: goFiles,
	}

	test := complete.Command{
		Flags: complete.Flags{
			"-args": complete.PredictAnything,
			"-c":    complete.PredictNothing,
			"-exec": complete.PredictAnything,

			"-bench":     predictTest("Benchmark"),
			"-benchtime": complete.PredictAnything,
			"-count":     complete.PredictAnything,
			"-cover":     complete.PredictNothing,
			"-covermode": complete.PredictSet("set", "count", "atomic"),
			"-coverpkg":  complete.PredictDirs("*"),
			"-cpu":       complete.PredictAnything,
			"-run":       predictTest("Test", "Example"),
			"-short":     complete.PredictNothing,
			"-timeout":   complete.PredictAnything,

			"-benchmem":             complete.PredictNothing,
			"-blockprofile":         complete.PredictFiles("*.out"),
			"-blockprofilerate":     complete.PredictAnything,
			"-coverprofile":         complete.PredictFiles("*.out"),
			"-cpuprofile":           complete.PredictFiles("*.out"),
			"-memprofile":           complete.PredictFiles("*.out"),
			"-memprofilerate":       complete.PredictAnything,
			"-mutexprofile":         complete.PredictFiles("*.out"),
			"-mutexprofilefraction": complete.PredictAnything,
			"-outputdir":            complete.PredictDirs("*"),
			"-trace":                complete.PredictFiles("*.out"),
		},
		Args: anyGo,
	}

	fmt := complete.Command{
		Flags: complete.Flags{
			"-n": complete.PredictNothing,
			"-x": complete.PredictNothing,
		},
		Args: anyGo,
	}

	get := complete.Command{
		Flags: complete.Flags{
			"-d":        complete.PredictNothing,
			"-f":        complete.PredictNothing,
			"-fix":      complete.PredictNothing,
			"-insecure": complete.PredictNothing,
			"-t":        complete.PredictNothing,
			"-u":        complete.PredictNothing,
		},
		Args: anyGo,
	}

	generate := complete.Command{
		Flags: complete.Flags{
			"-n":   complete.PredictNothing,
			"-x":   complete.PredictNothing,
			"-v":   complete.PredictNothing,
			"-run": complete.PredictAnything,
		},
		Args: anyGo,
	}

	vet := complete.Command{
		Flags: complete.Flags{
			"-n": complete.PredictNothing,
			"-x": complete.PredictNothing,
		},
		Args: anyGo,
	}

	list := complete.Command{
		Flags: complete.Flags{
			"-e":    complete.PredictNothing,
			"-f":    complete.PredictAnything,
			"-json": complete.PredictNothing,
		},
		Args: complete.PredictOr(anyPackage, ellipsis),
	}

	tool := complete.Command{
		Flags: complete.Flags{
			"-n": complete.PredictNothing,
		},
		Args: complete.PredictAnything,
	}

	clean := complete.Command{
		Flags: complete.Flags{
			"-i": complete.PredictNothing,
			"-r": complete.PredictNothing,
			"-n": complete.PredictNothing,
			"-x": complete.PredictNothing,
		},
		Args: complete.PredictOr(anyPackage, ellipsis),
	}

	env := complete.Command{
		Args: complete.PredictAnything,
	}

	bug := complete.Command{}
	version := complete.Command{}

	fix := complete.Command{
		Args: anyGo,
	}

	// commands that also accepts the build flags
	for name, options := range build.Flags {
		test.Flags[name] = options
		run.Flags[name] = options
		list.Flags[name] = options
		vet.Flags[name] = options
	}

	gogo := complete.Command{
		Sub: complete.Commands{
			"build":    build,
			"install":  build, // install and build have the same flags
			"run":      run,
			"test":     test,
			"fmt":      fmt,
			"get":      get,
			"generate": generate,
			"vet":      vet,
			"list":     list,
			"tool":     tool,
			"clean":    clean,
			"env":      env,
			"bug":      bug,
			"fix":      fix,
			"version":  version,
		},
		Flags: complete.Flags{
			"-h": complete.PredictNothing,
		},
	}

	complete.New("go", gogo).Run()
}
<commit_msg>gocomplete: add build flags to get command<commit_after>// Package main is complete tool for the go command line
package main

import "github.com/posener/complete"

var (
	ellipsis   = complete.PredictSet("./...")
	anyPackage = predictPackages("")
	goFiles    = complete.PredictFiles("*.go")
	anyFile    = complete.PredictFiles("*")
	anyGo      = complete.PredictOr(goFiles, anyPackage, ellipsis)
)

func main() {
	build := complete.Command{
		Flags: complete.Flags{
			"-o": anyFile,
			"-i": complete.PredictNothing,

			"-a":             complete.PredictNothing,
			"-n":             complete.PredictNothing,
			"-p":             complete.PredictAnything,
			"-race":          complete.PredictNothing,
			"-msan":          complete.PredictNothing,
			"-v":             complete.PredictNothing,
			"-work":          complete.PredictNothing,
			"-x":             complete.PredictNothing,
			"-asmflags":      complete.PredictAnything,
			"-buildmode":     complete.PredictAnything,
			"-compiler":      complete.PredictAnything,
			"-gccgoflags":    complete.PredictAnything,
			"-gcflags":       complete.PredictAnything,
			"-installsuffix": complete.PredictAnything,
			"-ldflags":       complete.PredictAnything,
			"-linkshared":    complete.PredictNothing,
			"-pkgdir":        anyPackage,
			"-tags":          complete.PredictAnything,
			"-toolexec":      complete.PredictAnything,
		},
		Args: anyGo,
	}

	run := complete.Command{
		Flags: complete.Flags{
			"-exec": complete.PredictAnything,
		},
		Args: goFiles,
	}

	test := complete.Command{
		Flags: complete.Flags{
			"-args": complete.PredictAnything,
			"-c":    complete.PredictNothing,
			"-exec": complete.PredictAnything,

			"-bench":     predictTest("Benchmark"),
			"-benchtime": complete.PredictAnything,
			"-count":     complete.PredictAnything,
			"-cover":     complete.PredictNothing,
			"-covermode": complete.PredictSet("set", "count", "atomic"),
			"-coverpkg":  complete.PredictDirs("*"),
			"-cpu":       complete.PredictAnything,
			"-run":       predictTest("Test", "Example"),
			"-short":     complete.PredictNothing,
			"-timeout":   complete.PredictAnything,

			"-benchmem":             complete.PredictNothing,
			"-blockprofile":         complete.PredictFiles("*.out"),
			"-blockprofilerate":     complete.PredictAnything,
			"-coverprofile":         complete.PredictFiles("*.out"),
			"-cpuprofile":           complete.PredictFiles("*.out"),
			"-memprofile":           complete.PredictFiles("*.out"),
			"-memprofilerate":       complete.PredictAnything,
			"-mutexprofile":         complete.PredictFiles("*.out"),
			"-mutexprofilefraction": complete.PredictAnything,
			"-outputdir":            complete.PredictDirs("*"),
			"-trace":                complete.PredictFiles("*.out"),
		},
		Args: anyGo,
	}

	fmt := complete.Command{
		Flags: complete.Flags{
			"-n": complete.PredictNothing,
			"-x": complete.PredictNothing,
		},
		Args: anyGo,
	}

	get := complete.Command{
		Flags: complete.Flags{
			"-d":        complete.PredictNothing,
			"-f":        complete.PredictNothing,
			"-fix":      complete.PredictNothing,
			"-insecure": complete.PredictNothing,
			"-t":        complete.PredictNothing,
			"-u":        complete.PredictNothing,
		},
		Args: anyGo,
	}

	generate := complete.Command{
		Flags: complete.Flags{
			"-n":   complete.PredictNothing,
			"-x":   complete.PredictNothing,
			"-v":   complete.PredictNothing,
			"-run": complete.PredictAnything,
		},
		Args: anyGo,
	}

	vet := complete.Command{
		Flags: complete.Flags{
			"-n": complete.PredictNothing,
			"-x": complete.PredictNothing,
		},
		Args: anyGo,
	}

	list := complete.Command{
		Flags: complete.Flags{
			"-e":    complete.PredictNothing,
			"-f":    complete.PredictAnything,
			"-json": complete.PredictNothing,
		},
		Args: complete.PredictOr(anyPackage, ellipsis),
	}

	tool := complete.Command{
		Flags: complete.Flags{
			"-n": complete.PredictNothing,
		},
		Args: complete.PredictAnything,
	}

	clean := complete.Command{
		Flags: complete.Flags{
			"-i": complete.PredictNothing,
			"-r": complete.PredictNothing,
			"-n": complete.PredictNothing,
			"-x": complete.PredictNothing,
		},
		Args: complete.PredictOr(anyPackage, ellipsis),
	}

	env := complete.Command{
		Args: complete.PredictAnything,
	}

	bug := complete.Command{}
	version := complete.Command{}

	fix := complete.Command{
		Args: anyGo,
	}

	// commands that also accepts the build flags
	for name, options := range build.Flags {
		test.Flags[name] = options
		run.Flags[name] = options
		list.Flags[name] = options
		vet.Flags[name] = options
		get.Flags[name] = options
	}

	gogo := complete.Command{
		Sub: complete.Commands{
			"build":    build,
			"install":  build, // install and build have the same flags
			"run":      run,
			"test":     test,
			"fmt":      fmt,
			"get":      get,
			"generate": generate,
			"vet":      vet,
			"list":     list,
			"tool":     tool,
			"clean":    clean,
			"env":      env,
			"bug":      bug,
			"fix":      fix,
			"version":  version,
		},
		Flags: complete.Flags{
			"-h": complete.PredictNothing,
		},
	}

	complete.New("go", gogo).Run()
}
<|endoftext|>


<commit_before>package set

import "github.com/clipperhouse/typewriter"

var templates = typewriter.TemplateSlice{
	signal,
}

var signal = &typewriter.Template{
	Name: "Signal",
	Text: `
// The primary type that represents a signal
type {{.Name}}Signal struct {
   listeners [](chan <%= type_name %>)
   mutex     sync.Mutex
}

// Add channel c to the signal to receive messages from this Signal
func (s *{{.Name}}Signal) Add(c chan {{.Name}}) {
   s.mutex.Lock()
   defer s.mutex.Unlock()
   s.listeners = append(s.listeners, c)
}

// Remove channel c from the signal
func (s *{{.Name}}Signal) Remove(c chan {{.Name}}) {
   s.mutex.Lock()
   defer s.mutex.Unlock()

   for i, l := range s.listeners {
      if c == l {
         s.listeners[i] = s.listeners[len(s.listeners)-1]
         s.listeners = s.listeners[:len(s.listeners)-1]
         return
      }
   }
}

// Dispatch synchronously sends msg to all channels that have been added to this signal.
func (s *{{.Name}}Signal) Dispatch(msg {{.Name}}) {
   s.mutex.Lock()
   defer s.mutex.Unlock()

   for _, l := range s.listeners {
      l <- msg
   }
}
`,
}
<commit_msg>Fix package name<commit_after>package signal

import "github.com/clipperhouse/typewriter"

var templates = typewriter.TemplateSlice{
	signal,
}

var signal = &typewriter.Template{
	Name: "Signal",
	Text: `
// The primary type that represents a signal
type {{.Name}}Signal struct {
   listeners [](chan <%= type_name %>)
   mutex     sync.Mutex
}

// Add channel c to the signal to receive messages from this Signal
func (s *{{.Name}}Signal) Add(c chan {{.Name}}) {
   s.mutex.Lock()
   defer s.mutex.Unlock()
   s.listeners = append(s.listeners, c)
}

// Remove channel c from the signal
func (s *{{.Name}}Signal) Remove(c chan {{.Name}}) {
   s.mutex.Lock()
   defer s.mutex.Unlock()

   for i, l := range s.listeners {
      if c == l {
         s.listeners[i] = s.listeners[len(s.listeners)-1]
         s.listeners = s.listeners[:len(s.listeners)-1]
         return
      }
   }
}

// Dispatch synchronously sends msg to all channels that have been added to this signal.
func (s *{{.Name}}Signal) Dispatch(msg {{.Name}}) {
   s.mutex.Lock()
   defer s.mutex.Unlock()

   for _, l := range s.listeners {
      l <- msg
   }
}
`,
}
<|endoftext|>


<commit_before>// Represent and unify Prolog terms.  Along with golog.Machine, term.Term
// is one of the most important data types in Golog.  It provides a Go
// representation of Prolog terms.  Terms represent Prolog code,
// Prolog queries and Prolog results.
//
// The current term API is messy and will definitely change in the future.
package term

import . "fmt"
import . "regexp"
import "math/big"
import "math"
import "strconv"
import "strings"
import "github.com/mndrix/golog/lex"
import "github.com/mndrix/ps"

// Returned by Unify() if the unification fails
var CantUnify error = Errorf("Can't unify the given terms")

// Term represents a single Prolog term which might be an atom, a
// compound structure, an integer, etc.  Many methods on Term will
// be replaced with functions in the future.  The Term interface is
// also likely to be split into several smaller interfaces like Atomic,
// Number, etc.
type Term interface {
    // Functor returns the term's name
    Functor() string

    // Arity returns the number of arguments a term has. An atom has 0 arity.
    Arity() int

    // Arguments returns a slice of this term's arguments, if any
    Arguments() []Term

    // Body returns a term's second argument; otherwise, panics
    Body() Term

    // Head returns a term's first argument; otherwise, panics
    Head() Term

    // Error returns an error value if this is an error term
    Error() error

    // IsClause returns true if the term is like 'Head :- Body'
    IsClause() bool

    // ReplaceVariables replaces any internal variables with the values
    // to which they're bound.  Unbound variables are left as they are
    ReplaceVariables(Bindings) Term

    // String provides a string representation of a term
    String() string

    // Indicator() provides a "predicate indicator" representation of a term
    Indicator() string

    // Unifies the invocant and another term in the presence of an
    // environment.
    // On succes, returns a new environment with additional variable
    // bindings.  On failure, returns CantUnify error along with the
    // original environment
    Unify(Bindings, Term) (Bindings, error)
}

// Returns true if term t is an atom
func IsAtom(t Term) bool {
    switch t.(type) {
        case *Atom:
            return true
        default:
            return false
    }
    panic("Impossible")
}

// Returns true if term t is a compound term.
func IsCompound(t Term) bool {
    switch t.(type) {
        case *Compound:
            return true
        case *Atom,
             *Variable,
             *Integer,
             *Float,
             *Error:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// Returns true if term t is a variable.
func IsVariable(t Term) bool {
    switch t.(type) {
        case *Variable:
            return true
        case *Atom,
             *Compound,
             *Integer,
             *Float,
             *Error:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// Returns true if term t is an error term.
func IsError(t Term) bool {
    switch t.(type) {
        case *Error:
            return true
        case *Atom,
             *Compound,
             *Variable,
             *Integer,
             *Float:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// Returns true if term t is a directive like `:- foo.`
func IsDirective(t Term) bool {
    return t.Indicator() == ":-/1"
}

// Returns true if term t is an integer
func IsInteger(t Term) bool {
    switch t.(type) {
        case *Atom:
            return false
        case *Compound:
            return false
        case *Variable:
            return false
        case *Integer:
            return true
        case *Float:
            return false
        case *Error:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// Returns true if term t is an floating point number
func IsFloat(t Term) bool {
    switch t.(type) {
        case *Atom:
            return false
        case *Compound:
            return false
        case *Variable:
            return false
        case *Integer:
            return false
        case *Float:
            return true
        case *Error:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// RenameVariables returns a new term like t with all variables replaced
// by fresh ones.
func RenameVariables(t Term) Term {
    renamed := make(map[string]*Variable)
    return renameVariables(t, renamed)
}

func renameVariables(t Term, renamed map[string]*Variable) Term {
    switch x := t.(type) {
        case *Float:    return x
        case *Integer:  return x
        case *Error:    return x
        case *Atom:     return x
        case *Compound:
            newArgs := make([]Term, x.Arity())
            for i, arg := range x.Arguments() {
                newArgs[i] = renameVariables(arg, renamed)
            }
            newTerm := NewTerm(x.Functor(), newArgs...)
            newTerm.(*Compound).ucache = x.ucache
            return newTerm
        case *Variable:
            name := x.Name
            v, ok := renamed[name]
            if ok {
                return v
            } else {
                v = x.WithNewId()
                renamed[name] = v
                return v
            }
    }
    panic("Unexpected term implementation")
}

// Variables returns a ps.Map whose keys are human-readable variable names
// and those values are *Variable used inside term t.
func Variables(t Term) ps.Map {
    names := ps.NewMap()
    switch x := t.(type) {
        case *Atom:     return names
        case *Float:    return names
        case *Integer:  return names
        case *Error:    return names
        case *Compound:
            if x.Arity() == 0 { return names }  // no variables in an atom
            for _, arg := range x.Arguments() {
                innerNames := Variables(arg)
                innerNames.ForEach(func (key string, val ps.Any) {
                    names = names.Set(key, val)
                })
            }
            return names
        case *Variable:
            return names.Set(x.Name, x)
    }
    panic("Unexpected term implementation")
}

// QuoteFunctor returns a canonical representation of a term's name
// by quoting characters that require quoting
func QuoteFunctor(name string) string {
    // cons must be quoted (to avoid confusion with full stop)
    if name == "." || name == "" {
        return Sprintf("'%s'", name)
    }

    // names composed entirely of graphic characters need no quoting
    allGraphic := true
    for _, c := range name {
        if !lex.IsGraphic(c) {
            allGraphic = false
            break
        }
    }
    if allGraphic || name == "[]" || name == "!" || name == ";" {
        return name
    }

    nonAlpha, err := MatchString(`\W`, name)
    maybePanic(err)
    nonLower, err := MatchString(`^[^a-z]`, name)
    if nonAlpha || nonLower {
        escapedName := strings.Replace(name, `'`, `\'`, -1)
        return Sprintf("'%s'", escapedName)
    }

    return name
}

// NewCodeList constructs a list of character codes from a string.
// The string should include opening and closing " characters.
// Nominally, the resulting term is just a chain of cons cells ('.'/2),
// but it might actually be a more efficient implementation under the hood.
func NewCodeListFromDoubleQuotedString(s string) Term {
    // make sure the content is long enough
    runes := []rune(s)
    end := len(runes) - 2
    if end < 0 {
        msg := Sprintf("Code list string must have bracketing double quotes: %s", s)
        panic(msg)
    }

    // build a cons cell chain, starting at the end ([])
    codes := NewAtom(`[]`)
    for i := end; i > 0; i-- {
        c := NewCode(runes[i])
        codes = NewTerm(`.`, c, codes)
    }

    return codes
}

// Precedes returns true if the first argument 'term-precedes'
// the second argument according to ISO §7.2
func Precedes(a, b Term) bool {
    aP := precedence(a)
    bP := precedence(b)
    if aP < bP { return true }
    if aP > bP { return false }

    // both terms have the same precedence by type, so delve deeper
    switch x := a.(type) {
        case *Variable:
            y := b.(*Variable)
            return x.Id() < y.Id()
        case *Float:
            y := b.(*Float)
            return x.Value() < y.Value()
        case *Integer:
            y := b.(*Integer)
            return x.Value().Cmp(y.Value()) < 0
        case *Atom:
            y := b.(*Atom)
            return x.Functor() < y.Functor()
        case *Compound:
            y := b.(*Compound)
            if x.Arity() < y.Arity() { return true }
            if x.Arity() > y.Arity() { return false }
            if x.Functor() < y.Functor() { return true }
            if x.Functor() > y.Functor() { return false }
            for i:=0; i<x.Arity(); i++ {
                if Precedes(x.Arguments()[i], y.Arguments()[i]) {
                    return true
                } else if Precedes(y.Arguments()[i], x.Arguments()[i]) {
                    return false
                }
            }
            return false    // identical terms
    }

    msg := Sprintf("Unexpected term type %s\n", a)
    panic(msg)
}
func precedence(t Term) int {
    switch t.(type) {
        case *Variable:
            return 0
        case *Float:
            return 1
        case *Integer:
            return 2
        case *Atom:
            return 3
        case *Compound:
            return 4
    }
    msg := Sprintf("Unexpected term type %s\n", t)
    panic(msg)
}

// UnificationHash generates a special hash value representing the
// terms in a slice.  Golog uses these hashes to optimize
// unification.  You probably don't need to call this function directly.
//
// In more detail, UnificationHash generates a 64-bit hash which
// represents the shape and content of a term.  If two terms share the same
// hash, those terms are likely to unify, although not guaranteed.  If
// two terms have different hashes, the two terms are guaranteed not
// to unify.  A compound term splits its 64-bit hash into multiple, smaller
// n-bit hashes for its functor and arguments.  Other terms occupy the entire
// hash space themselves.
//
// Variables require special handling.  During "preparation" we can think of
// 1-bits as representing what content a term "provides".  During "query" we
// can think of 1-bits as representing what content a term "requires".
// In the first phase, a variable hashes to all 1s since it can provide
// whatever is needed.  In the second phase, a variable hashes to all 0s since
// it demands nothing of the opposing term.
var bigMaxInt64 *big.Int
func init() {
    bigMaxInt64 = big.NewInt(math.MaxInt64)
}
func UnificationHash(terms []Term, n uint, preparation bool) uint64 {
    var hash uint64 = 0
    var blockSize uint = n / uint(len(terms))

    // mask to select blockSize least significant bits
    var mask uint64
    if blockSize == 64 {
        mask = math.MaxUint64
    } else if blockSize == 0 {
        // pretend that terms was a single variable
        if preparation {
            return (1 << n) - 1
        } else {
            return 0
        }
    } else {
        mask = (1 << blockSize) - 1
    }

    for _, term := range terms {
        hash = hash << blockSize
        switch t := term.(type) {
            case *Atom:
                hash = hash | (hashString(t.Functor()) & mask)
            case *Integer:
                if t.Value().Sign() < 0 || t.Value().Cmp(bigMaxInt64) > 0 {
                    str := Sprintf("%x", t.Value())
                    hash = hash | (hashString(str) & mask)
                } else {
                    hash = hash | (uint64(t.Value().Int64()) & mask)
                }
            case *Float:
                str := strconv.FormatFloat(t.Value(), 'b', 0, 64)
                hash = hash | (hashString(str) & mask)
            case *Error:
                panic("No UnificationHash for Error terms")
            case *Compound:
                var termHash uint64
                arity := uint(t.Arity())
                if arity == 2 && t.Functor() == "." {   // don't hash pair's functor
                    rightSize := blockSize / 2
                    leftSize := blockSize - rightSize
                    termHash = UnificationHash(t.Args[0:1], leftSize, preparation)
                    termHash = termHash << rightSize
                    termHash |= UnificationHash(t.Args[1:2], rightSize, preparation)
                } else {
                    // how many bits allocated to functor vs arguments?
                    functorBits := blockSize / (arity+1)
                    if functorBits > 12 { functorBits = 12 }
                    argumentBits := (blockSize-functorBits) / arity

                    // give extra bits (from rounding) back to the functor
                    functorBits = blockSize - argumentBits*arity

                    // generate the hash
                    var functorMask uint64 = (1<<functorBits) - 1
                    termHash = hashString(t.Functor()) & functorMask
                    for _, arg := range t.Arguments() {
                        termHash = termHash << argumentBits
                        termHash = termHash | UnificationHash([]Term{arg}, argumentBits, preparation)
                    }
                }
                hash |= (termHash & mask)
            case *Variable:
                if preparation {
                    hash = hash | mask
                }
            default:
                msg := Sprintf("Unexpected term type %s\n", t)
                panic(msg)
        }
    }

    return hash
}

// constants for FNV-1a hash algorithm
const (
    offset64 uint64 = 14695981039346656037
    prime64  uint64 = 1099511628211
)
// hashString returns a hash code for a given string
func hashString(x string) uint64 {
    bytes := []byte(x)
    hash := offset64
    for _, byte := range bytes {
        hash ^= uint64(byte)
        hash *= prime64
    }
    return hash
}

// Converts a '.'/2 list terminated in []/0 into a slice of the associated
// terms.  Panics if the argument is not a proper list.
func ProperListToTermSlice(t Term) []Term {
    l := make([]Term, 0)
    if !IsCompound(t) && !IsAtom(t) { panic("Not a list") }
    for {
        switch t.Indicator() {
            case "[]/0":
                return l
            case "./2":
                l = append(l, t.Arguments()[0])
                t = t.Arguments()[1]
            default:
                panic("Improper list")
        }
    }
    return l
}

// Implement sort.Interface for []Term
type TermSlice []Term
func (self *TermSlice) Len() int {
    ts := []Term(*self)
    return len(ts)
}
func (self *TermSlice) Less(i, j int) bool {
    ts := []Term(*self)
    return Precedes(ts[i], ts[j]);
}
func (self *TermSlice) Swap(i, j int) {
    ts := []Term(*self)
    tmp := ts[i]
    ts[i] = ts[j]
    ts[j] = tmp
}

func maybePanic(err error) {
    if err != nil {
        panic(err)
    }
}
<commit_msg>Hash string's codepoints directly<commit_after>// Represent and unify Prolog terms.  Along with golog.Machine, term.Term
// is one of the most important data types in Golog.  It provides a Go
// representation of Prolog terms.  Terms represent Prolog code,
// Prolog queries and Prolog results.
//
// The current term API is messy and will definitely change in the future.
package term

import . "fmt"
import . "regexp"
import "math/big"
import "math"
import "strconv"
import "strings"
import "github.com/mndrix/golog/lex"
import "github.com/mndrix/ps"

// Returned by Unify() if the unification fails
var CantUnify error = Errorf("Can't unify the given terms")

// Term represents a single Prolog term which might be an atom, a
// compound structure, an integer, etc.  Many methods on Term will
// be replaced with functions in the future.  The Term interface is
// also likely to be split into several smaller interfaces like Atomic,
// Number, etc.
type Term interface {
    // Functor returns the term's name
    Functor() string

    // Arity returns the number of arguments a term has. An atom has 0 arity.
    Arity() int

    // Arguments returns a slice of this term's arguments, if any
    Arguments() []Term

    // Body returns a term's second argument; otherwise, panics
    Body() Term

    // Head returns a term's first argument; otherwise, panics
    Head() Term

    // Error returns an error value if this is an error term
    Error() error

    // IsClause returns true if the term is like 'Head :- Body'
    IsClause() bool

    // ReplaceVariables replaces any internal variables with the values
    // to which they're bound.  Unbound variables are left as they are
    ReplaceVariables(Bindings) Term

    // String provides a string representation of a term
    String() string

    // Indicator() provides a "predicate indicator" representation of a term
    Indicator() string

    // Unifies the invocant and another term in the presence of an
    // environment.
    // On succes, returns a new environment with additional variable
    // bindings.  On failure, returns CantUnify error along with the
    // original environment
    Unify(Bindings, Term) (Bindings, error)
}

// Returns true if term t is an atom
func IsAtom(t Term) bool {
    switch t.(type) {
        case *Atom:
            return true
        default:
            return false
    }
    panic("Impossible")
}

// Returns true if term t is a compound term.
func IsCompound(t Term) bool {
    switch t.(type) {
        case *Compound:
            return true
        case *Atom,
             *Variable,
             *Integer,
             *Float,
             *Error:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// Returns true if term t is a variable.
func IsVariable(t Term) bool {
    switch t.(type) {
        case *Variable:
            return true
        case *Atom,
             *Compound,
             *Integer,
             *Float,
             *Error:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// Returns true if term t is an error term.
func IsError(t Term) bool {
    switch t.(type) {
        case *Error:
            return true
        case *Atom,
             *Compound,
             *Variable,
             *Integer,
             *Float:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// Returns true if term t is a directive like `:- foo.`
func IsDirective(t Term) bool {
    return t.Indicator() == ":-/1"
}

// Returns true if term t is an integer
func IsInteger(t Term) bool {
    switch t.(type) {
        case *Atom:
            return false
        case *Compound:
            return false
        case *Variable:
            return false
        case *Integer:
            return true
        case *Float:
            return false
        case *Error:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// Returns true if term t is an floating point number
func IsFloat(t Term) bool {
    switch t.(type) {
        case *Atom:
            return false
        case *Compound:
            return false
        case *Variable:
            return false
        case *Integer:
            return false
        case *Float:
            return true
        case *Error:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// RenameVariables returns a new term like t with all variables replaced
// by fresh ones.
func RenameVariables(t Term) Term {
    renamed := make(map[string]*Variable)
    return renameVariables(t, renamed)
}

func renameVariables(t Term, renamed map[string]*Variable) Term {
    switch x := t.(type) {
        case *Float:    return x
        case *Integer:  return x
        case *Error:    return x
        case *Atom:     return x
        case *Compound:
            newArgs := make([]Term, x.Arity())
            for i, arg := range x.Arguments() {
                newArgs[i] = renameVariables(arg, renamed)
            }
            newTerm := NewTerm(x.Functor(), newArgs...)
            newTerm.(*Compound).ucache = x.ucache
            return newTerm
        case *Variable:
            name := x.Name
            v, ok := renamed[name]
            if ok {
                return v
            } else {
                v = x.WithNewId()
                renamed[name] = v
                return v
            }
    }
    panic("Unexpected term implementation")
}

// Variables returns a ps.Map whose keys are human-readable variable names
// and those values are *Variable used inside term t.
func Variables(t Term) ps.Map {
    names := ps.NewMap()
    switch x := t.(type) {
        case *Atom:     return names
        case *Float:    return names
        case *Integer:  return names
        case *Error:    return names
        case *Compound:
            if x.Arity() == 0 { return names }  // no variables in an atom
            for _, arg := range x.Arguments() {
                innerNames := Variables(arg)
                innerNames.ForEach(func (key string, val ps.Any) {
                    names = names.Set(key, val)
                })
            }
            return names
        case *Variable:
            return names.Set(x.Name, x)
    }
    panic("Unexpected term implementation")
}

// QuoteFunctor returns a canonical representation of a term's name
// by quoting characters that require quoting
func QuoteFunctor(name string) string {
    // cons must be quoted (to avoid confusion with full stop)
    if name == "." || name == "" {
        return Sprintf("'%s'", name)
    }

    // names composed entirely of graphic characters need no quoting
    allGraphic := true
    for _, c := range name {
        if !lex.IsGraphic(c) {
            allGraphic = false
            break
        }
    }
    if allGraphic || name == "[]" || name == "!" || name == ";" {
        return name
    }

    nonAlpha, err := MatchString(`\W`, name)
    maybePanic(err)
    nonLower, err := MatchString(`^[^a-z]`, name)
    if nonAlpha || nonLower {
        escapedName := strings.Replace(name, `'`, `\'`, -1)
        return Sprintf("'%s'", escapedName)
    }

    return name
}

// NewCodeList constructs a list of character codes from a string.
// The string should include opening and closing " characters.
// Nominally, the resulting term is just a chain of cons cells ('.'/2),
// but it might actually be a more efficient implementation under the hood.
func NewCodeListFromDoubleQuotedString(s string) Term {
    // make sure the content is long enough
    runes := []rune(s)
    end := len(runes) - 2
    if end < 0 {
        msg := Sprintf("Code list string must have bracketing double quotes: %s", s)
        panic(msg)
    }

    // build a cons cell chain, starting at the end ([])
    codes := NewAtom(`[]`)
    for i := end; i > 0; i-- {
        c := NewCode(runes[i])
        codes = NewTerm(`.`, c, codes)
    }

    return codes
}

// Precedes returns true if the first argument 'term-precedes'
// the second argument according to ISO §7.2
func Precedes(a, b Term) bool {
    aP := precedence(a)
    bP := precedence(b)
    if aP < bP { return true }
    if aP > bP { return false }

    // both terms have the same precedence by type, so delve deeper
    switch x := a.(type) {
        case *Variable:
            y := b.(*Variable)
            return x.Id() < y.Id()
        case *Float:
            y := b.(*Float)
            return x.Value() < y.Value()
        case *Integer:
            y := b.(*Integer)
            return x.Value().Cmp(y.Value()) < 0
        case *Atom:
            y := b.(*Atom)
            return x.Functor() < y.Functor()
        case *Compound:
            y := b.(*Compound)
            if x.Arity() < y.Arity() { return true }
            if x.Arity() > y.Arity() { return false }
            if x.Functor() < y.Functor() { return true }
            if x.Functor() > y.Functor() { return false }
            for i:=0; i<x.Arity(); i++ {
                if Precedes(x.Arguments()[i], y.Arguments()[i]) {
                    return true
                } else if Precedes(y.Arguments()[i], x.Arguments()[i]) {
                    return false
                }
            }
            return false    // identical terms
    }

    msg := Sprintf("Unexpected term type %s\n", a)
    panic(msg)
}
func precedence(t Term) int {
    switch t.(type) {
        case *Variable:
            return 0
        case *Float:
            return 1
        case *Integer:
            return 2
        case *Atom:
            return 3
        case *Compound:
            return 4
    }
    msg := Sprintf("Unexpected term type %s\n", t)
    panic(msg)
}

// UnificationHash generates a special hash value representing the
// terms in a slice.  Golog uses these hashes to optimize
// unification.  You probably don't need to call this function directly.
//
// In more detail, UnificationHash generates a 64-bit hash which
// represents the shape and content of a term.  If two terms share the same
// hash, those terms are likely to unify, although not guaranteed.  If
// two terms have different hashes, the two terms are guaranteed not
// to unify.  A compound term splits its 64-bit hash into multiple, smaller
// n-bit hashes for its functor and arguments.  Other terms occupy the entire
// hash space themselves.
//
// Variables require special handling.  During "preparation" we can think of
// 1-bits as representing what content a term "provides".  During "query" we
// can think of 1-bits as representing what content a term "requires".
// In the first phase, a variable hashes to all 1s since it can provide
// whatever is needed.  In the second phase, a variable hashes to all 0s since
// it demands nothing of the opposing term.
var bigMaxInt64 *big.Int
func init() {
    bigMaxInt64 = big.NewInt(math.MaxInt64)
}
func UnificationHash(terms []Term, n uint, preparation bool) uint64 {
    var hash uint64 = 0
    var blockSize uint = n / uint(len(terms))

    // mask to select blockSize least significant bits
    var mask uint64
    if blockSize == 64 {
        mask = math.MaxUint64
    } else if blockSize == 0 {
        // pretend that terms was a single variable
        if preparation {
            return (1 << n) - 1
        } else {
            return 0
        }
    } else {
        mask = (1 << blockSize) - 1
    }

    for _, term := range terms {
        hash = hash << blockSize
        switch t := term.(type) {
            case *Atom:
                hash = hash | (hashString(t.Functor()) & mask)
            case *Integer:
                if t.Value().Sign() < 0 || t.Value().Cmp(bigMaxInt64) > 0 {
                    str := Sprintf("%x", t.Value())
                    hash = hash | (hashString(str) & mask)
                } else {
                    hash = hash | (uint64(t.Value().Int64()) & mask)
                }
            case *Float:
                str := strconv.FormatFloat(t.Value(), 'b', 0, 64)
                hash = hash | (hashString(str) & mask)
            case *Error:
                panic("No UnificationHash for Error terms")
            case *Compound:
                var termHash uint64
                arity := uint(t.Arity())
                if arity == 2 && t.Functor() == "." {   // don't hash pair's functor
                    rightSize := blockSize / 2
                    leftSize := blockSize - rightSize
                    termHash = UnificationHash(t.Args[0:1], leftSize, preparation)
                    termHash = termHash << rightSize
                    termHash |= UnificationHash(t.Args[1:2], rightSize, preparation)
                } else {
                    // how many bits allocated to functor vs arguments?
                    functorBits := blockSize / (arity+1)
                    if functorBits > 12 { functorBits = 12 }
                    argumentBits := (blockSize-functorBits) / arity

                    // give extra bits (from rounding) back to the functor
                    functorBits = blockSize - argumentBits*arity

                    // generate the hash
                    var functorMask uint64 = (1<<functorBits) - 1
                    termHash = hashString(t.Functor()) & functorMask
                    for _, arg := range t.Arguments() {
                        termHash = termHash << argumentBits
                        termHash = termHash | UnificationHash([]Term{arg}, argumentBits, preparation)
                    }
                }
                hash |= (termHash & mask)
            case *Variable:
                if preparation {
                    hash = hash | mask
                }
            default:
                msg := Sprintf("Unexpected term type %s\n", t)
                panic(msg)
        }
    }

    return hash
}

// constants for FNV-1a hash algorithm
const (
    offset64 uint64 = 14695981039346656037
    prime64  uint64 = 1099511628211
)
// hashString returns a hash code for a given string
func hashString(x string) uint64 {
    hash := offset64
    for _, codepoint := range x {
        hash ^= uint64(codepoint)
        hash *= prime64
    }
    return hash
}

// Converts a '.'/2 list terminated in []/0 into a slice of the associated
// terms.  Panics if the argument is not a proper list.
func ProperListToTermSlice(t Term) []Term {
    l := make([]Term, 0)
    if !IsCompound(t) && !IsAtom(t) { panic("Not a list") }
    for {
        switch t.Indicator() {
            case "[]/0":
                return l
            case "./2":
                l = append(l, t.Arguments()[0])
                t = t.Arguments()[1]
            default:
                panic("Improper list")
        }
    }
    return l
}

// Implement sort.Interface for []Term
type TermSlice []Term
func (self *TermSlice) Len() int {
    ts := []Term(*self)
    return len(ts)
}
func (self *TermSlice) Less(i, j int) bool {
    ts := []Term(*self)
    return Precedes(ts[i], ts[j]);
}
func (self *TermSlice) Swap(i, j int) {
    ts := []Term(*self)
    tmp := ts[i]
    ts[i] = ts[j]
    ts[j] = tmp
}

func maybePanic(err error) {
    if err != nil {
        panic(err)
    }
}
<|endoftext|>


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

/*
Package gorilla/context provides a container to store values for a request.

A context stores global variables used during a request. For example, a router
can set variables extracted from the URL and later application handlers can
access those values. There are several others common cases.

Here's the basic usage: first define the keys that you will need. The key
type is interface{} so a key can be of any type that supports equality.
Here we define a key using a custom int type to avoid name collisions:

	package foo

	type contextKey int

	const Key1 contextKey = 0

Then somewhere in the package set a variable in the context. Context variables
are bound to a http.Request object, so you need a request instance to set a
value:

	context.DefaultContext.Set(request, Key1, "bar")

The application can later access the variable using the same key you provided:

	func MyHandler(w http.ResponseWriter, r *http.Request) {
		// val is "bar".
		val = context.DefaultContext.Get(r, foo.Key1)

		// ...
	}

You can store any type in the request context, because it accepts and returns
interface{}. To enforce a given type, a good idea is to make the key private
and wrap the getter and setter to accept and return values of a specific type:

	type contextKey int

	const key1 contextKey = 0

	// GetKey1 returns a value for this package from the request context.
	func GetKey1(request *http.Request) SomeType {
		rv := context.DefaultContext.Get(request, key1)
		if rv != nil {
			return rv.(SomeType)
		}
		return nil
	}

	// SetKey1 sets a value for this package in the request context.
	func SetKey1(request *http.Request, val SomeType) {
		context.DefaultContext.Set(request, key1, val)
	}

A context must be cleared at the end of a request, to remove all values
that were stored. This is done in a http.Handler, after a request was served.
Just call Clear() passing the request:

	context.DefaultContext.Clear(request)

The package gorilla/mux clears the default context, so if you are using the
default handler from there you don't need to do anything: context variables
will be deleted at the end of a request.
*/
package context
<commit_msg>context: docs.<commit_after>// Copyright 2011 Gorilla Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/*
Package gorilla/context provides a container to store values for a request.

A context stores global variables used during a request. For example, a router
can set variables extracted from the URL and later application handlers can
access those values. There are several others common cases.

Here's the basic usage: first define the keys that you will need. The key
type is interface{} so a key can be of any type that supports equality.
Here we define a key using a custom int type to avoid name collisions:

	package foo

	type contextKey int

	const Key1 contextKey = 0

Then set a variable in the context. Context variables are bound to a
http.Request object, so you need a request instance to set a value:

	context.DefaultContext.Set(request, Key1, "bar")

The application can later access the variable using the same key you provided:

	func MyHandler(w http.ResponseWriter, r *http.Request) {
		// val is "bar".
		val = context.DefaultContext.Get(r, foo.Key1)

		// ...
	}

And that's all about the basic usage. We discuss some other ideas below.

A Context can store any type. To enforce a given type, make the key private
and wrap Get() and Set() to accept and return values of a specific type:

	type contextKey int

	const key1 contextKey = 0

	// GetKey1 returns a value for this package from the request context.
	func GetKey1(request *http.Request) SomeType {
		rv := context.DefaultContext.Get(request, key1)
		if rv != nil {
			return rv.(SomeType)
		}
		return nil
	}

	// SetKey1 sets a value for this package in the request context.
	func SetKey1(request *http.Request, val SomeType) {
		context.DefaultContext.Set(request, key1, val)
	}

A context must be cleared at the end of a request, to remove all values
that were stored. This can be done in a http.Handler, after a request was
served. Just call Clear() passing the request:

	context.DefaultContext.Clear(request)

The package gorilla/mux clears the default context, so if you are using the
default handler from there you don't need to do anything: context variables
will be deleted at the end of a request.
*/
package context
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"go/build"
	"go/format"
	"io"
	"log"
	"os"
	"path/filepath"
	"strings"
)

const boxFilename = "rice-box.go"

// errEmptyBox is returned by writeBoxesGo when no calls to rice.FindBox
// are found in the package.
var errEmptyBox = errors.New("no calls to rice.FindBox() found")

func writeBoxesGo(pkg *build.Package, out io.Writer) error {
	boxMap := findBoxes(pkg)

	if len(boxMap) == 0 {
		return errEmptyBox
	}

	verbosef("\n")
	out.Write("// Code generated by rice embed-go; DO NOT EDIT.\n")

	var boxes []*boxDataType

	for boxname := range boxMap {
		// find path and filename for this box
		boxPath := filepath.Join(pkg.Dir, boxname)

		// Check to see if the path for the box is a symbolic link.  If so, simply
		// box what the symbolic link points to.  Note: the filepath.Walk function
		// will NOT follow any nested symbolic links.  This only handles the case
		// where the root of the box is a symbolic link.
		symPath, serr := os.Readlink(boxPath)
		if serr == nil {
			boxPath = symPath
		}

		// verbose info
		verbosef("embedding box '%s' to '%s'\n", boxname, boxFilename)

		// read box metadata
		boxInfo, ierr := os.Stat(boxPath)
		if ierr != nil {
			return fmt.Errorf("unable to access box at %s", boxPath)
		}

		// create box datastructure (used by template)
		box := &boxDataType{
			BoxName: boxname,
			UnixNow: boxInfo.ModTime().Unix(),
			Files:   make([]*fileDataType, 0),
			Dirs:    make(map[string]*dirDataType),
		}

		if !boxInfo.IsDir() {
			return fmt.Errorf("box %s must point to a directory but points to %s instead",
				boxname, boxPath)
		}

		// fill box datastructure with file data
		err := filepath.Walk(boxPath, func(path string, info os.FileInfo, err error) error {
			if err != nil {
				return fmt.Errorf("error walking box: %s", err)
			}

			filename := strings.TrimPrefix(path, boxPath)
			filename = strings.Replace(filename, "\\", "/", -1)
			filename = strings.TrimPrefix(filename, "/")
			if info.IsDir() {
				dirData := &dirDataType{
					Identifier: "dir" + nextIdentifier(),
					FileName:   filename,
					ModTime:    info.ModTime().Unix(),
					ChildFiles: make([]*fileDataType, 0),
					ChildDirs:  make([]*dirDataType, 0),
				}
				verbosef("\tincludes dir: '%s'\n", dirData.FileName)
				box.Dirs[dirData.FileName] = dirData

				// add tree entry (skip for root, it'll create a recursion)
				if dirData.FileName != "" {
					pathParts := strings.Split(dirData.FileName, "/")
					parentDir := box.Dirs[strings.Join(pathParts[:len(pathParts)-1], "/")]
					parentDir.ChildDirs = append(parentDir.ChildDirs, dirData)
				}
			} else if !generated(filename) {
				fileData := &fileDataType{
					Identifier: "file" + nextIdentifier(),
					FileName:   filename,
					ModTime:    info.ModTime().Unix(),
				}
				verbosef("\tincludes file: '%s'\n", fileData.FileName)

				// Instead of injecting content, inject placeholder for fasttemplate.
				// This allows us to stream the content into the final file,
				// and it also avoids running gofmt on a very large source code.
				fileData.Path = path
				box.Files = append(box.Files, fileData)

				// add tree entry
				pathParts := strings.Split(fileData.FileName, "/")
				parentDir := box.Dirs[strings.Join(pathParts[:len(pathParts)-1], "/")]
				if parentDir == nil {
					return fmt.Errorf("parent of %s is not within the box", path)
				}
				parentDir.ChildFiles = append(parentDir.ChildFiles, fileData)
			}
			return nil
		})
		if err != nil {
			return fmt.Errorf("failed in filepath walk: %v", err)
		}
		boxes = append(boxes, box)

	}

	embedSourceUnformated := bytes.NewBuffer(make([]byte, 0))

	// execute template to buffer
	err := tmplEmbeddedBox.Execute(
		embedSourceUnformated,
		embedFileDataType{pkg.Name, boxes},
	)
	if err != nil {
		return fmt.Errorf("error writing embedded box to file (template execute): %s", err)
	}

	// format the source code
	embedSource, err := format.Source(embedSourceUnformated.Bytes())
	if err != nil {
		return fmt.Errorf("error formatting embedSource: %s", err)
	}

	// write source to file
	bufWriter := bufio.NewWriterSize(out, 100*1024)
	err = embeddedBoxFasttemplate(bufWriter, string(embedSource))
	if err != nil {
		return fmt.Errorf("error writing embedSource to file: %s\n", err)
	}
	err = bufWriter.Flush()
	if err != nil {
		return fmt.Errorf("error writing embedSource to file: %s", err)
	}
	return nil
}

func operationEmbedGo(pkg *build.Package) {
	// create go file for box
	boxFile, err := os.Create(filepath.Join(pkg.Dir, boxFilename))
	if err != nil {
		log.Printf("error creating embedded box file: %s\n", err)
		os.Exit(1)
	}

	err = writeBoxesGo(pkg, boxFile)
	boxFile.Close()
	if err != nil {
		// don't leave an invalid go file in the package directory.
		if errRemove := os.Remove(boxFile.Name()); errRemove != nil {
			log.Printf("error while removing file: %s\n", errRemove)
		}
		if err != errEmptyBox {
			log.Printf("error creating embedded box file: %s\n", err)
			os.Exit(1)
		} else {
			// notify user when no calls to rice.FindBox are made,
			// but don't fail, since it's useful to be able to run
			// go.rice unconditionally.
			log.Println(errEmptyBox)
		}
	}
}
<commit_msg>convert to byte slice<commit_after>package main

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"go/build"
	"go/format"
	"io"
	"log"
	"os"
	"path/filepath"
	"strings"
)

const boxFilename = "rice-box.go"

// errEmptyBox is returned by writeBoxesGo when no calls to rice.FindBox
// are found in the package.
var errEmptyBox = errors.New("no calls to rice.FindBox() found")

func writeBoxesGo(pkg *build.Package, out io.Writer) error {
	boxMap := findBoxes(pkg)

	if len(boxMap) == 0 {
		return errEmptyBox
	}

	verbosef("\n")
	out.Write([]byte("// Code generated by rice embed-go; DO NOT EDIT.\n"))

	var boxes []*boxDataType

	for boxname := range boxMap {
		// find path and filename for this box
		boxPath := filepath.Join(pkg.Dir, boxname)

		// Check to see if the path for the box is a symbolic link.  If so, simply
		// box what the symbolic link points to.  Note: the filepath.Walk function
		// will NOT follow any nested symbolic links.  This only handles the case
		// where the root of the box is a symbolic link.
		symPath, serr := os.Readlink(boxPath)
		if serr == nil {
			boxPath = symPath
		}

		// verbose info
		verbosef("embedding box '%s' to '%s'\n", boxname, boxFilename)

		// read box metadata
		boxInfo, ierr := os.Stat(boxPath)
		if ierr != nil {
			return fmt.Errorf("unable to access box at %s", boxPath)
		}

		// create box datastructure (used by template)
		box := &boxDataType{
			BoxName: boxname,
			UnixNow: boxInfo.ModTime().Unix(),
			Files:   make([]*fileDataType, 0),
			Dirs:    make(map[string]*dirDataType),
		}

		if !boxInfo.IsDir() {
			return fmt.Errorf("box %s must point to a directory but points to %s instead",
				boxname, boxPath)
		}

		// fill box datastructure with file data
		err := filepath.Walk(boxPath, func(path string, info os.FileInfo, err error) error {
			if err != nil {
				return fmt.Errorf("error walking box: %s", err)
			}

			filename := strings.TrimPrefix(path, boxPath)
			filename = strings.Replace(filename, "\\", "/", -1)
			filename = strings.TrimPrefix(filename, "/")
			if info.IsDir() {
				dirData := &dirDataType{
					Identifier: "dir" + nextIdentifier(),
					FileName:   filename,
					ModTime:    info.ModTime().Unix(),
					ChildFiles: make([]*fileDataType, 0),
					ChildDirs:  make([]*dirDataType, 0),
				}
				verbosef("\tincludes dir: '%s'\n", dirData.FileName)
				box.Dirs[dirData.FileName] = dirData

				// add tree entry (skip for root, it'll create a recursion)
				if dirData.FileName != "" {
					pathParts := strings.Split(dirData.FileName, "/")
					parentDir := box.Dirs[strings.Join(pathParts[:len(pathParts)-1], "/")]
					parentDir.ChildDirs = append(parentDir.ChildDirs, dirData)
				}
			} else if !generated(filename) {
				fileData := &fileDataType{
					Identifier: "file" + nextIdentifier(),
					FileName:   filename,
					ModTime:    info.ModTime().Unix(),
				}
				verbosef("\tincludes file: '%s'\n", fileData.FileName)

				// Instead of injecting content, inject placeholder for fasttemplate.
				// This allows us to stream the content into the final file,
				// and it also avoids running gofmt on a very large source code.
				fileData.Path = path
				box.Files = append(box.Files, fileData)

				// add tree entry
				pathParts := strings.Split(fileData.FileName, "/")
				parentDir := box.Dirs[strings.Join(pathParts[:len(pathParts)-1], "/")]
				if parentDir == nil {
					return fmt.Errorf("parent of %s is not within the box", path)
				}
				parentDir.ChildFiles = append(parentDir.ChildFiles, fileData)
			}
			return nil
		})
		if err != nil {
			return fmt.Errorf("failed in filepath walk: %v", err)
		}
		boxes = append(boxes, box)

	}

	embedSourceUnformated := bytes.NewBuffer(make([]byte, 0))

	// execute template to buffer
	err := tmplEmbeddedBox.Execute(
		embedSourceUnformated,
		embedFileDataType{pkg.Name, boxes},
	)
	if err != nil {
		return fmt.Errorf("error writing embedded box to file (template execute): %s", err)
	}

	// format the source code
	embedSource, err := format.Source(embedSourceUnformated.Bytes())
	if err != nil {
		return fmt.Errorf("error formatting embedSource: %s", err)
	}

	// write source to file
	bufWriter := bufio.NewWriterSize(out, 100*1024)
	err = embeddedBoxFasttemplate(bufWriter, string(embedSource))
	if err != nil {
		return fmt.Errorf("error writing embedSource to file: %s\n", err)
	}
	err = bufWriter.Flush()
	if err != nil {
		return fmt.Errorf("error writing embedSource to file: %s", err)
	}
	return nil
}

func operationEmbedGo(pkg *build.Package) {
	// create go file for box
	boxFile, err := os.Create(filepath.Join(pkg.Dir, boxFilename))
	if err != nil {
		log.Printf("error creating embedded box file: %s\n", err)
		os.Exit(1)
	}

	err = writeBoxesGo(pkg, boxFile)
	boxFile.Close()
	if err != nil {
		// don't leave an invalid go file in the package directory.
		if errRemove := os.Remove(boxFile.Name()); errRemove != nil {
			log.Printf("error while removing file: %s\n", errRemove)
		}
		if err != errEmptyBox {
			log.Printf("error creating embedded box file: %s\n", err)
			os.Exit(1)
		} else {
			// notify user when no calls to rice.FindBox are made,
			// but don't fail, since it's useful to be able to run
			// go.rice unconditionally.
			log.Println(errEmptyBox)
		}
	}
}
<|endoftext|>


<commit_before>package radius

func init() {
	Builtin = &Dictionary{}

	AttributeText = attributeText{}
	AttributeString = attributeString{}
	AttributeAddress = attributeAddress{}
	AttributeInteger = attributeInteger{}
	AttributeTime = attributeTime{}
	AttributeUnknown = attributeString{}

	// RFC 2865
	// TODO: Attribute* should be initialized before
	Builtin.MustRegister("User-Name", 1, AttributeText)
	Builtin.MustRegister("User-Password", 2, rfc2865UserPassword{})
	Builtin.MustRegister("CHAP-Password", 3, AttributeString)
	Builtin.MustRegister("NAS-IP-Address", 4, AttributeAddress)
	Builtin.MustRegister("NAS-Port", 5, AttributeInteger)
	Builtin.MustRegister("Service-Type", 6, AttributeInteger)
	Builtin.MustRegister("Framed-Protocol", 7, AttributeInteger)
	Builtin.MustRegister("Framed-IP-Address", 8, AttributeAddress)
	Builtin.MustRegister("Framed-IP-Netmask", 9, AttributeAddress)
	Builtin.MustRegister("Framed-Routing", 10, AttributeInteger)
	Builtin.MustRegister("Filter-Id", 11, AttributeText)
	Builtin.MustRegister("Framed-MTU", 12, AttributeInteger)
	Builtin.MustRegister("Framed-Compression", 13, AttributeInteger)
	Builtin.MustRegister("Login-IP-Host", 14, AttributeAddress)
	Builtin.MustRegister("Login-Service", 15, AttributeInteger)
	Builtin.MustRegister("Login-TCP-Port", 16, AttributeInteger)
	Builtin.MustRegister("Reply-Message", 18, AttributeText)
	Builtin.MustRegister("Callback-Number", 19, AttributeString)
	Builtin.MustRegister("Callback-Id", 20, AttributeString)
	Builtin.MustRegister("Framed-Route", 22, AttributeText)
	Builtin.MustRegister("Framed-IPX-Network", 23, AttributeAddress)
	Builtin.MustRegister("State", 24, AttributeString)
	Builtin.MustRegister("Class", 25, AttributeString)
	Builtin.MustRegister("Vendor-Specific", 26, AttributeString)
	Builtin.MustRegister("Session-Timeout", 27, AttributeInteger)
	Builtin.MustRegister("Idle-Timeout", 28, AttributeInteger)
	Builtin.MustRegister("Termination-Action", 29, AttributeInteger)
	Builtin.MustRegister("Called-Station-Id", 30, AttributeString)
	Builtin.MustRegister("Calling-Station-Id", 31, AttributeString)
	Builtin.MustRegister("NAS-Identifier", 32, AttributeString)
	Builtin.MustRegister("Proxy-State", 33, AttributeString)
	Builtin.MustRegister("Login-LAT-Service", 34, AttributeString)
	Builtin.MustRegister("Login-LAT-Node", 35, AttributeString)
	Builtin.MustRegister("Login-LAT-Group", 36, AttributeString)
	Builtin.MustRegister("Framed-AppleTalk-Link", 37, AttributeInteger)
	Builtin.MustRegister("Framed-AppleTalk-Network", 38, AttributeInteger)
	Builtin.MustRegister("Framed-AppleTalk-Zone", 39, AttributeString)
	Builtin.MustRegister("CHAP-Challenge", 60, AttributeString)
	Builtin.MustRegister("NAS-Port-Type", 61, AttributeInteger)
	Builtin.MustRegister("Port-Limit", 62, AttributeInteger)
	Builtin.MustRegister("Login-LAT-Port", 63, AttributeString)

	// RFC 2866
	Builtin.MustRegister("Acct-Status-Type", 40, AttributeInteger)
	Builtin.MustRegister("Acct-Delay-Time", 41, AttributeInteger)
	Builtin.MustRegister("Acct-Input-Octets", 42, AttributeInteger)
	Builtin.MustRegister("Acct-Output-Octets", 43, AttributeInteger)
	Builtin.MustRegister("Acct-Session-Id", 44, AttributeText)
	Builtin.MustRegister("Acct-Authentic", 45, AttributeInteger)
	Builtin.MustRegister("Acct-Session-Time", 46, AttributeInteger)
	Builtin.MustRegister("Acct-Input-Packets", 47, AttributeInteger)
	Builtin.MustRegister("Acct-Output-Packets", 48, AttributeInteger)
	Builtin.MustRegister("Acct-Terminate-Cause", 49, AttributeInteger)
	Builtin.MustRegister("Acct-Multi-Session-Id", 50, AttributeText)
	Builtin.MustRegister("Acct-Link-Count", 51, AttributeInteger)
}
<commit_msg>remove old TODO<commit_after>package radius

func init() {
	Builtin = &Dictionary{}

	AttributeText = attributeText{}
	AttributeString = attributeString{}
	AttributeAddress = attributeAddress{}
	AttributeInteger = attributeInteger{}
	AttributeTime = attributeTime{}
	AttributeUnknown = attributeString{}

	// RFC 2865
	Builtin.MustRegister("User-Name", 1, AttributeText)
	Builtin.MustRegister("User-Password", 2, rfc2865UserPassword{})
	Builtin.MustRegister("CHAP-Password", 3, AttributeString)
	Builtin.MustRegister("NAS-IP-Address", 4, AttributeAddress)
	Builtin.MustRegister("NAS-Port", 5, AttributeInteger)
	Builtin.MustRegister("Service-Type", 6, AttributeInteger)
	Builtin.MustRegister("Framed-Protocol", 7, AttributeInteger)
	Builtin.MustRegister("Framed-IP-Address", 8, AttributeAddress)
	Builtin.MustRegister("Framed-IP-Netmask", 9, AttributeAddress)
	Builtin.MustRegister("Framed-Routing", 10, AttributeInteger)
	Builtin.MustRegister("Filter-Id", 11, AttributeText)
	Builtin.MustRegister("Framed-MTU", 12, AttributeInteger)
	Builtin.MustRegister("Framed-Compression", 13, AttributeInteger)
	Builtin.MustRegister("Login-IP-Host", 14, AttributeAddress)
	Builtin.MustRegister("Login-Service", 15, AttributeInteger)
	Builtin.MustRegister("Login-TCP-Port", 16, AttributeInteger)
	Builtin.MustRegister("Reply-Message", 18, AttributeText)
	Builtin.MustRegister("Callback-Number", 19, AttributeString)
	Builtin.MustRegister("Callback-Id", 20, AttributeString)
	Builtin.MustRegister("Framed-Route", 22, AttributeText)
	Builtin.MustRegister("Framed-IPX-Network", 23, AttributeAddress)
	Builtin.MustRegister("State", 24, AttributeString)
	Builtin.MustRegister("Class", 25, AttributeString)
	Builtin.MustRegister("Vendor-Specific", 26, AttributeString)
	Builtin.MustRegister("Session-Timeout", 27, AttributeInteger)
	Builtin.MustRegister("Idle-Timeout", 28, AttributeInteger)
	Builtin.MustRegister("Termination-Action", 29, AttributeInteger)
	Builtin.MustRegister("Called-Station-Id", 30, AttributeString)
	Builtin.MustRegister("Calling-Station-Id", 31, AttributeString)
	Builtin.MustRegister("NAS-Identifier", 32, AttributeString)
	Builtin.MustRegister("Proxy-State", 33, AttributeString)
	Builtin.MustRegister("Login-LAT-Service", 34, AttributeString)
	Builtin.MustRegister("Login-LAT-Node", 35, AttributeString)
	Builtin.MustRegister("Login-LAT-Group", 36, AttributeString)
	Builtin.MustRegister("Framed-AppleTalk-Link", 37, AttributeInteger)
	Builtin.MustRegister("Framed-AppleTalk-Network", 38, AttributeInteger)
	Builtin.MustRegister("Framed-AppleTalk-Zone", 39, AttributeString)
	Builtin.MustRegister("CHAP-Challenge", 60, AttributeString)
	Builtin.MustRegister("NAS-Port-Type", 61, AttributeInteger)
	Builtin.MustRegister("Port-Limit", 62, AttributeInteger)
	Builtin.MustRegister("Login-LAT-Port", 63, AttributeString)

	// RFC 2866
	Builtin.MustRegister("Acct-Status-Type", 40, AttributeInteger)
	Builtin.MustRegister("Acct-Delay-Time", 41, AttributeInteger)
	Builtin.MustRegister("Acct-Input-Octets", 42, AttributeInteger)
	Builtin.MustRegister("Acct-Output-Octets", 43, AttributeInteger)
	Builtin.MustRegister("Acct-Session-Id", 44, AttributeText)
	Builtin.MustRegister("Acct-Authentic", 45, AttributeInteger)
	Builtin.MustRegister("Acct-Session-Time", 46, AttributeInteger)
	Builtin.MustRegister("Acct-Input-Packets", 47, AttributeInteger)
	Builtin.MustRegister("Acct-Output-Packets", 48, AttributeInteger)
	Builtin.MustRegister("Acct-Terminate-Cause", 49, AttributeInteger)
	Builtin.MustRegister("Acct-Multi-Session-Id", 50, AttributeText)
	Builtin.MustRegister("Acct-Link-Count", 51, AttributeInteger)
}
<|endoftext|>