tcl.c revision 1.3.4.2 1 1.3.4.2 yamt /*-
2 1.3.4.2 yamt * Copyright (c) 1992, 1993, 1994
3 1.3.4.2 yamt * The Regents of the University of California. All rights reserved.
4 1.3.4.2 yamt * Copyright (c) 1992, 1993, 1994, 1995
5 1.3.4.2 yamt * Keith Bostic. All rights reserved.
6 1.3.4.2 yamt * Copyright (c) 1995
7 1.3.4.2 yamt * George V. Neville-Neil. All rights reserved.
8 1.3.4.2 yamt *
9 1.3.4.2 yamt * See the LICENSE file for redistribution information.
10 1.3.4.2 yamt */
11 1.3.4.2 yamt
12 1.3.4.2 yamt #include "config.h"
13 1.3.4.2 yamt
14 1.3.4.2 yamt #include <sys/cdefs.h>
15 1.3.4.2 yamt #if 0
16 1.3.4.2 yamt #ifndef lint
17 1.3.4.2 yamt static const char sccsid[] = "Id: tcl.c,v 8.19 2001/08/24 12:17:27 skimo Exp (Berkeley) Date: 2001/08/24 12:17:27 ";
18 1.3.4.2 yamt #endif /* not lint */
19 1.3.4.2 yamt #else
20 1.3.4.2 yamt __RCSID("$NetBSD: tcl.c,v 1.3.4.2 2014/05/22 15:50:35 yamt Exp $");
21 1.3.4.2 yamt #endif
22 1.3.4.2 yamt
23 1.3.4.2 yamt #include <sys/types.h>
24 1.3.4.2 yamt #include <sys/queue.h>
25 1.3.4.2 yamt #include <sys/time.h>
26 1.3.4.2 yamt
27 1.3.4.2 yamt #include <bitstring.h>
28 1.3.4.2 yamt #include <errno.h>
29 1.3.4.2 yamt #include <limits.h>
30 1.3.4.2 yamt #include <signal.h>
31 1.3.4.2 yamt #include <stdio.h>
32 1.3.4.2 yamt #include <stdlib.h>
33 1.3.4.2 yamt #include <string.h>
34 1.3.4.2 yamt #include <tcl.h>
35 1.3.4.2 yamt #include <termios.h>
36 1.3.4.2 yamt #include <unistd.h>
37 1.3.4.2 yamt
38 1.3.4.2 yamt #include "../common/common.h"
39 1.3.4.2 yamt #include "tcl_api_extern.h"
40 1.3.4.2 yamt
41 1.3.4.2 yamt static int getint __P((Tcl_Interp *, char *, char *, int *));
42 1.3.4.2 yamt static int getscreenid __P((Tcl_Interp *, SCR **, char *, char *));
43 1.3.4.2 yamt static void msghandler __P((SCR *, mtype_t, char *, size_t));
44 1.3.4.2 yamt
45 1.3.4.2 yamt extern GS *__global_list; /* XXX */
46 1.3.4.2 yamt
47 1.3.4.2 yamt /*
48 1.3.4.2 yamt * INITMESSAGE --
49 1.3.4.2 yamt * Macros to point messages at the Tcl message handler.
50 1.3.4.2 yamt */
51 1.3.4.2 yamt #define INITMESSAGE(sp) \
52 1.3.4.2 yamt scr_msg = sp->wp->scr_msg; \
53 1.3.4.2 yamt sp->wp->scr_msg = msghandler;
54 1.3.4.2 yamt #define ENDMESSAGE(sp) \
55 1.3.4.2 yamt sp->wp->scr_msg = scr_msg;
56 1.3.4.2 yamt
57 1.3.4.2 yamt /*
58 1.3.4.2 yamt * tcl_fscreen --
59 1.3.4.2 yamt * Return the screen id associated with file name.
60 1.3.4.2 yamt *
61 1.3.4.2 yamt * Tcl Command: viFindScreen
62 1.3.4.2 yamt * Usage: viFindScreen file
63 1.3.4.2 yamt */
64 1.3.4.2 yamt static int
65 1.3.4.2 yamt tcl_fscreen(clientData, interp, argc, argv)
66 1.3.4.2 yamt ClientData clientData;
67 1.3.4.2 yamt Tcl_Interp *interp;
68 1.3.4.2 yamt int argc;
69 1.3.4.2 yamt char **argv;
70 1.3.4.2 yamt {
71 1.3.4.2 yamt SCR *sp;
72 1.3.4.2 yamt
73 1.3.4.2 yamt if (argc != 2) {
74 1.3.4.2 yamt Tcl_SetResult(interp, "Usage: viFindScreen file", TCL_STATIC);
75 1.3.4.2 yamt return (TCL_ERROR);
76 1.3.4.2 yamt }
77 1.3.4.2 yamt
78 1.3.4.2 yamt if (getscreenid(interp, &sp, NULL, argv[1]))
79 1.3.4.2 yamt return (TCL_ERROR);
80 1.3.4.2 yamt
81 1.3.4.2 yamt (void)sprintf(interp->result, "%d", sp->id);
82 1.3.4.2 yamt return (TCL_OK);
83 1.3.4.2 yamt }
84 1.3.4.2 yamt
85 1.3.4.2 yamt /*
86 1.3.4.2 yamt * tcl_aline --
87 1.3.4.2 yamt * -- Append the string text after the line in lineNumber.
88 1.3.4.2 yamt *
89 1.3.4.2 yamt * Tcl Command: viAppendLine
90 1.3.4.2 yamt * Usage: viAppendLine screenId lineNumber text
91 1.3.4.2 yamt */
92 1.3.4.2 yamt static int
93 1.3.4.2 yamt tcl_aline(clientData, interp, argc, argv)
94 1.3.4.2 yamt ClientData clientData;
95 1.3.4.2 yamt Tcl_Interp *interp;
96 1.3.4.2 yamt int argc;
97 1.3.4.2 yamt char **argv;
98 1.3.4.2 yamt {
99 1.3.4.2 yamt SCR *sp;
100 1.3.4.2 yamt void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
101 1.3.4.2 yamt int lno, rval;
102 1.3.4.2 yamt
103 1.3.4.2 yamt if (argc != 4) {
104 1.3.4.2 yamt Tcl_SetResult(interp,
105 1.3.4.2 yamt "Usage: viAppendLine screenId lineNumber text", TCL_STATIC);
106 1.3.4.2 yamt return (TCL_ERROR);
107 1.3.4.2 yamt }
108 1.3.4.2 yamt
109 1.3.4.2 yamt if (getscreenid(interp, &sp, argv[1], NULL) ||
110 1.3.4.2 yamt getint(interp, "line number", argv[2], &lno))
111 1.3.4.2 yamt return (TCL_ERROR);
112 1.3.4.2 yamt INITMESSAGE(sp);
113 1.3.4.2 yamt rval = api_aline(sp, (db_recno_t)lno, argv[3], strlen(argv[3]));
114 1.3.4.2 yamt ENDMESSAGE(sp);
115 1.3.4.2 yamt
116 1.3.4.2 yamt return (rval ? TCL_ERROR : TCL_OK);
117 1.3.4.2 yamt }
118 1.3.4.2 yamt
119 1.3.4.2 yamt /*
120 1.3.4.2 yamt * tcl_dline --
121 1.3.4.2 yamt * Delete lineNum.
122 1.3.4.2 yamt *
123 1.3.4.2 yamt * Tcl Command: viDelLine
124 1.3.4.2 yamt * Usage: viDelLine screenId lineNum
125 1.3.4.2 yamt */
126 1.3.4.2 yamt static int
127 1.3.4.2 yamt tcl_dline(clientData, interp, argc, argv)
128 1.3.4.2 yamt ClientData clientData;
129 1.3.4.2 yamt Tcl_Interp *interp;
130 1.3.4.2 yamt int argc;
131 1.3.4.2 yamt char **argv;
132 1.3.4.2 yamt {
133 1.3.4.2 yamt SCR *sp;
134 1.3.4.2 yamt void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
135 1.3.4.2 yamt int lno, rval;
136 1.3.4.2 yamt
137 1.3.4.2 yamt if (argc != 3) {
138 1.3.4.2 yamt Tcl_SetResult(interp,
139 1.3.4.2 yamt "Usage: viDelLine screenId lineNumber", TCL_STATIC);
140 1.3.4.2 yamt return (TCL_ERROR);
141 1.3.4.2 yamt }
142 1.3.4.2 yamt
143 1.3.4.2 yamt if (getscreenid(interp, &sp, argv[1], NULL) ||
144 1.3.4.2 yamt getint(interp, "line number", argv[2], &lno))
145 1.3.4.2 yamt return (TCL_ERROR);
146 1.3.4.2 yamt INITMESSAGE(sp);
147 1.3.4.2 yamt rval = api_dline(sp, (db_recno_t)lno);
148 1.3.4.2 yamt ENDMESSAGE(sp);
149 1.3.4.2 yamt
150 1.3.4.2 yamt return (rval ? TCL_ERROR : TCL_OK);
151 1.3.4.2 yamt }
152 1.3.4.2 yamt
153 1.3.4.2 yamt /*
154 1.3.4.2 yamt * tcl_gline --
155 1.3.4.2 yamt * Return lineNumber.
156 1.3.4.2 yamt *
157 1.3.4.2 yamt * Tcl Command: viGetLine
158 1.3.4.2 yamt * Usage: viGetLine screenId lineNumber
159 1.3.4.2 yamt */
160 1.3.4.2 yamt static int
161 1.3.4.2 yamt tcl_gline(clientData, interp, argc, argv)
162 1.3.4.2 yamt ClientData clientData;
163 1.3.4.2 yamt Tcl_Interp *interp;
164 1.3.4.2 yamt int argc;
165 1.3.4.2 yamt char **argv;
166 1.3.4.2 yamt {
167 1.3.4.2 yamt SCR *sp;
168 1.3.4.2 yamt size_t len;
169 1.3.4.2 yamt void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
170 1.3.4.2 yamt int lno, rval;
171 1.3.4.2 yamt char *line, *p;
172 1.3.4.2 yamt
173 1.3.4.2 yamt if (argc != 3) {
174 1.3.4.2 yamt Tcl_SetResult(interp,
175 1.3.4.2 yamt "Usage: viGetLine screenId lineNumber", TCL_STATIC);
176 1.3.4.2 yamt return (TCL_ERROR);
177 1.3.4.2 yamt }
178 1.3.4.2 yamt if (getscreenid(interp, &sp, argv[1], NULL) ||
179 1.3.4.2 yamt getint(interp, "line number", argv[2], &lno))
180 1.3.4.2 yamt return (TCL_ERROR);
181 1.3.4.2 yamt INITMESSAGE(sp);
182 1.3.4.2 yamt rval = api_gline(sp, (db_recno_t)lno, &p, &len);
183 1.3.4.2 yamt ENDMESSAGE(sp);
184 1.3.4.2 yamt
185 1.3.4.2 yamt if (rval)
186 1.3.4.2 yamt return (TCL_ERROR);
187 1.3.4.2 yamt
188 1.3.4.2 yamt if ((line = malloc(len + 1)) == NULL)
189 1.3.4.2 yamt exit(1); /* XXX */
190 1.3.4.2 yamt memmove(line, p, len);
191 1.3.4.2 yamt line[len] = '\0';
192 1.3.4.2 yamt Tcl_SetResult(interp, line, TCL_DYNAMIC);
193 1.3.4.2 yamt return (TCL_OK);
194 1.3.4.2 yamt }
195 1.3.4.2 yamt
196 1.3.4.2 yamt /*
197 1.3.4.2 yamt * tcl_iline --
198 1.3.4.2 yamt * Insert the string text after the line in lineNumber.
199 1.3.4.2 yamt *
200 1.3.4.2 yamt * Tcl Command: viInsertLine
201 1.3.4.2 yamt * Usage: viInsertLine screenId lineNumber text
202 1.3.4.2 yamt */
203 1.3.4.2 yamt static int
204 1.3.4.2 yamt tcl_iline(clientData, interp, argc, argv)
205 1.3.4.2 yamt ClientData clientData;
206 1.3.4.2 yamt Tcl_Interp *interp;
207 1.3.4.2 yamt int argc;
208 1.3.4.2 yamt char **argv;
209 1.3.4.2 yamt {
210 1.3.4.2 yamt SCR *sp;
211 1.3.4.2 yamt void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
212 1.3.4.2 yamt int lno, rval;
213 1.3.4.2 yamt
214 1.3.4.2 yamt if (argc != 4) {
215 1.3.4.2 yamt Tcl_SetResult(interp,
216 1.3.4.2 yamt "Usage: viInsertLine screenId lineNumber text", TCL_STATIC);
217 1.3.4.2 yamt return (TCL_ERROR);
218 1.3.4.2 yamt }
219 1.3.4.2 yamt
220 1.3.4.2 yamt if (getscreenid(interp, &sp, argv[1], NULL) ||
221 1.3.4.2 yamt getint(interp, "line number", argv[2], &lno))
222 1.3.4.2 yamt return (TCL_ERROR);
223 1.3.4.2 yamt INITMESSAGE(sp);
224 1.3.4.2 yamt rval = api_iline(sp, (db_recno_t)lno, argv[3], strlen(argv[3]));
225 1.3.4.2 yamt ENDMESSAGE(sp);
226 1.3.4.2 yamt
227 1.3.4.2 yamt return (rval ? TCL_ERROR : TCL_OK);
228 1.3.4.2 yamt }
229 1.3.4.2 yamt
230 1.3.4.2 yamt /*
231 1.3.4.2 yamt * tcl_lline --
232 1.3.4.2 yamt * Return the last line in the screen.
233 1.3.4.2 yamt *
234 1.3.4.2 yamt * Tcl Command: viLastLine
235 1.3.4.2 yamt * Usage: viLastLine screenId
236 1.3.4.2 yamt */
237 1.3.4.2 yamt static int
238 1.3.4.2 yamt tcl_lline(clientData, interp, argc, argv)
239 1.3.4.2 yamt ClientData clientData;
240 1.3.4.2 yamt Tcl_Interp *interp;
241 1.3.4.2 yamt int argc;
242 1.3.4.2 yamt char **argv;
243 1.3.4.2 yamt {
244 1.3.4.2 yamt SCR *sp;
245 1.3.4.2 yamt db_recno_t last;
246 1.3.4.2 yamt void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
247 1.3.4.2 yamt int rval;
248 1.3.4.2 yamt
249 1.3.4.2 yamt if (argc != 2) {
250 1.3.4.2 yamt Tcl_SetResult(interp, "Usage: viLastLine screenId", TCL_STATIC);
251 1.3.4.2 yamt return (TCL_ERROR);
252 1.3.4.2 yamt }
253 1.3.4.2 yamt
254 1.3.4.2 yamt if (getscreenid(interp, &sp, argv[1], NULL))
255 1.3.4.2 yamt return (TCL_ERROR);
256 1.3.4.2 yamt INITMESSAGE(sp);
257 1.3.4.2 yamt rval = api_lline(sp, &last);
258 1.3.4.2 yamt ENDMESSAGE(sp);
259 1.3.4.2 yamt if (rval)
260 1.3.4.2 yamt return (TCL_ERROR);
261 1.3.4.2 yamt
262 1.3.4.2 yamt (void)sprintf(interp->result, "%lu", (unsigned long)last);
263 1.3.4.2 yamt return (TCL_OK);
264 1.3.4.2 yamt }
265 1.3.4.2 yamt
266 1.3.4.2 yamt /*
267 1.3.4.2 yamt * tcl_sline --
268 1.3.4.2 yamt * Set lineNumber to the text supplied.
269 1.3.4.2 yamt *
270 1.3.4.2 yamt * Tcl Command: viSetLine
271 1.3.4.2 yamt * Usage: viSetLine screenId lineNumber text
272 1.3.4.2 yamt */
273 1.3.4.2 yamt static int
274 1.3.4.2 yamt tcl_sline(clientData, interp, argc, argv)
275 1.3.4.2 yamt ClientData clientData;
276 1.3.4.2 yamt Tcl_Interp *interp;
277 1.3.4.2 yamt int argc;
278 1.3.4.2 yamt char **argv;
279 1.3.4.2 yamt {
280 1.3.4.2 yamt SCR *sp;
281 1.3.4.2 yamt void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
282 1.3.4.2 yamt int lno, rval;
283 1.3.4.2 yamt
284 1.3.4.2 yamt if (argc != 4) {
285 1.3.4.2 yamt Tcl_SetResult(interp,
286 1.3.4.2 yamt "Usage: viSetLine screenId lineNumber text", TCL_STATIC);
287 1.3.4.2 yamt return (TCL_ERROR);
288 1.3.4.2 yamt }
289 1.3.4.2 yamt
290 1.3.4.2 yamt if (getscreenid(interp, &sp, argv[1], NULL) ||
291 1.3.4.2 yamt getint(interp, "line number", argv[2], &lno))
292 1.3.4.2 yamt return (TCL_ERROR);
293 1.3.4.2 yamt INITMESSAGE(sp);
294 1.3.4.2 yamt rval = api_sline(sp, (db_recno_t)lno, argv[3], strlen(argv[3]));
295 1.3.4.2 yamt ENDMESSAGE(sp);
296 1.3.4.2 yamt
297 1.3.4.2 yamt return (rval ? TCL_ERROR : TCL_OK);
298 1.3.4.2 yamt }
299 1.3.4.2 yamt
300 1.3.4.2 yamt /*
301 1.3.4.2 yamt * tcl_getmark --
302 1.3.4.2 yamt * Return the mark's cursor position as a list with two elements.
303 1.3.4.2 yamt * {line, column}.
304 1.3.4.2 yamt *
305 1.3.4.2 yamt * Tcl Command: viGetMark
306 1.3.4.2 yamt * Usage: viGetMark screenId mark
307 1.3.4.2 yamt */
308 1.3.4.2 yamt static int
309 1.3.4.2 yamt tcl_getmark(clientData, interp, argc, argv)
310 1.3.4.2 yamt ClientData clientData;
311 1.3.4.2 yamt Tcl_Interp *interp;
312 1.3.4.2 yamt int argc;
313 1.3.4.2 yamt char **argv;
314 1.3.4.2 yamt {
315 1.3.4.2 yamt MARK cursor;
316 1.3.4.2 yamt SCR *sp;
317 1.3.4.2 yamt void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
318 1.3.4.2 yamt int rval;
319 1.3.4.2 yamt char buf[20];
320 1.3.4.2 yamt
321 1.3.4.2 yamt if (argc != 3) {
322 1.3.4.2 yamt Tcl_SetResult(interp,
323 1.3.4.2 yamt "Usage: viGetMark screenId mark", TCL_STATIC);
324 1.3.4.2 yamt return (TCL_ERROR);
325 1.3.4.2 yamt }
326 1.3.4.2 yamt
327 1.3.4.2 yamt if (getscreenid(interp, &sp, argv[1], NULL))
328 1.3.4.2 yamt return (TCL_ERROR);
329 1.3.4.2 yamt INITMESSAGE(sp);
330 1.3.4.2 yamt rval = api_getmark(sp, (int)argv[2][0], &cursor);
331 1.3.4.2 yamt ENDMESSAGE(sp);
332 1.3.4.2 yamt
333 1.3.4.2 yamt if (rval)
334 1.3.4.2 yamt return (TCL_ERROR);
335 1.3.4.2 yamt
336 1.3.4.2 yamt (void)snprintf(buf, sizeof(buf), "%lu", (u_long)cursor.lno);
337 1.3.4.2 yamt Tcl_AppendElement(interp, buf);
338 1.3.4.2 yamt (void)snprintf(buf, sizeof(buf), "%lu", (u_long)cursor.cno);
339 1.3.4.2 yamt Tcl_AppendElement(interp, buf);
340 1.3.4.2 yamt return (TCL_OK);
341 1.3.4.2 yamt }
342 1.3.4.2 yamt
343 1.3.4.2 yamt /*
344 1.3.4.2 yamt * tcl_setmark --
345 1.3.4.2 yamt * Set the mark to the line and column numbers supplied.
346 1.3.4.2 yamt *
347 1.3.4.2 yamt * Tcl Command: viSetMark
348 1.3.4.2 yamt * Usage: viSetMark screenId mark line column
349 1.3.4.2 yamt */
350 1.3.4.2 yamt static int
351 1.3.4.2 yamt tcl_setmark(clientData, interp, argc, argv)
352 1.3.4.2 yamt ClientData clientData;
353 1.3.4.2 yamt Tcl_Interp *interp;
354 1.3.4.2 yamt int argc;
355 1.3.4.2 yamt char **argv;
356 1.3.4.2 yamt {
357 1.3.4.2 yamt MARK cursor;
358 1.3.4.2 yamt SCR *sp;
359 1.3.4.2 yamt void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
360 1.3.4.2 yamt int i, rval;
361 1.3.4.2 yamt
362 1.3.4.2 yamt if (argc != 5) {
363 1.3.4.2 yamt Tcl_SetResult(interp,
364 1.3.4.2 yamt "Usage: viSetMark screenId mark line column", TCL_STATIC);
365 1.3.4.2 yamt return (TCL_ERROR);
366 1.3.4.2 yamt }
367 1.3.4.2 yamt
368 1.3.4.2 yamt if (getscreenid(interp, &sp, argv[1], NULL))
369 1.3.4.2 yamt return (TCL_ERROR);
370 1.3.4.2 yamt if (getint(interp, "line number", argv[3], &i))
371 1.3.4.2 yamt return (TCL_ERROR);
372 1.3.4.2 yamt cursor.lno = i;
373 1.3.4.2 yamt if (getint(interp, "column number", argv[4], &i))
374 1.3.4.2 yamt return (TCL_ERROR);
375 1.3.4.2 yamt cursor.cno = i;
376 1.3.4.2 yamt INITMESSAGE(sp);
377 1.3.4.2 yamt rval = api_setmark(sp, (int)argv[2][0], &cursor);
378 1.3.4.2 yamt ENDMESSAGE(sp);
379 1.3.4.2 yamt
380 1.3.4.2 yamt return (rval ? TCL_ERROR : TCL_OK);
381 1.3.4.2 yamt }
382 1.3.4.2 yamt
383 1.3.4.2 yamt /*
384 1.3.4.2 yamt * tcl_getcursor --
385 1.3.4.2 yamt * Return the current cursor position as a list with two elements.
386 1.3.4.2 yamt * {line, column}.
387 1.3.4.2 yamt *
388 1.3.4.2 yamt * Tcl Command: viGetCursor
389 1.3.4.2 yamt * Usage: viGetCursor screenId
390 1.3.4.2 yamt */
391 1.3.4.2 yamt static int
392 1.3.4.2 yamt tcl_getcursor(clientData, interp, argc, argv)
393 1.3.4.2 yamt ClientData clientData;
394 1.3.4.2 yamt Tcl_Interp *interp;
395 1.3.4.2 yamt int argc;
396 1.3.4.2 yamt char **argv;
397 1.3.4.2 yamt {
398 1.3.4.2 yamt MARK cursor;
399 1.3.4.2 yamt SCR *sp;
400 1.3.4.2 yamt void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
401 1.3.4.2 yamt int rval;
402 1.3.4.2 yamt char buf[20];
403 1.3.4.2 yamt
404 1.3.4.2 yamt if (argc != 2) {
405 1.3.4.2 yamt Tcl_SetResult(interp,
406 1.3.4.2 yamt "Usage: viGetCursor screenId", TCL_STATIC);
407 1.3.4.2 yamt return (TCL_ERROR);
408 1.3.4.2 yamt }
409 1.3.4.2 yamt
410 1.3.4.2 yamt if (getscreenid(interp, &sp, argv[1], NULL))
411 1.3.4.2 yamt return (TCL_ERROR);
412 1.3.4.2 yamt INITMESSAGE(sp);
413 1.3.4.2 yamt rval = api_getcursor(sp, &cursor);
414 1.3.4.2 yamt ENDMESSAGE(sp);
415 1.3.4.2 yamt
416 1.3.4.2 yamt if (rval)
417 1.3.4.2 yamt return (TCL_ERROR);
418 1.3.4.2 yamt
419 1.3.4.2 yamt (void)snprintf(buf, sizeof(buf), "%lu", (u_long)cursor.lno);
420 1.3.4.2 yamt Tcl_AppendElement(interp, buf);
421 1.3.4.2 yamt (void)snprintf(buf, sizeof(buf), "%lu", (u_long)cursor.cno);
422 1.3.4.2 yamt Tcl_AppendElement(interp, buf);
423 1.3.4.2 yamt return (TCL_OK);
424 1.3.4.2 yamt }
425 1.3.4.2 yamt
426 1.3.4.2 yamt /*
427 1.3.4.2 yamt * tcl_setcursor --
428 1.3.4.2 yamt * Set the cursor to the line and column numbers supplied.
429 1.3.4.2 yamt *
430 1.3.4.2 yamt * Tcl Command: viSetCursor
431 1.3.4.2 yamt * Usage: viSetCursor screenId line column
432 1.3.4.2 yamt */
433 1.3.4.2 yamt static int
434 1.3.4.2 yamt tcl_setcursor(clientData, interp, argc, argv)
435 1.3.4.2 yamt ClientData clientData;
436 1.3.4.2 yamt Tcl_Interp *interp;
437 1.3.4.2 yamt int argc;
438 1.3.4.2 yamt char **argv;
439 1.3.4.2 yamt {
440 1.3.4.2 yamt MARK cursor;
441 1.3.4.2 yamt SCR *sp;
442 1.3.4.2 yamt void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
443 1.3.4.2 yamt int i, rval;
444 1.3.4.2 yamt
445 1.3.4.2 yamt if (argc != 4) {
446 1.3.4.2 yamt Tcl_SetResult(interp,
447 1.3.4.2 yamt "Usage: viSetCursor screenId line column", TCL_STATIC);
448 1.3.4.2 yamt return (TCL_ERROR);
449 1.3.4.2 yamt }
450 1.3.4.2 yamt
451 1.3.4.2 yamt if (getscreenid(interp, &sp, argv[1], NULL))
452 1.3.4.2 yamt return (TCL_ERROR);
453 1.3.4.2 yamt if (getint(interp, "screen id", argv[2], &i))
454 1.3.4.2 yamt return (TCL_ERROR);
455 1.3.4.2 yamt cursor.lno = i;
456 1.3.4.2 yamt if (getint(interp, "screen id", argv[3], &i))
457 1.3.4.2 yamt return (TCL_ERROR);
458 1.3.4.2 yamt cursor.cno = i;
459 1.3.4.2 yamt INITMESSAGE(sp);
460 1.3.4.2 yamt rval = api_setcursor(sp, &cursor);
461 1.3.4.2 yamt ENDMESSAGE(sp);
462 1.3.4.2 yamt
463 1.3.4.2 yamt return (rval ? TCL_ERROR : TCL_OK);
464 1.3.4.2 yamt }
465 1.3.4.2 yamt
466 1.3.4.2 yamt /*
467 1.3.4.2 yamt * tcl_msg --
468 1.3.4.2 yamt * Set the message line to text.
469 1.3.4.2 yamt *
470 1.3.4.2 yamt * Tcl Command: viMsg
471 1.3.4.2 yamt * Usage: viMsg screenId text
472 1.3.4.2 yamt */
473 1.3.4.2 yamt static int
474 1.3.4.2 yamt tcl_msg(clientData, interp, argc, argv)
475 1.3.4.2 yamt ClientData clientData;
476 1.3.4.2 yamt Tcl_Interp *interp;
477 1.3.4.2 yamt int argc;
478 1.3.4.2 yamt char **argv;
479 1.3.4.2 yamt {
480 1.3.4.2 yamt SCR *sp;
481 1.3.4.2 yamt
482 1.3.4.2 yamt if (argc != 3) {
483 1.3.4.2 yamt Tcl_SetResult(interp, "Usage: viMsg screenId text", TCL_STATIC);
484 1.3.4.2 yamt return (TCL_ERROR);
485 1.3.4.2 yamt }
486 1.3.4.2 yamt
487 1.3.4.2 yamt if (getscreenid(interp, &sp, argv[1], NULL))
488 1.3.4.2 yamt return (TCL_ERROR);
489 1.3.4.2 yamt api_imessage(sp, argv[2]);
490 1.3.4.2 yamt
491 1.3.4.2 yamt return (TCL_OK);
492 1.3.4.2 yamt }
493 1.3.4.2 yamt
494 1.3.4.2 yamt /*
495 1.3.4.2 yamt * tcl_iscreen --
496 1.3.4.2 yamt * Create a new screen. If a filename is specified then the screen
497 1.3.4.2 yamt * is opened with that file.
498 1.3.4.2 yamt *
499 1.3.4.2 yamt * Tcl Command: viNewScreen
500 1.3.4.2 yamt * Usage: viNewScreen screenId [file]
501 1.3.4.2 yamt */
502 1.3.4.2 yamt static int
503 1.3.4.2 yamt tcl_iscreen(clientData, interp, argc, argv)
504 1.3.4.2 yamt ClientData clientData;
505 1.3.4.2 yamt Tcl_Interp *interp;
506 1.3.4.2 yamt int argc;
507 1.3.4.2 yamt char **argv;
508 1.3.4.2 yamt {
509 1.3.4.2 yamt SCR *sp, *nsp;
510 1.3.4.2 yamt void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
511 1.3.4.2 yamt int rval;
512 1.3.4.2 yamt
513 1.3.4.2 yamt if (argc != 2 && argc != 3) {
514 1.3.4.2 yamt Tcl_SetResult(interp,
515 1.3.4.2 yamt "Usage: viNewScreen screenId [file]", TCL_STATIC);
516 1.3.4.2 yamt return (TCL_ERROR);
517 1.3.4.2 yamt }
518 1.3.4.2 yamt
519 1.3.4.2 yamt if (getscreenid(interp, &sp, argv[1], NULL))
520 1.3.4.2 yamt return (TCL_ERROR);
521 1.3.4.2 yamt INITMESSAGE(sp);
522 1.3.4.2 yamt rval = api_edit(sp, argv[2], &nsp, 1);
523 1.3.4.2 yamt ENDMESSAGE(sp);
524 1.3.4.2 yamt
525 1.3.4.2 yamt if (rval)
526 1.3.4.2 yamt return (TCL_ERROR);
527 1.3.4.2 yamt
528 1.3.4.2 yamt (void)sprintf(interp->result, "%d", nsp->id);
529 1.3.4.2 yamt return (TCL_OK);
530 1.3.4.2 yamt }
531 1.3.4.2 yamt
532 1.3.4.2 yamt /*
533 1.3.4.2 yamt * tcl_escreen --
534 1.3.4.2 yamt * End a screen.
535 1.3.4.2 yamt *
536 1.3.4.2 yamt * Tcl Command: viEndScreen
537 1.3.4.2 yamt * Usage: viEndScreen screenId
538 1.3.4.2 yamt */
539 1.3.4.2 yamt static int
540 1.3.4.2 yamt tcl_escreen(clientData, interp, argc, argv)
541 1.3.4.2 yamt ClientData clientData;
542 1.3.4.2 yamt Tcl_Interp *interp;
543 1.3.4.2 yamt int argc;
544 1.3.4.2 yamt char **argv;
545 1.3.4.2 yamt {
546 1.3.4.2 yamt SCR *sp;
547 1.3.4.2 yamt void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
548 1.3.4.2 yamt int rval;
549 1.3.4.2 yamt
550 1.3.4.2 yamt if (argc != 2) {
551 1.3.4.2 yamt Tcl_SetResult(interp,
552 1.3.4.2 yamt "Usage: viEndScreen screenId", TCL_STATIC);
553 1.3.4.2 yamt return (TCL_ERROR);
554 1.3.4.2 yamt }
555 1.3.4.2 yamt
556 1.3.4.2 yamt if (getscreenid(interp, &sp, argv[1], NULL))
557 1.3.4.2 yamt return (TCL_ERROR);
558 1.3.4.2 yamt INITMESSAGE(sp);
559 1.3.4.2 yamt rval = api_escreen(sp);
560 1.3.4.2 yamt ENDMESSAGE(sp);
561 1.3.4.2 yamt
562 1.3.4.2 yamt return (rval ? TCL_ERROR : TCL_OK);
563 1.3.4.2 yamt }
564 1.3.4.2 yamt
565 1.3.4.2 yamt /*
566 1.3.4.2 yamt * tcl_swscreen --
567 1.3.4.2 yamt * Change the current focus to screen.
568 1.3.4.2 yamt *
569 1.3.4.2 yamt * Tcl Command: viSwitchScreen
570 1.3.4.2 yamt * Usage: viSwitchScreen screenId screenId
571 1.3.4.2 yamt */
572 1.3.4.2 yamt static int
573 1.3.4.2 yamt tcl_swscreen(clientData, interp, argc, argv)
574 1.3.4.2 yamt ClientData clientData;
575 1.3.4.2 yamt Tcl_Interp *interp;
576 1.3.4.2 yamt int argc;
577 1.3.4.2 yamt char **argv;
578 1.3.4.2 yamt {
579 1.3.4.2 yamt SCR *sp, *new;
580 1.3.4.2 yamt void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
581 1.3.4.2 yamt int rval;
582 1.3.4.2 yamt
583 1.3.4.2 yamt if (argc != 3) {
584 1.3.4.2 yamt Tcl_SetResult(interp,
585 1.3.4.2 yamt "Usage: viSwitchScreen cur_screenId new_screenId",
586 1.3.4.2 yamt TCL_STATIC);
587 1.3.4.2 yamt return (TCL_ERROR);
588 1.3.4.2 yamt }
589 1.3.4.2 yamt
590 1.3.4.2 yamt if (getscreenid(interp, &sp, argv[1], NULL))
591 1.3.4.2 yamt return (TCL_ERROR);
592 1.3.4.2 yamt if (getscreenid(interp, &new, argv[2], NULL))
593 1.3.4.2 yamt return (TCL_ERROR);
594 1.3.4.2 yamt INITMESSAGE(sp);
595 1.3.4.2 yamt rval = api_swscreen(sp, new);
596 1.3.4.2 yamt ENDMESSAGE(sp);
597 1.3.4.2 yamt
598 1.3.4.2 yamt return (rval ? TCL_ERROR : TCL_OK);
599 1.3.4.2 yamt }
600 1.3.4.2 yamt
601 1.3.4.2 yamt /*
602 1.3.4.2 yamt * tcl_map --
603 1.3.4.2 yamt * Associate a key with a tcl procedure.
604 1.3.4.2 yamt *
605 1.3.4.2 yamt * Tcl Command: viMapKey
606 1.3.4.2 yamt * Usage: viMapKey screenId key tclproc
607 1.3.4.2 yamt */
608 1.3.4.2 yamt static int
609 1.3.4.2 yamt tcl_map(clientData, interp, argc, argv)
610 1.3.4.2 yamt ClientData clientData;
611 1.3.4.2 yamt Tcl_Interp *interp;
612 1.3.4.2 yamt int argc;
613 1.3.4.2 yamt char **argv;
614 1.3.4.2 yamt {
615 1.3.4.2 yamt SCR *sp;
616 1.3.4.2 yamt void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
617 1.3.4.2 yamt int rval;
618 1.3.4.2 yamt char command[256];
619 1.3.4.2 yamt
620 1.3.4.2 yamt if (argc != 4) {
621 1.3.4.2 yamt Tcl_SetResult(interp,
622 1.3.4.2 yamt "Usage: viMapKey screenId key tclproc", TCL_STATIC);
623 1.3.4.2 yamt return (TCL_ERROR);
624 1.3.4.2 yamt }
625 1.3.4.2 yamt
626 1.3.4.2 yamt if (getscreenid(interp, &sp, argv[1], NULL))
627 1.3.4.2 yamt return (TCL_ERROR);
628 1.3.4.2 yamt INITMESSAGE(sp);
629 1.3.4.2 yamt (void)snprintf(command, sizeof(command), ":tcl %s\n", argv[3]);
630 1.3.4.2 yamt rval = api_map(sp, argv[2], command, strlen(command));
631 1.3.4.2 yamt ENDMESSAGE(sp);
632 1.3.4.2 yamt
633 1.3.4.2 yamt return (rval ? TCL_ERROR : TCL_OK);
634 1.3.4.2 yamt }
635 1.3.4.2 yamt
636 1.3.4.2 yamt /*
637 1.3.4.2 yamt * tcl_unmap --
638 1.3.4.2 yamt * Unmap a key.
639 1.3.4.2 yamt *
640 1.3.4.2 yamt * Tcl Command: viUnmapKey
641 1.3.4.2 yamt * Usage: viUnmMapKey screenId key
642 1.3.4.2 yamt */
643 1.3.4.2 yamt static int
644 1.3.4.2 yamt tcl_unmap(clientData, interp, argc, argv)
645 1.3.4.2 yamt ClientData clientData;
646 1.3.4.2 yamt Tcl_Interp *interp;
647 1.3.4.2 yamt int argc;
648 1.3.4.2 yamt char **argv;
649 1.3.4.2 yamt {
650 1.3.4.2 yamt SCR *sp;
651 1.3.4.2 yamt void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
652 1.3.4.2 yamt int rval;
653 1.3.4.2 yamt
654 1.3.4.2 yamt if (argc != 3) {
655 1.3.4.2 yamt Tcl_SetResult(interp,
656 1.3.4.2 yamt "Usage: viUnmapKey screenId key", TCL_STATIC);
657 1.3.4.2 yamt return (TCL_ERROR);
658 1.3.4.2 yamt }
659 1.3.4.2 yamt
660 1.3.4.2 yamt if (getscreenid(interp, &sp, argv[1], NULL))
661 1.3.4.2 yamt return (TCL_ERROR);
662 1.3.4.2 yamt INITMESSAGE(sp);
663 1.3.4.2 yamt rval = api_unmap(sp, argv[2]);
664 1.3.4.2 yamt ENDMESSAGE(sp);
665 1.3.4.2 yamt
666 1.3.4.2 yamt return (rval ? TCL_ERROR : TCL_OK);
667 1.3.4.2 yamt }
668 1.3.4.2 yamt
669 1.3.4.2 yamt /*
670 1.3.4.2 yamt * tcl_opts_set --
671 1.3.4.2 yamt * Set an option.
672 1.3.4.2 yamt *
673 1.3.4.2 yamt * Tcl Command: viSetOpt
674 1.3.4.2 yamt * Usage: viSetOpt screenId command
675 1.3.4.2 yamt */
676 1.3.4.2 yamt static int
677 1.3.4.2 yamt tcl_opts_set(clientData, interp, argc, argv)
678 1.3.4.2 yamt ClientData clientData;
679 1.3.4.2 yamt Tcl_Interp *interp;
680 1.3.4.2 yamt int argc;
681 1.3.4.2 yamt char **argv;
682 1.3.4.2 yamt {
683 1.3.4.2 yamt SCR *sp;
684 1.3.4.2 yamt void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
685 1.3.4.2 yamt int rval;
686 1.3.4.2 yamt char *setting;
687 1.3.4.2 yamt
688 1.3.4.2 yamt if (argc != 3) {
689 1.3.4.2 yamt Tcl_SetResult(interp,
690 1.3.4.2 yamt "Usage: viSetOpt screenId command", TCL_STATIC);
691 1.3.4.2 yamt return (TCL_ERROR);
692 1.3.4.2 yamt }
693 1.3.4.2 yamt
694 1.3.4.2 yamt if (getscreenid(interp, &sp, argv[1], NULL))
695 1.3.4.2 yamt return (TCL_ERROR);
696 1.3.4.2 yamt INITMESSAGE(sp);
697 1.3.4.2 yamt /*rval = api_opts_set(sp, argv[2]);*/
698 1.3.4.2 yamt MALLOC(sp, setting, char *, strlen(argv[2])+6);
699 1.3.4.2 yamt strcpy(setting, ":set ");
700 1.3.4.2 yamt strcpy(setting+5, argv[2]);
701 1.3.4.2 yamt rval=api_run_str(sp, setting);
702 1.3.4.2 yamt free(setting);
703 1.3.4.2 yamt ENDMESSAGE(sp);
704 1.3.4.2 yamt
705 1.3.4.2 yamt return (rval ? TCL_ERROR : TCL_OK);
706 1.3.4.2 yamt }
707 1.3.4.2 yamt
708 1.3.4.2 yamt /*
709 1.3.4.2 yamt * tcl_opts_get --
710 1.3.4.2 yamt Return the value of an option.
711 1.3.4.2 yamt *
712 1.3.4.2 yamt * Tcl Command: viGetOpt
713 1.3.4.2 yamt * Usage: viGetOpt screenId option
714 1.3.4.2 yamt */
715 1.3.4.2 yamt static int
716 1.3.4.2 yamt tcl_opts_get(clientData, interp, argc, argv)
717 1.3.4.2 yamt ClientData clientData;
718 1.3.4.2 yamt Tcl_Interp *interp;
719 1.3.4.2 yamt int argc;
720 1.3.4.2 yamt char **argv;
721 1.3.4.2 yamt {
722 1.3.4.2 yamt SCR *sp;
723 1.3.4.2 yamt void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
724 1.3.4.2 yamt int rval;
725 1.3.4.2 yamt char *value;
726 1.3.4.2 yamt
727 1.3.4.2 yamt if (argc != 3) {
728 1.3.4.2 yamt Tcl_SetResult(interp,
729 1.3.4.2 yamt "Usage: viGetOpt screenId option", TCL_STATIC);
730 1.3.4.2 yamt return (TCL_ERROR);
731 1.3.4.2 yamt }
732 1.3.4.2 yamt
733 1.3.4.2 yamt if (getscreenid(interp, &sp, argv[1], NULL))
734 1.3.4.2 yamt return (TCL_ERROR);
735 1.3.4.2 yamt INITMESSAGE(sp);
736 1.3.4.2 yamt rval = api_opts_get(sp, argv[2], &value, NULL);
737 1.3.4.2 yamt ENDMESSAGE(sp);
738 1.3.4.2 yamt if (rval)
739 1.3.4.2 yamt return (TCL_ERROR);
740 1.3.4.2 yamt
741 1.3.4.2 yamt Tcl_SetResult(interp, value, TCL_DYNAMIC);
742 1.3.4.2 yamt return (TCL_OK);
743 1.3.4.2 yamt }
744 1.3.4.2 yamt
745 1.3.4.2 yamt /*
746 1.3.4.2 yamt * tcl_init --
747 1.3.4.2 yamt * Create the TCL commands used by nvi.
748 1.3.4.2 yamt *
749 1.3.4.2 yamt * PUBLIC: int tcl_init __P((GS *));
750 1.3.4.2 yamt */
751 1.3.4.2 yamt int
752 1.3.4.2 yamt tcl_init(gp)
753 1.3.4.2 yamt GS *gp;
754 1.3.4.2 yamt {
755 1.3.4.2 yamt gp->tcl_interp = Tcl_CreateInterp();
756 1.3.4.2 yamt if (Tcl_Init(gp->tcl_interp) == TCL_ERROR)
757 1.3.4.2 yamt return (1);
758 1.3.4.2 yamt
759 1.3.4.2 yamt #define TCC(name, function) { \
760 1.3.4.2 yamt Tcl_CreateCommand(gp->tcl_interp, name, function, \
761 1.3.4.2 yamt (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); \
762 1.3.4.2 yamt }
763 1.3.4.2 yamt TCC("viAppendLine", tcl_aline);
764 1.3.4.2 yamt TCC("viDelLine", tcl_dline);
765 1.3.4.2 yamt TCC("viEndScreen", tcl_escreen);
766 1.3.4.2 yamt TCC("viFindScreen", tcl_fscreen);
767 1.3.4.2 yamt TCC("viGetCursor", tcl_getcursor);
768 1.3.4.2 yamt TCC("viGetLine", tcl_gline);
769 1.3.4.2 yamt TCC("viGetMark", tcl_getmark);
770 1.3.4.2 yamt TCC("viGetOpt", tcl_opts_get);
771 1.3.4.2 yamt TCC("viInsertLine", tcl_iline);
772 1.3.4.2 yamt TCC("viLastLine", tcl_lline);
773 1.3.4.2 yamt TCC("viMapKey", tcl_map);
774 1.3.4.2 yamt TCC("viMsg", tcl_msg);
775 1.3.4.2 yamt TCC("viNewScreen", tcl_iscreen);
776 1.3.4.2 yamt TCC("viSetCursor", tcl_setcursor);
777 1.3.4.2 yamt TCC("viSetLine", tcl_sline);
778 1.3.4.2 yamt TCC("viSetMark", tcl_setmark);
779 1.3.4.2 yamt TCC("viSetOpt", tcl_opts_set);
780 1.3.4.2 yamt TCC("viSwitchScreen", tcl_swscreen);
781 1.3.4.2 yamt TCC("viUnmapKey", tcl_unmap);
782 1.3.4.2 yamt
783 1.3.4.2 yamt return (0);
784 1.3.4.2 yamt }
785 1.3.4.2 yamt
786 1.3.4.2 yamt /*
787 1.3.4.2 yamt * getscreenid --
788 1.3.4.2 yamt * Get the specified screen pointer.
789 1.3.4.2 yamt *
790 1.3.4.2 yamt * XXX
791 1.3.4.2 yamt * This is fatal. We can't post a message into vi that we're unable to find
792 1.3.4.2 yamt * the screen without first finding the screen... So, this must be the first
793 1.3.4.2 yamt * thing a Tcl routine does, and, if it fails, the last as well.
794 1.3.4.2 yamt */
795 1.3.4.2 yamt static int
796 1.3.4.2 yamt getscreenid(interp, spp, id, name)
797 1.3.4.2 yamt Tcl_Interp *interp;
798 1.3.4.2 yamt SCR **spp;
799 1.3.4.2 yamt char *id, *name;
800 1.3.4.2 yamt {
801 1.3.4.2 yamt int scr_no;
802 1.3.4.2 yamt char buf[64];
803 1.3.4.2 yamt
804 1.3.4.2 yamt if (id != NULL && getint(interp, "screen id", id, &scr_no))
805 1.3.4.2 yamt return (1);
806 1.3.4.2 yamt if ((*spp = api_fscreen(scr_no, name)) == NULL) {
807 1.3.4.2 yamt (void)snprintf(buf, sizeof(buf),
808 1.3.4.2 yamt "unknown screen id: %s", name == NULL ? id : name);
809 1.3.4.2 yamt Tcl_SetResult(interp, buf, TCL_VOLATILE);
810 1.3.4.2 yamt return (1);
811 1.3.4.2 yamt }
812 1.3.4.2 yamt return (0);
813 1.3.4.2 yamt }
814 1.3.4.2 yamt
815 1.3.4.2 yamt /*
816 1.3.4.2 yamt * getint --
817 1.3.4.2 yamt * Get a Tcl integer.
818 1.3.4.2 yamt *
819 1.3.4.2 yamt * XXX
820 1.3.4.2 yamt * This code assumes that both db_recno_t and size_t are larger than ints.
821 1.3.4.2 yamt */
822 1.3.4.2 yamt static int
823 1.3.4.2 yamt getint(interp, msg, s, intp)
824 1.3.4.2 yamt Tcl_Interp *interp;
825 1.3.4.2 yamt char *msg, *s;
826 1.3.4.2 yamt int *intp;
827 1.3.4.2 yamt {
828 1.3.4.2 yamt char buf[64];
829 1.3.4.2 yamt
830 1.3.4.2 yamt if (Tcl_GetInt(interp, s, intp) == TCL_ERROR)
831 1.3.4.2 yamt return (1);
832 1.3.4.2 yamt if (*intp < 0) {
833 1.3.4.2 yamt (void)snprintf(buf, sizeof(buf),
834 1.3.4.2 yamt "illegal %s %s: may not be negative", msg, s);
835 1.3.4.2 yamt Tcl_SetResult(interp, buf, TCL_VOLATILE);
836 1.3.4.2 yamt return (1);
837 1.3.4.2 yamt }
838 1.3.4.2 yamt return (0);
839 1.3.4.2 yamt }
840 1.3.4.2 yamt
841 1.3.4.2 yamt /*
842 1.3.4.2 yamt * msghandler --
843 1.3.4.2 yamt * Tcl message routine so that error messages are processed in
844 1.3.4.2 yamt * Tcl, not in nvi.
845 1.3.4.2 yamt */
846 1.3.4.2 yamt static void
847 1.3.4.2 yamt msghandler(sp, mtype, msg, len)
848 1.3.4.2 yamt SCR *sp;
849 1.3.4.2 yamt mtype_t mtype;
850 1.3.4.2 yamt char *msg;
851 1.3.4.2 yamt size_t len;
852 1.3.4.2 yamt {
853 1.3.4.2 yamt /* Replace the trailing <newline> with an EOS. */
854 1.3.4.2 yamt msg[len - 1] = '\0';
855 1.3.4.2 yamt
856 1.3.4.2 yamt Tcl_SetResult(sp->gp->tcl_interp, msg, TCL_VOLATILE);
857 1.3.4.2 yamt }
858