|
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 */ }