PageRenderTime 46ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/Source/Modules/directors.cxx

#
C++ | 318 lines | 229 code | 27 blank | 62 comment | 67 complexity | cb90fa900455ffe1aa39e96604bc1d3f MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  1. /* -----------------------------------------------------------------------------
  2. * This file is part of SWIG, which is licensed as a whole under version 3
  3. * (or any later version) of the GNU General Public License. Some additional
  4. * terms also apply to certain portions of SWIG. The full details of the SWIG
  5. * license and copyrights can be found in the LICENSE and COPYRIGHT files
  6. * included with the SWIG source code as distributed by the SWIG developers
  7. * and at http://www.swig.org/legal.html.
  8. *
  9. * directors.cxx
  10. *
  11. * Director support functions.
  12. * Not all of these may be necessary, and some may duplicate existing functionality
  13. * in SWIG. --MR
  14. * ----------------------------------------------------------------------------- */
  15. char cvsroot_directors_cxx[] = "$Id";
  16. #include "swigmod.h"
  17. /* Swig_csuperclass_call()
  18. *
  19. * Generates a fully qualified method call, including the full parameter list.
  20. * e.g. "base::method(i, j)"
  21. *
  22. */
  23. String *Swig_csuperclass_call(String *base, String *method, ParmList *l) {
  24. String *call = NewString("");
  25. int arg_idx = 0;
  26. Parm *p;
  27. if (base) {
  28. Printf(call, "%s::", base);
  29. }
  30. Printf(call, "%s(", method);
  31. for (p = l; p; p = nextSibling(p)) {
  32. String *pname = Getattr(p, "name");
  33. if (!pname && Cmp(Getattr(p, "type"), "void")) {
  34. pname = NewString("");
  35. Printf(pname, "arg%d", arg_idx++);
  36. }
  37. if (p != l)
  38. Printf(call, ", ");
  39. Printv(call, pname, NIL);
  40. }
  41. Printf(call, ")");
  42. return call;
  43. }
  44. /* Swig_class_declaration()
  45. *
  46. * Generate the start of a class/struct declaration.
  47. * e.g. "class myclass"
  48. *
  49. */
  50. String *Swig_class_declaration(Node *n, String *name) {
  51. if (!name) {
  52. name = Getattr(n, "sym:name");
  53. }
  54. String *result = NewString("");
  55. String *kind = Getattr(n, "kind");
  56. Printf(result, "%s %s", kind, name);
  57. return result;
  58. }
  59. String *Swig_class_name(Node *n) {
  60. String *name;
  61. name = Copy(Getattr(n, "sym:name"));
  62. return name;
  63. }
  64. /* Swig_director_declaration()
  65. *
  66. * Generate the full director class declaration, complete with base classes.
  67. * e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {"
  68. *
  69. */
  70. String *Swig_director_declaration(Node *n) {
  71. String *classname = Swig_class_name(n);
  72. String *directorname = NewStringf("SwigDirector_%s", classname);
  73. String *base = Getattr(n, "classtype");
  74. String *declaration = Swig_class_declaration(n, directorname);
  75. Printf(declaration, " : public %s, public Swig::Director {\n", base);
  76. Delete(classname);
  77. Delete(directorname);
  78. return declaration;
  79. }
  80. String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms) {
  81. String *func;
  82. int i = 0;
  83. int comma = 0;
  84. Parm *p = parms;
  85. SwigType *pt;
  86. String *nname;
  87. func = NewString("");
  88. nname = SwigType_namestr(name);
  89. Printf(func, "%s(", nname);
  90. while (p) {
  91. String *pname;
  92. pt = Getattr(p, "type");
  93. if ((SwigType_type(pt) != T_VOID)) {
  94. if (comma)
  95. Printf(func, ",");
  96. pname = Getattr(p, "name");
  97. Printf(func, "%s", pname);
  98. comma = 1;
  99. i++;
  100. }
  101. p = nextSibling(p);
  102. }
  103. Printf(func, ")");
  104. return func;
  105. }
  106. /* Swig_method_decl
  107. *
  108. * Misnamed and misappropriated! Taken from SWIG's type string manipulation utilities
  109. * and modified to generate full (or partial) type qualifiers for method declarations,
  110. * local variable declarations, and return value casting. More importantly, it merges
  111. * parameter type information with actual parameter names to produce a complete method
  112. * declaration that fully mirrors the original method declaration.
  113. *
  114. * There is almost certainly a saner way to do this.
  115. *
  116. * This function needs to be cleaned up and possibly split into several smaller
  117. * functions. For instance, attaching default names to parameters should be done in a
  118. * separate function.
  119. *
  120. */
  121. String *Swig_method_decl(SwigType *returntype, SwigType *decl, const_String_or_char_ptr id, List *args, int strip, int values) {
  122. String *result;
  123. List *elements;
  124. String *element = 0, *nextelement;
  125. int is_const = 0;
  126. int nelements, i;
  127. int is_func = 0;
  128. int arg_idx = 0;
  129. if (id) {
  130. result = NewString(Char(id));
  131. } else {
  132. result = NewString("");
  133. }
  134. elements = SwigType_split(decl);
  135. nelements = Len(elements);
  136. if (nelements > 0) {
  137. element = Getitem(elements, 0);
  138. }
  139. for (i = 0; i < nelements; i++) {
  140. if (i < (nelements - 1)) {
  141. nextelement = Getitem(elements, i + 1);
  142. } else {
  143. nextelement = 0;
  144. }
  145. if (SwigType_isqualifier(element)) {
  146. int skip = 0;
  147. DOH *q = 0;
  148. if (!strip) {
  149. q = SwigType_parm(element);
  150. if (!Cmp(q, "const")) {
  151. is_const = 1;
  152. is_func = SwigType_isfunction(nextelement);
  153. if (is_func)
  154. skip = 1;
  155. skip = 1;
  156. }
  157. if (!skip) {
  158. Insert(result, 0, " ");
  159. Insert(result, 0, q);
  160. }
  161. Delete(q);
  162. }
  163. } else if (SwigType_isfunction(element)) {
  164. Parm *parm;
  165. String *p;
  166. Append(result, "(");
  167. parm = args;
  168. while (parm != 0) {
  169. String *type = Getattr(parm, "type");
  170. String *name = Getattr(parm, "name");
  171. if (!name && Cmp(type, "void")) {
  172. name = NewString("");
  173. Printf(name, "arg%d", arg_idx++);
  174. Setattr(parm, "name", name);
  175. }
  176. if (!name) {
  177. name = NewString("");
  178. }
  179. p = SwigType_str(type, name);
  180. Append(result, p);
  181. String *value = Getattr(parm, "value");
  182. if (values && (value != 0)) {
  183. Printf(result, " = %s", value);
  184. }
  185. parm = nextSibling(parm);
  186. if (parm != 0)
  187. Append(result, ", ");
  188. }
  189. Append(result, ")");
  190. } else if (returntype) { // This check is intended for conversion operators to a pointer/reference which needs the pointer/reference ignoring in the declaration
  191. if (SwigType_ispointer(element)) {
  192. Insert(result, 0, "*");
  193. if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
  194. Insert(result, 0, "(");
  195. Append(result, ")");
  196. }
  197. } else if (SwigType_ismemberpointer(element)) {
  198. String *q;
  199. q = SwigType_parm(element);
  200. Insert(result, 0, "::*");
  201. Insert(result, 0, q);
  202. if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
  203. Insert(result, 0, "(");
  204. Append(result, ")");
  205. }
  206. Delete(q);
  207. } else if (SwigType_isreference(element)) {
  208. Insert(result, 0, "&");
  209. } else if (SwigType_isarray(element)) {
  210. DOH *size;
  211. Append(result, "[");
  212. size = SwigType_parm(element);
  213. Append(result, size);
  214. Append(result, "]");
  215. Delete(size);
  216. } else {
  217. if (Strcmp(element, "v(...)") == 0) {
  218. Insert(result, 0, "...");
  219. } else {
  220. String *bs = SwigType_namestr(element);
  221. Insert(result, 0, " ");
  222. Insert(result, 0, bs);
  223. Delete(bs);
  224. }
  225. }
  226. }
  227. element = nextelement;
  228. }
  229. Delete(elements);
  230. if (is_const) {
  231. if (is_func) {
  232. Append(result, " ");
  233. Append(result, "const");
  234. } else {
  235. Insert(result, 0, "const ");
  236. }
  237. }
  238. Chop(result);
  239. if (returntype) {
  240. Insert(result, 0, " ");
  241. String *rtype = SwigType_str(returntype, 0);
  242. Insert(result, 0, rtype);
  243. Delete(rtype);
  244. }
  245. return result;
  246. }
  247. /* -----------------------------------------------------------------------------
  248. * Swig_director_emit_dynamic_cast()
  249. *
  250. * In order to call protected virtual director methods from the target language, we need
  251. * to add an extra dynamic_cast to call the public C++ wrapper in the director class.
  252. * Also for non-static protected members when the allprotected option is on.
  253. * ----------------------------------------------------------------------------- */
  254. void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f) {
  255. // TODO: why is the storage element removed in staticmemberfunctionHandler ??
  256. if ((!is_public(n) && (is_member_director(n) || GetFlag(n, "explicitcall"))) ||
  257. (is_non_virtual_protected_access(n) && !(checkAttribute(n, "staticmemberfunctionHandler:storage", "static") ||
  258. checkAttribute(n, "storage", "static"))
  259. && !Equal(nodeType(n), "constructor"))) {
  260. Node *parent = Getattr(n, "parentNode");
  261. String *symname = Getattr(parent, "sym:name");
  262. String *dirname = NewStringf("SwigDirector_%s", symname);
  263. String *dirdecl = NewStringf("%s *darg = 0", dirname);
  264. Wrapper_add_local(f, "darg", dirdecl);
  265. Printf(f->code, "darg = dynamic_cast<%s *>(arg1);\n", dirname);
  266. Delete(dirname);
  267. Delete(dirdecl);
  268. }
  269. }
  270. /* ------------------------------------------------------------
  271. * Swig_director_parms_fixup()
  272. *
  273. * For each parameter in the C++ member function, copy the parameter name
  274. * to its "lname"; this ensures that Swig_typemap_attach_parms() will do
  275. * the right thing when it sees strings like "$1" in "directorin" typemaps.
  276. * ------------------------------------------------------------ */
  277. void Swig_director_parms_fixup(ParmList *parms) {
  278. Parm *p;
  279. int i;
  280. for (i = 0, p = parms; p; p = nextSibling(p), ++i) {
  281. String *arg = Getattr(p, "name");
  282. String *lname = 0;
  283. if (!arg && !Equal(Getattr(p, "type"), "void")) {
  284. lname = NewStringf("arg%d", i);
  285. Setattr(p, "name", lname);
  286. } else
  287. lname = Copy(arg);
  288. Setattr(p, "lname", lname);
  289. Delete(lname);
  290. }
  291. }