|
|
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.