/* CONSTANT.C */
/* Edward A. Green */
/* Purpose: to implement constant lists */

/* CONSTANT LISTS: */
/* A constant list is a MOD linked list with two embedded fields */
/* in the VAR string, separated by a blank;  a variable name and */
/* a string representation of it;s value.  It has several uses. */

#include "proj3.h"

/* RETURN A STRING POINTER TO THE VALUE CORRESPONDING */
/* TO THE VARIABLE NAME */
char *constant (char *varname, MOD *list)
{
	MOD *ptr;   /* pointer to the constant list */
	int i;      /* a string index */

	MOD *find_const_list(char *varname, MOD *list);

	ptr=find_const_list(varname, list);
	if (ptr==NULL) return(NULL);
	for (i=0; ptr->var[i]!=' '; i++);
	return(&ptr->var[i+1]);
}


/* RETURN A POINTER TO THE CONSTANT LIST ELEMENT OF A VARIABLE NAME */
MOD *find_const_list(char *varname, MOD *list)
{
	MOD *ptr;  /* pointer into the list */
	int i;     /* displacement into a string */
	int fail;  /* flag to indicate search failure */

	ptr=list;
	fail=1;
	while (ptr!=NULL && fail)
	  {
	  fail=0;
	  for (i=0; ptr->var[i]!=' '; i++)
	    if (ptr->var[i]!=varname[i]) fail=1;
	  if (varname[i]!='\0') fail=1;
	  if (fail) ptr=ptr->next;
	  }
	return(ptr);
}


/* ADD A NEW ELEMENT TO THE CONSTANT LIST */
/*   If the element is already there, replace it with the */
/*   incoming data. */
MOD *insert_const_list (char *varname, char *value, MOD *list)
{
	MOD *ptr;
	char s[100];
	char *strsave(char *s);
	MOD *make_mod(void);

	/* construct a new record */
	strcpy(s,varname);
	strcat(s," ");
	strcat(s,value);

	ptr=find_const_list(varname,list);
	if (ptr!=NULL)
	  {
	  free(ptr->var);
	  ptr->var=strsave(s);
	  return(list);
	  }
	else
	  {
	  ptr=make_mod();
	  ptr->var=strsave(s);
	  ptr->next=list;
	  return(ptr);
	  }

}

/* REMOVE THE ELEMENT CORRESPONDING TO VARNAME */
MOD *remove_const_list(char *varname, MOD *list)
{
	MOD *ptr;       /* search pointer */
	MOD *last_ptr;  /* holder to test of the list */
	int i;          /* string displacement */
	int fail;       /* search flag */

	last_ptr=NULL;
	ptr=list;
	fail=1;
	while (ptr!=NULL && fail)
	  {
	  fail=0;
	  for (i=0; ptr->var[i]!=' '; i++)
	    if (ptr->var[i]!=varname[i]) fail=1;
	  if (varname[i]!='\0') fail=1;
	  if (fail)
	    {
	    last_ptr=ptr;
	    ptr=ptr->next;
	    }
	  }
	if (ptr==NULL) return(list);
	if (last_ptr==NULL)  list=ptr->next;
	else                 last_ptr->next=ptr->next;
	free(ptr->var);
	free(ptr);
	return(list);
}
