 /*
  * Khoros: $Id: routines.c,v 1.1 1991/05/10 15:41:00 khoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: routines.c,v 1.1 1991/05/10 15:41:00 khoros Exp $";
#endif

 /*
  * $Log: routines.c,v $
 * Revision 1.1  1991/05/10  15:41:00  khoros
 * Initial revision
 *
  */ 

/*
 *----------------------------------------------------------------------
 *
 * Copyright 1990, University of New Mexico.  All rights reserved.
 * 
 * Permission to copy and modify this software and its documen-
 * tation only for internal use in your organization is hereby
 * granted, provided that this notice is retained thereon and
 * on all copies.  UNM makes no representations as too the sui-
 * tability and operability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 * 
 * UNM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
 * NESS.  IN NO EVENT SHALL UNM BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY OTHER DAMAGES WHAT-
 * SOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PER-
 * FORMANCE OF THIS SOFTWARE.
 * 
 * No other rights, including for example, the right to redis-
 * tribute this software and its documentation or the right to
 * prepare derivative works, are granted unless specifically
 * provided in a separate license agreement.
 *----------------------------------------------------------------------
 */

#include "unmcopyright.h"	 /* Copyright 1990 by UNM */
#include "expr.h"
#include "y.tab.h"

/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>								<<<<
   >>>>	    	    file name: routines.c			<<<<
   >>>>								<<<<
   >>>>		Various Public Utility Routines			<<<<
   >>>>		For the xvexpr Library				<<<<
   >>>>								<<<<
   >>>>             xve_init()					<<<<
   >>>>             xve_eval_int()				<<<<
   >>>>             xve_eval_float()				<<<<
   >>>>             xve_eval_string()				<<<<
   >>>>								<<<<
   >>>>             xve_set_parent()				<<<<
   >>>>             xve_unset_parent()				<<<<
   >>>>             xve_list_variables()			<<<<
   >>>>             xve_copy_variables()			<<<<
   >>>>             xve_clear_variables()			<<<<
   >>>>             xve_delete_variables()			<<<<
   >>>>								<<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */



/************************************************************
*
*  Routine Name: xve_init()
*
*       Purpose: initializes the xvexpr parser.  This call is
*		 used to initialize the constants, functions, and
*		 global varlists.
*
*        Input:  none
*
*       Output:  none - initializes varlists
*
*   Written By:  Mark Young
*
*
************************************************************/


xve_init()
{
	int	i;
	Symbol  *symbol;
	Varlist *varlist;


	/*
	 * Install the varlist for Constants, Functions, and Global
	 * variables.
	 */
	if ((varlist = _xve_get_varlist(CONSTANT_ID)) != NULL)
	{
	   for (i = 0; constants[i].name != NULL; i++)
	   {
	       (void) _xve_add_symbol(varlist, constants[i].name, CONSTANT,
			       constants[i].value);
	   }
	}

	if ((varlist = _xve_get_varlist(FUNCTION_ID)) != NULL)
	{
	   for (i = 0; functions[i].name != NULL; i++)
	   {
	       symbol = _xve_add_symbol(varlist, functions[i].name, FUNCTION,
				0.0);
	       symbol->num     = functions[i].num_args;
	       symbol->Function = functions[i].routine;
	   }
	}

	/*
	 *  Create the global variable list.
	 */
	(void) _xve_get_varlist(GLOBAL_ID);
}



/************************************************************
*
*  Routine Name: xve_eval_int()
*
*       Purpose: evaluates the string and returns the value
*		 of that expression.
*
*        Input:  id     - the variable identifier 
*		 string - the string to be evaluated
*
*       Output:  value  - if no error occurred then the integer
*			  value of the expression is stored and
*			  True returned.
*
*		 error  - if an error occurred the message is
*			  stored in the string array and False
*			  returned.  If this field is NULL then
*			  the error message is printed to stderr.
*
*   Written By:  Mark Young
*
*
************************************************************/


int xve_eval_int(id, string, value, error)

