Implement grep -F
This commit is contained in:
		
							
								
								
									
										26
									
								
								grep.1
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								grep.1
									
									
									
									
									
								
							| @@ -3,7 +3,7 @@ | |||||||
| grep \- search files for a pattern | grep \- search files for a pattern | ||||||
| .SH SYNOPSIS | .SH SYNOPSIS | ||||||
| .B grep | .B grep | ||||||
| .RB [ \-EHchilnqsv ] | .RB [ \-EFHchilnqsv ] | ||||||
| .RB [ \-e | .RB [ \-e | ||||||
| .I pattern ] | .I pattern ] | ||||||
| .I pattern | .I pattern | ||||||
| @@ -22,14 +22,18 @@ status code is 2. | |||||||
| .SH OPTIONS | .SH OPTIONS | ||||||
| .TP | .TP | ||||||
| .B \-E | .B \-E | ||||||
| matches using extended regex. | Matches using extended regex. | ||||||
|  | .TP | ||||||
|  | .B \-F | ||||||
|  | Match using fixed strings.  Treat each pattern specified as a string instead of a regular | ||||||
|  | expression. | ||||||
| .TP | .TP | ||||||
| .B \-H | .B \-H | ||||||
| prefixes each matching line with its filename in the output. This is the | Prefixes each matching line with its filename in the output. This is the | ||||||
| default when there is more than one file specified. | default when there is more than one file specified. | ||||||
| .TP | .TP | ||||||
| .B \-c | .B \-c | ||||||
| prints only a count of matching lines. | Prints only a count of matching lines. | ||||||
| .TP | .TP | ||||||
| .B \-e pattern | .B \-e pattern | ||||||
| Specify a pattern used during the search of the input: an input | Specify a pattern used during the search of the input: an input | ||||||
| @@ -39,26 +43,26 @@ specify multiple patterns, or when a pattern begins with a dash | |||||||
| (`-'). | (`-'). | ||||||
| .TP | .TP | ||||||
| .B \-h | .B \-h | ||||||
| do not prefix each line with 'filename:' prefix. | Do not prefix each line with 'filename:' prefix. | ||||||
| .TP | .TP | ||||||
| .B \-i | .B \-i | ||||||
| matches lines case insensitively. | Matches lines case insensitively. | ||||||
| .TP | .TP | ||||||
| .B \-l | .B \-l | ||||||
| prints only the names of files with matching lines. | Prints only the names of files with matching lines. | ||||||
| .TP | .TP | ||||||
| .B \-n | .B \-n | ||||||
| prefixes each matching line with its line number in the input. | Prefixes each matching line with its line number in the input. | ||||||
| .TP | .TP | ||||||
| .B \-q | .B \-q | ||||||
| prints nothing, only returns status. | Prints nothing, only returns status. | ||||||
| .TP | .TP | ||||||
| .B \-s | .B \-s | ||||||
| Suppress the error messages ordinarily written for nonexistent or unreadable files. | Suppress the error messages ordinarily written for nonexistent or unreadable files. | ||||||
| .TP | .TP | ||||||
| .B \-v | .B \-v | ||||||
| selects lines which do | Selects lines which do | ||||||
| .B not | .B not | ||||||
| match the pattern. | Match the pattern. | ||||||
| .SH SEE ALSO | .SH SEE ALSO | ||||||
| .IR regex (7) | .IR regex (7) | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								grep.c
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								grep.c
									
									
									
									
									
								
							| @@ -14,6 +14,7 @@ enum { Match = 0, NoMatch = 1, Error = 2 }; | |||||||
| static void addpattern(const char *); | static void addpattern(const char *); | ||||||
| static int grep(FILE *, const char *); | static int grep(FILE *, const char *); | ||||||
|  |  | ||||||
|  | static int Fflag; | ||||||
| static int Hflag; | static int Hflag; | ||||||
| static int eflag; | static int eflag; | ||||||
| static int hflag; | static int hflag; | ||||||
| @@ -33,7 +34,7 @@ static SLIST_HEAD(phead, pattern) phead; | |||||||
| static void | static void | ||||||
| usage(void) | usage(void) | ||||||
| { | { | ||||||
| 	enprintf(Error, "usage: %s [-EHcilnqsv] [-e pattern] pattern [files...]\n", argv0); | 	enprintf(Error, "usage: %s [-EFHcilnqsv] [-e pattern] pattern [files...]\n", argv0); | ||||||
| } | } | ||||||
|  |  | ||||||
| int | int | ||||||
| @@ -49,6 +50,9 @@ main(int argc, char *argv[]) | |||||||
| 	case 'E': | 	case 'E': | ||||||
| 		flags |= REG_EXTENDED; | 		flags |= REG_EXTENDED; | ||||||
| 		break; | 		break; | ||||||
|  | 	case 'F': | ||||||
|  | 		Fflag = 1; | ||||||
|  | 		break; | ||||||
| 	case 'H': | 	case 'H': | ||||||
| 		Hflag = 1; | 		Hflag = 1; | ||||||
| 		break; | 		break; | ||||||
| @@ -88,6 +92,7 @@ main(int argc, char *argv[]) | |||||||
| 		argv++; | 		argv++; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if (!Fflag) | ||||||
| 		/* Compile regex for all search patterns */ | 		/* Compile regex for all search patterns */ | ||||||
| 		SLIST_FOREACH(pnode, &phead, entry) | 		SLIST_FOREACH(pnode, &phead, entry) | ||||||
| 			enregcomp(Error, &pnode->preg, pnode->pattern, flags); | 			enregcomp(Error, &pnode->preg, pnode->pattern, flags); | ||||||
| @@ -111,6 +116,7 @@ main(int argc, char *argv[]) | |||||||
| 	while (!SLIST_EMPTY(&phead)) { | 	while (!SLIST_EMPTY(&phead)) { | ||||||
| 		pnode = SLIST_FIRST(&phead); | 		pnode = SLIST_FIRST(&phead); | ||||||
| 		SLIST_REMOVE_HEAD(&phead, entry); | 		SLIST_REMOVE_HEAD(&phead, entry); | ||||||
|  | 		if (!Fflag) | ||||||
| 			regfree(&pnode->preg); | 			regfree(&pnode->preg); | ||||||
| 		free(pnode->pattern); | 		free(pnode->pattern); | ||||||
| 		free(pnode); | 		free(pnode); | ||||||
| @@ -142,8 +148,15 @@ grep(FILE *fp, const char *str) | |||||||
| 		if (len && buf[len - 1] == '\n') | 		if (len && buf[len - 1] == '\n') | ||||||
| 			buf[len - 1] = '\0'; | 			buf[len - 1] = '\0'; | ||||||
| 		SLIST_FOREACH(pnode, &phead, entry) { | 		SLIST_FOREACH(pnode, &phead, entry) { | ||||||
|  | 			if (!Fflag) { | ||||||
| 				if (regexec(&pnode->preg, buf, 0, NULL, 0) ^ vflag) | 				if (regexec(&pnode->preg, buf, 0, NULL, 0) ^ vflag) | ||||||
| 					continue; | 					continue; | ||||||
|  | 			} else { | ||||||
|  | 				match = strstr(buf, pnode->pattern) ? Match : NoMatch; | ||||||
|  | 				match ^= vflag; | ||||||
|  | 				if (match) | ||||||
|  | 					continue; | ||||||
|  | 			} | ||||||
| 			switch (mode) { | 			switch (mode) { | ||||||
| 			case 'c': | 			case 'c': | ||||||
| 				c++; | 				c++; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user