home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Geek Gadgets 1
/
ADE-1.bin
/
ade-dist
/
gnat-2.06-src.tgz
/
tar.out
/
fsf
/
gnat
/
ada
/
stringt.adb
< prev
next >
Wrap
Text File
|
1996-09-28
|
9KB
|
302 lines
------------------------------------------------------------------------------
-- --
-- GNAT COMPILER COMPONENTS --
-- --
-- S T R I N G T --
-- --
-- B o d y --
-- --
-- $Revision: 1.28 $ --
-- --
-- Copyright (c) 1992,1993,1994,1995 NYU, All Rights Reserved --
-- --
-- The GNAT library is free software; you can redistribute it and/or modify --
-- it under terms of the GNU Library General Public License as published by --
-- the Free Software Foundation; either version 2, or (at your option) any --
-- later version. The GNAT library is distributed in the hope that it will --
-- be useful, but WITHOUT ANY WARRANTY; without even the implied warranty --
-- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --
-- Library General Public License for more details. You should have --
-- received a copy of the GNU Library General Public License along with --
-- the GNAT library; see the file COPYING.LIB. If not, write to the Free --
-- Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. --
-- --
------------------------------------------------------------------------------
with Alloc; use Alloc;
with Output; use Output;
package body Stringt is
-- The following table stores the sequence of character codes for the
-- stored string constants. The entries are referenced from the
-- separate Strings table.
package String_Chars is new Table (
Table_Component_Type => Char_Code,
Table_Index_Type => Int,
Table_Low_Bound => 0,
Table_Initial => Alloc_String_Chars_Initial,
Table_Increment => Alloc_String_Chars_Increment,
Table_Name => "String_Chars");
-- The String_Id values reference entries in the Strings table, which
-- contains String_Entry records that record the length of each stored
-- string and its starting location in the String_Chars table.
type String_Entry is record
String_Index : Int;
Length : Nat;
end record;
package Strings is new Table (
Table_Component_Type => String_Entry,
Table_Index_Type => String_Id,
Table_Low_Bound => First_String_Id,
Table_Initial => Alloc_Strings_Initial,
Table_Increment => Alloc_Strings_Increment,
Table_Name => "Strings");
-- Note: it is possible that two entries in the Strings table can share
-- string data in the String_Chars table, and in particular this happens
-- when Start_String is called with a parameter that is the last string
-- currently allocated in the table.
----------------
-- End_String --
----------------
function End_String return String_Id is
begin
return Strings.Last;
end End_String;
---------------------
-- Get_String_Char --
---------------------
function Get_String_Char (Id : String_Id; Index : Int) return Char_Code is
begin
pragma Assert (Id in First_String_Id .. Strings.Last
and then Index in 1 .. Strings.Table (Id).Length);
return String_Chars.Table (Strings.Table (Id).String_Index + Index - 1);
end Get_String_Char;
----------------
-- Initialize --
----------------
procedure Initialize is
begin
String_Chars.Init;
Strings.Init;
end Initialize;
------------------
-- Start_String --
------------------
procedure Start_String is
begin
Strings.Increment_Last;
Strings.Table (Strings.Last).String_Index := String_Chars.Last + 1;
Strings.Table (Strings.Last).Length := 0;
end Start_String;
procedure Start_String (S : String_Id) is
begin
Strings.Increment_Last;
-- Case of initial string value is at the end of the string characters
-- table, so it does not need copying, instead it can be shared.
if Strings.Table (S).String_Index + Strings.Table (S).Length =
String_Chars.Last + 1
then
Strings.Table (Strings.Last).String_Index :=
Strings.Table (S).String_Index;
-- Case of initial string value must be copied to new string
else
Strings.Table (Strings.Last).String_Index :=
String_Chars.Last + 1;
for J in 1 .. Strings.Table (S).Length loop
String_Chars.Increment_Last;
String_Chars.Table (String_Chars.Last) :=
String_Chars.Table (Strings.Table (S).String_Index + (J - 1));
end loop;
end if;
-- In either case the result string length is copied from the argument
Strings.Table (Strings.Last).Length := Strings.Table (S).Length;
end Start_String;
-----------------------
-- Store_String_Char --
-----------------------
procedure Store_String_Char (C : Char_Code) is
begin
String_Chars.Increment_Last;
String_Chars.Table (String_Chars.Last) := C;
Strings.Table (Strings.Last).Length :=
Strings.Table (Strings.Last).Length + 1;
end Store_String_Char;
------------------------
-- Store_String_Chars --
------------------------
procedure Store_String_Chars (S : String) is
begin
for J in S'First .. S'Last loop
Store_String_Char (Get_Char_Code (S (J)));
end loop;
end Store_String_Chars;
--------------------------
-- String_Chars_Address --
--------------------------
function String_Chars_Address return System.Address is
begin
return String_Chars.Table (0)'Address;
end String_Chars_Address;
------------------
-- String_Equal --
------------------
function String_Equal (L, R : String_Id) return Boolean is
Len : constant Nat := Strings.Table (L).Length;
begin
if Len /= Strings.Table (R).Length then
return False;
else
for J in 1 .. Len loop
if Get_String_Char (L, J) /= Get_String_Char (R, J) then
return False;
end if;
end loop;
return True;
end if;
end String_Equal;
-------------------
-- String_Length --
-------------------
function String_Length (Id : String_Id) return Nat is
begin
return Strings.Table (Id).Length;
end String_Length;
---------------------
-- Strings_Address --
---------------------
function Strings_Address return System.Address is
begin
return Strings.Table (First_String_Id)'Address;
end Strings_Address;
---------------
-- Tree_Read --
---------------
procedure Tree_Read is
begin
String_Chars.Tree_Read;
Strings.Tree_Read;
end Tree_Read;
----------------
-- Tree_Write --
----------------
procedure Tree_Write is
begin
String_Chars.Tree_Write;
Strings.Tree_Write;
end Tree_Write;
-------------------------
-- Unstore_String_Char --
-------------------------
procedure Unstore_String_Char is
begin
String_Chars.Decrement_Last;
Strings.Table (Strings.Last).Length :=
Strings.Table (Strings.Last).Length - 1;
end Unstore_String_Char;
---------------------
-- Write_Char_Code --
---------------------
procedure Write_Char_Code (Code : Char_Code) is
procedure Write_Hex_Byte (J : Natural);
-- Write single hex digit
procedure Write_Hex_Byte (J : Natural) is
Hexd : String := "0123456789abcdef";
begin
Write_Char (Hexd (J / 16 + 1));
Write_Char (Hexd (J mod 16 + 1));
end Write_Hex_Byte;
-- Start of processing for Write_Char_Code
begin
if Code in 16#20# .. 16#7A#
or else Code in 16#7C# .. 16#7F#
then
Write_Char (Character'Val (Code));
else
Write_Char ('{');
if Code > 16#FF# then
Write_Hex_Byte (Natural (Code / 256));
end if;
Write_Hex_Byte (Natural (Code mod 256));
Write_Char ('}');
end if;
end Write_Char_Code;
------------------------------
-- Write_String_Table_Entry --
------------------------------
procedure Write_String_Table_Entry (Id : String_Id) is
C : Char_Code;
begin
Write_Char ('"');
for I in 1 .. String_Length (Id) loop
C := Get_String_Char (Id, I);
if Character'Val (C) = '"' then
Write_Str ("""""");
else
Write_Char_Code (C);
end if;
end loop;
Write_Char ('"');
end Write_String_Table_Entry;
end Stringt;