/tags/rel-1-3-15/SWIG/Source/Swig/wrapfunc.c

# · C · 308 lines · 205 code · 36 blank · 67 comment · 67 complexity · d64a96e7c9e39527d979e49accda077b MD5 · raw file

  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. static char cvsroot[] = "$Header$";
  17. #include "swig.h"
  18. #include <ctype.h>
  19. /* -----------------------------------------------------------------------------
  20. * NewWrapper()
  21. *
  22. * Create a new wrapper function object.
  23. * ----------------------------------------------------------------------------- */
  24. Wrapper *
  25. NewWrapper() {
  26. Wrapper *w;
  27. w = (Wrapper *) malloc(sizeof(Wrapper));
  28. w->localh = NewHash();
  29. w->locals = NewString("");
  30. w->code = NewString("");
  31. w->def = NewString("");
  32. return w;
  33. }
  34. /* -----------------------------------------------------------------------------
  35. * DelWrapper()
  36. *
  37. * Delete a wrapper function object.
  38. * ----------------------------------------------------------------------------- */
  39. void
  40. DelWrapper(Wrapper *w) {
  41. Delete(w->localh);
  42. Delete(w->locals);
  43. Delete(w->code);
  44. Delete(w->def);
  45. free(w);
  46. }
  47. /* -----------------------------------------------------------------------------
  48. * Wrapper_pretty_print()
  49. *
  50. * Formats a wrapper function and fixes up the indentation.
  51. * ----------------------------------------------------------------------------- */
  52. void
  53. Wrapper_pretty_print(String *str, File *f) {
  54. String *ts;
  55. int level = 0;
  56. int c, i;
  57. int empty = 1;
  58. ts = NewString("");
  59. Seek(str,0, SEEK_SET);
  60. Clear(ts);
  61. while ((c = Getc(str)) != EOF) {
  62. if (c == '\"') {
  63. Putc(c,ts);
  64. while ((c = Getc(str)) != EOF) {
  65. if (c == '\\') {
  66. Putc(c,ts);
  67. c = Getc(str);
  68. }
  69. Putc(c,ts);
  70. if (c == '\"') break;
  71. }
  72. } else if (c == '\'') {
  73. Putc(c,ts);
  74. while ((c = Getc(str)) != EOF) {
  75. if (c == '\\') {
  76. Putc(c,ts);
  77. c = Getc(str);
  78. }
  79. Putc(c,ts);
  80. if (c == '\'') break;
  81. }
  82. } else if (c == '{') {
  83. Putc(c,ts);
  84. Putc('\n',ts);
  85. for (i = 0; i < level; i++)
  86. Putc(' ',f);
  87. Printf(f,"%s", ts);
  88. Clear(ts);
  89. level+=4;
  90. while ((c = Getc(str)) != EOF) {
  91. if (!isspace(c)) {
  92. Ungetc(c,str);
  93. break;
  94. }
  95. }
  96. } else if (c == '}') {
  97. if (!empty) {
  98. Putc('\n',ts);
  99. for (i = 0; i < level; i++)
  100. Putc(' ',f);
  101. Printf(f,"%s",ts);
  102. Clear(ts);
  103. }
  104. level-=4;
  105. Putc(c,ts);
  106. } else if (c == '\n') {
  107. Putc(c,ts);
  108. for (i = 0; i < level; i++)
  109. Putc(' ',f);
  110. Printf(f,"%s",ts);
  111. Clear(ts);
  112. empty = 1;
  113. } else if (c == '/') {
  114. Putc(c,ts);
  115. c = Getc(str);
  116. if (c != EOF) {
  117. Putc(c,ts);
  118. if (c == '/') { /* C++ comment */
  119. while ((c = Getc(str)) != EOF) {
  120. if (c == '\n') {
  121. Ungetc(c,str);
  122. break;
  123. }
  124. Putc(c,ts);
  125. }
  126. } else if (c == '*') { /* C comment */
  127. int endstar = 0;
  128. while ((c = Getc(str)) != EOF) {
  129. if (endstar && c == '/') { /* end of C comment */
  130. Putc(c,ts);
  131. break;
  132. }
  133. endstar = (c == '*');
  134. Putc(c,ts);
  135. if (c == '\n') { /* multi-line C comment. Could be improved slightly. */
  136. for (i = 0; i < level; i++)
  137. Putc(' ',ts);
  138. }
  139. }
  140. }
  141. }
  142. } else {
  143. if (!empty || !isspace(c)) {
  144. Putc(c,ts);
  145. empty = 0;
  146. }
  147. }
  148. }
  149. if (!empty) Printf(f,"%s",ts);
  150. Delete(ts);
  151. Printf(f,"\n");
  152. }
  153. /* -----------------------------------------------------------------------------
  154. * Wrapper_print()
  155. *
  156. * Print out a wrapper function. Does pretty printing as well.
  157. * ----------------------------------------------------------------------------- */
  158. void
  159. Wrapper_print(Wrapper *w, File *f) {
  160. String *str;
  161. str = NewString("");
  162. Printf(str,"%s\n", w->def);
  163. Printf(str,"%s\n", w->locals);
  164. Printf(str,"%s\n", w->code);
  165. Wrapper_pretty_print(str,f);
  166. }
  167. /* -----------------------------------------------------------------------------
  168. * Wrapper_add_local()
  169. *
  170. * Adds a new local variable declaration to a function. Returns -1 if already
  171. * present (which may or may not be okay to the caller).
  172. * ----------------------------------------------------------------------------- */
  173. int
  174. Wrapper_add_local(Wrapper *w, const String_or_char *name, const String_or_char *decl) {
  175. /* See if the local has already been declared */
  176. if (Getattr(w->localh,name)) {
  177. return -1;
  178. }
  179. Setattr(w->localh,name,decl);
  180. Printf(w->locals,"%s;\n", decl);
  181. return 0;
  182. }
  183. /* -----------------------------------------------------------------------------
  184. * Wrapper_add_localv()
  185. *
  186. * Same as add_local(), but allows a NULL terminated list of strings to be
  187. * used as a replacement for decl. This saves the caller the trouble of having
  188. * to manually construct the 'decl' string before calling.
  189. * ----------------------------------------------------------------------------- */
  190. int
  191. Wrapper_add_localv(Wrapper *w, const String_or_char *name, ...) {
  192. va_list ap;
  193. int ret;
  194. String *decl;
  195. DOH *obj;
  196. decl = NewString("");
  197. va_start(ap,name);
  198. obj = va_arg(ap,void *);
  199. while (obj) {
  200. Printv(decl,obj,NIL);
  201. Putc(' ', decl);
  202. obj = va_arg(ap, void *);
  203. }
  204. va_end(ap);
  205. ret = Wrapper_add_local(w,name,decl);
  206. Delete(decl);
  207. return ret;
  208. }
  209. /* -----------------------------------------------------------------------------
  210. * Wrapper_check_local()
  211. *
  212. * Check to see if a local name has already been declared
  213. * ----------------------------------------------------------------------------- */
  214. int
  215. Wrapper_check_local(Wrapper *w, const String_or_char *name) {
  216. if (Getattr(w->localh,name)) {
  217. return 1;
  218. }
  219. return 0;
  220. }
  221. /* -----------------------------------------------------------------------------
  222. * Wrapper_new_local()
  223. *
  224. * Adds a new local variable with a guarantee that a unique local name will be
  225. * used. Returns the name that was actually selected.
  226. * ----------------------------------------------------------------------------- */
  227. char *
  228. Wrapper_new_local(Wrapper *w, const String_or_char *name, const String_or_char *decl) {
  229. int i;
  230. String *nname = NewString(name);
  231. String *ndecl = NewString(decl);
  232. char *ret;
  233. i = 0;
  234. while (Wrapper_check_local(w,nname)) {
  235. Clear(nname);
  236. Printf(nname,"%s%d",name,i);
  237. i++;
  238. }
  239. Replace(ndecl, name, nname, DOH_REPLACE_ID);
  240. Setattr(w->localh,nname,ndecl);
  241. Printf(w->locals,"%s;\n", ndecl);
  242. ret = Char(nname);
  243. Delete(nname);
  244. Delete(ndecl);
  245. return ret; /* Note: nname should still exists in the w->localh hash */
  246. }
  247. /* -----------------------------------------------------------------------------
  248. * Wrapper_add_localv()
  249. *
  250. * Same as add_local(), but allows a NULL terminated list of strings to be
  251. * used as a replacement for decl. This saves the caller the trouble of having
  252. * to manually construct the 'decl' string before calling.
  253. * ----------------------------------------------------------------------------- */
  254. char *
  255. Wrapper_new_localv(Wrapper *w, const String_or_char *name, ...) {
  256. va_list ap;
  257. char *ret;
  258. String *decl;
  259. DOH *obj;
  260. decl = NewString("");
  261. va_start(ap,name);
  262. obj = va_arg(ap,void *);
  263. while (obj) {
  264. Printv(decl,obj,NIL);
  265. Putc(' ',decl);
  266. obj = va_arg(ap, void *);
  267. }
  268. va_end(ap);
  269. ret = Wrapper_new_local(w,name,decl);
  270. Delete(decl);
  271. return ret;
  272. }