(file) Return to process.c CVS log (file) (dir) Up to [RizwankCVS] / testProject / source / states

  1 rizwank 1.1 /*
  2              * Process input according to the specified rules.
  3              * Copyright (c) 1997-1999 Markku Rossi.
  4              *
  5              * Author: Markku Rossi <mtr@iki.fi>
  6              */
  7             
  8             /*
  9              * This file is part of GNU enscript.
 10              *
 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)
 14              * any later version.
 15              *
 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.
 20              *
 21              * You should have received a copy of the GNU General Public License
 22 rizwank 1.1  * 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.
 25              */
 26             
 27             #include "defs.h"
 28             
 29             /*
 30              * Prototypes for static functions.
 31              */
 32             
 33             /*
 34              * Evaluate the begin rules of state <state>.  The begin rules are
 35              * evaluated from parent to child.
 36              */
 37             static Node *eval_begin_rules ___P ((State *state, int *return_seen));
 38             
 39             /*
 40              * Evaluate the end rules of state <state>.  The end rules are
 41              * evaluated from child to parent.
 42              */
 43 rizwank 1.1 static Node *eval_end_rules ___P ((State *state, int *found_return));
 44             
 45             /*
 46              * Global functions.
 47              */
 48             
 49             void
 50             process_file (fname)
 51                  char *fname;
 52             {
 53               Node *result;
 54               int return_seen = 0;
 55             
 56               start_state = NULL;
 57               current_fname = fname;
 58               current_linenum = 1;
 59             
 60               /* Init buffer variables. */
 61               data_in_buffer = 0;
 62               bufpos = 0;
 63               eof_seen = 0;
 64 rizwank 1.1 
 65               /* Enter build-in variables. */
 66               enter_system_variable ("filename", fname);
 67             
 68               /* Read in the first block of data. */
 69               data_in_buffer = fread (inbuf, 1, INBUFSIZE, ifp);
 70               if (data_in_buffer < INBUFSIZE)
 71                 eof_seen = 1;
 72             
 73               if (start_state_arg)
 74                 start_state = start_state_arg;
 75             
 76               /* Execute start block. */
 77               result = eval_statement_list (start_stmts, NULL, &return_seen);
 78               node_free (result);
 79             
 80               if (start_state == NULL)
 81                 {
 82                   /* No start state found, copy our input to output. */
 83                   while (data_in_buffer)
 84             	{
 85 rizwank 1.1 	  fwrite (inbuf, 1, data_in_buffer, ofp);
 86             	  data_in_buffer = fread (inbuf, 1, INBUFSIZE, ifp);
 87             	}
 88                 }
 89               else
 90                 {
 91                   result = execute_state (start_state);
 92                   node_free (result);
 93                 }
 94             }
 95             
 96             
 97             Node *
 98             execute_state (name)
 99                  char *name;
100             {
101               State *state;
102               State *s;
103               int to_read, got;
104               ListItem *rule, *first_rule;
105               unsigned int first_idx;
106 rizwank 1.1   unsigned int match_len;
107               Node *result = nvoid;
108               Cons *r;
109               Node *exp;
110               int return_seen = 0;
111               int idx;
112             
113               /* Lookup state. */
114               state = lookup_state (name);
115               if (state == NULL)
116                 {
117                   fprintf (stderr, _("%s: undefined state `%s'\n"), program, name);
118                   exit (1);
119                 }
120             
121               /* Begin rules. */
122               result = eval_begin_rules (state, &return_seen);
123               if (return_seen)
124                 goto out;
125             
126               /* Execute this state. */
127 rizwank 1.1   while (1)
128                 {
129                   int eol;
130             
131                   /* Do we have enough data? */
132                   if (bufpos >= data_in_buffer)
133             	{
134             	  if (eof_seen)
135             	    /* All done. */
136             	    break;
137             
138             	  /* Read more data. */
139             	  data_in_buffer = fread (inbuf, 1, INBUFSIZE, ifp);
140             	  if (data_in_buffer < INBUFSIZE)
141             	    eof_seen = 1;
142             
143             	  bufpos = 0;
144             	  continue;
145             	}
146             
147                   /* Check line number. */
148 rizwank 1.1       if (bufpos > 0 && inbuf[bufpos - 1] == '\n')
149             	current_linenum++;
150             
151                   /* Find the end of the input line. */
152                   for (eol = bufpos; eol < data_in_buffer && inbuf[eol] != '\n'; eol++)
153             	;
154                   if (eol < data_in_buffer && inbuf[eol] == '\n')
155             	eol++;
156                   if (eol >= data_in_buffer && !eof_seen && bufpos > 0)
157             	{
158             	  /* Must read more data to the buffer. */
159             	  memmove (inbuf, inbuf + bufpos, eol - bufpos);
160             	  data_in_buffer = eol - bufpos;
161             	  bufpos = 0;
162             
163             	  to_read = INBUFSIZE - data_in_buffer;
164             	  got = fread (inbuf + data_in_buffer, 1, to_read, ifp);
165             	  if (got < to_read)
166             	    eof_seen = 1;
167             
168             	  data_in_buffer += got;
169 rizwank 1.1 	  continue;
170             	}
171             
172                   /* Evaluate state expressions. */
173                   first_idx = eol;
174                   match_len = 0;
175                   first_rule = NULL;
176                   current_match = NULL;
177             
178                   for (s = state; s; s = s->super)
179             	{
180             	  for (rule = s->rules->head; rule; rule = rule->next)
181             	    {
182             	      int err;
183             
184             	      r = (Cons *) rule->data;
185             	      exp = (Node *) r->car;
186             	      if (exp == RULE_BEGIN || exp == RULE_END)
187             		continue;
188             
189             	      if (exp->type == nSYMBOL)
190 rizwank 1.1 		{
191             		  Node *n;
192             
193             		  /* Lookup this variable by hand from global variables. */
194             		  if (!strhash_get (ns_vars, exp->u.sym, strlen (exp->u.sym),
195             				    (void **) &n))
196             		    {
197             		      fprintf (stderr,
198             			       _("%s: error: undefined variable `%s'\n"),
199             			       program, exp->u.sym);
200             		      exit (1);
201             		    }
202             		  if (n->type != nREGEXP)
203             		    /* Skip this rule */
204             		    continue;
205             
206             		  exp = n;
207             		}
208             
209             	      err = re_search (REGEXP (exp), inbuf, eol, bufpos,
210             			       eol - bufpos, &exp->u.re.matches);
211 rizwank 1.1 	      if (err < 0)
212             		/* No mach. */
213             		continue;
214             
215             	      idx = exp->u.re.matches.start[0];
216             	      if (idx >= 0
217             		  && (idx < first_idx
218             		      || (idx == first_idx
219             			  && (exp->u.re.matches.end[0]
220             			      - exp->u.re.matches.start[0]
221             			      > match_len))))
222             		{
223             		  first_idx = idx;
224             		  first_rule = rule;
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;
229             		}
230             	    }
231             	}
232 rizwank 1.1 
233                   /* Print all data before the first rule. */
234                   fwrite (inbuf + bufpos, 1, first_idx - bufpos, ofp);
235             
236                   if (first_rule)
237             	{
238             	  /* Execute statements. */
239             	  bufpos = current_match->end[0];
240             
241             	  node_free (result);
242             	  result = eval_statement_list ((List *)
243             					((Cons *) first_rule->data)->cdr,
244             					NULL, &return_seen);
245             	  if (return_seen)
246             	    goto out;
247             	}
248                   else
249             	bufpos = first_idx;
250                 }
251             
252             out:
253 rizwank 1.1 
254               /* End rules. */
255               {
256                 int found = 0;
257                 Node *result2;
258             
259                 result2 = eval_end_rules (state, &found);
260                 if (found)
261                   {
262             	node_free (result);
263             	result = result2;
264                   }
265               }
266             
267               return result;
268             }
269             
270             
271             /*
272              * Static functions.
273              */
274 rizwank 1.1 
275             static Node *
276             eval_begin_rules (state, return_seen)
277                  State *state;
278                  int *return_seen;
279             {
280               Node *result = nvoid;
281               Cons *r;
282               ListItem *rule;
283             
284               /* The begin rules are evaluated from the parent to child. */
285             
286               /* Autoload the super if needed. */
287               if (state->super_name && state->super == NULL)
288                 {
289                   state->super = lookup_state (state->super_name);
290                   if (state->super == NULL)
291             	{
292             	  fprintf (stderr, _("%s: undefined super state `%s'\n"),
293             		   program, state->super_name);
294             	  exit (1);
295 rizwank 1.1 	}
296                 }
297             
298               if (state->super)
299                 {
300                   result = eval_begin_rules (state->super, return_seen);
301                   if (*return_seen)
302             	return result;
303                 }
304             
305               /* Eval our begin rule. */
306               for (rule = state->rules->head; rule; rule = rule->next)
307                 {
308                   r = (Cons *) rule->data;
309                   if (r->car == RULE_BEGIN)
310             	{
311             	  node_free (result);
312             	  result = eval_statement_list ((List *) r->cdr, NULL, return_seen);
313             	  if (*return_seen)
314             	    break;
315             	}
316 rizwank 1.1     }
317             
318               return result;
319             }
320             
321             
322             static Node *
323             eval_end_rules (state, found_return)
324                  State *state;
325                  int *found_return;
326             {
327               ListItem *rule;
328               Cons *r;
329               Node *result = nvoid;
330               int return_seen;
331             
332               /* The end rules are evaluated from child to parent. */
333             
334               for (; state; state = state->super)
335                 for (rule = state->rules->head; rule; rule = rule->next)
336                   {
337 rizwank 1.1 	r = (Cons *) rule->data;
338             	if (r->car == RULE_END)
339             	  {
340             	    *found_return = 1;
341             	    node_free (result);
342             	    result = eval_statement_list ((List *) r->cdr, NULL, &return_seen);
343             	  }
344                   }
345             
346               return result;
347             }

Rizwan Kassim
Powered by
ViewCVS 0.9.2