Changeset 2909


Ignore:
Timestamp:
Dec 26, 2006, 8:12:42 PM (19 years ago)
Author:
bird
Message:

Cleaning up time stuff. Early commit (dinner).

Location:
trunk/libc
Files:
2 added
3 deleted
29 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/libc/include/InnoTekLIBC/locale.h

    r2729 r2909  
    1 /* $Id$ */
    2 /** @file
    3  *
    4  * Internal InnoTek LIBC header.
    5  * Locale support implementation through OS/2 Unicode API.
    6  *
    7  * Copyright (c) 2003 InnoTek Systemberatung GmbH
    8  * Copyright (c) 2003-2004 knut st. osmundsen <bird-srcspam@anduin.net>
    9  *
    10  *
    11  * This file is part of InnoTek LIBC.
    12  *
    13  * InnoTek LIBC is free software; you can redistribute it and/or modify
    14  * it under the terms of the GNU General Public License as published by
    15  * the Free Software Foundation; either version 2 of the License, or
    16  * (at your option) any later version.
    17  *
    18  * InnoTek LIBC is distributed in the hope that it will be useful,
    19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    21  * GNU General Public License for more details.
    22  *
    23  * You should have received a copy of the GNU General Public License
    24  * along with InnoTek LIBC; if not, write to the Free Software
    25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    26  *
    27  */
    28 
    29 #ifndef __InnoTekLIBC_locale_h__
    30 #define __InnoTekLIBC_locale_h__
    31 
    32 #include <sys/cdefs.h>
    33 #include <sys/types.h>
    34 #include <locale.h>
    35 #ifdef __OS2__
    36 # include <uconv.h>
    37 #endif
    38 
    39 __BEGIN_DECLS
    40 
    41 /**
    42  * LC_COLLATE information.
    43  */
    44 typedef struct __libc_LocaleCollate
    45 {
    46     /** Character weight for SBCS codepages. */
    47     unsigned char   auchWeight[256];
    48     /** MBCS prefixes. Two bits per character. */
    49     unsigned char   au2MBCSPrefixs[256/4];
    50 #ifdef __OS2__
    51     /** The converter object to convert to and from selected codepage
    52       (used with MBCS codepages only). */
    53     UconvObject     uobj;
    54     /** The locale object. */
    55     LocaleObject    lobj;
    56 #endif
    57     /** Non-zero if there are any MBCS prefix characters in codepage. */
    58     char            mbcs;
    59 } __LIBC_LOCALECOLLATE;
    60 /** Pointer to locale collate structure. */
    61 typedef __LIBC_LOCALECOLLATE *__LIBC_PLOCALECOLLATE;
    62 
    63 /**
    64  * Multibyte to/from wide character conversion functions.
    65  */
    66 typedef struct __libc_localeCTypeFuncs
    67 {
    68     int     (*pfnmbsinit)(const __mbstate_t *);
    69     size_t  (*pfnmbrtowc)(__wchar_t * __restrict, const char * __restrict, size_t, __mbstate_t * __restrict);
    70     size_t  (*pfnmbsnrtowcs)(__wchar_t * __restrict, const char ** __restrict, size_t, size_t, __mbstate_t * __restrict);
    71     size_t  (*pfnwcrtomb)(char * __restrict, __wchar_t, __mbstate_t * __restrict);
    72     size_t  (*pfnwcsnrtombs)(char * __restrict, const __wchar_t ** __restrict, size_t, size_t, __mbstate_t * __restrict);
    73 } __LIBC_LOCALECTYPEFUNCS;
    74 /** Pointer to multibyte/wide character conversion functions. */
    75 typedef __LIBC_LOCALECTYPEFUNCS *__LIBC_PLOCALECTYPEFUNCS;
    76 /** Pointer to const multibyte/wide character conversion functions. */
    77 typedef const __LIBC_LOCALECTYPEFUNCS *__LIBC_PCLOCALECTYPEFUNCS;
    78 
    79 /**
    80  * This structure contains the flags and uppercase/lowercase tables.
    81  */
    82 typedef struct __libc_LocaleCtype
    83 {
    84     /** All uppercased characters. */
    85     unsigned char           auchUpper[256];
    86     /** All lowercased characters. */
    87     unsigned char           auchLower[256];
    88     /** Bit flags for every character (for isXXX() function series). */
    89     unsigned                aufType[256];
    90 
    91 /* part which we don't 'expose': */
    92     /** MBCS prefixes. Two bits per character. */
    93     unsigned char           au2MBCSPrefixs[256/4];
    94     /** Unicode translation. (0xffff means no translation.) */
    95     unsigned short          aucUnicode[256];
    96     /** Unicode -> SBCS conversion: 0..128. */
    97     unsigned char           auchToSBCS0To128[128];
    98     /** Unicode -> SBCS conversion: Custom regions. */
    99     struct
    100     {
    101         /** First unicode code point. */
    102         unsigned short      usStart;
    103         /** Number of entries used. */
    104         unsigned short      cChars;
    105         /** Array SBCS chars corresponding to (wc - usStart). 0 means no conversion. */
    106         unsigned char       auch[28];
    107     }                       aSBCSs[8];
    108     /** Number of aSBCS regions in use. */
    109     unsigned                cSBCSs;
    110     /** Conversion functions. */
    111     __LIBC_LOCALECTYPEFUNCS CtypeFuncs;
    112 #ifdef __OS2__
    113     /** The converter object to convert to and from selected codepage
    114       (used with MBCS codepages only). */
    115     UconvObject             uobj;
    116     /** The locale object. */
    117     LocaleObject            lobj;
    118 #endif
    119     /** Non-zero if there are any MBCS prefix characters in codepage. */
    120     char                    mbcs;
    121     /** Codeset name. */
    122     char                    szCodeSet[32];
    123 } __LIBC_LOCALECTYPE;
    124 /** Pointer to the Ctype locale struct. */
    125 typedef __LIBC_LOCALECTYPE *__LIBC_PLOCALECTYPE;
    126 
    127 
    128 /**
    129  * Unicode CType data.
    130  * The structure contains information for the first 256 unicode chars.
    131  */
    132 typedef struct __libc_localeWCType
    133 {
    134     /** All uppercased characters. */
    135     __wchar_t       awcUpper[256];
    136     /** All lowercased characters. */
    137     __wchar_t       awcLower[256];
    138     /** Bit flags for every character (for iswXXX() function series). */
    139     unsigned        aufType[256];
    140     /** Mask used to check if an index is within the above arrays.
    141      * This is required because 'C' doesn't do more than 0-127. So,
    142      * the mask is either ~0xff or ~0x7f. */
    143     unsigned        uMask;
    144 } __LIBC_LOCALEWCTYPE;
    145 /** Pointer to the Ctype unicode struct. */
    146 typedef __LIBC_LOCALEWCTYPE *__LIBC_PLOCALEWCTYPE;
    147 
    148 /**
    149  * This structure keeps the time formatting rules.
    150  * The fConsts flag indicates what kind of memory is backing the strings.
    151  */
    152 typedef struct __libc_LocaleTime
    153 {
    154     /** Short month names. */
    155     char   *smonths[12];
    156     /** Long month names. */
    157     char   *lmonths[12];
    158     /** Short weekday names. */
    159     char   *swdays[7];
    160     /** Long weekday names. */
    161     char   *lwdays[7];
    162     /** Date and time format. */
    163     char   *date_time_fmt;
    164     /** Date format. */
    165     char   *date_fmt;
    166     /** Time format. */
    167     char   *time_fmt;
    168     /** AM strings. */
    169     char   *am;
    170     /** PM strings. */
    171     char   *pm;
    172     /** AM/PM format. (T_FMT_AMPM) */
    173     char   *ampm_fmt;
    174     /** ERA */
    175     char   *era;
    176     /** ERA_D_FMT. */
    177     char   *era_date_fmt;
    178     /** ERA_D_T_FMT. */
    179     char   *era_date_time_fmt;
    180     /** ERA_T_FMT. */
    181     char   *era_time_fmt;
    182     /** ALT_DIGITS. */
    183     char   *alt_digits;
    184     /** DATESEP. */
    185     char   *datesep;
    186     /** TIMESEP. */
    187     char   *timesep;
    188     /** LISTSEP. */
    189     char   *listsep;
    190     /** If set all the strings are consts and shall not be free()ed. */
    191     int     fConsts;
    192 } __LIBC_LOCALETIME;
    193 /** Pointer to time locale data. */
    194 typedef __LIBC_LOCALETIME *__LIBC_PLOCALETIME;
    195 
    196 
    197 /**
    198  * Locale information structure.
    199  *
    200  * This is the lconv struct with a couple of private field indicating
    201  * which parts of it we have updated and assigned heap strings.
    202  */
    203 typedef struct __libc_localeLconv
    204 {
    205     /** The lconv structure. */
    206     struct lconv    s;
    207     /** CRNCYSTR. */
    208     char           *pszCrncyStr;
    209     /** Indicates that all the numeric members are readonly const strings. */
    210     int             fNumericConsts;
    211     /** Indicates that all the monetary members are readonly const strings. */
    212     int             fMonetaryConsts;
    213 } __LIBC_LOCALELCONV;
    214 /** Pointer to extended locale information structure. */
    215 typedef __LIBC_LOCALELCONV *__LIBC_PLOCALELCONV;
    216 
    217 
    218 /**
    219  * Message locale information.
    220  * The content is available thru the nl_langinfo() interface only.
    221  */
    222 typedef struct __libc_localeMsg
    223 {
    224     /** YESEXPR */
    225     char           *pszYesExpr;
    226     /** NOEXPR */
    227     char           *pszNoExpr;
    228     /** YESSTR */
    229     char           *pszYesStr;
    230     /** NOSTR */
    231     char           *pszNoStr;
    232     /** Indicates that all members are readonly const strings. */
    233     int             fConsts;
    234 } __LIBC_LOCALEMSG;
    235 /** Pointer to the message locale information. */
    236 typedef __LIBC_LOCALEMSG *__LIBC_PLOCALEMSG;
    237 
    238 
    239 /** String collation information. */
    240 extern __LIBC_LOCALECOLLATE         __libc_gLocaleCollate;
    241 /** Character case conversion tables. */
    242 extern __LIBC_LOCALECTYPE           __libc_GLocaleCtype;
    243 /** Character case conversion tables for the default 'C'/'POSIX' locale. */
    244 extern const __LIBC_LOCALECTYPE     __libc_GLocaleCtypeDefault;
    245 /** Cached Unicode (__wchar_t) case conversion tables and flags. */
    246 extern __LIBC_LOCALEWCTYPE          __libc_GLocaleWCtype;
    247 /** Locale information structure. */
    248 extern __LIBC_LOCALELCONV           __libc_gLocaleLconv;
    249 /* Locale information structure for the 'C'/'POSIX' locale. */
    250 extern const __LIBC_LOCALELCONV     __libc_gLocaleLconvDefault;
    251 /** Date / time formatting rules. */
    252 extern __LIBC_LOCALETIME            __libc_gLocaleTime;
    253 /** Date / time formatting rules for the 'C'/'POSIX' locale. */
    254 extern const __LIBC_LOCALETIME      __libc_gLocaleTimeDefault;
    255 /** Message locale information. */
    256 extern __LIBC_LOCALEMSG             __libc_gLocaleMsg;
    257 /** Message locale information for the 'C'/'POSIX' locale. */
    258 extern const __LIBC_LOCALEMSG       __libc_gLocaleMsgDefault;
    259 
    260 /** Macros to lock the different locale structures.
    261  * @{
    262  */
    263 #define LOCALE_LOCK()               do {} while (0)
    264 #define LOCALE_UNLOCK()             do {} while (0)
    265 #define LOCALE_CTYPE_RW_LOCK()      do {} while (0)
    266 #define LOCALE_CTYPE_RW_UNLOCK()    do {} while (0)
    267 #define LOCALE_CTYPE_RW_LOCK()      do {} while (0)
    268 #define LOCALE_CTYPE_RW_UNLOCK()    do {} while (0)
    269 /** @} */
    270 
    271 extern void __libc_localeFuncsSBCS(__LIBC_PLOCALECTYPEFUNCS pFuncs);
    272 extern void __libc_localeFuncsDBCS(__LIBC_PLOCALECTYPEFUNCS pFuncs);
    273 extern void __libc_localeFuncsMBCS(__LIBC_PLOCALECTYPEFUNCS pFuncs);
    274 extern void __libc_localeFuncsUCS2(__LIBC_PLOCALECTYPEFUNCS pFuncs);
    275 extern void __libc_localeFuncsUTF8(__LIBC_PLOCALECTYPEFUNCS pFuncs);
    276 extern void __libc_localeFuncsDefault(__LIBC_PLOCALECTYPEFUNCS pFuncs);
    277 
    278 extern size_t  __libc_localeFuncsGeneric_mbsnrtowcs(size_t  (*pfnmbrtowc)(__wchar_t * __restrict, const char * __restrict, size_t, __mbstate_t * __restrict),
    279                                                     __wchar_t * __restrict dst, const char ** __restrict src, size_t nms, size_t len, __mbstate_t * __restrict ps);
    280 extern size_t  __libc_localeFuncsGeneric_wcsnrtombs(size_t  (*pfnwcrtomb)(char * __restrict, __wchar_t, __mbstate_t * __restrict),
    281                                                     char * __restrict dst, const __wchar_t ** __restrict src, size_t nwc, size_t len, __mbstate_t * __restrict ps);
    282 
    283 extern void     __libc_localeFuncsNone(__LIBC_PLOCALECTYPEFUNCS pFuncs);
    284 extern size_t   __libc_locale_none_mbrtowc(__wchar_t * __restrict, const char * __restrict, size_t, __mbstate_t * __restrict);
    285 extern int      __libc_locale_none_mbsinit(const __mbstate_t *);
    286 extern size_t   __libc_locale_none_mbsnrtowcs(__wchar_t * __restrict dst, const char ** __restrict src, size_t nms, size_t len, __mbstate_t * __restrict ps __unused);
    287 extern size_t   __libc_locale_none_wcrtomb(char * __restrict, __wchar_t, __mbstate_t * __restrict);
    288 extern size_t   __libc_locale_none_wcsnrtombs(char * __restrict, const __wchar_t ** __restrict, size_t, size_t, __mbstate_t * __restrict);
    289 
    290 
    291 /** Handy macros for working with the au2MBCSPrefixs members of
    292  * the locale data structures. The au2MBCSPrefixs members are
    293  * array which elements are 2 bits long.
    294  * @{
    295  */
    296 #define SET_MBCS_PREFIX(a, c, v) \
    297     a[((unsigned char)(c)) >> 2] |= (v) << (2 * ((c) & 3))
    298 
    299 #define LEN_MBCS_PREFIX(a, c) \
    300     ((a[((unsigned char)(c)) >> 2] >> (2 * (((c) & 3) ^ 3))) & 3)
    301 
    302 #define IS_MBCS_PREFIX(p, c) \
    303     (LEN_MBCS_PREFIX((p)->au2MBCSPrefixs, c) != 1)
    304 
    305 #define CHK_MBCS_PREFIX(p, c, v) \
    306     ((v = LEN_MBCS_PREFIX((p)->au2MBCSPrefixs, c)) > 1)
    307 /** @} */
    308 
    309 #ifdef __OS2__
    310 #include <ctype.h>
    311 
    312 /**
    313  * Convert the type info we get from the unicode lib to libc talk.
    314  * ASSUMES that none of the locals differs from the unicode spec
    315  *
    316  * @returns libc ctype flags.
    317  * @param   pUniType    The unicode type info to translate.
    318  * @param   wc          The unicode code point.
    319  */
    320 static inline unsigned ___wctype_uni(const UNICTYPE *pUniType, wchar_t wc)
    321 {
    322     unsigned    ufType = 0;
    323     /* ASSUMES CT_* << 8 == __* ! */
    324     ufType = ((unsigned)pUniType->itype << 8)
    325            & (__CT_UPPER  | __CT_LOWER  | __CT_DIGIT | __CT_SPACE |
    326               __CT_PUNCT  | __CT_CNTRL  | __CT_BLANK | __CT_XDIGIT |
    327               __CT_ALPHA  | __CT_ALNUM  | __CT_GRAPH | __CT_PRINT |
    328               __CT_NUMBER | __CT_SYMBOL | __CT_ASCII);
    329     if (pUniType->extend & C3_IDEOGRAPH)
    330         ufType |= __CT_IDEOGRAM;
    331     if (ufType & (__CT_XDIGIT | __CT_DIGIT))
    332     {
    333         if (     (unsigned)wc - 0x30U <= (0x39 - 0x30))
    334             ufType |= (unsigned)wc - 0x30;
    335         else if ((unsigned)wc - 0x41U <= (0x46 - 0x41))
    336             ufType |= (unsigned)wc - 0x41 + 0xa;
    337         else
    338         {
    339             unsigned uVal = UniQueryNumericValue(wc);
    340             if (!(uVal & ~0xffU))
    341                 ufType |= uVal;
    342         }
    343     }
    344     ufType |= (pUniType->bidi & 0xf << 24);
    345 
    346     /** @todo screen width. */
    347     return ufType;
    348 }
    349 
    350 /** Convert a string to Unicode, apply some transform and convert back. */
    351 extern void __libc_ucs2Do(UconvObject *uconv, char *s, void *arg, int (*xform)(UniChar *, void *));
    352 /** Convert a MBCS character to Unicode; returns number of bytes in MBCS char. */
    353 extern int  __libc_ucs2To(UconvObject, const unsigned char *, size_t, UniChar *);
    354 /** Convert a Unicode character to MBCS. */
    355 extern int  __libc_ucs2From(UconvObject, UniChar, unsigned char *, size_t);
    356 /** Converts a codepage string to unichar and something libuni might recognize. */
    357 extern void __libc_TranslateCodepage(const char *cp, UniChar *ucp);
    358 
    359 extern int __libc_localeCreateObjects(const char *pszLocale, const char *pszCodepage, char *pszCodepageActual, LocaleObject *plobj, UconvObject *puobj);
    360 #endif /* __OS2__ */
    361 
    362 
    363 __END_DECLS
    364 
    365 #endif /* __SYS_LOCALE_H__ */
    366 
     1#include <klibc/locale.h>
  • trunk/libc/include/_ctype.h

    r2672 r2909  
    3131#include <sys/_types.h>
    3232
    33 #if !defined(__InnoTekLIBC_locale_h__)
     33#if !defined(__klibc_locale_h__)
    3434__BEGIN_DECLS
    3535/**
     
    7777} __libc_GLocaleWCtype;
    7878__END_DECLS
    79 #endif /* !__InnoTekLIBC_locale_h__ */
     79#endif /* !__klibc_locale_h__ */
    8080
    8181
  • trunk/libc/include/emx/syscalls.h

    r2907 r2909  
    194194//dead int __setsockopt (int handle, int level, int optname, __const__ void *optval,
    195195//dead     int optlen);
    196 int __settime (const struct timeval *tp);
     196//int __settime (const struct timeval *tp);
    197197//dead int __shutdown (int handle, int how);
    198198int __sigaction (int _sig, __const__ struct sigaction *_iact,
  • trunk/libc/include/emx/time.h

    r2717 r2909  
    1 /* emx/time.h (emx+gcc) */
    2 
    3 #ifndef _EMX_TIME_H
    4 #define _EMX_TIME_H
    5 
    6 #define _YEARS          (2059 - 1900 + 1)
    7 #define TIME_T_MAX      0x7fffffffL
    8 #define TIME_T_MIN      (-0x7fffffffL - 1)
    9 
    10 #ifndef __LIBC_BUILD_PROGRAM__
    11 #include <sys/cdefs.h>
    12 #include <sys/_types.h>
    13 
    14 __BEGIN_DECLS
    15 
    16 #if !defined(_TIME_T_DECLARED) && !defined(_TIME_T) /* bird: EMX */
    17 typedef __time_t        time_t;
    18 #define _TIME_T_DECLARED
    19 #define _TIME_T                         /* bird: EMX */
    20 #endif
    21 
    22 #ifndef _TIME64_T_DECLARED              /* bird: LIBC */
    23 typedef __int64_t       time64_t;       /* bird: LIBC */
    24 #define _TIME64_T_DECLARED              /* bird: LIBC */
    25 #endif                                  /* bird: LIBC */
    26 
    27 struct tm;
    28 
    29 /* Maximum length for time zone standard - "GMT", "CEST" etc. */
    30 #define __MAX_TZ_STANDARD_LEN 15
    31 
    32 struct _tzinfo
    33 {
    34   char tzname[__MAX_TZ_STANDARD_LEN + 1];
    35   char dstzname[__MAX_TZ_STANDARD_LEN + 1];
    36   int tz, dst, shift;
    37   int sm, sw, sd, st;
    38   int em, ew, ed, et;
    39 };
    40 
    41 extern int _tzset_flag;
    42 extern struct _tzinfo _tzi;
    43 
    44 extern signed short const   _year_day[_YEARS+1];
    45 extern unsigned short const _month_day_leap[];
    46 extern unsigned short const _month_day_non_leap[];
    47 
    48 
    49 int _day (int, int, int);
    50 int _gmt2loc (time_t *);
    51 int _gmt2loc64 (time64_t *p);
    52 int _loc2gmt (time_t *, int);
    53 int _loc2gmt64 (time64_t *, int);
    54 /* struct tm *_gmtime (struct tm *, const time_t *); - use _gmtime64_r */
    55 /* struct tm *_localtime (struct tm *, const time_t *); - use _localtime64_r */
    56 unsigned long _mktime (struct tm *);
    57 time64_t __mktime64 (struct tm *);
    58 void _compute_dst_table (void);
    59 
    60 
    61 static __inline__ int _leap_year (unsigned y)
    62 {
    63   return (y % 4 != 0 ? 0 : y % 100 != 0 ? 1 : y % 400 != 0 ? 0 : 1);
    64 }
    65 
    66 
    67 __END_DECLS
    68 
    69 #endif /* not __LIBC_BUILD_PROGRAM__ */
    70 #endif /* not _EMX_TIME_H */
     1#error dead
  • trunk/libc/include/klibc/io.h

    r2805 r2909  
    201201    int (*pfnForkChild)(struct __libc_FileHandle *pFH, __LIBC_PFORKHANDLE pForkHandle, __LIBC_FORKOP enmOperation);
    202202
     203    /** Non-Zero dummy for ensuring that we update all instances when adding new members. */
     204    int iDummy;
    203205} __LIBC_FHOPS;
    204206/** Pointer to file handle operations. */
  • trunk/libc/include/klibc/locale.h

    r2899 r2909  
    22/** @file
    33 *
    4  * Internal InnoTek LIBC header.
    5  * Locale support implementation through OS/2 Unicode API.
     4 * kLIBC - Internal locale header.
    65 *
    76 * Copyright (c) 2003 InnoTek Systemberatung GmbH
    8  * Copyright (c) 2003-2004 knut st. osmundsen <bird-srcspam@anduin.net>
    9  *
    10  *
    11  * This file is part of InnoTek LIBC.
    12  *
    13  * InnoTek LIBC is free software; you can redistribute it and/or modify
    14  * it under the terms of the GNU General Public License as published by
    15  * the Free Software Foundation; either version 2 of the License, or
     7 * Copyright (c) 2003-2006 knut st. osmundsen <bird-srcspam@anduin.net>
     8 *
     9 *
     10 * This file is part of kLIBC.
     11 *
     12 * kLIBC is free software; you can redistribute it and/or modify
     13 * it under the terms of the GNU Lesser General Public License as published
     14 * by the Free Software Foundation; either version 2 of the License, or
    1615 * (at your option) any later version.
    1716 *
    18  * InnoTek LIBC is distributed in the hope that it will be useful,
     17 * kLIBC is distributed in the hope that it will be useful,
    1918 * but WITHOUT ANY WARRANTY; without even the implied warranty of
    2019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    21  * GNU General Public License for more details.
    22  *
    23  * You should have received a copy of the GNU General Public License
    24  * along with InnoTek LIBC; if not, write to the Free Software
     20 * GNU Lesser General Public License for more details.
     21 *
     22 * You should have received a copy of the GNU Lesser General Public License
     23 * along with kLIBC; if not, write to the Free Software
    2524 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    2625 *
    2726 */
    2827
    29 #ifndef __InnoTekLIBC_locale_h__
    30 #define __InnoTekLIBC_locale_h__
     28#ifndef __klibc_locale_h__
     29#define __klibc_locale_h__
    3130
    3231#include <sys/cdefs.h>
     
    3534#ifdef __OS2__
    3635# include <uconv.h>
     36#endif
     37#ifdef __CTYPE_H_
     38# error "klibc/locale.h must be included *before* ctype.h!"
    3739#endif
    3840
     
    363365__END_DECLS
    364366
    365 #endif /* __SYS_LOCALE_H__ */
    366 
     367#endif
     368
  • trunk/libc/include/klibc/logstrict.h

    r2906 r2909  
    284284/** Backend IO APIs. */
    285285#define __LIBC_LOG_GRP_BACK_IO      26
     286/** Backend Time APIs. */
     287#define __LIBC_LOG_GRP_BACK_TIME    26 /** @todo fixme */
    286288/** Backend OS/2 Files (the file handle class). */
    287289#define __LIBC_LOG_GRP_BACK_OS2FILE 26
  • trunk/libc/src/kNIX/kNIX.h

    r2905 r2909  
    4343#include <string.h>
    4444#include <signal.h>
     45#include <process.h>
    4546#include <sys/builtin.h>
     47#include <sys/dirent.h>
    4648#include <sys/fmutex.h>
    4749#include <sys/fcntl.h>
  • trunk/libc/src/kNIX/os2/__settime.c

    r2732 r2909  
    1818  dst->seconds = t % 60; t /= 60;
    1919  dst->minutes = t % 60; t /= 60;
    20   dst->hours = t % 24; t /= 24;
     20  dst->hours   = t % 24; t /= 24;
    2121
    2222  /* Find an i such that _year_day[i] <= t < _year_day[i+1]. */
  • trunk/libc/src/kNIX/os2/__spawnve.c

    r2732 r2909  
    1 /* sys/spawnve.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes */
    2 
    3 #include "libc-alias.h"
    4 #include <stdlib.h>
    5 #include <string.h>
    6 #include <process.h>
    7 #include <errno.h>
    8 #include <alloca.h>
    9 #include <386/builtin.h>
    10 #include <sys/fmutex.h>
    11 #define INCL_DOSPROCESS
    12 #define INCL_FSMACROS
    13 #define INCL_DOSERRORS
    14 #include <os2emx.h>
    15 #include "b_fs.h"
     1/* $Id$ */
     2/** @file
     3 *
     4 * kNIX - Process Creation, OS/2.
     5 *
     6 * Copyright (c) 1992-1996 by Eberhard Mattes
     7 * Copyright (c) 2004-2006 knut st. osmundsen <bird-srcspam@anduin.net>
     8 *
     9 *
     10 * This file is part of kLIBC.
     11 *
     12 * kLIBC is free software; you can redistribute it and/or modify
     13 * it under the terms of the GNU Lesser General Public License as published
     14 * by the Free Software Foundation; either version 2 of the License, or
     15 * (at your option) any later version.
     16 *
     17 * kLIBC is distributed in the hope that it will be useful,
     18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     20 * GNU Lesser General Public License for more details.
     21 *
     22 * You should have received a copy of the GNU Lesser General Public License
     23 * along with kLIBC; if not, write to the Free Software
     24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     25 *
     26 */
     27
     28/*******************************************************************************
     29*   Header Files                                                               *
     30*******************************************************************************/
     31#include "kNIX.h"
     32/** @todo Cleanup __spawnve.c properly! */
    1633#include "b_signal.h"
    1734#include "b_process.h"
    1835#include <emx/syscalls.h>
    1936#include <InnoTekLIBC/sharedpm.h>
    20 #include <InnoTekLIBC/backend.h>
    2137#define __LIBC_LOG_GROUP    __LIBC_LOG_GRP_PROCESS
    22 #include <InnoTekLIBC/logstrict.h>
     38#include <klibc/logstrict.h>
    2339#include "syscalls.h"
    2440
  • trunk/libc/src/kNIX/os2/b_dir.c

    r2739 r2909  
    1 /* $Id$ */
     1/* $Id$ *//* $Id$ */
    22/** @file
    33 *
    4  * LIBC SYS Backend - Directory Access.
    5  *
    6  * Copyright (c) 2005 knut st. osmundsen <bird@anduin.net>
    7  *
    8  *
    9  * This file is part of InnoTek LIBC.
    10  *
    11  * InnoTek LIBC is free software; you can redistribute it and/or modify
    12  * it under the terms of the GNU General Public License as published by
    13  * the Free Software Foundation; either version 2 of the License, or
     4 * kNIX - Directory Access, OS/2.
     5 *
     6 * Copyright (c) 2004-2006 knut st. osmundsen <bird-srcspam@anduin.net>
     7 *
     8 *
     9 * This file is part of kLIBC.
     10 *
     11 * kLIBC is free software; you can redistribute it and/or modify
     12 * it under the terms of the GNU Lesser General Public License as published
     13 * by the Free Software Foundation; either version 2 of the License, or
    1414 * (at your option) any later version.
    1515 *
    16  * InnoTek LIBC is distributed in the hope that it will be useful,
     16 * kLIBC is distributed in the hope that it will be useful,
    1717 * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1818 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    19  * GNU General Public License for more details.
    20  *
    21  * You should have received a copy of the GNU General Public License
    22  * along with InnoTek LIBC; if not, write to the Free Software
     19 * GNU Lesser General Public License for more details.
     20 *
     21 * You should have received a copy of the GNU Lesser General Public License
     22 * along with kLIBC; if not, write to the Free Software
    2323 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    2424 *
    2525 */
    26 
    2726
    2827/*******************************************************************************
    2928*   Header Files                                                               *
    3029*******************************************************************************/
    31 #include "libc-alias.h"
    32 #define INCL_BASE
    33 #define INCL_FSMACROS
    34 #include <os2emx.h>
    35 #include "b_fs.h"
    36 #include "b_dir.h"
    37 #include <string.h>
    38 #include <errno.h>
    39 #include <limits.h>
    40 #include <sys/fcntl.h>
    41 #include <sys/dirent.h>
    42 #include <emx/umalloc.h>
    43 #include <emx/io.h>
     30#include "kNIX.h"
    4431#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_BACK_IO
    4532#include <InnoTekLIBC/logstrict.h>
    46 #include <InnoTekLIBC/libc.h>
    4733
    4834
     
    5036*   Internal Functions                                                         *
    5137*******************************************************************************/
    52 static int dirClose(__LIBC_PFH pFH, int fh);
    53 static int dirRead(__LIBC_PFH pFH, int fh, void *pvBuf, size_t cbRead, size_t *pcbRead);
    54 static int dirWrite(__LIBC_PFH pFH, int fh, const void *pvBuf, size_t cbWrite, size_t *pcbWritten);
    55 static int dirDuplicate(__LIBC_PFH pFH, int fh, int *pfhNew);
    56 static int dirFileControl(__LIBC_PFH pFH, int fh, int iRequest, int iArg, int *prc);
    57 static int dirIOControl(__LIBC_PFH pFH, int fh, int iIOControl, int iArg, int *prc);
    58 static int dirSeek(__LIBC_PFH pFH, int fh, off_t off, int iMethod, off_t *poffNew);
     38static int dirClose(__LIBC_PFH pFH);
     39static int dirRead(__LIBC_PFH pFH, void *pvBuf, size_t cbRead, size_t *pcbRead);
     40static int dirWrite(__LIBC_PFH pFH, const void *pvBuf, size_t cbWrite, size_t *pcbWritten);
     41static int dirSetSize(__LIBC_PFH pFH, off_t cbFile, int fZero);
     42static int dirDuplicate(__LIBC_PFH pFH, int *pfhNew);
     43static int dirFileControl(__LIBC_PFH pFH, int iRequest, int iArg, int *prc);
     44static int dirIOControl(__LIBC_PFH pFH, int iIOControl, int iArg, int *prc);
     45static int dirSeek(__LIBC_PFH pFH, off_t off, int iMethod, off_t *poffNew);
    5946static int dirSelect(int cFHs, struct fd_set *pRead, struct fd_set *pWrite, struct fd_set *pExcept, struct timeval *tv, int *prc);
    60 static int dirForkChild(__LIBC_PFH pFH, int fh, __LIBC_PFORKHANDLE pForkHandle, __LIBC_FORKOP enmOperation);
     47static int dirForkChild(__LIBC_PFH pFH, __LIBC_PFORKHANDLE pForkHandle, __LIBC_FORKOP enmOperation);
    6148static int dirOpen(const char *pszNativePath, unsigned fLibc, int *pfh, __LIBC_PFHDIR *ppFHDir);
    6249
     
    7461    dirRead,
    7562    dirWrite,
     63    dirSeek,
     64    dirSetSize,
    7665    dirDuplicate,
    7766    dirFileControl,
    7867    dirIOControl,
    79     //dirSeek,
    8068    dirSelect,
    8169    NULL,
    82     dirForkChild
     70    dirForkChild,
     71    42
    8372};
    8473
     
    9079 * @returns OS/2 error code or negated errno on failure.
    9180 * @param   pFH         Pointer to the handle structure to operate on.
    92  * @param   fh          It's associated filehandle.
    93  */
    94 static int dirClose(__LIBC_PFH pFH, int fh)
     81 */
     82static int dirClose(__LIBC_PFH pFH)
    9583{
    9684    __LIBC_PFHDIR pFHDir = (__LIBC_PFHDIR)pFH;
    97     LIBCLOG_ENTER("pFH=%p:{.hDir=%lx} fh=%d\n", (void *)pFH, pFHDir->hDir, fh);
     85    LIBCLOG_ENTER("pFH=%p:{.fh=%d, .hDir=%lx}\n", (void *)pFH, pFH->fh, pFHDir->hDir);
    9886
    9987    if (pFHDir->hDir != HDIR_CREATE)
     
    126114 * @returns OS/2 error code or negated errno on failure.
    127115 * @param   pFH         Pointer to the handle structure to operate on.
    128  * @param   fh          It's associated filehandle.
    129116 * @param   pvBuf       Pointer to the buffer to read into.
    130117 * @param   cbRead      Number of bytes to read.
    131118 * @param   pcbRead     Where to store the count of bytes actually read.
    132119 */
    133 static int dirRead(__LIBC_PFH pFH, int fh, void *pvBuf, size_t cbRead, size_t *pcbRead)
    134 {
    135     LIBCLOG_ENTER("pFH=%p fh=%d pvBuf=%p cbRead=%d pcbRead=%p\n", (void *)pFH, fh, pvBuf, cbRead, (void *)pcbRead);
     120static int dirRead(__LIBC_PFH pFH, void *pvBuf, size_t cbRead, size_t *pcbRead)
     121{
     122    LIBCLOG_ENTER("pFH=%p:{.fh=%d} pvBuf=%p cbRead=%d pcbRead=%p\n", (void *)pFH, pFH->fh, pvBuf, cbRead, (void *)pcbRead);
    136123    if (cbRead >= sizeof(struct dirent))
    137124    {
     
    152139 * @returns OS/2 error code or negated errno on failure.
    153140 * @param   pFH         Pointer to the handle structure to operate on.
    154  * @param   fh          It's associated filehandle.
    155141 * @param   pvBuf       Pointer to the buffer which contains the data to write.
    156142 * @param   cbWrite     Number of bytes to write.
    157143 * @param   pcbWritten  Where to store the count of bytes actually written.
    158144 */
    159 static int dirWrite(__LIBC_PFH pFH, int fh, const void *pvBuf, size_t cbWrite, size_t *pcbWritten)
    160 {
    161     LIBCLOG_ENTER("pFH=%p fh=%d pvBuf=%p cbWrite=%d pcbWritten=%p\n", (void *)pFH, fh, pvBuf, cbWrite, (void *)pcbWritten);
     145static int dirWrite(__LIBC_PFH pFH, const void *pvBuf, size_t cbWrite, size_t *pcbWritten)
     146{
     147    LIBCLOG_ENTER("pFH=%p:{.fd=%d} pvBuf=%p cbWrite=%d pcbWritten=%p\n", (void *)pFH, pFH->fh, pvBuf, cbWrite, (void *)pcbWritten);
    162148    LIBCLOG_ERROR_RETURN_INT(-EOPNOTSUPP);
     149}
     150
     151
     152/**
     153 * Sets the size of an open file.
     154 *
     155 * @returns 0 on success.
     156 * @returns Negative error code (errno.h) on failure.
     157 * @param   pFH     The file handle structure.
     158 * @param   cbFile  The new filesize.
     159 * @param   fZero   If set any new allocated file space should be initialized to zero.
     160 */
     161static int dirSetSize(__LIBC_PFH pFH, off_t cbFile, int fZero)
     162{
     163    return -EOPNOTSUPP;
    163164}
    164165
     
    167168 * @returns 0 on success, OS/2 error code on failure.
    168169 * @param   pFH         Pointer to the handle structure to operate on.
    169  * @param   fh          It's associated filehandle.
    170170 * @param   pfhNew      Where to store the duplicate filehandle.
    171171 *                      The input value describe how the handle is to be
     
    175175 *                      value will be closed.
    176176 */
    177 static int dirDuplicate(__LIBC_PFH pFH, int fh, int *pfhNew)
     177static int dirDuplicate(__LIBC_PFH pFH, int *pfhNew)
    178178{
    179179    /** @todo */
     
    186186 * @returns OS/2 error code or negated errno on failure.
    187187 * @param   pFH         Pointer to the handle structure to operate on.
    188  * @param   fh          It's associated filehandle.
    189188 * @param   iRequest    Which file file descriptior request to perform.
    190189 * @param   iArg        Argument which content is specific to each
     
    193192 *                      returned to the caller.
    194193 */
    195 static int dirFileControl(__LIBC_PFH pFH, int fh, int iRequest, int iArg, int *prc)
    196 {
    197     LIBCLOG_ENTER("pFH=%p fh=%d iRequest=%d iArg=%d prc=%p\n", (void *)pFH, fh, iRequest, iArg, (void *)prc);
     194static int dirFileControl(__LIBC_PFH pFH, int iRequest, int iArg, int *prc)
     195{
     196    LIBCLOG_ENTER("pFH=%p:{.fh=%d} iRequest=%d iArg=%d prc=%p\n", (void *)pFH, pFH->fh, iRequest, iArg, (void *)prc);
    198197    LIBCLOG_ERROR_RETURN_INT(-EOPNOTSUPP);
    199198}
     
    204203 * @returns OS/2 error code or negated errno on failure.
    205204 * @param   pFH         Pointer to the handle structure to operate on.
    206  * @param   fh          It's associated filehandle.
    207205 * @param   iIOControl  Which I/O control operation to perform.
    208206 * @param   iArg        Argument which content is specific to each
     
    211209 *                      returned to the caller.
    212210 */
    213 static int dirIOControl(__LIBC_PFH pFH, int fh, int iIOControl, int iArg, int *prc)
    214 {
    215     LIBCLOG_ENTER("pFH=%p fh=%d iIOControl=%d iArg=%d prc=%p\n", (void *)pFH, fh, iIOControl, iArg, (void *)prc);
     211static int dirIOControl(__LIBC_PFH pFH, int iIOControl, int iArg, int *prc)
     212{
     213    LIBCLOG_ENTER("pFH=%p:{.fd=%d} iIOControl=%d iArg=%d prc=%p\n", (void *)pFH, pFH->fh, iIOControl, iArg, (void *)prc);
    216214    LIBCLOG_ERROR_RETURN_INT(-EOPNOTSUPP);
    217215}
     
    223221 * @returns OS/2 error code or negated errno on failure.
    224222 * @param   pFH         Pointer to the handle structure to operate on.
    225  * @param   fh          It's associated filehandle.
    226223 * @param   off         The offset to seek. The meaning depends on SEEK_.
    227224 * @param   iMethod     The seek method, any of the SEEK_* macros.
    228225 * @param   poffNew     Where to store the new file offset.
    229226 */
    230 static int dirSeek(__LIBC_PFH pFH, int fh, off_t off, int iMethod, off_t *poffNew)
     227static int dirSeek(__LIBC_PFH pFH, off_t off, int iMethod, off_t *poffNew)
    231228{
    232229    /** @todo Implement reading and seeking. */
     
    264261 * @returns OS/2 error code or negated errno on failure.
    265262 * @param   pFH             Pointer to the handle structure to operate on.
    266  * @param   fh              It's associated filehandle.
    267263 * @param   pForkHandle     The fork handle.
    268264 * @param   enmOperation    The fork operation.
    269265 */
    270 static int dirForkChild(__LIBC_PFH pFH, int fh, __LIBC_PFORKHANDLE pForkHandle, __LIBC_FORKOP enmOperation)
     266static int dirForkChild(__LIBC_PFH pFH, __LIBC_PFORKHANDLE pForkHandle, __LIBC_FORKOP enmOperation)
    271267{
    272268    switch (enmOperation)
     
    309305                unsigned uCurEntry = pFHDir->uCurEntry;
    310306                pFHDir->uCurEntry = 0;
    311                 dirSeek(&pFHDir->Core, fh, uCurEntry * sizeof(struct dirent), SEEK_SET, NULL);
     307                dirSeek(&pFHDir->Core, uCurEntry * sizeof(struct dirent), SEEK_SET, NULL);
    312308            }
    313309            break;
     
    463459         */
    464460        if (uCurEntry)
    465             dirSeek(&pFHDir->Core, fh, uCurEntry * sizeof(struct dirent), SEEK_SET, NULL);
     461            dirSeek(&pFHDir->Core, uCurEntry * sizeof(struct dirent), SEEK_SET, NULL);
    466462
    467463        LIBCLOG_MSG("pFHDir=%p:{.hDir=%#lx, .fType=%d, .cFiles=%ld, .cbBuf=%#x, .uCurEntry=%d} fh=%d\n",
     
    536532 * @returns Negative error code (errno.h) on failure.
    537533 *
    538  * @param   fh      The file handle of an open directory.
    539534 * @param   pvBuf   Where to store the directory entries.
    540535 *                  The returned data is a series of dirent structs with
     
    620615        if (fMayHaveEAs)
    621616        {
    622             if (!__libc_gfNoUnix)
    623             {
    624                 /** @todo */
    625                 /** @todo */
    626                 fMayHaveEAs = 0;
    627             }
    628             else
    629                 fMayHaveEAs = 0;
     617            /** @todo */
     618            fMayHaveEAs = 0;
    630619        }
    631620        if (!fMayHaveEAs)
  • trunk/libc/src/kNIX/os2/b_fsDirChangeRoot.c

    r2732 r2909  
    2929*   Header Files                                                               *
    3030*******************************************************************************/
    31 #include "libc-alias.h"
    32 #include "b_fs.h"
    33 #include <string.h>
    34 #include <InnoTekLIBC/backend.h>
    35 #include <InnoTekLIBC/libc.h>
    36 #define __LIBC_LOG_GROUP    __LIBC_LOG_GRP_BACK_FS
     31#include "kNIX.h"
     32#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_BACK_FS
    3733#include <InnoTekLIBC/logstrict.h>
    3834
     
    7066        memcpy(__libc_gszUnixRoot, &szNativePath[0], cch + 1);
    7167        __libc_gcchUnixRoot = cch;
    72         __libc_gfNoUnix     = 0;
    7368        __libc_gfInUnixTree = 0; /** @todo logic for correct __libc_gfInUnixTree update in chroot() operation. */
    7469    }
  • trunk/libc/src/kNIX/os2/syscalls.h

    r2739 r2909  
    3535
    3636#define XUSHORT(x) (*(USHORT *)&(x))
    37 
    38 /* Maximum number of heap objects (16 = 512 / 32). */
    39 
    40 #define CFG_KNIX_MAX_HEAP_OBJS   16
    4137
    4238EXTERN unsigned _sys_uflags INIT (0);
  • trunk/libc/src/libc/app/setenv.c

    r2254 r2909  
    3535#include <errno.h>
    3636#include <emx/startup.h>
    37 #include <emx/time.h>           /* _tzset_flag */
    38 #define __LIBC_LOG_GROUP  __LIBC_LOG_GRP_ENV
    39 #include <InnoTekLIBC/logstrict.h>
     37#include <klibc/time.h>
     38#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_ENV
     39#include <klibc/logstrict.h>
    4040
    4141
     
    7373        LIBCLOG_RETURN_INT(-1);
    7474    }
    75     _tzset_flag = 0;              /* Call tzset() */
     75
     76    /* look for the TZ variable and invalid the time zone data when encountered. */
     77    if (envname[0] == 'T' && envname[1] == 'Z' && envname[2] == '\0')
     78        __libc_gfTZInfoOk = 0;
    7679
    7780    /* BSD Compatability. */
  • trunk/libc/src/libc/time/Makefile.kmk

    r2908 r2909  
    4747    $(PATH_LIBC_SRC)/libc/time/time.c \
    4848    $(PATH_LIBC_SRC)/libc/time/times.c \
     49    $(PATH_LIBC_SRC)/libc/time/timedata.c \
    4950    $(PATH_LIBC_SRC)/libc/time/timetabs.c \
    50     $(PATH_LIBC_SRC)/libc/time/tzset.c \
    51     $(PATH_LIBC_SRC)/libc/time/tzsetflag.c \
     51    $(PATH_LIBC_SRC)/libc/time/tzset.c
    5252
    5353# configure the variants. */
  • trunk/libc/src/libc/time/ctime.c

    r2254 r2909  
    1 /* ctime.c (emx+gcc) -- Copyright (c) 1990-1999 by Eberhard Mattes
    2                      -- Copyright (c) 2003 by Knut Stange Osmundsen */
     1/* $Id: $ */
     2/** @file
     3 *
     4 * kLIBC - ctime() and ctime_r().
     5 *
     6 * Copyright (c) 1990-1999 by Eberhard Mattes
     7 * Copyright (c) 2003-2006 knut st. osmundsen <bird-srcspam@anduin.net>
     8 *
     9 *
     10 * This file is part of kLIBC.
     11 *
     12 * kLIBC is free software; you can redistribute it and/or modify
     13 * it under the terms of the GNU Lesser General Public License as published
     14 * by the Free Software Foundation; either version 2 of the License, or
     15 * (at your option) any later version.
     16 *
     17 * kLIBC is distributed in the hope that it will be useful,
     18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     20 * GNU Lesser General Public License for more details.
     21 *
     22 * You should have received a copy of the GNU Lesser General Public License
     23 * along with kLIBC; if not, write to the Free Software
     24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     25 *
     26 */
     27
    328#include "libc-alias.h"
    429#include <time.h>
    5 #include <emx/time.h>
     30#include <klibc/time.h>
    631#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME
    7 #include <InnoTekLIBC/logstrict.h>
     32#include <klibc/logstrict.h>
    833
    934char *_STD(ctime)(const time_t *t)
     
    3358    LIBCLOG_ERROR_RETURN_P(NULL);
    3459}
     60
  • trunk/libc/src/libc/time/ftime.c

    r2254 r2909  
    1 /* ftime.c (emx+gcc) -- Copyright (c) 1993-1996 by Eberhard Mattes */
     1/* $Id: $ */
     2/** @file
     3 *
     4 * kLIBC - ftime().
     5 *
     6 * Copyright (c) 1993-1996 by Eberhard Mattes
     7 * Copyright (c) 2006 knut st. osmundsen <bird-srcspam@anduin.net>
     8 *
     9 *
     10 * This file is part of kLIBC.
     11 *
     12 * kLIBC is free software; you can redistribute it and/or modify
     13 * it under the terms of the GNU Lesser General Public License as published
     14 * by the Free Software Foundation; either version 2 of the License, or
     15 * (at your option) any later version.
     16 *
     17 * kLIBC is distributed in the hope that it will be useful,
     18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     20 * GNU Lesser General Public License for more details.
     21 *
     22 * You should have received a copy of the GNU Lesser General Public License
     23 * along with kLIBC; if not, write to the Free Software
     24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     25 *
     26 */
    227
    328#include "libc-alias.h"
    429#include <sys/timeb.h>
    530#include <time.h>
    6 #include <emx/time.h>
    7 #include <emx/syscalls.h>
     31#include <klibc/time.h>
     32#include <emx/syscalls.h> /// @todo fixme!
    833#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME
    9 #include <InnoTekLIBC/logstrict.h>
     34#include <klibc/logstrict.h>
    1035
    1136void _STD(ftime)(struct timeb *ptr)
     
    1338    LIBCLOG_ENTER("ptr=%p\n", (void *)ptr);
    1439
    15     if (!_tzset_flag)
     40    if (!__libc_gfTZInfoOk)
    1641        tzset();
    1742
     
    2045    t_loc = ptr->time;
    2146    ptr->dstflag = _loc2gmt(&ptr->time, -1);
    22     ptr->timezone = _tzi.tz / 60;
     47    ptr->timezone = __libc_gTZInfo.tz / 60;
    2348
    2449    LIBCLOG_RETURN_MSG_VOID("ptr=%p:{.time=%ld, .millitm=%u, .timezone=%d, .dstflag=%d}\n",
  • trunk/libc/src/libc/time/gettimeofday.c

    r2908 r2909  
    55#include <time.h>
    66#include <sys/time.h>
    7 #include <emx/time.h>
     7#include <klibc/time.h>
    88#include <emx/syscalls.h>
    99#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME
    10 #include <InnoTekLIBC/logstrict.h>
     10#include <klibc/logstrict.h>
    1111
    1212int _STD(gettimeofday)(struct timeval *tp, struct timezone *tzp)
     
    1717    int dst;
    1818
    19     if (!_tzset_flag)
     19    if (!__libc_gfTZInfoOk)
    2020        tzset();
    2121    __ftime(&tb);
     
    2929    if (tzp != NULL)
    3030    {
    31         tzp->tz_minuteswest = _tzi.tz / 60;
     31        tzp->tz_minuteswest = __libc_gTZInfo.tz / 60;
    3232        tzp->tz_dsttime = dst;
    3333    }
     
    4545                           (void *)tzp, tzp->tz_minuteswest, tzp->tz_dsttime);
    4646}
     47
  • trunk/libc/src/libc/time/gmtime.c

    r2260 r2909  
    1 /* gmtime.c (emx+gcc) -- Copyright (c) 1990-1999 by Eberhard Mattes */
     1/* $Id: $ */
     2/** @file
     3 *
     4 * kLIBC - gmtime(), gmtime_r() and _gmtime64_r().
     5 *
     6 * Copyright (c) 1990-1999 by Eberhard Mattes
     7 * Copyright (c) 2005-2006 knut st. osmundsen <bird-srcspam@anduin.net>
     8 *
     9 *
     10 * This file is part of kLIBC.
     11 *
     12 * kLIBC is free software; you can redistribute it and/or modify
     13 * it under the terms of the GNU Lesser General Public License as published
     14 * by the Free Software Foundation; either version 2 of the License, or
     15 * (at your option) any later version.
     16 *
     17 * kLIBC is distributed in the hope that it will be useful,
     18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     20 * GNU Lesser General Public License for more details.
     21 *
     22 * You should have received a copy of the GNU Lesser General Public License
     23 * along with kLIBC; if not, write to the Free Software
     24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     25 *
     26 */
    227
    328#include "libc-alias.h"
     
    530#include <time.h>
    631#include <stdint.h>
    7 #include <InnoTekLIBC/thread.h>
    8 #include <emx/time.h>
     32#include <klibc/thread.h>
     33#include <klibc/time.h>
    934#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME
    10 #include <InnoTekLIBC/logstrict.h>
     35#include <klibc/logstrict.h>
    1136
    1237
     
    3762
    3863    {
    39         /* Find an i such that _year_day[i] <= days < _year_day[i+1]. */
     64        /* Find an i such that __libc_gaiYearDay[i] <= days < __libc_gaiYearDay[i+1]. */
    4065        int hi = _YEARS - 1;
    41         if ((int)_year_day[hi] < days)
     66        if ((int)__libc_gaiYearDay[hi] < days)
    4267            LIBCLOG_ERROR_RETURN_P(NULL);
    43         else if ((int)_year_day[0] > days)
     68        else if ((int)__libc_gaiYearDay[0] > days)
    4469            LIBCLOG_ERROR_RETURN_P(NULL);
    4570        else
     
    5075            {
    5176                i = (lo + hi) / 2;
    52                 if (_year_day[i] > days)
     77                if (__libc_gaiYearDay[i] > days)
    5378                    hi = i - 1;
    54                 else if (_year_day[i+1] <= days)
     79                else if (__libc_gaiYearDay[i+1] <= days)
    5580                    lo = i + 1;
    5681                else
     
    5883            }
    5984            dst->tm_year = i;
    60             days -= _year_day[i];
     85            days -= __libc_gaiYearDay[i];
    6186            dst->tm_yday = days;
    6287        }
     
    6590    {
    6691        int i;
    67         const unsigned short *p;
     92        uint16_t const *p;
    6893
    6994        p = (_leap_year (dst->tm_year + 1900)
    70              ? _month_day_leap : _month_day_non_leap);
     95             ? __libc_gauMonthDayLeap : __libc_gauMonthDayNonLeap);
    7196        for (i = 0; (int)days >= p[i+1]; ++i)
    7297            ;
     
    99124                       pTm->tm_wday, pTm->tm_yday, pTm->tm_isdst, /*pTm->tm_gmtoff*/-2, /*pTm->tm_zone*/(void *)NULL, /*pTm->tm_zone*/"");
    100125}
     126
  • trunk/libc/src/libc/time/gmtloc.c

    r1788 r2909  
    1 /* gmtloc.c (emx+gcc) -- Copyright (c) 1995-1996 by Eberhard Mattes */
    2 
     1/* $Id: $ */
     2/** @file
     3 *
     4 * kLIBC - GMT (UCT) to/from localtime conversions.
     5 *
     6 * Copyright (c) 1995-1996 by Eberhard Mattes
     7 *
     8 *
     9 * This file is part of kLIBC.
     10 *
     11 * kLIBC is free software; you can redistribute it and/or modify
     12 * it under the terms of the GNU Lesser General Public License as published
     13 * by the Free Software Foundation; either version 2 of the License, or
     14 * (at your option) any later version.
     15 *
     16 * kLIBC is distributed in the hope that it will be useful,
     17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19 * GNU Lesser General Public License for more details.
     20 *
     21 * You should have received a copy of the GNU Lesser General Public License
     22 * along with kLIBC; if not, write to the Free Software
     23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     24 *
     25 */
     26
     27/*******************************************************************************
     28*   Header Files                                                               *
     29*******************************************************************************/
    330#include <time.h>
    431#include <limits.h>
    532#include <assert.h>
    6 #include <emx/time.h>
    7 
     33#include <klibc/time.h>
     34
     35/*******************************************************************************
     36*   Defined Constants And Macros                                               *
     37*******************************************************************************/
    838/* Return true iff adding A to T does not overflow or underflow time_t.
    939   (Correct but not fast!!!) */
     
    1545     || ((a) < 0 && (t) > 0 && (a) + (t) > (a)) )
    1646
     47/*******************************************************************************
     48*   Structures and Typedefs                                                    *
     49*******************************************************************************/
    1750struct _dstswitch
    1851{
    19   time_t time;                  /* UTC */
    20   int shift;
     52    time_t time;                  /* UTC */
     53    int shift;
    2154};
    2255
    23 static struct _dstswitch _dstsw[2*_YEARS+2] = {{TIME_T_MIN, 0}, {TIME_T_MAX, 0}};
     56/*******************************************************************************
     57*   Global Variables                                                           *
     58*******************************************************************************/
     59static struct _dstswitch g_aDstSwitches[2*_YEARS+2] =
     60{
     61    { TIME_T_MIN, 0 },
     62    { TIME_T_MAX, 0 }
     63};
    2464static int _dstsw_count = 2;
    2565
    2666
    27 /* Compute the day of the year on which DST switching occurs. */
    28 
    29 static int switch_day (int month, int week, int day, int ywday,
    30                        const unsigned short *month_table)
    31 {
    32   int d, wday;
    33 
    34   if (week > 0)
    35     {
    36       d = month_table[month-1];
    37       wday = (d + ywday) % 7;   /* Wekkday of the first day the month */
    38       if (wday != 0)
    39         d += 7 - wday;          /* d is the first Sunday of the month */
    40       d += day;                 /* First DAY in `first week' */
    41       d += 7 * (week - 1);
    42     }
    43   else if (week < 0)
    44     {
    45       if (month == 12)
    46         d = month_table[11] + 31 - 1;
    47       else
    48         d = month_table[month] - 1;
    49       wday = (d + ywday) % 7;   /* Weekday of the last day of the month */
    50       if (wday != 0)
    51         d -= wday;              /* d is the last Sunday of the month */
    52       d += day;                 /* First DAY in `last week' */
    53       d -= 7 * (week + 1);
    54     }
    55   else
    56     d = month_table[month-1] + day - 1;
    57   return d;
    58 }
    59 
    60 
    61 void _compute_dst_table (void)
    62 {
    63   int y, i, ywday, d_year, d_start, d_end;
    64   const unsigned short *month_table;
    65   time_t t_year, t_start, t_end;
    66 
    67   if (!_tzi.dst)
    68     {
    69       _dstsw[0].time = TIME_T_MIN;
    70       _dstsw[0].shift = 0;
    71       _dstsw[1].time = TIME_T_MAX;
    72       _dstsw[1].shift = 0;
    73       _dstsw_count = 2;
    74       return;
    75     }
    76 
    77   i = 0;
    78   for (y = 2; _year_day[y] != SHRT_MAX; ++y) /* 1900, 1901, 1902 underflows second count. */
    79     {
    80       month_table = (_leap_year (y + 1900)
    81                      ? _month_day_leap : _month_day_non_leap);
    82       d_year = _year_day[y];
    83       ywday = d_year + 4;       /* 01-Jan-1970 was a Thursday, ie, 4 */
    84       t_year = d_year * 24 * 60 * 60;
    85 
    86       d_start = switch_day (_tzi.sm, _tzi.sw, _tzi.sd, ywday, month_table);
    87       t_start = d_start * 24 * 60 * 60 + _tzi.st + _tzi.tz;
    88       if (ADD_OK (t_start, t_year))
    89         t_start += t_year;
    90       else
    91         t_start = t_year >= 0 ? TIME_T_MAX : TIME_T_MIN;
    92 
    93       d_end = switch_day (_tzi.em, _tzi.ew, _tzi.ed, ywday, month_table);
    94       t_end = d_end * 24 * 60 * 60 + _tzi.et + _tzi.tz - _tzi.shift;
    95       if (ADD_OK (t_end, t_year))
    96         t_end += t_year;
    97       else
    98         t_end = t_year >= 0 ? TIME_T_MAX : TIME_T_MIN;
    99 
    100       if (d_start < d_end || (d_start == d_end && _tzi.st <= _tzi.et))
    101         {
    102           /* Northern hemisphere. */
    103 
    104           if (i == 0)
    105             {
    106               _dstsw[0].time = TIME_T_MIN;
    107               _dstsw[0].shift = 0;
    108               ++i;
    109             }
    110           _dstsw[i].time = t_start;
    111           _dstsw[i].shift = _tzi.shift;
    112           ++i;
    113           _dstsw[i].time = t_end;
    114           _dstsw[i].shift = 0;
    115           ++i;
    116         }
    117       else
    118         {
    119           /* Southern hemisphere. */
    120 
    121           if (i == 0)
    122             {
    123               _dstsw[0].time = TIME_T_MIN;
    124               _dstsw[0].shift = _tzi.shift;
    125               ++i;
    126             }
    127           _dstsw[i].time = t_end;
    128           _dstsw[i].shift = 0;
    129           ++i;
    130           _dstsw[i].time = t_start;
    131           _dstsw[i].shift = _tzi.shift;
    132           ++i;
    133         }
    134     }
    135   _dstsw[i].time = TIME_T_MAX;
    136   _dstsw[i].shift = TIME_T_MAX;
    137   ++i;
    138   _dstsw_count = i;
    139 
    140   assert (_dstsw_count == sizeof (_dstsw) / sizeof (_dstsw[0]) - 4);
    141 }
    142 
    143 
    144 static struct _dstswitch *find_switch (time_t t)
    145 {
    146   int lo, hi, i;
    147 
    148   if (t == TIME_T_MAX)
    149     {
    150       i = _dstsw_count - 2;
    151       assert (_dstsw[i].time <= t);
    152       assert (t <= _dstsw[i+1].time);
    153     }
    154   else
    155     {
    156       lo = 0; hi = _dstsw_count - 2;
    157       for (;;)
    158         {
    159           i = (lo + hi) / 2;
    160           if (_dstsw[i].time > t)
    161             hi = i - 1;
    162           else if (_dstsw[i+1].time <= t)
    163             lo = i + 1;
    164           else
    165             break;
    166         }
    167       assert (_dstsw[i].time <= t);
    168       assert (t < _dstsw[i+1].time);
    169     }
    170   return &_dstsw[i];
     67/**
     68 * Compute the day of the year on which DST switching occurs.
     69 */
     70static int switch_day(int month, int week, int day, int ywday,
     71                      const unsigned short *month_table)
     72{
     73    int d, wday;
     74
     75    if (week > 0)
     76    {
     77        d = month_table[month-1];
     78        wday = (d + ywday) % 7;   /* Weekday of the first day the month */
     79        if (wday != 0)
     80            d += 7 - wday;        /* d is the first Sunday of the month */
     81        d += day;                 /* First DAY in `first week' */
     82        d += 7 * (week - 1);
     83    }
     84    else if (week < 0)
     85    {
     86        if (month == 12)
     87            d = month_table[11] + 31 - 1;
     88        else
     89            d = month_table[month] - 1;
     90        wday = (d + ywday) % 7;   /* Weekday of the last day of the month */
     91        if (wday != 0)
     92            d -= wday;            /* d is the last Sunday of the month */
     93        d += day;                 /* First DAY in `last week' */
     94        d -= 7 * (week + 1);
     95    }
     96    else
     97        d = month_table[month-1] + day - 1;
     98    return d;
     99}
     100
     101
     102void _compute_dst_table(void)
     103{
     104    int y, i, ywday, d_year, d_start, d_end;
     105    const unsigned short *month_table;
     106    time_t t_year, t_start, t_end;
     107
     108    if (!__libc_gTZInfo.dst)
     109    {
     110        g_aDstSwitches[0].time = TIME_T_MIN;
     111        g_aDstSwitches[0].shift = 0;
     112        g_aDstSwitches[1].time = TIME_T_MAX;
     113        g_aDstSwitches[1].shift = 0;
     114        _dstsw_count = 2;
     115        return;
     116    }
     117
     118    i = 0;
     119    for (y = 2; __libc_gaiYearDay[y] != SHRT_MAX; y++) /* 1900, 1901, 1902 underflows second count. */
     120    {
     121        month_table = _leap_year(y + 1900)
     122                      ? __libc_gauMonthDayLeap : __libc_gauMonthDayNonLeap;
     123        d_year = __libc_gaiYearDay[y];
     124        ywday = d_year + 4;       /* 01-Jan-1970 was a Thursday, ie, 4 */
     125        t_year = d_year * 24 * 60 * 60;
     126
     127        d_start = switch_day(__libc_gTZInfo.sm, __libc_gTZInfo.sw, __libc_gTZInfo.sd, ywday, month_table);
     128        t_start = d_start * 24 * 60 * 60 + __libc_gTZInfo.st + __libc_gTZInfo.tz;
     129        if (ADD_OK(t_start, t_year))
     130            t_start += t_year;
     131        else
     132            t_start = t_year >= 0 ? TIME_T_MAX : TIME_T_MIN;
     133
     134        d_end = switch_day(__libc_gTZInfo.em, __libc_gTZInfo.ew, __libc_gTZInfo.ed, ywday, month_table);
     135        t_end = d_end * 24 * 60 * 60 + __libc_gTZInfo.et + __libc_gTZInfo.tz - __libc_gTZInfo.shift;
     136        if (ADD_OK(t_end, t_year))
     137            t_end += t_year;
     138        else
     139            t_end = t_year >= 0 ? TIME_T_MAX : TIME_T_MIN;
     140
     141        if (    d_start < d_end
     142            || (d_start == d_end && __libc_gTZInfo.st <= __libc_gTZInfo.et))
     143        {
     144            /* Northern hemisphere. */
     145            if (i == 0)
     146            {
     147                g_aDstSwitches[0].time = TIME_T_MIN;
     148                g_aDstSwitches[0].shift = 0;
     149                ++i;
     150            }
     151            g_aDstSwitches[i].time = t_start;
     152            g_aDstSwitches[i].shift = __libc_gTZInfo.shift;
     153            ++i;
     154            g_aDstSwitches[i].time = t_end;
     155            g_aDstSwitches[i].shift = 0;
     156            ++i;
     157        }
     158        else
     159        {
     160            /* Southern hemisphere. */
     161            if (i == 0)
     162            {
     163                g_aDstSwitches[0].time = TIME_T_MIN;
     164                g_aDstSwitches[0].shift = __libc_gTZInfo.shift;
     165                ++i;
     166            }
     167            g_aDstSwitches[i].time = t_end;
     168            g_aDstSwitches[i].shift = 0;
     169            ++i;
     170            g_aDstSwitches[i].time = t_start;
     171            g_aDstSwitches[i].shift = __libc_gTZInfo.shift;
     172            ++i;
     173        }
     174    }
     175    g_aDstSwitches[i].time = TIME_T_MAX;
     176    g_aDstSwitches[i].shift = TIME_T_MAX;
     177    _dstsw_count = ++i;
     178
     179    assert(_dstsw_count == sizeof(g_aDstSwitches) / sizeof(g_aDstSwitches[0]) - 4);
     180}
     181
     182
     183static struct _dstswitch *find_switch(time_t t)
     184{
     185    int lo, hi, i;
     186
     187    if (t == TIME_T_MAX)
     188    {
     189        i = _dstsw_count - 2;
     190        assert(g_aDstSwitches[i].time <= t);
     191        assert(t <= g_aDstSwitches[i+1].time);
     192    }
     193    else
     194    {
     195        lo = 0; hi = _dstsw_count - 2;
     196        for (;;)
     197        {
     198            i = (lo + hi) / 2;
     199            if (g_aDstSwitches[i].time > t)
     200                hi = i - 1;
     201            else if (g_aDstSwitches[i+1].time <= t)
     202                lo = i + 1;
     203            else
     204                break;
     205        }
     206        assert(g_aDstSwitches[i].time <= t);
     207        assert(t < g_aDstSwitches[i+1].time);
     208    }
     209    return &g_aDstSwitches[i];
    171210}
    172211
     
    176215   applies or not. */
    177216
    178 int _gmt2loc (time_t *p)
    179 {
    180   struct _dstswitch *sw;
    181 
    182   sw = find_switch (*p);
    183   if (!ADD_OK (*p, _tzi.tz - sw->shift))
    184     return -1;
    185   *p -= _tzi.tz - sw->shift;
    186   return sw->shift != 0;
     217int _gmt2loc(time_t *p)
     218{
     219    struct _dstswitch *sw;
     220
     221    sw = find_switch(*p);
     222    if (!ADD_OK(*p, __libc_gTZInfo.tz - sw->shift))
     223        return -1;
     224    *p -= __libc_gTZInfo.tz - sw->shift;
     225    return sw->shift != 0;
    187226}
    188227
     
    195234 * @param   p   The time to convert.
    196235 */
    197 int _gmt2loc64 (time64_t *p)
     236int _gmt2loc64(time64_t *p)
    198237{
    199238    struct _dstswitch *sw;
    200     sw = find_switch ((time_t)*p); //fixme!
    201     time64_t t = *p - (_tzi.tz - sw->shift);
    202     if (_tzi.tz - sw->shift > 0 ? t > *p : t < *p)
     239    sw = find_switch((time_t)*p); //fixme!
     240    time64_t t = *p - (__libc_gTZInfo.tz - sw->shift);
     241    if (__libc_gTZInfo.tz - sw->shift > 0 ? t > *p : t < *p)
    203242        return -1;
    204243    *p = t;
     
    207246
    208247
    209 /* Note that this function returns -1 on error (overflow).
    210    Previously, it returned -1 if it could not determine whether
    211    daylight saving applies or not. */
    212 
    213 int _loc2gmt (time_t *p, int is_dst)
    214 {
    215   time_t x;
    216   struct _dstswitch *sw;
    217   int count;
    218 
    219   if (is_dst > 0)
    220     {
    221       /* Our caller says that *P is specified as DST.  Compute UTC
    222          from *P, assuming that daylight saving applies. */
    223 
    224       if (!ADD_OK (*p, _tzi.tz - _tzi.shift))
    225         return -1;
    226       x = *p + _tzi.tz - _tzi.shift;
    227       sw = find_switch (x);
    228       *p = x;
    229       return sw->shift != 0;
    230     }
    231   else if (is_dst == 0)
    232     {
    233       /* Our caller says that *P is specified as standard time.
    234          Compute UTC from *P, assuming that daylight saving does not
    235          apply. */
    236 
    237       if (!ADD_OK (*p, _tzi.tz))
    238         return -1;
    239       x = *p + _tzi.tz;
    240       sw = find_switch (x);
    241       *p = x;
    242       return sw->shift != 0;
    243     }
    244   else
    245     {
    246       /* Our caller does not know whether *P is specified as DST or
    247          standard time.  Try to find out.  First try DST. */
    248 
    249       count = 0;
    250       if (ADD_OK (*p, _tzi.tz - _tzi.shift))
    251         {
    252           x = *p + _tzi.tz - _tzi.shift;
    253           sw = find_switch (x);
    254           if (sw->shift != 0)
    255             {
    256               *p = x;
    257               return 1;         /* DST */
    258             }
    259           ++count;
    260         }
    261 
    262       if (ADD_OK (*p, _tzi.tz))
    263         {
    264           x = *p + _tzi.tz;
    265           sw = find_switch (x);
    266           if (sw->shift == 0)
    267             {
    268               *p = x;
    269               return 0;         /* Not DST */
    270             }
    271           ++count;
    272         }
    273 
    274       if (count != 2)
    275         return -1;              /* Overflow */
    276 
    277       /* Assume that DST does not apply in the gap.  This makes moving
    278          into the gap from below work, but breaks moving into the gap
    279          from above.  The advantage of this choice is that ftime()
    280          works correctly in the gap if the clock is not adjusted. */
    281 
    282       *p += _tzi.tz;
    283       return 0;                 /* Not DST */
     248/**
     249 * ...
     250 * @remark Note that this function returns -1 on error (overflow).
     251 *         Previously, it returned -1 if it could not determine whether
     252 *         daylight saving applies or not.
     253 */
     254int _loc2gmt(time_t *p, int is_dst)
     255{
     256    time_t x;
     257    struct _dstswitch *sw;
     258    int count;
     259
     260    if (is_dst > 0)
     261    {
     262        /* Our caller says that *P is specified as DST.  Compute UTC
     263           from *P, assuming that daylight saving applies. */
     264
     265        if (!ADD_OK(*p, __libc_gTZInfo.tz - __libc_gTZInfo.shift))
     266            return -1;
     267        x = *p + __libc_gTZInfo.tz - __libc_gTZInfo.shift;
     268        sw = find_switch(x);
     269        *p = x;
     270        return sw->shift != 0;
     271    }
     272    else if (is_dst == 0)
     273    {
     274        /* Our caller says that *P is specified as standard time.
     275           Compute UTC from *P, assuming that daylight saving does not
     276           apply. */
     277
     278        if (!ADD_OK(*p, __libc_gTZInfo.tz))
     279            return -1;
     280        x = *p + __libc_gTZInfo.tz;
     281        sw = find_switch(x);
     282        *p = x;
     283        return sw->shift != 0;
     284    }
     285    else
     286    {
     287        /* Our caller does not know whether *P is specified as DST or
     288           standard time.  Try to find out.  First try DST. */
     289
     290        count = 0;
     291        if (ADD_OK(*p, __libc_gTZInfo.tz - __libc_gTZInfo.shift))
     292        {
     293            x = *p + __libc_gTZInfo.tz - __libc_gTZInfo.shift;
     294            sw = find_switch(x);
     295            if (sw->shift != 0)
     296            {
     297                *p = x;
     298                return 1;         /* DST */
     299            }
     300            ++count;
     301        }
     302
     303        if (ADD_OK(*p, __libc_gTZInfo.tz))
     304        {
     305            x = *p + __libc_gTZInfo.tz;
     306            sw = find_switch(x);
     307            if (sw->shift == 0)
     308            {
     309                *p = x;
     310                return 0;         /* Not DST */
     311            }
     312            ++count;
     313        }
     314
     315        if (count != 2)
     316            return -1;            /* Overflow */
     317
     318        /* Assume that DST does not apply in the gap.  This makes moving
     319           into the gap from below work, but breaks moving into the gap
     320           from above.  The advantage of this choice is that ftime()
     321           works correctly in the gap if the clock is not adjusted. */
     322
     323        *p += __libc_gTZInfo.tz;
     324        return 0;                 /* Not DST */
    284325    }
    285326}
     
    304345        /* Our caller says that *P is specified as DST.  Compute UTC
    305346           from *P, assuming that daylight saving applies. */
    306 
    307         x = *p + (_tzi.tz - _tzi.shift);
    308         if (_tzi.tz - _tzi.shift > 0 ? x < *p : x > *p)
     347        x = *p + (__libc_gTZInfo.tz - __libc_gTZInfo.shift);
     348        if (__libc_gTZInfo.tz - __libc_gTZInfo.shift > 0 ? x < *p : x > *p)
    309349            return -1;
    310         sw = find_switch (x);
     350        sw = find_switch(x);
    311351        *p = x;
    312352        return sw->shift != 0;
     
    317357           Compute UTC from *P, assuming that daylight saving does not
    318358           apply. */
    319 
    320         x = *p + _tzi.tz;
    321         if (_tzi.tz > 0 ? x < *p : x > *p)
     359        x = *p + __libc_gTZInfo.tz;
     360        if (__libc_gTZInfo.tz > 0 ? x < *p : x > *p)
    322361            return -1;
    323         sw = find_switch (x);
     362        sw = find_switch(x);
    324363        *p = x;
    325364        return sw->shift != 0;
     
    329368        /* Our caller does not know whether *P is specified as DST or
    330369           standard time.  Try to find out.  First try DST. */
    331 
    332370        count = 0;
    333         x = *p + _tzi.tz - _tzi.shift;
    334         if (!(_tzi.tz - _tzi.shift > 0 ? x < *p : x > *p))
    335         {
    336             sw = find_switch (x);
     371        x = *p + __libc_gTZInfo.tz - __libc_gTZInfo.shift;
     372        if (!(__libc_gTZInfo.tz - __libc_gTZInfo.shift > 0 ? x < *p : x > *p))
     373        {
     374            sw = find_switch(x);
    337375            if (sw->shift != 0)
    338376            {
     
    343381        }
    344382
    345         x = *p + _tzi.tz;
    346         if (!(_tzi.tz > 0 ? x < *p : x > *p))
    347         {
    348             sw = find_switch (x);
     383        x = *p + __libc_gTZInfo.tz;
     384        if (!(__libc_gTZInfo.tz > 0 ? x < *p : x > *p))
     385        {
     386            sw = find_switch(x);
    349387            if (sw->shift == 0)
    350388            {
     
    356394
    357395        if (count != 2)
    358             return -1;              /* Overflow */
     396            return -1;            /* Overflow */
    359397
    360398        /* Assume that DST does not apply in the gap.  This makes moving
     
    362400           from above.  The advantage of this choice is that ftime()
    363401           works correctly in the gap if the clock is not adjusted. */
    364 
    365         *p += _tzi.tz;
     402        *p += __libc_gTZInfo.tz;
    366403        return 0;                 /* Not DST */
    367404    }
    368405}
     406
  • trunk/libc/src/libc/time/localtime.c

    r2908 r2909  
    1 /* localtim.c (emx+gcc) -- Copyright (c) 1990-1999 by Eberhard Mattes */
     1/* $Id: $ */
     2/** @file
     3 *
     4 * kLIBC - localtime(), localtime_r() and _localtime64_r().
     5 *
     6 * Copyright (c) 1990-1999 by Eberhard Mattes
     7 * Copyright (c) 2005-2006 knut st. osmundsen <bird-srcspam@anduin.net>
     8 *
     9 *
     10 * This file is part of kLIBC.
     11 *
     12 * kLIBC is free software; you can redistribute it and/or modify
     13 * it under the terms of the GNU Lesser General Public License as published
     14 * by the Free Software Foundation; either version 2 of the License, or
     15 * (at your option) any later version.
     16 *
     17 * kLIBC is distributed in the hope that it will be useful,
     18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     20 * GNU Lesser General Public License for more details.
     21 *
     22 * You should have received a copy of the GNU Lesser General Public License
     23 * along with kLIBC; if not, write to the Free Software
     24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     25 *
     26 */
    227
    328#include "libc-alias.h"
    429#include <time.h>
    5 #include <InnoTekLIBC/thread.h>
    6 #include <emx/time.h>
     30#include <klibc/time.h>
     31#include <klibc/thread.h>
    732#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME
    8 #include <InnoTekLIBC/logstrict.h>
     33#include <klibc/logstrict.h>
    934
    1035struct tm *_localtime64_r(const time64_t *t, struct tm *dst)
    1136{
    1237    LIBCLOG_ENTER("t=%p:{%lld (%#llx)} dst=%p\n", (void *)t, (long long)*t, (long long)*t, (void *)dst);
    13     if (!_tzset_flag)
     38    if (!__libc_gfTZInfoOk)
    1439        tzset();
    1540    time64_t lt = *t;
  • trunk/libc/src/libc/time/mktime.c

    r2260 r2909  
    1 /* mktime.c (emx+gcc) -- Copyright (c) 1990-1999 by Eberhard Mattes */
     1/* $Id: $ */
     2/** @file
     3 *
     4 * kLIBC - mktime() and _mktime64().
     5 *
     6 * Copyright (c) 1990-1999 by Eberhard Mattes
     7 * Copyright (c) 2005-2006 knut st. osmundsen <bird-srcspam@anduin.net>
     8 *
     9 *
     10 * This file is part of kLIBC.
     11 *
     12 * kLIBC is free software; you can redistribute it and/or modify
     13 * it under the terms of the GNU Lesser General Public License as published
     14 * by the Free Software Foundation; either version 2 of the License, or
     15 * (at your option) any later version.
     16 *
     17 * kLIBC is distributed in the hope that it will be useful,
     18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     20 * GNU Lesser General Public License for more details.
     21 *
     22 * You should have received a copy of the GNU Lesser General Public License
     23 * along with kLIBC; if not, write to the Free Software
     24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     25 *
     26 */
    227
    328#include "libc-alias.h"
    429#include <time.h>
    530#include <limits.h>
    6 #include <emx/time.h>
     31#include <klibc/time.h>
    732#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME
    8 #include <InnoTekLIBC/logstrict.h>
     33#include <klibc/logstrict.h>
    934
    10 time_t _STD(mktime) (struct tm *t)
     35
     36time_t _STD(mktime)(struct tm *t)
    1137{
    1238    LIBCLOG_ENTER("t=%p:{.tm_sec=%d, .tm_min=%d, .tm_hour=%d, .tm_mday=%d, .tm_mon=%d, .tm_year=%d, .tm_wday=%d, .tm_yday=%d, .tm_isdst=%d, .tm_gmtoff=%d, .tm_zone=%p:{%s}}\n",
     
    3359    int dst;
    3460
    35     if (!_tzset_flag)
     61    if (!__libc_gfTZInfoOk)
    3662        tzset();
    3763
    3864    /* mktime() requires that tm_mon is in range.  The other members
    3965       are not restricted. */
    40 
    4166    if (t->tm_mon < 0)
    4267    {
     
    4469           as the results are implementation-defined for negative
    4570           numbers. */
    46 
    4771        t->tm_year -= 1 + ((-t->tm_mon) / 12);
    4872        t->tm_mon = 12 - ((-t->tm_mon) % 12);
     
    7397
    7498
    75 /* year >= 1582, 1 <= month <= 12, 1 <= day <= 31 */
    76 
    77 int _day (int year, int month, int day)
     99/**
     100 * year >= 1582, 1 <= month <= 12, 1 <= day <= 31
     101 * @internal
     102 */
     103int _day(int year, int month, int day)
    78104{
    79105  int result;
     
    102128  x = t->tm_sec
    103129      + 60 * t->tm_min
    104       + 60 *60 * t->tm_hour;
     130      + 60 * 60 * t->tm_hour;
    105131
    106132  r += x;
  • trunk/libc/src/libc/time/settimeofday.c

    r2908 r2909  
    55#include <sys/time.h>
    66#include <errno.h>
    7 #include <emx/time.h>
    8 #include <emx/syscalls.h>
     7#include <klibc/time.h>
     8#include <emx/syscalls.h> /** @todo fixme! */
    99#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME
    10 #include <InnoTekLIBC/logstrict.h>
     10#include <klibc/logstrict.h>
    1111
    1212int _STD(settimeofday)(const struct timeval *tp, const struct timezone *tzp)
     
    2323        LIBCLOG_ERROR_RETURN(-1, "ret -1 - tzp is NULL!\n");
    2424    }
    25     if (!_tzset_flag)
     25    if (!__libc_gfTZInfoOk)
    2626        tzset();
    2727    t = tp->tv_sec;
  • trunk/libc/src/libc/time/strftime.c

    r2254 r2909  
    1 /*
    2     Locale support implementation through OS/2 Unicode API.
    3     Copyright (c) 1992-1996 by Eberhard Mattes
    4     Copyright (c) 2003 InnoTek Systemberatung GmbH
    5 
    6     For conditions of distribution and use, see the file COPYING.
    7 
    8     Format time. The output string is written to the array of size characters
    9     pointed to by string, including the terminating null character. Like
    10     sprintf(), strftime() copies the string pointed to by format to the
    11     array pointed to by string, replacing format specifications with formatted
    12     data from t. Ordinary characters are copied unmodified.
    13 
    14     On success, strftime() returns the number of characters copied to the
    15     array pointed to by string, excluding the terminating null character.
    16     On failure (size exceeded), strftime() returns 0.
    17 */
     1/* $Id: $ */
     2/** @file
     3 *
     4 * kLIBC - strftime().
     5 *
     6 * Copyright (c) 1992-1996 by Eberhard Mattes
     7 * Copyright (c) 2003 InnoTek Systemberatung GmbH
     8 * Copyright (c) 2004-2006 knut st. osmundsen <bird-srcspam@anduin.net>
     9 *
     10 *
     11 * This file is part of kLIBC.
     12 *
     13 * kLIBC is free software; you can redistribute it and/or modify
     14 * it under the terms of the GNU Lesser General Public License as published
     15 * by the Free Software Foundation; either version 2 of the License, or
     16 * (at your option) any later version.
     17 *
     18 * kLIBC is distributed in the hope that it will be useful,
     19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     21 * GNU Lesser General Public License for more details.
     22 *
     23 * You should have received a copy of the GNU Lesser General Public License
     24 * along with kLIBC; if not, write to the Free Software
     25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     26 *
     27 */
    1828
    1929#define __INTERNAL_DEFS
     
    2333#include <time.h>
    2434#include <limits.h>
    25 #include <InnoTekLIBC/locale.h>
    26 #include <emx/time.h>
    2735#include <sys/builtin.h>
     36#include <klibc/locale.h>
     37#include <klibc/time.h>
    2838#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME
    29 #include <InnoTekLIBC/logstrict.h>
     39#include <klibc/logstrict.h>
    3040
    3141#define INS(STR) \
    32   if (!(i = ins (string, size, STR))) \
    33     return 0; \
    34   else \
    35     string += i, size -= i
     42    do { \
     43        if (!(i = ins (string, size, STR))) \
     44            return 0; \
     45        else \
     46            string += i, size -= i; \
     47    } while (0)
    3648#define NUM2(X) \
    37   if (!(i = num2 (string, size, X, minlen))) \
    38     return 0; \
    39   else \
    40     string += i, size -= i
     49    do { \
     50        if (!(i = num2 (string, size, X, minlen))) \
     51            return 0; \
     52        else \
     53            string += i, size -= i; \
     54    } while (0)
    4155#define NUM3(X) \
    42   if (!(i = num3 (string, size, X, minlen))) \
    43     return 0; \
    44   else \
    45     string += i, size -= i
     56    do { \
     57        if (!(i = num3 (string, size, X, minlen))) \
     58            return 0; \
     59        else \
     60            string += i, size -= i; \
     61    } while (0)
    4662#define FMT(F) \
    47   if (!(i = strftime (string, size, F, t))) \
    48     return 0; \
    49   else \
    50     string += i, size -= i
     63    do { \
     64        if (!(i = strftime (string, size, F, t))) \
     65            return 0; \
     66        else \
     67            string += i, size -= i; \
     68    } while (0)
    5169#define CHR(C) \
    52   if (!size) \
    53     return 0; \
    54   else \
    55     *string++ = C, size--
    56 
    57 static size_t ins (char *string, size_t size, const char *s)
    58 {
    59   size_t len = strlen (s);
    60 
    61   if (len >= size)
    62     return 0;
    63 
    64   memcpy (string, s, len);
    65   return len;
    66 }
    67 
    68 static size_t num2 (char *string, size_t size, int x, unsigned char minlen)
    69 {
    70   char *orgstring = string;
    71   long r;
    72 
    73   if (size < 2)
    74     return 0;
    75 
    76   if (x < 0)
    77     x = 0;
    78 
    79   x = __ldivmod (x, 10, &r);
    80   if (x > 9)
    81     x = x % 10;
    82 
    83   if (minlen > 1 || x > 0)
    84     *string++ = x + '0';
    85   *string++ = r + '0';
    86   return string - orgstring;
    87 }
    88 
    89 static size_t num3 (char *string, size_t size, int x, unsigned char minlen)
    90 {
    91   char *orgstring = string;
    92   long r1, r2;
    93 
    94   if (size < 3)
    95     return 0;
    96 
    97   if (x < 0)
    98     x = 0;
    99 
    100   x = __ldivmod (x, 10, &r1);
    101   x = __ldivmod (x, 10, &r2);
    102   if (x > 9)
    103     x = x % 10;
    104 
    105   if (minlen >= 3 || x > 0)
    106     *string++ = x + '0', minlen = 2;
    107   if (minlen >= 2 || r2 > 0)
    108     *string++ = r2 + '0';
    109   *string++ = r1 + '0';
    110   return string - orgstring;
    111 }
    112 
    113 static int week (const struct tm *t, int first)
    114 {
    115   int wd, tmp;
    116 
    117   wd = t->tm_wday - first;    /* wd = relative day in week (w.r.t. first) */
    118   if (wd < 0) wd += 7;
    119   tmp = t->tm_yday - wd;      /* Start of current week */
    120   if (tmp <= 0) return 0;     /* In partial first week */
    121   return (tmp + 6) / 7;       /* Week number */
    122 }
    123 
    124 size_t _STD(strftime) (char *string, size_t size, const char *format,
    125   const struct tm *t)
    126 {
    127   LIBCLOG_ENTER("string=%p size=%d format=%p:{%s} t=%p:{.tm_sec=%d, .tm_min=%d, .tm_hour=%d, .tm_mday=%d, .tm_mon=%d, .tm_year=%d, .tm_wday=%d, .tm_yday=%d, .tm_isdst=%d, .tm_gmtoff=%d, .tm_zone=%p:{%s}}\n",
    128                 (void *)string, size, (void *)format, format, (void *)t,
    129                  t ? t->tm_sec : -1,  t ? t->tm_min : -1, t ? t->tm_hour : -1, t ? t->tm_mday : -1, t ? t->tm_mon : -1,
    130                  t ? t->tm_year : -1, t ? t->tm_wday : -1, t ? t->tm_yday : -1, t ? t->tm_isdst : -1, t ? /*t->tm_gmtoff*/-2 : -1,
    131                  (void *)(t ? /*t->tm_zone*/NULL : NULL), t ? /*t->tm_zone*/"" : "");
    132   size_t i;
    133   unsigned char c, minlen;
    134   char *orgstring = string;
    135 
    136   if (!_tzset_flag) tzset ();
    137 
    138   while ((c = *format) != 0)
    139   {
    140     if (c == '%')
     70    do { \
     71        if (!size) \
     72            return 0; \
     73        else \
     74            *string++ = C, size--; \
     75    } while (0)
     76
     77static size_t ins(char *string, size_t size, const char *s)
     78{
     79    size_t len = strlen(s);
     80
     81    if (len >= size)
     82        return 0;
     83
     84    memcpy(string, s, len);
     85    return len;
     86}
     87
     88static size_t num2(char *string, size_t size, int x, unsigned char minlen)
     89{
     90    char *orgstring = string;
     91    long r;
     92
     93    if (size < 2)
     94        return 0;
     95
     96    if (x < 0)
     97        x = 0;
     98
     99    x = __ldivmod(x, 10, &r);
     100    if (x > 9)
     101        x = x % 10;
     102
     103    if (minlen > 1 || x > 0)
     104        *string++ = x + '0';
     105    *string++ = r + '0';
     106    return string - orgstring;
     107}
     108
     109static size_t num3(char *string, size_t size, int x, unsigned char minlen)
     110{
     111    char *orgstring = string;
     112    long r1, r2;
     113
     114    if (size < 3)
     115        return 0;
     116
     117    if (x < 0)
     118        x = 0;
     119
     120    x = __ldivmod(x, 10, &r1);
     121    x = __ldivmod(x, 10, &r2);
     122    if (x > 9)
     123        x = x % 10;
     124
     125    if (minlen >= 3 || x > 0)
     126        *string++ = x + '0', minlen = 2;
     127    if (minlen >= 2 || r2 > 0)
     128        *string++ = r2 + '0';
     129    *string++ = r1 + '0';
     130    return string - orgstring;
     131}
     132
     133static int week(const struct tm *t, int first)
     134{
     135    int wd, tmp;
     136
     137    wd = t->tm_wday - first;    /* wd = relative day in week (w.r.t. first) */
     138    if (wd < 0)
     139        wd += 7;
     140    tmp = t->tm_yday - wd;      /* Start of current week */
     141    if (tmp <= 0)               /* In partial first week */
     142        return 0;
     143    return (tmp + 6) / 7;       /* Week number */
     144}
     145
     146size_t _STD(strftime)(char *string, size_t size, const char *format, const struct tm *t)
     147{
     148    LIBCLOG_ENTER("string=%p size=%d format=%p:{%s} t=%p:{.tm_sec=%d, .tm_min=%d, .tm_hour=%d, .tm_mday=%d, .tm_mon=%d, .tm_year=%d, .tm_wday=%d, .tm_yday=%d, .tm_isdst=%d, .tm_gmtoff=%d, .tm_zone=%p:{%s}}\n",
     149                  (void *)string, size, (void *)format, format, (void *)t,
     150                  t ? t->tm_sec : -1,  t ? t->tm_min : -1, t ? t->tm_hour : -1, t ? t->tm_mday : -1, t ? t->tm_mon : -1,
     151                  t ? t->tm_year : -1, t ? t->tm_wday : -1, t ? t->tm_yday : -1, t ? t->tm_isdst : -1, t ? /*t->tm_gmtoff*/-2 : -1,
     152                  (void *)(t ? /*t->tm_zone*/NULL : NULL), t ? /*t->tm_zone*/"" : "");
     153    size_t i;
     154    unsigned char c, minlen;
     155    char *orgstring = string;
     156
     157    if (!__libc_gfTZInfoOk)
     158        tzset();
     159
     160    while ((c = *format) != 0)
    141161    {
    142       minlen = 9;
    143 nextformat:
    144       ++format;
    145       switch (*format)
    146       {
    147         case 0:
    148         case '%':
    149           CHR ('%');
    150           if (*format == 0)
    151             --format;
    152           break;
    153 
    154         /* Handle prefixes first */
    155         case 'E':
    156           /* Alternative date/time formats not supported for now */
    157         case 'O':
    158           /* Alternative numeric formats not supported for now */
    159           goto nextformat;
    160 
    161         case '1':
    162           /* Undocumented in Unicode API reference, encountered in Russian
    163              locale. I think it should mean that the next number should occupy
    164              such much characters how it should (e.g. %1H:%M = 1:20 or 23:00). */
    165           minlen = 1;
    166           goto nextformat;
    167 
    168         case 'a':
    169           INS (__libc_gLocaleTime.swdays [t->tm_wday]);
    170           break;
    171         case 'A':
    172           INS (__libc_gLocaleTime.lwdays [t->tm_wday]);
    173           break;
    174         case 'b':
    175         case 'h':
    176           INS (__libc_gLocaleTime.smonths [t->tm_mon]);
    177           break;
    178         case 'B':
    179           INS (__libc_gLocaleTime.lmonths [t->tm_mon]);
    180           break;
    181         case 'c':
    182           FMT (__libc_gLocaleTime.date_time_fmt);
    183           break;
    184         case 'C':
    185           /* 2000 A.D. is still 20th century (not 21st) */
    186           NUM2 (1 + (t->tm_year - 1) / 100);
    187           break;
    188         case 'd':
    189           NUM2 (t->tm_mday);
    190           break;
    191         case 'D':
    192           FMT ("%m/%d/%y");
    193           break;
    194         case 'e':
    195           NUM2 (t->tm_mday);
    196           if (string [-2] == '0')
    197             string [-2] = ' ';
    198           break;
    199         case 'F': /* ISO Date - C99 */
    200           FMT ("%Y-%m-%d");
    201           break;
    202         case 'H':
    203           NUM2 (t->tm_hour);
    204           break;
    205         case 'I':
    206           NUM2 ((t->tm_hour + 11) % 12 + 1);
    207           break;
    208         case 'j':
    209           NUM3 (t->tm_yday + 1);
    210           break;
    211         case 'm':
    212           NUM2 (t->tm_mon + 1);
    213           break;
    214         case 'M':
    215           NUM2 (t->tm_min);
    216           break;
    217         case 'n':
    218           CHR ('\n');
    219           break;
    220         case 'p':
    221           INS (t->tm_hour >= 12 ? __libc_gLocaleTime.pm : __libc_gLocaleTime.am);
    222           break;
    223         case 'r':
    224           FMT ("%I:%M:%S %p");
    225           break;
    226         case 'S':
    227           NUM2 (t->tm_sec);
    228           break;
    229         case 't':
    230           CHR ('\t');
    231           break;
    232         case 'T':
    233           FMT ("%H:%M:%S");
    234           break;
    235         case 'U':
    236           NUM2 (week (t, 0));
    237           break;
    238         case 'w':
    239           NUM2 (t->tm_wday);
    240           break;
    241         case 'W':
    242           NUM2 (week (t, 1));
    243           break;
    244         case 'x':
    245           FMT (__libc_gLocaleTime.date_fmt);
    246           break;
    247         case 'X':
    248           FMT (__libc_gLocaleTime.time_fmt);
    249           break;
    250         case 'y':
    251           NUM2 (t->tm_year % 100);
    252           break;
    253         case 'Y':
    254           CHR ('0' + (1900 + t->tm_year) / 1000);
    255           NUM3 ((t->tm_year + 1900) % 1000);
    256           break;
    257         case 'Z':
    258           if (t->tm_isdst >= 0)
    259           {
    260             INS (_tzname [(t->tm_isdst ? 1 : 0)]);
    261           }
    262           break;
    263       }
     162        if (c == '%')
     163        {
     164            minlen = 9;
     165            nextformat:
     166            ++format;
     167            switch (*format)
     168            {
     169                case 0:
     170                case '%':
     171                    CHR('%');
     172                    if (*format == 0)
     173                        --format;
     174                    break;
     175
     176                    /* Handle prefixes first */
     177                case 'E':
     178                    /* Alternative date/time formats not supported for now */
     179                case 'O':
     180                    /* Alternative numeric formats not supported for now */
     181                    goto nextformat;
     182
     183                case '1':
     184                    /* Undocumented in Unicode API reference, encountered in Russian
     185                       locale. I think it should mean that the next number should occupy
     186                       such much characters how it should (e.g. %1H:%M = 1:20 or 23:00). */
     187                    minlen = 1;
     188                    goto nextformat;
     189
     190                case 'a':
     191                    INS(__libc_gLocaleTime.swdays [t->tm_wday]);
     192                    break;
     193                case 'A':
     194                    INS(__libc_gLocaleTime.lwdays [t->tm_wday]);
     195                    break;
     196                case 'b':
     197                case 'h':
     198                    INS(__libc_gLocaleTime.smonths [t->tm_mon]);
     199                    break;
     200                case 'B':
     201                    INS(__libc_gLocaleTime.lmonths [t->tm_mon]);
     202                    break;
     203                case 'c':
     204                    FMT(__libc_gLocaleTime.date_time_fmt);
     205                    break;
     206                case 'C':
     207                    /* 2000 A.D. is still 20th century (not 21st) */
     208                    NUM2(1 + (t->tm_year - 1) / 100);
     209                    break;
     210                case 'd':
     211                    NUM2(t->tm_mday);
     212                    break;
     213                case 'D':
     214                    FMT("%m/%d/%y");
     215                    break;
     216                case 'e':
     217                    NUM2(t->tm_mday);
     218                    if (string [-2] == '0')
     219                        string [-2] = ' ';
     220                    break;
     221                case 'F': /* ISO Date - C99 */
     222                    FMT("%Y-%m-%d");
     223                    break;
     224                case 'H':
     225                    NUM2(t->tm_hour);
     226                    break;
     227                case 'I':
     228                    NUM2((t->tm_hour + 11) % 12 + 1);
     229                    break;
     230                case 'j':
     231                    NUM3(t->tm_yday + 1);
     232                    break;
     233                case 'm':
     234                    NUM2(t->tm_mon + 1);
     235                    break;
     236                case 'M':
     237                    NUM2(t->tm_min);
     238                    break;
     239                case 'n':
     240                    CHR('\n');
     241                    break;
     242                case 'p':
     243                    INS(t->tm_hour >= 12 ? __libc_gLocaleTime.pm : __libc_gLocaleTime.am);
     244                    break;
     245                case 'r':
     246                    FMT("%I:%M:%S %p");
     247                    break;
     248                case 'S':
     249                    NUM2(t->tm_sec);
     250                    break;
     251                case 't':
     252                    CHR('\t');
     253                    break;
     254                case 'T':
     255                    FMT("%H:%M:%S");
     256                    break;
     257                case 'U':
     258                    NUM2(week(t, 0));
     259                    break;
     260                case 'w':
     261                    NUM2(t->tm_wday);
     262                    break;
     263                case 'W':
     264                    NUM2(week(t, 1));
     265                    break;
     266                case 'x':
     267                    FMT(__libc_gLocaleTime.date_fmt);
     268                    break;
     269                case 'X':
     270                    FMT(__libc_gLocaleTime.time_fmt);
     271                    break;
     272                case 'y':
     273                    NUM2(t->tm_year % 100);
     274                    break;
     275                case 'Y':
     276                    CHR('0' + (1900 + t->tm_year) / 1000);
     277                    NUM3((t->tm_year + 1900) % 1000);
     278                    break;
     279                case 'Z':
     280                    if (t->tm_isdst >= 0)
     281                        INS(_tzname[(t->tm_isdst ? 1 : 0)]);
     282                    break;
     283            }
     284        }
     285        else if (!CHK_MBCS_PREFIX(&__libc_GLocaleCtype, c, i))
     286            CHR(c);
     287        else
     288        {
     289            if (i > size)
     290                LIBCLOG_ERROR_RETURN_INT(0);
     291            memcpy (string, format, i);
     292            string += i;
     293            format += i - 1;
     294        }
     295        ++format;
    264296    }
    265     else if (!CHK_MBCS_PREFIX (&__libc_GLocaleCtype, c, i))
    266       CHR (c);
    267     else
     297
     298    if (size)
    268299    {
    269       if (i > size)
    270         LIBCLOG_ERROR_RETURN_INT(0);
    271       memcpy (string, format, i);
    272       string += i;
    273       format += i - 1;
     300        *string = '\0';
     301        LIBCLOG_RETURN_MSG(string - orgstring, "ret %d (%#x) - string={%s}\n", string - orgstring, string - orgstring, string);
    274302    }
    275     ++format;
    276   }
    277 
    278   if (size)
    279   {
    280     *string = '\0';
    281     LIBCLOG_RETURN_MSG(string - orgstring, "ret %d (%#x) - string={%s}\n", string - orgstring, string - orgstring, string);
    282   }
    283 
    284   LIBCLOG_ERROR_RETURN_INT(0);
    285 }
     303
     304    LIBCLOG_ERROR_RETURN_INT(0);
     305}
     306
  • trunk/libc/src/libc/time/strptime.c

    r2254 r2909  
    1 /*
    2     Locale support implementation through OS/2 Unicode API.
    3     Copyright (c) 1992-1996 by Eberhard Mattes
    4     Copyright (c) 2003 InnoTek Systemberatung GmbH
    5     Copyright (c) 2005 knut st. osmundsen <bird@anduin.net>
    6 
    7     For conditions of distribution and use, see the file COPYING.
    8 
    9     Parse a time specification in the input string pointed to by buffer
    10     according to the format string pointed to by format, updating the
    11     structure pointed to by t.
    12 
    13     Whitespace (any number of spaces) in the format string matches whitespace
    14     (any number of spaces, including zero) in the input string. All other
    15     characters except for % are compared to the input. Parsing ends (with an
    16     error being indicated) when a mismatch is encountered. %% in the format
    17     string matches % in the input string. A % which is not followed by another
    18     % or the end of the string starts a field specification. The field in the
    19     input is interpreted according to the field specification. For all field
    20     types, whitespace is ignored at the start of a field. Field specifications
    21     matching numbers skip leading zeros. Case is ignored when comparing strings.
    22     The field width is not restricted, that is, as many characters as possible
    23     are matched.
    24 
    25     If successful, strptime() returns a pointer to the character following the
    26     last character parsed. On error, strptime() returns NULL.
    27 */
    28 
     1/* $Id: $ */
     2/** @file
     3 *
     4 * kLIBC - strptime().
     5 *
     6 * Copyright (c) 1992-1996 by Eberhard Mattes
     7 * Copyright (c) 2003 InnoTek Systemberatung GmbH
     8 * Copyright (c) 2005-2006 knut st. osmundsen <bird-srcspam@anduin.net>
     9 *
     10 *
     11 * This file is part of kLIBC.
     12 *
     13 * kLIBC is free software; you can redistribute it and/or modify
     14 * it under the terms of the GNU Lesser General Public License as published
     15 * by the Free Software Foundation; either version 2 of the License, or
     16 * (at your option) any later version.
     17 *
     18 * kLIBC is distributed in the hope that it will be useful,
     19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     21 * GNU Lesser General Public License for more details.
     22 *
     23 * You should have received a copy of the GNU Lesser General Public License
     24 * along with kLIBC; if not, write to the Free Software
     25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     26 *
     27 */
     28
     29/*******************************************************************************
     30*   Internal Functions                                                         *
     31*******************************************************************************/
    2932#define __INTERNAL_DEFS
    3033#include "libc-alias.h"
     
    3235#include <string.h>
    3336#include <time.h>
    34 #include <InnoTekLIBC/locale.h>
     37#include <klibc/locale.h>
    3538#include <ctype.h>
    36 #include <emx/time.h>
     39#include <klibc/time.h>
    3740#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME
    38 #include <InnoTekLIBC/logstrict.h>
    39 
    40 
     41#include <klibc/logstrict.h>
     42
     43
     44/*******************************************************************************
     45*   Defined Constants And Macros                                               *
     46*******************************************************************************/
    4147#define RECURSE(FMT) \
    42   if (!(s = parse_fmt (s, FMT, tm, &mask))) \
     48    if (!(s = parse_fmt (s, FMT, tm, &mask))) \
     49        return NULL;
     50#define NUMBER(DST,MIN,MAX,ADD,LEN) \
     51    if (!(s = parse_number (s, DST, MIN, MAX, ADD, LEN))) \
     52        return NULL;
     53#define STRING(STR) \
     54    if (!(s = parse_string (s, STR))) \
     55        return NULL;
     56#define TABLE(DST,TAB,N) \
     57    if (!(s = parse_table (s, DST, TAB, N))) \
     58        return NULL;
     59
     60
     61static const char *parse_number(const char *s, int *dst, int min, int max, int add, int len)
     62{
     63    int n;
     64
     65    while (*s != 0 && isspace(*s))
     66        ++s;
     67    if (*s == 0 || !isdigit(*s))
     68        return NULL;
     69    n = 0;
     70    while (isdigit(*s) && len-- > 0)
     71        n = n * 10 + (*s++ - '0');  /** @todo check for overflow */
     72    if (n < min || (max >= 0 && n > max))
     73        return NULL;
     74    *dst = n + add;
     75    return s;
     76}
     77
     78static const char *parse_string(const char *s, const char *str)
     79{
     80    size_t len;
     81
     82    while (isspace(*s) && *s != '\0')
     83        ++s;
     84    len = strlen(str);
     85    if (len == 0 || strnicmp(s, str, len) != 0)
     86        return NULL;
     87    return s + len;
     88}
     89
     90static const char *parse_table (const char *s, int *dst, char **tab, int n)
     91{
     92    int i;
     93    size_t len;
     94
     95    while (isspace(*s) && *s != '\0')
     96        ++s;
     97    for (i = 0; i < n; ++i)
     98    {
     99        len = strlen(tab[i]);
     100        if (strnicmp(s, tab[i], len) == 0)
     101        {
     102            *dst = i;
     103            return s + len;
     104        }
     105    }
    43106    return NULL;
    44 #define NUMBER(DST,MIN,MAX,ADD,LEN) \
    45   if (!(s = parse_number (s, DST, MIN, MAX, ADD, LEN))) \
    46     return NULL;
    47 #define STRING(STR) \
    48   if (!(s = parse_string (s, STR))) \
    49     return NULL;
    50 #define TABLE(DST,TAB,N) \
    51   if (!(s = parse_table (s, DST, TAB, N))) \
    52     return NULL;
    53 
    54 static const char *parse_number (const char *s, int *dst,
    55   int min, int max, int add, int len)
     107}
     108
     109static const char *parse_fmt(const char *s, const char *f, struct tm *tm, unsigned *retmask)
    56110{
    57   int n;
    58 
    59   while (*s != 0 && isspace (*s))
    60     ++s;
    61   if (*s == 0 || !isdigit (*s))
    62     return NULL;
    63   n = 0;
    64   while (isdigit (*s) && len-- > 0)
    65     n = n * 10 + (*s++ - '0');  /* TODO: check for overflow */
    66   if (n < min || (max >= 0 && n > max))
    67     return NULL;
    68   *dst = n + add;
    69   return s;
    70 }
    71 
    72 static const char *parse_string (const char *s,
    73   const char *str)
    74 {
    75   size_t len;
    76 
    77   while (*s != 0 && isspace (*s))
    78     ++s;
    79   len = strlen (str);
    80   if (len == 0 || strnicmp (s, str, len) != 0)
    81     return NULL;
    82   return s + len;
    83 }
    84 
    85 static const char *parse_table (const char *s, int *dst,
    86   char **tab, int n)
    87 {
    88   int i;
    89   size_t len;
    90 
    91   while (*s != 0 && isspace (*s))
    92     ++s;
    93   for (i = 0; i < n; ++i)
    94   {
    95     len = strlen (tab[i]);
    96     if (strnicmp (s, tab[i], len) == 0)
    97     {
    98       *dst = i;
    99       return s + len;
    100     }
    101   }
    102   return NULL;
    103 }
    104 
    105 static const char *parse_fmt (const char *s,
    106   const char *f, struct tm *tm, unsigned *retmask)
    107 {
    108   const char *t;
    109   int week = -1;
    110   int century = -1;
    111   /* The mask of found fields */
    112   unsigned mask = 0;
     111    const char *t;
     112    int week = -1;
     113    int century = -1;
     114    /* The mask of found fields */
     115    unsigned mask = 0;
    113116
    114117#define MASK_CENTURY    0x00000001
     
    128131#define MASK_SECOND     0x00000800
    129132
    130   while (*f != 0)
    131   {
    132     if (isspace (*f))
    133     {
    134       while (*s != 0 && isspace (*s))
    135         ++s;
    136       ++f;
    137     }
    138     else if (*f != '%')
    139     {
    140       if (*s != *f)
    141         return NULL;
    142       ++s; ++f;
    143     }
    144     else
    145     {
    146       ++f;
    147 nextformat:
    148       switch (*f++)
    149       {
    150         case 0:
    151           if (*s != '%')
    152             return NULL;
    153           return s + 1;
    154           break;
    155 
    156         case '%': /* A percent is just a percent */
    157           if (*s != '%')
    158             return NULL;
    159           ++s;
    160           break;
    161 
    162         /* Handle prefixes first */
    163         case 'E':
    164           /* Alternative date/time formats not supported for now */
    165         case 'O':
    166           /* Alternative numeric formats not supported for now */
    167         case '1':
    168           /* Numeric length does not have sense here */
    169           goto nextformat;
    170 
    171         case 'a': /* Short weekday name */
    172           TABLE (&tm->tm_wday, __libc_gLocaleTime.swdays, 7);
    173           mask |= MASK_WEEKDAY;
    174           break;
    175 
    176         case 'A': /* Long weekday name */
    177           TABLE (&tm->tm_wday, __libc_gLocaleTime.lwdays, 7);
    178           mask |= MASK_WEEKDAY;
    179           break;
    180 
    181         case 'b': /* Short month name */
    182         case 'h':
    183           TABLE (&tm->tm_mon, __libc_gLocaleTime.smonths, 12);
    184           mask |= MASK_MONTH;
    185           break;
    186 
    187         case 'B': /* Long month name */
    188           TABLE (&tm->tm_mon, __libc_gLocaleTime.lmonths, 12);
    189           mask |= MASK_MONTH;
    190           break;
    191 
    192         case 'c': /* Locale's defined time and date format */
    193           RECURSE (__libc_gLocaleTime.date_time_fmt);
    194           break;
    195 
    196         case 'C': /* Century number */
    197           NUMBER (&century, 0, 99, 0, 2);
    198           mask |= MASK_CENTURY;
    199           break;
    200 
    201         case 'd': /* Day of the month (1-31) */
    202         case 'e':
    203           NUMBER (&tm->tm_mday, 1, 31, 0, 2);
    204           mask |= MASK_MONTHDAY;
    205           break;
    206 
    207         case 'D': /* MM/DD/YY */
    208           RECURSE ("%m/%d/%y");
    209           break;
    210 
    211         case 'F': /* ISO Date - C99 */
    212           RECURSE ("%Y-%m-%d");
    213           break;
    214 
    215         case 'H': /* Hour (00-23) */
    216         case 'k':
    217           NUMBER (&tm->tm_hour, 0, 23, 0, 2);
    218           mask |= MASK_HOUR;
    219           break;
    220 
    221         case 'I': /* Hour (01-12) */
    222         case 'l':
    223           NUMBER (&tm->tm_hour, 1, 12, 0, 2);
    224           mask |= MASK_HOUR;
    225           break;
    226 
    227         case 'j': /* Day of the year (1-366) */
    228           NUMBER (&tm->tm_yday, 1, 366, -1, 3);
    229           mask |= MASK_YEARDAY;
    230           break;
    231 
    232         case 'm': /* Month (01-12) */
    233           NUMBER (&tm->tm_mon, 1, 12, -1, 2);
    234           mask |= MASK_MONTH;
    235           break;
    236 
    237         case 'M': /* Minutes (00-59) */
    238           NUMBER (&tm->tm_min, 0, 59, 0, 2);
    239           mask |= MASK_MINUTE;
    240           break;
    241 
    242         case 'n': /* Newline */
    243           if (*s != '\n')
    244             return NULL;
    245           ++s;
    246           break;
    247 
    248         case 'p': /* AM or PM */
    249           if (!(mask & MASK_HOUR)
    250            || (tm->tm_hour < 1)
    251            || (tm->tm_hour > 12))
    252             return NULL;
    253           if (   (t = parse_string (s, "AM")) != NULL
    254               || (t = parse_string (s, __libc_gLocaleTime.am)) != NULL)
    255           {
    256             if (tm->tm_hour == 12)
    257               tm->tm_hour = 0;
    258           }
    259           else if (   (t = parse_string (s, "PM")) != NULL
    260                    || (t = parse_string (s, __libc_gLocaleTime.pm)) != NULL)
    261           {
    262             if (tm->tm_hour != 12)
    263               tm->tm_hour += 12;
    264           }
    265           else
    266             return NULL;
    267           s = t;
    268           break;
    269 
    270         case 'P': /* am or pm */
    271           if (!(mask & MASK_HOUR)
    272            || (tm->tm_hour < 1)
    273            || (tm->tm_hour > 12))
    274             return NULL;
    275           if (   (t = parse_string (s, "am")) != NULL
    276               || (t = parse_string (s, __libc_gLocaleTime.am)) != NULL)
    277           {
    278             if (tm->tm_hour == 12)
    279               tm->tm_hour = 0;
    280           }
    281           else if (   (t = parse_string (s, "pm")) != NULL
    282                    || (t = parse_string (s, __libc_gLocaleTime.pm)) != NULL)
    283           {
    284             if (tm->tm_hour != 12)
    285               tm->tm_hour += 12;
    286           }
    287           else
    288             return NULL;
    289           s = t;
    290           break;
    291 
    292         case 'r': /* HH:MM:SS am/pm */
    293           RECURSE ("%I:%M:%S %p");
    294           break;
    295 
    296         case 'R': /* HH:MM */
    297           RECURSE ("%H:%M");
    298           break;
    299 
    300         case 'S': /* Seconds (00-61(?)) */
    301           NUMBER (&tm->tm_sec, 0, 61, 0, 2);
    302           mask |= MASK_SECOND;
    303           break;
    304 
    305         case 't': /* Tabulation */
    306           if (*s != '\t')
    307             return NULL;
    308           ++s;
    309           break;
    310 
    311         case 'T': /* HH:MM:SS */
    312           RECURSE ("%H:%M:%S");
    313           break;
    314 
    315         case 'w': /* Weekday (0-6), 0 = Sunday */
    316           NUMBER (&tm->tm_wday, 0, 6, 0, 1);
    317           mask |= MASK_WEEKDAY;
    318           break;
    319 
    320         case 'U': /* Week number (0-53), 0 = Sunday */
    321           NUMBER (&week, 0, 53, 0, 2);
    322           mask |= MASK_WEEKS;
    323           break;
    324 
    325         case 'W': /* Week number (0-53), 0 = Monday */
    326           NUMBER (&week, 0, 53, 0, 2);
    327           mask |= MASK_WEEKM;
    328           break;
    329 
    330         case 'x':
    331           RECURSE (__libc_gLocaleTime.date_fmt);
    332           break;
    333 
    334         case 'X':
    335           RECURSE (__libc_gLocaleTime.time_fmt);
    336           break;
    337 
    338         case 'y':
    339           NUMBER (&tm->tm_year, 0, 99, 0, 2);
    340           if (tm->tm_year < 69)
    341             tm->tm_year += 100;
    342           mask |= MASK_YEAR2;
    343           break;
    344 
    345         case 'Y':
    346           NUMBER (&tm->tm_year, 1900, -1, -1900, 4);
    347           mask |= MASK_YEAR4;
    348           /* Ignore century since it was explicitely given */
    349           century = -1;
    350           mask &= ~MASK_CENTURY;
    351           break;
    352 
    353         default:
    354           return NULL;
    355       }
    356     }
    357   }
    358 
    359   if (mask & MASK_CENTURY)
    360   {
    361     if (!(mask & MASK_YEAR_ANY))
    362       tm->tm_year = 0;
    363     tm->tm_year = (century - 19) * 100 + (tm->tm_year % 100);
    364     mask |= MASK_YEAR4;
    365   }
    366 
    367   /* We should know which fields are already correctly filled */
    368   if (retmask)
    369     mask |= *retmask;
    370 
    371   if ((mask & MASK_YEAR_ANY) && (mask & MASK_YEARDAY)
    372    && (mask & (MASK_MONTH | MASK_MONTHDAY)) != (MASK_MONTH | MASK_MONTHDAY))
    373   {
    374     /* Compute month and day of the month if any of them is not given */
    375     const unsigned short *md = _leap_year (tm->tm_year + 1900) ?
    376       _month_day_leap : _month_day_non_leap;
    377     for (tm->tm_mon = 11; tm->tm_mon > 0 && tm->tm_yday < md [tm->tm_mon]; tm->tm_mon--)
    378         /* nothing */;
    379     tm->tm_mday = 1 + tm->tm_yday - md [tm->tm_mon];
    380     mask |= MASK_MONTH | MASK_MONTHDAY;
    381   }
    382 
    383   if (!(mask & MASK_YEARDAY))
    384   {
    385     if ((mask & MASK_WEEK_ANY) && (mask & MASK_WEEKDAY) && (mask & MASK_YEAR_ANY)
    386      && (tm->tm_year >= 70) && (tm->tm_year <= 206))
    387     {
    388       /* Compute day of the year given week number and weekday */
    389       int dow = (mask & MASK_WEEKM) == MASK_WEEKM ? 3 : 4;
    390       dow = (dow + _year_day [tm->tm_year]) % 7;
    391       if (!dow)
    392           week--;
    393       dow = (tm->tm_wday - ((mask & MASK_WEEKM) == MASK_WEEKM) - dow) % 7;
    394       if (dow < 0)
    395         dow += 7;
    396       tm->tm_yday = week * 7 + dow;
    397       mask |= MASK_YEARDAY;
    398     }
    399     else if ((mask & MASK_YEAR_ANY) && (mask & MASK_MONTH) && (mask & MASK_MONTHDAY))
    400     {
    401       /* Compute year day from month and day of the month */
    402       const unsigned short *md = _leap_year (tm->tm_year + 1900) ?
    403         _month_day_leap : _month_day_non_leap;
    404       tm->tm_yday = tm->tm_mday - 1 + md [tm->tm_mon];
    405       mask |= MASK_YEARDAY;
    406     }
    407   }
    408 
    409   if (!(mask & MASK_WEEKDAY) && (mask & MASK_YEAR_ANY) && (mask & MASK_YEARDAY))
    410   {
    411     /* Compute day of the week if it was not given */
    412     if ((tm->tm_year < 70) || (tm->tm_year > 206))
    413       tm->tm_wday = 0; /* Unknown */
    414     else
    415     {
    416       int absday = _year_day [tm->tm_year] + tm->tm_yday;
    417       /* 1st January 1970 was Thursday (4) */
    418       tm->tm_wday = ((4 + absday) % 7);
    419       mask |= MASK_WEEKDAY;
    420     }
    421   }
    422 
    423   if (((mask & (MASK_WEEK_ANY | MASK_WEEKDAY | MASK_YEAR_ANY)) == (MASK_WEEK_ANY | MASK_WEEKDAY | MASK_YEAR_ANY))
    424    && ((mask & (MASK_MONTH | MASK_MONTHDAY)) != (MASK_MONTH | MASK_MONTHDAY)))
    425   {
    426     /* Compute month and day of the month given weekday and week number */
    427     const unsigned short *md = _leap_year (tm->tm_year + 1900) ?
    428       _month_day_leap : _month_day_non_leap;
    429 
    430     for (tm->tm_mon = 11; tm->tm_mon > 0 && tm->tm_yday < md [tm->tm_mon]; tm->tm_mon--)
    431         /* nothing */;
    432     tm->tm_mday = 1 + tm->tm_yday - md [tm->tm_mon];
    433     mask |= MASK_MONTH | MASK_MONTHDAY;
    434   }
    435 
    436   /* Communicate to the caller which fields are filled, except fields
    437      that are not located inside the tm structure. */
    438   if (retmask)
    439     *retmask |= mask & ~(MASK_WEEKI | MASK_WEEKM | MASK_WEEKS | MASK_CENTURY);
    440 
    441   return s;
     133    while (*f != 0)
     134    {
     135        if (isspace(*f))
     136        {
     137            while (isspace(*s) && *s != '\0')
     138                ++s;
     139            ++f;
     140        }
     141        else if (*f != '%')
     142        {
     143            if (*s != *f)
     144                return NULL;
     145            ++s; ++f;
     146        }
     147        else
     148        {
     149            ++f;
     150            nextformat:
     151            switch (*f++)
     152            {
     153                case 0:
     154                    if (*s != '%')
     155                        return NULL;
     156                    return s + 1;
     157
     158                case '%': /* A percent is just a percent */
     159                    if (*s != '%')
     160                        return NULL;
     161                    ++s;
     162                    break;
     163
     164                    /* Handle prefixes first */
     165                case 'E':
     166                    /* Alternative date/time formats not supported for now */
     167                case 'O':
     168                    /* Alternative numeric formats not supported for now */
     169                case '1':
     170                    /* Numeric length does not have sense here */
     171                    goto nextformat;
     172
     173                case 'a': /* Short weekday name */
     174                    TABLE(&tm->tm_wday, __libc_gLocaleTime.swdays, 7);
     175                    mask |= MASK_WEEKDAY;
     176                    break;
     177
     178                case 'A': /* Long weekday name */
     179                    TABLE(&tm->tm_wday, __libc_gLocaleTime.lwdays, 7);
     180                    mask |= MASK_WEEKDAY;
     181                    break;
     182
     183                case 'b': /* Short month name */
     184                case 'h':
     185                    TABLE(&tm->tm_mon, __libc_gLocaleTime.smonths, 12);
     186                    mask |= MASK_MONTH;
     187                    break;
     188
     189                case 'B': /* Long month name */
     190                    TABLE(&tm->tm_mon, __libc_gLocaleTime.lmonths, 12);
     191                    mask |= MASK_MONTH;
     192                    break;
     193
     194                case 'c': /* Locale's defined time and date format */
     195                    RECURSE(__libc_gLocaleTime.date_time_fmt);
     196                    break;
     197
     198                case 'C': /* Century number */
     199                    NUMBER(&century, 0, 99, 0, 2);
     200                    mask |= MASK_CENTURY;
     201                    break;
     202
     203                case 'd': /* Day of the month (1-31) */
     204                case 'e':
     205                    NUMBER(&tm->tm_mday, 1, 31, 0, 2);
     206                    mask |= MASK_MONTHDAY;
     207                    break;
     208
     209                case 'D': /* MM/DD/YY */
     210                    RECURSE("%m/%d/%y");
     211                    break;
     212
     213                case 'F': /* ISO Date - C99 */
     214                    RECURSE("%Y-%m-%d");
     215                    break;
     216
     217                case 'H': /* Hour (00-23) */
     218                case 'k':
     219                    NUMBER(&tm->tm_hour, 0, 23, 0, 2);
     220                    mask |= MASK_HOUR;
     221                    break;
     222
     223                case 'I': /* Hour (01-12) */
     224                case 'l':
     225                    NUMBER(&tm->tm_hour, 1, 12, 0, 2);
     226                    mask |= MASK_HOUR;
     227                    break;
     228
     229                case 'j': /* Day of the year (1-366) */
     230                    NUMBER(&tm->tm_yday, 1, 366, -1, 3);
     231                    mask |= MASK_YEARDAY;
     232                    break;
     233
     234                case 'm': /* Month (01-12) */
     235                    NUMBER(&tm->tm_mon, 1, 12, -1, 2);
     236                    mask |= MASK_MONTH;
     237                    break;
     238
     239                case 'M': /* Minutes (00-59) */
     240                    NUMBER(&tm->tm_min, 0, 59, 0, 2);
     241                    mask |= MASK_MINUTE;
     242                    break;
     243
     244                case 'n': /* Newline */
     245                    if (*s != '\n')
     246                        return NULL;
     247                    ++s;
     248                    break;
     249
     250                case 'p': /* AM or PM */
     251                    if (    !(mask & MASK_HOUR)
     252                        ||  (tm->tm_hour < 1)
     253                        ||  (tm->tm_hour > 12))
     254                        return NULL;
     255                    if (    (t = parse_string(s, "AM")) != NULL
     256                        ||  (t = parse_string(s, __libc_gLocaleTime.am)) != NULL)
     257                    {
     258                        if (tm->tm_hour == 12)
     259                            tm->tm_hour = 0;
     260                    }
     261                    else if (   (t = parse_string(s, "PM")) != NULL
     262                             || (t = parse_string(s, __libc_gLocaleTime.pm)) != NULL)
     263                    {
     264                        if (tm->tm_hour != 12)
     265                            tm->tm_hour += 12;
     266                    }
     267                    else
     268                        return NULL;
     269                    s = t;
     270                    break;
     271
     272                case 'P': /* am or pm */
     273                    if (    !(mask & MASK_HOUR)
     274                        ||  (tm->tm_hour < 1)
     275                        ||  (tm->tm_hour > 12))
     276                        return NULL;
     277                    if (    (t = parse_string(s, "am")) != NULL
     278                        ||  (t = parse_string(s, __libc_gLocaleTime.am)) != NULL)
     279                    {
     280                        if (tm->tm_hour == 12)
     281                            tm->tm_hour = 0;
     282                    }
     283                    else if (   (t = parse_string(s, "pm")) != NULL
     284                             || (t = parse_string(s, __libc_gLocaleTime.pm)) != NULL)
     285                    {
     286                        if (tm->tm_hour != 12)
     287                            tm->tm_hour += 12;
     288                    }
     289                    else
     290                        return NULL;
     291                    s = t;
     292                    break;
     293
     294                case 'r': /* HH:MM:SS am/pm */
     295                    RECURSE("%I:%M:%S %p");
     296                    break;
     297
     298                case 'R': /* HH:MM */
     299                    RECURSE("%H:%M");
     300                    break;
     301
     302                case 'S': /* Seconds (00-61(?)) */
     303                    NUMBER(&tm->tm_sec, 0, 61, 0, 2);
     304                    mask |= MASK_SECOND;
     305                    break;
     306
     307                case 't': /* Tabulation */
     308                    if (*s != '\t')
     309                        return NULL;
     310                    ++s;
     311                    break;
     312
     313                case 'T': /* HH:MM:SS */
     314                    RECURSE("%H:%M:%S");
     315                    break;
     316
     317                case 'w': /* Weekday (0-6), 0 = Sunday */
     318                    NUMBER(&tm->tm_wday, 0, 6, 0, 1);
     319                    mask |= MASK_WEEKDAY;
     320                    break;
     321
     322                case 'U': /* Week number (0-53), 0 = Sunday */
     323                    NUMBER(&week, 0, 53, 0, 2);
     324                    mask |= MASK_WEEKS;
     325                    break;
     326
     327                case 'W': /* Week number (0-53), 0 = Monday */
     328                    NUMBER(&week, 0, 53, 0, 2);
     329                    mask |= MASK_WEEKM;
     330                    break;
     331
     332                case 'x':
     333                    RECURSE(__libc_gLocaleTime.date_fmt);
     334                    break;
     335
     336                case 'X':
     337                    RECURSE(__libc_gLocaleTime.time_fmt);
     338                    break;
     339
     340                case 'y':
     341                    NUMBER(&tm->tm_year, 0, 99, 0, 2);
     342                    if (tm->tm_year < 69)
     343                        tm->tm_year += 100;
     344                    mask |= MASK_YEAR2;
     345                    break;
     346
     347                case 'Y':
     348                    NUMBER(&tm->tm_year, 1900, -1, -1900, 4);
     349                    mask |= MASK_YEAR4;
     350                    /* Ignore century since it was explicitely given */
     351                    century = -1;
     352                    mask &= ~MASK_CENTURY;
     353                    break;
     354
     355                default:
     356                    return NULL;
     357            }
     358        }
     359    }
     360
     361    if (mask & MASK_CENTURY)
     362    {
     363        if (!(mask & MASK_YEAR_ANY))
     364            tm->tm_year = 0;
     365        tm->tm_year = (century - 19) * 100 + (tm->tm_year % 100);
     366        mask |= MASK_YEAR4;
     367    }
     368
     369    /* We should know which fields are already correctly filled */
     370    if (retmask)
     371        mask |= *retmask;
     372
     373    if (    (mask & MASK_YEAR_ANY)
     374        &&  (mask & MASK_YEARDAY)
     375        &&  (mask & (MASK_MONTH | MASK_MONTHDAY)) != (MASK_MONTH | MASK_MONTHDAY))
     376    {
     377        /* Compute month and day of the month if any of them is not given */
     378        uint16_t const *md = _leap_year(tm->tm_year + 1900)
     379                           ? __libc_gauMonthDayLeap : __libc_gauMonthDayNonLeap;
     380        for (tm->tm_mon = 11; tm->tm_mon > 0 && tm->tm_yday < md[tm->tm_mon]; tm->tm_mon--)
     381            /* nothing */;
     382        tm->tm_mday = 1 + tm->tm_yday - md[tm->tm_mon];
     383        mask |= MASK_MONTH | MASK_MONTHDAY;
     384    }
     385
     386    if (!(mask & MASK_YEARDAY))
     387    {
     388        if (    (mask & MASK_WEEK_ANY)
     389            &&  (mask & MASK_WEEKDAY)
     390            &&  (mask & MASK_YEAR_ANY)
     391            &&  (tm->tm_year >= 70)
     392            &&  (tm->tm_year <= 206))
     393        {
     394            /* Compute day of the year given week number and weekday */
     395            int dow = (mask & MASK_WEEKM) == MASK_WEEKM ? 3 : 4;
     396            dow = (dow + __libc_gaiYearDay[tm->tm_year]) % 7;
     397            if (!dow)
     398                week--;
     399            dow = (tm->tm_wday - ((mask & MASK_WEEKM) == MASK_WEEKM) - dow) % 7;
     400            if (dow < 0)
     401                dow += 7;
     402            tm->tm_yday = week * 7 + dow;
     403            mask |= MASK_YEARDAY;
     404        }
     405        else if ((mask & MASK_YEAR_ANY) && (mask & MASK_MONTH) && (mask & MASK_MONTHDAY))
     406        {
     407            /* Compute year day from month and day of the month */
     408            uint16_t const *md = _leap_year(tm->tm_year + 1900)
     409                               ? __libc_gauMonthDayLeap : __libc_gauMonthDayNonLeap;
     410            tm->tm_yday = tm->tm_mday - 1 + md[tm->tm_mon];
     411            mask |= MASK_YEARDAY;
     412        }
     413    }
     414
     415    if (!(mask & MASK_WEEKDAY) && (mask & MASK_YEAR_ANY) && (mask & MASK_YEARDAY))
     416    {
     417        /* Compute day of the week if it was not given */
     418        if ((tm->tm_year < 70) || (tm->tm_year > 206))
     419            tm->tm_wday = 0; /* Unknown */
     420        else
     421        {
     422            int absday = __libc_gaiYearDay[tm->tm_year] + tm->tm_yday;
     423            /* 1st January 1970 was Thursday (4) */
     424            tm->tm_wday = ((4 + absday) % 7);
     425            mask |= MASK_WEEKDAY;
     426        }
     427    }
     428
     429    if (((mask & (MASK_WEEK_ANY | MASK_WEEKDAY | MASK_YEAR_ANY)) == (MASK_WEEK_ANY | MASK_WEEKDAY | MASK_YEAR_ANY))
     430        && ((mask & (MASK_MONTH | MASK_MONTHDAY)) != (MASK_MONTH | MASK_MONTHDAY)))
     431    {
     432        /* Compute month and day of the month given weekday and week number */
     433        uint16_t const *md = _leap_year(tm->tm_year + 1900)
     434                           ? __libc_gauMonthDayLeap : __libc_gauMonthDayNonLeap;
     435
     436        for (tm->tm_mon = 11; tm->tm_mon > 0 && tm->tm_yday < md[tm->tm_mon]; tm->tm_mon--)
     437            /* nothing */;
     438        tm->tm_mday = 1 + tm->tm_yday - md[tm->tm_mon];
     439        mask |= MASK_MONTH | MASK_MONTHDAY;
     440    }
     441
     442    /* Communicate to the caller which fields are filled, except fields
     443       that are not located inside the tm structure. */
     444    if (retmask)
     445        *retmask |= mask & ~(MASK_WEEKI | MASK_WEEKM | MASK_WEEKS | MASK_CENTURY);
     446
     447    return s;
    442448}
    443449
    444 char *_STD(strptime) (const char *buf, const char *format, struct tm *tm)
     450char *_STD(strptime)(const char *buf, const char *format, struct tm *tm)
    445451{
    446452    LIBCLOG_ENTER("buf=%p:{%s} format=%p:{%s} tm=%p:{.tm_sec=%d, .tm_min=%d, .tm_hour=%d, .tm_mday=%d, .tm_mon=%d, .tm_year=%d, .tm_wday=%d, .tm_yday=%d, .tm_isdst=%d, .tm_gmtoff=%d, .tm_zone=%p:{%s}}\n",
  • trunk/libc/src/libc/time/time.c

    r2254 r2909  
    1 /* time.c (emx+gcc) -- Copyright (c) 1990-1995 by Eberhard Mattes */
     1/* $Id: $ */
     2/** @file
     3 *
     4 * kLIBC - time().
     5 *
     6 * Copyright (c) 1990-1995 by Eberhard Mattes
     7 *
     8 *
     9 * This file is part of kLIBC.
     10 *
     11 * kLIBC is free software; you can redistribute it and/or modify
     12 * it under the terms of the GNU Lesser General Public License as published
     13 * by the Free Software Foundation; either version 2 of the License, or
     14 * (at your option) any later version.
     15 *
     16 * kLIBC is distributed in the hope that it will be useful,
     17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19 * GNU Lesser General Public License for more details.
     20 *
     21 * You should have received a copy of the GNU Lesser General Public License
     22 * along with kLIBC; if not, write to the Free Software
     23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     24 *
     25 */
    226
    327#include "libc-alias.h"
     28#include <time.h>
    429#include <sys/timeb.h>
    5 #include <time.h>
    630#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME
    7 #include <InnoTekLIBC/logstrict.h>
     31#include <klibc/logstrict.h>
    832
    9 time_t _STD(time) (time_t *t)
     33time_t _STD(time)(time_t *t)
    1034{
    1135    LIBCLOG_ENTER("t=%p\n", (void *)t);
  • trunk/libc/src/libc/time/times.c

    r2254 r2909  
    1 /* times.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes */
     1/* $Id: $ */
     2/** @file
     3 *
     4 * kLIBC - times().
     5 *
     6 * Copyright (c) 1990-1996 by Eberhard Mattes
     7 * Copyright (c) 2004-2006 knut st. osmundsen <bird-srcspam@anduin.net>
     8 *
     9 *
     10 * This file is part of kLIBC.
     11 *
     12 * kLIBC is free software; you can redistribute it and/or modify
     13 * it under the terms of the GNU Lesser General Public License as published
     14 * by the Free Software Foundation; either version 2 of the License, or
     15 * (at your option) any later version.
     16 *
     17 * kLIBC is distributed in the hope that it will be useful,
     18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     20 * GNU Lesser General Public License for more details.
     21 *
     22 * You should have received a copy of the GNU Lesser General Public License
     23 * along with kLIBC; if not, write to the Free Software
     24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     25 *
     26 */
    227
    328#include "libc-alias.h"
     
    631#include <sys/times.h>
    732#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME
    8 #include <InnoTekLIBC/logstrict.h>
     33#include <klibc/logstrict.h>
    934
    10 /* Note: return value overflows */
    1135
     36/**
     37 * ...
     38 * @remark return value overflows
     39 */
    1240clock_t _STD(times)(struct tms *buffer)
    1341{
  • trunk/libc/src/libc/time/timetabs.c

    r903 r2909  
    1 /* timetabs.c (emx+gcc) -- Copyright (c) 1996 by Eberhard Mattes */
     1/* $Id: $ */
     2/** @file
     3 *
     4 * kLIBC - Time Tables.
     5 *
     6 * Copyright (c) 1996 by Eberhard Mattes
     7 * Copyright (c) 2004-2006 knut st. osmundsen <bird-srcspam@anduin.net>
     8 *
     9 *
     10 * This file is part of kLIBC.
     11 *
     12 * kLIBC is free software; you can redistribute it and/or modify
     13 * it under the terms of the GNU Lesser General Public License as published
     14 * by the Free Software Foundation; either version 2 of the License, or
     15 * (at your option) any later version.
     16 *
     17 * kLIBC is distributed in the hope that it will be useful,
     18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     20 * GNU Lesser General Public License for more details.
     21 *
     22 * You should have received a copy of the GNU Lesser General Public License
     23 * along with kLIBC; if not, write to the Free Software
     24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     25 *
     26 */
    227
     28/*******************************************************************************
     29*   Header Files                                                               *
     30*******************************************************************************/
     31#include "libc-alias.h"
     32#include <klibc/time.h>
    333#include <limits.h>
    4 #include <emx/time.h>
    534
    6 /* Day number, relative to 01-Jan-1970, of 01-Jan for the years 1900
    7    through 2059 */
    8 signed short const _year_day[_YEARS+1] =
     35
     36/*******************************************************************************
     37*   Global Variables                                                           *
     38*******************************************************************************/
     39/**
     40 * Day number, relative to 01-Jan-1970, of 01-Jan for the years 1900 through 2059.
     41 */
     42int16_t const __libc_gaiYearDay[_YEARS+1] =
    943{
    1044   -25567,-25202,-24837,-24472,-24107,-23741,-23376,-23011,-22646,-22280,  /* 1900 - 1909 */
     
    2761};
    2862
     63/**
     64 * Day number for non-leap years.
     65 * The day number is relative to 01-Jan, of day 01 for January through December.
     66 */
     67uint16_t const __libc_gauMonthDayNonLeap[] =
     68{
     69    0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, USHRT_MAX
     70};
    2971
    30 /* Day number, relative to 01-Jan, of day 01 for January through
    31    December. */
     72/**
     73 * Day number for leap years.
     74 * The day number is relative to 01-Jan, of day 01 for January through December.
     75 */
     76uint16_t const __libc_gauMonthDayLeap[] =
     77{
     78    0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, USHRT_MAX
     79};
    3280
    33 unsigned short const _month_day_non_leap[] =
    34   {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, USHRT_MAX};
    35 
    36 unsigned short const _month_day_leap[] =
    37   {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, USHRT_MAX};
  • trunk/libc/src/libc/time/timetabs_gen.c

    r2717 r2909  
    22/** @file
    33 *
    4  * Generate year table.
     4 * kLIBC - Build program for generating the year table.
    55 *
    6  * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
     6 * Copyright (c) 2006 knut st. osmundsen <bird-srcspam@anduin.net>
    77 *
    88 *
    9  * This file is part of Innotek LIBC.
     9 * This file is part of kLIBC.
    1010 *
    11  * Innotek LIBC is free software; you can redistribute it and/or modify
     11 * kLIBC is free software; you can redistribute it and/or modify
    1212 * it under the terms of the GNU Lesser General Public License as published
    1313 * by the Free Software Foundation; either version 2 of the License, or
    1414 * (at your option) any later version.
    1515 *
    16  * Innotek LIBC is distributed in the hope that it will be useful,
     16 * kLIBC is distributed in the hope that it will be useful,
    1717 * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1818 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     
    2020 *
    2121 * You should have received a copy of the GNU Lesser General Public License
    22  * along with Innotek LIBC; if not, write to the Free Software
     22 * along with kLIBC; if not, write to the Free Software
    2323 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    2424 *
     
    2626
    2727#include <stdio.h>
    28 #include "include/emx/time.h"
     28#include "include/klibc/time.h"
    2929
    3030int main()
  • trunk/libc/src/libc/time/tzset.c

    r2254 r2909  
    1 /* tzset.c (emx+gcc) -- Copyright (c) 1992-1996 by Kai Uwe Rommel */
    2 /*                      Copyright (c) 1996 by Eberhard Mattes */
    3 
     1/* $Id: $ */
     2/** @file
     3 *
     4 * kLIBC - Update time zone data.
     5 *
     6 * Copyright (c) 1992-1996 by Kai Uwe Rommel
     7 * Copyright (c) 1996 by Eberhard Mattes
     8 *
     9 * This file is part of kLIBC.
     10 *
     11 * kLIBC is free software; you can redistribute it and/or modify
     12 * it under the terms of the GNU Lesser General Public License as published
     13 * by the Free Software Foundation; either version 2 of the License, or
     14 * (at your option) any later version.
     15 *
     16 * kLIBC is distributed in the hope that it will be useful,
     17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19 * GNU Lesser General Public License for more details.
     20 *
     21 * You should have received a copy of the GNU Lesser General Public License
     22 * along with kLIBC; if not, write to the Free Software
     23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     24 *
     25 */
     26
     27
     28/*******************************************************************************
     29*   Header Files                                                               *
     30*******************************************************************************/
    431#include "libc-alias.h"
    532#include <stdlib.h>
     
    734#include <time.h>
    835#include <sys/timeb.h>
    9 #include <emx/time.h>
    10 #include <emx/syscalls.h>
     36#include <klibc/time.h>
    1137#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME
    12 #include <InnoTekLIBC/logstrict.h>
    13 
    14 int _STD(daylight) = 0;
    15 long _STD(timezone) = 0;
    16 char *_STD(tzname)[2] = {"UCT", ""};
    17 
    18 struct _tzinfo _tzi = {"UCT", "", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    19 
    20 
    21 /* Parse a decimal number.  Return a non-zero value if successful,
    22    zero on error. */
    23 
    24 static int dnum (int *dst, char **pp, int min, int max, int opt_sign,
    25                  int delim)
    26 {
    27   char *p;
    28   int n, sign, amax;
    29 
    30   p = *pp; n = 0; sign = 1;
    31 
    32   /* Optional sign. */
    33 
    34   if (opt_sign)
    35     {
    36       if (*p == '+')
     38#include <klibc/logstrict.h>
     39
     40
     41/**
     42 * Parse a decimal number.  Return a non-zero value if successful,
     43 * zero on error.
     44 */
     45static int dnum(int *dst, char **pp, int min, int max, int opt_sign, int delim)
     46{
     47    char *p = *pp;
     48    int n = 0;
     49    int sign = 1;
     50    int amax;
     51
     52    /* Optional sign. */
     53    if (opt_sign)
     54    {
     55         if (*p == '+')
     56            ++p;
     57        else if (*p == '-')
     58        {
     59            sign = -1;
     60            ++p;
     61        }
     62    }
     63
     64    /* There must be at least one digit. */
     65    if (*p < '0' || *p > '9')
     66        return 0;
     67
     68    /* Compute the maximum absolute value of the number.  This is used
     69       to detect overflow. */
     70    amax = max;
     71    if (-min > amax)
     72        amax = -min;
     73    do
     74    {
     75        n = n * 10 + *p - '0';
     76        if (n > amax)
     77            return 0;   /* Overflow */
    3778        ++p;
    38       else if (*p == '-')
    39         sign = -1, ++p;
    40     }
    41 
    42   /* There must be at least one digit. */
    43 
    44   if (!(*p >= '0' && *p <= '9'))
    45     return 0;
    46 
    47   /* Compute the maximum absolute value of the number.  This is used
    48      to detect overflow. */
    49 
    50   amax = max;
    51   if (-min > amax) amax = -min;
    52   do
    53     {
    54       n = n * 10 + *p - '0';
    55       if (n > amax) return 0;   /* Overflow */
    56       ++p;
    5779    } while (*p >= '0' && *p <= '9');
    5880
    59   /* Check the delimiter if DELIM is not -1. */
    60 
    61   if (delim != -1 && *p++ != delim)
    62     return 0;
    63 
    64   /* Apply the sign. */
    65 
    66   if (sign == -1)
    67     n = -n;
    68 
    69   /* Check the range. */
    70 
    71   if (n < min || n > max)
    72     return 0;
    73 
    74   /* Return the result. */
    75 
    76   *dst = n;
    77   *pp = p;
    78   return 1;
    79 }
    80 
    81 
    82 /* Copy a timezone name.  Return a non-zero value if successful, zero
    83    on error. */
    84 
    85 static int copy_tzname (char *dst, char **pp)
    86 {
    87   char *p;
    88   int i;
    89 
    90   p = *pp;
    91   i = 0;
    92 
    93   /* Skip the characters making up base timezone name */
    94   while ((p [i] >= 'A' && p [i] <= 'Z') || (p [i] >= 'a' && p [i] <= 'z'))
    95     i++;
    96 
    97   *pp = p + i;
    98   if (i > __MAX_TZ_STANDARD_LEN)
    99     i = __MAX_TZ_STANDARD_LEN;
    100   memcpy (dst, p, i);
    101   dst [i] = 0;
    102   return 1;
    103 }
    104 
    105 static int parse_delta (char **src, int *offset, int opt_sign)
    106 {
    107   int ofs = 0, sign = 1, temp;
    108 
    109   if (!dnum (&ofs, src, -23, 23, opt_sign, -1))
    110     return 0;
    111   if (ofs < 0)
    112     sign = -1, ofs = -ofs;
    113 
    114   ofs *= 60;
    115   if (**src == ':')            /* Minutes specified? */
    116     {
    117       (*src)++;
    118       if (!dnum (&temp, src, 0, 59, 0, -1))
    119         return 0;
     81    /* Check the delimiter if DELIM is not -1. */
     82    if (delim != -1 && *p++ != delim)
     83        return 0;
     84
     85    /* Apply the sign. */
     86    if (sign == -1)
     87        n = -n;
     88
     89    /* Check the range. */
     90    if (n < min || n > max)
     91        return 0;
     92
     93    /* Return the result. */
     94    *dst = n;
     95    *pp = p;
     96    return 1;
     97}
     98
     99
     100/**
     101 * Copy a timezone name.  Return a non-zero value if successful, zero on error.
     102 */
     103static int copy_tzname(char *dst, char **pp)
     104{
     105    char *p = *pp;
     106    int i = 0;
     107
     108    /* Skip the characters making up base timezone name */
     109    while (     (p[i] >= 'A' && p[i] <= 'Z')
     110           ||   (p[i] >= 'a' && p[i] <= 'z'))
     111        i++;
     112    *pp = p + i;
     113
     114    if (i > __MAX_TZ_STANDARD_LEN)
     115        i = __MAX_TZ_STANDARD_LEN;
     116    memcpy(dst, p, i);
     117    dst[i] = '\0';
     118    return 1;
     119}
     120
     121static int parse_delta(char **src, int *offset, int opt_sign)
     122{
     123    int ofs = 0;
     124    int sign = 1;
     125    int temp;
     126
     127    if (!dnum(&ofs, src, -23, 23, opt_sign, -1))
     128        return 0;
     129    if (ofs < 0)
     130    {
     131        sign = -1;
     132        ofs = -ofs;
     133    }
     134
     135    ofs *= 60;
     136    if (**src == ':')            /* Minutes specified? */
     137    {
     138        (*src)++;
     139        if (!dnum(&temp, src, 0, 59, 0, -1))
     140            return 0;
     141        ofs += temp;
     142    }
     143
     144    ofs *= 60;
     145    if (**src == ':')            /* Seconds specified? */
     146    {
     147        (*src)++;
     148        if (!dnum(&temp, src, 0, 59, 0, -1))
     149            return 0;
    120150      ofs += temp;
    121151    }
    122152
    123   ofs *= 60;
    124   if (**src == ':')            /* Seconds specified? */
    125     {
    126       (*src)++;
    127       if (!dnum (&temp, src, 0, 59, 0, -1))
    128         return 0;
    129       ofs += temp;
    130     }
    131 
    132   *offset = sign > 0 ? ofs : -ofs;
    133 
    134   return 1;
     153    *offset = sign > 0 ? ofs : -ofs;
     154    return 1;
    135155}
    136156
    137157static int parse_switchtime (char **src, int *m, int *w, int *d, int *t)
    138158{
    139   if (!dnum (m, src, 1, 12, 0, ',')
    140    || !dnum (w, src, -4, 4, 1, ',')
    141    || !dnum (d, src, *w ? 0 : 1, *w ? 6 : 31, 0, ',')
    142    || !dnum (t, src, 0, 86399, 0, ','))
    143     return 0;
    144 
    145   return 1;
     159    if (    !dnum(m, src, 1, 12, 0, ',')
     160        ||  !dnum(w, src, -4, 4, 1, ',')
     161        ||  !dnum(d, src, *w ? 0 : 1, *w ? 6 : 31, 0, ',')
     162        ||  !dnum(t, src, 0, 86399, 0, ','))
     163        return 0;
     164    return 1;
    146165}
    147166
     
    176195 *   KWT-4KWST,3,-1,0,7200,10,-1,0,10800,3600
    177196 */
    178 void _STD(tzset) (void)
    179 {
    180   LIBCLOG_ENTER("\n");
    181   struct _tzinfo ntz;
    182   struct timeb tb;
    183   char *p;
    184   int offset;
    185   time_t t_loc;
    186 
    187   p = getenv ("TZ");
    188   if (p == NULL || *p == 0)
    189     p = "UCT";                  /* Our best approximation :-) */
    190   LIBCLOG_MSG("TZ=%s\n", p);
    191 
    192   if (!copy_tzname (ntz.tzname, &p))
    193     LIBCLOG_ERROR_RETURN_VOID();
    194 
    195   if (*p == 0)
    196     offset = 0;                 /* TZ=XYZ is valid (in contrast to POSIX.1) */
    197   else if (!parse_delta (&p, &offset, 1))
    198     LIBCLOG_ERROR_RETURN_VOID();
    199 
    200   ntz.tz = offset;
    201 
    202   ntz.dst = 0;
    203   ntz.dstzname[0] = 0;
    204 
    205   if (*p != 0)
    206     {
    207       ntz.dst = 1;
    208       if (!copy_tzname (ntz.dstzname, &p))
     197void _STD(tzset)(void)
     198{
     199    LIBCLOG_ENTER("\n");
     200    struct _tzinfo ntz;
     201    char *p;
     202    int offset;
     203
     204    p = getenv("TZ");
     205    if (p == NULL || *p == 0)
     206        p = "UCT";                  /* Our best approximation :-) */
     207    LIBCLOG_MSG("TZ=%s\n", p);
     208
     209    if (!copy_tzname(ntz.tzname, &p))
    209210        LIBCLOG_ERROR_RETURN_VOID();
    210       if (*p == ',')
    211         {
    212           p++;
    213           /* Parse DST start date/time */
    214           if (!parse_switchtime (&p, &ntz.sm, &ntz.sw, &ntz.sd, &ntz.st))
     211
     212    if (*p == '\0')
     213        offset = 0;                 /* TZ=XYZ is valid (in contrast to POSIX.1) */
     214    else if (!parse_delta(&p, &offset, 1))
     215        LIBCLOG_ERROR_RETURN_VOID();
     216
     217    ntz.tz = offset;
     218    ntz.dst = 0;
     219    ntz.dstzname[0] = 0;
     220
     221    if (*p != '\0')
     222    {
     223        ntz.dst = 1;
     224        if (!copy_tzname(ntz.dstzname, &p))
    215225            LIBCLOG_ERROR_RETURN_VOID();
    216           if (!parse_switchtime (&p, &ntz.em, &ntz.ew, &ntz.ed, &ntz.et))
     226        if (*p == ',')
     227        {
     228            p++;
     229            /* Parse DST start date/time */
     230            if (!parse_switchtime(&p, &ntz.sm, &ntz.sw, &ntz.sd, &ntz.st))
     231                LIBCLOG_ERROR_RETURN_VOID();
     232            if (!parse_switchtime(&p, &ntz.em, &ntz.ew, &ntz.ed, &ntz.et))
     233                LIBCLOG_ERROR_RETURN_VOID();
     234            if (!dnum(&ntz.shift, &p, 0, 86400, 0, 0))
     235                LIBCLOG_ERROR_RETURN_VOID();
     236        }
     237        else if (*p == '\0')
     238        {
     239            /* VAC++ default values */
     240            ntz.sm = 4;  ntz.sw =  1; ntz.sd = 0; ntz.st = 3600;
     241            ntz.em = 10; ntz.ew = -1; ntz.ed = 0; ntz.et = 7200;
     242            ntz.shift = 3600;
     243        }
     244        else
     245        {
     246            /* TODO: POSIX.1 */
    217247            LIBCLOG_ERROR_RETURN_VOID();
    218           if (!dnum (&ntz.shift, &p, 0, 86400, 0, 0))
    219             LIBCLOG_ERROR_RETURN_VOID();
    220         }
    221       else if (*p == 0)
    222         {
    223           /* VAC++ default values */
    224           ntz.sm = 4;  ntz.sw =  1; ntz.sd = 0; ntz.st = 3600;
    225           ntz.em = 10; ntz.ew = -1; ntz.ed = 0; ntz.et = 7200;
    226           ntz.shift = 3600;
    227         }
    228       else
    229         {
    230           /* TODO: POSIX.1 */
    231           LIBCLOG_ERROR_RETURN_VOID();
    232         }
    233       _STD(daylight) = 1;
    234     }
    235   else
    236     _STD(daylight) = 0;
    237 
    238 
    239   /* TODO: Make this thread-safe! */
    240   _tzi = ntz;
    241   _STD(tzname)[0] = _tzi.tzname;
    242   _STD(tzname)[1] = _tzi.dstzname;
    243   _compute_dst_table ();
    244 
    245   __ftime (&tb);
    246   t_loc = tb.time;
    247 /*  _STD(daylight) = _loc2gmt (&tb.time, -1); */
    248   _STD(timezone) = _tzi.tz;
    249 
    250   _tzset_flag = 1;
    251   LIBCLOG_RETURN_MSG_VOID("ret void - _tzi={.tzname=\"%s\", .dstzname=\"%s\" .tz=%d, .dst=%d, .shift=%d, .sm=%d, .sw=%d, .sd=%d, .st=%d, .em=%d, .ew=%d, .ed=%d, .et=%d}\n",
    252                           ntz.tzname, ntz.dstzname, ntz.tz, ntz.dst, ntz.shift, ntz.sm, ntz.sw, ntz.sd, ntz.st, ntz.em, ntz.ew, ntz.ed, ntz.et);
    253 }
     248        }
     249        _STD(daylight) = 1;
     250    }
     251    else
     252        _STD(daylight) = 0;
     253
     254    /** @todo Make this thread-safe! */
     255    __libc_gTZInfo = ntz;
     256    _STD(tzname)[0] = __libc_gTZInfo.tzname;
     257    _STD(tzname)[1] = __libc_gTZInfo.dstzname;
     258    _compute_dst_table();
     259    _STD(timezone) = __libc_gTZInfo.tz;
     260    __libc_gfTZInfoOk = 1;
     261
     262    LIBCLOG_RETURN_MSG_VOID("ret void - __libc_gTZInfo={.tzname=\"%s\", .dstzname=\"%s\" .tz=%d, .dst=%d, .shift=%d, .sm=%d, .sw=%d, .sd=%d, .st=%d, .em=%d, .ew=%d, .ed=%d, .et=%d}\n",
     263                            ntz.tzname, ntz.dstzname, ntz.tz, ntz.dst, ntz.shift, ntz.sm, ntz.sw, ntz.sd, ntz.st, ntz.em, ntz.ew, ntz.ed, ntz.et);
     264}
Note: See TracChangeset for help on using the changeset viewer.