4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
30 /* Copyright (c) 1981 Regents of the University of California */
32 #pragma ident "%Z%%M% %I% %E% SMI"
41 extern bool pflag
, nflag
; /* extern; also in ex_cmds.c */
42 extern int poffset
; /* extern; also in ex_cmds.c */
43 extern short slevel
; /* extern; has level of source() */
46 * Subroutines for major command loop.
50 * Is there a single letter indicating a named buffer next?
59 if (wh
&& isalpha(c
= peekchar()) && isascii(c
) && !isdigit(c
))
61 if (wh
&& isalpha(c
= peekchar()) && isascii(c
))
74 * Tell whether the character ends a command
95 * Insist on the end of the command.
102 error(value(vi_TERSE
) ? gettext("Extra chars") :
103 gettext("Extra characters at end of command"));
109 * Print out the message in the error message file at str,
110 * with i an integer argument to printf.
124 * noerror(): like error(), but doesn't inc errcnt.
125 * the reason why we created this routine, instead of fixing up errcnt
126 * after error() is called, is because we will do a longjmp, and
127 * not a return. it does other things closing file i/o, reset, etc;
128 * so we follow those procedures.
140 serror((unsigned char *)
141 gettext(" [Warning - %s is incomplete]"), file
);
149 * Print out the message in the error message file at str,
150 * with i an integer argument to printf.
163 serror((unsigned char *)
164 gettext(" [Warning - %s is incomplete]"), file
);
172 * Rewind the argument list.
181 if (argc
> 1 && !hush
&& cur_term
) {
182 viprintf(mesg(value(vi_TERSE
) ? gettext("%d files") :
183 gettext("%d files to edit")), argc
);
192 * Guts of the pre-printing error processing.
193 * If in visual and catching errors, then we don't mung up the internals,
194 * just fixing up the echo area for the print.
195 * Otherwise we reset a number of externals, and discard unused input.
211 if (!enter_standout_mode
|| !exit_bold
)
216 input
= strend(input
) - 1;
224 if (!enter_standout_mode
|| !exit_bold
)
228 * We are coming out of open/visual ungracefully.
229 * Restore columns, undo, and fix tty mode.
234 /* ostop should be doing this
235 putpad(cursor_normal);
245 * Post error printing processing.
246 * Close the i/o file if left open.
247 * If catching in visual then throw to the visual catch,
248 * else if a child after a fork, then exit.
249 * Otherwise, in the normal command mode error case,
250 * finish state reset, and throw to top.
253 error1(unsigned char *str
)
256 extern short ttyindes
;
258 if ((io
> 0) && (io
!= ttyindes
)) {
263 die
= (getpid() != ppid
); /* Only children die */
264 inappend
= inglobal
= 0;
265 globp
= vglobp
= vmacp
= 0;
266 if (vcatch
&& !die
) {
286 * Set inexrc to 0 so that this error is printed only
287 * once (eg. when stdin is redirected from /dev/null and
288 * vi prints "Input read error" because it is unable to
293 "Error detected in .exrc.[Hit return to continue] "),
299 while ((lastchar() != '\n') && (lastchar() != EOF
))
309 if (Outchar
!= vputchar
) {
311 if (state
== ONEOPEN
|| state
== HARDOPEN
)
312 outline
= destline
= 0;
316 * Outchar could be set to termchar() through vcontin().
328 * Does an ! character follow in the command stream?
334 if (peekchar() == '!') {
342 * Make an argument list for e.g. next.
356 * Advance to next file in argument list.
361 extern short isalt
; /* defined in ex_io.c */
364 error(value(vi_TERSE
) ?
365 (unsigned char *)gettext("No more files") :
366 (unsigned char *)gettext("No more files to edit"));
368 isalt
= (strcmp(altfile
, args
)==0) + 1;
370 CP(altfile
, savedfile
);
371 (void) strlcpy(savedfile
, args
, sizeof (savedfile
));
373 args
= argv
? *++argv
: strend(args
) + 1;
380 * Eat trailing flags and offsets after a command,
381 * saving for possible later post-command prints.
425 serror(value(vi_TERSE
) ?
426 (unsigned char *)gettext("Extra chars") :
427 (unsigned char *)gettext(
428 "Extra characters at end of \"%s\" command"),
440 * Before quit or respec of arg list, check that there are
441 * no more files in the arg list.
447 if (argc
== 0 || morargc
== argc
)
451 merror(value(vi_TERSE
) ? gettext("1 more file") :
452 gettext("1 more file to edit"), argc
);
454 merror(value(vi_TERSE
) ? gettext("%d more files") :
455 gettext("%d more files to edit"), argc
);
461 * Before edit of new file check that either an ! follows
462 * or the file has not been changed.
470 if (chng
&& dol
> zero
) {
475 error(value(vi_TERSE
) ? (unsigned char *)gettext("No write") :
477 gettext("No write since last change (:%s! overrides)"),
484 * Reset the flavor of the output to print mode with no numbering.
500 * Print an error message with a %s type argument to printf.
501 * Message text comes from error message file.
504 serror(unsigned char *str
, unsigned char *cp
)
513 * Set the flavor of the output based on the flags given
514 * and the number and list options to either number or not number lines
515 * and either use normally decoded (ARPAnet standard) characters or list mode,
516 * where end of lines are marked and tabs print as ^I.
524 setnumb(nflag
|| value(vi_NUMBER
));
525 setlist(listf
|| value(vi_LIST
));
531 * Skip white space and tell whether command ends then.
538 return (endcmd(peekchar()) && peekchar() != '"');
542 * Set the command name for non-word commands.
547 static unsigned char foocmd
[2];
554 * Try to read off the rest of the command word.
555 * If alphabetics follow, then this is not the command we seek.
558 tail(unsigned char *comm
)
561 tailprim(comm
, 1, 0);
565 tail2of(unsigned char *comm
)
568 tailprim(comm
, 2, 0);
571 unsigned char tcommand
[20];
574 tailprim(unsigned char *comm
, int i
, bool notinvis
)
580 for (cp
= tcommand
; i
> 0; i
--)
582 while (*comm
&& peekchar() == *comm
)
583 *cp
++ = getchar(), comm
++;
585 if (notinvis
|| (isalpha(c
) && isascii(c
))) {
587 * Of the trailing lp funny business, only dl and dp
588 * survive the move from ed to ex.
590 if (tcommand
[0] == 'd' && any(c
, "lp"))
592 if (tcommand
[0] == 's' && any(c
, "gcr"))
594 while (cp
< &tcommand
[19] && isalpha(c
= peekchar()) && isascii(c
))
598 serror(value(vi_TERSE
) ?
599 (unsigned char *)gettext("What?") :
600 (unsigned char *)gettext(
601 "%s: No such command from open/visual"), tcommand
);
603 serror(value(vi_TERSE
) ?
604 (unsigned char *)gettext("What?") :
605 (unsigned char *)gettext(
606 "%s: Not an editor command"), tcommand
);
613 * Continue after a : command from open/visual.
622 if (state
!= VISUAL
) {
624 * We don't know what a shell command may have left on
625 * the screen, so we move the cursor to the right place
626 * and then put out a newline. But this makes an extra
627 * blank line most of the time so we only do it for :sh
628 * since the prompt gets left on the screen.
630 * BUG: :!echo longer than current line \\c
633 if (state
== CRTOPEN
) {
644 merror(gettext("[Hit return to continue] "));
653 * Gobble ^Q/^S since the tty driver should be eating
654 * them (as far as the user can see)
656 while (peekkey() == CTRL('Q') || peekkey() == CTRL('S'))
659 if(getkey() == ':') {
660 /* Extra newlines, but no other way */
667 if (Peekkey
!= ':') {
669 putpad((unsigned char *)enter_ca_mode
);
676 * Put out a newline (before a shell escape)
684 if (state
!= VISUAL
&& state
!= CRTOPEN
&& destline
<= WECHO
)
689 vclrbyte(vtube
[WECHO
], WCOLS
);
691 /* replaced by the ostop above
692 putpad(cursor_normal);