Various fixes to lemon.c
(1) By anonymous on 2021-02-12 14:57:14 [source]
Here are some fixes to lemon.c:
- consistently check for allocation errors
- remove unnecessary
memset
aftercalloc
- remove superfluous
return
s fromvoid
functions State_new
checks forNULL
so removeMemoryCheck
Index: tool/lemon.c
==================================================================
--- tool/lemon.c
+++ tool/lemon.c
@@ -623,11 +623,10 @@
acttab *p = (acttab *) calloc( 1, sizeof(*p) );
if( p==0 ){
fprintf(stderr,"Unable to allocate memory for a new acttab.");
exit(1);
}
- memset(p, 0, sizeof(*p));
p->nsymbol = nsymbol;
p->nterminal = nterminal;
return p;
}
@@ -826,11 +825,10 @@
rp->precsym = rp->rhs[i];
}
}
}
}
- return;
}
/* Find all nonterminals which will generate the empty string.
** Then go back and compute the first sets of every nonterminal.
** The first set is the set of all terminal symbols which can begin
@@ -889,11 +887,10 @@
if( s2->lambda==LEMON_FALSE ) break;
}
}
}
}while( progress );
- return;
}
/* Compute all LR(0) states for the grammar. Links
** are added to between some states so that the LR(1) follow sets
** can be computed later.
@@ -949,11 +946,10 @@
/* Compute the first state. All other states will be
** computed automatically during the computation of the first one.
** The returned pointer to the first state is not used. */
(void)getstate(lemp);
- return;
}
/* Return a pointer to a state which is described by the configuration
** list which has been built from calls to Configlist_add.
*/
@@ -986,11 +982,10 @@
/* This really is a new state. Construct all the details */
Configlist_closure(lemp); /* Compute the configuration closure */
Configlist_sort(); /* Sort the configuration closure */
cfp = Configlist_return(); /* Get a pointer to the config list */
stp = State_new(); /* A new state structure */
- MemoryCheck(stp);
stp->bp = bp; /* Remember the configuration basis */
stp->cfp = cfp; /* Remember the configuration closure */
stp->statenum = lemp->nstate++; /* Every state gets a sequence number */
stp->ap = 0; /* No actions, yet. */
State_insert(stp,stp->bp); /* Add to the state table */
@@ -1328,21 +1323,19 @@
current = 0;
currentend = ¤t;
basis = 0;
basisend = &basis;
Configtable_init();
- return;
}
/* Initialized the configuration list builder */
void Configlist_reset(void){
current = 0;
currentend = ¤t;
basis = 0;
basisend = &basis;
Configtable_clear(0);
- return;
}
/* Add another configuration to the configuration list */
struct config *Configlist_add(
struct rule *rp, /* The rule */
@@ -1438,27 +1431,24 @@
}
if( i==rp->nrhs ) Plink_add(&cfp->fplp,newcfp);
}
}
}
- return;
}
/* Sort the configuration list */
void Configlist_sort(void){
current = (struct config*)msort((char*)current,(char**)&(current->next),
Configcmp);
currentend = 0;
- return;
}
/* Sort the basis configuration list */
void Configlist_sortbasis(void){
basis = (struct config*)msort((char*)current,(char**)&(current->bp),
Configcmp);
basisend = 0;
- return;
}
/* Return a pointer to the head of the configuration list and
** reset the list */
struct config *Configlist_return(void){
@@ -1488,11 +1478,10 @@
assert( cfp->fplp==0 );
assert( cfp->bplp==0 );
if( cfp->fws ) SetFree(cfp->fws);
deleteconfig(cfp);
}
- return;
}
/***************** From the file "error.c" *********************************/
/*
** Code for printing error message.
*/
@@ -2429,21 +2418,32 @@
}else if( (x[0]=='|' || x[0]=='/') && psp->nrhs>0 && ISUPPER(x[1]) ){
struct symbol *msp = psp->rhs[psp->nrhs-1];
if( msp->type!=MULTITERMINAL ){
struct symbol *origsp = msp;
msp = (struct symbol *) calloc(1,sizeof(*msp));
- memset(msp, 0, sizeof(*msp));
+ if( msp==0 ){
+ fprintf(stderr,"malloc failed\n");
+ exit(1);
+ }
msp->type = MULTITERMINAL;
msp->nsubsym = 1;
msp->subsym = (struct symbol **) calloc(1,sizeof(struct symbol*));
+ if( msp->subsym==0 ){
+ fprintf(stderr,"malloc failed\n");
+ exit(1);
+ }
msp->subsym[0] = origsp;
msp->name = origsp->name;
psp->rhs[psp->nrhs-1] = msp;
}
msp->nsubsym++;
msp->subsym = (struct symbol **) realloc(msp->subsym,
sizeof(struct symbol*)*msp->nsubsym);
+ if( msp->subsym==0 ){
+ fprintf(stderr,"malloc failed\n");
+ exit(1);
+ }
msp->subsym[msp->nsubsym-1] = Symbol_new(&x[1]);
if( ISLOWER(x[1]) || ISLOWER(msp->subsym[0]->name[0]) ){
ErrorMsg(psp->filename,psp->tokenlineno,
"Cannot form a compound containing a non-terminal");
psp->errorcnt++;
@@ -2764,10 +2764,14 @@
}else if( ISUPPER(x[0]) || ((x[0]=='|' || x[0]=='/') && ISUPPER(x[1])) ){
struct symbol *msp = psp->tkclass;
msp->nsubsym++;
msp->subsym = (struct symbol **) realloc(msp->subsym,
sizeof(struct symbol*)*msp->nsubsym);
+ if( msp->subsym==0 ){
+ fprintf(stderr,"malloc failed\n");
+ exit(1);
+ }
if( !ISUPPER(x[0]) ) x++;
msp->subsym[msp->nsubsym-1] = Symbol_new(x);
}else{
ErrorMsg(psp->filename, psp->tokenlineno,
"%%token_class argument \"%s\" should be a token", x);
@@ -2957,11 +2961,11 @@
int lineno;
int c;
char *cp, *nextcp;
int startline = 0;
- memset(&ps, '\0', sizeof(ps));
+ memset(&ps, 0, sizeof(ps));
ps.gp = gp;
ps.filename = gp->filename;
ps.errorcnt = 0;
ps.state = INITIALIZE;
@@ -2974,10 +2978,14 @@
}
fseek(fp,0,2);
filesize = ftell(fp);
rewind(fp);
filebuf = (char *)malloc( filesize+1 );
+ if( filebuf==0 ){
+ fprintf(stderr,"malloc failed\n");
+ exit(1);
+ }
if( filesize>100000000 || filebuf==0 ){
ErrorMsg(ps.filename,0,"Input file too large.");
free(filebuf);
gp->errorcnt++;
fclose(fp);
@@ -3507,11 +3515,10 @@
rp->precsym->name, rp->precsym->prec);
}
fprintf(fp,"\n");
}
fclose(fp);
- return;
}
/* Search for the file "name" which is in the same directory as
** the executable */
PRIVATE char *pathsearch(char *argv0, char *name, int modemask)
@@ -3712,11 +3719,10 @@
(*lineno)++;
}
if (!lemp->nolinenosflag) {
(*lineno)++; tplt_linedir(out,*lineno,lemp->outname);
}
- return;
}
/*
** The following routine emits code for the destructor for the
** symbol sp
@@ -3759,11 +3765,10 @@
fprintf(out,"\n"); (*lineno)++;
if (!lemp->nolinenosflag) {
(*lineno)++; tplt_linedir(out,*lineno,lemp->outname);
}
fprintf(out,"}\n"); (*lineno)++;
- return;
}
/*
** Return TRUE (non-zero) if the given symbol has a destructor.
*/
@@ -4071,12 +4076,10 @@
}
if( rp->codePrefix ){
fprintf(out, "}\n"); (*lineno)++;
}
-
- return;
}
/*
** Print the definition of the union used for the parser's data stack.
** This union contains fields for every possible data type for tokens
@@ -4934,11 +4937,10 @@
acttab_free(pActtab);
fclose(in);
fclose(out);
if( sql ) fclose(sql);
- return;
}
/* Generate a header file for the parser */
void ReportHeader(struct lemon *lemp)
{
@@ -4970,11 +4972,10 @@
for(i=1; i<lemp->nterminal; i++){
fprintf(out,"#define %s%-30s %3d\n",prefix,lemp->symbols[i]->name,i);
}
fclose(out);
}
- return;
}
/* Reduce the size of the action tables, if possible, by making use
** of defaults.
**
@@ -5879,7 +5880,6 @@
int i;
if( x4a==0 || x4a->count==0 ) return;
if( f ) for(i=0; i<x4a->count; i++) (*f)(x4a->tbl[i].data);
for(i=0; i<x4a->size; i++) x4a->ht[i] = 0;
x4a->count = 0;
- return;
}