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 getch_lnbuff(void);
/* find: prints lines containing pattern, returns number of matching lines
* gracefully handle line overflow */
int find(char *pattern)
int find(char *pattern, char lineno_flag, char except_flag)
{
int found, i, c;
const int plen = strlen(pattern);
long lineno = 1;
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])
i = 0;
else if (++i == plen) { // found match
if (except_flag) {
match = 1;
continue;
}
i = 0;
found++;
print_lineno();
flush_lnbuff();
println();
println(), lineno++;
}
}
return found;
#undef print_lineno
}
/* 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 {
char self[LNBUFF_LEN];
unsigned len;
} lnbuff = {.len= 0};
char newline;
} lnbuff = {.len=0, .newline=1};
/* LNBUFF_I: current index in line buffer */
#define LNBUFF_I (lnbuff.len & (LNBUFF_LEN - 1))
@ -58,9 +78,13 @@ struct {
int getch_lnbuff()
{
int c = getchar();
if (c == EOF || c == '\n') // new line
if (lnbuff.newline) {
lnbuff.len = 0;
lnbuff.newline = 0;
}
if (c == EOF || c == '\n') // new line
lnbuff.newline = 1;
else {
lnbuff.self[LNBUFF_I] = c;
lnbuff.len++;
@ -89,3 +113,4 @@ int flush_lnbuff()
lnbuff.len = 0;
return i;
}

View File

@ -7,14 +7,17 @@ int getln(char line[], int lim);
int strindex(char source[], char searchfor[], int slen);
/* 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];
int found = 0;
int slen = strlen(pattern);
long lineno;
while (getln(line, MAXLINE) > 0)
if (strindex(line, pattern, slen) >= 0) {
for (lineno = 1; getln(line, MAXLINE) > 0; lineno++)
if ((strindex(line, pattern, slen) >= 0) != except_flag) {
if (lineno_flag)
printf("%ld:", lineno);
printf("%s", line);
found++;
}

View File

@ -3,7 +3,7 @@
/* 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] */
int find(char *pattern);
int find(char *pattern, char lineno_flag, char except_flag);
#define ARG_FLAGS X('n', lineno) X('x', except)
@ -17,7 +17,7 @@ int main(int argc, char *argv[])
char c;
/* declare flag variables */
#define X(c, flag_var) int flag_var = 0;
#define X(c, flag) char flag##_flag = 0;
ARG_FLAGS
#undef X
char **parg = argv;
@ -29,7 +29,7 @@ int main(int argc, char *argv[])
}
while (c = *++parg[0])
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
#undef X
default:
@ -40,6 +40,7 @@ int main(int argc, char *argv[])
--argc;
}
/* illegal arguments */
if (argc != 2) {
printf("usage: find ");
#define X(c, _) printf("[-%c] ", c);
@ -57,6 +58,6 @@ int main(int argc, char *argv[])
return -2;
}
int found = find(pattern);
int found = find(pattern, lineno_flag, except_flag);
return found;
}