CVS difference for ai05s/ai05-0049-1.txt

Differences between 1.3 and version 1.4
Log of other versions for file ai05s/ai05-0049-1.txt

--- ai05s/ai05-0049-1.txt	2010/02/04 07:11:42	1.3
+++ ai05s/ai05-0049-1.txt	2010/02/23 04:10:50	1.4
@@ -1,4 +1,4 @@
-!standard  A.16(82/2)                                         09-11-03    AI05-0049-1/01
+!standard  A.16(82/2)                                       10-02-22    AI05-0049-1/02
 !class Amendment 07-04-10
 !status work item 07-04-10
 !status received 07-02-28
@@ -39,22 +39,74 @@
 
 !proposal
 
-Add a new package Ada.Directories.Hierarchical_Names:
+Add a new package Ada.Directories.Hierarchical_File_Names.
 
+Add a new function Name_Case_Equivalence to Ada.Directories.
+
+
+!wording
+
+[Editor's note: I removed "Fragments" and "Relative indicators" in an
+attempt to improve the terminology as requested. I kept "Relative_Name"
+as we need a term to be the counterpart of "Full_Name" and "Simple_Name".
+It is more typical to talk about "absolute paths" and "relative paths",
+but since these functions work both on paths and on file names (and make
+no differentiation between them), it would be confusing to use those
+terms. (To do so we'd have to abandon the entire model of the existing
+Ada.Directories; that would be too disruptive in my view.)] 
+
+Add after A.16(20/2) (in Ada.Directories):
+
+type Name_Case_Kind is (Unknown, Case_Sensitive, Case_Insensitive,
+                        Case_Preserving);
+
+function Name_Case_Equivalence (Name : in String) return Name_Case_Kind;
+
+Add after A.16(82/2):
+
+function Name_Case_Equivalence (Name : in String) return Name_Case_Kind;
+
+   Returns the file name equivalence rule for the directory containing Name.
+   Raises Name_Error if Name is not a full name. Returns Case_Sensitive if
+   file names that differ only in the case of letters are considered different
+   names. If file names that differ only in the case of letters are considered
+   the same name, then Case_Preserving is returned if the name has the case
+   of the file name when a file is created; and Case_Insensitive otherwise.
+   Returns Unknown if it is not known which answer is correct.
+
+AARM Note: Unix, Linux, and its relatives are Case_Sensitive systems.
+Windows is a Case_Preserving system. Ancient systems like CP/M and early
+MS-DOS were Case_Insensitive systems (file names were always in UPPER CASE).
+Unknown is provided in case it is impossible to tell (such as could be the
+case for network files).
+
+Add a new clause A.16.1:
+
+A.16.1 The package Directories.Hierarchical_File_Names
+
+The library package Directories.Hierarchical_File_Names is an optional package
+providing operations for file name construction and decomposition for 
+targets with hierarchical file naming.
+
+Static Semantics
+
+If provided, the library package Directories.Hierarchical_File_Names has
+the following declaration:
+
 package Ada.Directories.Hierarchical_File_Names is
 
    function Is_Simple_Name (Name : in String) return Boolean;
 
    function Is_Root_Directory (Name : in String) return Boolean;
 
-   function Is_Relative_Indicator (Name : in String) return Boolean;
+   function Is_Parent_Directory_Name (Name : in String) return Boolean;
 
+   function Is_Current_Directory_Name (Name : in String) return Boolean;
+
    function Is_Full_Name (Name : in String) return Boolean;
 
    function Is_Relative_Name (Name : in String) return Boolean;
 
-   function Is_Fragment (Name : in String) return Boolean;
-
    function Full_Name (Name : in String) return String;
 
    function Simple_Name (Name : in String) return String;
@@ -63,74 +115,126 @@
 
    function Initial_Directory (Name : in String) return String;
 
-   function Fragment (Name : in String) return String;
+   function Relative_Name (Name : in String) return String;
 
    function Extension (Name : in String) return String;
 
    function Base_Name (Name : in String) return String;
 
    function Compose (Directory      : in String := "";
-                     Fragment       : in String;
+                     Relative_Name  : in String;
                      Extension      : in String := "") return String;
 
