1do 2 local ffi = require("ffi") 3 local ptrtype = ffi.typeof("uint64_t") 4 local strformat = string.format 5 function string.format(format, ...) 6 local args = {...} 7 local match_no = 1 8 local newfmt, count = string.gsub(format, "()%%(.-)(%a)", 9 function(_, mods, t) 10 local n = match_no 11 match_no = match_no + 1 12 if t == 'p' and ffi.istype(ptrtype, args[n]) then 13 local lo = tonumber(args[n] % 4294967296ULL) 14 local hi = tonumber(args[n] / 4294967296ULL) 15 args[n] = (hi == 0) and strformat("%x", lo) or strformat("%x%08x", hi, lo) 16 return "%"..mods.."s" 17 end 18 end) 19 if count == 0 then 20 return strformat(format, ...) 21 else 22 return strformat(newfmt, unpack(args,1,select('#',...))) 23 end 24 end 25end 26 27function string.starts(s, p) 28 return string.sub(s, 1, string.len(p)) == p 29end 30 31function string.lstrip(s, p) 32 return string.sub(s, string.len(p) + 1) 33end 34 35function string.ends(s, e) 36 return e == '' or string.sub(s, -string.len(e))==e 37end 38 39function string.escape(s) 40 return s:gsub('[%-%.%+%[%]%(%)%$%^%%%?%*]','%%%1') 41end 42 43--- split a string into a list of strings separated by a delimiter. 44-- @param s The input string 45-- @param re A Lua string pattern; defaults to '%s+' 46-- @param plain don't use Lua patterns 47-- @param n optional maximum number of splits 48-- @return a list-like table 49-- @raise error if s is not a string 50function string.split(s,re,plain,n) 51 local find,sub,append = string.find, string.sub, table.insert 52 local i1,ls = 1,{} 53 if not re then re = '%s+' end 54 if re == '' then return {s} end 55 while true do 56 local i2,i3 = find(s,re,i1,plain) 57 if not i2 then 58 local last = sub(s,i1) 59 if last ~= '' then append(ls,last) end 60 if #ls == 1 and ls[1] == '' then 61 return {} 62 else 63 return ls 64 end 65 end 66 append(ls,sub(s,i1,i2-1)) 67 if n and #ls == n then 68 ls[#ls] = sub(s,i1) 69 return ls 70 end 71 i1 = i3+1 72 end 73end 74 75function table.count(T) 76 local count = 0 77 for _ in pairs(T) do count = count + 1 end 78 return count 79end 80 81function table.bsearch(list, value, mkval) 82 local low = 1 83 local high = #list 84 while low <= high do 85 local mid = math.floor((low+high)/2) 86 local this = mkval and mkval(list[mid]) or list[mid] 87 if this > value then 88 high = mid - 1 89 elseif this < value then 90 low = mid + 1 91 else 92 return mid 93 end 94 end 95 return low - 1 96end 97 98function table.join(a, b) 99 assert(a) 100 if b == nil or #b == 0 then 101 return a 102 end 103 104 local res = {} 105 for _, v in ipairs(a) do 106 table.insert(res, v) 107 end 108 for _, v in ipairs(b) do 109 table.insert(res, v) 110 end 111 return res 112end 113 114function table.build(iterator_fn, build_fn) 115 build_fn = (build_fn or function(arg) return arg end) 116 local res = {} 117 while true do 118 local vars = {iterator_fn()} 119 if vars[1] == nil then break end 120 table.insert(res, build_fn(vars)) 121 end 122 return res 123end 124 125function table.values(T) 126 local V = {} 127 for k, v in pairs(T) do 128 table.insert(V, v) 129 end 130 return V 131end 132 133function table.tuples(T) 134 local i = 0 135 local n = table.getn(t) 136 return function () 137 i = i + 1 138 if i <= n then return t[i][1], t[i][2] end 139 end 140end 141 142getmetatable("").__mod = function(a, b) 143 if not b then 144 return a 145 elseif type(b) == "table" then 146 return string.format(a, unpack(b)) 147 else 148 return string.format(a, b) 149 end 150end 151 152function os.exists(path) 153 local f=io.open(path,"r") 154 if f~=nil then 155 io.close(f) 156 return true 157 else 158 return false 159 end 160end 161 162function os.spawn(...) 163 local cmd = string.format(...) 164 local proc = assert(io.popen(cmd)) 165 local out = proc:read("*a") 166 proc:close() 167 return out 168end 169 170local function logline(...) 171 if not log.enabled then 172 return 173 end 174 175 local c_green = "\27[32m" 176 local c_grey = "\27[1;30m" 177 local c_clear = "\27[0m" 178 179 local msg = string.format(...) 180 local info = debug.getinfo(2, "Sln") 181 local line = string.format("%s[%s:%s]%s %s", c_grey, 182 info.short_src:match("^.+/(.+)$"), info.currentline, c_clear, info.name) 183 184 io.stderr:write( 185 string.format("%s[%s]%s %s: %s\n", c_green, 186 os.date("%H:%M:%S"), c_clear, line, msg)) 187end 188 189setmetatable(_G, { 190 __newindex = function (_, n) 191 error("attempt to write to undeclared variable "..n, 2) 192 end, 193 __index = function (_, n) 194 error("attempt to read undeclared variable "..n, 2) 195 end, 196}) 197 198rawset(_G, "log", { info = logline, enabled = false }) 199rawset(_G, "class", require("bcc.vendor.middleclass")) 200