From 9a0d5dbcffd6d34aeedaad9a52282160225d8605 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Fri, 4 Dec 2020 12:26:48 +0100 Subject: [PATCH] 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 Trust: Alex Brainman Run-TryBot: Jason A. Donenfeld TryBot-Result: Go Bot Reviewed-by: Alex Brainman --- windows/mkwinsyscall/mkwinsyscall.go | 33 +++++++++++++++++++++------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/windows/mkwinsyscall/mkwinsyscall.go b/windows/mkwinsyscall/mkwinsyscall.go index 0f2f645e..22f844e8 100644 --- a/windows/mkwinsyscall/mkwinsyscall.go +++ b/windows/mkwinsyscall/mkwinsyscall.go @@ -239,10 +239,11 @@ func join(ps []*Param, fn func(*Param) string, sep string) string { // Rets describes function return parameters. type Rets struct { - Name string - Type string - ReturnsError bool - FailCond string + Name string + Type string + ReturnsError bool + FailCond string + fnMaybeAbsent bool } // 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 }, ", ") if len(s) > 0 { s = "(" + s + ")" + } else if r.fnMaybeAbsent { + s = "(err error)" } return s } @@ -345,7 +348,6 @@ type Fn struct { Params []*Param Rets *Rets PrintTrace bool - MaybeAbsent bool dllname string dllfuncname string src string @@ -475,7 +477,7 @@ func newFn(s string) (*Fn, error) { } if n := f.dllfuncname; strings.HasSuffix(n, "?") { f.dllfuncname = n[:len(n)-1] - f.MaybeAbsent = true + f.Rets.fnMaybeAbsent = true } return f, nil } @@ -575,6 +577,22 @@ func (f *Fn) HelperCallParamList() string { 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 // for all A (ascii) functions. func (f *Fn) IsUTF16() bool { @@ -915,8 +933,7 @@ func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{ {{define "helpertmpvars"}}{{range .Params}}{{if .TmpVarHelperCode}} {{.TmpVarHelperCode}} {{end}}{{end}}{{end}} -{{define "maybeabsent"}}{{if .MaybeAbsent}}err = proc{{.DLLFuncName}}.Find() -if err != nil { return } +{{define "maybeabsent"}}{{if .MaybeAbsent}}{{.MaybeAbsent}} {{end}}{{end}} {{define "tmpvars"}}{{range .Params}}{{if .TmpVarCode}} {{.TmpVarCode}}