svn commit: r303047 - head/usr.bin/sed

Pedro F. Giffuni pfg at FreeBSD.org
Tue Jul 19 22:56:42 UTC 2016


Author: pfg
Date: Tue Jul 19 22:56:40 2016
New Revision: 303047
URL: https://svnweb.freebsd.org/changeset/base/303047

Log:
  sed(1):	Assorted cleanups and simplifications.
  
  Const-ify several variables, make it build cleanly with WARNS level 5.
  
  Submitted by:	mi
  PR:		195929
  MFC after:	1 month

Modified:
  head/usr.bin/sed/Makefile
  head/usr.bin/sed/compile.c
  head/usr.bin/sed/defs.h
  head/usr.bin/sed/extern.h
  head/usr.bin/sed/main.c
  head/usr.bin/sed/misc.c
  head/usr.bin/sed/process.c

Modified: head/usr.bin/sed/Makefile
==============================================================================
--- head/usr.bin/sed/Makefile	Tue Jul 19 20:22:13 2016	(r303046)
+++ head/usr.bin/sed/Makefile	Tue Jul 19 22:56:40 2016	(r303047)
@@ -6,7 +6,7 @@
 PROG=	sed
 SRCS=	compile.c main.c misc.c process.c
 
-WARNS?=	2
+WARNS?=	5
 
 .if ${MK_TESTS} != "no"
 SUBDIR+= tests

Modified: head/usr.bin/sed/compile.c
==============================================================================
--- head/usr.bin/sed/compile.c	Tue Jul 19 20:22:13 2016	(r303046)
+++ head/usr.bin/sed/compile.c	Tue Jul 19 22:56:40 2016	(r303047)
@@ -64,21 +64,21 @@ static struct labhash {
 	int	lh_ref;
 } *labels[LHSZ];
 
-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 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 struct s_command
 		**compile_stream(struct s_command **);
-static char	 *duptoeol(char *, const char *);
+static char	 *duptoeol(const char *, const char *, size_t *);
 static void	  enterlabel(struct s_command *);
 static struct s_command
-		 *findlabel(char *);
-static void	  fixuplabel(struct s_command *, struct s_command *);
+		 *findlabel(const char *);
+static void	  fixuplabel(struct s_command *, const struct s_command *);
 static void	  uselabel(void);
 
 /*
@@ -144,17 +144,20 @@ compile(void)
 		err(1, "malloc");
 }
 
-#define EATSPACE() do {							\
-	if (p)								\
-		while (*p && isspace((unsigned char)*p))                \
-			p++;						\
+#define	EATSPACE() do {						\
+	while (*p && isspace((unsigned char)*p))		\
+		p++;						\
+	} while (0)
+
+#define	EATSPACEN() do {					\
+	while (*p && *p != '\n' && isspace((unsigned char)*p))  \
+		p++;						\
 	} while (0)
 
 static struct s_command **
 compile_stream(struct s_command **link)
 {
-	char *p;
-	static char lbuf[_POSIX2_LINE_MAX + 1];	/* To save stack */
+	const char *p;
 	struct s_command *cmd, *cmd2, *stack;
 	struct s_format *fp;
 	char re[_POSIX2_LINE_MAX + 1];
