move a bit of code
[nvi.git] / ip / ip_main.c
blob0837b2dc4d38a34cd8e6b5268307f3ba873693ea
1 /*-
2 * Copyright (c) 1996
3 * Keith Bostic. All rights reserved.
5 * See the LICENSE file for redistribution information.
6 */
8 #include "config.h"
10 #ifndef lint
11 static const char sccsid[] = "$Id: ip_main.c,v 8.14 2000/06/30 20:11:28 skimo Exp $ (Berkeley) $Date: 2000/06/30 20:11:28 $";
12 #endif /* not lint */
14 #include <sys/types.h>
15 #include <sys/queue.h>
17 #include <bitstring.h>
18 #include <ctype.h>
19 #include <errno.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
25 #include <sys/uio.h>
26 #include <pthread.h>
28 #include "../common/common.h"
29 #include "../ipc/ip.h"
30 #include "extern.h"
32 GS *__global_list; /* GLOBAL: List of screens. */
34 static void ip_func_std __P((GS *));
35 static IP_PRIVATE *ip_init __P((WIN *wp, int i_fd, int o_fd, int argc, char *argv[]));
36 static void perr __P((char *, char *));
37 static int get_fds __P((char *ip_arg, int *i_fd, int *o_fd));
38 static void run_editor __P((void * vp));
41 * ip_main --
42 * This is the main loop for the vi-as-library editor.
44 * PUBLIC: int ip_main __P((int, char *[], GS *, char *));
46 int
47 main(argc, argv)
48 int argc;
49 char *argv[];
51 IP_PRIVATE *ipp;
52 int rval;
53 char *ip_arg;
54 char **p_av, **t_av;
55 GS *gp;
56 WIN *wp;
57 int i_fd, o_fd, main_ifd, main_ofd;
59 /* Create and initialize the global structure. */
60 __global_list = gp = gs_init(argv[0]);
63 * Strip out any arguments that vi isn't going to understand. There's
64 * no way to portably call getopt twice, so arguments parsed here must
65 * be removed from the argument list.
67 ip_arg = NULL;
68 for (p_av = t_av = argv;;) {
69 if (*t_av == NULL) {
70 *p_av = NULL;
71 break;
73 if (!strcmp(*t_av, "--")) {
74 while ((*p_av++ = *t_av++) != NULL);
75 break;
77 if (!memcmp(*t_av, "-I", sizeof("-I") - 1)) {
78 if (t_av[0][2] != '\0') {
79 ip_arg = t_av[0] + 2;
80 ++t_av;
81 --argc;
82 continue;
84 else if (t_av[1] != NULL) {
85 ip_arg = t_av[1];
86 t_av += 2;
87 argc -= 2;
88 continue;
91 *p_av++ = *t_av++;
94 if (get_fds(ip_arg, &i_fd, &o_fd))
95 return 1;
97 /* Create new window */
98 wp = gs_new_win(gp);
100 /* Create and partially initialize the IP structure. */
101 if ((ipp = ip_init(wp, i_fd, o_fd, argc, argv)) == NULL)
102 return (1);
104 run_editor((void *)wp);
106 /* Free the global and IP private areas. */
107 #if defined(DEBUG) || defined(PURIFY) || defined(LIBRARY)
108 free(gp);
109 #endif
110 exit (rval);
113 static void
114 run_editor(void * vp)
116 GS *gp;
117 IP_PRIVATE *ipp;
118 WIN *wp;
119 EVENT ev;
120 int rval;
121 IP_BUF ipb;
123 wp = (WIN *) vp;
124 gp = wp->gp;
125 ipp = wp->ip_private;
127 /* Add the terminal type to the global structure. */
128 if ((OG_D_STR(gp, GO_TERM) =
129 OG_STR(gp, GO_TERM) = strdup("ip_curses")) == NULL)
130 perr(gp->progname, NULL);
133 * Figure out how big the screen is -- read events until we get
134 * the rows and columns.
136 for (;;) {
137 if (ip_wevent(wp, NULL, &ev, 0, 0))
138 return;
139 if (ev.e_event == E_WRESIZE)
140 break;
141 if (ev.e_event == E_EOF || ev.e_event == E_ERR ||
142 ev.e_event == E_SIGHUP || ev.e_event == E_SIGTERM)
143 return;
144 if (ev.e_event == E_IPCOMMAND && ev.e_ipcom == VI_QUIT)
145 return;
148 /* Run ex/vi. */
149 rval = editor(wp, ipp->argc, ipp->argv);
151 /* Clean up the screen. */
152 (void)ip_quit(wp);
154 /* Send the quit message. */
155 ipb.code = SI_QUIT;
156 (void)vi_send(ipp->o_fd, NULL, &ipb);
158 /* Give the screen a couple of seconds to deal with it. */
159 sleep(2);
161 #if defined(DEBUG) || defined(PURIFY) || defined(LIBRARY)
162 free(ipp);
163 #endif
167 * ip_init --
168 * Create and partially initialize the GS structure.
170 static IP_PRIVATE *
171 ip_init(WIN *wp, int i_fd, int o_fd, int argc, char *argv[])
173 IP_PRIVATE *ipp;
175 /* Allocate the IP private structure. */
176 CALLOC_NOMSG(NULL, ipp, IP_PRIVATE *, 1, sizeof(IP_PRIVATE));
177 if (ipp == NULL)
178 perr(wp->gp->progname, NULL);
179 wp->ip_private = ipp;
181 ipp->i_fd = i_fd;
182 ipp->o_fd = o_fd;
184 ipp->argc = argc;
185 ipp->argv = argv;
187 /* Initialize the list of ip functions. */
188 ip_func_std(wp->gp);
190 return (ipp);
193 static int
194 get_fds(char *ip_arg, int *i_fd, int *o_fd)
196 char *ep;
199 * Crack ip_arg -- it's of the form #.#, where the first number is the
200 * file descriptor from the screen, the second is the file descriptor
201 * to the screen.
203 if (!ip_arg || !isdigit(ip_arg[0]))
204 goto usage;
205 *i_fd = strtol(ip_arg, &ep, 10);
206 if (ep[0] != '.' || !isdigit(ep[1]))
207 goto usage;
208 *o_fd = strtol(++ep, &ep, 10);
209 if (ep[0] != '\0') {
210 usage: ip_usage();
211 return 1;
214 return 0;
218 * ip_func_std --
219 * Initialize the standard ip functions.
221 static void
222 ip_func_std(gp)
223 GS *gp;
225 gp->scr_addstr = ip_addstr;
226 gp->scr_attr = ip_attr;
227 gp->scr_baud = ip_baud;
228 gp->scr_bell = ip_bell;
229 gp->scr_busy = ip_busy;
230 gp->scr_clrtoeol = ip_clrtoeol;
231 gp->scr_cursor = ip_cursor;
232 gp->scr_deleteln = ip_deleteln;
233 gp->scr_discard = ip_discard;
234 gp->scr_event = ip_event;
235 gp->scr_ex_adjust = ip_ex_adjust;
236 gp->scr_fmap = ip_fmap;
237 gp->scr_insertln = ip_insertln;
238 gp->scr_keyval = ip_keyval;
239 gp->scr_move = ip_move;
240 gp->scr_msg = NULL;
241 gp->scr_optchange = ip_optchange;
242 gp->scr_refresh = ip_refresh;
243 gp->scr_rename = ip_rename;
244 gp->scr_reply = ip_reply;
245 gp->scr_screen = ip_screen;
246 gp->scr_split = ip_split;
247 gp->scr_suspend = ip_suspend;
248 gp->scr_usage = ip_usage;
252 * perr --
253 * Print system error.
255 static void
256 perr(name, msg)
257 char *name, *msg;
259 (void)fprintf(stderr, "%s:", name);
260 if (msg != NULL)
261 (void)fprintf(stderr, "%s:", msg);
262 (void)fprintf(stderr, "%s\n", strerror(errno));
263 exit(1);