Commit 25caf18a authored by Rob Pike's avatar Rob Pike

improve generated code for godocability

R=rsc
DELTA=459  (168 added, 279 deleted, 12 changed)
OCL=34005
CL=34007
parent f7e92c59
...@@ -14,6 +14,7 @@ import ( ...@@ -14,6 +14,7 @@ import (
"http"; "http";
"log"; "log";
"os"; "os";
"sort";
"strconv"; "strconv";
"strings"; "strings";
"regexp"; "regexp";
...@@ -235,7 +236,7 @@ func printCategories() { ...@@ -235,7 +236,7 @@ func printCategories() {
die.Log(err); die.Log(err);
} }
if resp.StatusCode != 200 { if resp.StatusCode != 200 {
die.Log("bad GET status for UnicodeData.txt", resp.StatusCode); die.Log("bad GET status for UnicodeData.txt", resp.Status);
} }
input := bufio.NewReader(resp.Body); input := bufio.NewReader(resp.Body);
for { for {
...@@ -279,6 +280,8 @@ func printCategories() { ...@@ -279,6 +280,8 @@ func printCategories() {
fmt.Printf("}\n\n"); fmt.Printf("}\n\n");
} }
decl := make(sort.StringArray, len(list));
ndecl := 0;
for _, name := range list { for _, name := range list {
if _, ok := category[name]; !ok { if _, ok := category[name]; !ok {
die.Log("unknown category", name); die.Log("unknown category", name);
...@@ -286,56 +289,52 @@ func printCategories() { ...@@ -286,56 +289,52 @@ func printCategories() {
// We generate an UpperCase name to serve as concise documentation and an _UnderScored // We generate an UpperCase name to serve as concise documentation and an _UnderScored
// name to store the data. This stops godoc dumping all the tables but keeps them // name to store the data. This stops godoc dumping all the tables but keeps them
// available to clients. // available to clients.
if name == "letter" { // special case
dumpRange(
"\n// Letter is the set of Unicode letters.\n"
"var Letter = letter\n"
"var letter = []Range {\n",
letterOp,
"}\n"
);
continue;
}
// Cases deserving special comments // Cases deserving special comments
varDecl := "";
switch name { switch name {
case "letter":
varDecl = "\tLetter = letter; // Letter is the set of Unicode letters.\n";
case "Nd": case "Nd":
fmt.Printf( varDecl = "\tDigit = _Nd; // Digit is the set of Unicode characters with the \"decimal digit\" property.\n";
"\n// Digit is the set of Unicode characters with the \"decimal digit\" property.\n"
"var Digit = Nd\n\n"
)
case "Lu": case "Lu":
fmt.Printf( varDecl = "\tUpper = _Lu; // Upper is the set of Unicode upper case letters.\n";
"\n// Upper is the set of Unicode upper case letters.\n"
"var Upper = Lu\n\n"
)
case "Ll": case "Ll":
fmt.Printf( varDecl = "\tLower = _Ll; // Lower is the set of Unicode lower case letters.\n";
"\n// Lower is the set of Unicode lower case letters.\n"
"var Lower = Ll\n\n"
)
case "Lt": case "Lt":
fmt.Printf( varDecl = "\tTitle = _Lt; // Title is the set of Unicode title case letters.\n";
"\n// Title is the set of Unicode title case letters.\n" }
"var Title = Lt\n\n" if name != "letter" {
) varDecl += fmt.Sprintf(
"\t%s = _%s; // %s is the set of Unicode characters in category %s.\n",
name, name, name, name
);
}
decl[ndecl] = varDecl;
ndecl++;
if name == "letter" { // special case
dumpRange(
"var letter = []Range {\n",
letterOp
);
continue;
} }
dumpRange( dumpRange(
fmt.Sprintf( fmt.Sprintf("var _%s = []Range {\n", name),
"// %s is the set of Unicode characters in category %s.\n" func(code int) bool { return chars[code].category == name }
"var %s = _%s\n"
"var _%s = []Range {\n",
name, name, name, name, name
),
func(code int) bool { return chars[code].category == name },
"}\n\n"
); );
} }
decl.Sort();
fmt.Println("var (");
for _, d := range decl {
fmt.Print(d);
}
fmt.Println(")\n");
} }
type Op func(code int) bool type Op func(code int) bool
const format = "\tRange{0x%04x, 0x%04x, %d},\n"; const format = "\tRange{0x%04x, 0x%04x, %d},\n";
func dumpRange(header string, inCategory Op, trailer string) { func dumpRange(header string, inCategory Op) {
fmt.Print(header); fmt.Print(header);
next := 0; next := 0;
// one Range for each iteration // one Range for each iteration
...@@ -382,7 +381,7 @@ func dumpRange(header string, inCategory Op, trailer string) { ...@@ -382,7 +381,7 @@ func dumpRange(header string, inCategory Op, trailer string) {
// next range: start looking where this range ends // next range: start looking where this range ends
next = hi + 1; next = hi + 1;
} }
fmt.Print(trailer); fmt.Print("}\n\n");
} }
func fullCategoryTest(list []string) { func fullCategoryTest(list []string) {
...@@ -510,19 +509,27 @@ func printScripts() { ...@@ -510,19 +509,27 @@ func printScripts() {
fmt.Printf("}\n\n"); fmt.Printf("}\n\n");
} }
decl := make(sort.StringArray, len(list));
ndecl := 0;
for _, name := range list { for _, name := range list {
fmt.Printf( decl[ndecl] = fmt.Sprintf(
"// %s is the set of Unicode characters in script %s.\n" "\t%s = _%s;\t// %s is the set of Unicode characters in script %s.\n",
"var %s = _%s\n" name, name, name, name
"var _%s = []Range {\n",
name, name, name, name, name
); );
ndecl++;
fmt.Printf("var _%s = []Range {\n", name);
ranges := foldAdjacent(scripts[name]); ranges := foldAdjacent(scripts[name]);
for _, s := range ranges { for _, s := range ranges {
fmt.Printf(format, s.Lo, s.Hi, s.Stride); fmt.Printf(format, s.Lo, s.Hi, s.Stride);
} }
fmt.Printf("}\n\n"); fmt.Printf("}\n\n");
} }
decl.Sort();
fmt.Println("var (");
for _, d := range decl {
fmt.Print(d);
}
fmt.Println(")\n");
} }
// The script tables have a lot of adjacent elements. Fold them together. // The script tables have a lot of adjacent elements. Fold them together.
......
...@@ -132,43 +132,38 @@ var inCategoryTest = []T { ...@@ -132,43 +132,38 @@ var inCategoryTest = []T {
} }
func TestScripts(t *testing.T) { func TestScripts(t *testing.T) {
notTested := make(map[string] bool);
for k := range Scripts {
notTested[k] = true
}
for i, test := range inTest { for i, test := range inTest {
if !Is(Scripts[test.script], test.rune) { if !Is(Scripts[test.script], test.rune) {
t.Errorf("IsScript(%#x, %s) = false, want true\n", test.rune, test.script); t.Errorf("IsScript(%#x, %s) = false, want true\n", test.rune, test.script);
} }
notTested[test.script] = false, false
} }
for i, test := range outTest { for i, test := range outTest {
if Is(Scripts[test.script], test.rune) { if Is(Scripts[test.script], test.rune) {
t.Errorf("IsScript(%#x, %s) = true, want false\n", test.rune, test.script); t.Errorf("IsScript(%#x, %s) = true, want false\n", test.rune, test.script);
} }
} }
tested := make(map[string] bool); for k := range notTested {
for k := range Scripts {
tested[k] = true
}
for _, test := range inTest {
tested[test.script] = false, false
}
for k := range tested {
t.Error("not tested:", k) t.Error("not tested:", k)
} }
} }
func TestCategories(t *testing.T) { func TestCategories(t *testing.T) {
notTested := make(map[string] bool);
for k := range Categories {
notTested[k] = true
}
for i, test := range inCategoryTest { for i, test := range inCategoryTest {
if !Is(Categories[test.script], test.rune) { if !Is(Categories[test.script], test.rune) {
t.Errorf("IsCategory(%#x, %s) = false, want true\n", test.rune, test.script); t.Errorf("IsCategory(%#x, %s) = false, want true\n", test.rune, test.script);
} }
notTested[test.script] = false, false
} }
tested := make(map[string] bool); for k := range notTested {
for k := range Categories {
tested[k] = true
}
for _, test := range inCategoryTest {
tested[test.script] = false, false
}
for k := range tested {
t.Error("not tested:", k) t.Error("not tested:", k)
} }
} }
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment