From b3c85772f7a16b79e679c78c9638a7afa4856432 Mon Sep 17 00:00:00 2001 From: Jarkko Hietaniemi Date: Thu, 19 Apr 2001 00:54:54 +0000 Subject: [PATCH] Move the strftime() wrapper from POSIX.xs to util.c as my_strftime(), requires HAS_STRFTIME. p4raw-id: //depot/perl@9746 --- Configure | 8 ++++++- Porting/Glossary | 4 ++++ Porting/config.sh | 11 +++++---- Porting/config_H | 8 ++++++- config_h.SH | 6 +++++ configure.com | 1 + embed.h | 4 ++++ embed.pl | 1 + epoc/config.sh | 1 + ext/POSIX/POSIX.xs | 62 +++--------------------------------------------- proto.h | 1 + uconfig.h | 6 +++++ uconfig.sh | 1 + util.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ vos/config.alpha.def | 1 + vos/config.alpha.h | 6 +++++ vos/config.ga.def | 1 + vos/config.ga.h | 6 +++++ win32/config.bc | 1 + win32/config.gc | 1 + win32/config.vc | 1 + 21 files changed, 131 insertions(+), 66 deletions(-) diff --git a/Configure b/Configure index c2034e1..4531138 100755 --- a/Configure +++ b/Configure @@ -20,7 +20,7 @@ # $Id: Head.U,v 3.0.1.9 1997/02/28 15:02:09 ram Exp $ # -# Generated on Sun Apr 8 02:03:47 EET DST 2001 [metaconfig 3.0 PL70] +# Generated on Thu Apr 19 03:28:20 EET DST 2001 [metaconfig 3.0 PL70] # (with additional metaconfig patches by perlbug@perl.org) cat >c1$$ <$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un */ #$d_sockatmark HAS_SOCKATMARK /**/ +/* HAS_STRFTIME: + * This symbol, if defined, indicates that the strftime routine is + * available to do time formatting. + */ +#$d_strftime HAS_STRFTIME /**/ + /* U32_ALIGNMENT_REQUIRED: * This symbol, if defined, indicates that you must access * character data through U32-aligned pointers. diff --git a/configure.com b/configure.com index fa06d20..ff86731 100644 --- a/configure.com +++ b/configure.com @@ -5158,6 +5158,7 @@ $ WC "d_strcoll='" + d_strcoll + "'" $ WC "d_strctcpy='define'" $ WC "d_strerrm='strerror((e),vaxc$errno)'" $ WC "d_strerror='define'" +$ WC "d_strftime='define'" $ WC "d_strtod='define'" $ WC "d_strtol='define'" $ WC "d_strtold='" + d_strtold + "'" diff --git a/embed.h b/embed.h index a5bb53e..887e9eb 100644 --- a/embed.h +++ b/embed.h @@ -439,6 +439,7 @@ #endif #define my_setenv Perl_my_setenv #define my_stat Perl_my_stat +#define my_strftime Perl_my_strftime #if defined(MYSWAP) #define my_swap Perl_my_swap #define my_htonl Perl_my_htonl @@ -1934,6 +1935,7 @@ #endif #define my_setenv(a,b) Perl_my_setenv(aTHX_ a,b) #define my_stat() Perl_my_stat(aTHX) +#define my_strftime(a,b,c,d,e,f,g,h,i,j) Perl_my_strftime(aTHX_ a,b,c,d,e,f,g,h,i,j) #if defined(MYSWAP) #define my_swap(a) Perl_my_swap(aTHX_ a) #define my_htonl(a) Perl_my_htonl(aTHX_ a) @@ -3786,6 +3788,8 @@ #define my_setenv Perl_my_setenv #define Perl_my_stat CPerlObj::Perl_my_stat #define my_stat Perl_my_stat +#define Perl_my_strftime CPerlObj::Perl_my_strftime +#define my_strftime Perl_my_strftime #if defined(MYSWAP) #define Perl_my_swap CPerlObj::Perl_my_swap #define my_swap Perl_my_swap diff --git a/embed.pl b/embed.pl index 3d0160d..99e063f 100755 --- a/embed.pl +++ b/embed.pl @@ -1778,6 +1778,7 @@ Ap |PerlIO*|my_popen_list |char* mode|int n|SV ** args #endif Ap |void |my_setenv |char* nam|char* val Ap |I32 |my_stat +p |char * |my_strftime |char *fmt|int sec|int min|int hour|int mday|int mon|int year|int wday|int yday|int isdst #if defined(MYSWAP) Ap |short |my_swap |short s Ap |long |my_htonl |long l diff --git a/epoc/config.sh b/epoc/config.sh index 90b7e70..0b5fa90 100644 --- a/epoc/config.sh +++ b/epoc/config.sh @@ -347,6 +347,7 @@ d_strcoll='define' d_strctcpy='define' d_strerrm='strerror(e)' d_strerror='define' +d_strftime='define' d_strtod='define' d_strtol='define' d_strtoq='undef' diff --git a/ext/POSIX/POSIX.xs b/ext/POSIX/POSIX.xs index 7658b39..3e273b0 100644 --- a/ext/POSIX/POSIX.xs +++ b/ext/POSIX/POSIX.xs @@ -3665,65 +3665,9 @@ strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1) int isdst CODE: { - char tmpbuf[128]; - struct tm mytm; - int len; - init_tm(&mytm); /* XXX workaround - see init_tm() above */ - mytm.tm_sec = sec; - mytm.tm_min = min; - mytm.tm_hour = hour; - mytm.tm_mday = mday; - mytm.tm_mon = mon; - mytm.tm_year = year; - mytm.tm_wday = wday; - mytm.tm_yday = yday; - mytm.tm_isdst = isdst; - mini_mktime(&mytm); - len = strftime(tmpbuf, sizeof tmpbuf, fmt, &mytm); - /* - ** The following is needed to handle to the situation where - ** tmpbuf overflows. Basically we want to allocate a buffer - ** and try repeatedly. The reason why it is so complicated - ** is that getting a return value of 0 from strftime can indicate - ** one of the following: - ** 1. buffer overflowed, - ** 2. illegal conversion specifier, or - ** 3. the format string specifies nothing to be returned(not - ** an error). This could be because format is an empty string - ** or it specifies %p that yields an empty string in some locale. - ** If there is a better way to make it portable, go ahead by - ** all means. - */ - if ((len > 0 && len < sizeof(tmpbuf)) || (len == 0 && *fmt == '\0')) - ST(0) = sv_2mortal(newSVpv(tmpbuf, len)); - else { - /* Possibly buf overflowed - try again with a bigger buf */ - int fmtlen = strlen(fmt); - int bufsize = fmtlen + sizeof(tmpbuf); - char* buf; - int buflen; - - New(0, buf, bufsize, char); - while (buf) { - buflen = strftime(buf, bufsize, fmt, &mytm); - if (buflen > 0 && buflen < bufsize) - break; - /* heuristic to prevent out-of-memory errors */ - if (bufsize > 100*fmtlen) { - Safefree(buf); - buf = NULL; - break; - } - bufsize *= 2; - Renew(buf, bufsize, char); - } - if (buf) { - ST(0) = sv_2mortal(newSVpvn(buf, buflen)); - Safefree(buf); - } - else - ST(0) = sv_2mortal(newSVpvn(tmpbuf, len)); - } + char *buf = my_strftime(fmt, sec, min, hour, mday, mon, year, wday, yday, isdst); + ST(0) = sv_2mortal(newSVpv(buf, 0)); + free(buf); } void diff --git a/proto.h b/proto.h index 644b6b9..63fc518 100644 --- a/proto.h +++ b/proto.h @@ -505,6 +505,7 @@ PERL_CALLCONV PerlIO* Perl_my_popen_list(pTHX_ char* mode, int n, SV ** args); #endif PERL_CALLCONV void Perl_my_setenv(pTHX_ char* nam, char* val); PERL_CALLCONV I32 Perl_my_stat(pTHX); +PERL_CALLCONV char * Perl_my_strftime(pTHX_ char *fmt, int sec, int min, int hour, int mday, int mon, int year, int wday, int yday, int isdst); #if defined(MYSWAP) PERL_CALLCONV short Perl_my_swap(pTHX_ short s); PERL_CALLCONV long Perl_my_htonl(pTHX_ long l); diff --git a/uconfig.h b/uconfig.h index 6914151..dd57e19 100644 --- a/uconfig.h +++ b/uconfig.h @@ -3322,6 +3322,12 @@ */ /*#define HAS_SOCKATMARK / **/ +/* HAS_STRFTIME: + * This symbol, if defined, indicates that the strftime routine is + * available to do time formatting. + */ +/*#define HAS_STRFTIME / **/ + /* U32_ALIGNMENT_REQUIRED: * This symbol, if defined, indicates that you must access * character data through U32-aligned pointers. diff --git a/uconfig.sh b/uconfig.sh index 9ded43b..ed31a3d 100755 --- a/uconfig.sh +++ b/uconfig.sh @@ -291,6 +291,7 @@ d_strcoll='undef' d_strctcpy='undef' d_strerrm='strerror(e)' d_strerror='undef' +d_strftime='undef' d_strtod='undef' d_strtol='undef' d_strtold='undef' diff --git a/util.c b/util.c index 542d0dd..4ccd589 100644 --- a/util.c +++ b/util.c @@ -4361,3 +4361,69 @@ mini_mktime(struct tm *ptm) if ((unsigned)ptm->tm_wday > 6) ptm->tm_wday = (jday + WEEKDAY_BIAS) % 7; } + +char * +my_strftime(char *fmt, int sec, int min, int hour, int mday, int mon, int year, int wday, int yday, int isdst) +{ +#ifdef HAS_STRFTIME + char *buf; + int buflen; + struct tm mytm; + int len; + + init_tm(&mytm); /* XXX workaround - see init_tm() above */ + mytm.tm_sec = sec; + mytm.tm_min = min; + mytm.tm_hour = hour; + mytm.tm_mday = mday; + mytm.tm_mon = mon; + mytm.tm_year = year; + mytm.tm_wday = wday; + mytm.tm_yday = yday; + mytm.tm_isdst = isdst; + mini_mktime(&mytm); + buflen = 64; + New(0, buf, buflen, char); + len = strftime(buf, buflen, fmt, &mytm); + /* + ** The following is needed to handle to the situation where + ** tmpbuf overflows. Basically we want to allocate a buffer + ** and try repeatedly. The reason why it is so complicated + ** is that getting a return value of 0 from strftime can indicate + ** one of the following: + ** 1. buffer overflowed, + ** 2. illegal conversion specifier, or + ** 3. the format string specifies nothing to be returned(not + ** an error). This could be because format is an empty string + ** or it specifies %p that yields an empty string in some locale. + ** If there is a better way to make it portable, go ahead by + ** all means. + */ + if ((len > 0 && len < buflen) || (len == 0 && *fmt == '\0')) + return buf; + else { + /* Possibly buf overflowed - try again with a bigger buf */ + int fmtlen = strlen(fmt); + int bufsize = fmtlen + buflen; + + New(0, buf, bufsize, char); + while (buf) { + buflen = strftime(buf, bufsize, fmt, &mytm); + if (buflen > 0 && buflen < bufsize) + break; + /* heuristic to prevent out-of-memory errors */ + if (bufsize > 100*fmtlen) { + Safefree(buf); + buf = NULL; + break; + } + bufsize *= 2; + Renew(buf, bufsize, char); + } + return buf; + } +#else + Perl_croak(aTHX_ "panic: no strftime"); +#endif +} + diff --git a/vos/config.alpha.def b/vos/config.alpha.def index 1242114..a6f03b3 100644 --- a/vos/config.alpha.def +++ b/vos/config.alpha.def @@ -258,6 +258,7 @@ $d_strcoll='define' $d_strctcpy='define' $d_strerrm='strerror(e)' $d_strerror='define' +$d_strftime='define' $d_strtod='define' $d_strtol='define' $d_strtold='undef' diff --git a/vos/config.alpha.h b/vos/config.alpha.h index c4291f9..774abae 100644 --- a/vos/config.alpha.h +++ b/vos/config.alpha.h @@ -3329,4 +3329,10 @@ */ #define U32_ALIGNMENT_REQUIRED /**/ +/* HAS_STRFTIME: + * This symbol, if defined, indicates that the strftime routine is + * available to do time formatting. + */ +#define HAS_STRFTIME /**/ + #endif diff --git a/vos/config.ga.def b/vos/config.ga.def index 63d2aa9..402428d 100644 --- a/vos/config.ga.def +++ b/vos/config.ga.def @@ -258,6 +258,7 @@ $d_strcoll='define' $d_strctcpy='define' $d_strerrm='strerror(e)' $d_strerror='define' +$d_strftime='define' $d_strtod='define' $d_strtol='define' $d_strtold='undef' diff --git a/vos/config.ga.h b/vos/config.ga.h index 642b65b..da40b86 100644 --- a/vos/config.ga.h +++ b/vos/config.ga.h @@ -3329,4 +3329,10 @@ */ #define U32_ALIGNMENT_REQUIRED /**/ +/* HAS_STRFTIME: + * This symbol, if defined, indicates that the strftime routine is + * available to do time formatting. + */ +#define HAS_STRFTIME /**/ + #endif diff --git a/win32/config.bc b/win32/config.bc index b859846..81722b5 100644 --- a/win32/config.bc +++ b/win32/config.bc @@ -343,6 +343,7 @@ d_strcoll='define' d_strctcpy='define' d_strerrm='strerror(e)' d_strerror='define' +d_strftime='define' d_strtod='define' d_strtol='define' d_strtold='undef' diff --git a/win32/config.gc b/win32/config.gc index e3bd468..de62f2b 100644 --- a/win32/config.gc +++ b/win32/config.gc @@ -343,6 +343,7 @@ d_strcoll='define' d_strctcpy='define' d_strerrm='strerror(e)' d_strerror='define' +d_strftime='define' d_strtod='define' d_strtol='define' d_strtold='undef' diff --git a/win32/config.vc b/win32/config.vc index 0495fd5..6ae23cb 100644 --- a/win32/config.vc +++ b/win32/config.vc @@ -343,6 +343,7 @@ d_strcoll='define' d_strctcpy='define' d_strerrm='strerror(e)' d_strerror='define' +d_strftime='define' d_strtod='define' d_strtol='define' d_strtold='undef' -- 1.8.3.1