This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

LIBC - add strptime()


Index: language/c/libc/time/current/ChangeLog
===================================================================
RCS file: /misc/cvsfiles/ecos/packages/language/c/libc/time/current/ChangeLog,v
retrieving revision 1.10
diff -u -5 -p -r1.10 ChangeLog
--- language/c/libc/time/current/ChangeLog	23 May 2002 23:07:31 -0000	1.10
+++ language/c/libc/time/current/ChangeLog	27 Jan 2003 20:24:43 -0000
@@ -1,5 +1,12 @@
+2003-01-27  Gary Thomas  <gary@mlbassoc.com>
+
+	* tests/strptime.c: 
+	* src/strptime.cxx: 
+	* include/time.h: 
+	* cdl/time.cdl: Add support for strptime().
+
 2002-05-14  Jesper Skov  <jskov@redhat.com>
 
 	* cdl/time.cdl: Added -Wno-format to the compiler flags. This is
 	to avoid warnings about Y2K problems with the format specifiers
 	used in the strftime test.
Index: language/c/libc/time/current/cdl/time.cdl
===================================================================
RCS file: /misc/cvsfiles/ecos/packages/language/c/libc/time/current/cdl/time.cdl,v
retrieving revision 1.5
diff -u -5 -p -r1.5 time.cdl
--- language/c/libc/time/current/cdl/time.cdl	23 May 2002 23:07:31 -0000	1.5
+++ language/c/libc/time/current/cdl/time.cdl	27 Jan 2003 20:54:42 -0000
@@ -63,15 +63,16 @@ cdl_package CYGPKG_LIBC_TIME {
                        "<cyg/libc/time/time.h>" }
     requires      CYGPKG_ISOINFRA
     requires      CYGINT_ISO_DIV
     requires      CYGINT_ISO_ABS
 
