~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/mapi/glapi/gen/glX_proto_size.py

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
# (C) Copyright IBM Corporation 2004, 2005
3
 
# All Rights Reserved.
4
 
#
5
 
# Permission is hereby granted, free of charge, to any person obtaining a
6
 
# copy of this software and associated documentation files (the "Software"),
7
 
# to deal in the Software without restriction, including without limitation
8
 
# on the rights to use, copy, modify, merge, publish, distribute, sub
9
 
# license, and/or sell copies of the Software, and to permit persons to whom
10
 
# the Software is furnished to do so, subject to the following conditions:
11
 
#
12
 
# The above copyright notice and this permission notice (including the next
13
 
# paragraph) shall be included in all copies or substantial portions of the
14
 
# Software.
15
 
#
16
 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
19
 
# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
 
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22
 
# IN THE SOFTWARE.
23
 
#
24
 
# Authors:
25
 
#    Ian Romanick <idr@us.ibm.com>
26
 
 
27
 
import argparse
28
 
import sys, string
29
 
 
30
 
import gl_XML, glX_XML
31
 
import license
32
 
 
33
 
 
34
 
class glx_enum_function(object):
35
 
    def __init__(self, func_name, enum_dict):
36
 
        self.name = func_name
37
 
        self.mode = 1
38
 
        self.sig = None
39
 
 
40
 
        # "enums" is a set of lists.  The element in the set is the
41
 
        # value of the enum.  The list is the list of names for that
42
 
        # value.  For example, [0x8126] = {"POINT_SIZE_MIN",
43
 
        # "POINT_SIZE_MIN_ARB", "POINT_SIZE_MIN_EXT",
44
 
        # "POINT_SIZE_MIN_SGIS"}.
45
 
 
46
 
        self.enums = {}
47
 
 
48
 
        # "count" is indexed by count values.  Each element of count
49
 
        # is a list of index to "enums" that have that number of
50
 
        # associated data elements.  For example, [4] = 
51
 
        # {GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_EMISSION,
52
 
        # GL_AMBIENT_AND_DIFFUSE} (the enum names are used here,
53
 
        # but the actual hexadecimal values would be in the array).
54
 
 
55
 
        self.count = {}
56
 
 
57
 
 
58
 
        # Fill self.count and self.enums using the dictionary of enums
59
 
        # that was passed in.  The generic Get functions (e.g.,
60
 
        # GetBooleanv and friends) are handled specially here.  In
61
 
        # the data the generic Get functions are referred to as "Get".
62
 
 
63
 
        if func_name in ["GetIntegerv", "GetBooleanv", "GetFloatv", "GetDoublev"]:
64
 
            match_name = "Get"
65
 
        else:
66
 
            match_name = func_name
67
 
 
68
 
        mode_set = 0
69
 
        for enum_name in enum_dict:
70
 
            e = enum_dict[ enum_name ]
71
 
 
72
 
            if match_name in e.functions:
73
 
                [count, mode] = e.functions[ match_name ]
74
 
 
75
 
                if mode_set and mode != self.mode:
76
 
                    raise RuntimeError("Not all enums for %s have the same mode." % (func_name))
77
 
 
78
 
                self.mode = mode
79
 
 
80
 
                if e.value in self.enums:
81
 
                    if e.name not in self.enums[ e.value ]:
82
 
                        self.enums[ e.value ].append( e )
83
 
                else:
84
 
                    if count not in self.count:
85
 
                        self.count[ count ] = []
86
 
 
87
 
                    self.enums[ e.value ] = [ e ]
88
 
                    self.count[ count ].append( e.value )
89
 
 
90
 
 
91
 
        return
92
 
 
93
 
 
94
 
    def signature( self ):
95
 
        if self.sig == None:
96
 
            self.sig = ""
97
 
            for i in self.count:
98
 
                if i == None:
99
 
                    raise RuntimeError("i is None.  WTF?")
100
 
 
101
 
                self.count[i].sort()
102
 
                for e in self.count[i]:
