From 91207ed3f400e34f7ff7377b3714c5e2468a00f8 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 2 Aug 2013 21:57:12 -0500 Subject: [PATCH] Update lemon.c to August 2012 version from SQLite. - Add a missing check for out-of-memory in the lemon code generator. - Fix a total unimportant file descriptor leak in lemon. This is to silence warning messages. - Fix a bug in lemon in computation of which non-terminals can generate an empty string. This bug and the fix make absolutely no difference for the grammar used by SQLite, but it can make a difference when lemon is used in other grammars. - In Lemon, when comparing the output to the *.h file to see if it has changed, make sure that the proposed new output and the preexisting output are the same size before deciding that they are the same. --- tools/lemon/lemon.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tools/lemon/lemon.c b/tools/lemon/lemon.c index 7fd95eb2dd..b544128cb9 100644 --- a/tools/lemon/lemon.c +++ b/tools/lemon/lemon.c @@ -632,7 +632,8 @@ struct lemon *lemp; if( rp->lhs->lambda ) continue; for(i=0; inrhs; i++){ struct symbol *sp = rp->rhs[i]; - if( sp->type!=TERMINAL || sp->lambda==LEMON_FALSE ) break; + assert( sp->type==NONTERMINAL || sp->lambda==LEMON_FALSE ); + if( sp->lambda==LEMON_FALSE ) break; } if( i==rp->nrhs ){ rp->lhs->lambda = LEMON_TRUE; @@ -2549,6 +2550,7 @@ struct lemon *gp; ErrorMsg(ps.filename,0,"Can't allocate %d of memory to hold this file.", filesize+1); gp->errorcnt++; + fclose(fp); return; } if( fread(filebuf,1,filesize,fp)!=filesize ){ @@ -2556,6 +2558,7 @@ struct lemon *gp; filesize); free(filebuf); gp->errorcnt++; + fclose(fp); return; } fclose(fp); @@ -3421,6 +3424,10 @@ int mhflag; /* True if generating makeheaders output */ /* Allocate and initialize types[] and allocate stddt[] */ arraysize = lemp->nsymbol * 2; types = (char**)calloc( arraysize, sizeof(char*) ); + if( types==0 ){ + fprintf(stderr,"Out of memory.\n"); + exit(1); + } maxdtlength = 0; if( lemp->vartype ){ maxdtlength = lemonStrlen(lemp->vartype); @@ -4028,12 +4035,14 @@ struct lemon *lemp; else prefix = ""; in = file_open(lemp,".h","rb"); if( in ){ + int nextChar; for(i=1; interminal && fgets(line,LINESIZE,in); i++){ sprintf(pattern,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); if( strcmp(line,pattern) ) break; } + nextChar = fgetc(in); fclose(in); - if( i==lemp->nterminal ){ + if( i==lemp->nterminal && nextChar==EOF ){ /* No change in the file. Don't rewrite it. */ /* (not the best idea if you use make tools that check the date! */ /*return;*/