hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 577fafa83ce9f075efcf5c7ee53a162b9ca30d85
parent 147f3d5c907a04d6091d0a216ebf27d6d0e0299b
Author: Alexey Yerin <yyp@disroot.org>
Date:   Thu, 14 Oct 2021 23:19:32 +0300

types: strflag: special case 0 value to not match on anything

This would cause things like this to work incorrectly:

    type permissions = enum u8 {
    	NONE  = 0,
    	READ  = 1 << 0,
    	WRITE = 1 << 1,
    };

    const perm = permissions::READ;
    strflag(type(permissions), &perm) // => NONE|READ

Signed-off-by: Alexey Yerin <yyp@disroot.org>

Diffstat:
Mtypes/util.ha | 27++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/types/util.ha b/types/util.ha @@ -44,8 +44,7 @@ export fn strenum(ty: type, val: *void) str = { // TODO: should we have a static version of that? // Returns the names of enabled flags of a bitfield enum at "val" formatted as -// '|' operation, or "0" when the value doesn't match any flags. The string -// must be freed by the caller. +// '|' operation. The string must be freed by the caller. export fn strflag(ty: type, val: *void) str = { const ty = unwrap(ty); const en = ty.repr as enumerated; @@ -78,19 +77,33 @@ export fn strflag(ty: type, val: *void) str = { }; let buf: []u8 = alloc([]); + let zeroname = ""; + + let pipe = false; for (let i = 0z; i < len(en.values); i += 1) { - if (en.values[i].1.u & value != 0) { - if (i > 0) { + const val = en.values[i]; + if (val.1.u == 0) { + zeroname = val.0; + continue; + }; + if (val.1.u & value != 0) { + if (pipe) { append(buf, '|': u8); }; - const name = en.values[i].0; - append(buf, *(&name: *[]u8)...); + append(buf, *(&val.0: *[]u8)...); + pipe = true; + } else { + pipe = false; }; }; + if (value == 0) { + append(buf, *(&zeroname: *[]u8)...); + }; + if (len(buf) == 0) { - append(buf, '0': u8); + abort("Enum has invalid value"); }; return *(&buf: *str);