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
		
			
				
	
	
		
			479 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			479 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.
 | |
|  *******************************************************************************/
 | |
| 
 | |
| /* ------------------------------------------------------------------------
 | |
|    $Header$
 | |
| 
 | |
|    parms.cxx
 | |
| 
 | |
|    This file is used to manage function parameters and parameter lists.
 | |
|    Rewritten (10/27) to solve a bunch of problems with memory management
 | |
|    and proper cleanup of things.
 | |
|    ------------------------------------------------------------------------ */
 | |
| 
 | |
| #include "swig.h"
 | |
| 
 | |
| // ------------------------------------------------------------------------
 | |
| // Parm::Parm(DataType *type, char *n)
 | |
| //
 | |
| // Create a new parameter from datatype 'type' and name 'n'.
 | |
| // Copies will be made of type and n, unless they aren't specified.
 | |
| // ------------------------------------------------------------------------
 | |
| 
 | |
| Parm::Parm(DataType *type, char *n) {
 | |
|   if (type) {
 | |
|     t = new DataType(type);
 | |
|   } else {
 | |
|     t = 0;
 | |
|   }
 | |
|   name = copy_string(n);
 | |
|   call_type = 0;
 | |
|   defvalue = 0;
 | |
|   ignore = 0;
 | |
|   objc_separator = 0;
 | |
| }
 | |
| 
 | |
| // ------------------------------------------------------------------------
 | |
| // Parm::Parm(Parm *p)
 | |
| //
 | |
| // Make a copy of a parameter
 | |
| // ------------------------------------------------------------------------
 | |
| 
 | |
| Parm::Parm(Parm *p) {
 | |
|   if (p->t) t = new DataType(p->t);
 | |
|   name = copy_string(p->name);
 | |
|   call_type = p->call_type;
 | |
|   defvalue = copy_string(p->defvalue);
 | |
|   ignore = p->ignore;
 | |
|   objc_separator = copy_string(p->objc_separator);
 | |
| }
 | |
| 
 | |
| // ------------------------------------------------------------------------
 | |
| // Parm::~Parm()
 | |
| //
 | |
| // Destroy a parameter
 | |
| // ------------------------------------------------------------------------
 | |
| 
 | |
| Parm::~Parm() {
 | |
|   if (t) delete t;
 | |
|   if (name) delete name;
 | |
|   if (defvalue) delete defvalue;
 | |
|   if (objc_separator) delete objc_separator;
 | |
| }
 | |
| 
 | |
| /********************************************************************
 | |
|  class ParmList
 | |
| 
 | |
|  These functions are used to manipulate lists of parameters
 | |
|  ********************************************************************/
 | |
| 
 | |
| // ------------------------------------------------------------------
 | |
| // ParmList::ParmList()
 | |
| //
 | |
| // Create a new (empty) parameter list
 | |
| // ------------------------------------------------------------------
 | |
| 
 | |
| ParmList::ParmList() {
 | |
| 
 | |
|   nparms = 0;
 | |
|   maxparms = MAXPARMS;
 | |
|   parms = new Parm *[maxparms];     // Create an array of parms
 | |
|   for (int i = 0; i < MAXPARMS; i++)
 | |
|     parms[i] = (Parm *) 0;
 | |
| }
 | |
| 
 | |
| // ------------------------------------------------------------------
 | |
| // ParmList::ParmList(ParmList *l)
 | |
| //
 | |
| // Make a copy of parameter list
 | |
| // ------------------------------------------------------------------
 | |
| 
 | |
| ParmList::ParmList(ParmList *l) {
 | |
|   int i;
 | |
| 
 | |
|   if (l) {
 | |
|     nparms = l->nparms;
 | |
|     maxparms = l->maxparms;
 | |
|     parms = new Parm *[maxparms];
 | |
|   
 | |
|     for (i = 0; i < maxparms; i++) {
 | |
|       if (l->parms[i])
 | |
| 	parms[i] = new Parm(l->parms[i]);
 | |
|       else
 | |
| 	parms[i] = 0;
 | |
|     }
 | |
| 
 | |
|   } else {
 | |
|     nparms = 0;
 | |
|     maxparms = MAXPARMS;
 | |
|     parms = new Parm *[maxparms];     // Create an array of parms
 | |
| 
 | |
|     for (i = 0; i < MAXPARMS; i++)
 | |
|       parms[i] = (Parm *) 0;
 | |
|   }
 | |
| }
 | |
| 
 | |
| // ------------------------------------------------------------------
 | |
| // ParmList::~ParmList()
 | |
| //
 | |
| // Delete a parameter list
 | |
