summaryrefslogtreecommitdiffstats
path: root/contrib/nvi/tcl_api/tcl.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/nvi/tcl_api/tcl.c')
-rw-r--r--contrib/nvi/tcl_api/tcl.c852
1 files changed, 852 insertions, 0 deletions
diff --git a/contrib/nvi/tcl_api/tcl.c b/contrib/nvi/tcl_api/tcl.c
new file mode 100644
index 0000000..8f4a430
--- /dev/null
+++ b/contrib/nvi/tcl_api/tcl.c
@@ -0,0 +1,852 @@
+/*-
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1992, 1993, 1994, 1995
+ * Keith Bostic. All rights reserved.
+ * Copyright (c) 1995
+ * George V. Neville-Neil. All rights reserved.
+ *
+ * See the LICENSE file for redistribution information.
+ */
+
+#include "config.h"
+
+#ifndef lint
+static const char sccsid[] = "@(#)tcl.c 8.16 (Berkeley) 10/16/96";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/time.h>
+
+#include <bitstring.h>
+#include <errno.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tcl.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "../common/common.h"
+#include "tcl_extern.h"
+
+static int getint __P((Tcl_Interp *, char *, char *, int *));
+static int getscreenid __P((Tcl_Interp *, SCR **, char *, char *));
+static void msghandler __P((SCR *, mtype_t, char *, size_t));
+
+extern GS *__global_list; /* XXX */
+
+/*
+ * INITMESSAGE --
+ * Macros to point messages at the Tcl message handler.
+ */
+#define INITMESSAGE \
+ scr_msg = __global_list->scr_msg; \
+ __global_list->scr_msg = msghandler;
+#define ENDMESSAGE \
+ __global_list->scr_msg = scr_msg;
+
+/*
+ * tcl_fscreen --
+ * Return the screen id associated with file name.
+ *
+ * Tcl Command: viFindScreen
+ * Usage: viFindScreen file
+ */
+static int
+tcl_fscreen(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char **argv;
+{
+ SCR *sp;
+
+ if (argc != 2) {
+ Tcl_SetResult(interp, "Usage: viFindScreen file", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+
+ if (getscreenid(interp, &sp, NULL, argv[1]))
+ return (TCL_ERROR);
+
+ (void)sprintf(interp->result, "%d", sp->id);
+ return (TCL_OK);
+}
+
+/*
+ * tcl_aline --
+ * -- Append the string text after the line in lineNumber.
+ *
+ * Tcl Command: viAppendLine
+ * Usage: viAppendLine screenId lineNumber text
+ */
+static int
+tcl_aline(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char **argv;
+{
+ SCR *sp;
+ void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
+ int lno, rval;
+
+ if (argc != 4) {
+ Tcl_SetResult(interp,
+ "Usage: viAppendLine screenId lineNumber text", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+
+ if (getscreenid(interp, &sp, argv[1], NULL) ||
+ getint(interp, "line number", argv[2], &lno))
+ return (TCL_ERROR);
+ INITMESSAGE;
+ rval = api_aline(sp, (recno_t)lno, argv[3], strlen(argv[3]));
+ ENDMESSAGE;
+
+ return (rval ? TCL_ERROR : TCL_OK);
+}
+
+/*
+ * tcl_dline --
+ * Delete lineNum.
+ *
+ * Tcl Command: viDelLine
+ * Usage: viDelLine screenId lineNum
+ */
+static int
+tcl_dline(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char **argv;
+{
+ SCR *sp;
+ void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
+ int lno, rval;
+
+ if (argc != 3) {
+ Tcl_SetResult(interp,
+ "Usage: viDelLine screenId lineNumber", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+
+ if (getscreenid(interp, &sp, argv[1], NULL) ||
+ getint(interp, "line number", argv[2], &lno))
+ return (TCL_ERROR);
+ INITMESSAGE;
+ rval = api_dline(sp, (recno_t)lno);
+ ENDMESSAGE;
+
+ return (rval ? TCL_ERROR : TCL_OK);
+}
+
+/*
+ * tcl_gline --
+ * Return lineNumber.
+ *
+ * Tcl Command: viGetLine
+ * Usage: viGetLine screenId lineNumber
+ */
+static int
+tcl_gline(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char **argv;
+{
+ SCR *sp;
+ size_t len;
+ void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
+ int lno, rval;
+ char *line, *p;
+
+ if (argc != 3) {
+ Tcl_SetResult(interp,
+ "Usage: viGetLine screenId lineNumber", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+ if (getscreenid(interp, &sp, argv[1], NULL) ||
+ getint(interp, "line number", argv[2], &lno))
+ return (TCL_ERROR);
+ INITMESSAGE;
+ rval = api_gline(sp, (recno_t)lno, &p, &len);
+ ENDMESSAGE;
+
+ if (rval)
+ return (TCL_ERROR);
+
+ if ((line = malloc(len + 1)) == NULL)
+ exit(1); /* XXX */
+ memmove(line, p, len);
+ line[len] = '\0';
+ Tcl_SetResult(interp, line, TCL_DYNAMIC);
+ return (TCL_OK);
+}
+
+/*
+ * tcl_iline --
+ * Insert the string text after the line in lineNumber.
+ *
+ * Tcl Command: viInsertLine
+ * Usage: viInsertLine screenId lineNumber text
+ */
+static int
+tcl_iline(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char **argv;
+{
+ SCR *sp;
+ void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
+ int lno, rval;
+
+ if (argc != 4) {
+ Tcl_SetResult(interp,
+ "Usage: viInsertLine screenId lineNumber text", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+
+ if (getscreenid(interp, &sp, argv[1], NULL) ||
+ getint(interp, "line number", argv[2], &lno))
+ return (TCL_ERROR);
+ INITMESSAGE;
+ rval = api_iline(sp, (recno_t)lno, argv[3], strlen(argv[3]));
+ ENDMESSAGE;
+
+ return (rval ? TCL_ERROR : TCL_OK);
+}
+
+/*
+ * tcl_lline --
+ * Return the last line in the screen.
+ *
+ * Tcl Command: viLastLine
+ * Usage: viLastLine screenId
+ */
+static int
+tcl_lline(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char **argv;
+{
+ SCR *sp;
+ recno_t last;
+ void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
+ int rval;
+
+ if (argc != 2) {
+ Tcl_SetResult(interp, "Usage: viLastLine screenId", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+
+ if (getscreenid(interp, &sp, argv[1], NULL))
+ return (TCL_ERROR);
+ INITMESSAGE;
+ rval = api_lline(sp, &last);
+ ENDMESSAGE;
+ if (rval)
+ return (TCL_ERROR);
+
+ (void)sprintf(interp->result, "%lu", (unsigned long)last);
+ return (TCL_OK);
+}
+
+/*
+ * tcl_sline --
+ * Set lineNumber to the text supplied.
+ *
+ * Tcl Command: viSetLine
+ * Usage: viSetLine screenId lineNumber text
+ */
+static int
+tcl_sline(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char **argv;
+{
+ SCR *sp;
+ void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
+ int lno, rval;
+
+ if (argc != 4) {
+ Tcl_SetResult(interp,
+ "Usage: viSetLine screenId lineNumber text", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+
+ if (getscreenid(interp, &sp, argv[1], NULL) ||
+ getint(interp, "line number", argv[2], &lno))
+ return (TCL_ERROR);
+ INITMESSAGE;
+ rval = api_sline(sp, (recno_t)lno, argv[3], strlen(argv[3]));
+ ENDMESSAGE;
+
+ return (rval ? TCL_ERROR : TCL_OK);
+}
+
+/*
+ * tcl_getmark --
+ * Return the mark's cursor position as a list with two elements.
+ * {line, column}.
+ *
+ * Tcl Command: viGetMark
+ * Usage: viGetMark screenId mark
+ */
+static int
+tcl_getmark(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char **argv;
+{
+ MARK cursor;
+ SCR *sp;
+ void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
+ int rval;
+ char buf[20];
+
+ if (argc != 3) {
+ Tcl_SetResult(interp,
+ "Usage: viGetMark screenId mark", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+
+ if (getscreenid(interp, &sp, argv[1], NULL))
+ return (TCL_ERROR);
+ INITMESSAGE;
+ rval = api_getmark(sp, (int)argv[2][0], &cursor);
+ ENDMESSAGE;
+
+ if (rval)
+ return (TCL_ERROR);
+
+ (void)snprintf(buf, sizeof(buf), "%lu", (u_long)cursor.lno);
+ Tcl_AppendElement(interp, buf);
+ (void)snprintf(buf, sizeof(buf), "%lu", (u_long)cursor.cno);
+ Tcl_AppendElement(interp, buf);
+ return (TCL_OK);
+}
+
+/*
+ * tcl_setmark --
+ * Set the mark to the line and column numbers supplied.
+ *
+ * Tcl Command: viSetMark
+ * Usage: viSetMark screenId mark line column
+ */
+static int
+tcl_setmark(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char **argv;
+{
+ MARK cursor;
+ SCR *sp;
+ void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
+ int i, rval;
+
+ if (argc != 5) {
+ Tcl_SetResult(interp,
+ "Usage: viSetMark screenId mark line column", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+
+ if (getscreenid(interp, &sp, argv[1], NULL))
+ return (TCL_ERROR);
+ if (getint(interp, "line number", argv[3], &i))
+ return (TCL_ERROR);
+ cursor.lno = i;
+ if (getint(interp, "column number", argv[4], &i))
+ return (TCL_ERROR);
+ cursor.cno = i;
+ INITMESSAGE;
+ rval = api_setmark(sp, (int)argv[2][0], &cursor);
+ ENDMESSAGE;
+
+ return (rval ? TCL_ERROR : TCL_OK);
+}
+
+/*
+ * tcl_getcursor --
+ * Return the current cursor position as a list with two elements.
+ * {line, column}.
+ *
+ * Tcl Command: viGetCursor
+ * Usage: viGetCursor screenId
+ */
+static int
+tcl_getcursor(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char **argv;
+{
+ MARK cursor;
+ SCR *sp;
+ void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
+ int rval;
+ char buf[20];
+
+ if (argc != 2) {
+ Tcl_SetResult(interp,
+ "Usage: viGetCursor screenId", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+
+ if (getscreenid(interp, &sp, argv[1], NULL))
+ return (TCL_ERROR);
+ INITMESSAGE;
+ rval = api_getcursor(sp, &cursor);
+ ENDMESSAGE;
+
+ if (rval)
+ return (TCL_ERROR);
+
+ (void)snprintf(buf, sizeof(buf), "%lu", (u_long)cursor.lno);
+ Tcl_AppendElement(interp, buf);
+ (void)snprintf(buf, sizeof(buf), "%lu", (u_long)cursor.cno);
+ Tcl_AppendElement(interp, buf);
+ return (TCL_OK);
+}
+
+/*
+ * tcl_setcursor --
+ * Set the cursor to the line and column numbers supplied.
+ *
+ * Tcl Command: viSetCursor
+ * Usage: viSetCursor screenId line column
+ */
+static int
+tcl_setcursor(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char **argv;
+{
+ MARK cursor;
+ SCR *sp;
+ void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
+ int i, rval;
+
+ if (argc != 4) {
+ Tcl_SetResult(interp,
+ "Usage: viSetCursor screenId line column", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+
+ if (getscreenid(interp, &sp, argv[1], NULL))
+ return (TCL_ERROR);
+ if (getint(interp, "screen id", argv[2], &i))
+ return (TCL_ERROR);
+ cursor.lno = i;
+ if (getint(interp, "screen id", argv[3], &i))
+ return (TCL_ERROR);
+ cursor.cno = i;
+ INITMESSAGE;
+ rval = api_setcursor(sp, &cursor);
+ ENDMESSAGE;
+
+ return (rval ? TCL_ERROR : TCL_OK);
+}
+
+/*
+ * tcl_msg --
+ * Set the message line to text.
+ *
+ * Tcl Command: viMsg
+ * Usage: viMsg screenId text
+ */
+static int
+tcl_msg(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char **argv;
+{
+ SCR *sp;
+
+ if (argc != 3) {
+ Tcl_SetResult(interp, "Usage: viMsg screenId text", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+
+ if (getscreenid(interp, &sp, argv[1], NULL))
+ return (TCL_ERROR);
+ api_imessage(sp, argv[2]);
+
+ return (TCL_OK);
+}
+
+/*
+ * tcl_iscreen --
+ * Create a new screen. If a filename is specified then the screen
+ * is opened with that file.
+ *
+ * Tcl Command: viNewScreen
+ * Usage: viNewScreen screenId [file]
+ */
+static int
+tcl_iscreen(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char **argv;
+{
+ SCR *sp, *nsp;
+ void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
+ int rval;
+
+ if (argc != 2 && argc != 3) {
+ Tcl_SetResult(interp,
+ "Usage: viNewScreen screenId [file]", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+
+ if (getscreenid(interp, &sp, argv[1], NULL))
+ return (TCL_ERROR);
+ INITMESSAGE;
+ rval = api_edit(sp, argv[2], &nsp, 1);
+ ENDMESSAGE;
+
+ if (rval)
+ return (TCL_ERROR);
+
+ (void)sprintf(interp->result, "%d", nsp->id);
+ return (TCL_OK);
+}
+
+/*
+ * tcl_escreen --
+ * End a screen.
+ *
+ * Tcl Command: viEndScreen
+ * Usage: viEndScreen screenId
+ */
+static int
+tcl_escreen(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char **argv;
+{
+ SCR *sp;
+ void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
+ int rval;
+
+ if (argc != 2) {
+ Tcl_SetResult(interp,
+ "Usage: viEndScreen screenId", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+
+ if (getscreenid(interp, &sp, argv[1], NULL))
+ return (TCL_ERROR);
+ INITMESSAGE;
+ rval = api_escreen(sp);
+ ENDMESSAGE;
+
+ return (rval ? TCL_ERROR : TCL_OK);
+}
+
+/*
+ * tcl_swscreen --
+ * Change the current focus to screen.
+ *
+ * Tcl Command: viSwitchScreen
+ * Usage: viSwitchScreen screenId screenId
+ */
+static int
+tcl_swscreen(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char **argv;
+{
+ SCR *sp, *new;
+ void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
+ int rval;
+
+ if (argc != 3) {
+ Tcl_SetResult(interp,
+ "Usage: viSwitchScreen cur_screenId new_screenId",
+ TCL_STATIC);
+ return (TCL_ERROR);
+ }
+
+ if (getscreenid(interp, &sp, argv[1], NULL))
+ return (TCL_ERROR);
+ if (getscreenid(interp, &new, argv[2], NULL))
+ return (TCL_ERROR);
+ INITMESSAGE;
+ rval = api_swscreen(sp, new);
+ ENDMESSAGE;
+
+ return (rval ? TCL_ERROR : TCL_OK);
+}
+
+/*
+ * tcl_map --
+ * Associate a key with a tcl procedure.
+ *
+ * Tcl Command: viMapKey
+ * Usage: viMapKey screenId key tclproc
+ */
+static int
+tcl_map(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char **argv;
+{
+ SCR *sp;
+ void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
+ int rval;
+ char command[256];
+
+ if (argc != 4) {
+ Tcl_SetResult(interp,
+ "Usage: viMapKey screenId key tclproc", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+
+ if (getscreenid(interp, &sp, argv[1], NULL))
+ return (TCL_ERROR);
+ INITMESSAGE;
+ (void)snprintf(command, sizeof(command), ":tcl %s\n", argv[3]);
+ rval = api_map(sp, argv[2], command, strlen(command));
+ ENDMESSAGE;
+
+ return (rval ? TCL_ERROR : TCL_OK);
+}
+
+/*
+ * tcl_unmap --
+ * Unmap a key.
+ *
+ * Tcl Command: viUnmapKey
+ * Usage: viUnmMapKey screenId key
+ */
+static int
+tcl_unmap(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char **argv;
+{
+ SCR *sp;
+ void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
+ int rval;
+
+ if (argc != 3) {
+ Tcl_SetResult(interp,
+ "Usage: viUnmapKey screenId key", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+
+ if (getscreenid(interp, &sp, argv[1], NULL))
+ return (TCL_ERROR);
+ INITMESSAGE;
+ rval = api_unmap(sp, argv[2]);
+ ENDMESSAGE;
+
+ return (rval ? TCL_ERROR : TCL_OK);
+}
+
+/*
+ * tcl_opts_set --
+ * Set an option.
+ *
+ * Tcl Command: viSetOpt
+ * Usage: viSetOpt screenId command
+ */
+static int
+tcl_opts_set(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char **argv;
+{
+ SCR *sp;
+ void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
+ int rval;
+ char *setting;
+
+ if (argc != 3) {
+ Tcl_SetResult(interp,
+ "Usage: viSetOpt screenId command", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+
+ if (getscreenid(interp, &sp, argv[1], NULL))
+ return (TCL_ERROR);
+ INITMESSAGE;
+ /*rval = api_opts_set(sp, argv[2]);*/
+ MALLOC(sp, setting, char *, strlen(argv[2])+6);
+ strcpy(setting, ":set ");
+ strcpy(setting+5, argv[2]);
+ rval=api_run_str(sp, setting);
+ free(setting);
+ ENDMESSAGE;
+
+ return (rval ? TCL_ERROR : TCL_OK);
+}
+
+/*
+ * tcl_opts_get --
+ Return the value of an option.
+ *
+ * Tcl Command: viGetOpt
+ * Usage: viGetOpt screenId option
+ */
+static int
+tcl_opts_get(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char **argv;
+{
+ SCR *sp;
+ void (*scr_msg) __P((SCR *, mtype_t, char *, size_t));
+ int rval;
+ char *value;
+
+ if (argc != 3) {
+ Tcl_SetResult(interp,
+ "Usage: viGetOpt screenId option", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+
+ if (getscreenid(interp, &sp, argv[1], NULL))
+ return (TCL_ERROR);
+ INITMESSAGE;
+ rval = api_opts_get(sp, argv[2], &value, NULL);
+ ENDMESSAGE;
+ if (rval)
+ return (TCL_ERROR);
+
+ Tcl_SetResult(interp, value, TCL_DYNAMIC);
+ return (TCL_OK);
+}
+
+/*
+ * tcl_init --
+ * Create the TCL commands used by nvi.
+ *
+ * PUBLIC: int tcl_init __P((GS *));
+ */
+int
+tcl_init(gp)
+ GS *gp;
+{
+ gp->tcl_interp = Tcl_CreateInterp();
+ if (Tcl_Init(gp->tcl_interp) == TCL_ERROR)
+ return (1);
+
+#define TCC(name, function) { \
+ Tcl_CreateCommand(gp->tcl_interp, name, function, \
+ (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); \
+}
+ TCC("viAppendLine", tcl_aline);
+ TCC("viDelLine", tcl_dline);
+ TCC("viEndScreen", tcl_escreen);
+ TCC("viFindScreen", tcl_fscreen);
+ TCC("viGetCursor", tcl_getcursor);
+ TCC("viGetLine", tcl_gline);
+ TCC("viGetMark", tcl_getmark);
+ TCC("viGetOpt", tcl_opts_get);
+ TCC("viInsertLine", tcl_iline);
+ TCC("viLastLine", tcl_lline);
+ TCC("viMapKey", tcl_map);
+ TCC("viMsg", tcl_msg);
+ TCC("viNewScreen", tcl_iscreen);
+ TCC("viSetCursor", tcl_setcursor);
+ TCC("viSetLine", tcl_sline);
+ TCC("viSetMark", tcl_setmark);
+ TCC("viSetOpt", tcl_opts_set);
+ TCC("viSwitchScreen", tcl_swscreen);
+ TCC("viUnmapKey", tcl_unmap);
+
+ return (0);
+}
+
+/*
+ * getscreenid --
+ * Get the specified screen pointer.
+ *
+ * XXX
+ * This is fatal. We can't post a message into vi that we're unable to find
+ * the screen without first finding the screen... So, this must be the first
+ * thing a Tcl routine does, and, if it fails, the last as well.
+ */
+static int
+getscreenid(interp, spp, id, name)
+ Tcl_Interp *interp;
+ SCR **spp;
+ char *id, *name;
+{
+ int scr_no;
+ char buf[64];
+
+ if (id != NULL && getint(interp, "screen id", id, &scr_no))
+ return (1);
+ if ((*spp = api_fscreen(scr_no, name)) == NULL) {
+ (void)snprintf(buf, sizeof(buf),
+ "unknown screen id: %s", name == NULL ? id : name);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ return (1);
+ }
+ return (0);
+}
+
+/*
+ * getint --
+ * Get a Tcl integer.
+ *
+ * XXX
+ * This code assumes that both recno_t and size_t are larger than ints.
+ */
+static int
+getint(interp, msg, s, intp)
+ Tcl_Interp *interp;
+ char *msg, *s;
+ int *intp;
+{
+ char buf[64];
+
+ if (Tcl_GetInt(interp, s, intp) == TCL_ERROR)
+ return (1);
+ if (*intp < 0) {
+ (void)snprintf(buf, sizeof(buf),
+ "illegal %s %s: may not be negative", msg, s);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ return (1);
+ }
+ return (0);
+}
+
+/*
+ * msghandler --
+ * Tcl message routine so that error messages are processed in
+ * Tcl, not in nvi.
+ */
+static void
+msghandler(sp, mtype, msg, len)
+ SCR *sp;
+ mtype_t mtype;
+ char *msg;
+ size_t len;
+{
+ /* Replace the trailing <newline> with an EOS. */
+ msg[len - 1] = '\0';
+
+ Tcl_SetResult(sp->gp->tcl_interp, msg, TCL_VOLATILE);
+}
OpenPOWER on IntegriCloud