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
This commit is contained in:
parent
c93e7add24
commit
2898b86e68
3 changed files with 135 additions and 14 deletions
|
@ -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")),
|
||||
|
|
|
@ -22,32 +22,151 @@
|
|||
#include <langinfo.h>
|
||||
#include <locale.h>
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "date-endian.h"
|
||||
|
||||
DateEndianess
|
||||
date_endian_get_default (void)
|
||||
/* 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)
|
||||
{
|
||||
const char *fmt;
|
||||
guint i;
|
||||
|
||||
fmt = nl_langinfo (D_FMT);
|
||||
g_return_val_if_fail (fmt != NULL, DATE_ENDIANESS_MIDDLE);
|
||||
|
||||
/* FIXME, implement */
|
||||
|
||||
return DATE_ENDIANESS_MIDDLE;
|
||||
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_for_lang (const char *lang)
|
||||
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, DEFAULT_ENDIANESS);
|
||||
|
||||
if (verbose)
|
||||
g_print ("%s", fmt);
|
||||
|
||||
if (g_str_equal (fmt, "%F"))
|
||||
return DATE_ENDIANESS_BIG;
|
||||
|
||||
i = 0;
|
||||
memset (&items, 0, sizeof(items));
|
||||
|
||||
/* 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,
|
||||
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 ();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue