fpspreadsheet: Fix arithmetic overflow in ooxml writer in case of empty worksheet but existing row records. Use try-finally blocks around test cases to make sure that memory is released and temp file is deleted in case of exceptions due to failed tests. Fix memory leak in rpn formula calculation (spreadtestgui, however, still reports a lot of memory leaks).

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3431 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2014-08-05 21:42:34 +00:00
parent d63dd1b715
commit 7e599ebd07
12 changed files with 525 additions and 435 deletions

View File

@ -17,6 +17,19 @@ type
TsArgNumberArray = array of double; TsArgNumberArray = array of double;
TsArgStringArray = array of string; TsArgStringArray = array of string;
TsArgument = record
IsMissing: Boolean;
Worksheet: TsWorksheet;
ArgumentType: TsArgumentType;
Cell: PCell;
FirstRow, FirstCol, LastRow, LastCol: Cardinal;
NumberValue: Double;
StringValue: String;
BoolValue: Boolean;
ErrorValue: TsErrorValue;
end;
{
TsArgument = record TsArgument = record
IsMissing: Boolean; IsMissing: Boolean;
Worksheet: TsWorksheet; Worksheet: TsWorksheet;
@ -28,6 +41,7 @@ type
atBool : (BoolValue: Boolean); atBool : (BoolValue: Boolean);
atError : (ErrorValue: TsErrorValue); atError : (ErrorValue: TsErrorValue);
end; end;
}
PsArgument = ^TsArgument; PsArgument = ^TsArgument;
TsArgumentStack = class(TFPList) TsArgumentStack = class(TFPList)
@ -191,6 +205,7 @@ uses
function CreateArgument: TsArgument; function CreateArgument: TsArgument;
begin begin
Result.StringValue := '';
FillChar(Result, SizeOf(Result), 0); FillChar(Result, SizeOf(Result), 0);
end; end;
@ -419,7 +434,7 @@ var
begin begin
P := PsArgument(Items[AIndex]); P := PsArgument(Items[AIndex]);
P^.StringValue := ''; P^.StringValue := '';
FreeMem(P, SizeOf(P)); FreeMem(P, SizeOf(P^));
inherited Delete(AIndex); inherited Delete(AIndex);
end; end;

View File