long	id;
int	*value;
char	*string, *error;
{
	int   status;

	_xve_set_value();
	status = _xve_eval_expression(id, string, error);
	if (value != NULL) *value = FinalValue.Value;
	return(status);
}



/************************************************************
*
*  Routine Name: xve_eval_float()
*
*       Purpose: evaluates the string and returns the value
*		 of that expression.
*
*        Input:  id     - the variable identifier 
*		 string - the string to be evaluated
*
*       Output:  value  - if no error occurred then the float
*			  value of the expression is stored and
*			  True returned.
*
*		 error  - if an error occurred the message is
*			  stored in the string array and False
*			  returned.  If this field is NULL then
*			  the error message is printed to stderr.
*
*   Written By:  Mark Young
*
*
************************************************************/


int xve_eval_float(id, string, value, error)

long	id;
float	*value;
char	*string, *error;
{
	int   status;

	_xve_set_value();
	status = _xve_eval_expression(id, string, error);
	if (value != NULL) *value = FinalValue.Value;
	return(status);
}



/************************************************************
*
*  Routine Name: xve_eval_string()
*
*       Purpose: evaluates the string and returns the value
*		 of that expression.
*
*        Input:  id     - the variable identifier 
*		 string - the string to be evaluated
*
*       Output:  value  - if no error occurred then the string
*			  value of the expression is stored and
*			  True returned.
*
*		 error  - if an error occurred the message is
*			  stored in the string array and False
*			  returned.  If this field is NULL then
*			  the error message is printed to stderr.
*
*   Written By:  Mark Young
*
*
************************************************************/


int xve_eval_string(id, string, value, error)

long id;
char *value;
char *string, *error;
{
	int   status;

	if (VStrlen(string) == 0)
	{
	   strcpy(value,"");
	   return(TRUE);
	}

	_xve_set_string();
	status = _xve_eval_expression(id, string, error);
	if (status == TRUE && value != NULL)
	{
	   if (FinalValue.type == STRING && FinalValue.String != NULL)
	      strcpy(value, FinalValue.String);
	   else if (FinalValue.type == NUMBER)
	      sprintf(value, "%g", FinalValue.Value);
	}
	return(status);
}



/************************************************************
*
*  Routine Name: xve_set_parent()
*
*       Purpose: This routine sets the child alternate varlist
*		 specified by the parent id.  This variable list
*		 will be searched when a variable is not found in
*		 the current variable list.  If the parent's varlist
*		 "parent" is set then the procedure is repeated
*		 until either the variable is found or no more
*		 varlists are available to search.
*
*        Input:  id   - the variable list identifier in which
*			we are to unset the parent varlist.
*
*       Output:  value  - if no error occurred then the integer
*			  value of the expression is stored and
*			  True returned.
*
*		 error  - if an error occurred the message is
*			  stored in the string array and False
*			  returned.  If this field is NULL then
*			  the error message is printed to stderr.
*
*   Written By:  Mark Young
*
*
************************************************************/


int xve_set_parent(id, parent)

long  id, parent;
{
	Varlist *varlist, *parlist;


	/*
	 *  Get the child's variable list.
	 */
	if ((varlist = _xve_get_varlist(id)) == NULL)
	{
	   fprintf(stderr,"Unable to get list for child id (%d)\n", id);
	   return(FALSE);
	}

	/*
	 *  Get the parents's variable list.
	 */
	if ((parlist = _xve_get_varlist(parent)) == NULL)
	{
	   fprintf(stderr,"Unable to get list for parent id (%d)\n", parent);
	   return(FALSE);
	}

	/*
	 *  Set the child's parent list to be that of the parent.
	 */
	varlist->parent = parlist;
	return(TRUE);
}



/************************************************************
*
*  Routine Name: xve_unset_parent()
*
*       Purpose: This routine unsets the parent varlist.  That way
*		 if a variable is not found no other variable list
*		 will be checked.
*
*        Input:  id   - the variable list identifier in which
*			we are to unset the parent varlist.
*
*       Output:  value  - if no error occurred then the integer
*			  value of the expression is stored and
*			  True returned.
*
*		 error  - if an error occurred the message is
*			  stored in the string array and False
*			  returned.  If this field is NULL then
*			  the error message is printed to stderr.
*
*   Written By:  Mark Young
*
*
************************************************************/


