#include <stdlib.h>
#include <string.h>
+#include "nfa.h"
+
/* Advice functions should be externally visible. */
#define ADVICE_FUNC __attribute__((visibility("default")))
int num_rules;
const char **symbol_names;
- const char **rules;
+ struct NFA **rules;
struct tuple *tuple_list;
};
every state machine whose params match the non-vacant params in the
event. */
struct tuple {
- int state;
-
/* For now, tuples are stored in a linked list. */
struct tuple *next;
- struct param_val param_vals[];
+ struct param_val *param_vals;
+
+ /* The state this tuple is in for each of the tracecut's regexp
+ rules. */
+ struct NState **states;
};
static void
}
void
-advance_state_machine (struct tuple *tuple, int symbol_index)
+advance_state_machine (struct tuple *tuple, int num_rules, int symbol_index)
{
+ int i;
+ for (i = 0; i < num_rules; i++)
+ {
+ step (tuple->states[i], symbol_index);
+ if (ismatch (tuple->states[i]))
+ fprintf (stderr, "Match!\n");
+ }
}
int
struct tracecut *tc = event->tracecut;
struct tuple *tuple;
int tuples_updated = 0;
+ int num_rules = event->tracecut->num_rules;
for (tuple = tc->tuple_list; tuple != NULL; tuple = tuple->next)
{
if (event_matches_tuple (event, tuple))
{
- advance_state_machine (tuple, event->symbol_index);
+ advance_state_machine (tuple, num_rules, event->symbol_index);
tuples_updated++;
fprintf (stderr, "Advancing existing tuple.\n");
}
struct tuple *add_tuple_for_event (struct event *event)
{
+ int i;
struct tracecut *tc = event->tracecut;
struct tuple *tuple;
size_t tuple_size;
return NULL;
}
- tuple->state = 0;
+ tuple->param_vals = calloc (tc->num_params, sizeof (struct param_val));
+ tuple->states = calloc (tc->num_rules, sizeof (struct DState *));
+ if (tuple->param_vals == NULL || tuple->states == NULL)
+ goto nomem;
+
+ /* Initialize the param_vals array. */
memcpy (tuple->param_vals, event->param_vals,
tc->num_params * sizeof (struct param_val));
+ /* Set each rule to its initial state. */
+ for (i = 0; i < tc->num_rules; i++)
+ {
+ tuple->states[i] = getstartstate (tc->rules[i]);
+ if (tuple->states[i] == NULL)
+ goto nomem;
+ }
+
/* Insert the tuple into the tracecut's tuple list. */
tuple->next = tc->tuple_list;
tc->tuple_list = tuple;
return tuple;
+
+ nomem:
+ if (tuple != NULL)
+ {
+ if (tuple->states != NULL)
+ {
+ for (i = 0; i < tc->num_rules; i++)
+ if (tuple->states[i] != NULL)
+ freenstate (tuple->states[i]);
+ free (tuple->states);
+ }
+
+ free (tuple->param_vals);
+ free (tuple);
+ }
+ return NULL;
}
/* An event is "complete" iff only if all its params are specified
do_transition (struct event *event)
{
int tuples_updated;
+ int num_rules = event->tracecut->num_rules;
tuples_updated = update_matching_tuples (event);
tuple = add_tuple_for_event (event);
if (tuple != NULL)
- advance_state_machine (tuple, event->symbol_index);
+ advance_state_machine (tuple, num_rules, event->symbol_index);
fprintf (stderr, "Creating new tuple.\n");
}
}
tc->num_symbols = num_symbols;
tc->num_rules = num_rules;
- if (tc->num_symbols > 0)
+ if (num_symbols > 0)
{
tc->symbol_names = calloc (num_symbols, sizeof (const char *));
if (tc->symbol_names == NULL)
fatal_tracecut_error ("Out of memory");
}
+
+ if (num_rules > 0)
+ {
+ tc->rules = calloc (num_rules, sizeof (struct State *));
+ if (tc->rules == NULL)
+ fatal_tracecut_error ("Out of memory");
+ }
}
ADVICE_FUNC void
tc = get_tracecut (tc_index);
if (tc == NULL)
- return;
+ {
+ return;
+ }
+ else if (rule_index < 0 || rule_index >= tc->num_rules)
+ {
+ fatal_tracecut_error ("Bad rule index at initialization.");
+ }
+
+ tc->rules[rule_index] = compile_re (specification, tc->symbol_names,
+ tc->num_symbols);
+ if (tc->rules[rule_index] == NULL)
+ {
+ fatal_tracecut_error ("Failed to compile rule.");
+ }
}
ADVICE_FUNC void