#include "defs.h"
void
process_file (fname)
char *fname;
{
Node *result;
int return_seen = 0;
start_state = NULL;
current_fname = fname;
current_linenum = 1;
data_in_buffer = 0;
bufpos = 0;
eof_seen = 0;
enter_system_variable ("filename", fname);
data_in_buffer = fread (inbuf, 1, INBUFSIZE, ifp);
if (data_in_buffer < INBUFSIZE)
eof_seen = 1;
if (start_state_arg)
start_state = start_state_arg;
result = eval_statement_list (start_stmts, NULL, &return_seen);
node_free (result);
if (start_state == NULL)
{
while (data_in_buffer)
{
fwrite (inbuf, 1, data_in_buffer, ofp);
data_in_buffer = fread (inbuf, 1, INBUFSIZE, ifp);
}
}
else
{
result = execute_state (start_state);
node_free (result);
}
}
Node *
execute_state (name)
char *name;
{
List *state;
int to_read, got;
ListItem *rule, *first_rule;
unsigned int first_idx;
unsigned int match_len;
Node *result = nvoid;
Cons *r;
Node *exp;
int return_seen = 0;
int idx;
if (!strhash_get (ns_states, name, strlen (name), (void **) &state))
{
fprintf (stderr, _("%s: undefined state `%s'\n"), program, name);
exit (1);
}
for (rule = state->head; rule; rule = rule->next)
{
r = (Cons *) rule->data;
if (r->car == RULE_BEGIN)
{
node_free (result);
result = eval_statement_list ((List *) r->cdr, NULL, &return_seen);
if (return_seen)
goto out;
break;
}
}
while (1)
{
int eol;
if (bufpos >= data_in_buffer)
{
if (eof_seen)
break;
data_in_buffer = fread (inbuf, 1, INBUFSIZE, ifp);
if (data_in_buffer < INBUFSIZE)
eof_seen = 1;
bufpos = 0;
continue;
}
if (bufpos > 0 && inbuf[bufpos - 1] == '\n')
current_linenum++;
for (eol = bufpos; eol < data_in_buffer && inbuf[eol] != '\n'; eol++)
;
if (inbuf[eol] == '\n')
eol++;
if (eol >= data_in_buffer && !eof_seen && bufpos > 0)
{
memmove (inbuf, inbuf + bufpos, eol - bufpos);
data_in_buffer = eol - bufpos;
bufpos = 0;
to_read = INBUFSIZE - data_in_buffer;
got = fread (inbuf + data_in_buffer, 1, to_read, ifp);
if (got < to_read)
eof_seen = 1;
data_in_buffer += got;
continue;
}
first_idx = eol;
match_len = 0;
first_rule = NULL;
current_match = NULL;
for (rule = state->head; rule; rule = rule->next)
{
int err;
r = (Cons *) rule->data;
exp = (Node *) r->car;
if (exp == RULE_BEGIN || exp == RULE_END)
continue;
if (exp->type == nSYMBOL)
{
Node *n;
if (!strhash_get (ns_vars, exp->u.sym, strlen (exp->u.sym),
(void **) &n))
{
fprintf (stderr, _("%s: error: undefined variable `%s'\n"),
program, exp->u.sym);
exit (1);
}
if (n->type != nREGEXP)
continue;
exp = n;
}
err = re_search (REGEXP (exp), inbuf, eol, bufpos,
eol - bufpos, &exp->u.re.matches);
if (err < 0)
continue;
idx = exp->u.re.matches.start[0];
if (idx >= 0
&& (idx < first_idx
|| (idx == first_idx
&& (exp->u.re.matches.end[0]
- exp->u.re.matches.start[0]
> match_len))))
{
first_idx = idx;
first_rule = rule;
match_len = (exp->u.re.matches.end[0]
- exp->u.re.matches.start[0]);
current_match = &exp->u.re.matches;
current_match_buf = inbuf;
}
}
fwrite (inbuf + bufpos, 1, first_idx - bufpos, ofp);
if (first_rule)
{
bufpos = current_match->end[0];
node_free (result);
result = eval_statement_list ((List *)
((Cons *) first_rule->data)->cdr,
NULL, &return_seen);
if (return_seen)
goto out;
}
else
bufpos = first_idx;
}
out:
for (rule = state->head; rule; rule = rule->next)
{
r = (Cons *) rule->data;
if (r->car == RULE_END)
{
node_free (result);
result = eval_statement_list ((List *) r->cdr, NULL, &return_seen);
}
}
return result;
}