diff --git a/README.markdown b/README.markdown
index dac3b69..def60b3 100644
--- a/README.markdown
+++ b/README.markdown
@@ -78,7 +78,7 @@ unfinished form on my harddrive for more than a year. Finally it slipped out.
-u TestUnit TestUnit2 | The units that shall be checked for code coverage |
-uf filename | Cover units listed in the file pointed to by filename. One unit per line in the file |
-v | Show verbose output |
- -dproj ProjectFile.dproj | Parse the project file for source dirs |
+ -dproj ProjectFile.dproj | Parse the project file for source dirs, executable name, code page and other options. Note that options that could only have single value, like code page, will be overwritten in the order of appearance if multiple related switches are encountered. |
-a Param Param2 | Parameters to pass on to the application that shall be checked for code coverage. ^ is an escape character |
-lt [filename] | Log events to a text log file. Default file name is: Delphi-Code-Coverage-Debug.log |
-lapi | Log events to the Windows API OutputDebugString |
@@ -94,6 +94,7 @@ unfinished form on my harddrive for more than a year. Finally it slipped out.
-uns dll_or_exe unitname [unitname_2] | Create a separate namespace (the namespace name will be the name of the module without extension) ONLY for the listed units within the module |
-mns name dll_or_exe [dll_or_exe_2] | Create a separate namespace with the given name for the listed dll:s. All modules loaded in those module(s) will be namespaced. |
-lcl LineCountLimit | Count number of times a line is executed up to the specified limit |
+ -cp CodePage | Code page number of source files |
-tec | Passthrough the exitcode of the application inspected |
-twd | Use the application's path as working directory |
diff --git a/Source/CoverageConfiguration.pas b/Source/CoverageConfiguration.pas
index 1e59fd6..91e3bf3 100644
--- a/Source/CoverageConfiguration.pas
+++ b/Source/CoverageConfiguration.pas
@@ -52,6 +52,7 @@ TCoverageConfiguration = class(TInterfacedObject, ICoverageConfiguration)
FModuleNameSpaces: TModuleNameSpaceList;
FUnitNameSpaces: TUnitNameSpaceList;
FLineCountLimit: Integer;
+ FCodePage: Integer;
FLogManager: ILogManager;
procedure ReadSourcePathFile(const ASourceFileName: string);
@@ -62,6 +63,7 @@ TCoverageConfiguration = class(TInterfacedObject, ICoverageConfiguration)
function GetBasePropertyGroupNode(const Project: IXMLNode): IXMLNode;
function GetExeOutputFromDProj(const Project: IXMLNode; const ProjectName: TFileName): string;
function GetSourceDirsFromDProj(const Project: IXMLNode): string;
+ function GetCodePageFromDProj(const Project: IXMLNode): Integer;
procedure ParseDProj(const DProjFilename: TFileName);
function IsPathInExclusionList(const APath: TFileName): Boolean;
procedure ExcludeSourcePaths;
@@ -90,6 +92,7 @@ TCoverageConfiguration = class(TInterfacedObject, ICoverageConfiguration)
procedure ParseModuleNameSpaceSwitch(var AParameter: Integer);
procedure ParseUnitNameSpaceSwitch(var AParameter: Integer);
procedure ParseLineCountSwitch(var AParameter: Integer);
+ procedure ParseCodePageSwitch(var AParameter: Integer);
public
constructor Create(const AParameterProvider: IParameterProvider);
destructor Destroy; override;
@@ -117,6 +120,7 @@ TCoverageConfiguration = class(TInterfacedObject, ICoverageConfiguration)
function TestExeExitCode: Boolean;
function UseTestExePathAsWorkingDir: Boolean;
function LineCountLimit: Integer;
+ function CodePage: Integer;
function ModuleNameSpace(const AModuleName: string): TModuleNameSpace;
function UnitNameSpace(const AModuleName: string): TUnitNameSpace;
@@ -213,6 +217,11 @@ function TCoverageConfiguration.LineCountLimit: integer;
Result := FLineCountLimit;
end;
+function TCoverageConfiguration.CodePage: Integer;
+begin
+ Result := FCodePage;
+end;
+
function TCoverageConfiguration.IsComplete(var AReason: string): Boolean;
begin
if FSourcePathLst.Count = 0 then
@@ -574,6 +583,8 @@ procedure TCoverageConfiguration.ParseSwitch(var AParameter: Integer);
FStripFileExtension := False
else if (SwitchItem = I_CoverageConfiguration.cPARAMETER_LINE_COUNT) then
ParseLineCountSwitch(AParameter)
+ else if (SwitchItem = I_CoverageConfiguration.cPARAMETER_CODE_PAGE) then
+ ParseCodePageSwitch(AParameter)
else if (SwitchItem = I_CoverageConfiguration.cPARAMETER_EMMA_OUTPUT)
or (SwitchItem = I_CoverageConfiguration.cPARAMETER_EMMA21_OUTPUT)
or (SwitchItem = I_CoverageConfiguration.cPARAMETER_EMMA_SEPARATE_META)
@@ -931,6 +942,20 @@ function TCoverageConfiguration.GetSourceDirsFromDProj(const Project: IXMLNode):
Result := StringReplace(Node.Text, '$(DCC_UnitSearchPath)', '', [rfReplaceAll, rfIgnoreCase]);
end;
+function TCoverageConfiguration.GetCodePageFromDProj(const Project: IXMLNode): Integer;
+var
+ Node: IXMLNode;
+begin
+ Result := 0;
+ Assert(Assigned(Project));
+
+ Node := GetBasePropertyGroupNode(Project);
+ if Node = nil then Exit;
+ Node := Node.ChildNodes.FindNode('DCC_CodePage');
+ if Node = nil then Exit;
+ Result := StrToIntDef(Node.Text, 0);
+end;
+
function TCoverageConfiguration.GetExeOutputFromDProj(const Project: IXMLNode; const ProjectName: TFileName): string;
var
CurrentConfig: string;
@@ -1007,6 +1032,8 @@ procedure TCoverageConfiguration.ParseDProj(const DProjFilename: TFileName);
end;
end;
+ FCodePage := GetCodePageFromDProj(Project);
+
ItemGroup := Project.ChildNodes.FindNode('ItemGroup');
if ItemGroup <> nil then
begin
@@ -1139,5 +1166,21 @@ procedure TCoverageConfiguration.ParseLineCountSwitch(var AParameter: Integer);
end;
end;
+procedure TCoverageConfiguration.ParseCodePageSwitch(var AParameter: Integer);
+var
+ ParsedParameter: string;
+begin
+ Inc(AParameter);
+ ParsedParameter := ParseParameter(AParameter);
+ if ParsedParameter.StartsWith('-') then // This is a switch, not a number
+ begin
+ Dec(AParameter);
+ end
+ else
+ begin
+ FCodePage := StrToIntDef(ParsedParameter, 0);
+ end;
+end;
+
end.
diff --git a/Source/Debugger.pas b/Source/Debugger.pas
index 34357ec..6f578cb 100644
--- a/Source/Debugger.pas
+++ b/Source/Debugger.pas
@@ -265,6 +265,8 @@ procedure TDebugger.PrintUsage;
' dll_or_exe unitname [unitname2] -- Create a separate namespace (the namespace name will be the name of the module without extension) *ONLY* for the listed units within the module.');
ConsoleOutput(I_CoverageConfiguration.cPARAMETER_LINE_COUNT +
' [number] -- Count number of times a line is executed up to the specified limit (default 0 - disabled)');
+ ConsoleOutput(I_CoverageConfiguration.cPARAMETER_CODE_PAGE +
+ ' [number] -- Code page of source files');
ConsoleOutput(I_CoverageConfiguration.cPARAMETER_TESTEXE_EXIT_CODE +
' -- Passthrough the exitcode of the application');
ConsoleOutput(I_CoverageConfiguration.cPARAMETER_USE_TESTEXE_WORKING_DIR +
diff --git a/Source/HTMLCoverageReport.pas b/Source/HTMLCoverageReport.pas
index dfece46..125a141 100644
--- a/Source/HTMLCoverageReport.pas
+++ b/Source/HTMLCoverageReport.pas
@@ -201,6 +201,7 @@ function THTMLCoverageReport.GenerateUnitReport(
OutputFile: TTextWriter;
SourceFileName: string;
OutputFileName: string;
+ Encoding: TEncoding;
begin
Result.HasFile:= False;
Result.LinkFileName:= ACoverageUnit.ReportFileName + '.html';
@@ -211,7 +212,11 @@ function THTMLCoverageReport.GenerateUnitReport(
SourceFileName := FindSourceFile(ACoverageUnit, Result);
try
- InputFile := TStreamReader.Create(SourceFileName, TEncoding.ANSI, True);
+ if FCoverageConfiguration.CodePage <> 0 then
+ Encoding := TEncoding.GetEncoding(FCoverageConfiguration.CodePage)
+ else
+ Encoding := TEncoding.ANSI;
+ InputFile := TStreamReader.Create(SourceFileName, Encoding, True);
except
on E: EFileStreamError do
begin
diff --git a/Source/I_CoverageConfiguration.pas b/Source/I_CoverageConfiguration.pas
index 67a6d5e..4695e65 100644
--- a/Source/I_CoverageConfiguration.pas
+++ b/Source/I_CoverageConfiguration.pas
@@ -44,6 +44,7 @@ interface
function ModuleNameSpace(const AModuleName: string): TModuleNameSpace;
function UnitNameSpace(const AModuleName: string): TUnitNameSpace;
function LineCountLimit: Integer;
+ function CodePage: Integer;
end;
const
@@ -77,6 +78,7 @@ interface
cPARAMETER_TESTEXE_EXIT_CODE = '-tec';
cPARAMETER_USE_TESTEXE_WORKING_DIR = '-twd';
cPARAMETER_LINE_COUNT = '-lcl';
+ cPARAMETER_CODE_PAGE = '-cp';
cIGNORE_UNIT_PREFIX = '!';
implementation
diff --git a/Test/CoverageConfigurationTest.pas b/Test/CoverageConfigurationTest.pas
index e1e1160..e90454a 100644
--- a/Test/CoverageConfigurationTest.pas
+++ b/Test/CoverageConfigurationTest.pas
@@ -31,6 +31,7 @@ TCoverageConfigurationTest = class(TTestCase)
procedure TestInvalidParameter;
procedure TestEnableApiLogging;
+ procedure TestSetCodepage;
procedure TestEnableFileLoggingDefaultFile;
procedure TestEnableFileLoggingSpecifiedFile;
@@ -115,6 +116,7 @@ implementation
cUNIT_PARAMETER : array [0 .. 0] of string = (I_CoverageConfiguration.cPARAMETER_UNIT);
cMAP_FILE_PARAMETER : array [0 .. 0] of string = (I_CoverageConfiguration.cPARAMETER_MAP_FILE);
cEXECUTABLE_PARAMETER : array [0 .. 0] of string = (I_CoverageConfiguration.cPARAMETER_EXECUTABLE);
+ cCODE_PAGE : array [0 .. 1] of string = (I_CoverageConfiguration.cPARAMETER_CODE_PAGE, '1250');
cSOME_EXTENSION = '.someExt';
cEXCLUDE_FILES_PREFIX = 'exclude';
//==============================================================================
@@ -231,6 +233,16 @@ procedure TCoverageConfigurationTest.TestEnableApiLogging;
CheckTrue(LCoverageConfiguration.UseApiDebug, 'API Logging was not turned on.');
end;
+//==============================================================================
+procedure TCoverageConfigurationTest.TestSetCodepage;
+var
+ LCoverageConfiguration: ICoverageConfiguration;
+begin
+ LCoverageConfiguration := TCoverageConfiguration.Create(TMockCommandLineProvider.Create(cCODE_PAGE));
+ LCoverageConfiguration.ParseCommandLine;
+ CheckEquals(StrToInt(cCODE_PAGE[1]), LCoverageConfiguration.CodePage, 'Code page was not set.');
+end;
+
//==============================================================================
procedure TCoverageConfigurationTest.TestEnableFileLoggingDefaultFile;
var
@@ -1485,6 +1497,7 @@ procedure TCoverageConfigurationTest.TestDProj;
LDProj.Add('');
LDProj.Add('..\build\$(PLATFORM)');
LDProj.Add('..\src\;$(DCC_UnitSearchPath)');
+ LDProj.Add('65001');
LDProj.Add('');
LTotalUnitList := TStringList.Create;