Move the strftime() wrapper from POSIX.xs to util.c
Jarkko Hietaniemi [Thu, 19 Apr 2001 00:54:54 +0000 (00:54 +0000)]
as my_strftime(), requires HAS_STRFTIME.

p4raw-id: //depot/perl@9746

21 files changed:
Configure
Porting/Glossary
Porting/config.sh
Porting/config_H
config_h.SH
configure.com
embed.h
embed.pl
epoc/config.sh
ext/POSIX/POSIX.xs
proto.h
uconfig.h
uconfig.sh
util.c
vos/config.alpha.def
vos/config.alpha.h
vos/config.ga.def
vos/config.ga.h
win32/config.bc
win32/config.gc
win32/config.vc

index c2034e1..4531138 100755 (executable)
--- 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$$ <<EOF
@@ -567,6 +567,7 @@ d_strerrm=''
 d_strerror=''
 d_sysernlst=''
 d_syserrlst=''
+d_strftime=''
 d_strtod=''
 d_strtol=''
 d_strtold=''
@@ -12229,6 +12230,10 @@ if test "X$d_strerror" = X -o "X$d_syserrlst" = X; then
     fi
 fi
 
+: see if strftime exists
+set strftime d_strftime
+eval $inlibc
+
 : see if strtod exists
 set strtod d_strtod
 eval $inlibc
@@ -16407,6 +16412,7 @@ d_strcoll='$d_strcoll'
 d_strctcpy='$d_strctcpy'
 d_strerrm='$d_strerrm'
 d_strerror='$d_strerror'
+d_strftime='$d_strftime'
 d_strtod='$d_strtod'
 d_strtol='$d_strtol'
 d_strtold='$d_strtold'
index d621d2f..4507f19 100644 (file)
@@ -1584,6 +1584,10 @@ d_strerror (d_strerror.U):
        This variable conditionally defines HAS_STRERROR if strerror() is
        available to translate error numbers to strings.
 
+d_strftime (d_strftime.U):
+       This variable conditionally defines the HAS_STRFTIME symbol, which
+       indicates to the C program that the strftime() routine is available.
+
 d_strtod (d_strtod.U):
        This variable conditionally defines the HAS_STRTOD symbol, which
        indicates to the C program that the strtod() routine is available
index 05bbeb7..415fa44 100644 (file)
@@ -8,7 +8,7 @@
 
 # Package name      : perl5
 # Source directory  : .
-# Configuration time: Sun Apr  8 02:05:27 EET DST 2001
+# Configuration time: Thu Apr 19 03:59:37 EET DST 2001
 # Configured by     : jhi
 # Target system     : osf1 alpha.hut.fi v4.0 878 alpha 
 
@@ -62,7 +62,7 @@ ccsymbols='__alpha=1 __LANGUAGE_C__=1 __osf__=1 __unix__=1 _LONGLONG=1 _SYSTYPE_
 ccversion='V5.6-082'
 cf_by='jhi'
 cf_email='yourname@yourhost.yourplace.com'
-cf_time='Sun Apr  8 02:05:27 EET DST 2001'
+cf_time='Thu Apr 19 03:59:37 EET DST 2001'
 charsize='1'
 chgrp=''
 chmod=''
@@ -360,6 +360,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'
@@ -415,7 +416,7 @@ dlext='so'
 dlsrc='dl_dlopen.xs'
 doublesize='8'
 drand01='drand48()'
-dynamic_ext='B ByteLoader Cwd DB_File Data/Dumper Devel/DProf Devel/Peek Digest/MD5 Encode Fcntl File/Glob Filter/Util/Call IO IPC/SysV MIME/Base64 NDBM_File ODBM_File Opcode POSIX PerlIO/Scalar PerlIO/Via SDBM_File Socket Storable Sys/Hostname Sys/Syslog Thread XS/Typemap attrs re'
+dynamic_ext='B ByteLoader Cwd DB_File Data/Dumper Devel/DProf Devel/Peek Digest/MD5 Encode Fcntl File/Glob Filter/Util/Call IO IPC/SysV List/Util MIME/Base64 NDBM_File ODBM_File Opcode POSIX PerlIO/Scalar PerlIO/Via SDBM_File Socket Storable Sys/Hostname Sys/Syslog Thread Time/HiRes XS/Typemap attrs re'
 eagain='EAGAIN'
 ebcdic='undef'
 echo='echo'