-    compile       asctime.cxx       asctime_r.cxx    clock.cxx      \
-                  ctime.cxx         ctime_r.cxx      difftime.cxx   \
-                  gmtime.cxx        gmtime_r.cxx     localtime.cxx  \
-                  localtime_r.cxx   mktime.cxx       settime.cxx    \
-                  strftime.cxx      time.cxx         timeutil.cxx  
+    compile       asctime.cxx       clock.cxx      \
+                  ctime.cxx         difftime.cxx   \
+                  gmtime.cxx        localtime.cxx  \
+                  mktime.cxx        settime.cxx    \
+                  strftime.cxx      time.cxx       \
+                  timeutil.cxx
 

 # ====================================================================
 
     cdl_option CYGSEM_LIBC_TIME_CLOCK_WORKING {
@@ -112,14 +113,17 @@ cdl_package CYGPKG_LIBC_TIME {
     }
     
     cdl_option CYGFUN_LIBC_TIME_POSIX {
         display       "POSIX time functions"
         default_value 1
+        requires      CYGFUN_LIBC_STRING_BSD_FUNCS
+        compile       asctime_r.cxx ctime_r.cxx gmtime_r.cxx \
+                      localtime_r.cxx strptime.cxx
         description   "
             Enabling this option allows the use of the
             following functions defined in POSIX 1003.1:
-            asctime_r(), ctime_r(), gmtime_r(), and
+            asctime_r(), ctime_r(), gmtime_r(), strptime(), and
             localtime_r()."
     }
 
     cdl_option CYGFUN_LIBC_TIME_SUS_EXTNS {
 	display       "Single UNIX extensions"
@@ -314,11 +318,14 @@ cdl_package CYGPKG_LIBC_TIME {
 
         cdl_option CYGPKG_LIBC_TIME_TESTS {
             display "C library time and date function tests"
             flavor  data
             no_define
-            calculated { "tests/asctime tests/clock tests/ctime tests/gmtime tests/localtime tests/mktime tests/strftime tests/time" }
+            calculated { 
+                "tests/asctime tests/clock tests/ctime tests/gmtime tests/localtime tests/mktime tests/strftime tests/time " 
+                . (CYGSEM_LIBC_TIME_POSIX_TIME_ROUTINES ? "tests/strptime" : "")
+            }
             description   "
                 This option specifies the set of tests for the C library
                 time and date functions."
         }
     }
Index: language/c/libc/time/current/include/time.h
===================================================================
RCS file: /misc/cvsfiles/ecos/packages/language/c/libc/time/current/include/time.h,v
retrieving revision 1.3
diff -u -5 -p -r1.3 time.h
--- language/c/libc/time/current/include/time.h	23 May 2002 23:07:32 -0000	1.3
+++ language/c/libc/time/current/include/time.h	27 Jan 2003 20:57:08 -0000
@@ -9,10 +9,11 @@
 //===========================================================================
 //####ECOSGPLCOPYRIGHTBEGIN####
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Gary Thomas
 //
 // eCos is free software; you can redistribute it and/or modify it under
 // the terms of the GNU General Public License as published by the Free
 // Software Foundation; either version 2 or (at your option) any later version.
 //
@@ -141,10 +142,21 @@ gmtime_r( const time_t *__timer, struct 
 // stores the result in the space occupied by __result
 //
 
 extern struct tm *
 localtime_r( const time_t *__timer, struct tm *__result );
+
+/////////////////////////////////////////////////////////
+// strptime() - 
+/////////////////////////////////////////////////////////
+//
+// Parse a time string into a struct tm  
+//
+
+extern char *
+strptime( const char *__s, const char *__format, 
+          struct tm *__timeptr); //__attribute__ ((format (strftime, 2)));
 

 #endif // ifdef CYGFUN_LIBC_TIME_POSIX
 
 //===========================================================================
Index: language/c/libc/time/current/src/strptime.cxx
===================================================================
RCS file: language/c/libc/time/current/src/strptime.cxx
diff -N language/c/libc/time/current/src/strptime.cxx
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ language/c/libc/time/current/src/strptime.cxx	27 Jan 2003 20:33:20 -0000
@@ -0,0 +1,427 @@
+//
+// Adapted for use in eCos by Gary Thomas
+// Copyright (C) 2003 Gary Thomas
+//
+
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of KTH nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <time.h>
+
+static const char *weekdays[] = {
+    "Sunday",
+    "Monday",
+    "Tuesday",
+    "Wednesday",
+    "Thursday",
+    "Friday",
+    "Saturday",
+    NULL
+};
+
+static const char *month[] = {
+    "January",
+    "February",
+    "Mars",
+    "April",
+    "May",
+    "June",
+    "July",
+    "August",
+    "September",
+    "October",
+    "November",
+    "December",
+    NULL,
+};
+
+static const char *ampm[] = {
+    "am",
+    "pm",
+    NULL
+};
+
+/*
+ * Try to match `*buf' to one of the strings in `strs'.  Return the
+ * index of the matching string (or -1 if none).  Also advance buf.
+ */
+
+static int
+match_string (const char **buf, const char **strs, int ablen)
+{
+    int i = 0;
+
+    for (i = 0; strs[i] != NULL; ++i) {
+	int len = ablen > 0 ? ablen : strlen (strs[i]);
+
+	if (strncasecmp (*buf, strs[i], len) == 0) {
+	    *buf += len;
+	    return i;
+	}
+    }
+    return -1;
+}
+
+/*
+ * tm_year is relative this year 
+ */
+
+const int tm_year_base = 1900;
+
+/*
+ * Return TRUE iff `year' was a leap year.
+ */
+
+static int
+is_leap_year (int year)
+{
+    return (year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0);
+}
+
+/*
+ * Return the weekday [0,6] (0 = Sunday) of the first day of `year'
+ */
+
+static int
+first_day (int year)
+{
+    int ret = 4;  // Jan 1, 1970 was on Thursday
+
+    for (; year > 1970; --year)
+	ret = (ret + 365 + is_leap_year (year) ? 1 : 0) % 7;
+    return ret;
+}
+
+/*
+ * Set `timeptr' given `wnum' (week number [0, 53])
+ */
+
+static void
+set_week_number_sun (struct tm *timeptr, int wnum)
+{
+    int fday = first_day (timeptr->tm_year + tm_year_base);
+
+    timeptr->tm_yday = wnum * 7 + timeptr->tm_wday - fday;
+    if (timeptr->tm_yday < 0) {
+	timeptr->tm_wday = fday;
+	timeptr->tm_yday = 0;
+    }
+}
+
+/*
+ * Set `timeptr' given `wnum' (week number [0, 53])
+ */
+
+static void
+set_week_number_mon (struct tm *timeptr, int wnum)
+{
+    int fday = (first_day (timeptr->tm_year + tm_year_base) + 6) % 7;
+
+    timeptr->tm_yday = wnum * 7 + (timeptr->tm_wday + 6) % 7 - fday;
+    if (timeptr->tm_yday < 0) {
+	timeptr->tm_wday = (fday + 1) % 7;
+	timeptr->tm_yday = 0;
+    }
+}
+
+/*
+ * Set `timeptr' given `wnum' (week number [0, 53])
+ */
+
+static void
+set_week_number_mon4 (struct tm *timeptr, int wnum)
+{
+    int fday = (first_day (timeptr->tm_year + tm_year_base) + 6) % 7;
+    int offset = 0;
+
+    if (fday < 4)
+	offset += 7;
+
+    timeptr->tm_yday = offset + (wnum - 1) * 7 + timeptr->tm_wday - fday;
+    if (timeptr->tm_yday < 0) {
+	timeptr->tm_wday = fday;
+	timeptr->tm_yday = 0;
+    }
+}
+
+/*
+ *
+ */
+
+char *
+strptime (const char *buf, const char *format, struct tm *timeptr)
+{
+    char c;
+
+    timeptr->tm_yday = 1;  // So it's always valid
+    timeptr->tm_isdst = 0;
+
+    for (; (c = *format) != '\0'; ++format) {
+	char *s;
+	int ret;
+
+	if (isspace (c)) {
+	    while (isspace (*buf))
+		++buf;
+	} else if (c == '%' && format[1] != '\0') {
+	    c = *++format;
+	    if (c == 'E' || c == 'O')
+		c = *++format;
+	    switch (c) {
+	    case 'A' :
+		ret = match_string (&buf, weekdays, 0);
+		if (ret < 0)
+		    return NULL;
+		timeptr->tm_wday = ret;
+		break;
+	    case 'a' :
+		ret = match_string (&buf, weekdays, 3);
+		if (ret < 0)
+		    return NULL;
+		timeptr->tm_wday = ret;
+		break;
+	    case 'B' :
+		ret = match_string (&buf, month, 0);
+		if (ret < 0)
+		    return NULL;
+		timeptr->tm_mon = ret;
+		break;
+	    case 'b' :
+	    case 'h' :
+		ret = match_string (&buf, month, 3);
+		if (ret < 0)
+		    return NULL;
+		timeptr->tm_mon = ret;
+		break;
+	    case 'C' :
+		ret = strtol (buf, &s, 10);
+		if (s == buf)
+		    return NULL;
+		timeptr->tm_year = (ret * 100) - tm_year_base;
+		buf = s;
+		break;
+	    case 'c' :
+                // Date and Time in the current locale - unsupported
+                return NULL;
+	    case 'D' :		/* %m/%d/%y */
+		s = strptime (buf, "%m/%d/%y", timeptr);
+		if (s == NULL)
+		    return NULL;
+		buf = s;
+		break;
+	    case 'd' :
+	    case 'e' :
+		ret = strtol (buf, &s, 10);
+		if (s == buf)
+		    return NULL;
+		timeptr->tm_mday = ret;
+		buf = s;
+		break;
+	    case 'H' :
+	    case 'k' :
+		ret = strtol (buf, &s, 10);
+		if (s == buf)
+		    return NULL;
+		timeptr->tm_hour = ret;
+		buf = s;
+		break;
+	    case 'I' :
+	    case 'l' :
+		ret = strtol (buf, &s, 10);
+		if (s == buf)
+		    return NULL;
+		if (ret == 12)
+		    timeptr->tm_hour = 0;
+		else
+		    timeptr->tm_hour = ret;
+		buf = s;
+		break;
+	    case 'j' :
+		ret = strtol (buf, &s, 10);
+		if (s == buf)
+		    return NULL;
+		timeptr->tm_yday = ret - 1;
+		buf = s;
+		break;
+	    case 'm' :
+		ret = strtol (buf, &s, 10);
+		if (s == buf)
+		    return NULL;
+		timeptr->tm_mon = ret - 1;
+		buf = s;
+		break;
+	    case 'M' :
+		ret = strtol (buf, &s, 10);
+		if (s == buf)
+		    return NULL;
+		timeptr->tm_min = ret;
+		buf = s;
+		break;
+	    case 'n' :
+		if (*buf == '\n')
+		    ++buf;
+		else
+		    return NULL;
+		break;
+	    case 'p' :
+		ret = match_string (&buf, ampm, 0);
+		if (ret < 0)
+		    return NULL;
+		if (timeptr->tm_hour == 0) {
+		    if (ret == 1)
+			timeptr->tm_hour = 12;
+		} else
+		    timeptr->tm_hour += 12;
+		break;
+	    case 'r' :		/* %I:%M:%S %p */
+		s = strptime (buf, "%I:%M:%S %p", timeptr);
+		if (s == NULL)
+		    return NULL;
+		buf = s;
+		break;
+	    case 'R' :		/* %H:%M */
+		s = strptime (buf, "%H:%M", timeptr);
+		if (s == NULL)
+		    return NULL;
+		buf = s;
+		break;
+	    case 'S' :
+		ret = strtol (buf, &s, 10);
+		if (s == buf)
+		    return NULL;
+		timeptr->tm_sec = ret;
+		buf = s;
+		break;
+	    case 't' :
+		if (*buf == '\t')
+		    ++buf;
+		else
+		    return NULL;
+		break;
+	    case 'T' :		/* %H:%M:%S */
+	    case 'X' :
+		s = strptime (buf, "%H:%M:%S", timeptr);
+		if (s == NULL)
+		    return NULL;
+		buf = s;
+		break;
+	    case 'u' :
+		ret = strtol (buf, &s, 10);
+		if (s == buf)
+		    return NULL;
+		timeptr->tm_wday = ret - 1;
+		buf = s;
+		break;
+	    case 'w' :
+		ret = strtol (buf, &s, 10);
+		if (s == buf)
+		    return NULL;
+		timeptr->tm_wday = ret;
+		buf = s;
+		break;
+	    case 'U' :
+		ret = strtol (buf, &s, 10);
+		if (s == buf)
+		    return NULL;
+		set_week_number_sun (timeptr, ret);
+		buf = s;
+		break;
+	    case 'V' :
+		ret = strtol (buf, &s, 10);
+		if (s == buf)
+		    return NULL;
+		set_week_number_mon4 (timeptr, ret);
+		buf = s;
+		break;
+	    case 'W' :
+		ret = strtol (buf, &s, 10);
+		if (s == buf)
+		    return NULL;
+		set_week_number_mon (timeptr, ret);
+		buf = s;
+		break;
+	    case 'x' :
+		s = strptime (buf, "%Y:%m:%d", timeptr);
+		if (s == NULL)
+		    return NULL;
+		buf = s;
+		break;
+	    case 'y' :
+		ret = strtol (buf, &s, 10);
+		if (s == buf)
+		    return NULL;
+		if (ret < 70)
+		    timeptr->tm_year = 100 + ret;
+		else
+		    timeptr->tm_year = ret;
+		buf = s;
+		break;
+	    case 'Y' :
+		ret = strtol (buf, &s, 10);
+		if (s == buf)
+		    return NULL;
+		timeptr->tm_year = ret - tm_year_base;
+		buf = s;
+		break;
+	    case 'Z' :
+                // Timezone spec not handled
+                return NULL;
+	    case '\0' :
+		--format;
+		/* FALLTHROUGH */
+	    case '%' :
+		if (*buf == '%')
+		    ++buf;
+		else
+		    return NULL;
+		break;
+	    default :
+		if (*buf == '%' || *++buf == c)
+		    ++buf;
+		else
+		    return NULL;
+		break;
+	    }
+	} else {
+	    if (*buf == c)
+		++buf;
+	    else
+		return NULL;
+	}
+    }
+    return (char *)buf;
+}
+
+// strptime.cxx
Index: language/c/libc/time/current/tests/strptime.c
===================================================================
RCS file: language/c/libc/time/current/tests/strptime.c
diff -N language/c/libc/time/current/tests/strptime.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ language/c/libc/time/current/tests/strptime.c	27 Jan 2003 20:24:32 -0000
@@ -0,0 +1,118 @@
+//=================================================================
+//
+//        strptime.c
+//
+//        Testcase for C library strptime() function
+//
+//=================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Gary Thomas
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     jlarmour
+// Contributors:  gthomas
+// Date:          1999-03-05
+// Description:   Contains testcode for C library strptime() function
+//
+//
+//####DESCRIPTIONEND####
+
+// CONFIGURATION
+
+#include <pkgconf/libc_time.h>          // C library configuration
+
+// INCLUDES
+
+#include <time.h>
+#include <cyg/infra/testcase.h>
+
+// HOW TO START TESTS
+
+# define START_TEST( test ) test(0)
+
+// FUNCTIONS
+
+static int my_strcmp(const char *s1, const char *s2)
+{
+    for ( ; *s1 == *s2 ; s1++,s2++ )
+    {
+        if ( *s1 == '\0' )
+            break;
+    } // for
+
+    return (*s1 - *s2);
+} // my_strcmp()
+
+static void
+test( CYG_ADDRWORD data )
+{
+    struct tm tm1;
+    char s[1000], *sp, *dp, *fp;
+    size_t size;
+    
+    dp = "Fri Jan 24 08:33:14 2003";
+    fp = "%a %b %d %H:%M:%S %Y";
+    sp = strptime(dp, fp, &tm1);    
+    CYG_TEST_PASS_FAIL(((sp!=NULL) && (*sp=='\0')), "strptime test #1");
+    size = strftime(s, sizeof(s), fp, &tm1);
+    CYG_TEST_PASS_FAIL(((size==strlen(dp)) && (my_strcmp(s, dp) == 0)), "strptime test #2");
+    
+    dp = "Friday January 24 08:33:14 2003";
+    fp = "%A %B %d %H:%M:%S %Y";
+    sp = strptime(dp, fp, &tm1);    
+    CYG_TEST_PASS_FAIL(((sp!=NULL) && (*sp=='\0')), "strptime test #3");
+    size = strftime(s, sizeof(s), fp, &tm1);
+    CYG_TEST_PASS_FAIL(((size==strlen(dp)) && (my_strcmp(s, dp) == 0)), "strptime test #4");
+
+    CYG_TEST_FINISH("Finished tests from testcase " __FILE__ " for C library "
+                    "strptime() function");
+} // test()
+
+
+int
+main(int argc, char *argv[])
+{
+    CYG_TEST_INIT();
+
+    CYG_TEST_INFO("Starting tests from testcase " __FILE__ " for C library "
+                  "strptime() function");
+
+    START_TEST( test );
+
+    CYG_TEST_NA("Testing is not applicable to this configuration");
+
+} // main()
+
+// EOF strptime.c


-- 
------------------------------------------------------------
Gary Thomas                 |
MLB Associates              |  Consulting for the
+1 (970) 229-1963           |    Embedded world
http://www.mlbassoc.com/    |
email: <gary@mlbassoc.com>  |
gpg: http://www.chez-thomas.org/gary/gpg_key.asc
------------------------------------------------------------


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]