diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 2001-04-19 00:54:54 +0000 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2001-04-19 00:54:54 +0000 |
commit | b3c85772f7a16b79e679c78c9638a7afa4856432 (patch) | |
tree | b6a7e16b673c4518a86a2fd1e9f5a4da514b4d2b /util.c | |
parent | e72cf795050cdfe9905e00270c38ba2547626581 (diff) | |
download | perl-b3c85772f7a16b79e679c78c9638a7afa4856432.tar.gz |
Move the strftime() wrapper from POSIX.xs to util.c
as my_strftime(), requires HAS_STRFTIME.
p4raw-id: //depot/perl@9746
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 66 |
1 files changed, 66 insertions, 0 deletions
@@ -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 +} + |