stringfix.lua (5128B)
1 -- stringfix.lua: Pure Lua string function implementations 2 -- for bare metal LuajitOS where C string functions cause triple faults 3 4 osprint("Loading stringfix.lua...\n") 5 6 -- Save the built-in sub function if it exists and works 7 local builtin_sub = string.sub 8 9 -- Create character/byte lookup tables using only string literals and sub 10 local byte_to_char = {} 11 local char_to_byte = {} 12 13 -- Build lookup using string literals with all ASCII characters 14 local ascii = "" 15 for i = 0, 255 do 16 if i < 32 then 17 -- Control characters 18 if i == 0 then ascii = ascii .. "\x00" 19 elseif i == 1 then ascii = ascii .. "\x01" 20 elseif i == 2 then ascii = ascii .. "\x02" 21 elseif i == 3 then ascii = ascii .. "\x03" 22 elseif i == 4 then ascii = ascii .. "\x04" 23 elseif i == 5 then ascii = ascii .. "\x05" 24 elseif i == 6 then ascii = ascii .. "\x06" 25 elseif i == 7 then ascii = ascii .. "\x07" 26 elseif i == 8 then ascii = ascii .. "\x08" 27 elseif i == 9 then ascii = ascii .. "\x09" 28 elseif i == 10 then ascii = ascii .. "\x0A" 29 elseif i == 11 then ascii = ascii .. "\x0B" 30 elseif i == 12 then ascii = ascii .. "\x0C" 31 elseif i == 13 then ascii = ascii .. "\x0D" 32 elseif i == 14 then ascii = ascii .. "\x0E" 33 elseif i == 15 then ascii = ascii .. "\x0F" 34 elseif i == 16 then ascii = ascii .. "\x10" 35 elseif i == 17 then ascii = ascii .. "\x11" 36 elseif i == 18 then ascii = ascii .. "\x12" 37 elseif i == 19 then ascii = ascii .. "\x13" 38 elseif i == 20 then ascii = ascii .. "\x14" 39 elseif i == 21 then ascii = ascii .. "\x15" 40 elseif i == 22 then ascii = ascii .. "\x16" 41 elseif i == 23 then ascii = ascii .. "\x17" 42 elseif i == 24 then ascii = ascii .. "\x18" 43 elseif i == 25 then ascii = ascii .. "\x19" 44 elseif i == 26 then ascii = ascii .. "\x1A" 45 elseif i == 27 then ascii = ascii .. "\x1B" 46 elseif i == 28 then ascii = ascii .. "\x1C" 47 elseif i == 29 then ascii = ascii .. "\x1D" 48 elseif i == 30 then ascii = ascii .. "\x1E" 49 elseif i == 31 then ascii = ascii .. "\x1F" 50 end 51 elseif i >= 32 and i < 127 then 52 -- Printable ASCII - build from literal string 53 local printable = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" 54 ascii = ascii .. builtin_sub(printable, i - 31, i - 31) 55 elseif i == 127 then 56 ascii = ascii .. "\x7F" 57 else 58 -- Extended ASCII - use placeholder 59 ascii = ascii .. "?" 60 end 61 62 -- Build lookup tables 63 local ch = builtin_sub(ascii, i + 1, i + 1) 64 byte_to_char[i] = ch 65 if i < 128 then -- Only map standard ASCII to avoid collisions 66 char_to_byte[ch] = i 67 end 68 end 69 70 osprint("Lookup tables built\n") 71 72 -- Override string.byte with pure Lua implementation 73 function string.byte(s, i, j) 74 i = i or 1 75 j = j or i 76 local len = #s 77 78 -- Handle negative indices 79 if i < 0 then i = len + i + 1 end 80 if j < 0 then j = len + j + 1 end 81 82 -- Clamp to bounds 83 if i < 1 then i = 1 end 84 if j > len then j = len end 85 if i > j then return end 86 87 -- Extract bytes 88 local results = {} 89 for pos = i, j do 90 local ch = builtin_sub(s, pos, pos) 91 local b = char_to_byte[ch] 92 if b then 93 results[#results + 1] = b 94 else 95 -- Unknown character, return '?' 96 results[#results + 1] = 63 97 end 98 end 99 100 -- Return multiple values 101 if #results == 1 then 102 return results[1] 103 else 104 return table.unpack(results) 105 end 106 end 107 108 -- Override string.char with pure Lua implementation 109 function string.char(...) 110 local args = {...} 111 local result = {} 112 113 for i = 1, #args do 114 local b = args[i] 115 if b < 0 or b > 255 then 116 error("bad argument to 'char' (invalid byte value)") 117 end 118 result[i] = byte_to_char[b] or "?" 119 end 120 121 return table.concat(result) 122 end 123 124 osprint("string.byte and string.char overridden\n") 125 126 -- Additional string functions using our safe byte/char 127 128 function string.charAt(s, i) 129 local len = #s 130 if i < 0 then i = len + i + 1 end 131 if i < 1 or i > len then return "" end 132 return builtin_sub(s, i, i) 133 end 134 135 function string.reverse(s) 136 local result = {} 137 for i = #s, 1, -1 do 138 result[#result + 1] = builtin_sub(s, i, i) 139 end 140 return table.concat(result) 141 end 142 143 function string.lower(s) 144 local result = {} 145 for i = 1, #s do 146 local b = string.byte(s, i) 147 -- A-Z is 65-90 148 if b >= 65 and b <= 90 then 149 b = b + 32 150 end 151 result[#result + 1] = string.char(b) 152 end 153 return table.concat(result) 154 end 155 156 function string.upper(s) 157 local result = {} 158 for i = 1, #s do 159 local b = string.byte(s, i) 160 -- a-z is 97-122 161 if b >= 97 and b <= 122 then 162 b = b - 32 163 end 164 result[#result + 1] = string.char(b) 165 end 166 return table.concat(result) 167 end 168 169 osprint("stringfix.lua loaded successfully!\n")