fixed grep
This commit is contained in:
parent
3be9df7610
commit
4834ffca63
1 changed files with 47 additions and 60 deletions
107
src/grep.c
107
src/grep.c
|
@ -6,13 +6,16 @@
|
|||
#include <regex.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
static struct pattern {
|
||||
struct pattern {
|
||||
char *str;
|
||||
|
||||
regex_t reg;
|
||||
char reg_set;
|
||||
} **ptrns;
|
||||
static size_t ptrns_size = 0;
|
||||
|
||||
struct pattern *next;
|
||||
};
|
||||
|
||||
static struct pattern *ptr;
|
||||
static struct pattern *ptrns;
|
||||
|
||||
static char i_flag;
|
||||
static char F_flag;
|
||||
|
@ -25,55 +28,39 @@ static char mode_flag;
|
|||
static int reg_flag;
|
||||
|
||||
static void free_patterns(void) {
|
||||
if (ptrns == NULL)
|
||||
return;
|
||||
while (ptrns != NULL) {
|
||||
ptr = ptrns->next;
|
||||
|
||||
for (size_t i = 0; i < ptrns_size; i++) {
|
||||
if (ptrns[i] == NULL)
|
||||
continue;
|
||||
if (ptrns->str != NULL)
|
||||
free(ptrns->str);
|
||||
|
||||
if (ptrns[i]->str != NULL)
|
||||
free(ptrns[i]->str);
|
||||
if (ptrns->reg_set)
|
||||
regfree(&ptrns->reg);
|
||||
|
||||
if (ptrns[i]->reg_set)
|
||||
regfree(&ptrns[i]->reg);
|
||||
|
||||
free(ptrns[i]);
|
||||
free(ptrns);
|
||||
ptrns = ptr;
|
||||
}
|
||||
|
||||
free(ptrns);
|
||||
ptrns = NULL;
|
||||
}
|
||||
|
||||
static int addpattern(const char *str, const size_t size) {
|
||||
char reg_error_flag = 0;
|
||||
|
||||
ptrns = malloc(sizeof(struct pattern));
|
||||
if (ptrns == NULL) {
|
||||
ptrns = malloc(sizeof(struct pattern *));
|
||||
if (ptrns == NULL) {
|
||||
fprintf(stderr, "grep: malloc: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
fprintf(stderr, "grep: malloc: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
char reg_error_flag = 0;
|
||||
struct pattern **bckp = realloc(ptrns, sizeof(struct pattern *) * (ptrns_size + 1));
|
||||
if (bckp == NULL)
|
||||
goto ADDP_ERROR;
|
||||
ptrns = bckp;
|
||||
|
||||
ptrns[ptrns_size] = malloc(sizeof(struct pattern));
|
||||
if (ptrns[ptrns_size] == NULL)
|
||||
goto ADDP_ERROR;
|
||||
|
||||
ptrns[ptrns_size]->str = strdup(str);
|
||||
if (ptrns[ptrns_size]->str == NULL)
|
||||
ptrns->str = strdup(str);
|
||||
if (ptrns->str == NULL)
|
||||
goto ADDP_ERROR;
|
||||
|
||||
if (!F_flag) {
|
||||
char *reg_str = ptrns[ptrns_size]->str;
|
||||
char *reg_str = ptrns->str;
|
||||
size_t rs_size = size;
|
||||
|
||||
char bol = (ptrns[ptrns_size]->str[0] == '^');
|
||||
char eol = (ptrns[ptrns_size]->str[size - 1] == '^');
|
||||
char bol = (ptrns->str[0] == '^');
|
||||
char eol = (ptrns->str[size - 1] == '^');
|
||||
|
||||
if (x_flag || w_flag) {
|
||||
if (w_flag)
|
||||
|
@ -85,28 +72,25 @@ static int addpattern(const char *str, const size_t size) {
|
|||
}
|
||||
|
||||
if (x_flag)
|
||||
snprintf(reg_str, rs_size + 4, "%s%s%s", (bol) ? "" : "^", ptrns[ptrns_size]->str, (eol) ? "" : "$");
|
||||
snprintf(reg_str, rs_size + 4, "%s%s%s", (bol) ? "" : "^", ptrns->str, (eol) ? "" : "$");
|
||||
|
||||
else if (w_flag)
|
||||
snprintf(reg_str, rs_size + 4, "%s\\<%s%.*s%s\\>%s", (bol) ? "^" : "", (E_flag) ? "(" : "\\(", (int)size - bol - eol, ptrns[ptrns_size]->str + bol, (E_flag) ? ")" : "\\)", (eol) ? "$" : "");
|
||||
snprintf(reg_str, rs_size + 4, "%s\\<%s%.*s%s\\>%s", (bol) ? "^" : "", (E_flag) ? "(" : "\\(", (int)size - bol - eol, ptrns->str + bol, (E_flag) ? ")" : "\\)", (eol) ? "$" : "");
|
||||
|
||||
if (regcomp(&ptrns[ptrns_size]->reg, reg_str, reg_flag) != 0)
|
||||
if (regcomp(&ptrns->reg, reg_str, reg_flag) != 0)
|
||||
reg_error_flag = 1;
|
||||
|
||||
ptrns[ptrns_size]->reg_set = 1;
|
||||
ptrns->reg_set = 1;
|
||||
if (x_flag || w_flag)
|
||||
free(reg_str);
|
||||
|
||||
}
|
||||
|
||||
if (reg_error_flag)
|
||||
goto ADDP_ERROR;
|
||||
|
||||
ptrns_size++;
|
||||
ptrns->next = ptr;
|
||||
ptr = ptrns;
|
||||
return 0;
|
||||
|
||||
ADDP_ERROR:
|
||||
ptrns_size++;
|
||||
free_patterns();
|
||||
fprintf(stderr, "grep: %s\n", (reg_error_flag) ? "bad regex" : strerror(errno));
|
||||
return 1;
|
||||
|
@ -173,19 +157,22 @@ static int grep(FILE *fp, const char *file) {
|
|||
buf[size - 1] = '\0';
|
||||
|
||||
char match = 0;
|
||||
size_t i = 0;
|
||||
for (; i < ptrns_size; i++) {
|
||||
if (F_flag) {
|
||||
if (cmp(buf, ptrns[i]->str)) {
|
||||
match = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else if (regexec(&ptrns[i]->reg, buf, 1, &m, 0) == 0) {
|
||||
struct pattern *bckp = ptrns;
|
||||
while (bckp != NULL) {
|
||||
ptr = bckp->next;
|
||||
|
||||
if (F_flag && cmp(buf, bckp->str)) {
|
||||
match = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
else if (regexec(&bckp->reg, buf, 1, &m, 0) == 0) {
|
||||
match = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
bckp = ptr;
|
||||
}
|
||||
|
||||
if (match != v_flag) {
|
||||
|
@ -195,14 +182,14 @@ static int grep(FILE *fp, const char *file) {
|
|||
break;
|
||||
|
||||
case 'o':
|
||||
if (ptrns[i]->reg_set) {
|
||||
if (bckp->reg_set) {
|
||||
unsigned int start = m.rm_so;
|
||||
unsigned int finish = m.rm_eo;
|
||||
printf("%.*s\n", finish - start, buf + start);
|
||||
}
|
||||
|
||||
else
|
||||
puts(ptrns[i]->str);
|
||||
puts(bckp->str);
|
||||
|
||||
break;
|
||||
|
||||
|
@ -290,14 +277,14 @@ int main(int argc, char **argv) {
|
|||
break;
|
||||
|
||||
default:
|
||||
puts("grep [efiFHvxwqoc] [FILE]\n\t-e PTRN Pattern to match\n\t-f FILE Read pattern from file\n\t-i Ignore case\n\t-H Add 'filename:' prefix\n\t-F PATTERN is a literal (not regexp)\n\t-E PATTERN is an extended regexp\n\t-v Select non-matching lines\n\t-x Match whole lines only\n\t-w Match whole words only\n\t-q Quiet\n\t-o Show only the matching part of line\n\t-c Show only count of matching lines");
|
||||
puts("grep [efiFHvxwqoc] [FILE]\n\t-e PTRN Pattern to match\n\t-f FILE Read pattern from file\n\t-i Ignore case\n\t-H Add 'filename:' prefix\n\t-F Pattern is a literal (not regexp)\n\t-E Pattern is an extended regexp\n\t-v Select non-matching lines\n\t-x Match whole lines only\n\t-w Match whole words only\n\t-q Quiet\n\t-o Show only the matching part of line\n\t-c Show only count of matching lines");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
if (ptrns_size == 0) {
|
||||
if (ptrns == NULL) {
|
||||
fprintf(stderr, "grep: no patterns specified\n");
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue