diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 5b8e7ae6d..87e7f6d50 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,14 @@ +2008-05-08 Corinna Vinschen + + * Makefile.in (DLL_OFILES): Add _def_time.o. Remove timelocal.o. + * include/sys/localedef.h: New file from NetBSD. + * libc/_def_time.c: Ditto. + * libc/getopt.c: Update to latest OpenBSD version 1.23. + * libc/strptime.cc: Replace FreeBSD version 1.35 with latest NetBSD + version 1.28. + * libc/timelocal.cc: Remove. + * libc/timelocal.h: Remove. + 2008-04-30 Corinna Vinschen * dtable.cc (dtable::release): Drop fixup_before handling. diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index 478c681f6..51b0eb38e 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -126,7 +126,7 @@ MT_SAFE_OBJECTS:= # Please maintain this list in sorted order, with maximum files per 86 col line # DLL_OFILES:=assert.o autoload.o bsdlib.o ctype.o cxx.o cygheap.o cygthread.o \ - cygtls.o dcrt0.o debug.o devices.o dir.o dlfcn.o dll_init.o \ + cygtls.o dcrt0.o debug.o _def_time.o devices.o dir.o dlfcn.o dll_init.o \ dtable.o environ.o errno.o exceptions.o exec.o external.o fcntl.o \ fhandler.o fhandler_clipboard.o fhandler_console.o fhandler_disk_file.o \ fhandler_dsp.o fhandler_fifo.o fhandler_floppy.o fhandler_mailslot.o \ @@ -144,9 +144,8 @@ DLL_OFILES:=assert.o autoload.o bsdlib.o ctype.o cxx.o cygheap.o cygthread.o \ sec_helper.o security.o select.o sem.o shared.o shm.o sigfe.o signal.o \ sigproc.o smallprint.o spawn.o strace.o strfuncs.o strptime.o strsep.o \ strsig.o sync.o syscalls.o sysconf.o syslog.o termios.o thread.o \ - timelocal.o timer.o times.o tls_pbuf.o tty.o uinfo.o uname.o \ - v8_regexp.o v8_regerror.o v8_regsub.o wait.o wincap.o window.o winf.o \ - xsique.o \ + timer.o times.o tls_pbuf.o tty.o uinfo.o uname.o v8_regexp.o \ + v8_regerror.o v8_regsub.o wait.o wincap.o window.o winf.o xsique.o \ $(EXTRA_DLL_OFILES) $(EXTRA_OFILES) $(MALLOC_OFILES) $(MT_SAFE_OBJECTS) GMON_OFILES:=gmon.o mcount.o profil.o diff --git a/winsup/cygwin/include/sys/localedef.h b/winsup/cygwin/include/sys/localedef.h new file mode 100644 index 000000000..6af264988 --- /dev/null +++ b/winsup/cygwin/include/sys/localedef.h @@ -0,0 +1,100 @@ +/* $NetBSD: localedef.h,v 1.8 2007/03/30 15:55:38 he Exp $ */ + +/* + * Copyright (c) 1994 Winning Strategies, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Winning Strategies, Inc. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SYS_LOCALEDEF_H_ +#define _SYS_LOCALEDEF_H_ + +typedef struct { + const char *yesexpr; + const char *noexpr; + const char *yesstr; + const char *nostr; +} _MessagesLocale; + +extern const _MessagesLocale *_CurrentMessagesLocale; +extern const _MessagesLocale _DefaultMessagesLocale; + + +typedef struct { + const char *int_curr_symbol; + const char *currency_symbol; + const char *mon_decimal_point; + const char *mon_thousands_sep; + const char *mon_grouping; + const char *positive_sign; + const char *negative_sign; + char int_frac_digits; + char frac_digits; + char p_cs_precedes; + char p_sep_by_space; + char n_cs_precedes; + char n_sep_by_space; + char p_sign_posn; + char n_sign_posn; + char int_p_cs_precedes; + char int_n_cs_precedes; + char int_p_sep_by_space; + char int_n_sep_by_space; + char int_p_sign_posn; + char int_n_sign_posn; +} _MonetaryLocale; + +extern const _MonetaryLocale *_CurrentMonetaryLocale; +extern const _MonetaryLocale _DefaultMonetaryLocale; + + +typedef struct { + const char *decimal_point; + const char *thousands_sep; + const char *grouping; +} _NumericLocale; + +extern const _NumericLocale *_CurrentNumericLocale; +extern const _NumericLocale _DefaultNumericLocale; + + +typedef struct { + const char *abday[7]; + const char *day[7]; + const char *abmon[12]; + const char *mon[12]; + const char *am_pm[2]; + const char *d_t_fmt; + const char *d_fmt; + const char *t_fmt; + const char *t_fmt_ampm; +} _TimeLocale; + +extern _TimeLocale *_CurrentTimeLocale; +extern _TimeLocale _DefaultTimeLocale; + +#endif /* !_SYS_LOCALEDEF_H_ */ diff --git a/winsup/cygwin/libc/_def_time.c b/winsup/cygwin/libc/_def_time.c new file mode 100644 index 000000000..40dc16102 --- /dev/null +++ b/winsup/cygwin/libc/_def_time.c @@ -0,0 +1,42 @@ +/* $NetBSD: _def_time.c,v 1.9 2007/03/28 19:05:53 manu Exp $ */ + +/* + * Written by J.T. Conklin . + * Public domain. + */ + +#include +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: _def_time.c,v 1.9 2007/03/28 19:05:53 manu Exp $"); +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +_TimeLocale _DefaultTimeLocale = +{ + { + "Sun","Mon","Tue","Wed","Thu","Fri","Sat", + }, + { + "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", + "Friday", "Saturday" + }, + { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }, + { + "January", "February", "March", "April", "May", "June", "July", + "August", "September", "October", "November", "December" + }, + { + "AM", "PM" + }, + "%a %b %e %H:%M:%S %Y", + "%m/%d/%y", + "%H:%M:%S", + "%I:%M:%S %p" +}; + +_TimeLocale *_CurrentTimeLocale = &_DefaultTimeLocale; diff --git a/winsup/cygwin/libc/getopt.c b/winsup/cygwin/libc/getopt.c index 0ed46310e..bbd1f37dd 100644 --- a/winsup/cygwin/libc/getopt.c +++ b/winsup/cygwin/libc/getopt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getopt_long.c,v 1.16 2004/02/04 18:17:25 millert Exp $ */ +/* $OpenBSD: getopt_long.c,v 1.23 2007/10/31 12:34:57 chl Exp $ */ /* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ /* @@ -35,13 +35,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED @@ -56,10 +49,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: getopt_long.c,v 1.16 2004/02/04 18:17:25 millert Exp $"; -#endif /* LIBC_SCCS and not lint */ - #include #include #include @@ -465,7 +454,6 @@ start: optarg = NULL; if (*place) /* no white space */ optarg = place; - /* XXX: disable test for :: if PC? (GNU doesn't) */ else if (oli[1] != ':') { /* arg not optional */ if (++optind >= nargc) { /* no arg */ place = EMSG; @@ -475,13 +463,6 @@ start: return (BADARG); } else optarg = nargv[optind]; - } else if (!(flags & FLAG_PERMUTE)) { - /* - * If permutation is disabled, we can accept an - * optional arg separated by whitespace. - */ - if (optind + 1 < nargc) - optarg = nargv[++optind]; } place = EMSG; ++optind; @@ -502,7 +483,7 @@ getopt(int nargc, char * const *nargv, const char *options) { /* - * We dont' pass FLAG_PERMUTE to getopt_internal() since + * We don't pass FLAG_PERMUTE to getopt_internal() since * the BSD getopt(3) (unlike GNU) has never done this. * * Furthermore, since many privileged programs call getopt() @@ -518,12 +499,8 @@ getopt(int nargc, char * const *nargv, const char *options) * Parse argc/argv argument vector. */ int -getopt_long(nargc, nargv, options, long_options, idx) - int nargc; - char * const *nargv; - const char *options; - const struct option *long_options; - int *idx; +getopt_long(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) { return (getopt_internal(nargc, nargv, options, long_options, idx, @@ -535,12 +512,8 @@ getopt_long(nargc, nargv, options, long_options, idx) * Parse argc/argv argument vector. */ int -getopt_long_only(nargc, nargv, options, long_options, idx) - int nargc; - char * const *nargv; - const char *options; - const struct option *long_options; - int *idx; +getopt_long_only(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) { return (getopt_internal(nargc, nargv, options, long_options, idx, diff --git a/winsup/cygwin/libc/strptime.cc b/winsup/cygwin/libc/strptime.cc index e81cdd580..d0a77a850 100644 --- a/winsup/cygwin/libc/strptime.cc +++ b/winsup/cygwin/libc/strptime.cc @@ -1,26 +1,11 @@ -/* - * Powerdog Industries kindly requests feedback from anyone modifying - * this function: +/* $NetBSD: strptime.c,v 1.28 2008/04/28 20:23:01 martin Exp $ */ + +/*- + * Copyright (c) 1997, 1998, 2005, 2008 The NetBSD Foundation, Inc. + * All rights reserved. * - * Date: Thu, 05 Jun 1997 23:17:17 -0400 - * From: Kevin Ruddy - * To: James FitzGibbon - * Subject: Re: Use of your strptime(3) code (fwd) - * - * The reason for the "no mod" clause was so that modifications would - * come back and we could integrate them and reissue so that a wider - * audience could use it (thereby spreading the wealth). This has - * made it possible to get strptime to work on many operating systems. - * I'm not sure why that's "plain unacceptable" to the FreeBSD team. - * - * Anyway, you can change it to "with or without modification" as - * you see fit. Enjoy. - * - * Kevin Ruddy - * Powerdog Industries, Inc. - */ -/* - * Copyright (c) 1994 Powerdog Industries. All rights reserved. + * This code was contributed to The NetBSD Foundation by Klaus Klein. + * Heavily optimised by David Laight * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,518 +13,374 @@ * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgement: - * This product includes software developed by Powerdog Industries. - * 4. The name of Powerdog Industries may not be used to endorse or - * promote products derived from this software without specific prior - * written permission. + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY POWERDOG INDUSTRIES ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE POWERDOG INDUSTRIES BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: strptime.c,v 1.28 2008/04/28 20:23:01 martin Exp $"); +#endif + #ifdef __CYGWIN__ #include "winsup.h" #else -#ifndef lint -#ifndef NOID -static char copyright[] __unused = -"@(#) Copyright (c) 1994 Powerdog Industries. All rights reserved."; -static char sccsid[] __unused = "@(#)strptime.c 0.1 (Powerdog) 94/03/27"; -#endif /* !defined NOID */ -#endif /* not lint */ -__FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/stdtime/strptime.c,v 1.35 2003/11/17 04:19:15 nectar Exp $"); - #include "namespace.h" #endif -#include +#include #include -#include -#include +#include #include -#ifndef __CYGWIN__ -#include -#include "un-namespace.h" -#include "libc_private.h" +#include +#include + +#ifdef __weak_alias +__weak_alias(strptime,_strptime) #endif -#include "timelocal.h" -static char * _strptime(const char *, const char *, struct tm *, int *); +#define _ctloc(x) (_CurrentTimeLocale->x) -#define asizeof(a) ((int)(sizeof (a) / sizeof ((a)[0]))) +/* + * We do not implement alternate representations. However, we always + * check whether a given modifier is allowed for a certain conversion. + */ +#define ALT_E 0x01 +#define ALT_O 0x02 +#define LEGAL_ALT(x) { if (alt_format & ~(x)) return NULL; } -static char * -_strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp) +static const char gmt[4] = { "GMT" }; + +static const u_char *conv_num(const unsigned char *, int *, uint, uint); +static const u_char *find_string(const u_char *, int *, const char * const *, + const char * const *, int); + + +char * +strptime(const char *buf, const char *fmt, struct tm *tm) { - char c; - const char *ptr; - int i, - len; - int Ealternative, Oalternative; - struct lc_time_T *tptr = __get_current_time_locale(); + unsigned char c; + const unsigned char *bp; + int alt_format, i, split_year = 0; + const char *new_fmt; - ptr = fmt; - while (*ptr != 0) { - if (*buf == 0) - break; + bp = (const u_char *)buf; - c = *ptr++; + while (bp != NULL && (c = *fmt++) != '\0') { + /* Clear `alternate' modifier prior to new conversion. */ + alt_format = 0; + i = 0; - if (c != '%') { - if (isspace((unsigned char)c)) - while (*buf != 0 && isspace((unsigned char)*buf)) - buf++; - else if (c != *buf++) - return 0; + /* Eat up white-space. */ + if (isspace(c)) { + while (isspace(*bp)) + bp++; continue; } - Ealternative = 0; - Oalternative = 0; -label: - c = *ptr++; - switch (c) { - case 0: - case '%': - if (*buf++ != '%') - return 0; - break; + if (c != '%') + goto literal; - case '+': - buf = _strptime(buf, tptr->date_fmt, tm, GMTp); - if (buf == 0) - return 0; - break; - case 'C': - if (!isdigit((unsigned char)*buf)) - return 0; +again: switch (c = *fmt++) { + case '%': /* "%%" is converted to "%". */ +literal: + if (c != *bp++) + return NULL; + LEGAL_ALT(0); + continue; - /* XXX This will break for 3-digit centuries. */ - len = 2; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { - i *= 10; - i += *buf - '0'; - len--; - } - if (i < 19) - return 0; + /* + * "Alternative" modifiers. Just set the appropriate flag + * and start over again. + */ + case 'E': /* "%E?" alternative conversion modifier. */ + LEGAL_ALT(0); + alt_format |= ALT_E; + goto again; - tm->tm_year = i * 100 - 1900; - break; + case 'O': /* "%O?" alternative conversion modifier. */ + LEGAL_ALT(0); + alt_format |= ALT_O; + goto again; - case 'c': - buf = _strptime(buf, tptr->c_fmt, tm, GMTp); - if (buf == 0) - return 0; - break; + /* + * "Complex" conversion rules, implemented through recursion. + */ + case 'c': /* Date and time, using the locale's format. */ + new_fmt = _ctloc(d_t_fmt); + goto recurse; - case 'D': - buf = _strptime(buf, "%m/%d/%y", tm, GMTp); - if (buf == 0) - return 0; - break; + case 'D': /* The date as "%m/%d/%y". */ + new_fmt = "%m/%d/%y"; + LEGAL_ALT(0); + goto recurse; - case 'E': - if (Ealternative || Oalternative) - break; - Ealternative++; - goto label; + case 'F': /* The date as "%Y-%m-%d". */ + new_fmt = "%Y-%m-%d"; + LEGAL_ALT(0); + goto recurse; - case 'O': - if (Ealternative || Oalternative) - break; - Oalternative++; - goto label; + case 'R': /* The time as "%H:%M". */ + new_fmt = "%H:%M"; + LEGAL_ALT(0); + goto recurse; - case 'F': - buf = _strptime(buf, "%Y-%m-%d", tm, GMTp); - if (buf == 0) - return 0; - break; + case 'r': /* The time in 12-hour clock representation. */ + new_fmt =_ctloc(t_fmt_ampm); + LEGAL_ALT(0); + goto recurse; - case 'R': - buf = _strptime(buf, "%H:%M", tm, GMTp); - if (buf == 0) - return 0; - break; + case 'T': /* The time as "%H:%M:%S". */ + new_fmt = "%H:%M:%S"; + LEGAL_ALT(0); + goto recurse; - case 'r': - buf = _strptime(buf, tptr->ampm_fmt, tm, GMTp); - if (buf == 0) - return 0; - break; + case 'X': /* The time, using the locale's format. */ + new_fmt =_ctloc(t_fmt); + goto recurse; - case 'T': - buf = _strptime(buf, "%H:%M:%S", tm, GMTp); - if (buf == 0) - return 0; - break; + case 'x': /* The date, using the locale's format. */ + new_fmt =_ctloc(d_fmt); + recurse: + bp = (const u_char *)strptime((const char *)bp, + new_fmt, tm); + LEGAL_ALT(ALT_E); + continue; - case 'X': - buf = _strptime(buf, tptr->X_fmt, tm, GMTp); - if (buf == 0) - return 0; - break; - - case 'x': - buf = _strptime(buf, tptr->x_fmt, tm, GMTp); - if (buf == 0) - return 0; - break; - - case 'j': - if (!isdigit((unsigned char)*buf)) - return 0; - - len = 3; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { - i *= 10; - i += *buf - '0'; - len--; - } - if (i < 1 || i > 366) - return 0; - - tm->tm_yday = i - 1; - break; - - case 'M': - case 'S': - if (*buf == 0 || isspace((unsigned char)*buf)) - break; - - if (!isdigit((unsigned char)*buf)) - return 0; - - len = 2; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { - i *= 10; - i += *buf - '0'; - len--; - } - - if (c == 'M') { - if (i > 59) - return 0; - tm->tm_min = i; - } else { - if (i > 60) - return 0; - tm->tm_sec = i; - } - - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) - ptr++; - break; - - case 'H': - case 'I': - case 'k': - case 'l': - /* - * Of these, %l is the only specifier explicitly - * documented as not being zero-padded. However, - * there is no harm in allowing zero-padding. - * - * XXX The %l specifier may gobble one too many - * digits if used incorrectly. - */ - if (!isdigit((unsigned char)*buf)) - return 0; - - len = 2; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { - i *= 10; - i += *buf - '0'; - len--; - } - if (c == 'H' || c == 'k') { - if (i > 23) - return 0; - } else if (i > 12) - return 0; - - tm->tm_hour = i; - - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) - ptr++; - break; - - case 'p': - /* - * XXX This is bogus if parsed before hour-related - * specifiers. - */ - len = strlen(tptr->am); - if (strncasecmp(buf, tptr->am, len) == 0) { - if (tm->tm_hour > 12) - return 0; - if (tm->tm_hour == 12) - tm->tm_hour = 0; - buf += len; - break; - } - - len = strlen(tptr->pm); - if (strncasecmp(buf, tptr->pm, len) == 0) { - if (tm->tm_hour > 12) - return 0; - if (tm->tm_hour != 12) - tm->tm_hour += 12; - buf += len; - break; - } - - return 0; - - case 'A': + /* + * "Elementary" conversion rules. + */ + case 'A': /* The day of week, using the locale's form. */ case 'a': - len = 0; - for (i = 0; i < asizeof(tptr->weekday); i++) { - len = strlen(tptr->weekday[i]); - if (strncasecmp(buf, tptr->weekday[i], - len) == 0) - break; - len = strlen(tptr->wday[i]); - if (strncasecmp(buf, tptr->wday[i], - len) == 0) - break; - } - if (i == asizeof(tptr->weekday)) - return 0; + bp = find_string(bp, &tm->tm_wday, _ctloc(day), + _ctloc(abday), 7); + LEGAL_ALT(0); + continue; - tm->tm_wday = i; - buf += len; - break; + case 'B': /* The month, using the locale's form. */ + case 'b': + case 'h': + bp = find_string(bp, &tm->tm_mon, _ctloc(mon), + _ctloc(abmon), 12); + LEGAL_ALT(0); + continue; - case 'U': - case 'W': + case 'C': /* The century number. */ + i = 20; + bp = conv_num(bp, &i, 0, 99); + + i = i * 100 - TM_YEAR_BASE; + if (split_year) + i += tm->tm_year % 100; + split_year = 1; + tm->tm_year = i; + LEGAL_ALT(ALT_E); + continue; + + case 'd': /* The day of month. */ + case 'e': + bp = conv_num(bp, &tm->tm_mday, 1, 31); + LEGAL_ALT(ALT_O); + continue; + + case 'k': /* The hour (24-hour clock representation). */ + LEGAL_ALT(0); + /* FALLTHROUGH */ + case 'H': + bp = conv_num(bp, &tm->tm_hour, 0, 23); + LEGAL_ALT(ALT_O); + continue; + + case 'l': /* The hour (12-hour clock representation). */ + LEGAL_ALT(0); + /* FALLTHROUGH */ + case 'I': + bp = conv_num(bp, &tm->tm_hour, 1, 12); + if (tm->tm_hour == 12) + tm->tm_hour = 0; + LEGAL_ALT(ALT_O); + continue; + + case 'j': /* The day of year. */ + i = 1; + bp = conv_num(bp, &i, 1, 366); + tm->tm_yday = i - 1; + LEGAL_ALT(0); + continue; + + case 'M': /* The minute. */ + bp = conv_num(bp, &tm->tm_min, 0, 59); + LEGAL_ALT(ALT_O); + continue; + + case 'm': /* The month. */ + i = 1; + bp = conv_num(bp, &i, 1, 12); + tm->tm_mon = i - 1; + LEGAL_ALT(ALT_O); + continue; + + case 'p': /* The locale's equivalent of AM/PM. */ + bp = find_string(bp, &i, _ctloc(am_pm), NULL, 2); + if (tm->tm_hour > 11) + return NULL; + tm->tm_hour += i * 12; + LEGAL_ALT(0); + continue; + + case 'S': /* The seconds. */ + bp = conv_num(bp, &tm->tm_sec, 0, 61); + LEGAL_ALT(ALT_O); + continue; + + case 'U': /* The week of year, beginning on sunday. */ + case 'W': /* The week of year, beginning on monday. */ /* * XXX This is bogus, as we can not assume any valid * information present in the tm structure at this * point to calculate a real value, so just check the * range for now. */ - if (!isdigit((unsigned char)*buf)) - return 0; + bp = conv_num(bp, &i, 0, 53); + LEGAL_ALT(ALT_O); + continue; - len = 2; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { - i *= 10; - i += *buf - '0'; - len--; + case 'w': /* The day of week, beginning on sunday. */ + bp = conv_num(bp, &tm->tm_wday, 0, 6); + LEGAL_ALT(ALT_O); + continue; + + case 'Y': /* The year. */ + i = TM_YEAR_BASE; /* just for data sanity... */ + bp = conv_num(bp, &i, 0, 9999); + tm->tm_year = i - TM_YEAR_BASE; + LEGAL_ALT(ALT_E); + continue; + + case 'y': /* The year within 100 years of the epoch. */ + /* LEGAL_ALT(ALT_E | ALT_O); */ + bp = conv_num(bp, &i, 0, 99); + + if (split_year) + /* preserve century */ + i += (tm->tm_year / 100) * 100; + else { + split_year = 1; + if (i <= 68) + i = i + 2000 - TM_YEAR_BASE; + else + i = i + 1900 - TM_YEAR_BASE; } - if (i > 53) - return 0; - - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) - ptr++; - break; - - case 'w': - if (!isdigit((unsigned char)*buf)) - return 0; - - i = *buf - '0'; - if (i > 6) - return 0; - - tm->tm_wday = i; - - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) - ptr++; - break; - - case 'd': - case 'e': - /* - * The %e specifier is explicitly documented as not - * being zero-padded but there is no harm in allowing - * such padding. - * - * XXX The %e specifier may gobble one too many - * digits if used incorrectly. - */ - if (!isdigit((unsigned char)*buf)) - return 0; - - len = 2; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { - i *= 10; - i += *buf - '0'; - len--; - } - if (i > 31) - return 0; - - tm->tm_mday = i; - - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) - ptr++; - break; - - case 'B': - case 'b': - case 'h': - len = 0; - for (i = 0; i < asizeof(tptr->month); i++) { - if (Oalternative) { - if (c == 'B') { - len = strlen(tptr->alt_month[i]); - if (strncasecmp(buf, - tptr->alt_month[i], - len) == 0) - break; - } - } else { - len = strlen(tptr->month[i]); - if (strncasecmp(buf, tptr->month[i], - len) == 0) - break; - len = strlen(tptr->mon[i]); - if (strncasecmp(buf, tptr->mon[i], - len) == 0) - break; - } - } - if (i == asizeof(tptr->month)) - return 0; - - tm->tm_mon = i; - buf += len; - break; - - case 'm': - if (!isdigit((unsigned char)*buf)) - return 0; - - len = 2; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { - i *= 10; - i += *buf - '0'; - len--; - } - if (i < 1 || i > 12) - return 0; - - tm->tm_mon = i - 1; - - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) - ptr++; - break; - - case 's': - { - char *cp; - int sverrno; - long n; - time_t t; - - sverrno = errno; - errno = 0; - n = strtol(buf, &cp, 10); - if (errno == ERANGE || (long)(t = n) != n) { - errno = sverrno; - return 0; - } - errno = sverrno; - buf = cp; - gmtime_r(&t, tm); - *GMTp = 1; - } - break; - - case 'Y': - case 'y': - if (*buf == 0 || isspace((unsigned char)*buf)) - break; - - if (!isdigit((unsigned char)*buf)) - return 0; - - len = (c == 'Y') ? 4 : 2; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { - i *= 10; - i += *buf - '0'; - len--; - } - if (c == 'Y') - i -= 1900; - if (c == 'y' && i < 69) - i += 100; - if (i < 0) - return 0; - tm->tm_year = i; - - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) - ptr++; - break; + continue; case 'Z': - { - const char *cp; - char *zonestr; + tzset(); + if (strncmp((const char *)bp, gmt, 3) == 0) { + tm->tm_isdst = 0; +#ifdef TM_GMTOFF + tm->TM_GMTOFF = 0; +#endif +#ifdef TM_ZONE + tm->TM_ZONE = gmt; +#endif + bp += 3; + } else { + const unsigned char *ep; - for (cp = buf; *cp && isupper((unsigned char)*cp); ++cp) {/*empty*/} - if (cp - buf) { - zonestr = (char *) alloca(cp - buf + 1); - strncpy(zonestr, buf, cp - buf); - zonestr[cp - buf] = '\0'; - tzset(); - if (0 == strcmp(zonestr, "GMT")) { - *GMTp = 1; - } else if (0 == strcmp(zonestr, tzname[0])) { - tm->tm_isdst = 0; - } else if (0 == strcmp(zonestr, tzname[1])) { - tm->tm_isdst = 1; - } else { - return 0; + ep = find_string(bp, &i, + (const char * const *)tzname, + NULL, 2); + if (ep != NULL) { + tm->tm_isdst = i; +#ifdef TM_GMTOFF + tm->TM_GMTOFF = -(timezone); +#endif +#ifdef TM_ZONE + tm->TM_ZONE = tzname[i]; +#endif } - buf += cp - buf; + bp = ep; } - } - break; + continue; + + /* + * Miscellaneous conversions. + */ + case 'n': /* Any kind of white-space. */ + case 't': + while (isspace(*bp)) + bp++; + LEGAL_ALT(0); + continue; + + + default: /* Unknown/unsupported conversion. */ + return NULL; } } - return (char *)buf; + + return (char *) bp; } -extern "C" char * -strptime(const char * __restrict buf, const char * __restrict fmt, - struct tm * __restrict tm) -{ - char *ret; - int gmt; - gmt = 0; - ret = _strptime(buf, fmt, tm, &gmt); - if (ret && gmt) { - time_t t = timegm(tm); - localtime_r(&t, tm); +static const u_char * +conv_num(const unsigned char *buf, int *dest, uint llim, uint ulim) +{ + uint result = 0; + unsigned char ch; + + /* The limit also determines the number of valid digits. */ + uint rulim = ulim; + + ch = *buf; + if (ch < '0' || ch > '9') + return NULL; + + do { + result *= 10; + result += ch - '0'; + rulim /= 10; + ch = *++buf; + } while ((result * 10 <= ulim) && rulim && ch >= '0' && ch <= '9'); + + if (result < llim || result > ulim) + return NULL; + + *dest = result; + return buf; +} + +static const u_char * +find_string(const u_char *bp, int *tgt, const char * const *n1, + const char * const *n2, int c) +{ + int i; + unsigned int len; + + /* check full name - then abbreviated ones */ + for (; n1 != NULL; n1 = n2, n2 = NULL) { + for (i = 0; i < c; i++, n1++) { + len = strlen(*n1); + if (strncasecmp(*n1, (const char *)bp, len) == 0) { + *tgt = i; + return bp + len; + } + } } - return (ret); + /* Nothing matched */ + return NULL; } diff --git a/winsup/cygwin/libc/timelocal.cc b/winsup/cygwin/libc/timelocal.cc deleted file mode 100644 index 59a2e4155..000000000 --- a/winsup/cygwin/libc/timelocal.cc +++ /dev/null @@ -1,125 +0,0 @@ -/*- - * Copyright (c) 2001 Alexey Zelkin - * Copyright (c) 1997 FreeBSD Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -//__FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/stdtime/timelocal.c,v 1.25 2003/06/13 00:14:07 jkh Exp $"); - -#include - -//#include "ldpart.h" -#include "timelocal.h" - -#ifndef __CYGWIN__ -static struct lc_time_T _time_locale; -static int _time_using_locale; -static char *time_locale_buf; -#endif - -#define LCTIME_SIZE (sizeof(struct lc_time_T) / sizeof(char *)) - -static const struct lc_time_T _C_time_locale = { - { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }, { - "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December" - }, { - "Sun", "Mon", "Tue", "Wed", - "Thu", "Fri", "Sat" - }, { - "Sunday", "Monday", "Tuesday", "Wednesday", - "Thursday", "Friday", "Saturday" - }, - - /* X_fmt */ - "%H:%M:%S", - - /* - * x_fmt - * Since the C language standard calls for - * "date, using locale's date format," anything goes. - * Using just numbers (as here) makes Quakers happier; - * it's also compatible with SVR4. - */ - "%m/%d/%y", - - /* - * c_fmt - */ - "%a %b %e %H:%M:%S %Y", - - /* am */ - "AM", - - /* pm */ - "PM", - - /* date_fmt */ - "%a %b %e %H:%M:%S %Z %Y", - - /* alt_month - * Standalone months forms for %OB - */ - { - "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December" - }, - - /* md_order - * Month / day order in dates - */ - "md", - - /* ampm_fmt - * To determine 12-hour clock format time (empty, if N/A) - */ - "%I:%M:%S %p" -}; - -extern "C" struct lc_time_T * -__get_current_time_locale(void) -{ -#ifdef __CYGWIN__ - return (struct lc_time_T *)&_C_time_locale; -#else - return (_time_using_locale - ? &_time_locale - : (struct lc_time_T *)&_C_time_locale); -#endif -} - -#ifndef __CYGWIN__ -extern "C" int -__time_load_locale(const char *name) -{ - return (__part_load_locale(name, &_time_using_locale, - &time_locale_buf, "LC_TIME", - LCTIME_SIZE, LCTIME_SIZE, - (const char **)&_time_locale)); -} -#endif diff --git a/winsup/cygwin/libc/timelocal.h b/winsup/cygwin/libc/timelocal.h deleted file mode 100644 index e7d515276..000000000 --- a/winsup/cygwin/libc/timelocal.h +++ /dev/null @@ -1,65 +0,0 @@ -/*- - * Copyright (c) 1997-2002 FreeBSD Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: /repoman/r/ncvs/src/lib/libc/stdtime/timelocal.h,v 1.11 2002/01/24 15:07:44 phantom Exp $ - */ - -#ifndef _TIMELOCAL_H_ -#define _TIMELOCAL_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Private header file for the strftime and strptime localization - * stuff. - */ -struct lc_time_T { - const char *mon[12]; - const char *month[12]; - const char *wday[7]; - const char *weekday[7]; - const char *X_fmt; - const char *x_fmt; - const char *c_fmt; - const char *am; - const char *pm; - const char *date_fmt; - const char *alt_month[12]; - const char *md_order; - const char *ampm_fmt; -}; - -struct lc_time_T *__get_current_time_locale(void); -#ifndef __CYGWIN__ -int __time_load_locale(const char *); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* !_TIMELOCAL_H_ */