/tools/SWIG-1.3.29/Source/Swig/wrapfunc.c

https://github.com/nmacherey/rheia · C · 528 lines · 411 code · 44 blank · 73 comment · 193 complexity · 960ac1f664348cdd01b83b95105b2b70 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[] = "$Header: /cvsroot/swig/SWIG/Source/Swig/wrapfunc.c,v 1.32 2006/03/06 22:51:01 wsfulton Exp $";
  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 *
  22. NewWrapper() {
  23. Wrapper *w;
  24. w = (Wrapper *) malloc(sizeof(Wrapper));
  25. w->localh = NewHash();
  26. w->locals = NewStringEmpty();
  27. w->code = NewStringEmpty();
  28. w->def = NewStringEmpty();
  29. return w;
  30. }
  31. /* -----------------------------------------------------------------------------
  32. * DelWrapper()
  33. *
  34. * Delete a wrapper function object.
  35. * ----------------------------------------------------------------------------- */
  36. void
  37. DelWrapper(Wrapper *w) {
  38. Delete(w->localh);
  39. Delete(w->locals);
  40. Delete(w->code);
  41. Delete(w->def);
  42. free(w);
  43. }
  44. /* -----------------------------------------------------------------------------
  45. * Wrapper_compact_print_mode_set()
  46. *
  47. * Set compact_mode.
  48. * ----------------------------------------------------------------------------- */
  49. void
  50. Wrapper_compact_print_mode_set(int flag) {
  51. Compact_mode = flag;
  52. }
  53. /* -----------------------------------------------------------------------------
  54. * Wrapper_pretty_print()
  55. *
  56. * Formats a wrapper function and fixes up the indentation.
  57. * ----------------------------------------------------------------------------- */
  58. void
  59. Wrapper_pretty_print(String *str, File *f) {
  60. String *ts;
  61. int level = 0;
  62. int c, i;
  63. int empty = 1;
  64. int indent = 2;
  65. int plevel = 0;
  66. int label = 0;
  67. ts = NewStringEmpty();
  68. Seek(str,0, SEEK_SET);
  69. while ((c = Getc(str)) != EOF) {
  70. if (c == '\"') {
  71. Putc(c,ts);
  72. while ((c = Getc(str)) != EOF) {
  73. if (c == '\\') {
  74. Putc(c,ts);
  75. c = Getc(str);
  76. }
  77. Putc(c,ts);
  78. if (c == '\"') break;
  79. }
  80. empty = 0;
  81. } else if (c == '\'') {
  82. Putc(c,ts);
  83. while ((c = Getc(str)) != EOF) {
  84. if (c == '\\') {
  85. Putc(c,ts);
  86. c = Getc(str);
  87. }
  88. Putc(c,ts);
  89. if (c == '\'') break;
  90. }
  91. empty = 0;
  92. } else if (c == ':') {
  93. Putc(c,ts);
  94. if ((c = Getc(str)) == '\n') {
  95. if (!empty && !strstr(Char(ts),"?")) label = 1;
  96. }
  97. Ungetc(c,str);
  98. } else if (c == '(') {
  99. Putc(c,ts);
  100. plevel+=indent;
  101. empty = 0;
  102. } else if (c == ')') {
  103. Putc(c,ts);
  104. plevel-=indent;
  105. empty = 0;
  106. } else if (c == '{') {
  107. Putc(c,ts);
  108. Putc('\n',ts);
  109. for (i = 0; i < level; i++)
  110. Putc(' ',f);
  111. Printf(f,"%s", ts);
  112. Clear(ts);
  113. level+=indent;
  114. while ((c = Getc(str)) != EOF) {
  115. if (!isspace(c)) {
  116. Ungetc(c,str);
  117. break;
  118. }
  119. }
  120. empty = 0;
  121. } else if (c == '}') {
  122. if (!empty) {
  123. Putc('\n',ts);
  124. for (i = 0; i < level; i++)
  125. Putc(' ',f);
  126. Printf(f,"%s",ts);
  127. Clear(ts);
  128. }
  129. level-=indent;
  130. Putc(c,ts);
  131. empty = 0;
  132. } else if (c == '\n') {
  133. Putc(c,ts);
  134. empty = 0;
  135. if (!empty) {
  136. int slevel = level;
  137. if (label && (slevel >= indent)) 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) Printf(f,"%s",ts);
  187. Delete(ts);
  188. Printf(f,"\n");
  189. }
  190. /* -----------------------------------------------------------------------------
  191. * Wrapper_compact_print()
  192. *
  193. * Formats a wrapper function and fixes up the indentation.
  194. * Print out in compact format, with Compact enabled.
  195. * ----------------------------------------------------------------------------- */
  196. void
  197. 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 == '\"') break;
  217. }
  218. } else if (c == '\'') { /* string 2 */
  219. empty = 0;
  220. Putc(c,ts);
  221. while ((c = Getc(str)) != EOF) {
  222. if (c == '\\') {
  223. Putc(c,ts);
  224. c = Getc(str);
  225. }
  226. Putc(c,ts);
  227. if (c == '\'') break;
  228. }
  229. } else if (c == '{') { /* start of {...} */
  230. empty = 0;
  231. Putc(c,ts);
  232. if (Len(tf) == 0) {
  233. for (i = 0; i < level; i++)
  234. Putc(' ',tf);
  235. } else if ((Len(tf) + Len(ts)) < Max_line_size) {
  236. Putc(' ',tf);
  237. } else {
  238. Putc('\n',tf);
  239. Printf(f,"%s", tf);
  240. Clear(tf);
  241. for (i = 0; i < level; i++)
  242. Putc(' ',tf);
  243. }
  244. Append(tf,ts);
  245. Clear(ts);
  246. level+=indent;
  247. while ((c = Getc(str)) != EOF) {
  248. if (!isspace(c)) {
  249. Ungetc(c,str);
  250. break;
  251. }
  252. }
  253. } else if (c == '}') { /* end of {...} */
  254. empty = 0;
  255. if (Len(tf) == 0) {
  256. for (i = 0; i < level; i++)
  257. Putc(' ',tf);
  258. } else if ((Len(tf) + Len(ts)) < Max_line_size) {
  259. Putc(' ',tf);
  260. } else {
  261. Putc('\n',tf);
  262. Printf(f,"%s", tf);
  263. Clear(tf);
  264. for (i = 0; i < level; i++)
  265. Putc(' ',tf);
  266. }
  267. Append(tf, ts);
  268. Putc(c, tf);
  269. Clear(ts);
  270. level-=indent;
  271. } else if (c == '\n') { /* line end */
  272. while ((c = Getc(str)) != EOF) {
  273. if (!isspace(c))
  274. break;
  275. }
  276. if (c == '#'){
  277. Putc('\n',ts);
  278. } else if (c == '}') {
  279. Putc(' ',ts);
  280. } else if ( (c != EOF) || (Len(ts)!=0) ){
  281. if (Len(tf) == 0) {
  282. for (i = 0; i < level; i++)
  283. Putc(' ',tf);
  284. } else if ((Len(tf) + Len(ts)) < Max_line_size) {
  285. Putc(' ',tf);
  286. } else {
  287. Putc('\n',tf);
  288. Printf(f,"%s", tf);
  289. Clear(tf);
  290. for (i = 0; i < level; i++)
  291. Putc(' ',tf);
  292. }
  293. Append(tf,ts);
  294. Clear(ts);
  295. }
  296. Ungetc(c,str);
  297. empty = 1;
  298. } else if (c == '/') { /* comment */
  299. empty = 0;
  300. c = Getc(str);
  301. if (c != EOF) {
  302. if (c == '/') { /* C++ comment */
  303. while ((c = Getc(str)) != EOF) {
  304. if (c == '\n') {
  305. Ungetc(c,str);
  306. break;
  307. }
  308. }
  309. } else if (c == '*') { /* C comment */
  310. int endstar = 0;
  311. while ((c = Getc(str)) != EOF) {
  312. if (endstar && c == '/') { /* end of C comment */
  313. break;
  314. }
  315. endstar = (c == '*');
  316. }
  317. } else {
  318. Putc('/',ts);
  319. Putc(c,ts);
  320. }
  321. }
  322. } else if (c == '#') { /* Preprocessor line */
  323. Putc('#', ts);
  324. while ((c = Getc(str)) != EOF) {
  325. Putc(c, ts);
  326. if (c == '\\') { /* Continued line of the same PP */
  327. c = Getc(str);
  328. if (c == '\n')
  329. Putc(c, ts);
  330. else
  331. Ungetc(c, str);
  332. } else if (c == '\n')
  333. break;
  334. }
  335. if (!empty) {
  336. Append(tf,"\n");
  337. }
  338. Append(tf,ts);
  339. Printf(f, "%s", tf);
  340. Clear(tf);
  341. Clear(ts);
  342. for (i = 0; i < level; i++)
  343. Putc(' ',tf);
  344. empty = 1;
  345. } else {
  346. if (!empty || !isspace(c)) {
  347. Putc(c,ts);
  348. empty = 0;
  349. }
  350. }
  351. }
  352. if (!empty) {
  353. Append(tf,ts);
  354. }
  355. if (Len(tf) != 0)
  356. Printf(f,"%s",tf);
  357. Delete(ts);
  358. Delete(tf);
  359. Printf(f,"\n");
  360. }
  361. /* -----------------------------------------------------------------------------
  362. * Wrapper_print()
  363. *
  364. * Print out a wrapper function. Does pretty or compact printing as well.
  365. * ----------------------------------------------------------------------------- */
  366. void
  367. Wrapper_print(Wrapper *w, File *f) {
  368. String *str;
  369. str = NewStringEmpty();
  370. Printf(str,"%s\n", w->def);
  371. Printf(str,"%s\n", w->locals);
  372. Printf(str,"%s\n", w->code);
  373. if (Compact_mode == 1)
  374. Wrapper_compact_print(str,f);
  375. else
  376. Wrapper_pretty_print(str,f);
  377. Delete(str);
  378. }
  379. /* -----------------------------------------------------------------------------
  380. * Wrapper_add_local()
  381. *
  382. * Adds a new local variable declaration to a function. Returns -1 if already
  383. * present (which may or may not be okay to the caller).
  384. * ----------------------------------------------------------------------------- */
  385. int
  386. 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
  403. Wrapper_add_localv(Wrapper *w, const String_or_char *name, ...) {
  404. va_list ap;
  405. int ret;
  406. String *decl;
  407. DOH *obj;
  408. decl = NewStringEmpty();
  409. va_start(ap,name);
  410. obj = va_arg(ap,void *);
  411. while (obj) {
  412. Append(decl,obj);
  413. Putc(' ', decl);
  414. obj = va_arg(ap, void *);
  415. }
  416. va_end(ap);
  417. ret = Wrapper_add_local(w,name,decl);
  418. Delete(decl);
  419. return ret;
  420. }
  421. /* -----------------------------------------------------------------------------
  422. * Wrapper_check_local()
  423. *
  424. * Check to see if a local name has already been declared
  425. * ----------------------------------------------------------------------------- */
  426. int
  427. Wrapper_check_local(Wrapper *w, const String_or_char *name) {
  428. if (Getattr(w->localh,name)) {
  429. return 1;
  430. }
  431. return 0;
  432. }
  433. /* -----------------------------------------------------------------------------
  434. * Wrapper_new_local()
  435. *
  436. * Adds a new local variable with a guarantee that a unique local name will be
  437. * used. Returns the name that was actually selected.
  438. * ----------------------------------------------------------------------------- */
  439. char *
  440. Wrapper_new_local(Wrapper *w, const String_or_char *name, const String_or_char *decl) {
  441. int i;
  442. String *nname = NewString(name);
  443. String *ndecl = NewString(decl);
  444. char *ret;
  445. i = 0;
  446. while (Wrapper_check_local(w,nname)) {
  447. Clear(nname);
  448. Printf(nname,"%s%d",name,i);
  449. i++;
  450. }
  451. Replace(ndecl, name, nname, DOH_REPLACE_ID);
  452. Setattr(w->localh,nname,ndecl);
  453. Printf(w->locals,"%s;\n", ndecl);
  454. ret = Char(nname);
  455. Delete(nname);
  456. Delete(ndecl);
  457. return ret; /* Note: nname should still exists in the w->localh hash */
  458. }
  459. /* -----------------------------------------------------------------------------
  460. * Wrapper_add_localv()
  461. *
  462. * Same as add_local(), but allows a NULL terminated list of strings to be
  463. * used as a replacement for decl. This saves the caller the trouble of having
  464. * to manually construct the 'decl' string before calling.
  465. * ----------------------------------------------------------------------------- */
  466. char *
  467. Wrapper_new_localv(Wrapper *w, const String_or_char *name, ...) {
  468. va_list ap;
  469. char *ret;
  470. String *decl;
  471. DOH *obj;
  472. decl = NewStringEmpty();
  473. va_start(ap,name);
  474. obj = va_arg(ap,void *);
  475. while (obj) {
  476. Append(decl,obj);
  477. Putc(' ',decl);
  478. obj = va_arg(ap, void *);
  479. }
  480. va_end(ap);
  481. ret = Wrapper_new_local(w,name,decl);
  482. Delete(decl);
  483. return ret;
  484. }