103
 
                    self.sig += "%04x,%d," % (e, i)
104
 
 
105
 
        return self.sig
106
 
 
107
 
 
108
 
    def is_set( self ):
109
 
        return self.mode
110
 
 
111
 
 
112
 
    def PrintUsingTable(self):
113
 
        """Emit the body of the __gl*_size function using a pair
114
 
        of look-up tables and a mask.  The mask is calculated such
115
 
        that (e & mask) is unique for all the valid values of e for
116
 
        this function.  The result of (e & mask) is used as an index
117
 
        into the first look-up table.  If it matches e, then the
118
 
        same entry of the second table is returned.  Otherwise zero
119
 
        is returned.
120
 
 
121
 
        It seems like this should cause better code to be generated.
122
 
        However, on x86 at least, the resulting .o file is about 20%
123
 
        larger then the switch-statment version.  I am leaving this
124
 
        code in because the results may be different on other
125
 
        platforms (e.g., PowerPC or x86-64)."""
126
 
 
127
 
        return 0
128
 
        count = 0
129
 
        for a in self.enums:
130
 
            count += 1
131
 
 
132
 
        if -1 in self.count:
133
 
            return 0
134
 
 
135
 
        # Determine if there is some mask M, such that M = (2^N) - 1,
136
 
        # that will generate unique values for all of the enums.
137
 
 
138
 
        mask = 0
139
 
        for i in [1, 2, 3, 4, 5, 6, 7, 8]:
140
 
            mask = (1 << i) - 1
141
 
 
142
 
            fail = 0;
143
 
            for a in self.enums:
144
 
                for b in self.enums:
145
 
                    if a != b:
146
 
                        if (a & mask) == (b & mask):
147
 
                            fail = 1;
148
 
 
149
 
            if not fail:
150
 
                break;
151
 
            else:
152
 
                mask = 0
153
 
 
154
 
        if (mask != 0) and (mask < (2 * count)):
155
 
            masked_enums = {}
156
 
            masked_count = {}
157
 
 
158
 
            for i in range(0, mask + 1):
159
 
                masked_enums[i] = "0";
160
 
                masked_count[i] = 0;
161
 
 
162
 
            for c in self.count:
163
 
                for e in self.count[c]:
164
 
                    i = e & mask
165
 
                    enum_obj = self.enums[e][0]
166
 
                    masked_enums[i] = '0x%04x /* %s */' % (e, enum_obj.name )
167
 
                    masked_count[i] = c
168
 
 
169
 
 
170
 
            print('    static const GLushort a[%u] = {' % (mask + 1))
171
 
            for e in masked_enums:
172
 
                print('        %s, ' % (masked_enums[e]))
173
 
            print('    };')
174
 
 
175
 
            print('    static const GLubyte b[%u] = {' % (mask + 1))
176
 
            for c in masked_count:
177
 
                print('        %u, ' % (masked_count[c]))
178
 
            print('    };')
179
 
 
180
 
            print('    const unsigned idx = (e & 0x%02xU);' % (mask))
181
 
            print('')
182
 
            print('    return (e == a[idx]) ? (GLint) b[idx] : 0;')
183
 
            return 1;
184
 
        else:
185
 
            return 0;
186
 
 
187
 
 
188
 
    def PrintUsingSwitch(self, name):
189
 
        """Emit the body of the __gl*_size function using a 
190
 
        switch-statement."""
191
 
 
192
 
        print('    switch( e ) {')
193
 
 
194
 
        for c in sorted(self.count):
195
 
            for e in self.count[c]:
196
 
                first = 1
197
 
 
198
 
                # There may be multiple enums with the same
199
 
                # value.  This happens has extensions are
200
 
                # promoted from vendor-specific or EXT to
201
 
                # ARB and to the core.  Emit the first one as
202
 
                # a case label, and emit the others as
203
 
                # commented-out case labels.
204
 
 
205
 
                list = {}
206
 
                for enum_obj in self.enums[e]:
207
 
                    list[ enum_obj.priority() ] = enum_obj.name
