OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [syscall/] [mksyscall.awk] - Blame information for rev 867

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
# Copyright 2011 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
# This AWK script reads a Go file with comments describing syscall
6
# functions and the C routines they map to.  It generates the Go code
7
# which calls the C routines.
8
 
9
# The syscall functins are marked by lines beginning with "//sys" and
10
# read like func declarations if //sys is replaced by func, but:
11
#       * The parameter lists must give a name for each argument.
12
#         This includes return parameters.
13
#       * The parameter lists must give a type for each argument:
14
#          the (x, y, z int) shorthand is not allowed.
15
#       * If the return parameter is an error, it must be named err.
16
 
17
# A line beginning with //sysnb is like //sys, except that the
18
# goroutine will not be suspended during the execution of the library
19
# call.  This must only be used for library calls which can never
20
# block, as otherwise the library call could cause all goroutines to
21
# hang.
22
 
23
# After the //sys or //sysnb line comes a second line which describes
24
# the C function.  The name must be the name of the function in the C
25
# library, and may be the same as the Go function.  The limitations on
26
# the argument list are the same as for the //sys line, but there must
27
# be at most one result parameter, and it must be given as just a
28
# type, without a name.
29
 
30
BEGIN {
31
    print "// This file was automatically generated by mksyscall.awk"
32
    print ""
33
    print "package syscall"
34
    print ""
35
    print "import \"unsafe\""
36
    print ""
37
    status = 0
38
}
39
 
