X-Git-Url: https://git.deb.at/?a=blobdiff_plain;f=edit.c;h=6ed553e0cd0134f9a8b2c705d59fa0c2902ade47;hb=3ccd3ae94e12f86945e4829d1797b33c15e9473f;hp=5f889f47f03a2c9e6667b9d5ca1a01f084edc614;hpb=67c93952226c03ec0de47b63500cdff8356d15e5;p=pkg%2Fabook.git diff --git a/edit.c b/edit.c index 5f889f4..6ed553e 100644 --- a/edit.c +++ b/edit.c @@ -24,6 +24,12 @@ #ifdef HAVE_CONFIG_H # include "config.h" #endif +#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE) +# include +#endif + + +static void locale_date(char *str, size_t str_len, int year, int month, int day); /* * some extern variables @@ -33,8 +39,6 @@ extern int views_count; WINDOW *editw; -static int parse_date_string(char *s, int *day, int *month, int *year); - static void editor_tab(const int tab) @@ -244,22 +248,16 @@ editor_print_data(int tab, int item) abook_list_free(&emails); } else if(cur->field->type == FIELD_DATE) { int day, month, year; - char buf[12]; + char buf[64]; find_field_number(cur->field->key, &nb); - if((str = db_fget_byid(item, nb)) != NULL) - strncpy(buf, str, sizeof(buf)); - - if(str && parse_date_string(buf, &day, &month, &year)) { - if(year) - str = strdup_printf("%04d-%02d-%02d", - year, month, day); - else - str = strdup_printf("--%02d-%02d", - month, day); - mvwaddnstr(editw, y, TAB_COLON_POS + 2, str, - bytes2width(str, FIELD_MAX_WIDTH)); - free(str); + str = db_fget_byid(item, nb); + + if(parse_date_string(str, &day, &month, &year)) { + /* put locale representation of date in buf */ + locale_date(buf, sizeof(buf), year, month, day); + mvwaddnstr(editw, y, TAB_COLON_POS + 2, buf, + bytes2width(buf, FIELD_MAX_WIDTH)); } } else { find_field_number(cur->field->key, &nb); @@ -399,6 +397,67 @@ edit_list(int item, int nb, int isemail) abook_list_free(&list); } +/* + * available %-sequences: + * - %y, %Y, %m, %M, %d, %D represent year, month, and day + * (the uppercase version telling to fill with leading zeros + * if necessary) + * - %I for ISO 8601 representation + */ +static size_t +format_date(char *str, size_t str_len, char *fmt, int year, int month, int day) +{ + char *s = str; + size_t len; + + while(*fmt && (s - str + 1 < str_len)) { + if(*fmt != '%') { + *s++ = *fmt++; + continue; + } + + len = str_len - (str - s); + switch(*++fmt) { + case 'y': s += snprintf(s, len, "%d", year); break; + case 'Y': s += snprintf(s, len, "%04d", year); break; + case 'm': s += snprintf(s, len, "%d", month); break; + case 'M': s += snprintf(s, len, "%02d", month); break; + case 'd': s += snprintf(s, len, "%d", day); break; + case 'D': s += snprintf(s, len, "%02d", day); break; + case 'I': s += format_date(s, len, + year ? "%Y-%M-%D" : "--%M-%D", + year, month, day); + break; + case '%': *s++ = '%'; break; + default: *s++ = '%'; *s++ = *fmt; break; + } + fmt++; + } + *s = 0; + return s - str; +} + +/* + * str is a buffer of max length str_len, which, after calling, will + * contain a representation of the given [y, m, d] date using the + * current locale (as defined by LC_TIME). + * + * In the absence of any localization, use an ISO 8601 representation. + */ +static void +locale_date(char *str, size_t str_len, int year, int month, int day) +{ + char *fmt; + +#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE) + fmt = year ? dcgettext(PACKAGE, "%Y-%M-%D", LC_TIME) : + dcgettext(PACKAGE, "--%M-%D", LC_TIME); +#else + fmt = "%I"; +#endif + format_date(str, str_len, fmt, year, month, day); +} + static int is_valid_date(const int day, const int month, const int year) { int valid = 1; @@ -421,12 +480,18 @@ static int is_valid_date(const int day, const int month, const int year) return valid; } -static int -parse_date_string(char *s, int *day, int *month, int *year) +int +parse_date_string(char *str, int *day, int *month, int *year) { int i = 0; - char *p = s; - assert(s && day && month && year); + char buf[12], *s, *p; + + assert(day && month && year); + + if(!str || !*str) + return FALSE; + + p = s = strncpy(buf, str, sizeof(buf)); if(*s == '-' && *s++ == '-') { /* omitted year */ *year = 0; @@ -448,7 +513,7 @@ parse_date_string(char *s, int *day, int *month, int *year) } p = s; } else - return FALSE; + return FALSE; } if (i != 2 || !*p) @@ -459,28 +524,14 @@ parse_date_string(char *s, int *day, int *month, int *year) return is_valid_date(*day, *month, *year); } -static int -is_number(char *s) -{ - char *p; - - for(p = s; *p; p++) - if(!isdigit(*p)) - return FALSE; - return TRUE; -} - static void edit_date(int item, int nb) { - int i, date[3], old = FALSE; - char buf[12], *s = db_fget_byid(item, nb); + int i, date[3], old; + char *s = db_fget_byid(item, nb); char *field[] = { N_("Day: "), N_("Month: "), N_("Year (optional): ") }; - if(s) { - strncpy(buf, s, sizeof(buf)); - old = parse_date_string(buf, &date[0], &date[1], &date[2]); - } + old = parse_date_string(s, &date[0], &date[1], &date[2]); for(i = 0; i < 3; i++) { s = (old && date[i]) ? strdup_printf("%d", date[i]) : NULL;