208
 
 
209
 
                keys = sorted(list.keys())
210
 
                for k in keys:
211
 
                    j = list[k]
212
 
                    if first:
213
 
                        print('        case GL_%s:' % (j))
214
 
                        first = 0
215
 
                    else:
216
 
                        print('/*      case GL_%s:*/' % (j))
217
 
 
218
 
            if c == -1:
219
 
                print('            return __gl%s_variable_size( e );' % (name))
220
 
            else:
221
 
                print('            return %u;' % (c))
222
 
 
223
 
        print('        default: return 0;')
224
 
        print('    }')
225
 
 
226
 
 
227
 
    def Print(self, name):
228
 
        print('_X_INTERNAL PURE FASTCALL GLint')
229
 
        print('__gl%s_size( GLenum e )' % (name))
230
 
        print('{')
231
 
 
232
 
        if not self.PrintUsingTable():
233
 
            self.PrintUsingSwitch(name)
234
 
 
235
 
        print('}')
236
 
        print('')
237
 
 
238
 
 
239
 
class glx_server_enum_function(glx_enum_function):
240
 
    def __init__(self, func, enum_dict):
241
 
        glx_enum_function.__init__(self, func.name, enum_dict)
242
 
 
243
 
        self.function = func
244
 
        return
245
 
 
246
 
 
247
 
    def signature( self ):
248
 
        if self.sig == None:
249
 
            sig = glx_enum_function.signature(self)
250
 
 
251
 
            p = self.function.variable_length_parameter()
252
 
            if p:
253
 
                sig += "%u" % (p.size())
254
 
 
255
 
            self.sig = sig
256
 
 
257
 
        return self.sig;
258
 
 
259
 
 
260
 
    def Print(self, name, printer):
261
 
        f = self.function
262
 
        printer.common_func_print_just_header( f )
263
 
 
264
 
        fixup = []
265
 
 
266
 
        foo = {}
267
 
        for param_name in f.count_parameter_list:
268
 
            o = f.offset_of( param_name )
269
 
            foo[o] = param_name
270
 
 
271
 
        for param_name in f.counter_list:
272
 
            o = f.offset_of( param_name )
273
 
            foo[o] = param_name
274
 
 
275
 
        keys = sorted(foo.keys())
276
 
        for o in keys:
277
 
            p = f.parameters_by_name[ foo[o] ]
278
 
 
279
 
            printer.common_emit_one_arg(p, "pc", 0)
280
 
            fixup.append( p.name )
281
 
 
282
 
 
283
 
        print('    GLsizei compsize;')
284
 
        print('')
285
 
 
286
 
        printer.common_emit_fixups(fixup)
287
 
 
288
 
        print('')
289
 
        print('    compsize = __gl%s_size(%s);' % (f.name, string.join(f.count_parameter_list, ",")))
290
 
        p = f.variable_length_parameter()
291
 
        print('    return safe_pad(%s);' % (p.size_string()))
292
 
 
293
 
        print('}')
294
 
        print('')
295
 
 
296
 
 
297
 
class PrintGlxSizeStubs_common(gl_XML.gl_print_base):
298
 
    do_get = (1 << 0)
299
 
    do_set = (1 << 1)
300
 
 
301
 
    def __init__(self, which_functions):
302
 
        gl_XML.gl_print_base.__init__(self)
303
 
 
304
 
        self.name = "glX_proto_size.py (from Mesa)"
305
 
        self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2004", "IBM")
306
 
 
307
 
        self.emit_set = ((which_functions & PrintGlxSizeStubs_common.do_set) != 0)
308
 
        self.emit_get = ((which_functions & PrintGlxSizeStubs_common.do_get) != 0)
309
 
        return
310
 
 
311
 
 
312
 
class PrintGlxSizeStubs_c(PrintGlxSizeStubs_common):
313
 
    def printRealHeader(self):
314
 
        print('')
315
 
        print('#include <X11/Xfuncproto.h>')
316
 
        print('#include <GL/gl.h>')
