windows/mkwinsyscall: account for non-"err" return values when processing "?"

The "?" code assumed that the error value was always called "err", when
in reality it might be called something different (like "ret") or even
entirely absent. This commit makes the templating robust to that. At the
same time, we move a lot of the complexity out of the actual templates
and into helper functions, so that this remains easy to read.

Change-Id: I939d56413a24f0e3e1bbf13da5adf13e9401747a
Reviewed-on: https://go-review.googlesource.com/c/sys/+/275472
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Trust: Alex Brainman <alex.brainman@gmail.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
This commit is contained in:
Jason A. Donenfeld
2020-12-04 22:54:03 +00:00
parent 69691e4674
commit 9a0d5dbcff
+25 -8
View File
@@ -239,10 +239,11 @@ func join(ps []*Param, fn func(*Param) string, sep string) string {
// Rets describes function return parameters. // Rets describes function return parameters.
type Rets struct { type Rets struct {
Name string Name string
Type string Type string
ReturnsError bool ReturnsError bool
FailCond string FailCond string
fnMaybeAbsent bool
} }
// ErrorVarName returns error variable name for r. // ErrorVarName returns error variable name for r.
@@ -273,6 +274,8 @@ func (r *Rets) List() string {
s := join(r.ToParams(), func(p *Param) string { return p.Name + " " + p.Type }, ", ") s := join(r.ToParams(), func(p *Param) string { return p.Name + " " + p.Type }, ", ")
if len(s) > 0 { if len(s) > 0 {
s = "(" + s + ")" s = "(" + s + ")"
} else if r.fnMaybeAbsent {
s = "(err error)"
} }
return s return s
} }
@@ -345,7 +348,6 @@ type Fn struct {
Params []*Param Params []*Param
Rets *Rets Rets *Rets
PrintTrace bool PrintTrace bool
MaybeAbsent bool
dllname string dllname string
dllfuncname string dllfuncname string
src string src string
@@ -475,7 +477,7 @@ func newFn(s string) (*Fn, error) {
} }
if n := f.dllfuncname; strings.HasSuffix(n, "?") { if n := f.dllfuncname; strings.HasSuffix(n, "?") {
f.dllfuncname = n[:len(n)-1] f.dllfuncname = n[:len(n)-1]
f.MaybeAbsent = true f.Rets.fnMaybeAbsent = true
} }
return f, nil return f, nil
} }
@@ -575,6 +577,22 @@ func (f *Fn) HelperCallParamList() string {
return strings.Join(a, ", ") return strings.Join(a, ", ")
} }
// MaybeAbsent returns source code for handling functions that are possibly unavailable.
func (p *Fn) MaybeAbsent() string {
if !p.Rets.fnMaybeAbsent {
return ""
}
const code = `%[1]s = proc%[2]s.Find()
if %[1]s != nil {
return
}`
errorVar := p.Rets.ErrorVarName()
if errorVar == "" {
errorVar = "err"
}
return fmt.Sprintf(code, errorVar, p.DLLFuncName())
}
// IsUTF16 is true, if f is W (utf16) function. It is false // IsUTF16 is true, if f is W (utf16) function. It is false
// for all A (ascii) functions. // for all A (ascii) functions.
func (f *Fn) IsUTF16() bool { func (f *Fn) IsUTF16() bool {
@@ -915,8 +933,7 @@ func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{
{{define "helpertmpvars"}}{{range .Params}}{{if .TmpVarHelperCode}} {{.TmpVarHelperCode}} {{define "helpertmpvars"}}{{range .Params}}{{if .TmpVarHelperCode}} {{.TmpVarHelperCode}}
{{end}}{{end}}{{end}} {{end}}{{end}}{{end}}
{{define "maybeabsent"}}{{if .MaybeAbsent}}err = proc{{.DLLFuncName}}.Find() {{define "maybeabsent"}}{{if .MaybeAbsent}}{{.MaybeAbsent}}
if err != nil { return }
{{end}}{{end}} {{end}}{{end}}
{{define "tmpvars"}}{{range .Params}}{{if .TmpVarCode}} {{.TmpVarCode}} {{define "tmpvars"}}{{range .Params}}{{if .TmpVarCode}} {{.TmpVarCode}}