Changeset 2909
- Timestamp:
- Dec 26, 2006, 8:12:42 PM (19 years ago)
- 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 31 31 #include <sys/_types.h> 32 32 33 #if !defined(__ InnoTekLIBC_locale_h__)33 #if !defined(__klibc_locale_h__) 34 34 __BEGIN_DECLS 35 35 /** … … 77 77 } __libc_GLocaleWCtype; 78 78 __END_DECLS 79 #endif /* !__ InnoTekLIBC_locale_h__ */79 #endif /* !__klibc_locale_h__ */ 80 80 81 81 -
trunk/libc/include/emx/syscalls.h
r2907 r2909 194 194 //dead int __setsockopt (int handle, int level, int optname, __const__ void *optval, 195 195 //dead int optlen); 196 int __settime (const struct timeval *tp);196 //int __settime (const struct timeval *tp); 197 197 //dead int __shutdown (int handle, int how); 198 198 int __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 201 201 int (*pfnForkChild)(struct __libc_FileHandle *pFH, __LIBC_PFORKHANDLE pForkHandle, __LIBC_FORKOP enmOperation); 202 202 203 /** Non-Zero dummy for ensuring that we update all instances when adding new members. */ 204 int iDummy; 203 205 } __LIBC_FHOPS; 204 206 /** Pointer to file handle operations. */ -
trunk/libc/include/klibc/locale.h
r2899 r2909 2 2 /** @file 3 3 * 4 * Internal InnoTek LIBC header. 5 * Locale support implementation through OS/2 Unicode API. 4 * kLIBC - Internal locale header. 6 5 * 7 6 * Copyright (c) 2003 InnoTek Systemberatung GmbH 8 * Copyright (c) 2003-200 4knut st. osmundsen <bird-srcspam@anduin.net>9 * 10 * 11 * This file is part of InnoTekLIBC.12 * 13 * InnoTekLIBC is free software; you can redistribute it and/or modify14 * it under the terms of the GNU General Public License as published by15 * the Free Software Foundation; either version 2 of the License, or7 * 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 16 15 * (at your option) any later version. 17 16 * 18 * InnoTekLIBC is distributed in the hope that it will be useful,17 * kLIBC is distributed in the hope that it will be useful, 19 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 19 * 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 License24 * along with InnoTekLIBC; if not, write to the Free Software20 * 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 25 24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 26 25 * 27 26 */ 28 27 29 #ifndef __ InnoTekLIBC_locale_h__30 #define __ InnoTekLIBC_locale_h__28 #ifndef __klibc_locale_h__ 29 #define __klibc_locale_h__ 31 30 32 31 #include <sys/cdefs.h> … … 35 34 #ifdef __OS2__ 36 35 # include <uconv.h> 36 #endif 37 #ifdef __CTYPE_H_ 38 # error "klibc/locale.h must be included *before* ctype.h!" 37 39 #endif 38 40 … … 363 365 __END_DECLS 364 366 365 #endif /* __SYS_LOCALE_H__ */366 367 #endif 368 -
trunk/libc/include/klibc/logstrict.h
r2906 r2909 284 284 /** Backend IO APIs. */ 285 285 #define __LIBC_LOG_GRP_BACK_IO 26 286 /** Backend Time APIs. */ 287 #define __LIBC_LOG_GRP_BACK_TIME 26 /** @todo fixme */ 286 288 /** Backend OS/2 Files (the file handle class). */ 287 289 #define __LIBC_LOG_GRP_BACK_OS2FILE 26 -
trunk/libc/src/kNIX/kNIX.h
r2905 r2909 43 43 #include <string.h> 44 44 #include <signal.h> 45 #include <process.h> 45 46 #include <sys/builtin.h> 47 #include <sys/dirent.h> 46 48 #include <sys/fmutex.h> 47 49 #include <sys/fcntl.h> -
trunk/libc/src/kNIX/os2/__settime.c
r2732 r2909 18 18 dst->seconds = t % 60; t /= 60; 19 19 dst->minutes = t % 60; t /= 60; 20 dst->hours = t % 24; t /= 24;20 dst->hours = t % 24; t /= 24; 21 21 22 22 /* 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! */ 16 33 #include "b_signal.h" 17 34 #include "b_process.h" 18 35 #include <emx/syscalls.h> 19 36 #include <InnoTekLIBC/sharedpm.h> 20 #include <InnoTekLIBC/backend.h>21 37 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_PROCESS 22 #include < InnoTekLIBC/logstrict.h>38 #include <klibc/logstrict.h> 23 39 #include "syscalls.h" 24 40 -
trunk/libc/src/kNIX/os2/b_dir.c
r2739 r2909 1 /* $Id$ */ 1 /* $Id$ *//* $Id$ */ 2 2 /** @file 3 3 * 4 * LIBC SYS Backend - Directory Access.5 * 6 * Copyright (c) 200 5 knut st. osmundsen <bird@anduin.net>7 * 8 * 9 * This file is part of InnoTekLIBC.10 * 11 * InnoTekLIBC is free software; you can redistribute it and/or modify12 * it under the terms of the GNU General Public License as published by13 * the Free Software Foundation; either version 2 of the License, or4 * 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 14 14 * (at your option) any later version. 15 15 * 16 * InnoTekLIBC is distributed in the hope that it will be useful,16 * kLIBC is distributed in the hope that it will be useful, 17 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 18 * 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 License22 * along with InnoTekLIBC; if not, write to the Free Software19 * 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 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 24 * 25 25 */ 26 27 26 28 27 /******************************************************************************* 29 28 * Header Files * 30 29 *******************************************************************************/ 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" 44 31 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_BACK_IO 45 32 #include <InnoTekLIBC/logstrict.h> 46 #include <InnoTekLIBC/libc.h>47 33 48 34 … … 50 36 * Internal Functions * 51 37 *******************************************************************************/ 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); 38 static int dirClose(__LIBC_PFH pFH); 39 static int dirRead(__LIBC_PFH pFH, void *pvBuf, size_t cbRead, size_t *pcbRead); 40 static int dirWrite(__LIBC_PFH pFH, const void *pvBuf, size_t cbWrite, size_t *pcbWritten); 41 static int dirSetSize(__LIBC_PFH pFH, off_t cbFile, int fZero); 42 static int dirDuplicate(__LIBC_PFH pFH, int *pfhNew); 43 static int dirFileControl(__LIBC_PFH pFH, int iRequest, int iArg, int *prc); 44 static int dirIOControl(__LIBC_PFH pFH, int iIOControl, int iArg, int *prc); 45 static int dirSeek(__LIBC_PFH pFH, off_t off, int iMethod, off_t *poffNew); 59 46 static 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);47 static int dirForkChild(__LIBC_PFH pFH, __LIBC_PFORKHANDLE pForkHandle, __LIBC_FORKOP enmOperation); 61 48 static int dirOpen(const char *pszNativePath, unsigned fLibc, int *pfh, __LIBC_PFHDIR *ppFHDir); 62 49 … … 74 61 dirRead, 75 62 dirWrite, 63 dirSeek, 64 dirSetSize, 76 65 dirDuplicate, 77 66 dirFileControl, 78 67 dirIOControl, 79 //dirSeek,80 68 dirSelect, 81 69 NULL, 82 dirForkChild 70 dirForkChild, 71 42 83 72 }; 84 73 … … 90 79 * @returns OS/2 error code or negated errno on failure. 91 80 * @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 */ 82 static int dirClose(__LIBC_PFH pFH) 95 83 { 96 84 __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); 98 86 99 87 if (pFHDir->hDir != HDIR_CREATE) … … 126 114 * @returns OS/2 error code or negated errno on failure. 127 115 * @param pFH Pointer to the handle structure to operate on. 128 * @param fh It's associated filehandle.129 116 * @param pvBuf Pointer to the buffer to read into. 130 117 * @param cbRead Number of bytes to read. 131 118 * @param pcbRead Where to store the count of bytes actually read. 132 119 */ 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);120 static 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); 136 123 if (cbRead >= sizeof(struct dirent)) 137 124 { … … 152 139 * @returns OS/2 error code or negated errno on failure. 153 140 * @param pFH Pointer to the handle structure to operate on. 154 * @param fh It's associated filehandle.155 141 * @param pvBuf Pointer to the buffer which contains the data to write. 156 142 * @param cbWrite Number of bytes to write. 157 143 * @param pcbWritten Where to store the count of bytes actually written. 158 144 */ 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);145 static 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); 162 148 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 */ 161 static int dirSetSize(__LIBC_PFH pFH, off_t cbFile, int fZero) 162 { 163 return -EOPNOTSUPP; 163 164 } 164 165 … … 167 168 * @returns 0 on success, OS/2 error code on failure. 168 169 * @param pFH Pointer to the handle structure to operate on. 169 * @param fh It's associated filehandle.170 170 * @param pfhNew Where to store the duplicate filehandle. 171 171 * The input value describe how the handle is to be … … 175 175 * value will be closed. 176 176 */ 177 static int dirDuplicate(__LIBC_PFH pFH, int fh, int*pfhNew)177 static int dirDuplicate(__LIBC_PFH pFH, int *pfhNew) 178 178 { 179 179 /** @todo */ … … 186 186 * @returns OS/2 error code or negated errno on failure. 187 187 * @param pFH Pointer to the handle structure to operate on. 188 * @param fh It's associated filehandle.189 188 * @param iRequest Which file file descriptior request to perform. 190 189 * @param iArg Argument which content is specific to each … … 193 192 * returned to the caller. 194 193 */ 195 static int dirFileControl(__LIBC_PFH pFH, int fh, intiRequest, 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);194 static 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); 198 197 LIBCLOG_ERROR_RETURN_INT(-EOPNOTSUPP); 199 198 } … … 204 203 * @returns OS/2 error code or negated errno on failure. 205 204 * @param pFH Pointer to the handle structure to operate on. 206 * @param fh It's associated filehandle.207 205 * @param iIOControl Which I/O control operation to perform. 208 206 * @param iArg Argument which content is specific to each … … 211 209 * returned to the caller. 212 210 */ 213 static int dirIOControl(__LIBC_PFH pFH, int fh, intiIOControl, 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);211 static 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); 216 214 LIBCLOG_ERROR_RETURN_INT(-EOPNOTSUPP); 217 215 } … … 223 221 * @returns OS/2 error code or negated errno on failure. 224 222 * @param pFH Pointer to the handle structure to operate on. 225 * @param fh It's associated filehandle.226 223 * @param off The offset to seek. The meaning depends on SEEK_. 227 224 * @param iMethod The seek method, any of the SEEK_* macros. 228 225 * @param poffNew Where to store the new file offset. 229 226 */ 230 static int dirSeek(__LIBC_PFH pFH, int fh,off_t off, int iMethod, off_t *poffNew)227 static int dirSeek(__LIBC_PFH pFH, off_t off, int iMethod, off_t *poffNew) 231 228 { 232 229 /** @todo Implement reading and seeking. */ … … 264 261 * @returns OS/2 error code or negated errno on failure. 265 262 * @param pFH Pointer to the handle structure to operate on. 266 * @param fh It's associated filehandle.267 263 * @param pForkHandle The fork handle. 268 264 * @param enmOperation The fork operation. 269 265 */ 270 static int dirForkChild(__LIBC_PFH pFH, int fh,__LIBC_PFORKHANDLE pForkHandle, __LIBC_FORKOP enmOperation)266 static int dirForkChild(__LIBC_PFH pFH, __LIBC_PFORKHANDLE pForkHandle, __LIBC_FORKOP enmOperation) 271 267 { 272 268 switch (enmOperation) … … 309 305 unsigned uCurEntry = pFHDir->uCurEntry; 310 306 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); 312 308 } 313 309 break; … … 463 459 */ 464 460 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); 466 462 467 463 LIBCLOG_MSG("pFHDir=%p:{.hDir=%#lx, .fType=%d, .cFiles=%ld, .cbBuf=%#x, .uCurEntry=%d} fh=%d\n", … … 536 532 * @returns Negative error code (errno.h) on failure. 537 533 * 538 * @param fh The file handle of an open directory.539 534 * @param pvBuf Where to store the directory entries. 540 535 * The returned data is a series of dirent structs with … … 620 615 if (fMayHaveEAs) 621 616 { 622 if (!__libc_gfNoUnix) 623 { 624 /** @todo */ 625 /** @todo */ 626 fMayHaveEAs = 0; 627 } 628 else 629 fMayHaveEAs = 0; 617 /** @todo */ 618 fMayHaveEAs = 0; 630 619 } 631 620 if (!fMayHaveEAs) -
trunk/libc/src/kNIX/os2/b_fsDirChangeRoot.c
r2732 r2909 29 29 * Header Files * 30 30 *******************************************************************************/ 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 37 33 #include <InnoTekLIBC/logstrict.h> 38 34 … … 70 66 memcpy(__libc_gszUnixRoot, &szNativePath[0], cch + 1); 71 67 __libc_gcchUnixRoot = cch; 72 __libc_gfNoUnix = 0;73 68 __libc_gfInUnixTree = 0; /** @todo logic for correct __libc_gfInUnixTree update in chroot() operation. */ 74 69 } -
trunk/libc/src/kNIX/os2/syscalls.h
r2739 r2909 35 35 36 36 #define XUSHORT(x) (*(USHORT *)&(x)) 37 38 /* Maximum number of heap objects (16 = 512 / 32). */39 40 #define CFG_KNIX_MAX_HEAP_OBJS 1641 37 42 38 EXTERN unsigned _sys_uflags INIT (0); -
trunk/libc/src/libc/app/setenv.c
r2254 r2909 35 35 #include <errno.h> 36 36 #include <emx/startup.h> 37 #include < emx/time.h> /* _tzset_flag */38 #define __LIBC_LOG_GROUP 39 #include < InnoTekLIBC/logstrict.h>37 #include <klibc/time.h> 38 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_ENV 39 #include <klibc/logstrict.h> 40 40 41 41 … … 73 73 LIBCLOG_RETURN_INT(-1); 74 74 } 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; 76 79 77 80 /* BSD Compatability. */ -
trunk/libc/src/libc/time/Makefile.kmk
r2908 r2909 47 47 $(PATH_LIBC_SRC)/libc/time/time.c \ 48 48 $(PATH_LIBC_SRC)/libc/time/times.c \ 49 $(PATH_LIBC_SRC)/libc/time/timedata.c \ 49 50 $(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 52 52 53 53 # 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 3 28 #include "libc-alias.h" 4 29 #include <time.h> 5 #include < emx/time.h>30 #include <klibc/time.h> 6 31 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME 7 #include < InnoTekLIBC/logstrict.h>32 #include <klibc/logstrict.h> 8 33 9 34 char *_STD(ctime)(const time_t *t) … … 33 58 LIBCLOG_ERROR_RETURN_P(NULL); 34 59 } 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 */ 2 27 3 28 #include "libc-alias.h" 4 29 #include <sys/timeb.h> 5 30 #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! 8 33 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME 9 #include < InnoTekLIBC/logstrict.h>34 #include <klibc/logstrict.h> 10 35 11 36 void _STD(ftime)(struct timeb *ptr) … … 13 38 LIBCLOG_ENTER("ptr=%p\n", (void *)ptr); 14 39 15 if (!_ tzset_flag)40 if (!__libc_gfTZInfoOk) 16 41 tzset(); 17 42 … … 20 45 t_loc = ptr->time; 21 46 ptr->dstflag = _loc2gmt(&ptr->time, -1); 22 ptr->timezone = _ tzi.tz / 60;47 ptr->timezone = __libc_gTZInfo.tz / 60; 23 48 24 49 LIBCLOG_RETURN_MSG_VOID("ptr=%p:{.time=%ld, .millitm=%u, .timezone=%d, .dstflag=%d}\n", -
trunk/libc/src/libc/time/gettimeofday.c
r2908 r2909 5 5 #include <time.h> 6 6 #include <sys/time.h> 7 #include < emx/time.h>7 #include <klibc/time.h> 8 8 #include <emx/syscalls.h> 9 9 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME 10 #include < InnoTekLIBC/logstrict.h>10 #include <klibc/logstrict.h> 11 11 12 12 int _STD(gettimeofday)(struct timeval *tp, struct timezone *tzp) … … 17 17 int dst; 18 18 19 if (!_ tzset_flag)19 if (!__libc_gfTZInfoOk) 20 20 tzset(); 21 21 __ftime(&tb); … … 29 29 if (tzp != NULL) 30 30 { 31 tzp->tz_minuteswest = _ tzi.tz / 60;31 tzp->tz_minuteswest = __libc_gTZInfo.tz / 60; 32 32 tzp->tz_dsttime = dst; 33 33 } … … 45 45 (void *)tzp, tzp->tz_minuteswest, tzp->tz_dsttime); 46 46 } 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 */ 2 27 3 28 #include "libc-alias.h" … … 5 30 #include <time.h> 6 31 #include <stdint.h> 7 #include < InnoTekLIBC/thread.h>8 #include < emx/time.h>32 #include <klibc/thread.h> 33 #include <klibc/time.h> 9 34 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME 10 #include < InnoTekLIBC/logstrict.h>35 #include <klibc/logstrict.h> 11 36 12 37 … … 37 62 38 63 { 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]. */ 40 65 int hi = _YEARS - 1; 41 if ((int)_ year_day[hi] < days)66 if ((int)__libc_gaiYearDay[hi] < days) 42 67 LIBCLOG_ERROR_RETURN_P(NULL); 43 else if ((int)_ year_day[0] > days)68 else if ((int)__libc_gaiYearDay[0] > days) 44 69 LIBCLOG_ERROR_RETURN_P(NULL); 45 70 else … … 50 75 { 51 76 i = (lo + hi) / 2; 52 if (_ year_day[i] > days)77 if (__libc_gaiYearDay[i] > days) 53 78 hi = i - 1; 54 else if (_ year_day[i+1] <= days)79 else if (__libc_gaiYearDay[i+1] <= days) 55 80 lo = i + 1; 56 81 else … … 58 83 } 59 84 dst->tm_year = i; 60 days -= _ year_day[i];85 days -= __libc_gaiYearDay[i]; 61 86 dst->tm_yday = days; 62 87 } … … 65 90 { 66 91 int i; 67 const unsigned short *p;92 uint16_t const *p; 68 93 69 94 p = (_leap_year (dst->tm_year + 1900) 70 ? _ month_day_leap : _month_day_non_leap);95 ? __libc_gauMonthDayLeap : __libc_gauMonthDayNonLeap); 71 96 for (i = 0; (int)days >= p[i+1]; ++i) 72 97 ; … … 99 124 pTm->tm_wday, pTm->tm_yday, pTm->tm_isdst, /*pTm->tm_gmtoff*/-2, /*pTm->tm_zone*/(void *)NULL, /*pTm->tm_zone*/""); 100 125 } 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 *******************************************************************************/ 3 30 #include <time.h> 4 31 #include <limits.h> 5 32 #include <assert.h> 6 #include <emx/time.h> 7 33 #include <klibc/time.h> 34 35 /******************************************************************************* 36 * Defined Constants And Macros * 37 *******************************************************************************/ 8 38 /* Return true iff adding A to T does not overflow or underflow time_t. 9 39 (Correct but not fast!!!) */ … … 15 45 || ((a) < 0 && (t) > 0 && (a) + (t) > (a)) ) 16 46 47 /******************************************************************************* 48 * Structures and Typedefs * 49 *******************************************************************************/ 17 50 struct _dstswitch 18 51 { 19 time_t time; /* UTC */20 int shift;52 time_t time; /* UTC */ 53 int shift; 21 54 }; 22 55 23 static struct _dstswitch _dstsw[2*_YEARS+2] = {{TIME_T_MIN, 0}, {TIME_T_MAX, 0}}; 56 /******************************************************************************* 57 * Global Variables * 58 *******************************************************************************/ 59 static struct _dstswitch g_aDstSwitches[2*_YEARS+2] = 60 { 61 { TIME_T_MIN, 0 }, 62 { TIME_T_MAX, 0 } 63 }; 24 64 static int _dstsw_count = 2; 25 65 26 66 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 */ 70 static 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 102 void _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 183 static 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]; 171 210 } 172 211 … … 176 215 applies or not. */ 177 216 178 int _gmt2loc 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;217 int _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; 187 226 } 188 227 … … 195 234 * @param p The time to convert. 196 235 */ 197 int _gmt2loc64 236 int _gmt2loc64(time64_t *p) 198 237 { 199 238 struct _dstswitch *sw; 200 sw = find_switch 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) 203 242 return -1; 204 243 *p = t; … … 207 246 208 247 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 */ 254 int _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 */ 284 325 } 285 326 } … … 304 345 /* Our caller says that *P is specified as DST. Compute UTC 305 346 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) 309 349 return -1; 310 sw = find_switch 350 sw = find_switch(x); 311 351 *p = x; 312 352 return sw->shift != 0; … … 317 357 Compute UTC from *P, assuming that daylight saving does not 318 358 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) 322 361 return -1; 323 sw = find_switch 362 sw = find_switch(x); 324 363 *p = x; 325 364 return sw->shift != 0; … … 329 368 /* Our caller does not know whether *P is specified as DST or 330 369 standard time. Try to find out. First try DST. */ 331 332 370 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 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); 337 375 if (sw->shift != 0) 338 376 { … … 343 381 } 344 382 345 x = *p + _ tzi.tz;346 if (!(_ tzi.tz > 0 ? x < *p : x > *p))347 { 348 sw = find_switch 383 x = *p + __libc_gTZInfo.tz; 384 if (!(__libc_gTZInfo.tz > 0 ? x < *p : x > *p)) 385 { 386 sw = find_switch(x); 349 387 if (sw->shift == 0) 350 388 { … … 356 394 357 395 if (count != 2) 358 return -1; 396 return -1; /* Overflow */ 359 397 360 398 /* Assume that DST does not apply in the gap. This makes moving … … 362 400 from above. The advantage of this choice is that ftime() 363 401 works correctly in the gap if the clock is not adjusted. */ 364 365 *p += _tzi.tz; 402 *p += __libc_gTZInfo.tz; 366 403 return 0; /* Not DST */ 367 404 } 368 405 } 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 */ 2 27 3 28 #include "libc-alias.h" 4 29 #include <time.h> 5 #include < InnoTekLIBC/thread.h>6 #include < emx/time.h>30 #include <klibc/time.h> 31 #include <klibc/thread.h> 7 32 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME 8 #include < InnoTekLIBC/logstrict.h>33 #include <klibc/logstrict.h> 9 34 10 35 struct tm *_localtime64_r(const time64_t *t, struct tm *dst) 11 36 { 12 37 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) 14 39 tzset(); 15 40 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 */ 2 27 3 28 #include "libc-alias.h" 4 29 #include <time.h> 5 30 #include <limits.h> 6 #include < emx/time.h>31 #include <klibc/time.h> 7 32 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME 8 #include < InnoTekLIBC/logstrict.h>33 #include <klibc/logstrict.h> 9 34 10 time_t _STD(mktime) (struct tm *t) 35 36 time_t _STD(mktime)(struct tm *t) 11 37 { 12 38 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", … … 33 59 int dst; 34 60 35 if (!_ tzset_flag)61 if (!__libc_gfTZInfoOk) 36 62 tzset(); 37 63 38 64 /* mktime() requires that tm_mon is in range. The other members 39 65 are not restricted. */ 40 41 66 if (t->tm_mon < 0) 42 67 { … … 44 69 as the results are implementation-defined for negative 45 70 numbers. */ 46 47 71 t->tm_year -= 1 + ((-t->tm_mon) / 12); 48 72 t->tm_mon = 12 - ((-t->tm_mon) % 12); … … 73 97 74 98 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 */ 103 int _day(int year, int month, int day) 78 104 { 79 105 int result; … … 102 128 x = t->tm_sec 103 129 + 60 * t->tm_min 104 + 60 * 60 * t->tm_hour;130 + 60 * 60 * t->tm_hour; 105 131 106 132 r += x; -
trunk/libc/src/libc/time/settimeofday.c
r2908 r2909 5 5 #include <sys/time.h> 6 6 #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! */ 9 9 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME 10 #include < InnoTekLIBC/logstrict.h>10 #include <klibc/logstrict.h> 11 11 12 12 int _STD(settimeofday)(const struct timeval *tp, const struct timezone *tzp) … … 23 23 LIBCLOG_ERROR_RETURN(-1, "ret -1 - tzp is NULL!\n"); 24 24 } 25 if (!_ tzset_flag)25 if (!__libc_gfTZInfoOk) 26 26 tzset(); 27 27 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 */ 18 28 19 29 #define __INTERNAL_DEFS … … 23 33 #include <time.h> 24 34 #include <limits.h> 25 #include <InnoTekLIBC/locale.h>26 #include <emx/time.h>27 35 #include <sys/builtin.h> 36 #include <klibc/locale.h> 37 #include <klibc/time.h> 28 38 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME 29 #include < InnoTekLIBC/logstrict.h>39 #include <klibc/logstrict.h> 30 40 31 41 #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) 36 48 #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) 41 55 #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) 46 62 #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) 51 69 #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 77 static 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 88 static 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 109 static 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 133 static 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 146 size_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) 141 161 { 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; 264 296 } 265 else if (!CHK_MBCS_PREFIX (&__libc_GLocaleCtype, c, i)) 266 CHR (c); 267 else 297 298 if (size) 268 299 { 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); 274 302 } 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 *******************************************************************************/ 29 32 #define __INTERNAL_DEFS 30 33 #include "libc-alias.h" … … 32 35 #include <string.h> 33 36 #include <time.h> 34 #include < InnoTekLIBC/locale.h>37 #include <klibc/locale.h> 35 38 #include <ctype.h> 36 #include < emx/time.h>39 #include <klibc/time.h> 37 40 #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 *******************************************************************************/ 41 47 #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 61 static 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 78 static 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 90 static 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 } 43 106 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 109 static const char *parse_fmt(const char *s, const char *f, struct tm *tm, unsigned *retmask) 56 110 { 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; 113 116 114 117 #define MASK_CENTURY 0x00000001 … … 128 131 #define MASK_SECOND 0x00000800 129 132 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 (¢ury, 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(¢ury, 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; 442 448 } 443 449 444 char *_STD(strptime) 450 char *_STD(strptime)(const char *buf, const char *format, struct tm *tm) 445 451 { 446 452 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 */ 2 26 3 27 #include "libc-alias.h" 28 #include <time.h> 4 29 #include <sys/timeb.h> 5 #include <time.h>6 30 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME 7 #include < InnoTekLIBC/logstrict.h>31 #include <klibc/logstrict.h> 8 32 9 time_t _STD(time) 33 time_t _STD(time)(time_t *t) 10 34 { 11 35 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 */ 2 27 3 28 #include "libc-alias.h" … … 6 31 #include <sys/times.h> 7 32 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME 8 #include < InnoTekLIBC/logstrict.h>33 #include <klibc/logstrict.h> 9 34 10 /* Note: return value overflows */11 35 36 /** 37 * ... 38 * @remark return value overflows 39 */ 12 40 clock_t _STD(times)(struct tms *buffer) 13 41 { -
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 */ 2 27 28 /******************************************************************************* 29 * Header Files * 30 *******************************************************************************/ 31 #include "libc-alias.h" 32 #include <klibc/time.h> 3 33 #include <limits.h> 4 #include <emx/time.h>5 34 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 */ 42 int16_t const __libc_gaiYearDay[_YEARS+1] = 9 43 { 10 44 -25567,-25202,-24837,-24472,-24107,-23741,-23376,-23011,-22646,-22280, /* 1900 - 1909 */ … … 27 61 }; 28 62 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 */ 67 uint16_t const __libc_gauMonthDayNonLeap[] = 68 { 69 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, USHRT_MAX 70 }; 29 71 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 */ 76 uint16_t const __libc_gauMonthDayLeap[] = 77 { 78 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, USHRT_MAX 79 }; 32 80 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 2 2 /** @file 3 3 * 4 * Generate year table.4 * kLIBC - Build program for generating the year table. 5 5 * 6 * Copyright (c) 200 3knut st. osmundsen <bird-srcspam@anduin.net>6 * Copyright (c) 2006 knut st. osmundsen <bird-srcspam@anduin.net> 7 7 * 8 8 * 9 * This file is part of InnotekLIBC.9 * This file is part of kLIBC. 10 10 * 11 * InnotekLIBC is free software; you can redistribute it and/or modify11 * kLIBC is free software; you can redistribute it and/or modify 12 12 * it under the terms of the GNU Lesser General Public License as published 13 13 * by the Free Software Foundation; either version 2 of the License, or 14 14 * (at your option) any later version. 15 15 * 16 * InnotekLIBC is distributed in the hope that it will be useful,16 * kLIBC is distributed in the hope that it will be useful, 17 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the … … 20 20 * 21 21 * You should have received a copy of the GNU Lesser General Public License 22 * along with InnotekLIBC; if not, write to the Free Software22 * along with kLIBC; if not, write to the Free Software 23 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 24 * … … 26 26 27 27 #include <stdio.h> 28 #include "include/ emx/time.h"28 #include "include/klibc/time.h" 29 29 30 30 int 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 *******************************************************************************/ 4 31 #include "libc-alias.h" 5 32 #include <stdlib.h> … … 7 34 #include <time.h> 8 35 #include <sys/timeb.h> 9 #include <emx/time.h> 10 #include <emx/syscalls.h> 36 #include <klibc/time.h> 11 37 #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 */ 45 static 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 */ 37 78 ++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 used48 to detect overflow. */49 50 amax = max;51 if (-min > amax) amax = -min;52 do53 {54 n = n * 10 + *p - '0';55 if (n > amax) return 0; /* Overflow */56 ++p;57 79 } while (*p >= '0' && *p <= '9'); 58 80 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 */ 103 static 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 121 static 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; 120 150 ofs += temp; 121 151 } 122 152 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; 135 155 } 136 156 137 157 static int parse_switchtime (char **src, int *m, int *w, int *d, int *t) 138 158 { 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; 146 165 } 147 166 … … 176 195 * KWT-4KWST,3,-1,0,7200,10,-1,0,10800,3600 177 196 */ 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)) 197 void _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)) 209 210 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)) 215 225 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 */ 217 247 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.