aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmmanuel Briot <briot@adacore.com>2007-12-13 11:27:07 +0100
committerArnaud Charlet <charlet@gcc.gnu.org>2007-12-13 11:27:07 +0100
commit7d304f61cd5e9835bbc600272772cf067f9b2b6b (patch)
tree59b00f6ec5dd4e255a6400d076e3b74290c96d52
parent36fcf362ce30d24b353f5ece90fb8d760af8626c (diff)
downloadgcc-7d304f61cd5e9835bbc600272772cf067f9b2b6b.zip
gcc-7d304f61cd5e9835bbc600272772cf067f9b2b6b.tar.gz
gcc-7d304f61cd5e9835bbc600272772cf067f9b2b6b.tar.bz2
g-calend.ads (No_Time): New constant, to represent an uninitialized time value
2007-12-06 Emmanuel Briot <briot@adacore.com> * g-calend.ads (No_Time): New constant, to represent an uninitialized time value * g-catiio.ads, g-catiio.adb (Value): Added support for more date formats. (Month_Name_To_Number): New subprogram * g-dirope.adb (Get_Current_Dir): On windows, normalize the drive letter to upper-case. From-SVN: r130839
-rw-r--r--gcc/ada/g-calend.ads10
-rw-r--r--gcc/ada/g-catiio.adb289
-rw-r--r--gcc/ada/g-catiio.ads23
-rw-r--r--gcc/ada/g-dirope.adb13
4 files changed, 248 insertions, 87 deletions
diff --git a/gcc/ada/g-calend.ads b/gcc/ada/g-calend.ads
index cc7ae32..e3cc791 100644
--- a/gcc/ada/g-calend.ads
+++ b/gcc/ada/g-calend.ads
@@ -56,6 +56,10 @@ package GNAT.Calendar is
subtype Day_In_Year_Number is Positive range 1 .. 366;
subtype Week_In_Year_Number is Positive range 1 .. 53;
+ No_Time : constant Ada.Calendar.Time;
+ -- A constant set to the first date that can be represented by the type
+ -- Time. It can be used to indicate an uninitialized date.
+
function Hour (Date : Ada.Calendar.Time) return Hour_Number;
function Minute (Date : Ada.Calendar.Time) return Minute_Number;
function Second (Date : Ada.Calendar.Time) return Second_Number;
@@ -131,4 +135,10 @@ private
-- the Collected Algorithms of the ACM. The author of algorithm 199 is
-- Robert G. Tantzen.
+ No_Time : constant Ada.Calendar.Time :=
+ Ada.Calendar.Time_Of
+ (Ada.Calendar.Year_Number'First,
+ Ada.Calendar.Month_Number'First,
+ Ada.Calendar.Day_Number'First);
+
end GNAT.Calendar;
diff --git a/gcc/ada/g-catiio.adb b/gcc/ada/g-catiio.adb
index 5286ef0..3a6bc39 100644
--- a/gcc/ada/g-catiio.adb
+++ b/gcc/ada/g-catiio.adb
@@ -36,6 +36,8 @@ with Ada.Characters.Handling;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO;
+with GNAT.Case_Util;
+
package body GNAT.Calendar.Time_IO is
type Month_Name is
@@ -52,6 +54,12 @@ package body GNAT.Calendar.Time_IO is
November,
December);
+ function Month_Name_To_Number
+ (Str : String) return Ada.Calendar.Month_Number;
+ -- Converts a string that contains an abbreviated month name to a month
+ -- number. Constraint_Error is raised if Str is not a valid month name.
+ -- Comparison is case insensitive
+
type Padding_Mode is (None, Zero, Space);
type Sec_Number is mod 2 ** 64;
@@ -168,6 +176,8 @@ package body GNAT.Calendar.Time_IO is
end case;
end Pad_Char;
+ -- Local Declarations
+
NI : constant String := Sec_Number'Image (N);
NIP : constant String := Pad_Char & NI (2 .. NI'Last);
@@ -514,12 +524,40 @@ package body GNAT.Calendar.Time_IO is
return To_String (Result);
end Image;
+ --------------------------
+ -- Month_Name_To_Number --
+ --------------------------
+
+ function Month_Name_To_Number
+ (Str : String) return Ada.Calendar.Month_Number
+ is
+ subtype String3 is String (1 .. 3);
+ Abbrev_Upper_Month_Names :
+ constant array (Ada.Calendar.Month_Number) of String3 :=
+ ("JAN", "FEB", "MAR", "APR", "MAY", "JUN",
+ "JUL", "AUG", "SEP", "OCT", "NOV", "DEC");
+ -- Short version of the month names, used when parsing date strings.
+
+ S : String := Str;
+
+ begin
+ GNAT.Case_Util.To_Upper (S);
+
+ for J in Abbrev_Upper_Month_Names'Range loop
+ if Abbrev_Upper_Month_Names (J) = S then
+ return J;
+ end if;
+ end loop;
+
+ return Abbrev_Upper_Month_Names'First;
+ end Month_Name_To_Number;
+
-----------
-- Value --
-----------
function Value (Date : String) return Ada.Calendar.Time is
- D : String (1 .. 19);
+ D : String (1 .. 21);
D_Length : constant Natural := Date'Length;
Year : Year_Number;
@@ -531,13 +569,12 @@ package body GNAT.Calendar.Time_IO is
Sub_Second : Second_Duration;
procedure Extract_Date
- (Year : out Year_Number;
- Month : out Month_Number;
- Day : out Day_Number;
- Y2K : Boolean := False);
- -- Try and extract a date value from string D. Set Y2K to True to
- -- account for the 20YY case. Raise Constraint_Error if the portion
- -- of D corresponding to the date is not well formatted.
+ (Year : out Year_Number;
+ Month : out Month_Number;
+ Day : out Day_Number;
+ Time_Start : out Natural);
+ -- Try and extract a date value from string D. Time_Start is set to the
+ -- first character that could be the start of time data.
procedure Extract_Time
(Index : Positive;
@@ -555,33 +592,133 @@ package body GNAT.Calendar.Time_IO is
------------------
procedure Extract_Date
- (Year : out Year_Number;
- Month : out Month_Number;
- Day : out Day_Number;
- Y2K : Boolean := False)
+ (Year : out Year_Number;
+ Month : out Month_Number;
+ Day : out Day_Number;
+ Time_Start : out Natural)
is
- Delim_Index : Positive := 5;
-
begin
- if Y2K then
- Delim_Index := 3;
- end if;
+ if D (3) = '-' or else D (3) = '/' then
+ if D_Length = 8 or else D_Length = 17 then
- if (D (Delim_Index) /= '-' or else D (Delim_Index + 3) /= '-')
- and then
- (D (Delim_Index) /= '/' or else D (Delim_Index + 3) /= '/')
- then
- raise Constraint_Error;
- end if;
+ -- Formats are "yy*mm*dd" or "yy*mm*dd hh:mm:ss"
+
+ if D (6) /= D (3) then
+ raise Constraint_Error;
+ end if;
+
+ Year := Year_Number'Value ("20" & D (1 .. 2));
+ Month := Month_Number'Value (D (4 .. 5));
+ Day := Day_Number'Value (D (7 .. 8));
+ Time_Start := 10;
+
+ elsif D_Length = 10 or else D_Length = 19 then
+
+ -- Formats are "mm*dd*yyyy" or "mm*dd*yyyy hh:mm:ss"
+
+ if D (6) /= D (3) then
+ raise Constraint_Error;
+ end if;
+
+ Year := Year_Number'Value (D (7 .. 10));
+ Month := Month_Number'Value (D (1 .. 2));
+ Day := Day_Number'Value (D (4 .. 5));
+ Time_Start := 12;
+
+ elsif D_Length = 11 or else D_Length = 20 then
+
+ -- Formats are "dd*mmm*yyyy" or "dd*mmm*yyyy hh:mm:ss"
+
+ if D (7) /= D (3) then
+ raise Constraint_Error;
+ end if;
+
+ Year := Year_Number'Value (D (8 .. 11));
+ Month := Month_Name_To_Number (D (4 .. 6));
+ Day := Day_Number'Value (D (1 .. 2));
+ Time_Start := 13;
+
+ else
+ raise Constraint_Error;
+ end if;
+
+ elsif D (3) = ' ' then
+ if D_Length = 11 or else D_Length = 20 then
+
+ -- Possible formats are "dd mmm yyyy", "dd mmm yyyy hh:mm:ss"
+
+ if D (7) /= ' ' then
+ raise Constraint_Error;
+ end if;
+
+ Year := Year_Number'Value (D (8 .. 11));
+ Month := Month_Name_To_Number (D (4 .. 6));
+ Day := Day_Number'Value (D (1 .. 2));
+ Time_Start := 13;
+
+ else
+ raise Constraint_Error;
+ end if;
- if Y2K then
- Year := Year_Number'Value ("20" & D (1 .. 2));
- Month := Month_Number'Value (D (4 .. 5));
- Day := Day_Number'Value (D (7 .. 8));
else
- Year := Year_Number'Value (D (1 .. 4));
- Month := Month_Number'Value (D (6 .. 7));
- Day := Day_Number'Value (D (9 .. 10));
+ if D_Length = 8 or else D_Length = 17 then
+
+ -- Possible formats are "yyyymmdd" or "yyyymmdd hh:mm:ss"
+
+ Year := Year_Number'Value (D (1 .. 4));
+ Month := Month_Number'Value (D (5 .. 6));
+ Day := Day_Number'Value (D (7 .. 8));
+ Time_Start := 10;
+
+ elsif D_Length = 10 or else D_Length = 19 then
+
+ -- Possible formats are "yyyy*mm*dd" or "yyyy*mm*dd hh:mm:ss"
+
+ if (D (5) /= '-' and then D (5) /= '/')
+ or else D (8) /= D (5)
+ then
+ raise Constraint_Error;
+ end if;
+
+ Year := Year_Number'Value (D (1 .. 4));
+ Month := Month_Number'Value (D (6 .. 7));
+ Day := Day_Number'Value (D (9 .. 10));
+ Time_Start := 12;
+
+ elsif D_Length = 11 or else D_Length = 20 then
+
+ -- Possible formats are "yyyy*mmm*dd"
+
+ if (D (5) /= '-' and then D (5) /= '/')
+ or else D (9) /= D (5)
+ then
+ raise Constraint_Error;
+ end if;
+
+ Year := Year_Number'Value (D (1 .. 4));
+ Month := Month_Name_To_Number (D (6 .. 8));
+ Day := Day_Number'Value (D (10 .. 11));
+ Time_Start := 13;
+
+ elsif D_Length = 12 or else D_Length = 21 then
+
+ -- Formats are "mmm dd, yyyy" or "mmm dd, yyyy hh:mm:ss"
+
+ if D (4) /= ' '
+ or else D (7) /= ','
+ or else D (8) /= ' '
+ then
+ raise Constraint_Error;
+ end if;
+
+ Year := Year_Number'Value (D (9 .. 12));
+ Month := Month_Name_To_Number (D (1 .. 3));
+ Day := Day_Number'Value (D (5 .. 6));
+ Time_Start := 14;
+
+ else
+ raise Constraint_Error;
+ end if;
end if;
end Extract_Date;
@@ -594,22 +731,42 @@ package body GNAT.Calendar.Time_IO is
Hour : out Hour_Number;
Minute : out Minute_Number;
Second : out Second_Number;
- Check_Space : Boolean := False) is
-
+ Check_Space : Boolean := False)
+ is
begin
- if Check_Space and then D (Index - 1) /= ' ' then
- raise Constraint_Error;
- end if;
+ -- If no time was specified in the string (do not allow trailing
+ -- character either)
- if D (Index + 2) /= ':' or else D (Index + 5) /= ':' then
- raise Constraint_Error;
- end if;
+ if Index = D_Length + 2 then
+ Hour := 0;
+ Minute := 0;
+ Second := 0;
+
+ else
+ -- Not enough characters left ?
+
+ if Index /= D_Length - 7 then
+ raise Constraint_Error;
+ end if;
- Hour := Hour_Number'Value (D (Index .. Index + 1));
- Minute := Minute_Number'Value (D (Index + 3 .. Index + 4));
- Second := Second_Number'Value (D (Index + 6 .. Index + 7));
+ if Check_Space and then D (Index - 1) /= ' ' then
+ raise Constraint_Error;
+ end if;
+
+ if D (Index + 2) /= ':' or else D (Index + 5) /= ':' then
+ raise Constraint_Error;
+ end if;
+
+ Hour := Hour_Number'Value (D (Index .. Index + 1));
+ Minute := Minute_Number'Value (D (Index + 3 .. Index + 4));
+ Second := Second_Number'Value (D (Index + 6 .. Index + 7));
+ end if;
end Extract_Time;
+ -- Local Declarations
+
+ Time_Start : Natural := 1;
+
-- Start of processing for Value
begin
@@ -620,8 +777,12 @@ package body GNAT.Calendar.Time_IO is
if D_Length /= 8
and then D_Length /= 10
+ and then D_Length /= 11
+ and then D_Length /= 12
and then D_Length /= 17
and then D_Length /= 19
+ and then D_Length /= 20
+ and then D_Length /= 21
then
raise Constraint_Error;
end if;
@@ -631,47 +792,13 @@ package body GNAT.Calendar.Time_IO is
D (1 .. D_Length) := Date;
- -- Case 1:
-
- -- hh:mm:ss
- -- yy*mm*dd
-
- if D_Length = 8 then
-
- if D (3) = ':' then
- Extract_Time (1, Hour, Minute, Second);
- else
- Extract_Date (Year, Month, Day, True);
- Hour := 0;
- Minute := 0;
- Second := 0;
- end if;
-
- -- Case 2:
-
- -- yyyy*mm*dd
-
- elsif D_Length = 10 then
- Extract_Date (Year, Month, Day);
- Hour := 0;
- Minute := 0;
- Second := 0;
-
- -- Case 3:
-
- -- yy*mm*dd hh:mm:ss
-
- elsif D_Length = 17 then
- Extract_Date (Year, Month, Day, True);
- Extract_Time (10, Hour, Minute, Second, True);
-
- -- Case 4:
-
- -- yyyy*mm*dd hh:mm:ss
-
+ if D_Length /= 8
+ or else D (3) /= ':'
+ then
+ Extract_Date (Year, Month, Day, Time_Start);
+ Extract_Time (Time_Start, Hour, Minute, Second, Check_Space => True);
else
- Extract_Date (Year, Month, Day);
- Extract_Time (12, Hour, Minute, Second, True);
+ Extract_Time (1, Hour, Minute, Second, Check_Space => False);
end if;
-- Sanity checks
diff --git a/gcc/ada/g-catiio.ads b/gcc/ada/g-catiio.ads
index 48abe6a1..5c2cbf9 100644
--- a/gcc/ada/g-catiio.ads
+++ b/gcc/ada/g-catiio.ads
@@ -118,15 +118,26 @@ package GNAT.Calendar.Time_IO is
function Value (Date : String) return Ada.Calendar.Time;
-- Parse the string Date and return its equivalent as a Time value. The
- -- following formats are supported:
+ -- following time format is supported:
--
- -- yyyy*mm*dd hh:mm:ss - Delimiter '*' is either '-' or '/'
- -- yyyy*mm*dd - The time of day is set to 00:00:00
+ -- hh:mm:ss - Date is the current date
--
- -- yy*mm*dd hh:mm:ss - Year is assumend to be 20YY
- -- yy*mm*dd - The time of day is set to 00:00:00
+ -- The following formats are also supported. They all accept an optional
+ -- time with the format "hh:mm:ss". The time is separated from the date by
+ -- exactly one space character.
+ -- When the time is not specified, it is set to 00:00:00. The delimiter '*'
+ -- must be either '-' and '/' and both occurrences must use the same
+ -- character.
+ -- Trailing characters (in particular spaces) are not allowed.
--
- -- hh:mm:ss - Date is the current date
+ -- yyyy*mm*dd
+ -- yy*mm*dd - Year is assumed to be 20yy
+ -- mm*dd*yyyy - (US date format)
+ -- dd*mmm*yyyy - month spelled out
+ -- yyyy*mmm*dd - month spelled out
+ -- yyyymmdd - Iso format, no separator
+ -- mmm dd, yyyy - month spelled out
+ -- dd mmm yyyy - month spelled out
--
-- Constraint_Error is raised if the input string is malformatted or
-- the resulting time is not valid.
diff --git a/gcc/ada/g-dirope.adb b/gcc/ada/g-dirope.adb
index fe9b5f1..774444d 100644
--- a/gcc/ada/g-dirope.adb
+++ b/gcc/ada/g-dirope.adb
@@ -56,6 +56,10 @@ package body GNAT.Directory_Operations is
procedure Free is new
Ada.Unchecked_Deallocation (Dir_Type_Value, Dir_Type);
+ On_Windows : constant Boolean := GNAT.OS_Lib.Directory_Separator = '\';
+ -- An indication that we are on Windows. Used in Get_Current_Dir, to
+ -- deal with drive letters in the beginning of absolute paths.
+
---------------
-- Base_Name --
---------------
@@ -591,6 +595,15 @@ package body GNAT.Directory_Operations is
end if;
Dir (Buffer'First .. Last) := Buffer (Buffer'First .. Last);
+
+ -- By default, the drive letter on Windows is in upper case
+
+ if On_Windows and then Last > Dir'First and then
+ Dir (Dir'First + 1) = ':'
+ then
+ Dir (Dir'First) :=
+ Ada.Characters.Handling.To_Upper (Dir (Dir'First));
+ end if;
end Get_Current_Dir;
-------------