@@ -417,15 +417,25 @@ gettmarg(PyObject *args, struct tm *p)
417417}
418418
419419#ifdef HAVE_STRFTIME
420+ #ifdef HAVE_WCSFTIME
421+ #define time_char wchar_t
422+ #define format_time wcsftime
423+ #define time_strlen wcslen
424+ #else
425+ #define time_char char
426+ #define format_time strftime
427+ #define time_strlen strlen
428+ #endif
429+
420430static PyObject *
421431time_strftime (PyObject * self , PyObject * args )
422432{
423433 PyObject * tup = NULL ;
424434 struct tm buf ;
425- const char * fmt ;
426- PyObject * format ;
435+ const time_char * fmt ;
436+ PyObject * format , * tmpfmt ;
427437 size_t fmtlen , buflen ;
428- char * outbuf = 0 ;
438+ time_char * outbuf = 0 ;
429439 size_t i ;
430440
431441 memset ((void * ) & buf , '\0' , sizeof (buf ));
@@ -508,50 +518,70 @@ time_strftime(PyObject *self, PyObject *args)
508518 return NULL ;
509519 }
510520
521+ #ifdef HAVE_WCSFTIME
522+ tmpfmt = PyBytes_FromStringAndSize (NULL ,
523+ sizeof (wchar_t ) * (PyUnicode_GetSize (format )+ 1 ));
524+ if (!tmpfmt )
525+ return NULL ;
526+ /* This assumes that PyUnicode_AsWideChar doesn't do any UTF-16
527+ expansion. */
528+ if (PyUnicode_AsWideChar ((PyUnicodeObject * )format ,
529+ (wchar_t * )PyBytes_AS_STRING (tmpfmt ),
530+ PyUnicode_GetSize (format )+ 1 ) == (size_t )-1 )
531+ /* This shouldn't fail. */
532+ Py_FatalError ("PyUnicode_AsWideChar failed" );
533+ format = tmpfmt ;
534+ fmt = (wchar_t * )PyBytes_AS_STRING (format );
535+ #else
511536 /* Convert the unicode string to an ascii one */
512537 format = PyUnicode_AsEncodedString (format , TZNAME_ENCODING , NULL );
513538 if (format == NULL )
514539 return NULL ;
515540 fmt = PyBytes_AS_STRING (format );
541+ #endif
516542
517543#ifdef MS_WINDOWS
518544 /* check that the format string contains only valid directives */
519- for (outbuf = strchr (fmt , '%' );
545+ for (outbuf = wcschr (fmt , L '%' );
520546 outbuf != NULL ;
521- outbuf = strchr (outbuf + 2 , '%' ))
547+ outbuf = wcschr (outbuf + 2 , L '%' ))
522548 {
523549 if (outbuf [1 ]== '#' )
524550 ++ outbuf ; /* not documented by python, */
525551 if (outbuf [1 ]== '\0' ||
526- !strchr ( "aAbBcdfHIjmMpSUwWxXyYzZ%" , outbuf [1 ]))
552+ !wcschr ( L "aAbBcdfHIjmMpSUwWxXyYzZ%" , outbuf [1 ]))
527553 {
528554 PyErr_SetString (PyExc_ValueError , "Invalid format string" );
529555 return 0 ;
530556 }
531557 }
532558#endif
533559
534- fmtlen = strlen (fmt );
560+ fmtlen = time_strlen (fmt );
535561
536562 /* I hate these functions that presume you know how big the output
537563 * will be ahead of time...
538564 */
539565 for (i = 1024 ; ; i += i ) {
540- outbuf = (char * )PyMem_Malloc (i );
566+ outbuf = (time_char * )PyMem_Malloc (i * sizeof ( time_char ) );
541567 if (outbuf == NULL ) {
542568 Py_DECREF (format );
543569 return PyErr_NoMemory ();
544570 }
545- buflen = strftime (outbuf , i , fmt , & buf );
571+ buflen = format_time (outbuf , i , fmt , & buf );
546572 if (buflen > 0 || i >= 256 * fmtlen ) {
547573 /* If the buffer is 256 times as long as the format,
548574 it's probably not failing for lack of room!
549575 More likely, the format yields an empty result,
550576 e.g. an empty format, or %Z when the timezone
551577 is unknown. */
552578 PyObject * ret ;
579+ #ifdef HAVE_WCSFTIME
580+ ret = PyUnicode_FromWideChar (outbuf , buflen );
581+ #else
553582 ret = PyUnicode_Decode (outbuf , buflen ,
554583 TZNAME_ENCODING , NULL );
584+ #endif
555585 PyMem_Free (outbuf );
556586 Py_DECREF (format );
557587 return ret ;
@@ -568,6 +598,9 @@ time_strftime(PyObject *self, PyObject *args)
568598 }
569599}
570600
601+ #undef time_char
602+ #undef format_time
603+
571604PyDoc_STRVAR (strftime_doc ,
572605"strftime(format[, tuple]) -> string\n\
573606\n\
0 commit comments