Tomas Hajny 21 éve
szülő
commit
af1ab052af
1 módosított fájl, 112 hozzáadás és 51 törlés
  1. 112 51
      rtl/inc/fexpand.inc

+ 112 - 51
rtl/inc/fexpand.inc

@@ -23,12 +23,32 @@
  {$ENDIF FPC_FEXPAND_DRIVES}
 {$ENDIF FPC_FEXPAND_VOLUMES}
 
+{$IFDEF FPC_FEXPAND_DIRSEP_IS_CURDIR}
+ {$IFNDEF FPC_FEXPAND_DRIVES}
+  (* If DirectorySeparator at the beginning marks a relative path, *)
+  (* an absolute path must always begin with a drive or volume.    *)
+  {$DEFINE FPC_FEXPAND_DRIVES}
+ {$ENDIF FPC_FEXPAND_DRIVES}
+ {$IFNDEF FPC_FEXPAND_MULTIPLE_UPDIR}
+  (* Traversing multiple levels at once explicitely allowed. *)
+  {$DEFINE FPC_FEXPAND_MULTIPLE_UPDIR}
+ {$ENDIF FPC_FEXPAND_MULTIPLE_UPDIR}
+ (* Helper define used to support common features of FPC_FEXPAND_DIRSEP_IS_* *)
+ {$DEFINE FPC_FEXPAND_UPDIR_HELPER}
+{$ENDIF FPC_FEXPAND_DIRSEP_IS_CURDIR}
+
 {$IFDEF FPC_FEXPAND_DIRSEP_IS_UPDIR}
- {$IFNDEF FPC_FEXPAND_DRIVESEP_IS_ROOT}
-  (* If DriveSeparator is used for upper directory,       *)
-  (* it cannot be used for marking root at the same time. *)
-  {$DEFINE FPC_FEXPAND_DRIVESEP_IS_ROOT}
- {$ENDIF FPC_FEXPAND_DRIVESEP_IS_ROOT}
+ {$IFNDEF FPC_FEXPAND_DRIVES}
+  (* If DirectorySeparator at the beginning marks a relative path, *)
+  (* an absolute path must always begin with a drive or volume.    *)
+  {$DEFINE FPC_FEXPAND_DRIVES}
+ {$ENDIF FPC_FEXPAND_DRIVES}
+ {$IFNDEF FPC_FEXPAND_MULTIPLE_UPDIR}
+  (* Traversing multiple levels at once explicitely allowed. *)
+  {$DEFINE FPC_FEXPAND_MULTIPLE_UPDIR}
+ {$ENDIF FPC_FEXPAND_MULTIPLE_UPDIR}
+ (* Helper define used to support common features of FPC_FEXPAND_DIRSEP_IS_* *)
+ {$DEFINE FPC_FEXPAND_UPDIR_HELPER}
 {$ENDIF FPC_FEXPAND_DIRSEP_IS_UPDIR}
 
 procedure GetDirIO (DriveNr: byte; var Dir: OpenString);
@@ -47,7 +67,7 @@ end;
 
 
 {$IFDEF FPC_FEXPAND_VOLUMES}
-{$IFNDEF FPC_FEXPAND_NO_DEFAULT_PATHS}
+ {$IFNDEF FPC_FEXPAND_NO_DEFAULT_PATHS}
 procedure GetDirIO (const VolumeName: OpenString; var Dir: OpenString);
 
 var
@@ -58,7 +78,7 @@ begin
   GetDir (VolumeName, Dir);
   InOutRes := OldInOutRes;
 end;
-{$ENDIF FPC_FEXPAND_NO_DEFAULT_PATHS}
+ {$ENDIF FPC_FEXPAND_NO_DEFAULT_PATHS}
 {$ENDIF FPC_FEXPAND_VOLUMES}
 
 
@@ -69,10 +89,10 @@ function FExpand (const Path: PathStr): PathStr;
    In addition, FPC_FEXPAND_UNC, FPC_FEXPAND_DRIVES, FPC_FEXPAND_GETENV_PCHAR,
    FPC_FEXPAND_TILDE, FPC_FEXPAND_VOLUMES, FPC_FEXPAND_NO_DEFAULT_PATHS,
    FPC_FEXPAND_DRIVESEP_IS_ROOT, FPC_FEXPAND_NO_CURDIR,
-   FPC_FEXPAND_NO_DOTS_UPDIR and FPC_FEXPAND_DIRSEP_IS_UPDIR conditionals might
-   be defined to specify FExpand behaviour - see end of this file for
+   FPC_FEXPAND_NO_DOTS_UPDIR, FPC_FEXPAND_DIRSEP_IS_UPDIR,
+   FPC_FEXPAND_DIRSEP_IS_CURDIR and FPC_FEXPAND_MULTIPLE_UPDIR conditionals
+   might be defined to specify FExpand behaviour - see end of this file for
    individual descriptions.
