--- /dev/null
+/*******************************************************************************
+ * 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));
+ }
+ }
+}
+
+
+
+
+