PageRenderTime 55ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/Source/Modules/allegrocl.cxx

#
C++ | 2061 lines | 1514 code | 285 blank | 262 comment | 406 complexity | 56e85084a7a4afb78afa412910f3ad6e MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  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. * allegrocl.cxx
  10. *
  11. * ALLEGROCL language module for SWIG.
  12. * ----------------------------------------------------------------------------- */
  13. char cvsroot_allegrocl_cxx[] = "$Id: allegrocl.cxx 12830 2011-10-30 21:51:50Z wsfulton $";
  14. #include "swigmod.h"
  15. #include "cparse.h"
  16. #include <ctype.h>
  17. // #define ALLEGROCL_DEBUG
  18. // #define ALLEGROCL_WRAP_DEBUG
  19. // #define ALLEGROCL_TYPE_DEBUG
  20. // #define ALLEGROCL_CLASS_DEBUG
  21. static const char *usage = (char *) "\
  22. Allegro CL Options (available with -allegrocl)\n\
  23. -identifier-converter <type or funcname> - \n\
  24. Specifies the type of conversion to do on C identifiers to convert\n\
  25. them to symbols. There are two built-in converters: 'null' and\n\
  26. 'lispify'. The default is 'null'. If you supply a name other\n\
  27. than one of the built-ins, then a function by that name will be\n\
  28. called to convert identifiers to symbols.\n\
  29. -[no]cwrap - Turn on or turn off generation of an intermediate C file when\n\
  30. creating a C interface. By default this is only done for C++ code.\n\
  31. -isolate - Define all SWIG helper functions in a package unique to this\n\
  32. module. Avoids redefinition warnings when loading multiple\n\
  33. SWIGged modules into the same running Allegro CL image.\n\
  34. ";
  35. static File *f_cl = 0;
  36. String *f_clhead = NewString("");
  37. String *f_clwrap = NewString("(swig-in-package ())\n\n");
  38. static File *f_begin;
  39. static File *f_runtime;
  40. static File *f_cxx_header = 0;
  41. static File *f_cxx_wrapper = 0;
  42. static String *module_name = 0;
  43. static String *swig_package = 0;
  44. const char *identifier_converter = "identifier-convert-null";
  45. static bool CWrap = true; // generate wrapper file for C code by default. most correct.
  46. static bool Generate_Wrapper = false;
  47. static bool unique_swig_package = false;
  48. static SwigType *fwdref_ffi_type = NewString("__SWIGACL_FwdReference");
  49. static String *current_namespace = NewString("");
  50. static String *current_package = NewString("");
  51. static Hash *defined_namespace_packages = NewHash();
  52. static Node *in_class = 0;
  53. static Node *first_linked_type = 0;
  54. static Hash *defined_foreign_types = NewHash();
  55. static Hash *defined_foreign_ltypes = NewHash();
  56. static String *anon_type_name = NewString("anontype");
  57. static int anon_type_count = 0;
  58. // stub
  59. String *convert_literal(String *num_param, String *type, bool try_to_split = true);
  60. class ALLEGROCL:public Language {
  61. public:
  62. virtual void main(int argc, char *argv[]);
  63. virtual int top(Node *n);
  64. virtual int functionWrapper(Node *n);
  65. virtual int namespaceDeclaration(Node *n);
  66. virtual int constructorHandler(Node *n);
  67. virtual int destructorHandler(Node *n);
  68. virtual int globalvariableHandler(Node *n);
  69. virtual int variableWrapper(Node *n);
  70. virtual int constantWrapper(Node *n);
  71. virtual int memberfunctionHandler(Node *n);
  72. virtual int membervariableHandler(Node *n);
  73. virtual int classHandler(Node *n);
  74. virtual int emit_one(Node *n);
  75. virtual int enumDeclaration(Node *n);
  76. virtual int enumvalueDeclaration(Node *n);
  77. virtual int typedefHandler(Node *n);
  78. virtual int classforwardDeclaration(Node *n);
  79. virtual int templateDeclaration(Node *n);
  80. virtual int validIdentifier(String *s);
  81. private:
  82. int emit_defun(Node *n, File *f_cl);
  83. int emit_dispatch_defun(Node *n);
  84. int emit_buffered_defuns(Node *n);
  85. int cClassHandler(Node *n);
  86. int cppClassHandler(Node *n);
  87. };
  88. static ALLEGROCL *allegrocl = 0;
  89. static String *trim(String *str) {
  90. char *c = Char(str);
  91. while (*c != '\0' && isspace((int) *c))
  92. ++c;
  93. String *result = NewString(c);
  94. Chop(result);
  95. return result;
  96. }
  97. int is_integer(String *s) {
  98. char *c = Char(s);
  99. if (c[0] == '#' && (c[1] == 'x' || c[1] == 'o'))
  100. c += 2;
  101. while (*c) {
  102. if (!isdigit(*c))
  103. return 0;
  104. c++;
  105. }
  106. return 1;
  107. }
  108. String *class_from_class_or_class_ref(String *type) {
  109. SwigType *stripped = SwigType_strip_qualifiers(type);
  110. if (SwigType_isclass(stripped))
  111. return stripped;
  112. if (SwigType_ispointer(stripped) || SwigType_isreference(stripped)) {
  113. // Printf(stderr,"It is a pointer/reference. Is it a class?\n");
  114. SwigType_pop(stripped);
  115. if (SwigType_isclass(stripped)) {
  116. return stripped;
  117. }
  118. }
  119. return 0;
  120. }
  121. String *lookup_defined_foreign_type(String *k) {
  122. #ifdef ALLEGROCL_TYPE_DEBUG
  123. Printf(stderr, "Looking up defined type '%s'.\n Found: '%s'\n", k, Getattr(defined_foreign_types, k));
  124. #endif
  125. return Getattr(defined_foreign_types, k);
  126. }
  127. String *listify_namespace(String *namespaze) {
  128. if (Len(namespaze) == 0)
  129. return NewString("()");
  130. String *result = NewStringf("(\"%s\")", namespaze);
  131. Replaceall(result, "::", "\" \"");
  132. return result;
  133. }
  134. String *namespaced_name(Node *n, String *ns = current_namespace) {
  135. return NewStringf("%s%s%s", ns, (Len(ns) != 0) ? "::" : "", Getattr(n, "sym:name"));
  136. }
  137. // "Namespace::Nested::Class2::Baz" -> "Baz"
  138. static String *strip_namespaces(String *str) {
  139. SwigType *new_type = Copy(str);
  140. SwigType *leading_type = SwigType_pop(new_type);
  141. char *result = Char(leading_type);
  142. if(SwigType_istemplate(leading_type)) {
  143. result = Char(SwigType_templateprefix(leading_type));
  144. } else {
  145. if (!SwigType_issimple(leading_type))
  146. return NewString(str);
  147. }
  148. String *stripped_one;
  149. while ((stripped_one = Strstr(result, "::")))
  150. result = Char(stripped_one) + 2;
  151. if(SwigType_istemplate(leading_type)) {
  152. SwigType_push(new_type, NewStringf("%s%s%s", result, SwigType_templateargs(leading_type),
  153. SwigType_templatesuffix(leading_type)));
  154. return new_type;
  155. }
  156. return NewString(result);
  157. }
  158. static String *namespace_of(String *str) {
  159. char *p = Char(str);
  160. char *start = Char(str);
  161. char *result = 0;
  162. String *stripped_one;
  163. while ((stripped_one = Strstr(p, "::"))) {
  164. p = Char(stripped_one) + 2;
  165. }
  166. if (p > start) {
  167. int len = p - start - 1;
  168. result = (char *) malloc(len);
  169. strncpy(result, start, len - 1);
  170. result[len - 1] = 0;
  171. }
  172. return Char(result);
  173. }
  174. void add_linked_type(Node *n) {
  175. #ifdef ALLEGROCL_CLASS_DEBUG
  176. Printf(stderr, "Adding linked node of type: %s(%s) %s(%x)\n\n", nodeType(n), Getattr(n, "storage"), Getattr(n, "name"), n);
  177. // Swig_print_node(n);
  178. #endif
  179. if (!first_linked_type) {
  180. first_linked_type = n;
  181. Setattr(n, "allegrocl:last_linked_type", n);
  182. } else {
  183. Node *t = Getattr(first_linked_type, "allegrocl:last_linked_type");
  184. Setattr(t, "allegrocl:next_linked_type", n);
  185. Setattr(first_linked_type, "allegrocl:last_linked_type", n);
  186. }
  187. }
  188. void replace_linked_type(Node *old, Node *new_node) {
  189. Node *prev = Getattr(old, "allegrocl:prev_linked_type");
  190. Setattr(new_node, "allegrocl:next_linked_type", Getattr(old, "allegrocl:next_linked_type"));
  191. if (prev)
  192. Setattr(prev, "allegrocl:next_linked_type", new_node);
  193. Delattr(old, "allegrocl:next_linked_type");
  194. Delattr(old, "allegrocl:prev_linked_type");
  195. // check if we're replacing the first link.
  196. if (first_linked_type == old) {
  197. first_linked_type = new_node;
  198. Setattr(first_linked_type, "allegrocl:last_linked_type", Getattr(old, "allegrocl:last_linked_type"));
  199. }
  200. // check if we're replacing the last link.
  201. if (Getattr(first_linked_type, "allegrocl:last_linked_type") == old)
  202. Setattr(first_linked_type, "allegrocl:last_linked_type", new_node);
  203. }
  204. void insert_linked_type_at(Node *old, Node *new_node, int before = 1) {
  205. Node *p = 0;
  206. if (!first_linked_type) {
  207. add_linked_type(new_node);
  208. return;
  209. }
  210. if (!before) {
  211. Setattr(new_node, "allegrocl:next_linked_type", Getattr(old, "allegrocl:next_linked_type"));
  212. Setattr(old, "allegrocl:next_linked_type", new_node);
  213. if (Getattr(first_linked_type, "allegrocl:last_linked_type") == old)
  214. Setattr(first_linked_type, "allegrocl:last_linked_type", new_node);
  215. } else {
  216. Node *c = first_linked_type;
  217. while (c) {
  218. if (c == old) {
  219. break;
  220. } else {
  221. p = c;
  222. c = Getattr(c, "allegrocl:next_linked_type");
  223. }
  224. }
  225. if (c == old) {
  226. Setattr(new_node, "allegrocl:next_linked_type", c);
  227. if (first_linked_type == c) {
  228. first_linked_type = new_node;
  229. Setattr(first_linked_type, "allegrocl:last_linked_type", Getattr(c, "allegrocl:last_linked_type"));
  230. Delattr(c, "allegrocl:last_linked_type");
  231. }
  232. if (p)
  233. Setattr(p, "allegrocl:next_linked_type", new_node);
  234. }
  235. }
  236. }
  237. Node *find_linked_type_by_name(String *name) {
  238. Node *p = 0;
  239. Node *c = first_linked_type;
  240. // Printf(stderr,"in find_linked_type_by_name '%s'...", name);
  241. while (c) {
  242. String *key = Getattr(c, "name");
  243. if (!Strcmp(key, name)) {
  244. break;
  245. } else {
  246. p = c;
  247. c = Getattr(c, "allegrocl:next_linked_type");
  248. }
  249. }
  250. // Printf(stderr,"exit find_linked_type_by_name.\n");
  251. if (p && c)
  252. Setattr(c, "allegrocl:prev_linked_type", p);
  253. // Printf(stderr,"find_linked_type_by_name: DONE\n");
  254. return c;
  255. }
  256. Node *get_primary_synonym_of(Node *n) {
  257. Node *p = Getattr(n, "allegrocl:synonym-of");
  258. Node *prim = n;
  259. // Printf(stderr, "getting primary synonym of %x\n", n);
  260. while (p) {
  261. // Printf(stderr, " found one! %x\n", p);
  262. prim = p;
  263. p = Getattr(p, "allegrocl:synonym-of");
  264. }
  265. // Printf(stderr,"get_primary_syn: DONE. returning %s(%x)\n", Getattr(prim,"name"),prim);
  266. return prim;
  267. }
  268. void add_forward_referenced_type(Node *n, int overwrite = 0) {
  269. String *k = Getattr(n, "name");
  270. String *name = Getattr(n, "sym:name");
  271. String *ns = listify_namespace(current_namespace);
  272. String *val = Getattr(defined_foreign_types, k);
  273. if (!val || overwrite) {
  274. #ifdef ALLEGROCL_TYPE_DEBUG
  275. Printf(stderr, "Adding forward reference for %s (overwrite=%d)\n", k, overwrite);
  276. #endif
  277. Setattr(defined_foreign_types, Copy(k), NewString("forward-reference"));
  278. String *mangled_lname_gen = NewStringf("#.(swig-insert-id \"%s\" %s :type :class)", name, ns);
  279. Setattr(defined_foreign_ltypes, Copy(k), mangled_lname_gen);
  280. // Printf(f_cl, ";; forward reference stub\n"
  281. // "(swig-def-foreign-class \"%s\" (ff:foreign-pointer) (:class ))\n\n"
  282. // , name);
  283. #ifdef ALLEGROCL_CLASS_DEBUG
  284. Printf(stderr, "Linking forward reference type = %s(%x)\n", k, n);
  285. #endif
  286. add_linked_type(n);
  287. }
  288. }
  289. void add_defined_foreign_type(Node *n, int overwrite = 0, String *k = 0,
  290. String *name = 0, String *ns = current_namespace) {
  291. String *val;
  292. String *ns_list = listify_namespace(ns);
  293. String *templated = n ? Getattr(n, "template") : 0;
  294. String *cDeclName = n ? Getattr(n, "name") : 0;
  295. #ifdef ALLEGROCL_CLASS_DEBUG
  296. Printf(stderr, "IN A-D-F-T. (n=%x, ow=%d, k=%s, name=%s, ns=%s\n", n, overwrite, k, name, ns);
  297. Printf(stderr, " templated = '%x', classDecl = '%x'\n", templated, cDeclName);
  298. #endif
  299. if (n) {
  300. if (!name)
  301. name = Getattr(n, "sym:name");
  302. if (!name)
  303. name = strip_namespaces(Getattr(n, "name"));
  304. if (templated) {
  305. k = namespaced_name(n);
  306. } else {
  307. String *kind_of_type = Getattr(n, "kind");
  308. /*
  309. For typedefs of the form:
  310. typedef struct __xxx { ... } xxx;
  311. behavior differs between C mode and C++ mode.
  312. C Mode:
  313. add_defined_foreign_type will be called once via classHandler
  314. to define the type for 'struct __xxx' and add the mapping from
  315. 'struct __xxx' -> 'xxx'
  316. It will also be called once via typedefHandler to add the
  317. mapping 'xxx' -> 'xxx'
  318. C++ Mode:
  319. add_defined_foreign_type will be called once via classHandler
  320. to define the type for 'xxx'. it also adds the mapping from
  321. 'xxx' -> 'xxx' and also for 'struct xxx' -> 'xxx'
  322. In typedefHandler, we again try to add the mapping from
  323. 'xxx' -> 'xxx', which already exists. This second mapping
  324. is ignored.
  325. Both modes:
  326. All references to this typedef'd struct will appear in
  327. generated lisp code as an objectd of type 'xxx'. For
  328. non-typedef'd structs, the classHand mapping will be
  329. struct __xxx -> (swig-insert-id "__xxx")
  330. */
  331. // Swig_print_node(n);
  332. String *unnamed = Getattr(n, "unnamed");
  333. if (kind_of_type && (!Strcmp(kind_of_type, "struct")
  334. || !Strcmp(kind_of_type, "union")) && cDeclName && !unnamed) {
  335. k = NewStringf("%s %s", kind_of_type, cDeclName);
  336. } else {
  337. if (!Strcmp(nodeType(n), "enum") && unnamed) {
  338. name = NewStringf("%s%d", anon_type_name, anon_type_count++);
  339. k = NewStringf("enum %s", name);
  340. Setattr(n, "allegrocl:name", name);
  341. } else {
  342. k = k ? k : Getattr(n, "name");
  343. }
  344. }
  345. }
  346. // Swig_print_node(n);
  347. }
  348. String *tname = SwigType_istemplate_templateprefix(name);
  349. if (tname) {
  350. String *temp = strip_namespaces(tname);
  351. name = NewStringf("%s%s%s", temp, SwigType_templateargs(name), SwigType_templatesuffix(name));
  352. Delete(temp);
  353. Delete(tname);
  354. }
  355. val = lookup_defined_foreign_type(k);
  356. int is_fwd_ref = 0;
  357. if (val)
  358. is_fwd_ref = !Strcmp(val, "forward-reference");
  359. if (!val || overwrite || is_fwd_ref) {
  360. #ifdef ALLEGROCL_CLASS_DEBUG
  361. Printf(stderr, "Adding defined type '%s' = '%s' '%s' (overwrite=%d, in-class=%d)\n", k, ns, name, overwrite, in_class);
  362. #endif
  363. String *mangled_name_gen = NewStringf("#.(swig-insert-id \"%s\" %s :type :type)", name, ns_list);
  364. String *mangled_lname_gen = NewStringf("#.(swig-insert-id \"%s\" %s :type :class)", name, ns_list);
  365. Setattr(defined_foreign_types, Copy(k), Copy(mangled_name_gen));
  366. Setattr(defined_foreign_ltypes, Copy(k), Copy(mangled_lname_gen));
  367. if (CPlusPlus) {
  368. bool cpp_struct = Strstr(k, "struct ") ? true : false;
  369. bool cpp_union = Strstr(k, "union ") ? true : false;
  370. String *cpp_type = 0;
  371. if (cpp_struct) {
  372. cpp_type = Copy(k);
  373. Replaceall(cpp_type, "struct ", "");
  374. } else if (cpp_union) {
  375. cpp_type = Copy(k);
  376. Replaceall(cpp_type, "union ", "");
  377. }
  378. if (cpp_struct || cpp_union) {
  379. #ifdef ALLEGROCL_CLASS_DEBUG
  380. Printf(stderr, " Also adding defined type '%s' = '%s' '%s' (overwrite=%d)\n", cpp_type, ns, name, overwrite);
  381. #endif
  382. Setattr(defined_foreign_types, Copy(cpp_type), Copy(mangled_name_gen));
  383. Setattr(defined_foreign_ltypes, Copy(cpp_type), Copy(mangled_lname_gen));
  384. }
  385. }
  386. #ifdef ALLEGROCL_CLASS_DEBUG
  387. Printf(stderr, "looking to add %s/%s(%x) to linked_type_list...\n", k, name, n);
  388. #endif
  389. if (is_fwd_ref) {
  390. // Printf(stderr,"*** 1\n");
  391. add_linked_type(n);
  392. } else {
  393. // Printf(stderr,"*** 1-a\n");
  394. if (SwigType_istemplate(k)) {
  395. SwigType *resolved = SwigType_typedef_resolve_all(k);
  396. // Printf(stderr,"*** 1-b\n");
  397. Node *match = find_linked_type_by_name(resolved);
  398. Node *new_node = 0;
  399. // Printf(stderr, "*** temp-1\n");
  400. if (n) {
  401. new_node = n;
  402. } else {
  403. #ifdef ALLEGROCL_CLASS_DEBUG
  404. Printf(stderr, "Creating a new templateInst:\n");
  405. Printf(stderr, " name = %s\n", resolved);
  406. Printf(stderr, " sym:name = %s\n", name);
  407. Printf(stderr, " real-name = %s\n", k);
  408. Printf(stderr, " type = %s\n", resolved);
  409. Printf(stderr, " ns = %s\n\n", ns);
  410. #endif
  411. new_node = NewHash();
  412. Setattr(new_node, "nodeType", "templateInst");
  413. Setattr(new_node, "name", Copy(resolved));
  414. Setattr(new_node, "sym:name", Copy(name));
  415. Setattr(new_node, "real-name", Copy(k));
  416. Setattr(new_node, "type", Copy(resolved));
  417. Setattr(new_node, "allegrocl:namespace", ns);
  418. Setattr(new_node, "allegrocl:package", ns);
  419. }
  420. if (!match) {
  421. if (!Strcmp(nodeType(new_node), "templateInst") && in_class) {
  422. /* this is an implicit template instantiation found while
  423. walking a class. need to insert this into the
  424. linked_type list before the current class definition */
  425. #ifdef ALLEGROCL_CLASS_DEBUG
  426. Printf(stderr, "trying to insert a templateInst before a class\n");
  427. #endif
  428. insert_linked_type_at(in_class, new_node);
  429. #ifdef ALLEGROCL_CLASS_DEBUG
  430. Printf(stderr, "DID IT!\n");
  431. #endif
  432. } else {
  433. // Printf(stderr,"*** 3\n");
  434. add_linked_type(new_node);
  435. }
  436. Setattr(new_node, "allegrocl:synonym:is-primary", "1");
  437. } else {
  438. // a synonym type was found (held in variable 'match')
  439. // Printf(stderr, "setting primary synonym of %x to %x\n", new_node, match);
  440. if (new_node == match)
  441. Printf(stderr, "Hey-4 * - '%s' is a synonym of iteself!\n", Getattr(new_node, "name"));
  442. Setattr(new_node, "allegrocl:synonym-of", match);
  443. // Printf(stderr,"*** 4\n");
  444. add_linked_type(new_node);
  445. }
  446. } else {
  447. Node *match;
  448. if (!Strcmp(nodeType(n), "cdecl") && !Strcmp(Getattr(n, "storage"), "typedef")) {
  449. SwigType *type = SwigType_strip_qualifiers(Getattr(n, "type"));
  450. #ifdef ALLEGROCL_CLASS_DEBUG
  451. Printf(stderr, "Examining typedef '%s' for class references. (%d)\n", type, SwigType_isclass(type));
  452. #endif
  453. if (SwigType_isclass(type)) {
  454. #ifdef ALLEGROCL_CLASS_DEBUG
  455. Printf(stderr, "Found typedef of a class '%s'\n", type);
  456. #endif
  457. /*
  458. For the following parsed expression:
  459. typedef struct __xxx { ... } xxx;
  460. if n is of kind "class" (defining the class 'struct __xxx'
  461. then we add n to the linked type list.
  462. if n is "cdecl" node of storage "typedef" (to note
  463. that xxx is equivalent to 'struct __xxx' then we don't
  464. want to add this node to the linked type list.
  465. */
  466. String *defined_type = lookup_defined_foreign_type(type);
  467. String *defined_key_type = lookup_defined_foreign_type(k);
  468. if ((Strstr(type, "struct ") || Strstr(type, "union "))
  469. && defined_type && !Strcmp(defined_type, defined_key_type)) {
  470. // mark as a synonym but don't add to linked_type list
  471. // Printf(stderr,"*** 4.8\n");
  472. Setattr(n, "allegrocl:synonym", "1");
  473. } else {
  474. SwigType *lookup_type = SwigType_istemplate(type) ? SwigType_typedef_resolve_all(type) : Copy(type);
  475. match = find_linked_type_by_name(lookup_type);
  476. if (match) {
  477. Setattr(n, "allegrocl:synonym", "1");
  478. Setattr(n, "allegrocl:synonym-of", match);
  479. Setattr(n, "real-name", Copy(lookup_type));
  480. // Printf(stderr, "*** pre-5: found match of '%s'(%x)\n", Getattr(match,"name"),match);
  481. // if(n == match) Printf(stderr, "Hey-5 *** setting synonym of %x to %x\n", n, match);
  482. // Printf(stderr,"*** 5\n");
  483. add_linked_type(n);
  484. } else {
  485. #ifdef ALLEGROCL_CLASS_DEBUG
  486. Printf(stderr, "Creating classfoward node for struct stub in typedef.\n");
  487. #endif
  488. Node *new_node = NewHash();
  489. String *symname = Copy(type);
  490. Replaceall(symname, "struct ", "");
  491. Setattr(new_node, "nodeType", "classforward");
  492. Setattr(new_node, "name", Copy(type));
  493. Setattr(new_node, "sym:name", symname);
  494. Setattr(new_node, "allegrocl:namespace", ns);
  495. Setattr(new_node, "allegrocl:package", ns);
  496. String *mangled_new_name = NewStringf("#.(swig-insert-id \"%s\" %s)", symname, ns_list);
  497. String *mangled_new_lname = NewStringf("#.(swig-insert-id \"%s\" %s :type :class)", symname, ns_list);
  498. Setattr(defined_foreign_types, Copy(symname), Copy(mangled_new_name));
  499. Setattr(defined_foreign_ltypes, Copy(symname), Copy(mangled_new_lname));
  500. // Printf(stderr,"Weird! Can't find the type!\n");
  501. add_forward_referenced_type(new_node);
  502. add_linked_type(new_node);
  503. Setattr(n, "allegrocl:synonym", "1");
  504. Setattr(n, "allegrocl:synonym-of", new_node);
  505. add_linked_type(n);
  506. }
  507. Delete(lookup_type);
  508. }
  509. } else {
  510. // check if it's a pointer or reference to a class.
  511. // Printf(stderr,"Checking if '%s' is a p. or r. to a class\n", type);
  512. String *class_ref = class_from_class_or_class_ref(type);
  513. if (class_ref) {
  514. match = find_linked_type_by_name(class_ref);
  515. Setattr(n, "allegrocl:synonym", "1");
  516. Setattr(n, "allegrocl:synonym-of", match);
  517. add_linked_type(n);
  518. }
  519. }
  520. Delete(type);
  521. // synonym types have already been added.
  522. // Printf(stderr,"*** 10\n");
  523. if (!Getattr(n, "allegrocl:synonym"))
  524. add_linked_type(n);
  525. } else if (Getattr(n, "template")) {
  526. // Printf(stderr, "this is a class template node(%s)\n", nodeType(n));
  527. String *resolved = SwigType_typedef_resolve_all(Getattr(n, "name"));
  528. #ifdef ALLEGROCL_CLASS_DEBUG
  529. Printf(stderr, " looking up %s for linked type match with %s...\n", Getattr(n, "sym:name"), resolved);
  530. #endif
  531. match = find_linked_type_by_name(resolved);
  532. if (!match) {
  533. #ifdef ALLEGROCL_CLASS_DEBUG
  534. Printf(stderr, "found no implicit instantiation of %%template node %s(%x)\n", Getattr(n, "name"), n);
  535. #endif
  536. add_linked_type(n);
  537. } else {
  538. Node *primary = get_primary_synonym_of(match);
  539. Setattr(n, "allegrocl:synonym:is-primary", "1");
  540. Delattr(primary, "allegrocl:synonym:is-primary");
  541. if (n == match)
  542. Printf(stderr, "Hey-7 * setting synonym of %x to %x\n (match = %x)", primary, n, match);
  543. Setattr(primary, "allegrocl:synonym-of", n);
  544. // Printf(stderr,"*** 7\n");
  545. add_linked_type(n);
  546. }
  547. } else {
  548. #ifdef ALLEGROCL_CLASS_DEBUG
  549. Printf(stderr, "linking type '%s'(%x)\n", k, n);
  550. #endif
  551. // Printf(stderr,"*** 8\n");
  552. add_linked_type(n);
  553. }
  554. }
  555. }
  556. Delete(mangled_name_gen);
  557. Delete(mangled_lname_gen);
  558. } else {
  559. if (!CPlusPlus || Strcmp(Getattr(n,"kind"),"typedef")) {
  560. Swig_warning(WARN_TYPE_REDEFINED, Getfile(n), Getline(n),
  561. "Attempting to store a foreign type that exists: %s (%s)\n",
  562. k, val);
  563. }
  564. }
  565. Delete(ns_list);
  566. #ifdef ALLEGROCL_CLASS_DEBUG
  567. Printf(stderr, "OUT A-D-F-T\n");
  568. #endif
  569. }
  570. void note_implicit_template_instantiation(SwigType *t) {
  571. // the namespace of the implicit instantiation is not necessarily
  572. // current_namespace. Attempt to cull this from the type.
  573. #ifdef ALLEGROCL_CLASS_DEBUG
  574. Printf(stderr, "culling namespace of '%s' from '%s'\n", t, SwigType_templateprefix(t));
  575. #endif
  576. SwigType *type = Copy(t);
  577. SwigType *tok = SwigType_pop(type);
  578. String *implicit_ns = SwigType_istemplate(tok) ? namespace_of(SwigType_templateprefix(tok)) : 0;
  579. add_defined_foreign_type(0, 0, t, t, implicit_ns ? implicit_ns : current_namespace);
  580. Delete(type);
  581. }
  582. String *get_ffi_type(Node *n, SwigType *ty, const_String_or_char_ptr name) {
  583. /* lookup defined foreign type.
  584. if it exists, it will return a form suitable for placing
  585. into lisp code to generate the def-foreign-type name */
  586. #ifdef ALLEGROCL_TYPE_DEBUG
  587. Printf(stderr, "inside g_f_t: looking up '%s' '%s'\n", ty, name);
  588. #endif
  589. String *found_type = lookup_defined_foreign_type(ty);
  590. if (found_type) {
  591. #ifdef ALLEGROCL_TYPE_DEBUG
  592. Printf(stderr, "found_type '%s'\n", found_type);
  593. #endif
  594. return (Strcmp(found_type, "forward-reference") ? Copy(found_type) : get_ffi_type(n, fwdref_ffi_type, ""));
  595. } else {
  596. Node *node = NewHash();
  597. Setattr(node, "type", ty);
  598. Setfile(node, Getfile(n));
  599. Setline(node, Getline(n));
  600. const String *tm = Swig_typemap_lookup("ffitype", node, name, 0);
  601. Delete(node);
  602. if (tm) {
  603. #ifdef ALLEGROCL_TYPE_DEBUG
  604. Printf(stderr, "g-f-t: found ffitype typemap '%s'\n", tm);
  605. #endif
  606. return NewString(tm);
  607. }
  608. if (SwigType_istemplate(ty)) {
  609. note_implicit_template_instantiation(ty);
  610. return Copy(lookup_defined_foreign_type(ty));
  611. }
  612. }
  613. return 0;
  614. }
  615. String *lookup_defined_foreign_ltype(String *l) {
  616. #ifdef ALLEGROCL_TYPE_DEBUG
  617. Printf(stderr, "Looking up defined ltype '%s'.\n Found: '%s'\n", l, Getattr(defined_foreign_ltypes, l));
  618. #endif
  619. return Getattr(defined_foreign_ltypes, l);
  620. }
  621. /* walk type and return string containing lisp version.
  622. recursive. */
  623. String *internal_compose_foreign_type(Node *n, SwigType *ty) {
  624. SwigType *tok;
  625. String *ffiType = NewString("");
  626. // for a function type, need to walk the parm list.
  627. while (Len(ty) != 0) {
  628. tok = SwigType_pop(ty);
  629. if (SwigType_isfunction(tok)) {
  630. // Generate Function wrapper
  631. Printf(ffiType, "(:function ");
  632. // walk parm list
  633. List *pl = SwigType_parmlist(tok);
  634. Printf(ffiType, "("); // start parm list
  635. for (Iterator i = First(pl); i.item; i = Next(i)) {
  636. SwigType *f_arg = SwigType_strip_qualifiers(i.item);
  637. Printf(ffiType, "%s ", internal_compose_foreign_type(n, f_arg));
  638. Delete(f_arg);
  639. }
  640. Printf(ffiType, ")"); // end parm list.
  641. // do function return type.
  642. Printf(ffiType, " %s)", internal_compose_foreign_type(n, ty));
  643. break;
  644. } else if (SwigType_ispointer(tok) || SwigType_isreference(tok)) {
  645. Printf(ffiType, "(* %s)", internal_compose_foreign_type(n, ty));
  646. } else if (SwigType_isarray(tok)) {
  647. Printf(ffiType, "(:array %s", internal_compose_foreign_type(n, ty));
  648. String *atype = NewString("int");
  649. String *dim = convert_literal(SwigType_array_getdim(tok, 0), atype);
  650. Delete(atype);
  651. if (is_integer(dim)) {
  652. Printf(ffiType, " %s)", dim);
  653. } else {
  654. Printf(ffiType, " #| %s |#)", SwigType_array_getdim(tok, 0));
  655. }
  656. } else if (SwigType_ismemberpointer(tok)) {
  657. // temp
  658. Printf(ffiType, "(* %s)", internal_compose_foreign_type(n, ty));
  659. } else {
  660. String *res = get_ffi_type(n, tok, "");
  661. if (res) {
  662. Printf(ffiType, "%s", res);
  663. } else {
  664. SwigType *resolved_type = SwigType_typedef_resolve_all(tok);
  665. if (Cmp(resolved_type, tok) != 0) {
  666. res = get_ffi_type(n, resolved_type, "");
  667. if (res) {
  668. } else {
  669. res = internal_compose_foreign_type(n, resolved_type);
  670. }
  671. if (res)
  672. Printf(ffiType, "%s", res);
  673. }
  674. if (!res) {
  675. String *is_struct = 0;
  676. String *tok_remove_text = 0;
  677. String *tok_name = Copy(tok);
  678. String *tok_key = SwigType_str(tok,0);
  679. if ((is_struct = Strstr(tok_key, "struct ")) || Strstr(tok_key, "union ")) {
  680. tok_remove_text = NewString(is_struct ? "struct " : "union ");
  681. }
  682. /* be more permissive of opaque types. This is the swig way.
  683. compiles will notice if these types are ultimately not
  684. present. */
  685. if(tok_remove_text) {
  686. Replaceall(tok_name,tok_remove_text,"");
  687. }
  688. tok_name = strip_namespaces(tok_name);
  689. Delete(tok_remove_text);
  690. // Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(tok), Getline(tok), "Unable to find definition of '%s', assuming forward reference.\n", tok);
  691. #ifdef ALLEGROCL_TYPE_DEBUG
  692. Printf(stderr, "i-c-f-t: adding forward reference for unknown type '%s'. mapping: %s -> %s\n", tok, tok_key, tok_name);
  693. #endif
  694. Node *nn = NewHash();
  695. Setattr(nn,"nodeType","classforward");
  696. Setattr(nn,"kind","class");
  697. Setattr(nn,"sym:name",tok_name);
  698. Setattr(nn,"name",tok_key);
  699. Setattr(nn,"allegrocl:package",current_namespace);
  700. add_forward_referenced_type(nn, 0);
  701. // tok_name is dangling here, unused. ouch. why?
  702. Printf(ffiType, "%s", get_ffi_type(n, tok, ""), tok_name);
  703. }
  704. }
  705. }
  706. }
  707. return ffiType;
  708. }
  709. String *compose_foreign_type(Node *n, SwigType *ty, String * /*id*/ = 0) {
  710. #ifdef ALLEGROCL_TYPE_DEBUG
  711. Printf(stderr, "compose_foreign_type: ENTER (%s)...\n ", ty);
  712. // Printf(stderr, "compose_foreign_type: ENTER (%s)(%s)...\n ", ty, (id ? id : 0));
  713. /* String *id_ref = SwigType_str(ty, id);
  714. Printf(stderr, "looking up typemap for %s, found '%s'(%x)\n",
  715. id_ref, lookup_res ? Getattr(lookup_res, "code") : 0, lookup_res);
  716. if (lookup_res) Swig_print_node(lookup_res);
  717. */
  718. #endif
  719. /* should we allow named lookups in the typemap here? YES! */
  720. /* unnamed lookups should be found in get_ffi_type, called
  721. by internal_compose_foreign_type(), below. */
  722. /* I'm reverting to 'no' for the question above. I can no longer
  723. remember why I needed it. If a user needed it, I'll find out
  724. as soon as they upgrade. Sigh. -mutandiz 9/16/2008. */
  725. /*
  726. if(id && lookup_res) {
  727. #ifdef ALLEGROCL_TYPE_DEBUG
  728. Printf(stderr, "compose_foreign_type: EXIT-1 (%s)\n ", Getattr(lookup_res, "code"));
  729. #endif
  730. return NewString(Getattr(lookup_res, "code"));
  731. }
  732. */
  733. SwigType *temp = SwigType_strip_qualifiers(ty);
  734. String *res = internal_compose_foreign_type(n, temp);
  735. Delete(temp);
  736. #ifdef ALLEGROCL_TYPE_DEBUG
  737. Printf(stderr, "compose_foreign_type: EXIT (%s)\n ", res);
  738. #endif
  739. return res;
  740. }
  741. void update_package_if_needed(Node *n, File *f = f_clwrap) {
  742. #ifdef ALLEGROCL_DEBUG
  743. Printf(stderr, "update_package: ENTER... \n");
  744. Printf(stderr, " current_package = '%s'\n", current_package);
  745. Printf(stderr, " node_package = '%s'\n", Getattr(n, "allegrocl:package"));
  746. Printf(stderr, " node(%x) = '%s'\n", n, Getattr(n, "name"));
  747. #endif
  748. String *node_package = Getattr(n, "allegrocl:package");
  749. if (Strcmp(current_package, node_package)) {
  750. String *lispy_package = listify_namespace(node_package);
  751. Delete(current_package);
  752. current_package = Copy(node_package);
  753. Printf(f, "\n(swig-in-package %s)\n", lispy_package);
  754. Delete(lispy_package);
  755. }
  756. #ifdef ALLEGROCL_DEBUG
  757. Printf(stderr, "update_package: EXIT.\n");
  758. #endif
  759. }
  760. static String *mangle_name(Node *n, char const *prefix = "ACL", String *ns = current_namespace) {
  761. String *suffix = Getattr(n, "sym:overname");
  762. String *pre_mangled_name = NewStringf("%s_%s__%s%s", prefix, ns, Getattr(n, "sym:name"), suffix);
  763. String *mangled_name = Swig_name_mangle(pre_mangled_name);
  764. Delete(pre_mangled_name);
  765. return mangled_name;
  766. }
  767. /* utilities */
  768. /* remove a pointer from ffitype. non-destructive.
  769. (* :char) ==> :char
  770. (* (:array :int 30)) ==> (:array :int 30) */
  771. String *dereference_ffitype(String *ffitype) {
  772. char *start;
  773. char *temp = Char(ffitype);
  774. String *reduced_type = 0;
  775. if(temp && temp[0] == '(' && temp[1] == '*') {
  776. temp += 2;
  777. // walk past start of pointer references
  778. while(*temp == ' ') temp++;
  779. start = temp;
  780. // temp = Char(reduced_type);
  781. reduced_type = NewString(start);
  782. temp = Char(reduced_type);
  783. // walk to end of string. remove closing paren
  784. while(*temp != '\0') temp++;
  785. *(--temp) = '\0';
  786. }
  787. return reduced_type ? reduced_type : Copy(ffitype);
  788. }
  789. /* returns new string w/ parens stripped */
  790. String *strip_parens(String *string) {
  791. string = Copy(string);
  792. Replaceall(string, "(", "");
  793. Replaceall(string, ")", "");
  794. return string;
  795. }
  796. int ALLEGROCL::validIdentifier(String *s) {
  797. #ifdef ALLEGROCL_DEBUG
  798. Printf(stderr, "validIdentifier %s\n", s);
  799. #endif
  800. char *c = Char(s);
  801. bool got_dot = false;
  802. bool only_dots = true;
  803. /* Check that s is a valid common lisp symbol. There's a lot of leeway here.
  804. A common lisp symbol is essentially any token that's not a number and
  805. does not consist of only dots.
  806. We are expressly not allowing spaces in identifiers here, but spaces
  807. could be added via the identifier converter. */
  808. while (*c) {
  809. if (*c == '.') {
  810. got_dot = true;
  811. } else {
  812. only_dots = false;
  813. }
  814. if (!isgraph(*c))
  815. return 0;
  816. c++;
  817. }
  818. return (got_dot && only_dots) ? 0 : 1;
  819. }
  820. String *infix_to_prefix(String *val, char split_op, const String *op, String *type) {
  821. List *ored = Split(val, split_op, -1);
  822. // some float hackery
  823. if (((split_op == '+') || (split_op == '-')) && Len(ored) == 2 &&
  824. (SwigType_type(type) == T_FLOAT || SwigType_type(type) == T_DOUBLE || SwigType_type(type) == T_LONGDOUBLE)) {
  825. // check that we're not splitting a float
  826. String *possible_result = convert_literal(val, type, false);
  827. if (possible_result)
  828. return possible_result;
  829. }
  830. // try parsing the split results. if any part fails, kick out.
  831. bool part_failed = false;
  832. if (Len(ored) > 1) {
  833. String *result = NewStringf("(%s", op);
  834. for (Iterator i = First(ored); i.item; i = Next(i)) {
  835. String *converted = convert_literal(i.item, type);
  836. if (converted) {
  837. Printf(result, " %s", converted);
  838. Delete(converted);
  839. } else {
  840. part_failed = true;
  841. break;
  842. }
  843. }
  844. Printf(result, ")");
  845. Delete(ored);
  846. return part_failed ? 0 : result;
  847. }
  848. Delete(ored);
  849. return 0;
  850. }
  851. /* To be called by code generating the lisp interface
  852. Will return a containing the literal based on type.
  853. Will return null if there are problems.
  854. try_to_split defaults to true (see stub above).
  855. */
  856. String *convert_literal(String *literal, String *type, bool try_to_split) {
  857. String *num_param = Copy(literal);
  858. String *trimmed = trim(num_param);
  859. String *num = strip_parens(trimmed), *res = 0;
  860. char *s = Char(num);
  861. String *ns = listify_namespace(current_namespace);
  862. // very basic parsing of infix expressions.
  863. if (try_to_split && SwigType_type(type) != T_STRING) {
  864. if ((res = infix_to_prefix(num, '|', "logior", type)))
  865. return res;
  866. if ((res = infix_to_prefix(num, '&', "logand", type)))
  867. return res;
  868. if ((res = infix_to_prefix(num, '^', "logxor", type)))
  869. return res;
  870. if ((res = infix_to_prefix(num, '*', "*", type)))
  871. return res;
  872. if ((res = infix_to_prefix(num, '/', "/", type)))
  873. return res;
  874. if ((res = infix_to_prefix(num, '+', "+", type)))
  875. return res;
  876. if ((res = infix_to_prefix(num, '-', "-", type)))
  877. return res;
  878. // if ((res = infix_to_prefix(num, '~', "lognot", type))) return res;
  879. // if( (res = infix_to_prefix(num, '<<', "ash", type)) ) return res;
  880. }
  881. // unary complement...
  882. if (s[0] == '~' && Len(num) >= 2) {
  883. String *id = NewString(++s);
  884. String *id_conv = convert_literal(id, type, false);
  885. Delete(id);
  886. if (id_conv)
  887. return NewStringf("(lognot %s)", id_conv);
  888. s--;
  889. }
  890. if (SwigType_type(type) == T_FLOAT || SwigType_type(type) == T_DOUBLE || SwigType_type(type) == T_LONGDOUBLE) {
  891. // Use CL syntax for float literals
  892. String *oldnum = Copy(num);
  893. // careful. may be a float identifier or float constant.
  894. char *num_start = Char(num);
  895. char *num_end = num_start + strlen(num_start) - 1;
  896. bool is_literal = isdigit(*num_start) || (*num_start == '.');
  897. String *lisp_exp = 0;
  898. if (is_literal) {
  899. if (*num_end == 'f' || *num_end == 'F') {
  900. lisp_exp = NewString("f");
  901. } else {
  902. lisp_exp = NewString("d");
  903. }
  904. if (*num_end == 'l' || *num_end == 'L' || *num_end == 'f' || *num_end == 'F') {
  905. *num_end = '\0';
  906. num_end--;
  907. }
  908. int exponents = Replaceall(num, "e", lisp_exp) + Replaceall(num, "E", lisp_exp);
  909. if (!exponents)
  910. Printf(num, "%s0", lisp_exp);
  911. if (exponents > 1 || (exponents + Replaceall(num, ".", ".") == 0)) {
  912. // Printf(stderr, "Can't parse '%s' as type '%s'.\n", oldnum, type);
  913. Delete(num);
  914. num = 0;
  915. }
  916. Delete(lisp_exp);
  917. } else {
  918. String *id = NewStringf("#.(swig-insert-id \"%s\" %s :type :constant)",
  919. num, ns);
  920. Delete(num);
  921. num = id;
  922. }
  923. Delete(oldnum);
  924. Delete(trimmed);
  925. Delete(ns);
  926. return num;
  927. } else if (SwigType_type(type) == T_CHAR) {
  928. /* Use CL syntax for character literals */
  929. Delete(num);
  930. Delete(trimmed);
  931. return NewStringf("#\\%s", num_param);
  932. } else if (SwigType_type(type) == T_STRING) {
  933. /* Use CL syntax for string literals */
  934. Delete(num);
  935. Delete(trimmed);
  936. return NewStringf("\"%s\"", num_param);
  937. } else if (Len(num) >= 1 && (isdigit(s[0]) || s[0] == '+' || s[0] == '-')) {
  938. /* use CL syntax for numbers */
  939. String *oldnum = Copy(num);
  940. int usuffixes = Replaceall(num, "u", "") + Replaceall(num, "U", "");
  941. int lsuffixes = Replaceall(num, "l", "") + Replaceall(num, "L", "");
  942. if (usuffixes > 1 || lsuffixes > 1) {
  943. Printf(stderr, "Weird!! number %s looks invalid.\n", oldnum);
  944. SWIG_exit(EXIT_FAILURE);
  945. }
  946. s = Char(num);
  947. if (s[0] == '0' && Len(num) >= 2) {
  948. /*octal or hex */
  949. res = NewStringf("#%c%s", tolower(s[1]) == 'x' ? 'x' : 'o', s + 2);
  950. Delete(num);
  951. } else {
  952. res = num;
  953. }
  954. Delete(oldnum);
  955. Delete(trimmed);
  956. return res;
  957. } else if (allegrocl->validIdentifier(num)) {
  958. /* convert C/C++ identifiers to CL symbols */
  959. res = NewStringf("#.(swig-insert-id \"%s\" %s :type :constant)", num, ns);
  960. Delete(num);
  961. Delete(trimmed);
  962. Delete(ns);
  963. return res;
  964. } else {
  965. Delete(trimmed);
  966. return num;
  967. }
  968. }
  969. void emit_stub_class(Node *n) {
  970. #ifdef ALLEGROCL_WRAP_DEBUG
  971. Printf(stderr, "emit_stub_class: ENTER... '%s'(%x)\n", Getattr(n, "sym:name"), n);
  972. Swig_print_node(n);
  973. #endif
  974. String *name = Getattr(n, "sym:name");
  975. if (Getattr(n, "allegrocl:synonym:already-been-stubbed"))
  976. return;
  977. String *tname = SwigType_istemplate_templateprefix(name);
  978. if (tname) {
  979. String *temp = strip_namespaces(tname);
  980. name = NewStringf("%s%s%s", temp, SwigType_templateargs(name), SwigType_templatesuffix(name));
  981. Delete(temp);
  982. Delete(tname);
  983. } else {
  984. name = strip_namespaces(name);
  985. }
  986. // Printf(f_clhead, ";; from emit-stub-class\n");
  987. update_package_if_needed(n, f_clhead);
  988. Printf(f_clhead, ";; class template stub.\n");
  989. Printf(f_clhead, "(swig-def-foreign-stub \"%s\")\n", name);
  990. Setattr(n, "allegrocl:synonym:already-been-stubbed", "1");
  991. #ifdef ALLEGROCL_WRAP_DEBUG
  992. Printf(stderr, "emit_stub_class: EXIT\n");
  993. #endif
  994. }
  995. void emit_synonym(Node *synonym) {
  996. #ifdef ALLEGROCL_WRAP_DEBUG
  997. Printf(stderr, "emit_synonym: ENTER... \n");
  998. #endif
  999. // Printf(stderr,"in emit_synonym for %s(%x)\n", Getattr(synonym,"name"),synonym);
  1000. int is_tempInst = !Strcmp(nodeType(synonym), "templateInst");
  1001. String *synonym_type;
  1002. Node *of = get_primary_synonym_of(synonym);
  1003. if (is_tempInst) {
  1004. // Printf(stderr, "*** using real-name '%s'\n", Getattr(synonym,"real-name"));
  1005. synonym_type = Getattr(synonym, "real-name");
  1006. } else {
  1007. // Printf(stderr, "*** using name '%s'\n", Getattr(synonym,"name"));
  1008. synonym_type = Getattr(synonym, "name");
  1009. }
  1010. String *synonym_ns = listify_namespace(Getattr(synonym, "allegrocl:namespace"));
  1011. String *syn_ltype, *syn_type, *of_ltype;
  1012. // String *of_cdeclname = Getattr(of,"allegrocl:classDeclarationName");
  1013. String *of_ns = Getattr(of, "allegrocl:namespace");
  1014. String *of_ns_list = listify_namespace(of_ns);
  1015. // String *of_name = of_cdeclname ? NewStringf("struct %s", Getattr(of,"name")) : NewStringf("%s::%s", of_ns, Getattr(of,"sym:name"));
  1016. // String *of_name = NewStringf("%s::%s", of_ns, Getattr(of,"sym:name"));
  1017. String *of_name = namespaced_name(of, of_ns);
  1018. if (CPlusPlus && !Strcmp(nodeType(synonym), "cdecl")) {
  1019. syn_ltype = NewStringf("#.(swig-insert-id \"%s\" %s :type :class)",
  1020. strip_namespaces(Getattr(synonym, "real-name")), synonym_ns);
  1021. syn_type = NewStringf("#.(swig-insert-id \"%s\" %s :type :type)",
  1022. strip_namespaces(Getattr(synonym, "real-name")), synonym_ns);
  1023. } else {
  1024. syn_ltype = lookup_defined_foreign_ltype(synonym_type);
  1025. syn_type = lookup_defined_foreign_type(synonym_type);
  1026. }
  1027. of_ltype = lookup_defined_foreign_ltype(of_name);
  1028. // Printf(stderr,";; from emit-synonym syn='%s' of_ltype='%s'\n", syn_ltype, of_ltype);
  1029. if( of_ltype )
  1030. Printf(f_clhead, "(swig-def-synonym-type %s\n %s\n %s)\n", syn_ltype, of_ltype, syn_type);
  1031. Delete(synonym_ns);
  1032. Delete(of_ns_list);
  1033. Delete(of_name);
  1034. #ifdef ALLEGROCL_WRAP_DEBUG
  1035. Printf(stderr, "emit_synonym: EXIT\n");
  1036. #endif
  1037. }
  1038. void emit_full_class(Node *n) {
  1039. #ifdef ALLEGROCL_WRAP_DEBUG
  1040. Printf(stderr, "emit_full_class: ENTER... \n");
  1041. #endif
  1042. String *name = Getattr(n, "sym:name");
  1043. String *kind = Getattr(n, "kind");
  1044. // Printf(stderr,"in emit_full_class: '%s'(%x).", Getattr(n,"name"),n);
  1045. if (Getattr(n, "allegrocl:synonym-of")) {
  1046. // Printf(stderr,"but it's a synonym of something.\n");
  1047. update_package_if_needed(n, f_clhead);
  1048. emit_synonym(n);
  1049. return;
  1050. }
  1051. // collect superclasses
  1052. String *bases = Getattr(n, "bases");
  1053. String *supers = NewString("(");
  1054. if (bases) {
  1055. int first = 1;
  1056. for (Iterator i = First(bases); i.item; i = Next(i)) {
  1057. if (!first)
  1058. Printf(supers, " ");
  1059. String *s = lookup_defined_foreign_ltype(Getattr(i.item, "name"));
  1060. // String *name = Getattr(i.item,"name");
  1061. if (s) {
  1062. Printf(supers, "%s", s);
  1063. } else {
  1064. #ifdef ALLEGROCL_TYPE_DEBUG
  1065. Printf(stderr, "emit_templ_inst: did not find ltype for base class %s (%s)", Getattr(i.item, "name"), Getattr(n, "allegrocl:namespace"));
  1066. #endif
  1067. }
  1068. }
  1069. } else {
  1070. Printf(supers, "ff:foreign-pointer");
  1071. }
  1072. // check for "feature:aclmixins" and add those as well.
  1073. Printf(supers, " %s)", Getattr(n,"feature:aclmixins"));
  1074. // Walk children to generate type definition.
  1075. String *slotdefs = NewString(" ");
  1076. #ifdef ALLEGROCL_WRAP_DEBUG
  1077. Printf(stderr, " walking children...\n");
  1078. #endif
  1079. Node *c;
  1080. for (c = firstChild(n); c; c = nextSibling(c)) {
  1081. String *storage_type = Getattr(c, "storage");
  1082. if ((!Strcmp(nodeType(c), "cdecl") && (!storage_type || Strcmp(storage_type, "typedef")))) {
  1083. String *access = Getattr(c, "access");
  1084. // hack. why would decl have a value of "variableHandler" and now "0"?
  1085. String *childDecl = Getattr(c, "decl");
  1086. // Printf(stderr,"childDecl = '%s' (%s)\n", childDecl, Getattr(c,"view"));
  1087. if (!Strcmp(childDecl, "0"))
  1088. childDecl = NewString("");
  1089. SwigType *childType;
  1090. String *cname;
  1091. // don't include types for private slots (yet). spr33959.
  1092. if(access && Strcmp(access,"public")) {
  1093. childType = NewStringf("int");
  1094. cname = NewString("nil");
  1095. } else {
  1096. childType = NewStringf("%s%s", childDecl, Getattr(c, "type"));
  1097. cname = Copy(Getattr(c, "name"));
  1098. }
  1099. if (!SwigType_isfunction(childType)) {
  1100. // Printf(slotdefs, ";;; member functions don't appear as slots.\n ");
  1101. // Printf(slotdefs, ";; ");
  1102. String *ns = listify_namespace(Getattr(n, "allegrocl:package"));
  1103. #ifdef ALLEGROCL_WRAP_DEBUG
  1104. Printf(stderr, "slot name = '%s' ns = '%s' class-of '%s' and type = '%s'\n", cname, ns, name, childType);
  1105. #endif
  1106. Printf(slotdefs, "(#.(swig-insert-id \"%s\" %s :type :slot :class \"%s\") %s)", cname, ns, name, compose_foreign_type(n, childType));
  1107. Delete(ns);
  1108. if (access && Strcmp(access, "public"))
  1109. Printf(slotdefs, " ;; %s member", access);
  1110. Printf(slotdefs, "\n ");
  1111. }
  1112. Delete(childType);
  1113. Delete(cname);
  1114. }
  1115. }
  1116. String *ns_list = listify_namespace(Getattr(n, "allegrocl:namespace"));
  1117. update_package_if_needed(n, f_clhead);
  1118. Printf(f_clhead, "(swig-def-foreign-class \"%s\"\n %s\n (:%s\n%s))\n\n", name, supers, kind, slotdefs);
  1119. Delete(supers);
  1120. Delete(ns_list);
  1121. Setattr(n, "allegrocl:synonym:already-been-stubbed", "1");
  1122. #ifdef ALLEGROCL_WRAP_DEBUG
  1123. Printf(stderr, "emit_full_class: EXIT\n");
  1124. #endif
  1125. }
  1126. void emit_class(Node *n) {
  1127. #ifdef ALLEGROCL_WRAP_DEBUG
  1128. Printf(stderr, "emit_class: ENTER... '%s'(%x)\n", Getattr(n, "sym:name"), n);
  1129. #endif
  1130. int is_tempInst = !Strcmp(nodeType(n), "templateInst");
  1131. String *ns_list = listify_namespace(Getattr(n, "allegrocl:namespace"));
  1132. String *name = Getattr(n, is_tempInst ? "real-name" : "name");
  1133. String *tname = SwigType_istemplate_templateprefix(name);
  1134. if (tname) {
  1135. String *temp = strip_namespaces(tname);
  1136. name = NewStringf("%s%s%s", temp, SwigType_templateargs(name), SwigType_templatesuffix(name));
  1137. Delete(temp);
  1138. Delete(tname);
  1139. } else {
  1140. name = strip_namespaces(name);
  1141. }
  1142. if (Getattr(n, "allegrocl:synonym:is-primary")) {
  1143. // Printf(stderr," is primary... ");
  1144. if (is_tempInst) {
  1145. emit_stub_class(n);
  1146. } else {
  1147. emit_full_class(n);
  1148. }
  1149. } else {
  1150. // Node *primary = Getattr(n,"allegrocl:synonym-of");
  1151. Node *primary = get_primary_synonym_of(n);
  1152. if (primary && (primary != n)) {
  1153. // Printf(stderr," emitting synonym... ");
  1154. emit_stub_class(primary);
  1155. update_package_if_needed(n, f_clhead);
  1156. emit_synonym(n);
  1157. } else {
  1158. emit_full_class(n);
  1159. }
  1160. }
  1161. // Printf(stderr,"DONE\n");
  1162. Delete(name);
  1163. Delete(ns_list);
  1164. #ifdef ALLEGROCL_WRAP_DEBUG
  1165. Printf(stderr, "emit_class: EXIT\n");
  1166. #endif
  1167. }
  1168. void emit_typedef(Node *n) {
  1169. #ifdef ALLEGROCL_WRAP_DEBUG
  1170. Printf(stderr, "emit_typedef: ENTER... \n");
  1171. #endif
  1172. String *name;
  1173. String *sym_name = Getattr(n, "sym:name");
  1174. String *type = NewStringf("%s%s", Getattr(n, "decl"), Getattr(n, "type"));
  1175. String *lisp_type = compose_foreign_type(n, type);
  1176. Delete(type);
  1177. Node *in_class = Getattr(n, "allegrocl:typedef:in-class");
  1178. // Printf(stderr,"in emit_typedef: '%s'(%x).",Getattr(n,"name"),n);
  1179. if (Getattr(n, "allegrocl:synonym-of")) {
  1180. // Printf(stderr," but it's a synonym of something.\n");
  1181. emit_synonym(n);
  1182. return;
  1183. }
  1184. if (in_class) {
  1185. String *class_name = Getattr(in_class, "name");
  1186. String *tname = SwigType_istemplate_templateprefix(class_name);
  1187. if (tname) {
  1188. String *temp = strip_namespaces(tname);
  1189. class_name = NewStringf("%s%s%s", temp, SwigType_templateargs(class_name), SwigType_templatesuffix(class_name));
  1190. Delete(temp);
  1191. Delete(tname);
  1192. }
  1193. name = NewStringf("%s__%s", class_name, sym_name);
  1194. Setattr(n, "allegrocl:in-class", in_class);
  1195. } else {
  1196. name = sym_name ? Copy(sym_name) : Copy(Getattr(n, "name"));
  1197. }
  1198. // leave these in for now. might want to change these to def-foreign-class at some point.
  1199. // Printf(f_clhead, ";; %s\n", SwigType_typedef_resolve_all(lisp_type));
  1200. Printf(f_clhead, "(swig-def-foreign-type \"%s\"\n %s)\n", name, lisp_type);
  1201. Delete(name);
  1202. #ifdef ALLEGROCL_WRAP_DEBUG
  1203. Printf(stderr, "emit_typedef: EXIT\n");
  1204. #endif
  1205. }
  1206. void emit_enum_type_no_wrap(Node *n) {
  1207. #ifdef ALLEGROCL_WRAP_DEBUG
  1208. Printf(stderr, "emit_enum_type_no_wrap: ENTER... \n");
  1209. #endif
  1210. String *unnamed = Getattr(n, "unnamed");
  1211. String *name;
  1212. // SwigType *enumtype;
  1213. name = unnamed ? Getattr(n, "allegrocl:name") : Getattr(n, "sym:name");
  1214. SwigType *tmp = NewStringf("enum %s", unnamed ? unnamed : name);
  1215. Node *node = NewHash();
  1216. Setattr(node, "type", tmp);
  1217. Setfile(node, Getfile(n));
  1218. Setline(node, Getline(n));
  1219. const String *enumtype = Swig_typemap_lookup("ffitype", node, "", 0);
  1220. Delete(node);
  1221. Delete(tmp);
  1222. if (name) {
  1223. String *ns = listify_namespace(current_namespace);
  1224. Printf(f_clhead, "(swig-def-foreign-type \"%s\" %s)\n", name, enumtype);
  1225. Delete(ns);
  1226. // walk children.
  1227. Node *c;
  1228. for (c = firstChild(n); c; c = nextSibling(c)) {
  1229. if (!Getattr(c, "error")) {
  1230. String *val = Getattr(c, "enumvalue");
  1231. if (!val)
  1232. val = Getattr(c, "enumvalueex");
  1233. String *converted_val = convert_literal(val, Getattr(c, "type"));
  1234. String *valname = Getattr(c, "sym:name");
  1235. if (converted_val) {
  1236. Printf(f_clhead, "(swig-defconstant \"%s\" %s)\n", valname, converted_val);
  1237. Delete(converted_val);
  1238. } else {
  1239. Swig_warning(WARN_LANG_DISCARD_CONST, Getfile(n), Getline(n), "Unable to parse enum value '%s'. Setting to NIL\n", val);
  1240. Printf(f_clhead, "(swig-defconstant \"%s\" nil #| %s |#)\n", valname, val);
  1241. }
  1242. }
  1243. }
  1244. }
  1245. Printf(f_clhead, "\n");
  1246. #ifdef ALLEGROCL_WRAP_DEBUG
  1247. Printf(stderr, "emit_enum_type_no_wrap: EXIT\n");
  1248. #endif
  1249. }
  1250. void emit_enum_type(Node *n) {
  1251. #ifdef ALLEGROCL_WRAP_DEBUG
  1252. Printf(stderr, "emit_enum_type: ENTER... \n");
  1253. #endif
  1254. if (!Generate_Wrapper) {
  1255. emit_enum_type_no_wrap(n);
  1256. return;
  1257. }
  1258. String *unnamed = Getattr(n, "unnamed");
  1259. String *name;
  1260. // SwigType *enumtype;
  1261. name = unnamed ? Getattr(n, "allegrocl:name") : Getattr(n, "sym:name");
  1262. SwigType *tmp = NewStringf("enum %s", unnamed ? unnamed : name);
  1263. Node *node = NewHash();
  1264. Setattr(node, "type", tmp);
  1265. Setfile(node, Getfile(n));
  1266. Setline(node, Getline(n));
  1267. const String *enumtype = Swig_typemap_lookup("ffitype", node, "", 0);
  1268. Delete(node);
  1269. Delete(tmp);
  1270. if (name) {
  1271. String *ns = listify_namespace(current_namespace);
  1272. Printf(f_clhead, "(swig-def-foreign-type \"%s\" %s)\n", name, enumtype);
  1273. Delete(ns);
  1274. // walk children.
  1275. Node *c;
  1276. for(c = firstChild(n); c; c=nextSibling(c)) {
  1277. String *mangled_name = mangle_name(c, "ACL_ENUM", Getattr(c,"allegrocl:package"));
  1278. Printf(f_clhead, "(swig-defvar \"%s\" \"%s\" :type :constant :ftype :signed-long)\n", Getattr(c, "sym:name"), mangled_name);
  1279. Delete(mangled_name);
  1280. }
  1281. }
  1282. #ifdef ALLEGROCL_WRAP_DEBUG
  1283. Printf(stderr, "emit_enum_type: EXIT\n");
  1284. #endif
  1285. }
  1286. void emit_default_linked_type(Node *n) {
  1287. #ifdef ALLEGROCL_WRAP_DEBUG
  1288. Printf(stderr, "emit_default_linked_type: ENTER... \n");
  1289. #endif
  1290. // catchall for non class types.
  1291. if (!Strcmp(nodeType(n), "classforward")) {
  1292. Printf(f_clhead, ";; forward referenced stub.\n");
  1293. Printf(f_clhead, "(swig-def-foreign-class \"%s\" (ff:foreign-pointer) (:class ))\n\n", Getattr(n, "sym:name"));
  1294. } else if (!Strcmp(nodeType(n), "enum")) {
  1295. emit_enum_type(n);
  1296. } else {
  1297. Printf(stderr, "Don't know how to emit node type '%s' named '%s'\n", nodeType(n), Getattr(n, "name"));
  1298. }
  1299. #ifdef ALLEGROCL_WRAP_DEBUG
  1300. Printf(stderr, "emit_default_linked_type: EXIT\n");
  1301. #endif
  1302. }
  1303. void dump_linked_types(File *f) {
  1304. Node *n = first_linked_type;
  1305. int i = 0;
  1306. while (n) {
  1307. Printf(f, "%d: (%x) node '%s' name '%s'\n", i++, n, nodeType(n), Getattr(n, "sym:name"));
  1308. Node *t = Getattr(n, "allegrocl:synonym-of");
  1309. if (t)
  1310. Printf(f, " synonym-of %s(%x)\n", Getattr(t, "name"), t);
  1311. n = Getattr(n, "allegrocl:next_linked_type");
  1312. }
  1313. }
  1314. void emit_linked_types() {
  1315. #ifdef ALLEGROCL_WRAP_DEBUG
  1316. Printf(stderr, "emit_linked_types: ENTER... ");
  1317. #endif
  1318. Node *n = first_linked_type;
  1319. while (n) {
  1320. String *node_type = nodeType(n);
  1321. // Printf(stderr,"emitting node %s(%x) of type %s.", Getattr(n,"name"),n, nodeType(n));
  1322. if (!Strcmp(node_type, "class") || !Strcmp(node_type, "templateInst")) {
  1323. // may need to emit a stub, so it will update the package itself.
  1324. // Printf(stderr," Passing to emit_class.");
  1325. emit_class(n);
  1326. }

Large files files are truncated, but you can click here to view the full file