Hi, The program looks working now, at least it can run through without any stop. Could you help me debug the program. And all of you should consider a test strategy, and write some code based on the source code, and do some performance check. 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); }