mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-12-02 23:27:23 +01:00
pas2js: logger adapted for pas2js
git-svn-id: trunk@40041 -
This commit is contained in:
parent
bcbc578287
commit
a089496183
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -6995,6 +6995,7 @@ packages/pastojs/src/pas2jscompiler.pp svneol=native#text/plain
|
||||
packages/pastojs/src/pas2jsfilecache.pp svneol=native#text/plain
|
||||
packages/pastojs/src/pas2jsfiler.pp svneol=native#text/plain
|
||||
packages/pastojs/src/pas2jsfileutils.pp svneol=native#text/plain
|
||||
packages/pastojs/src/pas2jsfileutilsnodejs.inc svneol=native#text/plain
|
||||
packages/pastojs/src/pas2jsfileutilsunix.inc svneol=native#text/plain
|
||||
packages/pastojs/src/pas2jsfileutilswin.inc svneol=native#text/plain
|
||||
packages/pastojs/src/pas2jslibcompiler.pp svneol=native#text/plain
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
|
||||
{$inline on}
|
||||
|
||||
{$IFDEF Windows}
|
||||
{$define CaseInsensitiveFilenames}
|
||||
{$define HasUNCPaths}
|
||||
@ -11,6 +12,11 @@
|
||||
{$DEFINE NotLiteralFilenames} // e.g. HFS+ normalizes file names
|
||||
{$ENDIF}
|
||||
|
||||
{$DEFINE UTF8_RTL}
|
||||
{$IFDEF FPC}
|
||||
{$DEFINE UsePChar}
|
||||
{$DEFINE HasInt64}
|
||||
{$DEFINE UTF8_RTL}
|
||||
{$DEFINE HasStdErr}
|
||||
{$ENDIF}
|
||||
|
||||
|
||||
|
||||
@ -2975,7 +2975,7 @@ var
|
||||
aFilename: String;
|
||||
begin
|
||||
// first try HOME directory
|
||||
aFilename:=ChompPathDelim(GetEnvironmentVariableUTF8('HOME'));
|
||||
aFilename:=ChompPathDelim(GetEnvironmentVariablePJ('HOME'));
|
||||
if aFilename<>'' then
|
||||
begin
|
||||
aFilename:=aFilename+PathDelim{$IFDEF UNIX}+'.'{$ENDIF}+DefaultConfigFile;
|
||||
@ -3716,7 +3716,7 @@ begin
|
||||
RegisterMessages;
|
||||
|
||||
FFileCache:=TPas2jsFilesCache.Create(Log);
|
||||
FFileCache.BaseDirectory:=GetCurrentDirUTF8;
|
||||
FFileCache.BaseDirectory:=GetCurrentDirPJ;
|
||||
FFileCacheAutoFree:=true;
|
||||
FDirectoryCache:=FFileCache.DirectoryCache;
|
||||
FLog.OnFormatPath:=@FileCache.FormatPath;
|
||||
@ -3793,7 +3793,7 @@ function TPas2jsCompiler.OnMacroEnv(Sender: TObject; var Params: string;
|
||||
Lvl: integer): boolean;
|
||||
begin
|
||||
if Lvl=0 then ;
|
||||
Params:=GetEnvironmentVariableUTF8(Params);
|
||||
Params:=GetEnvironmentVariablePJ(Params);
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
@ -4428,7 +4428,7 @@ end;
|
||||
|
||||
function TPas2jsCompiler.ExpandFileName(const Filename: string): string;
|
||||
begin
|
||||
Result:=ExpandFileNameUTF8(Filename,FileCache.BaseDirectory);
|
||||
Result:=ExpandFileNamePJ(Filename,FileCache.BaseDirectory);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
@ -1425,7 +1425,7 @@ begin
|
||||
|
||||
if ExtractFilePath(aFilename)<>'' then
|
||||
begin
|
||||
Result:=ExpandFileNameUTF8(aFilename,BaseDirectory);
|
||||
Result:=ExpandFileNamePJ(aFilename,BaseDirectory);
|
||||
if not FileExistsLogged(Result) then
|
||||
Result:='';
|
||||
exit;
|
||||
@ -1993,7 +1993,7 @@ begin
|
||||
if ExtractFilename(Result)='' then
|
||||
if RaiseOnError then
|
||||
raise EFileNotFoundError.Create('invalid file name "'+Filename+'"');
|
||||
Result:=ExpandFileNameUTF8(Result,BaseDirectory);
|
||||
Result:=ExpandFileNamePJ(Result,BaseDirectory);
|
||||
if (ExtractFilename(Result)='') or not FilenameIsAbsolute(Result) then
|
||||
if RaiseOnError then
|
||||
raise EFileNotFoundError.Create('invalid file name "'+Filename+'"');
|
||||
@ -2128,9 +2128,9 @@ function TPas2jsFilesCache.ExpandDirectory(const Filename, BaseDir: string
|
||||
begin
|
||||
if Filename='' then exit('');
|
||||
if BaseDir<>'' then
|
||||
Result:=ExpandFileNameUTF8(Filename,BaseDir)
|
||||
Result:=ExpandFileNamePJ(Filename,BaseDir)
|
||||
else
|
||||
Result:=ExpandFileNameUTF8(Filename,BaseDirectory);
|
||||
Result:=ExpandFileNamePJ(Filename,BaseDirectory);
|
||||
if Result='' then exit;
|
||||
Result:=IncludeTrailingPathDelimiter(Result);
|
||||
end;
|
||||
|
||||
@ -28,6 +28,9 @@ uses
|
||||
{$IFDEF Unix}
|
||||
BaseUnix,
|
||||
{$ENDIF}
|
||||
{$IFDEF Pas2JS}
|
||||
NodeJSFS,
|
||||
{$ENDIF}
|
||||
SysUtils, Classes;
|
||||
|
||||
function FilenameIsAbsolute(const aFilename: string):boolean;
|
||||
@ -35,7 +38,7 @@ function FilenameIsWinAbsolute(const aFilename: string):boolean;
|
||||
function FilenameIsUnixAbsolute(const aFilename: string):boolean;
|
||||
function FileIsInPath(const Filename, Path: string): boolean;
|
||||
function ChompPathDelim(const Path: string): string;
|
||||
function ExpandFileNameUTF8(const FileName: string; {const} BaseDir: string = ''): string;
|
||||
function ExpandFileNamePJ(const FileName: string; {const} BaseDir: string = ''): string;
|
||||
function ExpandDirectory(const aDirectory: string): string;
|
||||
function TryCreateRelativePath(const Filename, BaseDirectory: String;
|
||||
UsePointDirectory: boolean; out RelPath: String): Boolean;
|
||||
@ -43,7 +46,7 @@ function ResolveDots(const AFilename: string): string;
|
||||
procedure ForcePathDelims(Var FileName: string);
|
||||
function GetForcedPathDelims(Const FileName: string): String;
|
||||
function ExtractFilenameOnly(const aFilename: string): string;
|
||||
function GetCurrentDirUTF8: String;
|
||||
function GetCurrentDirPJ: String;
|
||||
function CompareFilenames(const File1, File2: string): integer;
|
||||
|
||||
function GetPhysicalFilename(const Filename: string;
|
||||
@ -53,9 +56,9 @@ function ResolveSymLinks(const Filename: string;
|
||||
function MatchGlobbing(Mask, Name: string): boolean;
|
||||
function FileIsWritable(const AFilename: string): boolean;
|
||||
|
||||
function GetEnvironmentVariableCountUTF8: Integer;
|
||||
function GetEnvironmentStringUTF8(Index: Integer): string;
|
||||
function GetEnvironmentVariableUTF8(const EnvVar: string): String;
|
||||
function GetEnvironmentVariableCountPJ: Integer;
|
||||
function GetEnvironmentStringPJ(Index: Integer): string;
|
||||
function GetEnvironmentVariablePJ(const EnvVar: string): String;
|
||||
|
||||
function GetNextDelimitedItem(const List: string; Delimiter: char;
|
||||
var Position: integer): string;
|
||||
@ -64,6 +67,7 @@ type TChangeStamp = SizeInt;
|
||||
const InvalidChangeStamp = low(TChangeStamp);
|
||||
procedure IncreaseChangeStamp(var Stamp: TChangeStamp);
|
||||
|
||||
{$IFDEF FPC_HAS_CPSTRING}
|
||||
const
|
||||
UTF8BOM = #$EF#$BB#$BF;
|
||||
EncodingUTF8 = 'UTF-8';
|
||||
@ -92,6 +96,7 @@ function SystemCPToUTF8(const s: string): string;
|
||||
function ConsoleToUTF8(const s: string): string;
|
||||
// converts UTF8 string to console encoding (used by Write, WriteLn)
|
||||
function UTF8ToConsole(const s: string): string;
|
||||
{$ENDIF FPC_HAS_CPSTRING}
|
||||
|
||||
implementation
|
||||
|
||||
@ -99,6 +104,7 @@ implementation
|
||||
uses Windows;
|
||||
{$ENDIF}
|
||||
|
||||
{$IFDEF FPC_HAS_CPSTRING}
|
||||
var
|
||||
EncodingValid: boolean = false;
|
||||
DefaultTextEncoding: string = EncodingSystem;
|
||||
@ -108,11 +114,12 @@ var
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
NonUTF8System: boolean = false;
|
||||
{$ENDIF}
|
||||
|
||||
function FilenameIsWinAbsolute(const aFilename: string): boolean;
|
||||
begin
|
||||
Result:=((length(aFilename)>=3) and
|
||||
(aFilename[1] in ['A'..'Z','a'..'z']) and (aFilename[2]=':') and (aFilename[3]in AllowDirectorySeparators))
|
||||
(aFilename[1] in ['A'..'Z','a'..'z']) and (aFilename[2]=':') and (aFilename[3]in AllowDirectorySeparators))
|
||||
or ((length(aFilename)>=2) and (aFilename[1] in AllowDirectorySeparators) and (aFilename[2] in AllowDirectorySeparators));
|
||||
end;
|
||||
|
||||
@ -136,7 +143,7 @@ begin
|
||||
ExpPath:=IncludeTrailingPathDelimiter(Path);
|
||||
l:=length(ExpPath);
|
||||
Result:=(l>0) and (length(ExpFile)>l) and (ExpFile[l]=PathDelim)
|
||||
and (AnsiCompareFileName(ExpPath,LeftStr(ExpFile,l))=0);
|
||||
and (CompareFileNames(ExpPath,LeftStr(ExpFile,l))=0);
|
||||
end;
|
||||
|
||||
function ChompPathDelim(const Path: string): string;
|
||||
@ -174,7 +181,7 @@ function ExpandDirectory(const aDirectory: string): string;
|
||||
begin
|
||||
Result:=aDirectory;
|
||||
if Result='' then exit;
|
||||
Result:=ExpandFileNameUTF8(Result);
|
||||
Result:=ExpandFileNamePJ(Result);
|
||||
if Result='' then exit;
|
||||
Result:=IncludeTrailingPathDelimiter(Result);
|
||||
end;
|
||||
@ -207,329 +214,44 @@ function TryCreateRelativePath(const Filename, BaseDirectory: String;
|
||||
- Filename = foo/bar BaseDirectory = bar/foo Result = False (no shared base directory)
|
||||
- Filename = /foo BaseDirectory = bar Result = False (mixed absolute and relative)
|
||||
}
|
||||
|
||||
function IsNameChar(c: char): boolean; inline;
|
||||
begin
|
||||
Result:=(c<>#0) and not (c in AllowDirectorySeparators);
|
||||
end;
|
||||
|
||||
var
|
||||
UpDirCount: Integer;
|
||||
ResultPos: Integer;
|
||||
i: Integer;
|
||||
FileNameRestLen, SharedDirs: Integer;
|
||||
FileP, BaseP, FileEndP, BaseEndP: PChar;
|
||||
begin
|
||||
Result:=false;
|
||||
RelPath:=Filename;
|
||||
if (BaseDirectory='') or (Filename='') then exit;
|
||||
// check for different windows file drives
|
||||
if (CompareText(ExtractFileDrive(Filename),
|
||||
ExtractFileDrive(BaseDirectory))<>0)
|
||||
then
|
||||
exit;
|
||||
|
||||
FileP:=PChar(Filename);
|
||||
BaseP:=PChar(BaseDirectory);
|
||||
|
||||
//writeln('TryCreateRelativePath START File="',FileP,'" Base="',BaseP,'"');
|
||||
|
||||
// skip matching directories
|
||||
SharedDirs:=0;
|
||||
if FileP^ in AllowDirectorySeparators then
|
||||
begin
|
||||
if not (BaseP^ in AllowDirectorySeparators) then exit;
|
||||
repeat
|
||||
while FileP^ in AllowDirectorySeparators do inc(FileP);
|
||||
while BaseP^ in AllowDirectorySeparators do inc(BaseP);
|
||||
if (FileP^=#0) or (BaseP^=#0) then break;
|
||||
//writeln('TryCreateRelativePath check match .. File="',FileP,'" Base="',BaseP,'"');
|
||||
FileEndP:=FileP;
|
||||
BaseEndP:=BaseP;
|
||||
while IsNameChar(FileEndP^) do inc(FileEndP);
|
||||
while IsNameChar(BaseEndP^) do inc(BaseEndP);
|
||||
if CompareFilenames(copy(Filename,FileP-PChar(Filename)+1,FileEndP-FileP),
|
||||
copy(BaseDirectory,BaseP-PChar(BaseDirectory)+1,BaseEndP-BaseP))<>0
|
||||
then
|
||||
break;
|
||||
FileP:=FileEndP;
|
||||
BaseP:=BaseEndP;
|
||||
inc(SharedDirs);
|
||||
until false;
|
||||
end else if (BaseP^ in AllowDirectorySeparators) then
|
||||
exit;
|
||||
|
||||
//writeln('TryCreateRelativePath skipped matches File="',FileP,'" Base="',BaseP,'"');
|
||||
if SharedDirs=0 then exit;
|
||||
|
||||
// calculate needed '../'
|
||||
UpDirCount:=0;
|
||||
BaseEndP:=BaseP;
|
||||
while IsNameChar(BaseEndP^) do begin
|
||||
inc(UpDirCount);
|
||||
while IsNameChar(BaseEndP^) do inc(BaseEndP);
|
||||
while BaseEndP^ in AllowDirectorySeparators do inc(BaseEndP);
|
||||
end;
|
||||
|
||||
//writeln('TryCreateRelativePath UpDirCount=',UpDirCount,' File="',FileP,'" Base="',BaseP,'"');
|
||||
// create relative filename
|
||||
if (FileP^=#0) and (UpDirCount=0) then
|
||||
begin
|
||||
// Filename is the BaseDirectory
|
||||
if UsePointDirectory then
|
||||
RelPath:='.'
|
||||
else
|
||||
RelPath:='';
|
||||
exit(true);
|
||||
end;
|
||||
|
||||
FileNameRestLen:=length(Filename)-(FileP-PChar(Filename));
|
||||
SetLength(RelPath,3*UpDirCount+FileNameRestLen);
|
||||
ResultPos:=1;
|
||||
for i:=1 to UpDirCount do begin
|
||||
RelPath[ResultPos]:='.';
|
||||
RelPath[ResultPos+1]:='.';
|
||||
RelPath[ResultPos+2]:=PathDelim;
|
||||
inc(ResultPos,3);
|
||||
end;
|
||||
if FileNameRestLen>0 then
|
||||
Move(FileP^,RelPath[ResultPos],FileNameRestLen);
|
||||
Result:=true;
|
||||
writeln('TryCreateRelativePath ToDo: ',Filename,' Base=',BaseDirectory,' UsePointDirectory=',UsePointDirectory);
|
||||
end;
|
||||
|
||||
function ResolveDots(const AFilename: string): string;
|
||||
//trim double path delims and expand special dirs like .. and .
|
||||
//on Windows change also '/' to '\' except for filenames starting with '\\?\'
|
||||
|
||||
{$ifdef windows}
|
||||
function IsDriveDelim(const Path: string; p: integer): boolean; inline;
|
||||
begin
|
||||
Result:=(p=2) and (Path[2]=DriveDelim) and (Path[1] in ['a'..'z','A'..'Z']);
|
||||
end;
|
||||
{$endif}
|
||||
|
||||
function IsPathDelim(const Path: string; p: integer): boolean;
|
||||
begin
|
||||
if (p<=0) or (Path[p]=PathDelim) then exit(true);
|
||||
{$ifdef windows}
|
||||
if IsDriveDelim(Path,p) then
|
||||
exit(true);
|
||||
{$endif}
|
||||
Result:=false;
|
||||
end;
|
||||
|
||||
var SrcPos, DestPos, Len, DirStart: integer;
|
||||
c: char;
|
||||
MacroPos: LongInt;
|
||||
var
|
||||
Len: Integer;
|
||||
begin
|
||||
Len:=length(AFilename);
|
||||
if Len=0 then exit('');
|
||||
|
||||
Result:=AFilename;
|
||||
|
||||
{$ifdef windows}
|
||||
//Special case: everything is literal after this, even dots (this does not apply to '//?/')
|
||||
if (length(AFilename)>=4) and (AFilename[1]='\') and (AFilename[2]='\')
|
||||
and (AFilename[3]='?') and (AFilename[4]='\') then
|
||||
exit;
|
||||
{$endif}
|
||||
|
||||
SrcPos:=1;
|
||||
DestPos:=1;
|
||||
|
||||
// trim double path delimiters and special dirs . and ..
|
||||
while (SrcPos<=Len) do begin
|
||||
c:=AFilename[SrcPos];
|
||||
{$ifdef windows}
|
||||
//change / to \. The WinApi accepts both, but it leads to strange effects in other places
|
||||
if (c in AllowDirectorySeparators) then c := PathDelim;
|
||||
{$endif}
|
||||
// check for duplicate path delims
|
||||
if (c=PathDelim) then
|
||||
begin
|
||||
inc(SrcPos);
|
||||
{$IFDEF Windows}
|
||||
if (DestPos>2)
|
||||
{$ELSE}
|
||||
if (DestPos>1)
|
||||
{$ENDIF}
|
||||
and (Result[DestPos-1]=PathDelim) then
|
||||
begin
|
||||
// skip duplicate PathDelim
|
||||
continue;
|
||||
end;
|
||||
Result[DestPos]:=c;
|
||||
inc(DestPos);
|
||||
continue;
|
||||
end;
|
||||
// check for special dirs . and ..
|
||||
if (c='.') then
|
||||
begin
|
||||
if (SrcPos<Len) then
|
||||
begin
|
||||
if (AFilename[SrcPos+1] in AllowDirectorySeparators)
|
||||
and IsPathDelim(Result,DestPos-1) then
|
||||
begin
|
||||
// special dir ./ or */./
|
||||
// -> skip
|
||||
inc(SrcPos,2);
|
||||
while (SrcPos<=Len) and (AFilename[SrcPos] in AllowDirectorySeparators) do
|
||||
inc(SrcPos);
|
||||
continue;
|
||||
end else if (AFilename[SrcPos+1]='.')
|
||||
and ((SrcPos+1=Len) or (AFilename[SrcPos+2] in AllowDirectorySeparators)) then
|
||||
begin
|
||||
// special dir ..
|
||||
// 1. .. -> copy
|
||||
// 2. /.. -> skip .., keep /
|
||||
// 3. C:.. -> copy
|
||||
// 4. C:\.. -> skip .., keep C:\
|
||||
// 5. \\.. -> skip .., keep \\
|
||||
// 6. ../.. -> copy because if the first '..' was not resolved, the next can't neither
|
||||
// 7. dir/.. -> trim dir and ..
|
||||
// 8. dir$macro/.. -> copy
|
||||
if DestPos=1 then
|
||||
begin
|
||||
// 1. .. or ../ -> copy
|
||||
end else if (DestPos=2) and (Result[1]=PathDelim) then
|
||||
begin
|
||||
// 2. /.. -> skip .., keep /
|
||||
inc(SrcPos,2);
|
||||
continue;
|
||||
{$IFDEF Windows}
|
||||
end else if (DestPos=3) and IsDriveDelim(Result,2) then
|
||||
begin
|
||||
// 3. C:.. -> copy
|
||||
end else if (DestPos=4) and (Result[3]=PathDelim)
|
||||
and IsDriveDelim(Result,2) then
|
||||
begin
|
||||
// 4. C:\.. -> skip .., keep C:\
|
||||
inc(SrcPos,2);
|
||||
continue;
|
||||
end else if (DestPos=3) and (Result[1]=PathDelim)
|
||||
and (Result[2]=PathDelim) then
|
||||
begin
|
||||
// 5. \\.. -> skip .., keep \\
|
||||
inc(SrcPos,2);
|
||||
continue;
|
||||
{$ENDIF}
|
||||
end else if (DestPos>1) and (Result[DestPos-1]=PathDelim) then
|
||||
begin
|
||||
// */.
|
||||
if (DestPos>3)
|
||||
and (Result[DestPos-2]='.') and (Result[DestPos-3]='.')
|
||||
and IsPathDelim(Result,DestPos-4) then
|
||||
begin
|
||||
// 6. ../.. -> copy because if the first '..' was not resolved, the next can't neither
|
||||
end else begin
|
||||
// 7. xxxdir/.. -> trim dir and skip ..
|
||||
DirStart:=DestPos-2;
|
||||
while (DirStart>1) and (Result[DirStart-1]<>PathDelim) do
|
||||
dec(DirStart);
|
||||
{$ifdef windows}
|
||||
if (DirStart=1) and IsDriveDelim(Result,2) then
|
||||
inc(DirStart,2);
|
||||
{$endif}
|
||||
MacroPos:=DirStart;
|
||||
while MacroPos<DestPos do begin
|
||||
if (Result[MacroPos]='$')
|
||||
and (Result[MacroPos+1] in ['(','a'..'z','A'..'Z']) then
|
||||
begin
|
||||
// 8. directory contains a macro -> keep
|
||||
break;
|
||||
end;
|
||||
inc(MacroPos);
|
||||
end;
|
||||
if MacroPos=DestPos then
|
||||
begin
|
||||
// previous directory does not contain a macro -> remove dir/..
|
||||
DestPos:=DirStart;
|
||||
inc(SrcPos,2);
|
||||
//writeln('ResolveDots ',DestPos,' SrcPos=',SrcPos,' File="',AFilename,'" Result="',copy(Result,1,DestPos-1),'"');
|
||||
if SrcPos>Len then
|
||||
begin
|
||||
// '..' at end of filename
|
||||
if (DestPos>1) and (Result[DestPos-1]=PathDelim) then
|
||||
begin
|
||||
// foo/dir/.. -> foo
|
||||
dec(DestPos);
|
||||
end else if (DestPos=1) then
|
||||
begin
|
||||
// foo/.. -> .
|
||||
Result[1]:='.';
|
||||
DestPos:=2;
|
||||
end;
|
||||
end else if DestPos=1 then
|
||||
begin
|
||||
// e.g. 'foo/../'
|
||||
while (SrcPos<=Len) and (AFilename[SrcPos] in AllowDirectorySeparators) do
|
||||
inc(SrcPos);
|
||||
end;
|
||||
continue;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end else begin
|
||||
// special dir . at end of filename
|
||||
if DestPos=1 then
|
||||
begin
|
||||
Result:='.';
|
||||
exit;
|
||||
end;
|
||||
if (DestPos>2) and (Result[DestPos-1]=PathDelim)
|
||||
{$ifdef windows}
|
||||
and not IsDriveDelim(Result,DestPos-2)
|
||||
{$endif}
|
||||
then begin
|
||||
// foo/. -> foo
|
||||
// C:foo\. -> C:foo
|
||||
// C:\. -> C:\
|
||||
dec(DestPos);
|
||||
end;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
// copy directory
|
||||
repeat
|
||||
Result[DestPos]:=c;
|
||||
inc(DestPos);
|
||||
inc(SrcPos);
|
||||
if (SrcPos>Len) then break;
|
||||
c:=AFilename[SrcPos];
|
||||
{$ifdef windows}
|
||||
//change / to \. The WinApi accepts both, but it leads to strange effects in other places
|
||||
if (c in AllowDirectorySeparators) then c := PathDelim;
|
||||
{$endif}
|
||||
if c=PathDelim then break;
|
||||
until false;
|
||||
end;
|
||||
// trim result
|
||||
if DestPos<=length(AFilename) then
|
||||
if (DestPos=1) then
|
||||
Result:='.'
|
||||
else
|
||||
SetLength(Result,DestPos-1);
|
||||
writeln('ResolveDots ToDo ',AFilename);
|
||||
end;
|
||||
|
||||
procedure ForcePathDelims(Var FileName: string);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
for i:=1 to length(FileName) do
|
||||
{$IFDEF Windows}
|
||||
if Filename[i]='/' then
|
||||
Filename[i]:='\';
|
||||
{$ELSE}
|
||||
if Filename[i]='\' then
|
||||
Filename[i]:='/';
|
||||
{$ENDIF}
|
||||
Filename:=GetForcedPathDelims(Filename);
|
||||
end;
|
||||
|
||||
function GetForcedPathDelims(const FileName: string): String;
|
||||
var
|
||||
i: Integer;
|
||||
c: Char;
|
||||
begin
|
||||
Result:=FileName;
|
||||
ForcePathDelims(Result);
|
||||
Result:=Filename;
|
||||
if PathDelim='/' then
|
||||
c:='\'
|
||||
else
|
||||
c:='/';
|
||||
for i:=1 to length(Result) do
|
||||
if Result[i]=c then
|
||||
Result[i]:=PathDelim;
|
||||
end;
|
||||
|
||||
function ExtractFilenameOnly(const aFilename: string): string;
|
||||
@ -552,73 +274,16 @@ end;
|
||||
|
||||
function CompareFilenames(const File1, File2: string): integer;
|
||||
begin
|
||||
Result:=AnsiCompareFileName(File1,File2);
|
||||
writeln('CompareFilenames ToDo ',File1,' ',File2);
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function MatchGlobbing(Mask, Name: string): boolean;
|
||||
// match * and ?
|
||||
|
||||
function IsNameEnd(NameP: PChar): boolean; inline;
|
||||
begin
|
||||
Result:=(NameP^=#0) and (NameP-PChar(Name)=length(Name));
|
||||
end;
|
||||
|
||||
function Check(MaskP, NameP: PChar): boolean;
|
||||
var
|
||||
c: Integer;
|
||||
begin
|
||||
repeat
|
||||
case MaskP^ of
|
||||
#0:
|
||||
exit(IsNameEnd(NameP));
|
||||
'?':
|
||||
if not IsNameEnd(NameP) then
|
||||
begin
|
||||
inc(MaskP);
|
||||
c:=UTF8CharacterStrictLength(NameP);
|
||||
if c<1 then c:=1;
|
||||
inc(NameP,c);
|
||||
end else
|
||||
exit(false);
|
||||
'*':
|
||||
begin
|
||||
repeat
|
||||
inc(MaskP);
|
||||
until MaskP^<>'*';
|
||||
if MaskP=#0 then exit(true);
|
||||
while not IsNameEnd(NameP) do begin
|
||||
inc(NameP);
|
||||
if Check(MaskP,NameP) then exit(true);
|
||||
end;
|
||||
exit(false);
|
||||
end;
|
||||
else
|
||||
if NameP^<>MaskP^ then exit(false);
|
||||
c:=UTF8CharacterStrictLength(MaskP);
|
||||
if c<1 then c:=1;
|
||||
inc(MaskP);
|
||||
c:=UTF8CharacterStrictLength(NameP);
|
||||
if c<1 then c:=1;
|
||||
inc(NameP,c);
|
||||
end;
|
||||
until false;
|
||||
end;
|
||||
|
||||
var
|
||||
MaskP: PChar;
|
||||
begin
|
||||
if Mask='' then exit(Name='');
|
||||
{$IFDEF CaseInsensitiveFilenames}
|
||||
Mask:=AnsiLowerCase(Mask);
|
||||
Name:=AnsiLowerCase(Name);
|
||||
{$ENDIF}
|
||||
MaskP:=PChar(Mask);
|
||||
while (MaskP^='*') and (MaskP[1]='*') do inc(MaskP);
|
||||
if (MaskP^='*') and (MaskP[1]=#0) then
|
||||
exit(true); // the * mask fits all, even the empty string
|
||||
if Name='' then
|
||||
exit(false);
|
||||
Result:=Check(MaskP,PChar(Name));
|
||||
writeln('MatchGlobbing ToDo ',Mask,' Name=',Name);
|
||||
Result:=false;
|
||||
end;
|
||||
|
||||
function GetNextDelimitedItem(const List: string; Delimiter: char;
|
||||
@ -641,6 +306,7 @@ begin
|
||||
Stamp:=InvalidChangeStamp+1;
|
||||
end;
|
||||
|
||||
{$IFDEF FPC_HAS_CPSTRING}
|
||||
function IsNonUTF8System: boolean;
|
||||
begin
|
||||
Result:=NonUTF8System;
|
||||
@ -756,6 +422,7 @@ begin
|
||||
// conversion magic
|
||||
SetCodePage(RawByteString(Result), CP_ACP, False);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
{$IFDEF Unix}
|
||||
{$I pas2jsfileutilsunix.inc}
|
||||
@ -763,9 +430,13 @@ end;
|
||||
{$IFDEF Windows}
|
||||
{$I pas2jsfileutilswin.inc}
|
||||
{$ENDIF}
|
||||
{$IFDEF NodeJS}
|
||||
{$I pas2jsfileutilsnodejs.inc}
|
||||
{$ENDIF}
|
||||
|
||||
procedure InternalInit;
|
||||
begin
|
||||
{$IFDEF FPC_HAS_CPSTRING}
|
||||
SetMultiByteConversionCodePage(CP_UTF8);
|
||||
// SetMultiByteFileSystemCodePage(CP_UTF8); not needed, this is the default under Windows
|
||||
SetMultiByteRTLFileSystemCodePage(CP_UTF8);
|
||||
@ -776,12 +447,16 @@ begin
|
||||
{$ELSE}
|
||||
NonUTF8System:=SysUtils.CompareText(DefaultTextEncoding,'UTF8')<>0;
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
|
||||
InitPlatform;
|
||||
end;
|
||||
|
||||
initialization
|
||||
InternalInit;
|
||||
{$IFDEF FPC}
|
||||
finalization
|
||||
FinalizePlatform;
|
||||
{$ENDIF}
|
||||
end.
|
||||
|
||||
|
||||
130
packages/pastojs/src/pas2jsfileutilsnodejs.inc
Normal file
130
packages/pastojs/src/pas2jsfileutilsnodejs.inc
Normal file
@ -0,0 +1,130 @@
|
||||
{%MainUnit pas2jsfileutils.pas}
|
||||
{
|
||||
This file is part of the Free Component Library (FCL)
|
||||
Copyright (c) 2018 Mattias Gaertner mattias@freepascal.org
|
||||
|
||||
NodeJS backend of pas2jsfileutils
|
||||
|
||||
See the file COPYING.FPC, included in this distribution,
|
||||
for details about the copyright.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
**********************************************************************
|
||||
}
|
||||
|
||||
function FilenameIsAbsolute(const aFilename: string): boolean;
|
||||
begin
|
||||
writeln('FilenameIsAbsolute ToDo ',aFilename);
|
||||
Result:=FilenameIsUnixAbsolute(aFilename);
|
||||
end;
|
||||
|
||||
function ExpandFileNamePJ(const FileName: string; BaseDir: string): string;
|
||||
var
|
||||
IsAbs: Boolean;
|
||||
HomeDir, Fn: String;
|
||||
begin
|
||||
Fn := FileName;
|
||||
ForcePathDelims(Fn);
|
||||
IsAbs := FileNameIsUnixAbsolute(Fn);
|
||||
if (not IsAbs) then
|
||||
begin
|
||||
if ((Length(Fn) > 1) and (Fn[1] = '~') and (Fn[2] = '/')) or (Fn = '~') then
|
||||
begin
|
||||
HomeDir := GetEnvironmentVariablePJ('HOME');
|
||||
if not FileNameIsUnixAbsolute(HomeDir) then
|
||||
HomeDir := ExpandFileNamePJ(HomeDir,'');
|
||||
Fn := HomeDir + Copy(Fn,2,length(Fn));
|
||||
IsAbs := True;
|
||||
end;
|
||||
end;
|
||||
if IsAbs then
|
||||
begin
|
||||
Result := ResolveDots(Fn);
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (BaseDir = '') then
|
||||
Fn := IncludeTrailingPathDelimiter(GetCurrentDirPJ) + Fn
|
||||
else
|
||||
Fn := IncludeTrailingPathDelimiter(BaseDir) + Fn;
|
||||
Fn := ResolveDots(Fn);
|
||||
//if BaseDir is not absolute then this needs to be expanded as well
|
||||
if not FileNameIsUnixAbsolute(Fn) then
|
||||
Fn := ExpandFileNamePJ(Fn, '');
|
||||
Result := Fn;
|
||||
end;
|
||||
end;
|
||||
|
||||
function GetCurrentDirPJ: String;
|
||||
begin
|
||||
writeln('GetCurrentDirPJ ToDo');
|
||||
Result:='';
|
||||
end;
|
||||
|
||||
function GetPhysicalFilename(const Filename: string; ExceptionOnError: boolean
|
||||
): string;
|
||||
var
|
||||
OldPath, NewPath: String;
|
||||
p, l: integer;
|
||||
begin
|
||||
Result:=Filename;
|
||||
p:=1;
|
||||
l:=length(Result);
|
||||
while p<=l do
|
||||
begin
|
||||
while (p<=l) and (Result[p]='/') do
|
||||
inc(p);
|
||||
if p>l then exit;
|
||||
if Result[p]<>'/' then
|
||||
begin
|
||||
repeat
|
||||
inc(p);
|
||||
until (p>l) or (Result[p]='/');
|
||||
OldPath:=LeftStr(Result,p-1);
|
||||
NewPath:=ResolveSymLinks(OldPath,ExceptionOnError);
|
||||
if NewPath='' then exit('');
|
||||
if OldPath<>NewPath then
|
||||
begin
|
||||
Result:=NewPath+copy(Result,length(OldPath)+1,length(Result));
|
||||
p:=length(NewPath)+1;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ResolveSymLinks(const Filename: string; ExceptionOnError: boolean
|
||||
): string;
|
||||
begin
|
||||
writeln('ResolveSymLinks ToDo ',Filename,' ',ExceptionOnError);
|
||||
Result:=Filename;
|
||||
end;
|
||||
|
||||
function FileIsWritable(const AFilename: string): boolean;
|
||||
begin
|
||||
writeln('FileIsWritable ToDo ',AFilename);
|
||||
Result := false;
|
||||
end;
|
||||
|
||||
function GetEnvironmentVariableCountPJ: Integer;
|
||||
begin
|
||||
Result:=GetEnvironmentVariableCount;
|
||||
end;
|
||||
|
||||
function GetEnvironmentStringPJ(Index: Integer): string;
|
||||
begin
|
||||
Result:=GetEnvironmentString(Index);
|
||||
end;
|
||||
|
||||
function GetEnvironmentVariablePJ(const EnvVar: string): String;
|
||||
begin
|
||||
Result:=GetEnvironmentVariable(EnvVar);
|
||||
end;
|
||||
|
||||
procedure InitPlatform;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
This file is part of the Free Component Library (FCL)
|
||||
Copyright (c) 2018 Mattias Gaertner mattias@freepascal.org
|
||||
|
||||
Pascal to Javascript converter class.
|
||||
Unix backend of pas2jsfileutils
|
||||
|
||||
See the file COPYING.FPC, included in this distribution,
|
||||
for details about the copyright.
|
||||
@ -20,7 +20,7 @@ begin
|
||||
Result:=FilenameIsUnixAbsolute(aFilename);
|
||||
end;
|
||||
|
||||
function ExpandFileNameUTF8(const FileName: string; BaseDir: string): string;
|
||||
function ExpandFileNamePJ(const FileName: string; BaseDir: string): string;
|
||||
var
|
||||
IsAbs: Boolean;
|
||||
HomeDir, Fn: String;
|
||||
@ -32,9 +32,9 @@ begin
|
||||
begin
|
||||
if ((Length(Fn) > 1) and (Fn[1] = '~') and (Fn[2] = '/')) or (Fn = '~') then
|
||||
begin
|
||||
HomeDir := GetEnvironmentVariableUTF8('HOME');
|
||||
HomeDir := GetEnvironmentVariablePJ('HOME');
|
||||
if not FileNameIsUnixAbsolute(HomeDir) then
|
||||
HomeDir := ExpandFileNameUtf8(HomeDir,'');
|
||||
HomeDir := ExpandFileNamePJ(HomeDir,'');
|
||||
Fn := HomeDir + Copy(Fn,2,length(Fn));
|
||||
IsAbs := True;
|
||||
end;
|
||||
@ -46,18 +46,18 @@ begin
|
||||
else
|
||||
begin
|
||||
if (BaseDir = '') then
|
||||
Fn := IncludeTrailingPathDelimiter(GetCurrentDirUtf8) + Fn
|
||||
Fn := IncludeTrailingPathDelimiter(GetCurrentDirPJ) + Fn
|
||||
else
|
||||
Fn := IncludeTrailingPathDelimiter(BaseDir) + Fn;
|
||||
Fn := ResolveDots(Fn);
|
||||
//if BaseDir is not absolute then this needs to be expanded as well
|
||||
if not FileNameIsUnixAbsolute(Fn) then
|
||||
Fn := ExpandFileNameUtf8(Fn, '');
|
||||
Fn := ExpandFileNamePJ(Fn, '');
|
||||
Result := Fn;
|
||||
end;
|
||||
end;
|
||||
|
||||
function GetCurrentDirUTF8: String;
|
||||
function GetCurrentDirPJ: String;
|
||||
begin
|
||||
Result:=GetCurrentDir;
|
||||
end;
|
||||
@ -148,17 +148,17 @@ begin
|
||||
Result := BaseUnix.FpAccess(AFilename, BaseUnix.W_OK) = 0;
|
||||
end;
|
||||
|
||||
function GetEnvironmentVariableCountUTF8: Integer;
|
||||
function GetEnvironmentVariableCountPJ: Integer;
|
||||
begin
|
||||
Result:=GetEnvironmentVariableCount;
|
||||
end;
|
||||
|
||||
function GetEnvironmentStringUTF8(Index: Integer): string;
|
||||
function GetEnvironmentStringPJ(Index: Integer): string;
|
||||
begin
|
||||
Result:=ConsoleToUTF8(GetEnvironmentString(Index));
|
||||
end;
|
||||
|
||||
function GetEnvironmentVariableUTF8(const EnvVar: string): String;
|
||||
function GetEnvironmentVariablePJ(const EnvVar: string): String;
|
||||
begin
|
||||
Result:=ConsoleToUTF8(GetEnvironmentVariable(EnvVar));
|
||||
end;
|
||||
@ -225,3 +225,4 @@ procedure FinalizePlatform;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
|
||||
@ -268,7 +268,7 @@ begin
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
function ExpandFileNameUtf8(const FileName: string; {const} BaseDir: String = ''): String;
|
||||
function ExpandFileNamePJ(const FileName: string; {const} BaseDir: String = ''): String;
|
||||
var
|
||||
IsAbs, StartsWithRoot, CanUseBaseDir : Boolean;
|
||||
{$ifndef WinCE}
|
||||
@ -305,11 +305,11 @@ begin
|
||||
begin
|
||||
FnDrive := UpCase(Fn[1]);
|
||||
GetDirUtf8(Byte(FnDrive)-64, CurDir{%H-});
|
||||
CurDrive := UpCase(GetCurrentDirUtf8[1]);
|
||||
CurDrive := UpCase(GetCurrentDirPJ[1]);
|
||||
end
|
||||
else
|
||||
begin
|
||||
CurDir := GetCurrentDirUtf8;
|
||||
CurDir := GetCurrentDirPJ;
|
||||
FnDrive := UpCase(CurDir[1]);
|
||||
CurDrive := FnDrive;
|
||||
end;
|
||||
@ -377,7 +377,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function GetCurrentDirUtf8: String;
|
||||
function GetCurrentDirPJ: String;
|
||||
{$ifndef WinCE}
|
||||
var
|
||||
w : UnicodeString;
|
||||
@ -421,7 +421,7 @@ begin
|
||||
Result:=((FileGetAttrUTF8(AFilename) and faReadOnly) = 0);
|
||||
end;
|
||||
|
||||
function GetEnvironmentVariableCountUTF8: Integer;
|
||||
function GetEnvironmentVariableCountPJ: Integer;
|
||||
var
|
||||
hp,p : PWideChar;
|
||||
begin
|
||||
@ -437,7 +437,7 @@ begin
|
||||
FreeEnvironmentStringsW(p);
|
||||
end;
|
||||
|
||||
function GetEnvironmentStringUTF8(Index: Integer): string;
|
||||
function GetEnvironmentStringPJ(Index: Integer): string;
|
||||
var
|
||||
hp,p : PWideChar;
|
||||
begin
|
||||
@ -455,7 +455,7 @@ begin
|
||||
FreeEnvironmentStringsW(p);
|
||||
end;
|
||||
|
||||
function GetEnvironmentVariableUTF8(const EnvVar: string): String;
|
||||
function GetEnvironmentVariablePJ(const EnvVar: string): String;
|
||||
begin
|
||||
Result:=UTF16ToUTF8(SysUtils.GetEnvironmentVariable(UTF8ToUTF16(EnvVar)));
|
||||
end;
|
||||
|
||||
@ -23,9 +23,14 @@ unit Pas2jsLogger;
|
||||
{$mode objfpc}{$H+}
|
||||
{$inline on}
|
||||
|
||||
{$i pas2js_defines.inc}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
{$IFDEF Pas2JS}
|
||||
JS, NodeJSFS,
|
||||
{$ENDIF}
|
||||
Classes, SysUtils, PasTree, PScanner, jstree, jsbase, jswriter, fpjson,
|
||||
Pas2jsFileUtils;
|
||||
|
||||
@ -42,6 +47,41 @@ const
|
||||
const
|
||||
DefaultLogMsgTypes = [mtFatal..mtDebug]; // by default show everything
|
||||
|
||||
type
|
||||
{$IFDEF Pas2JS}
|
||||
|
||||
{ TPas2jsStream }
|
||||
|
||||
TPas2jsStream = class
|
||||
public
|
||||
procedure Write(const s: string); virtual; abstract;
|
||||
end;
|
||||
|
||||
{ TPas2jsFileStream }
|
||||
|
||||
TPas2jsFileStream = class(TPas2JSStream)
|
||||
public
|
||||
constructor Create(Filename: string; Mode: cardinal);
|
||||
destructor Destroy; override;
|
||||
procedure Write(const s: string); override;
|
||||
end;
|
||||
const
|
||||
fmCreate = $FF00;
|
||||
fmOpenRead = 0;
|
||||
//fmOpenWrite = 1;
|
||||
//fmOpenReadWrite = 2;
|
||||
{ Share modes}
|
||||
//fmShareCompat = $0000;
|
||||
//fmShareExclusive = $0010;
|
||||
//fmShareDenyWrite = $0020;
|
||||
//fmShareDenyRead = $0030;
|
||||
fmShareDenyNone = $0040;
|
||||
|
||||
{$ELSE}
|
||||
TPas2jsStream = TStream;
|
||||
TPas2jsFileStream = TFileStream;
|
||||
{$ENDIF}
|
||||
|
||||
type
|
||||
|
||||
{ TPas2jsMessage }
|
||||
@ -59,7 +99,7 @@ type
|
||||
|
||||
TPas2jsLogger = class
|
||||
private
|
||||
FDebugLog: TStream;
|
||||
FDebugLog: TPas2JSStream;
|
||||
FEncoding: string;
|
||||
FLastMsgCol: integer;
|
||||
FLastMsgFile: string;
|
||||
@ -67,8 +107,7 @@ type
|
||||
FLastMsgNumber: integer;
|
||||
FLastMsgTxt: string;
|
||||
FLastMsgType: TMessageType;
|
||||
FMsgNumberDisabled: PInteger;// sorted ascending
|
||||
FMsgNumberDisabledCount: integer;
|
||||
FMsgNumberDisabled: array of Integer;// sorted ascending
|
||||
FMsg: TFPList; // list of TPas2jsMessage
|
||||
FOnFormatPath: TPScannerFormatPathEvent;
|
||||
FOnLog: TPas2jsLogEvent;
|
||||
@ -77,7 +116,9 @@ type
|
||||
FShowMsgNumbers: boolean;
|
||||
FShowMsgTypes: TMessageTypes;
|
||||
FSorted: boolean;
|
||||
{$IFDEF HasStdErr}
|
||||
FWriteMsgToStdErr: boolean;
|
||||
{$ENDIF}
|
||||
function GetMsgCount: integer;
|
||||
function GetMsgNumberDisabled(MsgNumber: integer): boolean;
|
||||
function GetMsgs(Index: integer): TPas2jsMessage; inline;
|
||||
@ -87,7 +128,7 @@ type
|
||||
procedure SetOutputFilename(AValue: string);
|
||||
procedure SetSorted(AValue: boolean);
|
||||
procedure DoLogRaw(const Msg: string; SkipEncoding : Boolean);
|
||||
function Concatenate(Args: array of const): string;
|
||||
function Concatenate(Args: array of {$IFDEF Pas2JS}jsvalue{$ELSE}const{$ENDIF}): string;
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
@ -95,20 +136,25 @@ type
|
||||
function FindMsg(MsgNumber: integer; ExceptionOnNotFound: boolean): TPas2jsMessage;
|
||||
procedure Sort;
|
||||
procedure LogRaw(const Msg: string); overload;
|
||||
procedure LogRaw(Args: array of const); overload;
|
||||
procedure LogRaw(Args: array of {$IFDEF Pas2JS}jsvalue{$ELSE}const{$ENDIF}); overload;
|
||||
procedure LogLn;
|
||||
procedure LogPlain(const Msg: string); overload;
|
||||
procedure LogPlain(Args: array of const); overload;
|
||||
procedure LogMsg(MsgNumber: integer; Args: array of const;
|
||||
procedure LogPlain(Args: array of {$IFDEF Pas2JS}jsvalue{$ELSE}const{$ENDIF}); overload;
|
||||
procedure LogMsg(MsgNumber: integer;
|
||||
Args: array of {$IFDEF Pas2JS}jsvalue{$ELSE}const{$ENDIF};
|
||||
const Filename: string = ''; Line: integer = 0; Col: integer = 0;
|
||||
UseFilter: boolean = true);
|
||||
procedure Log(MsgType: TMessageType; Msg: string; MsgNumber: integer = 0;
|
||||
const Filename: string = ''; Line: integer = 0; Col: integer = 0;
|
||||
UseFilter: boolean = true);
|
||||
procedure LogMsgIgnoreFilter(MsgNumber: integer; Args: array of const);
|
||||
procedure LogMsgIgnoreFilter(MsgNumber: integer;
|
||||
Args: array of {$IFDEF Pas2JS}jsvalue{$ELSE}const{$ENDIF});
|
||||
{$IFDEF FPC}
|
||||
procedure LogExceptionBackTrace;
|
||||
{$ENDIF}
|
||||
function MsgTypeToStr(MsgType: TMessageType): string;
|
||||
function GetMsgText(MsgNumber: integer; Args: array of const): string;
|
||||
function GetMsgText(MsgNumber: integer;
|
||||
Args: array of {$IFDEF Pas2JS}jsvalue{$ELSE}const{$ENDIF}): string;
|
||||
function FormatMsg(MsgType: TMessageType; Msg: string; MsgNumber: integer = 0;
|
||||
const Filename: string = ''; Line: integer = 0; Col: integer = 0): string;
|
||||
function FormatJSONMsg(MsgType: TMessageType; Msg: string; MsgNumber: integer = 0;
|
||||
@ -131,7 +177,9 @@ type
|
||||
property OutputFilename: string read FOutputFilename write SetOutputFilename;
|
||||
property ShowMsgNumbers: boolean read FShowMsgNumbers write FShowMsgNumbers;
|
||||
property ShowMsgTypes: TMessageTypes read FShowMsgTypes write FShowMsgTypes;
|
||||
{$IFDEF HasStdErr}
|
||||
property WriteMsgToStdErr: boolean read FWriteMsgToStdErr write FWriteMsgToStdErr;
|
||||
{$ENDIF}
|
||||
property Sorted: boolean read FSorted write SetSorted;
|
||||
property OnLog: TPas2jsLogEvent read FOnLog write FOnLog;
|
||||
property LastMsgType: TMessageType read FLastMsgType write FLastMsgType;
|
||||
@ -140,13 +188,13 @@ type
|
||||
property LastMsgCol: integer read FLastMsgCol write FLastMsgCol;
|
||||
property LastMsgTxt: string read FLastMsgTxt write FLastMsgTxt;
|
||||
property LastMsgNumber: integer read FLastMsgNumber write FLastMsgNumber;
|
||||
property DebugLog: TStream read FDebugLog write FDebugLog;
|
||||
property DebugLog: TPas2jsStream read FDebugLog write FDebugLog;
|
||||
end;
|
||||
|
||||
function CompareP2JMessage(Item1, Item2: Pointer): Integer;
|
||||
function CompareP2JMessage(Item1, Item2: {$IFDEF Pas2JS}JSValue{$ELSE}Pointer{$ENDIF}): Integer;
|
||||
|
||||
function QuoteStr(const s: string): string;
|
||||
function DeQuoteStr(const s: string): string;
|
||||
function QuoteStr(const s: string; Quote: char = '"'): string;
|
||||
function DeQuoteStr(const s: string; Quote: char = '"'): string;
|
||||
function AsString(Element: TPasElement; Full: boolean = true): string; overload;
|
||||
function AsString(Element: TJSElement): string; overload;
|
||||
function DbgString(Element: TJSElement; Indent: integer): string; overload;
|
||||
@ -154,12 +202,14 @@ function DbgAsString(Element: TJSValue; Indent: integer): string; overload;
|
||||
function DbgAsString(Element: TJSArrayLiteralElements; Indent: integer): string; overload;
|
||||
function DbgAsString(Element: TJSObjectLiteralElements; Indent: integer): string; overload;
|
||||
function DbgAsString(Element: TJSObjectLiteralElement; Indent: integer): string; overload;
|
||||
{$IFDEF UsePChar}
|
||||
function DbgHexMem(p: Pointer; Count: integer): string;
|
||||
{$ENDIF}
|
||||
function DbgStr(const s: string): string;
|
||||
|
||||
implementation
|
||||
|
||||
function CompareP2JMessage(Item1, Item2: Pointer): Integer;
|
||||
function CompareP2JMessage(Item1, Item2: {$IFDEF Pas2JS}JSValue{$ELSE}Pointer{$ENDIF}): Integer;
|
||||
var
|
||||
Msg1: TPas2jsMessage absolute Item1;
|
||||
Msg2: TPas2jsMessage absolute Item2;
|
||||
@ -167,14 +217,14 @@ begin
|
||||
Result:=Msg1.Number-Msg2.Number;
|
||||
end;
|
||||
|
||||
function QuoteStr(const s: string): string;
|
||||
function QuoteStr(const s: string; Quote: char): string;
|
||||
begin
|
||||
Result:=AnsiQuotedStr(S,'"');
|
||||
Result:={$IFDEF Pas2JS}SysUtils.QuotedStr{$ELSE}AnsiQuotedStr{$ENDIF}(S,Quote);
|
||||
end;
|
||||
|
||||
function DeQuoteStr(const s: string): string;
|
||||
function DeQuoteStr(const s: string; Quote: char): string;
|
||||
begin
|
||||
Result:=AnsiDequotedStr(S,'"');
|
||||
Result:={$IFDEF Pas2JS}SysUtils.DeQuoteString{$ELSE}AnsiDequotedStr{$ENDIF}(S,Quote);
|
||||
end;
|
||||
|
||||
function AsString(Element: TPasElement; Full: boolean): string;
|
||||
@ -252,16 +302,16 @@ begin
|
||||
if Element is TJSStatementList then
|
||||
begin
|
||||
Result:=DbgString(TJSBinaryExpression(Element).A,Indent+2)+';'+LineEnding
|
||||
+Space(Indent)+DbgString(TJSBinaryExpression(Element).B,Indent);
|
||||
+StringOfChar(' ',Indent)+DbgString(TJSBinaryExpression(Element).B,Indent);
|
||||
end else if Element is TJSVariableDeclarationList then
|
||||
begin
|
||||
Result:=DbgString(TJSBinaryExpression(Element).A,Indent+2)+';'+LineEnding
|
||||
+Space(Indent)+DbgString(TJSBinaryExpression(Element).B,Indent);
|
||||
+StringOfChar(' ',Indent)+DbgString(TJSBinaryExpression(Element).B,Indent);
|
||||
end else if Element is TJSWithStatement then
|
||||
begin
|
||||
Result:='with ('+DbgString(TJSBinaryExpression(Element).A,Indent+2)+'){'+LineEnding
|
||||
+Space(Indent)+DbgString(TJSBinaryExpression(Element).B,Indent+2)+LineEnding
|
||||
+Space(Indent)+'}';
|
||||
+StringOfChar(' ',Indent)+DbgString(TJSBinaryExpression(Element).B,Indent+2)+LineEnding
|
||||
+StringOfChar(' ',Indent)+'}';
|
||||
end else if Element is TJSBinaryExpression then
|
||||
begin
|
||||
Result:=DbgString(TJSBinaryExpression(Element).A,Indent+2);
|
||||
@ -299,12 +349,12 @@ begin
|
||||
end else if Element is TJSIfStatement then
|
||||
begin
|
||||
Result:='if('+DbgString(TJSIfStatement(Element).Cond,Indent+2)+'){'+LineEnding
|
||||
+Space(Indent+2)+DbgString(TJSIfStatement(Element).BTrue,Indent+2)+LineEnding
|
||||
+Space(Indent);
|
||||
+StringOfChar(' ',Indent+2)+DbgString(TJSIfStatement(Element).BTrue,Indent+2)+LineEnding
|
||||
+StringOfChar(' ',Indent);
|
||||
if TJSIfStatement(Element).BFalse<>nil then
|
||||
Result+=' else {'+LineEnding
|
||||
+Space(Indent+2)+DbgString(TJSIfStatement(Element).BFalse,Indent+2)+LineEnding
|
||||
+Space(Indent)+'}';
|
||||
+StringOfChar(' ',Indent+2)+DbgString(TJSIfStatement(Element).BFalse,Indent+2)+LineEnding
|
||||
+StringOfChar(' ',Indent)+'}';
|
||||
|
||||
// body
|
||||
end else if Element is TJSBodyStatement then
|
||||
@ -351,8 +401,8 @@ begin
|
||||
end else begin
|
||||
if TJSBodyStatement(Element).Body<>nil then
|
||||
Result+='{'+LineEnding
|
||||
+Space(Indent+2)+DbgString(TJSBodyStatement(Element).Body,Indent+2)+LineEnding
|
||||
+Space(Indent)+'}'
|
||||
+StringOfChar(' ',Indent+2)+DbgString(TJSBodyStatement(Element).Body,Indent+2)+LineEnding
|
||||
+StringOfChar(' ',Indent)+'}'
|
||||
else
|
||||
Result+='{}';
|
||||
end;
|
||||
@ -372,14 +422,14 @@ begin
|
||||
jstNull: Result:='null';
|
||||
jstBoolean: Result:=BoolToStr(Element.AsBoolean,'true','false');
|
||||
jstNumber: str(Element.AsNumber,Result);
|
||||
jstString: Result:=AnsiQuotedStr(Element.AsString{%H-},'''');
|
||||
jstString: Result:=QuoteStr(Element.AsString{%H-},'''');
|
||||
jstObject: Result:='{:OBJECT:}';
|
||||
jstReference: Result:='{:REFERENCE:}';
|
||||
JSTCompletion: Result:='{:COMPLETION:}';
|
||||
else Result:='{:Unknown ValueType '+IntToStr(ord(Element.ValueType))+':}';
|
||||
end;
|
||||
end;
|
||||
Result:=Space(Indent)+Result;
|
||||
Result:=StringOfChar(' ',Indent)+Result;
|
||||
end;
|
||||
|
||||
function DbgAsString(Element: TJSArrayLiteralElements; Indent: integer): string;
|
||||
@ -410,6 +460,7 @@ begin
|
||||
+':'+DbgString(TJSObjectLiteralElement(Element).Expr,Indent+2);
|
||||
end;
|
||||
|
||||
{$IFDEF UsePChar}
|
||||
function DbgHexMem(p: Pointer; Count: integer): string;
|
||||
var
|
||||
i: Integer;
|
||||
@ -418,6 +469,7 @@ begin
|
||||
for i:=0 to Count-1 do
|
||||
Result:=Result+HexStr(ord(PChar(p)[i]),2);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
function DbgStr(const s: string): string;
|
||||
var
|
||||
@ -434,6 +486,26 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{$IFDEF Pas2JS}
|
||||
{ TPas2jsFileStream }
|
||||
|
||||
constructor TPas2jsFileStream.Create(Filename: string; Mode: cardinal);
|
||||
begin
|
||||
writeln('TPas2JSFileStream.Create TODO ',Filename,' Mode=',Mode);
|
||||
end;
|
||||
|
||||
destructor TPas2jsFileStream.Destroy;
|
||||
begin
|
||||
writeln('TPas2JSFileStream.Destroy TODO');
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TPas2jsFileStream.Write(const s: string);
|
||||
begin
|
||||
writeln('TPas2JSFileStream.Write TODO s="',s,'"');
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
{ TPas2jsLogger }
|
||||
|
||||
function TPas2jsLogger.GetMsgs(Index: integer): TPas2jsMessage;
|
||||
@ -447,7 +519,7 @@ var
|
||||
l, r, m, CurMsgNumber: Integer;
|
||||
begin
|
||||
l:=0;
|
||||
r:=FMsgNumberDisabledCount-1;
|
||||
r:=length(FMsgNumberDisabled)-1;
|
||||
m:=0;
|
||||
while l<=r do begin
|
||||
m:=(l+r) div 2;
|
||||
@ -472,7 +544,11 @@ procedure TPas2jsLogger.SetEncoding(const AValue: string);
|
||||
var
|
||||
NewValue: String;
|
||||
begin
|
||||
{$IFDEF Pas2JS}
|
||||
NewValue:=Trim(lowercase(AValue));
|
||||
{$ELSE}
|
||||
NewValue:=NormalizeEncoding(AValue);
|
||||
{$ENDIF}
|
||||
if FEncoding=NewValue then Exit;
|
||||
//LogPlain(ClassName+': Encoding changed from "'+FEncoding+'" to "'+NewValue+'"');
|
||||
FEncoding:=NewValue;
|
||||
@ -488,28 +564,33 @@ procedure TPas2jsLogger.SetMsgNumberDisabled(MsgNumber: integer; AValue: boolean
|
||||
var
|
||||
InsertPos, OldCount: Integer;
|
||||
begin
|
||||
OldCount:=FMsgNumberDisabledCount;
|
||||
OldCount:=length(FMsgNumberDisabled);
|
||||
if AValue then
|
||||
begin
|
||||
// enable
|
||||
InsertPos:=FindMsgNumberDisabled(MsgNumber,true);
|
||||
if (InsertPos<OldCount) and (FMsgNumberDisabled[InsertPos]=MsgNumber) then
|
||||
exit; // already disabled
|
||||
inc(FMsgNumberDisabledCount);
|
||||
ReAllocMem(FMsgNumberDisabled,SizeOf(Integer)*FMsgNumberDisabledCount);
|
||||
if InsertPos<OldCount then
|
||||
Move(FMsgNumberDisabled[InsertPos],FMsgNumberDisabled[InsertPos+1],
|
||||
SizeOf(Integer)*(OldCount-InsertPos));
|
||||
// insert into array
|
||||
{$IF defined(FPC) and (FPC_FULLVERSION<30101)}
|
||||
SetLength(FMsgNumberDisabled,OldCount+1);
|
||||
FMsgNumberDisabled[InsertPos]:=MsgNumber;
|
||||
{$ELSE}
|
||||
Insert(MsgNumber,FMsgNumberDisabled,InsertPos);
|
||||
{$ENDIF}
|
||||
end else begin
|
||||
// disable
|
||||
InsertPos:=FindMsgNumberDisabled(MsgNumber,false);
|
||||
if InsertPos<0 then exit;
|
||||
// delete from array
|
||||
{$IF defined(FPC) and (FPC_FULLVERSION<30101)}
|
||||
if InsertPos+1<OldCount then
|
||||
Move(FMsgNumberDisabled[InsertPos+1],FMsgNumberDisabled[InsertPos],
|
||||
SizeOf(Integer)*(OldCount-InsertPos-1));
|
||||
dec(FMsgNumberDisabledCount);
|
||||
ReAllocMem(FMsgNumberDisabled,SizeOf(Integer)*FMsgNumberDisabledCount);
|
||||
SetLength(FMsgNumberDisabled,OldCount-1);
|
||||
{$ELSE}
|
||||
Delete(FMsgNumberDisabled,InsertPos,1);
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -536,6 +617,7 @@ begin
|
||||
if SkipEncoding then
|
||||
S:=Msg
|
||||
else begin
|
||||
{$IFDEF FPC_HAS_CPSTRING}
|
||||
if (Encoding='utf8') or (Encoding='json') then
|
||||
S:=Msg
|
||||
else if Encoding='console' then
|
||||
@ -547,6 +629,9 @@ begin
|
||||
if FOutputFile=nil then
|
||||
S:=UTF8ToConsole(Msg);
|
||||
end;
|
||||
{$ELSE}
|
||||
S:=Msg;
|
||||
{$ENDIF}
|
||||
end;
|
||||
//writeln('TPas2jsLogger.LogPlain "',Encoding,'" "',DbgStr(S),'"');
|
||||
if DebugLog<>nil then
|
||||
@ -556,48 +641,74 @@ begin
|
||||
else if FOutputFile<>nil then
|
||||
FOutputFile.Write(S+LineEnding)
|
||||
else begin
|
||||
{$IFDEF FPC_HAS_CPSTRING}
|
||||
// prevent codepage conversion magic
|
||||
SetCodePage(RawByteString(S), CP_OEMCP, False);
|
||||
{$ENDIF}
|
||||
{AllowWriteln}
|
||||
{$IFDEF HasStdErr}
|
||||
if WriteMsgToStdErr then
|
||||
writeln(StdErr,S)
|
||||
else
|
||||
{$ENDIF}
|
||||
writeln(S);
|
||||
{AllowWriteln-}
|
||||
end;
|
||||
end;
|
||||
|
||||
function TPas2jsLogger.Concatenate(Args: array of const): string;
|
||||
function TPas2jsLogger.Concatenate(
|
||||
Args: array of {$IFDEF Pas2JS}jsvalue{$ELSE}const{$ENDIF}): string;
|
||||
var
|
||||
s: String;
|
||||
i: Integer;
|
||||
{$IFDEF Pas2JS}
|
||||
V: JSValue;
|
||||
{$ELSE}
|
||||
V: TVarRec;
|
||||
{$ENDIF}
|
||||
begin
|
||||
s:='';
|
||||
for i:=Low(Args) to High(Args) do
|
||||
begin
|
||||
case Args[i].VType of
|
||||
vtInteger: s += IntToStr(Args[i].VInteger);
|
||||
vtBoolean: s += BoolToStr(Args[i].VBoolean);
|
||||
vtChar: s += Args[i].VChar;
|
||||
{$ifndef FPUNONE}
|
||||
vtExtended: ; // Args[i].VExtended^;
|
||||
{$ENDIF}
|
||||
vtString: s += Args[i].VString^;
|
||||
vtPointer: ; // Args[i].VPointer;
|
||||
vtPChar: s += Args[i].VPChar;
|
||||
vtObject: ; // Args[i].VObject;
|
||||
vtClass: ; // Args[i].VClass;
|
||||
vtWideChar: s += AnsiString(Args[i].VWideChar);
|
||||
vtPWideChar: s += AnsiString(Args[i].VPWideChar);
|
||||
vtAnsiString: s += AnsiString(Args[i].VAnsiString);
|
||||
vtCurrency: ; // Args[i].VCurrency^);
|
||||
vtVariant: ; // Args[i].VVariant^);
|
||||
vtInterface: ; // Args[i].VInterface^);
|
||||
vtWidestring: s += AnsiString(WideString(Args[i].VWideString));
|
||||
vtInt64: s += IntToStr(Args[i].VInt64^);
|
||||
vtQWord: s += IntToStr(Args[i].VQWord^);
|
||||
vtUnicodeString:s += AnsiString(UnicodeString(Args[i].VUnicodeString));
|
||||
V:=Args[i];
|
||||
{$IFDEF Pas2JS}
|
||||
case jsTypeOf(V) of
|
||||
'boolean':
|
||||
if V then s+='true' else s+='false';
|
||||
'number':
|
||||
if isInteger(V) then
|
||||
s+=str(NativeInt(V))
|
||||
else
|
||||
s+=str(Double(V));
|
||||
'string':
|
||||
s+=String(V);
|
||||
else continue;
|
||||
end;
|
||||
{$ELSE}
|
||||
case V.VType of
|
||||
vtInteger: s += IntToStr(V.VInteger);
|
||||
vtBoolean: s += BoolToStr(V.VBoolean);
|
||||
vtChar: s += V.VChar;
|
||||
{$ifndef FPUNONE}
|
||||
vtExtended: ; // V.VExtended^;
|
||||
{$ENDIF}
|
||||
vtString: s += V.VString^;
|
||||
vtPointer: ; // V.VPointer;
|
||||
vtPChar: s += V.VPChar;
|
||||
vtObject: ; // V.VObject;
|
||||
vtClass: ; // V.VClass;
|
||||
vtWideChar: s += AnsiString(V.VWideChar);
|
||||
vtPWideChar: s += AnsiString(V.VPWideChar);
|
||||
vtAnsiString: s += AnsiString(V.VAnsiString);
|
||||
vtCurrency: ; // V.VCurrency^);
|
||||
vtVariant: ; // V.VVariant^);
|
||||
vtInterface: ; // V.VInterface^);
|
||||
vtWidestring: s += AnsiString(WideString(V.VWideString));
|
||||
vtInt64: s += IntToStr(V.VInt64^);
|
||||
vtQWord: s += IntToStr(V.VQWord^);
|
||||
vtUnicodeString:s += AnsiString(UnicodeString(V.VUnicodeString));
|
||||
end;
|
||||
{$ENDIF}
|
||||
end;
|
||||
Result:=s;
|
||||
end;
|
||||
@ -615,10 +726,9 @@ begin
|
||||
CloseOutputFile;
|
||||
CloseDebugLog;
|
||||
for i:=0 to FMsg.Count-1 do
|
||||
TObject(FMsg[i]).Free;
|
||||
TObject(FMsg[i]).{$IFDEF Pas2JS}Destroy{$ELSE}Free{$ENDIF};
|
||||
FreeAndNil(FMsg);
|
||||
ReAllocMem(FMsgNumberDisabled,0);
|
||||
FMsgNumberDisabledCount:=0;
|
||||
FMsgNumberDisabled:=nil;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
@ -688,7 +798,7 @@ begin
|
||||
end;
|
||||
|
||||
function TPas2jsLogger.GetMsgText(MsgNumber: integer;
|
||||
Args: array of const): string;
|
||||
Args: array of {$IFDEF Pas2JS}jsvalue{$ELSE}const{$ENDIF}): string;
|
||||
var
|
||||
Msg: TPas2jsMessage;
|
||||
begin
|
||||
@ -702,7 +812,8 @@ begin
|
||||
DoLogRaw(Msg,False);
|
||||
end;
|
||||
|
||||
procedure TPas2jsLogger.LogRaw(Args: array of const);
|
||||
procedure TPas2jsLogger.LogRaw(
|
||||
Args: array of {$IFDEF Pas2JS}jsvalue{$ELSE}const{$ENDIF});
|
||||
begin
|
||||
LogRaw(Concatenate(Args));
|
||||
end;
|
||||
@ -716,7 +827,11 @@ procedure TPas2jsLogger.DebugLogWriteLn(Msg: string);
|
||||
begin
|
||||
if FDebugLog=nil then exit;
|
||||
Msg:=Msg+LineEnding;
|
||||
{$IFDEF Pas2JS}
|
||||
FDebugLog.Write(Msg);
|
||||
{$ELSE}
|
||||
FDebugLog.Write(Msg[1],length(Msg));
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
function TPas2jsLogger.GetEncodingCaption: string;
|
||||
@ -724,9 +839,11 @@ begin
|
||||
Result:=Encoding;
|
||||
if Result='' then
|
||||
begin
|
||||
{$IFDEF FPC_HAS_CPSTRING}
|
||||
if FOutputFile=nil then
|
||||
Result:='console'
|
||||
else
|
||||
{$ENDIF}
|
||||
Result:='utf-8';
|
||||
end;
|
||||
if Result='console' then
|
||||
@ -753,12 +870,14 @@ begin
|
||||
DoLogRaw(Msg,False);
|
||||
end;
|
||||
|
||||
procedure TPas2jsLogger.LogPlain(Args: array of const);
|
||||
procedure TPas2jsLogger.LogPlain(
|
||||
Args: array of {$IFDEF Pas2JS}jsvalue{$ELSE}const{$ENDIF});
|
||||
begin
|
||||
LogPlain(Concatenate(Args));
|
||||
end;
|
||||
|
||||
procedure TPas2jsLogger.LogMsg(MsgNumber: integer; Args: array of const;
|
||||
procedure TPas2jsLogger.LogMsg(MsgNumber: integer;
|
||||
Args: array of {$IFDEF Pas2JS}jsvalue{$ELSE}const{$ENDIF};
|
||||
const Filename: string; Line: integer; Col: integer; UseFilter: boolean);
|
||||
var
|
||||
Msg: TPas2jsMessage;
|
||||
@ -789,11 +908,12 @@ begin
|
||||
end;
|
||||
|
||||
procedure TPas2jsLogger.LogMsgIgnoreFilter(MsgNumber: integer;
|
||||
Args: array of const);
|
||||
Args: array of {$IFDEF Pas2JS}jsvalue{$ELSE}const{$ENDIF});
|
||||
begin
|
||||
LogMsg(MsgNumber,Args,'',0,0,false);
|
||||
end;
|
||||
|
||||
{$IFDEF FPC}
|
||||
procedure TPas2jsLogger.LogExceptionBackTrace;
|
||||
var
|
||||
lErrorAddr: CodePointer;
|
||||
@ -808,6 +928,7 @@ begin
|
||||
for FrameNumber := 0 to FrameCount-1 do
|
||||
Log(mtDebug,BackTraceStrFunc(Frames[FrameNumber]));
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
function TPas2jsLogger.MsgTypeToStr(MsgType: TMessageType): string;
|
||||
begin
|
||||
@ -887,8 +1008,10 @@ begin
|
||||
if DirectoryExists(OutputFilename) then
|
||||
raise Exception.Create('Log is directory: "'+OutputFilename+'"');
|
||||
FOutputFile:=TFileWriter.Create(OutputFilename);
|
||||
{$IFDEF FPC_HAS_CPSTRING}
|
||||
if (Encoding='') or (Encoding='utf8') then
|
||||
FOutputFile.Write(UTF8BOM);
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
procedure TPas2jsLogger.Flush;
|
||||
@ -907,11 +1030,7 @@ end;
|
||||
procedure TPas2jsLogger.Reset;
|
||||
begin
|
||||
OutputFilename:='';
|
||||
if FMsgNumberDisabled<>nil then
|
||||
begin
|
||||
ReAllocMem(FMsgNumberDisabled,0);
|
||||
FMsgNumberDisabledCount:=0;
|
||||
end;
|
||||
FMsgNumberDisabled:=nil;
|
||||
ShowMsgNumbers:=false;
|
||||
FShowMsgTypes:=DefaultLogMsgTypes;
|
||||
end;
|
||||
@ -930,7 +1049,7 @@ procedure TPas2jsLogger.OpenDebugLog;
|
||||
const
|
||||
DbgLogFilename = 'pas2jsdebug.log';
|
||||
begin
|
||||
FDebugLog:=TFileStream.Create(DbgLogFilename,fmCreate or fmShareDenyNone);
|
||||
FDebugLog:=TPas2jsFileStream.Create(DbgLogFilename,fmCreate or fmShareDenyNone);
|
||||
end;
|
||||
|
||||
procedure TPas2jsLogger.CloseDebugLog;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user