|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T r
Length: 9910 (0x26b6)
Types: TextFile
Names: »recs.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦e83f91978⟧ »EurOpenD22/isode/osimis-2.0.tar.Z«
└─⟦d846658bd⟧
└─⟦this⟧ »osimis/smap/recs.c«
/*
* 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 */
}