gen_char_blob.lua (2449B)
1 if arg[1] == '--help' then 2 print('Usage:') 3 print(' ' .. arg[0] .. ' [-c] target source varname [source varname]...') 4 print('') 5 print('Generates C file with big uint8_t blob.') 6 print('Blob will be stored in a static const array named varname.') 7 os.exit() 8 end 9 10 -- Recognized options: 11 -- -c compile Lua bytecode 12 local options = {} 13 14 while true do 15 local opt = string.match(arg[1], '^-(%w)') 16 if not opt then 17 break 18 end 19 20 options[opt] = true 21 table.remove(arg, 1) 22 end 23 24 assert(#arg >= 3 and (#arg - 1) % 2 == 0) 25 26 local target_file = arg[1] or error('Need a target file') 27 local target = io.open(target_file, 'w') 28 29 target:write('#include <stdint.h>\n\n') 30 31 local index_items = {} 32 33 local warn_on_missing_compiler = true 34 local modnames = {} 35 for argi = 2, #arg, 2 do 36 local source_file = arg[argi] 37 local modname = arg[argi + 1] 38 if modnames[modname] then 39 error(string.format('modname %q is already specified for file %q', modname, modnames[modname])) 40 end 41 modnames[modname] = source_file 42 43 local varname = string.gsub(modname, '%.', '_dot_') .. '_module' 44 target:write(('static const uint8_t %s[] = {\n'):format(varname)) 45 46 local output 47 if options.c then 48 local luac = os.getenv('LUAC_PRG') 49 if luac and luac ~= '' then 50 output = io.popen(luac:format(source_file), 'r'):read('*a') 51 elseif warn_on_missing_compiler then 52 print('LUAC_PRG is missing, embedding raw source') 53 warn_on_missing_compiler = false 54 end 55 end 56 57 if not output then 58 local source = io.open(source_file, 'r') 59 or error(string.format("source_file %q doesn't exist", source_file)) 60 output = source:read('*a') 61 source:close() 62 end 63 64 local num_bytes = 0 65 local MAX_NUM_BYTES = 15 -- 78 / 5: maximum number of bytes on one line 66 target:write(' ') 67 68 local increase_num_bytes 69 increase_num_bytes = function() 70 num_bytes = num_bytes + 1 71 if num_bytes == MAX_NUM_BYTES then 72 num_bytes = 0 73 target:write('\n ') 74 end 75 end 76 77 for i = 1, string.len(output) do 78 local byte = output:byte(i) 79 target:write(string.format(' %3u,', byte)) 80 increase_num_bytes() 81 end 82 83 target:write(' 0};\n') 84 if modname ~= '_' then 85 table.insert( 86 index_items, 87 ' { "' .. modname .. '", ' .. varname .. ', sizeof ' .. varname .. ' },\n\n' 88 ) 89 end 90 end 91 92 target:write('static ModuleDef builtin_modules[] = {\n') 93 target:write(table.concat(index_items)) 94 target:write('};\n') 95 96 target:close()