implemented optional argument flags
parent
3c529c1b9b
commit
11e44def75
|
@ -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))
|
||||||
|
@ -58,9 +78,13 @@ struct {
|
||||||
int getch_lnbuff()
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue