/* labels.c */
/* author: Edward A. Green */
/* purpose: to handle program labels (goto fields and targets) */

#include "proj3.h"


/*********************************************/
/* Routine to add a label record to the list */
/*********************************************/
/* LABELS are used to keep track of gotos labels, calls, etc. */
/*        for the purpose of finding leaders and basic blocks */
/*        Labels are kept in line number order. */

/* LINK ON A NEW LABEL RECORD WITH THE TYPE, FLD, AND LINE FIELDS */
LABELS *add_label(LABELS *label_list, char type, char *fld, int line)
{
	LABELS *holder;  /* variables to manage the list of labels */
	LABELS *index;
	LABELS *index2;

	LABELS *new_label(void);
	char   *strsave(char *subject);

	holder=new_label();
	holder->label=strsave(fld);
	holder->field=type;
	holder->line=line;

	if (label_list==NULL)
	  {
	  label_list=holder;
	  return(label_list);
	  }

	if (label_list->line > line)
	  {
	  holder->next=label_list;
	  label_list=holder;
	  return(label_list);
	  }

	index2=label_list->next;
	index=label_list;
	while (index2!=NULL)
	  {
	  if (index2->line>=line) index2=NULL;
	  else
	    {
	    index=index2;
	    index2=index2->next;
	    }
	  }
	holder->next=index->next;
	index->next=holder;
	return(label_list);
}


/* ALLOCATE SPACE FOR A NEW LABEL, RETURN THE POINTER */
LABELS *new_label(void)
{
	LABELS *return_label;

	return_label=(LABELS *)malloc(sizeof(LABELS));
	if (return_label==NULL)
	  {
	  printf("Error on allocation of a new LABEL\n");
	  exit(1);
	  }
	return_label->field=' ';
	return_label->label=NULL;
	return_label->line=0;
	return_label->next=NULL;

	return(return_label);
}


/***************************************************************/
/* Routines to retrieve information from the LABELS structures */
/***************************************************************/

/* FIND THE LINE WHICH IS LABELED WITH THE ARGUEMENT */
int label_line(LABELS *label_list, char *lbl)
{
	LABELS *test;

	test=label_list;
	while (test!=NULL)
	  {
	  if (test->field=='L')
	    if (!strcmp(test->label,lbl))
	      return(test->line);
	  test=test->next;
	  }
	return(0);
}