@ -4540,7 +4540,6 @@ end;
} }
procedure TsWorksheet.InsertRow(ARow: Cardinal); procedure TsWorksheet.InsertRow(ARow: Cardinal);
var var
cell: PCell;
row: PRow; row: PRow;
cellnode: TAVLTreeNode; cellnode: TAVLTreeNode;
i: Integer; i: Integer;
@ -4817,7 +4816,6 @@ procedure TsWorkbook.GetLastRowColIndex(out ALastRow, ALastCol: Cardinal);
var var
i: Integer; i: Integer;
sheet: TsWorksheet; sheet: TsWorksheet;
r1,r2, c1,c2: Cardinal;
begin begin
if (boVirtualMode in Options) then begin if (boVirtualMode in Options) then begin
ALastRow := FVirtualRowCount - 1; ALastRow := FVirtualRowCount - 1;
@ -6555,9 +6553,11 @@ end;
} }
procedure DisposeRPNItem(AItem: PRPNItem); procedure DisposeRPNItem(AItem: PRPNItem);
begin begin
if AItem <> nil then if AItem <> nil then begin
AItem.FE.StringValue := '';;
FreeMem(AItem, SizeOf(TRPNItem)); FreeMem(AItem, SizeOf(TRPNItem));
end; end;
end;
{@@ {@@
Creates a boolean value entry in the RPN array. Creates a boolean value entry in the RPN array.

View File

@ -120,6 +120,7 @@ begin
TempFile:=GetTempFileName; TempFile:=GetTempFileName;
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkSheet:= MyWorkBook.AddWorksheet(ColorsSheet); MyWorkSheet:= MyWorkBook.AddWorksheet(ColorsSheet);
// Define palette // Define palette
@ -156,10 +157,13 @@ begin
inc(row); inc(row);
end; end;
MyWorkBook.WriteToFile(TempFile, AFormat, true); MyWorkBook.WriteToFile(TempFile, AFormat, true);
finally
MyWorkbook.Free; MyWorkbook.Free;
end;
// Open the spreadsheet // Open the spreadsheet
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkbook.ReadFromFile(TempFile, AFormat); MyWorkbook.ReadFromFile(TempFile, AFormat);
if AFormat = sfExcel2 then if AFormat = sfExcel2 then
MyWorksheet := MyWorkbook.GetFirstWorksheet MyWorksheet := MyWorkbook.GetFirstWorksheet
@ -177,10 +181,11 @@ begin
CheckEquals(expectedRGB, currentRGB, CheckEquals(expectedRGB, currentRGB,
'Test saved background color, cell '+CellNotation(MyWorksheet,Row,Col)); 'Test saved background color, cell '+CellNotation(MyWorksheet,Row,Col));
end; end;
finally
MyWorkbook.Free; MyWorkbook.Free;
DeleteFile(TempFile); DeleteFile(TempFile);
end; end;
end;
procedure TSpreadWriteReadColorTests.TestWriteReadFontColors(AFormat: TsSpreadsheetFormat; procedure TSpreadWriteReadColorTests.TestWriteReadFontColors(AFormat: TsSpreadsheetFormat;
WhichPalette: Integer); WhichPalette: Integer);
@ -204,6 +209,7 @@ begin
TempFile:=GetTempFileName; TempFile:=GetTempFileName;
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkSheet:= MyWorkBook.AddWorksheet(ColorsSheet); MyWorkSheet:= MyWorkBook.AddWorksheet(ColorsSheet);
// Define palette // Define palette
@ -241,10 +247,13 @@ begin
inc(row); inc(row);
end; end;
MyWorkBook.WriteToFile(TempFile, AFormat, true); MyWorkBook.WriteToFile(TempFile, AFormat, true);
finally
MyWorkbook.Free; MyWorkbook.Free;
end;
// Open the spreadsheet // Open the spreadsheet
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkbook.ReadFromFile(TempFile, AFormat); MyWorkbook.ReadFromFile(TempFile, AFormat);
if AFormat = sfExcel2 then if AFormat = sfExcel2 then
MyWorksheet := MyWorkbook.GetFirstWorksheet MyWorksheet := MyWorkbook.GetFirstWorksheet
@ -263,10 +272,11 @@ begin
CheckEquals(expectedRGB, currentRGB, CheckEquals(expectedRGB, currentRGB,
'Test saved font color, cell '+CellNotation(MyWorksheet,Row,Col)); 'Test saved font color, cell '+CellNotation(MyWorksheet,Row,Col));
end; end;
finally
MyWorkbook.Free; MyWorkbook.Free;
DeleteFile(TempFile); DeleteFile(TempFile);
end; end;
end;
{ Tests for BIFF2 file format } { Tests for BIFF2 file format }
{ BIFF2 supports only a fixed palette, and no background color --> test only { BIFF2 supports only a fixed palette, and no background color --> test only

View File

@ -389,6 +389,7 @@ begin
} }
// Write out all test values // Write out all test values
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkSheet:=MyWorkBook.AddWorksheet(DatesSheet); MyWorkSheet:=MyWorkBook.AddWorksheet(DatesSheet);
for Row := Low(SollDates) to High(SollDates) do for Row := Low(SollDates) to High(SollDates) do
begin begin
@ -399,10 +400,13 @@ begin
CheckEquals(SollDates[Row],ActualDateTime,'Test date/time value mismatch cell '+CellNotation(MyWorksheet,Row)); CheckEquals(SollDates[Row],ActualDateTime,'Test date/time value mismatch cell '+CellNotation(MyWorksheet,Row));
end; end;
MyWorkBook.WriteToFile(TempFile, AFormat, true); MyWorkBook.WriteToFile(TempFile, AFormat, true);
finally
MyWorkbook.Free; MyWorkbook.Free;
end;
// Open the spreadsheet, as biff8 // Open the spreadsheet, as biff8
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkbook.ReadFromFile(TempFile, AFormat); MyWorkbook.ReadFromFile(TempFile, AFormat);
if AFormat = sfExcel2 then if AFormat = sfExcel2 then
MyWorksheet := MyWorkbook.GetFirstWorksheet MyWorksheet := MyWorkbook.GetFirstWorksheet
@ -418,11 +422,11 @@ begin
Fail('Could not read date time for cell '+CellNotation(MyWorkSheet,Row)); Fail('Could not read date time for cell '+CellNotation(MyWorkSheet,Row));
CheckEquals(SollDates[Row],ActualDateTime,'Test date/time value mismatch cell '+CellNotation(MyWorkSheet,Row)); CheckEquals(SollDates[Row],ActualDateTime,'Test date/time value mismatch cell '+CellNotation(MyWorkSheet,Row));
end; end;
// Finalization finally
MyWorkbook.Free; MyWorkbook.Free;
DeleteFile(TempFile); DeleteFile(TempFile);
end; end;
end;
procedure TSpreadWriteReadDateTests.TestWriteReadDates_BIFF2; procedure TSpreadWriteReadDateTests.TestWriteReadDates_BIFF2;
begin begin

View File

@ -155,15 +155,16 @@ var
begin begin
TempFile := GetTempFileName; TempFile := GetTempFileName;
MyWorkbook := TsWorkbook.Create;
MyWorkSheet:= MyWorkBook.AddWorksheet(EmptyCellsSheet);
L := TStringList.Create; L := TStringList.Create;
try try
L.Delimiter := '|'; L.Delimiter := '|';
L.StrictDelimiter := true; L.StrictDelimiter := true;
L.DelimitedText := SollLayoutStrings[ALayout]; L.DelimitedText := SollLayoutStrings[ALayout];
MyWorkbook := TsWorkbook.Create;
try
MyWorkSheet:= MyWorkBook.AddWorksheet(EmptyCellsSheet);
// Write out cells // Write out cells
for row := 0 to L.Count-1 do begin for row := 0 to L.Count-1 do begin
s := L[row]; s := L[row];
@ -176,10 +177,13 @@ begin
end; end;
end; end;
MyWorkBook.WriteToFile(TempFile, AFormat, true); MyWorkBook.WriteToFile(TempFile, AFormat, true);
finally
MyWorkbook.Free; MyWorkbook.Free;
end;
// Open the spreadsheet // Open the spreadsheet
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkbook.ReadFromFile(TempFile, AFormat); MyWorkbook.ReadFromFile(TempFile, AFormat);
if AFormat = sfExcel2 then if AFormat = sfExcel2 then
MyWorksheet := MyWorkbook.GetFirstWorksheet MyWorksheet := MyWorkbook.GetFirstWorksheet
@ -205,12 +209,13 @@ begin
'Test empty cell layout mismatch, cell '+CellNotation(MyWorksheet, Row, Col)); 'Test empty cell layout mismatch, cell '+CellNotation(MyWorksheet, Row, Col));
end; end;
finally finally
L.Free; MyWorkbook.Free;
DeleteFile(TempFile);
end; end;
MyWorkbook.Free; finally
L.Free;
DeleteFile(TempFile); end;
end; end;
{ BIFF2 tests } { BIFF2 tests }

