import source from 1.3.40
[external/swig.git] / Source / Modules / lua.cxx
1 /* -----------------------------------------------------------------------------
2  * See the LICENSE file for information on copyright, usage and redistribution
3  * of SWIG, and the README file for authors - http://www.swig.org/release.html.
4  *
5  * lua.cxx
6  *
7  * Lua language module for SWIG.
8  * ----------------------------------------------------------------------------- */
9
10 /* NEW LANGUAGE NOTE:
11  * ver001
12    this is simply a copy of tcl8.cxx, which has been renamed
13  * ver002
14    all non essential code commented out, program now does virtually nothing
15    it prints to stderr the list of functions to wrap, but does not create
16    the XXX_wrap.c file
17  * ver003
18    added back top(), still prints the list of fns to stderr
19    but now creates a rather empty XXX_wrap.c with some basic boilerplate code
20  * ver004
21    very basic version of functionWrapper()
22    also uncommented usage_string() to keep compiler happy
23    this will start producing proper looking code soon (I hope)
24    produced the wrapper code, but without any type conversion (in or out)
25    generates a few warning because of no wrappering
26    does not generate SWIG_init()
27    reason for this is that lua.swg is empty
28    we will need to add code into this to make it work
29  * ver005/6
30    massive rework, basing work on the pike module instead of tcl
31    (pike module it only 1/3 of the size)(though not as complete)
32  * ver007
33    added simple type checking
34  * ver008
35    INPUT, OUTPUT, INOUT typemaps handled (though not all types yet)
36  * ver009
37    class support: ok for basic types, but methods still TDB
38    (code is VERY messed up & needs to be cleaned)
39  
40  
41 */
42
43 char cvsroot_lua_cxx[] = "$Id: lua.cxx 11133 2009-02-20 07:52:24Z wsfulton $";
44
45 #include "swigmod.h"
46
47 /**** Diagnostics:
48   With the #define REPORT(), you can change the amount of diagnostics given
49   This helps me search the parse tree & figure out what is going on inside SWIG
50   (because its not clear or documented)
51 */
52 #define REPORT(T,D)             // no info:
53 //#define REPORT(T,D)   {Printf(stdout,T"\n");} // only title
54 //#define REPORT(T,D)           {Printf(stdout,T" %p\n",n);} // title & pointer
55 //#define REPORT(T,D)   {Printf(stdout,T"\n");display_mapping(D);}      // the works
56 //#define REPORT(T,D)   {Printf(stdout,T"\n");if(D)Swig_print_node(D);}      // the works
57
58 void display_mapping(DOH *d) {
59   if (d == 0 || !DohIsMapping(d))
60     return;
61   for (DohIterator it = DohFirst(d); it.item; it = DohNext(it)) {
62     if (DohIsString(it.item))
63       Printf(stdout, "  %s = %s\n", it.key, it.item);
64     else if (DohIsMapping(it.item))
65       Printf(stdout, "  %s = <mapping>\n", it.key);
66     else if (DohIsSequence(it.item))
67       Printf(stdout, "  %s = <sequence>\n", it.key);
68     else
69       Printf(stdout, "  %s = <unknown>\n", it.key);
70   }
71 }
72
73
74
75 /* NEW LANGUAGE NOTE:***********************************************
76  most of the default options are handled by SWIG
77  you can add new ones here
78  (though for now I have not bothered)
79 NEW LANGUAGE NOTE:END ************************************************/
80 static const char *usage = (char *) "\
81                            Lua Options (available with -lua)\n\
82                            (coming soon.)\n\n";
83
84
85
86 /* NEW LANGUAGE NOTE:***********************************************
87  To add a new language, you need to derive your class from
88  Language and the overload various virtual functions
89  (more on this as I figure it out)
90 NEW LANGUAGE NOTE:END ************************************************/
91
92 class LUA:public Language {
93 private:
94
95   File *f_begin;
96   File *f_runtime;
97   File *f_header;
98   File *f_wrappers;
99   File *f_init;
100   File *f_initbeforefunc;
101   String *PrefixPlusUnderscore;
102   String *s_cmd_tab;            // table of command names
103   String *s_var_tab;            // table of global variables
104   String *s_const_tab;          // table of global constants
105   String *s_methods_tab;        // table of class methods
106   String *s_attr_tab;           // table of class atributes
107   String *s_luacode;            // luacode to be called during init
108
109   int have_constructor;
110   int have_destructor;
111   String *destructor_action;
112   String *class_name;
113   String *constructor_name;
114
115   enum {
116     NO_CPP,
117     VARIABLE,
118     MEMBER_FUNC,
119     CONSTRUCTOR,
120     DESTRUCTOR,
121     MEMBER_VAR,
122     CLASS_CONST,
123     STATIC_FUNC,
124     STATIC_VAR
125   }current;
126
127 public:
128
129   /* ---------------------------------------------------------------------
130    * LUA()
131    *
132    * Initialize member data
133    * --------------------------------------------------------------------- */
134
135   LUA() {
136     f_begin = 0;
137     f_runtime = 0;
138     f_header = 0;
139     f_wrappers = 0;
140     f_init = 0;
141     f_initbeforefunc = 0;
142     PrefixPlusUnderscore = 0;
143
144     s_cmd_tab = s_var_tab = s_const_tab = s_luacode = 0;
145     current=NO_CPP;
146   }
147
148   /* NEW LANGUAGE NOTE:***********************************************
149      This is called to initalise the system & read any command line args
150      most of this is boilerplate code, except the command line args
151      which depends upon what args your code supports
152      NEW LANGUAGE NOTE:END ************************************************/
153
154   /* ---------------------------------------------------------------------
155   * main()
156   *
157   * Parse command line options and initializes variables.
158   * --------------------------------------------------------------------- */
159
160   virtual void main(int argc, char *argv[]) {
161
162     /* Set location of SWIG library */
163     SWIG_library_directory("lua");
164
165     /* Look for certain command line options */
166     for (int i = 1; i < argc; i++) {
167       if (argv[i]) {
168         if (strcmp(argv[i], "-help") == 0) {    // usage flags
169           fputs(usage, stderr);
170         }
171       }
172     }
173
174     /* NEW LANGUAGE NOTE:***********************************************
175      This is the boilerplate code, setting a few #defines
176      and which lib directory to use
177      the SWIG_library_directory() is also boilerplate code
178      but it always seems to be the first line of code
179     NEW LANGUAGE NOTE:END ************************************************/
180     /* Add a symbol to the parser for conditional compilation */
181     Preprocessor_define("SWIGLUA 1", 0);
182
183     /* Set language-specific configuration file */
184     SWIG_config_file("lua.swg");
185
186     /* Set typemap language */
187     SWIG_typemap_lang("lua");
188
189     /* Enable overloaded methods support */
190     allow_overloading();
191   }
192
193
194
195
196   /* NEW LANGUAGE NOTE:***********************************************
197    After calling main, SWIG parses the code to wrap (I believe)
198    then calls top()
199    in this is more boilerplate code to set everything up
200    and a call to Language::top()
201    which begins the code generations by calling the member fns
202    after all that is more boilerplate code to close all down
203    (overall there is virtually nothing here that needs to be edited
204    just use as is)
205   NEW LANGUAGE NOTE:END ************************************************/
206   /* ---------------------------------------------------------------------
207    * top()
208    * --------------------------------------------------------------------- */
209
210   virtual int top(Node *n) {
211     /* Get the module name */
212     String *module = Getattr(n, "name");
213
214     /* Get the output file name */
215     String *outfile = Getattr(n, "outfile");
216
217     /* Open the output file */
218     f_begin = NewFile(outfile, "w", SWIG_output_files());
219     if (!f_begin) {
220       FileErrorDisplay(outfile);
221       SWIG_exit(EXIT_FAILURE);
222     }
223     f_runtime = NewString("");
224     f_init = NewString("");
225     f_header = NewString("");
226     f_wrappers = NewString("");
227     f_initbeforefunc = NewString("");
228
229     /* Register file targets with the SWIG file handler */
230     Swig_register_filebyname("header", f_header);
231     Swig_register_filebyname("wrapper", f_wrappers);
232     Swig_register_filebyname("begin", f_begin);
233     Swig_register_filebyname("runtime", f_runtime);
234     Swig_register_filebyname("init", f_init);
235     Swig_register_filebyname("initbeforefunc", f_initbeforefunc);
236
237     /* NEW LANGUAGE NOTE:***********************************************
238      s_cmd_tab,s_var_tab & s_const_tab hold the names of the fns for
239      registering with SWIG.
240      These will be filled in when the functions/variables are wrapped &
241      then added to the end of the wrappering code
242      just before it is written to file
243     NEW LANGUAGE NOTE:END ************************************************/
244     // Initialize some variables for the object interface
245     s_cmd_tab = NewString("");
246     s_var_tab = NewString("");
247     //    s_methods_tab    = NewString("");
248     s_const_tab = NewString("");
249     
250     s_luacode = NewString("");
251     Swig_register_filebyname("luacode", s_luacode);
252     
253     current=NO_CPP;
254
255     /* Standard stuff for the SWIG runtime section */
256     Swig_banner(f_begin);
257
258     Printf(f_runtime, "\n");
259     Printf(f_runtime, "#define SWIGLUA\n");
260
261     //    if (NoInclude) {
262     //      Printf(f_runtime, "#define SWIG_NOINCLUDE\n");
263     //    }
264
265     Printf(f_runtime, "\n");
266
267     //String *init_name = NewStringf("%(title)s_Init", module);
268     //Printf(f_header, "#define SWIG_init    %s\n", init_name);
269     //Printf(f_header, "#define SWIG_name    \"%s\"\n", module);
270     /* SWIG_import is a special function name for importing within Lua5.1 */
271     //Printf(f_header, "#define SWIG_import  luaopen_%s\n\n", module);
272     Printf(f_header, "#define SWIG_name      \"%s\"\n", module);
273     Printf(f_header, "#define SWIG_init      luaopen_%s\n", module);
274     Printf(f_header, "#define SWIG_init_user luaopen_%s_user\n\n", module);
275     Printf(f_header, "#define SWIG_LUACODE   luaopen_%s_luacode\n\n", module);
276
277     Printf(s_cmd_tab, "\nstatic const struct luaL_reg swig_commands[] = {\n");
278     Printf(s_var_tab, "\nstatic swig_lua_var_info swig_variables[] = {\n");
279     Printf(s_const_tab, "\nstatic swig_lua_const_info swig_constants[] = {\n");
280     Printf(f_wrappers, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
281
282     /* %init code inclusion, effectively in the SWIG_init function */
283     Printf(f_init, "void SWIG_init_user(lua_State* L)\n{\n");
284     Language::top(n);
285     Printf(f_init,"/* exec Lua code if applicable */\nSWIG_Lua_dostring(L,SWIG_LUACODE);\n");
286     Printf(f_init, "}\n");
287
288     Printf(f_wrappers, "#ifdef __cplusplus\n}\n#endif\n");
289
290     // Done.  Close up the module & write to the wrappers
291     Printv(s_cmd_tab, tab4, "{0,0}\n", "};\n", NIL);
292     Printv(s_var_tab, tab4, "{0,0,0}\n", "};\n", NIL);
293     Printv(s_const_tab, tab4, "{0,0,0,0,0,0}\n", "};\n", NIL);
294     Printv(f_wrappers, s_cmd_tab, s_var_tab, s_const_tab, NIL);
295     SwigType_emit_type_table(f_runtime, f_wrappers);
296
297     /* NEW LANGUAGE NOTE:***********************************************
298      this basically combines several of the strings together
299      and then writes it all to a file
300     NEW LANGUAGE NOTE:END ************************************************/
301     Dump(f_runtime, f_begin);
302     Dump(f_header, f_begin);
303     Dump(f_wrappers, f_begin);
304     Dump(f_initbeforefunc, f_begin);
305     /* for the Lua code it needs to be properly excaped to be added into the C/C++ code */
306     EscapeCode(s_luacode);
307     Printf(f_begin, "const char* SWIG_LUACODE=\n  \"%s\";\n\n",s_luacode);
308     Wrapper_pretty_print(f_init, f_begin);
309     /* Close all of the files */
310     Delete(s_luacode);
311     Delete(s_cmd_tab);
312     Delete(s_var_tab);
313     Delete(s_const_tab);
314     Delete(f_header);
315     Delete(f_wrappers);
316     Delete(f_init);
317     Delete(f_initbeforefunc);
318     Close(f_begin);
319     Delete(f_runtime);
320     Delete(f_begin);
321
322     /* Done */
323     return SWIG_OK;
324   }
325
326   /* ------------------------------------------------------------
327    * importDirective()
328    * ------------------------------------------------------------ */
329
330   virtual int importDirective(Node *n) {
331     return Language::importDirective(n);
332   }
333
334   /* NEW LANGUAGE NOTE:***********************************************
335    This is it!
336    you get this one right, and most of your work is done
337    but its going to take soem file to get it working right
338    quite a bit of this is generally boilerplate code
339    (or stuff I dont understand)
340    that which matters will have extra added comments
341   NEW LANGUAGE NOTE:END ************************************************/
342   /* ---------------------------------------------------------------------
343    * functionWrapper()
344    *
345    * Create a function declaration and register it with the interpreter.
346    * --------------------------------------------------------------------- */
347
348   virtual int functionWrapper(Node *n) {
349     REPORT("functionWrapper",n);
350
351     String *name = Getattr(n, "name");
352     String *iname = Getattr(n, "sym:name");
353     SwigType *d = Getattr(n, "type");
354     ParmList *l = Getattr(n, "parms");
355     //Printf(stdout,"functionWrapper %s %s\n",name,iname);
356     Parm *p;
357     String *tm;
358     int i;
359     //Printf(stdout,"functionWrapper %s %s %d\n",name,iname,current);
360     //    int returnval=0;  // number of arguments returned
361
362     String *overname = 0;
363     if (Getattr(n, "sym:overloaded")) {
364       overname = Getattr(n, "sym:overname");
365     } else {
366       if (!addSymbol(iname, n)) {
367         Printf(stderr,"addSymbol(%s) failed\n",iname);
368         return SWIG_ERROR;
369       }
370     }
371
372     /* NEW LANGUAGE NOTE:***********************************************
373        the wrapper object holds all the wrappering code
374         we need to add a couple of local variables
375     NEW LANGUAGE NOTE:END ************************************************/
376     Wrapper *f = NewWrapper();
377     Wrapper_add_local(f, "SWIG_arg", "int SWIG_arg = 0");
378
379
380     String *wname = Swig_name_wrapper(iname);
381     if (overname) {
382       Append(wname, overname);
383     }
384
385     /* NEW LANGUAGE NOTE:***********************************************
386        the format of a lua fn is:
387          static int wrap_XXX(lua_State* L){...}
388        this line adds this into the wrappering code
389     NEW LANGUAGE NOTE:END ************************************************/
390     Printv(f->def, "static int ", wname, "(lua_State* L) {", NIL);
391
392     /* NEW LANGUAGE NOTE:***********************************************
393        this prints the list of args, eg for a C fn
394        int gcd(int x,int y);
395        it will print
396          int arg1;
397          int arg2;
398     NEW LANGUAGE NOTE:END ************************************************/
399     /* Write code to extract function parameters. */
400     emit_parameter_variables(l, f);
401
402     /* Attach the standard typemaps */
403     emit_attach_parmmaps(l, f);
404     Setattr(n, "wrap:parms", l);
405
406     /* Get number of required and total arguments */
407     int num_arguments = emit_num_arguments(l);
408     int num_required = emit_num_required(l);
409     int varargs = emit_isvarargs(l);
410
411     // Check if we have to ignore arguments that are passed by LUA.
412     // Needed for unary minus, where lua passes two arguments and
413     // we have to ignore the second.
414
415     int args_to_ignore = 0;
416     if (Getattr(n, "lua:ignore_args")) {
417       args_to_ignore = GetInt(n, "lua:ignore_args");
418     }
419
420
421     /* Which input argument to start with? */
422     //    int start = (current == MEMBER_FUNC || current == MEMBER_VAR || current == DESTRUCTOR) ? 1 : 0;
423
424     /* Offset to skip over the attribute name */
425     // int offset = (current == MEMBER_VAR) ? 1 : 0;
426
427     /* NEW LANGUAGE NOTE:***********************************************
428        from here on in, it gets rather hairy
429        this is the code to convert from the scripting language to C/C++
430        some of the stuff will refer to the typemaps code written in your swig file
431        (lua.swg), and some is done in the code here
432        I suppose you could do all the conversion on C, but it would be a nightmare to do
433     NEW LANGUAGE NOTE:END ************************************************/
434     /* Generate code for argument marshalling */
435     //    String *description = NewString("");
436     /* NEW LANGUAGE NOTE:***********************************************
437        argument_check is a new feature I added to check types of arguments:
438        eg for int gcd(int,int)
439        I want to check that arg1 & arg2 really are integers
440     NEW LANGUAGE NOTE:END ************************************************/
441     String *argument_check = NewString("");
442     String *argument_parse = NewString("");
443     String *checkfn = NULL;
444     //    String *numoutputs=NULL;
445     char source[64];
446     //Printf(argument_check, "SWIG_check_num_args(\"%s\",%d,%d)\n",name,num_required,num_arguments);
447     Printf(argument_check, "SWIG_check_num_args(\"%s\",%d,%d)\n",name,num_required+args_to_ignore,num_arguments+args_to_ignore);
448
449     for (i = 0, p = l; i < num_arguments; i++) {
450
451       while (checkAttribute(p, "tmap:in:numinputs", "0")) {
452         p = Getattr(p, "tmap:in:next");
453       }
454
455       SwigType *pt = Getattr(p, "type");
456       String *ln = Getattr(p, "lname");
457
458       /* Look for an input typemap */
459       sprintf(source, "%d", i + 1);
460       if ((tm = Getattr(p, "tmap:in"))) {
461         Replaceall(tm, "$source", source);
462         Replaceall(tm, "$target", ln);
463         Replaceall(tm, "$input", source);
464         Setattr(p, "emit:input", source);
465         if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
466           Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
467         } else {
468           Replaceall(tm, "$disown", "0");
469         }
470         /* NEW LANGUAGE NOTE:***********************************************
471            look for a 'checkfn' typemap
472            this an additional parameter added to the in typemap
473            if found the type will be tested for
474            this will result in code either in the
475            argument_check or argument_parse string
476         NEW LANGUAGE NOTE:END ************************************************/
477         if ((checkfn = Getattr(p, "tmap:in:checkfn"))) {
478           if (i < num_required) {
479             Printf(argument_check, "if(!%s(L,%s))", checkfn, source);
480           } else {
481             Printf(argument_check, "if(lua_gettop(L)>=%s && !%s(L,%s))", source, checkfn, source);
482           }
483           Printf(argument_check, " SWIG_fail_arg(\"%s\",%s,\"%s\");\n", name, source, SwigType_str(pt, 0));
484         }
485         /* NEW LANGUAGE NOTE:***********************************************
486            lua states the number of arguments passed to a function using the fn
487            lua_gettop()
488            we can use this to deal with default arguments
489         NEW LANGUAGE NOTE:END ************************************************/
490         if (i < num_required) {
491           Printf(argument_parse, "%s\n", tm);
492         } else {
493           Printf(argument_parse, "if(lua_gettop(L)>=%s){%s}\n", source, tm);
494         }
495         p = Getattr(p, "tmap:in:next");
496         continue;
497       } else {
498         /* NEW LANGUAGE NOTE:***********************************************
499                            // why is this code not called when I dont have a typemap?
500                            // instead of giving a warning, no code is generated
501         NEW LANGUAGE NOTE:END ************************************************/
502         Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
503         break;
504       }
505     }
506
507     // add all argcheck code
508     Printv(f->code, argument_check, argument_parse, NIL);
509
510     /* Check for trailing varargs */
511     if (varargs) {
512       if (p && (tm = Getattr(p, "tmap:in"))) {
513         Replaceall(tm, "$input", "varargs");
514         Printv(f->code, tm, "\n", NIL);
515       }
516     }
517
518     /* Insert constraint checking code */
519     for (p = l; p;) {
520       if ((tm = Getattr(p, "tmap:check"))) {
521         Replaceall(tm, "$target", Getattr(p, "lname"));
522         Printv(f->code, tm, "\n", NIL);
523         p = Getattr(p, "tmap:check:next");
524       } else {
525         p = nextSibling(p);
526       }
527     }
528
529     /* Insert cleanup code */
530     String *cleanup = NewString("");
531     for (p = l; p;) {
532       if ((tm = Getattr(p, "tmap:freearg"))) {
533         Replaceall(tm, "$source", Getattr(p, "lname"));
534         Printv(cleanup, tm, "\n", NIL);
535         p = Getattr(p, "tmap:freearg:next");
536       } else {
537         p = nextSibling(p);
538       }
539     }
540
541     /* Insert argument output code */
542     String *outarg = NewString("");
543     for (p = l; p;) {
544       if ((tm = Getattr(p, "tmap:argout"))) {
545         //          // managing the number of returning variables
546         //        if (numoutputs=Getattr(p,"tmap:argout:numoutputs")){
547         //                      int i=GetInt(p,"tmap:argout:numoutputs");
548         //                      printf("got argout:numoutputs of %d\n",i);
549         //                      returnval+=GetInt(p,"tmap:argout:numoutputs");
550         //        }
551         //        else returnval++;
552         Replaceall(tm, "$source", Getattr(p, "lname"));
553         Replaceall(tm, "$target", "result");
554         Replaceall(tm, "$arg", Getattr(p, "emit:input"));
555         Replaceall(tm, "$input", Getattr(p, "emit:input"));
556         Printv(outarg, tm, "\n", NIL);
557         p = Getattr(p, "tmap:argout:next");
558       } else {
559         p = nextSibling(p);
560       }
561     }
562
563     Setattr(n, "wrap:name", wname);
564
565     /* Emit the function call */
566     String *actioncode = emit_action(n);
567
568     /* NEW LANGUAGE NOTE:***********************************************
569     FIXME:
570     returns 1 if there is a void return type
571     this is because there is a typemap for void
572     NEW LANGUAGE NOTE:END ************************************************/
573     // Return value if necessary
574     if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
575       // managing the number of returning variables
576       //      if (numoutputs=Getattr(tm,"numoutputs")){
577       //              int i=GetInt(tm,"numoutputs");
578       //              printf("return numoutputs %d\n",i);
579       //              returnval+=GetInt(tm,"numoutputs");
580       //      }
581       //        else returnval++;
582       Replaceall(tm, "$source", "result");
583       if (GetFlag(n, "feature:new")) {
584         Replaceall(tm, "$owner", "1");
585       } else {
586         Replaceall(tm, "$owner", "0");
587       }
588       Printf(f->code, "%s\n", tm);
589       //      returnval++;
590     } else {
591       Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name);
592     }
593     emit_return_variable(n, d, f);
594
595     /* Output argument output code */
596     Printv(f->code, outarg, NIL);
597
598     /* Output cleanup code */
599     Printv(f->code, cleanup, NIL);
600
601     /* Look to see if there is any newfree cleanup code */
602     if (GetFlag(n, "feature:new")) {
603       if ((tm = Swig_typemap_lookup("newfree", n, "result", 0))) {
604         Replaceall(tm, "$source", "result");
605         Printf(f->code, "%s\n", tm);
606       }
607     }
608
609     /* See if there is any return cleanup code */
610     if ((tm = Swig_typemap_lookup("ret", n, "result", 0))) {
611       Replaceall(tm, "$source", "result");
612       Printf(f->code, "%s\n", tm);
613     }
614
615
616     /* Close the function */
617     Printv(f->code, "return SWIG_arg;\n", NIL);
618     // add the failure cleanup code:
619     Printv(f->code, "\nif(0) SWIG_fail;\n", NIL);
620     Printv(f->code, "\nfail:\n", NIL);
621     Printv(f->code, "$cleanup", "lua_error(L);\n", NIL);
622     Printv(f->code, "return SWIG_arg;\n", NIL);
623     Printf(f->code, "}\n");
624
625     /* Substitute the cleanup code */
626     Replaceall(f->code, "$cleanup", cleanup);
627
628     /* Substitute the function name */
629     Replaceall(f->code, "$symname", iname);
630     Replaceall(f->code, "$result", "result");
631
632     /* Dump the function out */
633     /* in Lua we will not emit the destructor as a wrappered function,
634     Lua will automatically call the destructor when the object is free'd
635     However: you cannot just skip this function as it will not emit
636     any custom destructor (using %extend), as you need to call emit_action()
637     Therefore we go though the whole function, 
638     but do not write the code into the wrapper
639     */
640     if(current!=DESTRUCTOR) {
641        Wrapper_print(f, f_wrappers);
642     }
643     
644     /* NEW LANGUAGE NOTE:***********************************************
645     register the function in SWIG
646     different language mappings seem to use different ideas
647     NEW LANGUAGE NOTE:END ************************************************/
648     /* Now register the function with the interpreter. */
649     if (!Getattr(n, "sym:overloaded")) {
650       //      add_method(n, iname, wname, description);
651       if (current==NO_CPP || current==STATIC_FUNC) // emit normal fns & static fns
652         Printv(s_cmd_tab, tab4, "{ \"", iname, "\", ", Swig_name_wrapper(iname), "},\n", NIL);
653       //      Printv(s_cmd_tab, tab4, "{ SWIG_prefix \"", iname, "\", (swig_wrapper_func) ", Swig_name_wrapper(iname), "},\n", NIL);
654     } else {
655       if (!Getattr(n, "sym:nextSibling")) {
656         dispatchFunction(n);
657       }
658     }
659
660     Delete(argument_check);
661     Delete(argument_parse);
662
663     Delete(cleanup);
664     Delete(outarg);
665     //    Delete(description);
666     Delete(wname);
667     DelWrapper(f);
668
669     return SWIG_OK;
670   }
671
672   /* ------------------------------------------------------------
673    * dispatchFunction()
674    *
675    * Emit overloading dispatch function
676    * ------------------------------------------------------------ */
677
678   /* NEW LANGUAGE NOTE:***********************************************
679   This is an extra function used for overloading of functions
680   it checks the args & then calls the relevant fn
681   nost of the real work in again typemaps:
682   look for %typecheck(SWIG_TYPECHECK_*) in the .swg file
683   NEW LANGUAGE NOTE:END ************************************************/
684   void dispatchFunction(Node *n) {
685     /* Last node in overloaded chain */
686
687     int maxargs;
688     String *tmp = NewString("");
689     String *dispatch = Swig_overload_dispatch(n, "return %s(L);", &maxargs);
690
691     /* Generate a dispatch wrapper for all overloaded functions */
692
693     Wrapper *f = NewWrapper();
694     String *symname = Getattr(n, "sym:name");
695     String *wname = Swig_name_wrapper(symname);
696
697     //Printf(stdout,"Swig_overload_dispatch %s %s '%s' %d\n",symname,wname,dispatch,maxargs);
698
699     Printv(f->def, "static int ", wname, "(lua_State* L) {", NIL);
700     Wrapper_add_local(f, "argc", "int argc");
701     Printf(tmp, "int argv[%d]={1", maxargs + 1);
702     for (int i = 1; i <= maxargs; i++) {
703       Printf(tmp, ",%d", i + 1);
704     }
705     Printf(tmp, "}");
706     Wrapper_add_local(f, "argv", tmp);
707     Printf(f->code, "argc = lua_gettop(L);\n");
708
709     Replaceall(dispatch, "$args", "self,args");
710     Printv(f->code, dispatch, "\n", NIL);
711     
712     Node *sibl = n;
713     while (Getattr(sibl, "sym:previousSibling"))
714       sibl = Getattr(sibl, "sym:previousSibling");      // go all the way up
715     String *protoTypes = NewString("");
716     do {
717       Printf(protoTypes, "\n\"    %s(%s)\\n\"", SwigType_str(Getattr(sibl, "name"), 0), ParmList_protostr(Getattr(sibl, "wrap:parms")));
718     } while ((sibl = Getattr(sibl, "sym:nextSibling")));
719     Printf(f->code, "lua_pushstring(L,\"Wrong arguments for overloaded function '%s'\\n\"\n"
720         "\"  Possible C/C++ prototypes are:\\n\"%s);\n",symname,protoTypes);
721     Delete(protoTypes);
722
723     Printf(f->code, "lua_error(L);return 0;\n");
724     Printv(f->code, "}\n", NIL);
725     Wrapper_print(f, f_wrappers);
726     //add_method(symname,wname,0);
727     if (current==NO_CPP || current==STATIC_FUNC) // emit normal fns & static fns
728       Printv(s_cmd_tab, tab4, "{ \"", symname, "\",", wname, "},\n", NIL);
729
730     DelWrapper(f);
731     Delete(dispatch);
732     Delete(tmp);
733     Delete(wname);
734   }
735
736
737   /* ------------------------------------------------------------
738    * variableWrapper()
739    * ------------------------------------------------------------ */
740
741   virtual int variableWrapper(Node *n) {
742     /* NEW LANGUAGE NOTE:***********************************************
743     Language::variableWrapper(n) will generate two wrapper fns
744     Foo_get & Foo_set by calling functionWrapper()
745     so we will just add these into the variable lists
746     ideally we should not have registered these as functions,
747     only WRT this variable will look into this later.
748     NEW LANGUAGE NOTE:END ************************************************/
749     //    REPORT("variableWrapper", n);
750     String *iname = Getattr(n, "sym:name");
751     current=VARIABLE;
752     // let SWIG generate the wrappers
753     int result = Language::variableWrapper(n);
754     current=NO_CPP;
755     // normally SWIG will generate 2 wrappers, a get and a set
756     // but in certain scenarios (immutable, or if its arrays), it will not
757     String *getName = Swig_name_wrapper(Swig_name_get(iname));
758     String *setName = 0;
759     // checking whether it can be set to or not appears to be a very error prone issue
760     // I refered to the Language::variableWrapper() to find this out
761     bool assignable=is_assignable(n) ? true : false;
762     SwigType *type = Getattr(n, "type");
763     String *tm = Swig_typemap_lookup("globalin", n, iname, 0);
764     if (!tm && SwigType_isarray(type))
765       assignable=false;
766     Delete(tm);
767
768     if (assignable) {
769       setName = Swig_name_wrapper(Swig_name_set(iname));
770     } else {
771       // how about calling a 'this is not settable' error message?
772       setName = NewString("SWIG_Lua_set_immutable"); // error message
773       //setName = NewString("0");
774     }
775     // register the variable
776     Printf(s_var_tab, "%s{ \"%s\", %s, %s },\n", tab4, iname, getName, setName);
777     Delete(getName);
778     Delete(setName);
779     return result;
780   }
781
782   /* ------------------------------------------------------------
783    * constantWrapper()
784    * ------------------------------------------------------------ */
785   virtual int constantWrapper(Node *n) {
786     //    REPORT("constantWrapper", n);
787     String *name = Getattr(n, "name");
788     String *iname = Getattr(n, "sym:name");
789     //String *nsname    = !nspace ? Copy(iname) : NewStringf("%s::%s",ns_name,iname);
790     String *nsname = Copy(iname);
791     SwigType *type = Getattr(n, "type");
792     String *rawval = Getattr(n, "rawval");
793     String *value = rawval ? rawval : Getattr(n, "value");
794     String *tm;
795
796     if (!addSymbol(iname, n))
797       return SWIG_ERROR;
798     //if (nspace) Setattr(n,"sym:name",nsname);
799
800     /* Special hook for member pointer */
801     if (SwigType_type(type) == T_MPOINTER) {
802       String *wname = Swig_name_wrapper(iname);
803       Printf(f_wrappers, "static %s = %s;\n", SwigType_str(type, wname), value);
804       value = Char(wname);
805     }
806
807     if ((tm = Swig_typemap_lookup("consttab", n, name, 0))) {
808       Replaceall(tm, "$source", value);
809       Replaceall(tm, "$target", name);
810       Replaceall(tm, "$value", value);
811       Replaceall(tm, "$nsname", nsname);
812       Printf(s_const_tab, "%s,\n", tm);
813     } else if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
814       Replaceall(tm, "$source", value);
815       Replaceall(tm, "$target", name);
816       Replaceall(tm, "$value", value);
817       Replaceall(tm, "$nsname", nsname);
818       Printf(f_init, "%s\n", tm);
819     } else {
820       Delete(nsname);
821       Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n");
822       return SWIG_NOWRAP;
823     }
824     Delete(nsname);
825     return SWIG_OK;
826   }
827
828   /* ------------------------------------------------------------
829    * nativeWrapper()
830    * ------------------------------------------------------------ */
831
832   virtual int nativeWrapper(Node *n) {
833     //    REPORT("nativeWrapper", n);
834     String *symname = Getattr(n, "sym:name");
835     String *wrapname = Getattr(n, "wrap:name");
836     if (!addSymbol(wrapname, n))
837       return SWIG_ERROR;
838
839     Printv(s_cmd_tab, tab4, "{ \"", symname, "\",", wrapname, "},\n", NIL);
840     //   return Language::nativeWrapper(n); // this does nothing...
841     return SWIG_OK;
842   }
843
844   /* ------------------------------------------------------------
845    * enumDeclaration()
846    * ------------------------------------------------------------ */
847
848   virtual int enumDeclaration(Node *n) {
849     return Language::enumDeclaration(n);
850   }
851
852   /* ------------------------------------------------------------
853    * enumvalueDeclaration()
854    * ------------------------------------------------------------ */
855
856   virtual int enumvalueDeclaration(Node *n) {
857     return Language::enumvalueDeclaration(n);
858   }
859
860   /* ------------------------------------------------------------
861    * classDeclaration()
862    * ------------------------------------------------------------ */
863
864   virtual int classDeclaration(Node *n) {
865     return Language::classDeclaration(n);
866   }
867
868   /* ------------------------------------------------------------
869    * classHandler()
870    * ------------------------------------------------------------ */
871
872   virtual int classHandler(Node *n) {
873     //REPORT("classHandler", n);
874
875     String *mangled_classname = 0;
876     String *real_classname = 0;
877
878     constructor_name = 0;
879     have_constructor = 0;
880     have_destructor = 0;
881     destructor_action = 0;
882
883     class_name = Getattr(n, "sym:name");
884     if (!addSymbol(class_name, n))
885       return SWIG_ERROR;
886
887     real_classname = Getattr(n, "name");
888     mangled_classname = Swig_name_mangle(real_classname);
889
890     // not sure exactly how this workswhat this works,
891     // but tcl has a static hashtable of all classes emitted and then only emits code for them once.
892     // this fixes issues in test suites: template_default2 & template_specialization
893
894     // * if i understand correctly, this is a bug.
895     // * consider effect on template_specialization_defarg
896
897     static Hash *emitted = NewHash();
898     if (Getattr(emitted, mangled_classname))
899       return SWIG_NOWRAP;
900     Setattr(emitted, mangled_classname, "1");
901
902     s_attr_tab = NewString("");
903     Printf(s_attr_tab, "static swig_lua_attribute swig_");
904     Printv(s_attr_tab, mangled_classname, "_attributes[] = {\n", NIL);
905
906     s_methods_tab = NewString("");
907     Printf(s_methods_tab, "static swig_lua_method swig_");
908     Printv(s_methods_tab, mangled_classname, "_methods[] = {\n", NIL);
909
910     // Generate normal wrappers
911     Language::classHandler(n);
912
913     SwigType *t = Copy(Getattr(n, "name"));
914     SwigType_add_pointer(t);
915
916     // Catch all: eg. a class with only static functions and/or variables will not have 'remembered'
917     String *wrap_class = NewStringf("&_wrap_class_%s", mangled_classname);
918     SwigType_remember_clientdata(t, wrap_class);
919
920     String *rt = Copy(Getattr(n, "classtype"));
921     SwigType_add_pointer(rt);
922
923     // Register the class structure with the type checker
924     //    Printf(f_init,"SWIG_TypeClientData(SWIGTYPE%s, (void *) &_wrap_class_%s);\n", SwigType_manglestr(t), mangled_classname);
925  
926     // emit a function to be called to delete the object 
927     if (have_destructor) {
928       Printv(f_wrappers, "static void swig_delete_", class_name, "(void *obj) {\n", NIL);
929       if (destructor_action) {
930         Printv(f_wrappers, SwigType_str(rt, "arg1"), " = (", SwigType_str(rt, 0), ") obj;\n", NIL);
931         Printv(f_wrappers, destructor_action, "\n", NIL);
932       } else {
933         if (CPlusPlus) {
934           Printv(f_wrappers, "    delete (", SwigType_str(rt, 0), ") obj;\n", NIL);
935         } else {
936           Printv(f_wrappers, "    free((char *) obj);\n", NIL);
937         }
938       }
939       Printf(f_wrappers, "}\n");
940     }
941
942     Printf(s_methods_tab, "    {0,0}\n};\n");
943     Printv(f_wrappers, s_methods_tab, NIL);
944
945     Printf(s_attr_tab, "    {0,0,0}\n};\n");
946     Printv(f_wrappers, s_attr_tab, NIL);
947
948     Delete(s_methods_tab);
949     Delete(s_attr_tab);
950
951     // Handle inheritance
952     // note: with the idea of class hireachied spread over multiple modules
953     // cf test-suite: imports.i
954     // it is not possible to just add the pointers to the base classes to the code
955     // (as sometimes these classes are not present)
956     // therefore we instead hold the name of the base class and a null pointer
957     // at runtime: we can query the swig type manager & see if the class exists
958     // if so, we can get the pointer to the base class & replace the null pointer
959     // if the type does not exist, then we cannot...
960     String *base_class = NewString("");
961     String *base_class_names = NewString("");
962
963     List *baselist = Getattr(n, "bases");
964     if (baselist && Len(baselist)) {
965       Iterator b;
966       int index = 0;
967       b = First(baselist);
968       while (b.item) {
969         String *bname = Getattr(b.item, "name");
970         if ((!bname) || GetFlag(b.item, "feature:ignore") || (!Getattr(b.item, "module"))) {
971           b = Next(b);
972           continue;
973         }
974         // old code: (used the pointer to the base class)
975         //String *bmangle = Swig_name_mangle(bname);
976         //Printf(base_class, "&_wrap_class_%s", bmangle);
977         //Putc(',', base_class);
978         //Delete(bmangle);
979         // new code: stores a null pointer & the name
980         Printf(base_class, "0,");
981         Printf(base_class_names, "\"%s *\",", SwigType_namestr(bname));
982
983         b = Next(b);
984         index++;
985       }
986     }
987
988     Printv(f_wrappers, "static swig_lua_class *swig_", mangled_classname, "_bases[] = {", base_class, "0};\n", NIL);
989     Delete(base_class);
990     Printv(f_wrappers, "static const char *swig_", mangled_classname, "_base_names[] = {", base_class_names, "0};\n", NIL);
991     Delete(base_class_names);
992
993     Printv(f_wrappers, "static swig_lua_class _wrap_class_", mangled_classname, " = { \"", class_name, "\", &SWIGTYPE", SwigType_manglestr(t), ",", NIL);
994
995     if (have_constructor) {
996       Printf(f_wrappers, "%s", Swig_name_wrapper(Swig_name_construct(constructor_name)));
997       Delete(constructor_name);
998       constructor_name = 0;
999     } else {
1000       Printf(f_wrappers, "0");
1001     }
1002
1003     if (have_destructor) {
1004       Printv(f_wrappers, ", swig_delete_", class_name, NIL);
1005     } else {
1006       Printf(f_wrappers, ",0");
1007     }
1008     Printf(f_wrappers, ", swig_%s_methods, swig_%s_attributes, swig_%s_bases, swig_%s_base_names };\n\n", mangled_classname, mangled_classname, mangled_classname, mangled_classname);
1009
1010     //    Printv(f_wrappers, ", swig_", mangled_classname, "_methods, swig_", mangled_classname, "_attributes, swig_", mangled_classname, "_bases };\n\n", NIL);
1011     //    Printv(s_cmd_tab, tab4, "{ SWIG_prefix \"", class_name, "\", (swig_wrapper_func) SWIG_ObjectConstructor, &_wrap_class_", mangled_classname, "},\n", NIL);
1012     Delete(t);
1013     Delete(mangled_classname);
1014     return SWIG_OK;
1015   }
1016
1017   /* ------------------------------------------------------------
1018    * memberfunctionHandler()
1019    * ------------------------------------------------------------ */
1020
1021   virtual int memberfunctionHandler(Node *n) {
1022     String *name = Getattr(n, "name");
1023     String *iname = GetChar(n, "sym:name");
1024     //Printf(stdout,"memberfunctionHandler %s %s\n",name,iname);
1025
1026     // Special case unary minus: LUA passes two parameters for the
1027     // wrapper function while we want only one. Tell our
1028     // functionWrapper to ignore a parameter.
1029
1030     if (Cmp(Getattr(n, "sym:name"), "__unm") == 0) {
1031       //Printf(stdout, "unary minus: ignore one argument\n");
1032       SetInt(n, "lua:ignore_args", 1);
1033     }
1034
1035     String *realname, *rname;
1036
1037     current = MEMBER_FUNC;
1038     Language::memberfunctionHandler(n);
1039     current = NO_CPP;
1040
1041     realname = iname ? iname : name;
1042     rname = Swig_name_wrapper(Swig_name_member(class_name, realname));
1043     if (!Getattr(n, "sym:nextSibling")) {
1044       Printv(s_methods_tab, tab4, "{\"", realname, "\", ", rname, "}, \n", NIL);
1045     }
1046     Delete(rname);
1047     return SWIG_OK;
1048   }
1049
1050   /* ------------------------------------------------------------
1051    * membervariableHandler()
1052    * ------------------------------------------------------------ */
1053
1054   virtual int membervariableHandler(Node *n) {
1055     //    REPORT("membervariableHandler",n);
1056     String *symname = Getattr(n, "sym:name");
1057     String *gname, *sname;
1058
1059     current = MEMBER_VAR;
1060     Language::membervariableHandler(n);
1061     current = NO_CPP;
1062     gname = Swig_name_wrapper(Swig_name_get(Swig_name_member(class_name, symname)));
1063     if (!GetFlag(n, "feature:immutable")) {
1064       sname = Swig_name_wrapper(Swig_name_set(Swig_name_member(class_name, symname)));
1065     } else {
1066       //sname = NewString("0");
1067       sname = NewString("SWIG_Lua_set_immutable"); // error message
1068     }
1069     Printf(s_attr_tab,"%s{ \"%s\", %s, %s},\n",tab4,symname,gname,sname);
1070     Delete(gname);
1071     Delete(sname);
1072     return SWIG_OK;
1073   }
1074
1075   /* ------------------------------------------------------------
1076    * constructorHandler()
1077    *
1078    * Method for adding C++ member constructor
1079    * ------------------------------------------------------------ */
1080
1081   virtual int constructorHandler(Node *n) {
1082     //    REPORT("constructorHandler", n);
1083     current = CONSTRUCTOR;
1084     Language::constructorHandler(n);
1085     current = NO_CPP;
1086     constructor_name = NewString(Getattr(n, "sym:name"));
1087     have_constructor = 1;
1088     return SWIG_OK;
1089   }
1090
1091   /* ------------------------------------------------------------
1092    * destructorHandler()
1093    * ------------------------------------------------------------ */
1094
1095   virtual int destructorHandler(Node *n) {
1096     REPORT("destructorHandler", n);
1097     current = DESTRUCTOR;
1098     Language::destructorHandler(n);
1099     current = NO_CPP;
1100     have_destructor = 1;
1101     destructor_action = Getattr(n, "wrap:action");
1102     return SWIG_OK;
1103   }
1104
1105   /* -----------------------------------------------------------------------
1106    * staticmemberfunctionHandler()
1107    *
1108    * Wrap a static C++ function
1109    * ---------------------------------------------------------------------- */
1110
1111   virtual int staticmemberfunctionHandler(Node *n) {
1112     current = STATIC_FUNC;
1113     return Language::staticmemberfunctionHandler(n);
1114   }
1115
1116   /* ------------------------------------------------------------
1117    * memberconstantHandler()
1118    *
1119    * Create a C++ constant
1120    * ------------------------------------------------------------ */
1121
1122   virtual int memberconstantHandler(Node *n) {
1123     //    REPORT("memberconstantHandler",n);
1124     return Language::memberconstantHandler(n);
1125   }
1126
1127   /* ---------------------------------------------------------------------
1128    * staticmembervariableHandler()
1129    * --------------------------------------------------------------------- */
1130
1131   virtual int staticmembervariableHandler(Node *n) {
1132     //    REPORT("staticmembervariableHandler",n);
1133     current = STATIC_VAR;
1134     return Language::staticmembervariableHandler(n);
1135   }
1136
1137   /* ---------------------------------------------------------------------
1138    * external runtime generation
1139    * --------------------------------------------------------------------- */
1140
1141   /* This is to support the usage
1142      SWIG -external-runtime <filename>
1143      The code consists of two functions:
1144      String *runtimeCode()  // returns a large string with all the runtimes in
1145      String *defaultExternalRuntimeFilename() // returns the default filename
1146      I am writing a generic solution, even though SWIG-Lua only has one file right now...
1147    */
1148   String *runtimeCode() {
1149     String *s = NewString("");
1150     const char *filenames[] = { "luarun.swg", 0
1151                               }
1152                               ; // must be 0 termiated
1153     String *sfile;
1154     for (int i = 0; filenames[i] != 0; i++) {
1155       sfile = Swig_include_sys(filenames[i]);
1156       if (!sfile) {
1157         Printf(stderr, "*** Unable to open '%s'\n", filenames[i]);
1158       } else {
1159         Append(s, sfile);
1160         Delete(sfile);
1161       }
1162     }
1163
1164     return s;
1165   }
1166
1167   String *defaultExternalRuntimeFilename() {
1168     return NewString("swigluarun.h");
1169   }
1170   
1171   /* ---------------------------------------------------------------------
1172    * helpers
1173    * --------------------------------------------------------------------- */
1174
1175   /* This is to convert the string of Lua code into a proper string, which can then be
1176      emitted into the C/C++ code.
1177      Basically is is a lot of search & replacing of odd sequences
1178    */
1179   void EscapeCode(String* str)
1180   {
1181     //Printf(f_runtime,"/* original luacode:[[[\n%s\n]]]\n*/\n",str);
1182     Chop(str); // trim
1183     Replace(str,"\\","\\\\",DOH_REPLACE_ANY); // \ to \\ (this must be done first)
1184     Replace(str,"\"","\\\"",DOH_REPLACE_ANY); // " to \"
1185     Replace(str,"\n","\\n\"\n  \"",DOH_REPLACE_ANY); // \n to \n"\n" (ie quoting every line)
1186     //Printf(f_runtime,"/* hacked luacode:[[[\n%s\n]]]\n*/\n",str);
1187   } 
1188 };
1189
1190 /* NEW LANGUAGE NOTE:***********************************************
1191  in order to add you language into swig, you need to make the following changes:
1192  - write this file (obviously)
1193  - add into the makefile (not 100% clear on how to do this)
1194  - edit swigmain.cxx to add your module
1195  
1196 near the top of swigmain.cxx, look for this code & add you own codes
1197 ======= begin change ==========
1198 extern "C" {
1199   Language *swig_tcl(void);
1200   Language *swig_python(void);
1201   //etc,etc,etc...
1202   Language *swig_lua(void);     // this is my code
1203 }
1204  
1205   //etc,etc,etc...
1206  
1207 swig_module  modules[] = {
1208   {"-guile",     swig_guile,     "Guile"},
1209   {"-java",      swig_java,      "Java"},
1210   //etc,etc,etc...
1211   {"-lua",       swig_lua,       "Lua"},        // this is my code
1212   {NULL, NULL, NULL}    // this must come at the end of the list
1213 };
1214 ======= end change ==========
1215  
1216 This is all that is needed
1217  
1218 NEW LANGUAGE NOTE:END ************************************************/
1219
1220 /* -----------------------------------------------------------------------------
1221  * swig_lua()    - Instantiate module
1222  * ----------------------------------------------------------------------------- */
1223
1224 extern "C" Language *swig_lua(void) {
1225   return new LUA();
1226 }