+
+ g_return_val_if_fail (g_utf8_validate (full_address, -1, NULL), NULL);
+
+ left = g_strrstr_len (full_address, strlen(full_address), "<");
+ if (left == NULL)
+ return g_strdup (full_address);
+
+ right = g_strstr_len (left, strlen(left), ">");
+ if (right == NULL)
+ return g_strdup (full_address);
+
+ return g_strndup (left + 1, right - left - 1);
+}
+
+gint
+modest_text_utils_get_subject_prefix_len (const gchar *sub)
+{
+ gint prefix_len = 0;
+
+ g_return_val_if_fail (sub, 0);
+
+ if (!sub)
+ return 0;
+
+ /* optimization: "Re", "RE", "re","Fwd", "FWD", "fwd","FW","Fw", "fw" */
+ if (sub[0] != 'R' && sub[0] != 'F' && sub[0] != 'r' && sub[0] != 'f')
+ return 0;
+ else if (sub[0] && sub[1] != 'e' && sub[1] != 'E' && sub[1] != 'w' && sub[1] != 'W')
+ return 0;
+
+ prefix_len = 2;
+ if (sub[2] == 'd')
+ ++prefix_len;
+
+ /* skip over a [...] block */
+ if (sub[prefix_len] == '[') {
+ int c = prefix_len + 1;
+ while (sub[c] && sub[c] != ']')
+ ++c;
+ if (!sub[c])
+ return 0; /* no end to the ']' found */
+ else
+ prefix_len = c + 1;
+ }
+
+ /* did we find the ':' ? */
+ if (sub[prefix_len] == ':') {
+ ++prefix_len;
+ if (sub[prefix_len] == ' ')
+ ++prefix_len;
+ prefix_len += modest_text_utils_get_subject_prefix_len (sub + prefix_len);
+/* g_warning ("['%s','%s']", sub, (char*) sub + prefix_len); */
+ return prefix_len;
+ } else
+ return 0;
+}
+
+
+gint
+modest_text_utils_utf8_strcmp (const gchar* s1, const gchar *s2, gboolean insensitive)
+{
+
+/* work even when s1 and/or s2 == NULL */
+ if (G_UNLIKELY(s1 == s2))
+ return 0;
+ if (G_UNLIKELY(!s1))
+ return -1;
+ if (G_UNLIKELY(!s2))
+ return 1;
+
+ /* if it's not case sensitive */
+ if (!insensitive) {
+
+ /* optimization: shortcut if first char is ascii */
+ if (((s1[0] & 0x80)== 0) && ((s2[0] & 0x80) == 0) &&
+ (s1[0] != s2[0]))
+ return s1[0] - s2[0];
+
+ return g_utf8_collate (s1, s2);
+
+ } else {
+ gint result;
+ gchar *n1, *n2;
+
+ /* optimization: shortcut if first char is ascii */
+ if (((s1[0] & 0x80) == 0) && ((s2[0] & 0x80) == 0) &&
+ (tolower(s1[0]) != tolower (s2[0])))
+ return tolower(s1[0]) - tolower(s2[0]);
+
+ n1 = g_utf8_strdown (s1, -1);
+ n2 = g_utf8_strdown (s2, -1);
+
+ result = g_utf8_collate (n1, n2);
+
+ g_free (n1);
+ g_free (n2);
+
+ return result;
+ }
+}
+
+
+const gchar*
+modest_text_utils_get_display_date (time_t date)
+{
+#define DATE_BUF_SIZE 64
+ static gchar date_buf[DATE_BUF_SIZE];
+
+ /* calculate the # of days since epoch for
+ * for today and for the date provided
+ * based on idea from pvanhoof */
+ int day = time(NULL) / (24 * 60 * 60);
+ int date_day = date / (24 * 60 * 60);
+
+ /* if it's today, show the time, if it's not today, show the date instead */
+
+ /* TODO: take into account the system config for 24/12h */
+ if (day == date_day) /* is the date today? */
+ modest_text_utils_strftime (date_buf, DATE_BUF_SIZE, _HL("wdgt_va_24h_time"), date);
+ else
+ modest_text_utils_strftime (date_buf, DATE_BUF_SIZE, _HL("wdgt_va_date"), date);
+
+ return date_buf; /* this is a static buffer, don't free! */
+}
+
+
+
+gboolean
+modest_text_utils_validate_folder_name (const gchar *folder_name)
+{
+ /* based on http://msdn2.microsoft.com/en-us/library/aa365247.aspx,
+ * with some extras */
+
+ guint len;
+ gint i;
+ const gchar **cursor = NULL;
+ const gchar *forbidden_names[] = { /* windows does not like these */
+ "CON", "PRN", "AUX", "NUL", ".", "..", "cur", "tmp", "new",
+ NULL /* cur, tmp, new are reserved for Maildir */
+ };
+
+ /* cannot be NULL */
+ if (!folder_name)
+ return FALSE;
+
+ /* cannot be empty */
+ len = strlen(folder_name);
+ if (len == 0)
+ return FALSE;
+
+ /* cannot start with a dot, vfat does not seem to like that */
+ if (folder_name[0] == '.')
+ return FALSE;
+
+ /* cannot start or end with a space */
+ if (g_ascii_isspace(folder_name[0]) || g_ascii_isspace(folder_name[len - 1]))
+ return FALSE;
+
+ /* cannot contain a forbidden char */
+ for (i = 0; i < len; i++)
+ if (modest_text_utils_is_forbidden_char (folder_name[i], FOLDER_NAME_FORBIDDEN_CHARS))
+ return FALSE;
+
+ /* Cannot contain Windows port numbers. I'd like to use GRegex
+ but it's still not available in Maemo. sergio */
+ if (!g_ascii_strncasecmp (folder_name, "LPT", 3) ||
+ !g_ascii_strncasecmp (folder_name, "COM", 3)) {
+ glong val;
+ gchar *endptr;
+
+ /* We skip the first 3 characters for the
+ comparison */
+ val = strtol(folder_name+3, &endptr, 10);
+
+ /* If the conversion to long succeeded then the string
+ is not valid for us */
+ if (*endptr == '\0')
+ return FALSE;
+ else
+ return TRUE;
+ }
+
+ /* cannot contain a forbidden word */
+ if (len <= 4) {
+ for (cursor = forbidden_names; cursor && *cursor; ++cursor) {
+ if (g_ascii_strcasecmp (folder_name, *cursor) == 0)
+ return FALSE;
+ }
+ }
+
+ return TRUE; /* it's valid! */
+}
+