int xve_unset_parent(id)

long  id;
{
	Varlist *varlist;


	/*
	 *  Get the child's variable list.
	 */
	if ((varlist = _xve_get_varlist(id)) == NULL)
	{
	   fprintf(stderr,"Unable to get list for child id (%d)\n", id);
	   return(FALSE);
	}

	/*
	 *  Set the child's parent list to be NULL
	 */
	varlist->parent = NULL;
	return(TRUE);
}



/************************************************************
*
*  Routine Name: xve_list_variables()
*
*       Purpose: lists the variables for the specified id.
*
*        Input:  id   - the list of id from which we will list 
*			current variables.
*		 file - the FILE pointer in which we will print
*			this information to
*
*       Output:  returns the TRUE or FALSE if we were able
*		 to list the workspace.
*
*   Written By:  Mark Young
*
*
************************************************************/


int xve_list_variables(id, file)

long id;
FILE *file;
{
	Varlist    *varlist;
	Symbol     *symbol;
	SymbolList *symlist;


	/*
	 * Check to see if it is a current variable list.
	 */
	fprintf(file,"\n\n");
	if ((varlist = _xve_get_varlist(id)) != NULL)
	{
	   symlist = varlist->symlist;
	   if (symlist == NULL)
	   {
	      fprintf(file,"\n# No variables currently declared. #\n\n");
	      return(TRUE);
	   }

	   fprintf(file,"#\n# list of currently declared variables\n#\n\n");
	   while (symlist != NULL)
	   {
	      symbol = symlist->symbol;
	      _xve_print_symbol(file, symbol, FALSE);
	      symlist = symlist->next;
	   }
	   fprintf(file,"\n");
	}
	else
	{
	   fprintf(file,"\n\n# Error! Unable to retrieve expressions. #\n\n");
	   return(FALSE);
	}
	return(TRUE);
}



/************************************************************
*
*  Routine Name: xve_copy_variables()
*
*       Purpose: copies the variables from one id to another.
*
*        Input:  from   - the list of id from which we will copy 
*			  the current variables.
*		 to     - the variable to receive the copied variables
*
*       Output:  returns the TRUE or FALSE if we were able
*		 to list the workspace.
*
*   Written By:  Mark Young
*
*
************************************************************/


int xve_copy_variables(from, to)

long from, to;
{
	Varlist	   *fromlist, *tolist;
	Symbol	   *symbol;
	SymbolList *symlist;


	if ((fromlist = _xve_get_varlist(from)) == NULL)
	{
	}

	if ((tolist = _xve_get_varlist(to)) == NULL)
	{
	}
	return(TRUE);
}



/************************************************************
*
*  Routine Name: xve_clear_variables()
*
*       Purpose: clear all the variables from the specified
*		 variable list id, but  the variable list (varlist)
*		 structure is NOT removed.
*
*        Input:  id   - the deleted to be cleared.
*
*       Output:  returns the TRUE or FALSE if we were able
*		 to list the workspace.
*
*   Written By:  Mark Young
*
*
************************************************************/


int xve_clear_variables(id)

long id;
{
	Varlist *varlist;


	/*
	 *  Get the child's variable list.
	 */
	if ((varlist = _xve_get_varlist(id)) == NULL)
	{
	   fprintf(stderr,"Unable to get list for child id (%d)\n", id);
	   return(FALSE);
	}
	_xve_free_symlist(varlist->symlist);
	varlist->symlist = NULL;
	return(TRUE);
}



/************************************************************
*
*  Routine Name: xve_delete_variables()
*
*       Purpose: deletes all the variables from the specified
*		 variable list id, and the variable list (varlist)
*		 structure is removed.
*
*        Input:  id   - the deleted to be cleared.
*
*       Output:  returns the TRUE or FALSE if we were able
*		 to list the workspace.
*
*   Written By:  Mark Young
*
*
************************************************************/


int xve_delete_variables(id)

long id;
{
	return(_xve_delete_varlist(id));
}
