aboutsummaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorPedro F. Giffuni <pfg@FreeBSD.org>2016-08-02 15:35:53 +0000
committerPedro F. Giffuni <pfg@FreeBSD.org>2016-08-02 15:35:53 +0000
commit249a8a8003098e796792e9c523d5211ba8018755 (patch)
tree28eb9f5b34b69220ddb6a8851690b7601c8f3e3c /usr.bin
parent27c9d425316339bed59b9669160deadb195ce443 (diff)
downloadsrc-249a8a8003098e796792e9c523d5211ba8018755.tar.gz
src-249a8a8003098e796792e9c523d5211ba8018755.zip
sed(1): Revert r303047 "cleanup" and therefore r303572.
While big, the change was meant to have no effect on behavior and instead so far we have found two regressions: one in the etcupdate tests and another one in the games/openttd port[1]. Revert to a known working state. We will likely have to split the patch in functional parts before bringing back the changes. PR: 195929 Reported by: danfe, madpilot [1]
Notes
Notes: svn path=/head/; revision=303662
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/sed/Makefile2
-rw-r--r--usr.bin/sed/compile.c236
-rw-r--r--usr.bin/sed/defs.h5
-rw-r--r--usr.bin/sed/extern.h6
-rw-r--r--usr.bin/sed/main.c78
-rw-r--r--usr.bin/sed/misc.c8
-rw-r--r--usr.bin/sed/process.c34
7 files changed, 192 insertions, 177 deletions
diff --git a/usr.bin/sed/Makefile b/usr.bin/sed/Makefile
index 51904a6efd94..a741da3233e6 100644
--- a/usr.bin/sed/Makefile
+++ b/usr.bin/sed/Makefile
@@ -6,7 +6,7 @@
PROG= sed
SRCS= compile.c main.c misc.c process.c
-WARNS?= 5
+WARNS?= 2
.if ${MK_TESTS} != "no"
SUBDIR+= tests
diff --git a/usr.bin/sed/compile.c b/usr.bin/sed/compile.c
index 891fe5b8d780..bafb339a4b5d 100644
--- a/usr.bin/sed/compile.c
+++ b/usr.bin/sed/compile.c
@@ -64,21 +64,21 @@ static struct labhash {
int lh_ref;
} *labels[LHSZ];
-static const char *compile_addr(const char *, struct s_addr *);
-static char *compile_ccl(const char **, char *);
-static const char *compile_delimited(const char *, char *, int);
-static const char *compile_flags(const char *, struct s_subst *);
-static const regex_t *compile_re(const char *, int);
-static const char *compile_subst(const char *, struct s_subst *);
-static char *compile_text(size_t *);
-static const char *compile_tr(const char *, struct s_tr **);
+static char *compile_addr(char *, struct s_addr *);
+static char *compile_ccl(char **, char *);
+static char *compile_delimited(char *, char *, int);
+static char *compile_flags(char *, struct s_subst *);
+static regex_t *compile_re(char *, int);
+static char *compile_subst(char *, struct s_subst *);
+static char *compile_text(void);
+static char *compile_tr(char *, struct s_tr **);
static struct s_command
**compile_stream(struct s_command **);
-static char *duptoeol(const char *, const char *, size_t *);
+static char *duptoeol(char *, const char *);
static void enterlabel(struct s_command *);
static struct s_command
- *findlabel(const char *);
-static void fixuplabel(struct s_command *, const struct s_command *);
+ *findlabel(char *);
+static void fixuplabel(struct s_command *, struct s_command *);
static void uselabel(void);
/*
@@ -144,20 +144,17 @@ compile(void)
err(1, "malloc");
}
-#define EATSPACE() do { \
- while (*p && isspace((unsigned char)*p)) \
- p++; \
- } while (0)
-
-#define EATSPACEN() do { \
- while (*p && *p != '\n' && isspace((unsigned char)*p)) \
- p++; \
+#define EATSPACE() do { \
+ if (p) \
+ while (*p && isspace((unsigned char)*p)) \
+ p++; \
} while (0)
static struct s_command **
compile_stream(struct s_command **link)
{
- const char *p;
+ char *p;
+ static char lbuf[_POSIX2_LINE_MAX + 1]; /* To save stack */
struct s_command *cmd, *cmd2, *stack;
struct s_format *fp;
char re[_POSIX2_LINE_MAX + 1];
@@ -165,22 +162,22 @@ compile_stream(struct s_command **link)
stack = NULL;
for (;;) {
- if ((p = cu_fgets(NULL)) == NULL) {
+ if ((p = cu_fgets(lbuf, sizeof(lbuf), NULL)) == NULL) {
if (stack != NULL)
errx(1, "%lu: %s: unexpected EOF (pending }'s)",
linenum, fname);
return (link);
}
-semicolon: EATSPACEN();
- switch (*p) {
- case '#': case '\0': case '\n':
- continue; /* to next command-unit */
- case ';':
- p++;
- goto semicolon;
+semicolon: EATSPACE();
+ if (p) {
+ if (*p == '#' || *p == '\0')
+ continue;
+ else if (*p == ';') {
+ p++;
+ goto semicolon;
+ }
}
-
if ((*link = cmd = malloc(sizeof(struct s_command))) == NULL)
err(1, "malloc");
link = &cmd->next;
@@ -211,14 +208,14 @@ semicolon: EATSPACEN();
cmd->a1 = cmd->a2 = NULL;
nonsel: /* Now parse the command */
- if (*p == '\0' || *p == '\n')
+ if (!*p)
errx(1, "%lu: %s: command expected", linenum, fname);
cmd->code = *p;
for (fp = cmd_fmts; fp->code; fp++)
if (fp->code == *p)
break;
if (!fp->code)
- errx(1, "%lu: %s: invalid command code %c (%s)", linenum, fname, *p, p);
+ errx(1, "%lu: %s: invalid command code %c", linenum, fname, *p);
if (naddr > fp->naddr)
errx(1,
"%lu: %s: command %c expects up to %d address(es), found %d",
@@ -231,11 +228,11 @@ nonsel: /* Now parse the command */
goto nonsel;
case GROUP: /* { */
p++;
- EATSPACEN();
+ EATSPACE();
cmd->next = stack;
stack = cmd;
link = &cmd->u.c;
- if (*p != '\0' && *p != '\n')
+ if (*p)
goto semicolon;
break;
case ENDGROUP:
@@ -252,13 +249,13 @@ nonsel: /* Now parse the command */
/*FALLTHROUGH*/
case EMPTY: /* d D g G h H l n N p P q x = \0 */
p++;
- EATSPACEN();
+ EATSPACE();
if (*p == ';') {
p++;
link = &cmd->next;
goto semicolon;
}
- if (*p != '\0' && *p != '\n')
+ if (*p)
errx(1, "%lu: %s: extra characters at the end of %c command",
linenum, fname, cmd->code);
break;
@@ -269,12 +266,12 @@ nonsel: /* Now parse the command */
errx(1,
"%lu: %s: command %c expects \\ followed by text", linenum, fname, cmd->code);
p++;
- EATSPACEN();
- if (*p != '\n')
+ EATSPACE();
+ if (*p)
errx(1,
- "%lu: %s: extra characters (%c) after \\ at the end of %c command",
- linenum, fname, *p, cmd->code);
- cmd->t = compile_text(&cmd->tlen);
+ "%lu: %s: extra characters after \\ at the end of %c command",
+ linenum, fname, cmd->code);
+ cmd->t = compile_text();
break;
case COMMENT: /* \0 # */
break;
@@ -283,10 +280,10 @@ nonsel: /* Now parse the command */
EATSPACE();
if (*p == '\0')
errx(1, "%lu: %s: filename expected", linenum, fname);
- cmd->t = duptoeol(p, "w command", &cmd->tlen);
+ cmd->t = duptoeol(p, "w command");
if (aflag)
cmd->u.fd = -1;
- else if ((cmd->u.fd = open(cmd->t,
+ else if ((cmd->u.fd = open(p,
O_WRONLY|O_APPEND|O_CREAT|O_TRUNC,
DEFFILEMODE)) == -1)
err(1, "%s", p);
@@ -297,27 +294,27 @@ nonsel: /* Now parse the command */
if (*p == '\0')
errx(1, "%lu: %s: filename expected", linenum, fname);
else
- cmd->t = duptoeol(p, "read command", &cmd->tlen);
+ cmd->t = duptoeol(p, "read command");
break;
case BRANCH: /* b t */
p++;
- EATSPACEN();
- if (*p == '\0' || *p == '\n')
+ EATSPACE();
+ if (*p == '\0')
cmd->t = NULL;
else
- cmd->t = duptoeol(p, "branch", &cmd->tlen);
+ cmd->t = duptoeol(p, "branch");
break;
case LABEL: /* : */
p++;
EATSPACE();
- cmd->t = duptoeol(p, "label", &cmd->tlen);
- if (cmd->t[0] == '\0')
+ cmd->t = duptoeol(p, "label");
+ if (strlen(p) == 0)
errx(1, "%lu: %s: empty label", linenum, fname);
enterlabel(cmd);
break;
case SUBST: /* s */
p++;
- if (*p == '\0' || *p == '\\' || *p == '\n')
+ if (*p == '\0' || *p == '\\')
errx(1,
"%lu: %s: substitute pattern can not be delimited by newline or backslash",
linenum, fname);
@@ -328,15 +325,21 @@ nonsel: /* Now parse the command */
errx(1,
"%lu: %s: unterminated substitute pattern", linenum, fname);
+ /* Compile RE with no case sensitivity temporarily */
+ if (*re == '\0')
+ cmd->u.s->re = NULL;
+ else
+ cmd->u.s->re = compile_re(re, 0);
--p;
p = compile_subst(p, cmd->u.s);
p = compile_flags(p, cmd->u.s);
- if (*re != '\0')
+ /* Recompile RE with case sensitivity from "I" flag if any */
+ if (*re == '\0')
+ cmd->u.s->re = NULL;
+ else
cmd->u.s->re = compile_re(re, cmd->u.s->icase);
-
EATSPACE();
-
if (*p == ';') {
p++;
link = &cmd->next;
@@ -369,8 +372,8 @@ nonsel: /* Now parse the command */
* in the case of a non-terminated string. The character array d is filled
* with the processed string.
*/
-static const char *
-compile_delimited(const char *p, char *d, int is_tr)
+static char *
+compile_delimited(char *p, char *d, int is_tr)
{
char c;
@@ -413,10 +416,10 @@ compile_delimited(const char *p, char *d, int is_tr)
/* compile_ccl: expand a POSIX character class */
static char *
-compile_ccl(const char **sp, char *t)
+compile_ccl(char **sp, char *t)
{
int c, d;
- const char *s = *sp;
+ char *s = *sp;
*t++ = *s++;
if (*s == '^')
@@ -438,8 +441,8 @@ compile_ccl(const char **sp, char *t)
* regular expression.
* Cflags are passed to regcomp.
*/
-static const regex_t *
-compile_re(const char *re, int case_insensitive)
+static regex_t *
+compile_re(char *re, int case_insensitive)
{
regex_t *rep;
int eval, flags;
@@ -463,13 +466,14 @@ compile_re(const char *re, int case_insensitive)
* point to a saved copy of it. Nsub is the number of parenthesized regular
* expressions.
*/
-static const char *
-compile_subst(const char *p, struct s_subst *s)
+static char *
+compile_subst(char *p, struct s_subst *s)
{
+ static char lbuf[_POSIX2_LINE_MAX + 1];
int asize, size;
u_char ref;
char c, *text, *op, *sp;
- int more = 0, sawesc = 0;
+ int more = 1, sawesc = 0;
c = *p++; /* Terminator character */
if (c == '\0')
@@ -483,7 +487,7 @@ compile_subst(const char *p, struct s_subst *s)
size = 0;
do {
op = sp = text + size;
- for (; *p != '\0' && *p != '\n'; p++) {
+ for (; *p; p++) {
if (*p == '\\' || sawesc) {
/*
* If this is a continuation from the last
@@ -505,10 +509,7 @@ compile_subst(const char *p, struct s_subst *s)
*/
sawesc = 1;
p--;
- break;
- } else if (*p == '\n') {
- *sp++ = '\n';
- break;
+ continue;
} else if (strchr("123456789", *p) != NULL) {
*sp++ = '\\';
ref = *p - '0';
@@ -522,11 +523,8 @@ compile_subst(const char *p, struct s_subst *s)
*sp++ = '\\';
} else if (*p == c) {
if (*++p == '\0' && more) {
- const char *nextp;
-
- nextp = cu_fgets(&more);
- if (nextp != NULL)
- p = nextp;
+ if (cu_fgets(lbuf, sizeof(lbuf), &more))
+ p = lbuf;
}
*sp++ = '\0';
size += sp - op;
@@ -546,7 +544,7 @@ compile_subst(const char *p, struct s_subst *s)
if ((text = realloc(text, asize)) == NULL)
err(1, "realloc");
}
- } while ((p = cu_fgets(&more)) != NULL);
+ } while (cu_fgets(p = lbuf, sizeof(lbuf), &more) != NULL);
errx(1, "%lu: %s: unterminated substitute in regular expression",
linenum, fname);
/* NOTREACHED */
@@ -555,12 +553,12 @@ compile_subst(const char *p, struct s_subst *s)
/*
* Compile the flags of the s command
*/
-static const char *
-compile_flags(const char *p, struct s_subst *s)
+static char *
+compile_flags(char *p, struct s_subst *s)
{
int gn; /* True if we have seen g or n */
unsigned long nval;
- char *q;
+ char wfile[_POSIX2_LINE_MAX + 1], *q, *eq;
s->n = 1; /* Default */
s->p = 0;
@@ -568,7 +566,7 @@ compile_flags(const char *p, struct s_subst *s)
s->wfd = -1;
s->icase = 0;
for (gn = 0;;) {
- EATSPACEN(); /* EXTENSION */
+ EATSPACE(); /* EXTENSION */
switch (*p) {
case 'g':
if (gn)
@@ -596,13 +594,13 @@ compile_flags(const char *p, struct s_subst *s)
"%lu: %s: more than one number or 'g' in substitute flags", linenum, fname);
gn = 1;
errno = 0;
- nval = strtol(p, &q, 10);
+ nval = strtol(p, &p, 10);
if (errno == ERANGE || nval > INT_MAX)
errx(1,
"%lu: %s: overflow in the 'N' substitute flag", linenum, fname);
s->n = nval;
- p = q;
- continue;
+ p--;
+ break;
case 'w':
p++;
#ifdef HISTORIC_PRACTICE
@@ -612,15 +610,27 @@ compile_flags(const char *p, struct s_subst *s)
}
#endif
EATSPACE();
- s->wfile = duptoeol(p, "w flag", NULL);
- if (!aflag && (s->wfd = open(s->wfile,
+ q = wfile;
+ eq = wfile + sizeof(wfile) - 1;
+ while (*p) {
+ if (*p == '\n')
+ break;
+ if (q >= eq)
+ err(1, "wfile too long");
+ *q++ = *p++;
+ }
+ *q = '\0';
+ if (q == wfile)
+ errx(1, "%lu: %s: no wfile specified", linenum, fname);
+ s->wfile = strdup(wfile);
+ if (!aflag && (s->wfd = open(wfile,
O_WRONLY|O_APPEND|O_CREAT|O_TRUNC,
DEFFILEMODE)) == -1)
- err(1, "%s", s->wfile);
+ err(1, "%s", wfile);
return (p);
default:
- errx(1, "%lu: %s: bad flag in substitute command: '%c' (%.10s)",
- linenum, fname, *p, p);
+ errx(1, "%lu: %s: bad flag in substitute command: '%c'",
+ linenum, fname, *p);
break;
}
p++;
@@ -630,8 +640,8 @@ compile_flags(const char *p, struct s_subst *s)
/*
* Compile a translation set of strings into a lookup table.
*/
-static const char *
-compile_tr(const char *p, struct s_tr **py)
+static char *
+compile_tr(char *p, struct s_tr **py)
{
struct s_tr *y;
int i;
@@ -642,7 +652,7 @@ compile_tr(const char *p, struct s_tr **py)
mbstate_t mbs1, mbs2;
if ((*py = y = malloc(sizeof(*y))) == NULL)
- err(1, "malloc");
+ err(1, NULL);
y->multis = NULL;
y->nmultis = 0;
@@ -662,11 +672,11 @@ compile_tr(const char *p, struct s_tr **py)
op = old;
oldlen = mbsrtowcs(NULL, &op, 0, NULL);
if (oldlen == (size_t)-1)
- err(1, "mbsrtowcs");
+ err(1, NULL);
np = new;
newlen = mbsrtowcs(NULL, &np, 0, NULL);
if (newlen == (size_t)-1)
- err(1, "mbsrtowcs");
+ err(1, NULL);
if (newlen != oldlen)
errx(1, "%lu: %s: transform strings are not the same length",
linenum, fname);
@@ -705,7 +715,7 @@ compile_tr(const char *p, struct s_tr **py)
y->multis = realloc(y->multis,
(y->nmultis + 1) * sizeof(*y->multis));
if (y->multis == NULL)
- err(1, "realloc");
+ err(1, NULL);
i = y->nmultis++;
y->multis[i].fromlen = oclen;
memcpy(y->multis[i].from, op, oclen);
@@ -723,24 +733,23 @@ compile_tr(const char *p, struct s_tr **py)
* Compile the text following an a, c, or i command.
*/
static char *
-compile_text(size_t *ptlen)
+compile_text(void)
{
int asize, esc_nl, size;
- char *text, *s;
- const char *p, *op;
+ char *text, *p, *op, *s;
+ char lbuf[_POSIX2_LINE_MAX + 1];
asize = 2 * _POSIX2_LINE_MAX + 1;
if ((text = malloc(asize)) == NULL)
err(1, "malloc");
size = 0;
- while ((p = cu_fgets(NULL)) != NULL) {
+ while (cu_fgets(lbuf, sizeof(lbuf), NULL) != NULL) {
op = s = text + size;
+ p = lbuf;
for (esc_nl = 0; *p != '\0'; p++) {
if (*p == '\\' && p[1] != '\0' && *++p == '\n')
esc_nl = 1;
*s++ = *p;
- if (*p == '\n')
- break;
}
size += s - op;
if (!esc_nl) {
@@ -754,18 +763,17 @@ compile_text(size_t *ptlen)
}
}
text[size] = '\0';
- if ((text = realloc(text, size + 1)) == NULL)
+ if ((p = realloc(text, size + 1)) == NULL)
err(1, "realloc");
- *ptlen = size;
- return (text);
+ return (p);
}
/*
* Get an address and return a pointer to the first character after
* it. Fill the structure pointed to according to the address.
*/
-static const char *
-compile_addr(const char *p, struct s_addr *a)
+static char *
+compile_addr(char *p, struct s_addr *a)
{
char *end, re[_POSIX2_LINE_MAX + 1];
int icase;
@@ -819,26 +827,22 @@ compile_addr(const char *p, struct s_addr *a)
* Return a copy of all the characters up to \n or \0.
*/
static char *
-duptoeol(const char *s, const char *ctype, size_t *ptlen)
+duptoeol(char *s, const char *ctype)
{
size_t len;
int ws;
- char *p;
- const char *start;
+ char *p, *start;
ws = 0;
for (start = s; *s != '\0' && *s != '\n'; ++s)
ws = isspace((unsigned char)*s);
+ *s = '\0';
if (ws)
warnx("%lu: %s: whitespace after %s", linenum, fname, ctype);
- len = s - start;
- if ((p = malloc(len + 1)) == NULL)
+ len = s - start + 1;
+ if ((p = malloc(len)) == NULL)
err(1, "malloc");
- memmove(p, start, len);
- p[len] = '\0';
- if (ptlen != NULL)
- *ptlen = len;
- return p;
+ return (memmove(p, start, len));
}
/*
@@ -849,7 +853,7 @@ duptoeol(const char *s, const char *ctype, size_t *ptlen)
* TODO: Remove } nodes
*/
static void
-fixuplabel(struct s_command *cp, const struct s_command *end)
+fixuplabel(struct s_command *cp, struct s_command *end)
{
for (; cp != end; cp = cp->next)
@@ -866,7 +870,7 @@ fixuplabel(struct s_command *cp, const struct s_command *end)
break;
}
if ((cp->u.c = findlabel(cp->t)) == NULL)
- errx(1, "%lu: %s: %c: undefined label '%s'", linenum, fname, cp->code, cp->t);
+ errx(1, "%lu: %s: undefined label '%s'", linenum, fname, cp->t);
free(cp->t);
break;
case '{':
@@ -906,13 +910,13 @@ enterlabel(struct s_command *cp)
* list cp. L is excluded from the search. Return NULL if not found.
*/
static struct s_command *
-findlabel(const char *name)
+findlabel(char *name)
{
struct labhash *lh;
- const u_char *p;
+ u_char *p;
u_int h, c;
- for (h = 0, p = (const u_char *)name; (c = *p) != 0; p++)
+ for (h = 0, p = (u_char *)name; (c = *p) != 0; p++)
h = (h << 5) + h + c;
for (lh = labels[h & LHMASK]; lh != NULL; lh = lh->lh_next) {
if (lh->lh_hash == h && strcmp(name, lh->lh_cmd->t) == 0) {
diff --git a/usr.bin/sed/defs.h b/usr.bin/sed/defs.h
index 7d48d75e0c91..fb336765d639 100644
--- a/usr.bin/sed/defs.h
+++ b/usr.bin/sed/defs.h
@@ -51,7 +51,7 @@ struct s_addr {
enum e_atype type; /* Address type */
union {
u_long l; /* Line number */
- const regex_t *r; /* Regular expression */
+ regex_t *r; /* Regular expression */
} u;
};
@@ -64,7 +64,7 @@ struct s_subst {
int icase; /* True if I flag */
char *wfile; /* NULL if no wfile */
int wfd; /* Cached file descriptor */
- const regex_t *re; /* Regular expression */
+ regex_t *re; /* Regular expression */
unsigned int maxbref; /* Largest backreference. */
u_long linenum; /* Line number. */
char *new; /* Replacement text */
@@ -94,7 +94,6 @@ struct s_command {
struct s_addr *a1, *a2; /* Start and end address */
u_long startline; /* Start line number or zero */
char *t; /* Text for : a c i r w */
- size_t tlen;
union {
struct s_command *c; /* Command(s) for b t { */
struct s_subst *s; /* Substitute command */
diff --git a/usr.bin/sed/extern.h b/usr.bin/sed/extern.h
index 85f10b62b1aa..f2bd71bacfa4 100644
--- a/usr.bin/sed/extern.h
+++ b/usr.bin/sed/extern.h
@@ -45,12 +45,12 @@ extern const char *fname, *outfname;
extern FILE *infile, *outfile;
extern int rflags; /* regex flags to use */
-void cfclose(struct s_command *, const struct s_command *);
+void cfclose(struct s_command *, struct s_command *);
void compile(void);
void cspace(SPACE *, const char *, size_t, enum e_spflag);
-const char *cu_fgets(int *);
+char *cu_fgets(char *, int, int *);
int mf_fgets(SPACE *, enum e_spflag);
int lastline(void);
void process(void);
void resetstate(void);
-char *strregerror(int, const regex_t *);
+char *strregerror(int, regex_t *);
diff --git a/usr.bin/sed/main.c b/usr.bin/sed/main.c
index 39d720cbb483..742881b649ba 100644
--- a/usr.bin/sed/main.c
+++ b/usr.bin/sed/main.c
@@ -72,7 +72,7 @@ static const char sccsid[] = "@(#)main.c 8.2 (Berkeley) 1/3/94";
struct s_compunit {
struct s_compunit *next;
enum e_cut {CU_FILE, CU_STRING} type;
- const char *s; /* Pointer to string or fname */
+ char *s; /* Pointer to string or fname */
};
/*
@@ -85,7 +85,7 @@ static struct s_compunit *script, **cu_nextp = &script;
* Linked list of files to be processed
*/
struct s_flist {
- const char *fname;
+ char *fname;
struct s_flist *next;
};
@@ -116,15 +116,15 @@ static char tmpfname[PATH_MAX]; /* Temporary file name (for in-place editing) */
static const char *inplace; /* Inplace edit file extension. */
u_long linenum;
-static void add_compunit(enum e_cut, const char *);
-static void add_file(const char *);
+static void add_compunit(enum e_cut, char *);
+static void add_file(char *);
static void usage(void);
int
main(int argc, char *argv[])
{
- char *temp_arg;
int c, fflag;
+ char *temp_arg;
(void) setlocale(LC_ALL, "");
@@ -146,9 +146,10 @@ main(int argc, char *argv[])
break;
case 'e':
eflag = 1;
- asprintf(&temp_arg, "%s\n", optarg);
- if (temp_arg == NULL)
- errx(1, "Couldn't allocate temporary buffer");
+ if ((temp_arg = malloc(strlen(optarg) + 2)) == NULL)
+ err(1, "malloc");
+ strcpy(temp_arg, optarg);
+ strcat(temp_arg, "\n");
add_compunit(CU_STRING, temp_arg);
break;
case 'f':
@@ -212,16 +213,14 @@ usage(void)
* Like fgets, but go through the chain of compilation units chaining them
* together. Empty strings and files are ignored.
*/
-const char *
-cu_fgets(int *more)
+char *
+cu_fgets(char *buf, int n, int *more)
{
static enum {ST_EOF, ST_FILE, ST_STRING} state = ST_EOF;
static FILE *f; /* Current open file */
- static const char *s; /* Current pointer inside string */
- static char string_ident[30], *lastresult;
- static size_t lastsize;
+ static char *s; /* Current pointer inside string */
+ static char string_ident[30];
char *p;
- const char *start;
again:
switch (state) {
@@ -251,16 +250,14 @@ again:
goto again;
}
case ST_FILE:
- p = lastresult;
- if (getline(&p, &lastsize, f) != -1) {
+ if ((p = fgets(buf, n, f)) != NULL) {
linenum++;
- if (linenum == 1 && p[0] == '#' && p[1] == 'n')
+ if (linenum == 1 && buf[0] == '#' && buf[1] == 'n')
nflag = 1;
if (more != NULL)
*more = !feof(f);
- return (lastresult = p);
- } else if (ferror(f))
- err(1, "%s", script->s);
+ return (p);
+ }
script = script->next;
(void)fclose(f);
state = ST_EOF;
@@ -268,26 +265,39 @@ again:
case ST_STRING:
if (linenum == 0 && s[0] == '#' && s[1] == 'n')
nflag = 1;
- else if (s[0] == '\0') {
- state = ST_EOF;
- script = script->next;
- goto again;
- }
- start = s;
+ p = buf;
for (;;) {
+ if (n-- <= 1) {
+ *p = '\0';
+ linenum++;
+ if (more != NULL)
+ *more = 1;
+ return (buf);
+ }
switch (*s) {
case '\0':
state = ST_EOF;
- script = script->next;
- /* FALLTHROUGH */
+ if (s == script->s) {
+ script = script->next;
+ goto again;
+ } else {
+ script = script->next;
+ *p = '\0';
+ linenum++;
+ if (more != NULL)
+ *more = 0;
+ return (buf);
+ }
case '\n':
+ *p++ = '\n';
+ *p = '\0';
s++;
linenum++;
if (more != NULL)
*more = 0;
- return (start);
+ return (buf);
default:
- s++;
+ *p++ = *s++;
}
}
}
@@ -390,7 +400,7 @@ mf_fgets(SPACE *sp, enum e_spflag spflag)
sizeof(oldfname));
len = strlcat(oldfname, inplace,
sizeof(oldfname));
- if ((size_t)len > sizeof(oldfname))
+ if (len > (ssize_t)sizeof(oldfname))
errx(1, "%s: name too long", fname);
}
if ((dirbuf = strdup(fname)) == NULL ||
@@ -401,7 +411,7 @@ mf_fgets(SPACE *sp, enum e_spflag spflag)
basename(basebuf));
free(dirbuf);
free(basebuf);
- if ((size_t)len >= sizeof(tmpfname))
+ if (len >= (ssize_t)sizeof(tmpfname))
errx(1, "%s: name too long", fname);
unlink(tmpfname);
if (outfile != NULL && outfile != stdout)
@@ -455,7 +465,7 @@ mf_fgets(SPACE *sp, enum e_spflag spflag)
* Add a compilation unit to the linked list
*/
static void
-add_compunit(enum e_cut type, const char *s)
+add_compunit(enum e_cut type, char *s)
{
struct s_compunit *cu;
@@ -472,7 +482,7 @@ add_compunit(enum e_cut type, const char *s)
* Add a file to the linked list
*/
static void
-add_file(const char *s)
+add_file(char *s)
{
struct s_flist *fp;
diff --git a/usr.bin/sed/misc.c b/usr.bin/sed/misc.c
index 650c728c9f54..f3b513784a6e 100644
--- a/usr.bin/sed/misc.c
+++ b/usr.bin/sed/misc.c
@@ -56,14 +56,16 @@ static const char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 6/6/93";
* the buffer).
*/
char *
-strregerror(int errcode, const regex_t *preg)
+strregerror(int errcode, regex_t *preg)
{
static char *oe;
size_t s;
+ if (oe != NULL)
+ free(oe);
s = regerror(errcode, preg, NULL, 0);
- if ((oe = realloc(oe, s)) == NULL)
- err(1, "realloc");
+ if ((oe = malloc(s)) == NULL)
+ err(1, "malloc");
(void)regerror(errcode, preg, oe, s);
return (oe);
}
diff --git a/usr.bin/sed/process.c b/usr.bin/sed/process.c
index ba2a12f4dd71..d4779febd8f6 100644
--- a/usr.bin/sed/process.c
+++ b/usr.bin/sed/process.c
@@ -67,14 +67,14 @@ static SPACE HS, PS, SS, YS;
#define hs HS.space
#define hsl HS.len
-static inline int applies(struct s_command *);
-static void do_tr(const struct s_tr *);
-static void flush_appends(void);
-static void lputs(const char *, size_t);
-static int regexec_e(const regex_t *, const char *, int, int,
- size_t, size_t);
-static void regsub(SPACE *, const char *, const char *);
-static int substitute(const struct s_command *);
+static inline int applies(struct s_command *);
+static void do_tr(struct s_tr *);
+static void flush_appends(void);
+static void lputs(char *, size_t);
+static int regexec_e(regex_t *, const char *, int, int, size_t,
+ size_t);
+static void regsub(SPACE *, char *, char *);
+static int substitute(struct s_command *);
struct s_appends *appends; /* Array of pointers to strings to append. */
static int appendx; /* Index into appends array. */
@@ -83,7 +83,7 @@ int appendnum; /* Size of appends array. */
static int lastaddr; /* Set by applies if last address of a range. */
static int sdone; /* If any substitutes since last line input. */
/* Iov structure for 'w' commands. */
-static const regex_t *defpreg;
+static regex_t *defpreg;
size_t maxnsub;
regmatch_t *match;
@@ -377,13 +377,13 @@ resetstate(void)
* and then swap them.
*/
static int
-substitute(const struct s_command *cp)
+substitute(struct s_command *cp)
{
SPACE tspace;
- const regex_t *re;
+ regex_t *re;
regoff_t slen;
int lastempty, n;
- regoff_t le = 0;
+ size_t le = 0;
char *s;
s = ps;
@@ -489,7 +489,7 @@ substitute(const struct s_command *cp)
* Perform translation ('y' command) in the pattern space.
*/
static void
-do_tr(const struct s_tr *y)
+do_tr(struct s_tr *y)
{
SPACE tmp;
char c, *p;
@@ -579,7 +579,7 @@ flush_appends(void)
}
static void
-lputs(const char *s, size_t len)
+lputs(char *s, size_t len)
{
static const char escapes[] = "\\\a\b\f\r\t\v";
int c, col, width;
@@ -659,7 +659,7 @@ lputs(const char *s, size_t len)
}
static int
-regexec_e(const regex_t *preg, const char *string, int eflags, int nomatch,
+regexec_e(regex_t *preg, const char *string, int eflags, int nomatch,
size_t start, size_t stop)
{
int eval;
@@ -691,7 +691,7 @@ regexec_e(const regex_t *preg, const char *string, int eflags, int nomatch,
* Based on a routine by Henry Spencer
*/
static void
-regsub(SPACE *sp, const char *string, const char *src)
+regsub(SPACE *sp, char *string, char *src)
{
int len, no;
char c, *dst;
@@ -763,7 +763,7 @@ cspace(SPACE *sp, const char *p, size_t len, enum e_spflag spflag)
* Close all cached opened files and report any errors
*/
void
-cfclose(struct s_command *cp, const struct s_command *end)
+cfclose(struct s_command *cp, struct s_command *end)
{
for (; cp != end; cp = cp->next)