#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; }