17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5f2f27852Scf * Common Development and Distribution License (the "License").
6f2f27852Scf * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
21f6db9f27Scf /*
2268c92b9fScf * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23f6db9f27Scf * Use is subject to license terms.
24f6db9f27Scf */
25f6db9f27Scf
267c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
277c478bd9Sstevel@tonic-gate /* All Rights Reserved */
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate
307c478bd9Sstevel@tonic-gate /* Copyright (c) 1981 Regents of the University of California */
317c478bd9Sstevel@tonic-gate
327c478bd9Sstevel@tonic-gate #include "ex.h"
337c478bd9Sstevel@tonic-gate #include "ex_argv.h"
347c478bd9Sstevel@tonic-gate #include "ex_temp.h"
357c478bd9Sstevel@tonic-gate #include "ex_tty.h"
367c478bd9Sstevel@tonic-gate #include "ex_vis.h"
37f6db9f27Scf #include <unistd.h>
387c478bd9Sstevel@tonic-gate
397c478bd9Sstevel@tonic-gate extern bool pflag, nflag; /* extern; also in ex_cmds.c */
407c478bd9Sstevel@tonic-gate extern int poffset; /* extern; also in ex_cmds.c */
417c478bd9Sstevel@tonic-gate extern short slevel; /* extern; has level of source() */
427c478bd9Sstevel@tonic-gate
437c478bd9Sstevel@tonic-gate /*
447c478bd9Sstevel@tonic-gate * Subroutines for major command loop.
457c478bd9Sstevel@tonic-gate */
467c478bd9Sstevel@tonic-gate
477c478bd9Sstevel@tonic-gate /*
487c478bd9Sstevel@tonic-gate * Is there a single letter indicating a named buffer next?
497c478bd9Sstevel@tonic-gate */
50f6db9f27Scf int
cmdreg(void)51f6db9f27Scf cmdreg(void)
527c478bd9Sstevel@tonic-gate {
53f6db9f27Scf int c = 0;
54f6db9f27Scf int wh = skipwh();
557c478bd9Sstevel@tonic-gate
567c478bd9Sstevel@tonic-gate #ifdef XPG4
577c478bd9Sstevel@tonic-gate if (wh && isalpha(c = peekchar()) && isascii(c) && !isdigit(c))
587c478bd9Sstevel@tonic-gate #else /* XPG4 */
597c478bd9Sstevel@tonic-gate if (wh && isalpha(c = peekchar()) && isascii(c))
607c478bd9Sstevel@tonic-gate #endif /* XPG4 */
617c478bd9Sstevel@tonic-gate c = getchar();
627c478bd9Sstevel@tonic-gate
637c478bd9Sstevel@tonic-gate #ifdef XPG4
647c478bd9Sstevel@tonic-gate if (isdigit(c)) {
657c478bd9Sstevel@tonic-gate c = 0;
667c478bd9Sstevel@tonic-gate }
677c478bd9Sstevel@tonic-gate #endif /* XPG4 */
687c478bd9Sstevel@tonic-gate return (c);
697c478bd9Sstevel@tonic-gate }
707c478bd9Sstevel@tonic-gate
717c478bd9Sstevel@tonic-gate /*
727c478bd9Sstevel@tonic-gate * Tell whether the character ends a command
737c478bd9Sstevel@tonic-gate */
74f6db9f27Scf int
endcmd(int ch)75f6db9f27Scf endcmd(int ch)
767c478bd9Sstevel@tonic-gate {
777c478bd9Sstevel@tonic-gate switch (ch) {
787c478bd9Sstevel@tonic-gate
797c478bd9Sstevel@tonic-gate case '\n':
807c478bd9Sstevel@tonic-gate case EOF:
817c478bd9Sstevel@tonic-gate endline = 1;
827c478bd9Sstevel@tonic-gate return (1);
837c478bd9Sstevel@tonic-gate
847c478bd9Sstevel@tonic-gate case '|':
857c478bd9Sstevel@tonic-gate case '"':
867c478bd9Sstevel@tonic-gate endline = 0;
877c478bd9Sstevel@tonic-gate return (1);
887c478bd9Sstevel@tonic-gate }
897c478bd9Sstevel@tonic-gate return (0);
907c478bd9Sstevel@tonic-gate }
917c478bd9Sstevel@tonic-gate
927c478bd9Sstevel@tonic-gate /*
937c478bd9Sstevel@tonic-gate * Insist on the end of the command.
947c478bd9Sstevel@tonic-gate */
95f6db9f27Scf void
eol(void)96f6db9f27Scf eol(void)
977c478bd9Sstevel@tonic-gate {
987c478bd9Sstevel@tonic-gate
997c478bd9Sstevel@tonic-gate if (!skipend())
1007c478bd9Sstevel@tonic-gate error(value(vi_TERSE) ? gettext("Extra chars") :
1017c478bd9Sstevel@tonic-gate gettext("Extra characters at end of command"));
1027c478bd9Sstevel@tonic-gate ignnEOF();
1037c478bd9Sstevel@tonic-gate }
1047c478bd9Sstevel@tonic-gate
1057c478bd9Sstevel@tonic-gate #ifdef XPG4
1067c478bd9Sstevel@tonic-gate /*
1077c478bd9Sstevel@tonic-gate * Print out the message in the error message file at str,
1087c478bd9Sstevel@tonic-gate * with i an integer argument to printf.
1097c478bd9Sstevel@tonic-gate */
1107c478bd9Sstevel@tonic-gate /*VARARGS2*/
111f6db9f27Scf void
error(str,i)1127c478bd9Sstevel@tonic-gate error(str, i)
113f6db9f27Scf unsigned char *str;
1147c478bd9Sstevel@tonic-gate int i;
1157c478bd9Sstevel@tonic-gate {
11668c92b9fScf tagflg = 0;
1177c478bd9Sstevel@tonic-gate errcnt++;
1187c478bd9Sstevel@tonic-gate noerror(str, i);
1197c478bd9Sstevel@tonic-gate }
1207c478bd9Sstevel@tonic-gate
1217c478bd9Sstevel@tonic-gate /*
122*2a8bcb4eSToomas Soome * noerror(): like error(), but doesn't inc errcnt.
1237c478bd9Sstevel@tonic-gate * the reason why we created this routine, instead of fixing up errcnt
1247c478bd9Sstevel@tonic-gate * after error() is called, is because we will do a longjmp, and
1257c478bd9Sstevel@tonic-gate * not a return. it does other things closing file i/o, reset, etc;
1267c478bd9Sstevel@tonic-gate * so we follow those procedures.
1277c478bd9Sstevel@tonic-gate */
1287c478bd9Sstevel@tonic-gate /*VARARGS2*/
129f6db9f27Scf void
noerror(str,i)1307c478bd9Sstevel@tonic-gate noerror(str, i)
131f6db9f27Scf unsigned char *str;
1327c478bd9Sstevel@tonic-gate int i;
1337c478bd9Sstevel@tonic-gate {
1347c478bd9Sstevel@tonic-gate
1357c478bd9Sstevel@tonic-gate error0();
1367c478bd9Sstevel@tonic-gate merror(str, i);
1377c478bd9Sstevel@tonic-gate if (writing) {
138f6db9f27Scf serror((unsigned char *)
139f6db9f27Scf gettext(" [Warning - %s is incomplete]"), file);
1407c478bd9Sstevel@tonic-gate writing = 0;
1417c478bd9Sstevel@tonic-gate }
1427c478bd9Sstevel@tonic-gate error1(str);
1437c478bd9Sstevel@tonic-gate }
1447c478bd9Sstevel@tonic-gate
1457c478bd9Sstevel@tonic-gate #else /* !XPG4 */
1467c478bd9Sstevel@tonic-gate /*
1477c478bd9Sstevel@tonic-gate * Print out the message in the error message file at str,
1487c478bd9Sstevel@tonic-gate * with i an integer argument to printf.
1497c478bd9Sstevel@tonic-gate */
1507c478bd9Sstevel@tonic-gate /*VARARGS2*/
151f6db9f27Scf void
error(str,i)1527c478bd9Sstevel@tonic-gate error(str, i)
153f6db9f27Scf unsigned char *str;
1547c478bd9Sstevel@tonic-gate int i;
1557c478bd9Sstevel@tonic-gate {
15668c92b9fScf tagflg = 0;
1577c478bd9Sstevel@tonic-gate errcnt++;
1587c478bd9Sstevel@tonic-gate error0();
1597c478bd9Sstevel@tonic-gate merror(str, i);
1607c478bd9Sstevel@tonic-gate if (writing) {
161f6db9f27Scf serror((unsigned char *)
162f6db9f27Scf gettext(" [Warning - %s is incomplete]"), file);
1637c478bd9Sstevel@tonic-gate writing = 0;
1647c478bd9Sstevel@tonic-gate }
1657c478bd9Sstevel@tonic-gate error1(str);
1667c478bd9Sstevel@tonic-gate }
1677c478bd9Sstevel@tonic-gate #endif /* XPG4 */
1687c478bd9Sstevel@tonic-gate
1697c478bd9Sstevel@tonic-gate /*
1707c478bd9Sstevel@tonic-gate * Rewind the argument list.
1717c478bd9Sstevel@tonic-gate */
172f6db9f27Scf void
erewind(void)173f6db9f27Scf erewind(void)
1747c478bd9Sstevel@tonic-gate {
1757c478bd9Sstevel@tonic-gate
1767c478bd9Sstevel@tonic-gate argc = argc0;
1777c478bd9Sstevel@tonic-gate argv = argv0;
1787c478bd9Sstevel@tonic-gate args = args0;
1797c478bd9Sstevel@tonic-gate if (argc > 1 && !hush && cur_term) {
180f6db9f27Scf viprintf(mesg(value(vi_TERSE) ? gettext("%d files") :
1817c478bd9Sstevel@tonic-gate gettext("%d files to edit")), argc);
1827c478bd9Sstevel@tonic-gate if (inopen)
1837c478bd9Sstevel@tonic-gate putchar(' ');
1847c478bd9Sstevel@tonic-gate else
1857c478bd9Sstevel@tonic-gate putNFL();
1867c478bd9Sstevel@tonic-gate }
1877c478bd9Sstevel@tonic-gate }
1887c478bd9Sstevel@tonic-gate
1897c478bd9Sstevel@tonic-gate /*
1907c478bd9Sstevel@tonic-gate * Guts of the pre-printing error processing.
1917c478bd9Sstevel@tonic-gate * If in visual and catching errors, then we don't mung up the internals,
1927c478bd9Sstevel@tonic-gate * just fixing up the echo area for the print.
1937c478bd9Sstevel@tonic-gate * Otherwise we reset a number of externals, and discard unused input.
1947c478bd9Sstevel@tonic-gate */
195f6db9f27Scf void
error0(void)196f6db9f27Scf error0(void)
1977c478bd9Sstevel@tonic-gate {
1987c478bd9Sstevel@tonic-gate
1997c478bd9Sstevel@tonic-gate if (laste) {
2007c478bd9Sstevel@tonic-gate #ifdef VMUNIX
2017c478bd9Sstevel@tonic-gate tlaste();
2027c478bd9Sstevel@tonic-gate #endif
2037c478bd9Sstevel@tonic-gate laste = 0;
2047c478bd9Sstevel@tonic-gate sync();
2057c478bd9Sstevel@tonic-gate }
2067c478bd9Sstevel@tonic-gate if (vcatch) {
2077c478bd9Sstevel@tonic-gate if (splitw == 0)
2087c478bd9Sstevel@tonic-gate fixech();
2097c478bd9Sstevel@tonic-gate if (!enter_standout_mode || !exit_bold)
2107c478bd9Sstevel@tonic-gate dingdong();
2117c478bd9Sstevel@tonic-gate return;
2127c478bd9Sstevel@tonic-gate }
2137c478bd9Sstevel@tonic-gate if (input) {
2147c478bd9Sstevel@tonic-gate input = strend(input) - 1;
2157c478bd9Sstevel@tonic-gate if (*input == '\n')
2167c478bd9Sstevel@tonic-gate setlastchar('\n');
2177c478bd9Sstevel@tonic-gate input = 0;
2187c478bd9Sstevel@tonic-gate }
2197c478bd9Sstevel@tonic-gate setoutt();
2207c478bd9Sstevel@tonic-gate flush();
2217c478bd9Sstevel@tonic-gate resetflav();
2227c478bd9Sstevel@tonic-gate if (!enter_standout_mode || !exit_bold)
2237c478bd9Sstevel@tonic-gate dingdong();
2247c478bd9Sstevel@tonic-gate if (inopen) {
2257c478bd9Sstevel@tonic-gate /*
2267c478bd9Sstevel@tonic-gate * We are coming out of open/visual ungracefully.
2277c478bd9Sstevel@tonic-gate * Restore columns, undo, and fix tty mode.
2287c478bd9Sstevel@tonic-gate */
2297c478bd9Sstevel@tonic-gate columns = OCOLUMNS;
2307c478bd9Sstevel@tonic-gate undvis();
2317c478bd9Sstevel@tonic-gate ostop(normf);
2327c478bd9Sstevel@tonic-gate /* ostop should be doing this
2337c478bd9Sstevel@tonic-gate putpad(cursor_normal);
2347c478bd9Sstevel@tonic-gate putpad(key_eol);
2357c478bd9Sstevel@tonic-gate */
2367c478bd9Sstevel@tonic-gate putnl();
2377c478bd9Sstevel@tonic-gate }
2387c478bd9Sstevel@tonic-gate inopen = 0;
2397c478bd9Sstevel@tonic-gate holdcm = 0;
2407c478bd9Sstevel@tonic-gate }
2417c478bd9Sstevel@tonic-gate
2427c478bd9Sstevel@tonic-gate /*
2437c478bd9Sstevel@tonic-gate * Post error printing processing.
2447c478bd9Sstevel@tonic-gate * Close the i/o file if left open.
2457c478bd9Sstevel@tonic-gate * If catching in visual then throw to the visual catch,
2467c478bd9Sstevel@tonic-gate * else if a child after a fork, then exit.
2477c478bd9Sstevel@tonic-gate * Otherwise, in the normal command mode error case,
2487c478bd9Sstevel@tonic-gate * finish state reset, and throw to top.
2497c478bd9Sstevel@tonic-gate */
250f6db9f27Scf void
error1(unsigned char * str)251f6db9f27Scf error1(unsigned char *str)
2527c478bd9Sstevel@tonic-gate {
2537c478bd9Sstevel@tonic-gate bool die;
2547c478bd9Sstevel@tonic-gate extern short ttyindes;
2557c478bd9Sstevel@tonic-gate
2567c478bd9Sstevel@tonic-gate if ((io > 0) && (io != ttyindes)) {
2577c478bd9Sstevel@tonic-gate close(io);
2587c478bd9Sstevel@tonic-gate io = -1;
2597c478bd9Sstevel@tonic-gate }
260*2a8bcb4eSToomas Soome
2617c478bd9Sstevel@tonic-gate die = (getpid() != ppid); /* Only children die */
2627c478bd9Sstevel@tonic-gate inappend = inglobal = 0;
2637c478bd9Sstevel@tonic-gate globp = vglobp = vmacp = 0;
2647c478bd9Sstevel@tonic-gate if (vcatch && !die) {
2657c478bd9Sstevel@tonic-gate inopen = 1;
2667c478bd9Sstevel@tonic-gate vcatch = 0;
2677c478bd9Sstevel@tonic-gate if (str)
2687c478bd9Sstevel@tonic-gate noonl();
2697c478bd9Sstevel@tonic-gate fixol();
2707c478bd9Sstevel@tonic-gate if (slevel > 0)
2717c478bd9Sstevel@tonic-gate reset();
2727c478bd9Sstevel@tonic-gate longjmp(vreslab,1);
2737c478bd9Sstevel@tonic-gate }
2747c478bd9Sstevel@tonic-gate if (str && !vcatch)
2757c478bd9Sstevel@tonic-gate putNFL();
2767c478bd9Sstevel@tonic-gate if (die)
2777c478bd9Sstevel@tonic-gate exit(++errcnt);
2787c478bd9Sstevel@tonic-gate lseek(0, 0L, 2);
2797c478bd9Sstevel@tonic-gate if (inglobal)
2807c478bd9Sstevel@tonic-gate setlastchar('\n');
2817c478bd9Sstevel@tonic-gate
2827c478bd9Sstevel@tonic-gate if (inexrc) {
283f2f27852Scf /*
284f2f27852Scf * Set inexrc to 0 so that this error is printed only
285f2f27852Scf * once (eg. when stdin is redirected from /dev/null and
286f2f27852Scf * vi prints "Input read error" because it is unable to
287f2f27852Scf * read() the <CR>).
288f2f27852Scf */
289f2f27852Scf inexrc = 0;
290f2f27852Scf lprintf(gettext(
291f2f27852Scf "Error detected in .exrc.[Hit return to continue] "),
292f2f27852Scf 0);
293f2f27852Scf putNFL();
294f2f27852Scf getkey();
2957c478bd9Sstevel@tonic-gate }
2967c478bd9Sstevel@tonic-gate
2977c478bd9Sstevel@tonic-gate while ((lastchar() != '\n') && (lastchar() != EOF))
2987c478bd9Sstevel@tonic-gate ignchar();
2997c478bd9Sstevel@tonic-gate ungetchar(0);
3007c478bd9Sstevel@tonic-gate endline = 1;
3017c478bd9Sstevel@tonic-gate reset();
3027c478bd9Sstevel@tonic-gate }
3037c478bd9Sstevel@tonic-gate
304f6db9f27Scf void
fixol(void)305f6db9f27Scf fixol(void)
3067c478bd9Sstevel@tonic-gate {
3077c478bd9Sstevel@tonic-gate if (Outchar != vputchar) {
3087c478bd9Sstevel@tonic-gate flush();
3097c478bd9Sstevel@tonic-gate if (state == ONEOPEN || state == HARDOPEN)
3107c478bd9Sstevel@tonic-gate outline = destline = 0;
3117c478bd9Sstevel@tonic-gate Outchar = vputchar;
3127c478bd9Sstevel@tonic-gate vcontin(1);
3137c478bd9Sstevel@tonic-gate /*
314*2a8bcb4eSToomas Soome * Outchar could be set to termchar() through vcontin().
3157c478bd9Sstevel@tonic-gate * So reset it again.
3167c478bd9Sstevel@tonic-gate */
3177c478bd9Sstevel@tonic-gate Outchar = vputchar;
3187c478bd9Sstevel@tonic-gate } else {
3197c478bd9Sstevel@tonic-gate if (destcol)
3207c478bd9Sstevel@tonic-gate vclreol();
3217c478bd9Sstevel@tonic-gate vclean();
3227c478bd9Sstevel@tonic-gate }
3237c478bd9Sstevel@tonic-gate }
3247c478bd9Sstevel@tonic-gate
3257c478bd9Sstevel@tonic-gate /*
3267c478bd9Sstevel@tonic-gate * Does an ! character follow in the command stream?
3277c478bd9Sstevel@tonic-gate */
328f6db9f27Scf int
exclam(void)329f6db9f27Scf exclam(void)
3307c478bd9Sstevel@tonic-gate {
3317c478bd9Sstevel@tonic-gate
3327c478bd9Sstevel@tonic-gate if (peekchar() == '!') {
3337c478bd9Sstevel@tonic-gate ignchar();
3347c478bd9Sstevel@tonic-gate return (1);
3357c478bd9Sstevel@tonic-gate }
3367c478bd9Sstevel@tonic-gate return (0);
3377c478bd9Sstevel@tonic-gate }
3387c478bd9Sstevel@tonic-gate
3397c478bd9Sstevel@tonic-gate /*
3407c478bd9Sstevel@tonic-gate * Make an argument list for e.g. next.
3417c478bd9Sstevel@tonic-gate */
342f6db9f27Scf void
makargs(void)343f6db9f27Scf makargs(void)
3447c478bd9Sstevel@tonic-gate {
3457c478bd9Sstevel@tonic-gate
3467c478bd9Sstevel@tonic-gate glob(&frob);
3477c478bd9Sstevel@tonic-gate argc0 = frob.argc0;
3487c478bd9Sstevel@tonic-gate argv0 = frob.argv;
3497c478bd9Sstevel@tonic-gate args0 = argv0[0];
3507c478bd9Sstevel@tonic-gate erewind();
3517c478bd9Sstevel@tonic-gate }
3527c478bd9Sstevel@tonic-gate
3537c478bd9Sstevel@tonic-gate /*
3547c478bd9Sstevel@tonic-gate * Advance to next file in argument list.
3557c478bd9Sstevel@tonic-gate */
356f6db9f27Scf void
next(void)357f6db9f27Scf next(void)
3587c478bd9Sstevel@tonic-gate {
3597c478bd9Sstevel@tonic-gate extern short isalt; /* defined in ex_io.c */
3607c478bd9Sstevel@tonic-gate
3617c478bd9Sstevel@tonic-gate if (argc == 0)
362f6db9f27Scf error(value(vi_TERSE) ?
363f6db9f27Scf (unsigned char *)gettext("No more files") :
364f6db9f27Scf (unsigned char *)gettext("No more files to edit"));
3657c478bd9Sstevel@tonic-gate morargc = argc;
3667c478bd9Sstevel@tonic-gate isalt = (strcmp(altfile, args)==0) + 1;
3677c478bd9Sstevel@tonic-gate if (savedfile[0])
3687c478bd9Sstevel@tonic-gate CP(altfile, savedfile);
3697c478bd9Sstevel@tonic-gate (void) strlcpy(savedfile, args, sizeof (savedfile));
3707c478bd9Sstevel@tonic-gate argc--;
3717c478bd9Sstevel@tonic-gate args = argv ? *++argv : strend(args) + 1;
3727c478bd9Sstevel@tonic-gate #if i386 || i286
3737c478bd9Sstevel@tonic-gate destcol = 0;
3747c478bd9Sstevel@tonic-gate #endif
3757c478bd9Sstevel@tonic-gate }
3767c478bd9Sstevel@tonic-gate
3777c478bd9Sstevel@tonic-gate /*
3787c478bd9Sstevel@tonic-gate * Eat trailing flags and offsets after a command,
3797c478bd9Sstevel@tonic-gate * saving for possible later post-command prints.
3807c478bd9Sstevel@tonic-gate */
381f6db9f27Scf void
donewline(void)382f6db9f27Scf donewline(void)
3837c478bd9Sstevel@tonic-gate {
384f6db9f27Scf int c;
3857c478bd9Sstevel@tonic-gate
3867c478bd9Sstevel@tonic-gate resetflav();
3877c478bd9Sstevel@tonic-gate for (;;) {
3887c478bd9Sstevel@tonic-gate c = getchar();
3897c478bd9Sstevel@tonic-gate switch (c) {
3907c478bd9Sstevel@tonic-gate
3917c478bd9Sstevel@tonic-gate case '^':
3927c478bd9Sstevel@tonic-gate case '-':
3937c478bd9Sstevel@tonic-gate poffset--;
3947c478bd9Sstevel@tonic-gate break;
3957c478bd9Sstevel@tonic-gate
3967c478bd9Sstevel@tonic-gate case '+':
3977c478bd9Sstevel@tonic-gate poffset++;
3987c478bd9Sstevel@tonic-gate break;
3997c478bd9Sstevel@tonic-gate
4007c478bd9Sstevel@tonic-gate case 'l':
4017c478bd9Sstevel@tonic-gate listf++;
4027c478bd9Sstevel@tonic-gate break;
4037c478bd9Sstevel@tonic-gate
4047c478bd9Sstevel@tonic-gate case '#':
4057c478bd9Sstevel@tonic-gate nflag++;
4067c478bd9Sstevel@tonic-gate break;
4077c478bd9Sstevel@tonic-gate
4087c478bd9Sstevel@tonic-gate case 'p':
4097c478bd9Sstevel@tonic-gate listf = 0;
4107c478bd9Sstevel@tonic-gate break;
4117c478bd9Sstevel@tonic-gate
4127c478bd9Sstevel@tonic-gate case ' ':
4137c478bd9Sstevel@tonic-gate case '\t':
4147c478bd9Sstevel@tonic-gate continue;
4157c478bd9Sstevel@tonic-gate
4167c478bd9Sstevel@tonic-gate case '"':
4177c478bd9Sstevel@tonic-gate comment();
4187c478bd9Sstevel@tonic-gate setflav();
4197c478bd9Sstevel@tonic-gate return;
4207c478bd9Sstevel@tonic-gate
4217c478bd9Sstevel@tonic-gate default:
4227c478bd9Sstevel@tonic-gate if (!endcmd(c))
423f6db9f27Scf serror(value(vi_TERSE) ?
424f6db9f27Scf (unsigned char *)gettext("Extra chars") :
425f6db9f27Scf (unsigned char *)gettext(
426f6db9f27Scf "Extra characters at end of \"%s\" command"),
427f6db9f27Scf Command);
4287c478bd9Sstevel@tonic-gate if (c == EOF)
4297c478bd9Sstevel@tonic-gate ungetchar(c);
4307c478bd9Sstevel@tonic-gate setflav();
4317c478bd9Sstevel@tonic-gate return;
4327c478bd9Sstevel@tonic-gate }
4337c478bd9Sstevel@tonic-gate pflag++;
4347c478bd9Sstevel@tonic-gate }
4357c478bd9Sstevel@tonic-gate }
4367c478bd9Sstevel@tonic-gate
4377c478bd9Sstevel@tonic-gate /*
4387c478bd9Sstevel@tonic-gate * Before quit or respec of arg list, check that there are
4397c478bd9Sstevel@tonic-gate * no more files in the arg list.
4407c478bd9Sstevel@tonic-gate */
441f6db9f27Scf int
nomore(void)442f6db9f27Scf nomore(void)
4437c478bd9Sstevel@tonic-gate {
4447c478bd9Sstevel@tonic-gate
4457c478bd9Sstevel@tonic-gate if (argc == 0 || morargc == argc)
4467c478bd9Sstevel@tonic-gate return(0);
4477c478bd9Sstevel@tonic-gate morargc = argc;
4487c478bd9Sstevel@tonic-gate if (argc == 1) {
4497c478bd9Sstevel@tonic-gate merror(value(vi_TERSE) ? gettext("1 more file") :
4507c478bd9Sstevel@tonic-gate gettext("1 more file to edit"), argc);
4517c478bd9Sstevel@tonic-gate } else {
4527c478bd9Sstevel@tonic-gate merror(value(vi_TERSE) ? gettext("%d more files") :
4537c478bd9Sstevel@tonic-gate gettext("%d more files to edit"), argc);
4547c478bd9Sstevel@tonic-gate }
4557c478bd9Sstevel@tonic-gate return(1);
4567c478bd9Sstevel@tonic-gate }
4577c478bd9Sstevel@tonic-gate
4587c478bd9Sstevel@tonic-gate /*
4597c478bd9Sstevel@tonic-gate * Before edit of new file check that either an ! follows
4607c478bd9Sstevel@tonic-gate * or the file has not been changed.
4617c478bd9Sstevel@tonic-gate */
462f6db9f27Scf int
quickly(void)463f6db9f27Scf quickly(void)
4647c478bd9Sstevel@tonic-gate {
4657c478bd9Sstevel@tonic-gate
4667c478bd9Sstevel@tonic-gate if (exclam())
4677c478bd9Sstevel@tonic-gate return (1);
4687c478bd9Sstevel@tonic-gate if (chng && dol > zero) {
4697c478bd9Sstevel@tonic-gate /*
4707c478bd9Sstevel@tonic-gate chng = 0;
4717c478bd9Sstevel@tonic-gate */
4727c478bd9Sstevel@tonic-gate xchng = 0;
473f6db9f27Scf error(value(vi_TERSE) ? (unsigned char *)gettext("No write") :
474f6db9f27Scf (unsigned char *)
475f6db9f27Scf gettext("No write since last change (:%s! overrides)"),
476f6db9f27Scf Command);
4777c478bd9Sstevel@tonic-gate }
4787c478bd9Sstevel@tonic-gate return (0);
4797c478bd9Sstevel@tonic-gate }
4807c478bd9Sstevel@tonic-gate
4817c478bd9Sstevel@tonic-gate /*
4827c478bd9Sstevel@tonic-gate * Reset the flavor of the output to print mode with no numbering.
4837c478bd9Sstevel@tonic-gate */
484f6db9f27Scf void
resetflav(void)485f6db9f27Scf resetflav(void)
4867c478bd9Sstevel@tonic-gate {
4877c478bd9Sstevel@tonic-gate
4887c478bd9Sstevel@tonic-gate if (inopen)
4897c478bd9Sstevel@tonic-gate return;
4907c478bd9Sstevel@tonic-gate listf = 0;
4917c478bd9Sstevel@tonic-gate nflag = 0;
4927c478bd9Sstevel@tonic-gate pflag = 0;
4937c478bd9Sstevel@tonic-gate poffset = 0;
4947c478bd9Sstevel@tonic-gate setflav();
4957c478bd9Sstevel@tonic-gate }
4967c478bd9Sstevel@tonic-gate
4977c478bd9Sstevel@tonic-gate /*
4987c478bd9Sstevel@tonic-gate * Print an error message with a %s type argument to printf.
4997c478bd9Sstevel@tonic-gate * Message text comes from error message file.
5007c478bd9Sstevel@tonic-gate */
501f6db9f27Scf void
serror(unsigned char * str,unsigned char * cp)502f6db9f27Scf serror(unsigned char *str, unsigned char *cp)
5037c478bd9Sstevel@tonic-gate {
50468c92b9fScf tagflg = 0;
5057c478bd9Sstevel@tonic-gate error0();
5067c478bd9Sstevel@tonic-gate smerror(str, cp);
5077c478bd9Sstevel@tonic-gate error1(str);
5087c478bd9Sstevel@tonic-gate }
5097c478bd9Sstevel@tonic-gate
5107c478bd9Sstevel@tonic-gate /*
5117c478bd9Sstevel@tonic-gate * Set the flavor of the output based on the flags given
5127c478bd9Sstevel@tonic-gate * and the number and list options to either number or not number lines
5137c478bd9Sstevel@tonic-gate * and either use normally decoded (ARPAnet standard) characters or list mode,
5147c478bd9Sstevel@tonic-gate * where end of lines are marked and tabs print as ^I.
5157c478bd9Sstevel@tonic-gate */
516f6db9f27Scf void
setflav(void)517f6db9f27Scf setflav(void)
5187c478bd9Sstevel@tonic-gate {
5197c478bd9Sstevel@tonic-gate
5207c478bd9Sstevel@tonic-gate if (inopen)
5217c478bd9Sstevel@tonic-gate return;
5227c478bd9Sstevel@tonic-gate setnumb(nflag || value(vi_NUMBER));
5237c478bd9Sstevel@tonic-gate setlist(listf || value(vi_LIST));
5247c478bd9Sstevel@tonic-gate if (!inopen)
5257c478bd9Sstevel@tonic-gate setoutt();
5267c478bd9Sstevel@tonic-gate }
5277c478bd9Sstevel@tonic-gate
5287c478bd9Sstevel@tonic-gate /*
5297c478bd9Sstevel@tonic-gate * Skip white space and tell whether command ends then.
5307c478bd9Sstevel@tonic-gate */
531f6db9f27Scf int
skipend(void)532f6db9f27Scf skipend(void)
5337c478bd9Sstevel@tonic-gate {
5347c478bd9Sstevel@tonic-gate
5357c478bd9Sstevel@tonic-gate pastwh();
5367c478bd9Sstevel@tonic-gate return (endcmd(peekchar()) && peekchar() != '"');
5377c478bd9Sstevel@tonic-gate }
5387c478bd9Sstevel@tonic-gate
5397c478bd9Sstevel@tonic-gate /*
5407c478bd9Sstevel@tonic-gate * Set the command name for non-word commands.
5417c478bd9Sstevel@tonic-gate */
542f6db9f27Scf void
tailspec(int c)543f6db9f27Scf tailspec(int c)
5447c478bd9Sstevel@tonic-gate {
5457c478bd9Sstevel@tonic-gate static unsigned char foocmd[2];
5467c478bd9Sstevel@tonic-gate
5477c478bd9Sstevel@tonic-gate foocmd[0] = c;
5487c478bd9Sstevel@tonic-gate Command = foocmd;
5497c478bd9Sstevel@tonic-gate }
5507c478bd9Sstevel@tonic-gate
5517c478bd9Sstevel@tonic-gate /*
5527c478bd9Sstevel@tonic-gate * Try to read off the rest of the command word.
5537c478bd9Sstevel@tonic-gate * If alphabetics follow, then this is not the command we seek.
5547c478bd9Sstevel@tonic-gate */
555f6db9f27Scf void
tail(unsigned char * comm)556f6db9f27Scf tail(unsigned char *comm)
5577c478bd9Sstevel@tonic-gate {
5587c478bd9Sstevel@tonic-gate
5597c478bd9Sstevel@tonic-gate tailprim(comm, 1, 0);
5607c478bd9Sstevel@tonic-gate }
5617c478bd9Sstevel@tonic-gate
562f6db9f27Scf void
tail2of(unsigned char * comm)563f6db9f27Scf tail2of(unsigned char *comm)
5647c478bd9Sstevel@tonic-gate {
5657c478bd9Sstevel@tonic-gate
5667c478bd9Sstevel@tonic-gate tailprim(comm, 2, 0);
5677c478bd9Sstevel@tonic-gate }
5687c478bd9Sstevel@tonic-gate
5697c478bd9Sstevel@tonic-gate unsigned char tcommand[20];
5707c478bd9Sstevel@tonic-gate
571f6db9f27Scf void
tailprim(unsigned char * comm,int i,bool notinvis)572f6db9f27Scf tailprim(unsigned char *comm, int i, bool notinvis)
5737c478bd9Sstevel@tonic-gate {
574f6db9f27Scf unsigned char *cp;
575f6db9f27Scf int c;
5767c478bd9Sstevel@tonic-gate
5777c478bd9Sstevel@tonic-gate Command = comm;
5787c478bd9Sstevel@tonic-gate for (cp = tcommand; i > 0; i--)
5797c478bd9Sstevel@tonic-gate *cp++ = *comm++;
5807c478bd9Sstevel@tonic-gate while (*comm && peekchar() == *comm)
5817c478bd9Sstevel@tonic-gate *cp++ = getchar(), comm++;
5827c478bd9Sstevel@tonic-gate c = peekchar();
5837c478bd9Sstevel@tonic-gate if (notinvis || (isalpha(c) && isascii(c))) {
5847c478bd9Sstevel@tonic-gate /*
5857c478bd9Sstevel@tonic-gate * Of the trailing lp funny business, only dl and dp
5867c478bd9Sstevel@tonic-gate * survive the move from ed to ex.
5877c478bd9Sstevel@tonic-gate */
5887c478bd9Sstevel@tonic-gate if (tcommand[0] == 'd' && any(c, "lp"))
5897c478bd9Sstevel@tonic-gate goto ret;
5907c478bd9Sstevel@tonic-gate if (tcommand[0] == 's' && any(c, "gcr"))
5917c478bd9Sstevel@tonic-gate goto ret;
5927c478bd9Sstevel@tonic-gate while (cp < &tcommand[19] && isalpha(c = peekchar()) && isascii(c))
5937c478bd9Sstevel@tonic-gate *cp++ = getchar();
5947c478bd9Sstevel@tonic-gate *cp = 0;
5957c478bd9Sstevel@tonic-gate if (notinvis)
596f6db9f27Scf serror(value(vi_TERSE) ?
597f6db9f27Scf (unsigned char *)gettext("What?") :
598f6db9f27Scf (unsigned char *)gettext(
599f6db9f27Scf "%s: No such command from open/visual"), tcommand);
6007c478bd9Sstevel@tonic-gate else
601f6db9f27Scf serror(value(vi_TERSE) ?
602f6db9f27Scf (unsigned char *)gettext("What?") :
603f6db9f27Scf (unsigned char *)gettext(
604f6db9f27Scf "%s: Not an editor command"), tcommand);
6057c478bd9Sstevel@tonic-gate }
6067c478bd9Sstevel@tonic-gate ret:
6077c478bd9Sstevel@tonic-gate *cp = 0;
6087c478bd9Sstevel@tonic-gate }
6097c478bd9Sstevel@tonic-gate
6107c478bd9Sstevel@tonic-gate /*
6117c478bd9Sstevel@tonic-gate * Continue after a : command from open/visual.
6127c478bd9Sstevel@tonic-gate */
613f6db9f27Scf void
vcontin(bool ask)614f6db9f27Scf vcontin(bool ask)
6157c478bd9Sstevel@tonic-gate {
6167c478bd9Sstevel@tonic-gate
6177c478bd9Sstevel@tonic-gate if (vcnt > 0)
6187c478bd9Sstevel@tonic-gate vcnt = -vcnt;
6197c478bd9Sstevel@tonic-gate if (inopen) {
6207c478bd9Sstevel@tonic-gate if (state != VISUAL) {
6217c478bd9Sstevel@tonic-gate /*
6227c478bd9Sstevel@tonic-gate * We don't know what a shell command may have left on
6237c478bd9Sstevel@tonic-gate * the screen, so we move the cursor to the right place
6247c478bd9Sstevel@tonic-gate * and then put out a newline. But this makes an extra
6257c478bd9Sstevel@tonic-gate * blank line most of the time so we only do it for :sh
6267c478bd9Sstevel@tonic-gate * since the prompt gets left on the screen.
6277c478bd9Sstevel@tonic-gate *
6287c478bd9Sstevel@tonic-gate * BUG: :!echo longer than current line \\c
6297c478bd9Sstevel@tonic-gate * will mess it up.
6307c478bd9Sstevel@tonic-gate */
6317c478bd9Sstevel@tonic-gate if (state == CRTOPEN) {
6327c478bd9Sstevel@tonic-gate termreset();
6337c478bd9Sstevel@tonic-gate vgoto(WECHO, 0);
6347c478bd9Sstevel@tonic-gate }
6357c478bd9Sstevel@tonic-gate if (!ask) {
636f6db9f27Scf (void) putch('\r');
637f6db9f27Scf (void) putch('\n');
6387c478bd9Sstevel@tonic-gate }
6397c478bd9Sstevel@tonic-gate return;
6407c478bd9Sstevel@tonic-gate }
6417c478bd9Sstevel@tonic-gate if (ask) {
6427c478bd9Sstevel@tonic-gate merror(gettext("[Hit return to continue] "));
6437c478bd9Sstevel@tonic-gate flush();
6447c478bd9Sstevel@tonic-gate }
6457c478bd9Sstevel@tonic-gate #ifndef CBREAK
6467c478bd9Sstevel@tonic-gate vraw();
6477c478bd9Sstevel@tonic-gate #endif
6487c478bd9Sstevel@tonic-gate if (ask) {
6497c478bd9Sstevel@tonic-gate #ifdef notdef
6507c478bd9Sstevel@tonic-gate /*
6517c478bd9Sstevel@tonic-gate * Gobble ^Q/^S since the tty driver should be eating
6527c478bd9Sstevel@tonic-gate * them (as far as the user can see)
6537c478bd9Sstevel@tonic-gate */
6547c478bd9Sstevel@tonic-gate while (peekkey() == CTRL('Q') || peekkey() == CTRL('S'))
6557c478bd9Sstevel@tonic-gate ignore(getkey());
6567c478bd9Sstevel@tonic-gate #endif
6577c478bd9Sstevel@tonic-gate if(getkey() == ':') {
6587c478bd9Sstevel@tonic-gate /* Extra newlines, but no other way */
659f6db9f27Scf (void) putch('\n');
6607c478bd9Sstevel@tonic-gate outline = WECHO;
6617c478bd9Sstevel@tonic-gate ungetkey(':');
6627c478bd9Sstevel@tonic-gate }
6637c478bd9Sstevel@tonic-gate }
6647c478bd9Sstevel@tonic-gate vclrech(1);
6657c478bd9Sstevel@tonic-gate if (Peekkey != ':') {
6667c478bd9Sstevel@tonic-gate fixterm();
667f6db9f27Scf putpad((unsigned char *)enter_ca_mode);
6687c478bd9Sstevel@tonic-gate tostart();
6697c478bd9Sstevel@tonic-gate }
6707c478bd9Sstevel@tonic-gate }
6717c478bd9Sstevel@tonic-gate }
6727c478bd9Sstevel@tonic-gate
6737c478bd9Sstevel@tonic-gate /*
6747c478bd9Sstevel@tonic-gate * Put out a newline (before a shell escape)
6757c478bd9Sstevel@tonic-gate * if in open/visual.
6767c478bd9Sstevel@tonic-gate */
677f6db9f27Scf void
vnfl(void)678f6db9f27Scf vnfl(void)
6797c478bd9Sstevel@tonic-gate {
6807c478bd9Sstevel@tonic-gate
6817c478bd9Sstevel@tonic-gate if (inopen) {
6827c478bd9Sstevel@tonic-gate if (state != VISUAL && state != CRTOPEN && destline <= WECHO)
6837c478bd9Sstevel@tonic-gate vclean();
6847c478bd9Sstevel@tonic-gate else
6857c478bd9Sstevel@tonic-gate vmoveitup(1, 0);
6867c478bd9Sstevel@tonic-gate vgoto(WECHO, 0);
6877c478bd9Sstevel@tonic-gate vclrbyte(vtube[WECHO], WCOLS);
6887c478bd9Sstevel@tonic-gate tostop();
6897c478bd9Sstevel@tonic-gate /* replaced by the ostop above
6907c478bd9Sstevel@tonic-gate putpad(cursor_normal);
6917c478bd9Sstevel@tonic-gate putpad(key_eol);
6927c478bd9Sstevel@tonic-gate */
6937c478bd9Sstevel@tonic-gate }
6947c478bd9Sstevel@tonic-gate flush();
6957c478bd9Sstevel@tonic-gate }
696