Source file src/cmd/internal/obj/mkcnames.go

     1  // Copyright 2024 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  // This is based on the implementation of src/cmd/internal/obj/stringer.go.
     8  // This is a mini version of the stringer tool customized for the Cnames
     9  // table in the architecture support for obj.
    10  
    11  package main
    12  
    13  import (
    14  	"bufio"
    15  	"flag"
    16  	"fmt"
    17  	"log"
    18  	"os"
    19  	"regexp"
    20  	"strings"
    21  )
    22  
    23  var (
    24  	input  = flag.String("i", "", "input file name")
    25  	output = flag.String("o", "", "output file name")
    26  	pkg    = flag.String("p", "", "package name")
    27  )
    28  
    29  var cnameExp = regexp.MustCompile(`^\tC_([A-Za-z0-9_]+)`)
    30  
    31  func main() {
    32  	flag.Parse()
    33  	if *input == "" || *output == "" || *pkg == "" {
    34  		flag.Usage()
    35  		os.Exit(2)
    36  	}
    37  
    38  	start := ""
    39  	switch *pkg {
    40  	case "arm64":
    41  		start = "var cnames7 = []string{\n\t\"\", // C_NONE starts from 1\n"
    42  	case "loong64", "mips":
    43  		start = "var cnames0 = []string{\n"
    44  	case "ppc64":
    45  		start = "var cnames9 = []string{\n"
    46  	case "s390x":
    47  		start = "var cnamesz = []string{\n"
    48  	default:
    49  		fmt.Printf("Only supports generating Cnames for arm64,loong64,mips,ppc64,s390x.")
    50  		os.Exit(0)
    51  	}
    52  
    53  	in, err := os.Open(*input)
    54  	if err != nil {
    55  		log.Fatal(err)
    56  	}
    57  	fd, err := os.Create(*output)
    58  	if err != nil {
    59  		log.Fatal(err)
    60  	}
    61  	out := bufio.NewWriter(fd)
    62  	closeOut := func() {
    63  		if err = out.Flush(); err != nil {
    64  			log.Fatal(err)
    65  		}
    66  
    67  		if err = fd.Close(); err != nil {
    68  			log.Fatal(err)
    69  		}
    70  	}
    71  	defer closeOut()
    72  
    73  	on := false
    74  	s := bufio.NewScanner(in)
    75  	for s.Scan() {
    76  		line := s.Text()
    77  		if !on {
    78  			// First relevant line contains "C_NONE = iota".
    79  			// If we find it, delete the "=" so we don't stop immediately.
    80  			const first = "C_NONE"
    81  			if !strings.Contains(line, first) {
    82  				continue
    83  			}
    84  
    85  			const suffix = "= iota"
    86  			index := strings.Index(line, suffix)
    87  			if index < 0 {
    88  				continue
    89  			}
    90  			line = line[:index]
    91  
    92  			// It's on. Start with the header.
    93  			fmt.Fprintf(out, header, *input, *output, *pkg, *pkg)
    94  			fmt.Fprintf(out, start)
    95  			on = true
    96  		}
    97  
    98  		// Strip comments so their text won't defeat our heuristic.
    99  		index := strings.Index(line, "//")
   100  		if index > 0 {
   101  			line = line[:index]
   102  		}
   103  		index = strings.Index(line, "/*")
   104  		if index > 0 {
   105  			comments := line[index:]
   106  			if !strings.Contains(comments, "*/") {
   107  				log.Fatalf("invalid comment: %s\n", comments)
   108  			}
   109  			line = line[:index]
   110  		}
   111  
   112  		// Termination condition: Any line with an = changes the sequence,
   113  		// so stop there, and stop at a closing brace.
   114  		if strings.HasPrefix(line, "}") || strings.ContainsRune(line, '=') {
   115  			break
   116  		}
   117  
   118  		sub := cnameExp.FindStringSubmatch(line)
   119  		if len(sub) < 2 {
   120  			continue
   121  		} else {
   122  			fmt.Fprintf(out, "\t%q,\n", sub[1])
   123  		}
   124  	}
   125  	fmt.Fprintln(out, "}")
   126  	if s.Err() != nil {
   127  		log.Fatal(err)
   128  	}
   129  }
   130  
   131  const header = `// Code generated by mkcnames -i %s -o %s -p %s; DO NOT EDIT.
   132  
   133  package %s
   134  
   135  // This order should be strictly consistent to that in a.out.go.
   136  `
   137  

View as plain text