View File

@ -143,6 +143,7 @@ begin
DeleteFile(TempFile); DeleteFile(TempFile);
} }
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkSheet:= MyWorkBook.AddWorksheet(FontSheet); MyWorkSheet:= MyWorkBook.AddWorksheet(FontSheet);
// Write out a cell without "bold" formatting style // Write out a cell without "bold" formatting style
@ -167,10 +168,13 @@ begin
TempFile:=NewTempFile; TempFile:=NewTempFile;
MyWorkBook.WriteToFile(TempFile, AFormat, true); MyWorkBook.WriteToFile(TempFile, AFormat, true);
finally
MyWorkbook.Free; MyWorkbook.Free;
end;
// Open the spreadsheet // Open the spreadsheet
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkbook.ReadFromFile(TempFile, AFormat); MyWorkbook.ReadFromFile(TempFile, AFormat);
if AFormat = sfExcel2 then if AFormat = sfExcel2 then
MyWorksheet := MyWorkbook.GetFirstWorksheet // only 1 sheet for BIFF2 MyWorksheet := MyWorkbook.GetFirstWorksheet // only 1 sheet for BIFF2
@ -195,10 +199,11 @@ begin
fail('Error in test code. Failed to get cell.'); fail('Error in test code. Failed to get cell.');
CheckEquals(uffBold in MyCell^.UsedFormattingFields, true, CheckEquals(uffBold in MyCell^.UsedFormattingFields, true,
'Test saved bold attribute, cell '+CellNotation(MyWorksheet,row,col)); 'Test saved bold attribute, cell '+CellNotation(MyWorksheet,row,col));
finally
MyWorkbook.Free; MyWorkbook.Free;
DeleteFile(TempFile); DeleteFile(TempFile);
end; end;
end;
procedure TSpreadWriteReadFontTests.TestWriteReadFont(AFormat: TsSpreadsheetFormat; procedure TSpreadWriteReadFontTests.TestWriteReadFont(AFormat: TsSpreadsheetFormat;
AFontName: String); AFontName: String);
@ -220,6 +225,7 @@ begin
DeleteFile(TempFile); DeleteFile(TempFile);
} }
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkSheet:= MyWorkBook.AddWorksheet(FontSheet); MyWorkSheet:= MyWorkBook.AddWorksheet(FontSheet);
// Write out all font styles at various sizes // Write out all font styles at various sizes
@ -245,10 +251,13 @@ begin
end; end;
TempFile:=NewTempFile; TempFile:=NewTempFile;
MyWorkBook.WriteToFile(TempFile, AFormat, true); MyWorkBook.WriteToFile(TempFile, AFormat, true);
finally
MyWorkbook.Free; MyWorkbook.Free;
end;
// Open the spreadsheet // Open the spreadsheet
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkbook.ReadFromFile(TempFile, AFormat); MyWorkbook.ReadFromFile(TempFile, AFormat);
if AFormat = sfExcel2 then if AFormat = sfExcel2 then
MyWorksheet := MyWorkbook.GetFirstWorksheet // only 1 sheet for BIFF2 MyWorksheet := MyWorkbook.GetFirstWorksheet // only 1 sheet for BIFF2
@ -275,10 +284,11 @@ begin
'Test unsaved font style, cell ' + CellNotation(MyWorksheet,0,0)); 'Test unsaved font style, cell ' + CellNotation(MyWorksheet,0,0));
inc(counter); inc(counter);
end; end;
finally
MyWorkbook.Free; MyWorkbook.Free;
DeleteFile(TempFile); DeleteFile(TempFile);
end; end;
end;
{ BIFF2 } { BIFF2 }

