special cases and other things in wxPython, and since I plan on making several more, I've decided to put the SWIG sources in wxPython's CVS instead of relying on maintaining patches. This effectivly becomes a fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still doesn't have some things I rely on in 1.1, not to mention that my custom patches would all have to be redone, I felt that this is the easier road to take. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15307 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			588 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			588 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*******************************************************************************
 | |
|  * Simplified Wrapper and Interface Generator  (SWIG)
 | |
|  * 
 | |
|  * Author : David Beazley
 | |
|  *
 | |
|  * Department of Computer Science        
 | |
|  * University of Chicago
 | |
|  * 1100 E 58th Street
 | |
|  * Chicago, IL  60637
 | |
|  * beazley@cs.uchicago.edu
 | |
|  *
 | |
|  * Please read the file LICENSE for the copyright and terms by which SWIG
 | |
|  * can be used and distributed.
 | |
|  *******************************************************************************/
 | |
| 
 | |
| #include "internal.h"
 | |
| #include <ctype.h>
 | |
| 
 | |
| //-----------------------------------------------------------------------
 | |
| // char *copy_string(char *str)
 | |
| //
 | |
| // Makes a copy of string str.  Returns a pointer to it.
 | |
| //-----------------------------------------------------------------------
 | |
| 
 | |
| char *copy_string(char *str) {
 | |
|   char *res = 0;
 | |
|   if (str) {
 | |
|     res = new char[strlen(str)+1];
 | |
|     strcpy(res,str);
 | |
|   }
 | |
|   return res;
 | |
| }
 | |
| 
 | |
| //-----------------------------------------------------------------------
 | |
| // void format_string(char *str)
 | |
| //
 | |
| // Replace all of the escape sequences in the string str.   It is
 | |
| // assumed that the new string is smaller than the original!
 | |
| //-----------------------------------------------------------------------
 | |
| 
 | |
| void format_string(char *str) {
 | |
|   char *newstr, *c,*c1;
 | |
|   int  state;
 | |
|   if (!str) return;
 | |
|   newstr = copy_string(str);
 | |
|   c = newstr;
 | |
|   c1 = str;
 | |
|   state = 0;
 | |
|   while (*c) {
 | |
|     switch(state) {
 | |
|     case 0:
 | |
|       if (*c == '\\') 
 | |
| 	state = 1;
 | |
|       else {
 | |
| 	*(c1++) = *c;
 | |
| 	state = 0;
 | |
|       }
 | |
|       break;
 | |
|    case 1:
 | |
|       // We're in a simple escape sequence figure out what to do
 | |
|       switch(*c) {
 | |
|       case 'n':
 | |
| 	*(c1++) = '\n';
 | |
| 	break;
 | |
|       case 'f':
 | |
| 	*(c1++) = '\f';
 | |
| 	break;
 | |
|       case 'r':
 | |
| 	*(c1++) = '\r';
 | |
| 	break;
 | |
|       case 't':
 | |
| 	*(c1++) = '\t';
 | |
| 	break;
 | |
|       case '\\':
 | |
| 	*(c1++) = '\\';
 | |
|       break;
 | |
|       case '\"':
 | |
| 	*(c1++) = '\"';
 | |
|       break;
 | |
|       case '\'':
 | |
| 	*(c1++) = '\'';
 | |
|       break;
 | |
|       default:
 | |
| 	*(c1++) = '\\';
 | |
|         *(c1++) = *c;
 | |
|       }
 | |
|       state = 0;
 | |
|       break;
 | |
|     default:
 | |
|       *(c1++) = *c;
 | |
|       state = 0;
 | |
|     }
 | |
|     c++;
 | |
|   }
 | |
|   *c1 = 0;
 | |
|   delete newstr;
 | |
| }
 | |
| 
 | |
| // ---------------------------------------------------------------------------
 | |
| // $Header$
 | |
| // sstring.cxx
 | |
| //
 | |
| // SWIG String class.
 | |
| // This class is used to construct long strings when writing 
 | |
| // wrapper functions.  It also "mimicks" the C++ streams I/O
 | |
| // library for creating strings.  For example :
 | |
| //
 | |
| //     str << "hi there" << 3 << "\n";
 | |
| // 
 | |
| // Will append the given strings to str.
 | |
| //
 | |
| // The idea here is to provide a mechanism for writing wrapper
 | |
