summaryrefslogtreecommitdiff
path: root/tools/bin2c.lua
blob: 352d18e07218c0305952c115b7e1deb57016723a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
--
-- BIN2C.LUA [filename] [-o output.lch]
--
-- Convert files to byte arrays for automatic loading with 'lua_dobuffer'.
--
-- Based on 'etc/bin2c.c' of Lua 5.0.1 sources by:
--      Luiz Henrique de Figueiredo (lhf@tecgraf.puc-rio.br)
--
-- Changes:
--
-- 12-Dec-07/AKa: changed the output to have just the "{ ... }" part; others
--                (variable name) can be explicitly given before the '#include'
-- 16-Nov-07/AKa: taken into luaSub
-- 16-Mar-04/AKa: added 'glua_wrap()' support
-- xx-Jan-04/AKa: subdirectory names are not included in debug info
--

local function USAGE()
    io.stderr:write "lua bin2c.lua [filename] [-o output.lch]"
    os.exit(-1)
end

local out_f   -- file to output to (stdout if nil)

local function OUT( ... )
    (out_f or io.stdout): write( ... );     -- ; actually needed by Lua
    (out_f or io.stdout): write "\n"
end

local HEAD= "{ "
local START= '  '
local FILL= '%3d,'
local STOP= ""
local TAIL= "};\n"

--
local function dump( f )
    --
    OUT [[
/* bin2c.lua generated code -- DO NOT EDIT
 *
 * To use from C source: 
 *    char my_chunk[]=
 *    #include "my.lch"
 */]]

    local str= HEAD..'\n'..START
    local len= 0
    
    while true do
        for n=1,20 do
            local c= f:read(1)
            if c then
                str= str..string.format( FILL, string.byte(c) )
                len= len+1
            else
                OUT( str..STOP.. string.format( TAIL, len ) )
                return  -- the end
            end
        end
        OUT(str..STOP)
        str= START
    end
end

--
local function fdump( fn )
    --
    local f= io.open( fn, "rb" )    -- must open as binary
    
    if not f then
        error( "bin2c: cannot open "..fn )
    else
        dump( f )
        f:close()
    end
end

--
local function main( argv )
    --
    local fn= argv.o
    if fn then
        local f,err= io.open( fn, "w" )
        assert( f, "Unable to write '"..fn.."': "..(err or "") )

        out_f= f
    end
    
    if argv[2] then
        USAGE()
    elseif argv[1] then
        fdump( argv[1] )
    else    -- use stdin (no params)
        if os.getenv("WINDIR") then
            error "using stdin not allowed on Win32!"  -- it wouldn't be binary
        end
        dump(io.stdin)
    end
    
    if out_f then
        out_f:close()
    end
end

--
local argv= {}
local valid_flags= { o=1 }    -- lookup: 0=no value, 1=value

-- Need to use while since '-o' advances 'i' by 2
--
local args= select('#',...)
local i=1

while i<=args do
    local v= select(i,...)
    local flag= string.match( v, "^%-(.+)" )
    
    if flag then
        if not valid_flags[flag] then
            error( "Unknown flag: -"..flag )
        end
        argv[flag]= (i+1<=args) and select(i+1,...) or true
        i= i+1
    else
        table.insert( argv, v )   -- [1..N]
    end
    i= i+1
end

return main(argv)