-
Notifications
You must be signed in to change notification settings - Fork 1
/
te_utils.c
executable file
·254 lines (218 loc) · 6.54 KB
/
te_utils.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
/* 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 */
/* version for multiple buffers 04/13/89 11.30 */
#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()
{
void *malloc(size_t);
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;
}
}
/* 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;
}
}
/* 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);
}
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 (!pbuff->f)
{
pbuff->f = get_bcell(); /* if no text buffer, make one */
pbuff->f->b = (struct buffcell *) &pbuff->f;
}
for (i = pos/CELLSIZE, t = pbuff->f; (i > 0) && (t->f != NULL); i--) t = t->f;
ptr->p = t;
ptr->c = pos % CELLSIZE;
ptr->dot = pos;
ptr->z = pbuff->z;
}
/* 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);
}