Allow manually specifying translations for modules

Parse the comment block above each module or assignment looking
for directives in the form:
Android.mk:<directive>
If a block delimited by start and end directives is found, use it
as the Android.mk translation instead of trying to automatically
translate.  If an ignore directive is found, ignore the module
completely.

Change-Id: I34fe392899ed27ce3f640a2a71fbbaaedea67169
This commit is contained in:
Colin Cross 2015-06-29 16:24:57 -07:00
parent b093124675
commit b1a66c0cf7
2 changed files with 116 additions and 0 deletions

View file

@ -10,6 +10,7 @@ import (
"path/filepath" "path/filepath"
"regexp" "regexp"
"strings" "strings"
"text/scanner"
bpparser "github.com/google/blueprint/parser" bpparser "github.com/google/blueprint/parser"
) )
@ -377,6 +378,14 @@ func (w *androidMkWriter) mutateModule(module *Module) (modules []*Module, err e
} }
func (w *androidMkWriter) handleModule(inputModule *bpparser.Module) error { func (w *androidMkWriter) handleModule(inputModule *bpparser.Module) error {
comment := w.getCommentBlock(inputModule.Type.Pos)
if translation, translated, err := getCommentTranslation(comment); err != nil {
return err
} else if translated {
w.WriteString(translation)
return nil
}
modules, err := w.mutateModule(newModule(inputModule)) modules, err := w.mutateModule(newModule(inputModule))
if err != nil { if err != nil {
return err return err
@ -403,6 +412,14 @@ func (w *androidMkWriter) handleSubdirs(value bpparser.Value) {
} }
func (w *androidMkWriter) handleAssignment(assignment *bpparser.Assignment) error { func (w *androidMkWriter) handleAssignment(assignment *bpparser.Assignment) error {
comment := w.getCommentBlock(assignment.Name.Pos)
if translation, translated, err := getCommentTranslation(comment); err != nil {
return err
} else if translated {
w.WriteString(translation)
return nil
}
if "subdirs" == assignment.Name.Name { if "subdirs" == assignment.Name.Name {
w.handleSubdirs(assignment.OrigValue) w.handleSubdirs(assignment.OrigValue)
} else if assignment.OrigValue.Type == bpparser.Map { } else if assignment.OrigValue.Type == bpparser.Map {
@ -450,6 +467,91 @@ func (w *androidMkWriter) handleLocalPath() error {
return nil return nil
} }
// Returns any block comment on the line preceding pos as a string
func (w *androidMkWriter) getCommentBlock(pos scanner.Position) string {
var buf []byte
comments := w.blueprint.Comments
for i, c := range comments {
if c.EndLine() == pos.Line-1 {
line := pos.Line
for j := i; j >= 0; j-- {
c = comments[j]
if c.EndLine() == line-1 {
buf = append([]byte(c.Text()), buf...)
line = c.Pos.Line
} else {
break
}
}
}
}
return string(buf)
}
func getCommentTranslation(comment string) (string, bool, error) {
lines := strings.Split(comment, "\n")
if directive, i, err := getCommentDirective(lines); err != nil {
return "", false, err
} else if directive != "" {
switch directive {
case "ignore":
return "", true, nil
case "start":
return getCommentTranslationBlock(lines[i+1:])
case "end":
return "", false, fmt.Errorf("Unexpected Android.mk:end translation directive")
default:
return "", false, fmt.Errorf("Unknown Android.mk module translation directive %q", directive)
}
}
return "", false, nil
}
func getCommentTranslationBlock(lines []string) (string, bool, error) {
var buf []byte
for _, line := range lines {
if directive := getLineCommentDirective(line); directive != "" {
switch directive {
case "end":
return string(buf), true, nil
default:
return "", false, fmt.Errorf("Unexpected Android.mk translation directive %q inside start", directive)
}
} else {
buf = append(buf, line...)
buf = append(buf, '\n')
}
}
return "", false, fmt.Errorf("Missing Android.mk:end translation directive")
}
func getCommentDirective(lines []string) (directive string, n int, err error) {
for i, line := range lines {
if directive := getLineCommentDirective(line); directive != "" {
return strings.ToLower(directive), i, nil
}
}
return "", -1, nil
}
func getLineCommentDirective(line string) string {
line = strings.TrimSpace(line)
if strings.HasPrefix(line, "Android.mk:") {
line = strings.TrimPrefix(line, "Android.mk:")
line = strings.TrimSpace(line)
return line
}
return ""
}
func (w *androidMkWriter) write(writer io.Writer) (err error) { func (w *androidMkWriter) write(writer io.Writer) (err error) {
w.Writer = writer w.Writer = writer

View file

@ -117,6 +117,20 @@ var moduleTestCases = []struct {
LOCAL_MODULE := test LOCAL_MODULE := test
include $(BUILD_HOST_STATIC_LIBRARY)`, include $(BUILD_HOST_STATIC_LIBRARY)`,
}, },
// Manual translation
{
blueprint: `/* Android.mk:start
# Manual translation
Android.mk:end */
cc_library { name: "test", host_supported: true, }`,
androidmk: `# Manual translation`,
},
// Ignored translation
{
blueprint: `/* Android.mk:ignore */
cc_library { name: "test", host_supported: true, }`,
androidmk: ``,
},
} }
func TestModules(t *testing.T) { func TestModules(t *testing.T) {