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