/Angel-v2.2/Code-vc9/Tools/swigwin-1.3.36/Source/Swig/wrapfunc.c

https://github.com/chrishaukap/GameDev · C · 518 lines · 407 code · 38 blank · 73 comment · 194 complexity · 820efaf456026ef080bab5da3ce0b5c1 MD5 · raw 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. * wrapfunc.c
  6. *
  7. * This file defines a object for creating wrapper functions. Primarily
  8. * this is used for convenience since it allows pieces of a wrapper function
  9. * to be created in a piecemeal manner.
  10. * ----------------------------------------------------------------------------- */
  11. char cvsroot_wrapfunc_c[] = "$Id: wrapfunc.c 9641 2007-01-16 04:50:43Z beazley $";
  12. #include "swig.h"
  13. #include <ctype.h>
  14. static int Compact_mode = 0; /* set to 0 on default */
  15. static int Max_line_size = 128;
  16. /* -----------------------------------------------------------------------------
  17. * NewWrapper()
  18. *
  19. * Create a new wrapper function object.
  20. * ----------------------------------------------------------------------------- */
  21. Wrapper *NewWrapper() {
  22. Wrapper *w;
  23. w = (Wrapper *) malloc(sizeof(Wrapper));
  24. w->localh = NewHash();
  25. w->locals = NewStringEmpty();
  26. w->code = NewStringEmpty();
  27. w->def = NewStringEmpty();
  28. return w;
  29. }
  30. /* -----------------------------------------------------------------------------
  31. * DelWrapper()
  32. *
  33. * Delete a wrapper function object.
  34. * ----------------------------------------------------------------------------- */
  35. void DelWrapper(Wrapper *w) {
  36. Delete(w->localh);
  37. Delete(w->locals);
  38. Delete(w->code);
  39. Delete(w->def);
  40. free(w);
  41. }
  42. /* -----------------------------------------------------------------------------
  43. * Wrapper_compact_print_mode_set()
  44. *
  45. * Set compact_mode.
  46. * ----------------------------------------------------------------------------- */
  47. void Wrapper_compact_print_mode_set(int flag) {
  48. Compact_mode = flag;
  49. }
  50. /* -----------------------------------------------------------------------------
  51. * Wrapper_pretty_print()
  52. *
  53. * Formats a wrapper function and fixes up the indentation.
  54. * ----------------------------------------------------------------------------- */
  55. void Wrapper_pretty_print(String *str, File *f) {
  56. String *ts;
  57. int level = 0;
  58. int c, i;
  59. int empty = 1;
  60. int indent = 2;
  61. int plevel = 0;
  62. int label = 0;
  63. ts = NewStringEmpty();
  64. Seek(str, 0, SEEK_SET);
  65. while ((c = Getc(str)) != EOF) {
  66. if (c == '\"') {
  67. Putc(c, ts);
  68. while ((c = Getc(str)) != EOF) {
  69. if (c == '\\') {
  70. Putc(c, ts);
  71. c = Getc(str);
  72. }
  73. Putc(c, ts);
  74. if (c == '\"')
  75. break;
  76. }
  77. empty = 0;
  78. } else if (c == '\'') {
  79. Putc(c, ts);
  80. while ((c = Getc(str)) != EOF) {
  81. if (c == '\\') {
  82. Putc(c, ts);
  83. c = Getc(str);
  84. }
  85. Putc(c, ts);
  86. if (c == '\'')
  87. break;
  88. }
  89. empty = 0;
  90. } else if (c == ':') {
  91. Putc(c, ts);
  92. if ((c = Getc(str)) == '\n') {
  93. if (!empty && !strchr(Char(ts), '?'))
  94. label = 1;
  95. }
  96. Ungetc(c, str);
  97. } else if (c == '(') {
  98. Putc(c, ts);
  99. plevel += indent;
  100. empty = 0;
  101. } else if (c == ')') {
  102. Putc(c, ts);
  103. plevel -= indent;
  104. empty = 0;
  105. } else if (c == '{') {
  106. Putc(c, ts);
  107. Putc('\n', ts);
  108. for (i = 0; i < level; i++)
  109. Putc(' ', f);
  110. Printf(f, "%s", ts);
  111. Clear(ts);
  112. level += indent;
  113. while ((c = Getc(str)) != EOF) {
  114. if (!isspace(c)) {
  115. Ungetc(c, str);
  116. break;
  117. }
  118. }
  119. empty = 0;
  120. } else if (c == '}') {
  121. if (!empty) {
  122. Putc('\n', ts);
  123. for (i = 0; i < level; i++)
  124. Putc(' ', f);
  125. Printf(f, "%s", ts);
  126. Clear(ts);
  127. }
  128. level -= indent;
  129. Putc(c, ts);
  130. empty = 0;
  131. } else if (c == '\n') {
  132. Putc(c, ts);
  133. empty = 0;
  134. if (!empty) {
  135. int slevel = level;
  136. if (label && (slevel >= indent))
  137. slevel -= indent;
  138. if ((Char(ts))[0] != '#') {
  139. for (i = 0; i < slevel; i++)
  140. Putc(' ', f);
  141. }
  142. Printf(f, "%s", ts);
  143. for (i = 0; i < plevel; i++)
  144. Putc(' ', f);
  145. }
  146. Clear(ts);
  147. label = 0;
  148. empty = 1;
  149. } else if (c == '/') {
  150. empty = 0;
  151. Putc(c, ts);
  152. c = Getc(str);
  153. if (c != EOF) {
  154. Putc(c, ts);
  155. if (c == '/') { /* C++ comment */
  156. while ((c = Getc(str)) != EOF) {
  157. if (c == '\n') {
  158. Ungetc(c, str);
  159. break;
  160. }
  161. Putc(c, ts);
  162. }
  163. } else if (c == '*') { /* C comment */
  164. int endstar = 0;
  165. while ((c = Getc(str)) != EOF) {
  166. if (endstar && c == '/') { /* end of C comment */
  167. Putc(c, ts);
  168. break;
  169. }
  170. endstar = (c == '*');
  171. Putc(c, ts);
  172. if (c == '\n') { /* multi-line C comment. Could be improved slightly. */
  173. for (i = 0; i < level; i++)
  174. Putc(' ', ts);
  175. }
  176. }
  177. }
  178. }
  179. } else {
  180. if (!empty || !isspace(c)) {
  181. Putc(c, ts);
  182. empty = 0;
  183. }
  184. }
  185. }
  186. if (!empty)
  187. Printf(f, "%s", ts);
  188. Delete(ts);
  189. Printf(f, "\n");
  190. }
  191. /* -----------------------------------------------------------------------------
  192. * Wrapper_compact_print()
  193. *
  194. * Formats a wrapper function and fixes up the indentation.
  195. * Print out in compact format, with Compact enabled.
  196. * ----------------------------------------------------------------------------- */
  197. void Wrapper_compact_print(String *str, File *f) {
  198. String *ts, *tf; /*temp string & temp file */
  199. int level = 0;
  200. int c, i;
  201. int empty = 1;
  202. int indent = 2;
  203. ts = NewStringEmpty();
  204. tf = NewStringEmpty();
  205. Seek(str, 0, SEEK_SET);
  206. while ((c = Getc(str)) != EOF) {
  207. if (c == '\"') { /* string 1 */
  208. empty = 0;
  209. Putc(c, ts);
  210. while ((c = Getc(str)) != EOF) {
  211. if (c == '\\') {
  212. Putc(c, ts);
  213. c = Getc(str);
  214. }
  215. Putc(c, ts);
  216. if (c == '\"')
  217. break;
  218. }
  219. } else if (c == '\'') { /* string 2 */
  220. empty = 0;
  221. Putc(c, ts);
  222. while ((c = Getc(str)) != EOF) {
  223. if (c == '\\') {
  224. Putc(c, ts);
  225. c = Getc(str);
  226. }
  227. Putc(c, ts);
  228. if (c == '\'')
  229. break;
  230. }
  231. } else if (c == '{') { /* start of {...} */
  232. empty = 0;
  233. Putc(c, ts);
  234. if (Len(tf) == 0) {
  235. for (i = 0; i < level; i++)
  236. Putc(' ', tf);
  237. } else if ((Len(tf) + Len(ts)) < Max_line_size) {
  238. Putc(' ', tf);
  239. } else {
  240. Putc('\n', tf);
  241. Printf(f, "%s", tf);
  242. Clear(tf);
  243. for (i = 0; i < level; i++)
  244. Putc(' ', tf);
  245. }
  246. Append(tf, ts);
  247. Clear(ts);
  248. level += indent;
  249. while ((c = Getc(str)) != EOF) {
  250. if (!isspace(c)) {
  251. Ungetc(c, str);
  252. break;
  253. }
  254. }
  255. } else if (c == '}') { /* end of {...} */
  256. empty = 0;
  257. if (Len(tf) == 0) {
  258. for (i = 0; i < level; i++)
  259. Putc(' ', tf);
  260. } else if ((Len(tf) + Len(ts)) < Max_line_size) {
  261. Putc(' ', tf);
  262. } else {
  263. Putc('\n', tf);
  264. Printf(f, "%s", tf);
  265. Clear(tf);
  266. for (i = 0; i < level; i++)
  267. Putc(' ', tf);
  268. }
  269. Append(tf, ts);
  270. Putc(c, tf);
  271. Clear(ts);
  272. level -= indent;
  273. } else if (c == '\n') { /* line end */
  274. while ((c = Getc(str)) != EOF) {
  275. if (!isspace(c))
  276. break;
  277. }
  278. if (c == '#') {
  279. Putc('\n', ts);
  280. } else if (c == '}') {
  281. Putc(' ', ts);
  282. } else if ((c != EOF) || (Len(ts) != 0)) {
  283. if (Len(tf) == 0) {
  284. for (i = 0; i < level; i++)
  285. Putc(' ', tf);
  286. } else if ((Len(tf) + Len(ts)) < Max_line_size) {
  287. Putc(' ', tf);
  288. } else {
  289. Putc('\n', tf);
  290. Printf(f, "%s", tf);
  291. Clear(tf);
  292. for (i = 0; i < level; i++)
  293. Putc(' ', tf);
  294. }
  295. Append(tf, ts);
  296. Clear(ts);
  297. }
  298. Ungetc(c, str);
  299. empty = 1;
  300. } else if (c == '/') { /* comment */
  301. empty = 0;
  302. c = Getc(str);
  303. if (c != EOF) {
  304. if (c == '/') { /* C++ comment */
  305. while ((c = Getc(str)) != EOF) {
  306. if (c == '\n') {
  307. Ungetc(c, str);
  308. break;
  309. }
  310. }
  311. } else if (c == '*') { /* C comment */
  312. int endstar = 0;
  313. while ((c = Getc(str)) != EOF) {
  314. if (endstar && c == '/') { /* end of C comment */
  315. break;
  316. }
  317. endstar = (c == '*');
  318. }
  319. } else {
  320. Putc('/', ts);
  321. Putc(c, ts);
  322. }
  323. }
  324. } else if (c == '#') { /* Preprocessor line */
  325. Putc('#', ts);
  326. while ((c = Getc(str)) != EOF) {
  327. Putc(c, ts);
  328. if (c == '\\') { /* Continued line of the same PP */
  329. c = Getc(str);
  330. if (c == '\n')
  331. Putc(c, ts);
  332. else
  333. Ungetc(c, str);
  334. } else if (c == '\n')
  335. break;
  336. }
  337. if (!empty) {
  338. Append(tf, "\n");
  339. }
  340. Append(tf, ts);
  341. Printf(f, "%s", tf);
  342. Clear(tf);
  343. Clear(ts);
  344. for (i = 0; i < level; i++)
  345. Putc(' ', tf);
  346. empty = 1;
  347. } else {
  348. if (!empty || !isspace(c)) {
  349. Putc(c, ts);
  350. empty = 0;
  351. }
  352. }
  353. }
  354. if (!empty) {
  355. Append(tf, ts);
  356. }
  357. if (Len(tf) != 0)
  358. Printf(f, "%s", tf);
  359. Delete(ts);
  360. Delete(tf);
  361. Printf(f, "\n");
  362. }
  363. /* -----------------------------------------------------------------------------
  364. * Wrapper_print()
  365. *
  366. * Print out a wrapper function. Does pretty or compact printing as well.
  367. * ----------------------------------------------------------------------------- */
  368. void Wrapper_print(Wrapper *w, File *f) {
  369. String *str;
  370. str = NewStringEmpty();
  371. Printf(str, "%s\n", w->def);
  372. Printf(str, "%s\n", w->locals);
  373. Printf(str, "%s\n", w->code);
  374. if (Compact_mode == 1)
  375. Wrapper_compact_print(str, f);
  376. else
  377. Wrapper_pretty_print(str, f);
  378. Delete(str);
  379. }
  380. /* -----------------------------------------------------------------------------
  381. * Wrapper_add_local()
  382. *
  383. * Adds a new local variable declaration to a function. Returns -1 if already
  384. * present (which may or may not be okay to the caller).
  385. * ----------------------------------------------------------------------------- */
  386. int Wrapper_add_local(Wrapper *w, const String_or_char *name, const String_or_char *decl) {
  387. /* See if the local has already been declared */
  388. if (Getattr(w->localh, name)) {
  389. return -1;
  390. }
  391. Setattr(w->localh, name, decl);
  392. Printf(w->locals, "%s;\n", decl);
  393. return 0;
  394. }
  395. /* -----------------------------------------------------------------------------
  396. * Wrapper_add_localv()
  397. *
  398. * Same as add_local(), but allows a NULL terminated list of strings to be
  399. * used as a replacement for decl. This saves the caller the trouble of having
  400. * to manually construct the 'decl' string before calling.
  401. * ----------------------------------------------------------------------------- */
  402. int Wrapper_add_localv(Wrapper *w, const String_or_char *name, ...) {
  403. va_list ap;
  404. int ret;
  405. String *decl;
  406. DOH *obj;
  407. decl = NewStringEmpty();
  408. va_start(ap, name);
  409. obj = va_arg(ap, void *);
  410. while (obj) {
  411. Append(decl, obj);
  412. Putc(' ', decl);
  413. obj = va_arg(ap, void *);
  414. }
  415. va_end(ap);
  416. ret = Wrapper_add_local(w, name, decl);
  417. Delete(decl);
  418. return ret;
  419. }
  420. /* -----------------------------------------------------------------------------
  421. * Wrapper_check_local()
  422. *
  423. * Check to see if a local name has already been declared
  424. * ----------------------------------------------------------------------------- */
  425. int Wrapper_check_local(Wrapper *w, const String_or_char *name) {
  426. if (Getattr(w->localh, name)) {
  427. return 1;
  428. }
  429. return 0;
  430. }
  431. /* -----------------------------------------------------------------------------
  432. * Wrapper_new_local()
  433. *
  434. * Adds a new local variable with a guarantee that a unique local name will be
  435. * used. Returns the name that was actually selected.
  436. * ----------------------------------------------------------------------------- */
  437. char *Wrapper_new_local(Wrapper *w, const String_or_char *name, const String_or_char *decl) {
  438. int i;
  439. String *nname = NewString(name);
  440. String *ndecl = NewString(decl);
  441. char *ret;
  442. i = 0;
  443. while (Wrapper_check_local(w, nname)) {
  444. Clear(nname);
  445. Printf(nname, "%s%d", name, i);
  446. i++;
  447. }
  448. Replace(ndecl, name, nname, DOH_REPLACE_ID);
  449. Setattr(w->localh, nname, ndecl);
  450. Printf(w->locals, "%s;\n", ndecl);
  451. ret = Char(nname);
  452. Delete(nname);
  453. Delete(ndecl);
  454. return ret; /* Note: nname should still exists in the w->localh hash */
  455. }
  456. /* -----------------------------------------------------------------------------
  457. * Wrapper_new_localv()
  458. *
  459. * Same as add_local(), but allows a NULL terminated list of strings to be
  460. * used as a replacement for decl. This saves the caller the trouble of having
  461. * to manually construct the 'decl' string before calling.
  462. * ----------------------------------------------------------------------------- */
  463. char *Wrapper_new_localv(Wrapper *w, const String_or_char *name, ...) {
  464. va_list ap;
  465. char *ret;
  466. String *decl;
  467. DOH *obj;
  468. decl = NewStringEmpty();
  469. va_start(ap, name);
  470. obj = va_arg(ap, void *);
  471. while (obj) {
  472. Append(decl, obj);
  473. Putc(' ', decl);
  474. obj = va_arg(ap, void *);
  475. }
  476. va_end(ap);
  477. ret = Wrapper_new_local(w, name, decl);
  478. Delete(decl);
  479. return ret;
  480. }