IDZEBRA  2.1.2
agrep.c
Go to the documentation of this file.
1 /* This file is part of the Zebra server.
2  Copyright (C) Index Data
3 
4 Zebra is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
7 version.
8 
9 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 for more details.
13 
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 
18 */
19 
20 
21 #if HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 #include <stdio.h>
25 #include <assert.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <stdarg.h>
29 
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <fcntl.h>
33 
34 #ifdef WIN32
35 #include <io.h>
36 #endif
37 #if HAVE_UNISTD_H
38 #include <unistd.h>
39 #endif
40 
41 #include <idzebra/util.h>
42 #include <dfa.h>
43 #include "imalloc.h"
44 
45 #ifndef O_BINARY
46 #define O_BINARY 0
47 #endif
48 
49 static char *prog;
50 
51 void error (const char *format, ...)
52 {
53  va_list argptr;
54  va_start (argptr, format);
55  fprintf (stderr, "%s error: ", prog);
56  (void) vfprintf (stderr, format, argptr);
57  putc ('\n', stderr);
58  exit (1);
59 }
60 
61 static int show_lines = 0;
62 
63 int agrep_options (int argc, char **argv)
64 {
65  while (--argc > 0)
66  if (**++argv == '-')
67  while (*++*argv)
68  {
69  switch (**argv)
70  {
71  case 'V':
72  fprintf (stderr, "%s: %s %s\n", prog, __DATE__, __TIME__);
73  continue;
74  case 'v':
75  dfa_verbose = 1;
76  continue;
77  case 'n':
78  show_lines = 1;
79  continue;
80  case 'd':
81  switch (*++*argv)
82  {
83  case 's':
84  debug_dfa_tran = 1;
85  break;
86  case 't':
87  debug_dfa_trav = 1;
88  break;
89  case 'f':
91  break;
92  default:
93  --*argv;
94  debug_dfa_tran = 1;
96  debug_dfa_trav = 1;
97  }
98  continue;
99  default:
100  fprintf (stderr, "%s: unknown option `-%s'\n", prog, *argv);
101  return 1;
102  }
103  break;
104  }
105  return 0;
106 }
107 
108 #define INF_BUF_SIZE 32768U
109 static char *inf_buf;
110 static char *inf_ptr, *inf_flsh;
111 static int inf_eof, line_no;
112 
113 static int inf_flush (int fd)
114 {
115  char *p;
116  unsigned b, r;
117 
118  r = (unsigned) (inf_buf+INF_BUF_SIZE - inf_ptr); /* no of `wrap' bytes */
119  if (r)
120  memcpy (inf_buf, inf_ptr, r);
121  inf_ptr = p = inf_buf + r;
122  b = INF_BUF_SIZE - r;
123  do
124  if ((r = read (fd, p, b)) == (unsigned) -1)
125  return -1;
126  else if (r)
127  p += r;
128  else
129  {
130  *p++ = '\n';
131  inf_eof = 1;
132  break;
133  }
134  while ((b -= r) > 0);
135  while (p != inf_buf && *--p != '\n')
136  ;
137  while (p != inf_buf && *--p != '\n')
138  ;
139  inf_flsh = p+1;
140  return 0;
141 }
142 
143 static char *prline (char *p)
144 {
145  char *p0;
146 
147  --p;
148  while (p != inf_buf && p[-1] != '\n')
149  --p;
150  p0 = p;
151  while (*p++ != '\n')
152  ;
153  p[-1] = '\0';
154  if (show_lines)
155  printf ("%5d:\t%s\n", line_no, p0);
156  else
157  puts (p0);
158  p[-1] = '\n';
159  return p;
160 }
161 
162 static int go (int fd, struct DFA_state **dfaar)
163 {
164  struct DFA_state *s = dfaar[0];
165  struct DFA_tran *t;
166  char *p;
167  int i;
168  unsigned char c;
169  int start_line = 1;
170 
171  while (1)
172  {
173  for (c = *inf_ptr++, t=s->trans, i=s->tran_no; --i >= 0; t++)
174  if (c >= t->ch[0] && c <= t->ch[1])
175  {
176  p = inf_ptr;
177  do
178  {
179  if ((s = dfaar[t->to])->rule_no &&
180  (start_line || s->rule_nno))
181  {
182  inf_ptr = prline (inf_ptr);
183  c = '\n';
184  break;
185  }
186  for (t=s->trans, i=s->tran_no; --i >= 0; t++)
187  if ((unsigned) *p >= t->ch[0]
188  && (unsigned) *p <= t->ch[1])
189  break;
190  p++;
191  } while (i >= 0);
192  s = dfaar[0];
193  break;
194  }
195  if (c == '\n')
196  {
197  start_line = 1;
198  ++line_no;
199  if (inf_ptr == inf_flsh)
200  {
201  if (inf_eof)
202  break;
203  ++line_no;
204  if (inf_flush (fd))
205  {
206  fprintf (stderr, "%s: read error\n", prog);
207  return -1;
208  }
209  }
210  }
211  else
212  start_line = 0;
213  }
214  return 0;
215 }
216 
217 int agrep (struct DFA_state **dfas, int fd)
218 {
219  inf_buf = imalloc (sizeof(char)*INF_BUF_SIZE);
220  inf_eof = 0;
222  inf_flush (fd);
223  line_no = 1;
224 
225  go (fd, dfas);
226 
227  ifree (inf_buf);
228  return 0;
229 }
230 
231 
232 int main (int argc, char **argv)
233 {
234  const char *pattern = NULL;
235  char outbuf[BUFSIZ];
236  int fd, i, no = 0;
237  struct DFA *dfa = dfa_init();
238 
239  prog = *argv;
240  if (argc < 2)
241  {
242  fprintf (stderr, "usage: agrep [options] pattern file..\n");
243  fprintf (stderr, " -v dfa verbose\n");
244  fprintf (stderr, " -n show lines\n");
245  fprintf (stderr, " -d debug\n");
246  fprintf (stderr, " -V show version\n");
247  exit (1);
248  }
249  setbuf (stdout, outbuf);
250  i = agrep_options (argc, argv);
251  if (i)
252  return i;
253  while (--argc > 0)
254  if (**++argv != '-' && **argv)
255  {
256  if (!pattern)
257  {
258  pattern = *argv;
259  i = dfa_parse (dfa, &pattern);
260  if (i || *pattern)
261  {
262  fprintf (stderr, "%s: illegal pattern\n", prog);
263  return 1;
264  }
265  dfa_mkstate (dfa);
266  }
267  else
268  {
269  ++no;
270  fd = open (*argv, O_RDONLY | O_BINARY);
271  if (fd == -1)
272  {
273  fprintf (stderr, "%s: couldn't open `%s'\n", prog, *argv);
274  return 1;
275  }
276  i = agrep (dfa->states, fd);
277  close (fd);
278  if (i)
279  return i;
280  }
281  }
282  if (!no)
283  {
284  fprintf (stderr, "usage:\n "
285  " %s [-d] [-v] [-n] [-f] pattern file ..\n", prog);
286  return 2;
287  }
288  fflush(stdout);
289  dfa_delete (&dfa);
290  return 0;
291 }
292 /*
293  * Local variables:
294  * c-basic-offset: 4
295  * c-file-style: "Stroustrup"
296  * indent-tabs-mode: nil
297  * End:
298  * vim: shiftwidth=4 tabstop=8 expandtab
299  */
300 
static int go(int fd, struct DFA_state **dfaar)
Definition: agrep.c:162
unsigned short to
Definition: dfa.h:32
Definition: dfa.h:30
struct DFA * dfa_init(void)
Definition: dfa.c:1090
void dfa_mkstate(struct DFA *)
Definition: dfa.c:1146
static char * prline(char *p)
Definition: agrep.c:143
static char * inf_ptr
Definition: agrep.c:110
static char * inf_buf
Definition: agrep.c:109
int main(int argc, char **argv)
Definition: agrep.c:232
short rule_nno
Definition: dfa.h:50
struct DFA_state ** states
Definition: dfa.h:55
void * imalloc(size_t size)
Definition: imalloc.c:43
void error(const char *format,...)
Definition: agrep.c:51
static char * inf_flsh
Definition: agrep.c:110
unsigned char ch[2]
Definition: dfa.h:31
int agrep(struct DFA_state **dfas, int fd)
Definition: agrep.c:217
static int inf_eof
Definition: agrep.c:111
void ifree(void *p)
Definition: imalloc.c:93
struct DFA_tran * trans
Definition: dfa.h:45
void dfa_delete(struct DFA **)
Definition: dfa.c:1156
int dfa_verbose
Definition: dfa.c:67
int debug_dfa_followpos
Definition: dfa.c:66
#define INF_BUF_SIZE
Definition: agrep.c:108
static int line_no
Definition: agrep.c:111
Definition: dfa.h:42
int agrep_options(int argc, char **argv)
Definition: agrep.c:63
int dfa_parse(struct DFA *, const char **)
Definition: dfa.c:1119
short tran_no
Definition: dfa.h:48
static char * prog
Definition: agrep.c:49
int debug_dfa_tran
Definition: dfa.c:65
int fd
Definition: tstlockscope.c:38
int debug_dfa_trav
Definition: dfa.c:64
#define O_BINARY
Definition: agrep.c:46
static int inf_flush(int fd)
Definition: agrep.c:113
Definition: dfa.h:53
static int show_lines
Definition: agrep.c:61