PageRenderTime 39ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/CableSwig-3.20.0/SWIG/Source/Swig/wrapfunc.c

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