apple: Remove apple_glx_get_proc_address
[profile/ivi/mesa.git] / src / glx / apple / gen_funcs.tcl
1 package require Tcl 8.5
2
3 #input is specs/gl.spec
4
5 set license {
6 /*
7  Copyright (c) 2008, 2009 Apple Inc.
8  
9  Permission is hereby granted, free of charge, to any person
10  obtaining a copy of this software and associated documentation files
11  (the "Software"), to deal in the Software without restriction,
12  including without limitation the rights to use, copy, modify, merge,
13  publish, distribute, sublicense, and/or sell copies of the Software,
14  and to permit persons to whom the Software is furnished to do so,
15  subject to the following conditions:
16  
17  The above copyright notice and this permission notice shall be
18  included in all copies or substantial portions of the Software.
19  
20  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23  NONINFRINGEMENT.  IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
24  HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  DEALINGS IN THE SOFTWARE.
28  
29  Except as contained in this notice, the name(s) of the above
30  copyright holders shall not be used in advertising or otherwise to
31  promote the sale, use or other dealings in this Software without
32  prior written authorization.
33 */
34 }
35
36
37 proc extension name {
38     global extensions
39
40     set extensions($name) 1
41 }
42
43 proc alias {from to} {
44     global aliases
45     
46     set aliases($from) $to
47 }
48
49 proc promoted name {
50     global promoted
51
52     set promoted($name) 1
53 }
54
55 proc noop name {
56     global noop
57     
58     set noop($name) 1
59 }
60
61 set dir [file dirname [info script]]
62
63 source [file join $dir GL_extensions]
64 source [file join $dir GL_aliases]
65 source [file join $dir GL_promoted]
66 source [file join $dir GL_noop]
67
68 proc is-extension-supported? name {
69     global extensions
70
71     return [info exists extensions($name)]
72 }
73
74 # This is going to need to be updated for future OpenGL versions:
75 #    cat specs/gl.tm  | grep -v '^#' | awk -F, '{sub(/[ \t]+/, ""); print "    "$1 " \"" $4 "\""}'
76 #    then change void from "*" to "void"
77 #
78 # TextureComponentCount is GLenum in SL for everything
79 # It is GLint in mesa, but is GLenum for glTexImage3DEXT
80 array set typemap {
81     AccumOp "GLenum"
82     AlphaFunction "GLenum"
83     AttribMask "GLbitfield"
84     BeginMode "GLenum"
85     BinormalPointerTypeEXT "GLenum"
86     BlendEquationMode "GLenum"
87     BlendEquationModeEXT "GLenum"
88     BlendFuncSeparateParameterEXT "GLenum"
89     BlendingFactorDest "GLenum"
90     BlendingFactorSrc "GLenum"
91     Boolean "GLboolean"
92     BooleanPointer "GLboolean*"
93     Char "GLchar"
94     CharPointer "GLchar*"
95     CheckedFloat32 "GLfloat"
96     CheckedInt32 "GLint"
97     ClampColorTargetARB "GLenum"
98     ClampColorModeARB "GLenum"
99     ClampedColorF "GLclampf"
100     ClampedFloat32 "GLclampf"
101     ClampedFloat64 "GLclampd"
102     ClampedStencilValue "GLint"
103     ClearBufferMask "GLbitfield"
104     ClientAttribMask "GLbitfield"
105     ClipPlaneName "GLenum"
106     ColorB "GLbyte"
107     ColorD "GLdouble"
108     ColorF "GLfloat"
109     ColorI "GLint"
110     ColorIndexValueD "GLdouble"
111     ColorIndexValueF "GLfloat"
112     ColorIndexValueI "GLint"
113     ColorIndexValueS "GLshort"
114     ColorIndexValueUB "GLubyte"
115     ColorMaterialParameter "GLenum"
116     ColorPointerType "GLenum"
117     ColorS "GLshort"
118     ColorTableParameterPName "GLenum"
119     ColorTableParameterPNameSGI "GLenum"
120     ColorTableTarget "GLenum"
121     ColorTableTargetSGI "GLenum"
122     ColorUB "GLubyte"
123     ColorUI "GLuint"
124     ColorUS "GLushort"
125     CombinerBiasNV "GLenum"
126     CombinerComponentUsageNV "GLenum"
127     CombinerMappingNV "GLenum"
128     CombinerParameterNV "GLenum"
129     CombinerPortionNV "GLenum"
130     CombinerRegisterNV "GLenum"
131     CombinerScaleNV "GLenum"
132     CombinerStageNV "GLenum"
133     CombinerVariableNV "GLenum"
134     CompressedTextureARB "GLvoid"
135     ControlPointNV "GLvoid"
136     ControlPointTypeNV "GLenum"
137     ConvolutionParameter "GLenum"
138     ConvolutionParameterEXT "GLenum"
139     ConvolutionTarget "GLenum"
140     ConvolutionTargetEXT "GLenum"
141     CoordD "GLdouble"
142     CoordF "GLfloat"
143     CoordI "GLint"
144     CoordS "GLshort"
145     CullFaceMode "GLenum"
146     CullParameterEXT "GLenum"
147     DepthFunction "GLenum"
148     DrawBufferMode "GLenum"
149     DrawBufferName "GLint"
150     DrawElementsType "GLenum"
151     ElementPointerTypeATI "GLenum"
152     EnableCap "GLenum"
153     ErrorCode "GLenum"
154     EvalMapsModeNV "GLenum"
155     EvalTargetNV "GLenum"
156     FeedbackElement "GLfloat"
157     FeedbackType "GLenum"
158     FenceNV "GLuint"
159     FenceConditionNV "GLenum"
160     FenceParameterNameNV "GLenum"
161     FfdMaskSGIX "GLbitfield"
162     FfdTargetSGIX "GLenum"
163     Float32 "GLfloat"
164     Float32Pointer "GLfloat*"
165     Float64 "GLdouble"
166     Float64Pointer "GLdouble*"
167     FogParameter "GLenum"
168     FogPointerTypeEXT "GLenum"
169     FogPointerTypeIBM "GLenum"
170     FragmentLightModelParameterSGIX "GLenum"
171     FragmentLightNameSGIX "GLenum"
172     FragmentLightParameterSGIX "GLenum"
173     FramebufferAttachment "GLenum"
174     FramebufferTarget "GLenum"
175     FrontFaceDirection "GLenum"
176     FunctionPointer "_GLfuncptr"
177     GetColorTableParameterPName "GLenum"
178     GetColorTableParameterPNameSGI "GLenum"
179     GetConvolutionParameterPName "GLenum"
180     GetHistogramParameterPName "GLenum"
181     GetHistogramParameterPNameEXT "GLenum"
182     GetMapQuery "GLenum"
183     GetMinmaxParameterPName "GLenum"
184     GetMinmaxParameterPNameEXT "GLenum"
185     GetPName "GLenum"
186     GetPointervPName "GLenum"
187     GetTextureParameter "GLenum"
188     HintMode "GLenum"
189     HintTarget "GLenum"
190     HintTargetPGI "GLenum"
191     HistogramTarget "GLenum"
192     HistogramTargetEXT "GLenum"
193     IglooFunctionSelectSGIX "GLenum"
194     IglooParameterSGIX "GLvoid"
195     ImageTransformPNameHP "GLenum"
196     ImageTransformTargetHP "GLenum"
197     IndexFunctionEXT "GLenum"
198     IndexMaterialParameterEXT "GLenum"
199     IndexPointerType "GLenum"
200     Int16 "GLshort"
201     Int32 "GLint"
202     Int8 "GLbyte"
203     InterleavedArrayFormat "GLenum"
204     LightEnvParameterSGIX "GLenum"
205     LightModelParameter "GLenum"
206     LightName "GLenum"
207     LightParameter "GLenum"
208     LightTextureModeEXT "GLenum"
209     LightTexturePNameEXT "GLenum"
210     LineStipple "GLushort"
211     List "GLuint"
212     ListMode "GLenum"
213     ListNameType "GLenum"
214     ListParameterName "GLenum"
215     LogicOp "GLenum"
216     MapAttribParameterNV "GLenum"
217     MapParameterNV "GLenum"
218     MapTarget "GLenum"
219     MapTargetNV "GLenum"
220     MapTypeNV "GLenum"
221     MaskedColorIndexValueF "GLfloat"
222     MaskedColorIndexValueI "GLuint"
223     MaskedStencilValue "GLuint"
224     MaterialFace "GLenum"
225     MaterialParameter "GLenum"
226     MatrixIndexPointerTypeARB "GLenum"
227     MatrixMode "GLenum"
228     MatrixTransformNV "GLenum"
229     MeshMode1 "GLenum"
230     MeshMode2 "GLenum"
231     MinmaxTarget "GLenum"
232     MinmaxTargetEXT "GLenum"
233     NormalPointerType "GLenum"
234     NurbsCallback "GLenum"
235     NurbsObj "GLUnurbs*"
236     NurbsProperty "GLenum"
237     NurbsTrim "GLenum"
238     OcclusionQueryParameterNameNV "GLenum"
239     PixelCopyType "GLenum"
240     PixelFormat "GLenum"
241     PixelInternalFormat "GLenum"
242     PixelMap "GLenum"
243     PixelStoreParameter "GLenum"
244     PixelTexGenModeSGIX "GLenum"
245     PixelTexGenParameterNameSGIS "GLenum"
246     PixelTransferParameter "GLenum"
247     PixelTransformPNameEXT "GLenum"
248     PixelTransformTargetEXT "GLenum"
249     PixelType "GLenum"
250     PointParameterNameARB "GLenum"
251     PolygonMode "GLenum"
252     ProgramNV "GLuint"
253     ProgramCharacterNV "GLubyte"
254     ProgramParameterNV "GLenum"
255     ProgramParameterPName "GLenum"
256     QuadricCallback "GLenum"
257     QuadricDrawStyle "GLenum"
258     QuadricNormal "GLenum"
259     QuadricObj "GLUquadric*"
260     QuadricOrientation "GLenum"
261     ReadBufferMode "GLenum"
262     RenderbufferTarget "GLenum"
263     RenderingMode "GLenum"
264     ReplacementCodeSUN "GLuint"
265     ReplacementCodeTypeSUN "GLenum"
266     SamplePassARB "GLenum"
267     SamplePatternEXT "GLenum"
268     SamplePatternSGIS "GLenum"
269     SecondaryColorPointerTypeIBM "GLenum"
270     SelectName "GLuint"
271     SeparableTarget "GLenum"
272     SeparableTargetEXT "GLenum"
273     ShadingModel "GLenum"
274     SizeI "GLsizei"
275     SpriteParameterNameSGIX "GLenum"
276     StencilFunction "GLenum"
277     StencilFaceDirection "GLenum"
278     StencilOp "GLenum"
279     StencilValue "GLint"
280     String "const GLubyte *"
281     StringName "GLenum"
282     TangentPointerTypeEXT "GLenum"
283     TessCallback "GLenum"
284     TessContour "GLenum"
285     TessProperty "GLenum"
286     TesselatorObj "GLUtesselator*"
287     TexCoordPointerType "GLenum"
288     Texture "GLuint"
289     TextureComponentCount "GLint"
290     TextureCoordName "GLenum"
291     TextureEnvParameter "GLenum"
292     TextureEnvTarget "GLenum"
293     TextureFilterSGIS "GLenum"
294     TextureGenParameter "GLenum"
295     TextureNormalModeEXT "GLenum"
296     TextureParameterName "GLenum"
297     TextureTarget "GLenum"
298     TextureUnit "GLenum"
299     UInt16 "GLushort"
300     UInt32 "GLuint"
301     UInt8 "GLubyte"
302     VertexAttribEnum "GLenum"
303     VertexAttribEnumNV "GLenum"
304     VertexAttribPointerTypeNV "GLenum"
305     VertexPointerType "GLenum"
306     VertexWeightPointerTypeEXT "GLenum"
307     Void "GLvoid"
308     VoidPointer "GLvoid*"
309     ConstVoidPointer "GLvoid* const"
310     WeightPointerTypeARB "GLenum"
311     WinCoord "GLint"
312     void "void"
313     ArrayObjectPNameATI "GLenum"
314     ArrayObjectUsageATI "GLenum"
315     ConstFloat32 "GLfloat"
316     ConstInt32 "GLint"
317     ConstUInt32 "GLuint"
318     ConstVoid "GLvoid"
319     DataTypeEXT "GLenum"
320     FragmentOpATI "GLenum"
321     GetTexBumpParameterATI "GLenum"
322     GetVariantValueEXT "GLenum"
323     ParameterRangeEXT "GLenum"
324     PreserveModeATI "GLenum"
325     ProgramFormatARB "GLenum"
326     ProgramTargetARB "GLenum"
327     ProgramTarget "GLenum"
328     ProgramPropertyARB "GLenum"
329     ProgramStringPropertyARB "GLenum"
330     ScalarType "GLenum"
331     SwizzleOpATI "GLenum"
332     TexBumpParameterATI "GLenum"
333     VariantCapEXT "GLenum"
334     VertexAttribPointerPropertyARB "GLenum"
335     VertexAttribPointerTypeARB "GLenum"
336     VertexAttribPropertyARB "GLenum"
337     VertexShaderCoordOutEXT "GLenum"
338     VertexShaderOpEXT "GLenum"
339     VertexShaderParameterEXT "GLenum"
340     VertexShaderStorageTypeEXT "GLenum"
341     VertexShaderTextureUnitParameter "GLenum"
342     VertexShaderWriteMaskEXT "GLenum"
343     VertexStreamATI "GLenum"
344     PNTrianglesPNameATI "GLenum"
345     BufferOffset "GLintptr"
346     BufferSize "GLsizeiptr"
347     BufferAccessARB "GLenum"
348     BufferOffsetARB "GLintptrARB"
349     BufferPNameARB "GLenum"
350     BufferPointerNameARB "GLenum"
351     BufferSizeARB "GLsizeiptrARB"
352     BufferTargetARB "GLenum"
353     BufferUsageARB "GLenum"
354     ObjectTypeAPPLE "GLenum"
355     VertexArrayPNameAPPLE "GLenum"
356     DrawBufferModeATI "GLenum"
357     Half16NV "GLhalfNV"
358     PixelDataRangeTargetNV "GLenum"
359     TypeEnum "GLenum"
360     GLbitfield "GLbitfield"
361     GLenum "GLenum"
362     Int64 "GLint64"
363     UInt64 "GLuint64"
364     handleARB "GLhandleARB"
365     charARB "GLcharARB"
366     charPointerARB "GLcharARB*"
367     sync "GLsync"
368     Int64EXT "GLint64EXT"
369     UInt64EXT "GLuint64EXT"
370     FramebufferAttachment "GLenum"
371     FramebufferAttachmentParameterName "GLenum"
372     Framebuffer "GLuint"
373     FramebufferStatus "GLenum"
374     FramebufferTarget "GLenum"
375     GetFramebufferParameter "GLenum"
376     Intptr "GLintptr"
377     ProgramFormat "GLenum"
378     ProgramProperty "GLenum"
379     ProgramStringProperty "GLenum"
380     ProgramTarget "GLenum"
381     Renderbuffer "GLuint"
382     RenderbufferParameterName "GLenum"
383     Sizeiptr "GLsizeiptr"
384     TextureInternalFormat "GLenum"
385     VertexBufferObjectAccess "GLenum"
386     VertexBufferObjectParameter "GLenum"
387     VertexBufferObjectUsage "GLenum"
388     BufferAccessMask "GLbitfield"
389     GetMultisamplePNameNV "GLenum"
390     SampleMaskNV "GLbitfield"
391 }
392
393 proc psplit s {
394     set r [list]
395     set token ""
396
397     foreach c [split $s ""] {
398         if {[string is space -strict $c]} {
399             if {[string length $token]} {
400                 lappend r $token
401             }
402             set token ""
403         } else {
404             append token $c
405         }
406     }
407
408     if {[string length $token]} {
409         lappend r $token
410     }
411
412     return $r
413 }
414
415 proc is-extension? str {
416     #Check if the trailing name of the function is NV, or EXT, and so on.
417     
418     if {[string is upper [string index $str end]]
419         && [string is upper [string index $str end-1]]} {
420         return 1
421     } 
422
423     return 0
424 }
425
426
427 proc parse {data arvar} {
428     upvar 1 $arvar ar
429
430     set state ""
431     set name ""
432
433     foreach line [split $data \n] {
434         if {"attr" eq $state} {
435             if {[string match "\t*" $line]} {
436                 set plist [psplit [lindex [split $line "#"] 0]]
437                 #puts PLIST:$plist
438                 set master $ar($name)
439                 set param [dict get $master parameters]
440
441                 switch -- [llength $plist] {
442                     1 {
443                         dict set master [lindex $plist 0] ""
444                     }
445
446                     2 {
447                         #standard key, value pair
448                         set key [lindex $plist 0]
449                         set value [lindex $plist 1]
450
451                         dict set master $key $value
452                     }
453
454                     default {
455                         set key [lindex $plist 0]
456
457                         #puts PLIST:$plist
458
459                         if {"param" eq $key} {
460                             lappend param [list [lindex $plist 1] [lindex $plist 2] [lindex $plist 3] [lindex $plist 4]]
461                         } else {
462                             dict set master $key [lrange $plist 1 end]
463                         }
464                     }               
465                 }
466                 
467                 dict set master parameters $param
468
469                 set ar($name) $master
470             } else {
471                 set state ""
472             }
473         } elseif {[regexp {^([A-Z_a-z0-9]+)\((.*)\)\S*} $line all name argv] > 0} {
474             #puts "MATCH:$name ARGV:$argv"
475             
476             #Trim the spaces in the elements.
477             set newargv [list]
478             foreach a [split $argv ,] {
479                 lappend newargv [string trim $a]
480             }
481             
482
483             set d [dict create name $name arguments $newargv \
484                        parameters [dict create]]
485             set ar($name) $d
486             set state attr
487         } 
488     }
489 }
490
491 #This returns true if the category is valid for an extension.
492 proc is-valid-category? c {
493     set clist [list display-list drawing drawing-control feedback framebuf misc modeling pixel-op pixel-rw state-req xform VERSION_1_0 VERSION_1_0_DEPRECATED VERSION_1_1 VERSION_1_1_DEPRECATED VERSION_1_2 VERSION_1_2_DEPRECATED VERSION_1_3 VERSION_1_3_DEPRECATED VERSION_1_4 VERSION_1_4_DEPRECATED VERSION_1_5 VERSION_2_0 VERSION_2_1 VERSION_3_0 VERSION_3_0_DEPRECATED VERSION_3_1 VERSION_3_2]
494
495     set result [expr {$c in $clist}]
496
497
498     if {!$result} {
499         set result [is-extension-supported? $c]
500     }
501
502     return $result
503 }
504
505 proc translate-parameters {func parameters} {
506     global typemap
507
508     set newparams [list]
509
510     foreach p $parameters {
511         set var [lindex $p 0]
512         
513         set ptype [lindex $p 1]
514         
515         if {![info exists typemap($ptype)]} {
516             set ::missingTypes($ptype) $func
517             continue
518         }
519         
520         set type $typemap($ptype)
521         
522         if {"array" eq [lindex $p 3]} {
523             if {"in" eq [lindex $p 2]} {
524                 set final_type "const $type *"
525             } else {
526                 set final_type "$type *"
527             }
528         } else {
529             set final_type $type
530         }
531             
532         lappend newparams [list $final_type $var]
533     }
534  
535     return $newparams
536 }
537
538 proc api-new-entry {info func} {
539     global typemap
540
541     set master [dict create]
542     set rettype [dict get $info return]
543     
544     if {![info exists typemap($rettype)]} {
545         set ::missingTypes($rettype) $func
546     } else {
547         dict set master return $typemap($rettype)
548     }
549     
550     dict set master parameters [translate-parameters $func \
551                                     [dict get $info parameters]]
552
553     return $master
554 }
555
556 proc main {argc argv} {
557     global extensions typemap aliases promoted noop
558
559     set fd [open [lindex $argv 0] r]
560     set data [read $fd]
561     close $fd
562   
563     array set ar {}
564     
565     parse $data ar
566     
567     array set newapi {}
568     array set missingTypes {}
569
570     foreach {key value} [array get ar] {
571         puts "KEY:$key VALUE:$value"
572
573         set category [dict get $value category]
574         
575         #Invalidate any of the extensions and things not in the spec we support.
576         set valid [is-valid-category? $category]
577         puts VALID:$valid
578         
579         if {!$valid} {
580            continue
581         }
582
583         puts "VALID:$key"
584
585         if {"BlitFramebuffer" eq $key} {
586             #This was promoted to an ARB extension after Leopard it seems.
587             set key BlitFramebufferEXT
588         }
589
590         if {"ARB_framebuffer_object" eq $category} {
591             #This wasn't an ARB extension in Leopard either.
592             if {![string match *EXT $key]} {
593                 append key EXT
594             }
595         }
596
597         set newapi($key) [api-new-entry $value $key]
598     }
599
600     #Now iterate and support as many aliases as we can for promoted functions
601     #based on if the newapi contains the function.
602     foreach {func value} [array get ar] {
603         if {![info exists promoted([dict get $value category])]} {
604             continue
605         }
606
607         if {[dict exists $value alias]} {
608             #We have an alias.  Let's see if we have the implementation.
609             set alias [dict get $value alias]
610
611             if {[info exists newapi($alias)] && ![info exists newapi($func)]} {
612                 #We have an implementing function available.
613                 puts "HAVE:$key ALIAS:$alias"
614
615                 set master [api-new-entry $value $func]
616                 dict set master alias_for $alias
617                 set newapi($func) $master               
618             }
619         }
620     } 
621
622     parray noop
623
624     #Now handle the no-op compatibility categories.
625     foreach {func value} [array get ar] {
626         if {[info exists noop([dict get $value category])]} {
627             if {[info exists newapi($func)]} {
628                 puts stderr "$func shouldn't be a noop"
629                 exit 1
630             }
631             
632             set master [api-new-entry $value $func]
633             dict set master noop 1
634             set newapi($func) $master
635         }
636     }
637
638     
639
640     parray newapi
641
642     if {[array size ::missingTypes]} {
643         parray ::missingTypes
644         return 1
645     }
646
647     foreach {from to} [array get aliases] {
648         set d $newapi($to)
649         dict set d alias_for $to
650         set newapi($from) $d
651     }
652
653     #Iterate the nm output and set each symbol in an associative array.
654     array set validapi {}
655
656     foreach line [split [exec nm -j -g /System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib] \n] {
657         set fn [string trim $line]
658
659         #Only match the _gl functions.
660         if {[string match _gl* $fn]} {
661             set finalfn [string range $fn 3 end]
662             puts FINALFN:$finalfn
663             set validapi($finalfn) $finalfn
664         }
665     }
666
667     puts "Correcting the API functions to match the OpenGL framework."
668     #parray validapi
669     
670     #Iterate the newapi and unset any members that the
671     #libGL.dylib doesn't support, assuming they aren't no-ops.
672     foreach fn [array names newapi] {
673         if {![info exists validapi($fn)]} {
674             puts "WARNING: libGL.dylib lacks support for: $fn"
675
676             if {[dict exists $newapi($fn) noop] 
677                 && [dict get $newapi($fn) noop]} {
678                 #This is no-op, so we should skip it.
679                 continue
680             }
681
682             #Is the function an alias for another in libGL?
683             if {[dict exists $newapi($fn) alias_for]} {
684                 set alias [dict get $newapi($fn) alias_for]
685
686                 if {![info exists validapi($alias)]} {
687                     puts "WARNING: alias function doesn't exist for $fn."
688                     puts "The alias is $alias."
689                     puts "unsetting $fn"                    
690                     unset newapi($fn)
691                 } 
692             } else {
693                 puts "unsetting $fn"
694                 unset newapi($fn)
695             }
696         }
697     }
698
699     
700     #Now print a warning about any symbols that libGL supports that we don't.
701     foreach fn [array names validapi] {
702         if {![info exists newapi($fn)]} {
703             puts "AppleSGLX is missing $fn"
704         }
705     }
706
707     puts "NOW GENERATING:[lindex $::argv 1]"
708     set fd [open [lindex $::argv 1] w]
709
710     set sorted [lsort -dictionary [array names newapi]]
711
712     foreach f $sorted {
713         set attr $newapi($f)
714         set pstr ""
715         foreach p [dict get $attr parameters] {
716             append pstr "[lindex $p 0] [lindex $p 1], "
717         }
718         set pstr [string trimright $pstr ", "]
719         puts $fd "[dict get $attr return] gl[set f]($pstr); "
720     }
721
722     close $fd
723
724     if {$::argc == 3} {
725         puts "NOW GENERATING:[lindex $::argv 2]"
726         #Dump the array as a serialized list.
727         set fd [open [lindex $::argv 2] w]
728         puts $fd [array get newapi]
729         close $fd
730     }
731
732     return 0
733 }
734 exit [main $::argc $::argv]
735