Re: g_strdup_strftime



> I think what you'd have to do is allocate an initial size buffer
> that was most likely large enough (say 256 chararacters) - that
> could be automatic on the stack, and then if necessary, increase
> the size of that buffer until strftime succeeded.

Here's a version I wrote and tested a bit.

    gchar *
    g_strdup_strftime (const gchar *format, const struct tm *time)
      {
        gchar buffer[256];
        size_t length;
        size_t bigger_buffer_size;
        gchar* bigger_buffer;
        
        /* Note that a too-small buffer passed in to strftime results
         * in either a return value of 0 (as specified by the ISO C
         * standard) or the size of the entire buffer (as done in some
         * historical implementations and in glibc).
         */

        /* This function will fail if:
         *
         *     - The underlying strftime returns 0 when the buffer is
         *       too small.
         *     - The format consists only of conversion specifiers that
         *       expand to no characters, like "%p" in a locale where
         *       there is no AM/PM concept.
         *
         * In this case it will loop and exhaust virtual memory.
         * This is a pathological case that doesn't come up if you use
         * either glibc or reasonable conversion specifiers.
         */
        
        /* Handle the case where it fits into a small buffer. */
        length = strftime (buffer, G_N_ELEMENTS (buffer),
                           format, time);
        if ((length != 0 || format[0] == '\0')
            && length < G_N_ELEMENTS (buffer))
          {
            return g_strdup (buffer);
          }

        /* Handle the unusual case where we need a bigger buffer. */
        bigger_buffer_size = G_N_ELEMENTS (buffer);
        do
          {
            bigger_buffer_size *= 2;
            bigger_buffer = g_malloc (bigger_buffer_size);
            length = strftime (bigger_buffer, bigger_buffer_size,
                               format, time);
          }
        while (length == 0 || length >= bigger_buffer_size);
        return bigger_buffer;
      }

Owen, would you consider adding this? Or should I resubmit it in the form of
a patch?

    -- Darin



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]