On 8/12/20 6:25 AM, Robert Elz wrote:
I think it might be just %Z (rarely) and %p (sometimes) which ever produce an empty string. How many of those other APIs would ever be given either "%Z" or "%p" as their arg?
It's pretty common to design a general-purpose API that is a wrapper around strftime. For example, Emacs has a function 'emacs_nmemftime' that is a wrapper around strftime that also allows formats containing NUL bytes (as these are allowed in Emacs strings). An Emacs Lisp program supplied by the user can invoke (format-time-string "%p") which invokes emacs_nmemftime which in turn invokes strftime with a "%p" argument. (The actual code is a bit more complicated than this, but for now let's assume this simpler version.) Now, emacs_nmemftime could be modified to treat formats like "%p%Z" as special cases, and format " %p%Z" instead and discard the leading space in the output. Or, we could modify emacs_nmemftime to always make a copy of the format with an extra space in it, call strftime, and then remove the leading space in the result. Or, we could document 'format-time-string' to mishandle formats like "%p%Z" in some cases. But none of these alternatives are good, for obvious reasons. They're all hacks to work around the deficiency in the C11 strftime API. Since POSIX is fixing strftime errno deficiencies anyway in other areas, by defining what to do with out-of-range times, it might as well fix this deficiency with "%p" too, while it's at it.
The problem with this one is that all implementations need to support it, or it is worthless.
That same objection applies to the EOVERFLOW errno change that is already in the POSIX strftime draft, as well as to many of the other changes in the POSIX draft, so evidently it's not a fatal objection.
[for mktime] ... In most cases it is safe to simply assume that won't be the case, and simply treat -1 as the error indicator only That isn't safe in general-purpose routines.
when more is needed, the check is not all that difficult (after a successful return, which is what it would be if the -1 indicates that 1969 date, the tm has been normalised, Dec 31, 1969 was a Wednesday, so set tm_wday to 0, and then check if on return it has become 3 or 4
I've used that hack too, but neither POSIX nor C11 require the hack to work. What I'd propose is that the standard specifies that mktime must not not update tm_yday when it fails. This matches all implementations that I know of, and allows the hack to work. The variant that I use is to set tm_yday to -1 before calling mktime, and test whether it's negative afterwards.
Another way, if -1 is returned, is to take the original struct tm do tm_sec++ and then mktime() again.
This won't work if tm_sec == INT_MAX.