-
 *)
 
 {$IFDEF FPC_FEXPAND_DRIVES}
@@ -108,17 +128,18 @@ begin
 (* by converting all to the native one.           *)
     if DirectorySeparator = '\' then
     {Allow slash as backslash}
-        begin
-            for I := 1 to Length (Pa) do
-                if Pa [I] = '/' then
-                    Pa [I] := DirectorySeparator
-        end
+      begin
+        for I := 1 to Length (Pa) do
+          if Pa [I] = '/' then
+            Pa [I] := DirectorySeparator
+      end
     else
+      if DirectorySeparator = '\' then
     {Allow backslash as slash}
         begin
-            for I := 1 to Length (Pa) do
-                if Pa [I] = '\' then
-                    Pa [I] := DirectorySeparator;
+          for I := 1 to Length (Pa) do
+            if Pa [I] = '\' then
+              Pa [I] := DirectorySeparator;
         end;
 
 (* PathStart is amount of characters to strip to get beginning *)
@@ -235,17 +256,18 @@ begin
  {$ENDIF FPC_FEXPAND_DRIVESEP_IS_ROOT}
 {$ENDIF FPC_FEXPAND_VOLUMES}
 
-(* Do we have an absolute path? *)
-{$IFDEF FPC_FEXPAND_DRIVES}
+(* Do we have an absolute path without drive or volume? *)
+{$IFNDEF FPC_FEXPAND_DIRSEP_IS_CURDIR}
+ {$IFDEF FPC_FEXPAND_DRIVES}
             if (Length (Pa) > 0)
- {$IFDEF FPC_FEXPAND_DRIVESEP_IS_ROOT}
+  {$IFDEF FPC_FEXPAND_DRIVESEP_IS_ROOT}
                                  and (Pa [1] = DriveSeparator)
- {$ELSE FPC_FEXPAND_DRIVESEP_IS_ROOT}
+  {$ELSE FPC_FEXPAND_DRIVESEP_IS_ROOT}
                                  and (Pa [1] = DirectorySeparator)
- {$ENDIF FPC_FEXPAND_DRIVESEP_IS_ROOT}
+  {$ENDIF FPC_FEXPAND_DRIVESEP_IS_ROOT}
                                                                    then
                 begin
- {$IFDEF FPC_FEXPAND_UNC}
+  {$IFDEF FPC_FEXPAND_UNC}
                     {Do not touch network drive names}
                     if (Length (Pa) > 1) and (Pa [2] = DirectorySeparator)
                                                             and LFNSupport then
@@ -274,32 +296,38 @@ begin
                                     end;
                         end
                     else
- {$ENDIF FPC_FEXPAND_UNC}
- {$IFDEF FPC_FEXPAND_VOLUMES}
+  {$ENDIF FPC_FEXPAND_UNC}
+  {$IFDEF FPC_FEXPAND_VOLUMES}
                         begin
                             I := Pos (DriveSeparator, S);
-  {$IFDEF FPC_FEXPAND_DIRSEP_IS_UPDIR}
-   {$IFDEF FPC_FEXPAND_DRIVESEP_IS_ROOT}
+   {$IFDEF FPC_FEXPAND_DIRSEP_IS_UPDIR}
+    {$IFDEF FPC_FEXPAND_DRIVESEP_IS_ROOT}
                             if (Pa [1] = DriveSeparator) then
                                 Delete (Pa, 1, 1);
-   {$ENDIF FPC_FEXPAND_DRIVESEP_IS_ROOT}
+    {$ENDIF FPC_FEXPAND_DRIVESEP_IS_ROOT}
                             Pa := Copy (S, 1, I) + Pa;
                             PathStart := I;
-  {$ELSE FPC_FEXPAND_DIRSEP_IS_UPDIR}
+   {$ELSE FPC_FEXPAND_DIRSEP_IS_UPDIR}
                             Pa := Copy (S, 1, Pred (I)) + DriveSeparator + Pa;
                             PathStart := Succ (I);
-  {$ENDIF FPC_FEXPAND_DIRSEP_IS_UPDIR}
+   {$ENDIF FPC_FEXPAND_DIRSEP_IS_UPDIR}
                         end;
- {$ELSE FPC_FEXPAND_VOLUMES}
+  {$ELSE FPC_FEXPAND_VOLUMES}
                         Pa := S [1] + DriveSeparator + Pa;
