DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T r

⟦d17e9359b⟧ TextFile

    Length: 9910 (0x26b6)
    Types: TextFile
    Names: »recs.c«

Derivation

└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
    └─⟦e83f91978⟧ »EurOpenD22/isode/osimis-2.0.tar.Z« 
        └─⟦d846658bd⟧ 
            └─⟦this⟧ »osimis/smap/recs.c« 

TextFile

/*
 * Copyright (c) 1988 University College London
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * by the Department of Computer Science, University College London.
 * The name of the University may not be used to
 * endorse or promote products derived from this software without
 * specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* routines to handle the array of recs being displayed in osimon */

/*
 * Initially by Graham Knight, modified by George Pavlou
 * October 1988
 */

#include <stdio.h>
#include "disp.h"
#include "recs.h"
#include "defs.h"


static int (*order) ();         /* to be initialised by initrecs() */
static int (*get) ();
static int (*openf) ();
static int (*closef) ();


#define MAXREC 100

REC  recs[MAXREC];              /* storage for records */
REC  temprecs[MAXREC];          /* temporary storage for new records */
int  recnt;

RECID  endrec;                  /* points one past last valid rec */



/*
 * force a pointer to be valid (should not be needed - for safety)
 */

RECID  validrec (rp)
register RECID rp;
{
    if (rp < recs)
	return (recs);

    if (rp >= endrec)
	return (endrec - 1);

    return (rp);
}


/* gets things started - has to be called first */

initrecs (gtfp, opfp, clfp, orfp)
int     (*gtfp) (), (*opfp) (), (*clfp) (), (*orfp) ();
{
    register RECID rp = recs;

    get    = gtfp;              /* save "get" function */
    openf  = opfp;              /* save "open"function */
    closef = clfp;              /* save "close" function */
    order  = orfp;              /* save "ordering" function */

    rp = endrec = recs;

    while (rp < &recs[MAXREC]) {
	if (rp->m_text != NULL)
	    free (rp->m_text);
	rp->m_text = NULL;
	if (rp->m_otext != NULL)
	    free (rp->m_otext);
	rp->m_otext = NULL;
	rp->m_lines = rp->m_olines = 0;
	rp->m_time = -1;
	rp->m_flag = 0;
	rp++;
    }
}


/* copy and count the lines, return number of lines */

static  copcnt (sp, dp, len)
register char *sp, *dp;
int     len;
{
    register int i;
    int     lines = 1;

    for (i = 0; i < len + 1; i++) {
	switch (*dp = *sp++) {
	    case '\r':
		*dp = '\n';
	    case '\n':
		lines++;
	    default:
		dp++;
		continue;
	    case '\0':
		break;
	}
	break;
    }

    /* dp => terminating null */
    /* remove trailing blank lines */

    while (*--dp == '\n') {
	*dp = '\0';
	lines--;
    }

    return (lines);
}


/* install record */

saverec (frp, rp)
FREC   *frp;
RECID   rp;
{
    register char *sp, *dp;
    char  *textp;
    register int i;
    char *malloc();

    sp = (char *) frp;
    dp = (char *) rp;

    for (i = 0; i < FRECSZ; i++)
	*dp++ = *sp++;

    if ((textp = (char *) malloc (frp->f_len + 2)) == (char *) NULL) {
	advise(NULLCP, "saverec: out of core");
	return (NOTOK);
    }
    rp->m_lines = copcnt (frp->f_text, textp, frp->f_len);
    rp->m_text  = textp;
    rp->m_otext = NULL;

    return (OK);
}


/* write a record to temporary storage (temprecs[]) */

writerec (frp, indx)
FREC  *frp;
int   indx;
{
    makerecspace (indx);
    return (saverec (frp, &temprecs[indx]));
}


overwriterec (frp, indx)
FREC  *frp;
int   indx;
{
    return (saverec (frp, &temprecs[indx]));
}


makerecspace (indx)
int  indx;
{
    register int i;

    for (i = recnt; i > indx; i--)
	mvrec(&temprecs[i-1], &temprecs[i]);
    recnt++;
}


/* remove a record from temporary storage (temprecs[]) */

deleterec (indx)
int  indx;
{
    register int i;

    if (indx < 0 || indx >= recnt)
	return (NOTOK);

    /* dont free text! */

    for (i = indx+1; i < recnt; i++)
	mvrec (&temprecs[i], &temprecs[i-1]);
    recnt--;

    return (OK);
}


/* remove a record from main storage (recs[]) */

remrec (rp)
RECID   rp;
{
    register RECID rrp;

    if ((rp < recs) || (rp >= endrec))
	return (NOTOK);

    if (rp->m_text != NULL)
	free (rp->m_text);
    if (rp->m_otext != NULL)
	free (rp->m_otext);

    for (rrp = rp + 1; rrp < endrec; rrp++)
	mvrec (rrp, rrp - 1);

    endrec--;

    return (OK);
}


/* read in the initial data, sort it and install it */

