|
|
1 # include "dgd.h"
2 # include "str.h"
3 # include "array.h"
4 # include "object.h"
5 # include "interpret.h"
6 # include "edcmd.h"
7 # include "editor.h"
8
9 typedef struct _editor_ {
10 cmdbuf *ed; /* editor instance */
11 struct _editor_ *next; /* next in free list */
12 } editor;
13
14 static editor *editors; /* editor table */
15 static editor *flist; /* free list */
16 static int neditors; /* # of editors */
17 static char *tmpedfile; /* proto temporary file */
18 static char *outbuf; /* output buffer */
19 static Uint outbufsz; /* chars in output buffer */
20 static eindex newed; /* new editor in current thread */
21 static bool recursion; /* recursion in editor command */
22 static bool internal; /* flag editor internal error */
23
24 /*
25 * NAME: ed->init()
26 * DESCRIPTION: initialize editor handling
27 */
28 void ed_init(tmp, num)
29 char *tmp;
30 register int num;
31 {
32 register editor *e, *f;
33
34 tmpedfile = tmp;
35 f = (editor *) NULL;
36 neditors = num;
37 if (num != 0) {
38 outbuf = ALLOC(char, USHRT_MAX + 1);
39 editors = ALLOC(editor, num);
40 for (e = editors + num; num != 0; --num) {
41 (--e)->ed = (cmdbuf *) NULL;
42 e->next = f;
43 f = e;
44 }
45 }
46 flist = f;
47 newed = EINDEX_MAX;
48 }
49
50 /*
51 * NAME: ed->finish()
52 * DESCRIPTION: terminate all editor sessions
53 */
54 void ed_finish()
55 {
56 register int i;
57 register editor *e;
58
59 for (i = neditors, e = editors; i > 0; --i, e++) {
60 if (e->ed != (cmdbuf *) NULL) {
61 cb_del(e->ed);
62 }
63 }
64 }
65
66 /*
67 * NAME: ed->clear()
68 * DESCRIPTION: allow new editor to be created
69 */
70 void ed_clear()
71 {
72 newed = EINDEX_MAX;
73 }
74
75 /*
76 * NAME: check_recursion()
77 * DESCRIPTION: check for recursion in editor commands
78 */
79 static void check_recursion()
80 {
81 if (recursion) {
82 error("Recursion in editor command");
83 }
84 }
85
86 /*
87 * NAME: ed->new()
88 * DESCRIPTION: start a new editor
89 */
90 void ed_new(obj)
91 object *obj;
92 {
93 char tmp[STRINGSZ + 3];
94 register editor *e;
95
96 check_recursion();
97 if (EINDEX(newed) != EINDEX_MAX) {
98 error("Too many simultaneous editors started");
99 }
100 e = flist;
101 if (e == (editor *) NULL) {
102 error("Too many editor instances");
103 }
104 flist = e->next;
105 obj->etabi = newed = e - editors;
106 obj->flags |= O_EDITOR;
107
108 sprintf(tmp, "%s%05u", tmpedfile, EINDEX(obj->etabi));
109 e->ed = cb_new(tmp);
110 }
111
112 /*
113 * NAME: ed->del()
114 * DESCRIPTION: delete an editor instance
115 */
116 void ed_del(obj)
117 object *obj;
118 {
119 register editor *e;
120
121 check_recursion();
122 e = &editors[EINDEX(obj->etabi)];
123 cb_del(e->ed);
124 if (obj->etabi == newed) {
125 newed = EINDEX_MAX;
126 }
127 e->ed = (cmdbuf *) NULL;
128 e->next = flist;
129 flist = e;
130 obj->flags &= ~O_EDITOR;
131 }
132
133 /*
134 * NAME: ed->handler()
135 * DESCRIPTION: fake error handler
136 */
137 static void ed_handler(f, depth)
138 frame *f;
139 Int depth;
140 {
141 /*
142 * This function just exists to prevent the higher level error handler
143 * from being called.
144 */
145 }
146
147 /*
148 * NAME: ed->command()
149 * DESCRIPTION: handle an editor command
150 */
151 string *ed_command(obj, cmd)
152 object *obj;
153 char *cmd;
154 {
155 register editor *e;
156 extern void output();
157
158 check_recursion();
159 if (strchr(cmd, LF) != (char *) NULL) {
160 error("Newline in editor command");
161 }
162
163 e = &editors[EINDEX(obj->etabi)];
164 outbufsz = 0;
165 internal = FALSE;
166 if (ec_push((ec_ftn) ed_handler)) {
167 e->ed->flags &= ~(CB_INSERT | CB_CHANGE);
168 lb_inact(e->ed->edbuf->lb);
169 recursion = FALSE;
170 if (!internal) {
171 error((char *) NULL); /* pass on error */
172 }
173 output("%s\012", errorstr()->text); /* LF */
174 } else {
175 recursion = TRUE;
176 if (cb_command(e->ed, cmd)) {
177 lb_inact(e->ed->edbuf->lb);
178 recursion = FALSE;
179 } else {
180 recursion = FALSE;
181 ed_del(obj);
182 }
183 ec_pop();
184 }
185
186 if (outbufsz == 0) {
187 return (string *) NULL;
188 }
189 return str_new(outbuf, (long) outbufsz);
190 }
191
192 /*
193 * NAME: ed->status()
194 * DESCRIPTION: return the editor status of an object
195 */
196 char *ed_status(obj)
197 object *obj;
198 {
199 return (editors[EINDEX(obj->etabi)].ed->flags & CB_INSERT) ?
200 "insert" : "command";
201 }
202
203 /*
204 * NAME: output()
205 * DESCRIPTION: handle output from the editor
206 */
207 void output(f, a1, a2, a3)
208 char *f, *a1, *a2, *a3;
209 {
210 char buf[2 * MAX_LINE_SIZE + 15];
211 Uint len;
212
213 sprintf(buf, f, a1, a2, a3);
214 len = strlen(buf);
215 if (outbufsz + len > USHRT_MAX) {
216 error("Editor output string too long");
217 }
218 memcpy(outbuf + outbufsz, buf, len);
219 outbufsz += len;
220 }
221
222 /*
223 * NAME: ed_error()
224 * DESCRIPTION: handle an editor internal error
225 */
226 void ed_error(f, a1, a2, a3)
227 char *f, *a1, *a2, *a3;
228 {
229 if (f != (char *) NULL) {
230 internal = TRUE;
231 }
232 error(f, a1,a2, a3);
233 }
234
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.