40
/^\/\/sys/ {
41
    if ($1 == "//sysnb") {
42
        blocking = 0
43
    } else {
44
        blocking = 1
45
    }
46
 
47
    line = $0
48
 
49
    if (match(line, "//sys(nb)?[        ]*[a-zA-Z0-9_]+\\([^()]*\\) *(\\(([^()]+)\\))?") == 0) {
50
        print "unmatched line:", $0 | "cat 1>&2"
51
        status = 1
52
        next
53
    }
54
 
55
    # Sets a[1] = //sysnb, a[2] == function name.
56
    split(line, a, "[   (]*")
57
    gofnname = a[2]
58
 
59
    off = match(line, "\\([^()]*\\)")
60
    end = index(substr(line, off, length(line) - off + 1), ")")
61
    gofnparams = substr(line, off + 1, end - 2)
62
 
63
    line = substr(line, off + end, length(line) - (off + end) + 1)
64
    off = match(line, "\\([^()]*\\)")
65
    if (off == 0) {
66
        gofnresults = ""
67
    } else {
68
        end = index(substr(line, off, length(line) - off + 1), ")")
69
        gofnresults = substr(line, off + 1, end - 2)
70
    }
71
 
72
    getline
73
    line = $0
74
 
75
    if (match(line, "//[a-zA-Z0-9_]+\\([^()]*\\)") == 0) {
76
        print "unmatched C line", $0, "after", gofnname | "cat 1>&2"
77
        status = 1
78
        next
79
    }
80
 
81
    split(line, a, "[   (]*")
82
    cfnname = substr(a[1], 3, length(a[1]) - 2)
83
 
84
    off = match(line, "\\([^()]*\\)")
85
    end = index(substr(line, off, length(line) - off + 1), ")")
86
    cfnparams = substr(line, off + 1, end - 2)
87
 
88
    line = substr(line, off + end + 1, length(line) - (off + end) + 1)
89
    while (substr(line, 1, 1) == " ") {
90
        line = substr(line, 2, length(line) - 1)
91
    }
92
    end = index(line, " ")
93
    if (end != 0) {
94
        line = substr(line, 1, end)
95
    }
96
    cfnresult = line
97
 
98
    printf("// Automatically generated wrapper for %s/%s\n", gofnname, cfnname)
99
    printf("//extern %s\n", cfnname)
100
    printf("func c_%s(%s) %s\n", cfnname, cfnparams, cfnresult)
101
    printf("func %s(%s) %s%s%s%s{\n",
102
           gofnname, gofnparams, gofnresults == "" ? "" : "(", gofnresults,
103
           gofnresults == "" ? "" : ")", gofnresults == "" ? "" : " ")
104
 
105
    loc = gofnname "/" cfnname ":"
106
 
107
    split(gofnparams, goargs, ", *")
108
    split(cfnparams, cargs, ", *")
109
    args = ""
110
    carg = 1
111
    for (goarg = 1; goargs[goarg] != ""; goarg++) {
112
        if (cargs[carg] == "") {
113
            print loc, "not enough C parameters"
114
        }
115
 
116
        if (args != "") {
117
            args = args ", "
118
        }
119
 
120
        if (split(goargs[goarg], a) != 2) {
121
            print loc, "bad parameter:", goargs[goarg] | "cat 1>&2"
122
            status = 1
123
            next
124
        }
125
 
126
        goname = a[1]
127
        gotype = a[2]
128
 
129
        if (split(cargs[carg], a) != 2) {
130
            print loc, "bad C parameter:", cargs[carg] | "cat 1>&2"
131
            status = 1
132
            next
133
        }
134
 
135
        ctype = a[2]
136
 
137
        if (gotype ~ /^\*/) {
138
            if (gotype != ctype) {
139
                print loc, "Go/C pointer type mismatch:", gotype, ctype | "cat 1>&2"
140
                status = 1
141
                next
142
            }
143
            args = args goname
144
        } else if (gotype == "string") {
145
            if (ctype != "*byte") {
146
                print loc, "Go string not matched to C *byte:", gotype, ctype | "cat 1>&2"
147
                status = 1
148
                next
149
            }
150
            printf("\t_p%d := StringBytePtr(%s)\n", goarg, goname)
151
            args = sprintf("%s_p%d", args, goarg)
152
        } else if (gotype ~ /^\[\](.*)/) {
153
            if (ctype !~ /^\*/ || cargs[carg + 1] == "") {
154
                print loc, "bad C type for slice:", gotype, ctype | "cat 1>&2"
155
                status = 1
156
                next
157
            }
158
 
159
            # Convert a slice into a pair of pointer, length.
160
            # Don't try to take the address of the zeroth element of a
161
            # nil slice.
162
            printf("\tvar _p%d %s\n", goarg, ctype)
163
            printf("\tif len(%s) > 0 {\n", goname)
164
            printf("\t\t_p%d = (%s)(unsafe.Pointer(&%s[0]))\n", goarg, ctype, goname)
165
            printf("\t} else {\n")
166
            printf("\t\t_p%d = (%s)(unsafe.Pointer(&_zero))\n", goarg, ctype)
167
            printf("\t}\n")
168
 
169
            ++carg
170
            if (split(cargs[carg], cparam) != 2) {
171
                print loc, "bad C parameter:", cargs[carg] | "cat 1>&2"
172
                status = 1
173
                next
174
            }
175
 
176
            args = sprintf("%s_p%d, %s(len(%s))", args, goarg, cparam[2], goname)
177
        } else if (gotype == "uintptr" && ctype ~ /^\*/) {
178
            args = sprintf("%s(%s)(unsafe.Pointer(%s))", args, ctype, goname)
179
        } else {
180
            args = sprintf("%s%s(%s)", args, ctype, goname)
181
        }
182
 
183
        carg++
184
    }
185
 
186
    if (cargs[carg] != "") {
187
        print loc, "too many C parameters" | "cat 1>&2"
188
        status = 1
189
        next
190
    }
191
 
192
    if (blocking) {
193
        print "\tentersyscall()"
194
    }
195
 
196
    printf("\t")
197
    if (gofnresults != "") {
198
        printf("_r := ")
199
    }
200
    printf("c_%s(%s)\n", cfnname, args)
201
 
202
    if (gofnresults != "") {
203
        fields = split(gofnresults, goresults, ", *")
204
        if (fields > 2) {
205
            print loc, "too many Go results" | "cat 1>&2"
206
            status = 1
207
            next
208
        }
209
        usedr = 0
210
        for (goresult = 1; goresults[goresult] != ""; goresult++) {
211
            if (split(goresults[goresult], goparam) != 2) {
212
                print loc, "bad result:", goresults[goresult] | "cat 1>&2"
213
                status = 1
214
                next
215
            }
216
 
217
            goname = goparam[1]
218
            gotype = goparam[2]
219
 
220
            if (goname == "err") {
221
                if (cfnresult ~ /^\*/) {
222
                    print "\tif _r == nil {"
223
                } else {
224
                    print "\tif _r < 0 {"
225
                }
226
                print "\t\terr = GetErrno()"
227
                print "\t}"
228
            } else if (gotype == "uintptr" && cfnresult ~ /^\*/) {
229
                printf("\t%s = (%s)(unsafe.Pointer(_r))\n", goname, gotype)
230
            } else {
231
                if (usedr) {
232
                    print loc, "two parameters but no errno parameter" | "cat 1>&2"
233
                    status = 1
234
                    next
235
                }
236
                printf("\t%s = (%s)(_r)\n", goname, gotype)
237
                usedr = 1
238
            }
239
        }
240
    }
241
 
242
    if (blocking) {
243
        print "\texitsyscall()"
244
    }
245
 
246
    if (gofnresults != "") {
247
        print "\treturn"
248
    }
249
 
250
    print "}"
251
 
252
    print ""
253
 
254
    next
255
}
256
 
257
{ next }
258
 
259
END {
260
    if (status != 0) {
261
        print "*** mksyscall.awk failed" | "cat 1>&2"
262
        exit status
263
    }
264
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.