2 * Process input according to the specified rules.
3 * Copyright (c) 1997-1999 Markku Rossi.
5 * Author: Markku Rossi <mtr@iki.fi>
9 * This file is part of GNU enscript.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2, or (at your option)
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; see the file COPYING. If not, write to
23 * the Free Software Foundation, 59 Temple Place - Suite 330,
24 * Boston, MA 02111-1307, USA.
30 * Prototypes for static functions.
34 * Evaluate the begin rules of state <state>. The begin rules are
35 * evaluated from parent to child.
37 static Node *eval_begin_rules ___P ((State *state, int *return_seen));
40 * Evaluate the end rules of state <state>. The end rules are
41 * evaluated from child to parent.
43 static Node *eval_end_rules ___P ((State *state, int *found_return));
57 current_fname = fname;
60 /* Init buffer variables. */
65 /* Enter build-in variables. */
66 enter_system_variable ("filename", fname);
68 /* Read in the first block of data. */
69 data_in_buffer = fread (inbuf, 1, INBUFSIZE, ifp);
70 if (data_in_buffer < INBUFSIZE)
74 start_state = start_state_arg;
76 /* Execute start block. */
77 result = eval_statement_list (start_stmts, NULL, &return_seen);
80 if (start_state == NULL)
82 /* No start state found, copy our input to output. */
83 while (data_in_buffer)
85 fwrite (inbuf, 1, data_in_buffer, ofp);
86 data_in_buffer = fread (inbuf, 1, INBUFSIZE, ifp);
91 result = execute_state (start_state);
104 ListItem *rule, *first_rule;
105 unsigned int first_idx;
106 unsigned int match_len;
107 Node *result = nvoid;
114 state = lookup_state (name);
117 fprintf (stderr, _("%s: undefined state `%s'\n"), program, name);
122 result = eval_begin_rules (state, &return_seen);
126 /* Execute this state. */
131 /* Do we have enough data? */
132 if (bufpos >= data_in_buffer)
138 /* Read more data. */
139 data_in_buffer = fread (inbuf, 1, INBUFSIZE, ifp);
140 if (data_in_buffer < INBUFSIZE)
147 /* Check line number. */
148 if (bufpos > 0 && inbuf[bufpos - 1] == '\n')
151 /* Find the end of the input line. */
152 for (eol = bufpos; eol < data_in_buffer && inbuf[eol] != '\n'; eol++)
154 if (eol < data_in_buffer && inbuf[eol] == '\n')
156 if (eol >= data_in_buffer && !eof_seen && bufpos > 0)
158 /* Must read more data to the buffer. */
159 memmove (inbuf, inbuf + bufpos, eol - bufpos);
160 data_in_buffer = eol - bufpos;
163 to_read = INBUFSIZE - data_in_buffer;
164 got = fread (inbuf + data_in_buffer, 1, to_read, ifp);
168 data_in_buffer += got;
172 /* Evaluate state expressions. */
176 current_match = NULL;
178 for (s = state; s; s = s->super)
180 for (rule = s->rules->head; rule; rule = rule->next)
184 r = (Cons *) rule->data;
185 exp = (Node *) r->car;
186 if (exp == RULE_BEGIN || exp == RULE_END)
189 if (exp->type == nSYMBOL)
193 /* Lookup this variable by hand from global variables. */
194 if (!strhash_get (ns_vars, exp->u.sym, strlen (exp->u.sym),
198 _("%s: error: undefined variable `%s'\n"),
199 program, exp->u.sym);
202 if (n->type != nREGEXP)
209 err = re_search (REGEXP (exp), inbuf, eol, bufpos,
210 eol - bufpos, &exp->u.re.matches);
215 idx = exp->u.re.matches.start[0];
219 && (exp->u.re.matches.end[0]
220 - exp->u.re.matches.start[0]
225 match_len = (exp->u.re.matches.end[0]
226 - exp->u.re.matches.start[0]);
227 current_match = &exp->u.re.matches;
228 current_match_buf = inbuf;
233 /* Print all data before the first rule. */
234 fwrite (inbuf + bufpos, 1, first_idx - bufpos, ofp);
238 /* Execute statements. */
239 bufpos = current_match->end[0];
242 result = eval_statement_list ((List *)
243 ((Cons *) first_rule->data)->cdr,
259 result2 = eval_end_rules (state, &found);
276 eval_begin_rules (state, return_seen)
280 Node *result = nvoid;
284 /* The begin rules are evaluated from the parent to child. */
286 /* Autoload the super if needed. */
287 if (state->super_name && state->super == NULL)
289 state->super = lookup_state (state->super_name);
290 if (state->super == NULL)
292 fprintf (stderr, _("%s: undefined super state `%s'\n"),
293 program, state->super_name);
300 result = eval_begin_rules (state->super, return_seen);
305 /* Eval our begin rule. */
306 for (rule = state->rules->head; rule; rule = rule->next)
308 r = (Cons *) rule->data;
309 if (r->car == RULE_BEGIN)
312 result = eval_statement_list ((List *) r->cdr, NULL, return_seen);
323 eval_end_rules (state, found_return)
329 Node *result = nvoid;
332 /* The end rules are evaluated from child to parent. */
334 for (; state; state = state->super)
335 for (rule = state->rules->head; rule; rule = rule->next)
337 r = (Cons *) rule->data;
338 if (r->car == RULE_END)
342 result = eval_statement_list ((List *) r->cdr, NULL, &return_seen);