OSSP CVS Repository

ossp - Check-in [2075]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 2075
Date: 2002-Apr-18 11:10:45 (local)
2002-Apr-18 09:10:45 (UTC)
User:rse
Branch:
Comment: Initial revision
Tickets:
Inspections:
Files:
ossp-pkg/tai/Makefile.in      added-> 1.1
ossp-pkg/tai/tai_lib.c      added-> 1.1
ossp-pkg/tai/tai_p.h      added-> 1.1
ossp-pkg/tai/tai_test.c      added-> 1.1

ossp-pkg/tai/Makefile.in -> 1.1

*** /dev/null    Sat Nov 23 01:24:58 2024
--- -    Sat Nov 23 01:25:09 2024
***************
*** 0 ****
--- 1,112 ----
+ ##
+ ##  OSSP tai - Time Handling
+ ##  Copyright (c) 2002 Ralf S. Engelschall <rse@engelschall.com>
+ ##  Copyright (c) 2002 The OSSP Project <http://www.ossp.org/>
+ ##  Copyright (c) 2002 Cable & Wireless Deutschland <http://www.cw.com/de/>
+ ##
+ ##  This file is part of OSSP tai, a time handling library
+ ##  which can be found at http://www.ossp.org/pkg/lib/tai/.
+ ##
+ ##  Permission to use, copy, modify, and distribute this software for
+ ##  any purpose with or without fee is hereby granted, provided that
+ ##  the above copyright notice and this permission notice appear in all
+ ##  copies.
+ ##
+ ##  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+ ##  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.
+ ##
+ ##  Makefile.in: make(1) build procedure
+ ##
+ 
+ @SET_MAKE@
+ 
+ DESTDIR     =
+ prefix      = @prefix@
+ exec_prefix = @exec_prefix@
+ bindir      = @bindir@
+ libdir      = @libdir@
+ includedir  = @includedir@
+ mandir      = @mandir@
+ 
+ CC          = @CC@
+ CPPFLAGS    = @CPPFLAGS@
+ CFLAGS      = @DEFS@ @CFLAGS@
+ LDFLAGS     = @LDFLAGS@
+ LIBS        = @LIBS@
+ RM          = rm -f
+ RMDIR       = rmdir
+ SHTOOL      = ./shtool
+ LIBTOOL     = ./libtool
+ TRUE        = true
+ 
+ LIB_NAME    = libtai.la
+ LIB_OBJS    = tai_lib.lo tai_format.lo tai_parse.lo tai_data.lo
+ 
+ TST_NAME    = tai_test
+ TST_OBJS    = tai_test.o ts.o
+ 
+ .SUFFIXES:
+ .SUFFIXES: .c .o .lo
+ 
+ all: $(LIB_NAME) $(TST_NAME)
+ 
+ .c.o:
+        $(CC) $(CPPFLAGS) $(CFLAGS) -c $<
+ 
+ .c.lo:
+        @$(LIBTOOL) --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS) -c $<
+ 
+ $(LIB_NAME): $(LIB_OBJS)
+        @$(LIBTOOL) --mode=link $(CC) -o $(LIB_NAME) $(LIB_OBJS) -rpath $(libdir) \
+            -version-info `$(SHTOOL) version -l txt -d libtool VERSION`
+ 
+ $(TST_NAME): $(TST_OBJS) $(LIB_NAME)
+        @$(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o $(TST_NAME) $(TST_OBJS) $(LIB_NAME) $(LIBS)
+ 
+ check: $(TST_NAME)
+        @$(LIBTOOL) --mode=execute ./$(TST_NAME)
+ 
+ install:
+        $(SHTOOL) mkdir -f -p -m 755 $(DESTDIR)$(prefix)
+        $(SHTOOL) mkdir -f -p -m 755 $(DESTDIR)$(bindir)
+        $(SHTOOL) mkdir -f -p -m 755 $(DESTDIR)$(includedir)
+        $(SHTOOL) mkdir -f -p -m 755 $(DESTDIR)$(libdir)
+        $(SHTOOL) install -c -m 755 tai-config $(DESTDIR)$(bindir)/
+        $(SHTOOL) install -c -m 644 tai.h $(DESTDIR)$(includedir)/
+        @$(LIBTOOL) --mode=install $(SHTOOL) install -c -m 644 libtai.la $(DESTDIR)$(libdir)/
+ 
+ uninstall:
+        @$(LIBTOOL) --mode=uninstall $(RM) $(DESTDIR)$(libdir)/libtai.la
+        -$(RM) $(DESTDIR)$(includedir)/tai.h
+        -$(RM) $(DESTDIR)$(bindir)/tai-config
+        -$(RMDIR) $(DESTDIR)$(libdir) >/dev/null 2>&1 || $(TRUE)
+        -$(RMDIR) $(DESTDIR)$(includedir) >/dev/null 2>&1 || $(TRUE)
+        -$(RMDIR) $(DESTDIR)$(bindir) >/dev/null 2>&1 || $(TRUE)
+        -$(RMDIR) $(DESTDIR)$(prefix) >/dev/null 2>&1 || $(TRUE)
+ 
+ clean:
+        -$(RM) $(LIB_NAME) $(LIB_OBJS)
+        -$(RM) $(TST_NAME) $(TST_OBJS)
+        -$(RM) -r .libs >/dev/null 2>&1 || $(TRUE)
+        -$(RM) *.o *.lo
+ 
+ distclean: clean
+        -$(RM) config.log config.status config.cache
+        -$(RM) Makefile config.h tai-config
+        -$(RM) libtool
+ 
+ realclean: distclean
+        -$(RM) configure config.h.in
+        -$(RM) shtool
+        -$(RM) ltmain.sh libtool.m4 config.guess config.sub
+ 


ossp-pkg/tai/tai_lib.c -> 1.1

*** /dev/null    Sat Nov 23 01:24:58 2024
--- -    Sat Nov 23 01:25:09 2024
***************
*** 0 ****
--- 1,252 ----
+ /*
+ **  OSSP tai - Time Handling
+ **  Copyright (c) 2002 Ralf S. Engelschall <rse@engelschall.com>
+ **  Copyright (c) 2002 The OSSP Project <http://www.ossp.org/>
+ **  Copyright (c) 2002 Cable & Wireless Deutschland <http://www.cw.com/de/>
+ **
+ **  This file is part of OSSP tai, a time handling library
+ **  which can be found at http://www.ossp.org/pkg/lib/tai/.
+ **
+ **  Permission to use, copy, modify, and distribute this software for
+ **  any purpose with or without fee is hereby granted, provided that
+ **  the above copyright notice and this permission notice appear in all
+ **  copies.
+ **
+ **  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+ **  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.
+ **
+ **  tm.c: API implementation
+ */
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <stdarg.h>
+ #include <string.h>
+ #include <time.h>
+ 
+ #include "tai.h"
+ #include "tai_p.h"
+ 
+ struct tai_st {
+     int    tai_sec;    /* seconds after the minute [0-61] */
+     int    tai_min;    /* minutes after the hour [0-59] */
+     int    tai_hour;   /* hours since midnight [0-23] */
+     int    tai_mday;   /* day of the month [1-31] */
+     int    tai_mon;    /* months since January [0-11] */
+     int    tai_year;   /* years since 1900 */
+     int    tai_wday;   /* days since Sunday [0-6] */
+     int    tai_yday;   /* days since January 1 [0-365] */
+     int    tai_isdst;  /* Daylight Savings Time flag */
+     long   tai_gmtoff; /* offset from CUT in seconds */
+     char  *tai_zone;   /* timezone abbreviation */
+ #if 0
+     int sign;
+     unsigned long long sec;
+     unsigned long nsec;
+     unsigned long asec;
+ #endif
+ };
+ 
+ tai_rc_t tai_create(tai_t **ptai)
+ {
+     tai_t *tai;
+     tai_rc_t rv;
+ 
+     if ((tai = (tai_t *)malloc(sizeof(tai_t))) == NULL)
+         return TAI_ERR_SYS;
+     if ((rv = tai_import(tai, TAI_TYPE_TIMET, 0)) != TAI_OK) {
+         free(tai);
+         return rv;
+     }
+     *ptai = tai;
+     return TAI_OK;
+ }
+ 
+ tai_rc_t tai_destroy(tai_t *tai)
+ {
+     if (tai == NULL)
+         return TAI_ERR_ARG;
+     if (tai->tai_zone != NULL)
+         free(tai->tai_zone);
+     free(tai);
+     return TAI_OK;
+ }
+ 
+ tai_rc_t tai_import(tai_t *tai, tai_type_t type, ...)
+ {
+     va_list ap;
+ 
+     if (tai == NULL)
+         return TAI_ERR_ARG;
+     va_start(ap, type); 
+     if (type == TAI_TYPE_TIMET) {
+         /* import from time_t */
+ #ifdef HAVE_GMTIME_R
+         struct tm stmbuf;
+ #endif
+         struct tm *stm;
+         time_t t;
+         t = (time_t)va_arg(ap, long);
+ #ifdef HAVE_GMTIME_R
+         stm = gmtime_r(&t, &stmbuf);
+ #else
+         stm = gmtime(&t);
+ #endif
+         tai->tai_sec    = stm->tm_sec;
+         tai->tai_min    = stm->tm_min;
+         tai->tai_hour   = stm->tm_hour;
+         tai->tai_mday   = stm->tm_mday;
+         tai->tai_mon    = stm->tm_mon;
+         tai->tai_year   = stm->tm_year;
+         tai->tai_wday   = stm->tm_wday;
+         tai->tai_yday   = stm->tm_yday;
+         tai->tai_isdst  = stm->tm_isdst;
+         tai->tai_gmtoff = stm->tm_gmtoff;
+         if (stm->tm_zone == NULL)
+             tai->tai_zone = strdup("");
+         else
+             tai->tai_zone = strdup(stm->tm_zone);
+     }
+     else if (type == TAI_TYPE_STRUCTTM) {
+         /* import from struct tm */
+         struct tm *stm;
+         stm = (struct tm *)va_arg(ap, void *);
+ #define TM_ISRANGE(var,field,min,max) \
+     (var->tm_##field >= (min) && var->tm_##field <= (max))
+         if (!TM_ISRANGE(stm,sec,0,61)   ||
+             !TM_ISRANGE(stm,min,0,59)   ||
+             !TM_ISRANGE(stm,hour,0,23)  ||
+             !TM_ISRANGE(stm,mday,1,31)  ||
+             !TM_ISRANGE(stm,mon,0,11)   ||
+             !TM_ISRANGE(stm,wday,0,6)   ||
+             !TM_ISRANGE(stm,yday,0,365) ||
+             !TM_ISRANGE(stm,isdst,0,1))
+             return TAI_ERR_ARG;
+         tai->tai_sec    = stm->tm_sec;
+         tai->tai_min    = stm->tm_min;
+         tai->tai_hour   = stm->tm_hour;
+         tai->tai_mday   = stm->tm_mday;
+         tai->tai_mon    = stm->tm_mon;
+         tai->tai_year   = stm->tm_year;
+         tai->tai_wday   = stm->tm_wday;
+         tai->tai_yday   = stm->tm_yday;
+         tai->tai_isdst  = stm->tm_isdst;
+         tai->tai_gmtoff = stm->tm_gmtoff;
+         if (stm->tm_zone == NULL)
+             tai->tai_zone = strdup("");
+         else
+             tai->tai_zone = strdup(stm->tm_zone);
+     }
+     else
+         return TAI_ERR_IMP; /* FIXME */
+     va_end(ap); 
+     return TAI_OK;
+ }
+ 
+ tai_rc_t tai_export(tai_t *tai, tai_type_t type, ...)
+ {
+     va_list ap;
+ 
+     if (tai == NULL)
+         return TAI_ERR_ARG;
+     va_start(ap, type); 
+     if (type == TAI_TYPE_TIMET) {
+         time_t *pt;
+         struct tm stmbuf;
+         struct tm *stm;
+ #ifndef HAVE_TIMEGM
+         time_t t;
+ #endif
+         pt = (time_t *)va_arg(ap, void *);
+         stm = &stmbuf;
+         stm->tm_sec    = tai->tai_sec;
+         stm->tm_min    = tai->tai_min;
+         stm->tm_hour   = tai->tai_hour;
+         stm->tm_mday   = tai->tai_mday;
+         stm->tm_mon    = tai->tai_mon;
+         stm->tm_year   = tai->tai_year;
+         stm->tm_wday   = tai->tai_wday;
+         stm->tm_yday   = tai->tai_yday;
+         stm->tm_isdst  = tai->tai_isdst;
+         stm->tm_gmtoff = tai->tai_gmtoff;
+         stm->tm_zone   = tai->tai_zone;
+ #ifdef HAVE_TIMEGM
+         /* non-standard timegm(3) makes our life easy */
+         *pt = timegm(stm);
+ #else
+         /* standard mktime(3) calculated relative to local timezone,
+            so we have to post-adjust result */
+         *pt = mktime(stm);
+         t = 12*60*60*2; /* max offset of 12 hours plus safety */
+         *pt += (mktime(localtime(&t)) - mktime(gmtime(&t)));
+ #endif
+     }
+     else if (type == TAI_TYPE_STRUCTTM) {
+         struct tm *stm;
+         
+         stm = (struct tm *)va_arg(ap, void *);
+         stm->tm_sec    = tai->tai_sec;
+         stm->tm_min    = tai->tai_min;
+         stm->tm_hour   = tai->tai_hour;
+         stm->tm_mday   = tai->tai_mday;
+         stm->tm_mon    = tai->tai_mon;
+         stm->tm_year   = tai->tai_year;
+         stm->tm_wday   = tai->tai_wday;
+         stm->tm_yday   = tai->tai_yday;
+         stm->tm_isdst  = tai->tai_isdst;
+         stm->tm_gmtoff = tai->tai_gmtoff;
+         stm->tm_zone   = strdup(tai->tai_zone);
+     }
+     else
+         return TAI_ERR_IMP; /* FIXME */
+     va_end(ap); 
+     return TAI_OK;
+ }
+ 
+ tai_rc_t tai_format(tai_t *tai, char *buf_ptr, size_t buf_len, const char *fmt)
+ {
+     struct tm stm;
+     tai_rc_t rv;
+ 
+     if (tai == NULL || buf_ptr == NULL || buf_len == 0 || fmt == NULL)
+         return TAI_ERR_ARG;
+     if ((rv = tai_export(tai, TAI_TYPE_STRUCTTM, &stm)) != TAI_OK)
+         return rv;
+     if (tai_format_int(buf_ptr, buf_len, fmt, &stm) == 0)
+         return TAI_ERR_FMT;
+     return TAI_OK;
+ }
+ 
+ tai_rc_t tai_parse(tai_t *tai, const char *buf_ptr, size_t buf_len, const char *fmt)
+ {
+     struct tm stm;
+     char *cp;
+     char *cp2;
+     tai_rc_t rv;
+ 
+     if (tai == NULL || buf_ptr == NULL || buf_len == 0 || fmt == NULL)
+         return TAI_ERR_ARG;
+     if ((cp = malloc(buf_len+1)) == NULL)
+         return TAI_ERR_SYS;
+     memmove(cp, buf_ptr, buf_len);
+     cp[buf_len] = '\0';
+     memset(&stm, 0, sizeof(struct tm));
+     cp2 = tai_parse_int(cp, fmt, &stm);
+     free(cp);
+     if (cp2 == NULL)
+         return TAI_ERR_PRS;
+     if ((rv = tai_import(tai, TAI_TYPE_STRUCTTM, &stm)) != TAI_OK)
+         return rv;
+     return TAI_OK;
+ }
+ 


ossp-pkg/tai/tai_p.h -> 1.1

*** /dev/null    Sat Nov 23 01:24:58 2024
--- -    Sat Nov 23 01:25:09 2024
***************
*** 0 ****
--- 1,63 ----
+ /*-
+  * Copyright (c) 1997-2002 FreeBSD Project.
+  * 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.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND 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 THE AUTHOR OR 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.
+  *
+  * $FreeBSD: src/lib/libc/stdtime/timelocal.h,v 1.11 2002/01/24 15:07:44 phantom Exp $
+  */
+ 
+ #ifndef _TIMELOCAL_H_
+ #define        _TIMELOCAL_H_
+ 
+ #include <time.h>
+ 
+ #include "config.h"
+ 
+ /*
+  * Private header file for the strftime and strptime localization
+  * stuff.
+  */
+ typedef struct {
+        const char      *mon[12];
+        const char      *month[12];
+        const char      *wday[7];
+        const char      *weekday[7];
+        const char      *X_fmt;
+        const char      *x_fmt;
+        const char      *c_fmt;
+        const char      *am;
+        const char      *pm;
+        const char      *date_fmt;
+        const char      *alt_month[12];
+        const char      *md_order;
+        const char      *ampm_fmt;
+ } tai_locale_t;
+ 
+ extern const tai_locale_t tai_locale;
+ 
+ #define TM_YEAR_BASE   1900
+ 
+ size_t  tai_format_int(char *const s, const size_t maxsize, const char *const format, const struct tm *const t);
+ char   *tai_parse_int (const char *buf, const char *fmt, struct tm *tm);
+ 
+ #endif /* !_TIMELOCAL_H_ */


ossp-pkg/tai/tai_test.c -> 1.1

*** /dev/null    Sat Nov 23 01:24:58 2024
--- -    Sat Nov 23 01:25:09 2024
***************
*** 0 ****
--- 1,138 ----
+ /*
+ **  OSSP tai - Time Handling
+ **  Copyright (c) 2002 Ralf S. Engelschall <rse@engelschall.com>
+ **  Copyright (c) 2002 The OSSP Project <http://www.ossp.org/>
+ **  Copyright (c) 2002 Cable & Wireless Deutschland <http://www.cw.com/de/>
+ **
+ **  This file is part of OSSP tai, a time handling library
+ **  which can be found at http://www.ossp.org/pkg/lib/tai/.
+ **
+ **  Permission to use, copy, modify, and distribute this software for
+ **  any purpose with or without fee is hereby granted, provided that
+ **  the above copyright notice and this permission notice appear in all
+ **  copies.
+ **
+ **  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+ **  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.
+ **
+ **  tai_test.c: test suite
+ */
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <time.h>
+ 
+ #include "ts.h"
+ #include "tai.h"
+ 
+ TS_TEST(test_object)
+ {
+     tai_t *tm;
+     tai_rc_t rv;
+ 
+     ts_test_check(TS_CTX, "object creation");
+     if ((rv = tai_create(&tm)) != TAI_OK) {
+         ts_test_fail(TS_CTX, "tai_create: rv=%d", rv);
+         return;
+     }
+ 
+     ts_test_check(TS_CTX, "object destruction");
+     if ((rv = tai_destroy(tm)) != TAI_OK)
+         ts_test_fail(TS_CTX, "tai_destroy: rv=%d", rv);
+ }
+ 
+ TS_TEST(test_importexport)
+ {
+     tai_t *tm;
+     tai_rc_t rv;
+     time_t t;
+     time_t t2;
+ 
+     ts_test_check(TS_CTX, "time import");
+     tai_create(&tm);
+     if ((rv = tai_import(tm, TAI_TYPE_TIMET, 0)) != TAI_OK)
+         ts_test_fail(TS_CTX, "tai_import: rv=%d", rv);
+     if ((rv = tai_export(tm, TAI_TYPE_TIMET, &t)) != TAI_OK)
+         ts_test_fail(TS_CTX, "tai_export: rv=%d", rv);
+     if (t != 0)
+         ts_test_fail(TS_CTX, "unexpected time %d (!= 0)", t);
+     t = time(NULL);
+     if ((rv = tai_import(tm, TAI_TYPE_TIMET, t)) != TAI_OK)
+         ts_test_fail(TS_CTX, "tai_import: rv=%d", rv);
+     if ((rv = tai_export(tm, TAI_TYPE_TIMET, &t2)) != TAI_OK)
+         ts_test_fail(TS_CTX, "tai_export: rv=%d", rv);
+     if (t != t2)
+         ts_test_fail(TS_CTX, "unexpected time %d (!= %d)", t2, t);
+     tai_destroy(tm);
+ }
+ 
+ TS_TEST(test_parsing)
+ {
+     tai_t *tm;
+     tai_rc_t rv;
+     char out[32];
+     int i;
+     struct {
+         char *date;
+         char *fmt;
+     } table[] = {
+         { "2000-02-22", "%Y-%m-%d" },
+         { "22-02-2000", "%d-%m-%Y" },
+         { "22-Feb-2000", "%d-%b-%Y" },
+         { "29-Feb-2000", "%d-%b-%Y" },
+         { "31-Feb-2000", "%d-%b-%Y" },
+         { NULL, NULL }
+     };
+ 
+     ts_test_check(TS_CTX, "time parsing");
+     tai_create(&tm);
+     for (i = 0; table[i].date != NULL; i++) {
+         ts_test_log(TS_CTX, "date=%s, fmt=%s", table[i].date, table[i].fmt);
+         if ((rv = tai_parse(tm, table[i].date, strlen(table[i].date), table[i].fmt)) != TAI_OK) 
+             ts_test_fail(TS_CTX, "#%d: tai_parse(\"%s\"): rv=%d", i, table[i].date, rv);
+         else {
+             if ((rv = tai_format(tm, out, sizeof(out), table[i].fmt)) != TAI_OK) 
+                 ts_test_fail(TS_CTX, "#%d: tai_format(\"%s\"): rv=%d", i, table[i].date, rv);
+             if (strcmp(table[i].date, out) != 0)
+                 ts_test_fail(TS_CTX, "#%d: output \"%s\", expected \"%s\" (input)", i, out, table[i].date);
+         }
+     }
+     tai_destroy(tm);
+ }
+ 
+ TS_TEST(test_formatting)
+ {
+     tai_t *tm;
+ 
+     ts_test_check(TS_CTX, "time formatting");
+     tai_create(&tm);
+     /* FIXME */
+     tai_destroy(tm);
+ }
+ 
+ int main(int argc, char *argv[])
+ {
+     ts_suite_t *ts;
+     int n;
+ 
+     ts = ts_suite_new("OSSP tai (Time Handling)");
+     ts_suite_test(ts, test_object,       "object handling");
+     ts_suite_test(ts, test_importexport, "time import/export");
+     ts_suite_test(ts, test_parsing,      "time parsing");
+     ts_suite_test(ts, test_formatting,   "time formatting");
+     n = ts_suite_run(ts);
+     ts_suite_free(ts);
+     return n;
+ }
+ 

CVSTrac 2.0.1