/*
 * $Copyright:	$
 * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989, 1990 
 * Sequent Computer Systems, Inc.   All rights reserved.
 *  
 * This software is furnished under a license and may be used
 * only in accordance with the terms of that license and with the
 * inclusion of the above copyright notice.   This software may not
 * be provided or otherwise made available to, or used by, any
 * other person.  No title to or ownership of the software is
 * hereby transferred."
 *
 */
/* rcsfcmp.c */

#ident "$Header: rcsfcmp.c 1.3 89/10/10 $"

/*
 *                     RCS file comparison
 */
/*****************************************************************************
 *                       rcsfcmp()
 *                       Testprogram: define FCMPTEST
 *****************************************************************************
 *
 * Copyright (C) 1982 by Walter F. Tichy
 *                       Purdue University
 *                       Computer Science Department
 *                       West Lafayette, IN 47907
 *
 * All rights reserved. No part of this software may be sold or distributed
 * in any form or by any means without the prior written permission of the
 * author.
 * Report problems and direct all inquiries to Tichy@purdue (ARPA net).
 */



/* $Log:	rcsfcmp.c,v $
 *
 */

/*
#define FCMPTEST
/* Testprogram; prints out whether two files are identical,
 * except for keywords
 */

#include  "rcsbase.h"
extern FILE * fopen();
extern enum markers trymatch(); /* check for keywords */


rcsfcmp(xfname,uxfname,delta)
char * xfname, *uxfname; struct hshentry *delta;
/* Function: compares the files xfname and uxfname. Returns true
 * if xfname has the same contents as uxfname, while disregarding
 * keyword values. For the LOG-keyword, rcsfcmp skips the log message
 * given by the parameter delta in xfname. Thus, rcsfcmp returns true
 * if xfname contains the same as uxfname, with the keywords expanded.
 * Implementation: character-by-character comparison until $ is found.
 * If a $ is found, read in the marker keywords; if they are real keywords
 * and identical, read in keyword value. If value is terminated properly,
 * disregard it and optionally skip log message; otherwise, compare value.
 */
{
    register int xc,uxc;
    char xkeyword[keylength+2],   uxkeyword[keylength+2];
    char xkeyval[keyvallength+1], uxkeyval[keyvallength+1];
    register char * tp;
    FILE * xfp, * uxfp;
    int result;
    enum markers match1,match2;

    if ((xfp=fopen(tp=xfname,"r"))==NULL || (uxfp=fopen(tp=uxfname,"r"))==NULL) {
       faterror("Can't open %s\n", tp);
       return false;
    }
    result=false;
    xc=getc(xfp); uxc=getc(uxfp);
    while( xc == uxc) { /* comparison loop */
        if (xc==EOF) { /* finished; everything is the same*/
            result=true;
            break;
        }
        if ( xc!=KDELIM) {
            /* get the next characters */
            xc=getc(xfp); uxc=getc(uxfp);
        } else {
            /* try to get both keywords */
            tp = xkeyword;
            while( (xc=getc(xfp))!=EOF && (tp< xkeyword+keylength) && (xc!='\n')
                   && (xc!=KDELIM) && (xc!=VDELIM))
                *tp++ = xc;
	    *tp++ = xc;  /* add closing K/VDELIM */
            *tp='\0';
            tp = uxkeyword;
            while( (uxc=getc(uxfp))!=EOF && (tp< uxkeyword+keylength) && (uxc!='\n')
                   && (uxc!=KDELIM) && (uxc!=VDELIM))
                *tp++ = uxc;
	    *tp++ = xc;  /* add closing K/VDELIM */
            *tp='\0';
            /* now we have 2 keywords, or something thal looks like it.*/
	    match1=trymatch(xkeyword,false);
	    match2=trymatch(uxkeyword,false);
	    if (match1 != match2) break; /* not identical */
#ifdef FCMPTEST
	    VOID printf("found potential keywords %s and %s\n",xkeyword,uxkeyword);
#endif

	    if (match1 == Nomatch) {
		/* not a keyword pattern, but could still be identical */
		if (strcmp(xkeyword,uxkeyword)==0)
		     continue;
		else break;
	    }
#ifdef FCMPTEST
	    VOID printf("found common keyword %s\n",xkeyword);
#endif
	    tp=xkeyval;
	    if (xc==VDELIM) {/* get value */
		while (((xc=getc(xfp))!=KDELIM) && (xc!='\n') && (xc!=EOF) &&
			(tp<xkeyval+keyvallength))
		    *tp++ = xc;
	    }
	    *tp = '\0';   /*xkeyval now filled with value; possibly empty*/
	    tp=uxkeyval;
	    if (uxc==VDELIM) {/* get value */
		while (((uxc=getc(uxfp))!=KDELIM) && (uxc!='\n') && (uxc!=EOF) &&
			(tp<uxkeyval+keyvallength))
		    *tp++ = uxc;
	    }
	    *tp = '\0';   /*uxkeyval now filled with value; possibly empty*/
	    if (xc!=uxc) break; /* not the same */
	    if (xc==KDELIM) {
		xc=getc(xfp); uxc=getc(uxfp); /* skip closing KDELIM */
		/* if the keyword is LOG, also skip the log message in xfp*/
		if (match1==Log) {
		    /* first, compute the number of line feeds in log msg */
		    int lncnt, ccnt;
		    lncnt=2; tp=delta->log;
		    while(*tp) if(*tp++=='\n') lncnt++;
		    while(xc!=EOF) {
			if (xc=='\n')
			    if(--lncnt==0) break;
			xc=getc(xfp);
		    }
		    /* skip last comment leader */
		    /* Can't just skip another line here, because there may be */
		    /* additional characters on the line (after the Log....$)  */
		    for (ccnt=strlen(Comment); ccnt>=0; lncnt--) {
			xc=getc(xfp);
			if(xc=='\n') break;
			/* reads to the end of the comment leader or '\n',     */
			/* whatever comes first. This is because some editors  */
			/* strip off trailing blanks from a leader like " * ". */
		    }
		}
	    } else {
		/* both end in the same character, but not a KDELIM */
		/* must compare string values.*/
#ifdef FCMPTEST
		VOID printf("non-terminated keywords %s, potentially different values\n",xkeyword);
#endif
		if (strcmp(xkeyval,uxkeyval)!=0) break; /*different */
		xc=getc(xfp); uxc=getc(uxfp); /* skip closing char  */
            }
        }
    }
    VOID fclose(xfp); VOID fclose(uxfp);
    return result;
}



#ifdef FCMPTEST
char * RCSfilename, * workfilename;

char * Comment;

main(argc, argv)
int  argc; char  *argv[];
/* first argument: comment leader; 2nd: log message, 3rd: expanded file,
 * 4th: unexpanded file
 */
{       struct hshentry delta;

        cmdid="rcsfcmp";
        Comment=argv[1];
        delta.log=argv[2];
        if (rcsfcmp(argv[3],argv[4],&delta))
                VOID printf("files are the same\n");
        else    VOID printf("files are different\n");
}
#endif