@@ -162,22 +165,22 @@ compile_stream(struct s_command **link)
 
 	stack = NULL;
 	for (;;) {
-		if ((p = cu_fgets(lbuf, sizeof(lbuf), NULL)) == NULL) {
+		if ((p = cu_fgets(NULL)) == NULL) {
 			if (stack != NULL)
 				errx(1, "%lu: %s: unexpected EOF (pending }'s)",
 							linenum, fname);
 			return (link);
 		}
 
-semicolon:	EATSPACE();
-		if (p) {
-			if (*p == '#' || *p == '\0')
-				continue;
-			else if (*p == ';') {
-				p++;
-				goto semicolon;
-			}
+semicolon:	EATSPACEN();
+		switch (*p) {
+		case '#': case '\0': case '\n':
+			continue;	/* to next command-unit */
+		case ';':
+			p++;
+			goto semicolon;
 		}
+
 		if ((*link = cmd = malloc(sizeof(struct s_command))) == NULL)
 			err(1, "malloc");
 		link = &cmd->next;
@@ -208,14 +211,14 @@ semicolon:	EATSPACE();
 			cmd->a1 = cmd->a2 = NULL;
 
 nonsel:		/* Now parse the command */
-		if (!*p)
+		if (*p == '\0' || *p == '\n')
 			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", linenum, fname, *p);
+			errx(1, "%lu: %s: invalid command code %c (%s)", linenum, fname, *p, p);
 		if (naddr > fp->naddr)
 			errx(1,
 				"%lu: %s: command %c expects up to %d address(es), found %d",
@@ -228,11 +231,11 @@ nonsel:		/* Now parse the command */
 			goto nonsel;
 		case GROUP:			/* { */
 			p++;
-			EATSPACE();
+			EATSPACEN();
 			cmd->next = stack;
 			stack = cmd;
 			link = &cmd->u.c;
-			if (*p)
+			if (*p != '\0' && *p != '\n')
 				goto semicolon;
 			break;
 		case ENDGROUP:
@@ -249,13 +252,13 @@ nonsel:		/* Now parse the command */
 			/*FALLTHROUGH*/
 		case EMPTY:		/* d D g G h H l n N p P q x = \0 */
 			p++;
-			EATSPACE();
+			EATSPACEN();
 			if (*p == ';') {
 				p++;
 				link = &cmd->next;
 				goto semicolon;
 			}
-			if (*p)
+			if (*p != '\0' && *p != '\n')
 				errx(1, "%lu: %s: extra characters at the end of %c command",
 						linenum, fname, cmd->code);
 			break;
@@ -266,12 +269,12 @@ nonsel:		/* Now parse the command */
 				errx(1,
 "%lu: %s: command %c expects \\ followed by text", linenum, fname, cmd->code);
 			p++;
-			EATSPACE();
-			if (*p)
+			EATSPACEN();
+			if (*p != '\n')
 				errx(1,
-				"%lu: %s: extra characters after \\ at the end of %c command",
-				linenum, fname, cmd->code);
-			cmd->t = compile_text();
+				"%lu: %s: extra characters (%c) after \\ at the end of %c command",
+				linenum, fname, *p, cmd->code);
+			cmd->t = compile_text(&cmd->tlen);
 			break;
 		case COMMENT:			/* \0 # */
 			break;
@@ -280,10 +283,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->t = duptoeol(p, "w command", &cmd->tlen);
 			if (aflag)
 				cmd->u.fd = -1;
-			else if ((cmd->u.fd = open(p,
+			else if ((cmd->u.fd = open(cmd->t,
 			    O_WRONLY|O_APPEND|O_CREAT|O_TRUNC,
 			    DEFFILEMODE)) == -1)
 				err(1, "%s", p);
@@ -294,27 +297,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->t = duptoeol(p, "read command", &cmd->tlen);
 			break;
 		case BRANCH:			/* b t */
 			p++;
-			EATSPACE();
-			if (*p == '\0')
+			EATSPACEN();
+			if (*p == '\0' || *p == '\n')
 				cmd->t = NULL;
 			else
-				cmd->t = duptoeol(p, "branch");
+				cmd->t = duptoeol(p, "branch", &cmd->tlen);
 			break;
 		case LABEL:			/* : */
 			p++;
 			EATSPACE();
-			cmd->t = duptoeol(p, "label");
-			if (strlen(p) == 0)
+			cmd->t = duptoeol(p, "label", &cmd->tlen);
+			if (cmd->t[0] == '\0')
 				errx(1, "%lu: %s: empty label", linenum, fname);
 			enterlabel(cmd);
 			break;
 		case SUBST:			/* s */
 			p++;
-			if (*p == '\0' || *p == '\\')
+			if (*p == '\0' || *p == '\\' || *p == '\n')
 				errx(1,
 "%lu: %s: substitute pattern can not be delimited by newline or backslash",
 					linenum, fname);
@@ -325,21 +328,15 @@ 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);
 
-			/* Recompile RE with case sensitivity from "I" flag if any */
-			if (*re == '\0')
-				cmd->u.s->re = NULL;
-			else
+			if (*re != '\0')
 				cmd->u.s->re = compile_re(re, cmd->u.s->icase);
+
 			EATSPACE();
+
 			if (*p == ';') {
 				p++;
 				link = &cmd->next;
@@ -372,8 +369,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 char *
-compile_delimited(char *p, char *d, int is_tr)
+static const char *
+compile_delimited(const char *p, char *d, int is_tr)
 {
 	char c;
 
@@ -416,10 +413,10 @@ compile_delimited(char *p, char *d, int 
 
 /* compile_ccl: expand a POSIX character class */
 static char *
-compile_ccl(char **sp, char *t)
+compile_ccl(const char **sp, char *t)
 {
 	int c, d;
-	char *s = *sp;
+	const char *s = *sp;
 
 	*t++ = *s++;
 	if (*s == '^')
@@ -441,8 +438,8 @@ compile_ccl(char **sp, char *t)
  * regular expression.
  * Cflags are passed to regcomp.
  */
-static regex_t *
-compile_re(char *re, int case_insensitive)
+static const regex_t *
+compile_re(const char *re, int case_insensitive)
 {
 	regex_t *rep;
 	int eval, flags;
@@ -466,14 +463,13 @@ compile_re(char *re, int case_insensitiv
  * point to a saved copy of it.  Nsub is the number of parenthesized regular
  * expressions.
  */
-static char *
-compile_subst(char *p, struct s_subst *s)
+static const char *
+compile_subst(const 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 = 1, sawesc = 0;
+	int more = 0, sawesc = 0;
 
 	c = *p++;			/* Terminator character */
 	if (c == '\0')
@@ -487,7 +483,7 @@ compile_subst(char *p, struct s_subst *s
 	size = 0;
 	do {
 		op = sp = text + size;
-		for (; *p; p++) {
+		for (; *p != '\0' && *p != '\n'; p++) {
 			if (*p == '\\' || sawesc) {
 				/*
 				 * If this is a continuation from the last
@@ -509,7 +505,10 @@ compile_subst(char *p, struct s_subst *s
 					 */
 					sawesc = 1;
 					p--;
-					continue;
+					break;
+				} else if (*p == '\n') {
+					*sp++ = '\n';
+					break;
 				} else if (strchr("123456789", *p) != NULL) {
 					*sp++ = '\\';
 					ref = *p - '0';
@@ -523,8 +522,11 @@ compile_subst(char *p, struct s_subst *s
 					*sp++ = '\\';
 			} else if (*p == c) {
 				if (*++p == '\0' && more) {
-					if (cu_fgets(lbuf, sizeof(lbuf), &more))
-						p = lbuf;
+					const char *nextp;
+
+					nextp = cu_fgets(&more);
+					if (nextp != NULL)
+						p = nextp;
 				}
 				*sp++ = '\0';
 				size += sp - op;
@@ -544,7 +546,7 @@ compile_subst(char *p, struct s_subst *s
 			if ((text = realloc(text, asize)) == NULL)
 				err(1, "realloc");
 		}
-	} while (cu_fgets(p = lbuf, sizeof(lbuf), &more));
+	} while ((p = cu_fgets(&more)));
 	errx(1, "%lu: %s: unterminated substitute in regular expression",
 			linenum, fname);
 	/* NOTREACHED */
@@ -553,12 +555,12 @@ compile_subst(char *p, struct s_subst *s
 /*
  * Compile the flags of the s command
  */
-static char *
-compile_flags(char *p, struct s_subst *s)
+static const char *
+compile_flags(const char *p, struct s_subst *s)
 {
 	int gn;			/* True if we have seen g or n */
 	unsigned long nval;
-	char wfile[_POSIX2_LINE_MAX + 1], *q, *eq;
+	char *q;
 
 	s->n = 1;				/* Default */
 	s->p = 0;
@@ -566,7 +568,7 @@ compile_flags(char *p, struct s_subst *s
 	s->wfd = -1;
 	s->icase = 0;
 	for (gn = 0;;) {
-		EATSPACE();			/* EXTENSION */
+		EATSPACEN();			/* EXTENSION */
 		switch (*p) {
 		case 'g':
 			if (gn)
@@ -594,13 +596,13 @@ compile_flags(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, &p, 10);
+			nval = strtol(p, &q, 10);
 			if (errno == ERANGE || nval > INT_MAX)
 				errx(1,
 "%lu: %s: overflow in the 'N' substitute flag", linenum, fname);
 			s->n = nval;
-			p--;
-			break;
+			p = q;
+			continue;
 		case 'w':
 			p++;
 #ifdef HISTORIC_PRACTICE
@@ -610,27 +612,15 @@ compile_flags(char *p, struct s_subst *s
 			}
 #endif
 			EATSPACE();
-			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,
+			s->wfile = duptoeol(p, "w flag", NULL);
+			if (!aflag && (s->wfd = open(s->wfile,
 			    O_WRONLY|O_APPEND|O_CREAT|O_TRUNC,
 			    DEFFILEMODE)) == -1)
-				err(1, "%s", wfile);
+				err(1, "%s", s->wfile);
 			return (p);
 		default:
-			errx(1, "%lu: %s: bad flag in substitute command: '%c'",
-					linenum, fname, *p);
+			errx(1, "%lu: %s: bad flag in substitute command: '%c' (%.10s)",
+					linenum, fname, *p, p);
 			break;
 		}
 		p++;
@@ -640,8 +630,8 @@ compile_flags(char *p, struct s_subst *s
 /*
  * Compile a translation set of strings into a lookup table.
  */
-static char *
-compile_tr(char *p, struct s_tr **py)
+static const char *
+compile_tr(const char *p, struct s_tr **py)
 {
 	struct s_tr *y;
 	int i;
@@ -652,7 +642,7 @@ compile_tr(char *p, struct s_tr **py)
 	mbstate_t mbs1, mbs2;
 
 	if ((*py = y = malloc(sizeof(*y))) == NULL)
-		err(1, NULL);
+		err(1, "malloc");
 	y->multis = NULL;
 	y->nmultis = 0;
 
@@ -672,11 +662,11 @@ compile_tr(char *p, struct s_tr **py)
 	op = old;
 	oldlen = mbsrtowcs(NULL, &op, 0, NULL);
 	if (oldlen == (size_t)-1)
-		err(1, NULL);
+		err(1, "mbsrtowcs");
 	np = new;
 	newlen = mbsrtowcs(NULL, &np, 0, NULL);
 	if (newlen == (size_t)-1)
-		err(1, NULL);
+		err(1, "mbsrtowcs");
 	if (newlen != oldlen)
 		errx(1, "%lu: %s: transform strings are not the same length",
 				linenum, fname);
@@ -715,7 +705,7 @@ compile_tr(char *p, struct s_tr **py)
 				y->multis = realloc(y->multis,
 				    (y->nmultis + 1) * sizeof(*y->multis));
 				if (y->multis == NULL)
-					err(1, NULL);
+					err(1, "realloc");
 				i = y->nmultis++;
 				y->multis[i].fromlen = oclen;
 				memcpy(y->multis[i].from, op, oclen);
@@ -733,23 +723,24 @@ compile_tr(char *p, struct s_tr **py)
  * Compile the text following an a, c, or i command.
  */
 static char *
-compile_text(void)
+compile_text(size_t *ptlen)
 {
 	int asize, esc_nl, size;
-	char *text, *p, *op, *s;
-	char lbuf[_POSIX2_LINE_MAX + 1];
+	char *text, *s;
+	const char *p, *op;
 
 	asize = 2 * _POSIX2_LINE_MAX + 1;
 	if ((text = malloc(asize)) == NULL)
 		err(1, "malloc");
 	size = 0;
-	while (cu_fgets(lbuf, sizeof(lbuf), NULL)) {
+	while ((p = cu_fgets(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) {
@@ -763,17 +754,18 @@ compile_text(void)
 		}
 	}
 	text[size] = '\0';
-	if ((p = realloc(text, size + 1)) == NULL)
+	if ((text = realloc(text, size + 1)) == NULL)
 		err(1, "realloc");
-	return (p);
+	*ptlen = size;
+	return (text);
 }
 
 /*
  * Get an address and return a pointer to the first character after
  * it.  Fill the structure pointed to according to the address.
  */
-static char *
-compile_addr(char *p, struct s_addr *a)
+static const char *
+compile_addr(const char *p, struct s_addr *a)
 {
 	char *end, re[_POSIX2_LINE_MAX + 1];
 	int icase;
@@ -827,22 +819,26 @@ compile_addr(char *p, struct s_addr *a)
  *	Return a copy of all the characters up to \n or \0.
  */
 static char *
-duptoeol(char *s, const char *ctype)
+duptoeol(const char *s, const char *ctype, size_t *ptlen)
 {
 	size_t len;
 	int ws;
-	char *p, *start;
+	char *p;
+	const char *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 + 1;
-	if ((p = malloc(len)) == NULL)
+	len = s - start;
+	if ((p = malloc(len + 1)) == NULL)
 		err(1, "malloc");
-	return (memmove(p, start, len));
+	memmove(p, start, len);
+	p[len] = '\0';
+	if (ptlen != NULL)
+		*ptlen = len;
+	return p;
 }
 
 /*
@@ -853,7 +849,7 @@ duptoeol(char *s, const char *ctype)
  * TODO: Remove } nodes
  */
 static void
-fixuplabel(struct s_command *cp, struct s_command *end)
+fixuplabel(struct s_command *cp, const struct s_command *end)
 {
 
 	for (; cp != end; cp = cp->next)
@@ -870,7 +866,7 @@ fixuplabel(struct s_command *cp, struct 
 				break;
 			}
 			if ((cp->u.c = findlabel(cp->t)) == NULL)
-				errx(1, "%lu: %s: undefined label '%s'", linenum, fname, cp->t);
+				errx(1, "%lu: %s: %c: undefined label '%s'", linenum, fname, cp->code, cp->t);
 			free(cp->t);
 			break;
 		case '{':
@@ -910,13 +906,13 @@ enterlabel(struct s_command *cp)
  * list cp.  L is excluded from the search.  Return NULL if not found.
  */
 static struct s_command *
-findlabel(char *name)
+findlabel(const char *name)
 {
 	struct labhash *lh;
-	u_char *p;
+	const u_char *p;
 	u_int h, c;
 
-	for (h = 0, p = (u_char *)name; (c = *p) != 0; p++)
+	for (h = 0, p = (const 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) {

Modified: head/usr.bin/sed/defs.h
==============================================================================
--- head/usr.bin/sed/defs.h	Tue Jul 19 20:22:13 2016	(r303046)
+++ head/usr.bin/sed/defs.h	Tue Jul 19 22:56:40 2016	(r303047)
@@ -51,7 +51,7 @@ struct s_addr {
 	enum e_atype type;			/* Address type */
 	union {
 		u_long l;			/* Line number */
-		regex_t *r;			/* Regular expression */
+		const 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 */
-	regex_t *re;				/* Regular expression */
+	const regex_t *re;			/* Regular expression */
 	unsigned int maxbref;			/* Largest backreference. */
 	u_long linenum;				/* Line number. */
 	char *new;				/* Replacement text */
@@ -94,6 +94,7 @@ 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 */

Modified: head/usr.bin/sed/extern.h
==============================================================================
--- head/usr.bin/sed/extern.h	Tue Jul 19 20:22:13 2016	(r303046)
+++ head/usr.bin/sed/extern.h	Tue Jul 19 22:56:40 2016	(r303047)
@@ -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 *, struct s_command *);
+void	 cfclose(struct s_command *, const struct s_command *);
 void	 compile(void);
 void	 cspace(SPACE *, const char *, size_t, enum e_spflag);
-char	*cu_fgets(char *, int, int *);
+const char *cu_fgets(int *);
 int	 mf_fgets(SPACE *, enum e_spflag);
 int	 lastline(void);
 void	 process(void);
 void	 resetstate(void);
-char	*strregerror(int, regex_t *);
+char	*strregerror(int, const regex_t *);

Modified: head/usr.bin/sed/main.c
==============================================================================
--- head/usr.bin/sed/main.c	Tue Jul 19 20:22:13 2016	(r303046)
+++ head/usr.bin/sed/main.c	Tue Jul 19 22:56:40 2016	(r303047)
@@ -73,7 +73,7 @@ static const char sccsid[] = "@(#)main.c
 struct s_compunit {
 	struct s_compunit *next;
 	enum e_cut {CU_FILE, CU_STRING} type;
-	char *s;			/* Pointer to string or fname */
+	const char *s;			/* Pointer to string or fname */
 };
 
 /*
@@ -86,7 +86,7 @@ static struct s_compunit *script, **cu_n
  * Linked list of files to be processed
  */
 struct s_flist {
-	char *fname;
+	const char *fname;
 	struct s_flist *next;
 };
 
@@ -117,15 +117,14 @@ static char tmpfname[PATH_MAX];	/* Tempo
 static const char *inplace;	/* Inplace edit file extension. */
 u_long linenum;
 
-static void add_compunit(enum e_cut, char *);
-static void add_file(char *);
+static void add_compunit(enum e_cut, const char *);
+static void add_file(const char *);
 static void usage(void);
 
 int
 main(int argc, char *argv[])
 {
 	int c, fflag;
-	char *temp_arg;
 
 	(void) setlocale(LC_ALL, "");
 
@@ -147,11 +146,7 @@ main(int argc, char *argv[])
 			break;
 		case 'e':
 			eflag = 1;
-			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);
+			add_compunit(CU_STRING, optarg);
 			break;
 		case 'f':
 			fflag = 1;
@@ -214,14 +209,16 @@ usage(void)
  * Like fgets, but go through the chain of compilation units chaining them
  * together.  Empty strings and files are ignored.
  */
-char *
-cu_fgets(char *buf, int n, int *more)
+const char *
+cu_fgets(int *more)
 {
 	static enum {ST_EOF, ST_FILE, ST_STRING} state = ST_EOF;
 	static FILE *f;		/* Current open file */
-	static char *s;		/* Current pointer inside string */
-	static char string_ident[30];
+	static const char *s;	/* Current pointer inside string */
+	static char string_ident[30], *lastresult;
+	static size_t lastsize;
 	char *p;
+	const char *start;
 
 again:
 	switch (state) {
@@ -251,14 +248,16 @@ again:
 			goto again;
 		}
 	case ST_FILE:
-		if ((p = fgets(buf, n, f)) != NULL) {
+		p = lastresult;
+		if (getline(&p, &lastsize, f) != -1) {
 			linenum++;
-			if (linenum == 1 && buf[0] == '#' && buf[1] == 'n')
+			if (linenum == 1 && p[0] == '#' && p[1] == 'n')
 				nflag = 1;
 			if (more != NULL)
 				*more = !feof(f);
-			return (p);
-		}
+			return (lastresult = p);
+		} else if (ferror(f))
+			err(1, "%s", script->s);
 		script = script->next;
 		(void)fclose(f);
 		state = ST_EOF;
@@ -266,39 +265,26 @@ again:
 	case ST_STRING:
 		if (linenum == 0 && s[0] == '#' && s[1] == 'n')
 			nflag = 1;
-		p = buf;
+		else if (s[0] == '\0') {
+			state = ST_EOF;
+			script = script->next;
+			goto again;
+		}
+		start = s;
 		for (;;) {
-			if (n-- <= 1) {
-				*p = '\0';
-				linenum++;
-				if (more != NULL)
-					*more = 1;
-				return (buf);
-			}
 			switch (*s) {
 			case '\0':
 				state = ST_EOF;
-				if (s == script->s) {
-					script = script->next;
-					goto again;
-				} else {
-					script = script->next;
-					*p = '\0';
-					linenum++;
-					if (more != NULL)
-						*more = 0;
-					return (buf);
-				}
+				script = script->next;
+				/* FALLTHROUGH */
 			case '\n':
-				*p++ = '\n';
-				*p = '\0';
 				s++;
 				linenum++;
 				if (more != NULL)
 					*more = 0;
-				return (buf);
+				return (start);
 			default:
-				*p++ = *s++;
+				s++;
 			}
 		}
 	}
@@ -400,13 +386,13 @@ mf_fgets(SPACE *sp, enum e_spflag spflag
 				    sizeof(oldfname));
 				len = strlcat(oldfname, inplace,
 				    sizeof(oldfname));
-				if (len > (ssize_t)sizeof(oldfname))
+				if ((size_t)len > sizeof(oldfname))
 					errx(1, "%s: name too long", fname);
 			}
 			len = snprintf(tmpfname, sizeof(tmpfname),
 			    "%s/.!%ld!%s", dirname(fname), (long)getpid(),
 			    basename(fname));
-			if (len >= (ssize_t)sizeof(tmpfname))
+			if ((size_t)len >= sizeof(tmpfname))
 				errx(1, "%s: name too long", fname);
 			unlink(tmpfname);
 			if (outfile != NULL && outfile != stdout)
@@ -460,7 +446,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, char *s)
+add_compunit(enum e_cut type, const char *s)
 {
 	struct s_compunit *cu;
 
@@ -477,7 +463,7 @@ add_compunit(enum e_cut type, char *s)
  * Add a file to the linked list
  */
 static void
-add_file(char *s)
+add_file(const char *s)
 {
 	struct s_flist *fp;
 

Modified: head/usr.bin/sed/misc.c
==============================================================================
--- head/usr.bin/sed/misc.c	Tue Jul 19 20:22:13 2016	(r303046)
+++ head/usr.bin/sed/misc.c	Tue Jul 19 22:56:40 2016	(r303047)
@@ -56,16 +56,14 @@ static const char sccsid[] = "@(#)misc.c
  * the buffer).
  */
 char *
-strregerror(int errcode, regex_t *preg)
+strregerror(int errcode, const regex_t *preg)
 {
 	static char *oe;
 	size_t s;
 
-	if (oe != NULL)
-		free(oe);
 	s = regerror(errcode, preg, NULL, 0);
-	if ((oe = malloc(s)) == NULL)
-		err(1, "malloc");
+	if ((oe = realloc(oe, s)) == NULL)
+		err(1, "realloc");
 	(void)regerror(errcode, preg, oe, s);
 	return (oe);
 }

Modified: head/usr.bin/sed/process.c
==============================================================================
--- head/usr.bin/sed/process.c	Tue Jul 19 20:22:13 2016	(r303046)
+++ head/usr.bin/sed/process.c	Tue Jul 19 22:56:40 2016	(r303047)
@@ -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(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 *);
+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 *);
 
 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 arra
 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 regex_t *defpreg;
+static const regex_t *defpreg;
 size_t maxnsub;
 regmatch_t *match;
 
@@ -376,13 +376,13 @@ resetstate(void)
  *	and then swap them.
  */
 static int
-substitute(struct s_command *cp)
+substitute(const struct s_command *cp)
 {
 	SPACE tspace;
-	regex_t *re;
+	const regex_t *re;
 	regoff_t slen;
 	int lastempty, n;
-	size_t le = 0;
+	regoff_t le = 0;
 	char *s;
 
 	s = ps;
@@ -488,7 +488,7 @@ substitute(struct s_command *cp)
  *	Perform translation ('y' command) in the pattern space.
  */
 static void
-do_tr(struct s_tr *y)
+do_tr(const struct s_tr *y)
 {
 	SPACE tmp;
 	char c, *p;
@@ -578,7 +578,7 @@ flush_appends(void)
 }
 
 static void
-lputs(char *s, size_t len)
+lputs(const char *s, size_t len)
 {
 	static const char escapes[] = "\\\a\b\f\r\t\v";
 	int c, col, width;
@@ -658,7 +658,7 @@ lputs(char *s, size_t len)
 }
 
 static int
-regexec_e(regex_t *preg, const char *string, int eflags, int nomatch,
+regexec_e(const regex_t *preg, const char *string, int eflags, int nomatch,
 	size_t start, size_t stop)
 {
 	int eval;
@@ -690,7 +690,7 @@ regexec_e(regex_t *preg, const char *str
  * Based on a routine by Henry Spencer
  */
 static void
-regsub(SPACE *sp, char *string, char *src)
+regsub(SPACE *sp, const char *string, const char *src)
 {
 	int len, no;
 	char c, *dst;
@@ -762,7 +762,7 @@ cspace(SPACE *sp, const char *p, size_t 
  * Close all cached opened files and report any errors
  */
 void
-cfclose(struct s_command *cp, struct s_command *end)
+cfclose(struct s_command *cp, const struct s_command *end)
 {
 
 	for (; cp != end; cp = cp->next)


More information about the svn-src-all mailing list