diff options
Diffstat (limited to 'gcc/ada/s-wwdwch.adb')
-rw-r--r-- | gcc/ada/s-wwdwch.adb | 147 |
1 files changed, 124 insertions, 23 deletions
diff --git a/gcc/ada/s-wwdwch.adb b/gcc/ada/s-wwdwch.adb index eb9d2fb6ac4..ac3d1e9cc45 100644 --- a/gcc/ada/s-wwdwch.adb +++ b/gcc/ada/s-wwdwch.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2002, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2005, 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- -- @@ -31,46 +31,147 @@ -- -- ------------------------------------------------------------------------------ +with Interfaces; use Interfaces; + +with System.WWd_Char; + package body System.Wwd_WChar is + ------------------------------------ + -- Wide_Wide_Width_Wide_Character -- + ------------------------------------ + + -- This is the case where we are talking about the Wide_Wide_Image of + -- a Wide_Character, which is always the same character sequence as the + -- Wide_Image of the same Wide_Character. + + function Wide_Wide_Width_Wide_Character + (Lo, Hi : Wide_Character) return Natural + is + begin + return Wide_Width_Wide_Character (Lo, Hi); + end Wide_Wide_Width_Wide_Character; + + ------------------------------------ + -- Wide_Wide_Width_Wide_Wide_Char -- + ------------------------------------ + + function Wide_Wide_Width_Wide_Wide_Char + (Lo, Hi : Wide_Wide_Character) return Natural + is + W : Natural := 0; + LV : constant Unsigned_32 := Wide_Wide_Character'Pos (Lo); + HV : constant Unsigned_32 := Wide_Wide_Character'Pos (Hi); + + begin + -- Return zero if empty range + + if LV > HV then + return 0; + end if; + + -- If any characters in normal character range, then use normal + -- Wide_Wide_Width attribute on this range to find out a starting point. + -- Otherwise start with zero. + + if LV <= 255 then + W := + System.WWd_Char.Wide_Wide_Width_Character + (Lo => Character'Val (LV), + Hi => Character'Val (Unsigned_32'Min (255, HV))); + else + W := 0; + end if; + + -- Increase to at least 4 if FFFE or FFFF present. These correspond + -- to the special language defined names FFFE/FFFF for these values. + + if 16#FFFF# in LV .. HV or else 16#FFFE# in LV .. HV then + W := Natural'Max (W, 4); + end if; + + -- Increase to at least 3 if any wide characters, corresponding to + -- the normal ' character ' sequence. We know that the character fits. + + if HV > 255 then + W := Natural'Max (W, 3); + end if; + + return W; + end Wide_Wide_Width_Wide_Wide_Char; + ------------------------------- -- Wide_Width_Wide_Character -- ------------------------------- function Wide_Width_Wide_Character - (Lo, Hi : Wide_Character) - return Natural + (Lo, Hi : Wide_Character) return Natural is - W : Natural; - P : Natural; + W : Natural := 0; + LV : constant Unsigned_32 := Wide_Character'Pos (Lo); + HV : constant Unsigned_32 := Wide_Character'Pos (Hi); begin - W := 0; + -- Return zero if empty range - for C in Lo .. Hi loop - P := Wide_Character'Pos (C); + if LV > HV then + return 0; + end if; - -- If we are in wide character range, the length is always 3 - -- and we are done, since all remaining characters are the same. + -- If any characters in normal character range, then use normal + -- Wide_Wide_Width attribute on this range to find out a starting point. + -- Otherwise start with zero. - if P > 255 then - return Natural'Max (W, 3); + if LV <= 255 then + W := + System.WWd_Char.Wide_Width_Character + (Lo => Character'Val (LV), + Hi => Character'Val (Unsigned_32'Min (255, HV))); + else + W := 0; + end if; - -- If we are in character range then use length of character image - -- Is this right, what about wide char encodings of 80-FF??? + -- Increase to at least 4 if FFFE or FFFF present. These correspond + -- to the special language defined names FFFE/FFFF for these values. - else - declare - S : constant Wide_String := - Character'Wide_Image (Character'Val (P)); + if 16#FFFF# in LV .. HV or else 16#FFFE# in LV .. HV then + W := Natural'Max (W, 4); + end if; - begin - W := Natural'Max (W, S'Length); - end; - end if; - end loop; + -- Increase to at least 3 if any wide characters, corresponding to + -- the normal 'character' sequence. We know that the character fits. + + if HV > 255 then + W := Natural'Max (W, 3); + end if; return W; end Wide_Width_Wide_Character; + ------------------------------------ + -- Wide_Width_Wide_Wide_Character -- + ------------------------------------ + + -- This is a nasty case, because we get into the business of representing + -- out of range wide wide characters as wide strings. Let's let image do + -- the work here. Too bad if this takes lots of time. It's silly anyway! + + function Wide_Width_Wide_Wide_Character + (Lo, Hi : Wide_Wide_Character) return Natural + is + W : Natural; + + begin + W := 0; + for J in Lo .. Hi loop + declare + S : constant Wide_String := Wide_Wide_Character'Wide_Image (J); + begin + W := Natural'Max (W, S'Length); + end; + end loop; + + return W; + end Wide_Width_Wide_Wide_Character; + end System.Wwd_WChar; |