Created
January 9, 2011 23:59
-
-
Save damienix/772161 to your computer and use it in GitHub Desktop.
simple grep
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <ctype.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <sys/types.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <regex.h> | |
/** | |
* Simple grep | |
* | |
* see: http://souptonuts.sourceforge.net/code/regexp.c.html | |
* see: http://www.gnu.org/s/libc/manual/html_node/Example-of-Getopt.html#Example-of-Getopt | |
*/ | |
#define NUM_MATCHES 4//max sub-matches | |
char buffer[1024]; | |
char pom[1024]; | |
char *pattern = NULL; | |
regex_t preg; | |
regmatch_t pmatch[NUM_MATCHES]; | |
size_t rm, i; | |
int mode = 0; | |
int counter; | |
int only_numbers = 0; | |
int reverse = 0; | |
int show_line_num = 0; | |
int only_matching = 0; | |
void parse(FILE * in) { | |
int i = 1; | |
while (fgets(buffer, 1024, in)) { | |
/* it's possible something won't compile like ./regexp '*' abc */ | |
if ((rm = regcomp(&preg, pattern, mode)) != 0) { | |
fprintf(stderr, "Invalid expression:'%s'\n", pattern); | |
} | |
if (!reverse ^ (rm = regexec(&preg, buffer, NUM_MATCHES, pmatch, mode))) { | |
if (!only_numbers) { | |
if (show_line_num) | |
printf("%i:", i); | |
if (!only_matching) | |
printf("%s", buffer); | |
else { // Print match | |
strncpy(pom, buffer + pmatch[0].rm_so, | |
pmatch[0].rm_eo - pmatch[0].rm_so); | |
pom[pmatch[0].rm_eo - pmatch[0].rm_so] = '\0'; | |
printf("%s\n", pom); | |
} | |
} | |
counter++; | |
} | |
i++; | |
} | |
if (only_numbers) | |
printf("%d\n", counter); | |
} | |
int main(int argc, char **argv) { | |
int c; | |
FILE * file; | |
opterr = 0; | |
while ((c = getopt(argc, argv, "Eicvno")) != -1) { | |
switch (c) { | |
case 'E': | |
mode |= REG_EXTENDED; | |
break; | |
case 'i': | |
mode |= REG_ICASE; | |
break; | |
case 'c': | |
only_numbers = 1; | |
break; | |
case 'v': | |
reverse = 1; | |
break; | |
case 'n': | |
show_line_num = 1; | |
break; | |
case 'o': | |
only_matching = 1; | |
break; | |
/* | |
case '?': | |
if (optopt == 'c') | |
fprintf(stderr, "Option -%c requires an argument.\n", optopt); | |
else | |
*/ | |
if (isprint(optopt)) | |
fprintf(stderr, "Unknown option `-%c'.\n", optopt); | |
else | |
fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt); | |
return 1; | |
default: | |
abort(); | |
} | |
} | |
if (!argv[optind]) { | |
fprintf(stderr, "No pattern given.\n"); | |
abort(); | |
} else { | |
pattern = argv[optind]; | |
//printf("pattern: %s\n", pattern); | |
} | |
if (argv[optind + 1]) { | |
//printf("file: %s\n", argv[optind + 1]); | |
file = fopen(argv[optind + 1], "r"); | |
if (!file) { | |
fprintf(stderr, "No such file!\n"); | |
abort(); | |
} | |
parse(file); | |
} else { | |
parse(stdin); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment