[rhythmbox] use g_date_time_format instead of eel_strdup_strftime (bug #647032, #647050)



commit c8e1896ecdc7ae54e46c4950dcd0dd8e0cdbac1f
Author: Jonathan Matthew <jonathan d14n org>
Date:   Fri May 20 08:33:19 2011 +1000

    use g_date_time_format instead of eel_strdup_strftime (bug #647032, #647050)
    
    g_date_time_format supports a wider range of format specifiers,
    including some that eel_strdup_strftime didn't support but have been
    used in translations for years (oops).
    
    Also return "Never" instead of NULL in rb_utf_friendly_time, since
    that isn't such an obviously incorrect case that it should be treated
    as an error.  This fixes some weird crashes.

 lib/rb-cut-and-paste-code.c |  223 ++++++-------------------------------------
 lib/rb-cut-and-paste-code.h |    3 -
 2 files changed, 30 insertions(+), 196 deletions(-)
---
diff --git a/lib/rb-cut-and-paste-code.c b/lib/rb-cut-and-paste-code.c
index 5b4d668..7880dd9 100644
--- a/lib/rb-cut-and-paste-code.c
+++ b/lib/rb-cut-and-paste-code.c
@@ -79,230 +79,64 @@ eel_create_colorized_pixbuf (GdkPixbuf *src,
 	return dest;
 }
 
-/* Legal conversion specifiers, as specified in the C standard. */
-#define C_STANDARD_STRFTIME_CHARACTERS "aAbBcdHIjmMpSUwWxXyYZ"
-#define C_STANDARD_NUMERIC_STRFTIME_CHARACTERS "dHIjmMSUwWyY"
-#define SUS_EXTENDED_STRFTIME_MODIFIERS "EO"
-
-/**
- * eel_strdup_strftime:
- *
- * Cover for standard date-and-time-formatting routine strftime that returns
- * a newly-allocated string of the correct size. The caller is responsible
- * for g_free-ing the returned string.
- *
- * Besides the buffer management, there are two differences between this
- * and the library strftime:
- *
- *   1) The modifiers "-" and "_" between a "%" and a numeric directive
- *      are defined as for the GNU version of strftime. "-" means "do not
- *      pad the field" and "_" means "pad with spaces instead of zeroes".
- *   2) Non-ANSI extensions to strftime are flagged at runtime with a
- *      warning, so it's easy to notice use of the extensions without
- *      testing with multiple versions of the library.
- *
- * @format: format string to pass to strftime. See strftime documentation
- * for details.
- * @time_pieces: date/time, in struct format.
- *
- * Return value: Newly allocated string containing the formatted time.
- **/
-char *
-eel_strdup_strftime (const char *format, struct tm *time_pieces)
-{
-	GString *string;
-	const char *remainder, *percent;
-	char code[4], buffer[512];
-	char *piece, *result, *converted;
-	size_t string_length;
-	gboolean strip_leading_zeros, turn_leading_zeros_to_spaces;
-	char modifier;
-	int i;
-
-	/* Format could be translated, and contain UTF-8 chars,
-	 * so convert to locale encoding which strftime uses */
-	converted = g_locale_from_utf8 (format, -1, NULL, NULL, NULL);
-	g_return_val_if_fail (converted != NULL, NULL);
-
-	string = g_string_new ("");
-	remainder = converted;
-
-	/* Walk from % character to % character. */
-	for (;;) {
-		percent = strchr (remainder, '%');
-		if (percent == NULL) {
-			g_string_append (string, remainder);
-			break;
-		}
-		g_string_append_len (string, remainder,
-				     percent - remainder);
-
-		/* Handle the "%" character. */
-		remainder = percent + 1;
-		switch (*remainder) {
-		case '-':
-			strip_leading_zeros = TRUE;
-			turn_leading_zeros_to_spaces = FALSE;
-			remainder++;
-			break;
-		case '_':
-			strip_leading_zeros = FALSE;
-			turn_leading_zeros_to_spaces = TRUE;
-			remainder++;
-			break;
-		case '%':
-			g_string_append_c (string, '%');
-			remainder++;
-			continue;
-		case '\0':
-			g_warning ("Trailing %% passed to eel_strdup_strftime");
-			g_string_append_c (string, '%');
-			continue;
-		default:
-			strip_leading_zeros = FALSE;
-			turn_leading_zeros_to_spaces = FALSE;
-			break;
-		}
-
-		modifier = 0;
-		if (strchr (SUS_EXTENDED_STRFTIME_MODIFIERS, *remainder) != NULL) {
-			modifier = *remainder;
-			remainder++;
-
-			if (*remainder == 0) {
-				g_warning ("Unfinished %%%c modifier passed to eel_strdup_strftime", modifier);
-				break;
-			}
-		}
-
-		if (strchr (C_STANDARD_STRFTIME_CHARACTERS, *remainder) == NULL) {
-			g_warning ("eel_strdup_strftime does not support "
-				   "non-standard escape code %%%c",
-				   *remainder);
-		}
-
-		/* Convert code to strftime format. We have a fixed
-		 * limit here that each code can expand to a maximum
-		 * of 512 bytes, which is probably OK. There's no
-		 * limit on the total size of the result string.
-		 */
-		i = 0;
-		code[i++] = '%';
-		if (modifier != 0) {
-#ifdef HAVE_STRFTIME_EXTENSION
-			code[i++] = modifier;
-#endif
-		}
-		code[i++] = *remainder;
-		code[i++] = '\0';
-		string_length = strftime (buffer, sizeof (buffer),
-					  code, time_pieces);
-		if (string_length == 0) {
-			/* We could put a warning here, but there's no
-			 * way to tell a successful conversion to
-			 * empty string from a failure.
-			 */
-			buffer[0] = '\0';
-		}
-
-		/* Strip leading zeros if requested. */
-		piece = buffer;
-		if (strip_leading_zeros || turn_leading_zeros_to_spaces) {
-			if (strchr (C_STANDARD_NUMERIC_STRFTIME_CHARACTERS, *remainder) == NULL) {
-				g_warning ("eel_strdup_strftime does not support "
-					   "modifier for non-numeric escape code %%%c%c",
-					   remainder[-1],
-					   *remainder);
-			}
-			if (*piece == '0') {
-				do {
-					piece++;
-				} while (*piece == '0');
-				if (!g_ascii_isdigit (*piece)) {
-				    piece--;
-				}
-			}
-			if (turn_leading_zeros_to_spaces) {
-				memset (buffer, ' ', piece - buffer);
-				piece = buffer;
-			}
-		}
-		remainder++;
-
-		/* Add this piece. */
-		g_string_append (string, piece);
-	}
-
-	/* Convert the string back into utf-8. */
-	result = g_locale_to_utf8 (string->str, -1, NULL, NULL, NULL);
-
-	g_string_free (string, TRUE);
-	g_free (converted);
-
-	return result;
-}
-
 /* Based on evolution/mail/message-list.c:filter_date() */
 char *
 rb_utf_friendly_time (time_t date)
 {
-	time_t nowdate;
-	time_t yesdate;
-	struct tm then, now, yesterday;
+	GDateTime *datetime, *now, *yesterday;
+	int d, m, y;
+	int nd, nm, ny;
+	int yd, ym, yy;
 	const char *format = NULL;
 	char *str = NULL;
-	gboolean done = FALSE;
 
-	nowdate = time (NULL);
+	if (date == 0) {
+		return g_strdup (_("Never"));
+	}
 
-	if (date == 0)
-		return NULL;
+	now = g_date_time_new_now_local ();
+	datetime = g_date_time_new_from_unix_local (date);
 
-	localtime_r (&date, &then);
-	localtime_r (&nowdate, &now);
+	g_date_time_get_ymd (datetime, &y, &m, &d);
+	g_date_time_get_ymd (now, &ny, &nm, &nd);
 
-	if (then.tm_mday == now.tm_mday &&
-	    then.tm_mon == now.tm_mon &&
-	    then.tm_year == now.tm_year) {
+	if (y == ny && m == nm && d == nd) {
 		/* Translators: "friendly time" string for the current day, strftime format. like "Today 12:34 am" */
 		format = _("Today %I:%M %p");
-		done = TRUE;
 	}
 
-	if (! done) {
-		yesdate = nowdate - 60 * 60 * 24;
-		localtime_r (&yesdate, &yesterday);
-		if (then.tm_mday == yesterday.tm_mday &&
-		    then.tm_mon == yesterday.tm_mon &&
-		    then.tm_year == yesterday.tm_year) {
+	if (format == NULL) {
+		yesterday = g_date_time_add_days (now, -1);
+
+		g_date_time_get_ymd (yesterday, &yy, &ym, &yd);
+		if (y == yy && m == ym && d == yd) {
 			/* Translators: "friendly time" string for the previous day,
 			 * strftime format. e.g. "Yesterday 12:34 am"
 			 */
 			format = _("Yesterday %I:%M %p");
-			done = TRUE;
 		}
+		g_date_time_unref (yesterday);
 	}
 
-	if (! done) {
+	if (format == NULL) {
 		int i;
 		for (i = 2; i < 7; i++) {
-			yesdate = nowdate - 60 * 60 * 24 * i;
-			localtime_r (&yesdate, &yesterday);
-			if (then.tm_mday == yesterday.tm_mday &&
-			    then.tm_mon == yesterday.tm_mon &&
-			    then.tm_year == yesterday.tm_year) {
+			yesterday = g_date_time_add_days (now, -i);
+			g_date_time_get_ymd (yesterday, &yy, &ym, &yd);
+			if (y == yy && m == ym && d == yd) {
 				/* Translators: "friendly time" string for a day in the current week,
 				 * strftime format. e.g. "Wed 12:34 am"
 				 */
 				format = _("%a %I:%M %p");
-				done = TRUE;
+				g_date_time_unref (yesterday);
 				break;
 			}
+			g_date_time_unref (yesterday);
 		}
 	}
 
-	if (! done) {
-		if (then.tm_year == now.tm_year) {
+	if (format == NULL) {
+		if (y == ny) {
 			/* Translators: "friendly time" string for a day in the current year,
 			 * strftime format. e.g. "Feb 12 12:34 am"
 			 */
@@ -316,7 +150,7 @@ rb_utf_friendly_time (time_t date)
 	}
 
 	if (format != NULL) {
-		str = eel_strdup_strftime (format, &then);
+		str = g_date_time_format (datetime, format);
 	}
 
 	if (str == NULL) {
@@ -324,6 +158,9 @@ rb_utf_friendly_time (time_t date)
 		str = g_strdup (_("Unknown"));
 	}
 
+	g_date_time_unref (datetime);
+	g_date_time_unref (now);
+
 	return str;
 }
 
diff --git a/lib/rb-cut-and-paste-code.h b/lib/rb-cut-and-paste-code.h
index bf4581f..feb4348 100644
--- a/lib/rb-cut-and-paste-code.h
+++ b/lib/rb-cut-and-paste-code.h
@@ -25,9 +25,6 @@
 
 G_BEGIN_DECLS
 
-char      *eel_strdup_strftime         (const char *format,
-			                struct tm *time_pieces);
-
 GdkPixbuf *eel_create_colorized_pixbuf (GdkPixbuf *src,
 					int red_value,
 					int green_value,



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