PageRenderTime 40ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/rel-1.3.35/Source/Swig/fragment.c

#
C | 181 lines | 143 code | 14 blank | 24 comment | 42 complexity | b588fa6c2628e3713ccfc9b313caaec7 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  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. * fragment.c
  6. *
  7. * This file manages named code fragments. Code fragments are typically
  8. * used to hold helper-code that may or may not be included in the wrapper
  9. * file (depending on what features are actually used in the interface).
  10. *
  11. * By using fragments, it's possible to greatly reduce the amount of
  12. * wrapper code and to generate cleaner wrapper files.
  13. * ----------------------------------------------------------------------------- */
  14. char cvsroot_fragment_c[] = "$Id: fragment.c 9632 2007-01-03 20:58:19Z beazley $";
  15. #include "swig.h"
  16. #include "swigwarn.h"
  17. static Hash *fragments = 0;
  18. static Hash *looking_fragments = 0;
  19. static int debug = 0;
  20. /* -----------------------------------------------------------------------------
  21. * Swig_fragment_register()
  22. *
  23. * Add a fragment. Use the original Node*, so, if something needs to be
  24. * changed, lang.cxx doesn't nedd to be touched again.
  25. * ----------------------------------------------------------------------------- */
  26. void Swig_fragment_register(Node *fragment) {
  27. if (Getattr(fragment, "emitonly")) {
  28. Swig_fragment_emit(fragment);
  29. return;
  30. } else {
  31. String *name = Copy(Getattr(fragment, "value"));
  32. String *type = Getattr(fragment, "type");
  33. if (type) {
  34. SwigType *rtype = SwigType_typedef_resolve_all(type);
  35. String *mangle = Swig_string_mangle(type);
  36. Append(name, mangle);
  37. Delete(mangle);
  38. Delete(rtype);
  39. if (debug)
  40. Printf(stdout, "register fragment %s %s\n", name, type);
  41. }
  42. if (!fragments) {
  43. fragments = NewHash();
  44. }
  45. if (!Getattr(fragments, name)) {
  46. String *section = Copy(Getattr(fragment, "section"));
  47. String *ccode = Copy(Getattr(fragment, "code"));
  48. Hash *kwargs = Getattr(fragment, "kwargs");
  49. Setmeta(ccode, "section", section);
  50. if (kwargs) {
  51. Setmeta(ccode, "kwargs", kwargs);
  52. }
  53. Setattr(fragments, name, ccode);
  54. if (debug)
  55. Printf(stdout, "registering fragment %s %s\n", name, section);
  56. Delete(section);
  57. Delete(ccode);
  58. }
  59. Delete(name);
  60. }
  61. }
  62. /* -----------------------------------------------------------------------------
  63. * Swig_fragment_emit()
  64. *
  65. * Emit a fragment
  66. * ----------------------------------------------------------------------------- */
  67. static
  68. char *char_index(char *str, char c) {
  69. while (*str && (c != *str))
  70. ++str;
  71. return (c == *str) ? str : 0;
  72. }
  73. void Swig_fragment_emit(Node *n) {
  74. String *code;
  75. char *pc, *tok;
  76. String *t;
  77. String *mangle = 0;
  78. String *name = 0;
  79. String *type = 0;
  80. if (!fragments) {
  81. Swig_warning(WARN_FRAGMENT_NOT_FOUND, Getfile(n), Getline(n), "Fragment '%s' not found.\n", name);
  82. return;
  83. }
  84. name = Getattr(n, "value");
  85. if (!name) {
  86. name = n;
  87. }
  88. type = Getattr(n, "type");
  89. if (type) {
  90. mangle = Swig_string_mangle(type);
  91. }
  92. if (debug)
  93. Printf(stdout, "looking fragment %s %s\n", name, type);
  94. t = Copy(name);
  95. tok = Char(t);
  96. pc = char_index(tok, ',');
  97. if (pc)
  98. *pc = 0;
  99. while (tok) {
  100. String *name = NewString(tok);
  101. if (mangle)
  102. Append(name, mangle);
  103. if (looking_fragments && Getattr(looking_fragments, name)) {
  104. return;
  105. }
  106. code = Getattr(fragments, name);
  107. if (debug)
  108. Printf(stdout, "looking subfragment %s\n", name);
  109. if (code && (Strcmp(code, "ignore") != 0)) {
  110. String *section = Getmeta(code, "section");
  111. Hash *nn = Getmeta(code, "kwargs");
  112. if (!looking_fragments)
  113. looking_fragments = NewHash();
  114. Setattr(looking_fragments, name, "1");
  115. while (nn) {
  116. if (Equal(Getattr(nn, "name"), "fragment")) {
  117. if (debug)
  118. Printf(stdout, "emitting fragment %s %s\n", nn, type);
  119. Setfile(nn, Getfile(n));
  120. Setline(nn, Getline(n));
  121. Swig_fragment_emit(nn);
  122. }
  123. nn = nextSibling(nn);
  124. }
  125. if (section) {
  126. File *f = Swig_filebyname(section);
  127. if (!f) {
  128. Swig_error(Getfile(code), Getline(code), "Bad section '%s' for code fragment '%s'\n", section, name);
  129. } else {
  130. if (debug)
  131. Printf(stdout, "emitting subfragment %s %s\n", name, section);
  132. if (debug)
  133. Printf(f, "/* begin fragment %s */\n", name);
  134. Printf(f, "%s\n", code);
  135. if (debug)
  136. Printf(f, "/* end fragment %s */\n\n", name);
  137. Setattr(fragments, name, "ignore");
  138. Delattr(looking_fragments, name);
  139. }
  140. }
  141. } else if (!code && type) {
  142. SwigType *rtype = SwigType_typedef_resolve_all(type);
  143. if (!Equal(type, rtype)) {
  144. String *name = Copy(Getattr(n, "value"));
  145. String *mangle = Swig_string_mangle(type);
  146. Append(name, mangle);
  147. Setfile(name, Getfile(n));
  148. Setline(name, Getline(n));
  149. Swig_fragment_emit(name);
  150. Delete(mangle);
  151. Delete(name);
  152. }
  153. Delete(rtype);
  154. }
  155. if (!code) {
  156. Swig_warning(WARN_FRAGMENT_NOT_FOUND, Getfile(n), Getline(n), "Fragment '%s' not found.\n", name);
  157. }
  158. tok = pc ? pc + 1 : 0;
  159. if (tok) {
  160. pc = char_index(tok, ',');
  161. if (pc)
  162. *pc = 0;
  163. }
  164. Delete(name);
  165. }
  166. Delete(t);
  167. }