char cvsroot_modula3_cxx[] = "$Id: modula3.cxx 11584 2009-08-16 00:04:29Z wsfulton $";
#include "swigmod.h"
#include <limits.h> // for INT_MAX
#include <ctype.h>
#define USAGE_ARG_DIR "m3wrapargdir typemap expect values: in, out, inout\n"
class MODULA3:public Language {
public:
enum block_type { no_block, constant, variable, blocktype, revelation };
private:
struct M3File {
String *f;
Hash *import;
block_type bt;
M3File():f(NewString("")), import(NewHash()), bt(no_block) {
}
~M3File() {
Delete(f);
Delete(import);
}
void enterBlock(block_type newbt) {
static const char *ident[] = { "", "\nCONST\n", "\nVAR\n", "\nTYPE\n", "\nREVEAL\n" };
#ifdef DEBUG
if ((bt < 0) || (4 < bt)) {
printf("bt %d out of range\n", bt);
}
#endif
if (newbt != bt) {
Append(f, ident[newbt]);
bt = newbt;
}
}
};
static const char *usage;
const String *empty_string;
Hash *swig_types_hash;
File *f_begin;
File *f_runtime;
File *f_header;
File *f_wrappers;
File *f_init;
bool proxy_flag; bool have_default_constructor_flag;
bool native_function_flag; bool enum_constant_flag; bool static_flag; bool variable_wrapper_flag; bool wrapping_member_flag; bool global_variable_flag; bool old_variable_names; bool unsafe_module;
String *m3raw_name; M3File m3raw_intf; M3File m3raw_impl; String *m3wrap_name; M3File m3wrap_intf;
M3File m3wrap_impl;
String *m3makefile;
String *targetlibrary;
String *proxy_class_def;
String *proxy_class_code;
String *proxy_class_name;
String *variable_name; String *variable_type; String *enumeration_name; Hash *enumeration_items; int enumeration_max;
Hash *enumeration_coll;
String *constant_values;
String *constantfilename;
String *renamefilename;
String *typemapfilename;
String *m3raw_imports; String *module_imports; String *m3raw_baseclass; String *module_baseclass; String *m3raw_interfaces; String *module_interfaces; String *m3raw_class_modifiers; String *m3wrap_modifiers; String *upcasts_code; String *m3raw_cppcasts_code; String *destructor_call; String *outfile;
enum type_additions { none, pointer, reference };
public:
MODULA3():
empty_string(NewString("")),
swig_types_hash(NULL),
f_begin(NULL),
f_runtime(NULL),
f_header(NULL),
f_wrappers(NULL),
f_init(NULL),
proxy_flag(true),
have_default_constructor_flag(false),
native_function_flag(false),
enum_constant_flag(false),
static_flag(false),
variable_wrapper_flag(false),
wrapping_member_flag(false),
global_variable_flag(false),
old_variable_names(false),
unsafe_module(false),
m3raw_name(NULL),
m3raw_intf(),
m3raw_impl(),
m3wrap_name(NULL),
m3wrap_intf(),
m3wrap_impl(),
m3makefile(NULL),
targetlibrary(NULL),
proxy_class_def(NULL),
proxy_class_code(NULL),
proxy_class_name(NULL),
variable_name(NULL),
variable_type(NULL),
enumeration_name(NULL),
enumeration_items(NULL),
enumeration_max(0),
enumeration_coll(NULL),
constant_values(NULL),
constantfilename(NULL),
renamefilename(NULL),
typemapfilename(NULL),
m3raw_imports(NULL),
module_imports(NULL),
m3raw_baseclass(NULL),
module_baseclass(NULL),
m3raw_interfaces(NULL),
module_interfaces(NULL),
m3raw_class_modifiers(NULL),
m3wrap_modifiers(NULL),
upcasts_code(NULL),
m3raw_cppcasts_code(NULL),
destructor_call(NULL),
outfile(NULL) {
}
String *getMappedType(Node *p, const char *map) {
String *mapattr = NewString("tmap:");
Append(mapattr, map);
String *tm = Getattr(p, mapattr);
if (tm == NIL) {
Swig_warning(WARN_MODULA3_TYPEMAP_TYPE_UNDEF, input_file, line_number,
"No '%s' typemap defined for type '%s'\n", map, SwigType_str(Getattr(p, "type"), 0));
}
Delete(mapattr);
return tm;
}
String *getMappedTypeNew(Node *n, const char *map, const char *lname = "", bool warn = true) {
String *tm = Swig_typemap_lookup(map, n, lname, 0);
if ((tm == NIL) && warn) {
Swig_warning(WARN_MODULA3_TYPEMAP_TYPE_UNDEF, input_file, line_number,
"No '%s' typemap defined for type '%s'\n", map, SwigType_str(Getattr(n, "type"), 0));
}
return tm;
}
void attachMappedType(Node *n, const char *map, const char *lname = "") {
String *tm = Swig_typemap_lookup(map, n, lname, 0);
if (tm != NIL) {
String *attr = NewStringf("tmap:%s", map);
Setattr(n, attr, tm);
Delete(attr);
}
}
Node *skipIgnored(Node *p, const char *map) {
String *niattr = NewStringf("tmap:%s:numinputs", map);
String *nextattr = NewStringf("tmap:%s:next", map);
while ((p != NIL) && checkAttribute(p, niattr, "0")) {
p = Getattr(p, nextattr);
}
Delete(nextattr);
Delete(niattr);
return p;
}
bool isInParam(Node *p) {
String *dir = Getattr(p, "tmap:m3wrapargdir");
if ((dir == NIL) || (Strcmp(dir, "in") == 0)
|| (Strcmp(dir, "inout") == 0)) {
return true;
} else if (Strcmp(dir, "out") == 0) {
return false;
} else {
printf("%s", USAGE_ARG_DIR);
return false;
}
}
bool isOutParam(Node *p) {
String *dir = Getattr(p, "tmap:m3wrapargdir");
if ((dir == NIL) || (Strcmp(dir, "in") == 0)) {
return false;
} else if ((Strcmp(dir, "out") == 0) || (Strcmp(dir, "inout") == 0)) {
return true;
} else {
printf("%s", USAGE_ARG_DIR);
return false;
}
}
void printAttrs(Node *n) {
Iterator it;
for (it = First(n); it.key != NIL; it = Next(it)) {
printf("%s = %s\n", Char(it.key), Char(Getattr(n, it.key)));
}
}
bool hasPrefix(const String *str, const String *prefix) {
int len_prefix = Len(prefix);
return (Len(str) > len_prefix)
&& (Strncmp(str, prefix, len_prefix) == 0);
}
#if 0
String *getQualifiedName(Node *n) {
String *qual = Swig_symbol_qualified(n);
String *name = Getattr(n, "name");
if (hasContent(qual)) {
return NewStringf("%s::%s", qual, name);
} else {
return name;
}
}
#else
String *getQualifiedName(Node *n) {
String *name = Copy(Getattr(n, "name"));
n = parentNode(n);
while (n != NIL) {
const String *type = nodeType(n);
if ((Strcmp(type, "class") == 0) || (Strcmp(type, "struct") == 0) || (Strcmp(type, "namespace") == 0)) {
String *newname = NewStringf("%s::%s", Getattr(n, "name"), name);
Delete(name);
return newname;
}
n = parentNode(n);
}
return name;
}
#endif
String *nameToModula3(const String *sym, bool leadingCap) {
int len_sym = Len(sym);
char *csym = Char(sym);
char *m3sym = new char[len_sym + 1];
int i, j;
bool cap = leadingCap;
for (i = 0, j = 0; j < len_sym; j++) {
char c = csym[j];
if ((c == '_') || (c == ':')) {
cap = true;
} else {
if (isdigit(c)) {
m3sym[i] = c;
cap = true;
} else {
if (cap) {
m3sym[i] = (char)toupper(c);
} else {
m3sym[i] = (char)tolower(c);
}
cap = false;
}
i++;
}
}
m3sym[i] = 0;
String *result = NewString(m3sym);
delete[]m3sym;
return result;
}
String *capitalizeFirst(const String *str) {
return NewStringf("%c%s", toupper(*Char(str)), Char(str) + 1);
}
String *prefixedNameToModula3(Node *n, const String *sym, bool leadingCap) {
String *oldPrefix = Getattr(n, "feature:modula3:oldprefix");
String *newPrefix = Getattr(n, "feature:modula3:newprefix");
String *result = NewString("");
char *short_sym = Char(sym);
if ((oldPrefix != NIL) || (newPrefix != NIL)) {
if ((oldPrefix == NIL) || hasPrefix(sym, oldPrefix)) {
short_sym += Len(oldPrefix);
if (newPrefix != NIL) {
Append(result, newPrefix);
}
}
}
String *suffix = nameToModula3(short_sym, leadingCap || hasContent(newPrefix));
Append(result, suffix);
Delete(suffix);
return result;
}
bool hasContent(const String *str) {
return (str != NIL) && (Strcmp(str, "") != 0);
}
File *openWriteFile(String *name) {
File *file = NewFile(name, "w", SWIG_output_files());
if (!file) {
FileErrorDisplay(name);
SWIG_exit(EXIT_FAILURE);
}
Delete(name);
return file;
}
long aToL(const String *value) {
char *endptr;
long numvalue = strtol(Char(value), &endptr, 0);
if (*endptr != 0) {
Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "The string <%s> does not denote a numeric value.\n", value);
}
return numvalue;
}
bool strToL(const String *value, long &numvalue) {
char *endptr;
numvalue = strtol(Char(value), &endptr, 0);
return (*endptr == 0);
}
bool evalExpr(String *value, long &numvalue) {
List *summands = Split(value, '+', INT_MAX);
Iterator sm = First(summands);
numvalue = 0;
for (; sm.item != NIL; sm = Next(sm)) {
String *smvalue = Getattr(constant_values, sm.item);
long smnumvalue;
if (smvalue != NIL) {
if (!strToL(smvalue, smnumvalue)) {
return false;
}
} else {
if (!strToL(sm.item, smnumvalue)) {
return false;
}
}
numvalue += smnumvalue;
}
return true;
}
bool log2(long n, long &exp) {
exp = 0;
while (n > 0) {
if ((n & 1) != 0) {
return n == 1;
}
exp++;
n >>= 1;
}
return false;
}
bool equalNilStr(const String *str0, const String *str1) {
if (str0 == NIL) {
return (str1 == NIL);
} else {
return (str1 != NIL) && (Cmp(str0, str1) == 0);
}
}
struct writeArgState {
String *mode, *name, *type, *value;
bool hold;
writeArgState():mode(NIL), name(NIL), type(NIL), value(NIL), hold(false) {
}
};
void writeArg(File *f, writeArgState & state, String *mode, String *name, String *type, String *value) {
if (state.name != NIL) {
if ((!state.hold) && (state.mode != NIL)) {
Printf(f, "%s ", state.mode);
}
if ((name != NIL) && equalNilStr(state.mode, mode) && equalNilStr(state.type, type) && (state.value == NIL) && (value == NIL)
) {
Printf(f, "%s, ", state.name);
state.hold = true;
} else {
Append(f, state.name);
if (state.type != NIL) {
Printf(f, ": %s", state.type);
}
if (state.value != NIL) {
Printf(f, ":= %s", state.value);
}
Append(f, ";\n");
state.hold = false;
}
}
state.mode = mode;
state.name = name;
state.type = type;
state.value = value;
}
String *getProxyName(SwigType *t) {
if (proxy_flag) {
Node *n = classLookup(t);
if (n) {
return Getattr(n, "sym:name");
}
}
return NULL;
}
virtual void main(int argc, char *argv[]) {
SWIG_library_directory("modula3");
for (int i = 1; i < argc; i++) {
if (argv[i]) {
if (strcmp(argv[i], "-generateconst") == 0) {
if (argv[i + 1]) {
constantfilename = NewString(argv[i + 1]);
Swig_mark_arg(i);
Swig_mark_arg(i + 1);
i++;
} else {
Swig_arg_error();
}
} else if (strcmp(argv[i], "-generaterename") == 0) {
if (argv[i + 1]) {
renamefilename = NewString(argv[i + 1]);
Swig_mark_arg(i);
Swig_mark_arg(i + 1);
i++;
} else {
Swig_arg_error();
}
} else if (strcmp(argv[i], "-generatetypemap") == 0) {
if (argv[i + 1]) {
typemapfilename = NewString(argv[i + 1]);
Swig_mark_arg(i);
Swig_mark_arg(i + 1);
i++;
} else {
Swig_arg_error();
}
} else if (strcmp(argv[i], "-noproxy") == 0) {
Swig_mark_arg(i);
proxy_flag = false;
} else if (strcmp(argv[i], "-oldvarnames") == 0) {
Swig_mark_arg(i);
old_variable_names = true;
} else if (strcmp(argv[i], "-help") == 0) {
Printf(stdout, "%s\n", usage);
}
}
}
Preprocessor_define("SWIGMODULA3 1", 0);
SWIG_typemap_lang("modula3");
SWIG_config_file("modula3.swg");
allow_overloading();
}
virtual int top(Node *n) {
if (hasContent(constantfilename) || hasContent(renamefilename) || hasContent(typemapfilename)) {
int result = SWIG_OK;
if (hasContent(constantfilename)) {
result = generateConstantTop(n) && result;
}
if (hasContent(renamefilename)) {
result = generateRenameTop(n) && result;
}
if (hasContent(typemapfilename)) {
result = generateTypemapTop(n) && result;
}
return result;
} else {
return generateM3Top(n);
}
}
void scanConstant(File *file, Node *n) {
Node *child = firstChild(n);
while (child != NIL) {
String *constname = NIL;
String *type = nodeType(child);
if ((Strcmp(type, "enumitem") == 0)
|| (Strcmp(type, "constant") == 0)) {
#if 1
constname = getQualifiedName(child);
#else
constname = Getattr(child, "value");
if ((!hasContent(constname))
|| (('0' <= *Char(constname)) && (*Char(constname) <= '9'))) {
constname = Getattr(child, "name");
}
#endif
}
if (constname != NIL) {
Printf(file, " printf(\"%%%%constnumeric(%%Lg) %s;\\n\", (long double)%s);\n", constname, constname);
}
scanConstant(file, child);
child = nextSibling(child);
}
}
int generateConstantTop(Node *n) {
File *file = openWriteFile(NewStringf("%s.c", constantfilename));
if (CPlusPlus) {
Printf(file, "#include <cstdio>\n");
} else {
Printf(file, "#include <stdio.h>\n");
}
Printf(file, "#include \"%s\"\n", input_file);
Printf(file, "\n");
Printf(file, "int main (int argc, char *argv[]) {\n");
Printf(file, "\
/*This progam must work for floating point numbers and integers.\n\
Thus all numbers are converted to double precision floating point format.*/\n");
scanConstant(file, n);
Printf(file, " return 0;\n");
Printf(file, "}\n");
Close(file);
return SWIG_OK;
}
void scanRename(File *file, Node *n) {
Node *child = firstChild(n);
while (child != NIL) {
String *type = nodeType(child);
if (Strcmp(type, "cdecl") == 0) {
ParmList *p = Getattr(child, "parms");
if (p != NIL) {
String *name = getQualifiedName(child);
String *m3name = nameToModula3(name, true);
Printf(file, "%%rename(\"%s\") %s;\n", m3name, name);
Delete(name);
Delete(m3name);
}
}
scanRename(file, child);
child = nextSibling(child);
}
}
int generateRenameTop(Node *n) {
File *file = openWriteFile(NewStringf("%s.i", renamefilename));
Printf(file, "\
/* This file was generated from %s\n\
by SWIG with option -generaterename. */\n\
\n", input_file);
scanRename(file, n);
Close(file);
return SWIG_OK;
}
void scanTypemap(File *file, Node *n) {
Node *child = firstChild(n);
while (child != NIL) {
String *type = nodeType(child);
String *storage = Getattr(child, "storage");
if ((Strcmp(type, "class") == 0) || ((Strcmp(type, "cdecl") == 0) && (storage != NIL)
&& (Strcmp(storage, "typedef") == 0))) {
String *name = getQualifiedName(child);
String *m3name = nameToModula3(name, true);
Printf(file, "%%typemap(\"m3wrapintype\") %s %%{%s%%}\n", name, m3name);
Printf(file, "%%typemap(\"m3rawintype\") %s %%{%s%%}\n", name, m3name);
Printf(file, "\n");
}
scanTypemap(file, child);
child = nextSibling(child);
}
}
int generateTypemapTop(Node *n) {
File *file = openWriteFile(NewStringf("%s.i", typemapfilename));
Printf(file, "\
/* This file was generated from %s\n\
by SWIG with option -generatetypemap. */\n\
\n", input_file);
scanTypemap(file, n);
Close(file);
return SWIG_OK;
}
int generateM3Top(Node *n) {
outfile = Getattr(n, "outfile");
f_begin = NewFile(outfile, "w", SWIG_output_files());
if (!f_begin) {
FileErrorDisplay(outfile);
SWIG_exit(EXIT_FAILURE);
}
f_runtime = NewString("");
f_init = NewString("");
f_header = NewString("");
f_wrappers = NewString("");
m3makefile = NewString("");
Swig_register_filebyname("header", f_header);
Swig_register_filebyname("wrapper", f_wrappers);
Swig_register_filebyname("begin", f_begin);
Swig_register_filebyname("runtime", f_runtime);
Swig_register_filebyname("init", f_init);
Swig_register_filebyname("m3rawintf", m3raw_intf.f);
Swig_register_filebyname("m3rawimpl", m3raw_impl.f);
Swig_register_filebyname("m3wrapintf", m3wrap_intf.f);
Swig_register_filebyname("m3wrapimpl", m3wrap_impl.f);
Swig_register_filebyname("m3makefile", m3makefile);
swig_types_hash = NewHash();
String *name = Getattr(n, "name");
Node *optionsnode = Getattr(Getattr(n, "module"), "options");
if (optionsnode != NIL) {
String *m3raw_name_tmp = Getattr(optionsnode, "m3rawname");
if (m3raw_name_tmp != NIL) {
m3raw_name = Copy(m3raw_name_tmp);
}
}
if (m3raw_name == NIL) {
m3raw_name = NewStringf("%sRaw", name);
}
Setattr(m3wrap_impl.import, m3raw_name, "");
m3wrap_name = Copy(name);
proxy_class_def = NewString("");
proxy_class_code = NewString("");
m3raw_baseclass = NewString("");
m3raw_interfaces = NewString("");
m3raw_class_modifiers = NewString(""); m3raw_imports = NewString("");
m3raw_cppcasts_code = NewString("");
m3wrap_modifiers = NewString("public");
module_baseclass = NewString("");
module_interfaces = NewString("");
module_imports = NewString("");
upcasts_code = NewString("");
Swig_banner(f_begin);
Printf(f_runtime, "\n");
Printf(f_runtime, "#define SWIGMODULA3\n");
Printf(f_runtime, "\n");
Swig_name_register((char *) "wrapper", (char *) "Modula3_%f");
if (old_variable_names) {
Swig_name_register((char *) "set", (char *) "set_%v");
Swig_name_register((char *) "get", (char *) "get_%v");
}
Printf(f_wrappers, "\n#ifdef __cplusplus\n");
Printf(f_wrappers, "extern \"C\" {\n");
Printf(f_wrappers, "#endif\n\n");
constant_values = NewHash();
scanForConstPragmas(n);
enumeration_coll = NewHash();
collectEnumerations(enumeration_coll, n);
Language::top(n);
{
File *file = openWriteFile(NewStringf("%sm3makefile", Swig_file_dirname(outfile)));
Printf(file, "%% automatically generated quake file for %s\n\n", name);
Printv(file, m3makefile, NIL);
Printf(file, "import(\"libm3\")\n");
Printf(file, "module(\"%s\")\n", m3raw_name);
Printf(file, "module(\"%s\")\n\n", m3wrap_name);
if (targetlibrary != NIL) {
Printf(file, "library(\"%s\")\n", targetlibrary);
} else {
Printf(file, "library(\"m3%s\")\n", name);
}
Close(file);
}
{
File *file = openWriteFile(NewStringf("%s%s.i3", Swig_file_dirname(outfile), m3raw_name));
emitBanner(file);
Printf(file, "INTERFACE %s;\n\n", m3raw_name);
emitImportStatements(m3raw_intf.import, file);
Printf(file, "\n");
Printv(file, m3raw_intf.f, NIL);
Printf(file, "\nEND %s.\n", m3raw_name);
Close(file);
}
{
File *file = openWriteFile(NewStringf("%s%s.m3", Swig_file_dirname(outfile), m3raw_name));
emitBanner(file);
Printf(file, "MODULE %s;\n\n", m3raw_name);
emitImportStatements(m3raw_impl.import, file);
Printf(file, "\n");
Printv(file, m3raw_impl.f, NIL);
Printf(file, "BEGIN\nEND %s.\n", m3raw_name);
Close(file);
}
{
File *file = openWriteFile(NewStringf("%s%s.i3", Swig_file_dirname(outfile), m3wrap_name));
emitBanner(file);
Printf(file, "INTERFACE %s;\n", m3wrap_name);
emitImportStatements(m3wrap_intf.import, file);
Printf(file, "\n");
{
Iterator it = First(enumeration_coll);
if (it.key != NIL) {
Printf(file, "TYPE\n");
}
for (; it.key != NIL; it = Next(it)) {
Printf(file, "\n");
emitEnumeration(file, it.key, it.item);
}
}
Printv(file, m3wrap_intf.f, NIL);
Printf(file, "\nEND %s.\n", m3wrap_name);
Close(file);
}
{
File *file = openWriteFile(NewStringf("%s%s.m3", Swig_file_dirname(outfile), m3wrap_name));
emitBanner(file);
if (unsafe_module) {
Printf(file, "UNSAFE ");
}
Printf(file, "MODULE %s;\n\n", m3wrap_name);
emitImportStatements(m3wrap_impl.import, file);
Printf(file, "\n");
Printv(file, m3wrap_impl.f, NIL);
Printf(file, "\nBEGIN\nEND %s.\n", m3wrap_name);
Close(file);
}
if (upcasts_code)
Printv(f_wrappers, upcasts_code, NIL);
Printf(f_wrappers, "#ifdef __cplusplus\n");
Printf(f_wrappers, "}\n");
Printf(f_wrappers, "#endif\n");
for (Iterator swig_type = First(swig_types_hash); swig_type.item != NIL; swig_type = Next(swig_type)) {
emitTypeWrapperClass(swig_type.key, swig_type.item);
}
Delete(swig_types_hash);
swig_types_hash = NULL;
Delete(constant_values);
constant_values = NULL;
Delete(enumeration_coll);
enumeration_coll = NULL;
Delete(m3raw_name);
m3raw_name = NULL;
Delete(m3raw_baseclass);
m3raw_baseclass = NULL;
Delete(m3raw_interfaces);
m3raw_interfaces = NULL;
Delete(m3raw_class_modifiers);
m3raw_class_modifiers = NULL;
Delete(m3raw_imports);
m3raw_imports = NULL;
Delete(m3raw_cppcasts_code);
m3raw_cppcasts_code = NULL;
Delete(proxy_class_def);
proxy_class_def = NULL;
Delete(proxy_class_code);
proxy_class_code = NULL;
Delete(m3wrap_name);
m3wrap_name = NULL;
Delete(m3wrap_modifiers);
m3wrap_modifiers = NULL;
Delete(targetlibrary);
targetlibrary = NULL;
Delete(module_baseclass);
module_baseclass = NULL;
Delete(module_interfaces);
module_interfaces = NULL;
Delete(module_imports);
module_imports = NULL;
Delete(upcasts_code);
upcasts_code = NULL;
Delete(constantfilename);
constantfilename = NULL;
Delete(renamefilename);
renamefilename = NULL;
Delete(typemapfilename);
typemapfilename = NULL;
Dump(f_runtime, f_begin);
Dump(f_header, f_begin);
Dump(f_wrappers, f_begin);
Wrapper_pretty_print(f_init, f_begin);
Delete(f_header);
Delete(f_wrappers);
Delete(f_init);
Close(f_begin);
Delete(f_runtime);
Delete(f_begin);
return SWIG_OK;
}
void emitBanner(File *f) {
Printf(f, "(*******************************************************************************\n");
Swig_banner_target_lang(f, " *");
Printf(f, "*******************************************************************************)\n\n");
}
virtual int nativeWrapper(Node *n) {
String *wrapname = Getattr(n, "wrap:name");
if (!addSymbol(wrapname, n))
return SWIG_ERROR;
if (Getattr(n, "type")) {
Swig_save("nativeWrapper", n, "name", NIL);
Setattr(n, "name", wrapname);
native_function_flag = true;
functionWrapper(n);
Swig_restore(n);
native_function_flag = false;
} else {
Printf(stderr, "%s : Line %d. No return type for %%native method %s.\n", input_file, line_number, Getattr(n, "wrap:name"));
}
return SWIG_OK;
}
virtual int functionWrapper(Node *n) {
String *type = nodeType(n);
String *funcType = Getattr(n, "modula3:functype");
String *rawname = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
String *capname = capitalizeFirst(symname);
if (Strcmp(type, "cdecl") == 0) {
if (funcType == NIL) {
emitM3RawPrototype(n, rawname, symname);
emitM3Wrapper(n, symname);
} else if (Strcmp(funcType, "method") == 0) {
Setattr(n, "modula3:funcname", capname);
emitCWrapper(n, capname);
emitM3RawPrototype(n, capname, capname);
emitM3Wrapper(n, capname);
} else if (Strcmp(funcType, "accessor") == 0) {
if (proxy_flag && wrapping_member_flag && !enum_constant_flag) {
Setattr(n, "proxyfuncname", capname);
Setattr(n, "imfuncname", symname);
if (hasPrefix(capname, "Set")) {
Setattr(n, "modula3:setname", capname);
} else {
Setattr(n, "modula3:getname", capname);
}
emitCWrapper(n, capname);
emitM3RawPrototype(n, capname, capname);
emitM3Wrapper(n, capname);
}
#ifdef DEBUG
} else {
Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Function type <%s> unknown.\n", Char(funcType));
#endif
}
} else if ((Strcmp(type, "constructor") == 0) || (Strcmp(type, "destructor") == 0)) {
emitCWrapper(n, capname);
emitM3RawPrototype(n, capname, capname);
emitM3Wrapper(n, capname);
}
#if 0
if (!(proxy_flag && is_wrapping_class()) && !enum_constant_flag) {
emitM3Wrapper(n, capname);
}
#endif
Delete(capname);
return SWIG_OK;
}
virtual int emitCWrapper(Node *n, const String *wname) {
String *rawname = Getattr(n, "name");
String *c_return_type = NewString("");
String *cleanup = NewString("");
String *outarg = NewString("");
String *body = NewString("");
Hash *throws_hash = NewHash();
ParmList *l = Getattr(n, "parms");
SwigType *t = Getattr(n, "type");
String *symname = Getattr(n, "sym:name");
if (!Getattr(n, "sym:overloaded")) {
if (!addSymbol(wname, n)) {
return SWIG_ERROR;
}
}
Wrapper *f = NewWrapper();
Swig_typemap_attach_parms("ctype", l, f);
{
String *tm = getMappedTypeNew(n, "ctype", "");
if (tm != NIL) {
Printf(c_return_type, "%s", tm);
}
}
bool is_void_return = (Cmp(c_return_type, "void") == 0);
if (!is_void_return) {
Wrapper_add_localv(f, "cresult", c_return_type, "cresult = 0", NIL);
}
Printv(f->def, " SWIGEXPORT ", c_return_type, " ", wname, "(", NIL);
emit_parameter_variables(l, f);
emit_attach_parmmaps(l, f);
Setattr(n, "wrap:parms", l);
{
Parm *p;
attachParameterNames(n, "tmap:name", "c:wrapname", "m3arg%d");
bool gencomma = false;
for (p = skipIgnored(l, "in"); p != NULL; p = skipIgnored(p, "in")) {
String *arg = Getattr(p, "c:wrapname");
{
String *c_param_type = getMappedType(p, "ctype");
Printv(f->def, gencomma ? ", " : "", c_param_type, " ", arg, NIL);
Delete(c_param_type);
gencomma = true;
}
String *tm = getMappedType(p, "in");
if (tm != NIL) {
addThrows(throws_hash, "in", p);
Replaceall(tm, "$input", arg);
Setattr(p, "emit:input", arg);
Printf(f->code, "%s\n", tm);
p = Getattr(p, "tmap:in:next");
} else {
p = nextSibling(p);
}
}
}
{
Parm *p;
for (p = l; p;) {
String *tm = Getattr(p, "tmap:check");
if (tm != NIL) {
addThrows(throws_hash, "check", p);
Replaceall(tm, "$target", Getattr(p, "lname"));
Replaceall(tm, "$arg", Getattr(p, "emit:input"));
Replaceall(tm, "$input", Getattr(p, "emit:input"));
Printv(f->code, tm, "\n", NIL);
p = Getattr(p, "tmap:check:next");
} else {
p = nextSibling(p);
}
}
}
{
Parm *p;
for (p = l; p;) {
String *tm = Getattr(p, "tmap:freearg");
if (tm != NIL) {
addThrows(throws_hash, "freearg", p);
Replaceall(tm, "$source", Getattr(p, "emit:input"));
Replaceall(tm, "$arg", Getattr(p, "emit:input"));
Replaceall(tm, "$input", Getattr(p, "emit:input"));
Printv(cleanup, tm, "\n", NIL);
p = Getattr(p, "tmap:freearg:next");
} else {
p = nextSibling(p);
}
}
}
{
Parm *p;
for (p = l; p;) {
String *tm = Getattr(p, "tmap:argout");
if (tm != NIL) {
addThrows(throws_hash, "argout", p);
Replaceall(tm, "$source", Getattr(p, "emit:input"));
Replaceall(tm, "$target", Getattr(p, "lname"));
Replaceall(tm, "$arg", Getattr(p, "emit:input"));
Replaceall(tm, "$result", "cresult");
Replaceall(tm, "$input", Getattr(p, "emit:input"));
Printv(outarg, tm, "\n", NIL);
p = Getattr(p, "tmap:argout:next");
} else {
p = nextSibling(p);
}
}
}
ParmList *throw_parm_list = NULL;
if ((throw_parm_list = Getattr(n, "catchlist"))) {
Swig_typemap_attach_parms("throws", throw_parm_list, f);
Parm *p;
for (p = throw_parm_list; p; p = nextSibling(p)) {
addThrows(throws_hash, "throws", p);
}
}
if (Cmp(nodeType(n), "constant") == 0) {
Swig_save("functionWrapper", n, "wrap:action", NIL);
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")));
}
Setattr(n, "wrap:name", wname);
if (!native_function_flag) {
String *actioncode = emit_action(n);
if (Cmp(nodeType(n), "constant") == 0) {
Swig_restore(n);
}
String *tm;
if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
addThrows(throws_hash, "out", n);
Replaceall(tm, "$source", "result");
Replaceall(tm, "$target", "cresult");
Replaceall(tm, "$result", "cresult");
Printf(f->code, "%s", tm);
if (hasContent(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), rawname);
}
emit_return_variable(n, t, f);
}
Printv(f->code, outarg, NIL);
Printv(f->code, cleanup, NIL);
if (GetFlag(n, "feature:new")) {
String *tm = Swig_typemap_lookup("newfree", n, "result", 0);
if (tm != NIL) {
addThrows(throws_hash, "newfree", n);
Replaceall(tm, "$source", "result");
Printf(f->code, "%s\n", tm);
}
}
if (!native_function_flag) {
String *tm = Swig_typemap_lookup("ret", n, "result", 0);
if (tm != NIL) {
Replaceall(tm, "$source", "result");
Printf(f->code, "%s\n", tm);
}
}
Printf(f->def, ") {");
if (!is_void_return)
Printv(f->code, " return cresult;\n", NIL);
Printf(f->code, "}\n");
Replaceall(f->code, "$cleanup", cleanup);
Replaceall(f->code, "$symname", symname);
if (!is_void_return) {
Replaceall(f->code, "$null", "0");
} else {
Replaceall(f->code, "$null", "");
}
if (!native_function_flag) {
Wrapper_print(f, f_wrappers);
}
Delete(c_return_type);
Delete(cleanup);
Delete(outarg);
Delete(body);
Delete(throws_hash);
DelWrapper(f);
return SWIG_OK;
}
virtual int emitM3RawPrototype(Node *n, const String *cname, const String *m3name) {
String *im_return_type = NewString("");
ParmList *l = Getattr(n, "parms");
Swig_typemap_attach_parms("m3rawinmode", l, NULL);
Swig_typemap_attach_parms("m3rawintype", l, NULL);
bool has_return;
{
String *tm = getMappedTypeNew(n, "m3rawrettype", "");
if (tm != NIL) {
Printf(im_return_type, "%s", tm);
}
has_return = hasContent(tm);
}
m3raw_intf.enterBlock(no_block);
Printf(m3raw_intf.f, "\n<* EXTERNAL %s *>\nPROCEDURE %s (", cname, m3name);
{
Parm *p;
writeArgState state;
attachParameterNames(n, "tmap:rawinname", "modula3:rawname", "arg%d");
for (p = skipIgnored(l, "m3rawintype"); p != NULL; p = skipIgnored(p, "m3rawintype")) {
String *mode = Getattr(p, "tmap:m3rawinmode");
String *argname = Getattr(p, "modula3:rawname");
String *im_param_type = getMappedType(p, "m3rawintype");
addImports(m3raw_intf.import, "m3rawintype", p);
writeArg(m3raw_intf.f, state, mode, argname, im_param_type, NIL);
if (im_param_type != NIL) {
p = Getattr(p, "tmap:m3rawintype:next");
} else {
p = nextSibling(p);
}
}
writeArg(m3raw_intf.f, state, NIL, NIL, NIL, NIL);
}
Printf(m3raw_intf.f, ")");
if (has_return) {
Printf(m3raw_intf.f, ": %s", im_return_type);
}
Printf(m3raw_intf.f, ";\n");
Delete(im_return_type);
return SWIG_OK;
}
virtual int variableWrapper(Node *n) {
Language::variableWrapper(n);
return SWIG_OK;
}
virtual int globalvariableHandler(Node *n) {
SwigType *t = Getattr(n, "type");
String *tm;
if ((tm = getMappedTypeNew(n, "m3wraptype", ""))) {
substituteClassname(t, tm);
}
variable_name = Getattr(n, "sym:name");
variable_type = Copy(tm);
if ((tm = getMappedTypeNew(n, "m3rawtype", ""))) {
m3raw_intf.enterBlock(no_block);
Printf(m3raw_intf.f, "\n<* EXTERNAL *> VAR %s: %s;\n", variable_name, tm);
}
Printf(m3wrap_impl.f, "\n\n");
return 1;
}
long getConstNumeric(Node *n) {
String *constnumeric = Getfeature(n, "constnumeric");
String *name = Getattr(n, "name");
long numvalue;
if (constnumeric == NIL) {
Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Feature 'constnumeric' is necessary to obtain value of %s.\n", name);
return 0;
} else if (!strToL(constnumeric, numvalue)) {
Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number,
"The feature 'constnumeric' of %s specifies value <%s> which is not an integer constant.\n", name, constnumeric);
return 0;
} else {
return numvalue;
}
}
void generateIntConstant(Node *n, String *name) {
String *value = Getattr(n, "value");
String *type = Getfeature(n, "modula3:constint:type");
String *conv = Getfeature(n, "modula3:constint:conv");
if (name == NIL) {
name = Getattr(n, "sym:name");
}
long numvalue;
bool isSimpleNum = strToL(value, numvalue);
if (!isSimpleNum) {
numvalue = getConstNumeric(n);
}
String *m3value;
if ((conv == NIL) || ((Strcmp(conv, "set:int") != 0) && (Strcmp(conv, "int:set") != 0))) {
if (isSimpleNum) {
if (hasPrefix(value, "0x")) {
m3value = NewStringf("16_%s", Char(value) + 2);
} else if ((Len(value) > 1) && (*Char(value) == '0')) {
m3value = NewStringf("8_%s", Char(value) + 1);
} else {
m3value = Copy(value);
}
} else {
m3value = Copy(Getfeature(n, "constnumeric"));
}
} else {
if (convertInt(numvalue, numvalue, conv)) {
m3value = NewStringf("%d", numvalue);
} else {
m3value = NIL;
}
}
if (m3value != NIL) {
m3wrap_intf.enterBlock(constant);
Printf(m3wrap_intf.f, "%s", name);
if (hasContent(type)) {
Printf(m3wrap_intf.f, ": %s", type);
}
Printf(m3wrap_intf.f, " = %s;\n", m3value);
Delete(m3value);
}
}
void generateSetConstant(Node *n, String *name) {
String *value = Getattr(n, "value");
String *type = Getfeature(n, "modula3:constset:type");
String *setname = Getfeature(n, "modula3:constset:set");
String *basename = Getfeature(n, "modula3:constset:base");
String *conv = Getfeature(n, "modula3:constset:conv");
m3wrap_intf.enterBlock(constant);
Printf(m3wrap_intf.f, "%s", name);
if (type != NIL) {
Printf(m3wrap_intf.f, ":%s ", type);
}
Printf(m3wrap_intf.f, " = %s{", setname);
long numvalue = 0;
if (!strToL(value, numvalue)) {
numvalue = getConstNumeric(n);
}
convertInt(numvalue, numvalue, conv);
bool isIntType = Strcmp(basename, "CARDINAL") == 0;
Hash *items = NIL;
if (!isIntType) {
Hash *enumeration = Getattr(enumeration_coll, basename);
if (enumeration == NIL) {
Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "There is no enumeration <%s> as needed for the set.\n", setname);
isIntType = true;
} else {
items = Getattr(enumeration, "items");
}
}
bool gencomma = false;
int bitpos = 0;
while (numvalue > 0) {
if ((numvalue & 1) != 0) {
if (isIntType) {
if (gencomma) {
Printv(m3wrap_intf.f, ",", NIL);
}
gencomma = true;
Printf(m3wrap_intf.f, "%d", bitpos);
} else {
char bitval[15];
sprintf(bitval, "%d", bitpos);
String *bitname = Getattr(items, bitval);
if (bitname == NIL) {
Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Enumeration <%s> has no value <%s>.\n", setname, bitval);
} else {
if (gencomma) {
Printv(m3wrap_intf.f, ",", NIL);
}
gencomma = true;
Printf(m3wrap_intf.f, "%s.%s", basename, bitname);
}
}
}
numvalue >>= 1;
bitpos++;
}
Printf(m3wrap_intf.f, "};\n");
}
void generateConstant(Node *n) {
String *enumitem = Getfeature(n, "modula3:enumitem:name");
String *constset = Getfeature(n, "modula3:constset:name");
String *constint = Getfeature(n, "modula3:constint:name");
if (hasContent(enumitem) || hasContent(constset) || hasContent(constint)) {
if (hasContent(constset)) {
generateSetConstant(n, constset);
}
if (hasContent(constint)) {
generateIntConstant(n, constint);
}
} else {
String *value = Getattr(n, "value");
String *name = Getattr(n, "sym:name");
if (name == NIL) {
name = Getattr(n, "name");
}
m3wrap_intf.enterBlock(constant);
Printf(m3wrap_intf.f, "%s = %s;\n", name, value);
}
}
#if 0
void generateEnumerationItem(const String *name, const String *value, int numvalue) {
String *oldsymname = Getattr(enumeration_items, value);
if (oldsymname != NIL) {
Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "The value <%s> is already assigned to <%s>.\n", value, oldsymname);
}
Setattr(enumeration_items, value, name);
if (enumeration_max < numvalue) {
enumeration_max = numvalue;
}
}
#endif
void emitEnumeration(File *file, String *name, Node *n) {
Printf(file, "%s = {", name);
int i;
bool gencomma = false;
int max = aToL(Getattr(n, "max"));
Hash *items = Getattr(n, "items");
for (i = 0; i <= max; i++) {
if (gencomma) {
Printf(file, ",");
}
Printf(file, "\n");
gencomma = true;
char numstr[15];
sprintf(numstr, "%d", i);
String *name = Getattr(items, numstr);
if (name != NIL) {
Printv(file, name, NIL);
} else {
Printf(file, "Dummy%d", i);
}
}
Printf(file, "\n};\n");
}
virtual int constantWrapper(Node *n) {
generateConstant(n);
return SWIG_OK;
}
#if 0
virtual int enumDeclaration(Node *n) {
String *symname = nameToModula3(Getattr(n, "sym:name"), true);
enumerationStart(symname);
int result = Language::enumDeclaration(n);
enumerationStop();
Delete(symname);
return result;
}
#endif
virtual int enumvalueDeclaration(Node *n) {
generateConstant(n);
return SWIG_OK;
}
virtual int pragmaDirective(Node *n) {
if (!ImportMode) {
String *lang = Getattr(n, "lang");
String *code = Getattr(n, "name");
String *value = Getattr(n, "value");
if (Strcmp(lang, "modula3") == 0) {
String *strvalue = NewString(value);
Replaceall(strvalue, "\\\"", "\"");
if (Strcmp(code, "imclassbase") == 0) {
Delete(m3raw_baseclass);
m3raw_baseclass = Copy(strvalue);
} else if (Strcmp(code, "imclassclassmodifiers") == 0) {
Delete(m3raw_class_modifiers);
m3raw_class_modifiers = Copy(strvalue);
} else if (Strcmp(code, "imclasscode") == 0) {
Printf(m3raw_intf.f, "%s\n", strvalue);
} else if (Strcmp(code, "imclassimports") == 0) {
Delete(m3raw_imports);
m3raw_imports = Copy(strvalue);
} else if (Strcmp(code, "imclassinterfaces") == 0) {
Delete(m3raw_interfaces);
m3raw_interfaces = Copy(strvalue);
} else if (Strcmp(code, "modulebase") == 0) {
Delete(module_baseclass);
module_baseclass = Copy(strvalue);
} else if (Strcmp(code, "moduleclassmodifiers") == 0) {
Delete(m3wrap_modifiers);
m3wrap_modifiers = Copy(strvalue);
} else if (Strcmp(code, "modulecode") == 0) {
Printf(m3wrap_impl.f, "%s\n", strvalue);
} else if (Strcmp(code, "moduleimports") == 0) {
Delete(module_imports);
module_imports = Copy(strvalue);
} else if (Strcmp(code, "moduleinterfaces") == 0) {
Delete(module_interfaces);
module_interfaces = Copy(strvalue);
} else if (Strcmp(code, "unsafe") == 0) {
unsafe_module = true;
} else if (Strcmp(code, "library") == 0) {
if (targetlibrary != NULL) {
Delete(targetlibrary);
}
targetlibrary = Copy(strvalue);
} else if (Strcmp(code, "enumitem") == 0) {
} else if (Strcmp(code, "constset") == 0) {
} else if (Strcmp(code, "constint") == 0) {
} else if (Strcmp(code, "makesetofenum") == 0) {
m3wrap_intf.enterBlock(blocktype);
Printf(m3wrap_intf.f, "%sSet = SET OF %s;\n", value, value);
} else {
Swig_warning(WARN_MODULA3_UNKNOWN_PRAGMA, input_file, line_number, "Unrecognized pragma <%s>.\n", code);
}
Delete(strvalue);
}
}
return Language::pragmaDirective(n);
}
void Setfeature(Node *n, const char *feature, const String *value, bool warn = false) {
String *attr = NewStringf("feature:%s", feature);
if ((Setattr(n, attr, value) != 0) && warn) {
Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Feature <%s> of %s did already exist.\n", feature, Getattr(n, "name"));
}
Delete(attr);
}
String *Getfeature(Node *n, const char *feature) {
String *attr = NewStringf("feature:%s", feature);
String *result = Getattr(n, attr);
Delete(attr);
return result;
}
bool convertInt(long in, long &out, const String *mode) {
if ((mode == NIL) || (Strcmp(mode, "int:int") == 0) || (Strcmp(mode, "set:set") == 0)) {
out = in;
return true;
} else if (Strcmp(mode, "set:int") == 0) {
return log2(in, out);
} else if (Strcmp(mode, "int:set") == 0) {
out = 1L << in;
return unsigned (in) < (sizeof(out) * 8);
} else {
Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Unknown integer conversion method <%s>.\n", mode);
return false;
}
}
void collectEnumerations(Hash *enums, Node *n) {
Node *child = firstChild(n);
while (child != NIL) {
String *name = Getattr(child, "name");
const bool isConstant = Strcmp(nodeType(child), "constant") == 0;
const bool isEnumItem = Strcmp(nodeType(child), "enumitem") == 0;
if (isConstant || isEnumItem) {
{
String *m3name = Getfeature(child, "modula3:enumitem:name");
String *m3enum = Getfeature(child, "modula3:enumitem:enum");
String *conv = Getfeature(child, "modula3:enumitem:conv");
if (m3enum != NIL) {
if (m3name == NIL) {
m3name = name;
}
long max = -1;
Hash *items;
Hash *enumnode = Getattr(enums, m3enum);
if (enumnode == NIL) {
enumnode = NewHash();
items = NewHash();
Setattr(enumnode, "items", items);
Setattr(enums, m3enum, enumnode);
} else {
String *maxstr = Getattr(enumnode, "max");
if (maxstr != NIL) {
max = aToL(maxstr);
}
items = Getattr(enumnode, "items");
}
long numvalue;
String *value = Getattr(child, "value");
if ((value == NIL) || (!strToL(value, numvalue))) {
value = Getattr(child, "enumvalue");
if ((value == NIL) || (!evalExpr(value, numvalue))) {
numvalue = getConstNumeric(child);
}
}
Setattr(constant_values, name, NewStringf("%d", numvalue));
if (convertInt(numvalue, numvalue, conv)) {
String *newvalue = NewStringf("%d", numvalue);
String *oldname = Getattr(items, newvalue);
if (oldname != NIL) {
Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "The value <%s> is already assigned to <%s>.\n", value, oldname);
}
Setattr(items, newvalue, m3name);
if (max < numvalue) {
max = numvalue;
}
Setattr(enumnode, "max", NewStringf("%d", max));
}
}
}
}
collectEnumerations(enums, child);
child = nextSibling(child);
}
}
enum const_pragma_type { cpt_none, cpt_constint, cpt_constset, cpt_enumitem };
struct const_id_pattern {
String *prefix, *parentEnum;
};
void tagConstants(Node *first, String *parentEnum, const const_id_pattern & pat, const String *pragma, List *convdesc) {
Node *n = first;
while (n != NIL) {
String *name = getQualifiedName(n);
bool isConstant = Strcmp(nodeType(n), "constant") == 0;
bool isEnumItem = Strcmp(nodeType(n), "enumitem") == 0;
if ((isConstant || isEnumItem) && ((pat.prefix == NIL) || (hasPrefix(name, pat.prefix))) && ((pat.parentEnum == NIL) || ((parentEnum != NIL)
&&
(Strcmp
(pat.parentEnum, parentEnum)
== 0)))) {
String *srctype = Getitem(convdesc, 1);
String *relationstr = Getitem(convdesc, 3);
List *relationdesc = Split(relationstr, ',', 2);
String *srcstyle = NIL;
String *newprefix = NIL;
{
List *namedesc = Split(Getitem(convdesc, 2), ',', INT_MAX);
Iterator nameit = First(namedesc);
for (; nameit.item != NIL; nameit = Next(nameit)) {
List *nameassign = Split(nameit.item, '=', 2);
String *tag = Getitem(nameassign, 0);
String *data = Getitem(nameassign, 1);
if (Strcmp(tag, "srcstyle") == 0) {
srcstyle = Copy(data);
} else if (Strcmp(tag, "prefix") == 0) {
newprefix = Copy(data);
} else {
Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Unknown name conversion tag <%s> with value <%s>.\n", tag, data);
}
Delete(nameassign);
}
Delete(namedesc);
}
const char *stem = Char(name);
if (pat.prefix != NIL) {
stem += Len(pat.prefix);
}
String *newname;
if (Strcmp(srcstyle, "underscore") == 0) {
if (newprefix != NIL) {
String *newstem = nameToModula3(stem, true);
newname = NewStringf("%s%s", newprefix, newstem);
Delete(newstem);
} else {
newname = nameToModula3(stem, true);
}
} else {
if (srcstyle != NIL) {
Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Unknown C identifier style <%s>.\n", srcstyle);
}
newname = Copy(name);
}
if (Strcmp(pragma, "enumitem") == 0) {
if (Len(relationdesc) != 1) {
Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Expected <enumeration>, got <%s>.\n", relationstr);
}
Setfeature(n, "modula3:enumitem:name", newname, true);
Setfeature(n, "modula3:enumitem:enum", relationstr, true);
Setfeature(n, "modula3:enumitem:conv", NewStringf("%s:int", srctype), true);
} else if (Strcmp(pragma, "constint") == 0) {
if (Len(relationdesc) != 1) {
Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Expected <ordinal type>, got <%s>.\n", relationstr);
}
Setfeature(n, "modula3:constint:name", newname, true);
Setfeature(n, "modula3:constint:type", Getitem(relationdesc, 0), true);
Setfeature(n, "modula3:constint:conv", NewStringf("%s:int", srctype), true);
} else if (Strcmp(pragma, "constset") == 0) {
if (Len(relationdesc) != 2) {
Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Expected <set type,base type>, got <%s>.\n", relationstr);
}
String *settype = Getitem(relationdesc, 0);
Setfeature(n, "modula3:constset:name", newname, true);
Setfeature(n, "modula3:constset:set", settype, true);
Setfeature(n, "modula3:constset:base", Getitem(relationdesc, 1), true);
Setfeature(n, "modula3:constset:conv", NewStringf("%s:set", srctype), true);
}
Delete(newname);
Delete(relationdesc);
}
if (Strcmp(nodeType(n), "enum") == 0) {
tagConstants(firstChild(n), name, pat, pragma, convdesc);
} else {
tagConstants(firstChild(n), NIL, pat, pragma, convdesc);
}
n = nextSibling(n);
}
}
void scanForConstPragmas(Node *n) {
Node *child = firstChild(n);
while (child != NIL) {
const String *type = nodeType(child);
if (Strcmp(type, "pragma") == 0) {
const String *lang = Getattr(child, "lang");
const String *code = Getattr(child, "name");
String *value = Getattr(child, "value");
if (Strcmp(lang, "modula3") == 0) {
const_pragma_type cpt = cpt_none;
if (Strcmp(code, "constint") == 0) {
cpt = cpt_constint;
} else if (Strcmp(code, "constset") == 0) {
cpt = cpt_constset;
} else if (Strcmp(code, "enumitem") == 0) {
cpt = cpt_enumitem;
}
if (cpt != cpt_none) {
const_id_pattern pat = { NIL, NIL };
List *convdesc = Split(value, ';', 4);
List *patterndesc = Split(Getitem(convdesc, 0), ',', INT_MAX);
Iterator patternit;
for (patternit = First(patterndesc); patternit.item != NIL; patternit = Next(patternit)) {
List *patternassign = Split(patternit.item, '=', 2);
String *tag = Getitem(patternassign, 0);
String *data = Getitem(patternassign, 1);
if (Strcmp(tag, "prefix") == 0) {
pat.prefix = Copy(data);
} else if (Strcmp(tag, "enum") == 0) {
pat.parentEnum = Copy(data);
} else {
Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Unknown identification tag <%s> with value <%s>.\n", tag, data);
}
Delete(patternassign);
}
tagConstants(child, NIL, pat, code, convdesc);
Delete(patterndesc);
}
}
}
scanForConstPragmas(child);
child = nextSibling(child);
}
}
void emitProxyClassDefAndCPPCasts(Node *n) {
String *c_classname = SwigType_namestr(Getattr(n, "name"));
String *c_baseclass = NULL;
String *baseclass = NULL;
String *c_baseclassname = NULL;
String *classDeclarationName = Getattr(n, "classDeclaration:name");
List *baselist = Getattr(n, "bases");
if (baselist != NIL) {
Iterator base = First(baselist);
c_baseclassname = Getattr(base.item, "name");
baseclass = Copy(getProxyName(c_baseclassname));
if (baseclass) {
c_baseclass = SwigType_namestr(Getattr(base.item, "name"));
}
base = Next(base);
if (base.item != NIL) {
Swig_warning(WARN_MODULA3_MULTIPLE_INHERITANCE, input_file,
line_number,
"Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Modula 3.\n",
classDeclarationName, Getattr(base.item, "name"));
}
}
bool derived = baseclass && getProxyName(c_baseclassname);
if (!baseclass)
baseclass = NewString("");
const String *pure_baseclass = typemapLookup(n, "m3base", classDeclarationName, WARN_NONE);
if (hasContent(pure_baseclass) && hasContent(baseclass)) {
Swig_warning(WARN_MODULA3_MULTIPLE_INHERITANCE, input_file,
line_number,
"Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Modula 3.\n", classDeclarationName, pure_baseclass);
}
const String *pure_interfaces = typemapLookup(n, derived ? "m3interfaces_derived" : "m3interfaces",
classDeclarationName, WARN_NONE);
Printv(proxy_class_def, typemapLookup(n, "m3imports", classDeclarationName, WARN_NONE), "\n", typemapLookup(n, "m3classmodifiers", classDeclarationName, WARN_MODULA3_TYPEMAP_CLASSMOD_UNDEF), " class $m3classname", (derived || *Char(pure_baseclass) || *Char(pure_interfaces)) ? " : " : "", baseclass, pure_baseclass, ((derived || *Char(pure_baseclass)) && *Char(pure_interfaces)) ? ", " : "", pure_interfaces, " {\n", " private IntPtr swigCPtr;\n", derived ? "" : " protected bool swigCMemOwn;\n", "\n", " ", typemapLookup(n, "m3ptrconstructormodifiers", classDeclarationName, WARN_MODULA3_TYPEMAP_PTRCONSTMOD_UNDEF), " $m3classname(IntPtr cPtr, bool cMemoryOwn) ", derived ?
": base($imclassname.$m3classnameTo$baseclass(cPtr), cMemoryOwn) {\n"
: "{\n swigCMemOwn = cMemoryOwn;\n", " swigCPtr = cPtr;\n", " }\n", NIL);
if (!have_default_constructor_flag) { Printv(proxy_class_def, "\n", " protected $m3classname() : this(IntPtr.Zero, false) {\n", " }\n", NIL);
}
String *destruct = NewString("");
const String *tm = NULL;
Node *attributes = NewHash();
String *destruct_methodname = NULL;
if (derived) {
tm = typemapLookup(n, "m3destruct_derived", classDeclarationName, WARN_NONE, attributes);
destruct_methodname = Getattr(attributes, "tmap:m3destruct_derived:methodname");
} else {
tm = typemapLookup(n, "m3destruct", classDeclarationName, WARN_NONE, attributes);
destruct_methodname = Getattr(attributes, "tmap:m3destruct:methodname");
}
if (!destruct_methodname) {
Swig_error(input_file, line_number, "No methodname attribute defined in m3destruct%s typemap for %s\n", (derived ? "_derived" : ""), proxy_class_name);
}
if (tm) {
if (*Char(destructor_call)) {
Printv(proxy_class_def, typemapLookup(n, "m3finalize", classDeclarationName, WARN_NONE), NIL);
}
Printv(destruct, tm, NIL);
if (*Char(destructor_call))
Replaceall(destruct, "$imcall", destructor_call);
else
Replaceall(destruct, "$imcall", "throw new MethodAccessException(\"C++ destructor does not have public access\")");
if (*Char(destruct))
Printv(proxy_class_def, "\n public ", derived ? "override" : "virtual", " void ", destruct_methodname, "() ", destruct, "\n", NIL);
}
Delete(attributes);
Delete(destruct);
Printv(proxy_class_def, typemapLookup(n, "m3getcptr", classDeclarationName, WARN_MODULA3_TYPEMAP_GETCPTR_UNDEF), typemapLookup(n, "m3code", classDeclarationName, WARN_NONE), "\n", NIL);
Replaceall(proxy_class_def, "$m3classname", proxy_class_name);
Replaceall(proxy_class_code, "$m3classname", proxy_class_name);
Replaceall(proxy_class_def, "$baseclass", baseclass);
Replaceall(proxy_class_code, "$baseclass", baseclass);
Replaceall(proxy_class_def, "$imclassname", m3raw_name);
Replaceall(proxy_class_code, "$imclassname", m3raw_name);
if (derived) {
Printv(m3raw_cppcasts_code, "\n [DllImport(\"", m3wrap_name, "\", EntryPoint=\"Modula3_", proxy_class_name, "To", baseclass, "\")]\n", NIL);
Printv(m3raw_cppcasts_code, " public static extern IntPtr ", "$m3classnameTo$baseclass(IntPtr objectRef);\n", NIL);
Replaceall(m3raw_cppcasts_code, "$m3classname", proxy_class_name);
Replaceall(m3raw_cppcasts_code, "$baseclass", baseclass);
Printv(upcasts_code,
"SWIGEXPORT long Modula3_$imclazznameTo$imbaseclass",
"(long objectRef) {\n",
" long baseptr = 0;\n" " *($cbaseclass **)&baseptr = *($cclass **)&objectRef;\n" " return baseptr;\n" "}\n", "\n", NIL);
Replaceall(upcasts_code, "$imbaseclass", baseclass);
Replaceall(upcasts_code, "$cbaseclass", c_baseclass);
Replaceall(upcasts_code, "$imclazzname", proxy_class_name);
Replaceall(upcasts_code, "$cclass", c_classname);
}
Delete(baseclass);
}
String *getAttrString(Node *n, const char *attr) {
String *str = Getattr(n, attr);
if (str == NIL) {
str = NewString("");
Setattr(n, attr, str);
}
return str;
}
String *getMethodDeclarations(Node *n) {
String *acc_str = Getattr(n, "access");
String *methodattr;
if (acc_str == NIL) {
methodattr = NewString("modula3:method:public");
} else {
methodattr = NewStringf("modula3:method:%s", acc_str);
}
String *methods = getAttrString(parentNode(n), Char(methodattr));
Delete(methodattr);
return methods;
}
virtual int classHandler(Node *n) {
File *f_proxy = NULL;
proxy_class_name = Copy(Getattr(n, "sym:name"));
if (proxy_flag) {
if (!addSymbol(proxy_class_name, n))
return SWIG_ERROR;
if (Cmp(proxy_class_name, m3raw_name) == 0) {
Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name);
SWIG_exit(EXIT_FAILURE);
}
if (Cmp(proxy_class_name, m3wrap_name) == 0) {
Printf(stderr, "Class name cannot be equal to module class name: %s\n", proxy_class_name);
SWIG_exit(EXIT_FAILURE);
}
String *filen = NewStringf("%s%s.m3", Swig_file_dirname(outfile), proxy_class_name);
f_proxy = NewFile(filen, "w", SWIG_output_files());
if (!f_proxy) {
FileErrorDisplay(filen);
SWIG_exit(EXIT_FAILURE);
}
Delete(filen);
filen = NULL;
emitBanner(f_proxy);
Clear(proxy_class_def);
Clear(proxy_class_code);
have_default_constructor_flag = false;
destructor_call = NewString("");
}
Language::classHandler(n);
{
String *kind = Getattr(n, "kind");
if (Cmp(kind, "struct") == 0) {
String *entries = NewString("");
Node *child;
writeArgState state;
for (child = firstChild(n); child != NIL; child = nextSibling(child)) {
String *childType = nodeType(child);
if (Strcmp(childType, "cdecl") == 0) {
String *member = Getattr(child, "sym:name");
ParmList *pl = Getattr(child, "parms");
if (pl == NIL) {
String *m3ct = getMappedTypeNew(child, "m3rawtype", "");
writeArg(entries, state, NIL, member, m3ct, NIL);
}
}
}
writeArg(entries, state, NIL, NIL, NIL, NIL);
m3raw_intf.enterBlock(blocktype);
Printf(m3raw_intf.f, "%s =\nRECORD\n%sEND;\n", proxy_class_name, entries);
Delete(entries);
} else if (Cmp(kind, "class") == 0) {
enum access_privilege { acc_public, acc_protected, acc_private };
int max_acc = acc_public;
const char *acc_name[3] = { "public", "protected", "private" };
String *methods[3];
int acc;
for (acc = acc_public; acc <= acc_private; acc++) {
String *methodattr = NewStringf("modula3:method:%s", acc_name[acc]);
methods[acc] = Getattr(n, methodattr);
Delete(methodattr);
max_acc = max_acc > acc ? max_acc : acc;
}
String *baseclassname = NewString("");
{
List *baselist = Getattr(n, "bases");
if (baselist) {
Iterator base = First(baselist);
Append(baseclassname, Getattr(base.item, "sym:name"));
base = Next(base);
if (base.item != NIL) {
Swig_warning(WARN_MODULA3_MULTIPLE_INHERITANCE, input_file,
line_number,
"Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Modula 3.\n",
proxy_class_name, Getattr(base.item, "name"));
}
}
}
bool need_private = !hasContent(baseclassname);
max_acc = need_private ? acc_private : max_acc;
if (hasContent(baseclassname)) {
m3raw_intf.enterBlock(blocktype);
Printf(m3raw_intf.f, "%s = %s;\n", proxy_class_name, baseclassname);
} else {
m3raw_intf.enterBlock(blocktype);
Printf(m3raw_intf.f, "%s <: ADDRESS;\n", proxy_class_name);
m3raw_impl.enterBlock(revelation);
Printf(m3raw_impl.f, "%s = UNTRACED BRANDED REF RECORD (*Dummy*) END;\n", proxy_class_name);
}
String *superclass;
m3wrap_intf.enterBlock(blocktype);
if (hasContent(methods[acc_public])) {
superclass = NewStringf("%sPublic", proxy_class_name);
} else if (hasContent(baseclassname)) {
superclass = Copy(baseclassname);
} else {
superclass = NewString("ROOT");
}
Printf(m3wrap_intf.f, "%s <: %s;\n", proxy_class_name, superclass);
Delete(superclass);
{
static const char *acc_m3suffix[] = { "Public", "Protected", "Private" };
int acc;
for (acc = acc_public; acc <= acc_private; acc++) {
bool process_private = (acc == acc_private) && need_private;
if (hasContent(methods[acc]) || process_private) {
String *subclass = NewStringf("%s%s", proxy_class_name, acc_m3suffix[acc]);
if (acc == max_acc) {
m3wrap_intf.enterBlock(revelation);
Printf(m3wrap_intf.f, "%s =\n", proxy_class_name);
} else {
m3wrap_intf.enterBlock(blocktype);
Printf(m3wrap_intf.f, "%s =\n", subclass);
}
Printf(m3wrap_intf.f, "%s BRANDED OBJECT\n", baseclassname);
if (process_private) {
Setattr(m3wrap_intf.import, m3raw_name, "");
Printf(m3wrap_intf.f, "cxxObj:%s.%s;\n", m3raw_name, proxy_class_name);
}
if (hasContent(methods[acc])) {
Printf(m3wrap_intf.f, "METHODS\n%s", methods[acc]);
}
if (acc == max_acc) {
String *overrides = Getattr(n, "modula3:override");
Printf(m3wrap_intf.f, "OVERRIDES\n%s", overrides);
}
Printf(m3wrap_intf.f, "END;\n");
Delete(baseclassname);
baseclassname = subclass;
}
}
}
Delete(methods[acc_public]);
Delete(methods[acc_protected]);
Delete(methods[acc_private]);
} else {
Swig_warning(WARN_MODULA3_TYPECONSTRUCTOR_UNKNOWN, input_file, line_number, "Unknown type constructor %s\n", kind);
}
}
if (proxy_flag) {
emitProxyClassDefAndCPPCasts(n);
Printv(f_proxy, proxy_class_def, proxy_class_code, NIL);
Printf(f_proxy, "}\n");
Close(f_proxy);
f_proxy = NULL;
Delete(proxy_class_name);
proxy_class_name = NULL;
Delete(destructor_call);
destructor_call = NULL;
}
return SWIG_OK;
}
virtual int memberfunctionHandler(Node *n) {
Setattr(n, "modula3:functype", "method");
Language::memberfunctionHandler(n);
{
ParmList *pl = Getattr(n, "parms");
Swig_typemap_attach_parms("m3wrapinmode", pl, NULL);
Swig_typemap_attach_parms("m3wrapinname", pl, NULL);
Swig_typemap_attach_parms("m3wrapintype", pl, NULL);
Swig_typemap_attach_parms("m3wrapindefault", pl, NULL);
attachParameterNames(n, "tmap:m3wrapinname", "autoname", "arg%d");
String *rettype = getMappedTypeNew(n, "m3wrapouttype", "");
String *methodname = Getattr(n, "sym:name");
String *arguments = createM3Signature(n);
String *storage = Getattr(n, "storage");
String *overridden = Getattr(n, "override");
bool isVirtual = (storage != NIL) && (Strcmp(storage, "virtual") == 0);
bool isOverridden = (overridden != NIL)
&& (Strcmp(overridden, "1") == 0);
if ((!isVirtual) || (!isOverridden)) {
{
String *methods = getMethodDeclarations(n);
Printf(methods, "%s(%s)%s%s;%s\n",
methodname, arguments,
hasContent(rettype) ? ": " : "", hasContent(rettype) ? (const String *) rettype : "", isVirtual ? " (* base method *)" : "");
}
{
String *fname = Getattr(n, "modula3:funcname");
String *overrides = getAttrString(parentNode(n), "modula3:override");
Printf(overrides, "%s := %s;\n", methodname, fname);
}
}
}
if (proxy_flag) {
String *overloaded_name = getOverloadedName(n);
String *intermediary_function_name = Swig_name_member(proxy_class_name, overloaded_name);
Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
Setattr(n, "imfuncname", intermediary_function_name);
proxyClassFunctionHandler(n);
Delete(overloaded_name);
}
return SWIG_OK;
}
virtual int staticmemberfunctionHandler(Node *n) {
static_flag = true;
Language::staticmemberfunctionHandler(n);
if (proxy_flag) {
String *overloaded_name = getOverloadedName(n);
String *intermediary_function_name = Swig_name_member(proxy_class_name, overloaded_name);
Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
Setattr(n, "imfuncname", intermediary_function_name);
proxyClassFunctionHandler(n);
Delete(overloaded_name);
}
static_flag = false;
return SWIG_OK;
}
void proxyClassFunctionHandler(Node *n) {
SwigType *t = Getattr(n, "type");
ParmList *l = Getattr(n, "parms");
Hash *throws_hash = NewHash();
String *intermediary_function_name = Getattr(n, "imfuncname");
String *proxy_function_name = Getattr(n, "proxyfuncname");
String *tm;
Parm *p;
int i;
String *imcall = NewString("");
String *return_type = NewString("");
String *function_code = NewString("");
bool setter_flag = false;
if (!proxy_flag)
return;
if (l) {
if (SwigType_type(Getattr(l, "type")) == T_VOID) {
l = nextSibling(l);
}
}
Swig_typemap_attach_parms("in", l, NULL);
Swig_typemap_attach_parms("m3wraptype", l, NULL);
Swig_typemap_attach_parms("m3in", l, NULL);
if ((tm = getMappedTypeNew(n, "m3wraptype", ""))) {
substituteClassname(t, tm);
Printf(return_type, "%s", tm);
}
if (proxy_flag && wrapping_member_flag && !enum_constant_flag) {
setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(Swig_name_member(proxy_class_name, variable_name)))
== 0);
}
Printf(function_code, " %s ", Getattr(n, "feature:modula3:methodmodifiers"));
if (static_flag)
Printf(function_code, "static ");
if (Getattr(n, "override"))
Printf(function_code, "override ");
else if (checkAttribute(n, "storage", "virtual"))
Printf(function_code, "virtual ");
Printf(function_code, "%s %s(", return_type, proxy_function_name);
Printv(imcall, m3raw_name, ".", intermediary_function_name, "(", NIL);
if (!static_flag)
Printv(imcall, "swigCPtr", NIL);
emit_mark_varargs(l);
int gencomma = !static_flag;
for (i = 0, p = l; p; i++) {
if (checkAttribute(p, "varargs:ignore", "1")) {
p = nextSibling(p);
continue;
}
if (checkAttribute(p, "tmap:in:numinputs", "0")) {
p = Getattr(p, "tmap:in:next");
continue;
}
if (!(variable_wrapper_flag && i == 0)) {
SwigType *pt = Getattr(p, "type");
String *param_type = NewString("");
if ((tm = getMappedType(p, "m3wraptype"))) {
substituteClassname(pt, tm);
Printf(param_type, "%s", tm);
}
if (gencomma)
Printf(imcall, ", ");
String *arg = variable_wrapper_flag ? NewString("value") : makeParameterName(n,
p,
i);
if ((tm = getMappedType(p, "in"))) {
addThrows(throws_hash, "in", p);
substituteClassname(pt, tm);
Replaceall(tm, "$input", arg);
Printv(imcall, tm, NIL);
}
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");
}
Printf(imcall, ")");
Printf(function_code, ")");
if ((tm = getMappedTypeNew(n, "m3out", ""))) {
addThrows(throws_hash, "m3out", n);
if (GetFlag(n, "feature:new"))
Replaceall(tm, "$owner", "true");
else
Replaceall(tm, "$owner", "false");
substituteClassname(t, tm);
Replaceall(tm, "$imcall", imcall);
}
generateThrowsClause(throws_hash, function_code);
Printf(function_code, " %s\n\n", tm ? (const String *) tm : empty_string);
if (proxy_flag && wrapping_member_flag && !enum_constant_flag) {
if (setter_flag) {
if ((tm = getMappedTypeNew(n, "m3varin", ""))) {
if (GetFlag(n, "feature:new"))
Replaceall(tm, "$owner", "true");
else
Replaceall(tm, "$owner", "false");
substituteClassname(t, tm);
Replaceall(tm, "$imcall", imcall);
Printf(proxy_class_code, "%s", tm);
}
} else {
if ((tm = getMappedTypeNew(n, "m3varout", ""))) {
if (GetFlag(n, "feature:new"))
Replaceall(tm, "$owner", "true");
else
Replaceall(tm, "$owner", "false");
substituteClassname(t, tm);
Replaceall(tm, "$imcall", imcall);
Printf(proxy_class_code, "%s", tm);
}
}
} else {
Printv(proxy_class_code, function_code, NIL);
}
Delete(function_code);
Delete(return_type);
Delete(imcall);
Delete(throws_hash);
}
virtual int constructorHandler(Node *n) {
Language::constructorHandler(n);
if (proxy_flag) {
ParmList *l = Getattr(n, "parms");
Hash *throws_hash = NewHash();
String *overloaded_name = getOverloadedName(n);
String *imcall = NewString("");
Printf(proxy_class_code, " %s %s(", Getattr(n, "feature:modula3:methodmodifiers"), proxy_class_name);
Printv(imcall, " : this(", m3raw_name, ".", Swig_name_construct(overloaded_name), "(", NIL);
Swig_typemap_attach_parms("in", l, NULL);
Swig_typemap_attach_parms("m3wraptype", l, NULL);
Swig_typemap_attach_parms("m3in", l, NULL);
emit_mark_varargs(l);
int gencomma = 0;
String *tm;
Parm *p = l;
int i;
for (i = 0; p; i++) {
if (checkAttribute(p, "varargs:ignore", "1")) {
p = nextSibling(p);
continue;
}
if (checkAttribute(p, "tmap:in:numinputs", "0")) {
p = Getattr(p, "tmap:in:next");
continue;
}
SwigType *pt = Getattr(p, "type");
String *param_type = NewString("");
if ((tm = getMappedType(p, "m3wraptype"))) {
substituteClassname(pt, tm);
Printf(param_type, "%s", tm);
}
if (gencomma)
Printf(imcall, ", ");
String *arg = makeParameterName(n, p, i);
if ((tm = getMappedType(p, "in"))) {
addThrows(throws_hash, "in", p);
substituteClassname(pt, tm);
Replaceall(tm, "$input", arg);
Printv(imcall, tm, NIL);
}
if (gencomma)
Printf(proxy_class_code, ", ");
Printf(proxy_class_code, "%s %s", param_type, arg);
gencomma = 1;
Delete(arg);
Delete(param_type);
p = Getattr(p, "tmap:in:next");
}
Printf(imcall, "), true)");
Printf(proxy_class_code, ")");
Printf(proxy_class_code, "%s", imcall);
generateThrowsClause(throws_hash, proxy_class_code);
Printf(proxy_class_code, " {\n");
Printf(proxy_class_code, " }\n\n");
if (!gencomma) have_default_constructor_flag = true;
Delete(overloaded_name);
Delete(imcall);
Delete(throws_hash);
}
return SWIG_OK;
}
virtual int destructorHandler(Node *n) {
Language::destructorHandler(n);
String *symname = Getattr(n, "sym:name");
if (proxy_flag) {
Printv(destructor_call, m3raw_name, ".", Swig_name_destroy(symname), "(swigCPtr)", NIL);
}
return SWIG_OK;
}
virtual int membervariableHandler(Node *n) {
SwigType *t = Getattr(n, "type");
String *tm;
if ((tm = getMappedTypeNew(n, "m3wraptype", ""))) {
substituteClassname(t, tm);
}
variable_name = Getattr(n, "sym:name");
Printf(proxy_class_code, " public %s %s {", tm, variable_name);
Setattr(n, "modula3:functype", "accessor");
wrapping_member_flag = true;
variable_wrapper_flag = true;
Language::membervariableHandler(n);
wrapping_member_flag = false;
variable_wrapper_flag = false;
Printf(proxy_class_code, "\n }\n\n");
{
String *methods = getMethodDeclarations(n);
String *overrides = getAttrString(parentNode(n), "modula3:override");
SwigType *type = Getattr(n, "type");
String *m3name = capitalizeFirst(variable_name);
if (!SwigType_isconst(type)) {
{
String *inmode = getMappedTypeNew(n, "m3wrapinmode", "", false);
String *intype = getMappedTypeNew(n, "m3wrapintype", "");
Printf(methods, "set%s(%s val:%s);\n", m3name, (inmode != NIL) ? (const String *) inmode : "", intype);
}
{
String *fname = Getattr(n, "modula3:setname");
Printf(overrides, "set%s := %s;\n", m3name, fname);
}
}
{
{
String *outtype = getMappedTypeNew(n, "m3wrapouttype", "");
Printf(methods, "get%s():%s;\n", m3name, outtype);
}
{
String *fname = Getattr(n, "modula3:getname");
Printf(overrides, "get%s := %s;\n", m3name, fname);
}
}
Delete(m3name);
}
return SWIG_OK;
}
virtual int staticmembervariableHandler(Node *n) {
bool static_const_member_flag = (Getattr(n, "value") == 0);
if (static_const_member_flag) {
SwigType *t = Getattr(n, "type");
String *tm;
if ((tm = getMappedTypeNew(n, "m3wraptype", ""))) {
substituteClassname(t, tm);
}
Printf(proxy_class_code, " public static %s %s {", tm, Getattr(n, "sym:name"));
}
variable_name = Getattr(n, "sym:name");
wrapping_member_flag = true;
static_flag = true;
Language::staticmembervariableHandler(n);
wrapping_member_flag = false;
static_flag = false;
if (static_const_member_flag)
Printf(proxy_class_code, "\n }\n\n");
return SWIG_OK;
}
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;
}
String *getOverloadedName(Node *n) {
String *overloaded_name = Copy(Getattr(n, "sym:name"));
if (Getattr(n, "sym:overloaded")) {
Printv(overloaded_name, Getattr(n, "sym:overname"), NIL);
}
return overloaded_name;
}
void emitM3Wrapper(Node *n, const String *func_name) {
SwigType *t = Getattr(n, "type");
ParmList *l = Getattr(n, "parms");
Hash *throws_hash = NewHash();
int num_exceptions = 0;
int num_returns = 0;
String *rawcall = NewString("");
String *reccall = NewString("");
String *local_variables = NewString("");
String *local_constants = NewString("");
String *incheck = NewString("");
String *outcheck = NewString("");
String *setup = NewString("");
String *cleanup = NewString("");
String *outarg = NewString("");
String *storeout = NewString("");
String *result_name = NewString("");
String *return_variables = NewString("");
const char *result_return = "ret";
String *function_code = NewString("");
String *raw_name = Getattr(n, "name");
bool setter_flag = false;
int multiretval = GetFlag(n, "feature:modula3:multiretval");
if (l) {
if (SwigType_type(Getattr(l, "type")) == T_VOID) {
l = nextSibling(l);
}
}
Swig_typemap_attach_parms("m3wrapargvar", l, NULL);
Swig_typemap_attach_parms("m3wrapargconst", l, NULL);
Swig_typemap_attach_parms("m3wrapargraw", l, NULL);
Swig_typemap_attach_parms("m3wrapargdir", l, NULL);
Swig_typemap_attach_parms("m3wrapinmode", l, NULL);
Swig_typemap_attach_parms("m3wrapinname", l, NULL);
Swig_typemap_attach_parms("m3wrapintype", l, NULL);
Swig_typemap_attach_parms("m3wrapindefault", l, NULL);
Swig_typemap_attach_parms("m3wrapinconv", l, NULL);
Swig_typemap_attach_parms("m3wrapincheck", l, NULL);
Swig_typemap_attach_parms("m3wrapoutname", l, NULL);
Swig_typemap_attach_parms("m3wrapouttype", l, NULL);
Swig_typemap_attach_parms("m3wrapoutconv", l, NULL);
Swig_typemap_attach_parms("m3wrapoutcheck", l, NULL);
attachMappedType(n, "m3wrapretraw");
attachMappedType(n, "m3wrapretname");
attachMappedType(n, "m3wraprettype");
attachMappedType(n, "m3wrapretvar");
attachMappedType(n, "m3wrapretconv");
attachMappedType(n, "m3wrapretcheck");
Swig_typemap_attach_parms("m3wrapfreearg", l, NULL);
attachParameterNames(n, "tmap:m3wrapinname", "autoname", "arg%d");
String *result_m3rawtype = Copy(getMappedTypeNew(n, "m3rawrettype", ""));
String *result_m3wraptype = Copy(getMappedTypeNew(n, "m3wraprettype", ""));
bool has_return_raw = hasContent(result_m3rawtype);
bool has_return_m3 = hasContent(result_m3wraptype);
if (has_return_m3) {
num_returns++;
}
String *arguments = createM3Signature(n);
{
writeArgState state;
if (multiretval && has_return_m3) {
writeArg(return_variables, state, NIL, NewString(result_return), result_m3wraptype, NIL);
}
Parm *p = skipIgnored(l, "m3wrapouttype");
while (p != NIL) {
String *arg = Getattr(p, "tmap:m3wrapoutname");
if (arg == NIL) {
arg = Getattr(p, "name");
}
String *tm = Getattr(p, "tmap:m3wrapouttype");
if (tm != NIL) {
if (isOutParam(p)) {
if (!multiretval) {
if (num_returns == 0) {
Printv(result_name, arg, NIL);
Clear(result_m3wraptype);
Printv(result_m3wraptype, tm, NIL);
} else {
Swig_warning(WARN_MODULA3_TYPEMAP_MULTIPLE_RETURN, input_file, line_number,
"Typemap m3wrapargdir set to 'out' for %s implies a RETURN value, but the routine %s has already one.\nUse %%multiretval feature.\n",
SwigType_str(Getattr(p, "type"), 0), raw_name);
}
}
num_returns++;
addImports(m3wrap_intf.import, "m3wrapouttype", p);
writeArg(return_variables, state, NIL, arg, tm, NIL);
}
p = skipIgnored(Getattr(p, "tmap:m3wrapouttype:next"), "m3wrapouttype");
} else {
p = nextSibling(p);
}
}
writeArg(return_variables, state, NIL, NIL, NIL, NIL);
if (multiretval) {
Printv(result_name, "result", NIL);
Printf(result_m3wraptype, "%sResult", func_name);
m3wrap_intf.enterBlock(blocktype);
Printf(m3wrap_intf.f, "%s =\nRECORD\n%sEND;\n", result_m3wraptype, return_variables);
Printf(local_variables, "%s: %s;\n", result_name, result_m3wraptype);
} else {
Append(local_variables, return_variables);
}
}
{
Parm *p = l;
while (p != NIL) {
String *arg = Getattr(p, "autoname");
String *tm = Getattr(p, "tmap:m3wrapargconst");
if (tm != NIL) {
addImports(m3wrap_impl.import, "m3wrapargconst", p);
Replaceall(tm, "$input", arg);
Printv(local_constants, tm, "\n", NIL);
p = Getattr(p, "tmap:m3wrapargconst:next");
} else {
p = nextSibling(p);
}
}
}
{
String *tm = getMappedTypeNew(n, "m3wrapretvar", "", false);
if (tm != NIL) {
addImports(m3wrap_impl.import, "m3wrapretvar", n);
addThrows(throws_hash, "m3wrapretvar", n);
Printv(local_variables, tm, "\n", NIL);
}
Parm *p = l;
while (p != NIL) {
String *arg = Getattr(p, "autoname");
tm = Getattr(p, "tmap:m3wrapargvar");
if (tm != NIL) {
addImports(m3wrap_impl.import, "m3wrapargvar", p);
addThrows(throws_hash, "m3wrapargvar", p);
Replaceall(tm, "$input", arg);
Printv(local_variables, tm, "\n", NIL);
p = Getattr(p, "tmap:m3wrapargvar:next");
} else {
p = nextSibling(p);
}
}
}
{
Parm *p = l;
while (p != NIL) {
String *arg = Getattr(p, "autoname");
String *tm = Getattr(p, "tmap:m3wrapinconv");
if (tm != NIL) {
addImports(m3wrap_impl.import, "m3wrapinconv", p);
num_exceptions += addThrows(throws_hash, "m3wrapinconv", p);
Replaceall(tm, "$input", arg);
Printv(setup, tm, "\n", NIL);
p = Getattr(p, "tmap:m3wrapinconv:next");
} else {
p = nextSibling(p);
}
}
}
{
Parm *p = l;
while (p != NIL) {
String *arg = Getattr(p, "autoname");
String *tm = Getattr(p, "tmap:m3wrapincheck");
if (tm != NIL) {
addImports(m3wrap_impl.import, "m3wrapincheck", p);
num_exceptions += addThrows(throws_hash, "m3wrapincheck", p);
Replaceall(tm, "$input", arg);
Printv(incheck, tm, "\n", NIL);
p = Getattr(p, "tmap:m3wrapincheck:next");
} else {
p = nextSibling(p);
}
}
}
Printv(rawcall, m3raw_name, ".", func_name, "(", NIL);
{
bool gencomma = false;
Parm *p = l;
while (p != NIL) {
if (gencomma) {
Printf(rawcall, ", ");
}
gencomma = true;
addImports(m3wrap_impl.import, "m3wrapargraw", p);
num_exceptions += addThrows(throws_hash, "m3wrapargraw", p);
String *arg = Getattr(p, "autoname");
String *qualarg = NewString("");
if (!isInParam(p)) {
String *tmparg = Getattr(p, "tmap:m3wrapoutname");
if (tmparg != NIL) {
arg = tmparg;
}
if (multiretval ) {
Printf(qualarg, "%s.", result_name);
}
}
Append(qualarg, arg);
Setattr(p, "m3outarg", qualarg);
String *tm = Getattr(p, "tmap:m3wrapargraw");
if (tm != NIL) {
Replaceall(tm, "$input", arg);
Replaceall(tm, "$output", qualarg);
Printv(rawcall, tm, NIL);
p = Getattr(p, "tmap:m3wrapargraw:next");
} else {
Printv(rawcall, qualarg, NIL);
p = nextSibling(p);
}
Delete(qualarg);
}
}
Printf(rawcall, ")");
{
String *tm = getMappedTypeNew(n, "m3wrapretcheck", "", false);
if (tm != NIL) {
addImports(m3wrap_impl.import, "m3wrapretcheck", n);
num_exceptions += addThrows(throws_hash, "m3wrapretcheck", n);
Printv(outcheck, tm, "\n", NIL);
}
Parm *p = l;
while (p != NIL) {
tm = Getattr(p, "tmap:m3wrapoutcheck");
if (tm != NIL) {
String *arg = Getattr(p, "autoname");
String *outarg = Getattr(p, "m3outarg");
addImports(m3wrap_impl.import, "m3wrapoutcheck", p);
num_exceptions += addThrows(throws_hash, "m3wrapoutcheck", p);
Replaceall(tm, "$input", arg);
Replaceall(tm, "$output", outarg);
Printv(outcheck, tm, "\n", NIL);
p = Getattr(p, "tmap:m3wrapoutcheck:next");
} else {
p = nextSibling(p);
}
}
}
{
Parm *p = l;
while (p != NIL) {
String *tm = Getattr(p, "tmap:m3wrapoutconv");
if (tm != NIL) {
String *arg = Getattr(p, "autoname");
String *outarg = Getattr(p, "m3outarg");
addImports(m3wrap_impl.import, "m3wrapoutconv", n);
num_exceptions += addThrows(throws_hash, "m3wrapoutconv", p);
Replaceall(tm, "$input", arg);
Replaceall(tm, "$output", outarg);
Printf(storeout, "%s := %s;\n", outarg, tm);
p = Getattr(p, "tmap:m3wrapoutconv:next");
} else {
p = nextSibling(p);
}
}
}
{
Parm *p = l;
while (p != NIL) {
String *tm = Getattr(p, "tmap:m3wrapfreearg");
if (tm != NIL) {
String *arg = Getattr(p, "autoname");
String *outarg = Getattr(p, "m3outarg");
addImports(m3wrap_impl.import, "m3wrapfreearg", p);
num_exceptions += addThrows(throws_hash, "m3wrapfreearg", p);
Replaceall(tm, "$input", arg);
Replaceall(tm, "$output", outarg);
Printv(cleanup, tm, "\n", NIL);
p = Getattr(p, "tmap:m3wrapfreearg:next");
} else {
p = nextSibling(p);
}
}
}
{
if (!has_return_raw) {
Printf(reccall, "%s;\n", rawcall);
if (hasContent(result_name)) {
Printf(outarg, "RETURN %s;\n", result_name);
}
} else {
String *return_raw = getMappedTypeNew(n, "m3wrapretraw", "", false);
String *return_conv = getMappedTypeNew(n, "m3wrapretconv", "", false);
if ((hasContent(outcheck) || hasContent(storeout)
|| hasContent(cleanup)) && (!hasContent(result_name))
&& (return_raw == NIL)) {
Printv(result_name, "result", NIL);
Printf(local_variables, "%s: %s;\n", result_name, result_m3wraptype);
}
String *result_lvalue = Copy(result_name);
if (multiretval) {
Printf(result_lvalue, ".%s", result_return);
}
if (return_raw != NIL) {
Printf(reccall, "%s := %s;\n", return_raw, rawcall);
} else if (hasContent(result_name)) {
Printf(reccall, "%s := %s;\n", result_lvalue, rawcall);
} else {
Printf(outarg, "RETURN %s;\n", rawcall);
}
if (return_conv != NIL) {
addImports(m3wrap_impl.import, "m3wrapretconv", n);
num_exceptions += addThrows(throws_hash, "m3wrapretconv", n);
if (hasContent(result_name)) {
Printf(reccall, "%s := %s;\n", result_lvalue, return_conv);
Printf(outarg, "RETURN %s;\n", result_name);
} else {
Printf(outarg, "RETURN %s;\n", return_conv);
}
} else {
if (hasContent(result_name)) {
Printf(outarg, "RETURN %s;\n", result_name);
}
}
}
}
{
String *header = NewStringf("PROCEDURE %s (%s)",
func_name, arguments);
if ((num_returns > 0) || multiretval) {
Printf(header, ": %s", result_m3wraptype);
}
generateThrowsClause(throws_hash, header);
Append(function_code, header);
m3wrap_intf.enterBlock(no_block);
Printf(m3wrap_intf.f, "%s;\n\n", header);
}
{
String *body = NewStringf("%s%s%s%s%s",
incheck,
setup,
reccall,
outcheck,
storeout);
String *exc_handler;
if (hasContent(cleanup) && (num_exceptions > 0)) {
exc_handler = NewStringf("TRY\n%sFINALLY\n%sEND;\n", body, cleanup);
} else {
exc_handler = NewStringf("%s%s", body, cleanup);
}
Printf(function_code, " =\n%s%s%s%sBEGIN\n%s%sEND %s;\n\n",
hasContent(local_constants) ? "CONST\n" : "", local_constants,
hasContent(local_variables) ? "VAR\n" : "", local_variables, exc_handler, outarg, func_name);
Delete(exc_handler);
Delete(body);
}
m3wrap_impl.enterBlock(no_block);
if (proxy_flag && global_variable_flag) {
if (setter_flag) {
String *tm = getMappedTypeNew(n, "m3varin", "");
if (tm != NIL) {
if (GetFlag(n, "feature:new")) {
Replaceall(tm, "$owner", "true");
} else {
Replaceall(tm, "$owner", "false");
}
substituteClassname(t, tm);
Replaceall(tm, "$rawcall", rawcall);
Replaceall(tm, "$vartype", variable_type);
Replaceall(tm, "$var", variable_name);
Printf(m3wrap_impl.f, "%s", tm);
}
} else {
String *tm = getMappedTypeNew(n, "m3varout", "");
if (tm != NIL) {
if (GetFlag(n, "feature:new"))
Replaceall(tm, "$owner", "true");
else
Replaceall(tm, "$owner", "false");
substituteClassname(t, tm);
Replaceall(tm, "$rawcall", rawcall);
Replaceall(tm, "$vartype", variable_type);
Replaceall(tm, "$var", variable_name);
Printf(m3wrap_impl.f, "%s", tm);
}
}
} else {
Printv(m3wrap_impl.f, function_code, NIL);
}
Delete(arguments);
Delete(return_variables);
Delete(local_variables);
Delete(local_constants);
Delete(outarg);
Delete(incheck);
Delete(outcheck);
Delete(setup);
Delete(cleanup);
Delete(storeout);
Delete(function_code);
Delete(result_name);
Delete(result_m3wraptype);
Delete(reccall);
Delete(rawcall);
Delete(throws_hash);
}
virtual void replaceSpecialVariables(String *method, String *tm, Parm *parm) {
(void)method;
SwigType *type = Getattr(parm, "type");
substituteClassname(type, tm);
}
bool substituteClassname(SwigType *pt, String *tm) {
bool substitution_performed = false;
if (Strstr(tm, "$m3classname") || Strstr(tm, "$&m3classname")) {
String *classname = getProxyName(pt);
if (classname) {
Replaceall(tm, "$&m3classname", classname); Replaceall(tm, "$m3classname", classname);
} else { String *descriptor = NULL;
SwigType *type = Copy(SwigType_typedef_resolve_all(pt));
if (Strstr(tm, "$&m3classname")) {
SwigType_add_pointer(type);
descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(type));
Replaceall(tm, "$&m3classname", descriptor);
} else { descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(type));
Replaceall(tm, "$m3classname", descriptor);
}
Setattr(swig_types_hash, descriptor, type);
Delete(descriptor);
Delete(type);
}
substitution_performed = true;
}
return substitution_performed;
}
String *makeParameterName(Node *n, Parm *p, int arg_num) {
String *pn = Getattr(p, "name");
int count = 0;
ParmList *plist = Getattr(n, "parms");
while (plist) {
if ((Cmp(pn, Getattr(plist, "name")) == 0))
count++;
plist = nextSibling(plist);
}
String *arg = (!pn || (count > 1)) ? NewStringf("arg%d",
arg_num) : Copy(Getattr(p,
"name"));
return arg;
}
void attachParameterNames(Node *n, const char *tmid, const char *nameid, const char *fmt) {
Hash *hash = NewHash();
Parm *p = Getattr(n, "parms");
int count = 0;
while (p != NIL) {
String *name = Getattr(p, tmid);
if (name == NIL) {
name = Getattr(p, "name");
}
String *newname;
if ((!hasContent(name)) || (Getattr(hash, name) != NIL)) {
newname = NewStringf(fmt, count);
} else {
newname = Copy(name);
}
if (1 == Setattr(hash, newname, "1")) {
Swig_warning(WARN_MODULA3_DOUBLE_ID, input_file, line_number, "Argument '%s' twice.\n", newname);
}
Setattr(p, nameid, newname);
p = nextSibling(p);
count++;
}
Delete(hash);
}
String *createM3Signature(Node *n) {
String *arguments = NewString("");
Parm *p = skipIgnored(Getattr(n, "parms"), "m3wrapintype");
writeArgState state;
while (p != NIL) {
String *tm = getMappedType(p, "m3wrapintype");
if (tm != NIL) {
if (isInParam(p)) {
addImports(m3wrap_intf.import, "m3wrapintype", p);
addImports(m3wrap_impl.import, "m3wrapintype", p);
String *mode = Getattr(p, "tmap:m3wrapinmode");
String *deflt = Getattr(p, "tmap:m3wrapindefault");
String *arg = Getattr(p, "autoname");
SwigType *pt = Getattr(p, "type");
substituteClassname(pt, tm);
writeArg(arguments, state, mode, arg, tm, deflt);
}
p = skipIgnored(Getattr(p, "tmap:m3wrapintype:next"), "m3wrapintype");
} else {
p = nextSibling(p);
}
}
writeArg(arguments, state, NIL, NIL, NIL, NIL);
return (arguments);
}
#if 0
String *createCSignature(Node *n) {
String *arguments = NewString("");
bool gencomma = false;
Node *p;
for (p = Getattr(n, "parms"); p != NIL; p = nextSibling(p)) {
if (gencomma) {
Append(arguments, ",");
}
gencomma = true;
String *type = Getattr(p, "type");
String *ctype = getMappedTypeNew(type, "ctype");
Append(arguments, ctype);
}
return arguments;
}
#endif
void emitTypeWrapperClass(String *classname, SwigType *type) {
Node *n = NewHash();
Setfile(n, input_file);
Setline(n, line_number);
String *filen = NewStringf("%s%s.m3", Swig_file_dirname(outfile), classname);
File *f_swigtype = NewFile(filen, "w", SWIG_output_files());
if (!f_swigtype) {
FileErrorDisplay(filen);
SWIG_exit(EXIT_FAILURE);
}
String *swigtype = NewString("");
emitBanner(f_swigtype);
const String *pure_baseclass = typemapLookup(n, "m3base", type, WARN_NONE);
const String *pure_interfaces = typemapLookup(n, "m3interfaces", type, WARN_NONE);
Printv(swigtype, typemapLookup(n, "m3imports", type, WARN_NONE), "\n", typemapLookup(n, "m3classmodifiers", type, WARN_MODULA3_TYPEMAP_CLASSMOD_UNDEF), " class $m3classname", *Char(pure_baseclass) ? " : " : "", pure_baseclass, *Char(pure_interfaces) ? " : " : "", pure_interfaces, " {\n", " private IntPtr swigCPtr;\n", "\n", " ", typemapLookup(n, "m3ptrconstructormodifiers", type, WARN_MODULA3_TYPEMAP_PTRCONSTMOD_UNDEF), " $m3classname(IntPtr cPtr, bool bFutureUse) {\n", " swigCPtr = cPtr;\n", " }\n", "\n", " protected $m3classname() {\n", " swigCPtr = IntPtr.Zero;\n", " }\n", typemapLookup(n, "m3getcptr", type, WARN_MODULA3_TYPEMAP_GETCPTR_UNDEF), typemapLookup(n, "m3code", type, WARN_NONE), "}\n", "\n", NIL);
Replaceall(swigtype, "$m3classname", classname);
Printv(f_swigtype, swigtype, NIL);
Close(f_swigtype);
Delete(filen);
Delete(swigtype);
}
const String *typemapLookup(Node *n, const_String_or_char_ptr tmap_method, SwigType *type, int warning, Node *typemap_attributes = 0) {
Node *node = !typemap_attributes ? NewHash() : typemap_attributes;
Setattr(node, "type", type);
Setfile(node, Getfile(n));
Setline(node, Getline(n));
const String *tm = Swig_typemap_lookup(tmap_method, node, "", 0);
if (!tm) {
tm = empty_string;
if (warning != WARN_NONE)
Swig_warning(warning, Getfile(n), Getline(n), "No %s typemap defined for %s\n", tmap_method, SwigType_str(type, 0));
}
if (!typemap_attributes)
Delete(node);
return tm;
}
int addThrows(Hash *throws_hash, const String *typemap, Node *parameter) {
int len = 0;
String *throws_attribute = NewStringf("%s:throws", typemap);
addImports(m3wrap_intf.import, throws_attribute, parameter);
addImports(m3wrap_impl.import, throws_attribute, parameter);
String *throws = getMappedTypeNew(parameter, Char(throws_attribute), "", false);
if (throws) {
List *temp_classes_list = Split(throws, ',', INT_MAX);
len = Len(temp_classes_list);
if (temp_classes_list ) {
for (Iterator cls = First(temp_classes_list); cls.item != NIL; cls = Next(cls)) {
String *exception_class = NewString(cls.item);
Replaceall(exception_class, " ", ""); Replaceall(exception_class, "\t", ""); if (hasContent(exception_class)) {
SwigType *pt = Getattr(parameter, "type");
substituteClassname(pt, exception_class);
Setattr(throws_hash, exception_class, "1");
}
Delete(exception_class);
}
}
Delete(temp_classes_list);
}
Delete(throws_attribute);
return len;
}
void generateThrowsClause(Hash *throws_hash, String *code) {
if (Len(throws_hash) > 0) {
Iterator cls = First(throws_hash);
Printf(code, " RAISES {%s", cls.key);
for (cls = Next(cls); cls.key != NIL; cls = Next(cls)) {
Printf(code, ", %s", cls.key);
}
Printf(code, "}");
}
}
void addImports(Hash *imports_hash, const String *typemap, Node *node) {
String *imports_attribute = NewStringf("%s:import", typemap);
String *imports = getMappedTypeNew(node, Char(imports_attribute), "", false);
if (imports != NIL) {
List *import_list = Split(imports, ',', INT_MAX);
if (import_list != NIL) {
for (Iterator imp = First(import_list); imp.item != NIL; imp = Next(imp)) {
List *import_pair = Split(imp.item, ' ', 3);
if (Len(import_pair) == 1) {
Setattr(imports_hash, Getitem(import_pair, 0), "");
} else if ((Len(import_pair) == 3)
&& Strcmp(Getitem(import_pair, 1), "AS") == 0) {
Setattr(imports_hash, Getitem(import_pair, 0), Getitem(import_pair, 2));
} else {
Swig_warning(WARN_MODULA3_BAD_IMPORT, input_file, line_number,
"Malformed import '%s' for typemap '%s' defined for type '%s'\n", imp, typemap, SwigType_str(Getattr(node, "type"), 0));
}
Delete(import_pair);
}
}
Delete(import_list);
}
Delete(imports_attribute);
}
void emitImportStatements(Hash *imports_hash, String *code) {
Iterator imp = First(imports_hash);
while (imp.key != NIL) {
Printf(code, "IMPORT %s", imp.key);
String *imp_as = imp.item;
if (hasContent(imp_as)) {
Printf(code, " AS %s", imp_as);
}
Printf(code, ";\n");
imp = Next(imp);
}
}
};
extern "C" Language *swig_modula3(void) {
return new MODULA3();
}
const char *MODULA3::usage = (char *) "\
Modula 3 Options (available with -modula3)\n\
-generateconst <file> - generate code for computing numeric values of constants\n\
-generaterename <file> - generate suggestions for %rename\n\
-generatetypemap <file> - generate templates for some basic typemaps\n\
-oldvarnames - old intermediary method names for variable wrappers\n\
\n";