home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / RCS_SRC.ZIP / RCSFCMP.C < prev    next >
C/C++ Source or Header  |  1991-01-15  |  7KB  |  227 lines

  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.    Distributed under license by the Free Software Foundation, Inc.
  15.  
  16. This file is part of RCS.
  17.  
  18. RCS is free software; you can redistribute it and/or modify
  19. it under the terms of the GNU General Public License as published by
  20. the Free Software Foundation; either version 1, or (at your option)
  21. any later version.
  22.  
  23. RCS is distributed in the hope that it will be useful,
  24. but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  26. GNU General Public License for more details.
  27.  
  28. You should have received a copy of the GNU General Public License
  29. along with RCS; see the file COPYING.  If not, write to
  30. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  31.  
  32. Report problems and direct all questions to:
  33.  
  34.     rcs-bugs@cs.purdue.edu
  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  eggert@sm.unisys.com (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
  227.