IDZEBRA 2.2.11
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 <idzebra/version.h>
43#include <dfa.h>
44#include "imalloc.h"
45
46#ifndef O_BINARY
47#define O_BINARY 0
48#endif
49
50static char *prog;
51
52void error (const char *format, ...)
53{
54 va_list argptr;
55 va_start (argptr, format);
56 fprintf (stderr, "%s error: ", prog);
57 (void) vfprintf (stderr, format, argptr);
58 putc ('\n', stderr);
59 exit (1);
60}
61
62static int show_lines = 0;
63
64int agrep_options (int argc, char **argv)
65{
66 char version_str[16];
67 zebra_get_version(version_str, NULL);
68 while (--argc > 0)
69 if (**++argv == '-')
70 while (*++*argv)
71 {
72 switch (**argv)
73 {
74 case 'V':
75 fprintf (stderr, "%s: %s\n", prog, version_str);
76 continue;
77 case 'v':
78 dfa_verbose = 1;
79 continue;
80 case 'n':
81 show_lines = 1;
82 continue;
83 case 'd':
84 switch (*++*argv)
85 {
86 case 's':
88 break;
89 case 't':
91 break;
92 case 'f':
94 break;
95 default:
96 --*argv;
100 }
101 continue;
102 default:
103 fprintf (stderr, "%s: unknown option `-%s'\n", prog, *argv);
104 return 1;
105 }
106 break;
107 }
108 return 0;
109}
110
111#define INF_BUF_SIZE 32768U
112static char *inf_buf;
113static char *inf_ptr, *inf_flsh;
114static int inf_eof, line_no;
115
116static int inf_flush (int fd)
117{
118 char *p;
119 unsigned b, r;
120
121 r = (unsigned) (inf_buf+INF_BUF_SIZE - inf_ptr); /* no of `wrap' bytes */
122 if (r)
123 memcpy (inf_buf, inf_ptr, r);
124 inf_ptr = p = inf_buf + r;
125 b = INF_BUF_SIZE - r;
126 do
127 if ((r = read (fd, p, b)) == (unsigned) -1)
128 return -1;
129 else if (r)
130 p += r;
131 else
132 {
133 *p++ = '\n';
134 inf_eof = 1;
135 break;
136 }
137 while ((b -= r) > 0);
138 while (p != inf_buf && *--p != '\n')
139 ;
140 while (p != inf_buf && *--p != '\n')
141 ;
142 inf_flsh = p+1;
143 return 0;
144}
145
146static char *prline (char *p)
147{
148 char *p0;
149
150 --p;
151 while (p != inf_buf && p[-1] != '\n')
152 --p;
153 p0 = p;
154 while (*p++ != '\n')
155 ;
156 p[-1] = '\0';
157 if (show_lines)
158 printf ("%5d:\t%s\n", line_no, p0);
159 else
160 puts (p0);
161 p[-1] = '\n';
162 return p;
163}
164
165static int go (int fd, struct DFA_state **dfaar)
166{
167 struct DFA_state *s = dfaar[0];
168 struct DFA_tran *t;
169 char *p;
170 int i;
171 unsigned char c;
172 int start_line = 1;
173
174 while (1)
175 {
176 for (c = *inf_ptr++, t=s->trans, i=s->tran_no; --i >= 0; t++)
177 if (c >= t->ch[0] && c <= t->ch[1])
178 {
179 p = inf_ptr;
180 do
181 {
182 if ((s = dfaar[t->to])->rule_no &&
183 (start_line || s->rule_nno))
184 {
186 c = '\n';
187 break;
188 }
189 for (t=s->trans, i=s->tran_no; --i >= 0; t++)
190 if ((unsigned) *p >= t->ch[0]
191 && (unsigned) *p <= t->ch[1])
192 break;
193 p++;
194 } while (i >= 0);
195 s = dfaar[0];
196 break;
197 }
198 if (c == '\n')
199 {
200 start_line = 1;
201 ++line_no;
202 if (inf_ptr == inf_flsh)
203 {
204 if (inf_eof)
205 break;
206 ++line_no;
207 if (inf_flush (fd))
208 {
209 fprintf (stderr, "%s: read error\n", prog);
210 return -1;
211 }
212 }
213 }
214 else
215 start_line = 0;
216 }
217 return 0;
218}
219
220int agrep (struct DFA_state **dfas, int fd)
221{
222 inf_buf = imalloc (sizeof(char)*INF_BUF_SIZE);
223 inf_eof = 0;
225 inf_flush (fd);
226 line_no = 1;
227
228 go (fd, dfas);
229
230 ifree (inf_buf);
231 return 0;
232}
233
234
235int main (int argc, char **argv)
236{
237 const char *pattern = NULL;
238 char outbuf[BUFSIZ];
239 int fd, i, no = 0;
240 struct DFA *dfa = dfa_init();
241
242 prog = *argv;
243 if (argc < 2)
244 {
245 fprintf (stderr, "usage: agrep [options] pattern file..\n");
246 fprintf (stderr, " -v dfa verbose\n");
247 fprintf (stderr, " -n show lines\n");
248 fprintf (stderr, " -d debug\n");
249 fprintf (stderr, " -V show version\n");
250 exit (1);
251 }
252 setbuf (stdout, outbuf);
253 i = agrep_options (argc, argv);
254 if (i)
255 return i;
256 while (--argc > 0)
257 if (**++argv != '-' && **argv)
258 {
259 if (!pattern)
260 {
261 pattern = *argv;
262 i = dfa_parse (dfa, &pattern);
263 if (i || *pattern)
264 {
265 fprintf (stderr, "%s: illegal pattern\n", prog);
266 return 1;
267 }
268 dfa_mkstate (dfa);
269 }
270 else
271 {
272 ++no;
273 fd = open (*argv, O_RDONLY | O_BINARY);
274 if (fd == -1)
275 {
276 fprintf (stderr, "%s: couldn't open `%s'\n", prog, *argv);
277 return 1;
278 }
279 i = agrep (dfa->states, fd);
280 close (fd);
281 if (i)
282 return i;
283 }
284 }
285 if (!no)
286 {
287 fprintf (stderr, "usage:\n "
288 " %s [-d] [-v] [-n] [-f] pattern file ..\n", prog);
289 return 2;
290 }
291 fflush(stdout);
292 dfa_delete (&dfa);
293 return 0;
294}
295/*
296 * Local variables:
297 * c-basic-offset: 4
298 * c-file-style: "Stroustrup"
299 * indent-tabs-mode: nil
300 * End:
301 * vim: shiftwidth=4 tabstop=8 expandtab
302 */
303
static char * inf_ptr
Definition agrep.c:113
static int go(int fd, struct DFA_state **dfaar)
Definition agrep.c:165
#define O_BINARY
Definition agrep.c:47
int main(int argc, char **argv)
Definition agrep.c:235
int agrep(struct DFA_state **dfas, int fd)
Definition agrep.c:220
static int inf_eof
Definition agrep.c:114
static char * inf_buf
Definition agrep.c:112
static int line_no
Definition agrep.c:114
int agrep_options(int argc, char **argv)
Definition agrep.c:64
static int inf_flush(int fd)
Definition agrep.c:116
static char * inf_flsh
Definition agrep.c:113
static char * prog
Definition agrep.c:50
static char * prline(char *p)
Definition agrep.c:146
static int show_lines
Definition agrep.c:62
#define INF_BUF_SIZE
Definition agrep.c:111
void error(const char *format,...)
Definition agrep.c:52
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
void zebra_get_version(char *version_str, char *sha1_str)
Returns Zebra version and SHA1 ID as generated by Git.
Definition version.c:32