* sh.h (REG_CLASS_FROM_LETTER): Change to:
[official-gcc.git] / gcc / ada / prj-util.adb
blob15d7360c2a4f115ef62b88d438f88b2783f2ac5f
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- P R J . U T I L --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2001 Free Software Foundation, Inc. --
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 2, 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. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, USA. --
21 -- --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 -- --
25 ------------------------------------------------------------------------------
27 with Ada.Unchecked_Deallocation;
29 with Namet; use Namet;
30 with Osint;
31 with Output; use Output;
32 with Stringt; use Stringt;
34 package body Prj.Util is
36 procedure Free is new Ada.Unchecked_Deallocation
37 (Text_File_Data, Text_File);
39 -----------
40 -- Close --
41 -----------
43 procedure Close (File : in out Text_File) is
44 begin
45 if File = null then
46 Osint.Fail ("Close attempted on an invalid Text_File");
47 end if;
49 Close (File.FD);
50 Free (File);
51 end Close;
53 -----------------
54 -- End_Of_File --
55 -----------------
57 function End_Of_File (File : Text_File) return Boolean is
58 begin
59 if File = null then
60 Osint.Fail ("End_Of_File attempted on an invalid Text_File");
61 end if;
63 return File.End_Of_File_Reached;
64 end End_Of_File;
66 --------------
67 -- Get_Line --
68 --------------
70 procedure Get_Line
71 (File : Text_File;
72 Line : out String;
73 Last : out Natural)
75 C : Character;
77 procedure Advance;
79 -------------
80 -- Advance --
81 -------------
83 procedure Advance is
84 begin
85 if File.Cursor = File.Buffer_Len then
86 File.Buffer_Len :=
87 Read
88 (FD => File.FD,
89 A => File.Buffer'Address,
90 N => File.Buffer'Length);
92 if File.Buffer_Len = 0 then
93 File.End_Of_File_Reached := True;
94 return;
95 else
96 File.Cursor := 1;
97 end if;
99 else
100 File.Cursor := File.Cursor + 1;
101 end if;
102 end Advance;
104 -- Start of processing for Get_Line
106 begin
107 if File = null then
108 Osint.Fail ("Get_Line attempted on an invalid Text_File");
109 end if;
111 Last := Line'First - 1;
113 if not File.End_Of_File_Reached then
114 loop
115 C := File.Buffer (File.Cursor);
116 exit when C = ASCII.CR or else C = ASCII.LF;
117 Last := Last + 1;
118 Line (Last) := C;
119 Advance;
121 if File.End_Of_File_Reached then
122 return;
123 end if;
125 exit when Last = Line'Last;
126 end loop;
128 if C = ASCII.CR or else C = ASCII.LF then
129 Advance;
131 if File.End_Of_File_Reached then
132 return;
133 end if;
134 end if;
136 if C = ASCII.CR
137 and then File.Buffer (File.Cursor) = ASCII.LF
138 then
139 Advance;
140 end if;
141 end if;
142 end Get_Line;
144 --------------
145 -- Is_Valid --
146 --------------
148 function Is_Valid (File : Text_File) return Boolean is
149 begin
150 return File /= null;
151 end Is_Valid;
153 ----------
154 -- Open --
155 ----------
157 procedure Open (File : out Text_File; Name : in String) is
158 FD : File_Descriptor;
159 File_Name : String (1 .. Name'Length + 1);
161 begin
162 File_Name (1 .. Name'Length) := Name;
163 File_Name (File_Name'Last) := ASCII.NUL;
164 FD := Open_Read (Name => File_Name'Address,
165 Fmode => GNAT.OS_Lib.Text);
166 if FD = Invalid_FD then
167 File := null;
168 else
169 File := new Text_File_Data;
170 File.FD := FD;
171 File.Buffer_Len :=
172 Read (FD => FD,
173 A => File.Buffer'Address,
174 N => File.Buffer'Length);
176 if File.Buffer_Len = 0 then
177 File.End_Of_File_Reached := True;
178 else
179 File.Cursor := 1;
180 end if;
181 end if;
182 end Open;
184 --------------
185 -- Value_Of --
186 --------------
188 function Value_Of
189 (Variable : Variable_Value;
190 Default : String)
191 return String
193 begin
194 if Variable.Kind /= Single
195 or else Variable.Default
196 or else Variable.Value = No_String then
197 return Default;
199 else
200 String_To_Name_Buffer (Variable.Value);
201 return Name_Buffer (1 .. Name_Len);
202 end if;
203 end Value_Of;
205 function Value_Of
206 (Index : Name_Id;
207 In_Array : Array_Element_Id)
208 return Name_Id
210 Current : Array_Element_Id := In_Array;
211 Element : Array_Element;
213 begin
214 while Current /= No_Array_Element loop
215 Element := Array_Elements.Table (Current);
217 if Index = Element.Index then
218 exit when Element.Value.Kind /= Single;
219 exit when String_Length (Element.Value.Value) = 0;
220 String_To_Name_Buffer (Element.Value.Value);
221 return Name_Find;
222 else
223 Current := Element.Next;
224 end if;
225 end loop;
227 return No_Name;
228 end Value_Of;
230 function Value_Of
231 (Index : Name_Id;
232 In_Array : Array_Element_Id)
233 return Variable_Value
235 Current : Array_Element_Id := In_Array;
236 Element : Array_Element;
238 begin
239 while Current /= No_Array_Element loop
240 Element := Array_Elements.Table (Current);
242 if Index = Element.Index then
243 return Element.Value;
244 else
245 Current := Element.Next;
246 end if;
247 end loop;
249 return Nil_Variable_Value;
250 end Value_Of;
252 function Value_Of
253 (Name : Name_Id;
254 Attribute_Or_Array_Name : Name_Id;
255 In_Package : Package_Id)
256 return Variable_Value
258 The_Array : Array_Element_Id;
259 The_Attribute : Variable_Value := Nil_Variable_Value;
261 begin
262 if In_Package /= No_Package then
264 -- First, look if there is an array element that fits
266 The_Array :=
267 Value_Of
268 (Name => Attribute_Or_Array_Name,
269 In_Arrays => Packages.Table (In_Package).Decl.Arrays);
270 The_Attribute :=
271 Value_Of
272 (Index => Name,
273 In_Array => The_Array);
275 -- If there is no array element, look for a variable
277 if The_Attribute = Nil_Variable_Value then
278 The_Attribute :=
279 Value_Of
280 (Variable_Name => Attribute_Or_Array_Name,
281 In_Variables => Packages.Table (In_Package).Decl.Attributes);
282 end if;
283 end if;
285 return The_Attribute;
286 end Value_Of;
288 function Value_Of
289 (Index : Name_Id;
290 In_Array : Name_Id;
291 In_Arrays : Array_Id)
292 return Name_Id
294 Current : Array_Id := In_Arrays;
295 The_Array : Array_Data;
297 begin
298 while Current /= No_Array loop
299 The_Array := Arrays.Table (Current);
300 if The_Array.Name = In_Array then
301 return Value_Of (Index, In_Array => The_Array.Value);
302 else
303 Current := The_Array.Next;
304 end if;
305 end loop;
307 return No_Name;
308 end Value_Of;
310 function Value_Of
311 (Name : Name_Id;
312 In_Arrays : Array_Id)
313 return Array_Element_Id
315 Current : Array_Id := In_Arrays;
316 The_Array : Array_Data;
318 begin
319 while Current /= No_Array loop
320 The_Array := Arrays.Table (Current);
322 if The_Array.Name = Name then
323 return The_Array.Value;
324 else
325 Current := The_Array.Next;
326 end if;
327 end loop;
329 return No_Array_Element;
330 end Value_Of;
332 function Value_Of
333 (Name : Name_Id;
334 In_Packages : Package_Id)
335 return Package_Id
337 Current : Package_Id := In_Packages;
338 The_Package : Package_Element;
340 begin
341 while Current /= No_Package loop
342 The_Package := Packages.Table (Current);
343 exit when The_Package.Name /= No_Name
344 and then The_Package.Name = Name;
345 Current := The_Package.Next;
346 end loop;
348 return Current;
349 end Value_Of;
351 function Value_Of
352 (Variable_Name : Name_Id;
353 In_Variables : Variable_Id)
354 return Variable_Value
356 Current : Variable_Id := In_Variables;
357 The_Variable : Variable;
359 begin
360 while Current /= No_Variable loop
361 The_Variable := Variable_Elements.Table (Current);
363 if Variable_Name = The_Variable.Name then
364 return The_Variable.Value;
365 else
366 Current := The_Variable.Next;
367 end if;
368 end loop;
370 return Nil_Variable_Value;
371 end Value_Of;
373 ---------------
374 -- Write_Str --
375 ---------------
377 procedure Write_Str
378 (S : String;
379 Max_Length : Positive;
380 Separator : Character)
382 First : Positive := S'First;
383 Last : Natural := S'Last;
385 begin
386 -- Nothing to do for empty strings
388 if S'Length > 0 then
390 -- Start on a new line if current line is already longer than
391 -- Max_Length.
393 if Positive (Column) >= Max_Length then
394 Write_Eol;
395 end if;
397 -- If length of remainder is longer than Max_Length, we need to
398 -- cut the remainder in several lines.
400 while Positive (Column) + S'Last - First > Max_Length loop
402 -- Try the maximum length possible
404 Last := First + Max_Length - Positive (Column);
406 -- Look for last Separator in the line
408 while Last >= First and then S (Last) /= Separator loop
409 Last := Last - 1;
410 end loop;
412 -- If we do not find a separator, we output the maximum length
413 -- possible.
415 if Last < First then
416 Last := First + Max_Length - Positive (Column);
417 end if;
419 Write_Line (S (First .. Last));
421 -- Set the beginning of the new remainder
423 First := Last + 1;
424 end loop;
426 -- What is left goes to the buffer, without EOL
428 Write_Str (S (First .. S'Last));
429 end if;
430 end Write_Str;
432 end Prj.Util;