| // ------------------------------------------------------------------
 | |
|   
 | |
| ParmList::~ParmList() {
 | |
|   for (int i = 0; i < maxparms; i++) {
 | |
|     if (parms[i]) delete parms[i];
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| // ------------------------------------------------------------------
 | |
| // void ParmList::moreparms()               (PRIVATE)
 | |
| //
 | |
| // Doubles the amount of parameter memory available.  
 | |
| // ------------------------------------------------------------------
 | |
| 
 | |
| void ParmList::moreparms() {
 | |
|   Parm  **newparms;
 | |
|   int     i;
 | |
| 
 | |
|   newparms = new Parm *[maxparms*2];
 | |
|   for (i = 0; i < 2*maxparms; i++)
 | |
|     newparms[i] = (Parm *) 0;
 | |
|   for (i = 0; i < maxparms; i++) {
 | |
|     newparms[i] = parms[i];
 | |
|   }
 | |
|   maxparms = 2*maxparms;
 | |
|   delete parms;
 | |
|   parms = newparms;
 | |
| }
 | |
| 
 | |
| // ------------------------------------------------------------------
 | |
| // void ParmList::append(Parm *p)
 | |
| //
 | |
| // Add a new parameter to the end of a parameter list
 | |
| // ------------------------------------------------------------------
 | |
| 
 | |
| void ParmList::append(Parm *p) {
 | |
| 
 | |
|   if (nparms == maxparms) moreparms();
 | |
| 
 | |
|   // Add parm onto the end 
 | |
| 
 | |
|   parms[nparms] = new Parm(p);
 | |
|   nparms++;
 | |
| }
 | |
| 
 | |
| // ------------------------------------------------------------------
 | |
| // void ParmList::insert(Parm *p, int pos)
 | |
| //
 | |
| // Inserts a parameter at position pos.   Parameters are inserted
 | |
| // *before* any existing parameter at position pos.
 | |
| // ------------------------------------------------------------------
 | |
| 
 | |
| void ParmList::insert(Parm *p, int pos) {
 | |
| 
 | |
|   // If pos is out of range, we'd better fix it
 | |
| 
 | |
|   if (pos < 0) pos = 0;
 | |
|   if (pos > nparms) pos = nparms;
 | |
| 
 | |
|   // If insertion is going to need more memory, take care of that now
 | |
| 
 | |
|   if (nparms >= maxparms) moreparms();
 | |
| 
 | |
|   // Now shift all of the existing parms to the right
 | |
| 
 | |
|   for (int i = nparms; i > pos; i--) {
 | |
|     parms[i] = parms[i-1];
 | |
|   }
 | |
| 
 | |
|   // Set new parameter
 | |
|   
 | |
|   parms[pos] = new Parm(p);
 | |
|   nparms++;
 | |
| 
 | |
| }
 | |
|   
 | |
| // ------------------------------------------------------------------
 | |
| // void ParmList::del(int pos)
 | |
| //
 | |
| // Deletes the parameter at position pos.
 | |
| // ------------------------------------------------------------------
 | |
| 
 | |
| void ParmList::del(int pos) {
 | |
| 
 | |
|   if (nparms <= 0) return;
 | |
|   if (pos < 0) pos = 0;
 | |
|   if (pos >= nparms) pos = nparms-1;
 | |
| 
 | |
|   // Delete the parameter (if it exists)
 | |
| 
 | |
|   if (parms[pos]) delete parms[pos];
 | |
| 
 | |
|   // Now slide all of the parameters to the left
 | |
| 
 | |
|   for (int i = pos; i < nparms-1; i++) {
 | |
|     parms[i] = parms[i+1];
 | |
|   }
 | |
|   nparms--;
 | |
| 
 | |
| }
 | |
| 
 | |
| // ------------------------------------------------------------------
 | |
| // Parm *ParmList::get(int pos)
 | |
| //
 | |
| // Gets the parameter at location pos.  Returns 0 if invalid
 | |
| // position.
 | |
| // ------------------------------------------------------------------
 | |
| 
 | |
| Parm *ParmList::get(int pos) {
 | |
| 
 | |
|   if ((pos < 0) || (pos >= nparms)) return 0;
 | |
|   return parms[pos];
 | |
| }
 | |
| 
 | |
| // ------------------------------------------------------------------
 | |
| // int ParmList::numopt()
 | |
| //
 | |
| // Gets the number of optional arguments. 
 | |
| // ------------------------------------------------------------------
 | |
| int ParmList::numopt() {
 | |
|   int  n = 0;
 | |
|   int  state = 0;
 | |
| 
 | |
|   for (int i = 0; i < nparms; i++) {
 | |
|     if (parms[i]->defvalue) {
 | |
|       n++;
 | |
|       state = 1;
 | |
|     } else if (typemap_check("default",typemap_lang,parms[i]->t,parms[i]->name)) {
 | |
|       n++;
 | |
|       state = 1;
 | |
|     } else if (typemap_check("ignore",typemap_lang,parms[i]->t,parms[i]->name)) {
 | |
|       n++;
 | |
|     } else if (typemap_check("build",typemap_lang,parms[i]->t,parms[i]->name)) {
 | |
|       n++;
 | |
|     } else {
 | |
|       if (state) {
 | |
| 	fprintf(stderr,"%s : Line %d.  Argument %d must have a default value!\n", input_file,line_number,i+1);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   return n;
 | |
| }
 | |
| 
 | |
| // ------------------------------------------------------------------
 | |
| // int ParmList::numarg()
 | |
| //
 | |
| // Gets the number of arguments
 | |
| // ------------------------------------------------------------------
 | |
| int ParmList::numarg() {
 | |
|   int  n = 0;
 | |
| 
 | |
|   for (int i = 0; i < nparms; i++) {
 | |
|     if (!parms[i]->ignore)
 | |
|       n++;
 | |
|   } 
 | |
|   return n;
 | |
| }
 | |
| 
 | |
| // ------------------------------------------------------------------
 | |
| // Parm &ParmList::operator[](int n)
 | |
| //
 | |
| // Returns parameter n in the parameter list.   May generate
 | |
| // an error if that parameter is out of range.
 | |
| // ------------------------------------------------------------------
 | |
| 
 | |
| Parm &ParmList::operator[](int n) {
 | |
|   
 | |
|   if ((n < 0) || (n >= nparms)) {
 | |
|     fprintf(stderr,"ParmList : Fatal error.  subscript out of range in ParmList.operator[]\n");
 | |
|     SWIG_exit(1);
 | |
|   }
 | |
| 
 | |
|   return *parms[n];
 | |
| }
 | |
| 
 | |
| // ---------------------------------------------------------------------
 | |
| // Parm * ParmList::get_first()
 | |
| //
 | |
| // Returns the first item on a parameter list.
 | |
| // ---------------------------------------------------------------------
 | |
| 
 | |
| Parm *ParmList::get_first() {
 | |
|   current_parm = 0;
 | |
|   if (nparms > 0) return parms[current_parm++];
 | |
|   else return (Parm *) 0;
 | |
| }
 | |
| 
 | |
| // ----------------------------------------------------------------------
 | |
| // Parm *ParmList::get_next()
 | |
| //
 | |
| // Returns the next item on the parameter list.
 | |
| // ----------------------------------------------------------------------
 | |
| 
 | |
| Parm * ParmList::get_next() {
 | |
|   if (current_parm >= nparms) return 0;
 | |
|   else return parms[current_parm++];
 | |
| }
 | |
| 
 | |
| // ---------------------------------------------------------------------
 | |
| // void ParmList::print_types(FILE *f)
 | |
| //
 | |
| // Prints a comma separated list of all of the parameter types.
 | |
| // This is for generating valid C prototypes.   Has to do some
 | |
| // manipulation of pointer types depending on how the call_type
 | |
| // variable has been set.
 | |
| // ----------------------------------------------------------------------
 | |
| 
 | |
| void ParmList::print_types(FILE *f) {
 | |
| 
 | |
|   int   is_pointer;
 | |
|   int   pn;
 | |
|   pn = 0;
 | |
|   while(pn < nparms) {
 | |
|     is_pointer = parms[pn]->t->is_pointer;
 | |
|     if (parms[pn]->t->is_reference) {
 | |
|       if (parms[pn]->t->is_pointer) {
 | |
| 	parms[pn]->t->is_pointer--;
 | |
| 	fprintf(f,"%s&", parms[pn]->t->print_real());
 | |
| 	parms[pn]->t->is_pointer++;
 | |
|       } else {
 | |
| 	fprintf(f,"%s&", parms[pn]->t->print_real());
 | |
|       }
 | |
|     } else {
 | |
|       if (parms[pn]->call_type & CALL_VALUE) parms[pn]->t->is_pointer++;
 | |
|       if (parms[pn]->call_type & CALL_REFERENCE) parms[pn]->t->is_pointer--;
 | |
|       fprintf(f,"%s", parms[pn]->t->print_real());
 | |
|       parms[pn]->t->is_pointer = is_pointer;
 | |
|     }
 | |
|     pn++;
 | |
|     if (pn < nparms)
 | |
|       fprintf(f,",");
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| // ---------------------------------------------------------------------
 | |
| // void ParmList::print_types(String &f)
 | |
| //
 | |
| // Generates a comma separated list of function types.   Is used in
 | |
| // C++ code generation when generating hash keys and for function overloading.
 | |
| // ----------------------------------------------------------------------
 | |
| 
 | |
| void ParmList::print_types(String &f) {
 | |
| 
 | |
|   int   is_pointer;
 | |
|   int   pn;
 | |
|   pn = 0;
 | |
|   while(pn < nparms) {
 | |
|     is_pointer = parms[pn]->t->is_pointer;
 | |
|     if (parms[pn]->t->is_reference) {
 | |
|       if (parms[pn]->t->is_pointer) {
 | |
| 	parms[pn]->t->is_pointer--;
 | |
| 	f << parms[pn]->t->print_real() << "&";
 | |
| 	parms[pn]->t->is_pointer++;
 | |
|       } else {
 | |
| 	f << parms[pn]->t->print_real() << "&";
 | |
|       }
 | |
|     } else {
 | |
|       if (parms[pn]->call_type & CALL_VALUE) parms[pn]->t->is_pointer++;
 | |
|       if (parms[pn]->call_type & CALL_REFERENCE) parms[pn]->t->is_pointer--;
 | |
|       f << parms[pn]->t->print_real();
 | |
|       parms[pn]->t->is_pointer = is_pointer;
 | |
|     }
 | |
|     pn++;
 | |
|     if (pn < nparms)
 | |
|       f << ",";
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| // ---------------------------------------------------------------------
 | |
| // void ParmList::print_args(FILE *f)
 | |
| //
 | |
| // Prints a comma separated list of all of the parameter arguments.
 | |
| // ----------------------------------------------------------------------
 | |
| 
 | |
| void ParmList::print_args(FILE *f) {
 | |
| 
 | |
|   int   is_pointer;
 | |
|   int   pn;
 | |
|   pn = 0;
 | |
|   while(pn < nparms) {
 | |
|     is_pointer = parms[pn]->t->is_pointer;
 | |
|     if (parms[pn]->t->is_reference) {
 | |
|       if (parms[pn]->t->is_pointer) {
 | |
| 	parms[pn]->t->is_pointer--;
 | |
| 	fprintf(f,"%s&", parms[pn]->t->print_full());
 | |
| 	parms[pn]->t->is_pointer++;
 | |
|       } else {
 | |
| 	fprintf(f,"%s&", parms[pn]->t->print_full());
 | |
|       }
 | |
|     } else {
 | |
|       if (parms[pn]->call_type & CALL_VALUE) parms[pn]->t->is_pointer++;
 | |
|       if (parms[pn]->call_type & CALL_REFERENCE) parms[pn]->t->is_pointer--;
 | |
|       fprintf(f,"%s", parms[pn]->t->print_full());
 | |
|       parms[pn]->t->is_pointer = is_pointer;
 | |
|     }
 | |
|     fprintf(f,"%s",parms[pn]->name);
 | |
|     pn++;
 | |
|     if (pn < nparms)
 | |
|       fprintf(f,",");
 | |
|   }
 | |
| }
 | |
| 
 | |
| // -------------------------------------------------------------------
 | |
| // int check_defined()
 | |
| //
 | |
| // Checks to see if all of the datatypes are defined.
 | |
| // -------------------------------------------------------------------
 | |
| 
 | |
| int ParmList::check_defined() {
 | |
|   int   a = 0;
 | |
|   int   i;
 | |
|   for (i = 0; i < nparms; i++) {
 | |
|     if (parms[i]) {
 | |
|       a+=parms[i]->t->check_defined();
 | |
|     }
 | |
|   }
 | |
|   if (a) return 1;
 | |
|   else return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| // -------------------------------------------------------------------
 | |
| // void ParmList::sub_parmnames(String &s)
 | |
| //
 | |
| // Given a string, this function substitutes all of the parameter
 | |
| // names with their internal representation.   Used in very special
 | |
| // kinds of typemaps.
 | |
| // -------------------------------------------------------------------
 | |
| 
 | |
| void ParmList::sub_parmnames(String &s) {
 | |
|   Parm *p;  
 | |
|   extern char *emit_local(int i);
 | |
|   for (int i = 0; i < nparms; i++) {
 | |
|     p = get(i);
 | |
|     if (strlen(p->name) > 0) {
 | |
|       s.replaceid(p->name, emit_local(i));
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
|   
 | |
| 
 | |
| 
 | |
| 
 |