Skip to content

Instantly share code, notes, and snippets.

@monzou
Created May 15, 2011 03:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save monzou/972876 to your computer and use it in GitHub Desktop.
Save monzou/972876 to your computer and use it in GitHub Desktop.
grep
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <regex.h>
#define _GNU_SOURCE
#include <getopt.h>
static void do_grep(regex_t *pattern, FILE *src, int invert);
static struct option longopts[] = {
{ "ignore-case", no_argument, NULL, 'i'},
{ "invert-match", no_argument, NULL, 'v'},
{ 0, 0, 0, 0 }
};
int main(int argc, char const *argv[])
{
int opt;
int reg_flags = REG_EXTENDED | REG_NOSUB | REG_NEWLINE;
int invert = 0;
while ((opt = getopt_long(argc, argv, "iv", longopts, NULL)) != -1) {
switch (opt) {
case 'i':
reg_flags |= REG_ICASE;
break;
case 'v':
invert = 1;
break;
case '?':
fprintf(stderr, "Usage: %s [-i] [-v] [pattern] [src]\n", argv[0]);
exit(1);
}
}
if (optind == argc) {
fprintf(stderr, "pattern must be specified.");
exit(1);
}
regex_t pattern;
int err = regcomp(&pattern, argv[optind], reg_flags);
if (err != 0) {
char buf[1024];
regerror(err, &pattern, buf, sizeof buf);
puts(buf);
exit(1);
}
if (index == argc) {
do_grep(&pattern, stdin, invert);
} else {
int i;
for (i = ++optind; i < argc; i++) {
FILE *src = fopen(argv[i], "r");
if (!src) {
perror(argv[i]);
exit(1);
}
do_grep(&pattern, src, invert);
fclose(src);
}
}
regfree(&pattern);
exit(0);
}
static void do_grep(regex_t *pattern, FILE *src, int invert)
{
char buf[4096];
while (fgets(buf, sizeof buf, src)) {
if (regexec(pattern, buf, 0, NULL, 0) == 0 && invert < 1) {
fputs(buf, stdout);
} else {
if (invert > 0) {
fputs(buf, stdout);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment