A.16.1 The Package Directories.Hierarchical_File_Names
1/3
{
AI05-0049-1}
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
2/3
{
AI05-0049-1}
If provided, the library package Directories.Hierarchical_File_Names
has the following declaration:
3/3
package Ada.Directories.Hierarchical_File_Names is
4/3
function Is_Simple_Name (Name : in String) return Boolean;
5/3
function Is_Root_Directory_Name (Name : in String) return Boolean;
6/3
function Is_Parent_Directory_Name (Name : in String) return Boolean;
7/3
function Is_Current_Directory_Name (Name : in String) return Boolean;
8/3
function Is_Full_Name (Name : in String) return Boolean;
9/3
function Is_Relative_Name (Name : in String) return Boolean;
10/3
function Simple_Name (Name : in String) return String
renames Ada.Directories.Simple_Name;
11/3
function Containing_Directory (Name : in String) return String
renames Ada.Directories.Containing_Directory;
12/3
function Initial_Directory (Name : in String) return String;
13/3
function Relative_Name (Name : in String) return String;
14/3
function Compose (Directory : in String := "";
Relative_Name : in String;
Extension : in String := "") return String;
15/3
end Ada.Directories.Hierarchical_File_Names;
16/3
{
AI05-0049-1}
In addition to the operations provided in package
Directories.Hierarchical_File_Names, operations in package Directories
can be used. In particular, functions Full_Name, Base_Name, and Extension
are usable with hierarchical file names.
17/3
function Is_Simple_Name (Name : in String) return Boolean;
18/3
Returns True if Name is
a simple name, and returns False otherwise.
19/3
function Is_Root_Directory_Name (Name : in String) return Boolean;
20/3
Returns True if Name is
syntactically a root (a directory that cannot be decomposed further),
and returns False otherwise.
20.a/3
Implementation Note:
For Unix and Unix-like systems, "/" is the root. For Windows,
"C:\" and "\\Computer\Share" are roots.
21/3
function Is_Parent_Directory_Name (Name : in String) return Boolean;
22/3
Returns True if Name can
be used to indicate symbolically the parent directory of any directory,
and returns False otherwise.
22.a/3
Implementation Note:
Is_Parent_Directory_Name returns True if and only if Name is ".."
for both Unix and Windows.
23/3
function Is_Current_Directory_Name (Name : in String) return Boolean;
24/3
Returns True if Name can
be used to indicate symbolically the directory itself for any directory,
and returns False otherwise.
24.a/3
Implementation Note:
Is_Current_Directory_Name returns True if and only if Name is "."
for both Unix and Windows.
25/3
function Is_Full_Name (Name : in String) return Boolean;
26/3
Returns True if the leftmost
directory part of Name is a root, and returns False otherwise.
27/3
function Is_Relative_Name (Name : in String) return Boolean;
28/3
Returns True if Name allows
the identification of an external file but is not a full name, and returns
False otherwise.
28.a/3
Ramification: Relative
names include simple names as a special case. This function returns False
if the syntax of the name is incorrect.
29/3
function Initial_Directory (Name : in String) return String;
30/3
{
AI05-0049-1}
{
AI05-0248-1}
Returns the leftmost directory part in Name. [That
is, it returns a root directory name (for a full name), or one of a parent
directory name, a current directory name, or a simple name (for a relative
name).] The exception Name_Error is propagated if the string given as
Name does not allow the identification of an external file (including
directories and special files).
31/3
function Relative_Name (Name : in String) return String;
32/3
Returns the entire file
name except the Initial_Directory portion. The exception Name_Error is
propagated if the string given as Name does not allow the identification
of an external file (including directories and special files), or if
Name has a single part (this includes if any of Is_Simple_Name, Is_Root_Directory_Name,
Is_Parent_Directory_Name, or Is_Current_Directory_Name are True).
32.a/3
Ramification: The
result might be a simple name.
33/3
function Compose (Directory : in String := "";
Relative_Name : in String;
Extension : in String := "") return String;
34/3
Returns the name of the
external file with the specified Directory, Relative_Name, and Extension.
The exception Name_Error is propagated if the string given as Directory
is not the null string and does not allow the identification of a directory,
or if Is_Relative_Name (Relative_Name) is False, or if the string given
as Extension is not the null string and is not a possible extension,
or if Extension is not the null string and Simple_Name (Relative_Name)
is not a base name.
35/3
The result of Compose is
a full name if Is_Full_Name (Directory) is True; result is a relative
name otherwise.
35.a/3
Ramification: Name_Error
is raised by Compose if Directory is not the null string, and both Is_Full_Name
and Is_Relative_Name return False.
35.b/3
Discussion: 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.
35.c/3
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, Unix file name "a/b"
is a Rel(2), "../c/d" is a Rel(3), and "/a/b" is
a Full(2). Rel(1) is equivalent to a simple name; thus we don't have
to describe that separately.
35.d/3
In
this notation,
35.e/3
For N>1,
Containing_Directory(Rel(N)) = Leftmost Rel(N-1),
Containing_Directory(Full(N)) = Leftmost Full(N-1),
Else if N = 1, raise Name_Error.
35.f/3
Similarly,
35.g/3
For N>1,
Relative_Name(Rel(N)) = Rightmost Rel(N-1),
Relative_Name(Full(N)) = Rightmost Full(N-1),
Else if N = 1, raise Name_Error.
35.h/3
Finally,
for Compose (ignoring the extension here):
35.i/3
Compose (Directory => Full(N), Relative_Name => Rel(M)) => Full(N+M)
Compose (Directory => Rel(N), Relative_Name => Rel(M)) => Rel(N+M)
Name_Error if Relative_Name is a Full(M).
35.j/3
We didn't try to write
wording to reflect these details of these functions.
Implementation Advice
36/3
{
AI05-0049-1}
Directories.Hierarchical_File_Names should be provided
for systems with hierarchical file naming, and should not be provided
on other systems.
36.a/3
Implementation Advice:
Directories.Hierarchical_File_Names
should be provided for systems with hierarchical file naming, and should
not be provided on other systems.
36.b/3
Implementation Note:
This package should be provided when targeting Microsoft® Windows®,
Unix, Linux, and most Unix-like systems.
37/3
46 {
AI05-0049-1}
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.
38/3
47 {
AI05-0049-1}
Containing_Directory raises Use_Error if Name does
not have a containing directory, including when any of Is_Simple_Name,
Is_Root_Directory_Name, Is_Parent_Directory_Name, or Is_Current_Directory_Name
are True.
Extensions to Ada 2005
38.a/3
{
AI05-0049-1}
Package Ada.Directories.Hierarchical_File_Names
is new.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe