Hi, This is the source code 1.3, already solved standard input redirection problem, more runnable. I'm fixing some bugs for single quote and double quote in pattern which stop working on Windows. I also wrote a sample, SmartTestCaseProvider, which should be reference for anyone want to implement more advanced strategy. Tao Wang -- Microsoft Certified Technology Specialist CCNA http://www.dancefire.org/ I'm enjoy in Operating System, Network Security and Embedded System.
/* -*- Last-Edit: Mon Dec 7 10:31:51 1992 by Tarak S. Goradia; -*- */ #define logerr(v) fprintf(stderr, "%d\n", v); #define FAULT_1 #define FAULT_2 #define FAULT_3 #define FAULT_4 #define FAULT_5 #define FAULT_6 #define FAULT_7 #define FAULT_8 #define FAULT_9 #define FAULT_10 #define FAULT_11 #define FAULT_12 #define FAULT_13 #define FAULT_14 #define FAULT_15 #define FAULT_16 #define FAULT_17 #define FAULT_18 #define FAULT_19 #define FAULT_20 #define FAULT_21 #define FAULT_22 #define FAULT_23 #define FAULT_24 #define FAULT_25 #define FAULT_26 #define FAULT_27 #define FAULT_28 #define FAULT_29 #define FAULT_30 #define FAULT_31 #define FAULT_32 extern void exit(); # include <stdio.h> void Caseerror(); typedef char bool; # define false 0 # define true 1 # define NULL 0 # define MAXSTR 100 #ifdef FAULT_12 # define MAXPAT 50 #else # define MAXPAT MAXSTR #endif # define ENDSTR '\0' # define ESCAPE '@' # define CLOSURE '*' # define BOL '%' # define EOL '$' # define ANY '?' # define CCL '[' # define CCLEND ']' # define NEGATE '^' # define NCCL '!' # define LITCHAR 'c' # define DITTO -1 # define DASH '-' # define TAB 9 # define NEWLINE 10 # define CLOSIZE 1 typedef char character; typedef char string[MAXSTR]; #ifdef FAULT_19 void getline(s, maxsize, result) char *s; int maxsize; bool *result; { logerr(19); *result = true; if (!fgets(s, 104, stdin)) { *result = 0; } } #else bool getline(s, maxsize) char *s; int maxsize; { char *result; result = fgets(s, maxsize, stdin); return (result != NULL); } #endif int addstr(c, outset, j, maxset) char c; char *outset; int *j; int maxset; { bool result; if (*j >= maxset) result = false; else { outset[*j] = c; *j = *j + 1; result = true; } return result; } char esc(s, i) char *s; int *i; { char result; if (s[*i] != ESCAPE) result = s[*i]; else { #ifdef FAULT_23 logerr(23); if (s[*i] == ENDSTR) #else if (s[*i + 1] == ENDSTR) #endif { #ifdef FAULT_17 logerr(17); result = NEWLINE; /* constant mutation ESCAPE; */ #else result = ESCAPE; #endif } else { *i = *i + 1; if (s[*i] == 'n') result = NEWLINE; else if (s[*i] == 't') result = TAB; else result = s[*i]; } } return result; } void change(); void dodash(delim, src, i, dest, j, maxset) char delim; char *src; int *i; char *dest; int *j; int maxset; { int k; bool junk; char escjunk; while ((src[*i] != delim) && (src[*i] != ENDSTR)) { #ifdef FAULT_2 logerr(2); #else #ifdef FAULT_1 logerr(1); if (src[*i] == ESCAPE) { #else if (src[*i - 1] == ESCAPE) { #endif escjunk = esc(src, i); junk = addstr(escjunk, dest, j, maxset); } else #endif { #ifdef FAULT_10 logerr(10); #endif #ifdef FAULT_9 logerr(9); #endif #ifdef FAULT_11 logerr(11); #endif #ifdef FAULT_32 logerr(32); #endif if (src[*i] != DASH) junk = addstr(src[*i], dest, j, maxset); else if (*j <= 1 || src[*i + 1] == ENDSTR) junk = addstr(DASH, dest, j, maxset); #ifdef FAULT_10 else if (isalnum(src[*i - 1])) { logerr(10); #else #ifdef FAULT_9 else if ((isalnum(src[*i - 1])) && (isalnum(src[*i + 1]))) { logerr(9); #else #ifdef FAULT_11 else if ((isalnum(src[*i - 1])) && (isalnum(src[*i + 1])) && (src[*i - 1] > src[*i])) /* operator mutation and off by one */ { logerr(11); #else #ifdef FAULT_32 else if ((isalnum(src[*i - 1])) & (isalnum(src[*i + 1])) && (src[*i - 1] <= src[*i + 1])) { logerr(32); #else else if ((isalnum(src[*i - 1])) && (isalnum(src[*i + 1])) && (src[*i - 1] <= src[*i + 1])) { #endif // FAULT_32 #endif // FAULT_11 #endif // FAULT_9 #endif // FAULT_10 #ifdef FAULT_5 logerr(5); for (k = src[*i-1]+1; k< /* = BUG! */ src[*i+1]; k++) { #else for (k = src[*i-1]+1; k<=src[*i+1]; k++) { #endif junk = addstr(k, dest, j, maxset); } *i = *i + 1; } else junk = addstr(DASH, dest, j, maxset); } (*i) = (*i) + 1; } } bool getccl(arg, i, pat, j) char *arg; int *i; char *pat; int *j; { int jstart; bool junk; #ifdef FAULT_22 logerr(22); if (arg[*i + 1] == NEGATE) junk = addstr(NCCL, pat, j, MAXPAT); else junk = addstr(CCL, pat, j, MAXPAT); *i = *i + 1; #else *i = *i + 1; if (arg[*i] == NEGATE) { junk = addstr(NCCL, pat, j, MAXPAT); *i = *i + 1; } else junk = addstr(CCL, pat, j, MAXPAT); #endif jstart = *j; junk = addstr(0, pat, j, MAXPAT); dodash(CCLEND, arg, i, pat, j, MAXPAT); pat[jstart] = *j - jstart - 1; return (arg[*i] == CCLEND); } void stclose(pat, j, lastj) char *pat; int *j; int lastj; { int jt; int jp; bool junk; for (jp = *j - 1; jp >= lastj ; jp--) { jt = jp + CLOSIZE; junk = addstr(pat[jp], pat, &jt, MAXPAT); } *j = *j + CLOSIZE; pat[lastj] = CLOSURE; } bool in_set_2(c) char c; { #ifdef FAULT_7 logerr(7); return (c == BOL || c == ANY/*EOL mutation BUG!*/ || c == CLOSURE); #else return (c == BOL || c == EOL || c == CLOSURE); #endif } bool in_pat_set(c) char c; { #ifdef FAULT_27 logerr(27); return ( c == LITCHAR || c == BOL || c == ANY #else return ( c == LITCHAR || c == BOL || c == EOL || c == ANY #endif || c == CCL || c == NCCL || c == CLOSURE); } int makepat(arg, start, delim, pat) char *arg; int start; char delim; char *pat; { int result; int i, j, lastj, lj; bool done, junk; bool getres; char escjunk; j = 0; i = start; lastj = 0; done = false; while ((!done) && (arg[i] != delim) && (arg[i] != ENDSTR)) { lj = j; if ((arg[i] == ANY)) junk = addstr(ANY, pat, &j, MAXPAT); else if ((arg[i] == BOL) && (i == start)) junk = addstr(BOL, pat, &j, MAXPAT); else if ((arg[i] == EOL) && (arg[i+1] == delim)) junk = addstr(EOL, pat, &j, MAXPAT); else if ((arg[i] == CCL)) { getres = getccl(arg, &i, pat, &j); done = (bool)(getres == false); } else if ((arg[i] == CLOSURE) && (i > start)) { lj = lastj; if (in_set_2(pat[lj])) done = true; else stclose(pat, &j, lastj); } else { junk = addstr(LITCHAR, pat, &j, MAXPAT); escjunk = esc(arg, &i); junk = addstr(escjunk, pat, &j, MAXPAT); } lastj = lj; if ((!done)) i = i + 1; } junk = addstr(ENDSTR, pat, &j, MAXPAT); if ((done) || (arg[i] != delim)) result = 0; else if ((!junk)) result = 0; else { #ifdef FAULT_15 result = i + 1; /* off by one error */ logerr(15); #else result = i; #endif } return result; } int getpat(arg, pat) char* arg; char* pat; { int makeres; makeres = makepat(arg, 0, ENDSTR, pat); return (makeres > 0); } int makesub(arg, from, delim, sub) char* arg; int from; character delim; char* sub; { int result; int i, j; bool junk; character escjunk; j = 0; i = from; while ((arg[i] != delim) && (arg[i] != ENDSTR)) { if ((arg[i] == (unsigned)('&'))) junk = addstr(DITTO, sub, &j, MAXPAT); else { escjunk = esc(arg, &i); junk = addstr(escjunk, sub, &j, MAXPAT); } i = i + 1; } if (arg[i] != delim) result = 0; else { junk = addstr(ENDSTR, &(*sub), &j, MAXPAT); if ((!junk)) result = 0; else result = i; } return result; } bool getsub(arg, sub) char* arg; char* sub; { int makeres; makeres = makesub(arg, 0, ENDSTR, sub); return (makeres > 0); } void subline(); bool locate(c, pat, offset) character c; char * pat; int offset; { int i; bool flag; flag = false; i = offset + pat[offset]; #ifdef FAULT_6 logerr(6); while ((i >= offset)) #else while ((i > offset)) #endif { if (c == pat[i]) { flag = true; #ifdef FAULT_6 logerr(6); break; #else i = offset; #endif } else i = i - 1; } return flag; } bool omatch(lin, i, pat, j) char* lin; int *i; char* pat; int j; { char advance; bool result; advance = -1; if ((lin[*i] == ENDSTR)) result = false; else { if (!in_pat_set(pat[j])) { (void)fprintf(stdout, "in omatch: can't happen\n"); abort(); } else { switch (pat[j]) { case LITCHAR: if (lin[*i] == pat[j + 1]) advance = 1; break ; case BOL: if (*i == 0) advance = 0; break ; case ANY: if (lin[*i] != NEWLINE) advance = 1; break ; case EOL: #ifdef FAULT_24 logerr(24); advance = 0; #else #ifdef FAULT_25 logerr(25); if (lin[*i] <= NEWLINE) #else if (lin[*i] == NEWLINE) #endif advance = 0; #endif break ; case CCL: if (locate(lin[*i], pat, j + 1)) advance = 1; break ; case NCCL: #ifdef FAULT_14 logerr(14); if ((lin[*i] != NEWLINE)) /* missing code && (!locate(lin[*i], pat, j+1))) */ #else if ((lin[*i] != NEWLINE) && (!locate(lin[*i], pat, j+1))) #endif advance = 1; break ; default: Caseerror(pat[j]); }; } } if ((advance >= 0)) { *i = *i + advance; result = true; } else result = false; return result; } patsize(pat, n) char* pat; int n; { int size; if (!in_pat_set(pat[n])) { (void)fprintf(stdout, "in patsize: can't happen\n"); abort(); } else switch (pat[n]) { case LITCHAR: size = 2; break; case BOL: case EOL: case ANY: size = 1; break; case CCL: case NCCL: size = pat[n + 1] + 2; break ; case CLOSURE: size = CLOSIZE; break ; default: Caseerror(pat[n]); } return size; } int amatch(lin, offset, pat, j) char* lin; int offset; char* pat; int j; { int i, k; bool result, done; done = false; while ((!done) && (pat[j] != ENDSTR)) if ((pat[j] == CLOSURE)) { j = j + patsize(pat, j); i = offset; while ((!done) && (lin[i] != ENDSTR)) { result = omatch(lin, &i, pat, j); if (!result) done = true; } done = false; while ((!done) && (i >= offset)) { k = amatch(lin, i, pat, j + patsize(pat, j)); if ((k >= 0)) done = true; else i = i - 1; } offset = k; done = true; } else { result = omatch(lin, &offset, pat, j); if ((!result)) { offset = -1; done = true; } else j = j + patsize(pat, j); } return offset; } void putsub(lin, s1, s2, sub) char * lin; int s1, s2; char * sub; { int i; int j; i = 0; while ((sub[i] != ENDSTR)) { if ((sub[i] == DITTO)) for (j = s1; j < s2; j++) { fputc(lin[j],stdout); } else { fputc(sub[i],stdout); } i = i + 1; } } void subline(lin, pat, sub) char *lin; char *pat; char *sub; { int i, lastm, m; lastm = -1; i = 0; while ((lin[i] != ENDSTR)) { m = amatch(lin, i, pat, 0); #ifdef FAULT_3 if (m >= 0) { logerr(3); #else if ((m >= 0) && (lastm != m)) { #endif putsub(lin, i, m, sub); lastm = m; } if ((m == -1) || (m == i)) { fputc(lin[i],stdout); #ifdef FAULT_13 logerr(13); if (m == -1) i = i + 1; else i = i + 2; /* added code */ #else i = i + 1; #endif } else i = m; } } void change(pat, sub) char *pat, *sub; { string line; bool result; #ifdef FAULT_19 getline(line, MAXSTR, &result); #else result = getline(line, MAXSTR); #endif while ((result)) { subline(line, pat, sub); #ifdef FAULT_19 getline(line, MAXSTR, &result); #else result = getline(line, MAXSTR); #endif } } main(argc, argv) int argc; char *argv[]; { string pat, sub; bool result; if (MAXPAT != MAXSTR) logerr(12); // For FAULT_12 detection if (argc < 2) { (void)fprintf(stdout, "usage: change from [to]\n"); exit(1); }; result = getpat(argv[1], pat); if (!result) { (void)fprintf(stdout, "change: illegal \"from\" pattern\n"); exit(2); } if (argc >= 3) { result = getsub(argv[2], sub); if (!result) { (void)fprintf(stdout, "change: illegal \"to\" string\n"); exit(3); } } else { sub[0] = '\0'; } change(pat, sub); return 0; } void Caseerror(n) int n; { (void)fprintf(stdout, "Missing case limb: line %d\n", n); exit(4); }