* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
"@(#) Copyright (c) 1980 Regents of the University of California.\n\
static char sccsid
[] = "@(#)ex.c 7.3 (Berkeley) %G%";
char tttrace
[] = { '/','d','e','v','/','t','t','y','x','x',0 };
* The code for ex is divided as follows:
* ex.c Entry point and routines handling interrupt, hangup
* signals; initialization code.
* ex_addr.c Address parsing routines for command mode decoding.
* Routines to set and check address ranges on commands.
* ex_cmds.c Command mode command decoding.
* ex_cmds2.c Subroutines for command decoding and processing of
* file names in the argument list. Routines to print
* messages and reset state when errors occur.
* ex_cmdsub.c Subroutines which implement command mode functions
* such as append, delete, join.
* ex_data.c Initialization of options.
* ex_get.c Command mode input routines.
* ex_io.c General input/output processing: file i/o, unix
* escapes, filtering, source commands, preserving
* ex_put.c Terminal driving and optimizing routines for low-level
* output (cursor-positioning); output line formatting
* ex_re.c Global commands, substitute, regular expression
* compilation and execution.
* ex_set.c The set command.
* ex_subr.c Loads of miscellaneous subroutines.
* ex_temp.c Editor buffer routines for main buffer and also
* for named buffers (Q registers if you will.)
* ex_tty.c Terminal dependent initializations from termcap
* data base, grabbing of tty modes (at beginning
* ex_unix.c Routines for the ! command and its variations.
* ex_v*.c Visual/open mode routines... see ex_v.c for a
* guide to the overall organization.
* Main procedure. Process arguments and then
* transfer control to the main command processing loop
* in the routine commands. We are entered as either "ex", "edit", "vi"
* or "view" and the distinction is made here. Actually, we are "vi" if
* there is a 'v' in our name, "view" is there is a 'w', and "edit" if
* there is a 'd' in our name. For edit we just diddle options;
* for vi we actually force an early visual command.
char *erpath
= EXSTRINGS
;
* Immediately grab the tty modes so that we wont
* get messed up if an interrupt comes in quickly.
* Defend against d's, v's, w's, and a's in directories of
* path leading to our true name.
* Figure out how we were invoked: ex, edit, vi, view.
ivis
= any('v', av
[0]); /* "vi" */
if (any('w', av
[0])) /* "view" */
if (any('d', av
[0])) { /* "edit" */
* For debugging take files out of . if name is a.out.
erpath
= tailpath(erpath
);
* Open the error message file.
erfile
= open(erpath
+4, 0);
erfile
= open(erpath
, 0);
* Initialize interrupt handling.
oldhup
= signal(SIGHUP
, SIG_IGN
);
oldquit
= signal(SIGQUIT
, SIG_IGN
);
ruptible
= signal(SIGINT
, SIG_IGN
) == SIG_DFL
;
if (signal(SIGTERM
, SIG_IGN
) == SIG_DFL
)
if (signal(SIGEMT
, SIG_IGN
) == SIG_DFL
)
* Process flag arguments.
while (ac
&& av
[0][0] == '-') {
trace
= fopen(tracef
, "w");
printf("Trace create error\n");
if (ac
> 1 && av
[1][0] != '-') {
/* BUG: should check for too long tag. */
if (av
[0][2] == 0) defwind
= 3;
else for (cp
= &av
[0][2]; isdigit(*cp
); cp
++)
defwind
= 10*defwind
+ *cp
- '0';
smerror("Unknown option %s\n", av
[0]);
* Initialize end of core pointers.
* Normally we avoid breaking back to fendcore after each
* file since this can be expensive (much core-core copying).
* If your system can scatter load processes you could do
* this as ed does, saving a little core, but it will probably
* not often make much difference.
fendcore
= (line
*) sbrk(0);
if (!hush
&& signal(SIGTSTP
, SIG_IGN
) == SIG_DFL
)
signal(SIGTSTP
, onsusp
), dosusp
++;
if (ac
&& av
[0][0] == '+') {
key
= getpass(KEYPROMPT
);
kflag
= crinit(key
, perm
);
* If we are doing a recover and no filename
* was given, then execute an exrecover command with
* the -r option to type out the list of saved file names.
* Otherwise set the remembered file name to the first argument
* file name so the "recover" initial command will find it.
execl(EXRECOVER
, "exrecover", "-r", 0);
CP(savedfile
, *av
++), ac
--;
* Initialize the argument list.
* Initialize a temporary file (buffer) and
* set up terminal environment. Read user startup commands.
if (cp
= getenv("SHELL"))
if ((cp
= getenv("TERM")) != 0 && *cp
)
if (setexit() == 0 && !fast
&& intty
) {
if ((globp
= getenv("EXINIT")) && *globp
)
if ((cp
= getenv("HOME")) != 0 && *cp
)
source(strcat(strcpy(genbuf
, cp
), "/.exrc"), 1);
* Allow local .exrc too. This loses if . is $HOME,
* but nobody should notice unless they do stupid things
* like putting a version command in .exrc. Besides,
* they should be using EXINIT, not .exrc, right?
init(); /* moved after prev 2 chunks to fix directory option */
* Initial processing. Handle tag, recover, and file argument
* implied next commands. If going in as 'vi', then don't do
* anything, just set initev so we will do it later (from within
globp
= ivis
? "tag" : "tag|p";
* Vi command... go into visual.
* Strange... everything in vi usually happens
* before we ever "start".
* Don't have to be upward compatible with stupidity
* of starting editing at line $.
* Clear out trash in state accumulated by startup,
* and then do the main command loop for a normal edit.
* If you quit out of a 'vi' command by doing Q or ^\,
* you also fall through to here.
* Initialization, before editing a new file.
* Main thing here is to get a new buffer (in fileinit),
* rest is peripheral state resetting.
dot
= zero
= truedol
= unddol
= dol
= fendcore
;
for (i
= 0; i
<= 'z'-'a'+1; i
++)
* Return last component of unix path name p.