pdirt/data/
pdirt/data/HELP/
pdirt/data/HELP/0/
pdirt/data/HELP/F/
pdirt/data/HELP/G/
pdirt/data/HELP/H/
pdirt/data/HELP/J/
pdirt/data/HELP/K/
pdirt/data/HELP/O/
pdirt/data/HELP/Q/
pdirt/data/HELP/R/
pdirt/data/HELP/U/
pdirt/data/HELP/V/
pdirt/data/HELP/Y/
pdirt/data/HELP/Z/
pdirt/data/MESSAGES/
pdirt/data/POWERINFO/
pdirt/data/WIZ_ZONES/
pdirt/drv/
pdirt/drv/bin/
pdirt/drv/compiler/converter/
pdirt/drv/compiler/libs/
pdirt/drv/compiler/scripts/
pdirt/drv/include/AberChat/
pdirt/drv/include/InterMud/
pdirt/drv/include/machine/
pdirt/drv/src/InterMud/
pdirt/drv/src/Players/
pdirt/drv/utils/UAFPort/
pdirt/drv/utils/dnsresolv/
pdirt/drv/utils/gdbm/
#include <stdlib.h>
#include "kernel.h"
#include "macros.h"
#include "pflagnames.h"
#include "levelnames.h"
#include "misc.h"

int num_levels[] = { 1, LVL_APPREN, LVL_APPREN + 1, LVL_ARCHWIZARD,
		       LVL_DEMI, LVL_GOD };

char *s;
int l;
PFLAGS p;
PFLAGS m;
char b[256];
char g[256];
char n[256];

static Boolean or_ok();

static Boolean test_bit(PFLAGS *f,int n)
{ int k;
  
  if (n >= 64) (k = (XTSTBIT(f->b3,n-64)));
  else if (n >= 32) (k = XTSTBIT(f->b2, n-32));
  else k = XTSTBIT(f->b1, n);
  return k;
}

static int lookup(char *e, char **t)
{ register int l = strlen(e);
  register int x = 0;
  
  for (;*t != TABLE_END; ++t, ++x) {
    if (*t == NULL)
      continue;
    if (strncasecmp(e,*t,l) == 0)
      return x;
  }
  return -1;
}

static Boolean ok()
{ Boolean j;
  int k;
  char *t;
  
  while (*s == ' ' || *s == '\t') ++s;
  switch (*s++) {
  case '(':
    j = or_ok();
    if (*s != ')') 
    { fprintf(stderr,"\nMissing ')' at %s.\n", s);
      exit(1);
    }
    ++s;
    return j;
  case '!': return !ok();
  case 'G': return (l >= LVL_GOD);
  case 'D': return (l >= LVL_DEMI);
  case 'A': return (l >= LVL_ARCHWIZARD);
  case 'W': return (l >= LVL_APPREN + 1);
  case 'X': return (l >= LVL_APPREN);
  case 'L':
    if (*s == '-' || isdigit(*s)) 
    {  k = strtol(s,&t,10);
       s = t;
    }  
    else 
    {  for (t = n; isalpha(*s);)
	  *t++ = *s++;
       *t = 0;
       if ((k = lookup(n,WizLevels)) >= 0)
	  k = num_levels[k];
       else if ((k = lookup(n,MLevels)) < 0) 
       {  fprintf(stderr, "\nUnknown name of level: %s.\n", n);
	  exit(1);
       }
    }
    return (l >= k);
  case 'P':
    for (t = n; isalpha(*s);)
      *t++ = *s++;
    *t = 0;
    if ((k = lookup(n,Pflags)) < 0) 
    {  fprintf(stderr, "\nUnknown name of Pflags: %s.\n", n);
       exit(1);
    }
    return test_bit(&p,k);
  case 'M':
    for (t = n; isalpha(*s);)
      *t++ = *s++;
    *t = 0;
    if ((k = lookup(n,Pflags)) < 0) 
    {  fprintf(stderr, "\nUnknown name of Pflags: %s.\n", n);
       exit(1);
    }
    return test_bit(&m,k);
  case 'Z': return ((p.b3 == 0 && p.b2 == 0 && p.b1 == 0));
  case 'Y': return ((m.b1 == 0 && m.b2 == 0 && m.b3 == 0));
  default:
    if (!isalpha(*s))
      return True;
    fprintf(stderr, "\nIllegal code, %c at %s\n", s[-1], s - 1);
    exit(1);
  }
}

static Boolean and_ok()
{ Boolean j = True;
  
  do 
  {  if (!ok()) j = False;
     while (*s == ' ' || *s == '\t') ++s;
     if (*s == '&')
	while (*++s == ' ' || *s == '\t');
  } while (isalpha(*s) || *s == '!' || *s == '(');
  return j;
}

static Boolean or_ok()
{ Boolean j = False;
  
  while (True) 
  { if (and_ok()) j = True;
    if (*s != '|') return j;
    ++s;
  }
}

static Boolean all_ok(char *t)
{
  Boolean j;
  
  s = t;
  j = or_ok();
  if (*s == 0)
    return j;
  fprintf(stderr, "\nIllegal syntax in string at %s.\n", s);
  exit(1);
}

static void filter(FILE *F)
{ char *t;
  
  while (fgets(b,sizeof(b),F) != NULL) 
  {  if (*b != '[' || (t = strchr(b,']')) == NULL) 
     {  fputs(b,stdout);
        continue;
     }
     *t = 0;
     if (*++t == '\\' && t[1] == '\n') 
     {  if (!fgets(g,sizeof(g),F))
	    break;
        t = g;
     }
     if (all_ok(b+1))
	fputs(t,stdout);
  }
}

int main(int argc, char **argv)
{ FILE  *F;
  
  if (argc < 3) 
  {  fprintf(stderr, "\nToo few arguments.\n");
     return 1;
  }
  l = atoi(argv[1]);
  sscanf(argv[2], "0x%8lx:0x%8lx:0x%8lx", &(p.b3), &(p.b2), &(p.b1));
  sscanf(argv[3], "0x%8lx:0x%8lx:0x%8lx", &(m.b3), &(m.b2), &(m.b1));
  if (argc < 5)
    filter(stdin);
  else if ((F = (FILE *)bopen(argv[4])) != NULL) 
  {  filter(F);
     bclose(F);
  } 
  else if (!strcmp(argv[4],"-"))
    filter(stdin);
  else 
  {  perror(argv[4]);
     return 1;
  }
  exit(0);
}