]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/wxSWIG/Modules/guile.cxx
1 /*******************************************************************************
2 * Simplified Wrapper and Interface Generator (SWIG)
4 * Author : David Beazley
6 * Department of Computer Science
7 * University of Chicago
10 * beazley@cs.uchicago.edu
12 * Please read the file LICENSE for the copyright and terms by which SWIG
13 * can be used and distributed.
14 *******************************************************************************/
16 /***********************************************************************
21 * Definitions for adding functions to Guile 3.0
22 ***********************************************************************/
27 static char *guile_usage
= "\
28 Guile Options (available with -guile)\n\
29 None available. \n\n";
31 // ---------------------------------------------------------------------
32 // GUILE::parse_args(int argc, char *argv[])
35 // ---------------------------------------------------------------------
37 void GUILE::parse_args(int argc
, char *argv
[]) {
41 sprintf(LibDir
,"%s",guile_path
);
43 // Look for certain command line options
45 // Look for additional command line options.
46 for (i
= 1; i
< argc
; i
++) {
48 if (strcmp(argv
[i
],"-help") == 0) {
49 fputs(guile_usage
,stderr
);
54 // Add a symbol for this module
56 add_symbol("SWIGGUILE",0,0);
58 // Set name of typemaps
60 typemap_lang
= "guile";
64 // --------------------------------------------------------------------
67 // Parse the input file
68 // --------------------------------------------------------------------
73 printf("Generating wrappers for Guile\n");
75 // Print out GUILE specific headers
85 // ---------------------------------------------------------------------
86 // GUILE::set_module(char *mod_name)
88 // Sets the module name.
89 // Does nothing if it's already set (so it can be overridden as a command
92 //----------------------------------------------------------------------
94 void GUILE::set_module(char *mod_name
, char **) {
98 module = new char[strlen(mod_name
)+1];
99 strcpy(module,mod_name
);
103 // ---------------------------------------------------------------------
104 // GUILE::set_init(char *iname)
106 // Sets the initialization function name.
107 // Does nothing if it's already set
109 //----------------------------------------------------------------------
111 void GUILE::set_init(char *iname
) {
115 // ---------------------------------------------------------------------
116 // GUILE::headers(void)
118 // Generate the appropriate header files for GUILE interface.
119 // ----------------------------------------------------------------------
121 void GUILE::headers(void)
124 emit_banner(f_header
);
126 fprintf(f_header
,"/* Implementation : GUILE */\n\n");
127 fprintf(f_header
,"#define SWIGGUILE\n");
128 fprintf(f_header
,"#include <stdio.h>\n");
129 fprintf(f_header
,"#include <string.h>\n");
130 fprintf(f_header
,"#include <stdlib.h>\n");
132 // Write out hex conversion functions
135 if (insert_file("guile.swg", f_header
) == -1) {
136 fprintf(stderr
,"SWIG : Fatal error. Unable to locate 'guile.swg' in SWIG library.\n");
141 fprintf(f_header
,"#ifdef __cplusplus\n");
142 fprintf(f_header
,"extern \"C\" {\n");
143 fprintf(f_header
,"#endif\n");
144 fprintf(f_header
,"extern void SWIG_MakePtr(char *, void *, char *);\n");
145 fprintf(f_header
,"extern void SWIG_RegisterMapping(char *, char *, void *(*)(void *));\n");
146 fprintf(f_header
,"extern char *SWIG_GetPtr(char *, void **, char *);\n");
147 fprintf(f_header
,"#ifdef __cplusplus\n");
148 fprintf(f_header
,"}\n");
149 fprintf(f_header
,"#endif\n");
153 // --------------------------------------------------------------------
154 // GUILE::initialize()
156 // Output initialization code that registers functions with the
158 // ---------------------------------------------------------------------
159 void GUILE::initialize()
165 module = "swig_init";
166 fprintf(stderr
,"SWIG : *** Warning. No module name specified.\n");
169 fprintf(f_header
,"#define SWIG_init %s\n\n", module);
170 fprintf(f_init
,"void %s() {\n", module);
174 while (InitNames
[i
]) {
175 fprintf(f_init
,"\t %s();\n",InitNames
[i
]);
181 // ---------------------------------------------------------------------
182 // GUILE::close(void)
184 // Wrap things up. Close initialization function.
185 // ---------------------------------------------------------------------
187 void GUILE::close(void)
190 emit_ptr_equivalence(f_init
);
191 fprintf(f_init
,"}\n");
195 // ----------------------------------------------------------------------
196 // GUILE::get_pointer(int parm, DataType *t)
198 // Emits code to get a pointer from a parameter and do type checking.
199 // parm is the parameter number. This function is only used
200 // in create_function().
201 // ----------------------------------------------------------------------
203 void GUILE::get_pointer(char *iname
, int parm
, DataType
*t
) {
205 // Pointers are read as hex-strings with encoded type information
206 fprintf(f_wrappers
,"\t _tempc = gh_scm2newstr(s_%d, &_len);\n",parm
);
207 fprintf(f_wrappers
,"\t if (SWIG_GetPtr(_tempc, (void **) &_arg%d,",parm
);
208 if (t
->type
== T_VOID
) fprintf(f_wrappers
,"(char *) 0)) {\n");
210 fprintf(f_wrappers
,"\"%s\")) {\n", t
->print_mangle());
212 // Now emit code according to the level of strictness desired
215 case 0: // No type checking
216 fprintf(f_wrappers
,"\t}\n");
218 case 1: // Warning message only
220 "\t fprintf(stderr,\"Warning : type mismatch in argument %d of %s. Expected %s, received %%s\\n\", _tempc);\n", parm
+1,iname
, t
->print_mangle());
221 fprintf(f_wrappers
,"\t }\n");
223 case 2: // Super strict mode.
225 // fprintf(f_wrappers,"\t\t gscm_error(\"Type error in argument %d of %s. Expected %s.\", s_%d);\n", parm+1,iname,t->print_mangle(),parm);
226 fprintf(f_wrappers
,"\t}\n");
230 fprintf(stderr
,"Unknown strictness level\n");
235 // ----------------------------------------------------------------------
236 // GUILE::create_function(char *name, char *iname, DataType *d,
239 // Create a function declaration and register it with the interpreter.
240 // ----------------------------------------------------------------------
242 void GUILE::create_function(char *name
, char *iname
, DataType
*d
, ParmList
*l
)
255 // Make a wrapper name for this
258 make_wrap_name(wname
);
260 // Now write the wrapper function itself....this is pretty ugly
262 fprintf(f_wrappers
,"SCM _wrap_gscm_%s(",wname
);
267 if (p
->t
->is_pointer
)
269 if ((p
->t
->type
!= T_CHAR
) && (p
->t
->is_pointer
))
272 if ((p
->t
->type
!= T_VOID
) || (p
->t
->is_pointer
))
273 fprintf(f_wrappers
,"SCM s_%d", i
);
274 if ((p
= l
->get_next()))
275 fprintf(f_wrappers
,", ");
278 fprintf(f_wrappers
,")\n{\n");
280 // Declare return variable and arguments
282 pcount
= emit_args(d
,l
,f_wrappers
);
284 // Now declare a few helper variables here
285 if (d
->is_pointer
&& (d
->type
!= T_CHAR
) &&
286 !typemap_lookup("out","guile",d
,name
,"_result","scmresult"))
287 fprintf(f_wrappers
," char _ptemp[128];\n");
289 fprintf(f_wrappers
," char *_tempc;\n");
291 fprintf(f_wrappers
," int _len;\n");
292 fprintf(f_wrappers
," SCM scmresult; /* fun1 */\n");
294 // Now write code to extract the parameters(this is super ugly)
299 // Produce names of source and target
300 sprintf(source
,"s_%d",i
);
301 sprintf(target
,"_arg%d",i
);
303 if ((tm
= typemap_lookup("in","guile",p
->t
,p
->name
,source
,target
))) {
304 // Yep. Use it instead of the default
305 fprintf(f_wrappers
,"%s\n", tm
);
307 if (!p
->t
->is_pointer
) {
319 fprintf(f_wrappers
,"\t _arg%d = %s gh_scm2long(s_%d);\n",i
, p
->t
->print_cast(), i
);
328 fprintf(f_wrappers
,"\t _arg%d = %s gh_scm2ulong(s_%d);\n", i
, p
->t
->print_cast(), i
);
331 // A single character
334 fprintf(f_wrappers
,"\t _arg%d = %s gh_scm2char(s_%d);\n", i
, p
->t
->print_cast(), i
);
341 fprintf(f_wrappers
,"\t _arg%d = %s gh_scm2double(s_%d);\n", i
, p
->t
->print_cast(), i
);
344 // Void.. Do nothing.
349 // This is some sort of user-defined call by value type. We're
350 // going to try and wing it here....
354 // User defined type not allowed by value.
357 fprintf(stderr
,"%s : Line %d. Unable to use type %s as a function argument.\n",
358 input_file
, line_number
, p
->t
->print_type());
363 // Argument is a pointer type. Special case is for char *
364 // since that is usually a string.
366 if ((p
->t
->type
== T_CHAR
) && (p
->t
->is_pointer
== 1)) {
367 fprintf(f_wrappers
,"\t _arg%d = gh_scm2newstr(s_%d, &_len);\n",i
,i
);
370 // Have a generic pointer type here.
372 get_pointer(iname
, i
, p
->t
);
376 if ((tm
= typemap_lookup("check","guile",p
->t
,p
->name
,source
,target
))) {
377 // Yep. Use it instead of the default
378 fprintf(f_wrappers
,"%s\n",tm
);
380 if ((tm
= typemap_lookup("freearg","guile",p
->t
,p
->name
,target
,"scmresult"))) {
381 // Yep. Use it instead of the default
382 cleanup
<< tm
<< "\n";
388 // Now write code to make the function call
390 fprintf(f_wrappers
,"\t SCM_DEFER_INTS;\n");
391 emit_func_call(name
,d
,l
,f_wrappers
);
393 fprintf(f_wrappers
,"\t SCM_ALLOW_INTS;\n");
394 // Now have return value, figure out what to do with it.
396 if ((d
->type
!= T_VOID
) || (d
->is_pointer
)) {
397 if ((tm
= typemap_lookup("out","guile",d
,name
,"_result","scmresult"))) {
398 // Yep. Use it instead of the default
399 fprintf(f_wrappers
,"%s\n",tm
);
401 if (!d
->is_pointer
) {
403 case T_INT
: case T_SINT
:
404 case T_SHORT
: case T_SSHORT
:
405 case T_LONG
: case T_SLONG
:
407 fprintf(f_wrappers
,"\t scmresult = gh_long2scm((long) _result);\n");
413 fprintf(f_wrappers
,"\t scmresult = gh_ulong2scm((unsigned long) _result);\n");
417 fprintf(f_wrappers
,"\t scmresult = gh_double2scm((double) _result);\n");
420 fprintf(f_wrappers
,"\t scmresult = gh_char2scm(_result);\n");
423 fprintf(stderr
,"%s : Line %d: Unable to use return type %s in function %s.\n",
424 input_file
, line_number
, d
->print_type(), name
);
429 // Is a pointer return type
431 if ((d
->type
== T_CHAR
) && (d
->is_pointer
== 1)) {
432 fprintf(f_wrappers
,"\t scmresult = gh_str02scm(_result);\n");
435 // Is an ordinary pointer type.
437 fprintf(f_wrappers
,"\t SWIG_MakePtr(_ptemp, _result,\"%s\");\n",
439 fprintf(f_wrappers
,"\t scmresult = gh_str02scm(_ptemp);\n");
444 /* Some void type. Need to return something. I'll return 1 */
445 fprintf(f_wrappers
,"\t scmresult = gh_int2scm(1);\n");
448 // Dump the argument cleanup code
449 fprintf(f_wrappers
,"%s\n",cleanup
.get());
451 // Look for any remaining cleanup
454 if ((tm
= typemap_lookup("newfree","guile",d
,iname
,"_result",""))) {
455 fprintf(f_wrappers
,"%s\n",tm
);
459 if ((tm
= typemap_lookup("ret","guile",d
,name
,"_result",""))) {
460 // Yep. Use it instead of the default
461 fprintf(f_wrappers
,"%s\n",tm
);
464 // Wrap things up (in a manner of speaking)
466 fprintf(f_wrappers
,"\t return scmresult;\n");
467 fprintf(f_wrappers
,"}\n");
469 // Now register the function
470 fprintf(f_init
,"\t gh_new_procedure(\"%s\", _wrap_gscm_%s, %d, 0, 0);\n",
471 iname
, wname
, pcount
);
473 // Make a documentation entry for this
476 static DocEntry
*last_doc_entry
= 0;
478 usage_func(iname
,d
,l
,&usage
);
479 doc_entry
->usage
<< usage
;
480 if (last_doc_entry
!= doc_entry
) {
481 doc_entry
->cinfo
<< "returns " << d
->print_type();
482 last_doc_entry
= doc_entry
;
488 // -----------------------------------------------------------------------
489 // GUILE::link_variable(char *name, char *iname, DataType *d)
491 // Create a link to a C variable.
492 // This creates a single function _wrap_gscm_var_varname().
493 // This function takes a single optional argument. If supplied, it means
494 // we are setting this variable to some value. If ommitted, it means we are
495 // simply evaluating this variable. Either way, we return the variables
497 // -----------------------------------------------------------------------
499 void GUILE::link_variable(char *name
, char *iname
, DataType
*t
)
504 char *tm2
= typemap_lookup("varout","guile",t
,name
,name
,"scmresult");
506 // evaluation function names
508 sprintf(var_name
,"_wrap_gscm_var_%s",iname
);
510 if ((t
->type
!= T_USER
) || (t
->is_pointer
)) {
512 fprintf(f_wrappers
,"SCM %s(SCM s_0) {\n", var_name
);
514 if (!(Status
& STAT_READONLY
) && (t
->is_pointer
)) {
515 fprintf(f_wrappers
,"\t char *_temp;\n");
516 fprintf(f_wrappers
,"\t int _len;\n");
520 fprintf(f_wrappers
,"\t char _ptemp[128];\n");
522 fprintf(f_wrappers
,"\t SCM scmresult; /* fun2 */\n");
524 // Check for a setting of the variable value
526 fprintf(f_wrappers
,"\t if (s_0 != GH_NOT_PASSED) {\n");
528 // Yup. Extract the type from s_0 and set variable value
529 if (Status
& STAT_READONLY
) {
530 // fprintf(f_wrappers,"\t\t gscm_error(\"Unable to set %s. Variable is read only.\", s_0);\n", iname);
532 if ((tm
= typemap_lookup("varin","guile",t
,name
,"s_0",name
))) {
533 // Yep. Use it instead of the default
534 fprintf(f_wrappers
,"%s\n",tm
);
536 if (!t
->is_pointer
) {
541 case T_INT
: case T_SINT
:
542 case T_SHORT
: case T_SSHORT
:
543 case T_LONG
: case T_SLONG
:
545 fprintf(f_wrappers
,"\t\t %s = %s gh_scm2long(s_0);\n",name
, t
->print_cast());
554 fprintf(f_wrappers
,"\t\t %s = %s gh_scm2ulong(s_0);\n",name
, t
->print_cast());
561 fprintf(f_wrappers
,"\t\t %s = %s gh_scm2double(s_0);\n",name
, t
->print_cast());
567 fprintf(f_wrappers
,"\t\t %s = gh_scm2char(s_0);\n", name
);
573 fprintf(stderr
,"Line %d. Error, unsupported data-type.\n", line_number
);
578 // Have some sort of pointer type here, Process it differently
580 if ((t
->type
== T_CHAR
) && (t
->is_pointer
== 1)) {
581 fprintf(f_wrappers
,"\t\t _temp = gh_scm2newstr(s_0, &_len);\n");
582 fprintf(f_wrappers
,"\t\t if (%s) { free(%s);}\n", name
,name
);
583 fprintf(f_wrappers
,"\t\t %s = (char *) malloc((_len+1)*sizeof(char));\n",name
);
584 fprintf(f_wrappers
,"\t\t strncpy(%s,_temp,_len);\n",name
);
585 fprintf(f_wrappers
,"\t\t %s[_len] = 0;\n", name
);
587 // Set the value of a pointer
588 fprintf(f_wrappers
,"\t\t _temp = gh_scm2newstr(s_0,&_len);\n");
589 fprintf(f_wrappers
,"\t if (SWIG_GetPtr(_temp, (void **) &%s,",name
);
590 if (t
->type
== T_VOID
) fprintf(f_wrappers
,"(char *) 0)) {\n");
592 fprintf(f_wrappers
,"\"%s\")) {\n", t
->print_mangle());
594 // Now emit code according to the level of strictness desired
597 case 0: // No type checking
598 fprintf(f_wrappers
,"\t}\n");
600 case 1: // Warning message only
602 "\t fprintf(stderr,\"Warning : type mismatch in variable %s. Expected %s, received %%s\\n\", _temp);\n", name
, t
->print_mangle());
603 fprintf(f_wrappers
,"\t }\n");
605 case 2: // Super strict mode.
607 // fprintf(f_wrappers,"\t\t gscm_error(\"Type error in variable %s. Expected %s.\", s_0);\n", name,t->print_mangle());
608 fprintf(f_wrappers
,"\t}\n");
612 fprintf(stderr
,"Unknown strictness level\n");
619 fprintf(f_wrappers
,"\t}\n");
621 // Now return the value of the variable (regardless of evaluating or setting)
624 // Yep. Use it instead of the default
625 fprintf(f_wrappers
,"%s\n",tm
);
627 if (!t
->is_pointer
) {
628 /* Return variable by value */
634 case T_INT
: case T_SINT
:
635 case T_SHORT
: case T_SSHORT
:
636 case T_LONG
: case T_SLONG
:
638 fprintf(f_wrappers
,"\t scmresult = gh_long2scm((long) %s);\n", name
);
647 fprintf(f_wrappers
,"\t scmresult = gh_ulong2scm((unsigned long) %s);\n",name
);
654 fprintf(f_wrappers
,"\t scmresult = gh_double2scm((double) %s);\n", name
);
657 fprintf(f_wrappers
,"\t scmresult = gh_char2scm(%s);\n",name
);
665 // Is a pointer return type
667 if ((t
->type
== T_CHAR
) && (t
->is_pointer
== 1)) {
668 fprintf(f_wrappers
,"\t scmresult = gh_str02scm(%s);\n",name
);
670 // Is an ordinary pointer type.
671 fprintf(f_wrappers
,"\t SWIG_MakePtr(_ptemp, %s,\"%s\");\n",name
,
673 fprintf(f_wrappers
,"\t scmresult = gh_str02scm(_ptemp);\n");
677 fprintf(f_wrappers
,"\t return scmresult;\n");
678 fprintf(f_wrappers
,"}\n");
680 // Now add symbol to the Guile interpreter
682 fprintf(f_init
,"\t gh_new_procedure(\"%s\", %s, 0, 1, 0);\n",iname
, var_name
);
685 fprintf(stderr
,"%s : Line %d. ** Warning. Unable to link with type %s (ignored).\n",
686 input_file
, line_number
, t
->print_type());
689 // Add a documentation entry
693 usage_var(iname
,t
,&usage
);
694 doc_entry
->usage
<< usage
;
695 doc_entry
->cinfo
<< "Global : " << t
->print_type() << " " << name
;
701 // -----------------------------------------------------------------------
702 // GUILE::declare_const(char *name, char *iname, DataType *type, char *value)
704 // Makes a constant. Not sure how this is really supposed to work.
705 // I'm going to fake out SWIG and create a variable instead.
706 // ------------------------------------------------------------------------
708 void GUILE::declare_const(char *name
, char *, DataType
*type
, char *value
) {
710 int OldStatus
= Status
; // Save old status flags
713 Status
= STAT_READONLY
; // Enable readonly mode.
715 // Make a static variable;
717 sprintf(var_name
,"_wrap_const_%s",name
);
719 if ((type
->type
== T_USER
) && (!type
->is_pointer
)) {
720 fprintf(stderr
,"%s : Line %d. Unsupported constant value.\n", input_file
, line_number
);
724 // Create variable and assign it a value
726 fprintf(f_header
,"static %s %s = ", type
->print_type(), var_name
);
727 if ((type
->type
== T_CHAR
) && (type
->is_pointer
<= 1)) {
728 fprintf(f_header
,"\"%s\";\n", value
);
730 fprintf(f_header
,"%s;\n", value
);
733 // Now create a variable declaration
735 link_variable(var_name
, name
, type
);
740 usage_const(name
,type
,value
,&usage
);
741 doc_entry
->usage
= "";
742 doc_entry
->usage
<< usage
;
743 doc_entry
->cinfo
= "";
744 doc_entry
->cinfo
<< "Constant: " << type
->print_type();
750 // ----------------------------------------------------------------------
751 // GUILE::usage_var(char *iname, DataType *t, char **s)
753 // Produces a usage string for a Guile variable.
754 // ----------------------------------------------------------------------
756 void GUILE::usage_var(char *iname
, DataType
*t
, char **s
) {
760 sprintf(temp
,"(%s)", iname
);
761 c
= temp
+ strlen(temp
);
763 if (!((t
->type
!= T_USER
) || (t
->is_pointer
))) {
764 sprintf(c
," - unsupported");
768 *s
= new char[strlen(temp
)+1];
772 // ---------------------------------------------------------------------------
773 // GUILE::usage_func(char *iname, DataType *t, ParmList *l, char **s)
775 // Produces a usage string for a function in Guile
776 // ---------------------------------------------------------------------------
778 void GUILE::usage_func(char *iname
, DataType
*, ParmList
*l
,
786 sprintf(temp
,"(%s ", iname
);
787 c
= temp
+ strlen(temp
);
789 /* Now go through and print parameters */
794 /* If parameter has been named, use that. Otherwise, just print a type */
796 if ((p
->t
->type
!= T_VOID
) || (p
->t
->is_pointer
)) {
797 if (strlen(p
->name
) > 0) {
798 sprintf(c
,"%s ",p
->name
);
799 c
+= strlen(p
->name
)+1;
802 sprintf(c
,"%s",p
->t
->name
);
803 c
+= strlen(p
->t
->name
);
804 if (p
->t
->is_pointer
) {
805 for (i
= 0; i
< (p
->t
->is_pointer
-p
->t
->implicit_ptr
); i
++) {
820 *s
= new char[strlen(temp
)+1];
825 // ----------------------------------------------------------------------
826 // GUILE::usage_const(char *iname, DataType *type, char *value, char **s)
828 // Produces a usage string for a Guile constant
829 // ----------------------------------------------------------------------
831 void GUILE::usage_const(char *iname
, DataType
*, char *value
, char **s
) {
835 sprintf(temp
,"(%s %s)", iname
, value
);
838 *s
= new char[strlen(temp
)+1];