blob: a865b8f15f2e3899c7a95d1323c8ceb284ee15c0 [file] [log] [blame]
/* -----------------------------------------------------------------------------
* This file is part of SWIG, which is licensed as a whole under version 3
* (or any later version) of the GNU General Public License. Some additional
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
*
* com.cxx
*
* COM module for SWIG.
* ----------------------------------------------------------------------------- */
char cvsroot_com_cxx[] = "$Id$";
#include "swigmod.h"
#include "cparse.h"
#include <stdio.h>
typedef struct {
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[8];
} GUID, UUID;
bool isNilGUID(GUID *arg) {
if (arg->Data1 != 0 || arg->Data2 != 0 || arg->Data3 != 0)
return false;
for (int i = 0; i < 8; ++i)
if (arg->Data4[i] != 0)
return false;
return true;
}
typedef struct {
unsigned char octets[20];
} SHA1_hash;
/* Rotate left a 32-bit number */
unsigned int leftrot(unsigned int a, unsigned int pos) {
return (a << pos) | ((a >> (32 - pos)) & ((1 << pos) - 1));
}
/* Implementation of SHA1. Needs unsigned int with at least 32 bits */
SHA1_hash SHA1(char *input_bytes, int input_len) {
unsigned int h0 = 0x67452301;
unsigned int h1 = 0xEFCDAB89;
unsigned int h2 = 0x98BADCFE;
unsigned int h3 = 0x10325476;
unsigned int h4 = 0xC3D2E1F0;
/*
* Preprocessing: a '1'-bit is appended, followed by '0'-bits
* until the number of bits % 512 == 448. Then the input's length
* in bits is appended as a 64-bit number. The preprocessed input's
* length is a multiple of 512 bits (64 bytes). Please note
* that below the counting is in bytes instead of bits.
*/
unsigned int padding = ((64 + 56) - (input_len + 1) % 64) % 64;
unsigned int total_len = input_len + 1 + padding + 8;
/* Preprocessed input */
unsigned char *prep = new unsigned char[total_len];
/* Copy the input to prep */
for (unsigned int i = 0; i < input_len; ++i)
prep[i] = input_bytes[i];
/* Marker with single '1'-bit in most significant position */
prep[input_len] = 0x80;
/* Pad with 0's */
for (unsigned int i = 0; i < padding; ++i)
prep[input_len + 1 + i] = 0;
/* Finally append 8 * input_len as a 64-bit number in big-endian format */
unsigned int high_dword = (input_len >> 29) & 7;
unsigned int low_dword = (input_len & ((1 << 29) - 1)) << 3;
prep[total_len - 8] = high_dword >> 24;
prep[total_len - 7] = (high_dword >> 16) & 0xff;
prep[total_len - 6] = (high_dword >> 8) & 0xff;
prep[total_len - 5] = high_dword & 0xff;
prep[total_len - 4] = low_dword >> 24;
prep[total_len - 3] = (low_dword >> 16) & 0xff;
prep[total_len - 2] = (low_dword >> 8) & 0xff;
prep[total_len - 1] = low_dword & 0xff;
/* Divide preprocessed input into 512 bit chunks */
for (unsigned int chunk = 0; chunk < total_len / 64; ++chunk) {
unsigned int w[80];
for (int i = 0; i < 16; ++i) {
w[i] = ((unsigned int) prep[64 * chunk + 4 * i] << 24) |
((unsigned int) prep[64 * chunk + 4 * i + 1] << 16) |
((unsigned int) prep[64 * chunk + 4 * i + 2] << 8) |
(unsigned int) prep[64 * chunk + 4 * i + 3];
}
for (int i = 16; i < 80; ++i) {
w[i] = leftrot(w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16], 1);
}
unsigned int a = h0;
unsigned int b = h1;
unsigned int c = h2;
unsigned int d = h3;
unsigned int e = h4;
for (int i = 0; i < 80; ++i) {
unsigned int f, k;
if (i < 20) {
f = (b & c) | (~b & d);
k = 0x5A827999;
} else if (i < 40) {
f = b ^ c ^ d;
k = 0x6ED9EBA1;
} else if (i < 60) {
f = (b & c) | (b & d) | (c & d);
k = 0x8F1BBCDC;
} else {
f = b ^ c ^ d;
k = 0xCA62C1D6;
}
int temp = leftrot(a, 5) + f + e + k + w[i];
e = d;
d = c;
c = leftrot(b, 30);
b = a;
a = temp;
}
h0 = h0 + a;
h1 = h1 + b;
h2 = h2 + c;
h3 = h3 + d;
h4 = h4 + e;
}
delete prep;
SHA1_hash res = {
(h0 >> 24) & 0xff, (h0 >> 16) & 0xff, (h0 >> 8) & 0xff, h0 & 0xff,
(h1 >> 24) & 0xff, (h1 >> 16) & 0xff, (h1 >> 8) & 0xff, h1 & 0xff,
(h2 >> 24) & 0xff, (h2 >> 16) & 0xff, (h2 >> 8) & 0xff, h2 & 0xff,
(h3 >> 24) & 0xff, (h3 >> 16) & 0xff, (h3 >> 8) & 0xff, h3 & 0xff,
(h4 >> 24) & 0xff, (h4 >> 16) & 0xff, (h4 >> 8) & 0xff, h4 & 0xff,
};
return res;
}
class COM:public Language {
static const char *usage;
const String *empty_string;
Hash *swig_types_hash;
List *filenames_list;
File *f_runtime;
File *f_header;
File *f_module;
File *f_deffile;
File *f_rcfile;
File *f_wrappers;
File *f_proxy;
File *f_interface_forward_defs;
File *f_class_defs;
File *f_vtables;
File *f_vtable_defs;
File *f_factory;
File *f_directors;
bool proxy_flag; // Flag for generating proxy classes
bool dllexports_flag;
bool deffile_flag;
bool rcfile_flag;
bool hresult_flag; // Flag specifying whether to use HRESULT as return type
bool enum_constant_flag; // Flag for when wrapping an enum or constant
bool static_flag; // Flag for when wrapping a static functions or member variables
bool variable_wrapper_flag; // Flag for when wrapping a nonstatic member variable
bool wrapping_member_flag; // Flag for when wrapping a member variable/enum/const
bool global_variable_flag; // Flag for when wrapping a global variable
bool generate_property_declaration_flag; // Flag for generating properties
bool member_func_flag;
bool constructor_flag;
String *proxy_class_def;
String *proxy_interface_def;
String *proxy_static_interface_def;
String *proxy_interface_forward_def;
String *proxy_interface_code;
String *proxy_static_interface_code;
String *proxy_class_name;
String *proxy_class_constants_code;
String *clsid_list;
List *proxy_class_member_functions;
String *variable_name; //Name of a variable being wrapped
GUID *proxy_iid;
GUID *proxy_static_iid;
GUID *proxy_clsid;
GUID master_guid;
GUID typelib_guid;
GUID module_iid;
GUID module_clsid;
String *module_class_vtable_code;
String *proxy_class_vtable_code;
String *proxy_static_class_vtable_code;
String *proxy_class_vtable_defs;
String *module_class_name; // module class name
String *module_class_code;
String *namespce;
String *default_ctor_wname;
#if 0
static Parm *NewParmFromNode(SwigType *type, const String_or_char *name, Node *n) {
Parm *p = NewParm(type, name);
Setfile(p, Getfile(n));
Setline(p, Getline(n));
return p;
}
#endif
public:
/* -----------------------------------------------------------------------------
* COM()
* ----------------------------------------------------------------------------- */
COM():empty_string(NewString("")),
proxy_flag(true),
dllexports_flag(true),
deffile_flag(true),
rcfile_flag(true),
hresult_flag(true),
enum_constant_flag(false),
clsid_list(NewString("")),
proxy_class_vtable_code(NewString("")),
proxy_static_class_vtable_code(NewString("")),
proxy_class_vtable_defs(NewString("")),
namespce(NULL) {
/* Use NIL GUID by default */
memset(&master_guid, 0, sizeof(GUID));
memset(&typelib_guid, 0, sizeof(GUID));
memset(&module_iid, 0, sizeof(GUID));
memset(&module_clsid, 0, sizeof(GUID));
director_language = 0;
Swig_symbol_set_case_insensitive_target(1);
}
/* -----------------------------------------------------------------------------
* getProxyName()
*
* Test to see if a type corresponds to something wrapped with a proxy class
* Return NULL if not otherwise the proxy class name
* ----------------------------------------------------------------------------- */
String *getProxyName(SwigType *t) {
if (proxy_flag) {
Node *n = classLookup(t);
if (n) {
return Getattr(n, "sym:name");
}
}
return NULL;
}
/* ------------------------------------------------------------
* main()
* ------------------------------------------------------------ */
virtual void main(int argc, char *argv[]) {
SWIG_library_directory("com");
// 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], "-nodllexports") == 0)) {
Swig_mark_arg(i);
dllexports_flag = false;
deffile_flag = false;
rcfile_flag = false;
} else if (strcmp(argv[i], "-nodeffile") == 0) {
Swig_mark_arg(i);
deffile_flag = false;
} else if (strcmp(argv[i], "-norcfile") == 0) {
Swig_mark_arg(i);
rcfile_flag = false;
} else if (strcmp(argv[i], "-namespace") == 0) {
if (argv[i + 1]) {
namespce = NewString("");
Printf(namespce, argv[i + 1]);
Swig_mark_arg(i);
Swig_mark_arg(i + 1);
i++;
} else {
Swig_arg_error();
}
}
}
}
// Add a symbol to the parser for conditional compilation
Preprocessor_define("SWIGCOM 1", 0);
// Add typemap definitions
SWIG_typemap_lang("com");
SWIG_config_file("com.swg");
allow_overloading(0);
}
/* ---------------------------------------------------------------------
* top()
* --------------------------------------------------------------------- */
virtual int top(Node *n) {
// Get any options set in the module directive
Node *optionsnode = Getattr(Getattr(n, "module"), "options");
if (optionsnode) {
if (Getattr(optionsnode, "masterguid")) {
if (!parseGUID(Getattr(optionsnode, "masterguid"), &master_guid)) {
/* Bad GUID */
/* FIXME: report an error */
}
}
if (Getattr(optionsnode, "tlbid")) {
if (!parseGUID(Getattr(optionsnode, "tlbid"), &typelib_guid)) {
/* Bad GUID */
/* FIXME: report an error */
}
}
if (Getattr(optionsnode, "moduleiid")) {
if (!parseGUID(Getattr(optionsnode, "moduleiid"), &module_iid)) {
/* Bad GUID */
/* FIXME: report an error */
}
}
if (Getattr(optionsnode, "moduleclsid")) {
if (!parseGUID(Getattr(optionsnode, "moduleclsid"), &module_clsid)) {
/* Bad GUID */
/* FIXME: report an error */
}
}
#if 0
if (Getattr(optionsnode, "directors")) {
allow_directors();
}
#endif
}
/* Initialize all of the output files */
String *outfile = Getattr(n, "outfile");
String *outfile_h = Getattr(n, "outfile_h");
if (!outfile) {
Printf(stderr, "Unable to determine outfile\n");
SWIG_exit(EXIT_FAILURE);
}
f_runtime = NewFile(outfile, "w", SWIG_output_files());
if (!f_runtime) {
FileErrorDisplay(outfile);
SWIG_exit(EXIT_FAILURE);
}
f_header = NewString("");
f_wrappers = NewString("");
f_proxy = NewString("");
f_class_defs = NewString("");
f_interface_forward_defs = NewString("");
f_vtables = NewString("");
f_vtable_defs = NewString("");
f_directors = NewString("");
f_factory = NewString("");
/* Register file targets with the SWIG file handler */
Swig_register_filebyname("header", f_header);
Swig_register_filebyname("wrapper", f_wrappers);
Swig_register_filebyname("runtime", f_runtime);
Swig_register_filebyname("factory", f_factory);
swig_types_hash = NewHash();
filenames_list = NewList();
/* FIXME: do it as it is done in other targets */
module_class_name = Copy(Getattr(n, "name"));
if (!namespce)
namespce = Copy(module_class_name);
module_class_code = NewString("");
proxy_class_def = NewString("");
proxy_interface_def = NewString("");
proxy_static_interface_def = NewString("");
proxy_interface_forward_def = NewString("");
proxy_interface_code = NewString("");
proxy_static_interface_code = NewString("");
if (isNilGUID(&typelib_guid)) {
String *tlbid_ident = NewStringf("%s.%s.TLBID", namespce, module_class_name);
generateGUID(&typelib_guid, tlbid_ident);
Delete(tlbid_ident);
}
if (isNilGUID(&module_iid)) {
String *module_iid_ident = NewStringf("%s.%s.IID", namespce, module_class_name);
generateGUID(&module_iid, module_iid_ident);
Delete(module_iid_ident);
}
if (isNilGUID(&module_clsid)) {
String *module_clsid_ident = NewStringf("%s.%s.CLSID", namespce, module_class_name);
generateGUID(&module_clsid, module_clsid_ident);
Delete(module_clsid_ident);
}
module_class_vtable_code = NewString("");
Printf(module_class_vtable_code, "GUID IID_I%s = ", module_class_name);
formatGUID(module_class_vtable_code, &module_iid, true);
Printf(module_class_vtable_code, ";\n\n");
Printf(module_class_vtable_code, "GUID CLSID_%s = ", module_class_name);
formatGUID(module_class_vtable_code, &module_clsid, true);
Printf(module_class_vtable_code, ";\n\n");
Printf(module_class_vtable_code, "extern SWIG_funcptr _wrap%s_vtable[];\n\n", module_class_name);
Printf(module_class_vtable_code,
"void * SWIGSTDCALL _wrap_new_%s() {\n"
" return _wrap_new_staticclass(_wrap%s_vtable, &IID_I%s);\n"
"};\n\n",
module_class_name, module_class_name, module_class_name);
Printf(module_class_vtable_code, "SWIG_funcptr _wrap%s_vtable[] = "
"{\n (SWIG_funcptr) _wrap_staticclass_QueryInterface,"
"\n (SWIG_funcptr) SWIGAddRef1,"
"\n (SWIG_funcptr) SWIGRelease1,"
"\n (SWIG_funcptr) SWIGGetTypeInfoCount,"
"\n (SWIG_funcptr) SWIGGetTypeInfo,"
"\n (SWIG_funcptr) SWIGGetIDsOfNames,"
"\n (SWIG_funcptr) SWIGInvoke",
module_class_name);
Printf(clsid_list, "static TCHAR * SWIG_tlb_guid_string = _T(\"{");
formatGUID(clsid_list, &typelib_guid, false);
Printf(clsid_list, "}\");\n\n");
Printf(clsid_list, "static SWIGClassDescription_t SWIGClassDescription[] = {\n");
Printf(clsid_list, " { (SWIG_funcptr) _wrap_new_%s, &CLSID_%s, _T(\"{", module_class_name, module_class_name);
formatGUID(clsid_list, &module_clsid, false);
Printf(clsid_list, "}\"), _T(\"%s.%s\"), 0 },\n", namespce, module_class_name);
/* Emit code */
Language::top(n);
/* Insert guard element */
Printf(clsid_list, " { NULL, NULL, NULL, NULL } /* guard element */\n");
Printf(clsid_list, "};\n\n");
Printv(module_class_vtable_code, "\n};\n\n", NIL);
// Output a COM type wrapper class for each SWIG type
for (Iterator swig_type = First(swig_types_hash); swig_type.key; swig_type = Next(swig_type)) {
emitTypeWrapperClass(swig_type.key, swig_type.item);
}
/* Generate DEF file */
if (deffile_flag) {
String *filen = NewStringf("%s%s.def", SWIG_output_directory(), module_class_name);
f_deffile = NewFile(filen, "w", SWIG_output_files());
if (!f_deffile) {
FileErrorDisplay(filen);
SWIG_exit(EXIT_FAILURE);
}
// Append(filenames_list, Copy(filen));
Delete(filen);
filen = NULL;
Printf(f_deffile, "LIBRARY %s\n", module_class_name);
Printf(f_deffile, "EXPORTS\n"
" DllGetClassObject PRIVATE\n"
" DllCanUnloadNow PRIVATE\n"
" DllRegisterServer PRIVATE\n"
" DllUnregisterServer PRIVATE\n"
" DllMain\n");
}
if (rcfile_flag) {
String *filen = NewStringf("%s%s.rc", SWIG_output_directory(), module_class_name);
f_rcfile = NewFile(filen, "w", SWIG_output_files());
if (!f_rcfile) {
FileErrorDisplay(filen);
SWIG_exit(EXIT_FAILURE);
}
// Append(filenames_list, Copy(filen));
Delete(filen);
filen = NULL;
Printf(f_rcfile, "1 typelib \"%s.tlb\"\n", module_class_name);
}
/* Generate the IDL file containing the module class and proxy classes */
{
String *filen = NewStringf("%s%s.idl", SWIG_output_directory(), module_class_name);
f_module = NewFile(filen, "w", SWIG_output_files());
if (!f_module) {
FileErrorDisplay(filen);
SWIG_exit(EXIT_FAILURE);
}
// Append(filenames_list, Copy(filen));
Delete(filen);
filen = NULL;
// Banner for the IDL file
emitBanner(f_module);
// Header containing IDispatch declaration
// NOTE: MIDL does not need this, but WIDL does (and is sensitive to the position
// in the file where it is imported)
Printf(f_module, "import \"oaidl.idl\";\n\n");
Printf(f_module, "[\n uuid(");
formatGUID(f_module, &typelib_guid, false);
Printf(f_module, "),\n version(1.0)\n]\nlibrary %sTLB {\n\n",
module_class_name);
// Import IDispatch declaration, part 2
Printf(f_module, " importlib(\"stdole2.tlb\");\n\n");
// Forward definitions of interfaces
Printf(f_module, " interface I%s;\n", module_class_name);
Printv(f_module, f_interface_forward_defs, "\n", NIL);
Printv(f_module, " [\n uuid(", NIL);
formatGUID(f_module, &module_clsid, false);
Printv(f_module, ")\n ]\n coclass ", module_class_name, " {\n"
" interface I", module_class_name, ";\n };\n\n", NIL);
// Add the COM class definitions
Printv(f_module, f_class_defs, NIL);
Printf(f_module, "};\n\n");
// Interface for module class
Printf(f_module, "[\n object,\n uuid(");
formatGUID(f_module, &module_iid, false);
Printf(f_module, "),\n dual\n]\ninterface I%s : IDispatch {\n", module_class_name);
// Add the wrapper methods
Printv(f_module, module_class_code, NIL);
Printf(f_module, "};\n\n");
// Add the proxy code
Printv(f_module, f_proxy, NIL);
}
/* Close all of the files */
Dump(f_header, f_runtime);
Delete(f_header);
Printv(f_runtime, f_vtable_defs, "\n", NIL);
Delete(f_vtable_defs);
Dump(f_wrappers, f_runtime);
Delete(f_wrappers);
Dump(f_directors, f_runtime);
Delete(f_directors);
// Vtable for the module class
Printv(f_runtime, module_class_vtable_code, NIL);
Dump(f_vtables, f_runtime);
Delete(f_vtables);
Dump(clsid_list, f_runtime);
Delete(clsid_list);
Replaceall(f_factory, "$module", module_class_name);
if (dllexports_flag)
Dump(f_factory, f_runtime);
Delete(f_factory);
Close(f_runtime);
Delete(f_runtime);
Close(f_module);
Delete(f_module);
if (deffile_flag) {
Close(f_deffile);
Delete(f_deffile);
}
if (rcfile_flag) {
Close(f_rcfile);
Delete(f_rcfile);
}
Delete(namespce);
return SWIG_OK;
}
/* -----------------------------------------------------------------------------
* emitBanner()
* ----------------------------------------------------------------------------- */
void emitBanner(File *f) {
Printf(f, "/* ----------------------------------------------------------------------------\n");
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, " * Do not make changes to this file unless you know what you are doing--modify\n");
Printf(f, " * the SWIG interface file instead.\n");
Printf(f, " * ----------------------------------------------------------------------------- */\n\n");
}
/* -----------------------------------------------------------------------------
* functionWrapper()
* ----------------------------------------------------------------------------- */
virtual int functionWrapper(Node *n) {
String *symname = Getattr(n, "sym:name");
SwigType *t = Getattr(n, "type");
ParmList *l = Getattr(n, "parms");
String *tm;
Parm *p;
int i;
String *c_return_type = NewString("");
String *cleanup = NewString("");
String *outarg = NewString("");
bool is_void_return;
int num_arguments = 0;
int num_required = 0;
/* FIXME */
String *overloaded_name = Copy(symname);
// A new wrapper function object
Wrapper *f = NewWrapper();
// Make a wrapper name for this function
String *wname = Swig_name_wrapper(overloaded_name);
/* Attach the non-standard typemaps to the parameter list. */
Swig_typemap_attach_parms("ctype", l, f);
/* Get return types */
if ((tm = Swig_typemap_lookup("ctype", n, "", 0))) {
String *ctypeout = Getattr(n, "tmap:ctype:out"); // the type in the ctype typemap's out attribute overrides the type in the typemap
if (ctypeout)
tm = ctypeout;
Printf(c_return_type, "%s", tm);
} else {
Swig_warning(WARN_COM_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s\n", SwigType_str(t, 0));
}
is_void_return = (Cmp(c_return_type, "void") == 0);
if (!is_void_return)
Wrapper_add_localv(f, "jresult", c_return_type, "jresult", NIL);
if (hresult_flag) {
Wrapper_add_localv(f, "hres", "HRESULT", "hres", NIL);
Printv(f->def, "HRESULT SWIGSTDCALL ", wname, "(", NIL);
} else {
Printv(f->def, c_return_type, " SWIGSTDCALL ", wname, "(", NIL);
}
// Emit all of the local variables for holding arguments.
emit_parameter_variables(l, f);
/* Attach the standard typemaps */
emit_attach_parmmaps(l, f);
// Parameter overloading
Setattr(n, "wrap:parms", l);
Setattr(n, "wrap:name", wname);
/* Get number of required and total arguments */
num_arguments = emit_num_arguments(l);
num_required = emit_num_required(l);
int gencomma = 0;
/* There are no global or static member functions in COM - thus they need fake 'this' arguments */
// FIXME: this should include static member functions too
if ((!is_wrapping_class() || static_flag) && !enum_constant_flag) {
Printv(f->def, "void *SWIG_ignored", NIL);
gencomma = 1;
}
// Now walk the function parameter list and generate code to get arguments
for (i = 0, p = l; i < num_arguments; i++) {
while (checkAttribute(p, "tmap:in:numinputs", "0")) {
p = Getattr(p, "tmap:in:next");
}
SwigType *pt = Getattr(p, "type");
String *ln = Getattr(p, "lname");
String *c_param_type = NewString("");
String *arg = NewString("");
Printf(arg, "j%s", ln);
/* Get the ctype types of the parameter */
if ((tm = Getattr(p, "tmap:ctype"))) {
Printv(c_param_type, tm, NIL);
} else {
Swig_warning(WARN_COM_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s\n", SwigType_str(pt, 0));
}
// Add parameter to C function
Printv(f->def, gencomma ? ", " : "", c_param_type, " ", arg, NIL);
gencomma = 1;
// Get typemap for this argument
if ((tm = Getattr(p, "tmap:in"))) {
Replaceall(tm, "$source", arg); /* deprecated */
Replaceall(tm, "$target", ln); /* deprecated */
Replaceall(tm, "$arg", arg); /* deprecated? */
Replaceall(tm, "$input", arg);
Setattr(p, "emit:input", arg);
Printf(f->code, "%s\n", tm);
p = Getattr(p, "tmap:in:next");
} else {
Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
p = nextSibling(p);
}
Delete(c_param_type);
Delete(arg);
}
if (!is_void_return && hresult_flag) {
Printv(f->def, gencomma ? ", " : "", c_return_type, "*SWIG_result_ptr", NIL);
gencomma = 1;
}
String *null_attribute = 0;
// Now write code to make the function call
if (Cmp(nodeType(n), "constant") == 0) {
// Wrapping a constant hack
Swig_save("functionWrapper", n, "wrap:action", NIL);
// below based on Swig_VargetToFunction()
SwigType *ty = Swig_wrapped_var_type(Getattr(n, "type"), use_naturalvar_mode(n));
Setattr(n, "wrap:action", NewStringf("result = (%s) %s;", SwigType_lstr(ty, 0), Getattr(n, "value")));
}
String *actioncode = emit_action(n);
if (Cmp(nodeType(n), "constant") == 0)
Swig_restore(n);
/* Return value if necessary */
if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
Replaceall(tm, "$source", "result"); /* deprecated */
if (!hresult_flag) {
Replaceall(tm, "$target", "jresult"); /* deprecated */
Replaceall(tm, "$result", "jresult");
} else {
Replaceall(tm, "$target", "*SWIG_result_ptr"); /* deprecated */
Replaceall(tm, "$result", "*SWIG_result_ptr");
}
if (GetFlag(n, "feature:new"))
Replaceall(tm, "$owner", "1");
else
Replaceall(tm, "$owner", "0");
/* FIXME: see if this is needed and works as it should */
substituteClassname(t, tm);
Printf(f->code, "%s", tm);
null_attribute = Getattr(n, "tmap:out:null");
if (Len(tm))
Printf(f->code, "\n");
} else {
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(t, 0), Getattr(n, "name"));
}
emit_return_variable(n, t, f);
/* Insert cleanup code */
for (p = l; p;) {
if ((tm = Getattr(p, "tmap:freearg"))) {
Replaceall(tm, "$source", Getattr(p, "emit:input")); /* deprecated */
Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */
Replaceall(tm, "$input", Getattr(p, "emit:input"));
Printv(cleanup, tm, "\n", NIL);
p = Getattr(p, "tmap:freearg:next");
} else {
p = nextSibling(p);
}
}
/* Insert argument output code */
for (p = l; p;) {
if ((tm = Getattr(p, "tmap:argout"))) {
Replaceall(tm, "$source", Getattr(p, "emit:input")); /* deprecated */
Replaceall(tm, "$target", Getattr(p, "lname")); /* deprecated */
Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */
Replaceall(tm, "$result", "jresult");
Replaceall(tm, "$input", Getattr(p, "emit:input"));
Printv(outarg, tm, "\n", NIL);
p = Getattr(p, "tmap:argout:next");
} else {
p = nextSibling(p);
}
}
/* Output argument output code */
Printv(f->code, outarg, NIL);
/* Output cleanup code */
Printv(f->code, cleanup, NIL);
Printf(f->def, ") {");
if (!is_void_return && !hresult_flag)
Printv(f->code, " return jresult;\n", NIL);
if (hresult_flag)
Printv(f->code, " return S_OK;\n", NIL);
Printf(f->code, "}\n");
/* Contract macro modification */
Replaceall(f->code, "SWIG_contract_assert(", "SWIG_contract_assert($null, ");
if (hresult_flag) {
Replaceall(f->code, "$null", "E_ABORT");
Replaceall(f->code, "$invalidarg", "E_INVALIDARG");
}
else if (!is_void_return) {
Replaceall(f->code, "$null", "0");
Replaceall(f->code, "$invalidarg", "0");
}
else {
Replaceall(f->code, "$null", "");
Replaceall(f->code, "$invalidarg", "");
}
Wrapper_print(f, f_wrappers);
if (!(proxy_flag && is_wrapping_class()) && !enum_constant_flag && !constructor_flag) {
moduleClassFunctionHandler(n);
Printf(module_class_vtable_code, ",\n (SWIG_funcptr) %s", wname);
} else if (constructor_flag) {
moduleClassFunctionHandler(n);
Printf(proxy_static_class_vtable_code, ",\n (SWIG_funcptr) %s", wname);
}
/*
* Generate the proxy class properties for public member variables.
* Not for enums and constants.
*/
if (proxy_flag && wrapping_member_flag && !enum_constant_flag) {
// Capitalize the first letter in the variable in the getter/setter function name
bool getter_flag = Cmp(symname, Swig_name_set(Swig_name_member(proxy_class_name, variable_name))) != 0;
String *getter_setter_name = NewString("");
Printf(getter_setter_name, "%s", variable_name);
Setattr(n, "proxyfuncname", getter_setter_name);
proxyClassFunctionHandler(n);
Delete(getter_setter_name);
}
Delete(cleanup);
Delete(outarg);
return SWIG_OK;
}
/* -----------------------------------------------------------------------
* globalvariableHandler()
* ------------------------------------------------------------------------ */
virtual int globalvariableHandler(Node *n) {
generate_property_declaration_flag = true;
variable_name = Getattr(n, "sym:name");
global_variable_flag = true;
int ret = Language::globalvariableHandler(n);
global_variable_flag = false;
generate_property_declaration_flag = false;
return ret;
}
/* -----------------------------------------------------------------------
* constantWrapper()
* ------------------------------------------------------------------------ */
virtual int constantWrapper(Node *n) {
generate_property_declaration_flag = true;
variable_wrapper_flag = true;
if (!wrapping_member_flag) {
global_variable_flag = true;
variable_name = Getattr(n, "sym:name");
} else {
static_flag = true;
}
int ret = Language::variableWrapper(n);
global_variable_flag = false;
static_flag = false;
variable_wrapper_flag = false;
generate_property_declaration_flag = false;
return ret;
}
/* ----------------------------------------------------------------------
* memberfunctionHandler()
* ---------------------------------------------------------------------- */
virtual int memberfunctionHandler(Node *n) {
Language::memberfunctionHandler(n);
if (proxy_flag) {
// FIXME: String *overloaded_name = getOverloadedName(n);
String *overloaded_name = Getattr(n, "sym:name");
String *intermediary_function_name = Swig_name_member(proxy_class_name, overloaded_name);
Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
proxyClassFunctionHandler(n);
Delete(overloaded_name);
}
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* membervariableHandler()
* ---------------------------------------------------------------------- */
virtual int membervariableHandler(Node *n) {
generate_property_declaration_flag = true;
variable_name = Getattr(n, "sym:name");
wrapping_member_flag = true;
variable_wrapper_flag = true;
Language::membervariableHandler(n);
wrapping_member_flag = false;
variable_wrapper_flag = false;
generate_property_declaration_flag = false;
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* staticmembervariableHandler()
* ---------------------------------------------------------------------- */
virtual int staticmembervariableHandler(Node *n) {
bool static_const_member_flag = (Getattr(n, "value") == 0);
generate_property_declaration_flag = true;
variable_name = Getattr(n, "sym:name");
wrapping_member_flag = true;
static_flag = true;
Language::staticmembervariableHandler(n);
wrapping_member_flag = false;
static_flag = false;
generate_property_declaration_flag = false;
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* memberconstantHandler()
* ---------------------------------------------------------------------- */
virtual int memberconstantHandler(Node *n) {
variable_name = Getattr(n, "sym:name");
wrapping_member_flag = true;
Language::memberconstantHandler(n);
wrapping_member_flag = false;
return SWIG_OK;
}
/* -----------------------------------------------------------------------------
* constructorHandler()
* ----------------------------------------------------------------------------- */
virtual int constructorHandler(Node *n) {
static_flag = true;
constructor_flag = true;
Language::constructorHandler(n);
constructor_flag = false;
static_flag = false;
if (Getattr(n, "default_constructor") ||
checkAttribute(n, "access", "public") && !Getattr(n, "parms")) {
default_ctor_wname = Copy(Getattr(n, "wrap:name"));
}
return SWIG_OK;
}
/* -----------------------------------------------------------------------------
* moduleClassFunctionHandler()
* ----------------------------------------------------------------------------- */
int moduleClassFunctionHandler(Node *n) {
SwigType *t = Getattr(n, "type");
ParmList *l = Getattr(n, "parms");
String *tm;
String *return_type = NewString("");
String *function_code = NewString("");
Parm *p;
int i;
String *func_name = NULL;
bool setter_flag = false;
bool is_void_return;
if (l) {
if (SwigType_type(Getattr(l, "type")) == T_VOID) {
l = nextSibling(l);
}
}
/* Attach the non-standard typemaps to the parameter list */
Swig_typemap_attach_parms("comtype", l, NULL);
Swig_typemap_attach_parms("comin", l, NULL);
/* Get return types */
if (!constructor_flag && (tm = Swig_typemap_lookup("comtype", n, "", 0))) {
String *comtypeout = Getattr(n, "tmap:comtype:out"); // the type in the comtype typemap's out attribute overrides the type in the typemap
if (comtypeout)
tm = comtypeout;
substituteClassname(t, tm);
Printf(return_type, "%s", tm);
} else if (constructor_flag) {
Printf(return_type, "I%s *", proxy_class_name);
} else {
Swig_warning(WARN_COM_TYPEMAP_COMTYPE_UNDEF, input_file, line_number, "No comtype typemap defined for %s\n", SwigType_str(t, 0));
}
is_void_return = (Cmp(return_type, "void") == 0);
if (proxy_flag && global_variable_flag) {
func_name = NewString("");
setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(variable_name)) == 0);
Printf(func_name, "%s", variable_name);
if (setter_flag) {
Printf(function_code, " [ propput ]\n");
} else {
Printf(function_code, " [ propget ]\n");
}
} else {
/* FIXME: ... */
func_name = Getattr(n, "sym:name");
}
if (hresult_flag) {
Printf(function_code, " HRESULT %s(", func_name);
} else {
Printf(function_code, " %s %s(", return_type, func_name);
}
/* Get number of required and total arguments */
int num_arguments = emit_num_arguments(l);
int num_required = emit_num_required(l);
int gencomma = 0;
/* Output each parameter */
for (i = 0, p = l; i < num_arguments; i++) {
/* Ignored parameters */
while (checkAttribute(p, "tmap:in:numinputs", "0")) {
p = Getattr(p, "tmap:in:next");
}
SwigType *pt = Getattr(p, "type");
String *param_type = NewString("");
/* Get the COM parameter type */
if ((tm = Getattr(p, "tmap:comtype"))) {
/* Check if we should set any special attributes */
String *tm_attr;
if (tm_attr = Getattr(p, "tmap:comptype:attribute")) {
Printf(param_type, "[ %s ] ", tm_attr);
}
substituteClassname(pt, tm);
Printf(param_type, "%s", tm);
} else {
Swig_warning(WARN_COM_TYPEMAP_COMTYPE_UNDEF, input_file, line_number, "No comtype typemap defined for %s\n", SwigType_str(pt, 0));
}
String *arg = makeParameterName(n, p, i, setter_flag);
/* Add parameter to module class function */
if (gencomma >= 2)
Printf(function_code, ", ");
gencomma = 2;
Printf(function_code, "%s %s", param_type, arg);
p = Getattr(p, "tmap:in:next");
Delete(arg);
Delete(param_type);
}
if (hresult_flag && !is_void_return) {
Printv(function_code, gencomma ? ", " : "", "[ retval, out ] ", return_type, "*SWIG_result_ptr", NIL);
gencomma = 2;
}
Printf(function_code, ");\n");
if (!constructor_flag)
Printv(module_class_code, function_code, NIL);
else
Printv(proxy_static_interface_code, function_code, NIL);
Delete(function_code);
Delete(return_type);
return SWIG_OK;
}
/* -----------------------------------------------------------------------------
* emitProxyClassDefAndCPPCasts()
* ----------------------------------------------------------------------------- */
void emitProxyClassDefAndCPPCasts(Node *n) {
String *c_classname = SwigType_namestr(Getattr(n, "name"));
String *c_baseclass = NULL;
String *baseclass = NULL;
String *c_baseclassname = NULL;
String *typemap_lookup_type = Getattr(n, "classtypeobj");
bool feature_director = Swig_directorclass(n) ? true : false;
Node *attributes = NewHash();
const String *pure_baseclass = NewString("");
List *baselist = Getattr(n, "bases");
if (baselist) {
Iterator base = First(baselist);
while (base.item && GetFlag(base.item, "feature:ignore")) {
base = Next(base);
}
if (base.item) {
c_baseclassname = Getattr(base.item, "name");
baseclass = Copy(getProxyName(c_baseclassname));
if (baseclass)
c_baseclass = SwigType_namestr(Getattr(base.item, "name"));
base = Next(base);
/* Warn about multiple inheritance for additional base class(es) */
while (base.item) {
if (GetFlag(base.item, "feature:ignore")) {
base = Next(base);
continue;
}
String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0);
String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0);
Swig_warning(WARN_COM_MULTIPLE_INHERITANCE, input_file, line_number,
"Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in COM.\n", proxyclassname, baseclassname);
base = Next(base);
}
}
}
const String *wanted_base = baseclass ? baseclass : pure_baseclass;
bool derived = baseclass && getProxyName(c_baseclassname);
if (!Getattr(n, "abstract") && default_ctor_wname != NULL) {
Printv(proxy_class_def, " [\n aggregatable,\n uuid(", NIL);
formatGUID(proxy_class_def, proxy_clsid, false);
Printv(proxy_class_def, ")\n ]\n coclass $comclassname {\n"
" interface I$comclassname;\n };\n\n", NIL);
}
Printv(proxy_interface_forward_def, " interface I$comclassname;\n", NIL);
Printv(proxy_interface_forward_def, " interface I$comclassnameStatic;\n", NIL);
Printv(proxy_interface_def, "[\n object,\n uuid(", NIL);
formatGUID(proxy_interface_def, proxy_iid, false);
Printv(proxy_interface_def, "),\n dual\n]\ninterface I$comclassname : ",
"I", *Char(wanted_base) ? wanted_base : "Dispatch", " {\n", NIL);
Delete(attributes);
Printv(proxy_static_interface_def, "[\n object,\n uuid(", NIL);
formatGUID(proxy_static_interface_def, proxy_static_iid, false);
Printv(proxy_static_interface_def, "),\n dual\n]\ninterface I$comclassnameStatic : "
"IDispatch {\n", NIL);
// Add static class property to module class
Printf(module_class_code, " [ propget ]\n"
" HRESULT %s([ retval, out ] I%sStatic **SWIG_result);\n",
proxy_class_name, proxy_class_name);
Printf(module_class_vtable_code, ",\n (SWIG_funcptr) _wrap_%sStatic", proxy_class_name);
Printf(f_wrappers, "extern GUID IID_I%sStatic;\n\n", proxy_class_name);
Printf(f_wrappers, "extern SWIG_funcptr _wrap%sStatic_vtable[];\n\n", proxy_class_name);
Printf(f_wrappers, "HRESULT SWIGSTDCALL _wrap_%sStatic(void *SWIG_ignored, SWIGIUnknown **SWIG_result) {\n"
" *SWIG_result = (SWIGIUnknown *) _wrap_new_staticclass(_wrap%sStatic_vtable, &IID_I%sStatic);\n"
"\n"
" return S_OK;\n"
"}\n\n", proxy_class_name, proxy_class_name, proxy_class_name);
// Substitute various strings into the above template
Replaceall(proxy_interface_code, "$comclassname", proxy_class_name);
Replaceall(proxy_static_interface_code, "$comclassname", proxy_class_name);
Replaceall(proxy_class_def, "$comclassname", proxy_class_name);
Replaceall(proxy_interface_forward_def, "$comclassname", proxy_class_name);
Replaceall(proxy_interface_def, "$comclassname", proxy_class_name);
Replaceall(proxy_static_interface_def, "$comclassname", proxy_class_name);
Replaceall(proxy_class_def, "$module", module_class_name);
Replaceall(proxy_interface_code, "$module", module_class_name);
Replaceall(proxy_static_interface_code, "$module", module_class_name);
Delete(baseclass);
}
/* ----------------------------------------------------------------------
* generateGUID()
* ---------------------------------------------------------------------- */
void generateGUID(GUID *result, String *name) {
int name_len = Len(name);
char *name_chars = Char(name);
char *prep_input = new char[16 + name_len];
/* master_guid serves as a "name space ID" as used in RFC 4122. */
prep_input[0] = (master_guid.Data1 >> 24) & 0xff;
prep_input[1] = (master_guid.Data1 >> 16) & 0xff;
prep_input[2] = (master_guid.Data1 >> 8) & 0xff;
prep_input[3] = master_guid.Data1 & 0xff;
prep_input[4] = (master_guid.Data2 >> 8) & 0xff;
prep_input[5] = master_guid.Data2 & 0xff;
prep_input[6] = (master_guid.Data3 >> 8) & 0xff;
prep_input[7] = master_guid.Data3 & 0xff;
for (int i = 0; i < 8; ++i) {
prep_input[8 + i] = master_guid.Data4[i];
}
for (int i = 0; i < name_len; ++i) {
prep_input[16 + i] = name_chars[i];
}
SHA1_hash hash = SHA1(prep_input, 16 + name_len);
GUID res = {
/* time_low */ ((unsigned int) hash.octets[0] << 24) |
((unsigned int) hash.octets[1] << 16) |
((unsigned int) hash.octets[2] << 8) |
(unsigned int) hash.octets[3],
/* time_mid */ ((unsigned int) hash.octets[4] << 8) |
(unsigned int) hash.octets[5],
/* time_hi_and_version */ ((unsigned int) hash.octets[6] << 8) |
(unsigned int) hash.octets[7],
hash.octets[8],
hash.octets[9],
hash.octets[10],
hash.octets[11],
hash.octets[12],
hash.octets[13],
hash.octets[14],
hash.octets[15],
};
/* Set version to 5 */
res.Data3 &= 0x0fff;
res.Data3 |= 0x5000;
/* Clear top 2 bits of Data4[0] */
res.Data4[0] &= 0x3f;
res.Data4[0] |= 0x80;
*result = res;
delete prep_input;
}
/* ----------------------------------------------------------------------
* formatGUID()
* ---------------------------------------------------------------------- */
void formatGUID(File *output, GUID *input, bool cFormat) {
if (cFormat) {
Printf(output,
"{ 0x%08x, 0x%04x, 0x%04x, { 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x}}",
input->Data1, input->Data2, input->Data3, input->Data4[0], input->Data4[1],
input->Data4[2], input->Data4[3], input->Data4[4], input->Data4[5], input->Data4[6], input->Data4[7]);
} else {
Printf(output,
"%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
input->Data1, input->Data2, input->Data3, (((int) input->Data4[0]) << 8) | input->Data4[1],
input->Data4[2], input->Data4[3], input->Data4[4], input->Data4[5], input->Data4[6], input->Data4[7]);
}
}
/* ----------------------------------------------------------------------
* parseHex()
* ---------------------------------------------------------------------- */
unsigned int parseHex(char *text, int start, int end) {
unsigned int result = 0;
for (int i = start; i < end; ++i) {
int digit = 0;
if (text[i] >= '0' && text[i] <= '9')
digit = text[i] - '0';
else if (text[i] >= 'a' && text[i] <= 'f')
digit = text[i] - 'a' + 10;
else
digit = text[i] - 'A' + 10;
result = 16 * result + digit;
}
return result;
}
/* ----------------------------------------------------------------------
* parseGUID()
* ---------------------------------------------------------------------- */
bool parseGUID(String *input, GUID *output) {
if (!input || Len(input) != 36)
return false;
char *input_chars = Char(input);
/* Check GUID format */
for (int i = 0; i < 36; ++i) {
if (i == 8 || i == 13 || i == 18 || i == 23) {
if (input_chars[i] != '-')
return false;
} else {
if (input_chars[i] >= '0' && input_chars[i] <= '9')
continue;
if (input_chars[i] >= 'a' && input_chars[i] <= 'f')
continue;
if (input_chars[i] >= 'A' && input_chars[i] <= 'F')
continue;
return false;
}
}
output->Data1 = parseHex(input_chars, 0, 8);
output->Data2 = parseHex(input_chars, 9, 13);
output->Data3 = parseHex(input_chars, 14, 18);
output->Data4[0] = parseHex(input_chars, 19, 21);
output->Data4[1] = parseHex(input_chars, 21, 23);
for (int i = 0; i < 6; ++i) {
output->Data4[2 + i] = parseHex(input_chars, 24 + 2 * i, 26 + 2 * i);
}
return true;
}
/* ----------------------------------------------------------------------
* classHandler()
* ---------------------------------------------------------------------- */
virtual int classHandler(Node *n) {
if (proxy_flag) {
proxy_class_name = NewString(Getattr(n, "sym:name"));
List *bases = NULL;
if (!addSymbol(proxy_class_name, n))
return SWIG_ERROR;
if (Cmp(proxy_class_name, module_class_name) == 0) {
Printf(stderr, "Class name cannot be equal to module class name: %s\n", proxy_class_name);
SWIG_exit(EXIT_FAILURE);
}
Clear(proxy_class_def);
Clear(proxy_interface_code);
Clear(proxy_static_interface_code);
Clear(proxy_interface_def);
Clear(proxy_static_interface_def);
Clear(proxy_interface_forward_def);
Clear(proxy_class_vtable_code);
Clear(proxy_static_class_vtable_code);
Clear(proxy_class_vtable_defs);
default_ctor_wname = NULL;
proxy_iid = new GUID;
if (Getattr(n, "feature:iid")) {
parseGUID(Getattr(n, "feature:iid"), proxy_iid);
} else {
String *proxy_iid_ident = NewStringf("%s.%s.IID", namespce, proxy_class_name);
generateGUID(proxy_iid, proxy_iid_ident);
Delete(proxy_iid_ident);
}
Printf(proxy_class_vtable_code, "GUID IID_I%s = ", proxy_class_name);
formatGUID(proxy_class_vtable_code, proxy_iid, true);
Printf(proxy_class_vtable_code, ";\n\n");
proxy_static_iid = new GUID;
{
String *proxy_static_iid_ident = NewStringf("%s.%s.StaticIID", namespce, proxy_class_name);
generateGUID(proxy_static_iid, proxy_static_iid_ident);
Delete(proxy_static_iid_ident);
}
Printf(proxy_static_class_vtable_code, "GUID IID_I%sStatic = ", proxy_class_name);
formatGUID(proxy_static_class_vtable_code, proxy_static_iid, true);
Printf(proxy_static_class_vtable_code, ";\n\n");
Printf(proxy_class_vtable_code, "HRESULT SWIGSTDCALL _wrap%sQueryInterface1(void *that, GUID *iid, "
"void ** ppvObject) {\n", proxy_class_name);
Printf(proxy_class_vtable_code,
" SWIGWrappedObject *obj = (SWIGWrappedObject *) that;\n\n");
/* Look if we are an aggregated object */
Printf(proxy_class_vtable_code,
" if (obj->outer != NULL) {\n"
" return ((HRESULT (SWIGSTDCALL *)(SWIGIUnknown *, GUID *, void **))\n"
" obj->outer->vtable[0])(obj->outer, iid, ppvObject);\n"
" } else {\n");
/* Look if the requested interface is ISWIGWrappedObject */
Printf(proxy_class_vtable_code,
" if (SWIGIsEqual(iid, &IID_ISWIGWrappedObject)) {\n"
" /* FIXME: This could be more elegant */\n"
" SWIGAddRef1(that);\n"
" *ppvObject = &obj->SWIGWrappedObject_vtable;\n"
" return S_OK;\n"
" } else if (SWIGIsEqual(iid, &IID_ISupportErrorInfo)) {\n"
" SWIGAddRef1(that);\n"
" *ppvObject = &obj->ISupportErrorInfo_vtable;\n"
" return S_OK;\n"
" }\n\n");
Printf(proxy_class_vtable_code, " if (SWIGIsEqual(iid, &IID_IUnknown) ||\n"
" SWIGIsEqual(iid, &IID_IDispatch) ||\n"
" SWIGIsEqual(iid, &IID_I%s)", proxy_class_name);
bases = Getattr(n, "bases");
/* Iterate through the ancestors */
while (bases) {
Iterator base = First(bases);
while (base.item && Getattr(base.item, "feature:ignore"))
base = Next(base);
if (base.item) {
Printf(proxy_class_vtable_code, " ||\n SWIGIsEqual(iid, &IID_I%s)", Getattr(base.item, "sym:name"));
/* Get next base */
bases = Getattr(base.item, "bases");
} else {
bases = NULL;
}
}
Printf(proxy_class_vtable_code, ") {\n"
" SWIGAddRef1(that);\n"
" *ppvObject = obj;\n"
" return S_OK;\n"
" }\n\n");
Printf(proxy_class_vtable_code, " return E_NOINTERFACE;\n }\n");
Printf(proxy_class_vtable_code, "}\n\n");
bases = NULL;
Printf(proxy_class_vtable_code, "HRESULT SWIGSTDCALL _wrap%sQueryInterface2(void *that, GUID *iid, "
"void ** ppvObject) {\n", proxy_class_name);
Printf(proxy_class_vtable_code,
" return _wrap%sQueryInterface1((void *) ((void **) that - 1), iid, ppvObject);\n", proxy_class_name);
Printf(proxy_class_vtable_code, "}\n\n");
/*
* This code is only slightly different from *QueryInterface1 but there are
* subtle differences because of COM aggregation rules.
*/
Printf(proxy_class_vtable_code, "HRESULT SWIGSTDCALL _wrap%sQueryInterface3(void *that, GUID *iid, "
"void ** ppvObject) {\n", proxy_class_name);
Printf(proxy_class_vtable_code,
" SWIGWrappedObject *obj = (SWIGWrappedObject *) ((void **)that - 2);\n\n");
/* Look if the requested interface is ISWIGWrappedObject */
Printf(proxy_class_vtable_code,
" if (SWIGIsEqual(iid, &IID_ISWIGWrappedObject)) {\n"
" /* FIXME: This could be more elegant */\n"
" SWIGAddRef3(that);\n"
" *ppvObject = &obj->SWIGWrappedObject_vtable;\n"
" return S_OK;\n"
" } else if (SWIGIsEqual(iid, &IID_ISupportErrorInfo)) {\n"
" SWIGAddRef1(that);\n"
" *ppvObject = &obj->ISupportErrorInfo_vtable;\n"
" return S_OK;\n"
" }\n\n");
/* Special case for aggregation - IUnknown has to be different */
Printf(proxy_class_vtable_code,
" if (SWIGIsEqual(iid, &IID_IUnknown)) {\n"
" /* FIXME: This could be more elegant */\n"
" SWIGAddRef3(that);\n"
" *ppvObject = &obj->aggregated_vtable;\n"
" return S_OK;\n"
" }\n\n");
Printf(proxy_class_vtable_code, " if (SWIGIsEqual(iid, &IID_IDispatch) ||\n"
" SWIGIsEqual(iid, &IID_I%s)", proxy_class_name);
bases = Getattr(n, "bases");
/* Iterate through the ancestors */
while (bases) {
Iterator base = First(bases);
while (base.item && Getattr(base.item, "feature:ignore"))
base = Next(base);
if (base.item) {
Printf(proxy_class_vtable_code, " ||\n SWIGIsEqual(iid, &IID_I%s)", Getattr(base.item, "sym:name"));
/* Get next base */
bases = Getattr(base.item, "bases");
} else {
bases = NULL;
}
}
Printf(proxy_class_vtable_code, ") {\n"
" /* FIXME: This could be more elegant */\n"
" SWIGAddRef3(that);\n"
" *ppvObject = obj;\n"
" return S_OK;\n"
" }\n\n");
Printf(proxy_class_vtable_code, " return E_NOINTERFACE;\n");
Printf(proxy_class_vtable_code, "}\n\n");
bases = NULL;
Printf(proxy_class_vtable_code, "SWIG_funcptr _wrap%sSWIGWrappedObject_vtable[] = "
"{\n (SWIG_funcptr) _wrap%sQueryInterface2,"
"\n (SWIG_funcptr) SWIGAddRef2,"
"\n (SWIG_funcptr) SWIGRelease2,"
"\n (SWIG_funcptr) SWIGGetCPtr"
"\n};\n\n",
proxy_class_name, proxy_class_name);
Printf(proxy_class_vtable_code, "SWIG_funcptr _wrap%saggregated_vtable[] = "
"{\n (SWIG_funcptr) _wrap%sQueryInterface3,"
"\n (SWIG_funcptr) SWIGAddRef3,"
"\n (SWIG_funcptr) SWIGRelease3"
"\n};\n\n",
proxy_class_name, proxy_class_name);
Printf(proxy_class_vtable_code, "SWIG_funcptr _wrap%svtable[] = "
"{\n (SWIG_funcptr) _wrap%sQueryInterface1,"
"\n (SWIG_funcptr) SWIGAddRef1,"
"\n (SWIG_funcptr) SWIGRelease1,"
"\n (SWIG_funcptr) SWIGGetTypeInfoCount,"
"\n (SWIG_funcptr) SWIGGetTypeInfo,"
"\n (SWIG_funcptr) SWIGGetIDsOfNames,"
"\n (SWIG_funcptr) SWIGInvoke",
proxy_class_name, proxy_class_name);
bases = Getattr(n, "bases");
if (!bases) {
proxy_class_member_functions = NewList();
} else {
Iterator base = First(bases);
List *base_member_functions = Getattr(base.item, "com:member_functions");
proxy_class_member_functions = NewList();
for (Iterator func = First(base_member_functions); func.item; func = Next(func)) {
Append(proxy_class_member_functions, func.item);
}
}
Setattr(n, "com:member_functions", proxy_class_member_functions);
Printf(proxy_static_class_vtable_code, "extern SWIG_funcptr _wrap%sStatic_vtable[];\n\n", proxy_class_name);
Printf(proxy_static_class_vtable_code, "SWIG_funcptr _wrap%sStatic_vtable[] = "
"{\n (SWIG_funcptr) _wrap_staticclass_QueryInterface,"
"\n (SWIG_funcptr) SWIGAddRef1,"
"\n (SWIG_funcptr) SWIGRelease1,"
"\n (SWIG_funcptr) SWIGGetTypeInfoCount,"
"\n (SWIG_funcptr) SWIGGetTypeInfo,"
"\n (SWIG_funcptr) SWIGGetIDsOfNames,"
"\n (SWIG_funcptr) SWIGInvoke",
proxy_class_name);
proxy_class_constants_code = NewString("");
}
Language::classHandler(n);
if (proxy_flag) {
for (Iterator func = First(proxy_class_member_functions); func.item; func = Next(func)) {
Printf(proxy_class_vtable_code, ",\n (SWIG_funcptr) %s", func.item);
}
if (!Getattr(n, "abstract") && default_ctor_wname != NULL) {
/* Generate class object */
proxy_clsid = new GUID;
if (Getattr(n, "feature:clsid")) {
parseGUID(Getattr(n, "feature:clsid"), proxy_clsid);
} else {
String *proxy_clsid_ident = NewStringf("%s.%s.CLSID", namespce, proxy_class_name);
generateGUID(proxy_clsid, proxy_clsid_ident);
Delete(proxy_clsid_ident);
}
}
emitProxyClassDefAndCPPCasts(n);
Replaceall(proxy_class_def, "$module", module_class_name);
Replaceall(proxy_interface_def, "$module", module_class_name);
Replaceall(proxy_interface_code, "$module", module_class_name);
Replaceall(proxy_static_interface_code, "$module", module_class_name);
Replaceall(proxy_class_constants_code, "$module", module_class_name);
Printv(f_class_defs, proxy_class_def, NIL);
Printv(f_interface_forward_defs, proxy_interface_forward_def, NIL);
Printv(f_proxy, proxy_interface_def, proxy_interface_code, NIL);
// Write out all the constants
if (Len(proxy_class_constants_code) != 0)
Printv(f_proxy, proxy_class_constants_code, NIL);
Printf(f_proxy, "};\n\n");
Printv(f_proxy, proxy_static_interface_def, proxy_static_interface_code, NIL);
Printf(f_proxy, "};\n\n");
Printv(proxy_class_vtable_code, "\n};\n\n", NIL);
String *classtype = Getattr(n, "classtype");
if (!Getattr(n, "abstract") && default_ctor_wname != NULL) {
Printf(proxy_class_vtable_code, "%s* SWIGSTDCALL SWIG_new_%s() {\n"
"#ifdef __cplusplus\n"
" return (%s *) SWIG_wrap%s((void *) new %s(), 1);\n"
"#else\n"
" return (%s *) SWIG_wrap%s((void *) malloc(sizeof(%s)), 1);\n"
"#endif\n"
"}\n\n", classtype, proxy_class_name, classtype, proxy_class_name,
classtype, classtype, proxy_class_name, classtype, classtype);
Printf(proxy_class_vtable_code, "GUID CLSID_%s = ", proxy_class_name);
formatGUID(proxy_class_vtable_code, proxy_clsid, true);
Printf(proxy_class_vtable_code, ";\n\n");
Printf(clsid_list, " { (SWIG_funcptr) SWIG_new_%s, &CLSID_%s, _T(\"{", proxy_class_name, proxy_class_name);
formatGUID(clsid_list, proxy_clsid, false);
Printf(clsid_list, "}\"), _T(\"%s.%s\"), 1 },\n", namespce, proxy_class_name);
}
if (Getattr(n, "has_destructor")) {
Printf(proxy_class_vtable_code, "void SWIG_delete_%s(%s *arg) {\n"
"#ifdef __cplusplus\n"
" delete arg;\n"
"#else\n"
" free(arg);\n"
"#endif\n"
"}\n\n", proxy_class_name, Getattr(n, "classtype"));
}
Printf(proxy_class_vtable_code, "void * SWIGSTDCALL SWIG_wrap%s(void *arg, int cMemOwn) {\n"
"#ifdef __cplusplus\n"
" SWIGWrappedObject *res = new SWIGWrappedObject;\n"
"#else\n"
" SWIGWrappedObject *res = (SWIGWrappedObject *) malloc(sizeof(SWIGWrappedObject));\n"
"#endif\n"
" res->vtable = _wrap%svtable;\n"
" res->SWIGWrappedObject_vtable = _wrap%sSWIGWrappedObject_vtable;\n"
" res->aggregated_vtable = _wrap%saggregated_vtable;\n"
" res->ISupportErrorInfo_vtable = ISupportErrorInfo_vtable;\n"
" res->cPtr = arg;\n"
" res->cMemOwn = cMemOwn;\n"
" res->outer = NULL;\n"
" InterlockedIncrement(&globalRefCount);\n"
" res->refCount = 1;\n",
proxy_class_name, proxy_class_name, proxy_class_name, proxy_class_name);
if (Getattr(n, "has_destructor")) {
Printf(proxy_class_vtable_code,
" res->deleteInstance = (void (*)(void *)) SWIG_delete_%s;\n",
proxy_class_name);
} else {
Printf(proxy_class_vtable_code,
" res->deleteInstance = (void (*)(void *)) 0;\n");
}
Printf(proxy_class_vtable_code,
" /* GetTypeInfoOfGuid */\n"
" ((HRESULT (SWIGSTDCALL *)(ITypeLib *, GUID *, ITypeInfo **)) (((SWIGIUnknown *) SWIG_typelib)->vtable[6]))(SWIG_typelib, &IID_I%s, &res->typeInfo);\n"
" return (void *) res;\n"
"}\n\n",
proxy_class_name);
Printf(proxy_class_vtable_defs,
"void * SWIGSTDCALL SWIG_wrap%s(void *arg, int cMemOwn);\n", proxy_class_name);
Printf(proxy_static_class_vtable_code, "\n};\n\n");
Printv(f_vtables, proxy_class_vtable_code, NIL);
Printv(f_vtables, proxy_static_class_vtable_code, NIL);
Printv(f_vtable_defs, proxy_class_vtable_defs, NIL);
Delete(proxy_class_name);
proxy_class_name = NULL;
Delete(proxy_class_constants_code);
proxy_class_constants_code = NULL;
delete proxy_iid;
delete proxy_static_iid;
if (default_ctor_wname != NULL)
Delete(default_ctor_wname);
}
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* staticmemberfunctionHandler()
* ---------------------------------------------------------------------- */
virtual int staticmemberfunctionHandler(Node *n) {
static_flag = true;
member_func_flag = true;
Language::staticmemberfunctionHandler(n);
if (proxy_flag) {
// FIXME: String *overloaded_name = getOverloadedName(n);
String *overloaded_name = Getattr(n, "sym:name");
String *intermediary_function_name = Swig_name_member(proxy_class_name, overloaded_name);
Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
proxyClassFunctionHandler(n);
Delete(overloaded_name);
}
static_flag = false;
member_func_flag = false;
return SWIG_OK;
}
/* -----------------------------------------------------------------------------
* proxyClassFunctionHandler()
*
* Function called for creating a COM wrapper function around a c++ function in the
* proxy class. Used for both static and non-static C++ class functions.
* C++ class static functions map to member functions of the objects and/or to
* member functions of the module class (TODO).
* ----------------------------------------------------------------------------- */
void proxyClassFunctionHandler(Node *n) {
SwigType *t = Getattr(n, "type");
ParmList *l = Getattr(n, "parms");
String *proxy_function_name = Getattr(n, "proxyfuncname");
String *tm;
Parm *p;
int i;
String *return_type = NewString("");
String *function_code = NewString("");
bool setter_flag = false;
String *pre_code = NewString("");
String *post_code = NewString("");
bool is_void_return;
if (!proxy_flag)
return;
// Wrappers not wanted for some methods where the parameters cannot be overloaded in COM
if (Getattr(n, "overload:ignore"))
return;
// Don't generate proxy method for additional explicitcall method used in directors
if (GetFlag(n, "explicitcall"))
return;
// Check if the name has not already been used in a base class
if (Getattr(n, "overloadsbase")) {
Node *over = Getattr(n, "overloadsbase");
SwigType *tc = Copy(Getattr(n, "decl"));
String *oname;
String *cname;
oname = NewStringf("%s::%s", Getattr(Getattr(n, "sym:symtab"), "name"), Getattr(n, "name"));
cname = NewStringf("%s::%s", Getattr(Getattr(over, "sym:symtab"), "name"), Getattr(over, "name"));
SwigType *tc2 = Copy(Getattr(over, "decl"));
Swig_warning(WARN_LANG_OVERLOAD_DECL, input_file, line_number, "Overloaded declaration ignored. %s\n", SwigType_str(tc, SwigType_namestr(oname)));
Swig_warning(WARN_LANG_OVERLOAD_DECL, Getfile(over), Getline(over), "Previous declaration is %s\n", SwigType_str(tc2, SwigType_namestr(cname)));
Delete(tc2);
Delete(tc);
Delete(oname);
Delete(cname);
return;
}
if (!Getattr(n, "override")) {
String *wname = Getattr(n, "wrap:name");
// FIXME: do we have to use strings?
Setattr(n, "com:vtable_index", NewStringf("%d", Len(proxy_class_member_functions)));
Append(proxy_class_member_functions, wname);
} else {
String *wname = Getattr(n, "wrap:name");
Node *prev = Getattr(n, "override");
int index;
// HACK: maybe there is a simpler way to store an integer in a node? :)
sscanf(Char(Getattr(prev, "com:vtable_index")), "%d", &index);
Setattr(n, "com:vtable_index", NewStringf("%d", index));
Setitem(proxy_class_member_functions, index, wname);
}
if (checkAttribute(n, "storage", "static")) {
// Add function to the static class
String *wname = Getattr(n, "wrap:name");
Printf(proxy_static_class_vtable_code, ",\n (SWIG_funcptr) %s", wname);
}
if (l) {
if (SwigType_type(Getattr(l, "type")) == T_VOID) {
l = nextSibling(l);
}
}
/* Attach the non-standard typemaps to the parameter list */
Swig_typemap_attach_parms("in", l, NULL);
Swig_typemap_attach_parms("comtype", l, NULL);
/* Get return types */
if ((tm = Swig_typemap_lookup("comtype", n, "", 0))) {
// Note that in the case of polymorphic (covariant) return types, the method's return type is changed to be the base of the C++ return type
SwigType *covariant = Getattr(n, "covariant");
substituteClassname(covariant ? covariant : t, tm);
Printf(return_type, "%s", tm);
if (covariant)
Swig_warning(WARN_COM_COVARIANT_RET, input_file, line_number,
"Covariant return types not supported in COM. Proxy method will return %s.\n", SwigType_str(covariant, 0));
} else {
Swig_warning(WARN_COM_TYPEMAP_COMTYPE_UNDEF, input_file, line_number, "No comtype typemap defined for %s\n", SwigType_str(t, 0));
}
is_void_return = (Cmp(return_type, "void") == 0);
if (wrapping_member_flag && !enum_constant_flag) {
// Properties
setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(Swig_name_member(proxy_class_name, variable_name))) == 0);
if (setter_flag) {
Printf(function_code, " [ propput ]\n");
} else {
Printf(function_code, " [ propget ]\n");
}
}
/* Start generating the proxy function */
if (hresult_flag) {
Printf(function_code, " HRESULT %s(", proxy_function_name);
} else {
Printf(function_code, " %s %s(", return_type, proxy_function_name);
}
emit_mark_varargs(l);
int gencomma = 1;
/* Output each parameter */
for (i = 0, p = l; p; i++) {
/* Ignored varargs */
if (checkAttribute(p, "varargs:ignore", "1")) {
p = nextSibling(p);
continue;
}
/* Ignored parameters */
if (checkAttribute(p, "tmap:in:numinputs", "0")) {
p = Getattr(p, "tmap:in:next");
continue;
}
/* Ignore the 'this' argument for variable wrappers */
if (!(variable_wrapper_flag && i == 0) || static_flag) {
SwigType *pt = Getattr(p, "type");
String *param_type = NewString("");
/* Get the COM parameter type */
if ((tm = Getattr(p, "tmap:comtype"))) {
/* Check if we should set any special attributes */
String *tm_attr;
if (tm_attr = Getattr(p, "tmap:comtype:attribute")) {
Printf(param_type, "[ %s ] ", tm_attr);
}
substituteClassname(pt, tm);
Printf(param_type, "%s", tm);
} else {
Swig_warning(WARN_COM_TYPEMAP_COMTYPE_UNDEF, input_file, line_number, "No comtype typemap defined for %s\n", SwigType_str(pt, 0));
}
String *arg = makeParameterName(n, p, i, setter_flag);
/* Add parameter to proxy function */
if (gencomma >= 2)
Printf(function_code, ", ");
gencomma = 2;
Printf(function_code, "%s %s", param_type, arg);
Delete(arg);
Delete(param_type);
}
p = Getattr(p, "tmap:in:next");
}
if (hresult_flag && !is_void_return) {
Printv(function_code, (gencomma >= 2) ? ", " : "", "[ retval, out ] ", return_type, "*SWIG_result_ptr", NIL);
gencomma = 2;
}
Printf(function_code, ")");
Printv(function_code, ";\n", NIL);
if (!Getattr(n, "override")) {
Printv(proxy_interface_code, function_code, NIL);
}
if (checkAttribute(n, "storage", "static")) {
Printv(proxy_static_interface_code, function_code, NIL);
}
Delete(pre_code);
Delete(post_code);
Delete(function_code);
Delete(return_type);
}
/* -----------------------------------------------------------------------------
* makeParameterName()
*
* Inputs:
* n - Node
* p - parameter node
* arg_num - parameter argument number
* setter - set this flag when wrapping variables
* Return:
* arg - a unique parameter name
* ----------------------------------------------------------------------------- */
String *makeParameterName(Node *n, Parm *p, int arg_num, bool setter) {
String *arg = 0;
String *pn = Getattr(p, "name");
// Use C parameter name unless it is a duplicate or an empty parameter name
int count = 0;
ParmList *plist = Getattr(n, "parms");
while (plist) {
if ((Cmp(pn, Getattr(plist, "name")) == 0))
count++;
plist = nextSibling(plist);
}
String *wrn = pn ? Swig_name_warning(p, 0, pn, 0) : 0;
arg = (!pn || (count > 1) || wrn) ? NewStringf("arg%d", arg_num) : Copy(pn);
if (setter && Cmp(arg, "self") != 0) {
// Note that for setters the parameter name is always set but sometimes includes C++
// scope resolution, so we need to strip off the scope resolution to make a valid name.
Delete(arg);
arg = NewString("value"); //Swig_scopename_last(pn);
}
return arg;
}
/* -----------------------------------------------------------------------------
* emitTypeWrapperClass()
* ----------------------------------------------------------------------------- */
void emitTypeWrapperClass(String *classname, SwigType *type) {
Clear(proxy_interface_forward_def);
Clear(proxy_interface_def);
proxy_iid = new GUID;
// FIXME: Maybe we should allow specifying IIDs for opaque classes?
{
String *proxy_iid_ident = NewStringf("%s.%s.IID", namespce, classname);
generateGUID(proxy_iid, proxy_iid_ident);
Delete(proxy_iid_ident);
}
Printf(f_vtable_defs, "GUID IID_I%s = ", classname);
formatGUID(f_vtable_defs, proxy_iid, true);
Printf(f_vtable_defs, ";\n\n");
Printv(proxy_interface_forward_def, " interface I$comclassname;\n", NIL);
Printv(proxy_interface_def, "[\n object,\n uuid(", NIL);
formatGUID(proxy_interface_def, proxy_iid, false);
Printv(proxy_interface_def, ")\n]\ninterface I$comclassname : IUnknown {\n};\n\n", NIL);
Replaceall(proxy_interface_forward_def, "$comclassname", classname);
Replaceall(proxy_interface_def, "$comclassname", classname);
Replaceall(proxy_interface_forward_def, "$module", module_class_name);
Replaceall(proxy_interface_def, "$module", module_class_name);
Printf(f_vtable_defs, "void * SWIGSTDCALL SWIG_wrap%s(void *ptr, int cMemOwn) {\n"
" return SWIG_wrap_opaque(ptr, cMemOwn, &IID_I%s);\n"
"};\n\n", classname, classname);
Printv(f_interface_forward_defs, proxy_interface_forward_def, NIL);
Printv(f_proxy, proxy_interface_def, NIL);
delete proxy_iid;
}
/* -----------------------------------------------------------------------------
* typemapLookup()
* ----------------------------------------------------------------------------- */
const String *typemapLookup(const String *op, String *type, int warning, Node *typemap_attributes = NULL) {
String *tm = NULL;
const String *code = NULL;
if ((tm = Swig_typemap_search(op, type, NULL, NULL))) {
code = Getattr(tm, "code");
if (typemap_attributes)
Swig_typemap_attach_kwargs(tm, op, typemap_attributes);
}
if (!code) {
code = empty_string;
if (warning != WARN_NONE)
Swig_warning(warning, input_file, line_number, "No %s typemap defined for %s\n", op, type);
}
return code ? code : empty_string;
}
/* -----------------------------------------------------------------------------
* substituteClassname()
*
* Substitute $comclassname with the proxy class name for classes/structs/unions that SWIG knows about.
* Also substitutes enums with enum name.
* Otherwise use the $descriptor name for the COM class name. Note that the $&comclassname substitution
* is the same as a $&descriptor substitution, ie one pointer added to descriptor name.
* Inputs:
* pt - parameter type
* tm - comtype typemap
* Outputs:
* tm - comtype typemap with $comclassname substitution
* Return:
* substitution_performed - flag indicating if a substitution was performed
* ----------------------------------------------------------------------------- */
bool substituteClassname(SwigType *pt, String *tm) {
bool substitution_performed = false;
SwigType *type = Copy(SwigType_typedef_resolve_all(pt));
SwigType *strippedtype = SwigType_strip_qualifiers(type);
if (Strstr(tm, "$comclassname")) {
SwigType *classnametype = Copy(strippedtype);
substituteClassnameSpecialVariable(classnametype, tm, "$comclassname");
substitution_performed = true;
Delete(classnametype);
}
if (Strstr(tm, "$*comclassname")) {
SwigType *classnametype = Copy(strippedtype);
Delete(SwigType_pop(classnametype));
substituteClassnameSpecialVariable(classnametype, tm, "$*comclassname");
substitution_performed = true;
Delete(classnametype);
}
if (Strstr(tm, "$&comclassname")) {
SwigType *classnametype = Copy(strippedtype);
SwigType_add_pointer(classnametype);
substituteClassnameSpecialVariable(classnametype, tm, "$&comclassname");
substitution_performed = true;
Delete(classnametype);
}
Delete(strippedtype);
Delete(type);
return substitution_performed;
}
/* -----------------------------------------------------------------------------
* substituteClassnameSpecialVariable()
* ----------------------------------------------------------------------------- */
void substituteClassnameSpecialVariable(SwigType *classnametype, String *tm, const char *classnamespecialvariable) {
if (SwigType_isenum(classnametype)) {
// FIXME: String *enumname = getEnumName(classnametype);
String *enumname = classnametype;
if (enumname)
Replaceall(tm, classnamespecialvariable, enumname);
else
Replaceall(tm, classnamespecialvariable, NewStringf("int"));
} else {
String *classname = getProxyName(classnametype);
if (classname) {
Replaceall(tm, classnamespecialvariable, classname); // getProxyName() works for pointers to classes too
} else { // use $descriptor if SWIG does not know anything about this type. Note that any typedefs are resolved.
String *descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(classnametype));
Replaceall(tm, classnamespecialvariable, descriptor);
// Add to hash table so that the type wrapper classes can be created later
Setattr(swig_types_hash, descriptor, classnametype);
Delete(descriptor);
}
}
}
}; /* class COM */
/* -----------------------------------------------------------------------------
* swig_com() - Instantiate module
* ----------------------------------------------------------------------------- */
static Language *new_swig_com() {
return new COM();
}
extern "C" Language *swig_com(void) {
return new_swig_com();
}
/* -----------------------------------------------------------------------------
* Static member variables
* ----------------------------------------------------------------------------- */
const char *COM::usage = (char *)
"COM Options (available with -com)\n"
" -namespace <nm> - Use <nm> as prefix for Automation names\n"
" (defaults to module name)\n"
// " -norcfile - Do not generate RC (resource definition) file\n"
// " -nodeffile - Do not generate DEF file\n"
// " -nodllexports - Do not generate DllGetClassObject and DllCanUnloadNow\n"
// " (implies -nodeffile)\n"
"\n";