| // functions as strings before writing them out to a file.
 | |
| //
 | |
| // ---------------------------------------------------------------------------
 | |
| #define INIT_MAXSIZE  64
 | |
| 
 | |
| // ---------------------------------------------------------------
 | |
| // Pools. This is a list of available strings for memory allocation
 | |
| // and deletion.
 | |
| // ---------------------------------------------------------------
 | |
| 
 | |
| struct StrMem {
 | |
|   char  *str;
 | |
|   int    len;
 | |
| };
 | |
| 
 | |
| #define POOLSIZE 100
 | |
| 
 | |
| static StrMem pool[POOLSIZE];
 | |
| static int pool_index = 0;
 | |
| 
 | |
| // Returns an item from the pool that can accomodate len
 | |
| static char *get_pool(int len, int &newlen) {
 | |
|   int i,j;
 | |
|   char *nc;
 | |
|   if (pool_index < 1) {
 | |
|     newlen = len;
 | |
|     return new char[len];
 | |
|   }
 | |
|   i = pool_index-1;
 | |
|   j = 0;
 | |
|   while(i >= 0) {
 | |
|     if ((pool[i].len >= len) && (pool[i].len <= 4*len)) {
 | |
|       nc = pool[i].str;
 | |
|       newlen = pool[i].len;
 | |
|       pool[i].str = pool[pool_index-1].str;
 | |
|       pool[i].len = pool[pool_index-1].len;
 | |
|       pool_index--;
 | |
|       return nc;
 | |
|     }
 | |
|     j++;
 | |
|     i--;
 | |
|   }
 | |
|   newlen = len;
 | |
|   return new char[len];
 | |
| }
 | |
| 
 | |
| // Puts an item onto the pool
 | |
| 
 | |
| static void put_pool(char *str, int len) {
 | |
|   if (len < INIT_MAXSIZE) {
 | |
|     delete [] str;
 | |
|     return;
 | |
|   }
 | |
|   if (pool_index == POOLSIZE) {
 | |
|     delete [] pool[pool_index-1].str;
 | |
|     pool_index--;
 | |
|   }
 | |
|   pool[pool_index].str = str;
 | |
|   pool[pool_index].len = len;
 | |
|   if (pool_index != POOLSIZE) 
 | |
|     pool_index++;
 | |
| }
 | |
| 
 | |
| // ---------------------------------------------------------------
 | |
| // String::String()
 | |
| //
 | |
| // Create a new string with nothing in it
 | |
| // ---------------------------------------------------------------
 | |
| 
 | |
| String::String() {
 | |
|   maxsize = INIT_MAXSIZE;
 | |
|   str = get_pool(maxsize,maxsize);   // May return a pool that is larger
 | |
|   str[0] = 0;
 | |
|   len = 0;
 | |
| }
 | |
| 
 | |
| // ---------------------------------------------------------------
 | |
| // String::String(const char *s)
 | |
| //
 | |
| // Create a new string copied from a normal C-style string
 | |
| // ---------------------------------------------------------------
 | |
| 
 | |
| String::String(const char *s) {
 | |
|   int  max = INIT_MAXSIZE;
 | |
|   int  l = 0;
 | |
|   if (s) {
 | |
|     l = (int) strlen(s);
 | |
|     if ((l+1) > max) max = l+1;
 | |
|   }
 | |
|   str = get_pool(max,maxsize);
 | |
|   if (s) {
 | |
|     strcpy(str,s);
 | |
|     len = l;
 | |
|   } else {
 | |
|     str[0] = 0;
 | |
|     len = 0;
 | |
|   }
 | |
| }
 | |
| 
 | |
| // ---------------------------------------------------------------
 | |
| // String::~String(const char *s)
 | |
| //
 | |
| // Destroy a string
 | |
| // ---------------------------------------------------------------
 | |
| 
 | |
| String::~String() {
 | |
|   put_pool(str,maxsize);
 | |
| }
 | |
| 
 | |
| // ---------------------------------------------------------------
 | |
| // String::add(const char *newstr)
 | |
| //
 | |
| // Concatenate newstr onto the current string
 | |
| // ---------------------------------------------------------------
 | |
| 
 | |