317
 
        if self.emit_get:
318
 
            print('#include "indirect_size_get.h"')
319
 
            print('#include "glxserver.h"')
320
 
            print('#include "indirect_util.h"')
321
 
 
322
 
        print('#include "indirect_size.h"')
323
 
 
324
 
        print('')
325
 
        self.printPure()
326
 
        print('')
327
 
        self.printFastcall()
328
 
        print('')
329
 
        print('')
330
 
        print('#ifdef HAVE_FUNC_ATTRIBUTE_ALIAS')
331
 
        print('#  define ALIAS2(from,to) \\')
332
 
        print('    _X_INTERNAL PURE FASTCALL GLint __gl ## from ## _size( GLenum e ) \\')
333
 
        print('        __attribute__ ((alias( # to )));')
334
 
        print('#  define ALIAS(from,to) ALIAS2( from, __gl ## to ## _size )')
335
 
        print('#else')
336
 
        print('#  define ALIAS(from,to) \\')
337
 
        print('    _X_INTERNAL PURE FASTCALL GLint __gl ## from ## _size( GLenum e ) \\')
338
 
        print('    { return __gl ## to ## _size( e ); }')
339
 
        print('#endif')
340
 
        print('')
341
 
        print('')
342
 
 
343
 
 
344
 
    def printBody(self, api):
345
 
        enum_sigs = {}
346
 
        aliases = []
347
 
 
348
 
        for func in api.functionIterateGlx():
349
 
            ef = glx_enum_function( func.name, api.enums_by_name )
350
 
            if len(ef.enums) == 0:
351
 
                continue
352
 
 
353
 
            if (ef.is_set() and self.emit_set) or (not ef.is_set() and self.emit_get):
354
 
                sig = ef.signature()
355
 
                if sig in enum_sigs:
356
 
                    aliases.append( [func.name, enum_sigs[ sig ]] )
357
 
                else:
358
 
                    enum_sigs[ sig ] = func.name
359
 
                    ef.Print( func.name )
360
 
 
361
 
 
362
 
        for [alias_name, real_name] in aliases:
363
 
            print('ALIAS( %s, %s )' % (alias_name, real_name))
364
 
 
365
 
 
366
 
 
367
 
class PrintGlxSizeStubs_h(PrintGlxSizeStubs_common):
368
 
    def printRealHeader(self):
369
 
        print("""/**
370
 
 * \\file
371
 
 * Prototypes for functions used to determine the number of data elements in
372
 
 * various GLX protocol messages.
373
 
 *
374
 
 * \\author Ian Romanick <idr@us.ibm.com>
375
 
 */
376
 
""")
377
 
        print('#include <X11/Xfuncproto.h>')
378
 
        print('')
379
 
        self.printPure();
380
 
        print('')
381
 
        self.printFastcall();
382
 
        print('')
383
 
 
384
 
 
385
 
    def printBody(self, api):
386
 
        for func in api.functionIterateGlx():
387
 
            ef = glx_enum_function( func.name, api.enums_by_name )
388
 
            if len(ef.enums) == 0:
389
 
                continue
390
 
 
391
 
            if (ef.is_set() and self.emit_set) or (not ef.is_set() and self.emit_get):
392
 
                print('extern _X_INTERNAL PURE FASTCALL GLint __gl%s_size(GLenum);' % (func.name))
393
 
 
394
 
 
395
 
class PrintGlxReqSize_common(gl_XML.gl_print_base):
396
 
    """Common base class for PrintGlxSizeReq_h and PrintGlxSizeReq_h.
397
 
 
398
 
    The main purpose of this common base class is to provide the infrastructure
399
 
    for the derrived classes to iterate over the same set of functions.
400
 
    """
401
 
 
402
 
    def __init__(self):
403
 
        gl_XML.gl_print_base.__init__(self)
404
 
 
405
 
        self.name = "glX_proto_size.py (from Mesa)"
406
 
        self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2005", "IBM")
407
 
 
408
 
 
409
 
