/*******************************************************************************
 * Simplified Wrapper and Interface Generator  (SWIG)
 * 
 * Dave Beazley
 * 
 * Department of Computer Science        Theoretical Division (T-11)
 * University of Utah                    Los Alamos National Laboratory
 * Salt Lake City, Utah  84112           Los Alamos, New Mexico  87545
 * beazley@cs.utah.edu                   beazley@lanl.gov
 *
 * Copyright (c) 1995-1997
 * The University of Utah and the Regents of the University of California
 * All Rights Reserved
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that 
 * (1) The above copyright notice and the following two paragraphs
 * appear in all copies of the source code and (2) redistributions
 * including binaries reproduces these notices in the supporting
 * documentation.   Substantial modifications to this software may be
 * copyrighted by their authors and need not follow the licensing terms
 * described here, provided that the new terms are clearly indicated in
 * all files where they apply.
 * 
 * IN NO EVENT SHALL THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, THE 
 * UNIVERSITY OF UTAH OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY
 * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
 * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
 * EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 * THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, AND THE UNIVERSITY OF UTAH
 * SPECIFICALLY DISCLAIM ANY WARRANTIES,INCLUDING, BUT NOT LIMITED TO, 
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND 
 * THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE,
 * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 *******************************************************************************/

