├── .gitignore
├── README.md
├── assets
└── preview.png
└── src
├── cat
├── Makefile
├── TEST-SUITE
│ ├── TEST-FILE_001
│ ├── TEST-FILE_002
│ ├── TEST-FILE_003
│ └── TEST-FILE_004
├── TEST.py
├── s21_cat.c
└── s21_cat.h
└── grep
├── Makefile
├── TEST-SUITE
├── TEST-FILE_001
├── TEST-FILE_002
├── TEST-FILE_003
├── TEST-FILE_004
├── TEST-FILE_005
├── TEST-FILE_006
└── TEST-TEMPLATE
├── TEST.py
├── s21_grep.c
└── s21_grep.h
/.gitignore:
--------------------------------------------------------------------------------
1 | # Prerequisites
2 | *.d
3 |
4 | # Object files
5 | *.o
6 | *.ko
7 | *.obj
8 | *.elf
9 |
10 | # Linker output
11 | *.ilk
12 | *.map
13 | *.exp
14 |
15 | # Precompiled Headers
16 | *.gch
17 | *.pch
18 |
19 | # Libraries
20 | *.lib
21 | *.a
22 | *.la
23 | *.lo
24 |
25 | # Shared objects (inc. Windows DLLs)
26 | *.dll
27 | *.so
28 | *.so.*
29 | *.dylib
30 |
31 | # Executables
32 | *.exe
33 | *.out
34 | *.app
35 | *.i*86
36 | *.x86_64
37 | *.hex
38 |
39 | # Debug files
40 | *.dSYM/
41 | *.su
42 | *.idb
43 | *.pdb
44 |
45 | # Kernel Module Compile Results
46 | *.mod*
47 | *.cmd
48 | .tmp_versions/
49 | modules.order
50 | Module.symvers
51 | Mkfile.old
52 | dkms.conf
53 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 21-simple-bash-utils
2 |
3 |
PREVIEW_WILL_BE_ADDED_LATER.png
4 |
5 | ---
6 |
7 | Educational project SimpleBashUtils from organization «School 21».
8 |
9 | Development of Bash text utilities cat & grep in C programming languages. Developed functions have all the original flags supported, including paired combinations.
10 |
11 | USEFUL NOTES:
12 |
13 | - there is a significant difference in work of commands on other operating systems. It was not possible to find best testing option, except for using machines on campus.
14 | - cat command has the ability to output contents of several files with one command, however, to submit the s21_cat project, it is enough to be able to process one file. There is a small difference in output, which is better to take into account at start, so as not to create crutches later.
15 |
16 |
17 | [ SPOILER ] Overview of implemented code
18 |
19 | ### s21_cat
20 |
21 | TEMPLATE: `cat [OPTION] [FILE]`
22 |
23 | | No. | Option | Description | Status |
24 | | --- | ----------------------------------------------------------- | -------------------------------------------- | ------ |
25 | | 1 | -b (GNU: --number-nonblank) | numbers only non-empty lines | ✅ |
26 | | 2 | -e подразумевает -v (только GNU: -E то же самое, но без -v) | but also display end-of-line characters as $ | ✅ |
27 | | 3 | -n (GNU: --number) | number all output lines | ✅ |
28 | | 4 | -s (GNU: --squeeze-blank) | squeeze multiple adjacent blank lines | ✅ |
29 | | 5 | -t подразумевает -v (GNU: -T то же самое, но без -v) | but also display tabs as ^I | ✅ |
30 |
31 | ### s21_grep
32 |
33 | TEMPLATE: `grep [OPTION] [TEMPLATE] [FILE]`
34 |
35 | | No. | Option | Description | Status |
36 | | --- | ------- | ------------------------------------------------------------- | ------ |
37 | | 1 | -e | pattern | ✅ |
38 | | 2 | -i | ignore uppercase vs. lowercase | ✅ |
39 | | 3 | -v | invert match | ✅ |
40 | | 4 | -c | output count of matching lines only. | ✅ |
41 | | 5 | -l | output matching files only | ✅ |
42 | | 6 | -n | precede each matching line with a line number | ✅ |
43 | | 7 | -h | output matching lines without preceding them by file names | ✅ |
44 | | 8 | -s | suppress error messages about nonexistent or unreadable files | ✅ |
45 | | 9 | -f file | take regexes from a file | ✅ |
46 | | 10 | -o | output the matched parts of a matching line | ✅ |
47 |
48 |
49 |
50 | — Thanks to 21-SCHOOL for provided assignment and special learning conditions ✌️🔥
51 |
52 | ## Usage
53 |
54 | 1. Clone this repository via
55 | - SSH `git@github.com:rynortheast/21-simple-bash-utils.git` or
56 | - HTTPS `https://github.com/rynortheast/21-simple-bash-utils.git`
57 | 2. Change code base if necessary
58 | 3. Working with s21_cat:
59 | - Run `make s21_cat` to build programm
60 | - Run `make test` to run main tests
61 | 4. Working with s21_grep:
62 | - Run `make s21_grep` to build programm
63 | - Run `make test` to run main tests
64 |
--------------------------------------------------------------------------------
/assets/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rynortheast/21-simple-bash-utils/c6ad898e675f57874e0788edd7a2538370dcc9f9/assets/preview.png
--------------------------------------------------------------------------------
/src/cat/Makefile:
--------------------------------------------------------------------------------
1 |
2 | FLAGS = -Wall -Wextra -Werror -std=c11 -pedantic
3 |
4 | all: s21_cat
5 |
6 | s21_cat: Makefile s21_cat.h s21_cat.c
7 | gcc $(FLAGS) s21_cat.c -o s21_cat
8 |
9 | test: s21_cat
10 | python3 ./TEST.py
11 |
12 | check:
13 | clang-format -style=Google -n *.c
14 |
15 | rebuild:
16 | make clean
17 | make all
18 |
19 | clean:
20 | rm -f s21_cat
21 |
--------------------------------------------------------------------------------
/src/cat/TEST-SUITE/TEST-FILE_001:
--------------------------------------------------------------------------------
1 | fas dfasd
2 | fas df sad
3 | fs
4 |
5 |
6 | krebs
7 |
8 | kepa krepea
9 |
10 |
11 |
12 | a edf
13 | fas dfasd
14 | fas df sad
15 | fs df
16 |
17 | fas dfasd
18 | fas df sad
19 | fs dffas dfasd
20 | fas df sad
21 | fs df
22 |
23 | Q
24 | 2314 23
25 | 4
26 |
27 | 2
28 |
29 |
30 |
31 | d
32 |
--------------------------------------------------------------------------------
/src/cat/TEST-SUITE/TEST-FILE_002:
--------------------------------------------------------------------------------
1 | asdf
2 | asdf
3 |
4 |
5 |
6 |
7 | SQUEEZE
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | LAST
--------------------------------------------------------------------------------
/src/cat/TEST-SUITE/TEST-FILE_003:
--------------------------------------------------------------------------------
1 | aboba_one
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | floppa_two
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | shleppa_three
25 |
26 |
27 |
28 |
29 |
30 | kopa_four
--------------------------------------------------------------------------------
/src/cat/TEST-SUITE/TEST-FILE_004:
--------------------------------------------------------------------------------
1 | aboba_one$
2 | $
3 | floppa_two$
4 | $
5 | shleppa_three$
6 | $
7 | kopa_four
--------------------------------------------------------------------------------
/src/cat/TEST.py:
--------------------------------------------------------------------------------
1 | #!python3
2 |
3 | from itertools import combinations_with_replacement
4 | from random import shuffle
5 | from os import system
6 |
7 | falshivka = "./s21_cat"
8 | original = "cat"
9 |
10 | file_name = 'TEST-FILE'
11 | file_format = ".testing"
12 |
13 | suite = [
14 | 'TEST-SUITE/TEST-FILE_002'
15 | ]
16 |
17 | flags = {
18 | '-b',
19 | '-e',
20 | '-n',
21 | '-s',
22 | '-v',
23 | '-t'
24 | }
25 |
26 | all_var = list(combinations_with_replacement(flags, len(flags)))
27 |
28 | def file_comparison(a, b):
29 | with open(a) as file_1:
30 | with open(b) as file_2:
31 | a, b = file_1.read(), file_2.read()
32 | if a != b:
33 |
34 | count = 0
35 | for i in range(len(a)):
36 | if a[i] == '\n':
37 | count += 1
38 | if len(b) == i:
39 | break
40 | if a[i] != b[i]:
41 | break
42 |
43 | print("===============A===============")
44 | print(a[max(0, i-50):min(len(a), i+50)])
45 | print("===============B===============")
46 | print(b[max(0, i-50):min(len(b), i+50)])
47 | print("===============================")
48 | print("Line:", count, " char:", i)
49 | input("Press any key to continue:\n")
50 |
51 | else:
52 | print("\033[42m\033[1m YES \033[0m")
53 |
54 |
55 | for test in range(len(all_var)):
56 | cur_flags_ = all_var[test]
57 | for cur_flags in (cur_flags_, set(cur_flags_)):
58 | shuffle(suite)
59 | print(f"Current TEST [{test + 1} / {len(all_var)}] - ", end='')
60 | for i, func in (('0', falshivka), ('1', original)):
61 | m_str = f'{func} {" ".join(cur_flags)} {" ".join(suite)} > {file_name+"-"+i+file_format}'
62 | system("echo '{}' >> commands.testing".format(m_str));
63 | system(m_str)
64 | file_comparison(file_name+'-0'+file_format,
65 | file_name+'-1'+file_format)
66 |
67 | system('rm -rf *' + file_format)
68 |
--------------------------------------------------------------------------------
/src/cat/s21_cat.c:
--------------------------------------------------------------------------------
1 | #include "s21_cat.h"
2 |
3 | int main(int argc, char **argv) {
4 | s21_cat_programm(argc, argv);
5 | return 0;
6 | }
7 |
8 | void s21_cat_programm(int argc, char **argv) {
9 | if (argc > 1) {
10 | options config = {0};
11 | if (scanOptions(argc, argv, &config)) {
12 | for (int x = (argc - config.numberFiles); x < argc; x += 1) {
13 | FILE *file = fopen(argv[x], "r");
14 | if (file != NULL)
15 | fclose(printData(file, &config));
16 | else
17 | fprintf(stderr, ERROR_01, argv[x]);
18 | }
19 | }
20 | }
21 | }
22 |
23 | int scanOptions(int argc, char **argv, options *config) {
24 | int indexStartFiles = 1, status = 1, x = 1;
25 |
26 | for (; (x < argc && argv[x][0] == '-'); indexStartFiles = (x += 1)) {
27 | if (!strcmp(argv[x], "-b") || !strcmp(argv[x], "--number-nonblank")) {
28 | config->b = (config->n = 0) + 1;
29 | } else if (!strcmp(argv[x], "-s") || !strcmp(argv[x], "--squeeze-blank")) {
30 | config->s = 1;
31 | } else if (!strcmp(argv[x], "-n") || !strcmp(argv[x], "--number")) {
32 | config->n = config->b ? 0 : 1;
33 | } else if (!strcmp(argv[x], "-T")) {
34 | config->t = 1;
35 | } else if (!strcmp(argv[x], "-v")) {
36 | config->v = 1;
37 | } else if (!strcmp(argv[x], "-t")) {
38 | config->t = 1;
39 | config->v = 1;
40 | } else if (!strcmp(argv[x], "-e")) {
41 | config->e = 1;
42 | config->v = 1;
43 | } else if (!strcmp(argv[x], "-E")) {
44 | config->e = 1;
45 | } else {
46 | fprintf(stderr, ERROR_02, argv[x][1]);
47 | status = 0;
48 | }
49 | }
50 |
51 | config->numberFiles = argc - indexStartFiles;
52 |
53 | return status;
54 | }
55 |
56 | FILE *printData(FILE *file, options *config) {
57 | for (char sym = '0'; (sym = getc(file)) != EOF;) {
58 | config->emptyLine = 0;
59 | if (config->s && config->counterS == 0 && sym == '\n') {
60 | config->counterS += 1;
61 | } else if (config->counterS != 0 && sym == '\n') {
62 | config->counterS += 1;
63 | config->emptyLine = 1;
64 | } else if (config->counterS > 1 && sym != '\n') {
65 | config->counterS = 0;
66 | config->e ? printf("$\n") : printf("\n");
67 | if (config->n != 0) printf("%6d\t", config->n++);
68 | } else {
69 | config->counterS = 0;
70 | }
71 | if (config->n != 0 || config->b != 0) {
72 | if (config->newLine == 1 && !(config->newLine = 0))
73 | printf("%6d\t", config->n++);
74 | if (config->n == 1) printf("%6d\t", config->n++);
75 | if (config->b == 1) printf("%6d\t", config->b++);
76 | if (sym == '\n' && config->n != 0 && config->emptyLine == 0)
77 | config->newLine = 1;
78 | if (sym == '\n' && config->b != 0) config->counterB += 1;
79 | if (sym != '\n' && config->counterB != 0 && config->counterS == 0)
80 | if (!(config->counterB = 0)) printf("%6d\t", config->b++);
81 | }
82 | if (sym == '\n' && config->e && config->emptyLine == 0) printf("$");
83 | if (config->v) {
84 | if (sym < 32 && sym != 9 && sym != 10)
85 | if (sym += 64) printf("^");
86 | if (sym == 127)
87 | if ((sym = '?')) printf("^");
88 | }
89 | if (config->t && sym == '\t')
90 | if ((sym = 'I')) printf("^");
91 | if (config->emptyLine == 0) printf("%c", sym);
92 | }
93 | return file;
94 | }
95 |
--------------------------------------------------------------------------------
/src/cat/s21_cat.h:
--------------------------------------------------------------------------------
1 | #ifndef SRC_CAT_S21_CAT_H_
2 | #define SRC_CAT_S21_CAT_H_
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | #define ERROR_01 "s21_cat: %s: No such file or directory\n"
9 | #define ERROR_02 "s21_cat: invalid option -- '%c'\n"
10 |
11 | typedef struct {
12 | int b;
13 | int e;
14 | int n;
15 | int s;
16 | int t;
17 | int v;
18 | int newLine;
19 | int counterB;
20 | int counterS;
21 | int emptyLine;
22 | int numberFiles;
23 | } options;
24 |
25 | void s21_cat_programm(int argc, char **argv);
26 |
27 | int scanOptions(int argc, char **argv, options *config);
28 | FILE *printData(FILE *file, options *config);
29 |
30 | #endif // SRC_CAT_S21_CAT_H_
31 |
--------------------------------------------------------------------------------
/src/grep/Makefile:
--------------------------------------------------------------------------------
1 |
2 | FLAGS = -Wall -Wextra -Werror -std=c11 -pedantic
3 |
4 | all: s21_grep
5 |
6 | s21_grep: Makefile s21_grep.h s21_grep.c
7 | gcc $(FLAGS) s21_grep.c -o s21_grep
8 |
9 | test: s21_grep
10 | python3 ./TEST.py
11 |
12 | check:
13 | clang-format -style=Google -n *.c
14 |
15 | rebuild:
16 | make clean
17 | make all
18 |
19 | clean:
20 | rm -f s21_grep
21 |
--------------------------------------------------------------------------------
/src/grep/TEST-SUITE/TEST-FILE_001:
--------------------------------------------------------------------------------
1 |
2 |
3 | ryuihn
4 | yudcsbapvndfgyhuijkl;'rtyuiop[]ghjkl;'
5 |
6 |
7 |
8 |
9 |
10 | 234567
11 | int get_flags(int argc, char** argv, flag *flags, char** template) {
12 | int i = 1;
13 | while (argv[i][0] == '-' && argc > i + 1) {
14 | if (!strcmp(argv[i], "-e")) {
15 | if (flags -> e == 0) { // && flags.f == 0) {
16 | (*template) = (char *) malloc(sizeof(char) * (strlen(argv[++i]) + 1));
17 | if (*template)
18 | strcpy((*template), argv[i]);
19 | } else {
20 | (*template) = (char *) s21_reallocf((*template),ghjkl;kjhgfdsasdfghjkl;'\';lkjhgfdssdfghjkl;'\rtyuiop[]sizeof(char) * (strlen(*template) + 2 + strlen(argv[++i])));if (*template) {strcat((*template), "|");
21 | strcat((*template), argv[i]);
22 | }
23 | }
24 | flags -> e = 1;
25 | }
26 | }
27 | if (!flags -> e) {
28 | (*template) = (char *) malloc(sizeof(char) * (strlen(argv[i]) + 1));
29 | if (*template)
30 | strcpy((*template), argv[i++]);
31 | }
32 | return i;
33 | }
34 |
--------------------------------------------------------------------------------
/src/grep/TEST-SUITE/TEST-FILE_002:
--------------------------------------------------------------------------------
1 | Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled “GNU Free Documentation License”.
2 |
3 |
4 | Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation
5 | License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections,
6 | with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled
7 | “GNU Free Documentation License”.
8 | a
9 | Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled “GNU Free Docu
10 | mentation License”.
11 |
12 |
13 |
14 |
15 | aboba_flex
--------------------------------------------------------------------------------
/src/grep/TEST-SUITE/TEST-FILE_003:
--------------------------------------------------------------------------------
1 | isadfasdfa
2 | fasdfasdf
3 |
4 | Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled “GNU Free Documentation License”.
5 | _\n
6 | Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation
7 | License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections,
8 | with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled
9 | “GNU Free Documentation License”.
10 | a
11 | Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled “GNU Free Docu
12 | mentation License”.
13 |
14 | permission
15 | permission permission permission permission
16 | permission permission permission
17 | permission permission
18 | permission
19 | permission
20 | permissionpermission
21 | permissionpermissionpermission
22 |
23 | aboba_flex__________FLEXOLOG
24 |
25 | is
26 |
27 |
28 |
29 | is
--------------------------------------------------------------------------------
/src/grep/TEST-SUITE/TEST-FILE_004:
--------------------------------------------------------------------------------
1 | 1
2 | 2
3 | 3
4 | 4
5 | 5
6 | 6
7 | 7
8 | 8
9 | 9
10 | 10
11 |
12 | 1
13 |
14 | 1
15 |
16 | 2
17 |
18 |
19 | floppa
20 |
21 |
22 | aboba
23 |
24 |
25 |
26 | special
27 |
28 |
29 |
30 |
31 | is
32 |
33 |
34 |
35 | is
--------------------------------------------------------------------------------
/src/grep/TEST-SUITE/TEST-FILE_005:
--------------------------------------------------------------------------------
1 | At vero eos et accusamus et iusto odio dignissimos ducimus, quis nostrum exercitationem ullam corporis suscipit laboriosam, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua!At vero eos et accusamus et iusto odio dignissimos ducimus, quisdduis nostrum exercitationem ullam corporis suscipit laboriosam, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua!At vero eos et accusamus et iusto odio dignissimos ducimus, quisdd
--------------------------------------------------------------------------------
/src/grep/TEST-SUITE/TEST-FILE_006:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rynortheast/21-simple-bash-utils/c6ad898e675f57874e0788edd7a2538370dcc9f9/src/grep/TEST-SUITE/TEST-FILE_006
--------------------------------------------------------------------------------
/src/grep/TEST-SUITE/TEST-TEMPLATE:
--------------------------------------------------------------------------------
1 | if
2 | [0-9]
3 |
--------------------------------------------------------------------------------
/src/grep/TEST.py:
--------------------------------------------------------------------------------
1 | #!python3
2 |
3 | from itertools import combinations_with_replacement
4 | from random import shuffle
5 | from os import system
6 |
7 | falshivka = "./s21_grep"
8 | original = "grep"
9 |
10 | file_name = 'TEST-FILE'
11 | file_format = ".testing"
12 |
13 | template = '[0-9]'
14 | test_file = './TEST-SUITE/TEST-FILE_001'
15 | test_template = './TEST-SUITE/TEST-TEMPLATE'
16 |
17 | suite_flag = [
18 | f'-e {template} -e {test_template} {test_file}',
19 | f'-f {test_template} -e {template} {test_file}',
20 | f'-f {test_template} s21_grep.c s21_grep.h',
21 | f'-vf {test_template} {test_file}',
22 | f'-cf {test_template} {test_file}',
23 | f'-lf {test_template} {test_file}',
24 | f'-nf {test_template} {test_file}',
25 | f'-hf {test_template} {test_file}',
26 | f'-h if {test_file} s21_grep.h',
27 | f'-ie {template} {test_file}',
28 | f'-ve {template} {test_file}',
29 | f'-ce {template} {test_file}',
30 | f'-le {template} {test_file}',
31 | f'-ne {template} {test_file}',
32 | f'-he {template} {test_file}',
33 | f'-se {template} {test_file}',
34 | f'-oe {template} {test_file}',
35 | f'-iv {template} {test_file}',
36 | f'-ic {template} {test_file}',
37 | f'-il {template} {test_file}',
38 | f'-in {template} {test_file}',
39 | f'-ih {template} {test_file}',
40 | f'-is {template} {test_file}',
41 | f'-io {template} {test_file}',
42 | f'-vc {template} {test_file}',
43 | f'-vl {template} {test_file}',
44 | f'-vn {template} {test_file}',
45 | f'-vh {template} {test_file}',
46 | f'-vs {template} {test_file}',
47 | f'-vo {template} {test_file}',
48 | f'-cl {template} {test_file}',
49 | f'-cn {template} {test_file}',
50 | f'-ch {template} {test_file}',
51 | f'-cs {template} {test_file}',
52 | f'-co {template} {test_file}',
53 | f'-ln {template} {test_file}',
54 | f'-lh {template} {test_file}',
55 | f'-ls {template} {test_file}',
56 | f'-lo {template} {test_file}',
57 | f'-nh {template} {test_file}',
58 | f'-ns {template} {test_file}',
59 | f'-no {template} {test_file}',
60 | f'-hs {template} {test_file}',
61 | f'-ho {template} {test_file}',
62 | f'-l {template} {test_file}',
63 | f'-v {template} {test_file}',
64 | f'-c {template} {test_file}',
65 | f'-n {template} {test_file}',
66 | f'-o {template} {test_file}',
67 | f'[0-9] {test_file}',
68 | f'-i RY {test_file}'
69 | ]
70 |
71 | # all_var = list(combinations_with_replacement(suite_flag, len(suite_flag)))
72 |
73 | def file_comparison(a, b):
74 | with open(a) as file_1:
75 | with open(b) as file_2:
76 | a, b = file_1.read(), file_2.read()
77 | if a != b:
78 |
79 | count = 0
80 | for i in range(len(a)):
81 | if a[i] == '\n':
82 | count += 1
83 | if len(b) == i:
84 | break
85 | if a[i] != b[i]:
86 | break
87 |
88 | print("===============A===============")
89 | print(a[max(0, i-50):min(len(a), i+50)])
90 | print("===============B===============")
91 | print(b[max(0, i-50):min(len(b), i+50)])
92 | print("===============================")
93 | print("Line:", count, " char:", i)
94 | input("Press any key to continue:\n")
95 |
96 | else:
97 | print("\033[42m\033[1m YES \033[0m")
98 |
99 | for index in range(len(suite_flag)):
100 | print(f'Current TEST [{index + 1} / {len(suite_flag)}] - {suite_flag[index]} - ', end='')
101 | system(f'{falshivka} {suite_flag[index]} > {file_name + "-0" + file_format}')
102 | system(f'{original} {suite_flag[index]} > {file_name + "-1" + file_format}')
103 | file_comparison(file_name+'-0'+file_format, file_name+'-1'+file_format)
104 |
105 | system('rm -rf *' + file_format)
106 |
--------------------------------------------------------------------------------
/src/grep/s21_grep.c:
--------------------------------------------------------------------------------
1 | #include "s21_grep.h"
2 |
3 | int main(int argc, char **argv) {
4 | s21_grep_programm(argc, argv);
5 | return 0;
6 | }
7 |
8 | void s21_grep_programm(int argc, char **argv) {
9 | if (argc > 1) {
10 | char *temp = NULL;
11 | options config = {0};
12 |
13 | for (int x = scanOptions(argc, argv, &config, &temp); x < argc; x += 1)
14 | s21_grep(argv[x], config, temp);
15 |
16 | if (temp != NULL) free(temp);
17 | }
18 | }
19 |
20 | int scanOptions(int argc, char **argv, options *config, char **template) {
21 | for (int sym = 0; (sym = getopt(argc, argv, "e:ivclnhsf:o")) != (-1);) {
22 | switch (sym) {
23 | case 'i':
24 | config->i = 1;
25 | break;
26 | case 'v':
27 | config->v = 1;
28 | break;
29 | case 'c':
30 | config->c = 1;
31 | break;
32 | case 'l':
33 | config->l = 1;
34 | break;
35 | case 'n':
36 | config->n = 1;
37 | break;
38 | case 'h':
39 | config->h = 1;
40 | break;
41 | case 's':
42 | config->s = 1;
43 | break;
44 | case 'o':
45 | config->o = 1;
46 | break;
47 | case 'e':
48 | setConfigE(config, template, optarg);
49 | break;
50 | case 'f':
51 | setConfigF(config, template, optarg);
52 | break;
53 | }
54 | }
55 | if ((config->e || config->f) == 0) {
56 | createTemplate(template, argv[optind]);
57 | optind += 1;
58 | }
59 | setupConfig(config, argc);
60 | return optind;
61 | }
62 |
63 | void s21_grep(char *path, options config, char *template) {
64 | FILE *file = fopen(path, "r");
65 | if (file != NULL) {
66 | for (char sym = '0'; (sym = getc(file)) != EOF;) {
67 | char *line = calloc(256, 1);
68 | config.numberLine += 1;
69 | int length = 0;
70 |
71 | for (line[length] = '\0'; sym != EOF && sym != '\n'; sym = getc(file)) {
72 | line[length] = sym;
73 | line[length += 1] = '\0';
74 | if (length % 255 == 0) line = increaseLengthStr(line, length + 256);
75 | }
76 |
77 | printMainData(line, &config, template, path);
78 | free(line);
79 | }
80 | printfAuxData(config, path);
81 | fclose(file);
82 | } else if (config.s == 0) {
83 | fprintf(stderr, ERROR_01, path);
84 | }
85 | }
86 |
87 | void setConfigF(options *config, char **template, char *optarg) {
88 | FILE *file = fopen(optarg, "r");
89 | if (file != NULL) {
90 | for (char sym = '0'; (sym = getc(file)) != EOF;) {
91 | int length = 0;
92 | char *line = calloc(256, 1);
93 |
94 | for (line[length] = '\0'; sym != EOF && sym != '\n'; sym = getc(file)) {
95 | line[length] = sym;
96 | line[length += 1] = '\0';
97 | if (length % 255 == 0)
98 | line = (char *)increaseLengthStr(line, length + 256);
99 | }
100 |
101 | if (!(config->e || config->f))
102 | config->f = createTemplate(template, line);
103 | else
104 | addTemplate(template, line);
105 | free(line);
106 | }
107 | fclose(file);
108 | } else if (config->s == 0) {
109 | fprintf(stderr, ERROR_01, optarg);
110 | }
111 | }
112 |
113 | void setConfigE(options *config, char **template, char *optarg) {
114 | if (!(config->e || config->f))
115 | config->e = createTemplate(template, optarg);
116 | else
117 | addTemplate(template, optarg);
118 | }
119 |
120 | void printfAuxData(options config, char *path) {
121 | if (config.c) {
122 | if (config.l) {
123 | config.countFiles > 1 ? printf("%s:1\n", path) : printf("1\n");
124 | } else {
125 | if (config.countFiles > 1) printf("%s:", path);
126 | printf("%i\n", config.countMatches);
127 | }
128 | }
129 | if (config.l && config.countMatches) printf("%s\n", path);
130 | }
131 |
132 | void printMainData(char *line, options *config, char *template, char *path) {
133 | regex_t regex;
134 | if (regcomp(®ex, template, config->i ? REG_ICASE : REG_EXTENDED) == 0) {
135 | if (regexec(®ex, line, 0, NULL, 0) == config->v) {
136 | config->countMatches += 1;
137 | if ((config->c || config->l) == 0) {
138 | if (config->countFiles > 1 && !(config->h)) printf("%s:", path);
139 | if (config->n) printf("%i:", config->numberLine);
140 | if (!config->o)
141 | printf("%s\n", line);
142 | else
143 | printfConfigO(regex, line, *config);
144 | }
145 | }
146 | regfree(®ex);
147 | }
148 | }
149 |
150 | void printfConfigO(regex_t regex, char *line, options config) {
151 | while (regexec(®ex, line, 0, NULL, 0) == config.v) {
152 | char *aux = (char *)calloc(strlen(line) + 1, 1);
153 | strcpy(aux, line);
154 | int end = strlen(line);
155 | while (regexec(®ex, aux, 0, NULL, 0) == config.v) {
156 | end--;
157 | aux[strlen(aux) - 1] = 0;
158 | }
159 | aux[strlen(aux)] = line[strlen(aux)];
160 | int start = 0;
161 | while (regexec(®ex, aux, 0, NULL, 0) == config.v && strlen(aux) > 0) {
162 | start++;
163 | int j = 0;
164 | while (aux[j] != 0) {
165 | aux[j] = aux[j + 1];
166 | j++;
167 | }
168 | }
169 | start--;
170 | int i = strlen(aux);
171 | while (i != 0) {
172 | aux[i] = aux[i - 1];
173 | i--;
174 | }
175 | aux[0] = line[start];
176 | printf("%s\n", aux);
177 | free(aux);
178 | i = start + 1;
179 | while (line[i] != 0) {
180 | line[i - start - 1] = line[i];
181 | i++;
182 | }
183 | line[i - start - 1] = 0;
184 | }
185 | }
186 |
187 | void setupConfig(options *config, int argc) {
188 | if (config->o && (config->l || config->v || config->c)) config->o = 0;
189 | config->countFiles = argc - optind;
190 | }
191 |
192 | int createTemplate(char **str, char *optarg) {
193 | *str = calloc(strlen(optarg) + 1, 1);
194 | if (*str) strcpy(*str, optarg);
195 | return str ? 1 : 0;
196 | }
197 |
198 | void addTemplate(char **str, char *optarg) {
199 | *str = increaseLengthStr(*str, strlen(*str) + strlen(optarg) + 2);
200 | if (*str) strcat(strcat(*str, "|"), optarg);
201 | }
202 |
203 | void *increaseLengthStr(void *str, int size) {
204 | char *aux = realloc(str, size);
205 | return aux;
206 | }
207 |
--------------------------------------------------------------------------------
/src/grep/s21_grep.h:
--------------------------------------------------------------------------------
1 | #ifndef SRC_GREP_S21_GREP_H_
2 | #define SRC_GREP_S21_GREP_H_
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | #define ERROR_01 "s21_grep: %s: No such file or directory\n"
11 |
12 | typedef struct {
13 | int e;
14 | int i;
15 | int v;
16 | int c;
17 | int l;
18 | int n;
19 | int h;
20 | int s;
21 | int f;
22 | int o;
23 | int countFiles;
24 | int numberLine;
25 | int countMatches;
26 | } options;
27 |
28 | void s21_grep_programm(int argc, char **argv);
29 |
30 | int scanOptions(int argc, char **argv, options *config, char **template);
31 | void printMainData(char *str, options *options, char *tmpl, char *name);
32 | void setConfigF(options *config, char **template, char *optarg);
33 | void setConfigE(options *config, char **template, char *optarg);
34 | void printfConfigO(regex_t my_regex, char *str, options config);
35 | void s21_grep(char *name, options config, char *tmpl);
36 | void printfAuxData(options config, char *path);
37 | void *increaseLengthStr(void *str, int size);
38 | int createTemplate(char **str, char *optarg);
39 | void setupConfig(options *config, int argc);
40 | void addTemplate(char **str, char *optarg);
41 |
42 | #endif // SRC_GREP_S21_GREP_H_
43 |
--------------------------------------------------------------------------------