class PrintGlxReqSize_h(PrintGlxReqSize_common):
410
 
    def __init__(self):
411
 
        PrintGlxReqSize_common.__init__(self)
412
 
        self.header_tag = "_INDIRECT_REQSIZE_H_"
413
 
 
414
 
 
415
 
    def printRealHeader(self):
416
 
        print('#include <X11/Xfuncproto.h>')
417
 
        print('')
418
 
        self.printPure()
419
 
        print('')
420
 
 
421
 
 
422
 
    def printBody(self, api):
423
 
        for func in api.functionIterateGlx():
424
 
            if not func.ignore and func.has_variable_size_request():
425
 
                print('extern PURE _X_HIDDEN int __glX%sReqSize(const GLbyte *pc, Bool swap, int reqlen);' % (func.name))
426
 
 
427
 
 
428
 
class PrintGlxReqSize_c(PrintGlxReqSize_common):
429
 
    """Create the server-side 'request size' functions.
430
 
 
431
 
    Create the server-side functions that are used to determine what the
432
 
    size of a varible length command should be.  The server then uses
433
 
    this value to determine if the incoming command packed it malformed.
434
 
    """
435
 
 
436
 
    def __init__(self):
437
 
        PrintGlxReqSize_common.__init__(self)
438
 
        self.counter_sigs = {}
439
 
 
440
 
 
441
 
    def printRealHeader(self):
442
 
        print('')
443
 
        print('#include <GL/gl.h>')
444
 
        print('#include "glxserver.h"')
445
 
        print('#include "glxbyteorder.h"')
446
 
        print('#include "indirect_size.h"')
447
 
        print('#include "indirect_reqsize.h"')
448
 
        print('')
449
 
        print('#ifdef HAVE_FUNC_ATTRIBUTE_ALIAS')
450
 
        print('#  define ALIAS2(from,to) \\')
451
 
        print('    GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap, int reqlen ) \\')
452
 
        print('        __attribute__ ((alias( # to )));')
453
 
        print('#  define ALIAS(from,to) ALIAS2( from, __glX ## to ## ReqSize )')
454
 
        print('#else')
455
 
        print('#  define ALIAS(from,to) \\')
456
 
        print('    GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap, int reqlen ) \\')
457
 
        print('    { return __glX ## to ## ReqSize( pc, swap, reqlen ); }')
458
 
        print('#endif')
459
 
        print('')
460
 
        print('')
461
 
 
462
 
 
463
 
    def printBody(self, api):
464
 
        aliases = []
465
 
        enum_functions = {}
466
 
        enum_sigs = {}
467
 
 
468
 
        for func in api.functionIterateGlx():
469
 
            if not func.has_variable_size_request(): continue
470
 
 
471
 
            ef = glx_server_enum_function( func, api.enums_by_name )
472
 
            if len(ef.enums) == 0: continue
473
 
 
474
 
            sig = ef.signature()
475
 
 
476
 
            if func.name not in enum_functions:
477
 
                enum_functions[ func.name ] = sig
478
 
 
479
 
            if sig not in enum_sigs:
480
 
                enum_sigs[ sig ] = ef
481
 
 
482
 
 
483
 
 
484
 
        for func in api.functionIterateGlx():
485
 
            # Even though server-handcode fuctions are on "the
486
 
            # list", and prototypes are generated for them, there
487
 
            # isn't enough information to generate a size
488
 
            # function.  If there was enough information, they
489
 
            # probably wouldn't need to be handcoded in the first
490
 
            # place!
491
 
 
492
 
            if func.server_handcode: continue
493
 
            if not func.has_variable_size_request(): continue
494
 
 
495
 
            if func.name in enum_functions:
496
 
                sig = enum_functions[func.name]
497
 
                ef = enum_sigs[ sig ]
498
 
 
499
 
                if ef.name != func.name:
500
 
                    aliases.append( [func.name, ef.name] )
501
 
                else:
502
 
                    ef.Print( func.name, self )
503
 
 
504
 
            elif func.images:
