From e9f28cafb8082d8185d4458a650dd74243fdb30d Mon Sep 17 00:00:00 2001 From: Michael McLoughlin Date: Sun, 11 Apr 2021 13:25:13 -0700 Subject: [PATCH] attr: flag test methods (#177) Adds a method to the Attribute type to test for each flag in the textflag.h header. --- attr/attr_test.go | 31 +++++++++++++++++++++++++++++++ attr/make_textflag.go | 6 ++++++ attr/ztextflag.go | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/attr/attr_test.go b/attr/attr_test.go index caeded9..13121b3 100644 --- a/attr/attr_test.go +++ b/attr/attr_test.go @@ -42,3 +42,34 @@ func TestAttributeContainsTextFlags(t *testing.T) { } } } + +func TestAttributeTestMethods(t *testing.T) { + cases := []struct { + Attribute Attribute + Predicate func(Attribute) bool + Expect bool + }{ + // Confirm logic works as expected. + {DUPOK | NOSPLIT, Attribute.DUPOK, true}, + {DUPOK | NOSPLIT, Attribute.NOSPLIT, true}, + {DUPOK | NOSPLIT, Attribute.NOFRAME, false}, + + // Basic test for every method. + {NOPROF, Attribute.NOPROF, true}, + {DUPOK, Attribute.DUPOK, true}, + {NOSPLIT, Attribute.NOSPLIT, true}, + {RODATA, Attribute.RODATA, true}, + {NOPTR, Attribute.NOPTR, true}, + {WRAPPER, Attribute.WRAPPER, true}, + {NEEDCTXT, Attribute.NEEDCTXT, true}, + {TLSBSS, Attribute.TLSBSS, true}, + {NOFRAME, Attribute.NOFRAME, true}, + {REFLECTMETHOD, Attribute.REFLECTMETHOD, true}, + {TOPFRAME, Attribute.TOPFRAME, true}, + } + for _, c := range cases { + if c.Predicate(c.Attribute) != c.Expect { + t.Errorf("%s: expected %#v", c.Attribute.Asm(), c.Expect) + } + } +} diff --git a/attr/make_textflag.go b/attr/make_textflag.go index 83d7220..88f1d77 100644 --- a/attr/make_textflag.go +++ b/attr/make_textflag.go @@ -197,4 +197,10 @@ func PrintFlagAttributes(w io.Writer, fs []Flag) { fmt.Fprintf(w, "\t%s: %q,\n", f.Name, f.Name) } fmt.Fprintf(w, "}\n") + + // Flag test methods. + for _, f := range fs { + fmt.Fprintf(w, "\n// %s reports whether the %s flag is set.\n", f.Name, f.Name) + fmt.Fprintf(w, "func (a Attribute) %s() bool { return (a & %s) != 0 }\n", f.Name, f.Name) + } } diff --git a/attr/ztextflag.go b/attr/ztextflag.go index 9330a19..4c7163a 100644 --- a/attr/ztextflag.go +++ b/attr/ztextflag.go @@ -55,3 +55,36 @@ var attrname = map[Attribute]string{ REFLECTMETHOD: "REFLECTMETHOD", TOPFRAME: "TOPFRAME", } + +// NOPROF reports whether the NOPROF flag is set. +func (a Attribute) NOPROF() bool { return (a & NOPROF) != 0 } + +// DUPOK reports whether the DUPOK flag is set. +func (a Attribute) DUPOK() bool { return (a & DUPOK) != 0 } + +// NOSPLIT reports whether the NOSPLIT flag is set. +func (a Attribute) NOSPLIT() bool { return (a & NOSPLIT) != 0 } + +// RODATA reports whether the RODATA flag is set. +func (a Attribute) RODATA() bool { return (a & RODATA) != 0 } + +// NOPTR reports whether the NOPTR flag is set. +func (a Attribute) NOPTR() bool { return (a & NOPTR) != 0 } + +// WRAPPER reports whether the WRAPPER flag is set. +func (a Attribute) WRAPPER() bool { return (a & WRAPPER) != 0 } + +// NEEDCTXT reports whether the NEEDCTXT flag is set. +func (a Attribute) NEEDCTXT() bool { return (a & NEEDCTXT) != 0 } + +// TLSBSS reports whether the TLSBSS flag is set. +func (a Attribute) TLSBSS() bool { return (a & TLSBSS) != 0 } + +// NOFRAME reports whether the NOFRAME flag is set. +func (a Attribute) NOFRAME() bool { return (a & NOFRAME) != 0 } + +// REFLECTMETHOD reports whether the REFLECTMETHOD flag is set. +func (a Attribute) REFLECTMETHOD() bool { return (a & REFLECTMETHOD) != 0 } + +// TOPFRAME reports whether the TOPFRAME flag is set. +func (a Attribute) TOPFRAME() bool { return (a & TOPFRAME) != 0 }