Remove BPA from Makefile
[icn.git] / cmd / bpa-operator / vendor / golang.org / x / sys / 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, 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)`