Browse Source

pastojs: added some nodejs file functions

git-svn-id: trunk@40101 -
Mattias Gaertner 6 years ago
parent
commit
16b421d344
2 changed files with 91 additions and 36 deletions
  1. 38 15
      packages/pastojs/src/pas2jsfileutils.pp
  2. 53 21
      packages/pastojs/src/pas2jsfileutilsnodejs.inc

+ 38 - 15
packages/pastojs/src/pas2jsfileutils.pp

@@ -29,7 +29,7 @@ uses
   BaseUnix,
   {$ENDIF}
   {$IFDEF Pas2JS}
-  NodeJSFS,
+  JS, NodeJS, NodeJSFS,
   {$ENDIF}
   SysUtils, Classes;
 
@@ -164,6 +164,10 @@ begin
     if (Len >= 2) and (Result[2] in AllowDirectorySeparators) then
       MinLen := 2; // keep UNC '\\', chomp 'a\' to 'a'
     {$ENDIF}
+    {$IFDEF Pas2js}
+    if (Len >= 2) and (Result[2]=Result[1]) and (PathDelim='\') then
+      MinLen := 2; // keep UNC '\\', chomp 'a\' to 'a'
+    {$ENDIF}
   end
   else begin
     MinLen := 0;
@@ -173,6 +177,13 @@ begin
     then
       MinLen := 3;
     {$ENDIF}
+    {$IFdef Pas2js}
+    if (PathDelim='\')
+        and (Len >= 3) and (Result[1] in ['a'..'z', 'A'..'Z'])
+        and (Result[2] = ':') and (Result[3] in AllowDirectorySeparators)
+    then
+      MinLen := 3;
+    {$ENDIF}
   end;
 
   while (Len > MinLen) and (Result[Len] in AllowDirectorySeparators) do dec(Len);
@@ -321,15 +332,8 @@ 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 Pas2js}
-var
-  Len: Integer;
 begin
-  Len:=length(AFilename);
-  if Len=0 then exit('');
-  Result:=AFilename;
-  {AllowWriteln}
-  writeln('ResolveDots ToDo ',AFilename);
-  {AllowWriteln-}
+  Result:=NJS_Path.resolve(AFilename);
 end;
 {$ELSE}
 
@@ -592,12 +596,20 @@ begin
 end;
 
 function CompareFilenames(const File1, File2: string): integer;
+{$IFDEF Pas2js}
+var
+  a, b: string;
+{$ENDIF}
 begin
   {$IFDEF Pas2js}
-  {AllowWriteln}
-  writeln('CompareFilenames ToDo ',File1,' ',File2);
-  {AllowWriteln-}
-  raise Exception.Create('CompareFilenames ToDo');
+  a:=FilenameToKey(File1);
+  b:=FilenameToKey(File2);
+  if a<b then
+    exit(-1)
+  else if a>b then
+    exit(1)
+  else
+    exit(0);
   Result:=0;
   {$ELSE}
   Result:=AnsiCompareFileName(File1,File2);
@@ -608,8 +620,19 @@ end;
 function FilenameToKey(const Filename: string): string;
 begin
   {$IFDEF Pas2js}
-  Result:=Filename;
-  // ToDo lowercase on windows, normalize on darwin
+  case NJS_OS.platform of
+  'darwin':
+    {$IF ECMAScript>5}
+    Result:=TJSString(Filename).normalize('NFD');
+    {$ELSE}
+    begin
+    Result:=Filename;
+    raise Exception.Create('requires ECMAScript6');
+    end;
+    {$ENDIF}
+  'win32': Result:=lowercase(Filename);
+  else Result:=Filename;
+  end;
   {$ELSE}
     {$IFDEF Windows}
     Result:=AnsiLowerCase(Filename);

+ 53 - 21
packages/pastojs/src/pas2jsfileutilsnodejs.inc

@@ -17,11 +17,7 @@
 
 function FilenameIsAbsolute(const aFilename: string): boolean;
 begin
-  {AllowWriteln}
-  writeln('FilenameIsAbsolute ToDo ',aFilename);
-  {AllowWriteln-}
-  Result:=FilenameIsUnixAbsolute(aFilename);
-  raise Exception.Create('FilenameIsAbsolute ToDo');
+  Result:=NJS_Path.isAbsolute(aFilename);
 end;
 
 function ExpandFileNamePJ(const FileName: string; BaseDir: string): string;
@@ -29,8 +25,7 @@ var
   IsAbs: Boolean;
   HomeDir, Fn: String;
 begin
-  Fn := FileName;
-  ForcePathDelims(Fn);
+  Fn := GetForcedPathDelims(Filename);
   IsAbs := FileNameIsUnixAbsolute(Fn);
   if (not IsAbs) then
   begin
@@ -63,11 +58,7 @@ end;
 
 function GetCurrentDirPJ: String;
 begin
-  {AllowWriteln}
-  writeln('GetCurrentDirPJ ToDo');
-  {AllowWriteln-}
-  Result:='';
-  raise Exception.Create('GetCurrentDirPJ ToDo');
+  Result:=GetCurrentDir;
 end;
 
 function GetPhysicalFilename(const Filename: string; ExceptionOnError: boolean
@@ -103,21 +94,62 @@ end;
 
 function ResolveSymLinks(const Filename: string; ExceptionOnError: boolean
   ): string;
+var
+  LinkFilename: string;
+  AText: string;
+  Depth: Integer;
 begin
-  {AllowWriteln}
-  writeln('ResolveSymLinks ToDo ',Filename,' ',ExceptionOnError);
-  {AllowWriteln-}
   Result:=Filename;
-  raise Exception.Create('ResolveSymLinks ToDo');
+  Depth:=0;
+  while Depth<12 do
+  begin
+    inc(Depth);
+    try
+      LinkFilename:=NJS_FS.readlinkSync(Result);
+    except
+      if not ExceptionOnError then
+        exit;
+      if isString(JSExceptValue) then
+        AText:=String(JSExceptValue)
+      else if isObject(JSExceptValue) and isString(TJSObject(JSExceptValue)['message']) then
+      begin
+        if TJSObject(JSExceptValue)['code']='EINVAL' then
+        begin
+          // not a symbolic link
+          exit;
+        end;
+        AText:=String(TJSObject(JSExceptValue)['message']);
+      end else
+        AText:='uknown error ('+jsTypeOf(JSExceptValue)+')';
+      if Pos(Filename,AText)<1 then
+        AText+=' "'+Filename+'"';
+      raise EFOpenError.Create(AText);
+    end;
+    if LinkFilename='' then
+    begin
+      // not a symbolic link, just a regular file
+      exit;
+    end;
+    if not FilenameIsAbsolute(LinkFilename) then
+      Result:=ExtractFilePath(Result)+LinkFilename
+    else
+      Result:=LinkFilename;
+  end;
+  // probably an endless loop
+  if ExceptionOnError then
+    raise EFOpenError.Create('too many links, maybe an endless loop.')
+  else
+    Result:='';
 end;
 
 function FileIsWritable(const AFilename: string): boolean;
 begin
-  {AllowWriteln}
-  writeln('FileIsWritable ToDo ',AFilename);
-  {AllowWriteln-}
-  Result := false;
-  raise Exception.Create('FileIsWritable ToDo');
+  try
+    NJS_FS.accessSync(AFilename,W_OK);
+  except
+    exit(false);
+  end;
+  Result:=true;
 end;
 
 function GetEnvironmentVariableCountPJ: Integer;