Listing 6

#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;
}

/* End of File */