File : s-valint.adb


   1 ------------------------------------------------------------------------------
   2 --                                                                          --
   3 --                         GNAT COMPILER COMPONENTS                         --
   4 --                                                                          --
   5 --                       S Y S T E M . V A L _ I N T                        --
   6 --                                                                          --
   7 --                                 B o d y                                  --
   8 --                                                                          --
   9 --          Copyright (C) 1992-2014, 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 System.Unsigned_Types; use System.Unsigned_Types;
  33 with System.Val_Uns;        use System.Val_Uns;
  34 with System.Val_Util;       use System.Val_Util;
  35 
  36 package body System.Val_Int is
  37 
  38    ------------------
  39    -- Scan_Integer --
  40    ------------------
  41 
  42    function Scan_Integer
  43      (Str : String;
  44       Ptr : not null access Integer;
  45       Max : Integer) return Integer
  46    is
  47       Uval : Unsigned;
  48       --  Unsigned result
  49 
  50       Minus : Boolean := False;
  51       --  Set to True if minus sign is present, otherwise to False
  52 
  53       Start : Positive;
  54       --  Saves location of first non-blank (not used in this case)
  55 
  56    begin
  57       Scan_Sign (Str, Ptr, Max, Minus, Start);
  58 
  59       if Str (Ptr.all) not in '0' .. '9' then
  60          Ptr.all := Start;
  61          Bad_Value (Str);
  62       end if;
  63 
  64       Uval := Scan_Raw_Unsigned (Str, Ptr, Max);
  65 
  66       --  Deal with overflow cases, and also with maximum negative number
  67 
  68       if Uval > Unsigned (Integer'Last) then
  69          if Minus and then Uval = Unsigned (-(Integer'First)) then
  70             return Integer'First;
  71          else
  72             Bad_Value (Str);
  73          end if;
  74 
  75       --  Negative values
  76 
  77       elsif Minus then
  78          return -(Integer (Uval));
  79 
  80       --  Positive values
  81 
  82       else
  83          return Integer (Uval);
  84       end if;
  85    end Scan_Integer;
  86 
  87    -------------------
  88    -- Value_Integer --
  89    -------------------
  90 
  91    function Value_Integer (Str : String) return Integer is
  92    begin
  93       --  We have to special case Str'Last = Positive'Last because the normal
  94       --  circuit ends up setting P to Str'Last + 1 which is out of bounds. We
  95       --  deal with this by converting to a subtype which fixes the bounds.
  96 
  97       if Str'Last = Positive'Last then
  98          declare
  99             subtype NT is String (1 .. Str'Length);
 100          begin
 101             return Value_Integer (NT (Str));
 102          end;
 103 
 104       --  Normal case where Str'Last < Positive'Last
 105 
 106       else
 107          declare
 108             V : Integer;
 109             P : aliased Integer := Str'First;
 110          begin
 111             V := Scan_Integer (Str, P'Access, Str'Last);
 112             Scan_Trailing_Blanks (Str, P);
 113             return V;
 114          end;
 115       end if;
 116    end Value_Integer;
 117 
 118 end System.Val_Int;