View File

@ -201,6 +201,7 @@ begin
} }
// Write out all test values // Write out all test values
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkSheet := MyWorkBook.AddWorksheet(NumbersSheet); MyWorkSheet := MyWorkBook.AddWorksheet(NumbersSheet);
for Row := Low(SollNumbers) to High(SollNumbers) do for Row := Low(SollNumbers) to High(SollNumbers) do
begin begin
@ -211,10 +212,13 @@ begin
end; end;
TempFile:=NewTempFile; TempFile:=NewTempFile;
MyWorkBook.WriteToFile(TempFile, AFormat, true); MyWorkBook.WriteToFile(TempFile, AFormat, true);
finally
MyWorkbook.Free; MyWorkbook.Free;
end;
// Open the spreadsheet, as biff8 // Open the spreadsheet, as biff8
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkbook.ReadFromFile(TempFile, AFormat); MyWorkbook.ReadFromFile(TempFile, AFormat);
if AFormat = sfExcel2 then if AFormat = sfExcel2 then
MyWorksheet := MyWorkbook.GetFirstWorksheet MyWorksheet := MyWorkbook.GetFirstWorksheet
@ -229,11 +233,11 @@ begin
ActualNumber:=MyWorkSheet.ReadAsNumber(Row,0); ActualNumber:=MyWorkSheet.ReadAsNumber(Row,0);
CheckEquals(SollNumbers[Row],ActualNumber,'Test value mismatch cell '+CellNotation(MyWorkSheet,Row)); CheckEquals(SollNumbers[Row],ActualNumber,'Test value mismatch cell '+CellNotation(MyWorkSheet,Row));
end; end;
// Finalization finally
MyWorkbook.Free; MyWorkbook.Free;
DeleteFile(TempFile); DeleteFile(TempFile);
end; end;
end;
procedure TSpreadWriteReadNumberTests.TestWriteReadNumbers_BIFF2; procedure TSpreadWriteReadNumberTests.TestWriteReadNumbers_BIFF2;
begin begin