getdata ()
{
    FILE  *fp;
    FREC  *frp;
    RECID  trp = temprecs, rp, rrp;
    int    p, ind = 0;


    if (openf != NULLIFP)               /* open external source (if any) */
	if ((fp = (FILE *) (*openf) ())
		== (FILE *) NULL) {
	    advise(NULLCP, "getdata: can't open source");
	    return (NOTOK);
	}

    if (get != NULLIFP)
	while (frp = (FREC *) (*get) (fp))      /* get and save data
						 * in temporary storage */
	    writerec (frp, ind++);

    if (closef != NULLIFP)              /* close source */
	(*closef) (fp);


    /* merge the records */

    trp = temprecs;
    rp  = recs;

    while ((rp < endrec) || (trp < &temprecs[recnt])) {
	if (rp == endrec)
	    p = 1;                      /* trp -> new record */
	else {
	    if (trp == &temprecs[recnt])
		p = -1;                 /* rp -> deleted record */
	    else {
		p = (*order) (rp, trp);
		if (p != 0)
		    p /= abs (p);
	    }
	}

	/*
	 * p = -1 => deleted, p = 0  => match, p = 1  => new
	 */

	switch (p) {
	    case 1:
		/* this is a new record */
		if (rp == &recs[MAXREC]) {
		    advise (NULLCP, "getdata: MAXREC overflow");
		    return (NOTOK);
		}

		/* make space */

		for (rrp = endrec; rrp > rp; rrp--)
		    mvrec (rrp - 1, rrp);

		endrec++;
		trp->m_otext = NULL;
		trp->m_olines = 0;
		trp->m_flag = R_NEW;
		mvrec (trp++, rp++);
		break;

	    case 0:
		/* record already present */
		if (strcmp (trp->m_text, rp->m_text)) {
		    /* change */
		    trp->m_otext = rp->m_text;
		    trp->m_olines = rp->m_lines;
		    trp->m_flag = R_CHANGE;
		    if (rp->m_otext != NULL)
			free (rp->m_otext);
		    mvrec (trp, rp);
		}
		else {
		    /* no change */
		    rp->m_flag = R_NOCHANGE;
		    if (rp->m_otext != NULL) {
			free (rp->m_otext);
			rp->m_otext = NULL;
		    }
		}
		rp++;
		trp++;
		break;

	    case -1:
		/* deletion */
		rp->m_flag = R_DEL;
		rp++;
		break;
	}
    }

    endrec = rp;
    return (OK);
}


static  mvrec (srp, drp)
RECID  *srp, *drp;
{
    register char *sp, *dp;
    register int i;

    sp = (char *) srp;
    dp = (char *) drp;

    for (i = 0; i < RECSZ; i++)
	*dp++ = *sp++;
}


int  find_rec (id1, id2)
int  id1, id2;
{
    int i, found = NO;

    for (i = 0; i < recnt; i++)
	if (id1 == NULL && id2 == NEW_GRP1) {
	    if (temprecs[i].m_compid.id1 == HDR2)
		return (i);
	}
	else
	if (id2 == NEW_GRP2) {
	    if (!found) {
		if (temprecs[i].m_compid.id1 == id1 &&
			temprecs[i].m_compid.id2 > 0)
		    found = YES;
	    }
	    else
		if (temprecs[i].m_compid.id1 != id1)
		    return (i);
	}
	else
	if (id2 == GRP2) {              /* any group2 rec for group1 rec id1*/
	    if (temprecs[i].m_compid.id1 == id1)
		return (i);
	}
	else                            /* existing record */
	    if (temprecs[i].m_compid.id1 == id1 &&
			temprecs[i].m_compid.id2 == id2)
		return (i);

    if (i >= recnt)
	if (id2 == NEW_GRP2)    /* first group2 rec for a group1 rec */
	    return (recnt);
	else
	    return (-1);        /* record not found */
}


/* routines for ordering */

/* compares based on timestamps */

int  timecmp (r1, r2)
FREC  *r1, *r2;
{
    COMPID  compid1, compid2;

    compid1.id1 = (r1->f_time ? r1->f_time : r1->f_compid.id1);
    compid2.id1 = (r2->f_time ? r2->f_time : r2->f_compid.id1);

    compid1.id2 = r1->f_compid.id2;
    compid2.id2 = r2->f_compid.id2;

    return (compare(&compid1, &compid2));
}


/* compares based on ids */

int  idcmp (r1, r2)
FREC *r1, *r2;
{
    return (compare(&r1->f_compid, &r2->f_compid));
}


/*  compares using the COMPID composite key.
 *  if compid1, compid2 belong to different 'groups':
 *  returns -1 if compid1 < compid2
 *  returns  1 if compid1 > compid2
 */

static int  compare (compid1, compid2)
COMPID  *compid1, *compid2;
{
    if (compid1->id1 < 0 || compid2->id1 < 0)   /* one or both are hdr recs
						 * ( < 0 : hdr rec) */
	switch (compid1->id1) {
	    case HDR1:
		if (compid2->id1 != HDR1)
		    return (-1);            /* hdr1 < anything else */
		break;                      /* both hdr1 recs */

	    case HDR2:
		switch (compid2->id1) {
		    case HDR1:
			return (1);         /* hdr1 > hdr2 */
		    case HDR2:
			break;              /* both hdr2 recs */
		    default:
			if (compid2->id2 == GRP1)
			    return (1);                 /* hdr2 > grp1 rec */
			return (-1);                    /* hdr2 < grp2 rec */
		}
		break;

	    default:
		switch (compid2->id1) {
		    case HDR1:
			return (1);         /* anything else > hdr1 */
		    case HDR2:
			if (compid1->id2 == GRP1)
			    return (-1);                /* grp1 rec < hdr2 */
			return (1);                     /* grp2 rec > hdr2 */
		    default:
			error(NULLCP, "compare: should not reach here!");
		}
		break;
	}

    switch (compid1->id2) {
	case GRP1:
	    switch (compid2->id2) {
		case GRP1:
		    break;                      /* both group1 recs */
		default:
		    return (-1);                /* group1 rec < group2 rec */
	    }
	    break;

	default:
	    switch (compid2->id2) {
		case GRP1:
		    return (1);                 /* group2 rec > group1 rec */
		default:
		    break;                      /* both group2 recs */
	    }
	    break;
    }

    /* both are group1 or group2 recs or hdrs now */

    if (compid1->id1 == compid2->id1)
	return (compid1->id2 - compid2->id2);   /* compare secondary keys */

    return (compid1->id1 - compid2->id1);       /* compare primary keys */
}