@@ -424,7 +425,7 @@ emacs=''
 eunicefix=':'
 exe_ext=''
 expr='expr'
-extensions='B ByteLoader Cwd DB_File Data/Dumper Devel/DProf Devel/Peek Digest/MD5 Encode Fcntl File/Glob Filter/Util/Call IO IPC/SysV MIME/Base64 NDBM_File ODBM_File Opcode POSIX PerlIO/Scalar PerlIO/Via SDBM_File Socket Storable Sys/Hostname Sys/Syslog Thread XS/Typemap attrs re Errno'
+extensions='B ByteLoader Cwd DB_File Data/Dumper Devel/DProf Devel/Peek Digest/MD5 Encode Fcntl File/Glob Filter/Util/Call IO IPC/SysV List/Util MIME/Base64 NDBM_File ODBM_File Opcode POSIX PerlIO/Scalar PerlIO/Via SDBM_File Socket Storable Sys/Hostname Sys/Syslog Thread Time/HiRes XS/Typemap attrs re Errno'
 fflushNULL='define'
 fflushall='undef'
 find=''
@@ -564,7 +565,7 @@ issymlink='test -h'
 ivdformat='"ld"'
 ivsize='8'
 ivtype='long'
-known_extensions='B ByteLoader Cwd DB_File Data/Dumper Devel/DProf Devel/Peek Digest/MD5 Encode Fcntl File/Glob Filter/Util/Call GDBM_File IO IPC/SysV MIME/Base64 NDBM_File ODBM_File Opcode POSIX PerlIO/Scalar PerlIO/Via SDBM_File Socket Storable Sys/Hostname Sys/Syslog Thread XS/Typemap attrs re'
+known_extensions='B ByteLoader Cwd DB_File Data/Dumper Devel/DProf Devel/Peek Digest/MD5 Encode Fcntl File/Glob Filter/Util/Call GDBM_File IO IPC/SysV List/Util MIME/Base64 NDBM_File ODBM_File Opcode POSIX PerlIO/Scalar PerlIO/Via SDBM_File Socket Storable Sys/Hostname Sys/Syslog Thread Time/HiRes XS/Typemap attrs re'
 ksh=''
 ld='ld'
 lddlflags='-shared -expect_unresolved "*" -msym -std -s'
index 7f3f8ab..98150fc 100644 (file)
@@ -17,7 +17,7 @@
 /*
  * Package name      : perl5
  * Source directory  : .
- * Configuration time: Sun Apr  8 02:05:27 EET DST 2001
+ * Configuration time: Thu Apr 19 03:59:37 EET DST 2001
  * Configured by     : jhi
  * Target system     : osf1 alpha.hut.fi v4.0 878 alpha 
  */
  */
 /*#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.
index 0b828e6..9188b79 100644 (file)
@@ -3346,6 +3346,12 @@ sed <<!GROK!THIS! >$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.
index fa06d20..ff86731 100644 (file)
@@ -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 (file)
--- a/embed.h
+++ b/embed.h
 #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
 #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)
 #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
index 3d0160d..99e063f 100755 (executable)
--- 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
index 90b7e70..0b5fa90 100644 (file)
@@ -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'
index 7658b39..3e273b0 100644 (file)
@@ -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 (file)
--- 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);
index 6914151..dd57e19 100644 (file)
--- a/uconfig.h
+++ b/uconfig.h
  */
 /*#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.
index 9ded43b..ed31a3d 100755 (executable)
@@ -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 (file)
--- 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
+}
+
index 1242114..a6f03b3 100644 (file)
@@ -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'
index c4291f9..774abae 100644 (file)
  */
 #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
index 63d2aa9..402428d 100644 (file)
@@ -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'
index 642b65b..da40b86 100644 (file)
  */
 #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
index b859846..81722b5 100644 (file)
@@ -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'
index e3bd468..de62f2b 100644 (file)
@@ -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'
index 0495fd5..6ae23cb 100644 (file)
@@ -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'