#include <stdio.h>
#include "ifdef.h"

#define STACKSIZE 10    /* max no of nested #ifdefs */

extern void parse_error(char *msg);

typedef enum { Normal, Skipping,
               InsideThen, InsideElse,
               SkippingThen, SkippingElse } IfState;

static IfState stack[STACKSIZE];
static IfState *sp=stack-1;     /* points to top element of stack */

int skipping(void)
{
  switch(*sp) {
    case SkippingThen:
    case SkippingElse:
    case Skipping:
      return 1;
    default:
      return 0;
  }
}

static void push(IfState s)
{
  *++sp=s;
  /* !! check for stack overflow */
}

static void pop(void)
{
  sp--;
}

void gotifdef(int cond)
{
  push(skipping() ? Skipping : cond ? InsideThen : SkippingThen);
}

void gotelse(void)
{
  switch(*sp) {
    case InsideThen:    *sp=SkippingElse; break;
    case SkippingThen:  *sp=InsideElse; break;
    case Skipping:      break;
    default:            parse_error("Misplaced #else directive ");
  }
}

void gotendif(void)
{
  switch(*sp) {
    case Normal:        parse_error("#endif without #ifdef "); break;
    default:            pop();
  }
}

void startfile(void)
{
  push(Normal);
}

void endfile(void)
{
  if(*sp!=Normal) parse_error("Missing #endif ");
  while(*sp--!=Normal);
}
