/branches/closed/matlab-branch/Source/Modules/allegrocl.cxx

# · C++ · 2053 lines · 1528 code · 278 blank · 247 comment · 422 complexity · 24048bb528dceab98507415ed6250852 MD5 · raw file

Large files are truncated click here to view the full file

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