View File

@ -116,6 +116,7 @@ begin
// Write out show/hide grid lines/sheet headers // Write out show/hide grid lines/sheet headers
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkSheet:= MyWorkBook.AddWorksheet(OptionsSheet); MyWorkSheet:= MyWorkBook.AddWorksheet(OptionsSheet);
if AShowGridLines then if AShowGridLines then
MyWorksheet.Options := MyWorksheet.Options + [soShowGridLines] MyWorksheet.Options := MyWorksheet.Options + [soShowGridLines]
@ -127,10 +128,13 @@ begin
MyWorksheet.Options := MyWorksheet.Options - [soShowHeaders]; MyWorksheet.Options := MyWorksheet.Options - [soShowHeaders];
MyWorkBook.WriteToFile(TempFile, AFormat, true); MyWorkBook.WriteToFile(TempFile, AFormat, true);
finally
MyWorkbook.Free; MyWorkbook.Free;
end;
// Read back presence of grid lines/sheet headers // Read back presence of grid lines/sheet headers
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkbook.ReadFromFile(TempFile, AFormat); MyWorkbook.ReadFromFile(TempFile, AFormat);
if AFormat = sfExcel2 then if AFormat = sfExcel2 then
MyWorksheet := MyWorkbook.GetFirstWorksheet MyWorksheet := MyWorkbook.GetFirstWorksheet
@ -142,10 +146,11 @@ begin
'Test saved show grid lines mismatch'); 'Test saved show grid lines mismatch');
CheckEquals(soShowHeaders in MyWorksheet.Options, AShowHeaders, CheckEquals(soShowHeaders in MyWorksheet.Options, AShowHeaders,
'Test saved show headers mismatch'); 'Test saved show headers mismatch');
finally
MyWorkbook.Free; MyWorkbook.Free;
DeleteFile(TempFile); DeleteFile(TempFile);
end; end;
end;
{ Tests for BIFF2 grid lines and/or headers } { Tests for BIFF2 grid lines and/or headers }
procedure TSpreadWriteReadOptionsTests.TestWriteRead_BIFF2_ShowGridLines_ShowHeaders; procedure TSpreadWriteReadOptionsTests.TestWriteRead_BIFF2_ShowGridLines_ShowHeaders;
@ -270,15 +275,19 @@ begin
// Write out pane sizes // Write out pane sizes
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkSheet:= MyWorkBook.AddWorksheet(OptionsSheet); MyWorkSheet:= MyWorkBook.AddWorksheet(OptionsSheet);
MyWorksheet.LeftPaneWidth := ALeftPaneWidth; MyWorksheet.LeftPaneWidth := ALeftPaneWidth;
MyWorksheet.TopPaneHeight := ATopPaneHeight; MyWorksheet.TopPaneHeight := ATopPaneHeight;
MyWorksheet.Options := MyWorksheet.Options + [soHasFrozenPanes]; MyWorksheet.Options := MyWorksheet.Options + [soHasFrozenPanes];
MyWorkBook.WriteToFile(TempFile, AFormat, true); MyWorkBook.WriteToFile(TempFile, AFormat, true);
finally
MyWorkbook.Free; MyWorkbook.Free;
end;
// Read back pane sizes // Read back pane sizes
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkbook.ReadFromFile(TempFile, AFormat); MyWorkbook.ReadFromFile(TempFile, AFormat);
if AFormat = sfExcel2 then if AFormat = sfExcel2 then
MyWorksheet := MyWorkbook.GetFirstWorksheet MyWorksheet := MyWorkbook.GetFirstWorksheet
@ -295,10 +304,11 @@ begin
'Test saved left pane width mismatch'); 'Test saved left pane width mismatch');
CheckEquals(ATopPaneHeight, MyWorksheet.TopPaneHeight, CheckEquals(ATopPaneHeight, MyWorksheet.TopPaneHeight,
'Test save top pane height mismatch'); 'Test save top pane height mismatch');
finally
MyWorkbook.Free; MyWorkbook.Free;
DeleteFile(TempFile); DeleteFile(TempFile);
end; end;
end;
{ Tests for BIFF5 frozen panes } { Tests for BIFF5 frozen panes }
procedure TSpreadWriteReadOptionsTests.TestWriteRead_BIFF5_Panes_HorVert; procedure TSpreadWriteReadOptionsTests.TestWriteRead_BIFF5_Panes_HorVert;