505
 
                self.printPixelFunction(func)
506
 
            elif func.has_variable_size_request():
507
 
                a = self.printCountedFunction(func)
508
 
                if a: aliases.append(a)
509
 
 
510
 
 
511
 
        for [alias_name, real_name] in aliases:
512
 
            print('ALIAS( %s, %s )' % (alias_name, real_name))
513
 
 
514
 
        return
515
 
 
516
 
 
517
 
    def common_emit_fixups(self, fixup):
518
 
        """Utility function to emit conditional byte-swaps."""
519
 
 
520
 
        if fixup:
521
 
            print('    if (swap) {')
522
 
            for name in fixup:
523
 
                print('        %s = bswap_32(%s);' % (name, name))
524
 
            print('    }')
525
 
 
526
 
        return
527
 
 
528
 
 
529
 
    def common_emit_one_arg(self, p, pc, adjust):
530
 
        offset = p.offset
531
 
        dst = p.string()
532
 
        src = '(%s *)' % (p.type_string())
533
 
        print('%-18s = *%11s(%s + %u);' % (dst, src, pc, offset + adjust));
534
 
        return
535
 
 
536
 
 
537
 
    def common_func_print_just_header(self, f):
538
 
        print('int')
539
 
        print('__glX%sReqSize( const GLbyte * pc, Bool swap, int reqlen )' % (f.name))
540
 
        print('{')
541
 
 
542
 
 
543
 
    def printPixelFunction(self, f):
544
 
        self.common_func_print_just_header(f)
545
 
 
546
 
        f.offset_of( f.parameters[0].name )
547
 
        [dim, w, h, d, junk] = f.get_images()[0].get_dimensions()
548
 
 
549
 
        print('    GLint row_length   = *  (GLint *)(pc +  4);')
550
 
 
551
 
        if dim < 3:
552
 
            fixup = ['row_length', 'skip_rows', 'alignment']
553
 
            print('    GLint image_height = 0;')
554
 
            print('    GLint skip_images  = 0;')
555
 
            print('    GLint skip_rows    = *  (GLint *)(pc +  8);')
556
 
            print('    GLint alignment    = *  (GLint *)(pc + 16);')
557
 
        else:
558
 
            fixup = ['row_length', 'image_height', 'skip_rows', 'skip_images', 'alignment']
559
 
            print('    GLint image_height = *  (GLint *)(pc +  8);')
560
 
            print('    GLint skip_rows    = *  (GLint *)(pc + 16);')
561
 
            print('    GLint skip_images  = *  (GLint *)(pc + 20);')
562
 
            print('    GLint alignment    = *  (GLint *)(pc + 32);')
563
 
 
564
 
        img = f.images[0]
565
 
        for p in f.parameterIterateGlxSend():
566
 
            if p.name in [w, h, d, img.img_format, img.img_type, img.img_target]:
567
 
                self.common_emit_one_arg(p, "pc", 0)
568
 
                fixup.append( p.name )
569
 
 
570
 
        print('')
571
 
 
572
 
        self.common_emit_fixups(fixup)
573
 
 
574
 
        if img.img_null_flag:
575
 
            print('')
576
 
            print('        if (*(CARD32 *) (pc + %s))' % (img.offset - 4))
577
 
            print('            return 0;')
578
 
 
579
 
        print('')
580
 
        print('    return __glXImageSize(%s, %s, %s, %s, %s, %s,' % (img.img_format, img.img_type, img.img_target, w, h, d ))
581
 
        print('                          image_height, row_length, skip_images,')
582
 
        print('                          skip_rows, alignment);')
583
 
        print('}')
584
 
        print('')
585
 
        return
586
 
 
587
 
 
588
 
    def printCountedFunction(self, f):
589
 
 
590
 
        sig = ""
591
 
        offset = 0
592
 
        fixup = []
593
 
        params = []
594
 
        size = ''
595
 
        param_offsets = {}
596
 
 
597
 
        # Calculate the offset of each counter parameter and the
