| ------------------------------------------------------------------------------ |
| -- -- |
| -- GNAT COMPILER COMPONENTS -- |
| -- -- |
| -- L I B . U T I L -- |
| -- -- |
| -- B o d y -- |
| -- -- |
| -- Copyright (C) 1992-2022, Free Software Foundation, Inc. -- |
| -- -- |
| -- GNAT is free software; you can redistribute it and/or modify it under -- |
| -- terms of the GNU General Public License as published by the Free Soft- -- |
| -- ware Foundation; either version 3, or (at your option) any later ver- -- |
| -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- |
| -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- |
| -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- |
| -- for more details. You should have received a copy of the GNU General -- |
| -- Public License distributed with GNAT; see file COPYING3. If not, go to -- |
| -- http://www.gnu.org/licenses for a complete copy of the license. -- |
| -- -- |
| -- GNAT was originally developed by the GNAT team at New York University. -- |
| -- Extensive contributions were provided by Ada Core Technologies Inc. -- |
| -- -- |
| ------------------------------------------------------------------------------ |
| |
| with Hostparm; |
| with Osint.C; use Osint.C; |
| with Stringt; use Stringt; |
| |
| package body Lib.Util is |
| |
| Max_Line : constant Natural := 2 * Hostparm.Max_Name_Length + 64; |
| Max_Buffer : constant Natural := 1000 * Max_Line; |
| |
| Info_Buffer : String (1 .. Max_Buffer); |
| -- Info_Buffer used to prepare lines of library output |
| |
| Info_Buffer_Len : Natural := 0; |
| -- Number of characters stored in Info_Buffer |
| |
| Info_Buffer_Col : Natural := 1; |
| -- Column number of next character to be written. |
| -- Can be different from Info_Buffer_Len + 1 because of tab characters |
| -- written by Write_Info_Tab. |
| |
| procedure Write_Info_Hex_Byte (J : Natural); |
| -- Place two hex digits representing the value J (which is in the range |
| -- 0-255) in Info_Buffer, incrementing Info_Buffer_Len by 2. The digits |
| -- are output using lower case letters. |
| |
| --------------------- |
| -- Write_Info_Char -- |
| --------------------- |
| |
| procedure Write_Info_Char (C : Character) is |
| begin |
| Info_Buffer_Len := Info_Buffer_Len + 1; |
| Info_Buffer (Info_Buffer_Len) := C; |
| Info_Buffer_Col := Info_Buffer_Col + 1; |
| end Write_Info_Char; |
| |
| -------------------------- |
| -- Write_Info_Char_Code -- |
| -------------------------- |
| |
| procedure Write_Info_Char_Code (Code : Char_Code) is |
| begin |
| -- 00 .. 7F |
| |
| if Code <= 16#7F# then |
| Write_Info_Char (Character'Val (Code)); |
| |
| -- 80 .. FF |
| |
| elsif Code <= 16#FF# then |
| Write_Info_Char ('U'); |
| Write_Info_Hex_Byte (Natural (Code)); |
| |
| -- 0100 .. FFFF |
| |
| else |
| Write_Info_Char ('W'); |
| Write_Info_Hex_Byte (Natural (Code / 256)); |
| Write_Info_Hex_Byte (Natural (Code mod 256)); |
| end if; |
| end Write_Info_Char_Code; |
| |
| -------------------- |
| -- Write_Info_Col -- |
| -------------------- |
| |
| function Write_Info_Col return Positive is |
| begin |
| return Info_Buffer_Col; |
| end Write_Info_Col; |
| |
| -------------------- |
| -- Write_Info_EOL -- |
| -------------------- |
| |
| procedure Write_Info_EOL is |
| begin |
| if Info_Buffer_Len + Max_Line + 1 > Max_Buffer then |
| Write_Info_Terminate; |
| |
| else |
| -- Delete any trailing blanks |
| |
| while Info_Buffer_Len > 0 |
| and then Info_Buffer (Info_Buffer_Len) = ' ' |
| loop |
| Info_Buffer_Len := Info_Buffer_Len - 1; |
| end loop; |
| |
| Info_Buffer_Len := Info_Buffer_Len + 1; |
| Info_Buffer (Info_Buffer_Len) := ASCII.LF; |
| Info_Buffer_Col := 1; |
| end if; |
| end Write_Info_EOL; |
| |
| ------------------------- |
| -- Write_Info_Hex_Byte -- |
| ------------------------- |
| |
| procedure Write_Info_Hex_Byte (J : Natural) is |
| Hexd : constant array (0 .. 15) of Character := "0123456789abcdef"; |
| begin |
| Write_Info_Char (Hexd (J / 16)); |
| Write_Info_Char (Hexd (J mod 16)); |
| end Write_Info_Hex_Byte; |
| |
| ------------------------- |
| -- Write_Info_Initiate -- |
| ------------------------- |
| |
| procedure Write_Info_Initiate (Key : Character) renames Write_Info_Char; |
| |
| -------------------- |
| -- Write_Info_Int -- |
| -------------------- |
| |
| procedure Write_Info_Int (N : Int) is |
| begin |
| if N >= 0 then |
| Write_Info_Nat (N); |
| |
| -- Negative numbers, use Write_Info_Uint to avoid problems with largest |
| -- negative number. |
| |
| else |
| Write_Info_Uint (UI_From_Int (N)); |
| end if; |
| end Write_Info_Int; |
| |
| --------------------- |
| -- Write_Info_Name -- |
| --------------------- |
| |
| procedure Write_Info_Name (Name : Name_Id) is |
| begin |
| Get_Name_String (Name); |
| Info_Buffer (Info_Buffer_Len + 1 .. Info_Buffer_Len + Name_Len) := |
| Name_Buffer (1 .. Name_Len); |
| Info_Buffer_Len := Info_Buffer_Len + Name_Len; |
| Info_Buffer_Col := Info_Buffer_Col + Name_Len; |
| end Write_Info_Name; |
| |
| procedure Write_Info_Name (Name : File_Name_Type) is |
| begin |
| Write_Info_Name (Name_Id (Name)); |
| end Write_Info_Name; |
| |
| procedure Write_Info_Name (Name : Unit_Name_Type) is |
| begin |
| Write_Info_Name (Name_Id (Name)); |
| end Write_Info_Name; |
| |
| ----------------------------------- |
| -- Write_Info_Name_May_Be_Quoted -- |
| ----------------------------------- |
| |
| procedure Write_Info_Name_May_Be_Quoted (Name : File_Name_Type) is |
| Quoted : Boolean := False; |
| Cur : Positive; |
| |
| begin |
| Get_Name_String (Name); |
| |
| -- The file/path name is quoted only if it includes spaces |
| |
| for J in 1 .. Name_Len loop |
| if Name_Buffer (J) = ' ' then |
| Quoted := True; |
| exit; |
| end if; |
| end loop; |
| |
| -- Deal with quoting string if needed |
| |
| if Quoted then |
| Insert_Str_In_Name_Buffer ("""", 1); |
| Add_Char_To_Name_Buffer ('"'); |
| |
| -- Any character '"' is doubled |
| |
| Cur := 2; |
| while Cur < Name_Len loop |
| if Name_Buffer (Cur) = '"' then |
| Insert_Str_In_Name_Buffer ("""", Cur); |
| Cur := Cur + 2; |
| else |
| Cur := Cur + 1; |
| end if; |
| end loop; |
| end if; |
| |
| Info_Buffer (Info_Buffer_Len + 1 .. Info_Buffer_Len + Name_Len) := |
| Name_Buffer (1 .. Name_Len); |
| Info_Buffer_Len := Info_Buffer_Len + Name_Len; |
| Info_Buffer_Col := Info_Buffer_Col + Name_Len; |
| end Write_Info_Name_May_Be_Quoted; |
| |
| -------------------- |
| -- Write_Info_Nat -- |
| -------------------- |
| |
| procedure Write_Info_Nat (N : Nat) is |
| begin |
| if N > 9 then |
| Write_Info_Nat (N / 10); |
| end if; |
| |
| Write_Info_Char (Character'Val (N mod 10 + Character'Pos ('0'))); |
| end Write_Info_Nat; |
| |
| --------------------- |
| -- Write_Info_Slit -- |
| --------------------- |
| |
| procedure Write_Info_Slit (S : String_Id) is |
| C : Character; |
| |
| begin |
| Write_Info_Str (""""); |
| |
| for J in 1 .. String_Length (S) loop |
| C := Get_Character (Get_String_Char (S, J)); |
| |
| if C in Character'Val (16#20#) .. Character'Val (16#7E#) |
| and then C /= '{' |
| then |
| Write_Info_Char (C); |
| |
| if C = '"' then |
| Write_Info_Char (C); |
| end if; |
| |
| else |
| Write_Info_Char ('{'); |
| Write_Info_Hex_Byte (Character'Pos (C)); |
| Write_Info_Char ('}'); |
| end if; |
| end loop; |
| |
| Write_Info_Char ('"'); |
| end Write_Info_Slit; |
| |
| -------------------- |
| -- Write_Info_Str -- |
| -------------------- |
| |
| procedure Write_Info_Str (Val : String) is |
| begin |
| Info_Buffer (Info_Buffer_Len + 1 .. Info_Buffer_Len + Val'Length) |
| := Val; |
| Info_Buffer_Len := Info_Buffer_Len + Val'Length; |
| Info_Buffer_Col := Info_Buffer_Col + Val'Length; |
| end Write_Info_Str; |
| |
| -------------------- |
| -- Write_Info_Tab -- |
| -------------------- |
| |
| procedure Write_Info_Tab (Col : Positive) is |
| Next_Tab : Positive; |
| |
| begin |
| if Col <= Info_Buffer_Col then |
| Write_Info_Str (" "); |
| else |
| loop |
| Next_Tab := 8 * ((Info_Buffer_Col - 1) / 8) + 8 + 1; |
| exit when Col < Next_Tab; |
| Write_Info_Char (ASCII.HT); |
| Info_Buffer_Col := Next_Tab; |
| end loop; |
| |
| while Info_Buffer_Col < Col loop |
| Write_Info_Char (' '); |
| end loop; |
| end if; |
| end Write_Info_Tab; |
| |
| -------------------------- |
| -- Write_Info_Terminate -- |
| -------------------------- |
| |
| procedure Write_Info_Terminate is |
| begin |
| -- Delete any trailing blanks |
| |
| while Info_Buffer_Len > 0 |
| and then Info_Buffer (Info_Buffer_Len) = ' ' |
| loop |
| Info_Buffer_Len := Info_Buffer_Len - 1; |
| end loop; |
| |
| -- Write_Library_Info adds the EOL |
| |
| Write_Library_Info (Info_Buffer (1 .. Info_Buffer_Len)); |
| |
| Info_Buffer_Len := 0; |
| Info_Buffer_Col := 1; |
| end Write_Info_Terminate; |
| |
| --------------------- |
| -- Write_Info_Uint -- |
| --------------------- |
| |
| procedure Write_Info_Uint (N : Uint) is |
| begin |
| UI_Image (N, Decimal); |
| Write_Info_Str (UI_Image_Buffer (1 .. UI_Image_Length)); |
| end Write_Info_Uint; |
| |
| end Lib.Util; |