Merge various fixes from NetBSD. This will allow the WordPerfect for

SCO installation to run all the way through (some POSIX fixes).
This commit is contained in:
Jordan K. Hubbard 1995-08-16 05:56:44 +00:00
parent f4df6549b2
commit ce19262d8c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=10075
3 changed files with 87 additions and 47 deletions

View File

@ -64,6 +64,7 @@ static struct labhash {
} *labels[LHSZ];
static char *compile_addr __P((char *, struct s_addr *));
static char *compile_ccl __P((char **, char *));
static char *compile_delimited __P((char *, char *));
static char *compile_flags __P((char *, struct s_subst *));
static char *compile_re __P((char *, regex_t **));
@ -71,7 +72,7 @@ static char *compile_subst __P((char *, struct s_subst *));
static char *compile_text __P((void));
static char *compile_tr __P((char *, char **));
static struct s_command
**compile_stream __P((char *, struct s_command **, char *));
**compile_stream __P((struct s_command **));
static char *duptoeol __P((char *, char *));
static void enterlabel __P((struct s_command *));
static struct s_command
@ -90,6 +91,7 @@ struct s_format {
static struct s_format cmd_fmts[] = {
{'{', 2, GROUP},
{'}', 0, ENDGROUP},
{'a', 1, TEXT},
{'b', 2, BRANCH},
{'c', 2, TEXT},
@ -129,7 +131,7 @@ struct s_command *prog;
void
compile()
{
*compile_stream(NULL, &prog, NULL) = NULL;
*compile_stream(&prog) = NULL;
fixuplabel(prog, NULL);
uselabel();
appends = xmalloc(sizeof(struct s_appends) * appendnum);
@ -143,21 +145,19 @@ compile()
} while (0)
static struct s_command **
compile_stream(terminator, link, p)
char *terminator;
compile_stream(link)
struct s_command **link;
register char *p;
{
register char *p;
static char lbuf[_POSIX2_LINE_MAX + 1]; /* To save stack */
struct s_command *cmd, *cmd2;
struct s_command *cmd, *cmd2, *stack;
struct s_format *fp;
int naddr; /* Number of addresses */
if (p != NULL)
goto semicolon;
stack = 0;
for (;;) {
if ((p = cu_fgets(lbuf, sizeof(lbuf))) == NULL) {
if (terminator != NULL)
if (stack != 0)
err(COMPILE, "unexpected EOF (pending }'s)");
return (link);
}
@ -165,17 +165,11 @@ compile_stream(terminator, link, p)
semicolon: EATSPACE();
if (p && (*p == '#' || *p == '\0'))
continue;
if (*p == '}') {
if (terminator == NULL)
err(COMPILE, "unexpected }");
return (link);
}
*link = cmd = xmalloc(sizeof(struct s_command));
link = &cmd->next;
cmd->nonsel = cmd->inrange = 0;
/* First parse the addresses */
naddr = 0;
cmd->a1 = cmd->a2 = NULL;
/* Valid characters to start an address */
#define addrchar(c) (strchr("0123456789/\\$", (c)))
@ -185,16 +179,18 @@ semicolon: EATSPACE();
p = compile_addr(p, cmd->a1);
EATSPACE(); /* EXTENSION */
if (*p == ',') {
naddr++;
p++;
EATSPACE(); /* EXTENSION */
naddr++;
cmd->a2 = xmalloc(sizeof(struct s_addr));
p = compile_addr(p, cmd->a2);
}
}
EATSPACE();
} else
cmd->a2 = 0;
} else
cmd->a1 = cmd->a2 = 0;
nonsel: /* Now parse the command */
EATSPACE();
if (!*p)
err(COMPILE, "command expected");
cmd->code = *p;
@ -208,22 +204,31 @@ semicolon: EATSPACE();
"command %c expects up to %d address(es), found %d", *p, fp->naddr, naddr);
switch (fp->args) {
case NONSEL: /* ! */
cmd->nonsel = ! cmd->nonsel;
p++;
EATSPACE();
cmd->nonsel = ! cmd->nonsel;
goto nonsel;
case GROUP: /* { */
p++;
EATSPACE();
if (!*p)
p = NULL;
cmd2 = xmalloc(sizeof(struct s_command));
cmd2->nonsel = cmd2->inrange = 0;
cmd2->a1 = cmd2->a2 = NULL;
cmd2->code = '}';
*compile_stream("}", &cmd->u.c, p) = cmd2;
cmd->next = cmd2;
link = &cmd2->next;
cmd->next = stack;
stack = cmd;
link = &cmd->u.c;
if (*p)
goto semicolon;
break;
case ENDGROUP:
/*
* Short-circuit command processing, since end of
* group is really just a noop.
*/
cmd->nonsel = 1;
if (stack == 0)
err(COMPILE, "unexpected }");
cmd2 = stack;
stack = cmd2->next;
cmd2->next = cmd;
/*FALLTHROUGH*/
case EMPTY: /* d D g G h H l n N p P q x = \0 */
p++;
EATSPACE();
@ -259,7 +264,7 @@ semicolon: EATSPACE();
cmd->t = duptoeol(p, "w command");
if (aflag)
cmd->u.fd = -1;
else if ((cmd->u.fd = open(p,
else if ((cmd->u.fd = open(p,
O_WRONLY|O_APPEND|O_CREAT|O_TRUNC,
DEFFILEMODE)) == -1)
err(FATAL, "%s: %s\n", p, strerror(errno));
@ -347,7 +352,13 @@ compile_delimited(p, d)
else if (c == '\n')
err(COMPILE, "newline can not be used as a string delimiter");
while (*p) {
if (*p == '\\' && p[1] == c)
if (*p == '[') {
if ((d = compile_ccl(&p, d)) == NULL)
err(COMPILE, "unbalanced brackets ([])");
continue;
} else if (*p == '\\' && p[1] == '[') {
*d++ = *p++;
} else if (*p == '\\' && p[1] == c)
p++;
else if (*p == '\\' && p[1] == 'n') {
*d++ = '\n';
@ -364,6 +375,32 @@ compile_delimited(p, d)
return (NULL);
}
/* compile_ccl: expand a POSIX character class */
static char *
compile_ccl(sp, t)
char **sp;
char *t;
{
int c, d;
char *s = *sp;
*t++ = *s++;
if (*s == '^')
*t++ = *s++;
if (*s == ']')
*t++ = *s++;
for (; *s && (*t = *s) != ']'; s++, t++)
if (*s == '[' && ((d = *(s+1)) == '.' || d == ':' || d == '=')) {
*++t = *++s, t++, s++;
for (c = *s; (*t = *s) != ']' || c != d; s++, t++)
if ((c = *s) == '\0')
return NULL;
} else if (*s == '\\' && s[1] == 'n')
*t = '\n', s++;
return (*s == ']') ? *sp = ++s, ++t : NULL;
}
/*
* Get a regular expression. P points to the delimiter of the regular
* expression; repp points to the address of a regexp pointer. Newline

View File

@ -100,6 +100,7 @@ enum e_args {
TEXT, /* a c i */
NONSEL, /* ! */
GROUP, /* { */
ENDGROUP, /* } */
COMMENT, /* # */
BRANCH, /* b t */
LABEL, /* : */

View File

@ -89,11 +89,12 @@ process()
{
struct s_command *cp;
SPACE tspace;
size_t len;
char oldc, *p;
size_t len, oldpsl;
char *p;
for (linenum = 0; mf_fgets(&PS, REPLACE);) {
pd = 0;
top:
cp = prog;
redirect:
while (cp != NULL) {
@ -130,13 +131,14 @@ process()
case 'D':
if (pd)
goto new;
if ((p = memchr(ps, '\n', psl)) == NULL)
if ((p = memchr(ps, '\n', psl - 1)) == NULL) {
pd = 1;
else {
psl -= (p - ps) + 1;
goto new;
} else {
psl -= (p + 1) - ps;
memmove(ps, p + 1, psl);
goto top;
}
goto new;
case 'g':
cspace(&PS, hs, hsl, REPLACE);
break;
@ -179,13 +181,13 @@ process()
case 'P':
if (pd)
break;
if ((p = memchr(ps, '\n', psl)) != NULL) {
oldc = *++p;
*p = '\0';
if ((p = memchr(ps, '\n', psl - 1)) != NULL) {
oldpsl = psl;
psl = (p + 1) - ps;
}
OUT(ps)
if (p != NULL)
*p = oldc;
psl = oldpsl;
break;
case 'q':
if (!nflag && !pd)
@ -226,7 +228,7 @@ process()
break;
case 'x':
if (hs == NULL)
cspace(&HS, "", 0, REPLACE);
cspace(&HS, "\n", 1, REPLACE);
tspace = PS;
PS = HS;
HS = tspace;
@ -345,18 +347,18 @@ substitute(cp)
regsub(&SS, s, cp->u.s->new);
}
/* Move past this match. */
/* Move past this match. */
if (match[0].rm_so != match[0].rm_eo) {
s += match[0].rm_eo;
slen -= match[0].rm_eo;
lastempty = 0;
} else {
if (match[0].rm_so == 0)
cspace(&SS,
s, match[0].rm_so + 1, APPEND);
cspace(&SS, s, match[0].rm_so + 1,
APPEND);
else
cspace(&SS,
s + match[0].rm_so, 1, APPEND);
cspace(&SS, s + match[0].rm_so, 1,
APPEND);
s += match[0].rm_so + 1;
slen -= match[0].rm_so + 1;
lastempty = 1;