1------------------------------------------------------------------------------ 2-- -- 3-- GNAT COMPILER COMPONENTS -- 4-- -- 5-- G N A T . D I R E C T O R Y _ O P E R A T I O N S -- 6-- -- 7-- S p e c -- 8-- -- 9-- Copyright (C) 1998-2010, AdaCore -- 10-- -- 11-- GNAT is free software; you can redistribute it and/or modify it under -- 12-- terms of the GNU General Public License as published by the Free Soft- -- 13-- ware Foundation; either version 3, or (at your option) any later ver- -- 14-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- 15-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- 16-- or FITNESS FOR A PARTICULAR PURPOSE. -- 17-- -- 18-- As a special exception under Section 7 of GPL version 3, you are granted -- 19-- additional permissions described in the GCC Runtime Library Exception, -- 20-- version 3.1, as published by the Free Software Foundation. -- 21-- -- 22-- You should have received a copy of the GNU General Public License and -- 23-- a copy of the GCC Runtime Library Exception along with this program; -- 24-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- 25-- <http://www.gnu.org/licenses/>. -- 26-- -- 27-- GNAT was originally developed by the GNAT team at New York University. -- 28-- Extensive contributions were provided by Ada Core Technologies Inc. -- 29-- -- 30------------------------------------------------------------------------------ 31 32-- Directory operations 33 34-- This package provides routines for manipulating directories. A directory 35-- can be treated as a file, using open and close routines, and a scanning 36-- routine is provided for iterating through the entries in a directory. 37 38-- See also child package GNAT.Directory_Operations.Iteration 39 40-- Note: support on OpenVMS is limited to the support of Unix-style 41-- directory names (OpenVMS native directory format is not supported). 42-- Read individual entries for more specific notes on OpenVMS support. 43 44with System; 45with Ada.Strings.Maps; 46 47package GNAT.Directory_Operations is 48 49 subtype Dir_Name_Str is String; 50 -- A subtype used in this package to represent string values that are 51 -- directory names. A directory name is a prefix for files that appear 52 -- with in the directory. This means that for UNIX systems, the string 53 -- includes a final '/', and for DOS-like systems, it includes a final 54 -- '\' character. It can also include drive letters if the operating 55 -- system provides for this. The final '/' or '\' in a Dir_Name_Str is 56 -- optional when passed as a procedure or function in parameter. 57 -- On OpenVMS, only Unix style path names are supported, not VMS style, 58 -- but the directory and file names are not case sensitive. 59 60 type Dir_Type is limited private; 61 -- A value used to reference a directory. Conceptually this value includes 62 -- the identity of the directory, and a sequential position within it. 63 64 Null_Dir : constant Dir_Type; 65 -- Represent the value for an uninitialized or closed directory 66 67 Directory_Error : exception; 68 -- Exception raised if the directory cannot be opened, read, closed, 69 -- created or if it is not possible to change the current execution 70 -- environment directory. 71 72 Dir_Separator : constant Character; 73 -- Running system default directory separator 74 75 -------------------------------- 76 -- Basic Directory operations -- 77 -------------------------------- 78 79 procedure Change_Dir (Dir_Name : Dir_Name_Str); 80 -- Changes the working directory of the current execution environment 81 -- to the directory named by Dir_Name. Raises Directory_Error if Dir_Name 82 -- does not exist. 83 84 procedure Make_Dir (Dir_Name : Dir_Name_Str); 85 -- Create a new directory named Dir_Name. Raises Directory_Error if 86 -- Dir_Name cannot be created. 87 88 procedure Remove_Dir 89 (Dir_Name : Dir_Name_Str; 90 Recursive : Boolean := False); 91 -- Remove the directory named Dir_Name. If Recursive is set to True, then 92 -- Remove_Dir removes all the subdirectories and files that are in 93 -- Dir_Name. Raises Directory_Error if Dir_Name cannot be removed. 94 95 function Get_Current_Dir return Dir_Name_Str; 96 -- Returns the current working directory for the execution environment 97 98 procedure Get_Current_Dir (Dir : out Dir_Name_Str; Last : out Natural); 99 -- Returns the current working directory for the execution environment 100 -- The name is returned in Dir_Name. Last is the index in Dir_Name such 101 -- that Dir_Name (Last) is the last character written. If Dir_Name is 102 -- too small for the directory name, the name will be truncated before 103 -- being copied to Dir_Name. 104 105 ------------------------- 106 -- Pathname Operations -- 107 ------------------------- 108 109 subtype Path_Name is String; 110 -- All routines using Path_Name handle both styles (UNIX and DOS) of 111 -- directory separators (either slash or back slash). 112 113 function Dir_Name (Path : Path_Name) return Dir_Name_Str; 114 -- Returns directory name for Path. This is similar to the UNIX dirname 115 -- command. Everything after the last directory separator is removed. If 116 -- there is no directory separator the current working directory is 117 -- returned. Note that the contents of Path is case-sensitive on 118 -- systems that have case-sensitive file names (like Unix), and 119 -- non-case-sensitive on systems where the file system is also non- 120 -- case-sensitive (such as Windows, and OpenVMS). 121 122 function Base_Name 123 (Path : Path_Name; 124 Suffix : String := "") return String; 125 -- Any directory prefix is removed. A directory prefix is defined as 126 -- text up to and including the last directory separator character in 127 -- the input string. In addition if Path ends with the string given for 128 -- Suffix, then it is also removed. Note that Suffix here can be an 129 -- arbitrary string (it is not required to be a file extension). This 130 -- is equivalent to the UNIX basename command. The following rule is 131 -- always true: 132 -- 133 -- 'Path' and 'Dir_Name (Path) & Dir_Separator & Base_Name (Path)' 134 -- represent the same file. 135 -- 136 -- The comparison of Suffix is case-insensitive on systems such as Windows 137 -- and VMS where the file search is case-insensitive (e.g. on such systems, 138 -- Base_Name ("/Users/AdaCore/BB12.patch", ".Patch") returns "BB12"). 139 -- 140 -- Note that the index bounds of the result match the corresponding indexes 141 -- in the Path string (you cannot assume that the lower bound of the 142 -- returned string is one). 143 144 function File_Extension (Path : Path_Name) return String; 145 -- Return the file extension. This is defined as the string after the 146 -- last dot, including the dot itself. For example, if the file name 147 -- is "file1.xyz.adq", then the returned value would be ".adq". If no 148 -- dot is present in the file name, or the last character of the file 149 -- name is a dot, then the null string is returned. 150 151 function File_Name (Path : Path_Name) return String; 152 -- Returns the file name and the file extension if present. It removes all 153 -- path information. This is equivalent to Base_Name with default Extension 154 -- value. 155 156 type Path_Style is (UNIX, DOS, System_Default); 157 function Format_Pathname 158 (Path : Path_Name; 159 Style : Path_Style := System_Default) return Path_Name; 160 -- Removes all double directory separator and converts all '\' to '/' if 161 -- Style is UNIX and converts all '/' to '\' if Style is set to DOS. This 162 -- function will help to provide a consistent naming scheme running for 163 -- different environments. If style is set to System_Default the routine 164 -- will use the default directory separator on the running environment. 165 -- 166 -- The Style argument indicates the syntax to be used for path names: 167 -- 168 -- UNIX 169 -- Use '/' as the directory separator. The default on Unix systems 170 -- and on OpenVMS. 171 -- 172 -- DOS 173 -- Use '\' as the directory separator. The default on Windows. 174 -- 175 -- System_Default 176 -- Use the default style for the current system 177 178 type Environment_Style is (UNIX, DOS, Both, System_Default); 179 function Expand_Path 180 (Path : Path_Name; 181 Mode : Environment_Style := System_Default) return Path_Name; 182 -- Returns Path with environment variables (or logical names on OpenVMS) 183 -- replaced by the current environment variable value. For example, 184 -- $HOME/mydir will be replaced by /home/joe/mydir if $HOME environment 185 -- variable is set to /home/joe and Mode is UNIX. If an environment 186 -- variable does not exists the variable will be replaced by the empty 187 -- string. Two dollar or percent signs are replaced by a single 188 -- dollar/percent sign. Note that a variable must start with a letter. 189 -- 190 -- The Mode argument indicates the recognized syntax for environment 191 -- variables as follows: 192 -- 193 -- UNIX 194 -- Environment variables and OpenVMS logical names use $ as prefix and 195 -- can use curly brackets as in ${HOME}/mydir. If there is no closing 196 -- curly bracket for an opening one then no translation is done, so for 197 -- example ${VAR/toto is returned as ${VAR/toto. The use of {} brackets 198 -- is required if the environment variable name contains other than 199 -- alphanumeric characters. 200 -- 201 -- DOS 202 -- Environment variables uses % as prefix and suffix (e.g. %HOME%/dir). 203 -- The name DOS refer to "DOS-like" environment. This includes all 204 -- Windows systems. 205 -- 206 -- Both 207 -- Recognize both forms described above. 208 -- 209 -- System_Default 210 -- Uses either UNIX on Unix and OpenVMS systems, or DOS on Windows, 211 -- depending on the running environment. What about other OS's??? 212 213 --------------- 214 -- Iterators -- 215 --------------- 216 217 procedure Open (Dir : out Dir_Type; Dir_Name : Dir_Name_Str); 218 -- Opens the directory named by Dir_Name and returns a Dir_Type value 219 -- that refers to this directory, and is positioned at the first entry. 220 -- Raises Directory_Error if Dir_Name cannot be accessed. In that case 221 -- Dir will be set to Null_Dir. 222 223 procedure Close (Dir : in out Dir_Type); 224 -- Closes the directory stream referred to by Dir. After calling Close 225 -- Is_Open will return False. Dir will be set to Null_Dir. 226 -- Raises Directory_Error if Dir has not be opened (Dir = Null_Dir). 227 228 function Is_Open (Dir : Dir_Type) return Boolean; 229 -- Returns True if Dir is open, or False otherwise 230 231 procedure Read 232 (Dir : Dir_Type; 233 Str : out String; 234 Last : out Natural); 235 -- Reads the next entry from the directory and sets Str to the name 236 -- of that entry. Last is the index in Str such that Str (Last) is the 237 -- last character written. Last is 0 when there are no more files in the 238 -- directory. If Str is too small for the file name, the file name will 239 -- be truncated before being copied to Str. The list of files returned 240 -- includes directories in systems providing a hierarchical directory 241 -- structure, including . (the current directory) and .. (the parent 242 -- directory) in systems providing these entries. The directory is 243 -- returned in target-OS form. Raises Directory_Error if Dir has not 244 -- be opened (Dir = Null_Dir). 245 246 function Read_Is_Thread_Safe return Boolean; 247 -- Indicates if procedure Read is thread safe. On systems where the 248 -- target system supports this functionality, Read is thread safe, 249 -- and this function returns True (e.g. this will be the case on any 250 -- UNIX or UNIX-like system providing a correct implementation of the 251 -- function readdir_r). If the system cannot provide a thread safe 252 -- implementation of Read, then this function returns False. 253 254private 255 256 type Dir_Type_Value is new System.Address; 257 -- Low-level address directory structure as returned by opendir in C 258 -- 259 -- Note that we used to define this type in the body of this package, 260 -- but this was causing troubles in the context of .NET code generation 261 -- (because Taft amendment types are not fully implemented and cause 262 -- undefined references to the class), so we moved the type declaration 263 -- to the spec's private part, which is no problem in any case here. 264 265 type Dir_Type is access Dir_Type_Value; 266 267 Null_Dir : constant Dir_Type := null; 268 269 pragma Import (C, Dir_Separator, "__gnat_dir_separator"); 270 271 Dir_Seps : constant Ada.Strings.Maps.Character_Set := 272 Ada.Strings.Maps.To_Set ("/\"); 273 -- UNIX and DOS style directory separators 274 275end GNAT.Directory_Operations; 276