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.
7 * This file defines a object for creating wrapper functions. Primarily
8 * this is used for convenience since it allows pieces of a wrapper function
9 * to be created in a piecemeal manner.
10 * ----------------------------------------------------------------------------- */
12 char cvsroot_wrapfunc_c[] = "$Id: wrapfunc.c 11080 2009-01-24 13:15:51Z bhy $";
17 static int Compact_mode = 0; /* set to 0 on default */
18 static int Max_line_size = 128;
20 /* -----------------------------------------------------------------------------
23 * Create a new wrapper function object.
24 * ----------------------------------------------------------------------------- */
26 Wrapper *NewWrapper(void) {
28 w = (Wrapper *) malloc(sizeof(Wrapper));
29 w->localh = NewHash();
30 w->locals = NewStringEmpty();
31 w->code = NewStringEmpty();
32 w->def = NewStringEmpty();
36 /* -----------------------------------------------------------------------------
39 * Delete a wrapper function object.
40 * ----------------------------------------------------------------------------- */
42 void DelWrapper(Wrapper *w) {
50 /* -----------------------------------------------------------------------------
51 * Wrapper_compact_print_mode_set()
54 * ----------------------------------------------------------------------------- */
56 void Wrapper_compact_print_mode_set(int flag) {
60 /* -----------------------------------------------------------------------------
61 * Wrapper_pretty_print()
63 * Formats a wrapper function and fixes up the indentation.
64 * ----------------------------------------------------------------------------- */
66 void Wrapper_pretty_print(String *str, File *f) {
75 ts = NewStringEmpty();
76 Seek(str, 0, SEEK_SET);
77 while ((c = Getc(str)) != EOF) {
80 while ((c = Getc(str)) != EOF) {
90 } else if (c == '\'') {
92 while ((c = Getc(str)) != EOF) {
102 } else if (c == ':') {
104 if ((c = Getc(str)) == '\n') {
105 if (!empty && !strchr(Char(ts), '?'))
109 } else if (c == '(') {
113 } else if (c == ')') {
117 } else if (c == '{') {
120 for (i = 0; i < level; i++)
125 while ((c = Getc(str)) != EOF) {
132 } else if (c == '}') {
135 for (i = 0; i < level; i++)
143 } else if (c == '\n') {
148 if (label && (slevel >= indent))
150 if ((Char(ts))[0] != '#') {
151 for (i = 0; i < slevel; i++)
155 for (i = 0; i < plevel; i++)
161 } else if (c == '/') {
167 if (c == '/') { /* C++ comment */
168 while ((c = Getc(str)) != EOF) {
175 } else if (c == '*') { /* C comment */
177 while ((c = Getc(str)) != EOF) {
178 if (endstar && c == '/') { /* end of C comment */
182 endstar = (c == '*');
184 if (c == '\n') { /* multi-line C comment. Could be improved slightly. */
185 for (i = 0; i < level; i++)
192 if (!empty || !isspace(c)) {
204 /* -----------------------------------------------------------------------------
205 * Wrapper_compact_print()
207 * Formats a wrapper function and fixes up the indentation.
208 * Print out in compact format, with Compact enabled.
209 * ----------------------------------------------------------------------------- */
211 void Wrapper_compact_print(String *str, File *f) {
212 String *ts, *tf; /*temp string & temp file */
218 ts = NewStringEmpty();
219 tf = NewStringEmpty();
220 Seek(str, 0, SEEK_SET);
222 while ((c = Getc(str)) != EOF) {
223 if (c == '\"') { /* string 1 */
226 while ((c = Getc(str)) != EOF) {
235 } else if (c == '\'') { /* string 2 */
238 while ((c = Getc(str)) != EOF) {
247 } else if (c == '{') { /* start of {...} */
251 for (i = 0; i < level; i++)
253 } else if ((Len(tf) + Len(ts)) < Max_line_size) {
259 for (i = 0; i < level; i++)
265 while ((c = Getc(str)) != EOF) {
271 } else if (c == '}') { /* end of {...} */
274 for (i = 0; i < level; i++)
276 } else if ((Len(tf) + Len(ts)) < Max_line_size) {
282 for (i = 0; i < level; i++)
289 } else if (c == '\n') { /* line end */
290 while ((c = Getc(str)) != EOF) {
296 } else if (c == '}') {
298 } else if ((c != EOF) || (Len(ts) != 0)) {
300 for (i = 0; i < level; i++)
302 } else if ((Len(tf) + Len(ts)) < Max_line_size) {
308 for (i = 0; i < level; i++)
317 } else if (c == '/') { /* comment */
321 if (c == '/') { /* C++ comment */
322 while ((c = Getc(str)) != EOF) {
328 } else if (c == '*') { /* C comment */
330 while ((c = Getc(str)) != EOF) {
331 if (endstar && c == '/') { /* end of C comment */
334 endstar = (c == '*');
341 } else if (c == '#') { /* Preprocessor line */
343 while ((c = Getc(str)) != EOF) {
345 if (c == '\\') { /* Continued line of the same PP */
351 } else if (c == '\n')
361 for (i = 0; i < level; i++)
365 if (!empty || !isspace(c)) {
381 /* -----------------------------------------------------------------------------
384 * Print out a wrapper function. Does pretty or compact printing as well.
385 * ----------------------------------------------------------------------------- */
387 void Wrapper_print(Wrapper *w, File *f) {
390 str = NewStringEmpty();
391 Printf(str, "%s\n", w->def);
392 Printf(str, "%s\n", w->locals);
393 Printf(str, "%s\n", w->code);
394 if (Compact_mode == 1)
395 Wrapper_compact_print(str, f);
397 Wrapper_pretty_print(str, f);
402 /* -----------------------------------------------------------------------------
403 * Wrapper_add_local()
405 * Adds a new local variable declaration to a function. Returns -1 if already
406 * present (which may or may not be okay to the caller).
407 * ----------------------------------------------------------------------------- */
409 int Wrapper_add_local(Wrapper *w, const_String_or_char_ptr name, const_String_or_char_ptr decl) {
410 /* See if the local has already been declared */
411 if (Getattr(w->localh, name)) {
414 Setattr(w->localh, name, decl);
415 Printf(w->locals, "%s;\n", decl);
419 /* -----------------------------------------------------------------------------
420 * Wrapper_add_localv()
422 * Same as add_local(), but allows a NULL terminated list of strings to be
423 * used as a replacement for decl. This saves the caller the trouble of having
424 * to manually construct the 'decl' string before calling.
425 * ----------------------------------------------------------------------------- */
427 int Wrapper_add_localv(Wrapper *w, const_String_or_char_ptr name, ...) {
432 decl = NewStringEmpty();
435 obj = va_arg(ap, void *);
439 obj = va_arg(ap, void *);
443 ret = Wrapper_add_local(w, name, decl);
448 /* -----------------------------------------------------------------------------
449 * Wrapper_check_local()
451 * Check to see if a local name has already been declared
452 * ----------------------------------------------------------------------------- */
454 int Wrapper_check_local(Wrapper *w, const_String_or_char_ptr name) {
455 if (Getattr(w->localh, name)) {
461 /* -----------------------------------------------------------------------------
462 * Wrapper_new_local()
464 * Adds a new local variable with a guarantee that a unique local name will be
465 * used. Returns the name that was actually selected.
466 * ----------------------------------------------------------------------------- */
468 char *Wrapper_new_local(Wrapper *w, const_String_or_char_ptr name, const_String_or_char_ptr decl) {
470 String *nname = NewString(name);
471 String *ndecl = NewString(decl);
476 while (Wrapper_check_local(w, nname)) {
478 Printf(nname, "%s%d", name, i);
481 Replace(ndecl, name, nname, DOH_REPLACE_ID);
482 Setattr(w->localh, nname, ndecl);
483 Printf(w->locals, "%s;\n", ndecl);
487 return ret; /* Note: nname should still exists in the w->localh hash */
491 /* -----------------------------------------------------------------------------
492 * Wrapper_new_localv()
494 * Same as add_local(), but allows a NULL terminated list of strings to be
495 * used as a replacement for decl. This saves the caller the trouble of having
496 * to manually construct the 'decl' string before calling.
497 * ----------------------------------------------------------------------------- */
499 char *Wrapper_new_localv(Wrapper *w, const_String_or_char_ptr name, ...) {
504 decl = NewStringEmpty();
507 obj = va_arg(ap, void *);
511 obj = va_arg(ap, void *);
515 ret = Wrapper_new_local(w, name, decl);