4 /*****************************************************************************
6 * Testprogram: define FCMPTEST
7 *****************************************************************************
10 /* Copyright (C) 1982, 1988, 1989 Walter Tichy
11 Copyright 1990, 1991 by Paul Eggert
12 Distributed under license by the Free Software Foundation, Inc.
14 This file is part of RCS.
16 RCS is free software; you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation; either version 2, or (at your option)
21 RCS is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with RCS; see the file COPYING. If not, write to
28 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
30 Report problems and direct all questions to:
32 rcs-bugs@cs.purdue.edu
40 /* $Log: rcsfcmp.c,v $
41 * Revision 5.9 1991/10/07 17:32:46 eggert
42 * Count log lines correctly.
44 * Revision 5.8 1991/08/19 03:13:55 eggert
47 * Revision 5.7 1991/04/21 11:58:22 eggert
48 * Fix errno bug. Add MS-DOS support.
50 * Revision 5.6 1991/02/28 19:18:47 eggert
51 * Open work file at most once.
53 * Revision 5.5 1990/11/27 09:26:05 eggert
54 * Fix comment leader bug.
56 * Revision 5.4 1990/11/01 05:03:42 eggert
57 * Permit arbitrary data in logs and comment leaders.
59 * Revision 5.3 1990/09/11 02:41:15 eggert
60 * Don't ignore differences inside keyword strings if -ko is set.
62 * Revision 5.1 1990/08/29 07:13:58 eggert
63 * Clean old log messages too.
65 * Revision 5.0 1990/08/22 08:12:49 eggert
66 * Don't append "checked in with -k by " log to logs,
67 * so that checking in a program with -k doesn't change it.
68 * Ansify and Posixate. Remove lint.
70 * Revision 4.5 89/05/01 15:12:42 narten
71 * changed copyright header to reflect current distribution rules
73 * Revision 4.4 88/08/09 19:12:50 eggert
74 * Shrink stdio code size.
76 * Revision 4.3 87/12/18 11:40:02 narten
77 * lint cleanups (Guy Harris)
79 * Revision 4.2 87/10/18 10:33:06 narten
80 * updting version number. Changes relative to 1.1 actually relative to
83 * Revision 1.2 87/03/27 14:22:19 jenkins
86 * Revision 4.1 83/05/10 16:24:04 wft
87 * Marker matching now uses trymatch(). Marker pattern is now
90 * Revision 3.1 82/12/04 13:21:40 wft
98 /* Testprogram; prints out whether two files are identical,
104 libId(fcmpId, "$Id: rcsfcmp.c,v 5.9 1991/10/07 17:32:46 eggert Exp $")
117 Igeteof(f, c, return EOF;);
123 rcsfcmp(xfp, xstatp, ufname, delta)
125 struct stat const *xstatp;
127 struct hshentry const *delta;
128 /* Compare the files xfp and ufname. Return zero
129 * if xfp has the same contents as ufname and neither has keywords,
130 * otherwise -1 if they are the same ignoring keyword values,
131 * and 1 if they differ even ignoring
132 * keyword values. For the LOG-keyword, rcsfcmp skips the log message
133 * given by the parameter delta in xfp. Thus, rcsfcmp returns nonpositive
134 * if xfp contains the same as ufname, with the keywords expanded.
135 * Implementation: character-by-character comparison until $ is found.
136 * If a $ is found, read in the marker keywords; if they are real keywords
137 * and identical, read in keyword value. If value is terminated properly,
138 * disregard it and optionally skip log message; otherwise, compare value.
142 char xkeyword[keylength+2];
145 register int xeof, ueof;
147 register char const *sp;
152 if (!(ufp = Iopen(ufname, FOPEN_R_WORK, &ustat))) {
156 if (Expand==OLD_EXPAND) {
157 if (!(result = xstatp->st_size!=ustat.st_size)) {
158 # if has_mmap && large_memory
159 result = !!memcmp(xfp->base,ufp->base,(size_t)xstatp->st_size);
162 /* get the next characters */
163 Igeteof(xfp, xc, xeof=true;);
164 Igeteof(ufp, uc, ueof=true;);
174 uc = 0; /* Keep lint happy. */
179 /* get the next characters */
180 Igeteof(xfp, xc, xeof=true;);
181 Igeteof(ufp, uc, ueof=true;);
185 /* try to get both keywords */
188 Igeteof(xfp, xc, xeof=true;);
189 Igeteof(ufp, uc, ueof=true;);
196 if (xkeyword+keylength <= tp)
200 case '\n': case KDELIM: case VDELIM:
206 (xc==KDELIM || xc==VDELIM) && (uc==KDELIM || uc==VDELIM) &&
207 (*tp = xc, (match1 = trymatch(xkeyword)) != Nomatch)
210 VOID printf("found common keyword %s\n",xkeyword);
215 xc = discardkeyval(xc, xfp);
216 uc = discardkeyval(uc, ufp);
217 if ((xeof = xc==EOF) | (ueof = uc==EOF))
224 Igeteof(xfp, xc, xeof=true;);
225 Igeteof(ufp, uc, ueof=true;);
230 case '\n': case KDELIM:
239 /* Skip closing KDELIM. */
240 Igeteof(xfp, xc, xeof=true;);
241 Igeteof(ufp, uc, ueof=true;);
244 /* if the keyword is LOG, also skip the log message in xfp*/
246 /* first, compute the number of line feeds in log msg */
249 sp = delta->log.string;
250 ls = delta->log.size;
251 if (ls<sizeof(ciklog)-1 || memcmp(sp,ciklog,sizeof(ciklog)-1)) {
252 /* This log message was inserted. */
254 while (ls--) if (*sp++=='\n') lncnt++;
257 if(--lncnt==0) break;
258 Igeteof(xfp, xc, goto returnresult;);
260 /* skip last comment leader */
261 /* Can't just skip another line here, because there may be */
262 /* additional characters on the line (after the Log....$) */
263 for (ccnt=Comment.size; ccnt--; ) {
264 Igeteof(xfp, xc, goto returnresult;);
267 * Read to the end of the comment leader or '\n',
268 * whatever comes first. Some editors strip
269 * trailing white space from a leader like " * ".
275 /* both end in the same character, but not a KDELIM */
276 /* must compare string values.*/
278 VOID printf("non-terminated keywords %s, potentially different values\n",xkeyword);
304 char const cmdid[] = "rcsfcmp";
307 int argc; char *argv[];
308 /* first argument: comment leader; 2nd: log message, 3rd: expanded file,
309 * 4th: unexpanded file
311 { struct hshentry delta;
313 Comment.string = argv[1];
314 Comment.size = strlen(argv[1]);
315 delta.log.string = argv[2];
316 delta.log.size = strlen(argv[2]);
317 if (rcsfcmp(Iopen(argv[3], FOPEN_R_WORK, (struct stat*)0), argv[4], &delta))
318 VOID printf("files are the same\n");
319 else VOID printf("files are different\n");