1: /* grep.Ρ */
2:
3: #include <alloca.h>
4: #include <ctype.h>
5: #include <popt.h>
6: #include <regex.h>
7: #include <stdio.h>
8: #include <string.h>
9: #include <unistd.h>
10:
11: #define MODE_REGEXP 1
12: #define MODE_EXTENDED 2
13: #define MODE_FIXED 3
14:
15: void do_regerror(int errcode, const regex_t *preg) {
16: char *errbuf;
17: size_t errbuf_size;
18:
19: errbuf_size = regerror(errcode, preg, NULL, 0);
20: errbuf = alloca(errbuf_size);
21: if (!errbuf) {
22: perror("alloca");
23: return;
24: }
25:
26: regerror(errcode, preg, errbuf, errbuf_size);
27: fprintf(stderr, "%s\n", errbuf);
28: }
29:
30: int scanFile(FILE * f, int mode, const void * pattern,
31: int ignoreCase, const char * fileName,
32: int * maxCountPtr) {
33: long lineLength;
34: char * line;
35: int match;
36: int rc;
37: char * chptr;
38: char * prefix = "";
39:
40: if (fileName) {
41: prefix = alloca(strlen(fileName) + 4);
42: sprintf(prefix, "%s: ", fileName);
43: }
44:
45: lineLength = sysconf(_SC_LINE_MAX);
46: line = alloca(lineLength);
47:
48: while (fgets(line, lineLength, f) && (*maxCountPtr)) {
49: /* Π΅ΡΠ»ΠΈ Ρ Π½Π°Ρ Π½Π΅ Π±ΡΠ΄Π΅Ρ Π·Π°Π²Π΅ΡΡΠ°ΡΡΠ΅Π³ΠΎ ΡΠΈΠΌΠ²ΠΎΠ»Π° '\n'
50: ΡΠΎ ΠΌΡ Π½Π΅ ΡΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠ»ΡΡΠΈΡΡ Π²ΡΡ ΡΡΡΠΎΠΊΡ ΡΠ΅Π»ΠΈΠΊΠΎΠΌ */
51: if (line [strlen (line) -1] != '\n') {
52: fprintf(stderr, " %s line ΡΠ»ΠΈΡΠΊΠΎΠΌ Π΄Π»ΠΈΠ½Π½Π°Ρ\n", prefix);
53: return 1;
54: }
55:
56: if (mode == MODE_FIXED) {
57: if (ignoreCase) {
58: for (chptr = line; *chptr; chptr++) {
59: if (isalpha(*chptr)) *chptr = tolower(*chptr);
60: }
61: }
62: match = (strstr(line, pattern) != NULL);
63: } else {
64: match = 0;
65: rc = regexec (pattern, line, 0, NULL, 0);
66: if (!rc)
67: match = 1;
68: else if (rc != REG_NOMATCH)
69: do_regerror(match, pattern);
70: }
71:
72: if (match) {
73: printf("%s%s", prefix, line);
74: if (*maxCountPtr > 0)
75: (*maxCountPtr)--;
76: }
77: }
78:
79: return 0;
80: }
81:
82: int main(int argc, const char ** argv) {
83: const char * pattern = NULL;
84: regex_t regPattern;
85: const void * finalPattern;
86: int mode = MODE_REGEXP;
87: int ignoreCase = 0;
88: int maxCount = -1;
89: int rc;
90: int regFlags;
91: const char ** files;
92: poptContext optCon;
93: FILE * f;
94: char * chptr;
95: struct poptOption optionsTable[] = {
96: { "extended-regexp", 'E', POPT_ARG_VAL,
97: &mode, MODE_EXTENDED,
98: "ΡΠ°Π±Π»ΠΎΠ½ΠΎΠΌ Π΄Π»Ρ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΡ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠ°ΡΡΠΈΡΠ΅Π½Π½ΠΎΠ΅ ΡΠ΅Π³ΡΠ»ΡΡΠ½ΠΎΠ΅ "
99: "Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠ΅"},
100: { "fixed-strings", 'F', POPT_ARG_VAL,
101: &mode, MODE_FIXED,
102: "ΡΠ°Π±Π»ΠΎΠ½ΠΎΠΌ Π΄Π»Ρ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΡ ΡΠ²Π»ΡΠ΅ΡΡΡ Π±Π°Π·ΠΎΠ²Π°Ρ ΡΡΡΠΎΠΊΠ° (Π½Π΅ "
103: "ΡΠ΅Π³ΡΠ»ΡΡΠ½ΠΎΠ΅ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠ΅)", NULL },
104: { "basic-regexp", 'G', POPT_ARG_VAL,
105: &mode, MODE_REGEXP,
106: "ΡΠ°Π±Π»ΠΎΠ½ΠΎΠΌ Π΄Π»Ρ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΡ ΡΠ²Π»ΡΠ΅ΡΡΡ Π±Π°Π·ΠΎΠ²ΠΎΠ΅ ΡΠ΅Π³ΡΠ»ΡΡΠ½ΠΎΠ΅ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠ΅" },
107: { "ignore-case", 'i', POPT_ARG_NONE, &ignoreCase, 0,
108: "Π²ΡΠΏΠΎΠ»Π½ΡΡΡ ΠΏΠΎΠΈΡΠΊ, ΡΡΠ²ΡΡΠ²ΠΈΡΠ΅Π»ΡΠ½ΡΠΉ ΠΊ ΡΠ΅Π³ΠΈΡΡΡΡ", NULL },
109: { "max-count", 'm', POPT_ARG_INT, &maxCount, 0,
110: "Π·Π°Π²Π΅ΡΡΠΈΡΡ ΠΏΠΎΡΠ»Π΅ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ N. ΡΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠΉ", "N" },
111: { "regexp", 'e', POPT_ARG_STRING, &pattern, 0,
112: "ΡΠ΅Π³ΡΠ»ΡΡΠ½ΠΎΠ΅ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Π΄Π»Ρ ΠΏΠΎΠΈΡΠΊΠ°", "pattern" },
113: POPT_AUTOHELP
114: { NULL, '\0', POPT_ARG_NONE, NULL, 0, NULL, NULL }
115: };
116:
117: optCon = poptGetContext("grep", argc, argv, optionsTable, 0);
118: poptSetOtherOptionHelp(optCon, "<ΡΠ°Π±Π»ΠΎΠ½> <ΡΠΏΠΈΡΠΎΠΊ ΡΠ°ΠΉΠ»ΠΎΠ²>");
119:
120: if ((rc = poptGetNextOpt(optCon)) < -1) {
121: /* Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ° Π²ΠΎΠ·Π½ΠΈΠΊΠ»Π° ΠΎΡΠΈΠ±ΠΊΠ° */
122: fprintf(stderr, "%s: %s\n",
123: poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
124: poptStrerror(rc));
125: return 1;
126: }
127:
128: files = poptGetArgs(optCon);
129: /* Π΅ΡΠ»ΠΈ ΠΌΡ Π½Π΅ ΠΏΠΎΠ»ΡΡΠΈΠ»ΠΈ ΡΠ°Π±Π»ΠΎΠ½, ΡΠΎ ΠΎΠ½ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±ΡΡΡ ΠΏΠ΅ΡΠ²ΡΠΌ
130: ΠΈΠ· ΠΎΡΡΠ°Π²ΡΠΈΡ ΡΡ */
131: if (!files && !pattern) {
132: poptPrintUsage(optCon, stdout, 0);
133: return 1;
134: }
135:
136: if (!pattern) {
137: pattern = files[0];
138: files++;
139: }
140:
141: regFlags = REG_NEWLINE | REG_NOSUB;
142: if (ignoreCase) {
143: regFlags |= REG_ICASE;
144: /* ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ ΡΠ°Π±Π»ΠΎΠ½Π° Π² Π½ΠΈΠΆΠ½ΠΈΠΉ ΡΠ΅Π³ΠΈΡΡΡ; ΡΡΠΎΠ³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π½Π΅ Π΄Π΅Π»Π°ΡΡ,
145: Π΅ΡΠ»ΠΈ ΠΌΡ ΠΈΠ³Π½ΠΎΡΠΈΡΡΠ΅ΠΌ ΡΠ΅Π³ΠΈΡΡΡ Π² ΡΠ΅Π³ΡΠ»ΡΡΠ½ΠΎΠΌ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠΈ, ΠΎΠ΄Π½Π°ΠΊΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ
146: ΡΡΠ½ΠΊΡΠΈΠΈ strstr() ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°ΡΡ -i */
147: chptr = alloca(strlen(pattern) + 1);
148: strcpy(chptr, pattern);
149: pattern = chptr;
150:
151: while (*chptr) {
152: if (isalpha(*chptr)) *chptr = tolower(*chptr);
153: chptr++;
154: }
155: }
156:
157:
158: switch (mode) {
159: case MODE_EXTENDED:
160: regFlags |= REG_EXTENDED;
161: case MODE_REGEXP:
162: if ((rc = regcomp(®Pattern, pattern, regFlags))) {
163: do_regerror(rc, ®Pattern);
164: return 1;
165: }
166: finalPattern = ®Pattern;
167: break;
168:
169: case MODE_FIXED:
170: finalPattern = pattern;
171: break;
172: }
173:
174: if (!*files) {
175: rc = scanFile(stdin, mode, finalPattern, ignoreCase, NULL,
176: &maxCount);
177: } else if (!files[1]) {
178: /* ΡΡΠ° ΡΠ°ΡΡΡ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅ΡΡΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎ, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΈΠΌΡ ΡΠ°ΠΉΠ»Π°
179: Π²ΡΠ²ΠΎΠ΄ΠΈΡΡ Π½Π΅ Π½ΡΠΆΠ½ΠΎ */
180: if (!(f = fopen(*files, "r"))) {
181: perror(*files);
182: rc = 1;
183: } else {
184: rc = scanFile(f, mode, finalPattern, ignoreCase, NULL,
185: &maxCount);
186: fclose(f);
187: }
188: } else {
189: rc = 0;
190:
191: while (*files) {
192: if (!(f = fopen(*files, "r"))) {
193: perror(*files);
194: rc = 1;
195: } else {
196: rc |= scanFile(f, mode, finalPattern, ignoreCase,
197: *files, &maxCount);
198: fclose(f);
199: }
200: files++;
201: if (!maxCount) break;
202: }
203: }
204:
205: return rc;
206: }
ΠΠ»Π°Π²Π° 24
Π£ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΡΠ΅ΡΠΌΠΈΠ½Π°Π»Π°ΠΌΠΈ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ S-Lang
Π‘ ΠΏΠΎΠΌΠΎΡΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ S-Lang, Π½Π°ΠΏΠΈΡΠ°Π½Π½ΠΎΠΉ ΠΠΆΠΎΠ½ΠΎΠΌ ΠΡΠ²ΠΈΡΠΎΠΌ (John Π. Davis), ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΡΡ Π΄ΠΎΡΡΡΠΏ ΠΊ ΡΠ΅ΡΠΌΠΈΠ½Π°Π»Π°ΠΌ Π½Π° ΡΡΠ΅Π΄Π½Π΅ΠΌ ΡΡΠΎΠ²Π½Π΅. ΠΡΠ΅ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ, ΡΠ²ΡΠ·Π°Π½Π½ΡΠ΅ Ρ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ ΡΠ΅ΡΠΌΠΈΠ½Π°Π»Π°ΠΌΠΈ Π½Π° Π½ΠΈΠ·ΠΊΠΎΠΌ ΡΡΠΎΠ²Π½Π΅, ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΡΡΡΡ ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²ΠΎΠΌ Π½Π°Π±ΠΎΡΠ° ΠΏΠΎΠ΄ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌ, ΠΏΡΠ΅Π΄Π»Π°Π³Π°ΡΡΠΈΡ ΠΏΡΡΠΌΠΎΠΉ Π΄ΠΎΡΡΡΠΏ ΠΊ Π²ΠΈΠ΄Π΅ΠΎΡΠ΅ΡΠΌΠΈΠ½Π°Π»Π°ΠΌ ΠΈ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΡΠΏΡΠ°Π²Π»ΡΡΡΠΈΡ ΠΏΡΠΎΠΊΡΡΡΠΊΠΎΠΉ ΠΈ ΡΠ²Π΅ΡΠ°ΠΌΠΈ. ΠΠ΅ΡΠΌΠΎΡΡΡ Π½Π° Π½Π΅Π·Π½Π°ΡΠΈΡΠ΅Π»ΡΠ½ΡΡ ΠΏΡΡΠΌΡΡ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΡ ΠΎΠΊΠΎΠ½ ΠΈ ΠΎΡΡΡΡΡΡΠ²ΠΈΠ΅ Π² S-Lang ΠΊΠ°ΠΊΠΈΡ -Π»ΠΈΠ±ΠΎ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ, Π΄Π»Ρ ΡΠ°ΠΊΠΈΡ Π·Π°Π΄Π°Ρ ΡΡΠ° Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° ΠΏΡΠ΅Π΄Π»Π°Π³Π°Π΅Ρ ΡΠ΄ΠΎΠ±Π½ΡΡ ΠΎΡΠ½ΠΎΠ²Ρ[167].
ΠΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ S-Lang ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΈ Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Π² DOS, ΡΡΠΎ Π΄Π΅Π»Π°Π΅Ρ Π΅Π΅ ΠΏΡΠΈΠ²Π»Π΅ΠΊΠ°ΡΠ΅Π»ΡΠ½ΠΎΠΉ Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, ΠΊΠΎΡΠΎΡΡΠ΅ Π±ΡΠ΄ΡΡ Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ Π½Π° ΠΏΠ»Π°ΡΡΠΎΡΠΌΠ°Ρ Unix ΠΈ DOS.
ΠΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ ΡΠ΅ΡΠΌΠΈΠ½Π°Π»Π°ΠΌΠΈ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ S-Lang ΠΌΠΎΠΆΠ½ΠΎ ΡΠ°Π·Π΄Π΅Π»ΠΈΡΡ Π½Π° Π΄Π²Π΅ ΠΊΠ°ΡΠ΅Π³ΠΎΡΠΈΠΈ. ΠΠΎ-ΠΏΠ΅ΡΠ²ΡΡ , Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° ΠΏΡΠ΅Π΄Π»Π°Π³Π°Π΅Ρ Π½Π°Π±ΠΎΡ ΡΡΠ½ΠΊΡΠΈΠΉ Π΄Π»Ρ ΡΠΏΡΠ°Π²Π»ΡΠ΅ΠΌΠΎΠ³ΠΎ ΡΡΠΈΡΡΠ²Π°Π½ΠΈΡ Π½Π°ΠΆΠ°ΡΠΈΠΉ ΠΊΠ»Π°Π²ΠΈΡ ΠΈΠ· ΡΠ΅ΡΠΌΠΈΠ½Π°Π»Π°. ΠΠΎ-Π²ΡΠΎΡΡΡ , ΠΎΠ½Π° ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π½Π°Π±ΠΎΡ ΠΏΠΎΠ΄ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌ Π΄Π»Ρ ΠΏΠΎΠ»Π½ΠΎΡΠΊΡΠ°Π½Π½ΠΎΠ³ΠΎ Π²ΡΠ²ΠΎΠ΄Π° Π½Π° ΡΠ΅ΡΠΌΠΈΠ½Π°Π». ΠΠ½ΠΎΠ³ΠΈΠ΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ ΡΠ΅ΡΠΌΠΈΠ½Π°Π»ΠΎΠ² Π±ΡΠ΄ΡΡ Π½Π΅Π΄ΠΎΡΡΡΠΏΠ½ΡΠΌΠΈ Π΄Π»Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΡΠΎΠ², ΠΎΠ΄Π½Π°ΠΊΠΎ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΠΌΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡΠΌΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡΠ΅ΡΠΌΠΈΠ½Π°Π»Π° ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΠ΄Π΅Ρ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ[168]. Π ΡΡΠΎΠΉ Π³Π»Π°Π²Π΅ Π²Ρ ΡΠ·Π½Π°Π΅ΡΠ΅ ΠΎ ΡΠΎΠΌ, ΠΊΠ°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ S-Lang ΠΏΡΠΈΠΌΠ΅Π½ΠΈΡΠ΅Π»ΡΠ½ΠΎ ΠΊΠΎ Π²ΡΠ΅ΠΌ ΡΡΠΈΠΌ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΠΌ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡΠΌ, Π° Π² ΠΊΠΎΠ½ΡΠ΅ Π³Π»Π°Π²Ρ Π²Π°ΠΌ Π±ΡΠ΄Π΅Ρ ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠ΅Π½ ΠΏΡΠΈΠΌΠ΅Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π΄Π»Ρ Π·Π°ΠΊΡΠ΅ΠΏΠ»Π΅Π½ΠΈΡ ΠΌΠ°ΡΠ΅ΡΠΈΠ°Π»Π°.
24.1. ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Π²Π²ΠΎΠ΄Π°
ΠΠΎΠ΄ΡΠΈΡΡΠ΅ΠΌΠ° ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ Π²Π²ΠΎΠ΄ΠΎΠΌ Π½Π° ΡΠ΅ΡΠΌΠΈΠ½Π°Π»Π°Ρ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΎΠ΄Π½ΠΎΠΉ ΠΈΠ· Π½Π°ΠΈΠΌΠ΅Π½Π΅Π΅ Π΄ΠΎΡΡΡΠΏΠ½ΡΡ ΠΏΠΎΠ΄ΡΠΈΡΡΠ΅ΠΌ Π² ΠΌΠΈΡΠ΅ Unix.
Π¨ΠΈΡΠΎΠΊΠΎ ΡΠ°ΡΠΏΡΠΎΡΡΡΠ°Π½Π΅Π½Π½ΡΠΌΠΈ ΠΏΠΎΠ΄ΡΠΈΡΡΠ΅ΠΌΠ°ΠΌΠΈ ΡΠ²Π»ΡΡΡΡΡ BSD sgtty, System termio, a ΡΠ°ΠΊΠΆΠ΅ POSIX termios. ΠΠ° ΡΠ°Π±ΠΎΡΡ ΠΏΠΎ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ Π²Ρ ΠΎΠ΄Π½ΡΠΌΠΈ Π΄Π°Π½Π½ΡΠΌΠΈ Π² Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ΅ S-Lang ΠΎΡΠ²Π΅ΡΠ°ΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΡΠ½ΠΊΡΠΈΠΉ, ΠΏΡΠ΅Π΄Π½Π°Π·Π½Π°ΡΠ΅Π½Π½ΡΡ ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΠΎ Π΄Π»Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΡΠ΄Π΅Π»Π°ΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ Π΄Π°Π½Π½ΡΡ , ΠΏΠΎΡΡΡΠΏΠ°ΡΡΠΈΡ Ρ ΠΊΠ»Π°Π²ΠΈΠ°ΡΡΡΡ, Π±ΠΎΠ»Π΅Π΅ ΠΏΡΠΎΡΡΠΎΠΉ ΠΈ Π΄ΠΎΡΡΡΠΏΠ½ΠΎΠΉ.