598
 
        # size string for the variable length parameter(s).  While
599
 
        # that is being done, calculate a unique signature for this
600
 
        # function.
601
 
 
602
 
        for p in f.parameterIterateGlxSend():
603
 
            if p.is_counter:
604
 
                fixup.append( p.name )
605
 
                params.append( p )
606
 
            elif p.counter:
607
 
                s = p.size()
608
 
                if s == 0: s = 1
609
 
 
610
 
                sig += "(%u,%u)" % (f.offset_of(p.counter), s)
611
 
                if size == '':
612
 
                    size = p.size_string()
613
 
                else:
614
 
                    size = "safe_add(%s, %s)" % (size, p.size_string())
615
 
 
616
 
        # If the calculated signature matches a function that has
617
 
        # already be emitted, don't emit this function.  Instead, add
618
 
        # it to the list of function aliases.
619
 
 
620
 
        if sig in self.counter_sigs:
621
 
            n = self.counter_sigs[sig];
622
 
            alias = [f.name, n]
623
 
        else:
624
 
            alias = None
625
 
            self.counter_sigs[sig] = f.name
626
 
 
627
 
            self.common_func_print_just_header(f)
628
 
 
629
 
            for p in params:
630
 
                self.common_emit_one_arg(p, "pc", 0)
631
 
 
632
 
 
633
 
            print('')
634
 
            self.common_emit_fixups(fixup)
635
 
            print('')
636
 
 
637
 
            print('    return safe_pad(%s);' % (size))
638
 
            print('}')
639
 
            print('')
640
 
 
641
 
        return alias
642
 
 
643
 
 
644
 
def _parser():
645
 
    """Parse arguments and return a namespace."""
646
 
    parser = argparse.ArgumentParser()
647
 
    parser.set_defaults(which_functions=(PrintGlxSizeStubs_common.do_get |
648
 
                                         PrintGlxSizeStubs_common.do_set))
649
 
    parser.add_argument('-f',
650
 
                        dest='filename',
651
 
                        default='gl_API.xml',
652
 
                        help='an XML file describing an OpenGL API.')
653
 
    parser.add_argument('-m',
654
 
                        dest='mode',
655
 
                        choices=['size_c', 'size_h', 'reqsize_c', 'reqsize_h'],
656
 
                        help='Which file to generate')
657
 
    getset = parser.add_mutually_exclusive_group()
658
 
    getset.add_argument('--only-get',
659
 
                        dest='which_functions',
660
 
                        action='store_const',
661
 
                        const=PrintGlxSizeStubs_common.do_get,
662
 
                        help='only emit "get-type" functions')
663
 
    getset.add_argument('--only-set',
664
 
                        dest='which_functions',
665
 
                        action='store_const',
666
 
                        const=PrintGlxSizeStubs_common.do_set,
667
 
                        help='only emit "set-type" functions')
668
 
    parser.add_argument('--header-tag',
669
 
                        dest='header_tag',
670
 
                        action='store',
671
 
                        default=None,
672
 
                        help='set header tag value')
673
 
    return parser.parse_args()
674
 
 
675
 
 
676
 
def main():
677
 
    """Main function."""
678
 
    args = _parser()
679
 
 
680
 
    if args.mode == "size_c":
681
 
        printer = PrintGlxSizeStubs_c(args.which_functions)
682
 
    elif args.mode == "size_h":
683
 
        printer = PrintGlxSizeStubs_h(args.which_functions)
684
 
        if args.header_tag is not None:
685
 
            printer.header_tag = args.header_tag
686
 
    elif args.mode == "reqsize_c":
687
 
        printer = PrintGlxReqSize_c()
688
 
    elif args.mode == "reqsize_h":
689
 
        printer = PrintGlxReqSize_h()
690
 
 
691
 
    api = gl_XML.parse_GL_API(args.filename, glX_XML.glx_item_factory())
692
 
 
693
 
    printer.Print(api)
694
 
 
695
 
 
696
 
if __name__ == '__main__':
697
 
    main()