#include /* compile with find-no-overflow.c or find-opt.c * gcc main.c [find-no-overflow.c | find-opt.c] */ int find(char *pattern, char lineno_flag, char except_flag); #define ARG_FLAGS X('n', lineno) X('x', except) /* find pattern given by first arg in lines and print them * takes optional flags * -x : print all except matching * -n : print line numbers */ int main(int argc, char *argv[]) { int i; char c; /* declare flag variables */ #define X(c, flag) char flag##_flag = 0; ARG_FLAGS #undef X char **parg = argv; /* parse flag arguments */ for (i = 1; *++parg; ) { if (**parg != '-' || !(*parg)[1]) { argv[i++] = *parg; continue; } while (c = *++parg[0]) switch (c) { #define X(C, flag) case C: flag##_flag = 1; break; ARG_FLAGS #undef X default: printf("error: illegal option -%c\n", c); argc = 0; break; } --argc; } /* illegal arguments */ if (argc != 2) { printf("usage: find "); #define X(c, _) printf("[-%c] ", c); ARG_FLAGS #undef X printf("pattern\n"); return -1; } char *pattern = argv[1]; /* verify pattern */ for (i = 0; (c = pattern[i]) != '\0'; i++) if (c == '\n') { printf("error: newline in pattern\n"); return -2; } int found = find(pattern, lineno_flag, except_flag); return found; }