xref: /csrg-svn/contrib/ed/main.c (revision 60663)
157694Sbostic /*-
2*60663Sbostic  * Copyright (c) 1992, 1993
3*60663Sbostic  *	The Regents of the University of California.  All rights reserved.
457694Sbostic  *
557694Sbostic  * This code is derived from software contributed to Berkeley by
657694Sbostic  * Rodney Ruddock of the University of Guelph.
757694Sbostic  *
857694Sbostic  * %sccs.include.redist.c%
957694Sbostic  */
1057694Sbostic 
1157694Sbostic #ifndef lint
12*60663Sbostic static char copyright[] =
13*60663Sbostic "@(#) Copyright (c) 1992, 1993\n\
14*60663Sbostic 	The Regents of the University of California.  All rights reserved.\n";
1557694Sbostic #endif /* not lint */
1657694Sbostic 
1759475Sbostic #ifndef lint
18*60663Sbostic static char sccsid[] = "@(#)main.c	8.1 (Berkeley) 05/31/93";
1959475Sbostic #endif /* not lint */
2059475Sbostic 
2157710Sbostic #include <sys/types.h>
2258315Sbostic #include <sys/ioctl.h>
2357710Sbostic 
2459477Sbostic #include <limits.h>
2557710Sbostic #include <regex.h>
2657710Sbostic #include <setjmp.h>
2757710Sbostic #include <signal.h>
2857710Sbostic #include <stdio.h>
2957710Sbostic #include <stdlib.h>
3057710Sbostic #include <string.h>
3159477Sbostic #include <unistd.h>
3257710Sbostic 
3358315Sbostic #ifdef DBI
3458315Sbostic #include <db.h>
3558315Sbostic #endif
3658315Sbostic 
3757694Sbostic #include "ed.h"
3857710Sbostic #include "extern.h"
3957694Sbostic 
4057694Sbostic /*
4157694Sbostic  * This is where all of the "global" variables are declared. They are
4257694Sbostic  * set for extern in the ed.h header file (so everyone can get them).
4357694Sbostic  */
4457694Sbostic 
4558564Sralph int nn_max, nn_max_flag, Start_default, End_default, address_flag;
4658315Sbostic int zsnum, filename_flag, add_flag=0, join_flag=0;
4759558Sbostic int help_flag=0, gut_num=-1;
4858315Sbostic #ifdef STDIO
4958315Sbostic FILE *fhtmp;
5058315Sbostic int file_seek;
5158315Sbostic #endif
5257694Sbostic 
5358315Sbostic #ifdef DBI
5457694Sbostic DB *dbhtmp;
5558315Sbostic #endif
5657694Sbostic 
5757694Sbostic LINE *nn_max_start, *nn_max_end;
5857694Sbostic 
5957694Sbostic struct MARK mark_matrix[26]; /* in init set all to null */
6057694Sbostic 
6157694Sbostic char *text;
6259475Sbostic LINE **gut=NULL;
6357694Sbostic char *filename_current, *prompt_string=NULL, help_msg[130];
6457694Sbostic char *template=NULL;
6557694Sbostic int prompt_str_flg=0, start_up_flag=0, name_set=0;
6657694Sbostic 
6758564Sralph LINE *top, *current, *bottom, *Start, *End;
6857694Sbostic struct u_layer *u_stk;
6957694Sbostic struct d_layer *d_stk;
7057694Sbostic LINE *u_current, *u_top, *u_bottom;
7157694Sbostic int u_set;
7257694Sbostic regex_t RE_comp;
7357694Sbostic regmatch_t RE_match[RE_SEC];
7457694Sbostic int RE_sol=0, RE_flag=0;
7557694Sbostic char *RE_patt=NULL;
7657694Sbostic 
7757694Sbostic int ss; /* for the getc() */
7859475Sbostic int explain_flag=1, g_flag=0, GV_flag=0, printsfx=0, exit_code=0;
7957694Sbostic long change_flag=0L;
8057694Sbostic int line_length;
8158352Sbostic jmp_buf ctrl_position, ctrl_position2, ctrl_position3; /* For SIGnal handling. */
8258352Sbostic int sigint_flag, sighup_flag, sigspecial=0, sigspecial2=0, sigspecial3=0;
8357694Sbostic 
8457710Sbostic static void sigint_handler __P((int));
8557710Sbostic static void sighup_handler __P((int));
8657710Sbostic 
8757710Sbostic /*
8857710Sbostic  * Starts the whole show going. Set things up as the arguments spec
8957710Sbostic  * in the shell and set a couple of the global variables.
9057710Sbostic  *
9157710Sbostic  * Note naming viol'n with errnum for consistancy.
9257694Sbostic  */
9357710Sbostic int
main(argc,argv)9457710Sbostic main(argc, argv)
9557710Sbostic 	int argc;
9657710Sbostic 	char *argv[];
9757694Sbostic {
9859915Sbostic 	int l_num, errnum=0, l_err=0;
9958710Sbostic 	char *l_fnametmp, *l_col, buf[2];
10058315Sbostic 	struct winsize win;
10157694Sbostic 
10258710Sbostic 	setbuffer(stdin, buf, 1);
10358315Sbostic 	line_length = ((l_col = getenv("COLUMNS")) == NULL ? 0 : atoi(l_col));
10459475Sbostic 	if ((line_length == 0 && isatty(STDOUT_FILENO) &&
10559475Sbostic 		ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) != -1))
10658315Sbostic 		line_length = win.ws_col;
10758315Sbostic 	if (line_length == 0)
10858315Sbostic 		line_length = 78;
10960656Sbostic 	line_length -= 3;	/* for the octal to break properly in 'l' */
11057694Sbostic 
11158564Sralph 	Start = End = NULL;
11257710Sbostic 	top = bottom = NULL;
11357710Sbostic 	current = NULL;
11457710Sbostic 	nn_max_flag = 0;
11557710Sbostic 	nn_max_start = nn_max_end = NULL;
11657710Sbostic 	l_fnametmp = calloc(FILENAME_LEN, sizeof(char));
11757710Sbostic 	if (l_fnametmp == NULL)
11857710Sbostic 		ed_exit(4);
11957710Sbostic 	text = calloc(NN_MAX_START + 2, sizeof(char));
12057710Sbostic 	if (text == NULL)
12157710Sbostic 		ed_exit(4);
12258564Sralph 	Start_default = End_default = 0;
12357710Sbostic 	zsnum = 22;		/* for the 'z' command */
12459558Sbostic 	help_msg[0] = '\0';
12557710Sbostic 	u_stk = NULL;
12657710Sbostic 	d_stk = NULL;
12757710Sbostic 	u_current = u_top = u_bottom = NULL;
12857710Sbostic 	u_set = 0;		/* for in d after a j */
12957710Sbostic 	filename_flag = 0;
13057710Sbostic 	filename_current = NULL;
13157694Sbostic 
13257710Sbostic 	l_num = 1;
13357710Sbostic 	for (;;) {
13457710Sbostic 		/* Process the command line options */
13557710Sbostic 		if (l_num >= argc)
13657710Sbostic 			break;
13757710Sbostic 		switch (argv[l_num][0]) {
13857710Sbostic 		case '-':
13957710Sbostic 			switch (argv[l_num][1]) {
14057710Sbostic 			case '\0':	/* this is why 'getopt' not used */
14157710Sbostic 			case 's':
14257710Sbostic 				explain_flag = 0;
14357710Sbostic 				break;
14457710Sbostic 			case 'p':
14557710Sbostic 				if (++l_num < argc) {
14657710Sbostic 					prompt_string =
14757710Sbostic 					    calloc(strlen(argv[l_num]),
14857710Sbostic 					    sizeof(char));
14957710Sbostic 					if (prompt_string == NULL)
15057710Sbostic 						ed_exit(4);
15157710Sbostic 					strcpy(prompt_string, argv[l_num]);
15257710Sbostic 					prompt_str_flg = 1;
15357710Sbostic 					break;
15457710Sbostic 				}
15557710Sbostic 				l_err = 1;
15658710Sbostic 			case 'v':
15758710Sbostic #ifdef BSD
15859558Sbostic 				(void)printf("ed: in BSD mode:\n");
15958710Sbostic #endif
16058710Sbostic #ifdef POSIX
16159558Sbostic 				(void)printf("ed: in POSIX mode:\n");
16258710Sbostic #endif
16359475Sbostic 				break;
16457710Sbostic 			default:
16557710Sbostic 				l_err++;
16657710Sbostic 				ed_exit(l_err);
16757710Sbostic 			}
16857710Sbostic 			break;
16957710Sbostic 		default:
17057710Sbostic 			if (name_set)
17157710Sbostic 				ed_exit(3);
17257710Sbostic 			strcpy(l_fnametmp, argv[l_num]);
17357710Sbostic 			filename_current = l_fnametmp;
17457710Sbostic 			name_set = 1;
17557710Sbostic 			if (prompt_str_flg)
17657710Sbostic 				break;
17757710Sbostic 			/* default ed prompt */
17857710Sbostic 			prompt_string = (char *) calloc(3, sizeof(char));
17957710Sbostic 			strcpy(prompt_string, "*");
18057710Sbostic 			break;
18157710Sbostic 		}
18257710Sbostic 		l_num++;
18357710Sbostic 	}
18457710Sbostic 
18557710Sbostic 	start_up_flag = 1;
18657710Sbostic 	cmd_loop(stdin, &errnum);
18757710Sbostic 	/* NOTREACHED */
18857710Sbostic }
18957710Sbostic 
19057694Sbostic /*
19157710Sbostic  * The command loop. What the command is that the user has specified
19257694Sbostic  * is determined here. This is not just for commands coming from
19357694Sbostic  * the terminal but any standard i/o stream; see the global commands.
19457694Sbostic  * Some of the commands are handled within here (i.e. 'H') while most
19557694Sbostic  * are handled in their own functions (as called).
19657694Sbostic  */
19757694Sbostic void
cmd_loop(inputt,errnum)19857694Sbostic cmd_loop(inputt, errnum)
19957710Sbostic 	FILE *inputt;
20057710Sbostic 	int *errnum;
20157694Sbostic {
20257710Sbostic 	LINE *l_tempp;
20357710Sbostic 	int l_last, l_jmp_flag;
20457694Sbostic 
20558315Sbostic 	l_last = 0; /* value in l_last may be clobbered (reset to = 0) by longjump, but that's okay */
20657694Sbostic 
20757710Sbostic 	if (g_flag == 0) {	/* big, BIG trouble if we don't check! think. */
20857710Sbostic 		/* set the jump point for the signals */
20957710Sbostic 		l_jmp_flag = setjmp(ctrl_position);
21057710Sbostic 		signal(SIGINT, sigint_handler);
21157710Sbostic 		signal(SIGHUP, sighup_handler);
21257710Sbostic 		switch (l_jmp_flag) {
21357710Sbostic 		case JMP_SET:
21457710Sbostic 			break;
21557710Sbostic 		/* Some general cleanup not specific to the jmp pt. */
21657710Sbostic 		case INTERUPT:
21757710Sbostic 			sigint_flag = 0;
21857710Sbostic 			GV_flag = 0;	/* safest place to do these flags */
21957710Sbostic 			g_flag = 0;
22059558Sbostic 			(void)printf("\n?\n");
22157710Sbostic 			break;
22257710Sbostic 		case HANGUP:		/* shouldn't get here. */
22357710Sbostic 			break;
22457710Sbostic 		default:
22557710Sbostic 			(void)fprintf(stderr, "Signal jump problem\n");
22657710Sbostic 		}
22757710Sbostic 		/* Only do this once! */
22857710Sbostic 		if (start_up_flag) {
22957710Sbostic 			start_up_flag = 0;
23057710Sbostic 			/* simulate the 'e' at startup */
23157710Sbostic 			e2(inputt, errnum);
23259915Sbostic 			if (*errnum == 0)
23359915Sbostic 				goto errmsg2;
23457710Sbostic 		}
23557710Sbostic 	}
23657710Sbostic 	for (;;) {
23757710Sbostic 		if (prompt_str_flg == 1)
23857710Sbostic 			(void)printf("%s", prompt_string);
23957710Sbostic 		ss = getc(inputt);
24057710Sbostic 		*errnum = 0;
24158564Sralph 		l_tempp = Start = End = NULL;
24258564Sralph 		Start_default = End_default = 1;
24357694Sbostic 
24457710Sbostic 		/*
24557710Sbostic 		 * This isn't nice and alphabetical mainly because of
24657710Sbostic 		 * restrictions with 'G' and 'V' (see ed(1)).
24757710Sbostic 		 */
24857710Sbostic 		for (;;) {
24957710Sbostic 			switch (ss) {
25057710Sbostic 			case 'd':
25157710Sbostic 				d(inputt, errnum);
25257710Sbostic 				break;
25357710Sbostic 			case 'e':
25457710Sbostic 			case 'E':
25557710Sbostic 				e(inputt, errnum);
25659915Sbostic 				if (*errnum == 0)
25759915Sbostic 					goto errmsg2;
25857710Sbostic 				break;
25957710Sbostic 			case 'f':
26057710Sbostic 				f(inputt, errnum);
26157710Sbostic 				break;
26257710Sbostic 			case 'a':
26357710Sbostic 			case 'c':
26457710Sbostic 			case 'i':
26557710Sbostic 			case 'g':
26657710Sbostic 			case 'G':
26757710Sbostic 			case 'v':
26857710Sbostic 			case 'V':
26957710Sbostic 				if (GV_flag == 1) {
27057710Sbostic 					(void)sprintf(help_msg,
27157710Sbostic 					    "command `%c' illegal in G/V", ss);
27257710Sbostic 					*errnum = -1;
27357710Sbostic 					break;
27457710Sbostic 				}
27557710Sbostic 				switch (ss) {
27657710Sbostic 				case 'a':
27757710Sbostic 					a(inputt, errnum);
27857710Sbostic 					break;
27957710Sbostic 				case 'c':
28057710Sbostic 					c(inputt, errnum);
28157710Sbostic 					break;
28257710Sbostic 				case 'i':
28357710Sbostic 					i(inputt, errnum);
28457710Sbostic 					break;
28557710Sbostic 				default:
28657710Sbostic 					g(inputt, errnum);
28757710Sbostic 				}
28857710Sbostic 				break;
28957710Sbostic 			case 'h':
29057710Sbostic 				if (rol(inputt, errnum))
29157710Sbostic 					break;
29259558Sbostic 				if (help_msg[0])
29359558Sbostic 					(void)printf("%s\n", help_msg);
29457710Sbostic 				*errnum = 1;
29557710Sbostic 				break;
29657710Sbostic 			case 'H':
29757710Sbostic 				if (rol(inputt, errnum))
29857710Sbostic 					break;
29957710Sbostic 				if (help_flag == 0) {
30057710Sbostic 					help_flag = 1;
30159558Sbostic 					if (help_msg[0])
30259558Sbostic 						(void)printf("%s\n",
30359558Sbostic 						    help_msg);
30457710Sbostic 				} else
30557710Sbostic 					help_flag = 0;
30657710Sbostic 				*errnum = 1;
30757710Sbostic 				break;
30857710Sbostic 			case 'j':
30957710Sbostic 				j(inputt, errnum);
31057710Sbostic 				break;
31157710Sbostic 			case 'k':
31257710Sbostic 				set_mark(inputt, errnum);
31357710Sbostic 				break;
31457710Sbostic 			case 'l':
31557710Sbostic 				l(inputt, errnum);
31657710Sbostic 				break;
31757710Sbostic 			case 'm':
31857710Sbostic 				m(inputt, errnum);
31957710Sbostic 				break;
32057694Sbostic #ifdef POSIX
32157710Sbostic 				/* In POSIX-land 'P' toggles the prompt. */
32257710Sbostic 			case 'P':
32357710Sbostic 				if (rol(inputt, errnum))
32457710Sbostic 					break;
32557710Sbostic 				prompt_str_flg = prompt_str_flg ? 0 : 1;
32657710Sbostic 				*errnum = 1;
32757710Sbostic 				break;
32857694Sbostic #endif
32957710Sbostic 			case '\n':
33057710Sbostic 				if (GV_flag == 1)
33157710Sbostic 					return;
33257710Sbostic 				/* For 'p' to consume. */
33357710Sbostic 				ungetc(ss, inputt);
33457710Sbostic 				if ((current == bottom) && (End == NULL)) {
33557710Sbostic 					strcpy(help_msg, "at end of buffer");
33657710Sbostic 					*errnum = -1;
33757710Sbostic 					break;
33857710Sbostic 				}
33957710Sbostic 				current = current->below;
34057694Sbostic #ifdef BSD
34157710Sbostic 				/* In BSD 'P'=='p'. */
34257710Sbostic 			case 'P':
34357694Sbostic #endif
34457710Sbostic 			case 'p':
34557710Sbostic 				p(inputt, errnum, 0);
34657710Sbostic 				break;
34757710Sbostic 			case 'n':
34857710Sbostic 				p(inputt, errnum, 1);
34957710Sbostic 				break;
35057710Sbostic 			/*
35157710Sbostic 			 * An EOF means 'q' unless we're still in the middle
35257710Sbostic 			 * of a global command, in which case it was just the
35357710Sbostic 			 * end of the command list found.
35457710Sbostic 			 */
35557710Sbostic 			case EOF:
35657710Sbostic 				clearerr(inputt);
35757710Sbostic 				if (g_flag > 0)
35857710Sbostic 					return;
35958710Sbostic 				/*ss = 'q';*/
36057710Sbostic 			case 'q':
36157710Sbostic 			case 'Q':
36259915Sbostic 				if ((!isatty(STDIN_FILENO)) && (ss == 'q'))
36359915Sbostic 					ss = 'Q';
36457710Sbostic 				q(inputt, errnum);
36557710Sbostic 				break;
36657710Sbostic 			case 'r':
36757710Sbostic 				r(inputt, errnum);
36859915Sbostic 				if (*errnum == 0)
36959915Sbostic 					goto errmsg2;
37057710Sbostic 				break;
37157710Sbostic 			case 's':
37257710Sbostic 				s(inputt, errnum);
37357710Sbostic 				break;
37457710Sbostic 			case 't':
37557710Sbostic 				t(inputt, errnum);
37657710Sbostic 				break;
37757710Sbostic 			case 'u':
37857710Sbostic 				u(inputt, errnum);
37957710Sbostic 				break;
38057710Sbostic 			case 'w':
38157710Sbostic 			case 'W':
38257710Sbostic 				w(inputt, errnum);
38357710Sbostic 				break;
38457710Sbostic 			case 'z':
38557710Sbostic 				z(inputt, errnum);
38657710Sbostic 				break;
38757710Sbostic 			case '!':
38857710Sbostic 				bang(inputt, errnum);
38957710Sbostic 				break;
39057710Sbostic 			case '=':
39157710Sbostic 				equal(inputt, errnum);
39257710Sbostic 				break;
39357710Sbostic 			/*
39457710Sbostic 			 * Control of address forms from here down.
39557710Sbostic 			 *
39657710Sbostic 			 * It's a head-game to understand why ";" and "," look
39757710Sbostic 			 * as they do below, but a lot of it has to do with ";"
39857710Sbostic 			 * and "," being special address pair forms themselves
39957710Sbostic 			 * and the compatibility for address "chains".
40057710Sbostic 			 */
40157710Sbostic 			case ';':
40258564Sralph 				if (End_default == 1 && Start_default == 1) {
40358564Sralph 					Start = current;
40457710Sbostic 					End = bottom;
40558564Sralph 					Start_default = End_default = 0;
40657710Sbostic 				} else {
40758564Sralph 					Start = current = End;
40858564Sralph 					Start_default = 0;
40957710Sbostic 					End_default = 1;
41057710Sbostic 				}
41157710Sbostic 				l_tempp = NULL;
41257710Sbostic 				break;
41357710Sbostic 			/*
41457710Sbostic 			 * Note address ".,x" where x is a cmd is legal; not a
41557710Sbostic 			 * bug - for backward compatability.
41657710Sbostic 			 */
41757710Sbostic 			case ',':
41858564Sralph 				if (End_default == 1 && Start_default == 1) {
41958564Sralph 					Start = top;
42057710Sbostic 					End = bottom;
42158564Sralph 					Start_default = End_default = 0;
42257710Sbostic 				} else {
42358564Sralph 					Start = End;
42458564Sralph 					Start_default = 0;
42557710Sbostic 					End_default = 1;
42657710Sbostic 				}
42757710Sbostic 				l_tempp = NULL;
42857710Sbostic 				break;
42957710Sbostic 			case '%':
43057710Sbostic 				if (End_default == 0) {
43157710Sbostic 					strcpy(help_msg,
43257710Sbostic 					    "'%' is an address pair");
43357710Sbostic 					*errnum = -1;
43457710Sbostic 					break;
43557710Sbostic 				}
43658564Sralph 				Start = top;
43757710Sbostic 				End = bottom;
43858564Sralph 				Start_default = End_default = 0;
43957710Sbostic 				l_tempp = NULL;
44057710Sbostic 				break;
44157710Sbostic 			/*
44257710Sbostic 			 * Within address_conv => l_last = '+', foobar, but
44357710Sbostic 			 * historical and now POSIX...
44457710Sbostic 			 */
44557710Sbostic 			case ' ':
44657710Sbostic 				break;
44757710Sbostic 			case '0':
44857710Sbostic 			case '1':
44957710Sbostic 			case '2':
45057710Sbostic 			case '3':
45157710Sbostic 			case '4':
45257710Sbostic 			case '5':
45357710Sbostic 			case '6':
45457710Sbostic 			case '7':
45557710Sbostic 			case '8':
45657710Sbostic 			case '9':
45757710Sbostic 			case '-':
45857710Sbostic 			case '^':
45957710Sbostic 			case '+':
46057710Sbostic 			case '\'':
46157710Sbostic 			case '$':
46257710Sbostic 			case '?':
46357710Sbostic 			case '/':
46457710Sbostic 			case '.':
46557710Sbostic 				ungetc(ss, inputt);
46658564Sralph 				if (Start_default == 0 && End_default == 0) {
46757710Sbostic 					strcpy(help_msg,
46857710Sbostic 					    "badly formed address");
46957710Sbostic 					*errnum = -1;
47057710Sbostic 					break;
47157710Sbostic 				}
47257710Sbostic 				ss = l_last;
47357710Sbostic 				l_tempp = address_conv(l_tempp, inputt, errnum);
47457710Sbostic 				if (*errnum < 0)
47557710Sbostic 					break;
47657710Sbostic 				End = l_tempp;
47757710Sbostic 				End_default = 0;
47858564Sralph 				if (Start_default == 0)
47958564Sralph 					*errnum = address_check(Start, End);
48057710Sbostic 				break;
48157710Sbostic 			default:
48257710Sbostic 				*errnum = -1;
48357710Sbostic 				strcpy(help_msg, "unknown command");
48457710Sbostic 				break;
48557710Sbostic 			}	/* end-switch(ss) */
48657694Sbostic 
48757710Sbostic 			/* Things came out okay with the last command. */
48857710Sbostic 			if (*errnum > 0) {
48957710Sbostic 				if (GV_flag == 1)
49057710Sbostic 					return;
49157710Sbostic 				/* Do the suffixes if there were any. */
49257710Sbostic 				if (printsfx > 0) {
49358564Sralph 					Start = End = current;
49457710Sbostic 					ungetc(ss, inputt);
49557710Sbostic 					if (printsfx == 1)
49657710Sbostic 						p(inputt, errnum, 0);
49757710Sbostic 					else
49857710Sbostic 						if (printsfx == 2)
49957710Sbostic 							p(inputt, errnum, 1);
50057710Sbostic 						else if (printsfx == 4)
50157710Sbostic 							l(inputt, errnum);
50257710Sbostic 					/* Unlikely it's needed, but... */
50357710Sbostic 					if (*errnum < 0)
50457710Sbostic 						goto errmsg;
50557710Sbostic 				}
50657710Sbostic 				break;
50757710Sbostic 			}
50857710Sbostic 			/* There was a problem with the last command. */
50957710Sbostic 			else if (*errnum < 0) {
51057710Sbostic errmsg:				while (((ss = getc(inputt)) != '\n') &&
51157710Sbostic 				    (ss != EOF));
51259915Sbostic 				(void)printf("?\n");
51359915Sbostic errmsg2:			if (help_flag)
51459915Sbostic 					(void)printf("%s\n", help_msg);
51559475Sbostic 				exit_code = 4;
51659475Sbostic /* for people wanting scripts to carry on after a cmd error, then
51759475Sbostic  * define NOENDONSCRIPT on the compile line.
51859475Sbostic  */
51959475Sbostic #ifndef NOENDONSCRIPT
52059475Sbostic 				if (!isatty(STDIN_FILENO)) {
52159475Sbostic 					ss = 'Q';
52259475Sbostic 					ungetc('\n', inputt);
52359475Sbostic 					q(inputt, errnum);
52459475Sbostic 				}
52559475Sbostic #endif
52658315Sbostic 				break;
52757710Sbostic 			}
52857710Sbostic 			l_last = ss;
52957710Sbostic 			ss = getc(inputt);
53057710Sbostic 		}
53157710Sbostic 	}
53257710Sbostic }
53357694Sbostic 
53457710Sbostic /*
53557710Sbostic  * Exits ed and prints an appropriate message about the command line
53657694Sbostic  * being malformed (see below).
53757694Sbostic  */
53857694Sbostic void
ed_exit(err)53957694Sbostic ed_exit(err)
54057710Sbostic 	int err;
54157694Sbostic {
54257710Sbostic 	switch (err) {
54357710Sbostic           case 1:
54457710Sbostic 		(void)fprintf(stderr, "ed: illegal option\n");
54557710Sbostic 		break;
54657710Sbostic           case 2:
54757710Sbostic 		(void)fprintf(stderr, "ed: missing promptstring\n");
54857710Sbostic 		break;
54957710Sbostic           case 3:
55057710Sbostic 		(void)fprintf(stderr, "ed: too many filenames\n");
55157710Sbostic 		break;
55257710Sbostic           case 4:
55357710Sbostic 		(void)fprintf(stderr, "ed: out of memory error\n");
55457710Sbostic 		break;
55558315Sbostic 	  case 5:
55658315Sbostic 		(void)fprintf(stderr, "ed: unable to create buffer\n");
55758315Sbostic 		break;
55857710Sbostic           default:
55957710Sbostic 		(void)fprintf(stderr, "ed: command line error\n");
56057710Sbostic 		break;
56157710Sbostic         }
56257710Sbostic 	(void)fprintf(stderr,
56357710Sbostic 	    "ed: ed [ -s ] [ -p promptstring ] [ filename ]\n");
56457710Sbostic 	exit(1);
56557710Sbostic }
56657694Sbostic 
56757694Sbostic /*
56857710Sbostic  * SIGINT is never turned off. We flag it happened and then pay attention
56957710Sbostic  * to it at certain logical locations in the code we don't do more here
57057710Sbostic  * cause some of our buffer pointer's may be in an inbetween state at the
57157710Sbostic  * time of the SIGINT. So we flag it happened, let the local fn handle it
57257710Sbostic  * and do a jump back to the cmd_loop
57357694Sbostic  */
57457710Sbostic static void
sigint_handler(signo)57557710Sbostic sigint_handler(signo)
57657710Sbostic 	int signo;
57757710Sbostic {
57857710Sbostic 	sigint_flag = 1;
57958352Sbostic 	if (sigspecial3) {
58058352Sbostic 		sigspecial3 = 0;
58158352Sbostic 		SIGINT_ILACTION;
58258352Sbostic 	}
58358315Sbostic 	else
58458315Sbostic 		if (sigspecial);
58558315Sbostic 		else
58658315Sbostic 			SIGINT_ACTION;
58757710Sbostic }
58857694Sbostic 
58957710Sbostic static void
sighup_handler(signo)59057710Sbostic sighup_handler(signo)
59157710Sbostic 	int signo;
59257694Sbostic {
59357710Sbostic 	sighup_flag = 1;
59457710Sbostic 	undo();
59557710Sbostic 	do_hup();
59657710Sbostic 	/* NOTREACHED */
59757694Sbostic 
59857710Sbostic 	SIGHUP_ACTION;
59957710Sbostic }
600