-
 end Ada.Directories.Hierarchical_File_Names;
 
-Hierarchical_File_Names provides file name construction/decomposition facilities
-for systems with hierarchical file naming. This package is optional, and
-should not be provided on systems that don't have hierarchical file naming.
-
-AARM Notes: This includes Microsoft Windows, Unix, Linux, and most Unix-like
-systems. These operations are on file names and are purely syntactical;
-there is no requirement that the file or any part of it actually exist.
+[Editor's note: The following doesn't have the correct format for this
+wording. The reorganization is mechanical, so I didn't do it until we've
+reviewed this version.]
 
 Is_Simple_Name returns True if Name is a simple name. Is_Root_Directory returns True
 if Name is syntactically a root (a directory that cannot be decomposed further).
 
 AARM Note: For Unix, "/" is the root. For Windows, "C:\" and "\\Computer\Share"
 are roots.
+
+Is_Parent_Directory_Name returns True if Name indicates the parent directory of
+any directory, and False otherwise.
+
+AARM Note: Is_Parent_Directory_Name returns True if and only if Name is ".." for
+both Unix and Windows.
 
-Is_Relative_Indicator returns True if Name indicates navigation within the
-directory hierarchy.
+Is_Current_Directory_Name returns True if Name indicates the current directory for
+any directory, and False otherwise.
 
-AARM Note: "." and ".." are relative indicators for both Unix and Windows.
+AARM Note: Is_Current_Directory_Name returns True if and only if Name is "." for
+both Unix and Windows.
 
 Is_Full_Name is true if the leftmost directory part of Name is a root.
-Is_Relative_Name is true if the leftmost directory part of Name is a relative
-indicator. Is_Fragment is true if Name has proper syntax but is not a 
-simple name, full name, or relative name.
+Is_Relative_Name is true if Name has proper syntax but is not a full name.
 
+AARM Note: Relative names include simple names as a special case.
+
 Full_Name, Simple_Name, Extension, and Base_Name work the same as they do in
 Ada.Directories.
 
 Containing_Directory returns the Containing_Directory; it raises Use_Error
 if Name does not identify a containing directory (this includes if
-any of Is_Simple_Name, Is_Root_Directory, or Is_Relative_Indicator are True).
+any of Is_Simple_Name, Is_Root_Directory, Is_Parent_Directory_Name, or
+Is_Current_Directory_Name are True).
 
 Initial_Directory returns the leftmost directory part in Name. (That is
-generally a root (for a full name), relative indicator (for a relative name),
-or a simple name (for a fragment)).
+generally a root (for a full name), or one of a parent directory name,
+a current directory name, or a simple name (for a relative name)).
+
+Relative_Name returns the entire name except the Initial_Directory portion;
+it raises Name_Error if Name does not identify a file name or has a
+single part (this includes if any of Is_Simple_Name, Is_Root_Directory,
+Is_Parent_Directory_Name, or Is_Current_Directory_Name are True).
 
-Fragment returns the entire name except the Initial_Directory portion.
+AARM Note: This might be a simple name.
 
 All of the above non-predicates raise Name_Error if the name cannot be
 interpreted as a file name.
 
-Compose combines the Directory, Fragment, and Extension. The Fragment
-must be a fragment or simple name (relative indicators in the middle of
-paths are a significant security problem), else Name_Error is raised.
+Compose combines the Directory, Relative_Name, and Extension. The Relative_Name
+cannot be a full name, else Name_Error is raised.
 The Directory can be any sort of name, but Name_Error is raised if
 all six predicates would return False. The extension has to represent
 an extension (if not null), else Name_Error is raised.
 
-AARM Note: There is a set of requirements on what the result is given
-various inputs. For instance, combining a fragment and a simple name
-gives another fragment. See e-mail of Mar 29, 2007 for the details -
-it not shown here yet.
-
-!wording
+The result of Compose is a full name if Directory is a Full_Name (including
+a root directory). The result of Compose is a relative name otherwise.
 
