PageRenderTime 32ms CodeModel.GetById 4ms app.highlight 11ms 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
 15char cvsroot_fragment_c[] = "$Id: fragment.c 9632 2007-01-03 20:58:19Z beazley $";
 16
 17#include "swig.h"
 18#include "swigwarn.h"
 19
 20static Hash *fragments = 0;
 21static Hash *looking_fragments = 0;
 22static int debug = 0;
 23
 24
 25/* -----------------------------------------------------------------------------
 26 * Swig_fragment_register()
 27 *
 28 * Add a fragment. Use the original Node*, so, if something needs to be
 29 * changed, lang.cxx doesn't nedd to be touched again.
 30 * ----------------------------------------------------------------------------- */
 31
 32void Swig_fragment_register(Node *fragment) {
 33  if (Getattr(fragment, "emitonly")) {
 34    Swig_fragment_emit(fragment);
 35    return;
 36  } else {
 37    String *name = Copy(Getattr(fragment, "value"));
 38    String *type = Getattr(fragment, "type");
 39    if (type) {
 40      SwigType *rtype = SwigType_typedef_resolve_all(type);
 41      String *mangle = Swig_string_mangle(type);
 42      Append(name, mangle);
 43      Delete(mangle);
 44      Delete(rtype);
 45      if (debug)
 46	Printf(stdout, "register fragment %s %s\n", name, type);
 47    }
 48    if (!fragments) {
 49      fragments = NewHash();
 50    }
 51    if (!Getattr(fragments, name)) {
 52      String *section = Copy(Getattr(fragment, "section"));
 53      String *ccode = Copy(Getattr(fragment, "code"));
 54      Hash *kwargs = Getattr(fragment, "kwargs");
 55      Setmeta(ccode, "section", section);
 56      if (kwargs) {
 57	Setmeta(ccode, "kwargs", kwargs);
 58      }
 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/* -----------------------------------------------------------------------------
 70 * Swig_fragment_emit()
 71 *
 72 * Emit a fragment
 73 * ----------------------------------------------------------------------------- */
 74
 75static
 76char *char_index(char *str, char c) {
 77  while (*str && (c != *str))
 78    ++str;
 79  return (c == *str) ? str : 0;
 80}
 81
 82void Swig_fragment_emit(Node *n) {
 83  String *code;
 84  char *pc, *tok;
 85  String *t;
 86  String *mangle = 0;
 87  String *name = 0;
 88  String *type = 0;
 89
 90  if (!fragments) {
 91    Swig_warning(WARN_FRAGMENT_NOT_FOUND, Getfile(n), Getline(n), "Fragment '%s' not found.\n", name);
 92    return;
 93  }
 94
 95
 96  name = Getattr(n, "value");
 97  if (!name) {
 98    name = n;
 99  }
100  type = Getattr(n, "type");
101  if (type) {
102    mangle = Swig_string_mangle(type);
103  }
104
105  if (debug)
106    Printf(stdout, "looking fragment %s %s\n", name, type);
107  t = Copy(name);
108  tok = Char(t);
109  pc = char_index(tok, ',');
110  if (pc)
111    *pc = 0;
112  while (tok) {
113    String *name = NewString(tok);
114    if (mangle)
115      Append(name, mangle);
116    if (looking_fragments && Getattr(looking_fragments, name)) {
117      return;
118    }
119    code = Getattr(fragments, name);
120    if (debug)
121      Printf(stdout, "looking subfragment %s\n", name);
122    if (code && (Strcmp(code, "ignore") != 0)) {
123      String *section = Getmeta(code, "section");
124      Hash *nn = Getmeta(code, "kwargs");
125      if (!looking_fragments)
126	looking_fragments = NewHash();
127      Setattr(looking_fragments, name, "1");
128      while (nn) {
129	if (Equal(Getattr(nn, "name"), "fragment")) {
130	  if (debug)
131	    Printf(stdout, "emitting fragment %s %s\n", nn, type);
132	  Setfile(nn, Getfile(n));
133	  Setline(nn, Getline(n));
134	  Swig_fragment_emit(nn);
135	}
136	nn = nextSibling(nn);
137      }
138      if (section) {
139	File *f = Swig_filebyname(section);
140	if (!f) {
141	  Swig_error(Getfile(code), Getline(code), "Bad section '%s' for code fragment '%s'\n", section, name);
142	} else {
143	  if (debug)
144	    Printf(stdout, "emitting subfragment %s %s\n", name, section);
145	  if (debug)
146	    Printf(f, "/* begin fragment %s */\n", name);
147	  Printf(f, "%s\n", code);
148	  if (debug)
149	    Printf(f, "/* end fragment %s */\n\n", name);
150	  Setattr(fragments, name, "ignore");
151	  Delattr(looking_fragments, name);
152	}
153      }
154    } else if (!code && type) {
155      SwigType *rtype = SwigType_typedef_resolve_all(type);
156      if (!Equal(type, rtype)) {
157	String *name = Copy(Getattr(n, "value"));
158	String *mangle = Swig_string_mangle(type);
159	Append(name, mangle);
160	Setfile(name, Getfile(n));
161	Setline(name, Getline(n));
162	Swig_fragment_emit(name);
163	Delete(mangle);
164	Delete(name);
165      }
166      Delete(rtype);
167    }
168
169    if (!code) {
170      Swig_warning(WARN_FRAGMENT_NOT_FOUND, Getfile(n), Getline(n), "Fragment '%s' not found.\n", name);
171    }
172    tok = pc ? pc + 1 : 0;
173    if (tok) {
174      pc = char_index(tok, ',');
175      if (pc)
176	*pc = 0;
177    }
178    Delete(name);
179  }
180  Delete(t);
181}