- {$ENDIF FPC_FEXPAND_VOLUMES}
+  {$ENDIF FPC_FEXPAND_VOLUMES}
                 end
             else
-{$ENDIF FPC_FEXPAND_DRIVES}
+ {$ENDIF FPC_FEXPAND_DRIVES}
 
                 (* We already have a slash if root is the curent directory. *)
                 if Length (S) = PathStart then
                     Pa := S + Pa
+{$ELSE FPC_FEXPAND_DIRSEP_IS_CURDIR}
+                (* More complex with DirectorySeparator as current directory *)
+                if (S [Length (S)] = DriveSeparator)
+                                         and (Pa [1] = DirectorySeparator) then
+                    Pa := S + Copy (Pa, 2, Pred (Length (Pa)))
+{$ENDIF FPC_FEXPAND_DIRSEP_IS_CURDIR}
                 else
 
                     (* We need an ending slash if FExpand was called  *)
@@ -312,11 +340,11 @@ begin
                         Pa := S + DirectorySeparator
 {$ENDIF FPC_FEXPAND_DIRSEP_IS_UPDIR}
                     else
- {$IFDEF FPC_FEXPAND_DIRSEP_IS_UPDIR}
+{$IFDEF FPC_FEXPAND_UPDIR_HELPER}
                         if Pa [1] = DirectorySeparator then
                             Pa := S + Pa
                         else
- {$ENDIF FPC_FEXPAND_DIRSEP_IS_UPDIR}
+{$ENDIF FPC_FEXPAND_UPDIR_HELPER}
                         Pa := S + DirectorySeparator + Pa;
         end;
 
@@ -324,6 +352,7 @@ begin
     Dirs := Copy (Pa, Succ (PathStart), Length (Pa) - PathStart);
 
 {$IFNDEF FPC_FEXPAND_NO_CURDIR}
