#include <stdio.h>

#define MAX_LINE 256
#define ID_WID 10

#define WAIT_NEW 1
#define WAIT_FREE 2

#define NEW_NEW 1
#define NEW_FREE 2
#define SAME_FREE 3
#define SAME_NEW 4
#define END_FILE 5
#define PARSE_ERR 6

char cur_obj[MAX_LINE];
char old_obj[MAX_LINE];
char cur_line[MAX_LINE];

void main()
{
	int state;
	int tok;

	state = WAIT_NEW;

	do {
          tok = nexttok();	  
  	  switch(state){
  	  	case WAIT_NEW:
  	  	   switch(tok) {
  	  	   	case NEW_NEW:
  	  	   	   state = WAIT_FREE;
  	  	   	   continue;
  	  	   	case NEW_FREE:
  	  	   	   printf("%s free without alloc\n", cur_obj);
  	  	   	   continue;
  	  	   	case SAME_FREE:
  	  	   	   printf("%s multiple frees\n", cur_obj);
                           continue;
                        case SAME_NEW:
                           printf("%s alloc after free\n", cur_obj);
                           continue;
                        case END_FILE:
                           exit();
                        case PARSE_ERR:
                           printf("%s doesn't parse\n", cur_line);
                           continue;
                        default:
                           printf("%s\n%s\nillegal token %d in state %d\n",
                                   cur_obj, cur_line, tok, state);
                           exit();
                        }
                     break;

            case WAIT_FREE:
               switch(tok){
                   case SAME_FREE:
                      state = WAIT_NEW;
                      continue;
                   case NEW_FREE:
                      state = WAIT_NEW;
                      printf("%s alloc without free\n", old_obj);
                      printf("%s free before alloc\n", cur_obj);
                      continue;
                   case NEW_NEW:
                      printf("%s missing free\n", old_obj);
                      continue;
                   case SAME_NEW:
                      printf("%s multiple allocs\n",cur_obj);
                      continue;
                   case END_FILE:
                      printf("%s missing free\n", cur_obj);
                      exit();
                   case PARSE_ERR:
                      printf("%s doesn't parse\n", cur_line);
                      continue;
                   default:
                      printf("%s\n%s\nillegal token %d in state %d\n", 
                               cur_obj, cur_line, tok, state);
                      exit();
                }
             default:
                printf("illegal state %d\n",state);                         	
                        
                       
            }                      
	} while (1);
}                        		

int nexttok()
{
    char loc_obj[ID_WID+1];

    /* short unparsable lines won't be detected
       unless we clear the buffer */
       
    memset(cur_line,'\0',20);
    if (gets(cur_line) == NULL) return END_FILE;
    if (strncmp(cur_line,cur_obj,ID_WID)==0) { 
        /* same object */
        if (strncmp(&cur_line[ID_WID+1], "free",4) == 0) {
           return SAME_FREE;
           }
        if (strncmp(&cur_line[ID_WID+1], "anew",4) == 0) {        
	   return SAME_NEW;
           }
	return PARSE_ERR;
        }
    /* new object */
    strcpy(old_obj,cur_obj);
    strncpy(cur_obj,cur_line,10);
    cur_obj[10] = '\0';
    if (strncmp(&cur_line[ID_WID+1], "free",4) == 0) {
       return NEW_FREE;
       }
    if (strncmp(&cur_line[ID_WID+1], "anew",4) == 0) {        
       return NEW_NEW;
       }
    return PARSE_ERR;
}
                            		
	
	
