1-- 2-- SPDX-License-Identifier: BSD-2-Clause 3-- 4-- Copyright (c) 2024 Tyler Baxter <agge@FreeBSD.org> 5-- Copyright (c) 2023 Warner Losh <imp@bsdimp.com> 6-- Copyright (c) 2019 Kyle Evans <kevans@FreeBSD.org> 7-- 8 9local util = {} 10 11-- 12-- Returns a trimmed string. Default is to trim whitespace. 13-- 14-- PARAM: String s, the string to trim. 15-- 16-- PARAM: char, nil or optional character to trim. 17-- 18function util.trim(s, char) 19 if s == nil then 20 return nil 21 end 22 if char == nil then 23 char = "%s" 24 end 25 return s:gsub("^" .. char .. "+", ""):gsub(char .. "+$", "") 26end 27 28-- Returns a table (list) of strings. 29function util.split(s, re) 30 local t = { } 31 32 for v in s:gmatch(re) do 33 table.insert(t, v) 34 end 35 return t 36end 37 38-- Aborts with a message and does a clean exit procedure. 39function util.abort(status, msg) 40 assert(io.stderr:write(msg .. "\n")) 41 -- cleanup 42 os.exit(status) 43end 44 45-- 46-- Returns a set. 47-- 48-- PARAM: t, a list. 49-- 50-- EXAMPLE: param: {"foo", "bar"}, return: {foo = true, bar = true} 51-- 52function util.set(t) 53 local s = { } 54 55 for _,v in pairs(t) do 56 s[v] = true 57 end 58 return s 59end 60 61-- 62-- Returns a set. 63-- 64-- PARAM: str, a string. 65-- PARAM: re, the pattern to construct keys from. 66-- 67function util.setFromString(str, re) 68 local s = { } 69 70 for v in str:gmatch(re) do 71 s[v] = true 72 end 73 return s 74end 75 76function util.isEmpty(tbl) 77 if tbl ~= nil then 78 if next(tbl) == nil then 79 return true 80 end 81 return false 82 end 83 return true 84end 85 86-- 87-- Iterator that traverses a table following the order of its keys. 88-- An optional parameter f allows the specification of an alternative order. 89-- 90-- CREDIT: https://www.lua.org/pil/19.3.html 91-- LICENSE: MIT 92-- 93function util.pairsByKeys(t, f) 94 local a = {} 95 for n in pairs(t) do table.insert(a, n) end 96 table.sort(a, f) 97 local i = 0 -- iterator variable 98 local iter = function () -- iterator function 99 i = i + 1 100 if a[i] == nil then 101 return nil 102 else 103 return a[i], t[a[i]] 104 end 105 end 106 return iter 107end 108 109-- 110-- Checks for pointer types: '*', caddr_t, or intptr_t. 111-- 112-- PARAM: type, the type to check. 113-- 114-- PARAM: abi, nil or optional ABI-specified intptr_t. 115-- 116function util.isPtrType(type, abi) 117 local default = abi or "intptr_t" 118 return type:find("*") or type:find("caddr_t") or type:find(default) 119end 120 121function util.isPtrArrayType(type) 122 return type:find("[*][*]") or type:find("[*][ ]*const[ ]*[*]") 123end 124 125-- Find types that are always 64-bits wide. 126function util.is64bitType(type) 127 return type:find("^dev_t[ ]*$") or type:find("^id_t[ ]*$") or 128 type:find("^off_t[ ]*$") 129end 130 131-- 132-- Returns the name of the struct pointed to by the argument or nil. 133-- 134-- PARAM: type, the type to check. 135-- 136function util.structName(type) 137 if util.isPtrType(type) then 138 local is_struct = false 139 for word in type:gmatch("[^ *]+") do 140 if is_struct then 141 return word 142 end 143 if word == "struct" then 144 -- next word is the struct name 145 is_struct = true 146 end 147 end 148 end 149 return nil 150end 151 152-- Strip the ABI function prefix if it exists (e.g., "freebsd32_"). Returns the 153-- function name with the ABI prefix stripped, or the original function name if 154-- there was no ABI function prefix. 155function util.stripAbiPrefix(funcname, abiprefix) 156 local stripped_name 157 if funcname == nil then 158 return nil 159 end 160 if abiprefix ~= "" and funcname:find("^" .. abiprefix) then 161 stripped_name = funcname:gsub("^" .. abiprefix, "") 162 else 163 stripped_name = funcname 164 end 165 166 return stripped_name 167end 168 169-- ipairs for a sparse array. 170-- CREDIT: Lua Game Development Cookbook, Mario Kasuba 171function util.ipairsSparse(t) 172 -- tmp_index will hold sorted indices, otherwise 173 -- this iterator would be no different from pairs iterator 174 local tmp_index = {} 175 local index, _ = next(t) 176 while index do 177 tmp_index[#tmp_index + 1] = index 178 index, _ = next(t, index) 179 end 180 -- sort table indices 181 table.sort(tmp_index) 182 local j = 1 183 184 return function() 185 -- get index value 186 local i = tmp_index[j] 187 j = j + 1 188 if i then 189 return i, t[i] 190 end 191 end 192end 193 194return util 195