2006-10-02 [colin] 2.5.2cvs35
authorColin Leroy <colin@colino.net>
Mon, 2 Oct 2006 17:29:24 +0000 (17:29 +0000)
committerColin Leroy <colin@colino.net>
Mon, 2 Oct 2006 17:29:24 +0000 (17:29 +0000)
* src/summaryview.c
Fix double freeze/thaw
* src/common/utils.c
* src/common/utils.h
Reimplement strftime
* src/procheader.c
Use it

ChangeLog
PATCHSETS
configure.ac
src/common/utils.c
src/common/utils.h
src/procheader.c
src/summaryview.c

index 3ac65737efeed73fc06b059de272f37b9d7f2d35..a3d1302f6f55226af8aa61ca539c893899d10d8e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2006-10-02 [colin]     2.5.2cvs35
+
+       * src/summaryview.c
+               Fix double freeze/thaw
+       * src/common/utils.c
+       * src/common/utils.h
+               Reimplement strftime
+       * src/procheader.c
+               Use it
+
+
 2006-10-02 [colin]     2.5.2cvs34
 
        * src/mh.c
index d93d04aea488844949580b94edc628373f665945..f5e6190aba9d02c3564e121f54b6308b18a91ef1 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.79.2.44 -r 1.79.2.45 src/mh.c;  cvs diff -u -r 1.16.2.42 -r 1.16.2.43 src/msgcache.c;  ) > 2.5.2cvs32.patchset
 ( cvs diff -u -r 1.213.2.118 -r 1.213.2.119 src/folder.c;  cvs diff -u -r 1.79.2.45 -r 1.79.2.46 src/mh.c;  cvs diff -u -r 1.9.2.3 -r 1.9.2.4 src/mh.h;  cvs diff -u -r 1.16.2.43 -r 1.16.2.44 src/msgcache.c;  ) > 2.5.2cvs33.patchset
 ( cvs diff -u -r 1.79.2.46 -r 1.79.2.47 src/mh.c;  cvs diff -u -r 1.395.2.259 -r 1.395.2.260 src/summaryview.c;  ) > 2.5.2cvs34.patchset
+( cvs diff -u -r 1.47.2.33 -r 1.47.2.34 src/procheader.c;  cvs diff -u -r 1.395.2.260 -r 1.395.2.261 src/summaryview.c;  cvs diff -u -r 1.36.2.81 -r 1.36.2.82 src/common/utils.c;  cvs diff -u -r 1.20.2.38 -r 1.20.2.39 src/common/utils.h;  ) > 2.5.2cvs35.patchset
index ef62708daa007c5db3ff21fa9dd42befff24aed2..4ff4f4f38576b3d50540269554c9e9154d58a12a 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=5
 MICRO_VERSION=2
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=34
+EXTRA_VERSION=35
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index c0d8b6578cbad2b8201389ee805387a44d46a2cc..733857fd1e24f96064cb4d1fae74b0e956d4e373 100644 (file)
@@ -336,13 +336,9 @@ gchar *itos(gint n)
 
 #define divide(num,divisor,i,d)                \
 {                                      \
-       register int tmp;               \
-       i = num/divisor;                \
-       tmp = i*divisor;                \
-       d = num-tmp;                    \
-       if (d > 1000) d /= 1000;        \
-       else if (d > 100) d /= 100;     \
-       else if (d > 10) d /= 10;               \
+       i = num >> divisor;             \
+       d = num% (1 << divisor);        \
+       d = (d*100) >> divisor;         \
 }
 
 gchar *to_human_readable(off_t size)
@@ -353,8 +349,8 @@ gchar *to_human_readable(off_t size)
        register int t = 0, r = 0;
        if (b_format == NULL) {
                b_format  = _("%dB");
-               kb_format = _("%d.%dKB");
-               mb_format = _("%.2fMB");
+               kb_format = _("%d.%02dKB");
+               mb_format = _("%d.%02dMB");
                gb_format = _("%.2fGB");
        }
        
@@ -362,11 +358,12 @@ gchar *to_human_readable(off_t size)
                g_snprintf(str, sizeof(str), b_format, (gint)size);
                return str;
        } else if (size >> 10 < 1024) {
-               divide(size, (1 << 10), t, r);
+               divide(size, 10, t, r);
                g_snprintf(str, sizeof(str), kb_format, t, r);
                return str;
        } else if (size >> 20 < 1024) {
-               g_snprintf(str, sizeof(str), mb_format, (gfloat)size / (1 << 20));
+               divide(size, 20, t, r);
+               g_snprintf(str, sizeof(str), mb_format, t, r);
                return str;
        } else {
                g_snprintf(str, sizeof(str), gb_format, (gfloat)size / (1 << 30));
@@ -4746,3 +4743,360 @@ gboolean sc_g_slist_bigger(GSList *list, gint max)
        }
        return (i > max);
 }
+
+const gchar *daynames[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+const gchar *monthnames[] = {NULL, NULL, NULL, NULL, NULL, NULL, 
+                            NULL, NULL, NULL, NULL, NULL, NULL};
+const gchar *s_daynames[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+const gchar *s_monthnames[] = {NULL, NULL, NULL, NULL, NULL, NULL, 
+                            NULL, NULL, NULL, NULL, NULL, NULL};
+const gchar *s_am_up = NULL;
+const gchar *s_pm_up = NULL;
+const gchar *s_am_low = NULL;
+const gchar *s_pm_low = NULL;
+const gchar *def_loc_format = NULL;
+const gchar *date_loc_format = NULL;
+const gchar *time_loc_format = NULL;
+const gchar *time_am_pm = NULL;
+
+static gboolean time_names_init_done = FALSE;
+
+static void init_time_names(void)
+{
+       daynames[0] = Q_("Complete day name for use by strftime|Sunday");
+       daynames[1] = Q_("Complete day name for use by strftime|Monday");
+       daynames[2] = Q_("Complete day name for use by strftime|Tuesday");
+       daynames[3] = Q_("Complete day name for use by strftime|Wednesday");
+       daynames[4] = Q_("Complete day name for use by strftime|Thursday");
+       daynames[5] = Q_("Complete day name for use by strftime|Friday");
+       daynames[6] = Q_("Complete day name for use by strftime|Saturday");
+       
+       monthnames[0] = Q_("Complete month name for use by strftime|January");
+       monthnames[1] = Q_("Complete month name for use by strftime|February");
+       monthnames[2] = Q_("Complete month name for use by strftime|March");
+       monthnames[3] = Q_("Complete month name for use by strftime|April");
+       monthnames[4] = Q_("Complete month name for use by strftime|May");
+       monthnames[5] = Q_("Complete month name for use by strftime|June");
+       monthnames[6] = Q_("Complete month name for use by strftime|July");
+       monthnames[7] = Q_("Complete month name for use by strftime|August");
+       monthnames[8] = Q_("Complete month name for use by strftime|September");
+       monthnames[9] = Q_("Complete month name for use by strftime|October");
+       monthnames[10] = Q_("Complete month name for use by strftime|November");
+       monthnames[11] = Q_("Complete month name for use by strftime|December");
+
+       s_daynames[0] = Q_("Abbr. day name for use by strftime|Sun");
+       s_daynames[1] = Q_("Abbr. day name for use by strftime|Mon");
+       s_daynames[2] = Q_("Abbr. day name for use by strftime|Tue");
+       s_daynames[3] = Q_("Abbr. day name for use by strftime|Wed");
+       s_daynames[4] = Q_("Abbr. day name for use by strftime|Thu");
+       s_daynames[5] = Q_("Abbr. day name for use by strftime|Fri");
+       s_daynames[6] = Q_("Abbr. day name for use by strftime|Sat");
+       
+       s_monthnames[0] = Q_("Abbr. month name for use by strftime|Jan");
+       s_monthnames[1] = Q_("Abbr. month name for use by strftime|Feb");
+       s_monthnames[2] = Q_("Abbr. month name for use by strftime|Mar");
+       s_monthnames[3] = Q_("Abbr. month name for use by strftime|Apr");
+       s_monthnames[4] = Q_("Abbr. month name for use by strftime|May");
+       s_monthnames[5] = Q_("Abbr. month name for use by strftime|Jun");
+       s_monthnames[6] = Q_("Abbr. month name for use by strftime|Jul");
+       s_monthnames[7] = Q_("Abbr. month name for use by strftime|Aug");
+       s_monthnames[8] = Q_("Abbr. month name for use by strftime|Sep");
+       s_monthnames[9] = Q_("Abbr. month name for use by strftime|Oct");
+       s_monthnames[10] = Q_("Abbr. month name for use by strftime|Nov");
+       s_monthnames[11] = Q_("Abbr. month name for use by strftime|Dec");
+
+       s_am_up = Q_("For use by strftime (morning)|AM");
+       s_pm_up = Q_("For use by strftime (afternoon)|PM");
+       s_am_low = Q_("For use by strftime (morning, lowercase)|am");
+       s_pm_low = Q_("For use by strftime (afternoon, lowercase)|pm");
+       
+       def_loc_format = Q_("For use by strftime (default date+time format)|%a %b %e %H:%M:%S %Y");
+       date_loc_format = Q_("For use by strftime (default date format)|%m/%d/%y");
+       time_loc_format = Q_("For use by strftime (default time format)|%H:%M:%S");
+
+       time_am_pm = Q_("For use by strftime (default 12-hour time format)|%I:%M:%S %p");
+
+       time_names_init_done = TRUE;
+#if 0
+       {
+       struct tm *lt;
+       time_t now = time(NULL), next;
+       gchar buf_a[1024], buf_b[1024];
+       
+       printf("test strftime:\n");
+       tzset();
+       for (next = now; next < now + 86400*365*2; next++) {
+               lt = localtime(&now);
+               strftime(buf_a, 1024, 
+                       "%a,%A,%b,%B,%c,%C,%d,%D,%e,%F,%G,%g,%h,%H,%I "
+                       "%j,%k,%l,%m,%M,%n,%p,%P,%r,%R,%s,%S,%t,%T,%u,%U,%V"
+                       "%w,%W,%x,%X,%y,%Y,%z,%Z,%%,%EY,%OY", lt);
+               fast_strftime(buf_b, 1024, 
+                       "%a,%A,%b,%B,%c,%C,%d,%D,%e,%F,%G,%g,%h,%H,%I "
+                       "%j,%k,%l,%m,%M,%n,%p,%P,%r,%R,%s,%S,%t,%T,%u,%U,%V"
+                       "%w,%W,%x,%X,%y,%Y,%z,%Z,%%,%EY,%OY", lt);
+               if (strcmp(buf_a, buf_b)) {
+                       printf("diff: \n%s\n%s\n", buf_a, buf_b);
+               }
+       }
+       }
+#endif
+}
+
+#define CHECK_SIZE() {                 \
+       total_done += len;              \
+       if (total_done >= buflen) {     \
+               buf[buflen-1] = '\0';   \
+               return 0;               \
+       }                               \
+}
+
+size_t fast_strftime(gchar *buf, gint buflen, const gchar *format, struct tm *lt)
+{
+       gchar *curpos = buf;
+       gint total_done = 0;
+       gchar subbuf[64], subfmt[64];
+       static time_t last_tzset = (time_t)0;
+       
+       if (!time_names_init_done)
+               init_time_names();
+       
+       if (format == NULL || lt == NULL)
+               return 0;
+               
+       if (last_tzset != time(NULL)) {
+               tzset();
+               last_tzset = time(NULL);
+       }
+       while(*format) {
+               if (*format == '%') {
+                       gint len = 0, tmp = 0;
+                       format++;
+                       switch(*format) {
+                       case '%':
+                               len = 1; CHECK_SIZE();
+                               *curpos = '%';
+                               break;
+                       case 'a':
+                               len = strlen(s_daynames[lt->tm_wday]); CHECK_SIZE();
+                               strncpy2(curpos, s_daynames[lt->tm_wday], buflen - total_done);
+                               break;
+                       case 'A':
+                               len = strlen(daynames[lt->tm_wday]); CHECK_SIZE();
+                               strncpy2(curpos, daynames[lt->tm_wday], buflen - total_done);
+                               break;
+                       case 'b':
+                       case 'h':
+                               len = strlen(s_monthnames[lt->tm_mon]); CHECK_SIZE();
+                               strncpy2(curpos, s_monthnames[lt->tm_mon], buflen - total_done);
+                               break;
+                       case 'B':
+                               len = strlen(monthnames[lt->tm_mon]); CHECK_SIZE();
+                               strncpy2(curpos, monthnames[lt->tm_mon], buflen - total_done);
+                               break;
+                       case 'c':
+                               fast_strftime(subbuf, 64, def_loc_format, lt);
+                               len = strlen(subbuf); CHECK_SIZE();
+                               strncpy2(curpos, subbuf, buflen - total_done);
+                               break;
+                       case 'C':
+                               total_done += 2; CHECK_SIZE();
+                               tmp = (lt->tm_year + 1900)/100;
+                               *curpos++ = '0'+(tmp / 10);
+                               *curpos++ = '0'+(tmp % 10);
+                               break;
+                       case 'd':
+                               total_done += 2; CHECK_SIZE();
+                               *curpos++ = '0'+(lt->tm_mday / 10);
+                               *curpos++ = '0'+(lt->tm_mday % 10);
+                               break;
+                       case 'D':
+                               total_done += 8; CHECK_SIZE();
+                               *curpos++ = '0'+((lt->tm_mon+1) / 10);
+                               *curpos++ = '0'+((lt->tm_mon+1) % 10);
+                               *curpos++ = '/';
+                               *curpos++ = '0'+(lt->tm_mday / 10);
+                               *curpos++ = '0'+(lt->tm_mday % 10);
+                               *curpos++ = '/';
+                               tmp = lt->tm_year%100;
+                               *curpos++ = '0'+(tmp / 10);
+                               *curpos++ = '0'+(tmp % 10);
+                               break;
+                       case 'e':
+                               len = 2; CHECK_SIZE();
+                               snprintf(curpos, buflen - total_done, "%2d", lt->tm_mday);
+                               break;
+                       case 'F':
+                               len = 10; CHECK_SIZE();
+                               snprintf(curpos, buflen - total_done, "%4d-%02d-%02d", 
+                                       lt->tm_year + 1900, lt->tm_mon +1, lt->tm_mday);
+                               break;
+                       case 'H':
+                               total_done += 2; CHECK_SIZE();
+                               *curpos++ = '0'+(lt->tm_hour / 10);
+                               *curpos++ = '0'+(lt->tm_hour % 10);
+                               break;
+                       case 'I':
+                               total_done += 2; CHECK_SIZE();
+                               tmp = lt->tm_hour;
+                               if (tmp > 12)
+                                       tmp -= 12;
+                               else if (tmp == 0)
+                                       tmp = 12;
+                               *curpos++ = '0'+(tmp / 10);
+                               *curpos++ = '0'+(tmp % 10);
+                               break;
+                       case 'j':
+                               len = 3; CHECK_SIZE();
+                               snprintf(curpos, buflen - total_done, "%03d", lt->tm_yday+1);
+                               break;
+                       case 'k':
+                               len = 2; CHECK_SIZE();
+                               snprintf(curpos, buflen - total_done, "%2d", lt->tm_hour);
+                               break;
+                       case 'l':
+                               len = 2; CHECK_SIZE();
+                               tmp = lt->tm_hour;
+                               if (tmp > 12)
+                                       tmp -= 12;
+                               else if (tmp == 0)
+                                       tmp = 12;
+                               snprintf(curpos, buflen - total_done, "%2d", tmp);
+                               break;
+                       case 'm':
+                               total_done += 2; CHECK_SIZE();
+                               tmp = lt->tm_mon + 1;
+                               *curpos++ = '0'+(tmp / 10);
+                               *curpos++ = '0'+(tmp % 10);
+                               break;
+                       case 'M':
+                               total_done += 2; CHECK_SIZE();
+                               *curpos++ = '0'+(lt->tm_min / 10);
+                               *curpos++ = '0'+(lt->tm_min % 10);
+                               break;
+                       case 'n':
+                               len = 1; CHECK_SIZE();
+                               *curpos = '\n';
+                               break;
+                       case 'p':
+                               if (lt->tm_hour >= 12) {
+                                       len = strlen(s_pm_up); CHECK_SIZE();
+                                       snprintf(curpos, buflen-total_done, s_pm_up);
+                               } else {
+                                       len = strlen(s_am_up); CHECK_SIZE();
+                                       snprintf(curpos, buflen-total_done, s_am_up);
+                               }
+                               break;
+                       case 'P':
+                               if (lt->tm_hour >= 12) {
+                                       len = strlen(s_pm_low); CHECK_SIZE();
+                                       snprintf(curpos, buflen-total_done, s_pm_low);
+                               } else {
+                                       len = strlen(s_am_low); CHECK_SIZE();
+                                       snprintf(curpos, buflen-total_done, s_am_low);
+                               }
+                               break;
+                       case 'r':
+                               fast_strftime(subbuf, 64, time_am_pm, lt);
+                               len = strlen(subbuf); CHECK_SIZE();
+                               strncpy2(curpos, subbuf, buflen - total_done);
+                               break;
+                       case 'R':
+                               total_done += 5; CHECK_SIZE();
+                               *curpos++ = '0'+(lt->tm_hour / 10);
+                               *curpos++ = '0'+(lt->tm_hour % 10);
+                               *curpos++ = ':';
+                               *curpos++ = '0'+(lt->tm_min / 10);
+                               *curpos++ = '0'+(lt->tm_min % 10);
+                               break;
+                       case 's':
+                               snprintf(subbuf, buflen - total_done, "%ld", mktime(lt));
+                               len = strlen(subbuf); CHECK_SIZE();
+                               strncpy2(curpos, subbuf, buflen - total_done);
+                               break;
+                       case 'S':
+                               total_done += 2; CHECK_SIZE();
+                               *curpos++ = '0'+(lt->tm_sec / 10);
+                               *curpos++ = '0'+(lt->tm_sec % 10);
+                               break;
+                       case 't':
+                               len = 1; CHECK_SIZE();
+                               *curpos = '\t';
+                               break;
+                       case 'T':
+                               total_done += 8; CHECK_SIZE();
+                               *curpos++ = '0'+(lt->tm_hour / 10);
+                               *curpos++ = '0'+(lt->tm_hour % 10);
+                               *curpos++ = ':';
+                               *curpos++ = '0'+(lt->tm_min / 10);
+                               *curpos++ = '0'+(lt->tm_min % 10);
+                               *curpos++ = ':';
+                               *curpos++ = '0'+(lt->tm_sec / 10);
+                               *curpos++ = '0'+(lt->tm_sec % 10);
+                               break;
+                       case 'u':
+                               len = 1; CHECK_SIZE();
+                               snprintf(curpos, buflen - total_done, "%d", lt->tm_wday == 0 ? 7: lt->tm_wday);
+                               break;
+                       case 'w':
+                               len = 1; CHECK_SIZE();
+                               snprintf(curpos, buflen - total_done, "%d", lt->tm_wday);
+                               break;
+                       case 'x':
+                               fast_strftime(subbuf, 64, date_loc_format, lt);
+                               len = strlen(subbuf); CHECK_SIZE();
+                               strncpy2(curpos, subbuf, buflen - total_done);
+                               break;
+                       case 'X':
+                               fast_strftime(subbuf, 64, time_loc_format, lt);
+                               len = strlen(subbuf); CHECK_SIZE();
+                               strncpy2(curpos, subbuf, buflen - total_done);
+                               break;
+                       case 'y':
+                               total_done += 2; CHECK_SIZE();
+                               tmp = lt->tm_year%100;
+                               *curpos++ = '0'+(tmp / 10);
+                               *curpos++ = '0'+(tmp % 10);
+                               break;
+                       case 'Y':
+                               len = 4; CHECK_SIZE();
+                               snprintf(curpos, buflen - total_done, "%4d", lt->tm_year + 1900);
+                               break;
+                       case 'G':
+                       case 'g':
+                       case 'U':
+                       case 'V':
+                       case 'W':
+                       case 'z':
+                       case 'Z':
+                       case '+':
+                               /* let these complicated ones be done with the libc */
+                               snprintf(subfmt, 64, "%%%c", *format);
+                               strftime(subbuf, 64, subfmt, lt);
+                               len = strlen(subbuf); CHECK_SIZE();
+                               strncpy2(curpos, subbuf, buflen - total_done);
+                               break;
+                       case 'E':
+                       case 'O':
+                               /* let these complicated modifiers be done with the libc */
+                               snprintf(subfmt, 64, "%%%c%c", *format, *(format+1));
+                               strftime(subbuf, 64, subfmt, lt);
+                               len = strlen(subbuf); CHECK_SIZE();
+                               strncpy2(curpos, subbuf, buflen - total_done);
+                               format++;
+                               break;
+                       default:
+                               g_warning("format error (%c)", *format);
+                               *curpos = '\0';
+                               return total_done;
+                       }
+                       curpos += len;
+                       format++;
+               } else {
+                       int len = 1; CHECK_SIZE();
+                       *curpos++ = *format++; 
+               }
+       }
+       *curpos++ = '\0';
+       return total_done;
+}
index c5b2e9440d3b261099893d7342c881fba51f0cd2..824c980f51eb0acae51459c8cff3739089f8083d 100644 (file)
@@ -474,6 +474,10 @@ size_t my_strftime         (gchar                  *s,
                                 size_t                  max,
                                 const gchar            *format,
                                 const struct tm        *tm);
+size_t fast_strftime           (gchar                  *buf, 
+                                gint                    buflen, 
+                                const gchar            *format, 
+                                struct tm              *lt);
 
 /* debugging */
 void debug_print_real  (const gchar *format, ...) G_GNUC_PRINTF(1, 2);
index 54ffa4bf524dc9edc4b999837dad16d6fc15d385..e5ffff366b2556f4a5acce2d255d28bc9491840e 100644 (file)
@@ -912,9 +912,9 @@ void procheader_date_get_localtime(gchar *dest, gint len, const time_t timer)
        lt = localtime(&timer);
 
        if (prefs_common.date_format)
-               strftime(dest, len, prefs_common.date_format, lt);
+               fast_strftime(dest, len, prefs_common.date_format, lt);
        else
-               strftime(dest, len, default_format, lt);
+               fast_strftime(dest, len, default_format, lt);
 
        if (!g_utf8_validate(dest, -1, NULL)) {
                src_codeset = conv_get_locale_charset_str_no_utf8();
index ff260a2d191b0e05204d64b266e2e34dbb952cb0..852078e2c08d362af5af85ba6bceec8ce2253945 100644 (file)
@@ -2493,7 +2493,6 @@ void summary_sort(SummaryView *summaryview,
 
                main_window_cursor_wait(summaryview->mainwin);
 
-                summary_freeze(summaryview);
                gtk_clist_set_compare_func(clist, cmp_func);
 
                gtk_clist_set_sort_type(clist, (GtkSortType)sort_type);
@@ -2502,7 +2501,6 @@ void summary_sort(SummaryView *summaryview,
                gtk_ctree_node_moveto(ctree, summaryview->selected, 0, 0.5, 0);
 
                main_window_cursor_normal(summaryview->mainwin);
-                summary_thaw(summaryview);
 
                debug_print("done.\n");
                STATUSBAR_POP(summaryview->mainwin);