Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _GNU_SOURCE
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <string.h>
- #include <unistd.h>
- #include <regex.h>
- #include "s21_grep.h"
- int main(int argc, char* argv[]) {
- int error = 0;
- struct opts grep_opt = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", ""};
- #if defined(__APPLE__)
- if (argc > 1 && *argv[1] != '-') {
- snprintf(grep_opt.pattern, MAX_LEN, "%s", argv[1]);
- getopt(argc, argv, "e:ivclnhsof:");
- optind++;
- }
- #endif
- for (int opt; (opt = getopt(argc, argv, "e:ivclnhsof:")) != -1;) {
- // printf("opt: %c, optind: %d\n", opt, optind);
- switch (opt) {
- case 'e':
- grep_opt.e = 1;
- if (!strlen(grep_opt.pattern)) {
- snprintf(grep_opt.pattern, MAX_LEN, "%s", optarg);
- } else {
- snprintf(grep_opt.pattern + strlen(grep_opt.pattern),
- MAX_LEN - strlen(grep_opt.pattern), "|%s", optarg);
- }
- break;
- case 'i':
- grep_opt.i = 1;
- break;
- case 'v':
- grep_opt.v = 1;
- break;
- case 'c':
- grep_opt.c = 1;
- break;
- case 'l':
- grep_opt.l = 1;
- break;
- case 'n':
- grep_opt.n = 1;
- break;
- case 'h':
- grep_opt.h = 1;
- break;
- case 's':
- grep_opt.s = 1;
- break;
- case 'o':
- grep_opt.o = 1;
- break;
- case 'f':
- grep_opt.f = 1;
- snprintf(grep_opt.file, MAX_LEN, "%s", optarg);
- break;
- case '?':
- error = 2;
- break;
- }
- }
- if (!error && argc > 1) {
- // printf("-e: %d\n", grep_opt.e);
- // printf("-e pattern: %s\n", grep_opt.pattern);
- // printf("-i: %d\n", grep_opt.i);
- // printf("-v: %d\n", grep_opt.v);
- // printf("-c: %d\n", grep_opt.c);
- // printf("-l: %d\n", grep_opt.l);
- // printf("-n: %d\n", grep_opt.n);
- // printf("-h: %d\n", grep_opt.h);
- // printf("-s: %d\n", grep_opt.s);
- // printf("-o: %d\n", grep_opt.o);
- // printf("-f: %d\n", grep_opt.f);
- // printf("-f file: %s\n", grep_opt.file);
- int index = optind;
- // printf("index: %d argc: %d\n", index, argc);
- if (!grep_opt.e && !grep_opt.f && index < argc && !strlen(grep_opt.pattern)) {
- // grep_opt.e = 1;
- snprintf(grep_opt.pattern, MAX_LEN, "%s", argv[index]);
- index++;
- } else {
- if (grep_opt.f) {
- if (create_pattern(&grep_opt)) {
- fprintf(stderr, "%s: %s: %s\n", GREP, grep_opt.file, strerror(errno));
- error = 2;
- }
- }
- }
- // printf("pattern: [%s]\n", grep_opt.pattern);
- if ((argc - index) == 1) { // the only one target
- grep_opt.h = 1;
- }
- if (!error) {
- for (; index < argc; index++) {
- // printf("Non-option argument %s\n", argv[index]);
- if (output(argv[index], grep_opt)) {;
- error = 2;
- }
- }
- }
- } else {
- promt();
- error = 2;
- }
- return error;
- }
- int output(const char* grep_file, struct opts grep_opt) {
- int error = 0;
- FILE* fp;
- fp = fopen(grep_file, "rt");
- if (fp) {
- char* str = NULL;
- size_t len_str = 0;
- ssize_t num_read = 0;
- size_t num_str = 0;
- int while_exit = 1; // instead of break;
- size_t count_sut_line = 0;
- size_t count_unsut_line = 0;
- while ((num_read = getline(&str, &len_str , fp)) != -1 && str && while_exit) {
- if (feof(fp) && num_read > 0 && str[num_read - 1] != '\n') {
- char* new_str = (char*)realloc(str, num_read + 2);
- if (!new_str) {
- fprintf(stderr, "%s: allocation memory error\n", GREP);
- error = 2;
- break;
- } else {
- str = new_str;
- snprintf(str + num_read, num_read + 2, "%c", '\n');
- }
- }
- num_str++;
- if (grep_opt.l) {
- if (!grep_opt.v) {
- if (!regular(str, grep_opt.pattern, grep_opt.i)) {
- printf("%s\n", grep_file);
- while_exit = 0;
- }
- } else {
- printf("%s\n", grep_file);
- while_exit = 0;
- }
- } else if (grep_opt.c) {
- if (!regular(str, grep_opt.pattern, grep_opt.i)) {
- count_sut_line++;
- } else {
- count_unsut_line++;
- }
- } else if (grep_opt.o) {
- if (!grep_opt.v) {
- regular_prn(str, grep_file, num_str, grep_opt);
- }
- }
- if (grep_opt.v && !grep_opt.l && !grep_opt.c) {
- if (grep_opt.o) {
- #if defined(__APPLE__)
- if (regular(str, grep_opt.pattern, grep_opt.i)) {
- print_str(str, grep_file, num_str, grep_opt);
- }
- #endif
- } else {
- if (regular(str, grep_opt.pattern, grep_opt.i)) {
- print_str(str, grep_file, num_str, grep_opt);
- }
- }
- } else if (!grep_opt.v && !grep_opt.l && !grep_opt.c && !grep_opt.o) {
- if (!regular(str, grep_opt.pattern, grep_opt.i)) {
- print_str(str, grep_file, num_str, grep_opt);
- }
- }
- }
- DESTROY(str);
- if (!error) {
- if (grep_opt.c) { // output for -c
- if (!grep_opt.h) {
- printf("%s:", grep_file);
- }
- if (!grep_opt.v) {
- printf("%zu\n", count_sut_line);
- } else {
- printf("%zu\n", count_unsut_line);
- }
- }
- }
- fclose(fp);
- } else {
- if (!grep_opt.s) {
- fprintf(stderr, "%s: %s: %s\n", GREP, grep_file, strerror(errno));
- error = 1;
- }
- }
- return error;
- }
- int regular(const char* str, const char* pattern, int opt_i) {
- int result; // -1 - bad pattern, 0 - found, 1 - not found
- regex_t rexp;
- int res_val;
- if (opt_i) {
- res_val = regcomp(&rexp, pattern, REG_EXTENDED | REG_NOSUB | REG_NEWLINE | REG_ICASE);
- } else {
- res_val = regcomp(&rexp, pattern, REG_EXTENDED | REG_NOSUB | REG_NEWLINE);
- }
- if (res_val) {
- printf("Failed, bad pattern\n");
- result = -1;
- } else {
- regmatch_t match;
- result = regexec(&rexp, str, 1, &match, 0);
- // printf("result: %d\n", result);
- regfree(&rexp);
- }
- return result;
- }
- int regular_prn(const char* str, const char* grep_file, const size_t num_str, struct opts grep_opt) {
- int result = 1; // -1 - bad pattern, 0 - found, 1 - not found
- regex_t rexp;
- char* str_ptr = (char*)str;
- int res_val;
- if (grep_opt.i) {
- res_val = regcomp(&rexp, grep_opt.pattern, REG_EXTENDED | REG_NEWLINE | REG_ICASE);
- } else {
- res_val = regcomp(&rexp, grep_opt.pattern, REG_EXTENDED | REG_NEWLINE);
- }
- if (res_val) {
- printf("Failed, bad pattern\n");
- result = -1;
- } else {
- regmatch_t match;
- #if defined(__APPLE__)
- if (!grep_opt.h && !regular(str, grep_opt.pattern, grep_opt.i)) {
- printf("%s:", grep_file);
- }
- if (grep_opt.n && !regular(str, grep_opt.pattern, grep_opt.i)) {
- printf("%zu:", num_str);
- }
- // printf("String = \"%s pattern %s as %d\"\n\n", str, pattern, opt_i);
- while (!regexec(&rexp, str_ptr, 1, &match, 0)) {
- result = 0;
- printf("%.*s\n", (int)(match.rm_eo - match.rm_so), str_ptr + match.rm_so);
- str_ptr += match.rm_eo;
- }
- #else
- while (!regexec(&rexp, str_ptr, 1, &match, 0)) {
- result = 0;
- if (!grep_opt.h) {
- printf("%s:", grep_file);
- }
- if (grep_opt.n) {
- printf("%zu:", num_str);
- }
- printf("%.*s\n", (int)(match.rm_eo - match.rm_so), str_ptr + match.rm_so);
- str_ptr += match.rm_eo;
- }
- #endif
- regfree(&rexp);
- }
- return result;
- }
- int create_pattern(struct opts* grep_opt) {
- int error = 0;
- FILE* fp;
- fp = fopen(grep_opt->file, "rt");
- if (fp) {
- char* str = NULL;
- size_t len_str = 0;
- ssize_t num_read = 0;
- if (!grep_opt->e) {
- if ((num_read = getline(&str, &len_str , fp)) != -1 && str) {
- if (num_read > 1 && str[num_read - 1] == '\n') {
- str[num_read - 1] = '\0';
- }
- snprintf(grep_opt->pattern, MAX_LEN, "%s", str);
- }
- }
- while ((num_read = getline(&str, &len_str , fp)) != -1 && str) {
- if (num_read > 1 && str[num_read - 1] == '\n') {
- str[num_read - 1] = '\0';
- }
- snprintf(grep_opt->pattern + strlen(grep_opt->pattern),
- MAX_LEN - strlen(grep_opt->pattern), "|%s", str);
- }
- DESTROY(str);
- fclose(fp);
- } else {
- error = 1;
- }
- return error;
- }
- void print_str(const char* str, const char* grep_file, const size_t num_str, struct opts grep_opt) {
- if (!grep_opt.h) {
- printf("%s:", grep_file);
- }
- if (grep_opt.n) {
- printf("%zu:", num_str);
- }
- printf("%s", str);
- }
- void promt() {
- fprintf(stderr, "usage: grep [-abcDEFGHhIiJLlmnOoqRSsUVvwxZ] [-A num] [-B num] [-C[num]]\n");
- fprintf(stderr, "\t[-e pattern] [-f file] [--binary-files=value] [--color=when]\n");
- fprintf(stderr, "\t[--context[=num]] [--directories=action] [--label] [--line-buffered]\n");
- fprintf(stderr, "\t[--null] [pattern] [file ...]\n");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement