git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2008-maciekd@10522 626c5289-ae23-0410-ae9c-e8d60b6d4f22
285 lines
8.3 KiB
C++
285 lines
8.3 KiB
C++
/* -----------------------------------------------------------------------------
|
|
* See the LICENSE file for information on copyright, usage and redistribution
|
|
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
|
|
*
|
|
* c.cxx
|
|
*
|
|
* C language module for SWIG.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
char cvsroot_c_cxx[] = "$Id$";
|
|
|
|
#include "swigmod.h"
|
|
|
|
class C:public Language {
|
|
static const char *usage;
|
|
|
|
File *f_runtime;
|
|
File *f_header;
|
|
File *f_wrappers;
|
|
File *f_init;
|
|
File *f_shadow_c;
|
|
File *f_shadow_h;
|
|
|
|
String *f_shadow_code;
|
|
String *f_shadow_header;
|
|
|
|
bool shadow_flag;
|
|
|
|
public:
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* C()
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
C() : shadow_flag(true) {
|
|
}
|
|
|
|
/* ------------------------------------------------------------
|
|
* main()
|
|
* ------------------------------------------------------------ */
|
|
|
|
virtual void main(int argc, char *argv[]) {
|
|
|
|
SWIG_library_directory("c");
|
|
|
|
// Add a symbol to the parser for conditional compilation
|
|
Preprocessor_define("SWIGC 1", 0);
|
|
|
|
// Add typemap definitions
|
|
SWIG_typemap_lang("c");
|
|
SWIG_config_file("c.swg");
|
|
|
|
// Look for certain command line options
|
|
for (int i = 1; i < argc; i++) {
|
|
if (argv[i]) {
|
|
if (strcmp(argv[i], "-help") == 0) {
|
|
Printf(stdout, "%s\n", usage);
|
|
} else if ((strcmp(argv[i], "-shadow") == 0) || (strcmp(argv[i], "-proxy") == 0)) {
|
|
shadow_flag = true;
|
|
} else if (strcmp(argv[i], "-noproxy") == 0) {
|
|
shadow_flag = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void emitBanner(File *f) {
|
|
Printf(f, "/* This file was automatically generated by SWIG (http://www.swig.org).\n");
|
|
Printf(f, " * Version %s\n", Swig_package_version());
|
|
Printf(f, " * \n");
|
|
Printf(f, " * Don't modify this file, modify the SWIG interface instead.\n");
|
|
Printf(f, " */\n\n");
|
|
}
|
|
|
|
void emitMingwLinkFix(File *f) {
|
|
Printf(f, "#ifndef __GNUC__\n");
|
|
Printf(f, "# define __DLL_IMPORT __declspec(dllimport)\n");
|
|
Printf(f, "#else\n");
|
|
Printf(f, "# define __DLL_IMPORT __attribute__((dllimport)) extern\n");
|
|
Printf(f, "#endif\n\n");
|
|
Printf(f, "#if defined (BUILD_ddd_DLL) || !defined (__WIN32__)\n");
|
|
Printf(f, "# define DLL_IMPORT extern\n");
|
|
Printf(f, "#else\n");
|
|
Printf(f, "# define DLL_IMPORT __DLL_IMPORT\n");
|
|
Printf(f, "#endif\n\n");
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------
|
|
* top()
|
|
* --------------------------------------------------------------------- */
|
|
|
|
virtual int top(Node *n) {
|
|
String *module = Getattr(n, "name");
|
|
String *outfile = Getattr(n, "outfile");
|
|
|
|
/* initialize I/O */
|
|
f_runtime = NewFile(outfile, "w");
|
|
if (!f_runtime) {
|
|
FileErrorDisplay(outfile);
|
|
SWIG_exit(EXIT_FAILURE);
|
|
}
|
|
f_init = NewString("");
|
|
f_header = NewString("");
|
|
f_wrappers = NewString("");
|
|
|
|
/* generate shadow files if enabled */
|
|
if (shadow_flag) {
|
|
f_shadow_code = NewString("");
|
|
f_shadow_header = NewString("");
|
|
|
|
/* create shadow file with appropriate name */
|
|
String *shadow_code_filename = NewStringf("%s%s_proxy.c", SWIG_output_directory(), Char(module));
|
|
if ((f_shadow_c = NewFile(shadow_code_filename, "w")) == 0) {
|
|
FileErrorDisplay(shadow_code_filename);
|
|
SWIG_exit(EXIT_FAILURE);
|
|
}
|
|
|
|
String *shadow_header_filename = NewStringf("%s%s_proxy.h", SWIG_output_directory(), Char(module));
|
|
if ((f_shadow_h = NewFile(shadow_header_filename, "w")) == 0) {
|
|
FileErrorDisplay(shadow_header_filename);
|
|
SWIG_exit(EXIT_FAILURE);
|
|
}
|
|
|
|
Swig_register_filebyname("shadow_code", f_shadow_code);
|
|
Swig_register_filebyname("shadow_header", f_shadow_header);
|
|
|
|
emitBanner(f_shadow_code);
|
|
emitBanner(f_shadow_header);
|
|
emitMingwLinkFix(f_shadow_header);
|
|
Printf(f_shadow_code, "#include \"%s\"\n\n", shadow_header_filename);
|
|
}
|
|
|
|
Swig_register_filebyname("header", f_header);
|
|
Swig_register_filebyname("wrappers", f_wrappers);
|
|
Swig_register_filebyname("runtime", f_runtime);
|
|
Swig_register_filebyname("init", f_init);
|
|
|
|
/* emit code for children */
|
|
Language::top(n);
|
|
|
|
/* finalize generating shadow file */
|
|
if (shadow_flag) {
|
|
Printv(f_shadow_c, f_shadow_code, "\n", NIL);
|
|
Printv(f_shadow_h, f_shadow_header, "\n", NIL);
|
|
Close(f_shadow_c);
|
|
Close(f_shadow_h);
|
|
Delete(f_shadow_code);
|
|
Delete(f_shadow_header);
|
|
}
|
|
|
|
/* write all to file */
|
|
Dump(f_header, f_runtime);
|
|
Dump(f_wrappers, f_runtime);
|
|
Wrapper_pretty_print(f_init, f_runtime);
|
|
|
|
/* cleanup */
|
|
Delete(f_header);
|
|
Delete(f_wrappers);
|
|
Delete(f_init);
|
|
Close(f_runtime);
|
|
Delete(f_runtime);
|
|
|
|
return SWIG_OK;
|
|
}
|
|
|
|
virtual int globalvariableHandler(Node *n) {
|
|
if (shadow_flag) {
|
|
Printv(f_shadow_header, "DLL_IMPORT ", Getattr(n, "type"), " ", Getattr(n, "name"), NIL);
|
|
String *defval = NewString("");
|
|
defval = Getattr(n, "value");
|
|
if (defval) {
|
|
Printv(f_shadow_header, " = ", defval, NIL);
|
|
}
|
|
Printf(f_shadow_header, ";\n");
|
|
}
|
|
return SWIG_OK;
|
|
}
|
|
|
|
virtual int functionWrapper(Node *n) {
|
|
String *name = Getattr(n, "sym:name");
|
|
SwigType *type = Getattr(n, "type");
|
|
ParmList *parms = Getattr(n, "parms");
|
|
|
|
/* create new wrapper name */
|
|
Wrapper *wrapper = NewWrapper();
|
|
String *wname = Swig_name_wrapper(name);
|
|
Setattr(n, "wrap:name", wname);
|
|
|
|
/* create wrapper function prototype */
|
|
Printv(wrapper->def, type, " ", wname, "(", NIL);
|
|
|
|
/* prepare parameter list */
|
|
Parm *p, *np;
|
|
for (p = parms; p; ) {
|
|
np = nextSibling(p);
|
|
Printv(wrapper->def, Getattr(p, "type"), " ", Getattr(p, "lname"), np ? ", " : "", NIL);
|
|
Printf(stdout, "%s\n", Getattr(p, "tmap:argout"));
|
|
p = np;
|
|
}
|
|
Printv(wrapper->def, ") {", NIL);
|
|
|
|
/* declare wrapper function local variables */
|
|
emit_return_variable(n, type, wrapper);
|
|
|
|
/* emit action code */
|
|
String *action = emit_action(n);
|
|
Append(wrapper->code, action);
|
|
Append(wrapper->code, "return result;\n}\n");
|
|
|
|
Wrapper_print(wrapper, f_wrappers);
|
|
|
|
/* take care of shadow function */
|
|
if (shadow_flag) {
|
|
String *proto = ParmList_str(parms);
|
|
String *arg_names = NewString("");
|
|
|
|
Parm *p, *np;
|
|
for (p = parms; p; ) {
|
|
np = nextSibling(p);
|
|
Printv(arg_names, Getattr(p, "name"), np ? ", " : "", NIL);
|
|
p = np;
|
|
}
|
|
|
|
Printv(f_shadow_code, "extern ", type, " _wrap_", name, "(", proto, ");\n", NIL);
|
|
Printv(f_shadow_code, type, " ", name, "(", proto, ") {\n", NIL);
|
|
|
|
/* handle 'prepend' feature */
|
|
String *prepend_str = Getattr(n, "feature:prepend");
|
|
if (prepend_str) {
|
|
char *t = Char(prepend_str);
|
|
if (*t == '{') {
|
|
Delitem(prepend_str, 0);
|
|
Delitem(prepend_str, DOH_END);
|
|
}
|
|
Printv(f_shadow_code, prepend_str, "\n", NIL);
|
|
}
|
|
|
|
/* call to the wrapper function */
|
|
Printv(f_shadow_code, " return ", wname, "(", arg_names, ");\n", NIL);
|
|
|
|
/* handle 'append' feature */
|
|
String *append_str = Getattr(n, "feature:append");
|
|
if (append_str) {
|
|
char *t = Char(append_str);
|
|
if (*t == '{') {
|
|
Delitem(append_str, 0);
|
|
Delitem(append_str, DOH_END);
|
|
}
|
|
Printv(f_shadow_code, append_str, "\n", NIL);
|
|
}
|
|
|
|
Printv(f_shadow_code, "}\n", NIL);
|
|
|
|
/* add function declaration to the proxy header file */
|
|
Printv(f_shadow_header, type, " ", name, "(", proto, ");\n");
|
|
}
|
|
|
|
Delete(wname);
|
|
DelWrapper(wrapper);
|
|
|
|
return SWIG_OK;
|
|
}
|
|
|
|
}; /* class C */
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* swig_c() - Instantiate module
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
static Language *new_swig_c() {
|
|
return new C();
|
|
}
|
|
|
|
extern "C" Language *swig_c(void) {
|
|
return new_swig_c();
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Static member variables
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
const char *C::usage = (char *) "\
|
|
C Options (available with -c)\n\
|
|
\n";
|
|
|