github.com/ie310mu/ie310go/forks/golang.org/x/sys@v0.0.0-20190821095322-9a46783d4de5/unix/mksysnum.go (about)

     1  // Copyright 2018 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  // +build ignore
     6  
     7  // Generate system call table for DragonFly, NetBSD,
     8  // FreeBSD, OpenBSD or Darwin from master list
     9  // (for example, /usr/src/sys/kern/syscalls.master or
    10  // sys/syscall.h).
    11  package main
    12  
    13  import (
    14  	"bufio"
    15  	"fmt"
    16  	"io"
    17  	"io/ioutil"
    18  	"net/http"
    19  	"os"
    20  	"regexp"
    21  	"strings"
    22  )
    23  
    24  var (
    25  	goos, goarch string
    26  )
    27  
    28  // cmdLine returns this programs's commandline arguments
    29  func cmdLine() string {
    30  	return "go run mksysnum.go " + strings.Join(os.Args[1:], " ")
    31  }
    32  
    33  // buildTags returns build tags
    34  func buildTags() string {
    35  	return fmt.Sprintf("%s,%s", goarch, goos)
    36  }
    37  
    38  func checkErr(err error) {
    39  	if err != nil {
    40  		fmt.Fprintf(os.Stderr, "%v\n", err)
    41  		os.Exit(1)
    42  	}
    43  }
    44  
    45  // source string and substring slice for regexp
    46  type re struct {
    47  	str string   // source string
    48  	sub []string // matched sub-string
    49  }
    50  
    51  // Match performs regular expression match
    52  func (r *re) Match(exp string) bool {
    53  	r.sub = regexp.MustCompile(exp).FindStringSubmatch(r.str)
    54  	if r.sub != nil {
    55  		return true
    56  	}
    57  	return false
    58  }
    59  
    60  // fetchFile fetches a text file from URL
    61  func fetchFile(URL string) io.Reader {
    62  	resp, err := http.Get(URL)
    63  	checkErr(err)
    64  	defer resp.Body.Close()
    65  	body, err := ioutil.ReadAll(resp.Body)
    66  	checkErr(err)
    67  	return strings.NewReader(string(body))
    68  }
    69  
    70  // readFile reads a text file from path
    71  func readFile(path string) io.Reader {
    72  	file, err := os.Open(os.Args[1])
    73  	checkErr(err)
    74  	return file
    75  }
    76  
    77  func format(name, num, proto string) string {
    78  	name = strings.ToUpper(name)
    79  	// There are multiple entries for enosys and nosys, so comment them out.
    80  	nm := re{str: name}
    81  	if nm.Match(`^SYS_E?NOSYS$`) {
    82  		name = fmt.Sprintf("// %s", name)
    83  	}
    84  	if name == `SYS_SYS_EXIT` {
    85  		name = `SYS_EXIT`
    86  	}
    87  	return fmt.Sprintf("	%s = %s;  // %s\n", name, num, proto)
    88  }
    89  
    90  func main() {
    91  	// Get the OS (using GOOS_TARGET if it exist)
    92  	goos = os.Getenv("GOOS_TARGET")
    93  	if goos == "" {
    94  		goos = os.Getenv("GOOS")
    95  	}
    96  	// Get the architecture (using GOARCH_TARGET if it exists)
    97  	goarch = os.Getenv("GOARCH_TARGET")
    98  	if goarch == "" {
    99  		goarch = os.Getenv("GOARCH")
   100  	}
   101  	// Check if GOOS and GOARCH environment variables are defined
   102  	if goarch == "" || goos == "" {
   103  		fmt.Fprintf(os.Stderr, "GOARCH or GOOS not defined in environment\n")
   104  		os.Exit(1)
   105  	}
   106  
   107  	file := strings.TrimSpace(os.Args[1])
   108  	var syscalls io.Reader
   109  	if strings.HasPrefix(file, "https://") || strings.HasPrefix(file, "http://") {
   110  		// Download syscalls.master file
   111  		syscalls = fetchFile(file)
   112  	} else {
   113  		syscalls = readFile(file)
   114  	}
   115  
   116  	var text, line string
   117  	s := bufio.NewScanner(syscalls)
   118  	for s.Scan() {
   119  		t := re{str: line}
   120  		if t.Match(`^(.*)\\$`) {
   121  			// Handle continuation
   122  			line = t.sub[1]
   123  			line += strings.TrimLeft(s.Text(), " \t")
   124  		} else {
   125  			// New line
   126  			line = s.Text()
   127  		}
   128  		t = re{str: line}
   129  		if t.Match(`\\$`) {
   130  			continue
   131  		}
   132  		t = re{str: line}
   133  
   134  		switch goos {
   135  		case "dragonfly":
   136  			if t.Match(`^([0-9]+)\s+STD\s+({ \S+\s+(\w+).*)$`) {
   137  				num, proto := t.sub[1], t.sub[2]
   138  				name := fmt.Sprintf("SYS_%s", t.sub[3])
   139  				text += format(name, num, proto)
   140  			}
   141  		case "freebsd":
   142  			if t.Match(`^([0-9]+)\s+\S+\s+(?:NO)?STD\s+({ \S+\s+(\w+).*)$`) {
   143  				num, proto := t.sub[1], t.sub[2]
   144  				name := fmt.Sprintf("SYS_%s", t.sub[3])
   145  				text += format(name, num, proto)
   146  			}
   147  		case "openbsd":
   148  			if t.Match(`^([0-9]+)\s+STD\s+(NOLOCK\s+)?({ \S+\s+\*?(\w+).*)$`) {
   149  				num, proto, name := t.sub[1], t.sub[3], t.sub[4]
   150  				text += format(name, num, proto)
   151  			}
   152  		case "netbsd":
   153  			if t.Match(`^([0-9]+)\s+((STD)|(NOERR))\s+(RUMP\s+)?({\s+\S+\s*\*?\s*\|(\S+)\|(\S*)\|(\w+).*\s+})(\s+(\S+))?$`) {
   154  				num, proto, compat := t.sub[1], t.sub[6], t.sub[8]
   155  				name := t.sub[7] + "_" + t.sub[9]
   156  				if t.sub[11] != "" {
   157  					name = t.sub[7] + "_" + t.sub[11]
   158  				}
   159  				name = strings.ToUpper(name)
   160  				if compat == "" || compat == "13" || compat == "30" || compat == "50" {
   161  					text += fmt.Sprintf("	%s = %s;  // %s\n", name, num, proto)
   162  				}
   163  			}
   164  		case "darwin":
   165  			if t.Match(`^#define\s+SYS_(\w+)\s+([0-9]+)`) {
   166  				name, num := t.sub[1], t.sub[2]
   167  				name = strings.ToUpper(name)
   168  				text += fmt.Sprintf("	SYS_%s = %s;\n", name, num)
   169  			}
   170  		default:
   171  			fmt.Fprintf(os.Stderr, "unrecognized GOOS=%s\n", goos)
   172  			os.Exit(1)
   173  
   174  		}
   175  	}
   176  	err := s.Err()
   177  	checkErr(err)
   178  
   179  	fmt.Printf(template, cmdLine(), buildTags(), text)
   180  }
   181  
   182  const template = `// %s
   183  // Code generated by the command above; see README.md. DO NOT EDIT.
   184  
   185  // +build %s
   186  
   187  package unix
   188  
   189  const(
   190  %s)`