implemented optional argument flags

master
Tibor Bizjak 2023-07-22 16:09:12 +02:00
parent 3c529c1b9b
commit 11e44def75
3 changed files with 43 additions and 14 deletions

View File

@ -7,25 +7,44 @@ void println(void);
int flush_lnbuff(void); int flush_lnbuff(void);
int getch_lnbuff(void); int getch_lnbuff(void);
/* find: prints lines containing pattern, returns number of matching lines /* find: prints lines containing pattern, returns number of matching lines
* gracefully handle line overflow */ * gracefully handle line overflow */
int find(char *pattern) int find(char *pattern, char lineno_flag, char except_flag)
{ {
int found, i, c; int found, i, c;
const int plen = strlen(pattern); const int plen = strlen(pattern);
long lineno = 1;
i = found = 0; i = found = 0;
char match = 0;
while ((c = getch_lnbuff()) != EOF) #define print_lineno() if (lineno_flag) printf("%ld:", lineno)
while ((c = getch_lnbuff()) != EOF) {
if (c == '\n') { /* newline */
if (except_flag && !match) {
print_lineno();
flush_lnbuff();
putchar('\n');
}
match = 0;
lineno++;
}
if (c != pattern[i]) if (c != pattern[i])
i = 0; i = 0;
else if (++i == plen) { // found match else if (++i == plen) { // found match
if (except_flag) {
match = 1;
continue;
}
i = 0; i = 0;
found++; found++;
print_lineno();
flush_lnbuff(); flush_lnbuff();
println(); println(), lineno++;
}
} }
return found; return found;
#undef print_lineno
} }
/* println: prints next line from stdin /* println: prints next line from stdin
@ -49,7 +68,8 @@ static_assert(!(LNBUFF_LEN % 2), "Line buffer length is not a power of two!");
struct { struct {
char self[LNBUFF_LEN]; char self[LNBUFF_LEN];
unsigned len; unsigned len;
} lnbuff = {.len= 0}; char newline;
} lnbuff = {.len=0, .newline=1};
/* LNBUFF_I: current index in line buffer */ /* LNBUFF_I: current index in line buffer */
#define LNBUFF_I (lnbuff.len & (LNBUFF_LEN - 1)) #define LNBUFF_I (lnbuff.len & (LNBUFF_LEN - 1))
@ -59,8 +79,12 @@ int getch_lnbuff()
{ {
int c = getchar(); int c = getchar();
if (c == EOF || c == '\n') // new line if (lnbuff.newline) {
lnbuff.len = 0; lnbuff.len = 0;
lnbuff.newline = 0;
}
if (c == EOF || c == '\n') // new line
lnbuff.newline = 1;
else { else {
lnbuff.self[LNBUFF_I] = c; lnbuff.self[LNBUFF_I] = c;
lnbuff.len++; lnbuff.len++;
@ -89,3 +113,4 @@ int flush_lnbuff()
lnbuff.len = 0; lnbuff.len = 0;
return i; return i;
} }

View File

@ -7,14 +7,17 @@ int getln(char line[], int lim);
int strindex(char source[], char searchfor[], int slen); int strindex(char source[], char searchfor[], int slen);
/* find: prints lines containing pattern, returns number of matching lines */ /* find: prints lines containing pattern, returns number of matching lines */
int find(char *pattern) int find(char *pattern, char lineno_flag, char except_flag)
{ {
char line[MAXLINE]; char line[MAXLINE];
int found = 0; int found = 0;
int slen = strlen(pattern); int slen = strlen(pattern);
long lineno;
while (getln(line, MAXLINE) > 0) for (lineno = 1; getln(line, MAXLINE) > 0; lineno++)
if (strindex(line, pattern, slen) >= 0) { if ((strindex(line, pattern, slen) >= 0) != except_flag) {
if (lineno_flag)
printf("%ld:", lineno);
printf("%s", line); printf("%s", line);
found++; found++;
} }

View File

@ -3,7 +3,7 @@
/* compile with 04-find-no-overflow.c or 04-find-opt.c /* compile with 04-find-no-overflow.c or 04-find-opt.c
* gcc 04-find.c [04-find-no-overflow.c | 04-find-opt.c] */ * gcc 04-find.c [04-find-no-overflow.c | 04-find-opt.c] */
int find(char *pattern); int find(char *pattern, char lineno_flag, char except_flag);
#define ARG_FLAGS X('n', lineno) X('x', except) #define ARG_FLAGS X('n', lineno) X('x', except)
@ -17,7 +17,7 @@ int main(int argc, char *argv[])
char c; char c;
/* declare flag variables */ /* declare flag variables */
#define X(c, flag_var) int flag_var = 0; #define X(c, flag) char flag##_flag = 0;
ARG_FLAGS ARG_FLAGS
#undef X #undef X
char **parg = argv; char **parg = argv;
@ -29,7 +29,7 @@ int main(int argc, char *argv[])
} }
while (c = *++parg[0]) while (c = *++parg[0])
switch (c) { switch (c) {
#define X(C, flag_var) case C: flag_var = 1; break; #define X(C, flag) case C: flag##_flag = 1; break;
ARG_FLAGS ARG_FLAGS
#undef X #undef X
default: default:
@ -40,6 +40,7 @@ int main(int argc, char *argv[])
--argc; --argc;
} }
/* illegal arguments */
if (argc != 2) { if (argc != 2) {
printf("usage: find "); printf("usage: find ");
#define X(c, _) printf("[-%c] ", c); #define X(c, _) printf("[-%c] ", c);
@ -57,6 +58,6 @@ int main(int argc, char *argv[])
return -2; return -2;
} }
int found = find(pattern); int found = find(pattern, lineno_flag, except_flag);
return found; return found;
} }