pan-users
[Top][All Lists]
Advanced

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

Re: [Pan-users] Date field in Header pane - 12/24 hours?


From: Rhialto
Subject: Re: [Pan-users] Date field in Header pane - 12/24 hours?
Date: Thu, 31 Oct 2013 20:09:42 +0100
User-agent: Mutt/1.5.21 (2010-09-15)

On Thu 31 Oct 2013 at 19:02:36 -0000, Mark Scott wrote:
> IMHO Pan should use the appropriate format based on the system locale
> (LC_TIME) setting.

I have somewhere a little program that overrides the date formatting
routine, since I wanted to do that for Thunderbird. It's Unix-specific
but it works like a charm:

I start Thunderbird like this:

export LD_PRELOAD=$HOME/bin/strftime_override.so
exec /usr/pkg/bin/thunderbird "$@"

where strftime_override.so is the compiled result of this code below.
It just works for the use case of Thunderbird but it can easily be
changed so it matches what Pan does:


# /*
cc -W -Wall -Wformat -Wshadow -shared -fPIC strftime_override.c  -o 
strftime_override.so
exit
*/
/*
 * Compile as shared object (very platform/compile dependend):
 * cc -W -Wall -Wformat -Wshadow -shared % -o strftime_override.so
 *
 * Add -DDEBUG to print the format string passed to strftime() to /dev/tty.
 *
 * Use and test:
 * LD_PRELOAD=./strftime_override.so date +%x
 */

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <dlfcn.h>
#include <errno.h>

#ifdef DEBUG
#include <unistd.h>
#include <fcntl.h>
#endif /* DEBUG */

typedef void (*func_ptr)(void);
typedef size_t (*strftime_func_ptr)(char *, size_t, const char *, const struct 
tm *);

size_t strftime(char *, size_t, const char *, const struct tm *)
        __attribute__((alias ("strftime_hack")));

static func_ptr
get_libc_symbol(const char *symbol)
{
  static void *handle;
  static const func_ptr zero_func;
  func_ptr func = zero_func;

#ifdef RTLD_NEXT
  handle = RTLD_NEXT;
#else /* !RTLD_NEXT */
  if (!handle) {
    handle = dlopen("libc.so", RTLD_NOW);
  }
#endif /* RTLD_NEXT */

  if (handle) {
    func = dlsym(handle, symbol);
    if (!func) {
      errno = ENOSYS;
    }
  } else {
    errno = ENOENT;
  }

  return func;
}

static inline void
trace(const char *format)
{
        (void) format;
#ifdef DEBUG
        {
                int fd = open("/dev/tty", O_WRONLY, 0);
                if (fd >= 0) {
                        write(fd, format, strlen(format));
                        write(fd, "\n", 1);
                        close(fd);
                }
        }
#endif  /* DEBUG */
}


size_t
strftime_real(char *buf, size_t maxsize,
        const char *format, const struct tm *timeptr)
{
        static strftime_func_ptr func;
        if (!func) {
                func = (strftime_func_ptr) get_libc_symbol("strftime");
        }
        return (*func)(buf, maxsize, format, timeptr);
}

static char *months[] = {
    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};

size_t
strftime_hack(char *buf, size_t maxsize,
        const char *format, const struct tm *timeptr)
{
        if (format && buf && maxsize > 0 && timeptr) {
                trace(format);  
                if (0 == strcmp(format, "%x %H:%M")) {
                        size_t len;
                
#if 0
                        len = snprintf(buf, maxsize, "%4u-%02u-%02u %02d:%02d",
                                timeptr->tm_year + 1900,
                                timeptr->tm_mon + 1,
                                timeptr->tm_mday,
                                timeptr->tm_hour,
                                timeptr->tm_min);
#else
                        len = snprintf(buf, maxsize, "%02u-%s-%4u %02d:%02d",
                                timeptr->tm_mday,
                                (timeptr->tm_mon >= 0 && timeptr->tm_mon < 12 ?
                                    months[timeptr->tm_mon] : "***"),
                                timeptr->tm_year + 1900,
                                timeptr->tm_hour,
                                timeptr->tm_min);
#endif
                        return len < maxsize ? len : 0;
                }
                if (0 == strcmp(format, "%H:%M")) {
                        size_t len;
                
                        len = snprintf(buf, maxsize, "%02d:%02d",
                                timeptr->tm_hour,
                                timeptr->tm_min);
                        return len < maxsize ? len : 0;
                }
                /* TODO: Handle more formats */
        }
        return strftime_real(buf, maxsize, format, timeptr);
}

-Olaf.
-- 
___ Olaf 'Rhialto' Seibert  -- The Doctor: No, 'eureka' is Greek for
\X/ rhialto/at/xs4all.nl    -- 'this bath is too hot.'

Attachment: pgpg2Qgx6dzwZ.pgp
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]