diff --git a/check/features.frm b/check/features.frm index 0df0e2920..55f8317e0 100644 --- a/check/features.frm +++ b/check/features.frm @@ -3190,6 +3190,27 @@ assert stdout =~ exact_pattern(<<'EOF') ~~~ EOF *--#] ZeroUnchanged : +*--#[ tablebase_dirty_blocks : +CTable,sparse f(1); +#do i = 1,1030 + Fill f(`i') = `i'; +#enddo +.sort +TableBase "dirty-blocks.tbl" create; +TableBase "dirty-blocks.tbl" addto f; +.end +CTable,sparse f(1); +TableBase "dirty-blocks.tbl" open; +TableBase "dirty-blocks.tbl" enter; +.sort +Local F = f(1)+f(1024)+f(1025)+f(1030); +Apply; +Print; +.end +#pend_if mpi? +assert succeeded? +assert result("F") =~ expr("3080") +*--#] tablebase_dirty_blocks : *--#[ tablebase_ro_1 : Table,sparse,no1fill(1); Fill no1fill(1) = 1; diff --git a/sources/declare.h b/sources/declare.h index 8056b656d..30f269a30 100644 --- a/sources/declare.h +++ b/sources/declare.h @@ -1379,6 +1379,7 @@ extern void convertnamesblock(NAMESBLOCK *,NAMESBLOCK *,int); extern void convertiniinfo(INIINFO *,INIINFO *,int); extern int ReadIndex(DBASE *); extern int WriteIndexBlock(DBASE *,MLONG); +extern int FlushDirtyIndexBlocks(DBASE *); extern int WriteNamesBlock(DBASE *,MLONG); extern int WriteIndex(DBASE *); extern int WriteIniInfo(DBASE *); diff --git a/sources/minos.c b/sources/minos.c index bd1402a3e..43ec49adb 100644 --- a/sources/minos.c +++ b/sources/minos.c @@ -415,9 +415,11 @@ int WriteIndexBlock(DBASE *d,MLONG num) /* INTERNAL_ERROR_EXCL_STOP */ } fseek(d->handle,d->iblocks[num]->position,SEEK_SET); + d->iblocks[num]->flags &= MCLEANFLAG; convertblock(d->iblocks[num],&scratchblock,TODISK); if ( minoswrite(d->handle,(char *)(&scratchblock),sizeof(INDEXBLOCK)) ) { /* INTERNAL_ERROR_EXCL_START */ + d->iblocks[num]->flags |= MDIRTYFLAG; MesPrint("!>Error while writing an index block in file %s\n",d->name); MesPrint("File may be unreliable now\n"); return(-1); @@ -428,6 +430,22 @@ int WriteIndexBlock(DBASE *d,MLONG num) /* #] WriteIndexBlock : + #[ FlushDirtyIndexBlocks : +*/ + +int FlushDirtyIndexBlocks(DBASE *d) +{ + MLONG i; + for ( i = 0; i < d->info.numberofindexblocks; i++ ) { + if ( ( d->iblocks[i]->flags & MDIRTYFLAG ) != 0 ) { + if ( WriteIndexBlock(d,i) ) return(-1); + } + } + return(0); +} + +/* + #] FlushDirtyIndexBlocks : #[ WriteNamesBlock : */ @@ -715,7 +733,7 @@ DBASE *NewDbase(char *name,MLONG number) else d->iblocks[i]->previousblock = -1; d->iblocks[i]->position = ftell(f); // Initialise, to keep valgrind happy - d->iblocks[i]->flags = -1; + d->iblocks[i]->flags = 0; /*----------change 10-feb-2003 */ /* Zero things properly. We don't want garbage in the file. @@ -1153,6 +1171,7 @@ int AddToIndex(DBASE *d,MLONG number) } if ( i > 0 ) ib[i]->previousblock = ib[i-1]->position; else ib[i]->previousblock = -1; + ib[i]->flags = 0; /* Zero things properly. We don't want garbage in the file. */ @@ -1337,7 +1356,8 @@ int WriteObject(DBASE *d,MLONG tablenumber,char *arguments,char *rhs,MLONG numbe #else obj->uncompressed = 0; #endif - return(WriteIndexBlock(d,j)); + d->iblocks[j]->flags |= MDIRTYFLAG; + return(0); } /* diff --git a/sources/tables.c b/sources/tables.c index 5dc1cf1e7..96a991ab0 100644 --- a/sources/tables.c +++ b/sources/tables.c @@ -813,7 +813,7 @@ int CoTBaddto(UBYTE *s) TABLES T = 0; MLONG basenumber; LONG x; - int i, j, error = 0, sum; + int i, j, error = 0, sum, writeini = 0; if ( ( d = FindTB(tablebasename) ) == 0 ) { MesPrint("&No open tablebase with the name %s",tablebasename); return(-1); @@ -854,7 +854,7 @@ int CoTBaddto(UBYTE *s) ParseSignedNumber(x,s); if ( FG.cTable[s[-1]] != 1 || ( *s != ',' && *s != ')' ) ) { MesPrint("&Table arguments in TableBase addto statement should be numbers"); - return(1); + goto tableabort; } *w++ = x; if ( *s == ')' ) break; @@ -956,17 +956,18 @@ int CoTBaddto(UBYTE *s) } while ( *s == ',' || *s == ' ' || *s == '\t' ) s++; } - if ( WriteIniInfo(d) ) goto tableabort; + writeini = 1; +tablefinish:; + if ( FlushDirtyIndexBlocks(d) ) error = 1; + if ( writeini && WriteIniInfo(d) ) error = 1; M_free(AO.DollarOutBuffer,"DollarOutBuffer"); AO.DollarOutBuffer = 0; AO.DollarOutSizeBuffer = 0; + AO.OutInBuffer = 0; return(error); tableabort:; - M_free(AO.DollarOutBuffer,"DollarOutBuffer"); - AO.DollarOutBuffer = 0; - AO.DollarOutSizeBuffer = 0; - AO.OutInBuffer = 0; - return(1); + error = 1; + goto tablefinish; } /*