|
|
1.1 ! root 1: /* ! 2: * RCS file comparison ! 3: */ ! 4: #ifndef lint ! 5: static char rcsid[]= "$Id: rcsfcmp.c,v 4.5 89/05/01 15:12:42 narten Exp $ Purdue CS"; ! 6: #endif ! 7: /***************************************************************************** ! 8: * rcsfcmp() ! 9: * Testprogram: define FCMPTEST ! 10: ***************************************************************************** ! 11: */ ! 12: ! 13: /* Copyright (C) 1982, 1988, 1989 Walter Tichy ! 14: * All rights reserved. ! 15: * ! 16: * Redistribution and use in source and binary forms are permitted ! 17: * provided that the above copyright notice and this paragraph are ! 18: * duplicated in all such forms and that any documentation, ! 19: * advertising materials, and other materials related to such ! 20: * distribution and use acknowledge that the software was developed ! 21: * by Walter Tichy. ! 22: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 23: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 24: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 25: * ! 26: * Report all problems and direct all questions to: ! 27: * [email protected] ! 28: * ! 29: ! 30: ! 31: ! 32: ! 33: ! 34: ! 35: ! 36: */ ! 37: ! 38: ! 39: ! 40: ! 41: ! 42: /* $Log: rcsfcmp.c,v $ ! 43: * Revision 4.5 89/05/01 15:12:42 narten ! 44: * changed copyright header to reflect current distribution rules ! 45: * ! 46: * Revision 4.4 88/11/08 12:01:33 narten ! 47: * changes from [email protected] (Paul Eggert) ! 48: * ! 49: * Revision 4.4 88/08/09 19:12:50 eggert ! 50: * Shrink stdio code size. ! 51: * ! 52: * Revision 4.3 87/12/18 11:40:02 narten ! 53: * lint cleanups (Guy Harris) ! 54: * ! 55: * Revision 4.2 87/10/18 10:33:06 narten ! 56: * updting version number. Changes relative to 1.1 actually relative to ! 57: * 4.1 ! 58: * ! 59: * Revision 1.2 87/03/27 14:22:19 jenkins ! 60: * Port to suns ! 61: * ! 62: * Revision 1.1 84/01/23 14:50:23 kcs ! 63: * Initial revision ! 64: * ! 65: * Revision 4.1 83/05/10 16:24:04 wft ! 66: * Marker matching now uses trymatch(). Marker pattern is now ! 67: * checked precisely. ! 68: * ! 69: * Revision 3.1 82/12/04 13:21:40 wft ! 70: * Initial revision. ! 71: * ! 72: */ ! 73: ! 74: /* ! 75: #define FCMPTEST ! 76: /* Testprogram; prints out whether two files are identical, ! 77: * except for keywords ! 78: */ ! 79: ! 80: #include "rcsbase.h" ! 81: extern FILE * fopen(); ! 82: extern enum markers trymatch(); /* check for keywords */ ! 83: ! 84: ! 85: rcsfcmp(xfname,uxfname,delta) ! 86: char * xfname, *uxfname; struct hshentry *delta; ! 87: /* Function: compares the files xfname and uxfname. Returns true ! 88: * if xfname has the same contents as uxfname, while disregarding ! 89: * keyword values. For the LOG-keyword, rcsfcmp skips the log message ! 90: * given by the parameter delta in xfname. Thus, rcsfcmp returns true ! 91: * if xfname contains the same as uxfname, with the keywords expanded. ! 92: * Implementation: character-by-character comparison until $ is found. ! 93: * If a $ is found, read in the marker keywords; if they are real keywords ! 94: * and identical, read in keyword value. If value is terminated properly, ! 95: * disregard it and optionally skip log message; otherwise, compare value. ! 96: */ ! 97: { ! 98: register int xc,uxc; ! 99: char xkeyword[keylength+2], uxkeyword[keylength+2]; ! 100: char xkeyval[keyvallength+1], uxkeyval[keyvallength+1]; ! 101: register FILE * xfp, * uxfp; ! 102: register char * tp; ! 103: int result; ! 104: enum markers match1,match2; ! 105: ! 106: if ((xfp=fopen(tp=xfname,"r"))==NULL || (uxfp=fopen(tp=uxfname,"r"))==NULL) { ! 107: faterror("Can't open %s\n", tp); ! 108: return false; ! 109: } ! 110: result=false; ! 111: xc=getc(xfp); uxc=getc(uxfp); ! 112: while( xc == uxc) { /* comparison loop */ ! 113: if (xc==EOF) { /* finished; everything is the same*/ ! 114: result=true; ! 115: break; ! 116: } ! 117: if ( xc!=KDELIM) { ! 118: /* get the next characters */ ! 119: xc=getc(xfp); uxc=getc(uxfp); ! 120: } else { ! 121: /* try to get both keywords */ ! 122: tp = xkeyword; ! 123: while( (xc=getc(xfp))!=EOF && (tp< xkeyword+keylength) && (xc!='\n') ! 124: && (xc!=KDELIM) && (xc!=VDELIM)) ! 125: *tp++ = xc; ! 126: *tp++ = xc; /* add closing K/VDELIM */ ! 127: *tp='\0'; ! 128: tp = uxkeyword; ! 129: while( (uxc=getc(uxfp))!=EOF && (tp< uxkeyword+keylength) && (uxc!='\n') ! 130: && (uxc!=KDELIM) && (uxc!=VDELIM)) ! 131: *tp++ = uxc; ! 132: *tp++ = xc; /* add closing K/VDELIM */ ! 133: *tp='\0'; ! 134: /* now we have 2 keywords, or something thal looks like it.*/ ! 135: match1=trymatch(xkeyword,false); ! 136: match2=trymatch(uxkeyword,false); ! 137: if (match1 != match2) break; /* not identical */ ! 138: #ifdef FCMPTEST ! 139: VOID printf("found potential keywords %s and %s\n",xkeyword,uxkeyword); ! 140: #endif ! 141: ! 142: if (match1 == Nomatch) { ! 143: /* not a keyword pattern, but could still be identical */ ! 144: if (strcmp(xkeyword,uxkeyword)==0) ! 145: continue; ! 146: else break; ! 147: } ! 148: #ifdef FCMPTEST ! 149: VOID printf("found common keyword %s\n",xkeyword); ! 150: #endif ! 151: tp=xkeyval; ! 152: if (xc==VDELIM) {/* get value */ ! 153: while (((xc=getc(xfp))!=KDELIM) && (xc!='\n') && (xc!=EOF) && ! 154: (tp<xkeyval+keyvallength)) ! 155: *tp++ = xc; ! 156: } ! 157: *tp = '\0'; /*xkeyval now filled with value; possibly empty*/ ! 158: tp=uxkeyval; ! 159: if (uxc==VDELIM) {/* get value */ ! 160: while (((uxc=getc(uxfp))!=KDELIM) && (uxc!='\n') && (uxc!=EOF) && ! 161: (tp<uxkeyval+keyvallength)) ! 162: *tp++ = uxc; ! 163: } ! 164: *tp = '\0'; /*uxkeyval now filled with value; possibly empty*/ ! 165: if (xc!=uxc) break; /* not the same */ ! 166: if (xc==KDELIM) { ! 167: xc=getc(xfp); uxc=getc(uxfp); /* skip closing KDELIM */ ! 168: /* if the keyword is LOG, also skip the log message in xfp*/ ! 169: if (match1==Log) { ! 170: /* first, compute the number of line feeds in log msg */ ! 171: int lncnt, ccnt; ! 172: lncnt=2; tp=delta->log; ! 173: while(*tp) if(*tp++=='\n') lncnt++; ! 174: while(xc!=EOF) { ! 175: if (xc=='\n') ! 176: if(--lncnt==0) break; ! 177: xc=getc(xfp); ! 178: } ! 179: /* skip last comment leader */ ! 180: /* Can't just skip another line here, because there may be */ ! 181: /* additional characters on the line (after the Log....$) */ ! 182: for (ccnt=strlen(Comment); ccnt>=0; lncnt--) { ! 183: xc=getc(xfp); ! 184: if(xc=='\n') break; ! 185: /* reads to the end of the comment leader or '\n', */ ! 186: /* whatever comes first. This is because some editors */ ! 187: /* strip off trailing blanks from a leader like " * ". */ ! 188: } ! 189: } ! 190: } else { ! 191: /* both end in the same character, but not a KDELIM */ ! 192: /* must compare string values.*/ ! 193: #ifdef FCMPTEST ! 194: VOID printf("non-terminated keywords %s, potentially different values\n",xkeyword); ! 195: #endif ! 196: if (strcmp(xkeyval,uxkeyval)!=0) break; /*different */ ! 197: xc=getc(xfp); uxc=getc(uxfp); /* skip closing char */ ! 198: } ! 199: } ! 200: } ! 201: VOID fclose(xfp); VOID fclose(uxfp); ! 202: return result; ! 203: } ! 204: ! 205: ! 206: ! 207: #ifdef FCMPTEST ! 208: char * RCSfilename, * workfilename; ! 209: ! 210: char * Comment; ! 211: ! 212: main(argc, argv) ! 213: int argc; char *argv[]; ! 214: /* first argument: comment leader; 2nd: log message, 3rd: expanded file, ! 215: * 4th: unexpanded file ! 216: */ ! 217: { struct hshentry delta; ! 218: ! 219: cmdid="rcsfcmp"; ! 220: Comment=argv[1]; ! 221: delta.log=argv[2]; ! 222: if (rcsfcmp(argv[3],argv[4],&delta)) ! 223: VOID printf("files are the same\n"); ! 224: else VOID printf("files are different\n"); ! 225: } ! 226: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.