Fix string array initialization

It's been broken since commit e1082f64bc4171884316621f6f62a49c45d97e81

Fixes #53 (one more time)
This commit is contained in:
Zeex 2015-04-06 15:24:25 +06:00
parent 7314b56579
commit 2e162eae9c

View File

@ -95,7 +95,7 @@ static void initials(int ident,int tag,cell *size,int dim[],int numdim,
static cell initarray(int ident,int tag,int dim[],int numdim,int cur, static cell initarray(int ident,int tag,int dim[],int numdim,int cur,
int startlit,int counteddim[],constvalue *lastdim, int startlit,int counteddim[],constvalue *lastdim,
constvalue *enumroot,int *errorfound); constvalue *enumroot,int *errorfound);
static cell initvector(int ident,int tag,cell size,int fillzero, static cell initvector(int ident,int tag,cell size,int startlit,int fillzero,
constvalue *enumroot,int *errorfound); constvalue *enumroot,int *errorfound);
static cell init(int ident,int *tag,int *errorfound); static cell init(int ident,int *tag,int *errorfound);
static int getstates(const char *funcname); static int getstates(const char *funcname);
@ -2423,7 +2423,7 @@ static void initials(int ident,int tag,cell *size,int dim[],int numdim,
} else { } else {
assert(numdim>0); assert(numdim>0);
if (numdim==1) { if (numdim==1) {
*size=initvector(ident,tag,dim[0],FALSE,enumroot,NULL); *size=initvector(ident,tag,dim[0],litidx,FALSE,enumroot,NULL);
} else { } else {
int errorfound=FALSE; int errorfound=FALSE;
int counteddim[sDIMEN_MAX]; int counteddim[sDIMEN_MAX];
@ -2522,22 +2522,25 @@ static cell initarray(int ident,int tag,int dim[],int numdim,int cur,
} else { } else {
curlit=litidx; curlit=litidx;
if (matchtoken(tELLIPS)!=0) { if (matchtoken(tELLIPS)!=0) {
/* found an ellipsis; fill up the rest of the array with a series
* of one-dimensional arrays ("2d ellipsis")
*/
if (prev1!=NULL) { if (prev1!=NULL) {
for (idx_ellips=1; idx < dim[cur]; idx++, idx_ellips++) { for (idx_ellips=1; idx < dim[cur]; idx++, idx_ellips++) {
for (vidx=0; vidx < dsize; vidx++) for (vidx=0; vidx < dsize; vidx++) {
if (prev2!=NULL) if (prev2!=NULL)
litadd(prev1[vidx]+idx_ellips*(prev1[vidx]-prev2[vidx])); litadd(prev1[vidx]+idx_ellips*(prev1[vidx]-prev2[vidx]));
else else
litadd(prev1[vidx]); litadd(prev1[vidx]);
} /* for */
append_constval(lastdim,itoh(idx),dsize,0); append_constval(lastdim,itoh(idx),dsize,0);
} /* for */ } /* for */
} else } else
error(41); /* invalid ellipsis, array size unknown */ error(41); /* invalid ellipsis, array size unknown */
} else { } else {
litidx=curlit; /* reset literal queue (could match a string token instead) */
prev2=prev1; prev2=prev1;
prev1=&litq[litidx]; prev1=&litq[litidx];
dsize=initvector(ident,tag,dim[cur+1],TRUE,enumroot,errorfound); dsize=initvector(ident,tag,dim[cur+1],curlit,TRUE,enumroot,errorfound);
/* The final dimension may be variable length. We need to save the /* The final dimension may be variable length. We need to save the
* lengths of the final dimensions in order to set the indirection * lengths of the final dimensions in order to set the indirection
* vectors for the next-to-last dimension. * vectors for the next-to-last dimension.
@ -2565,12 +2568,11 @@ static cell initarray(int ident,int tag,int dim[],int numdim,int cur,
/* initvector /* initvector
* Initialize a single dimensional array * Initialize a single dimensional array
*/ */
static cell initvector(int ident,int tag,cell size,int fillzero, static cell initvector(int ident,int tag,cell size,int startlit,int fillzero,
constvalue *enumroot,int *errorfound) constvalue *enumroot,int *errorfound)
{ {
cell prev1=0,prev2=0; cell prev1=0,prev2=0;
int ellips=FALSE; int ellips=FALSE;
int curlit=litidx;
int rtag,ctag; int rtag,ctag;
assert(ident==iARRAY || ident==iREFARRAY); assert(ident==iARRAY || ident==iREFARRAY);
@ -2642,25 +2644,25 @@ static cell initvector(int ident,int tag,cell size,int fillzero,
} /* if */ } /* if */
/* fill up the literal queue with a series */ /* fill up the literal queue with a series */
if (ellips) { if (ellips) {
cell step=((litidx-curlit)==1) ? (cell)0 : prev1-prev2; cell step=((litidx-startlit)==1) ? (cell)0 : prev1-prev2;
if (size==0 || (litidx-curlit)==0) if (size==0 || (litidx-startlit)==0)
error(41); /* invalid ellipsis, array size unknown */ error(41); /* invalid ellipsis, array size unknown */
else if ((litidx-curlit)==(int)size) else if ((litidx-startlit)==(int)size)
error(18); /* initialisation data exceeds declared size */ error(18); /* initialisation data exceeds declared size */
while ((litidx-curlit)<(int)size) { while ((litidx-startlit)<(int)size) {
prev1+=step; prev1+=step;
litadd(prev1); litadd(prev1);
} /* while */ } /* while */
} /* if */ } /* if */
if (fillzero && size>0) { if (fillzero && size>0) {
while ((litidx-curlit)<(int)size) while ((litidx-startlit)<(int)size)
litadd(0); litadd(0);
} /* if */ } /* if */
if (size==0) { if (size==0) {
size=litidx-curlit; /* number of elements defined */ size=litidx-startlit; /* number of elements defined */
} else if (litidx-curlit>(int)size) { /* e.g. "myvar[3]={1,2,3,4};" */ } else if (litidx-startlit>(int)size) { /* e.g. "myvar[3]={1,2,3,4};" */
error(18); /* initialisation data exceeds declared size */ error(18); /* initialisation data exceeds declared size */
litidx=(int)size+curlit; /* avoid overflow in memory moves */ litidx=(int)size+startlit; /* avoid overflow in memory moves */
} /* if */ } /* if */
return size; return size;
} }