blob: e7dab1a87734f14b1585ea11c513bfe1f337ab1b [file] [log] [blame]
// Copyright (C) 2015 The Android Open Source Project
//
// 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 copyright
import (
"bytes"
"fmt"
"regexp"
"strings"
"text/template"
)
const generatedPrefix = "generated"
const externalPrefix = "external"
var (
current = Info{Year: "2015"}
languages = []*Language{
{
Name: "go",
License: "aosp_cpp",
Extensions: []string{".go"},
},
{
Name: "c",
License: "aosp_c",
Extensions: []string{".c", ".cpp", ".h", ".mm", ".java"},
},
{
Name: "api",
License: "aosp_cpp",
Extensions: []string{".api"},
},
{
Name: "template",
License: "aosp_tmpl",
Extensions: []string{".tmpl"},
},
}
External = []*regexp.Regexp{}
Generated = []*regexp.Regexp{}
Normal = []*regexp.Regexp{}
)
type Info struct {
Year string
Tool string
}
type Language struct {
Name string
Extensions []string
License string
Emit string
Current []*regexp.Regexp
Old []*regexp.Regexp
}
func init() {
for _, l := range languages {
l.Emit = Build(l.License, current)
l.Current = []*regexp.Regexp{Regexp(l.License, current, false)}
l.Old = []*regexp.Regexp{Regexp(l.License, Info{}, true)}
}
for name, _ := range embedded {
re := Regexp(name, Info{}, true)
if strings.HasPrefix(name, externalPrefix) {
External = append(External, re)
} else if strings.HasPrefix(name, generatedPrefix) {
Generated = append(Generated, re)
} else {
Normal = append(Normal, re)
}
}
}
func get(name string) string {
header, ok := embedded[name]
if !ok {
panic(fmt.Errorf("Invalid header name %s", name))
}
return header
}
func build(name string, header string, i Info) string {
funcs := template.FuncMap{
"Year": func() string { return i.Year },
"Tool": func() string { return i.Tool },
}
t := template.Must(template.New(name).
Delims("«", "»").
Funcs(funcs).
Parse(header))
b := &bytes.Buffer{}
if err := t.Execute(b, i); err != nil {
panic(fmt.Errorf("Error building %s: %s", name, err))
}
return b.String()
}
func Build(name string, i Info) string {
return build(name, get(name), i)
}
func Regexp(name string, i Info, trim bool) *regexp.Regexp {
if i.Year == "" {
i.Year = `(.*)`
}
if i.Tool == "" {
i.Tool = `(.*)`
}
header := get(name)
if trim {
header = `^\s*` + regexp.QuoteMeta(strings.TrimSpace(header)) + `\s*`
} else {
header = `^` + regexp.QuoteMeta(header)
}
return regexp.MustCompile(build(name, header, i))
}
func FindLanguage(name string) *Language {
for _, l := range languages {
if l.Name == name {
return l
}
}
return nil
}
func FindExtension(ext string) *Language {
for _, l := range languages {
for _, e := range l.Extensions {
if e == ext {
return l
}
}
}
return nil
}
func match(file []byte, list []*regexp.Regexp) int {
for _, re := range list {
match := re.Find(file)
if len(match) > 0 {
return len(match)
}
}
return 0
}
func (l *Language) MatchCurrent(file []byte) int {
return match(file, l.Current)
}
func (l *Language) MatchOld(file []byte) int {
return match(file, l.Old)
}
func MatchNormal(file []byte) int {
return match(file, Normal)
}
func MatchExternal(file []byte) int {
return match(file, External)
}
func MatchGenerated(file []byte) int {
return match(file, Generated)
}