MFC: An off-by-one malloc size was corrupting the installer's memory,
[dragonfly.git] / contrib / nvi / tk / tk_util.c
blob096fa7bb3eba24af51b4c07346143e4028d0b0c2
1 /*-
2 * Copyright (c) 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1993, 1994, 1995, 1996
5 * Keith Bostic. All rights reserved.
7 * See the LICENSE file for redistribution information.
8 */
10 #include "config.h"
12 #ifndef lint
13 static const char sccsid[] = "@(#)tk_util.c 8.14 (Berkeley) 7/19/96";
14 #endif /* not lint */
16 #include <sys/types.h>
17 #include <sys/queue.h>
19 #include <bitstring.h>
20 #include <errno.h>
21 #include <limits.h>
22 #include <signal.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <termios.h>
27 #include <unistd.h>
29 #include "../common/common.h"
30 #include "tki.h"
32 static int tk_op_push __P((SCR *, TK_PRIVATE *, e_event_t));
35 * tk_op --
36 * Events provided directly from Tcl/Tk.
38 * PUBLIC: int tk_op __P((ClientData, Tcl_Interp *, int, char *[]));
40 int
41 tk_op(clientData, interp, argc, argv)
42 ClientData clientData;
43 Tcl_Interp *interp;
44 int argc;
45 char *argv[];
47 SCR *sp;
48 TK_PRIVATE *tkp;
50 sp = __global_list->dq.cqh_first; /* XXX */
51 tkp = (TK_PRIVATE *)clientData;
53 switch (argv[1][0]) {
54 case 'q':
55 if (!strcmp(argv[1], "quit"))
56 return (tk_op_push(sp, tkp, E_QUIT));
57 break;
58 case 'w':
59 if (!strcmp(argv[1], "write"))
60 return (tk_op_push(sp, tkp, E_WRITE));
61 if (!strcmp(argv[1], "writequit")) {
62 if (tk_op_push(sp, tkp, E_WRITE) != TCL_OK)
63 return (TCL_ERROR);
64 if (tk_op_push(sp, tkp, E_QUIT) != TCL_OK)
65 return (TCL_ERROR);
66 return (TCL_OK);
68 break;
70 (void)Tcl_VarEval(tkp->interp,
71 "tk_err {", argv[1], ": unknown event", "}", NULL);
72 return (TCL_OK);
76 * tk_op_push --
77 * Push an event.
79 static int
80 tk_op_push(sp, tkp, et)
81 SCR *sp;
82 TK_PRIVATE *tkp;
83 e_event_t et;
85 EVENT *evp;
87 CALLOC(sp, evp, EVENT *, 1, sizeof(EVENT));
88 if (evp == NULL)
89 return (TCL_ERROR);
91 evp->e_event = et;
92 TAILQ_INSERT_TAIL(&tkp->evq, evp, q);
93 return (TCL_OK);
97 * tk_opt_init --
98 * Initialize the values of the current options.
100 * PUBLIC: int tk_opt_init __P((ClientData, Tcl_Interp *, int, char *[]));
103 tk_opt_init(clientData, interp, argc, argv)
104 ClientData clientData;
105 Tcl_Interp *interp;
106 int argc;
107 char *argv[];
109 OPTLIST const *op;
110 SCR *sp;
111 TK_PRIVATE *tkp;
112 int off;
113 char buf[20];
115 sp = __global_list->dq.cqh_first; /* XXX */
117 tkp = (TK_PRIVATE *)clientData;
118 for (op = optlist, off = 0; op->name != NULL; ++op, ++off) {
119 if (F_ISSET(op, OPT_NDISP))
120 continue;
121 switch (op->type) {
122 case OPT_0BOOL:
123 case OPT_1BOOL:
124 (void)Tcl_VarEval(tkp->interp, "set tko_",
125 op->name, O_ISSET(sp, off) ? " 1" : " 0", NULL);
126 break;
127 case OPT_NUM:
128 (void)snprintf(buf,
129 sizeof(buf), " %lu", O_VAL(sp, off));
130 (void)Tcl_VarEval(tkp->interp,
131 "set tko_", op->name, buf, NULL);
132 break;
133 case OPT_STR:
134 (void)Tcl_VarEval(tkp->interp,
135 "set tko_", op->name, " {",
136 O_STR(sp, off) == NULL ? "" : O_STR(sp, off),
137 "}", NULL);
138 break;
141 return (TCL_OK);
145 * tk_opt_set --
146 * Set an options button.
148 * PUBLIC: int tk_opt_set __P((ClientData, Tcl_Interp *, int, char *[]));
151 tk_opt_set(clientData, interp, argc, argv)
152 ClientData clientData;
153 Tcl_Interp *interp;
154 int argc;
155 char *argv[];
157 ARGS *ap[2], a, b;
158 GS *gp;
159 SCR *sp;
160 int rval;
161 void (*msg) __P((SCR *, mtype_t, char *, size_t));
162 char buf[64];
164 gp = __global_list;
165 sp = gp->dq.cqh_first; /* XXX */
167 switch (argc) {
168 case 2:
169 a.bp = argv[1] + (sizeof("tko_") - 1);
170 a.len = strlen(a.bp);
171 break;
172 case 3:
173 a.bp = buf;
174 a.len = snprintf(buf, sizeof(buf),
175 "%s%s", atoi(argv[2]) ? "no" : "", argv[1]);
176 break;
177 default:
178 abort();
180 b.bp = NULL;
181 b.len = 0;
182 ap[0] = &a;
183 ap[1] = &b;
185 /* Use Tcl/Tk for error messages. */
186 msg = gp->scr_msg;
187 gp->scr_msg = tk_msg;
189 rval = opts_set(sp, ap, NULL);
191 gp->scr_msg = msg;
192 return (rval ? TCL_ERROR : TCL_OK);
196 * tk_version --
197 * Display the version in Tcl/Tk.
199 * PUBLIC: int tk_version __P((ClientData, Tcl_Interp *, int, char *[]));
202 tk_version(clientData, interp, argc, argv)
203 ClientData clientData;
204 Tcl_Interp *interp;
205 int argc;
206 char *argv[];
208 EXCMD cmd;
209 GS *gp;
210 SCR *sp;
211 int rval;
212 void (*msg) __P((SCR *, mtype_t, char *, size_t));
214 gp = __global_list;
215 sp = gp->dq.cqh_first; /* XXX */
217 msg = gp->scr_msg;
218 gp->scr_msg = tk_msg;
220 ex_cinit(&cmd, C_VERSION, 0, OOBLNO, OOBLNO, 0, NULL);
221 rval = cmd.cmd->fn(sp, &cmd);
222 (void)ex_fflush(sp);
224 gp->scr_msg = msg;
225 return (rval ? TCL_ERROR : TCL_OK);
229 * tk_msg --
230 * Display an error message in Tcl/Tk.
232 * PUBLIC: void tk_msg __P((SCR *, mtype_t, char *, size_t));
234 void
235 tk_msg(sp, mtype, line, rlen)
236 SCR *sp;
237 mtype_t mtype;
238 char *line;
239 size_t rlen;
241 TK_PRIVATE *tkp;
242 char buf[2048];
244 if (line == NULL)
245 return;
247 tkp = TKP(sp);
248 (void)snprintf(buf, sizeof(buf), "%.*s", (int)rlen, line);
249 (void)Tcl_VarEval(tkp->interp, "tk_err {", buf, "}", NULL);