blob: d6eb32e2aeefa318724befe041c973d7edfd50fc [file] [log] [blame]
Russ Cox6ca324f2019-04-26 10:32:15 -04001// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Russ Coxd4b26382021-02-19 18:35:10 -05005//go:build ignore
Russ Cox6ca324f2019-04-26 10:32:15 -04006
7// Gen generates sais2.go by duplicating functions in sais.go
8// using different input types.
9// See the comment at the top of sais.go for details.
10package main
11
12import (
13 "bytes"
Russ Cox6ca324f2019-04-26 10:32:15 -040014 "log"
Russ Cox4f1b0a42020-10-29 14:17:47 -040015 "os"
Russ Cox6ca324f2019-04-26 10:32:15 -040016 "strings"
17)
18
19func main() {
20 log.SetPrefix("gen: ")
21 log.SetFlags(0)
22
Russ Cox4f1b0a42020-10-29 14:17:47 -040023 data, err := os.ReadFile("sais.go")
Russ Cox6ca324f2019-04-26 10:32:15 -040024 if err != nil {
25 log.Fatal(err)
26 }
27
28 x := bytes.Index(data, []byte("\n\n"))
29 if x < 0 {
30 log.Fatal("cannot find blank line after copyright comment")
31 }
32
33 var buf bytes.Buffer
34 buf.Write(data[:x])
35 buf.WriteString("\n\n// Code generated by go generate; DO NOT EDIT.\n\npackage suffixarray\n")
36
37 for {
38 x := bytes.Index(data, []byte("\nfunc "))
39 if x < 0 {
40 break
41 }
42 data = data[x:]
43 p := bytes.IndexByte(data, '(')
44 if p < 0 {
45 p = len(data)
46 }
47 name := string(data[len("\nfunc "):p])
48
49 x = bytes.Index(data, []byte("\n}\n"))
50 if x < 0 {
51 log.Fatalf("cannot find end of func %s", name)
52 }
53 fn := string(data[:x+len("\n}\n")])
54 data = data[x+len("\n}"):]
55
56 if strings.HasSuffix(name, "_32") {
57 buf.WriteString(fix32.Replace(fn))
58 }
59 if strings.HasSuffix(name, "_8_32") {
60 // x_8_32 -> x_8_64 done above
61 fn = fix8_32.Replace(stripByteOnly(fn))
62 buf.WriteString(fn)
63 buf.WriteString(fix32.Replace(fn))
64 }
65 }
66
Russ Cox4f1b0a42020-10-29 14:17:47 -040067 if err := os.WriteFile("sais2.go", buf.Bytes(), 0666); err != nil {
Russ Cox6ca324f2019-04-26 10:32:15 -040068 log.Fatal(err)
69 }
70}
71
72var fix32 = strings.NewReplacer(
73 "32", "64",
74 "int32", "int64",
75)
76
77var fix8_32 = strings.NewReplacer(
78 "_8_32", "_32",
79 "byte", "int32",
80)
81
82func stripByteOnly(s string) string {
83 lines := strings.SplitAfter(s, "\n")
84 w := 0
85 for _, line := range lines {
86 if !strings.Contains(line, "256") && !strings.Contains(line, "byte-only") {
87 lines[w] = line
88 w++
89 }
90 }
91 return strings.Join(lines[:w], "")
92}