implemented optional argument flags
parent
3c529c1b9b
commit
11e44def75
|
@ -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))
|
||||
|
@ -59,8 +79,12 @@ 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue