1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2023, Free Software Foundation, Inc. --
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. 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 COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
27 with Osint
.C
; use Osint
.C
;
28 with Stringt
; use Stringt
;
30 package body Lib
.Util
is
32 Max_Line
: constant Natural := 2 * Hostparm
.Max_Name_Length
+ 64;
33 Max_Buffer
: constant Natural := 1000 * Max_Line
;
35 Info_Buffer
: String (1 .. Max_Buffer
);
36 -- Info_Buffer used to prepare lines of library output
38 Info_Buffer_Len
: Natural := 0;
39 -- Number of characters stored in Info_Buffer
41 Info_Buffer_Col
: Natural := 1;
42 -- Column number of next character to be written.
43 -- Can be different from Info_Buffer_Len + 1 because of tab characters
44 -- written by Write_Info_Tab.
46 procedure Write_Info_Hex_Byte
(J
: Natural);
47 -- Place two hex digits representing the value J (which is in the range
48 -- 0-255) in Info_Buffer, incrementing Info_Buffer_Len by 2. The digits
49 -- are output using lower case letters.
55 procedure Write_Info_Char
(C
: Character) is
57 Info_Buffer_Len
:= Info_Buffer_Len
+ 1;
58 Info_Buffer
(Info_Buffer_Len
) := C
;
59 Info_Buffer_Col
:= Info_Buffer_Col
+ 1;
62 --------------------------
63 -- Write_Info_Char_Code --
64 --------------------------
66 procedure Write_Info_Char_Code
(Code
: Char_Code
) is
70 if Code
<= 16#
7F#
then
71 Write_Info_Char
(Character'Val (Code
));
75 elsif Code
<= 16#FF#
then
76 Write_Info_Char
('U');
77 Write_Info_Hex_Byte
(Natural (Code
));
82 Write_Info_Char
('W');
83 Write_Info_Hex_Byte
(Natural (Code
/ 256));
84 Write_Info_Hex_Byte
(Natural (Code
mod 256));
86 end Write_Info_Char_Code
;
92 function Write_Info_Col
return Positive is
94 return Info_Buffer_Col
;
101 procedure Write_Info_EOL
is
103 if Info_Buffer_Len
+ Max_Line
+ 1 > Max_Buffer
then
104 Write_Info_Terminate
;
107 -- Delete any trailing blanks
109 while Info_Buffer_Len
> 0
110 and then Info_Buffer
(Info_Buffer_Len
) = ' '
112 Info_Buffer_Len
:= Info_Buffer_Len
- 1;
115 Info_Buffer_Len
:= Info_Buffer_Len
+ 1;
116 Info_Buffer
(Info_Buffer_Len
) := ASCII
.LF
;
117 Info_Buffer_Col
:= 1;
121 -------------------------
122 -- Write_Info_Hex_Byte --
123 -------------------------
125 procedure Write_Info_Hex_Byte
(J
: Natural) is
126 Hexd
: constant array (0 .. 15) of Character := "0123456789abcdef";
128 Write_Info_Char
(Hexd
(J
/ 16));
129 Write_Info_Char
(Hexd
(J
mod 16));
130 end Write_Info_Hex_Byte
;
132 -------------------------
133 -- Write_Info_Initiate --
134 -------------------------
136 procedure Write_Info_Initiate
(Key
: Character) renames Write_Info_Char
;
142 procedure Write_Info_Int
(N
: Int
) is
147 -- Negative numbers, use Write_Info_Uint to avoid problems with largest
151 Write_Info_Uint
(UI_From_Int
(N
));
155 ---------------------
156 -- Write_Info_Name --
157 ---------------------
159 procedure Write_Info_Name
(Name
: Name_Id
) is
161 Get_Name_String
(Name
);
162 Info_Buffer
(Info_Buffer_Len
+ 1 .. Info_Buffer_Len
+ Name_Len
) :=
163 Name_Buffer
(1 .. Name_Len
);
164 Info_Buffer_Len
:= Info_Buffer_Len
+ Name_Len
;
165 Info_Buffer_Col
:= Info_Buffer_Col
+ Name_Len
;
168 procedure Write_Info_Name
(Name
: File_Name_Type
) is
170 Write_Info_Name
(Name_Id
(Name
));
173 procedure Write_Info_Name
(Name
: Unit_Name_Type
) is
175 Write_Info_Name
(Name_Id
(Name
));
178 -----------------------------------
179 -- Write_Info_Name_May_Be_Quoted --
180 -----------------------------------
182 procedure Write_Info_Name_May_Be_Quoted
(Name
: File_Name_Type
) is
183 Quoted
: Boolean := False;
187 Get_Name_String
(Name
);
189 -- The file/path name is quoted only if it includes spaces
191 for J
in 1 .. Name_Len
loop
192 if Name_Buffer
(J
) = ' ' then
198 -- Deal with quoting string if needed
201 Insert_Str_In_Name_Buffer
("""", 1);
202 Add_Char_To_Name_Buffer
('"');
204 -- Any character '"' is doubled
207 while Cur
< Name_Len
loop
208 if Name_Buffer
(Cur
) = '"' then
209 Insert_Str_In_Name_Buffer
("""", Cur
);
217 Info_Buffer
(Info_Buffer_Len
+ 1 .. Info_Buffer_Len
+ Name_Len
) :=
218 Name_Buffer
(1 .. Name_Len
);
219 Info_Buffer_Len
:= Info_Buffer_Len
+ Name_Len
;
220 Info_Buffer_Col
:= Info_Buffer_Col
+ Name_Len
;
221 end Write_Info_Name_May_Be_Quoted
;
227 procedure Write_Info_Nat
(N
: Nat
) is
230 Write_Info_Nat
(N
/ 10);
233 Write_Info_Char
(Character'Val (N
mod 10 + Character'Pos ('0')));
236 ---------------------
237 -- Write_Info_Slit --
238 ---------------------
240 procedure Write_Info_Slit
(S
: String_Id
) is
244 Write_Info_Str
("""");
246 for J
in 1 .. String_Length
(S
) loop
247 C
:= Get_Character
(Get_String_Char
(S
, J
));
249 if C
in Character'Val (16#
20#
) .. Character'Val (16#
7E#
)
259 Write_Info_Char
('{');
260 Write_Info_Hex_Byte
(Character'Pos (C
));
261 Write_Info_Char
('}');
265 Write_Info_Char
('"');
272 procedure Write_Info_Str
(Val
: String) is
274 Info_Buffer
(Info_Buffer_Len
+ 1 .. Info_Buffer_Len
+ Val
'Length)
276 Info_Buffer_Len
:= Info_Buffer_Len
+ Val
'Length;
277 Info_Buffer_Col
:= Info_Buffer_Col
+ Val
'Length;
284 procedure Write_Info_Tab
(Col
: Positive) is
288 if Col
<= Info_Buffer_Col
then
289 Write_Info_Str
(" ");
292 Next_Tab
:= 8 * ((Info_Buffer_Col
- 1) / 8) + 8 + 1;
293 exit when Col
< Next_Tab
;
294 Write_Info_Char
(ASCII
.HT
);
295 Info_Buffer_Col
:= Next_Tab
;
298 while Info_Buffer_Col
< Col
loop
299 Write_Info_Char
(' ');
304 --------------------------
305 -- Write_Info_Terminate --
306 --------------------------
308 procedure Write_Info_Terminate
is
310 -- Delete any trailing blanks
312 while Info_Buffer_Len
> 0
313 and then Info_Buffer
(Info_Buffer_Len
) = ' '
315 Info_Buffer_Len
:= Info_Buffer_Len
- 1;
318 -- Write_Library_Info adds the EOL
320 Write_Library_Info
(Info_Buffer
(1 .. Info_Buffer_Len
));
322 Info_Buffer_Len
:= 0;
323 Info_Buffer_Col
:= 1;
324 end Write_Info_Terminate
;
326 ---------------------
327 -- Write_Info_Uint --
328 ---------------------
330 procedure Write_Info_Uint
(N
: Uint
) is
332 UI_Image
(N
, Decimal
);
333 Write_Info_Str
(UI_Image_Buffer
(1 .. UI_Image_Length
));