[Ada] Clean up GNAT.Calendar.Time_IO.Value

gcc/ada/

	* libgnat/g-catiio.adb (Parse_ISO_8601): Minor cleanups:

	Give some objects clearer names.
	Make some objects more local to where they are used.

	Remove some validity checks that can't fail, because some of
	the variables tested have been moved so they're not visible here.
	Anyway, Wrong_Syntax is about errors in the input, not data
	validity.

	Use Time_Zone_Seen instead of Local_Sign = ' ' to determine
	that a time zone indication was seen.

	We don't need to distinguish two different kinds of
	syntax error (End_Of_Source_Reached and Wrong_Syntax),
	so use Wrong_Syntax always.

	Remove comment, "Certain scanning scenarios may handle
	this exception on their own."; there are no such scenarios.
This commit is contained in:
Bob Duff 2020-05-09 13:09:37 -04:00 committed by Pierre-Marie de Rodat
parent b1e78e8577
commit bf8467d806

View File

@ -593,13 +593,10 @@ package body GNAT.Calendar.Time_IO is
-- The current character scan index. After a call to Advance, Index -- The current character scan index. After a call to Advance, Index
-- points to the next character. -- points to the next character.
End_Of_Source_Reached : exception;
-- An exception used to signal that the scan pointer has reached the
-- end of the source string.
Wrong_Syntax : exception; Wrong_Syntax : exception;
-- An exception used to signal that the scan pointer has reached an -- An exception used to signal that the scan pointer has reached an
-- unexpected character in the source string. -- unexpected character in the source string, or if premature
-- end-of-source was reached.
procedure Advance; procedure Advance;
pragma Inline (Advance); pragma Inline (Advance);
@ -657,13 +654,12 @@ package body GNAT.Calendar.Time_IO is
procedure Advance is procedure Advance is
begin begin
-- Signal the end of the source string. This stops a complex scan by -- Signal the end of the source string. This stops a complex scan
-- bottoming up any recursive calls till control reaches routine Scan -- by bottoming up any recursive calls till control reaches routine
-- which handles the exception. Certain scanning scenarios may handle -- Scan, which handles the exception.
-- this exception on their own.
if Index > Date'Last then if Index > Date'Last then
raise End_Of_Source_Reached; raise Wrong_Syntax;
-- Advance the scan pointer as long as there are characters to scan, -- Advance the scan pointer as long as there are characters to scan,
-- in other words, the scan pointer has not passed the end of the -- in other words, the scan pointer has not passed the end of the
@ -819,7 +815,7 @@ package body GNAT.Calendar.Time_IO is
-- this exception on their own. -- this exception on their own.
if Index > Date'Last then if Index > Date'Last then
raise End_Of_Source_Reached; raise Wrong_Syntax;
else else
return Date (Index); return Date (Index);
@ -833,22 +829,22 @@ package body GNAT.Calendar.Time_IO is
Date_Separator : constant Character := '-'; Date_Separator : constant Character := '-';
Hour_Separator : constant Character := ':'; Hour_Separator : constant Character := ':';
Day : Day_Number; Day : Day_Number;
Month : Month_Number; Month : Month_Number;
Year : Year_Number; Year : Year_Number;
Hour : Hour_Number := 0; Hour : Hour_Number := 0;
Minute : Minute_Number := 0; Minute : Minute_Number := 0;
Second : Second_Number := 0; Second : Second_Number := 0;
Subsec : Second_Duration := 0.0; Subsec : Second_Duration := 0.0;
Local_Hour : Hour_Number := 0; Time_Zone_Seen : Boolean := False;
Local_Minute : Minute_Number := 0; Time_Zone_Offset : Time_Offset; -- Valid only if Time_Zone_Seen
Local_Sign : Character := ' ';
Time_Zone : Time_Offset; -- initialized when Local_Sign is set
Sep_Required : Boolean := False; Sep_Required : Boolean := False;
-- True if a separator is seen (and therefore required after it!) -- True if a separator is seen (and therefore required after it!)
subtype Sign_Type is Character with Predicate => Sign_Type in '+' | '-';
begin begin
-- Parse date -- Parse date
@ -880,8 +876,8 @@ package body GNAT.Calendar.Time_IO is
-- Suffix 'Z' signifies that this is UTC time (time zone 0) -- Suffix 'Z' signifies that this is UTC time (time zone 0)
if Symbol = 'Z' then if Symbol = 'Z' then
Local_Sign := '+'; Time_Zone_Seen := True;
Time_Zone := 0; Time_Zone_Offset := 0;
Advance; Advance;
-- A decimal fraction shall have at least one digit, and has as -- A decimal fraction shall have at least one digit, and has as
@ -902,59 +898,58 @@ package body GNAT.Calendar.Time_IO is
-- if the difference between the time scales is exactly an -- if the difference between the time scales is exactly an
-- integral number of hours. -- integral number of hours.
elsif Symbol = '+' or else Symbol = '-' then elsif Symbol in Sign_Type then
Local_Sign := Symbol; declare
Advance; Time_Zone_Sign : constant Sign_Type := Symbol;
Local_Hour := Scan_Hour;
-- Past ':' Time_Zone_Hour : Hour_Number;
Time_Zone_Minute : Minute_Number;
if Index < Date'Last and then Symbol = Hour_Separator then begin
Time_Zone_Seen := True;
Advance; Advance;
Local_Minute := Scan_Minute; Time_Zone_Hour := Scan_Hour;
end if;
-- Compute local displacement -- Past ':'
Time_Zone := Time_Offset (Local_Hour * 60 + Local_Minute); if Index < Date'Last and then Symbol = Hour_Separator then
Advance;
Time_Zone_Minute := Scan_Minute;
else
Time_Zone_Minute := 0;
end if;
if Local_Sign = '-' then -- Compute Time_Zone_Offset
Time_Zone := -Time_Zone;
end if; Time_Zone_Offset :=
Time_Offset (Time_Zone_Hour * 60 + Time_Zone_Minute);
if Time_Zone_Sign = '-' then
Time_Zone_Offset := -Time_Zone_Offset;
end if;
end;
else else
raise Wrong_Syntax; raise Wrong_Syntax;
end if; end if;
end if; end if;
end if; end if;
-- Sanity checks. The check on Index ensures that there are no trailing -- Check for trailing characters
-- characters.
if Index /= Date'Length + 1 if Index /= Date'Length + 1 then
or else not Year'Valid
or else not Month'Valid
or else not Day'Valid
or else not Hour'Valid
or else not Minute'Valid
or else not Second'Valid
or else not Subsec'Valid
or else not Local_Hour'Valid
or else not Local_Minute'Valid
then
raise Wrong_Syntax; raise Wrong_Syntax;
end if; end if;
-- If no time zone was specified, we call GNAT.Calendar.Time_Of, which -- If a time zone was specified, use Ada.Calendar.Formatting.Time_Of,
-- uses local time. Otherwise, we use Ada.Calendar.Formatting.Time_Of -- and specify the time zone. Otherwise, call GNAT.Calendar.Time_Of,
-- and specify the time zone. -- which uses local time.
if Local_Sign = ' ' then if Time_Zone_Seen then
Time := GNAT.Calendar.Time_Of
(Year, Month, Day, Hour, Minute, Second, Subsec);
else
Time := Ada.Calendar.Formatting.Time_Of Time := Ada.Calendar.Formatting.Time_Of
(Year, Month, Day, Hour, Minute, Second, Subsec, (Year, Month, Day, Hour, Minute, Second, Subsec,
Time_Zone => Time_Zone); Time_Zone => Time_Zone_Offset);
else
Time := GNAT.Calendar.Time_Of
(Year, Month, Day, Hour, Minute, Second, Subsec);
end if; end if;
-- Notify that the input string was successfully parsed -- Notify that the input string was successfully parsed
@ -962,9 +957,7 @@ package body GNAT.Calendar.Time_IO is
Success := True; Success := True;
exception exception
when End_Of_Source_Reached when Wrong_Syntax =>
| Wrong_Syntax
=>
Time := Time :=
Time_Of (Year_Number'First, Month_Number'First, Day_Number'First); Time_Of (Year_Number'First, Month_Number'First, Day_Number'First);
Success := False; Success := False;