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

/trunk/Source/Swig/fragment.c

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