-(** TBD **)
+AARM Note: A common security problem is to include a parent directory
+name in the middle of a file name; this is often used to navigate outside
+of an intended root directory. We considered attempting to prevent that
+case by having Compose detect it and raise an exception. But the extra
+rules necessary were more confusing than helpful.
+
+We can say more about the details of these operations by adopting the notation of
+a subscript to specify how many path fragments a particular result has.
+Then, we can abbreviate "Full Name" as "Full" and "Relative Name" as "Rel".
+In this notation, "a/b" is a Rel(2), "../c/d" is a Rel(3), and "/a/b" is
+a Full(2) [for Unix]. Rel(1) is equivalent to a simple name; thus we
+don't have to describe that separately.
+
+In this notation,
+    For N>1,
+    Containing_Directory(Rel(N)) = Leftmost Rel(N-1),
+    Containing_Directory(Full(N)) = Leftmost Full(N-1),
+    Name_Error if N = 1 in the above.
+
+Similarly,
+    For N>1,
+    Relative_Name(Rel(N)) = Rightmost Rel(N-1),
+    Relative_Name(Full(N)) = Rightmost Full(N-1),
+    Name_Error if N = 1 in the above.
+
+Finally, for Compose (ignoring the extension here):
+
+    Compose (Directory => Full(N), Relative_Name => Rel(M)) => Full(N+M)
+    Compose (Directory => Rel(N), Relative_Name => Rel(M)) => Rel(N+M)
+    Name_Error is Relative_Name is a Full(M).
+
+We didn't try to write wording to reflect these rules, but this is the
+intent.
+End AARM Notes.
+
+Implementation Advice
+
+Directories.Hierarchical_File_Names should be provided for systems with
+hierarchical file naming, and should not be provided on other systems.
+
+AARM Note: This package should be provided on Microsoft Windows, Unix,
+Linux, and most Unix-like systems.
+
+[Editor: The following is a user note, similar to A.16(127/2).]
+
+NOTES: These operations operate on file names, not external files. The
+files identified by these operations do not need to exist. Name_Error is
+raised only as specified or if the file name is malformed and cannot
+possibly identify a file. The result of these operations depends only
+on their parameters.
 
 !discussion
 
@@ -138,36 +242,33 @@
 
 The function Is_Root_Directory provides the solution to problem (2).
 
-Case sensitivity:
+The function Name_Case_Equivalence provides some assistance to problem (3).
 
-It would be nice to provide some case sensitivity help for file name
-construction. Unfortunately, it is hard to find anything workable.
-
-One suggestion has been file name comparison facilities that presumably
-would adjust to the appropriate target semantics. Unfortunately,
+We do not provide file name comparison facilities that adjust to the
+appropriate target semantics. This is an appealing idea, but unfortunately,
 Microsoft recommends that Windows programmers not attempt to compare
 file names. That's because the case-sensitity used is locale-dependent,
 and the locale of a file system is set when it is created: it is not
-necessarily that of the host operating system. (That's even more of a
-problem across networks.) Windows does not provide an API for this purpose.
+necessarily the same as that of the host operating system. (That's even more
+of a problem across networks.) Windows does not provide an API for this
+purpose.
 
 We could ignore this problem by saying that the comparison only works for
 Latin-1 file names. But that is obnoxious as Windows (and other systems)
 supports full Unicode file naming.
-
-An alternative would be to provide a file name normalization function. However,
-normalization can only be done on Windows for files that actually exist (the
-idea is that you look up and return the actual case used by the existing file).
-That does not work in this context (of file name construction) as we want to
-support building names of files that we haven't yet created.
-
 
+Similarly, we don't provide a file name normalization function, which would
+be an alternative. However, normalization can only be done on Windows for files
+that actually exist (the idea is that you look up and return the actual case
+used by the existing file). That does not work in this context (of file name
+construction) as we want to support building names of files that we haven't
+yet created.
 
 !example
 
 !ACATS test
 
-Create an ACATS test to check that the above changes work.
+Create an ACATS test to check that the above new facilities work.
 
 !appendix
 

Questions? Ask the ACAA Technical Agent