From b1a66c0cf7a76b37e6509e2e9a77ae252f38526c Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Mon, 29 Jun 2015 16:24:57 -0700 Subject: [PATCH] Allow manually specifying translations for modules Parse the comment block above each module or assignment looking for directives in the form: Android.mk: 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 --- androidbp/cmd/androidbp.go | 102 ++++++++++++++++++++++++++++++++ androidbp/cmd/androidbp_test.go | 14 +++++ 2 files changed, 116 insertions(+) diff --git a/androidbp/cmd/androidbp.go b/androidbp/cmd/androidbp.go index 46753a0d8..4a850a845 100644 --- a/androidbp/cmd/androidbp.go +++ b/androidbp/cmd/androidbp.go @@ -10,6 +10,7 @@ import ( "path/filepath" "regexp" "strings" + "text/scanner" 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 { + 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)) if err != nil { return err @@ -403,6 +412,14 @@ func (w *androidMkWriter) handleSubdirs(value bpparser.Value) { } 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 { w.handleSubdirs(assignment.OrigValue) } else if assignment.OrigValue.Type == bpparser.Map { @@ -450,6 +467,91 @@ func (w *androidMkWriter) handleLocalPath() error { 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) { w.Writer = writer diff --git a/androidbp/cmd/androidbp_test.go b/androidbp/cmd/androidbp_test.go index f5590e27d..56ceca561 100644 --- a/androidbp/cmd/androidbp_test.go +++ b/androidbp/cmd/androidbp_test.go @@ -117,6 +117,20 @@ var moduleTestCases = []struct { LOCAL_MODULE := test 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) {