PR/50914: David Binderman: Fix memory leaks.

While here, fix error handling too.
This commit is contained in:
christos 2016-03-08 20:13:44 +00:00
parent 2c7c3a0713
commit f6295e9141
2 changed files with 102 additions and 114 deletions

View File

@ -1,8 +1,11 @@
# $NetBSD: Makefile,v 1.8 2009/10/29 14:35:25 christos Exp $
# $NetBSD: Makefile,v 1.9 2016/03/08 20:13:44 christos Exp $
CPPFLAGS+= -I${.CURDIR}
PROG= fgen
SRCS= fgen.l
MAN= fgen.1
LDADD+= -lutil
DPADD+= ${LIBUTIL}
.include <bsd.prog.mk>

View File

@ -1,5 +1,5 @@
%{
/* $NetBSD: fgen.l,v 1.36 2013/10/18 20:47:06 christos Exp $ */
/* $NetBSD: fgen.l,v 1.37 2016/03/08 20:13:44 christos Exp $ */
/* FLEX input for FORTH input file scanner */
/*
* Copyright (c) 1998 Eduardo Horvath.
@ -42,7 +42,7 @@
#endif
#if defined(__RCSID) && !defined(lint)
__RCSID("$NetBSD: fgen.l,v 1.36 2013/10/18 20:47:06 christos Exp $");
__RCSID("$NetBSD: fgen.l,v 1.37 2016/03/08 20:13:44 christos Exp $");
#endif
%}
@ -66,6 +66,7 @@ tail {white}
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <util.h>
#include "fgen.h"
static TOKEN ltoken;
@ -101,7 +102,7 @@ static YY_DECL;
static int debug = 0;
#define ASSERT if (debug) assert
#define STATE(y, x) do { if (debug) printf( "%lx State %s: token `%s'\n", outpos, x, y); } while (0)
#define STATE(y, x) do { if (debug) printf("%lx State %s: token `%s'\n", outpos, x, y); } while (0)
static int mark_fload = 0;
%}
@ -310,7 +311,7 @@ static struct fcode *flookup(struct fcode *, const char *);
static int aadd(struct macro *, struct macro *);
static struct macro *alookup(struct macro *, const char *);
static void initdic(void);
__dead static void usage(const char *);
__dead static void usage(void);
static void tokenize(YY_BUFFER_STATE);
static int emit(const char *);
static int spit(long);
@ -787,10 +788,8 @@ push(Cell val)
if (debug > 1)
printf("push %lx\n", (long)val);
parse_stack[parse_stack_ptr++] = val;
if (parse_stack_ptr >= PSTKSIZ) {
(void)printf( "Parse stack overflow\n");
exit(1);
}
if (parse_stack_ptr >= PSTKSIZ)
errx(EXIT_FAILURE, "Parse stack overflow");
}
static Cell
@ -831,7 +830,7 @@ fadd(struct fcode *dict, struct fcode *new)
return fadd(dict->l, new);
else {
if (debug > 5)
(void)printf( "fadd: new FCode `%s' is %lx\n",
printf("fadd: new FCode `%s' is %lx\n",
new->name, new->num);
new->l = new->r = NULL;
dict->l = new;
@ -841,7 +840,7 @@ fadd(struct fcode *dict, struct fcode *new)
return fadd(dict->r, new);
else {
if (debug > 5)
(void)printf( "fadd: new FCode `%s' is %lx\n",
printf("fadd: new FCode `%s' is %lx\n",
new->name, new->num);
new->l = new->r = NULL;
dict->r = new;
@ -862,7 +861,7 @@ flookup(struct fcode *dict, const char *str)
res = strcmp(dict->name, str);
ASSERT(dict->type == FCODE);
if (debug > 5)
(void)printf( "flookup: `%s' and `%s' %s match\n",
printf("flookup: `%s' and `%s' %s match\n",
str, dict->name, res?"don't":"do");
if (!res) return (dict);
if (res < 0)
@ -895,7 +894,7 @@ aadd(struct macro *dict, struct macro *new)
new->l = new->r = NULL;
dict->l = new;
if (debug > 5)
(void)printf( "aadd: new alias `%s' to `%s'\n",
printf("aadd: new alias `%s' to `%s'\n",
new->name, new->equiv);
}
} else {
@ -905,7 +904,7 @@ aadd(struct macro *dict, struct macro *new)
new->l = new->r = NULL;
dict->r = new;
if (debug > 5)
(void)printf( "aadd: new alias `%s' to `%s'\n",
printf("aadd: new alias `%s' to `%s'\n",
new->name, new->equiv);
}
}
@ -948,8 +947,8 @@ initdic(void)
while ((++code)->name) {
if(!fadd(dictionary, code)) {
printf("init: duplicate dictionary entry %s\n",
code->name);
warnx("%s: duplicate dictionary entry `%s'", __func__,
code->name);
}
}
@ -959,8 +958,8 @@ initdic(void)
alias->type = MACRO;
while ((++alias)->name) {
if(!aadd(aliases, alias)) {
printf("init: duplicate macro entry %s\n",
alias->name);
warnx("%s: duplicate macro entry `%s'", __func__,
alias->name);
}
}
@ -987,10 +986,11 @@ apply_macros(YY_BUFFER_STATE yinput, const char *str)
}
static void
usage(const char *me)
usage(void)
{
(void)fprintf(stderr, "%s: [-d level] [-o outfile] <infile>\n", me);
exit(1);
(void)fprintf(stderr, "%s: [-d level] [-o outfile] <infile>\n",
getprogname());
exit(EXIT_FAILURE);
}
int
@ -1004,7 +1004,6 @@ main(int argc, char *argv[])
int i;
outf = 1; /* stdout */
myname = argv[0];
while ((ch = getopt(argc, argv, "d:o:")) != -1)
switch(ch) {
@ -1016,13 +1015,13 @@ main(int argc, char *argv[])
outfile = optarg;
break;
default:
usage(myname);
usage();
}
argc -= optind;
argv += optind;
if (argc != 1)
usage(myname);
usage();
infile = argv[0];
@ -1031,8 +1030,8 @@ main(int argc, char *argv[])
*/
initdic();
outbufsiz = BUFCLICK;
outbuf = malloc(outbufsiz);
fheader = (struct fcode_header *)outbuf;
fheader = emalloc(outbufsiz);
outbuf = (void *)fheader;
outpos = 0;
emit(hdrtype);
outpos = sizeof(*fheader);
@ -1041,9 +1040,9 @@ main(int argc, char *argv[])
* Do it.
*/
if ((inf = fopen(infile, "r")) == NULL)
(void)err(1, "can not open %s for reading", infile);
err(EXIT_FAILURE, "Cannot open `%s'", infile);
inbuf = yy_create_buffer( inf, YY_BUF_SIZE );
inbuf = yy_create_buffer(inf, YY_BUF_SIZE);
yy_switch_to_buffer(inbuf);
tokenize(inbuf);
yy_delete_buffer(inbuf);
@ -1059,15 +1058,16 @@ main(int argc, char *argv[])
fheader->checksum = htons(fheader->checksum);
if ((outf = open(outfile, O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1)
err(1, "can out open %s for writing", outfile);
err(EXIT_FAILURE, "Cannot open `%s'", outfile);
if (write(outf, outbuf, outpos) != outpos) {
int serrno = errno;
close(outf);
unlink(outfile);
err(1, "write error");
errc(EXIT_FAILURE, serrno, "write error");
}
close(outf);
return (0);
return EXIT_SUCCESS;
};
/*
@ -1134,14 +1134,14 @@ tokenize(YY_BUFFER_STATE yinput)
case TOK_STRING_LIT:
STATE(token->text, "TOK_STRING_LIT:");
{
int len;
size_t len;
char *p = token->text;
++p; /* Skip the quote */
len = strlen(++p); /* Skip the 1st space */
#define ERR_TOOLONG \
token_err(yylineno, infile, yytext, "string length %d too long", len)
token_err(yylineno, infile, yytext, "string length %zu too long", len)
if (len > 255)
ERR_TOOLONG;
@ -1157,7 +1157,7 @@ tokenize(YY_BUFFER_STATE yinput)
case TOK_PSTRING:
STATE(token->text, "TOK_PSTRING:");
{
int len;
size_t len;
char *p = token->text;
if (*p++ == '.') p++; /* Skip over delimiter */
@ -1179,7 +1179,7 @@ tokenize(YY_BUFFER_STATE yinput)
case TOK_ABORT_S:
STATE(token->text, "TOK_PSTRING:");
{
int len;
size_t len;
Cell value = -2;
char *p = token->text;
@ -1235,19 +1235,19 @@ tokenize(YY_BUFFER_STATE yinput)
"EOF in colon definition");
/* Add new code to dictionary */
fcode = malloc(sizeof(*fcode));
fcode = emalloc(sizeof(*fcode));
fcode->num = nextfcode++;
fcode->name = strdup(token->text);
fcode->name = estrdup(token->text);
if (!fadd(dictionary, fcode)) {
/* Duplicate definition. Free the memory. */
if (debug)
(void)printf("%s: duplicate FCode\n",
printf("%s: duplicate FCode\n",
token->text);
free(__UNCONST(fcode->name));
free(fcode);
}
if (debug)
(void)printf("Adding %s to dictionary\n", token->text);
printf("Adding %s to dictionary\n", token->text);
if (state == 0)
emit("new-token");
else {
@ -1290,21 +1290,23 @@ tokenize(YY_BUFFER_STATE yinput)
token = yylex();
if (token == NULL) {
(void)printf( "EOF in alias definition\n");
warnx("EOF in alias definition");
return;
}
if (token->type != TOK_OTHER) {
(void)printf( "ENDCOMMENT aliasing weird token type %d\n",
token->type);
warnx("ENDCOMMENT aliasing weird token type %d",
token->type);
}
alias = malloc(sizeof(*alias));
alias->name = strdup(token->text);
alias = emalloc(sizeof(*alias));
alias->name = estrdup(token->text);
token = yylex();
if (token == NULL) {
(void)printf( "EOF in alias definition\n");
warnx("EOF in alias definition");
free(__UNCONST(alias->name));
free(alias);
return;
}
alias->equiv = strdup(token->text);
alias->equiv = estrdup(token->text);
if (!aadd(aliases, alias)) {
free(__UNCONST(alias->name));
free(alias);
@ -1317,22 +1319,19 @@ tokenize(YY_BUFFER_STATE yinput)
emit("b(')");
token = yylex();
if (token == NULL) {
(void)printf( "EOF in [']\n");
warnx("EOF in [']");
return;
}
if ((fcode = flookup(dictionary, token->text)) == NULL) {
(void)printf( "[']: %s not found\n", token->text);
exit(1);
}
if ((fcode = flookup(dictionary, token->text)) == NULL)
errx(EXIT_FAILURE, "[']: %s not found",
token->text);
spit(fcode->num);
break;
case TOK_ASCII:
STATE(token->text, "TOK_ASCII");
token = yylex();
if (token == NULL) {
(void)printf( "EOF after \"ascii\"\n");
exit(1);
}
if (token == NULL)
errx(EXIT_FAILURE, "EOF after \"ascii\"");
emit("b(lit)");
spit(0);
spit(0);
@ -1349,14 +1348,14 @@ tokenize(YY_BUFFER_STATE yinput)
token = yylex();
if (token == NULL) {
(void)printf( "EOF in colon definition\n");
warnx("EOF in colon definition");
return;
}
/* Add new code to dictionary */
fcode = malloc(sizeof(*fcode));
fcode = emalloc(sizeof(*fcode));
fcode->num = nextfcode++;
fcode->name = strdup(token->text);
fcode->name = estrdup(token->text);
fadd(dictionary, fcode);
if (state == 0)
@ -1382,14 +1381,14 @@ tokenize(YY_BUFFER_STATE yinput)
token = yylex();
if (token == NULL) {
(void)printf( "EOF in constant definition\n");
warnx("EOF in constant definition");
return;
}
/* Add new code to dictionary */
fcode = malloc(sizeof(*fcode));
fcode = emalloc(sizeof(*fcode));
fcode->num = nextfcode++;
fcode->name = strdup(token->text);
fcode->name = estrdup(token->text);
fadd(dictionary, fcode);
if (state == 0)
@ -1408,10 +1407,8 @@ tokenize(YY_BUFFER_STATE yinput)
case TOK_CONTROL:
STATE(token->text, "TOK_CONTROL");
token = yylex();
if (token == NULL) {
(void)printf( "EOF after \"ascii\"\n");
exit(1);
}
if (token == NULL)
errx(EXIT_FAILURE, "EOF after \"ascii\"");
emit("b(lit)");
spit(0);
spit(0);
@ -1423,14 +1420,14 @@ tokenize(YY_BUFFER_STATE yinput)
/* Don't know what this does or if it's right */
token = yylex();
if (token == NULL) {
(void)printf( "EOF in create definition\n");
warnx("EOF in create definition");
return;
}
/* Add new code to dictionary */
fcode = malloc(sizeof(*fcode));
fcode = emalloc(sizeof(*fcode));
fcode->num = nextfcode++;
fcode->name = strdup(token->text);
fcode->name = estrdup(token->text);
fadd(dictionary, fcode);
if (state == 0)
@ -1465,7 +1462,7 @@ tokenize(YY_BUFFER_STATE yinput)
token = yylex();
if (token == NULL) {
(void)printf( "EOF after d#\n");
warnx("EOF after d#");
return;
}
if (token->type == TOK_OTHER) {
@ -1504,14 +1501,14 @@ tokenize(YY_BUFFER_STATE yinput)
/* Don't know what this does or if it's right */
token = yylex();
if (token == NULL) {
(void)printf( "EOF in colon definition\n");
warnx("EOF in colon definition");
return;
}
/* Add new code to dictionary */
fcode = malloc(sizeof(*fcode));
fcode = emalloc(sizeof(*fcode));
fcode->num = nextfcode++;
fcode->name = strdup(token->text);
fcode->name = estrdup(token->text);
fadd(dictionary, fcode);
if (state == 0)
@ -1598,9 +1595,9 @@ tokenize(YY_BUFFER_STATE yinput)
(unsigned char)outbuf[outpos+1];
}
next = outpos + disp;
if (debug > 3)
printf("Next endof: %x at %x\n",
disp, next);
if (debug > -3)
printf("Next endof: %x at %x\n",
disp, next);
/* process this offset */
off = pos - outpos;
@ -1661,14 +1658,14 @@ tokenize(YY_BUFFER_STATE yinput)
token = yylex();
if (token == NULL) {
(void)printf( "EOF in field definition\n");
warnx("EOF in field definition");
return;
}
/* Add new code to dictionary */
fcode = malloc(sizeof(*fcode));
fcode = emalloc(sizeof(*fcode));
fcode->num = nextfcode++;
fcode->name = strdup(token->text);
fcode->name = estrdup(token->text);
fadd(dictionary, fcode);
if (state == 0)
@ -1704,15 +1701,14 @@ tokenize(YY_BUFFER_STATE yinput)
token = yylex();
if (token == NULL) {
(void)printf( "EOF after h#\n");
warnx("EOF after h#");
return;
}
value = strtol(token->text, &end, 16);
if (*end != 0) {
(void)printf("Illegal number conversion:%s:%d: %s\n",
if (*end != 0)
errx(EXIT_FAILURE, "Illegal number"
" conversion:%s:%d: %s\n",
infile, yylineno, yytext);
exit(1);
}
/*
* If this is a 64-bit value we need to store two literals
* and issue a `lxjoin' to combine them. But that's a future
@ -1788,14 +1784,14 @@ tokenize(YY_BUFFER_STATE yinput)
token = yylex();
if (token == NULL) {
(void)printf( "EOF after o#\n");
warnx("EOF after o#");
return;
}
value = strtol(token->text, &end, 8);
if (*end != 0) {
(void)printf("Illegal number conversion:%s:%d: %s\n",
errx(EXIT_FAILURE, "Illegal number"
" conversion:%s:%d: %s\n",
infile, yylineno, yytext);
exit(1);
}
/*
* If this is a 64-bit value we need to store two literals
@ -1893,14 +1889,14 @@ tokenize(YY_BUFFER_STATE yinput)
token = yylex();
if (token == NULL) {
(void)printf( "EOF in value definition\n");
warnx("EOF in value definition");
return;
}
/* Add new code to dictionary */
fcode = malloc(sizeof(*fcode));
fcode = emalloc(sizeof(*fcode));
fcode->num = nextfcode++;
fcode->name = strdup(token->text);
fcode->name = estrdup(token->text);
fadd(dictionary, fcode);
if (state == 0)
@ -1921,14 +1917,14 @@ tokenize(YY_BUFFER_STATE yinput)
token = yylex();
if (token == NULL) {
(void)printf( "EOF in variable definition\n");
warnx("EOF in variable definition");
return;
}
/* Add new code to dictionary */
fcode = malloc(sizeof(*fcode));
fcode = emalloc(sizeof(*fcode));
fcode->num = nextfcode++;
fcode->name = strdup(token->text);
fcode->name = estrdup(token->text);
fadd(dictionary, fcode);
if (state == 0)
@ -1981,13 +1977,10 @@ tokenize(YY_BUFFER_STATE yinput)
/* Parse a different file for a while */
token = yylex();
if ((inf = fopen(token->text, "r")) == NULL) {
(void)printf("%s: Could not "
"open %s: %s\n",
myname, token->text,
strerror(errno));
warn("Cannot open `%s'", token->text);
break;
}
infile = strdup(token->text);
infile = estrdup(token->text);
if (mark_fload) {
/*
* Insert commands to print out the
@ -2048,14 +2041,9 @@ tokenize(YY_BUFFER_STATE yinput)
emit("drop");
emit("execute");
#else
printf("%s:%d: undefined token %s\n",
infile, yylineno, yytext);
exit(1);
token_err(yylineno, infile, yytext,
"%s: undefined token `%s'\n",
myname, token->text);
fflush(stderr);
exit(1);
#endif
}
break;
@ -2075,15 +2063,16 @@ token_err(int lineno, const char *file, const char *text, const char *fmt, ...)
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "%s: ", getprogname());
if (file)
(void)fprintf(stderr, "%s:%d: ", file, lineno);
(void)fprintf(stderr, "%s,%d: ", file, lineno);
if (fmt)
(void)vfprintf(stderr, fmt, ap);
fputc('\n', stderr);
if (text)
fprintf(stderr, "\t%s", text);
va_end(ap);
exit(1);
exit(EXIT_FAILURE);
}
/*
@ -2095,13 +2084,13 @@ static int
emit(const char *str)
{
struct fcode *code;
if ((code = flookup( dictionary, str)))
if ((code = flookup(dictionary, str)))
spit(code->num);
if (debug > 1) {
if (code)
(void)printf( "emitting `%s'\n", code->name);
printf("emitting `%s'\n", code->name);
else
(void)printf( "emit: not found `%s'\n", str);
printf("emit: not found `%s'\n", str);
}
return (code == NULL);
}
@ -2121,11 +2110,7 @@ spit(long n)
count += spit(n >> 8);
if ((size_t)outpos >= outbufsiz) {
while ((size_t)outpos >= outbufsiz) outbufsiz += BUFCLICK;
if (!(outbuf = realloc(outbuf, outbufsiz))) {
(void)printf( "realloc of %ld bytes failed -- out of memory\n",
(long)outbufsiz);
exit(1);
}
outbuf = erealloc(outbuf, outbufsiz);
}
if (debug > 3) printf("%lx: spitting %2.2x\n", outpos, (unsigned char)n);
outbuf[outpos++] = n;
@ -2141,11 +2126,11 @@ sspit(const char *s)
int len = strlen(s);
if (len > 255) {
(void)printf( "string length %d too long\n", len);
warnx("string length %d too long", len);
return;
}
if (debug > 2)
(void)printf( "sspit: len %d str `%s'\n", len, s);
printf("sspit: len %d str `%s'\n", len, s);
spit(len);
while (len--)
spit(*s++);