View File

@ -48,10 +48,12 @@
<Unit1> <Unit1>
<Filename Value="datetests.pas"/> <Filename Value="datetests.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="datetests"/>
</Unit1> </Unit1>
<Unit2> <Unit2>
<Filename Value="stringtests.pas"/> <Filename Value="stringtests.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="stringtests"/>
</Unit2> </Unit2>
<Unit3> <Unit3>
<Filename Value="numberstests.pas"/> <Filename Value="numberstests.pas"/>
@ -81,18 +83,22 @@
<Unit8> <Unit8>
<Filename Value="colortests.pas"/> <Filename Value="colortests.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="colortests"/>
</Unit8> </Unit8>
<Unit9> <Unit9>
<Filename Value="fonttests.pas"/> <Filename Value="fonttests.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="fonttests"/>
</Unit9> </Unit9>
<Unit10> <Unit10>
<Filename Value="optiontests.pas"/> <Filename Value="optiontests.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="optiontests"/>
</Unit10> </Unit10>
<Unit11> <Unit11>
<Filename Value="numformatparsertests.pas"/> <Filename Value="numformatparsertests.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="numformatparsertests"/>
</Unit11> </Unit11>
<Unit12> <Unit12>
<Filename Value="rpnformulaunit.pas"/> <Filename Value="rpnformulaunit.pas"/>
@ -127,6 +133,9 @@
<DebugInfoType Value="dsDwarf2Set"/> <DebugInfoType Value="dsDwarf2Set"/>
</Debugging> </Debugging>
</Linking> </Linking>
<Other>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions> </CompilerOptions>
<Debugging> <Debugging>
<Exceptions Count="6"> <Exceptions Count="6">

View File

@ -2,13 +2,27 @@ program spreadtestgui;
{$mode objfpc}{$H+} {$mode objfpc}{$H+}
{.$DEFINE HEAPTRC} // Instead of using -gh activate this to write the heap trace to file
uses uses
{$IFDEF HEAPTRC}
HeapTrc, SysUtils,
{$ENDIF}
Interfaces, Forms, GuiTestRunner, datetests, stringtests, numberstests, Interfaces, Forms, GuiTestRunner, datetests, stringtests, numberstests,
manualtests, testsutility, internaltests, formattests, colortests, fonttests, manualtests, testsutility, internaltests, formattests, colortests, fonttests,
optiontests, numformatparsertests, formulatests, rpnFormulaUnit, optiontests, numformatparsertests, formulatests, rpnFormulaUnit,
emptycelltests; emptycelltests;
begin begin
{$IFDEF HEAPTRC}
// Assuming your build mode sets -dDEBUG in Project Options/Other when defining -gh
// This avoids interference when running a production/default build without -gh
if FileExists('heap.trc') then
DeleteFile('heap.trc');
SetHeapTraceOutput('heap.trc');
{$ENDIF HEAPTRC}
Application.Initialize; Application.Initialize;
Application.CreateForm(TGuiTestRunner, TestRunner); Application.CreateForm(TGuiTestRunner, TestRunner);
Application.Run; Application.Run;

View File