| void String::add(const char *newstr) {
 | |
|   int   newlen;
 | |
|   char  *nstr = 0;
 | |
|   int   newmaxsize;
 | |
|   int   l;
 | |
| 
 | |
|   l = (int) strlen(newstr);
 | |
|   newlen = len+l + 1;
 | |
|   if (newlen >= maxsize-1) {
 | |
|     newmaxsize = 2*maxsize;
 | |
|     if (newlen >= newmaxsize -1) newmaxsize = newlen + 1;
 | |
|     nstr = get_pool(newmaxsize,newmaxsize);
 | |
|     strcpy(nstr,str);
 | |
|     put_pool(str,maxsize);
 | |
|     maxsize = newmaxsize;
 | |
|     str = nstr;
 | |
|   }
 | |
|   strcpy(str+len,newstr);
 | |
|   len += l;
 | |
| }
 | |
| 
 | |
| // ---------------------------------------------------------------
 | |
| // String::add(char)
 | |
| //
 | |
| // Adds a single character to the current string
 | |
| // ---------------------------------------------------------------
 | |
| 
 | |
| void String::add(char nc) {
 | |
|   int   newlen;
 | |
|   char  *nstr = 0;
 | |
|   int   newmaxsize;
 | |
| 
 | |
|   newlen = len+ 1;
 | |
|   if (newlen >= maxsize-1) {
 | |
|     newmaxsize = 2*maxsize;
 | |
|     if (newlen >= newmaxsize -1) newmaxsize = newlen + 1;
 | |
|     nstr = get_pool(newmaxsize,newmaxsize);
 | |
|     strcpy(nstr,str);
 | |
|     put_pool(str,maxsize);
 | |
|     maxsize = newmaxsize;
 | |
|     str = nstr;
 | |
|   }
 | |
|   str[len++] = nc;
 | |
|   str[len] = 0;
 | |
| }
 | |
| 
 | |
| // -----------------------------------------------------------------
 | |
| // String::insert(const char *newstr)
 | |
| //
 | |
| // Inserts a string into the front of a string.  (Primarily used
 | |
| // for documentation generation)
 | |
| // -----------------------------------------------------------------
 | |
| 
 | |
| void String::insert(const char *newstr) {
 | |
|   int  newlen;
 | |
|   char *nstr = 0;
 | |
|   int  newmaxsize;
 | |
|   int  i,l;
 | |
| 
 | |
|   l = strlen(newstr);
 | |
|   newlen = len + l + 1;
 | |
|   if (newlen >= maxsize-1) {
 | |
|     newmaxsize = 2*maxsize;
 | |
|     if (newlen >= newmaxsize -1) newmaxsize = newlen + 1;
 | |
|     nstr = get_pool(newmaxsize,newmaxsize);
 | |
|     strcpy(nstr,str);
 | |
|     put_pool(str,maxsize);
 | |
|     maxsize = newmaxsize;
 | |
|     str = nstr;
 | |
|   }
 | |
|   
 | |
|   /* Shift all of the characters over */
 | |
| 
 | |
|   for (i = len -1; i >= 0; i--) {
 | |
|     str[i+l] = str[i];
 | |
|   }
 | |
|   
 | |
|   /* Now insert the new string */
 | |
| 
 | |
|   strncpy(str,newstr,l);
 | |
|   len += l;
 | |
|   str[len] = 0;                         
 | |
| 
 | |
| }
 | |
| 
 | |
| // -----------------------------------------------------------------
 | |
| // char *String::get()
 | |
| //
 | |
| // Get the current value of the string
 | |
| // -----------------------------------------------------------------
 | |
| 
 | |
| char *String::get() const {
 | |
|   return str;
 | |
| }
 | |
| 
 | |
| // -----------------------------------------------------------------
 | |
| // String &operator<<(...)
 | |
| //
 | |
| // Shorthand for appending to the end of a string
 | |
| // -----------------------------------------------------------------
 | |
| 
 | |
| String &operator<<(String &t,const char *s) {
 | |
|   t.add(s);
 | |
|   return t;
 | |
| }
 | |
| 
 | |
| 
 | |
| String &operator<<(String &t,const char s) {
 | |
|   t.add(s);
 | |
|   return t;
 | |
| }
 | |
| 
 | |
| String &operator<<(String &t,const int a) {
 | |
|   char  temp[64];
 | |
|   sprintf(temp,"%d",a);
 | |
|   t.add(temp);
 | |
|   return t;
 | |
| }
 | |
