1 /* $NetBSD: rcsfcmp.c,v 1.1.1.2 1996/10/13 21:57:01 veego Exp $ */
3 /* Compare working files, ignoring RCS keyword strings. */
5 /*****************************************************************************
7 * Testprogram: define FCMPTEST
8 *****************************************************************************
11 /* Copyright 1982, 1988, 1989 Walter Tichy
12 Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
13 Distributed under license by the Free Software Foundation, Inc.
15 This file is part of RCS.
17 RCS is free software; you can redistribute it and/or modify
18 it under the terms of the GNU General Public License as published by
19 the Free Software Foundation; either version 2, or (at your option)
22 RCS is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 GNU General Public License for more details.
27 You should have received a copy of the GNU General Public License
28 along with RCS; see the file COPYING.
29 If not, write to the Free Software Foundation,
30 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 Report problems and direct all questions to:
34 rcs-bugs@cs.purdue.edu
44 * Revision 5.14 1995/06/16 06:19:24 eggert
47 * Revision 5.13 1995/06/01 16:23:43 eggert
48 * (rcsfcmp): Add -kb support.
50 * Revision 5.12 1994/03/17 14:05:48 eggert
51 * Normally calculate the $Log prefix from context, not from RCS file.
52 * Calculate line numbers correctly even if the $Log prefix contains newlines.
55 * Revision 5.11 1993/11/03 17:42:27 eggert
56 * Fix yet another off-by-one error when comparing Log string expansions.
58 * Revision 5.10 1992/07/28 16:12:44 eggert
59 * Statement macro names now end in _.
61 * Revision 5.9 1991/10/07 17:32:46 eggert
62 * Count log lines correctly.
64 * Revision 5.8 1991/08/19 03:13:55 eggert
67 * Revision 5.7 1991/04/21 11:58:22 eggert
68 * Fix errno bug. Add MS-DOS support.
70 * Revision 5.6 1991/02/28 19:18:47 eggert
71 * Open work file at most once.
73 * Revision 5.5 1990/11/27 09:26:05 eggert
74 * Fix comment leader bug.
76 * Revision 5.4 1990/11/01 05:03:42 eggert
77 * Permit arbitrary data in logs and comment leaders.
79 * Revision 5.3 1990/09/11 02:41:15 eggert
80 * Don't ignore differences inside keyword strings if -ko is set.
82 * Revision 5.1 1990/08/29 07:13:58 eggert
83 * Clean old log messages too.
85 * Revision 5.0 1990/08/22 08:12:49 eggert
86 * Don't append "checked in with -k by " log to logs,
87 * so that checking in a program with -k doesn't change it.
88 * Ansify and Posixate. Remove lint.
90 * Revision 4.5 89/05/01 15:12:42 narten
91 * changed copyright header to reflect current distribution rules
93 * Revision 4.4 88/08/09 19:12:50 eggert
94 * Shrink stdio code size.
96 * Revision 4.3 87/12/18 11:40:02 narten
97 * lint cleanups (Guy Harris)
99 * Revision 4.2 87/10/18 10:33:06 narten
100 * updting version number. Changes relative to 1.1 actually relative to
103 * Revision 1.2 87/03/27 14:22:19 jenkins
106 * Revision 4.1 83/05/10 16:24:04 wft
107 * Marker matching now uses trymatch(). Marker pattern is now
110 * Revision 3.1 82/12/04 13:21:40 wft
118 /* Testprogram; prints out whether two files are identical,
119 * except for keywords
124 libId(fcmpId
, "Id: rcsfcmp.c,v 5.14 1995/06/16 06:19:24 eggert Exp")
126 static int discardkeyval
P((int,RILE
*));
138 Igeteof_(f
, c
, return EOF
;)
144 rcsfcmp(xfp
, xstatp
, uname
, delta
)
146 struct stat
const *xstatp
;
148 struct hshentry
const *delta
;
149 /* Compare the files xfp and uname. Return zero
150 * if xfp has the same contents as uname and neither has keywords,
151 * otherwise -1 if they are the same ignoring keyword values,
152 * and 1 if they differ even ignoring
153 * keyword values. For the LOG-keyword, rcsfcmp skips the log message
154 * given by the parameter delta in xfp. Thus, rcsfcmp returns nonpositive
155 * if xfp contains the same as uname, with the keywords expanded.
156 * Implementation: character-by-character comparison until $ is found.
157 * If a $ is found, read in the marker keywords; if they are real keywords
158 * and identical, read in keyword value. If value is terminated properly,
159 * disregard it and optionally skip log message; otherwise, compare value.
163 char xkeyword
[keylength
+2];
166 register int xeof
, ueof
;
168 register char const *sp
;
169 register size_t leaderlen
;
174 if (!(ufp
= Iopen(uname
, FOPEN_R_WORK
, &ustat
))) {
178 if (MIN_UNEXPAND
<= Expand
) {
179 if (!(result
= xstatp
->st_size
!=ustat
.st_size
)) {
180 # if large_memory && maps_memory
181 result
= !!memcmp(xfp
->base
,ufp
->base
,(size_t)xstatp
->st_size
);
184 /* get the next characters */
185 Igeteof_(xfp
, xc
, xeof
=true;)
186 Igeteof_(ufp
, uc
, ueof
=true;)
196 uc
= 0; /* Keep lint happy. */
202 /* get the next characters */
203 Igeteof_(xfp
, xc
, xeof
=true;)
204 Igeteof_(ufp
, uc
, ueof
=true;)
208 /* try to get both keywords */
211 Igeteof_(xfp
, xc
, xeof
=true;)
212 Igeteof_(ufp
, uc
, ueof
=true;)
219 if (xkeyword
+keylength
<= tp
)
223 case '\n': case KDELIM
: case VDELIM
:
229 (xc
==KDELIM
|| xc
==VDELIM
) && (uc
==KDELIM
|| uc
==VDELIM
) &&
230 (*tp
= xc
, (match1
= trymatch(xkeyword
)) != Nomatch
)
233 VOID
printf("found common keyword %s\n",xkeyword
);
238 xc
= discardkeyval(xc
, xfp
);
239 uc
= discardkeyval(uc
, ufp
);
240 if ((xeof
= xc
==EOF
) | (ueof
= uc
==EOF
))
247 Igeteof_(xfp
, xc
, xeof
=true;)
248 Igeteof_(ufp
, uc
, ueof
=true;)
253 case '\n': case KDELIM
:
262 /* Skip closing KDELIM. */
263 Igeteof_(xfp
, xc
, xeof
=true;)
264 Igeteof_(ufp
, uc
, ueof
=true;)
267 /* if the keyword is LOG, also skip the log message in xfp*/
269 /* first, compute the number of line feeds in log msg */
272 sp
= delta
->log
.string
;
273 ls
= delta
->log
.size
;
274 if (ls
<sizeof(ciklog
)-1 || memcmp(sp
,ciklog
,sizeof(ciklog
)-1)) {
276 * This log message was inserted. Skip its header.
277 * The number of newlines to skip is
278 * 1 + (C+1)*(1+L+1), where C is the number of newlines
279 * in the comment leader, and L is the number of
280 * newlines in the log string.
283 for (ccnt
=Comment
.size
; ccnt
--; )
284 c1
+= Comment
.string
[ccnt
] == '\n';
286 while (ls
--) if (*sp
++=='\n') lncnt
+= c1
;
289 if(--lncnt
==0) break;
290 Igeteof_(xfp
, xc
, goto returnresult
;)
292 /* skip last comment leader */
293 /* Can't just skip another line here, because there may be */
294 /* additional characters on the line (after the Log....$) */
295 ccnt
= RCSversion
<VERSION(5) ? Comment
.size
: leaderlen
;
297 Igeteof_(xfp
, xc
, goto returnresult
;)
299 * Read to the end of the comment leader or '\n',
300 * whatever comes first, because the leader's
301 * trailing white space was probably stripped.
303 } while (ccnt
-- && (xc
!='\n' || --c1
));
307 /* both end in the same character, but not a KDELIM */
308 /* must compare string values.*/
310 VOID
printf("non-terminated keywords %s, potentially different values\n",xkeyword
);
340 char const cmdid
[] = "rcsfcmp";
343 int argc
; char *argv
[];
344 /* first argument: comment leader; 2nd: log message, 3rd: expanded file,
345 * 4th: unexpanded file
347 { struct hshentry delta
;
349 Comment
.string
= argv
[1];
350 Comment
.size
= strlen(argv
[1]);
351 delta
.log
.string
= argv
[2];
352 delta
.log
.size
= strlen(argv
[2]);
353 if (rcsfcmp(Iopen(argv
[3], FOPEN_R_WORK
, (struct stat
*)0), argv
[4], &delta
))
354 VOID
printf("files are the same\n");
355 else VOID
printf("files are different\n");