File : s-valwch.adb


   1 ------------------------------------------------------------------------------
   2 --                                                                          --
   3 --                         GNAT COMPILER COMPONENTS                         --
   4 --                                                                          --
   5 --                     S Y S T E M . V A L _ W C H A R                      --
   6 --                                                                          --
   7 --                                 B o d y                                  --
   8 --                                                                          --
   9 --          Copyright (C) 1992-2012, 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 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.                                     --
  17 --                                                                          --
  18 --                                                                          --
  19 --                                                                          --
  20 --                                                                          --
  21 --                                                                          --
  22 -- You should have received a copy of the GNU General Public License and    --
  23 -- a copy of the GCC Runtime Library Exception along with this program;     --
  24 -- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
  25 -- <http://www.gnu.org/licenses/>.                                          --
  26 --                                                                          --
  27 -- GNAT was originally developed  by the GNAT team at  New York University. --
  28 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
  29 --                                                                          --
  30 ------------------------------------------------------------------------------
  31 
  32 with Interfaces;      use Interfaces;
  33 with System.Val_Util; use System.Val_Util;
  34 with System.WCh_Cnv;  use System.WCh_Cnv;
  35 with System.WCh_Con;  use System.WCh_Con;
  36 
  37 package body System.Val_WChar is
  38 
  39    --------------------------
  40    -- Value_Wide_Character --
  41    --------------------------
  42 
  43    function Value_Wide_Character
  44      (Str : String;
  45       EM  : System.WCh_Con.WC_Encoding_Method) return Wide_Character
  46    is
  47       WC : constant Wide_Wide_Character := Value_Wide_Wide_Character (Str, EM);
  48       WV : constant Unsigned_32         := Wide_Wide_Character'Pos (WC);
  49    begin
  50       if WV > 16#FFFF# then
  51          Bad_Value (Str);
  52       else
  53          return Wide_Character'Val (WV);
  54       end if;
  55    end Value_Wide_Character;
  56 
  57    -------------------------------
  58    -- Value_Wide_Wide_Character --
  59    -------------------------------
  60 
  61    function Value_Wide_Wide_Character
  62      (Str : String;
  63       EM  : System.WCh_Con.WC_Encoding_Method) return Wide_Wide_Character
  64    is
  65       F : Natural;
  66       L : Natural;
  67       S : String (Str'Range) := Str;
  68 
  69    begin
  70       Normalize_String (S, F, L);
  71 
  72       --  Character literal case
  73 
  74       if S (F) = ''' and then S (L) = ''' then
  75 
  76          --  Must be at least three characters
  77 
  78          if L - F < 2 then
  79             Bad_Value (Str);
  80 
  81          --  If just three characters, simple character case
  82 
  83          elsif L - F = 2 then
  84             return Wide_Wide_Character'Val (Character'Pos (S (F + 1)));
  85 
  86          --  Only other possibility for quoted string is wide char sequence
  87 
  88          else
  89             declare
  90                P : Natural;
  91                W : Wide_Wide_Character;
  92 
  93                function In_Char return Character;
  94                --  Function for instantiations of Char_Sequence_To_UTF_32
  95 
  96                -------------
  97                -- In_Char --
  98                -------------
  99 
 100                function In_Char return Character is
 101                begin
 102                   P := P + 1;
 103 
 104                   if P = Str'Last then
 105                      Bad_Value (Str);
 106                   end if;
 107 
 108                   return Str (P);
 109                end In_Char;
 110 
 111                function UTF_32 is
 112                  new Char_Sequence_To_UTF_32 (In_Char);
 113 
 114             begin
 115                P := F + 1;
 116 
 117                --  Brackets encoding
 118 
 119                if S (F + 1) = '[' then
 120                   W := Wide_Wide_Character'Val (UTF_32 ('[', WCEM_Brackets));
 121                else
 122                   W := Wide_Wide_Character'Val (UTF_32 (S (F + 1), EM));
 123                end if;
 124 
 125                if P /= L - 1 then
 126                   Bad_Value (Str);
 127                end if;
 128 
 129                return W;
 130             end;
 131          end if;
 132 
 133       --  Deal with Hex_hhhhhhhh cases for wide_[wide_]character cases
 134 
 135       elsif Str'Length = 12
 136         and then Str (Str'First .. Str'First + 3) = "Hex_"
 137       then
 138          declare
 139             W : Unsigned_32 := 0;
 140 
 141          begin
 142             for J in Str'First + 4 .. Str'First + 11 loop
 143                W := W * 16 + Character'Pos (Str (J));
 144 
 145                if Str (J) in '0' .. '9' then
 146                   W := W - Character'Pos ('0');
 147                elsif Str (J) in 'A' .. 'F' then
 148                   W := W - Character'Pos ('A') + 10;
 149                elsif Str (J) in 'a' .. 'f' then
 150                   W := W - Character'Pos ('a') + 10;
 151                else
 152                   Bad_Value (Str);
 153                end if;
 154             end loop;
 155 
 156             if W > 16#7FFF_FFFF# then
 157                Bad_Value (Str);
 158             else
 159                return Wide_Wide_Character'Val (W);
 160             end if;
 161          end;
 162 
 163       --  Otherwise must be one of the special names for Character
 164 
 165       else
 166          return
 167            Wide_Wide_Character'Val (Character'Pos (Character'Value (Str)));
 168       end if;
 169 
 170    exception
 171       when Constraint_Error =>
 172          Bad_Value (Str);
 173    end Value_Wide_Wide_Character;
 174 
 175 end System.Val_WChar;