4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
30 /* Copyright (c) 1987, 1988 Microsoft Corporation */
31 /* All Rights Reserved */
33 /* Copyright 2012 Nexenta Systems, Inc. All rights reserved. */
36 * grep -- print lines matching (or not matching) a pattern
39 * 0 - ok, and some matches
40 * 1 - ok, but no matches
44 #include <sys/types.h>
56 static const char *errstr
[] = {
57 "Range endpoint too large.",
59 "``\\digit'' out of range.",
60 "No remembered search string.",
63 "More than 2 numbers given in \\{ \\}.",
64 "} expected after \\.",
65 "First number exceeds second in \\{ \\}.",
67 "Regular expression overflow.",
68 "Illegal byte sequence.",
69 "Unknown regexp error code!!",
73 #define errmsg(msg, arg) (void) fprintf(stderr, gettext(msg), arg)
78 static long long lnum
;
80 static char *prntbuf
= NULL
;
81 static long fw_lPrntBufLen
= 0;
97 static char *ptr
, *ptrend
;
100 static void execute(char *);
101 static void regerr(int);
102 static int succeed(char *);
105 main(int argc
, char **argv
)
111 (void) setlocale(LC_ALL
, "");
112 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
113 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
115 (void) textdomain(TEXT_DOMAIN
);
117 while ((c
= getopt(argc
, argv
, "hqblcnsviyw")) != -1)
122 case 'q': /* POSIX: quiet: status only */
154 if (errflg
|| (optind
>= argc
)) {
155 errmsg("Usage: grep [-c|-l|-q] -hbnsviw pattern file . . .\n",
160 argv
= &argv
[optind
];
164 if (strrchr(*argv
, '\n') != NULL
)
168 for (arg
= *argv
; *arg
!= NULL
; ++arg
)
169 *arg
= (char)tolower((int)((unsigned char)*arg
));
173 unsigned int wordlen
;
176 wordlen
= strlen(*argv
) + 5; /* '\\' '<' *argv '\\' '>' '\0' */
177 if ((wordbuf
= malloc(wordlen
)) == NULL
) {
178 errmsg("grep: Out of memory for word\n", (char *)NULL
);
182 (void) strcpy(wordbuf
, "\\<");
183 (void) strcat(wordbuf
, *argv
);
184 (void) strcat(wordbuf
, "\\>");
188 expbuf
= compile(*argv
, (char *)0, (char *)0);
198 return (nsucc
== 2 ? 2 : (nsucc
== 0 ? 1 : 0));
207 char *next_ptr
= NULL
;
212 if (prntbuf
== NULL
) {
213 fw_lPrntBufLen
= GBUFSIZ
+ 1;
214 if ((prntbuf
= malloc(fw_lPrntBufLen
)) == NULL
) {
215 exit(2); /* out of memory - BAIL */
217 if ((linebuf
= malloc(fw_lPrntBufLen
)) == NULL
) {
218 exit(2); /* out of memory - BAIL */
224 else if ((temp
= open(file
, O_RDONLY
)) == -1) {
226 errmsg("grep: can't open %s\n", file
);
231 /* read in first block of bytes */
232 if ((count
= read(temp
, prntbuf
, GBUFSIZ
)) <= 0) {
235 if (cflag
&& !qflag
) {
236 if (nfile
> 1 && !hflag
&& file
)
237 (void) fprintf(stdout
, "%s:", file
);
238 (void) fprintf(stdout
, "%lld\n", tln
);
246 /* look for next newline */
247 if ((ptrend
= memchr(ptr
+ offset
, '\n', count
)) == NULL
) {
251 * shift unused data to the beginning of the buffer
254 (void) memmove(prntbuf
, ptr
, offset
);
259 * re-allocate a larger buffer if this one is full
261 if (offset
+ GBUFSIZ
> fw_lPrntBufLen
) {
263 * allocate a new buffer and preserve the
266 fw_lPrntBufLen
+= GBUFSIZ
;
267 if ((prntbuf
= realloc(prntbuf
,
268 fw_lPrntBufLen
)) == NULL
)
272 * set up a bigger linebuffer (this is only used
273 * for case insensitive operations). Contents do
274 * not have to be preserved.
277 if ((linebuf
= malloc(fw_lPrntBufLen
)) == NULL
)
283 p
= prntbuf
+ offset
;
284 if ((count
= read(temp
, p
, GBUFSIZ
)) > 0)
288 /* end of file already reached */
291 /* last line of file has no newline */
292 ptrend
= ptr
+ offset
;
295 next_ptr
= ptrend
+ 1;
296 next_count
= offset
+ count
- (next_ptr
- ptr
);
304 * Make a lower case copy of the record
307 for (lbuf
= linebuf
; p
< ptrend
; )
308 *lbuf
++ = (char)tolower((int)
309 (unsigned char)*p
++);
318 /* lflag only once */
319 if ((step(lbuf
, expbuf
) ^ vflag
) && succeed(file
) == 1)
331 if (cflag
&& !qflag
) {
332 if (nfile
> 1 && !hflag
&& file
)
333 (void) fprintf(stdout
, "%s:", file
);
334 (void) fprintf(stdout
, "%lld\n", tln
);
342 nsucc
= (nsucc
== 2) ? 2 : 1;
348 /* no need to continue */
358 (void) fprintf(stdout
, "%s\n", f
);
362 if (nfile
> 1 && !hflag
)
364 (void) fprintf(stdout
, "%s:", f
);
367 /* print block number */
368 (void) fprintf(stdout
, "%lld:", (offset_t
)
369 ((lseek(temp
, (off_t
)0, SEEK_CUR
) - 1) / BLKSIZE
));
372 /* print line number */
373 (void) fprintf(stdout
, "%lld:", lnum
);
376 /* newline at end of line */
378 nchars
= ptrend
- ptr
+ 1;
380 /* don't write sentinel \0 */
381 nchars
= ptrend
- ptr
;
384 (void) fwrite(ptr
, 1, nchars
, stdout
);
391 errmsg("grep: RE error %d: ", err
);
434 errmsg("%s\n", gettext(errstr
[err
]));