/
solidbase
/
C2_SimpleBashUtils
Обзор
Документация
Войти
/
solidbase
/
C2_SimpleBashUtils
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop
src/grep/options.c
266 строк
5 KB
Dmitrii Isaev
style(grep): improve code formatting in options.c
02 дек 2025, 11:48
02 дек 2025, 11:48
736bdb4
Код
Авторство
О чём код?
#include "options.h" #include <errno.h> #include <getopt.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> static char* dup_string(const char* s) { if (!s) { return NULL; } size_t len = strlen(s) + 1; char* copy = malloc(len); if (!copy) { return NULL; } memcpy(copy, s, len); return copy; } static void trim_newline(char* line) { size_t len = strlen(line); if (len > 0 && line[len - 1] == '\n') { line[len - 1] = '\0'; } } void init_options(Options* opts) { opts->flag_e = 0; opts->flag_i = 0; opts->flag_v = 0; opts->flag_c = 0; opts->flag_l = 0; opts->flag_n = 0; opts->flag_h = 0; opts->flag_s = 0; opts->flag_f = 0; opts->flag_o = 0; opts->pattern_count = 0; opts->pattern_file_count = 0; for (int i = 0; i < MAX_PATTERNS; i++) { opts->patterns[i] = NULL; } for (int i = 0; i < MAX_PATTERN_FILES; i++) { opts->pattern_files[i] = NULL; } } void free_options(Options* opts) { for (int i = 0; i < opts->pattern_count; i++) { free(opts->patterns[i]); opts->patterns[i] = NULL; } for (int i = 0; i < opts->pattern_file_count; i++) { free(opts->pattern_files[i]); opts->pattern_files[i] = NULL; } } static bool add_pattern(Options* opts, const char* pattern) { if (opts->pattern_count >= MAX_PATTERNS) { fprintf(stderr, "s21_grep: too many patterns\n"); return false; } char* pattern_copy = dup_string(pattern); if (!pattern_copy) { fprintf(stderr, "s21_grep: memory allocation failed\n"); return false; } opts->patterns[opts->pattern_count] = pattern_copy; opts->pattern_count++; return true; } static bool add_pattern_file(Options* opts, const char* filename) { if (opts->pattern_file_count >= MAX_PATTERN_FILES) { fprintf(stderr, "s21_grep: too many pattern files\n"); return false; } char* filename_copy = dup_string(filename); if (!filename_copy) { fprintf(stderr, "s21_grep: memory allocation failed\n"); return false; } opts->pattern_files[opts->pattern_file_count] = filename_copy; opts->pattern_file_count++; return true; } static bool load_patterns_from_file(Options* opts, const char* filename) { FILE* fp = fopen(filename, "r"); if (!fp) { if (!opts->flag_s) { fprintf(stderr, "s21_grep: %s: %s\n", filename, strerror(errno)); } return false; } char buf[4096]; bool success = true; while (success && fgets(buf, sizeof buf, fp)) { trim_newline(buf); if (!add_pattern(opts, buf)) { success = false; } } if (ferror(fp)) { if (!opts->flag_s) { fprintf(stderr, "s21_grep: %s: %s\n", filename, strerror(errno)); } success = false; } if (fclose(fp) != 0) { if (!opts->flag_s) { fprintf(stderr, "s21_grep: %s: %s\n", filename, strerror(errno)); } success = false; } return success; } static bool load_patterns_from_files(Options* opts) { bool success = true; for (int i = 0; i < opts->pattern_file_count && success; i++) { if (!load_patterns_from_file(opts, opts->pattern_files[i])) { success = false; } } return success; } static bool handle_simple_flag(Options* opts, char flag) { switch (flag) { case 'i': opts->flag_i = 1; break; case 'v': opts->flag_v = 1; break; case 'c': opts->flag_c = 1; break; case 'l': opts->flag_l = 1; break; case 'n': opts->flag_n = 1; break; case 'h': opts->flag_h = 1; break; case 's': opts->flag_s = 1; break; case 'o': opts->flag_o = 1; break; default: return false; } return true; } static int handle_option(int opt, Options* opts) { if (opt == 'e') { opts->flag_e = 1; return add_pattern(opts, optarg) ? 0 : 1; } if (opt == 'f') { opts->flag_f = 1; return add_pattern_file(opts, optarg) ? 0 : 1; } if (opt == '?') { fprintf(stderr, "s21_grep: invalid option -- '%c'\n", optopt); return 1; } if (handle_simple_flag(opts, opt)) { return 0; } return 1; } static int parse_flag_options(int argc, char* argv[], Options* opts) { int opt; opterr = 0; while ((opt = getopt(argc, argv, "e:ivclnhsf:o")) != -1) { int result = handle_option(opt, opts); if (result != 0) { return result; } } return 0; } static int add_positional_pattern(int argc, char* argv[], Options* opts) { if (opts->flag_e || opts->flag_f) { return 0; } if (optind >= argc) { fprintf(stderr, "Usage: s21_grep [OPTION]... PATTERN [FILE]...\n"); return 1; } if (!add_pattern(opts, argv[optind])) { return 1; } optind++; return 0; } static int validate_file_arguments(int argc, int* file_start_index) { if (optind >= argc) { fprintf(stderr, "s21_grep: no input files\n"); return 1; } *file_start_index = optind; return 0; } int parse_options(int argc, char* argv[], Options* opts, int* file_start_index) { int status; status = parse_flag_options(argc, argv, opts); if (status != 0) { return status; } status = add_positional_pattern(argc, argv, opts); if (status != 0) { return status; } if (!load_patterns_from_files(opts)) { return 1; } return validate_file_arguments(argc, file_start_index); }