| 
 | |
| String &operator<<(String &t, String &s) {
 | |
|   t.add(s.get());
 | |
|   return t;
 | |
| }
 | |
| 
 | |
| String &String::operator=(const char *s) {
 | |
|   int newlen;
 | |
| 
 | |
|   if (s) {
 | |
|     newlen = strlen(s);
 | |
|     if ((newlen >= maxsize) && (str)) {
 | |
|       put_pool(str,maxsize);
 | |
|       str = get_pool(newlen+1,maxsize);
 | |
|       maxsize = newlen+1;
 | |
|     }
 | |
|     strcpy(str,s);
 | |
|     len = newlen;
 | |
|   } else {
 | |
|     str[0] = 0;
 | |
|     len = 0;
 | |
|   }
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| // -----------------------------------------------------------------
 | |
| // String &operator>>(...)
 | |
| //
 | |
| // Shorthand for inserting into the beginning of a string
 | |
| // -----------------------------------------------------------------
 | |
| 
 | |
| String &operator>>(const char *s, String &t) {
 | |
|   t.insert(s);
 | |
|   return t;
 | |
| }
 | |
| 
 | |
| String &operator>>(String &s, String &t) {
 | |
|   t.insert(s.get());
 | |
|   return t;
 | |
| }
 | |
| 
 | |
| // -----------------------------------------------------------------
 | |
| // void String::untabify()
 | |
| //
 | |
| // Expand all tabs into spaces.   This is useful for producing
 | |
| // documentation and other things.
 | |
| // -----------------------------------------------------------------
 | |
| 
 | |
| void String::untabify() {
 | |
|   char *s;
 | |
|   char *c;
 | |
|   int   pos;
 | |
|   int   i;
 | |
|   int   oldmaxsize;
 | |
|   // Copy the current string representation
 | |
| 
 | |
|   s = str;
 | |
|   oldmaxsize = maxsize;
 | |
| 
 | |
|   // Reset the internal state of this string
 | |
| 
 | |
|   len = 0;
 | |
|   str = get_pool(maxsize,maxsize);
 | |
|   str[0]= 0;
 | |
| 
 | |
|   // Now walk down the old string and expand tabs.  Tabs are usually place
 | |
|   // every 8 characters.
 | |
| 
 | |
|   pos = 0;
 | |
|   c = s;
 | |
|   while (*c) {
 | |
|     if (*c == '\n') {
 | |
|       pos = -1;
 | |
|     }
 | |
|     if (*c == '\t') {
 | |
|       // Expand the character
 | |
|       for (i = 0; i < (8 - (pos % 8)); i++) {
 | |
| 	this->add(' ');
 | |
|       }
 | |
|       pos+=(8-(pos % 8));
 | |
|     } else {
 | |
|       this->add(*c);
 | |
|       pos++;
 | |
|     }
 | |
|     c++;
 | |
|   }
 | |
| 
 | |
|   // Blow away the old string
 | |
|   put_pool(s,oldmaxsize);
 | |
| }
 | |
| 
 | |
| 
 | |
| // -----------------------------------------------------------------
 | |
| // void String::replace(const char *token, const char *rep)
 | |
| //
 | |
| // Search for tokens in a string and replace them with rep.
 | |
| // This probably isn't the fastest implementation, but fortunately
 | |
| // SWIG rarely calls this function.
 | |
| // -----------------------------------------------------------------
 | |
| 
 | |
| void String::replace(const char *token, const char *rep) {
 | |
|   char *s, *c, *t;
 | |
|   int  oldmaxsize = maxsize;
 | |
|   // Copy the current string representation
 | |
| 
 | |
|   s = str;
 | |
| 
 | |
|   // Now walk down the old string and search for tokens
 | |
| 
 | |
|   c = s;
 | |
|   t = strstr(c,token);
 | |
|   if (t) {
 | |
|     len = 0;
 | |
|     str = get_pool(maxsize,maxsize);
 | |
|     while (t) {
 | |
|       // Found a token in string s
 | |
|       // Dump characters into our string
 | |
|       char temp;
 | |
|       temp = *t;
 | |
|       *t = 0;
 | |
|       this->add(c);
 | |
|       c = t;
 | |
|       *t = temp;
 | |
| 
 | |
|       // Now dump the replacement string into place
 | |
| 
 | |
|       this->add(rep);
 | |
|       
 | |
|       // Jump over the token
 | |
|       
 | |
|       c+=strlen(token);
 | |
|       t = strstr(c,token);
 | |
|     }
 | |
|     // Attach rest of the string
 | |
|     if (*c) 
 | |
|       this->add(c);
 | |
|     put_pool(s,oldmaxsize);
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| // -----------------------------------------------------------------
 | |
| // void String::replaceid(char *token, char *rep)
 | |
| //
 | |
| // Searches for valid identifiers matching token and replaces
 | |
| // them with rep.    Unlike replace() tokens must be a valid C
 | |
| // identifier (surrounded by whitespace).
 | |
| // -----------------------------------------------------------------
 | |
| 
 | |
| void String::replaceid(const char *token, const char *rep) {
 | |
|   char *s, *c, *t;
 | |
|   int  whitespace, tokenlen;
 | |
|   int  oldmaxsize = maxsize;
 | |
|   // Copy the current string representation
 | |
| 
 | |
|   s = str;
 | |
| 
 | |
|   // Reset the internal state of this string
 | |
| 
 | |
|   tokenlen = strlen(token);
 | |
| 
 | |
|   // Now walk down the old string and search for tokens
 | |
| 
 | |
|   c = s;
 | |
|   t = strstr(c,token);
 | |
|   if (t) {
 | |
|     len = 0;
 | |
|     str = get_pool(maxsize,maxsize);
 | |
|     while (t) {
 | |
|       // Found a token in string s
 | |
|       // Dump characters into our string
 | |
| 
 | |
|       whitespace = 1;
 | |
|       while (c != t) {
 | |
| 	this->add(*c);
 | |
| 	if (!(isalpha(*c) || (*c == '_') || (*c == '$'))) whitespace = 1;
 | |
| 	else whitespace = 0;
 | |
| 	c++;
 | |
|       }
 | |
|     
 | |
|       if (whitespace) {
 | |
| 	// Check to see if there is whitespace afterwards
 | |
| 	if ((!c[tokenlen]) || (!(isalnum(c[tokenlen]) || (c[tokenlen] == '_') || (c[tokenlen] == '$')))) {
 | |
| 	  this->add(rep);
 | |
| 	} else {
 | |
| 	  this->add(token);
 | |
| 	}
 | |
| 	c+=tokenlen;
 | |
|       } else {
 | |
| 	this->add(*c);
 | |
| 	c++;
 | |
|       }
 | |
|       t = strstr(c,token);
 | |
|     }
 | |
| 
 | |
|     // Attach rest of the string
 | |
|     if (*c) 
 | |
|       this->add(c);
 | |
| 
 | |
|     // Delete the old string
 | |
|     put_pool(s,oldmaxsize);
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| // -----------------------------------------------------------------
 | |
| // void String::strip()
 | |
| //
 | |
| // Intelligently strips whitespace from a string.    Will not strip
 | |
| // whitespace if it is between two characters that are part of a
 | |
| // legal C identifier. For example 'unsigned int'.
 | |
| // -----------------------------------------------------------------
 | |
| 
 | |
| void String::strip() {
 | |
|   char *s = str;          // Old pointer value
 | |
|   char *c, lastchar = 0;    
 | |
|   int   whitespace = 0;
 | |
|   int   oldmaxsize = maxsize;
 | |
| 
 | |
|   str = get_pool(maxsize,maxsize);   // Get a new string.
 | |
|   len = 0;
 | |
| 
 | |
|   c = s;
 | |
|   while(*c) {
 | |
|     if (!isspace(*c)) {
 | |
|       // See if this character doesn't violate our whitespace rules
 | |
|       if (whitespace) {
 | |
| 	if (isalnum(lastchar) || (lastchar == '_') || (lastchar == '$')) {
 | |
| 	  if (isalnum(*c) || (*c == '_') || (*c == '$')) 
 | |
| 	    this->add(' ');
 | |
| 	}
 | |
|       }
 | |
|       this->add(*c);
 | |
|       lastchar = *c;
 | |
|       whitespace = 0;
 | |
|     } else {
 | |
|       whitespace = 1;
 | |
|     }
 | |
|     c++;
 | |
|   }
 | |
|   put_pool(s,oldmaxsize);
 | |
| }
 |