mirror of
https://github.com/GnoConsortium/gno.git
synced 2024-12-22 14:30:29 +00:00
784e3de7cd
passwd, ps, purge, shutdown, stty, upper, and vi. These sources are for the versions of the utils shipped with GNO v2.0.4.
830 lines
16 KiB
C
830 lines
16 KiB
C
/*
|
|
* STEVIE - Simply Try this Editor for VI Enthusiasts
|
|
*
|
|
* Code Contributions By : Tim Thompson twitch!tjt
|
|
* Tony Andrews onecom!wldrdg!tony
|
|
* G. R. (Fred) Walter watmath!grwalter
|
|
*/
|
|
|
|
#ifdef __ORCAC__
|
|
segment "seg2";
|
|
#include <stdarg.h>
|
|
#endif
|
|
#include "stevie.h"
|
|
|
|
static char *altfile = NULL; /* alternate file */
|
|
static int altline; /* line # in alternate file */
|
|
|
|
static char *nowrtmsg = "No write since last change (use ! to override)";
|
|
|
|
extern char **files; /* used for "n" and "rew" */
|
|
extern int curfile;
|
|
extern int numfiles;
|
|
|
|
#ifdef WILD_CARDS
|
|
char **cmd_files = NULL; /* list of input files */
|
|
int cmd_numfiles = 0; /* number of input files */
|
|
#endif
|
|
|
|
/*
|
|
* The next two variables contain the bounds of any range given in a command.
|
|
* If no range was given, both contain null line pointers. If only a single
|
|
* line was given, u_pos will contain a null line pointer.
|
|
*/
|
|
static LPtr l_pos, u_pos;
|
|
|
|
static bool_t interactive; /* TRUE if we're reading a real command line */
|
|
|
|
static bool_t doecmd(char *);
|
|
static void badcmd(void);
|
|
static void doshell(void);
|
|
static void get_range(char **);
|
|
static LPtr *get_line(char **);
|
|
|
|
#ifdef MEGAMAX
|
|
overlay "cmdline"
|
|
#endif
|
|
|
|
/*
|
|
* readcmdline() - accept a command line starting with ':', '/', or '?'
|
|
*
|
|
* readcmdline() accepts and processes colon commands and searches. If
|
|
* 'cmdline' is null, the command line is read here. Otherwise, cmdline
|
|
* points to a complete command line that should be used. This is used in
|
|
* main() to handle initialization commands in the environment variable
|
|
* "EXINIT".
|
|
*/
|
|
void
|
|
readcmdline(char firstc, char *cmdline)
|
|
/*char firstc; /* either ':', '/', or '?' */
|
|
/*char *cmdline; /* optional command string */
|
|
{
|
|
char c;
|
|
char buff[CMDBUFFSIZE];
|
|
char cmdbuf[CMDBUFFSIZE];
|
|
char argbuf[CMDBUFFSIZE];
|
|
char *p, *q, *cmd, *arg;
|
|
bool_t literal_next_flag = FALSE;
|
|
|
|
/*
|
|
* Clear the range variables.
|
|
*/
|
|
l_pos.linep = (LINE *) NULL;
|
|
u_pos.linep = (LINE *) NULL;
|
|
|
|
interactive = (cmdline == NULL);
|
|
|
|
if (interactive)
|
|
gotocmdline(YES, firstc);
|
|
p = buff;
|
|
if (firstc != ':')
|
|
*p++ = firstc;
|
|
|
|
if (interactive) {
|
|
/* collect the command string, handling '\b' and @ */
|
|
for (;;) {
|
|
c = vgetc();
|
|
if (c == CTRL('V') && !literal_next_flag) {
|
|
literal_next_flag = TRUE;
|
|
outchar('^');
|
|
continue;
|
|
}
|
|
if (c == '\n' || ((c == '\r' || c == ESC) && (!literal_next_flag)))
|
|
break;
|
|
if ((c == '\b') && (!literal_next_flag)) {
|
|
if (p > buff + (firstc != ':')) {
|
|
p--;
|
|
/*
|
|
* this is gross, but it relies only on 'gotocmdline'
|
|
*/
|
|
gotocmdline(YES, firstc == ':' ? ':' : NUL);
|
|
for (q = buff; q < p; q++)
|
|
outstr(chars[*q].ch_str);
|
|
} else {
|
|
msg("");
|
|
return; /* back to cmd mode */
|
|
}
|
|
continue;
|
|
}
|
|
if ((c == '@') && (!literal_next_flag)) {
|
|
p = buff;
|
|
if (firstc != ':')
|
|
*p++ = firstc;
|
|
gotocmdline(YES, firstc);
|
|
continue;
|
|
}
|
|
if (literal_next_flag) {
|
|
literal_next_flag = FALSE;
|
|
outchar('\b');
|
|
}
|
|
outstr(chars[c].ch_str);
|
|
*p++ = c;
|
|
}
|
|
*p = '\0';
|
|
} else {
|
|
if (strlen(cmdline) > CMDBUFFSIZE - 2) /* should really do something
|
|
* better here... */
|
|
return;
|
|
strcpy(p, cmdline);
|
|
}
|
|
|
|
/* skip any initial white space */
|
|
for (cmd = buff; *cmd != NUL && isspace(*cmd); cmd++);
|
|
|
|
/* search commands */
|
|
c = *cmd;
|
|
if (c == '/' || c == '?') {
|
|
cmd++;
|
|
/* was the command was '//' or '??' (I.E. repeat last search) */
|
|
if ((*cmd == c) || (*cmd == NUL)) {
|
|
if (c == '/')
|
|
searchagain(FORWARD);
|
|
else
|
|
searchagain(BACKWARD);
|
|
return;
|
|
}
|
|
/* If there is a matching '/' or '?' at the end, toss it */
|
|
p = strchr(cmd, NUL);
|
|
if (*(p - 1) == c && *(p - 2) != '\\')
|
|
*(p - 1) = NUL;
|
|
dosearch((c == '/') ? FORWARD : BACKWARD, cmd);
|
|
return;
|
|
}
|
|
/*
|
|
* Parse a range, if present (and update the cmd pointer).
|
|
*/
|
|
get_range(&cmd);
|
|
if (l_pos.linep != NULL) {
|
|
if (LINEOF(&l_pos) > LINEOF(&u_pos)) {
|
|
emsg("Invalid range");
|
|
return;
|
|
}
|
|
}
|
|
strcpy(cmdbuf, cmd); /* save the unmodified command */
|
|
|
|
/* isolate the command and find any argument */
|
|
for (p = cmd; *p != NUL && !isspace(*p); p++);
|
|
if (*p == NUL)
|
|
arg = NULL;
|
|
else {
|
|
*p = NUL;
|
|
for (p++; *p != NUL && isspace(*p); p++);
|
|
if (*p == NUL) {
|
|
arg = NULL;
|
|
} else {
|
|
strcpy(argbuf, p);
|
|
arg = argbuf;
|
|
}
|
|
}
|
|
|
|
if (strcmp(cmd, "q!") == 0) {
|
|
getout(0);
|
|
}
|
|
if (strcmp(cmd, "q") == 0) {
|
|
if (Changed) {
|
|
emsg(nowrtmsg);
|
|
} else {
|
|
getout(0);
|
|
}
|
|
return;
|
|
}
|
|
if (strcmp(cmd, "w") == 0) {
|
|
if (arg == NULL) {
|
|
if (Filename != NULL) {
|
|
if (!writeit(Filename, &l_pos, &u_pos)) {
|
|
emsg("Problems occured while writing output file");
|
|
}
|
|
} else {
|
|
emsg("No output file");
|
|
}
|
|
} else {
|
|
(void) writeit(arg, &l_pos, &u_pos);
|
|
}
|
|
return;
|
|
}
|
|
if (strcmp(cmd, "wq") == 0) {
|
|
if (Filename != NULL) {
|
|
if (writeit(Filename, (LPtr *) NULL, (LPtr *) NULL)) {
|
|
getout(0);
|
|
}
|
|
} else {
|
|
emsg("No output file");
|
|
}
|
|
return;
|
|
}
|
|
if (strcmp(cmd, "x") == 0) {
|
|
if (Changed) {
|
|
if (Filename != NULL) {
|
|
if (!writeit(Filename, (LPtr *) NULL, (LPtr *) NULL)) {
|
|
emsg("Problems occured while writing output file");
|
|
return;
|
|
}
|
|
} else {
|
|
emsg("No output file");
|
|
return;
|
|
}
|
|
}
|
|
getout(0);
|
|
}
|
|
if (strcmp(cmd, "f") == 0 && arg == NULL) {
|
|
fileinfo();
|
|
return;
|
|
}
|
|
if (*cmd == 'n') {
|
|
if ((curfile + 1) < numfiles) {
|
|
/*
|
|
* stuff ":e[!] FILE\n"
|
|
*/
|
|
stuffReadbuff(":e");
|
|
if (cmd[1] == '!')
|
|
stuffReadbuff("!");
|
|
stuffReadbuff(" ");
|
|
stuffReadbuff(files[++curfile]);
|
|
stuffReadbuff("\n");
|
|
} else
|
|
emsg("No more files!");
|
|
return;
|
|
}
|
|
if (*cmd == 'p') {
|
|
if (curfile > 0) {
|
|
/*
|
|
* stuff ":e[!] FILE\n"
|
|
*/
|
|
stuffReadbuff(":e");
|
|
if (cmd[1] == '!')
|
|
stuffReadbuff("!");
|
|
stuffReadbuff(" ");
|
|
stuffReadbuff(files[--curfile]);
|
|
stuffReadbuff("\n");
|
|
} else
|
|
emsg("No more files!");
|
|
return;
|
|
}
|
|
if (strncmp(cmd, "rew", 3) == 0) {
|
|
if (numfiles <= 1) /* nothing to rewind */
|
|
return;
|
|
curfile = 0;
|
|
/*
|
|
* stuff ":e[!] FILE\n"
|
|
*/
|
|
stuffReadbuff(":e");
|
|
if (cmd[3] == '!')
|
|
stuffReadbuff("!");
|
|
stuffReadbuff(" ");
|
|
stuffReadbuff(files[0]);
|
|
stuffReadbuff("\n");
|
|
return;
|
|
}
|
|
if (strcmp(cmd, "e") == 0) {
|
|
if (Changed) {
|
|
emsg(nowrtmsg);
|
|
} else {
|
|
if (strcmp(arg, "%") == 0) {
|
|
(void) doecmd(NULL);
|
|
return;
|
|
}
|
|
#ifdef WILD_CARDS
|
|
if (strcmp(arg, "#") != 0) {
|
|
ExpandWildCards(1, &arg, &cmd_numfiles, &cmd_files);
|
|
if (cmd_numfiles == 0) {
|
|
emsg("Can't open file");
|
|
return;
|
|
} else if (cmd_numfiles == 1) {
|
|
arg = cmd_files[0];
|
|
} else {
|
|
emsg("Too many file names");
|
|
}
|
|
}
|
|
#endif
|
|
(void) doecmd(arg);
|
|
}
|
|
return;
|
|
}
|
|
if (strcmp(cmd, "e!") == 0) {
|
|
if (strcmp(arg, "%") == 0) {
|
|
if (!doecmd(NULL))
|
|
ResetBuffers();
|
|
return;
|
|
}
|
|
#ifdef WILD_CARDS
|
|
if (strcmp(arg, "#") != 0) {
|
|
ExpandWildCards(1, &arg, &cmd_numfiles, &cmd_files);
|
|
if (cmd_numfiles == 0) {
|
|
emsg("Can't open file");
|
|
return;
|
|
} else if (cmd_numfiles == 1) {
|
|
arg = cmd_files[0];
|
|
} else {
|
|
emsg("Too many file names");
|
|
}
|
|
}
|
|
#endif
|
|
if (!doecmd(arg))
|
|
ResetBuffers();
|
|
return;
|
|
}
|
|
if (strcmp(cmd, "f") == 0) {
|
|
Filename = strsave(arg);
|
|
filemess("");
|
|
return;
|
|
}
|
|
if (strcmp(cmd, "r") == 0 || strcmp(cmd, ".r") == 0) {
|
|
if (arg == NULL) {
|
|
badcmd();
|
|
return;
|
|
}
|
|
#ifdef WILD_CARDS
|
|
if (strcmp(arg, "#") != 0) {
|
|
ExpandWildCards(1, &arg, &cmd_numfiles, &cmd_files);
|
|
if (cmd_numfiles == 0) {
|
|
emsg("Can't open file");
|
|
return;
|
|
} else if (cmd_numfiles == 1) {
|
|
arg = cmd_files[0];
|
|
} else {
|
|
emsg("Too many file names");
|
|
}
|
|
}
|
|
#endif
|
|
if (readfile(arg, Curschar, 1)) {
|
|
emsg("Can't open file");
|
|
return;
|
|
}
|
|
ResetBuffers();
|
|
CHANGED;
|
|
return;
|
|
}
|
|
if (strcmp(cmd, ".=") == 0) {
|
|
smsg("line %d", cntllines(Filemem, Curschar));
|
|
return;
|
|
}
|
|
if (strcmp(cmd, "$=") == 0) {
|
|
smsg("%d", cntllines(Filemem, Fileend) - 1);
|
|
return;
|
|
}
|
|
if (strncmp(cmd, "ta", 2) == 0) {
|
|
dotag(arg, cmd[2] == '!');
|
|
return;
|
|
}
|
|
if (strcmp(cmd, "set") == 0) {
|
|
doset(arg, interactive);
|
|
return;
|
|
}
|
|
if (strcmp(cmd, "help") == 0) {
|
|
if (help())
|
|
s_clear();
|
|
return;
|
|
}
|
|
if (strcmp(cmd, "version") == 0) {
|
|
extern char *Version;
|
|
|
|
msg(Version);
|
|
return;
|
|
}
|
|
if (strcmp(cmd, "sh") == 0) {
|
|
doshell();
|
|
return;
|
|
}
|
|
if (strncmp(cmd, "d", 1) == 0) {
|
|
LINE *cp;
|
|
int n;
|
|
|
|
if (l_pos.linep == NULL)
|
|
l_pos = *Curschar;
|
|
if (u_pos.linep == NULL)
|
|
u_pos = l_pos;
|
|
|
|
ResetBuffers();
|
|
n = RowNumber(&l_pos);
|
|
AppendPositionToUndoUndobuff(0, n);
|
|
AppendPositionToUndobuff(0, n);
|
|
if ((Filetop->linep->next == l_pos.linep) &&
|
|
(u_pos.linep->next == Fileend->linep))
|
|
AppendToUndobuff("a");
|
|
else if (u_pos.linep->next == Fileend->linep)
|
|
AppendToUndobuff("o");
|
|
else
|
|
AppendToUndobuff("O");
|
|
|
|
n = 0;
|
|
cp = l_pos.linep;
|
|
for (; cp != NULL && cp != Fileend->linep; cp = cp->next) {
|
|
AppendToUndobuff(cp->s);
|
|
n++;
|
|
if (cp == u_pos.linep)
|
|
break;
|
|
AppendToUndobuff(NL_STR);
|
|
}
|
|
AppendToUndobuff(ESC_STR);
|
|
|
|
if (n > 1)
|
|
AppendNumberToUndoUndobuff(n);
|
|
AppendToUndoUndobuff("dd");
|
|
|
|
*Curschar = l_pos;
|
|
delline(n);
|
|
S_NOT_VALID;
|
|
return;
|
|
}
|
|
if (strncmp(cmd, "s/", 2) == 0) {
|
|
dosub(&l_pos, &u_pos, cmdbuf + 1);
|
|
return;
|
|
}
|
|
if (strncmp(cmd, "g/", 2) == 0) {
|
|
doglob(&l_pos, &u_pos, cmdbuf + 1);
|
|
return;
|
|
}
|
|
if (cmd[0] == '!') {
|
|
if (cmd[1] == '\0') {
|
|
emsg("Incomplete shell escape command");
|
|
return;
|
|
}
|
|
outstr("\n");
|
|
flushbuf();
|
|
#ifdef BSD
|
|
set_ostate();
|
|
#endif
|
|
#ifdef UNIX
|
|
set_ostate();
|
|
#endif
|
|
(void) system(&cmd[1]);
|
|
#ifdef BSD
|
|
set_nstate();
|
|
#endif
|
|
#ifdef UNIX
|
|
set_nstate();
|
|
#endif
|
|
wait_return();
|
|
return;
|
|
}
|
|
/*
|
|
* If we got a line, but no command, then go to the line.
|
|
*/
|
|
if (*cmd == NUL && l_pos.linep != NULL) {
|
|
if (u_pos.linep != NULL)
|
|
*Curschar = u_pos;
|
|
else
|
|
*Curschar = l_pos;
|
|
|
|
S_CHECK_TOPCHAR_AND_BOTCHAR;
|
|
|
|
return;
|
|
}
|
|
badcmd();
|
|
}
|
|
|
|
/*
|
|
* get_range - parse a range specifier
|
|
*
|
|
* Ranges are of the form:
|
|
*
|
|
* addr[,addr]
|
|
*
|
|
* where 'addr' is:
|
|
*
|
|
* % (entire file)
|
|
* $ [+-NUM]
|
|
* 'x [+-NUM] (where x denotes a currently defined mark)
|
|
* . [+-NUM]
|
|
* NUM
|
|
*
|
|
* The pointer *cp is updated to point to the first character following the
|
|
* range spec. If an initial address is found, but no second, the upper bound
|
|
* is equal to the lower.
|
|
*/
|
|
static void
|
|
get_range(char **cp)
|
|
{
|
|
LPtr *l;
|
|
char *p;
|
|
|
|
if (**cp == '%') {
|
|
l_pos.index = 0;
|
|
l_pos.linep = Filetop->linep->next;
|
|
u_pos.index = 0;
|
|
u_pos.linep = Fileend->linep->prev;
|
|
(*cp)++;
|
|
return;
|
|
}
|
|
if ((l = get_line(cp)) == NULL)
|
|
return;
|
|
|
|
l_pos = *l;
|
|
|
|
for (p = *cp; *p != NUL && isspace(*p); p++);
|
|
|
|
*cp = p;
|
|
|
|
if (*p != ',') { /* is there another line spec ? */
|
|
u_pos = l_pos;
|
|
return;
|
|
}
|
|
*cp = ++p;
|
|
|
|
if ((l = get_line(cp)) == NULL) {
|
|
u_pos = l_pos;
|
|
return;
|
|
}
|
|
u_pos = *l;
|
|
}
|
|
|
|
static LPtr *
|
|
get_line(char **cp)
|
|
{
|
|
static LPtr pos;
|
|
LPtr *lp;
|
|
char *p, c;
|
|
int lnum;
|
|
|
|
pos.index = 0; /* shouldn't matter... check back later */
|
|
|
|
p = *cp;
|
|
/*
|
|
* Determine the basic form, if present.
|
|
*/
|
|
switch (c = *p++) {
|
|
|
|
case '$':
|
|
pos.linep = Fileend->linep->prev;
|
|
break;
|
|
|
|
case '.':
|
|
pos.linep = Curschar->linep;
|
|
break;
|
|
|
|
case '\'':
|
|
if ((lp = getmark(*p++)) == NULL) {
|
|
emsg("Unknown mark");
|
|
return (LPtr *) NULL;
|
|
}
|
|
pos = *lp;
|
|
break;
|
|
|
|
case '0':
|
|
case '1':
|
|
case '2':
|
|
case '3':
|
|
case '4':
|
|
case '5':
|
|
case '6':
|
|
case '7':
|
|
case '8':
|
|
case '9':
|
|
for (lnum = c - '0'; isdigit(*p); p++)
|
|
lnum = (lnum * 10) + (*p - '0');
|
|
|
|
if (lnum == 0)
|
|
lnum = 1;
|
|
|
|
pos = *gotoline(lnum);
|
|
break;
|
|
|
|
default:
|
|
return (LPtr *) NULL;
|
|
}
|
|
|
|
while (*p != NUL && isspace(*p))
|
|
p++;
|
|
|
|
if (*p == '-' || *p == '+') {
|
|
bool_t neg = (*p++ == '-');
|
|
|
|
for (lnum = 0; isdigit(*p); p++)
|
|
lnum = (lnum * 10) + (*p - '0');
|
|
|
|
if (neg)
|
|
lnum = -lnum;
|
|
|
|
pos = *gotoline(cntllines(Filemem, &pos) + lnum);
|
|
}
|
|
*cp = p;
|
|
return &pos;
|
|
}
|
|
|
|
static void
|
|
badcmd(void)
|
|
{
|
|
if (interactive)
|
|
emsg("Unrecognized command");
|
|
}
|
|
|
|
/*
|
|
* dotag(tag, force) - goto tag
|
|
*/
|
|
void
|
|
dotag(char *tag, bool_t force)
|
|
/*char *tag;
|
|
bool_t force;*/
|
|
{
|
|
FILE *tp, *fopen();
|
|
char lbuf[LSIZE];
|
|
char *fname, *str;
|
|
|
|
if ((tp = fopen("tags", "r")) == NULL) {
|
|
emsg("Can't open tags file");
|
|
return;
|
|
}
|
|
while (fgets(lbuf, LSIZE, tp) != NULL) {
|
|
if ((fname = strchr(lbuf, TAB)) == NULL) {
|
|
emsg("Format error in tags file");
|
|
return;
|
|
}
|
|
*fname++ = '\0';
|
|
if ((str = strchr(fname, TAB)) == NULL) {
|
|
emsg("Format error in tags file");
|
|
return;
|
|
}
|
|
*str++ = '\0';
|
|
|
|
if (strcmp(lbuf, tag) == 0) {
|
|
if (!force && Changed) {
|
|
emsg(nowrtmsg);
|
|
return;
|
|
}
|
|
if (doecmd(fname)) {
|
|
stuffReadbuff(str); /* str has \n at end */
|
|
stuffReadbuff("\007"); /* CTRL('G') */
|
|
fclose(tp);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
emsg("tag not found");
|
|
fclose(tp);
|
|
}
|
|
|
|
static bool_t
|
|
doecmd(char *arg)
|
|
{
|
|
int line = 1; /* line # to go to in new file */
|
|
|
|
if (arg != NULL) {
|
|
/*
|
|
* First detect a ":e" on the current file. This is mainly for ":ta"
|
|
* commands where the destination is within the current file.
|
|
*/
|
|
if (Filename != NULL) {
|
|
if (strcmp(arg, Filename) == 0) {
|
|
if (!Changed) {
|
|
altfile = Filename;
|
|
altline = cntllines(Filemem, Curschar);
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
if (strcmp(arg, "#") == 0) { /* alternate */
|
|
char *s = Filename;
|
|
|
|
if (altfile == NULL) {
|
|
emsg("No alternate file");
|
|
return FALSE;
|
|
}
|
|
if (strcmp(altfile, Filename) == 0) {
|
|
if (!Changed) {
|
|
line = altline;
|
|
altline = cntllines(Filemem, Curschar);
|
|
goto DO_THE_STUFF_THING;
|
|
}
|
|
}
|
|
Filename = altfile;
|
|
altfile = s;
|
|
line = altline;
|
|
altline = cntllines(Filemem, Curschar);
|
|
} else {
|
|
altfile = Filename;
|
|
altline = cntllines(Filemem, Curschar);
|
|
Filename = strsave(arg);
|
|
}
|
|
}
|
|
if (Filename == NULL) {
|
|
emsg("No filename");
|
|
return FALSE;
|
|
}
|
|
/* clear mem and read file */
|
|
freeall();
|
|
filealloc();
|
|
UNCHANGED;
|
|
|
|
if (readfile(Filename, Filemem, 0)) {
|
|
emsg("Can't open file");
|
|
return FALSE;
|
|
}
|
|
*Topchar = *Curschar;
|
|
if (line != 1) {
|
|
DO_THE_STUFF_THING:
|
|
stuffnumReadbuff(line);
|
|
stuffReadbuff("G");
|
|
}
|
|
setpcmark();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
doshell(void)
|
|
{
|
|
char *sh, *getenv();
|
|
|
|
sh = getenv("SHELL");
|
|
if (sh == NULL) {
|
|
emsg("Shell variable not set");
|
|
return;
|
|
}
|
|
gotocmdline(YES, NUL);
|
|
|
|
if (system(sh) < 0) {
|
|
emsg("Exec failed");
|
|
return;
|
|
}
|
|
wait_return();
|
|
}
|
|
|
|
void
|
|
gotocmdline(bool_t clr, char firstc)
|
|
{
|
|
windgoto(Rows - 1, 0);
|
|
if (clr)
|
|
toutstr(T_EL); /* clear the bottom line */
|
|
if (firstc)
|
|
outchar(firstc);
|
|
}
|
|
|
|
/*
|
|
* msg(s) - displays the string 's' on the status line
|
|
*/
|
|
void
|
|
msg(char *s)
|
|
{
|
|
gotocmdline(YES, NUL);
|
|
outstr(s);
|
|
#ifdef AMIGA
|
|
flushbuf();
|
|
#endif
|
|
#ifdef BSD
|
|
flushbuf();
|
|
#endif
|
|
}
|
|
|
|
/* VARARGS */
|
|
#ifdef __ORCAC__
|
|
void smsg(char *s, ...)
|
|
{
|
|
static char sbuf[MAX_COLUMNS+1];
|
|
va_list ap;
|
|
|
|
|
|
va_start(ap,s);
|
|
vsprintf(sbuf,s,ap);
|
|
msg(sbuf);
|
|
va_end(ap);
|
|
}
|
|
#else
|
|
void
|
|
smsg(s, a1, a2, a3, a4, a5, a6, a7, a8, a9)
|
|
char *s;
|
|
int a1, a2, a3, a4, a5, a6, a7, a8, a9;
|
|
{
|
|
char sbuf[MAX_COLUMNS + 1];
|
|
|
|
sprintf(sbuf, s, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
msg(sbuf);
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* emsg() - display an error message
|
|
*
|
|
* Rings the bell, if appropriate, and calls message() to do the real work
|
|
*/
|
|
void
|
|
emsg(char *s)
|
|
{
|
|
UndoInProgress = FALSE;
|
|
RedrawingDisabled = FALSE;
|
|
|
|
if (P(P_EB))
|
|
beep();
|
|
toutstr(T_TI);
|
|
msg(s);
|
|
toutstr(T_TP);
|
|
#ifdef AMIGA
|
|
flushbuf();
|
|
#endif
|
|
#ifdef BSD
|
|
flushbuf();
|
|
#endif
|
|
}
|
|
|
|
void
|
|
wait_return(void)
|
|
{
|
|
char c;
|
|
|
|
outstr("Press RETURN to continue");
|
|
do {
|
|
c = vgetc();
|
|
} while (c != '\r' && c != '\n');
|
|
|
|
s_clear();
|
|
}
|