IDZEBRA 2.2.8
agrep.c
Go to the documentation of this file.
1/* This file is part of the Zebra server.
2 Copyright (C) Index Data
3
4Zebra is free software; you can redistribute it and/or modify it under
5the terms of the GNU General Public License as published by the Free
6Software Foundation; either version 2, or (at your option) any later
7version.
8
9Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10WARRANTY; without even the implied warranty of MERCHANTABILITY or
11FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, 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
49static char *prog;
50
51void 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
61static int show_lines = 0;
62
63int 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':
85 break;
86 case 't':
88 break;
89 case 'f':
91 break;
92 default:
93 --*argv;
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
109static char *inf_buf;
110static char *inf_ptr, *inf_flsh;
111static int inf_eof, line_no;
112
113static 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
143static 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
162static 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 {
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
217int 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
232int 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 char * inf_ptr
Definition agrep.c:110
static int go(int fd, struct DFA_state **dfaar)
Definition agrep.c:162
#define O_BINARY
Definition agrep.c:46
int main(int argc, char **argv)
Definition agrep.c:232
int agrep(struct DFA_state **dfas, int fd)
Definition agrep.c:217
static int inf_eof
Definition agrep.c:111
static char * inf_buf
Definition agrep.c:109
static int line_no
Definition agrep.c:111
int agrep_options(int argc, char **argv)
Definition agrep.c:63
static int inf_flush(int fd)
Definition agrep.c:113
static char * inf_flsh
Definition agrep.c:110
static char * prog
Definition agrep.c:49
static char * prline(char *p)
Definition agrep.c:143
static int show_lines
Definition agrep.c:61
#define INF_BUF_SIZE
Definition agrep.c:108
void error(const char *format,...)
Definition agrep.c:51
int dfa_parse(struct DFA *, const char **)
Definition dfa.c:1121
void dfa_mkstate(struct DFA *)
Definition dfa.c:1148
void dfa_delete(struct DFA **)
Definition dfa.c:1158
int debug_dfa_followpos
Definition dfa.c:68
int debug_dfa_trav
Definition dfa.c:66
struct DFA * dfa_init(void)
Definition dfa.c:1092
int dfa_verbose
Definition dfa.c:69
int debug_dfa_tran
Definition dfa.c:67
void ifree(void *p)
Definition imalloc.c:93
void * imalloc(size_t size)
Definition imalloc.c:43
short tran_no
Definition dfa.h:48
short rule_nno
Definition dfa.h:50
struct DFA_tran * trans
Definition dfa.h:45
Definition dfa.h:30
unsigned short to
Definition dfa.h:32
unsigned char ch[2]
Definition dfa.h:31
Definition dfa.h:53
struct DFA_state ** states
Definition dfa.h:55
int fd