#include <ctype.h>
#include "stringops.h"
#include "stim.h"
static char io[1024];
static char *find_token (char *start, char *end, char token)
{
int parencount = 0;
char *scan;
scan = start;
while ((scan <= end) && ((*scan != token) || (parencount > 0)))
{
if (*scan == '(') parencount++;
if (*scan == ')') parencount--;
scan++;
}
if (scan <= end)
return scan;
else
return NULL;
}
stim_elt *stim_tree_parse (char *start, char *end)
{
stim_elt *ret = NULL;
char *token;
#ifdef FUNCTIONS
puts ("<stim_tree_parse>");
#endif
while (isspace (*start)) start++;
while (isspace (*end)) end++;
if (token = find_token (start, end, '|'))
{
ret = allocate (stim_elt);
ret->left = stim_tree_parse (start, token - 1);
ret->right = stim_tree_parse (token + 1, end);
ret->s = "|";
return ret;
}
else
{
if (token = find_token (start, end, '&'))
{
ret = allocate (stim_elt);
ret->left = stim_tree_parse (start, token - 1);
ret->right = stim_tree_parse (token + 1, end);
ret->s = "&";
return ret;
}
else
{
if (*start == '!')
{
ret = allocate (stim_elt);
ret->left = NULL;
ret->right = stim_tree_parse (start + 1, end);
ret->s = "!";
return ret;
}
else
{
if ((*start == '(') && (*end == ')'))
{
return stim_tree_parse
(start + 1, end - 1);
}
else
{
ret = allocate (stim_elt);
ret->left = NULL;
ret->right = NULL;
ret->s = clip (start, end);
return ret;
}
}
}
}
}
void stim_output (stim_elt *se, globals *g)
{
#ifdef FUNCTIONS
puts ("**stim_output");
#endif
if (se->left)
{
if (!strcasecmp (se->left->s, "|") && !strcasecmp (se->s, "&"))
{
socket_write_noret (g->socket, "(");
stim_output (se->left, g);
socket_write_noret (g->socket, ")");
}
else stim_output (se->left, g);
}
socket_write_noret (g->socket, se->s);
if (se->right)
{
if ((!strcasecmp (se->right->s, "|") &&
!strcasecmp (se->s, "&")) ||
((!strcasecmp (se->right->s, "&") ||
!strcasecmp (se->right->s, "|")) &&
!strcasecmp (se->s, "!")))
{
socket_write_noret (g->socket, "(");
stim_output (se->right, g);
socket_write_noret (g->socket, ")");
}
else stim_output (se->right, g);
}
}
static void stim_tree_burn (stim_elt *se)
{
#ifdef FUNCTIONS
puts ("**stim_tree_burn");
#endif
if (se != NULL)
{
stim_tree_burn (se->left);
stim_tree_burn (se->right);
free (se->s);
free (se);
}
}
static void stim_elements_burn (stim *s)
{
#ifdef FUNCTIONS
puts ("**stim_elements_burn");
#endif
if (s != NULL)
{
stim_elements_burn (s->next);
stim_tree_burn (s->tree);
free (s);
}
}
void stim_burn (stim_list *sl)
{
#ifdef FUNCTIONS
puts ("**stim_burn");
#endif
if (sl != NULL)
{
stim_elements_burn (sl->head);
free (sl);
}
}
void stim_add (stim_list *sl, char *l)
{
stim *new;
#ifdef FUNCTIONS
puts ("**stim_add");
#endif
new = allocate (stim);
new->tree = stim_tree_parse (l, l + strlen(l) - 1);
new->next = NULL;
if (sl->tail != NULL) sl->tail->next = new;
sl->tail = new;
if (sl->head == NULL) sl->head = new;
(sl->size)++;
}
void stim_delete (stim_list *sl, stim *elt)
{
stim *scan, *dead;
#ifdef FUNCTIONS
puts ("**stim_delete");
#endif
if (sl->head = elt)
{
dead = sl->head;
sl->head = dead->next;
if (sl->tail == dead)
sl->tail = sl->head;
stim_tree_burn (dead->tree);
free (dead);
(sl->size)--;
return;
}
for
(
scan = sl->head;
(scan->next != NULL) && (scan->next != elt);
scan = scan->next
);
if (scan != NULL)
{
if (sl->tail == scan->next)
sl->tail = scan;
dead = scan->next;
scan->next = dead->next;
stim_tree_burn (dead->tree);
free (dead);
(sl->size)--;
}
}
stim *stim_find_num (stim_list *sl, int n)
{
stim *scan;
for
(
scan = sl->head;
(n > 1) && (scan != NULL);
scan = scan->next, n--
);
return scan;
}
void stim_file_output (stim_elt *s, FILE *f)
{
#ifdef FUNCTIONS
puts ("**stim_file_output");
#endif
if (s->left)
{
if (!strcasecmp (s->left->s, "|") && !strcasecmp (s->s, "&"))
{
putc ('(', f);
stim_file_output (s->left, f);
putc (')', f);
}
else stim_file_output (s->left, f);
}
fputs (s->s, f);
if (s->right)
{
if ((!strcasecmp (s->right->s, "|") &&
!strcasecmp (s->s, "&")) ||
((!strcasecmp (s->right->s, "&") ||
!strcasecmp (s->right->s, "|")) &&
!strcasecmp (s->s, "!")))
{
putc ('(', f);
stim_file_output (s->right, f);
putc (')', f);
}
else stim_file_output (s->right, f);
}
}
static int stim_tree_evaluate (stim_elt *tree, name_list *nl, char *l)
{
int result_left, result_right;
#ifdef FUNCTIONS
puts ("<stim_tree_evaluate>");
#endif
if (tree)
{
if (tree->right)
{
result_left = stim_tree_evaluate (tree->left, nl, l);
result_right = stim_tree_evaluate (tree->right, nl, l);
if (!strcasecmp (tree->s, "|"))
return (result_left || result_right);
if (!strcasecmp (tree->s, "&"))
return (result_left && result_right);
if (!strcasecmp (tree->s, "!"))
return (!result_right);
}
else
{
if (!strcasecmp (tree->s, "^"))
return (name_test (nl, l));
return ((int) find (l, tree->s));
}
}
else return 0;
}
int stim_evaluate (stim_list *sl, name_list *nl, char *l)
{
stim *scan;
int ret = 0;
#ifdef FUNCTIONS
puts ("**stim_evaluate");
#endif
for (scan = sl->head; scan != NULL; scan = scan->next)
ret |= stim_tree_evaluate (scan->tree, nl, l);
return ret;
}