[gnome-control-center] datetime: Implement date endianess detection
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center] datetime: Implement date endianess detection
- Date: Tue, 8 Mar 2011 07:59:50 +0000 (UTC)
commit 2898b86e68be5be01e8fe5bba72f2df87e92225d
Author: Bastien Nocera <hadess hadess net>
Date: Tue Mar 8 07:57:37 2011 +0000
datetime: Implement date endianess detection
Implement fairly robust detection of endianess based on
the d_fmt format exported by glibc.
https://bugzilla.gnome.org/show_bug.cgi?id=636896
panels/datetime/cc-datetime-panel.c | 2 +-
panels/datetime/date-endian.c | 131 +++++++++++++++++++++++++++++++++--
panels/datetime/date-endian.h | 6 +-
3 files changed, 130 insertions(+), 9 deletions(-)
---
diff --git a/panels/datetime/cc-datetime-panel.c b/panels/datetime/cc-datetime-panel.c
index 369ea1e..16bb0e8 100644
--- a/panels/datetime/cc-datetime-panel.c
+++ b/panels/datetime/cc-datetime-panel.c
@@ -828,7 +828,7 @@ cc_date_time_panel_init (CcDateTimePanel *self)
/* set up date editing widgets */
priv->date = g_date_time_new_now_local ();
- endianess = date_endian_get_default ();
+ endianess = date_endian_get_default (FALSE);
reorder_date_widget (endianess, priv);
gtk_combo_box_set_active (GTK_COMBO_BOX (W ("month-combobox")),
diff --git a/panels/datetime/date-endian.c b/panels/datetime/date-endian.c
index a45f849..715d22b 100644
--- a/panels/datetime/date-endian.c
+++ b/panels/datetime/date-endian.c
@@ -22,32 +22,151 @@
#include <langinfo.h>
#include <locale.h>
#include <glib.h>
+#include <string.h>
#include "date-endian.h"
+/* We default to returning DATE_ENDIANESS_MIDDLE because that's
+ * what 3.2 billion people use */
+#define DEFAULT_ENDIANESS DATE_ENDIANESS_LITTLE
+
+typedef enum {
+ ITEM_NONE = 0,
+ ITEM_DAY,
+ ITEM_MONTH,
+ ITEM_YEAR
+} Item;
+
+static gboolean
+has_item (Item *items,
+ Item item)
+{
+ guint i;
+
+ for (i = 0; i < 3; i++) {
+ if (items[i] == ITEM_NONE)
+ return FALSE;
+ if (items[i] == item)
+ return TRUE;
+ }
+ return FALSE;
+}
+
DateEndianess
-date_endian_get_default (void)
+date_endian_get_default (gboolean verbose)
{
const char *fmt;
+ const char *p;
+ Item items[3];
+ guint i;
fmt = nl_langinfo (D_FMT);
- g_return_val_if_fail (fmt != NULL, DATE_ENDIANESS_MIDDLE);
+ g_return_val_if_fail (fmt != NULL, DEFAULT_ENDIANESS);
+
+ if (verbose)
+ g_print ("%s", fmt);
+
+ if (g_str_equal (fmt, "%F"))
+ return DATE_ENDIANESS_BIG;
- /* FIXME, implement */
+ i = 0;
+ memset (&items, 0, sizeof(items));
- return DATE_ENDIANESS_MIDDLE;
+ /* Assume ASCII only */
+ for (p = fmt; *p != '\0'; p++) {
+ char c;
+
+ /* Look for '%' */
+ if (*p != '%')
+ continue;
+
+ /* Only assert when we're sure we don't have another '%' */
+ if (i >= 4) {
+ g_warning ("Could not parse format '%s', too many formats", fmt);
+ return DEFAULT_ENDIANESS;
+ }
+
+ c = *(p + 1);
+ /* Ignore alternative formats */
+ if (c == 'O' || c == '-' || c == 'E')
+ c = *(p + 2);
+ if (c == '\0') {
+ g_warning ("Count not parse format '%s', unterminated '%%'", fmt);
+ return DEFAULT_ENDIANESS;
+ }
+ switch (c) {
+ case 'd':
+ case 'e':
+ if (has_item (items, ITEM_DAY) == FALSE) {
+ items[i] = ITEM_DAY;
+ i++;
+ }
+ break;
+ case 'm':
+ case 'b':
+ case 'B':
+ if (has_item (items, ITEM_MONTH) == FALSE) {
+ items[i] = ITEM_MONTH;
+ i++;
+ }
+ break;
+ case 'y':
+ case 'Y':
+ if (has_item (items, ITEM_YEAR) == FALSE) {
+ items[i] = ITEM_YEAR;
+ i++;
+ }
+ break;
+ case 'A':
+ case 'a':
+ /* Ignore */
+ ;
+ }
+ }
+
+ if (items[0] == ITEM_DAY &&
+ items[1] == ITEM_MONTH &&
+ items[2] == ITEM_YEAR)
+ return DATE_ENDIANESS_LITTLE;
+ if (items[0] == ITEM_YEAR &&
+ items[1] == ITEM_MONTH &&
+ items[2] == ITEM_DAY)
+ return DATE_ENDIANESS_BIG;
+ if (items[0] == ITEM_MONTH &&
+ items[1] == ITEM_DAY &&
+ items[2] == ITEM_YEAR)
+ return DATE_ENDIANESS_MIDDLE;
+
+ g_warning ("Could not parse format '%s'", fmt);
+
+ return DEFAULT_ENDIANESS;
}
DateEndianess
-date_endian_get_for_lang (const char *lang)
+date_endian_get_for_lang (const char *lang,
+ gboolean verbose)
{
const char *old_lang;
DateEndianess endian;
old_lang = setlocale (LC_TIME, lang);
- endian = date_endian_get_default ();
+ endian = date_endian_get_default (verbose);
setlocale (LC_TIME, old_lang);
return endian;
}
+const char *
+date_endian_to_string (DateEndianess endianess)
+{
+ switch (endianess) {
+ case DATE_ENDIANESS_LITTLE:
+ return "Little (DD-MM-YYYY)";
+ case DATE_ENDIANESS_BIG:
+ return "Big (YYYY-MM-DD)";
+ case DATE_ENDIANESS_MIDDLE:
+ return "Middle (MM-DD-YYYY)";
+ default:
+ g_assert_not_reached ();
+ }
+}
diff --git a/panels/datetime/date-endian.h b/panels/datetime/date-endian.h
index 3c10a6b..4916485 100644
--- a/panels/datetime/date-endian.h
+++ b/panels/datetime/date-endian.h
@@ -26,5 +26,7 @@ typedef enum {
DATE_ENDIANESS_MIDDLE /* Middle-endian (month, day, year), e.g. 04/05/03 */
} DateEndianess;
-DateEndianess date_endian_get_default (void);
-DateEndianess date_endian_get_for_lang (const char *lang);
+DateEndianess date_endian_get_default (gboolean verbose);
+DateEndianess date_endian_get_for_lang (const char *lang,
+ gboolean verbose);
+const char * date_endian_to_string (DateEndianess endianess);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]