Skip to content

Instantly share code, notes, and snippets.

@Yepoleb
Created February 13, 2019 14:03
Show Gist options
  • Save Yepoleb/27354e87f90daae87aa48fcc48a6785f to your computer and use it in GitHub Desktop.
Save Yepoleb/27354e87f90daae87aa48fcc48a6785f to your computer and use it in GitHub Desktop.
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <assert.h>
const char* const ANSI_COLOR_RED = "\x1b[31m";
const char* const ANSI_COLOR_RESET = "\x1b[0m";
const size_t BUFFERGROWTH = 128;
size_t getline_(char **lineptr, size_t *linesize, FILE *stream)
{
if (*lineptr == NULL) {
*lineptr = malloc(BUFFERGROWTH);
*linesize = BUFFERGROWTH;
}
size_t buffer_i = 0;
char c = 0;
while (c != '\n') {
// Detect need for buffer growth
if (buffer_i >= *linesize) {
*linesize += BUFFERGROWTH;
*lineptr = realloc(*lineptr, *linesize);
}
c = getc(stream);
if (c == -1) { // EOF
break;
}
(*lineptr)[buffer_i++] = c;
}
(*lineptr)[buffer_i] = '\0';
return buffer_i;
}
int main(int argc, char **argv)
{
//TODO: create self-made strstr() function just for fun
char *search_pattern;
char *(*search_func)(const char*, const char*);
if (argc == 2) {
search_func = strstr;
search_pattern = argv[1];
} else if (argc == 3 && strcmp(argv[1], "-i") == 0) {
search_func = strcasestr;
search_pattern = argv[2];
} else {
fprintf(stderr, "Usage: grep [OPTION] [PATTERN]\n");
return EXIT_FAILURE;
}
FILE *fp = stdin;
size_t pattern_size = strlen(search_pattern);
char *linebuffer = NULL;
size_t linesize;
size_t buffersize;
while (linesize = getline_(&linebuffer, &buffersize, fp)) {
char *search_start = linebuffer;
while (1) {
char *search_res = search_func(search_start, search_pattern);
if ((search_start == linebuffer) && search_res == NULL) {
// Skip line
break;
}
if (search_res == NULL) {
// Write remaining part of the line
size_t size_remain = linebuffer + linesize - search_start;
fwrite(search_start, 1, size_remain, stdout);
break;
}
// Write non-matching part
fwrite(search_start, 1, search_res - search_start, stdout);
printf(ANSI_COLOR_RED);
// Write matching part
fwrite(search_res, 1, pattern_size, stdout);
printf(ANSI_COLOR_RESET);
search_start = search_res + pattern_size;
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment