Untitled
unknown
c_cpp
2 years ago
7.6 kB
5
Indexable
#define _GNU_SOURCE
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 4096
typedef struct short_flags {
int i_flag;
int v_flag;
int c_flag;
int l_flag;
int n_flag;
int h_flag;
int s_flag;
int o_flag;
} shortflags;
void short_flags_parser(char argv, shortflags *flags) {
if (argv == 'i') flags->i_flag = 1;
if (argv == 'v') flags->v_flag = 1;
if (argv == 'c') flags->c_flag = 1;
if (argv == 'l') flags->l_flag = 1;
if (argv == 'n') flags->n_flag = 1;
if (argv == 'h') flags->h_flag = 1;
if (argv == 's') flags->s_flag = 1;
if (argv == 'o') flags->o_flag = 1;
}
void add_elem_arr(char ***array, int *size, char *data) {
char **new_array;
*size = *size + 1;
new_array = realloc(*array, sizeof(char *) * (*size));
new_array[*size - 1] = malloc(sizeof(char) * strlen(data) + 1);
strcpy(new_array[*size - 1], data);
*array = new_array;
}
char **init_arr(char **array, char *data,
int *size) { //создаёт массив размером 1 где в нулевом элементе
//лежит название массива
*size = 1;
array = malloc(sizeof(char *));
array[0] = malloc(strlen(data) * sizeof(char) + 1);
strcpy(array[0], data);
return array;
}
void rm_arr(char **array, int size) {
for (int i = 0; i < size; i++) {
free(array[i]);
}
free(array);
}
void print_arr(char **array, int size) {
printf("print_arr size: %d\n", size);
for (int i = 0; i < size; i++) {
printf("print_arr[%d]: %s\n",i, array[i]);
}
}
int f_flag_handler(char *filename, char ***templates, int *templates_size) {
FILE *file = fopen(filename, "r");
char *line = NULL;
int err_flag = 0;
size_t length = 0;
if (file == NULL) {
printf("grep: %s: No such file or directory\n", filename);
err_flag = 1;
} else {
while (getline(&line, &length, file) > 0) {
char *pos;
if ((pos = strchr(line, '\n')) != NULL) *pos = '\0';
add_elem_arr(templates, templates_size, line);
}
fclose(file);
}
free(line);
return err_flag;
}
int arg_handler(int argc, char **argv, shortflags *flags, char ***templates,
int *templates_size, char ***filenames, int *filenames_size,
int *err_flag) //получает массив argv
{
for (int i = 1; i < argc; i++) {
for (size_t j = 1; j < strlen(argv[i]); j++) {
if (argv[i][0] == '-' && argv[i][1] != 'e' && argv[i][1] != 'f') {
short_flags_parser(argv[i][j], flags);
}
}
if (argv[i][0] != '-') {
add_elem_arr(filenames, filenames_size, argv[i]);
}
if (argv[i][0] == '-' && argv[i][1] == 'e') {
if (argv[i + 1] != NULL) {
add_elem_arr(templates, templates_size, argv[i + 1]);
i++;
} else
*err_flag = 1;
}
if (argv[i][0] == '-' && argv[i][1] == 'f') {
if (argv[i + 1] != NULL) {
if (f_flag_handler(argv[i + 1], templates, templates_size) == 1) {
*err_flag = 1;
break;
}
i++;
} else
*err_flag = 1;
}
}
return *err_flag;
}
int fill_all_matches_one_file(shortflags *flags, char ***templates,
int *templates_size, char ***matches,
int *matches_size, FILE *file,
int *line_numbers) {
int err_flag = 0;
regex_t comp_template_storage;
regex_t *comp_template = &comp_template_storage;
regmatch_t pmatch;
size_t length = 0;
int regflag = REG_EXTENDED;
if (flags->i_flag == 1) regflag = REG_ICASE;
char *line = NULL;
int line_number = 0, index = 0, v_case = 0;
if (flags->v_flag) v_case = REG_NOMATCH;
for (int i = 1; i < *templates_size; i++) {
regcomp(comp_template, *templates[i], regflag);
}
while (getline(&line, &length, file) > 0) {
line_number++;
if (regexec(comp_template, line, 1, &pmatch, 0) == v_case)
add_elem_arr(matches, matches_size, line);
line_numbers[index] = line_number; // -1 na vyzov
index = index + 1;
}
regfree(comp_template);
free(line);
return err_flag;
}
int grepfile(char *filename, char ***templates, int *templates_size,
shortflags *flags, char ***matches, int *matches_size,
int *line_numbers) {
int err_flag = 0;
FILE *file = fopen(filename, "r");
if (file == NULL) {
if (flags->s_flag == 0)
printf("grep: %s: No such file or directory\n", filename);
err_flag = 1;
} else {
fill_all_matches_one_file(flags, templates, templates_size, matches,
matches_size, file, line_numbers);
fclose(file);
}
return err_flag;
}
int output(char *filename, shortflags *flags, char ***matches,
int *matches_size, int *line_numbers, char ***templates,
int *templates_size) {
int err_flag = 0;
int c_counter = *matches_size - 1;
if (flags->l_flag && c_counter >= 1) c_counter = 1; // macos c_flag l case
if (!flags->c_flag && !flags->l_flag) {
int ind = 0;
// while (matches->next != NULL) {
for (int i = 1; i < *matches_size; i++) {
if (!flags->h_flag) printf("%s:", filename);
if (flags->n_flag) printf("%d:", line_numbers[ind]);
if (!flags->o_flag) printf("%s", *matches[i]);
if (flags->o_flag && flags->v_flag) printf("%s\n", *matches[i]);
if (flags->o_flag && !flags->v_flag)
// o_flag_handler(*matches[i], templates, flags);
ind++;
if (!flags->o_flag) printf("\n");
}
}
if (flags->c_flag && c_counter > 0) {
if (!flags->h_flag) printf("%s:%d\n", filename, c_counter);
if (flags->h_flag) printf("%d\n", c_counter);
}
if (flags->l_flag && c_counter >= 1) { // l_flag
printf("%s\n", filename);
}
return err_flag;
}
int logic_handler( char ***templates, int *templates_size,shortflags *flags, char ***filenames, int *filenames_size) {
int err_flag = 0;
int line_numbers[MAX_SIZE];
for (int i = 1; i < *filenames_size; i++) {
char **matches;
int matches_size = 0;
matches = init_arr(matches, "root_matches", &matches_size);
if (grepfile(*filenames[i], templates, templates_size, flags, &matches,
&matches_size, line_numbers) == 1)
err_flag = 1;
// output(*filenames[i], flags, &matches, &matches_size, line_numbers,
// templates, templates_size);
rm_arr(matches, matches_size);
}
return err_flag;
}
int main(int argc, char *argv[]) {
int err_flag = 0;
if (argc > 1) {
shortflags flags = {0, 0, 0, 0, 0, 0, 0, 0};
char **filenames;
int filenames_size = 0;
filenames = init_arr(filenames, "root_filenames", &filenames_size);
char **templates;
int templates_size = 0;
templates = init_arr(templates, "root_templates", &templates_size);
if (!arg_handler(argc, argv, &flags, &templates, &templates_size,
&filenames, &filenames_size, &err_flag)) {
printf("templates_size: %d\n", templates_size);
if(templates_size > 1){
if(logic_handler(&templates, &templates_size, &flags, &filenames, &filenames_size)==1) err_flag = 1;
}
} else {
printf(
"grep: options require an argument -- [-ef]\nUsage: grep [OPTION]... "
"PATTERNS [FILE]...\nTry 'grep --help' for more information.\n");
}
rm_arr(filenames, filenames_size);
rm_arr(templates, templates_size);
} else {
printf("err: empty input\nusage: [-e pattern] [-f file] [-ivclnhso]\n");
err_flag = 1;
}
return err_flag;
}Editor is loading...