@ -172,6 +172,7 @@ begin
} }
// Write out all test values // Write out all test values
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkSheet:=MyWorkBook.AddWorksheet(StringsSheet); MyWorkSheet:=MyWorkBook.AddWorksheet(StringsSheet);
for Row := Low(SollStrings) to High(SollStrings) do for Row := Low(SollStrings) to High(SollStrings) do
begin begin
@ -182,10 +183,13 @@ begin
end; end;
TempFile:=NewTempFile; TempFile:=NewTempFile;
MyWorkBook.WriteToFile(TempFile,sfExcel8,true); MyWorkBook.WriteToFile(TempFile,sfExcel8,true);
finally
MyWorkbook.Free; MyWorkbook.Free;
end;
// Open the spreadsheet, as biff8 // Open the spreadsheet, as biff8
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkbook.ReadFromFile(TempFile, sfExcel8); MyWorkbook.ReadFromFile(TempFile, sfExcel8);
MyWorksheet:=GetWorksheetByName(MyWorkBook,StringsSheet); MyWorksheet:=GetWorksheetByName(MyWorkBook,StringsSheet);
if MyWorksheet=nil then if MyWorksheet=nil then
@ -197,11 +201,11 @@ begin
ActualString:=MyWorkSheet.ReadAsUTF8Text(Row,0); ActualString:=MyWorkSheet.ReadAsUTF8Text(Row,0);
CheckEquals(SollStrings[Row],ActualString,'Test value mismatch, cell '+CellNotation(MyWorkSheet,Row)); CheckEquals(SollStrings[Row],ActualString,'Test value mismatch, cell '+CellNotation(MyWorkSheet,Row));
end; end;
// Finalization finally
MyWorkbook.Free; MyWorkbook.Free;
DeleteFile(TempFile); DeleteFile(TempFile);
end; end;
end;
procedure TSpreadWriteReadStringTests.TestWriteReadStringsLimits; procedure TSpreadWriteReadStringTests.TestWriteReadStringsLimits;
const const
@ -227,6 +231,7 @@ begin
} }
// Write out all test values // Write out all test values
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkSheet:=MyWorkBook.AddWorksheet(StringsSheet); MyWorkSheet:=MyWorkBook.AddWorksheet(StringsSheet);
for Row := Low(LocalNormStrings) to High(LocalNormStrings) do for Row := Low(LocalNormStrings) to High(LocalNormStrings) do
@ -279,10 +284,13 @@ begin
end; end;
// Notify user of exception if it happened where we didn't expect it: // Notify user of exception if it happened where we didn't expect it:
CheckTrue(TestResult,'Exception: '+ExceptionMessage); CheckTrue(TestResult,'Exception: '+ExceptionMessage);
finally
MyWorkbook.Free; MyWorkbook.Free;
end;
// Open the spreadsheet, as biff8 // Open the spreadsheet, as biff8
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkbook.ReadFromFile(TempFile, sfExcel8); MyWorkbook.ReadFromFile(TempFile, sfExcel8);
MyWorksheet:=GetWorksheetByName(MyWorkBook,StringsSheet); MyWorksheet:=GetWorksheetByName(MyWorkBook,StringsSheet);
if MyWorksheet=nil then if MyWorksheet=nil then
@ -302,11 +310,11 @@ begin
'Test value mismatch cell '+CellNotation(MyWorkSheet,Row)+ 'Test value mismatch cell '+CellNotation(MyWorkSheet,Row)+
' for string length.'); ' for string length.');
end; end;
// Finalization finally
MyWorkbook.Free; MyWorkbook.Free;
DeleteFile(TempFile); DeleteFile(TempFile);
end; end;
end;
{ TSpreadReadStringTests } { TSpreadReadStringTests }

View File

@ -1677,6 +1677,9 @@ begin
end else end else
begin begin
// The cells need to be written in order, row by row, cell by cell // The cells need to be written in order, row by row, cell by cell
c1 := AWorksheet.GetFirstColIndex;
c2 := AWorksheet.GetLastColIndex;
if (c1 = $FFFFFFFF) and (c2 = 0) then c1 := 0; // avoid arithmetic overflow in case of empty worksheet
for r := 0 to AWorksheet.GetLastRowIndex do begin for r := 0 to AWorksheet.GetLastRowIndex do begin
// If the row has a custom height add this value to the <row> specification // If the row has a custom height add this value to the <row> specification
row := AWorksheet.FindRow(r); row := AWorksheet.FindRow(r);
@ -1685,8 +1688,6 @@ begin
(row^.Height + ROW_HEIGHT_CORRECTION)*h0]) (row^.Height + ROW_HEIGHT_CORRECTION)*h0])
else else
rh := ''; rh := '';
c1 := AWorksheet.GetFirstColIndex;
c2 := AWorksheet.GetLastColIndex;
AppendToStream(AStream, Format( AppendToStream(AStream, Format(
'<row r="%d" spans="%d:%d"%s>', [r+1, c1+1, c2+1, rh])); '<row r="%d" spans="%d:%d"%s>', [r+1, c1+1, c2+1, rh]));
// Write cells belonging to this row. // Write cells belonging to this row.