gen.mx raw

   1  // 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  
   5  //go:build ignore
   6  
   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.
  10  package main
  11  
  12  import (
  13  	"bytes"
  14  	"log"
  15  	"os"
  16  )
  17  
  18  func main() {
  19  	log.SetPrefix("gen: ")
  20  	log.SetFlags(0)
  21  
  22  	data, err := os.ReadFile("sais.go")
  23  	if err != nil {
  24  		log.Fatal(err)
  25  	}
  26  
  27  	x := bytes.Index(data, []byte("\n\n"))
  28  	if x < 0 {
  29  		log.Fatal("cannot find blank line after copyright comment")
  30  	}
  31  
  32  	var buf bytes.Buffer
  33  	buf.Write(data[:x])
  34  	buf.WriteString("\n\n// Code generated by go generate; DO NOT EDIT.\n\npackage suffixarray\n")
  35  
  36  	for {
  37  		x := bytes.Index(data, []byte("\nfunc "))
  38  		if x < 0 {
  39  			break
  40  		}
  41  		data = data[x:]
  42  		p := bytes.IndexByte(data, '(')
  43  		if p < 0 {
  44  			p = len(data)
  45  		}
  46  		name := []byte(data[len("\nfunc "):p])
  47  
  48  		x = bytes.Index(data, []byte("\n}\n"))
  49  		if x < 0 {
  50  			log.Fatalf("cannot find end of func %s", name)
  51  		}
  52  		fn := []byte(data[:x+len("\n}\n")])
  53  		data = data[x+len("\n}"):]
  54  
  55  		if bytes.HasSuffix(name, "_32") {
  56  			buf.WriteString(fix32.Replace(fn))
  57  		}
  58  		if bytes.HasSuffix(name, "_8_32") {
  59  			// x_8_32 -> x_8_64 done above
  60  			fn = fix8_32.Replace(stripByteOnly(fn))
  61  			buf.WriteString(fn)
  62  			buf.WriteString(fix32.Replace(fn))
  63  		}
  64  	}
  65  
  66  	if err := os.WriteFile("sais2.go", buf.Bytes(), 0666); err != nil {
  67  		log.Fatal(err)
  68  	}
  69  }
  70  
  71  var fix32 = bytes.NewReplacer(
  72  	"32", "64",
  73  	"int32", "int64",
  74  )
  75  
  76  var fix8_32 = bytes.NewReplacer(
  77  	"_8_32", "_32",
  78  	"byte", "int32",
  79  )
  80  
  81  func stripByteOnly(s []byte) []byte {
  82  	lines := bytes.SplitAfter(s, "\n")
  83  	w := 0
  84  	for _, line := range lines {
  85  		if !bytes.Contains(line, "256") && !bytes.Contains(line, "byte-only") {
  86  			lines[w] = line
  87  			w++
  88  		}
  89  	}
  90  	return bytes.Join(lines[:w], "")
  91  }
  92