#include "kernel.h"
#include "macros.h"
#include "pflagnames.h"
#include "levelnames.h"
#include "stdinc.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))
{
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);
}