From owner-svn-src-head@freebsd.org Tue Jul 19 22:56:42 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 6C9F0B9E267; Tue, 19 Jul 2016 22:56:42 +0000 (UTC) (envelope-from pfg@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3E6D512C1; Tue, 19 Jul 2016 22:56:42 +0000 (UTC) (envelope-from pfg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u6JMufRb007511; Tue, 19 Jul 2016 22:56:41 GMT (envelope-from pfg@FreeBSD.org) Received: (from pfg@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u6JMuewv007503; Tue, 19 Jul 2016 22:56:40 GMT (envelope-from pfg@FreeBSD.org) Message-Id: <201607192256.u6JMuewv007503@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: pfg set sender to pfg@FreeBSD.org using -f From: "Pedro F. Giffuni" Date: Tue, 19 Jul 2016 22:56:40 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r303047 - head/usr.bin/sed X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 Jul 2016 22:56:42 -0000 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)