~ubuntu-branches/ubuntu/natty/lua-gtk/natty

« back to all changes in this revision

Viewing changes to script/parse-xml.lua

  • Committer: Bazaar Package Importer
  • Author(s): Enrico Tassi
  • Date: 2009-05-17 18:16:21 UTC
  • mfrom: (1.2.1 upstream) (4.1.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20090517181621-9kmdd82nxg54jsio
* new upstream snapshot comprising many more GNOME libraries:
    Gtk, GDK, GLib, Pango, Atk, Libxml2, Cairo, Clutter, Gtkhtml, 
    GtkSourceView, Gio, Gtkspell and GConf. 
* new upstream release includes a new configure script written in Lua,
  no more bashisms there (Closes: #507205)
* renamed binary packages to liblua5.1-gnome-*
* updated standards-version to 3.8.1, no changes needed
* patch to load .so.* version of libraries and not .so (that was requiring
  -dev packages) (Closes: #522087)
* removed redundant Architecture line from the source stanza of control
  (Closes: #498120)
* updated copyright file, Wolfgang Oertl holds it for 2009 too.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
--  2008-02-24  split into multiple files
18
18
--
19
19
 
 
20
-- BitOp, see http://bitop.luajit.org/
20
21
require "bit"
21
22
 
 
23
-- The binding to the hash functions used in this package.  Compiled during
 
24
-- building.
 
25
require "gnomedev"
 
26
 
 
27
require "lfs"
 
28
 
 
29
-- locally defined
 
30
require "script.util"
 
31
 
22
32
-- add the directory where this Lua file is in to the package search path.
23
33
package.path = package.path .. ";" .. string.gsub(arg[0], "%/[^/]+$", "/?.lua")
24
 
require "common"
25
 
 
26
 
char_ptr_second = nil
27
34
 
28
35
xml = require "xml-parser"
29
36
typedefs = xml.typedefs
30
37
types = require "xml-types"
31
38
output = require "xml-output"
 
39
require "xml-const"
32
40
 
33
41
typedefs_sorted = {}
34
42
typedefs_name2id = {}
35
 
 
36
 
architecture = nil  -- target architecture
37
 
free_methods = {}       -- [name] = 0/1
38
 
input_file_name = nil
39
 
parse_errors = 0        -- count errors
 
43
config = {}             -- configuration of architecture, module etc.
 
44
parse_errors = 0        -- count errors (used in xml-parser.lua)
40
45
verbose = 0             -- verbosity level
 
46
good_files = {}         -- [file_id] = true for "interesting" include files
 
47
logfile = nil
 
48
non_native_includes = {}    -- [path] = libname
 
49
function_list = {}
 
50
build_errors = 0
 
51
 
 
52
 
 
53
-- Print an error message and increase the error counter.
 
54
function err(fmt, ...)
 
55
    if select('#', ...) > 0 then
 
56
        fmt = string.format(fmt, ...)
 
57
    end
 
58
    print(fmt)
 
59
    build_errors = build_errors + 1
 
60
end
41
61
 
42
62
---
43
63
-- Unfortunately, sometimes ENUM fields in structures are not declared as such,
49
67
function mark_all_enums_as_used()
50
68
    local fid, tp
51
69
    for id, t in pairs(typedefs) do
52
 
        if t.type == "enum" and not t.in_use then
53
 
            types.mark_type_id_in_use(id, nil)
 
70
        if t.type == "enum" then
 
71
            if not t.in_use then
 
72
                if good_files[t.file_id] then
 
73
                    types.mark_type_id_in_use(id, nil)
 
74
                end
 
75
            else
 
76
                if not good_files[t.file_id] then
 
77
                    t.no_good = true
 
78
                end
 
79
            end
54
80
        end
55
81
    end
56
82
end
67
93
 
68
94
    -- find all enums
69
95
    for id, t in pairs(typedefs) do
70
 
        if t.type == "enum" then
 
96
        if t.type == "enum" and t.in_use then
71
97
            enum_list[id] = true
72
98
        end
73
99
    end
76
102
    for id, t in pairs(typedefs) do
77
103
        if t.type == "typedef" and enum_list[t.what] then
78
104
            -- print("FOUND typedef for enum:", t.full_name)
79
 
            types.mark_type_id_in_use(id)
 
105
            types.mark_type_id_in_use(id, nil)
80
106
            t2 = typedefs[t.what]
81
107
            t.counter = t.counter + t2.counter - 1
82
108
            t2.in_use = false
86
112
    end
87
113
end
88
114
 
 
115
 
89
116
---
90
117
-- The structures named *Iface are required to be able to override interface
 
118
-- virtual functions.  They are not intended to be used directly by the user,
 
119
-- and therefore don't show up as function arguments.
 
120
-- All of these structures are named _*Iface, and have a typedef with
 
121
-- *Iface for them.  Actually, we need a pointer to that, which isn't defined.
91
122
--
92
123
function mark_ifaces_as_used()
 
124
    local name2id = {}
93
125
    for type_id, t in pairs(typedefs) do
94
 
        if t.type == "struct" and string.match(t.name, "Iface$") then
95
 
            types.mark_type_id_in_use(type_id)
96
 
        end
97
 
    end
98
 
end
99
 
 
100
 
 
101
 
 
102
 
function_list = {}
 
126
        if t.type == "typedef" and string.match(t.name, "Iface$")
 
127
            and good_files[t.file_id] then
 
128
            -- types.mark_type_id_in_use(type_id)
 
129
            name2id[t.name] = type_id
 
130
            synthesize_type(t.name .. "*", name2id)
 
131
        end
 
132
    end
 
133
end
 
134
 
 
135
 
 
136
---
 
137
-- Read all config files for the libraries in the current setup.  Note
 
138
-- that this usually is just one, and probably never is more than one.
 
139
--
 
140
function load_lib_config()
 
141
    local cfg_file, cfg
 
142
 
 
143
    -- config_libs = {}
 
144
    cfg_file = string.format("%s/spec.lua", config.srcdir)
 
145
    config.lib = load_spec(cfg_file)
 
146
 
 
147
    if config.lib.native_types then
 
148
        for k, v in pairs(config.lib.native_types) do
 
149
            config.native_types[k] = v
 
150
        end
 
151
    end
 
152
end
 
153
 
 
154
---
 
155
-- Read all spec files of other modules and extract the include_dirs.  This
 
156
-- is used to store for non-native types which module should handle it.
 
157
--
 
158
function load_other_lib_config()
 
159
    local ifile
 
160
 
 
161
    for libname in lfs.dir("src") do
 
162
        ifile = "src/" .. libname .. "/spec.lua"
 
163
        if string.sub(libname, 1, 1) ~= "."
 
164
            and lfs.attributes(ifile, "mode") == "file" then
 
165
            cfg = load_spec(ifile, true)
 
166
            for _, path in ipairs(cfg.include_dirs or {}) do
 
167
                non_native_includes[path] = libname
 
168
            end
 
169
        end
 
170
    end
 
171
        
 
172
end
 
173
 
 
174
-- Make a table listing all include paths of the current module.
 
175
function _get_include_paths()
 
176
    local tbl = {}
 
177
    for _, path in ipairs(config.lib.include_dirs or {}) do
 
178
        tbl[#tbl + 1] = "/" .. path .. "/"
 
179
    end
 
180
    return tbl
 
181
end
 
182
 
 
183
 
 
184
---
 
185
-- Look at all the file IDs and mark those files that are relevant for the
 
186
-- current module.
 
187
--
 
188
function make_file_list()
 
189
    local paths = _get_include_paths()
 
190
    good_files = {}         -- [id] = true
 
191
 
 
192
    for id, name in pairs(xml.filelist) do
 
193
        for i, path in ipairs(paths) do
 
194
            if string.find(name, path, 1, true) then
 
195
                good_files[id] = true
 
196
                break
 
197
            end
 
198
        end
 
199
    end
 
200
end
 
201
        
103
202
 
104
203
---
105
204
-- Take a look at all relevant functions and the data types they reference.
 
205
-- Mark all these data types as used.  Note that functions prototypes that only
 
206
-- appear in structures (i.e., function pointers) are not considered here.
106
207
--
 
208
-- Note that this does not consider function types, which are only to be
 
209
-- found in the typedefs list.
107
210
--
108
211
function analyze_functions()
109
 
    local inc_prefixes = {
110
 
        g=true, gdk=true,       -- for glib, gdk
111
 
        gtk=true,               -- for gtk
112
 
        atk=true,               -- for atk
113
 
        pango=true,             -- for pango
114
 
        cairo=true,             -- for cairo
115
 
        html=true, css=true, dom=true,  -- for libgtkhtml-2.0
116
 
    }
117
212
 
118
 
    -- Make a sorted list of functions to output.  Only use function with
119
 
    -- one of the prefixes in the inc_prefixes list.
 
213
    -- Make a sorted list of functions to output.  Only use functions declared
 
214
    -- in one of the "good" files, and ignore those starting with "_", which
 
215
    -- are most likely private.  v[1][3] contains the file's ID.
120
216
    for k, v in pairs(xml.funclist) do
121
 
        pos = k:find("_")
122
 
        if pos ~= nil and inc_prefixes[k:sub(1, pos - 1)] then
 
217
        local found = false
 
218
        assert(v[1][3])
 
219
        if good_files[v[1][3]] and string.sub(k, 1, 1) ~= "_" then
123
220
            function_list[#function_list + 1] = k
124
221
            _function_analyze(k)
125
222
        end
126
223
    end
 
224
 
 
225
    -- If aliases are defined, add them too.  The "from" function must
 
226
    -- exist, while the "to" function must not exist.  Note that the "from"
 
227
    -- function remains available, and must remain, because the argument
 
228
    -- list is defined there and not in the alias function entry.
 
229
    if config.lib.aliases then
 
230
        for to, from in pairs(config.lib.aliases) do
 
231
            assert(xml.funclist[from])
 
232
            assert(not xml.funclist[to])
 
233
            function_list[#function_list + 1] = to
 
234
            xml.funclist[to] = from
 
235
            _function_analyze(from)
 
236
        end
 
237
    end
 
238
 
127
239
    table.sort(function_list)
128
240
end
129
241
 
145
251
                fname, arg_nr))
146
252
            for k, v in pairs(arg_info) do print(">", k, v) end
147
253
        end
 
254
 
148
255
        types.mark_type_id_in_use(arg_info[1],
149
256
            string.format("%s.%s", fname, arg_info[2]))
150
257
    end
163
270
            -- in_use: directly used; marked: indirectly used
164
271
            if t.in_use or t.marked then
165
272
                _analyze_struct(id, t)
166
 
--          else
167
 
--              print("SKIP", t.name)
168
273
            end
169
274
        end
170
275
    end
171
276
end
172
277
 
 
278
---
 
279
-- After finding all "native" types, those that refer to them are also
 
280
-- marked as native.
 
281
--
 
282
function analyze_structs_native()
 
283
    for id, t in pairs(typedefs) do
 
284
        if t.in_use then
 
285
            _is_native(t)
 
286
        end
 
287
    end
 
288
end
 
289
 
 
290
---
 
291
-- Given a type ID, check whether that type is native, or a fundamental type.
 
292
--
 
293
-- @param t  Typespec
 
294
-- @return  false=not native, 1=native, 2=fundamental
 
295
--
 
296
function _is_native(t)
 
297
    if t.is_native ~= nil then return t.is_native end
 
298
    local is_native, t2
 
299
 
 
300
    if t.type == 'fundamental' then
 
301
        is_native = 2
 
302
    elseif good_files[t.file_id] then
 
303
        is_native = 1
 
304
    elseif config.native_types[t.full_name] then
 
305
        is_native = 1
 
306
    else
 
307
        -- follow pointers and qualifiers, then check that type.
 
308
        t2 = t
 
309
        while t2.type == 'pointer' or t2.type == 'qualifier' do
 
310
            t2 = typedefs[t2.what]
 
311
        end
 
312
        if t2.type == 'fundamental' then
 
313
            is_native = 2
 
314
        elseif t2.type == 'func' then
 
315
            is_native = 1
 
316
        else
 
317
            is_native = false
 
318
        end
 
319
    end
 
320
 
 
321
    t.is_native = is_native
 
322
    return is_native
 
323
end
 
324
 
 
325
 
 
326
-- For each member of the structure, mark their type in use.
173
327
function _analyze_struct(id, t)
174
328
    local st = t.struct
175
329
    local ignorelist = { constructor=true, union=true, struct=true }
176
 
    local name, tp
177
330
 
178
331
    for _, member_name in ipairs(st.members) do
179
332
        member = st.fields[member_name]
180
333
        if member and not ignorelist[member.type] then
181
 
            -- tp = types.resolve_type(member.type, member.size)
182
 
            -- assert(tp.fid)
183
334
            types.mark_type_id_in_use(member.type,
184
335
                string.format("%s.%s", t.name, member.name or member_name))
185
336
        end
188
339
 
189
340
 
190
341
---
 
342
-- Run through all useful globals and mark their types as used.
191
343
--
192
344
function analyze_globals()
193
345
    for name, var in pairs(xml.globals) do
194
 
        types.mark_type_id_in_use(var.type, name)
 
346
        var.is_native = good_files[var.file]
 
347
        if var.is_native then
 
348
            types.mark_type_id_in_use(var.type, name)
 
349
        end
195
350
    end
196
351
end
197
352
 
198
 
local next_synth_nr = 1
199
353
 
200
354
---
201
355
-- Mark some types as used, or create them.  This is for such types that are
204
357
--
205
358
-- Some required types are not even in the type list, like
206
359
-- GtkFileChooserWidget*; only GtkFileChooserWidget is defined, i.e. without
 
360
-- the pointer.  For these types, new ones are "synthetized", or derived, with
 
361
-- additional pointers.
207
362
--
208
363
function mark_override()
209
364
    local ar = {}
210
365
    local name2id = {}
211
366
 
212
 
    -- get the list of types from the file
213
 
    for line in io.lines("src/include_types.txt") do
214
 
        line = string.gsub(line, "%s*#.*$", "")
215
 
        if line ~= "" then
216
 
            ar[line] = true
217
 
        end
 
367
    for _, name in ipairs(config.lib.include_types or {}) do
 
368
        ar[name] = true
218
369
    end
219
370
 
220
371
    -- Scan all typedefs, resolve their names.  Requested types that can be
224
374
        if not t.full_name then
225
375
            types.resolve_type(id, nil, true)
226
376
            if not t.full_name then
227
 
                print("COULD NOT RESOLVE TYPE", id, t.name, t.fname)
 
377
                err("Could not resolve type %s %s %s", id, t.name, t.fname)
228
378
            end
229
379
        end
230
380
        if t.full_name then
233
383
                    print("mark_override", id, t.type, t.full_name)
234
384
                end
235
385
                types.mark_type_id_in_use(id)
 
386
                t.is_native = true  -- all types in include_types are native.
236
387
                ar[t.full_name] = nil
237
388
            elseif not name2id[t.full_name] then
238
389
                name2id[t.full_name] = id
243
394
    -- Try to synthetize a new pointer type for still undefined types.
244
395
    for full_name, v in pairs(ar) do
245
396
        if not synthesize_type(full_name, name2id) then
246
 
            print("Can't synthesize type for " .. full_name)
 
397
            err("Type in include_types can't be synthesized: %s", full_name)
247
398
        else
248
399
            ar[full_name] = nil
249
400
        end
250
401
    end
251
 
 
252
 
    -- what's left hasn't been found.
253
 
    for full_name, v in pairs(ar) do
254
 
        print("OVERRIDE NOT FOUND", full_name)
255
 
    end
256
402
end
257
403
 
258
404
 
 
405
local next_synth_nr = 1
259
406
 
260
407
---
 
408
-- The requested type doesn't exist, so try to create it by deriving a new
 
409
-- type from an existing type.  This includes removing "const" and
 
410
-- indirections.
261
411
--
262
412
function synthesize_type(full_name, name2id)
 
413
    local parent_name, parent_id, new_id, parent, t, new_item
263
414
 
264
 
    if string.sub(full_name, -1) ~= "*" then
 
415
    if string.sub(full_name, 1, 6) == "const " then
 
416
        parent_name = string.sub(full_name, 7)
 
417
        new_item = { type="qualifier", const=true }
 
418
    elseif string.sub(full_name, -1) == "*" then
 
419
        parent_name = string.sub(full_name, 1, -2)
 
420
        new_item = { type="pointer" }
 
421
    else
265
422
        return false
266
423
    end
267
424
 
268
 
    local parent_name = string.sub(full_name, 1, -2)
269
 
    local parent_id = name2id[parent_name] or synthesize_type(parent_name,
270
 
        name2id)
 
425
    parent_id = name2id[parent_name] or synthesize_type(parent_name, name2id)
271
426
    if not parent_id then return false end
272
427
 
273
 
    local new_id = "synth" .. next_synth_nr
 
428
    new_id = "synth" .. next_synth_nr
274
429
    next_synth_nr = next_synth_nr + 1
275
 
    local parent = typedefs[parent_id]
276
 
    typedefs[new_id] = { type="pointer", what=parent_id, name=parent.name }
277
 
    local t = types.mark_type_id_in_use(new_id, nil)
 
430
    parent = typedefs[parent_id]
 
431
 
 
432
    new_item.what = parent_id
 
433
    new_item.is_native = parent.is_native
 
434
    typedefs[new_id] = new_item
 
435
 
 
436
    t = types.mark_type_id_in_use(new_id, nil)
278
437
    if verbose > 1 then
279
 
        print("mark override new", new_id, t.type, t.full_name)
 
438
        print("mark override new", new_id, t.type, t.full_name, full_name)
280
439
    end
 
440
 
281
441
    return new_id
282
442
end
283
443
 
284
444
 
285
445
---
286
 
--
287
 
--
288
 
function _handle_char_ptr_returns(arg_list, tp, fname)
289
 
 
290
 
    local method
291
 
 
292
 
    -- this is what the API says; consts should not be freed.
293
 
    local default_method = tp.const and 0 or 1
294
 
 
295
 
    -- The free_method may have been defined by reading the
296
 
    -- char_ptr_handling.txt file.
297
 
    if arg_list.free_method then
298
 
        method = arg_list.free_method
299
 
    else
300
 
 
301
 
        -- This might be a function argument or structure member, and therefore
302
 
        -- should have an entry in this table:
303
 
        method = free_methods[fname]
304
 
 
305
 
        if not method then
306
 
            print(string.format("Warning: free method not defined for %s",
307
 
                fname))
308
 
            method = default_method
309
 
        end
310
 
    end
311
 
 
312
 
    -- Warn if API and my list differ.  Sometimes this is intentionally,
313
 
    -- but then should be documented in char_ptr_handling.txt.
314
 
    if method ~= default_method then
315
 
        print("Warning: inconsistency of free method of function " .. fname)
316
 
    end
317
 
 
318
 
    return tp.fid + method
319
 
 
320
 
end
321
 
 
322
 
 
323
 
---
324
 
--
325
 
function get_extra_data()
326
 
    local active = true
327
 
    local arch, arch2, func, method, inverse
328
 
 
329
 
    for line in io.lines("src/char_ptr_handling.txt") do
330
 
 
331
 
        arch = string.match(line, "^arch (.*)$")
332
 
        if arch then
333
 
            arch2 = string.match(arch, "^not (.*)$")
334
 
            inverse = false
335
 
            if arch2 then
336
 
                inverse = true
337
 
                arch = arch2
338
 
            end
339
 
            active = arch == "all" and true or string.match(architecture, arch)
340
 
            if inverse then active = not active end
341
 
        end
342
 
 
343
 
        if not arch and active then
344
 
            func, method = string.match(line, '^([^#,]*),(%d)$')
345
 
            if func and method then
346
 
                _set_char_ptr_handling(func, tonumber(method))
347
 
            end
348
 
        end
349
 
    end
350
 
end
351
 
 
352
 
---
353
 
--
354
 
function _set_char_ptr_handling(funcname, method)
355
 
 
356
 
    -- funcnames that include a dot are not simple functions, but refer to
357
 
    -- an argument of a function, or a member of a structure.
358
 
    local parent, item = string.match(funcname, "^([^.]+)%.(.*)$")
359
 
    if parent and item then
360
 
        free_methods[parent == "funcptr" and item or funcname] = method
361
 
        return
362
 
    end
363
 
 
364
 
    local fi = xml.funclist[funcname]
365
 
    if not fi then
366
 
        print("Warning: undefined function in char_ptr_handling: " .. funcname)
367
 
        return
368
 
    end
369
 
 
370
 
    assert(fi.free_method == nil, "Duplicate in char_ptr_handling.txt: "
371
 
        .. funcname)
372
 
    tp = types.resolve_type(fi[1][1])
373
 
 
374
 
    -- must be a char*, i.e. with one level of indirection
375
 
    assert(tp.fname == "char")
376
 
    assert(tp.pointer == 1)
377
 
 
378
 
    -- If a return type is "const char*", then this usually means "do not
379
 
    -- free it".  Alas, this rule of thumb has exceptions.
380
 
    if not (method == 0 and tp.const or method == 1 and not tp.const) then
381
 
        print("Warning: inconsistency of free method of function " .. funcname)
382
 
    end
383
 
 
384
 
    fi.free_method = method
385
 
end
386
 
 
387
 
 
388
 
 
389
 
enums = {}
390
 
 
391
 
---
392
446
-- Certain #defines from the Gtk/Gdk include files are relevant, but not
393
447
-- included in types.xml.  Extract them and add them to the ENUM list.
394
448
--
 
449
-- @param fname  Full pathname of the file to read
 
450
-- @param nums  boolean - whether to extract numerical #defines
 
451
--
395
452
function parse_header_file(fname, nums)
396
453
    local line2 = ""
397
454
    local name, value
427
476
                if name and value then
428
477
                    assert(not enums[name])
429
478
                    enums[name] = { val=tonumber(value), context="__dummy" }
430
 
                    -- print(encode_enum(name, tonumber(value), 0))
431
479
                    break
432
480
                end
433
481
            end
438
486
            if name and value then
439
487
                assert(not enums[name])
440
488
                enums[name] = { val=value, context="__dummy" }
441
 
                -- print(encode_enum(name, value, 0))
442
489
                break
443
490
            end
444
491
 
449
496
                -- *4 is what G_TYPE_MAKE_FUNDAMENTAL does.
450
497
                assert(not enums[name])
451
498
                enums[name] = { val=tonumber(value) * 4, context="__dummy" }
452
 
                -- print(encode_enum(name, value * 4, 0))
453
499
                break
454
500
            end
455
501
 
 
502
            -- Atoms
 
503
            name, value = string.match(line,
 
504
                "^#define ([A-Z0-9_]+)%s+_GDK_MAKE_ATOM%s*%((%d+)%)")
 
505
            if name and value then
 
506
                assert(not enums[name])
 
507
                local ctx = typedefs_name2id["GdkAtom"]
 
508
                assert(ctx, "Unknown type GdkAtom in #define")
 
509
                enums[name] = { val=tonumber(value), context=ctx }
 
510
            end
 
511
 
456
512
            -- nothing usable in this line, skip.
457
513
            break
458
514
        end
465
521
-- Show a numeric statistical information
466
522
--
467
523
function info_num(label, value)
468
 
    print(string.format("  %-40s%d", label, value))
469
 
end
 
524
    logfile:write(string.format("  %-40s%d\n", label, value))
 
525
end
 
526
 
 
527
-- read additional ENUMs from header files.  Do this after assign_type_idx,
 
528
-- so that the __dummy entry isn't being output.
 
529
function read_extra_headers()
 
530
    for _, row in ipairs(config.lib.headers or {}) do
 
531
        parse_header_file(row[1], row[2])
 
532
    end
 
533
end
 
534
 
 
535
 
 
536
function write_summary()
 
537
    logfile:write("Parsing Results for " .. arg[2] .. "\n\n")
 
538
    xml.show_statistics()
 
539
    types.show_statistics()
 
540
    output.show_statistics()
 
541
    enum_statistics()
 
542
    logfile:close()
 
543
    logfile = nil
 
544
end
 
545
 
470
546
 
471
547
 
472
548
-- MAIN --
483
559
 
484
560
-- remaining must be three --
485
561
if #arg ~= 3 then
486
 
    print(string.format("Usage: %s [options] {outputdir} {xmlfile} {arch}",
 
562
    print(string.format("Usage: %s [options] {outputdir} {xmlfile} {cfgfile}",
487
563
        arg[0]))
488
564
    return
489
565
end
490
566
 
491
 
architecture = arg[3]
 
567
-- read config file for this build
 
568
config = load_config(arg[3])
 
569
assert(config.arch, "No architecture defined in config file")
 
570
config.arch = string.lower(config.arch)
 
571
config.arch_os = string.match(config.arch, "^[^-]+")
 
572
config.native_types = {}
 
573
 
 
574
logfile = assert(io.open(arg[1] .. "/parse-xml.log", "w"))
 
575
 
 
576
-- read config file for the library in this module
 
577
load_lib_config()
 
578
load_other_lib_config()
492
579
 
493
580
-- read the XML data
494
581
xml.parse_xml(arg[2])
495
582
 
496
 
get_extra_data()
 
583
make_file_list()
497
584
mark_ifaces_as_used()
498
585
analyze_globals()
499
 
 
500
586
analyze_functions()
501
587
mark_override()
502
588
analyze_structs()
503
589
mark_all_enums_as_used()
 
590
analyze_structs_native()
504
591
promote_enum_typedefs()
505
592
 
506
593
-- before writing the structures, the functions must be looked at to
507
594
-- find prototypes that need registering.
508
595
 
509
 
types.assign_type_idx()
 
596
typedefs_sorted = types.assign_type_idx()
510
597
 
511
598
-- Now that all used types have their IDs, the function prototypes
512
599
-- can be registered.
513
600
types.register_function_prototypes()
514
601
 
515
 
path_gtk = "/usr/include/gtk-2.0"
516
 
path_glib = "/usr/include/glib-2.0"
517
 
parse_header_file(path_gtk .. "/gtk/gtkstock.h", false)
518
 
parse_header_file(path_glib .. "/gobject/gtype.h", false)
519
 
parse_header_file(path_gtk .. "/gdk/gdkkeysyms.h", true)
520
 
 
521
 
output.output_types(arg[1] .. "/gtkdata.structs.c")
522
 
output.output_enums(arg[1] .. "/gtkdata.enums.txt")
523
 
output.output_functions(arg[1] .. "/gtkdata.funcs.txt")
524
 
output.output_fundamental_types(arg[1] .. "/gtkdata.types.c")
525
 
output.output_globals(arg[1] .. "/gtkdata.globals.c")
526
 
 
527
 
print("\n --- " ..arg[2] .. " Parsing Results ---\n")
528
 
xml.show_statistics()
529
 
types.show_statistics()
530
 
output.show_statistics()
531
 
enum_statistics()
532
 
print ""
 
602
read_extra_headers()
 
603
 
 
604
-- The core library must provide support for all fundamental types, even though
 
605
-- it doesn't use all of them.  The modules don't have type handling, just
 
606
-- have a list of names of fundamental types they use.
 
607
if config.is_core then
 
608
    types.register_all_fundamental_types()
 
609
end
 
610
 
 
611
if build_errors > 0 then
 
612
    os.exit(1)
 
613
end
 
614
 
 
615
output.output_init()
 
616
output.output_types(arg[1] .. "/types.c")
 
617
output.output_constants(arg[1] .. "/constants.txt")
 
618
output.output_functions(arg[1] .. "/functions.txt")
 
619
if config.is_core then
 
620
    output.output_fundamental_types(arg[1] .. "/fundamentals.c")
 
621
else
 
622
    output.output_fundamental_hash(arg[1] .. "/fundamentals.c")
 
623
end
 
624
output.output_globals(arg[1] .. "/globals.c")
 
625
output.output_code(arg[1] .. "/generated.c")
 
626
write_summary(arg[1] .. "/parse.log")
 
627
 
 
628
if false then
 
629
    for k, t in pairs(typedefs) do
 
630
        if not t.in_use and not t.marked and good_files[t.file_id] then
 
631
            print("unused", k, t.type, t.name)
 
632
        end
 
633
    end
 
634
end
 
635
 
533
636