HTMLify
main.c
Views: 8 | Author: abh
/* grep */
#include <stdio.h>
#include <regex.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>
#include <dirent.h>
#include <malloc.h>
#include <argp.h>
struct csf { // Current Search File
char *name;
} csf;
struct arguments {
bool recursive;
bool print_file_name;
char *regex_string;
char **files;
int file_count;
char *rdir;
} arguments;
void change_color(char c) {
if (!isatty(fileno(stdout))) return;
switch (c) {
case 'r': printf("\e[1;31m"); break;
case 'p': printf("\e[0;35m"); break;
case 'c': printf("\e[36m"); break;
case 'n': printf("\e[0;97m"); break;
}
}
void print_csf() {
change_color('p');
printf("%s", csf.name);
change_color('c');
printf(":");
change_color('n');
}
void search_in_line(const regex_t *regex, const char *line) {
regmatch_t regmatch;
int error;
error = regexec(regex, line, 1, ®match, 0);
if (!error) {
int i = 0;
if (arguments.print_file_name)
print_csf();
for (i=0; line[i] != '\0'; i++) {
if (i == regmatch.rm_so)
change_color('r');
if (i == regmatch.rm_eo)
change_color('n');
printf("%c", line[i]);
}
}
}
void search_in_file(const regex_t *regex, const char *filename) {
FILE *f = fopen(filename, "r");
if (f == NULL) {
fprintf(stderr, "Unable to open file %s \n", filename);
return;
}
if (arguments.print_file_name)
csf.name = strdup(filename);
char line[10240];
while (fgets(line, 10240, f) != NULL) {
search_in_line(regex, line);
}
}
void search_in_dir(const regex_t *regex, const char *dpath) {
char *dirpath = strdup(dpath);
if (strlen(dirpath) > 1 && dirpath[strlen(dirpath)] == '\0')
dirpath[strlen(dirpath)] = '\0';
DIR *dir = opendir(dirpath);
if (dir == NULL)
return;
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
continue;
int len = strlen(dirpath) + strlen(entry->d_name) + 2;
char *fullpath = malloc(len);
sprintf(fullpath, "%s/%s", dirpath, entry->d_name);
if (entry->d_type == DT_DIR) {
search_in_dir(regex, fullpath);
} else {
search_in_file(regex, fullpath);
}
}
}
void search_in_stdin(const regex_t *regex) {
char line[10240];
while (fgets(line, 10240, stdin) != NULL)
search_in_line(regex, line);
}
int parse_opt(int key, char *arg, struct argp_state *state) {
struct arguments *arguments = state->input;
switch (key) {
case 'r': {
arguments->recursive = true;
if (arg) {
arguments->rdir = strdup(arg);
} else if (state->argv[state->next]) {
arguments->rdir = state->argv[state->next];
state->next++;
} else {
arguments->rdir = strdup(".");
}
break;
}
case ARGP_KEY_ARG: {
if (!arguments->regex_string) {
arguments->regex_string = arg;
} else {
arguments->files = &state->argv[state->next - 1];
arguments->file_count = state->argc - (state->next - 1);
state->next = state->argc;
}
break;
}
}
return 0;
}
int main(int argc, char *argv[]) {
struct argp_option options[] = {
{ "recursive", 'r', "DIR", OPTION_ARG_OPTIONAL, "Search recursivly in directory" },
{ 0 }
};
struct argp argp = { options, parse_opt, 0, 0 };
argp_parse(&argp, argc, argv, 0, 0, &arguments);
if (arguments.regex_string == NULL) {
fprintf(stderr, "RegEx is required");
return 1;
}
regex_t regex;
if (regcomp(®ex, arguments.regex_string, 0) != 0) {
fprintf(stderr, "Faild to compile the regex");
return 1;
}
if (arguments.recursive) {
arguments.print_file_name = true;
search_in_dir(®ex, arguments.rdir);
return 0;
}
if (!arguments.file_count) {
search_in_stdin(®ex);
return 0;
}
if (arguments.file_count > 1)
arguments.print_file_name = true;
for (int i = 0; i < arguments.file_count; i++)
search_in_file(®ex, arguments.files[i]);
return 0;
}