2607

s21_grep.c

Dec 5th, 2021
783
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <regex.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5.  
  6. void spam_error(char* filename, int flag_s);
  7. void open_file(int flag_i, int flag_v, int flag_c, int flag_l, int flag_n, int flag_b,
  8.                int flag_h, int flag_s, int flag_o, int flag_e, int flag_f, char** argv,
  9.                int file_numbers, char* find_str);
  10. void s21_grep(int flag_i, int flag_v, int flag_c, int flag_l, int flag_n, int flag_b,
  11.               int flag_h, int flag_s, int flag_o, int file_numbers, char* find_str,
  12.               FILE* fp, char* filename);
  13. int flag_to_int(char* flags, char flag);
  14. void outputFlagC(int flag_c, int flag_v, int count_c, int count_vc, int flag_h,
  15.                  char* filename, int file_numbers, int flag_l);
  16. void* s21_to_lower(const char* str);
  17. void* s21_to_upper(const char* str);
  18. char* s21_strcat(char* dest, const char* src);
  19. char* s21_strcpy(char* dest, const char* src);
  20. char* convert_for_char(unsigned int num);
  21. void s21_grep_core(int flag_b, int flag_n, int flag_c, int flag_l, int count, size_t count_b, char* line);
  22.  
  23. // Support Function
  24. char* s21_strcat(char* dest, const char* src) {
  25.     size_t i, j;
  26.     for (i = 0; dest[i] != '\0'; i++) {
  27.     }
  28.     for (j = 0; src[j] != '\0'; j++)
  29.         dest[i + j] = src[j];
  30.     dest[i + j] = '\0';
  31.     return dest;
  32. }
  33.  
  34. char* s21_strcpy(char* dest, const char* src) {
  35.     char* tmp = dest;
  36.     for (; *src; src++, dest++)
  37.         *dest = *src;
  38.     *dest = 0;
  39.     return tmp;
  40. }
  41.  
  42. void* s21_to_lower(const char* string) {
  43.     short isError = 1;
  44.     char* pString = calloc((strlen(string) + 1), sizeof(char));
  45.     if (pString) {
  46.         s21_strcpy(pString, string);
  47.         for (char* p = (char*)pString; *p != '\0'; p++) {
  48.             if (*p >= 'A' && *p <= 'Z') {
  49.                 *p += 32;
  50.             }
  51.         }
  52.         isError = 0;
  53.     }
  54.     return (isError) ? NULL : (void*)pString;
  55. }
  56.  
  57. void* s21_to_upper(const char* string) {
  58.     short isError = 1;
  59.     char* pString = calloc((strlen(string) + 1), sizeof(char));
  60.     if (pString) {
  61.         s21_strcpy(pString, string);
  62.         for (char* p = (char*)pString; *p != '\0'; p++) {
  63.             if (*p >= 'a' && *p <= 'z') {
  64.                 *p -= 32;
  65.             }
  66.         }
  67.         isError = 0;
  68.     }
  69.     return (isError) ? NULL : (void*)pString;
  70. }
  71.  
  72. void spam_error(char* filename, int flag_s) {
  73.     if (!flag_s) {
  74.         printf("grep: %s: No such file or directory\n", filename);
  75.     }
  76. }
  77.  
  78. int flag_to_int(char* flags, char flag) {
  79.     int tmp = 0;
  80.     for (int i = 0; i < strlen(flags); i++) {
  81.         if (flags[i] == flag) {
  82.             tmp = 1;
  83.             break;
  84.         }
  85.     }
  86.     return tmp;
  87. }
  88.  
  89. char* convert_for_char(unsigned int num) {
  90.     static char buffer[2];
  91.     char* ptr;
  92.     ptr = &buffer[1];
  93.     *ptr = '\0';
  94.     *--ptr = (char)num;
  95.     return (ptr);
  96. }
  97.  
  98. void open_file(int flag_i, int flag_v, int flag_c, int flag_l, int flag_n, int flag_b,
  99.                int flag_h, int flag_s, int flag_o, int flag_e, int flag_f,
  100.                char** argv, int file_numbers, char* find_str) {
  101.     FILE* fp;
  102.     char* filename;
  103.     int find = 0;
  104.     argv++;
  105.     while (*argv) {
  106.         if (flag_to_int(*argv, '-')) {
  107.             if (flag_to_int(*argv, 'e') || flag_to_int(*argv, 'f'))
  108.                 argv++;
  109.             argv++;
  110.         } else {
  111.             if (find == 0 && flag_e == 0 && flag_f == 0) {
  112.                 find++;
  113.                 argv++;
  114.             } else if ((fp = fopen(*argv, "r")) == NULL) {
  115.                 spam_error(*argv, flag_s);
  116.                 argv++;
  117.             } else {
  118.                 filename = *argv++;
  119.                 s21_grep(flag_i, flag_v, flag_c, flag_l, flag_n, flag_b,
  120.                          flag_h, flag_s, flag_o, file_numbers, find_str, fp, filename);
  121.                 fclose(fp);
  122.             }
  123.         }
  124.     }
  125. }
  126.  
  127. void s21_grep_core(int flag_b, int flag_n, int flag_c, int flag_l, int count, size_t count_b, char* line) {
  128.     if (flag_b && !flag_n && !flag_c && !flag_l) {
  129.         printf("%zu:", count_b);
  130.     }
  131.     if (flag_n && !flag_c && !flag_l) {
  132.         printf("%d:", count);
  133.         if (flag_b) {
  134.             printf("%zu:", count_b);
  135.         }
  136.         printf("%s", line);
  137.     } else if (!flag_c && !flag_l) {
  138.         printf("%s", line);
  139.     }
  140. }
  141.  
  142. void outputFlagL(int flag_l, int flag_v, int flag_c, int count_c,
  143.                  int count_vc, int flag_h, char* filename, int file_numbers) {
  144.     if (flag_l && !flag_v) {
  145.         if (count_c != 0)
  146.             printf("%s\n", filename);
  147.     } else if (flag_l && flag_v) {
  148.         if (count_vc != 0)
  149.             printf("%s\n", filename);
  150.     }
  151. }
  152.  
  153. void s21_grep(int flag_i, int flag_v, int flag_c, int flag_l, int flag_n, int flag_b,
  154.               int flag_h, int flag_s, int flag_o, int file_numbers, char* find_str,
  155.               FILE* fp, char* filename) {
  156.     regex_t regex;
  157.     char* line = NULL;
  158.     size_t len = 0, count_b = 0, nmatch = 2, read;
  159.     int count = 1, count_c = 0, count_vc = 0, reti;
  160.     regcomp(&regex, find_str, REG_EXTENDED);
  161.     regmatch_t pmatch[2];
  162.     while ((read = getline(&line, &len, fp)) != EOF) {
  163.         size_t count_b_ex = strlen(line);
  164.         char* line_tmp = calloc(strlen(line), sizeof(char));
  165.         if (line[strlen(line)] == '\n' && strlen(line) == 1)
  166.             s21_strcat(line, "\n");
  167.         if (line[strlen(line) - 1] != '\n')
  168.             s21_strcat(line, "\n");
  169.         if (flag_i) {
  170.             s21_strcpy(line_tmp, line);
  171.             char* line_tmp2 = s21_to_lower(line_tmp);
  172.             char* line_tmp3 = s21_to_upper(line_tmp);
  173.             int reti_tmp;
  174.             reti_tmp = regexec(&regex, line_tmp3, nmatch, pmatch, 0);
  175.             reti = regexec(&regex, line_tmp2, nmatch,
  176.                            pmatch, 0);
  177.             reti = reti && reti_tmp;
  178.             free(line_tmp2);
  179.             free(line_tmp3);
  180.         } else {
  181.             reti = regexec(&regex, line, nmatch, pmatch, 0);
  182.         }
  183.         if (flag_o && !flag_v && !reti) {
  184.             if (strlen(line) != 1) {
  185.                 char* str_tmp = calloc(strlen(line) + 1, sizeof(char));
  186.                 snprintf(str_tmp, strlen(line) + 1, "%c%s", '\t', line);
  187.                 snprintf(line, strlen(line), "%.*s", (int)(pmatch[1].rm_eo - pmatch[1].rm_so),
  188.                 &str_tmp[pmatch[1].rm_so + 1]);
  189.                 s21_strcat(line, "\n");
  190.             }
  191.         }
  192.         if (file_numbers > 1 && !flag_h && !reti && !flag_v && !flag_c && !flag_l)
  193.             printf("%s:", filename);
  194.         if (file_numbers > 1 && !flag_h && reti && flag_v && !flag_c && !flag_l)
  195.             printf("%s:", filename);
  196.         if (!reti && !flag_v) {
  197.             s21_grep_core(flag_b, flag_n, flag_c, flag_l, count, count_b, line);
  198.             count_c++;
  199.         } else if (flag_v && reti) {
  200.             s21_grep_core(flag_b, flag_n, flag_c, flag_l, count, count_b, line);
  201.             count_vc++;
  202.         }
  203.         count++;
  204.         count_b += count_b_ex;
  205.         if (line_tmp) free(line_tmp);
  206.     }
  207.     outputFlagL(flag_l, flag_v, flag_c, count_c, count_vc, flag_h, filename, file_numbers);
  208.     if (line) free(line);
  209.     regfree(&regex);
  210. }
  211.  
  212. int main(int argc, char** argv) {
  213.     char* find_str = calloc(1000, sizeof(char));
  214.     int i = 1, file_numbers = 0, find = 0;
  215.     int flag_e = 0, flag_f = 0, flag_i = 0, flag_v = 0, flag_c = 0, flag_l = 0,
  216.         flag_n = 0, flag_b = 0, flag_h = 0, flag_s = 0, flag_o = 0;
  217.     s21_strcat(find_str, convert_for_char('('));
  218.     while (i < argc) {
  219.         if (argv[i][0] == '-') {
  220.             flag_i = flag_i == 1 ? 1 : flag_to_int(argv[i], 'i');
  221.             flag_v = flag_v == 1 ? 1 : flag_to_int(argv[i], 'v');
  222.             flag_c = flag_c == 1 ? 1 : flag_to_int(argv[i], 'c');
  223.             flag_l = flag_l == 1 ? 1 : flag_to_int(argv[i], 'l');
  224.             flag_n = flag_n == 1 ? 1 : flag_to_int(argv[i], 'n');
  225.             flag_b = flag_b == 1 ? 1 : flag_to_int(argv[i], 'b');
  226.             flag_h = flag_h == 1 ? 1 : flag_to_int(argv[i], 'h');
  227.             flag_s = flag_s == 1 ? 1 : flag_to_int(argv[i], 's');
  228.             flag_o = flag_o == 1 ? 1 : flag_to_int(argv[i], 'o');
  229.             if (flag_to_int(argv[i], 'e')) {
  230.                 flag_e++;
  231.                 if (flag_e == 1 && flag_f == 0) {
  232.                     s21_strcpy(find_str, convert_for_char('('));
  233.                     s21_strcat(find_str, argv[i + 1]);
  234.                 } else {
  235.                     if (flag_e > 0 || flag_f > 0) {
  236.                         s21_strcat(find_str, convert_for_char('|'));
  237.                         s21_strcat(find_str, argv[i + 1]);
  238.                     }
  239.                 }
  240.                 i++;
  241.             }
  242.             if (flag_to_int(argv[i], 'f')) {
  243.                 FILE* fp;
  244.                 fp = fopen(argv[i + 1], "r");
  245.                 if (fp == NULL) exit(EXIT_FAILURE);
  246.                 flag_f++;
  247.                 char current, prev = 'z';
  248.                 if (flag_e > 0 && flag_f > 0) {
  249.                     s21_strcat(find_str, convert_for_char('|'));
  250.                 }
  251.                 while ((current = getc(fp)) != EOF) {
  252.                     if (prev == '\n' && current != '\n') {
  253.                         s21_strcat(find_str, convert_for_char('|'));
  254.                     }
  255.                     if (current != '\n') {
  256.                         s21_strcat(find_str, convert_for_char(current));
  257.                     }
  258.                     if (prev == '\n' && current == '\n') {
  259.                         s21_strcat(find_str, convert_for_char('|'));
  260.                         s21_strcat(find_str, "\n");
  261.                     }
  262.                     prev = current;
  263.                 }
  264.                 fclose(fp);
  265.                 i++;
  266.             }
  267.         } else {
  268.             if (flag_e == 0 && flag_f == 0 && find == 0) {
  269.                 find++;
  270.                 s21_strcat(find_str, argv[i]);
  271.             } else {
  272.                 file_numbers++;
  273.             }
  274.         }
  275.         i++;
  276.     }
  277.     if (find_str) s21_strcat(find_str, convert_for_char(')'));
  278.     open_file(flag_i, flag_v, flag_c, flag_l, flag_n, flag_b,
  279.               flag_h, flag_s, flag_o, flag_e, flag_f, argv, file_numbers, find_str);
  280.     free(find_str);
  281.     return 0;
  282. }
  283.  
RAW Paste Data