]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/wxSWIG/SWIG/emit.cxx
Since I have made several changes to SWIG over the years to accomodate
[wxWidgets.git] / wxPython / wxSWIG / SWIG / emit.cxx
diff --git a/wxPython/wxSWIG/SWIG/emit.cxx b/wxPython/wxSWIG/SWIG/emit.cxx
new file mode 100644 (file)
index 0000000..57f67af
--- /dev/null
@@ -0,0 +1,829 @@
+/*******************************************************************************
+ * 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"
+/*******************************************************************************
+ * $Header$
+ *
+ * File : emit.cxx
+ *
+ * This file contains some useful functions for emitting code that would be
+ * common to all of the interface languages.  Mainly this function deals with
+ * declaring functions external, creating lists of arguments, and making
+ * function calls.
+ *******************************************************************************/
+
+// -----------------------------------------------------------------------------
+// void emit_banner(FILE *f)
+// 
+// Emits the SWIG identifying banner in the wrapper file
+//
+// Inputs : f   = FILE handle
+//
+// Output : None
+//
+// Side Effects : None
+// -----------------------------------------------------------------------------
+
+void emit_banner(FILE *f) {
+
+  extern char *get_time();
+  extern char fn_header[];
+
+  fprintf(f,
+"/*\n\
+ * FILE : %s\n\
+ * \n\
+ * This file was automatically generated by :\n\
+ * Simplified Wrapper and Interface Generator (SWIG)\n\
+ * Version %d.%d %s\n\
+ * \n\
+ * Portions Copyright (c) 1995-1998\n\
+ * The University of Utah and The Regents of the University of California.\n\
+ * Permission is granted to distribute this file in any manner provided\n\
+ * this notice remains intact.\n\
+ * \n\
+ * Do not make changes to this file--changes will be lost!\n\
+ *\n\
+ */\n\n", fn_header, SWIG_MAJOR_VERSION, SWIG_MINOR_VERSION, SWIG_SPIN);
+
+  fprintf(f,"\n#define SWIGCODE\n");
+
+}
+
+// -----------------------------------------------------------------------------
+// emit_extern_var(char *decl, DataType *t, int extern_type, FILE *f)
+// 
+// Emits an external variables declaration.   Extern_type defines the
+// type of external declaration.  Currently, only C/C++ declarations
+// are allowed, but this might be extended to allow Fortran linkage
+// someday
+//
+// Inputs :
+//          decl        = Name of the declaration
+//          t           = Datatype
+//          extern_type = Numeric code indicating type of extern
+//                              0   - No "extern"
+//                              1,2 -  Normal extern (C/C++)
+//          f           = FILE handle
+//
+// Output : None
+//
+// Side Effects : None
+// -----------------------------------------------------------------------------
+
+void emit_extern_var(char *decl, DataType *t, int extern_type, FILE *f) {
+  char *arr = 0;
+
+  if (t->arraystr) arr = t->arraystr;
+  else arr = "";
+
+  switch(extern_type) {
+
+  case 0:
+    // No extern.  Just a forward reference
+    if (t->arraystr)
+      t->is_pointer--;
+
+    if (t->is_reference) {
+      t->is_pointer--;
+      fprintf(f,"%s& %s%s; \n", t->print_full(), decl, arr);
+      t->is_pointer++;
+    } else {
+      fprintf(f,"%s %s%s; \n", t->print_full(), decl,arr);
+    }
+    if (t->arraystr)
+      t->is_pointer++;
+    break;
+  case 1: case 2:
+    if (t->arraystr)
+      t->is_pointer--;
+
+    // Normal C/C++ extern
+//    fprintf(f,"#line %d \"%s\"\n", line_number, input_file);
+    if (t->is_reference) {
+      t->is_pointer--;
+      fprintf(f,"extern %s& %s%s; \n", t->print_full(), decl,arr);
+      t->is_pointer++;
+    } else {
+      fprintf(f,"extern %s %s%s; \n", t->print_full(), decl,arr);
+    }
+    if (t->arraystr)
+      t->is_pointer++;
+
+  default:
+    break;
+  }
+}
+
+// -----------------------------------------------------------------------------
+// emit_extern_func(char *decl, DataType *t, ParmList *L, int extern_type,
+//                  FILE *f)
+//
+// Emits an external function declaration (similiar to emit_extern_var).
+// 
+// Inputs : 
+//          decl        = Name of declaration
+//          t           = Return datatype
+//          L           = parameter list
+//          extern_type = Type of extern
+//                           0 - No "extern"
+//                           1 - extern
+//                           2 - extern "C"
+//                           3 - Function declaration (with arg names)
+//          f           = FILE Handle
+//
+// Output : None
+//
+// Side Effects : None
+// 
+// -----------------------------------------------------------------------------
+
+void emit_extern_func(char *decl, DataType *t, ParmList *L, int extern_type, FILE *f) {
+
+  switch(extern_type) {
+  case 0:
+    if (t->is_reference) {
+       t->is_pointer--;
+       fprintf(f,"%s&", t->print_full());
+       t->is_pointer++;
+    } else {
+      fprintf(f,"%s", t->print_full());
+    }
+    
+    fprintf(f,"%s(", decl);
+    L->print_types(f);
+    fprintf(f,");\n");
+    break;
+  case 1:
+    // Normal C/C++ extern
+//    fprintf(f,"#line %d \"%s\"\n", line_number, input_file);
+    if (t->is_reference) {
+       t->is_pointer--;
+       fprintf(f,"extern %s&", t->print_full());
+       t->is_pointer++;
+    } else {
+      fprintf(f,"extern %s", t->print_full());
+    }
+    fprintf(f,"%s(", decl);
+    L->print_types(f);
+    fprintf(f,");\n");
+    break;
+  case 2:
+    // A C++ --- > C Extern
+//    fprintf(f,"#line %d \"%s\"\n", line_number, input_file);
+    if (t->is_reference) {
+       t->is_pointer--;
+       fprintf(f,"extern \"C\" %s&", t->print_full());
+       t->is_pointer++;
+    } else {
+      fprintf(f,"extern \"C\" %s", t->print_full());
+    }
+    fprintf(f,"%s(", decl);
+    L->print_types(f);
+    fprintf(f,");\n");
+    break;
+  case 3:
+    // A function declaration (for inlining )
+    if (t->is_reference) {
+       t->is_pointer--;
+       fprintf(f,"%s&", t->print_full());
+       t->is_pointer++;
+    } else {
+      fprintf(f,"%s", t->print_full());
+    }
+    
+    fprintf(f,"%s(", decl);
+    L->print_args(f);
+    fprintf(f,")\n");
+    break;
+  default:
+    break;
+  }
+}  
+
+// -----------------------------------------------------------------------------
+// char *emit_local(int i)
+//
+// Returns the name of local variable for parameter i
+//
+// Inputs : i      = Parameter number
+//
+// Output : NULL terminated ASCII string
+//
+// Side Effects : Result is left in a static local variable.
+// -----------------------------------------------------------------------------
+
+char *emit_local(int i) {
+  static char arg[64];
+
+  sprintf(arg,"_arg%d", i);
+  return arg;
+}
+
+// -----------------------------------------------------------------------------
+// int emit_args(char *d, DataType *rt, ParmList *l, FILE *f)
+//
+// Creates a list of variable declarations for both the return value
+// and function parameters.
+//
+// The return value is always called _result and arguments label as
+// _arg0, _arg1, _arg2, etc...
+//
+// Returns the number of parameters associated with a function.
+// 
+// Inputs :
+//          d     = Name of function
+//          rt    = Return type
+//          l     = Parameter list
+//          f     = FILE Handle
+//
+// Output : Number of function arguments 
+//
+// Side Effects : None
+//
+// Note : This function is obsolete.  Use emit_args below...
+// -----------------------------------------------------------------------------
+
+int emit_args(DataType *rt, ParmList *l, FILE *f) {
+
+  Parm *p;
+  int   i;
+  char  temp[64];
+  String def;
+  char  *tm;
+
+  // Declare the return variable
+
+  if ((rt->type != T_VOID) || (rt->is_pointer)) {
+    if ((rt->type == T_USER) && (!rt->is_pointer)) {
+
+      // Special case for return by "value"
+
+      rt->is_pointer++;
+      fprintf(f,"\t %s _result;\n", rt->print_type());
+      rt->is_pointer--;
+    } else {
+
+      // Normal return value
+
+      fprintf(f,"\t %s _result;\n", rt->print_type());
+    }
+  }
+
+  // Emit function arguments
+
+  i = 0;
+  p = l->get_first();
+  while (p != 0) {
+    if ((p->t->type != T_VOID) || (p->t->is_pointer))  {
+      sprintf(temp,"_arg%d", i);
+      if (p->defvalue) {
+       if ((p->t->is_reference) || ((p->t->type == T_USER) && (p->call_type == CALL_REFERENCE)))
+           fprintf(f,"\t %s _arg%d = &%s;\n", p->t->print_type(),i, p->defvalue);
+         else  
+           fprintf(f,"\t %s _arg%d = %s;\n", p->t->print_type(),i, p->defvalue);
+      } else {
+       fprintf(f,"\t %s _arg%d;\n", p->t->print_type(),i);
+       tm = typemap_lookup("arginit", typemap_lang, p->t, p->name,"",temp);
+       if (tm) {
+         def << tm;
+       }
+      }
+
+      // Check for ignore or default typemaps
+      
+      tm = typemap_lookup("default",typemap_lang,p->t,p->name,"",temp);
+      if (tm) 
+       def << tm;
+      tm = typemap_lookup("ignore",typemap_lang,p->t,p->name,"",temp);
+
+      if (tm) {
+       def << tm;
+       p->ignore = 1;
+      }
+      tm = typemap_check("build",typemap_lang,p->t,p->name);
+      if (tm) {
+       p->ignore = 1;
+      }
+      i++;
+    }
+    p = l->get_next();
+  }
+
+  fprintf(f,"%s",def.get());
+
+  // i now contains number of parameters
+  
+  return(i);
+
+ }
+
+
+// -----------------------------------------------------------------------------
+// int emit_args(char *d, DataType *rt, ParmList *l, WrapperFunction &f)
+//
+// Creates a list of variable declarations for both the return value
+// and function parameters.
+//
+// The return value is always called _result and arguments label as
+// _arg0, _arg1, _arg2, etc...
+//
+// Returns the number of parameters associated with a function.
+// 
+// Inputs :
+//          d     = Name of function
+//          rt    = Return type
+//          l     = Parameter list
+//          f     = Wrapper function object
+//
+// Output : Number of function arguments 
+//
+// Side Effects : None
+//
+// -----------------------------------------------------------------------------
+
+int emit_args(DataType *rt, ParmList *l, WrapperFunction &f) {
+
+  Parm *p;
+  int   i;
+  char *tm;
+
+  // Declare the return variable
+
+  if ((rt->type != T_VOID) || (rt->is_pointer)) {
+    if ((rt->type == T_USER) && (!rt->is_pointer)) {
+
+      // Special case for return by "value"
+      rt->is_pointer++;
+      f.add_local(rt->print_type(), "_result");
+      rt->is_pointer--;
+    } else {
+
+      // Normal return value
+
+      f.add_local(rt->print_type(), "_result");
+    }
+  }
+
+  // Emit function arguments
+
+  i = 0;
+  p = l->get_first();
+  while (p != 0) {
+    if ((p->t->type != T_VOID) || (p->t->is_pointer))  {
+      char *temp = emit_local(i);
+      // Figure out default values
+      if (((p->t->is_reference) && (p->defvalue)) || 
+         ((p->t->type == T_USER) && (p->call_type == CALL_REFERENCE) && (p->defvalue))) {
+       String deftmp;
+       deftmp << "(" << p->t->print_type() << ") &" << p->defvalue;
+       f.add_local(p->t->print_type(),temp,deftmp.get());
+      } else {
+       String deftmp;
+       char *dv = 0;
+       if (p->defvalue) {
+         deftmp << "(" << p->t->print_type() << ") " << p->defvalue;
+         dv = deftmp.get();
+       }
+       f.add_local(p->t->print_type(), temp, dv);
+       tm = typemap_lookup("arginit", typemap_lang, p->t,p->name,"",temp,&f);
+       if (tm) {
+         f.code << tm << "\n";
+       }
+      }
+      // Check for ignore or default typemaps
+      tm = typemap_lookup("default",typemap_lang,p->t,p->name,"",temp,&f);
+      if (tm) 
+       f.code << tm << "\n";
+      tm = typemap_lookup("ignore",typemap_lang,p->t,p->name,"",temp,&f);
+      if (tm) {
+       f.code << tm << "\n";
+       p->ignore = 1;
+      }
+      tm = typemap_check("build",typemap_lang,p->t,p->name);
+      if (tm) {
+       p->ignore = 1;
+      }
+      i++;
+    }
+    p = l->get_next();
+  }
+
+  // i now contains number of parameters
+  return(i);
+}
+
+// -----------------------------------------------------------------------------
+// int emit_func_call(char *decl, DataType *t, ParmList *l, FILE *f)
+//
+// Emits code for a function call.
+// 
+// Inputs :
+//           decl   = name of function
+//           t      = Return datatype
+//           l      = Parameter list
+//           f      = FILE Handle
+//
+// Output : None
+//
+// Side Effects : None
+//
+// Note : This function is obsolete
+// -----------------------------------------------------------------------------
+
+void emit_func_call(char *decl, DataType *t, ParmList *l, FILE *f) {
+
+  int  i;
+  Parm  *p;
+
+//  fprintf(f,"#line %d \"%s\"\n", line_number, input_file);
+  fprintf(f,"\t ");
+
+  // First check if there is a return value
+
+  if ((t->type != T_VOID) || (t->is_pointer)) {
+    if ((t->type == T_USER) && (!t->is_pointer)) {
+
+      // Special case for return by "value"
+      // Caution : This *will* cause a memory leak if not
+      // used properly.
+
+      if (CPlusPlus) {
+       fprintf(f,"_result = new %s(", t->print_type());
+      } else {
+       t->is_pointer++;
+       fprintf(f,"_result = %s malloc(sizeof(", t->print_cast());
+       t->is_pointer--;
+       fprintf(f,"%s));\n", t->print_type());
+       fprintf(f,"\t*(_result) = ");
+      }
+    } else {
+      // Check if this is a C++ reference
+      if (t->is_reference) {
+       t->is_pointer--;
+       fprintf(f,"%s& _result_ref = ", t->print_full());
+       t->is_pointer++;
+      } else {
+       
+      // Normal return values
+       fprintf(f,"_result = %s", t->print_cast());
+      }
+    }
+  }
+
+  // Now print out function call
+
+  fprintf(f,"%s(",decl);
+
+  i = 0;
+  p = l->get_first();
+  while(p != 0) {
+    if ((p->t->type != T_VOID) || (p->t->is_pointer)){
+      fprintf(f,"%s",p->t->print_arraycast());
+      if ((!p->t->is_reference) && (p->call_type & CALL_VALUE)) fprintf(f,"&");
+      if ((!(p->call_type & CALL_VALUE)) &&
+         ((p->t->is_reference) || (p->call_type & CALL_REFERENCE)))
+       fprintf(f,"*");
+      fprintf(f,"_arg%d",i);
+      i++;
+    }
+    p = l->get_next();
+    if (p != 0)
+      fprintf(f,",");
+  }
+
+  fprintf(f,")");
+  if ((t->type == T_USER) && (!t->is_pointer)) {
+    if (CPlusPlus) {
+      fprintf(f,")");
+    }
+  }
+  fprintf(f,";\n");
+  if (t->is_reference) {
+    fprintf(f,"\t _result = %s &_result_ref;\n", t->print_cast());
+  }
+}
+
+
+
+// -----------------------------------------------------------------------------
+// int emit_func_call(char *decl, DataType *t, ParmList *l, WrapperFunction &f)
+//
+// Emits code for a function call (new version).
+// 
+// Exception handling support :
+//
+//     -  This function checks to see if any sort of exception mechanism
+//        has been defined.  If so, we emit the function call in an exception
+//        handling block.
+//
+// Inputs :
+//           decl   = name of function
+//           t      = Return datatype
+//           l      = Parameter list
+//           f      = WrapperFunction object
+//
+// Output : None
+//
+// Side Effects : None
+//
+// -----------------------------------------------------------------------------
+
+void emit_func_call(char *decl, DataType *t, ParmList *l, WrapperFunction &f) {
+
+  int  i;
+  Parm  *p;
+  String fcall;
+  String exc;
+  char *tm;
+
+//  f.code << "#line " << line_number << " \"" << input_file << "\"\n";
+  fcall << tab4;
+
+  // First check if there is a return value
+
+  if ((t->type != T_VOID) || (t->is_pointer)) {
+    if ((t->type == T_USER) && (!t->is_pointer)) {
+
+      // Special case for return by "value"
+      // Caution : This *will* cause a memory leak if not
+      // used properly.
+
+      if (CPlusPlus) {
+       fcall << "_result = new " << t->print_type() << "(";
+      } else {
+       t->is_pointer++;
+       fcall << "_result = " << t->print_cast() << " malloc(sizeof(";
+       t->is_pointer--;
+       fcall << t->print_type() << "));\n";
+       fcall << tab4 << "*(_result) = ";
+      }
+    } else {
+      // Check if this is a C++ reference
+      if (t->is_reference) {
+       t->is_pointer--;
+       fcall << t->print_full() << "& _result_ref = ";
+       t->is_pointer++;
+      } else {
+
+       // Normal return value
+       fcall << "_result = " << t->print_cast();
+      }
+    }
+  }
+
+  // Now print out function call
+
+  fcall << decl << "(";
+
+  i = 0;
+  p = l->get_first();
+  while(p != 0) {
+    if ((p->t->type != T_VOID) || (p->t->is_pointer)){
+      fcall << p->t->print_arraycast();
+      if ((!p->t->is_reference) && (p->call_type & CALL_VALUE))
+       fcall << "&";
+      if ((!(p->call_type & CALL_VALUE)) &&
+         ((p->t->is_reference) || (p->call_type & CALL_REFERENCE)))
+       fcall << "*";
+      fcall << emit_local(i);
+      i++;
+    }
+    p = l->get_next();
+    if (p != 0)
+      fcall << ",";
+  }
+  fcall << ")";
+
+  if ((t->type == T_USER) && (!t->is_pointer)) {
+    if (CPlusPlus) {
+      fcall << ")";
+    }
+  }
+  fcall << ";\n";
+
+  if (t->is_reference) {
+    fcall << tab4 << "_result = "<< t->print_cast() << " &_result_ref;\n";
+  }
+  // Check for exception handling
+
+  if ((tm = typemap_lookup("except",typemap_lang,t,decl,"_result",""))) {
+    // Found a type-specific mapping
+    exc << tm;
+    exc.replace("$function",fcall);
+    exc.replace("$name",decl);
+    f.code << exc;
+  } else if ((tm = fragment_lookup("except",typemap_lang, t->id))) {
+    exc << tm;
+    exc.replace("$function",fcall);
+    exc.replace("$name",decl);
+    f.code << exc;
+  } else {
+    f.code << fcall;
+  }
+}
+
+// -----------------------------------------------------------------------------
+// void emit_hex(FILE *f)
+// 
+// Emits the default C-code to handle pointers.   This is normally contained
+// in the SWIG library file 'swigptr.swg'
+//
+// Inputs : f   = FILE handle
+//
+// Output : None
+//
+// Side Effects : None
+// -----------------------------------------------------------------------------
+
+void emit_hex(FILE *f) {
+  
+  int stat;
+
+   // Look for a pointer configuration file
+
+   stat = insert_file("swigptr.swg", f);
+
+   if (stat == -1) {
+     fprintf(stderr,"** Fatal error.  Unable to locate 'swigptr.swg'\n");
+     SWIG_exit(1);
+   }
+}
+
+// -----------------------------------------------------------------------------
+// void emit_set_get(char *name, char *iname, DataType *type)
+//
+// Emits a pair of functions to set/get the value of a variable.
+// This should be used as backup in case the target language can't
+// provide variable linking.
+// 
+// double foo;
+//
+// Gets translated into the following :
+//
+// double foo_set(double x) {
+//      return foo = x;
+// }
+//
+// double foo_get() {
+//      return foo;
+// }
+//
+// Need to handle special cases for char * and for user
+// defined types. 
+//
+// 1.  char *
+//
+//     Will free previous contents (if any) and allocate
+//     new storage.   Could be risky, but it's a reasonably
+//     natural thing to do.
+//
+// 2.  User_Defined
+//     Will assign value from a pointer. 
+//     Will return a pointer to current value.
+// 
+// 
+// Inputs :
+//          name    = Name of variable
+//          iname   = Renamed version of variable
+//          type    = Datatype of the variable
+//
+// Output : None
+//
+// Side Effects : None
+// -----------------------------------------------------------------------------
+
+void emit_set_get(char *name, char *iname, DataType *t) {
+
+    Parm *p;
+    ParmList *l;
+    String new_name;
+    String new_iname;
+    String wname;
+
+    // First write a function to set the variable of the variable
+
+    if (!(Status & STAT_READONLY)) {
+      if ((t->type == T_USER) && (!t->is_pointer)) {
+       t->is_pointer++;
+       fprintf(f_header,"static %s %s(%s val) {\n",
+               t->print_type(), name_set(name), t->print_type());
+       t->is_pointer--;
+      } else {
+       fprintf(f_header,"static %s %s(%s val) {\n",
+               t->print_type(), name_set(name), t->print_type());
+      }
+      
+      if ((t->type != T_VOID) || (t->is_pointer)) {
+       if (!t->is_pointer) {
+         
+         // Have a real value here 
+         // If it's a user defined type, we'll do something special.
+         // Otherwise, just assign it.
+         
+         if (t->type != T_USER) {
+           fprintf(f_header,"\t return (%s) (%s = val);\n", t->print_type(), name);
+         } else {
+           fprintf(f_header,"\t %s = *(val);\n", name);
+           t->is_pointer++;
+           fprintf(f_header,"\t return (%s) &%s;\n", t->print_type(),name);
+           t->is_pointer--;
+         }
+       } else {
+         
+         // Is a pointer type here.  If string, we do something
+         // special.  Otherwise. No problem.
+         
+         if ((t->type == T_CHAR) && (t->is_pointer == 1)) {
+           if (CPlusPlus) {
+             fprintf(f_header,"\t if (%s) delete %s;\n", name,name);
+             fprintf(f_header,"\t %s = new char[strlen(val)+1];\n",name);
+             fprintf(f_header,"\t strcpy(%s,val);\n", name);
+             fprintf(f_header,"\t return %s;\n", name);
+           } else {
+             fprintf(f_header,"\t if (%s) free(%s);\n", name,name);
+             fprintf(f_header,"\t %s = (char *) malloc(strlen(val)+1);\n",name);
+             fprintf(f_header,"\t strcpy(%s,val);\n", name);
+             fprintf(f_header,"\t return %s;\n", name);
+           }
+         } else {
+           fprintf(f_header,"\t return (%s) (%s = val);\n", t->print_type(), name);
+         }
+       }
+      }
+
+      fprintf(f_header,"}\n");
+
+      // Now wrap it.
+
+      l = new ParmList;
+      p = new Parm(t,0);
+      if ((t->type == T_USER) && (!t->is_pointer)) p->t->is_pointer++;
+      p->name = new char[1];
+      p->name[0] = 0;
+      l->append(p);
+      
+      new_name = name_set(name);
+      new_iname = name_set(iname);
+      
+      if ((t->type == T_USER) && (!t->is_pointer)) {
+       t->is_pointer++;
+       lang->create_function(new_name, new_iname, t, l);
+       t->is_pointer--;
+      } else {
+       lang->create_function(new_name, new_iname, t, l);
+      }
+      delete l;
+      delete p;
+      if (doc_entry) doc_entry->usage << "\n";
+    }
+
+    // Now write a function to get the value of the variable
+
+    if ((t->type == T_USER) && (!t->is_pointer)) {
+      t->is_pointer++;
+      fprintf(f_header,"static %s %s() { \n",
+             t->print_type(), name_get(name));
+      fprintf(f_header,"\t return (%s) &%s;\n", t->print_type(), name);
+      t->is_pointer--;
+    } else {
+      fprintf(f_header,"static %s %s() { \n",
+             t->print_type(), name_get(name));
+      fprintf(f_header,"\t return (%s) %s;\n", t->print_type(), name);
+    }
+
+    fprintf(f_header,"}\n");
+    
+    // Wrap this function
+
+    l = new ParmList;
+
+    new_name = name_get(name);
+    new_iname = name_get(iname);
+
+    if ((t->type == T_USER) && (!t->is_pointer)) {
+      t->is_pointer++;
+      lang->create_function(new_name, new_iname, t, l);
+      t->is_pointer--;
+    } else {
+      lang->create_function(new_name, new_iname, t, l);
+    }
+    delete l;
+}
+  
+
+
+