#include "internal.h"
/*******************************************************************************
 * $Header: /home/beazley/SWIG/SWIG1.1/SWIG/RCS/emit.cxx,v 1.50 1997/06/17 04:48:25 beazley Exp $
 *
 * 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))) {
	char *deftmp = new char [strlen(p->defvalue)+2];
	*deftmp = 0;
	sprintf(deftmp,"&%s",p->defvalue);
	f.add_local(p->t->print_type(),temp,deftmp);
	delete deftmp;
      } else {
	f.add_local(p->t->print_type(), temp, p->defvalue);
	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;
}

/*******************************************************************************
 *
 * -- Revision History
 * $Log: emit.cxx,v $
 * Revision 1.50  1997/06/17 04:48:25  beazley
 * Changed to use new naming system.
 *
 * Revision 1.49  1997/05/28 06:07:11  beazley
 * Moved revision history to end.
 *
 * Revision 1.48  1997/05/24 04:15:06  beazley
 * Added support for "build" typemap.
 *
 * Revision 1.47  1997/05/05 15:54:46  beazley
 * Added support for parameterized typemaps.
 *
 * Revision 1.46  1997/04/18 04:06:15  beazley
 * Fixed bug with default values and references.
 *
 * Revision 1.45  1997/03/16 21:25:43  beazley
 * Modified banner slightly.
 *
 * Revision 1.44  1997/03/08 19:20:27  beazley
 * Fixed a number of code generation problems related to multidimensional arrays.
 * Added an explicit type cast to function arguments involving multidimensional
 * arrays.
 *
 * Revision 1.43  1997/03/02 22:40:12  beazley
 * Changed function call code to use C++ copy constructors.
 *
 * Revision 1.42  1997/02/19 23:01:51  beazley
 * Added exception handling support.
 *
 * Revision 1.41  1997/02/16 20:15:29  beazley
 * Added support for "default" and "ignore" typemaps.
 *
 * Revision 1.40  1997/01/30 05:49:10  beazley
 * Fixed bug in global variables involving complex datatypes.
 *
 * Revision 1.39  1997/01/15 05:44:41  beazley
 * Fixed bug when emitted functions returning constant references.
 *
 * Revision 1.38  1997/01/08 18:40:51  beazley
 * Fixed some problems with const datatypes (by casting it away).
 *
 * Revision 1.37  1997/01/08 01:24:51  beazley
 * Pre 1.1b3 checkin
 *
 * Revision 1.36  1997/01/06 17:08:17  beazley
 * Cleanup. A few minor modifications
 *
 * Revision 1.35  1996/12/26 04:41:38  beazley
 * Fixed some bugs related to references
 *
 * Revision 1.34  1996/12/03 08:38:58  beazley
 * pre-1.1b2 checkin
 *
 * Revision 1.33  1996/11/12 19:49:29  beazley
 * A few minor tweaks to support the new documentation system
 *
 * Revision 1.32  1996/10/29 19:21:42  beazley
 * Fixed some things related to new parameter list handling
 *
 * Revision 1.31  1996/10/22 16:41:52  beazley
 * Took out long string constant that was causing problems under
 * certain compilers.
 *
 * Revision 1.30  1996/08/31 21:41:18  dmb
 * Minor fix to emit_hex()
 *
 * Revision 1.29  1996/08/29 17:13:14  dmb
 * Whoops, didn't quite nail it....
 *
 * Revision 1.28  1996/08/29 17:07:08  dmb
 * Fixed bug in return type.
 *
 * Revision 1.27  1996/08/27 22:58:44  dmb
 * Took out #line directives
 *
 * Revision 1.26  1996/08/21 16:48:40  dmb
 * Minor cleanup to eliminate compiler warnings.
 *
 * Revision 1.25  1996/08/21 05:47:32  dmb
 * Minor changes to clean things up
 *
 * Revision 1.24  1996/08/12 01:47:54  dmb
 * Many changes to fix C++ references.  Also added some code in support
 * of new wrapper coding style.
 *
 * Revision 1.23  1996/08/02 02:59:12  dmb
 * Changed to use better parameter list functions
 *
 * Revision 1.22  1996/08/01 16:46:27  dmb
 * Removed unused variable "dt" from emit_hex function.
 *
 * Revision 1.21  1996/07/23 14:39:33  dmb
 * Minor change to pointer handling
 *
 * Revision 1.20  1996/07/17 15:46:55  dmb
 * Whoops. Didn't quite do it right last time.
 *
 * Revision 1.19  1996/07/17 15:43:24  dmb
 * Changed hex-emit code.
 *
 * Revision 1.18  1996/06/20 18:27:56  dmb
 * Fixed bug in get/set function
 *
 * Revision 1.17  1996/06/18 15:33:13  dmb
 * Fixed string constant bugs with SPARCWorks compiler
 *
 * Revision 1.16  1996/06/10 23:33:56  beazley
 * Added const to hex functions.
 *
 * Revision 1.15  1996/06/02  00:14:04  beazley
 * Fixed bug with C++ references.
 *
 * Revision 1.14  1996/05/22  20:20:21  beazley
 * Minor changes
 *
 * Revision 1.13  1996/05/20  23:35:18  beazley
 * Added a few things to help support C++
 *
 * Revision 1.12  1996/05/17  05:52:50  beazley
 * Added set/get functions.  Changed emit_hex() function to include
 * C++ support.
 *
 * Revision 1.11  1996/05/14  23:23:34  beazley
 * A few minor fixes to emit_hex()
 *
 * Revision 1.10  1996/05/13  23:43:53  beazley
 * Modified the emit_hex() function to look for an input file
 * (allowing the user to redefine the pointer conversions).
 *
 * Revision 1.9  1996/04/14  15:24:03  dmb
 * Fixed headers.
 *
 * Revision 1.8  1996/03/28 02:46:00  beazley
 * Made a few slight changes to support bug fix in %typedef declaration.
 *
 * Revision 1.7  1996/03/24  22:14:09  beazley
 * Changed pointer/hex functions to use "NULL" for 0 pointer instead of 0.
 *
 * Revision 1.6  1996/03/22  23:40:07  beazley
 * A few minor changes. Cleaned some stuff up.
 *
 * Revision 1.5  1996/03/16  06:25:44  beazley
 * Major revision. Cleaned up functions.  Added type checking
 * to hex conversion functions.
 *
 * Revision 1.4  1996/03/04  21:28:05  beazley
 * Add typename to hex conversion functions.
 *
 * Revision 1.3  1996/02/19  05:31:49  beazley
 * Added function to emit hexadecimal conversions.
 *
 * Revision 1.2  1996/02/15  22:37:24  beazley
 * Changed copyright.   A few minor fixes.
 *
 * Revision 1.1  1996/02/07  05:25:24  beazley
 * Initial revision
 *
 *
 *******************************************************************************/
	 
  





syntax highlighted by Code2HTML, v. 0.9.1