#include <stdlib.h>
#include "kernel.h"
#include "macros.h"
#include "pflags.h"
#include "pflagnames.h"
#include "levelnames.h"
int num_levels[] =
{1, LVL_WIZARD, LVL_DORQ, LVL_EMERITI, LVL_STDWIZ,
LVL_ARCHWIZARD, LVL_DEMI, LVL_SHALAFI, LVL_GOD,
LVL_CREATOR};
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)
{
if (n >= 64)
return xtstbit (f->u, (n - 64));
if (n >= 32)
return xtstbit (f->h, (n - 32));
return xtstbit (f->l, n);
}
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 'U':
return (l >= LVL_CREATOR);
case 'G':
return (l >= LVL_GOD);
case 'D':
return (l >= LVL_DEMI);
case 'V':
return (l >= LVL_SHALAFI);
case 'A':
return (l >= LVL_ARCHWIZARD);
case 'R':
return (l >= LVL_ISTARI);
case 'W':
return (l >= LVL_STDWIZ);
case 'X':
return (l >= LVL_WIZARD);
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, MWizLevels)) >= 0 ||
(k = lookup (n, FWizLevels)) >= 0)
k = num_levels[k];
else if ((k = lookup (n, MageLevels)) >= 0 ||
(k = lookup (n, ThiefLevels)) >= 0 ||
(k = lookup (n, PriestLevels)) >= 0 ||
(k = lookup (n, WarriorLevels)) >= 0);
else {
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.l == 0 && p.h == 0 && p.u == 0);
case 'Y':
return (m.h == 0 && m.h == 0 && m.u == 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.u), &(p.h), &(p.l));
sscanf (argv[3], "0x%8lx:0x%8lx:0x%8lx", &(m.u), &(m.h), &(m.l));
if (argc < 5)
filter (stdin);
else if ((F = fopen (argv[4], "r")) != NULL) {
filter (F);
fclose (F);
} else if (strcmp (argv[4], "-"))
filter (stdin);
else {
perror (argv[4]);
return 1;
}
exit (0);
}