Untitled
unknown
c_cpp
2 years ago
7.6 kB
4
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...