|
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 - downloadIndex: ┃ T t ┃
Length: 5967 (0x174f) Types: TextFile Names: »te_utils.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/teco/te_utils.c«
/* TECO for Ultrix Copyright 1986 Matt Fichtenbaum */ /* This program and its components belong to GenRad Inc, Concord MA 01742 */ /* They may be copied if this copyright notice is included */ /* te_utils.c utility subroutines 10/28/85 */ #include "te_defs.h" /* routines to handle storage */ /* get a buffcell */ /* if there are no buffcells available, call malloc for more storage */ struct buffcell *get_bcell() { char *malloc(); struct buffcell *p; int i; if (freebuff == NULL) { p = (struct buffcell *) malloc(BLOCKSIZE); if (!p) ERROR(E_MEM); else { freebuff = p; /* take the given address as storage */ for (i = 0; i < (BLOCKSIZE/sizeof(struct buffcell)) - 1; i++) /* for all cells in the new block */ (p+i)->f = p+i+1; /* chain the forward pointers together */ (p+i)->f = NULL; /* make the last one's forward pointer NULL */ } } p = freebuff; /* cut out head of "free" list */ freebuff = freebuff->f; p->f = p->b = NULL; return(p); } /* free a list of buffcells */ free_blist(p) struct buffcell *p; { struct buffcell *t; if (p != NULL) { for (t = p; t -> f != NULL; t = t -> f); /* find end of ret'd list */ t->f = freebuff; /* put ret'd list at head of "free" list */ freebuff = p; } } \f /* free a list of buffcells to the "delayed free" list */ dly_free_blist(p) struct buffcell *p; { struct buffcell *t; if (p != NULL) { for (t = p; t -> f != NULL; t = t -> f); /* find end of ret'd list */ t->f = dly_freebuff; /* put ret'd list at head of "free" list */ dly_freebuff = p; } } /* get a cell */ /* if there are no cells available, get a buffcell and make more */ struct qp *get_dcell() { struct qp *t; int i; if (freedcell == NULL) { t = freedcell = (struct qp *) get_bcell(); /* get a buffcell */ for (i = 0; i < (sizeof(struct buffcell)/sizeof(struct qp)) - 1; i++) { (t+i)->f = t+i+1; /* chain the fwd pointers together */ (t+i)->f = NULL; /* make the last one's forward pointer NULL */ } } t = freedcell; /* cut out head of "free" list */ freedcell = (struct qp *) freedcell->f; t->f = NULL; return(t); } /* free a list of cells */ free_dlist(p) struct qp *p; { struct qp *t; if (p != NULL) { for (t = p; t->f != NULL; t = t->f); /* find end of ret'd list */ t->f = freedcell; /* put ret'd list at head of "free" list */ freedcell = p; } } \f /* build a buffer: called with address of a qh */ /* if no buffer there, get a cell and link it in */ make_buffer(p) struct qh *p; { if (!(p->f)) { p->f = get_bcell(); p->f->b = (struct buffcell *) p; } } /* routines to advance one character forward or backward */ /* argument is the address of a qp */ /* fwdc, backc return 1 if success, 0 if beyond extremes of buffer) */ /* fwdcx extends buffer if failure */ int fwdc(arg) struct qp *arg; { if ((*arg).c >= CELLSIZE-1) /* test char count for max */ { if ((*arg).p->f == NULL) return(0); /* last cell: fail */ else { (*arg).p = (*arg).p->f; /* chain through list */ (*arg).c = 0; /* and reset char count */ } } else ++(*arg).c; /* otherwise just incr char count */ ++(*arg).dot; return(1); } fwdcx(arg) struct qp *arg; { if ((*arg).c >= CELLSIZE-1) /* test char count for max */ { if ((*arg).p->f == NULL) /* last cell: extend */ { (*arg).p->f = get_bcell(); (*arg).p->f->b = (*arg).p; } (*arg).p = (*arg).p->f; /* chain through list */ (*arg).c = 0; /* and reset char count */ } else ++(*arg).c; /* otherwise just incr char count */ ++(*arg).dot; return(1); } \f int backc(arg) struct qp *arg; { if ((*arg).c <= 0) /* test char count for min */ { if ((*arg).p->b->b == NULL) return(0); /* first cell: fail */ else { (*arg).p = (*arg).p->b; /* chain through list */ (*arg).c = CELLSIZE-1; /* reset char count */ } } else --(*arg).c; /* otherwise just decr char count */ --(*arg).dot; return(1); } /* set up a pointer to a particular text buffer position */ set_pointer(pos, ptr) /* first arg is position, 2nd is addr of pointer */ int pos; struct qp *ptr; { struct buffcell *t; int i; if (!buff.f) { buff.f = get_bcell(); /* if no text buffer, make one */ buff.f->b = (struct buffcell *) &buff; } for (i = pos/CELLSIZE, t = buff.f; (i > 0) && (t->f != NULL); i--) t = t->f; ptr->p = t; ptr->c = pos % CELLSIZE; ptr->dot = pos; ptr->z = z; } \f /* routines to get next character from command buffer */ /* getcmdc0, when reading beyond command string, pops */ /* macro stack and continues. */ /* getcmdc, in similar circumstances, reports an error */ /* if pushcmdc() has returned any chars, read them first */ /* routines type characters as read, if argument != 0 */ char getcmdc0(trace) { while (cptr.dot >= cptr.z) /* if at end of this level, pop macro stack */ { if (--msp < &mstack[0]) /* pop stack; if top level */ { msp = &mstack[0]; /* restore stack pointer */ cmdc = ESC; /* return an ESC (ignored) */ exitflag = 1; /* set to terminate execution */ return(cmdc); /* exit "while" and return */ } } cmdc = cptr.p->ch[cptr.c++]; /* get char */ ++cptr.dot; /* increment character count */ if (trace) type_char(cmdc); /* trace */ if (cptr.c > CELLSIZE-1) /* and chain if need be */ { cptr.p = cptr.p->f; cptr.c = 0; } return(cmdc); } char getcmdc(trace) { if (cptr.dot++ >= cptr.z) ERROR((msp <= &mstack[0]) ? E_UTC : E_UTM); else { cmdc = cptr.p->ch[cptr.c++]; /* get char */ if (trace) type_char(cmdc); /* trace */ if (cptr.c > CELLSIZE-1) /* and chain if need be */ { cptr.p = cptr.p->f; cptr.c = 0; } } return(cmdc); } /* peek at next char in command string, return 1 if it is equal (case independent) to argument */ int peekcmdc(arg) char arg; { return(((cptr.dot < cptr.z) && (mapch_l[cptr.p->ch[cptr.c]] == mapch_l[arg])) ? 1 : 0); }