+ {$IFNDEF FPC_FEXPAND_DIRSEP_IS_CURDIR}
     {First remove all references to '\.\'}
     I := Pos (DirectorySeparator + '.' + DirectorySeparator, Dirs);
     while I <> 0 do
@@ -331,9 +360,20 @@ begin
             Delete (Dirs, I, 2);
             I := Pos (DirectorySeparator + '.' + DirectorySeparator, Dirs);
         end;
+ {$ENDIF FPC_FEXPAND_DIRSEP_IS_CURDIR}
 {$ENDIF FPC_FEXPAND_NO_CURDIR}
 
 {$IFNDEF FPC_FEXPAND_NO_DOTS_UPDIR}
+ {$IFDEF FPC_FEXPAND_MULTIPLE_UPDIR}
+    {Now replace all references to '\...' with '\..\..'}
+    I := Pos (DirectorySeparator + '...', Dirs);
+    while I <> 0 do
+        begin
+            Insert (DirectorySeparator + '.', Dirs, I + 3);
+            I := Pos (DirectorySeparator + '...', Dirs);
+        end;
+ {$ENDIF FPC_FEXPAND_MULTIPLE_UPDIR}
+
     {Now remove also all references to '\..\' + of course previous dirs..}
     I := Pos (DirectorySeparator + '..' + DirectorySeparator, Dirs);
     while I <> 0 do
@@ -346,7 +386,7 @@ begin
         end;
 {$ENDIF FPC_FEXPAND_NO_DOTS_UPDIR}
 
-{$IFDEF FPC_FEXPAND_DIRSEP_IS_UPDIR}
+{$IFDEF FPC_FEXPAND_UPDIR_HELPER}
     (* Now remove all references to '//' plus previous directories... *)
     I := Pos (DirectorySeparator + DirectorySeparator, Dirs);
     while I <> 0 do
@@ -357,7 +397,7 @@ begin
             Delete (Dirs, Succ (J), Succ (I - J));
             I := Pos (DirectorySeparator + DirectorySeparator, Dirs);
         end;
-{$ENDIF FPC_FEXPAND_DIRSEP_IS_UPDIR}
+{$ENDIF FPC_FEXPAND_UPDIR_HELPER}
 
 {$IFNDEF FPC_FEXPAND_NO_DOTS_UPDIR}
     {Then remove also a reference to '\..' at the end of line
@@ -392,6 +432,7 @@ begin
 {$ENDIF FPC_FEXPAND_DIRSEP_IS_UPDIR}
 
 {$IFNDEF FPC_FEXPAND_NO_CURDIR}
+ {$IFNDEF FPC_FEXPAND_DIRSEP_IS_CURDIR}
     {...and also a possible reference to '\.'}
     if (Length (Dirs) = 1) then
         begin
@@ -408,6 +449,7 @@ begin
     while (Length (Dirs) >= 2) and (Dirs [1] = '.')
                                          and (Dirs [2] = DirectorySeparator) do
         Delete (Dirs, 1, 2);
+ {$ENDIF FPC_FEXPAND_DIRSEP_IS_CURDIR}
 {$ENDIF FPC_FEXPAND_NO_CURDIR}
 
 {$IFDEF FPC_FEXPAND_DIRSEP_IS_UPDIR}
@@ -425,8 +467,10 @@ begin
 
     {Two special cases - '.' and '..' alone}
 {$IFNDEF FPC_FEXPAND_NO_CURDIR}
+ {$IFNDEF FPC_FEXPAND_DIRSEP_IS_CURDIR}
     if (Length (Dirs) = 1) and (Dirs [1] = '.') then
         Dirs := '';
+ {$ENDIF FPC_FEXPAND_DIRSEP_IS_CURDIR}
 {$ENDIF FPC_FEXPAND_NO_CURDIR}
 {$IFNDEF FPC_FEXPAND_NO_DOTS_UPDIR}
     if (Length (Dirs) = 2) and (Dirs [1] = '.') and (Dirs [2] = '.') then
@@ -451,9 +495,11 @@ begin
     if (Pa [Length (Pa)] = DirectorySeparator)
          and ((Length (Pa) > PathStart) or
 {A special case with UNC paths}
-            (RootNotNeeded and (Length (Pa) = PathStart))) and
-                     (Length (Path) <> 0)
-                          and (Path [Length (Path)] <> DirectorySeparator) then
+            (RootNotNeeded and (Length (Pa) = PathStart)))
+    {Reference to current directory at the end should be removed}
+                    and (Length (Path) <> 0)
+                          and (Path [Length (Path)] <> DirectorySeparator)
+                                                                           then
         Dec (Pa [0]);
 {$ENDIF FPC_FEXPAND_DIRSEP_IS_UPDIR}
 
@@ -499,9 +545,9 @@ end;
    should be used as beginning of the "real" path for a particular
    drive or volume instead of the DirectorySeparator. This would be
    used in case that there is only one character (DriveSeparator)
-   delimiting the drive letter or volume name from the remaining
-   path _and_ the DriveSeparator marks the root of an absolute path.
-   Example - 'Volume:This/Is/Absolute/Path'.
+   delimitting the drive letter or volume name from the remaining
+   path _and_ the DriveSeparator marks the root of an absolute path
+   in that case. Example - 'Volume:This/Is/Absolute/Path'.
 
    FPC_FEXPAND_NO_CURDIR - there is no support to refer to current
    directory explicitely (like '.' used under both Unix and DOS-like
@@ -510,17 +556,32 @@ end;
    FPC_FEXPAND_NO_DOTS_UPDIR - '..' cannot be used to refer to the
    upper directory.
 
-   FPC_FEXPAND_DIRSEP_IS_UPDIR - DirectorySeparator at the beginning of a
-   path (or doubled DirectorySeparator inside the path) refer to the
-   upper directory. Please, note that you can decide to support both '..'
-   and DirectorySeparator as references to the parent directory at the
-   same time for compatibility reasons (although that means that you'd
-   make it impossible to use an otherwise valid name of '..').
+   FPC_FEXPAND_DIRSEP_IS_UPDIR - DirectorySeparator at the beginning of
+   a path (or doubled DirectorySeparator inside the path) refer to the
+   parent directory, one more DirectorySeparator to parent directory of
+   parent directory and so on (Amiga). Please, note that you can decide
+   to support both '..' and DirectorySeparator as references to the parent
+   directory at the same time for compatibility reasons - however this
+   support makes it impossible to use an otherwise possibly valid name
+   of '..'.
+
+   FPC_FEXPAND_DIRSEP_IS_CURDIR - DirectorySeparator at the beginning of
+   a path refers to the current directory (i.e. path beginning with
+   DirectorySeparator is always a relative path). Two DirectorySeparator
+   characters refer to the parent directory, three refer to parent
+   directory of the parent directory and so on (MacOS).
+
+   FPC_FEXPAND_MULTIPLE_UPDIR - grouping of more characters specifying
+   upper directory references higher directory levels. Example: '...'
+   (Netware).
 *)
 
 {
   $Log$
-  Revision 1.16  2004-05-29 18:25:21  hajny
+  Revision 1.17  2004-11-21 14:45:17  hajny
+    + MacOS support
+
+  Revision 1.16  2004/05/29 18:25:21  hajny
     * description of individual conditional defines added
 
   Revision 1.15  2002/12/07 16:26:39  hajny