static gboolean char_class_digit_extract(const gunichar *s, gsize length, struct char_class_data *data, GValueArray *array) { long ret = 0; gsize i; GValue value; for (i = 0; i < length; i++) { ret *= 10; ret += g_unichar_digit_value(s[i]) == -1 ? 0 : g_unichar_digit_value(s[i]); } memset(&value, 0, sizeof(value)); g_value_init(&value, G_TYPE_LONG); g_value_set_long(&value, ret - data->inc); g_value_array_append(array, &value); g_value_unset(&value); return TRUE; }
static void _vte_table_extract_numbers(GValueArray **array, struct _vte_table_arginfo *arginfo) { GValue value = {0,}; GValue subvalue = {0,}; GValueArray *subarray = NULL; gssize i; if (G_UNLIKELY (*array == NULL)) { *array = g_value_array_new(1); } g_value_init(&value, G_TYPE_LONG); g_value_init(&subvalue, G_TYPE_VALUE_ARRAY); i = 0; do { long total = 0; for (; i < arginfo->length && arginfo->start[i] != ';' && arginfo->start[i] != ':'; i++) { gint v = g_unichar_digit_value (arginfo->start[i]); total *= 10; total += v == -1 ? 0 : v; } g_value_set_long(&value, CLAMP (total, 0, G_MAXUSHORT)); if (i < arginfo->length && arginfo->start[i] == ':') { if (subarray == NULL) { subarray = g_value_array_new(2); } g_value_array_append(subarray, &value); } else { if (subarray == NULL) { g_value_array_append(*array, &value); } else { g_value_array_append(subarray, &value); g_value_set_boxed(&subvalue, subarray); g_value_array_append(*array, &subvalue); subarray = NULL; } } } while (i++ < arginfo->length); g_value_unset(&value); }
static void _vte_table_extract_numbers(GValueArray **array, struct _vte_table_arginfo *arginfo, long increment) { GValue value = {0,}; gssize i; g_value_init(&value, G_TYPE_LONG); i = 0; do { long total = 0; for (; i < arginfo->length && arginfo->start[i] != ';'; i++) { gint v = g_unichar_digit_value (arginfo->start[i]); total *= 10; total += v == -1 ? 0 : v; } if (G_UNLIKELY (*array == NULL)) { *array = g_value_array_new(1); } g_value_set_long(&value, CLAMP (total, 0, G_MAXUSHORT)); g_value_array_append(*array, &value); } while (i++ < arginfo->length); g_value_unset(&value); }
gint donna_strcmp (const gchar *s1, const gchar *s2, DonnaSortOptions options) { gboolean is_string = TRUE; gint res_fb = 0; /* fallback */ gint res_cs = 0; /* case-sensitive */ gint res = 0; /* if at least one string if NULL or empty, we have a result */ if (!s1 || *s1 == '\0') { if (s2 && *s2 != '\0') return -1; else return 0; } else if (!s2 || *s2 == '\0') return 1; if (options & DONNA_SORT_DOT_FIRST) { if (*s1 == '.') { if (*s2 != '.') /* only s1 is dotted, it comes first */ return -1; else { /* both are dotted, skip the dot */ ++s1; ++s2; } } else if (*s2 == '.') /* only s2 is dotted, it comes first */ return 1; } else if (options & DONNA_SORT_DOT_MIXED) { if (*s1 == '.') ++s1; if (*s2 == '.') ++s2; } for (;;) { gunichar c1, c2; /* is at least one string over? */ if (!*s1) { if (!*s2) res = 0; else /* shorter first */ res = -1; goto done; } else if (!*s2) { /* shorter first */ res = 1; goto done; } c1 = g_utf8_get_char (s1); c2 = g_utf8_get_char (s2); if (is_string) { if (options & DONNA_SORT_IGNORE_SPUNCT) { while (g_unichar_isspace (c1) || g_unichar_ispunct (c1)) { s1 = g_utf8_next_char (s1); c1 = (*s1) ? g_utf8_get_char (s1) : 0; } while (g_unichar_isspace (c2) || g_unichar_ispunct (c2)) { s2 = g_utf8_next_char (s2); c2 = (*s2) ? g_utf8_get_char (s2) : 0; } /* did we reached the end of a string? */ if (!*s1 || !*s2) continue; } /* is at least one string a number? */ if (g_unichar_isdigit (c1)) { if (g_unichar_isdigit (c2)) { if (options & DONNA_SORT_NATURAL_ORDER) { /* switch to number comparison */ is_string = FALSE; continue; } } else { /* number first */ res = -1; goto done; } } else if (g_unichar_isdigit (c2)) { /* number first */ res = 1; goto done; } /* compare chars */ if (c1 > c2) res_cs = 1; else if (c1 < c2) res_cs = -1; if (options & DONNA_SORT_CASE_INSENSITIVE) { /* compare uppper chars */ c1 = g_unichar_toupper (c1); c2 = g_unichar_toupper (c2); if (c1 > c2) { res = 1; goto done; } else if (c1 < c2) { res = -1; goto done; } else if (res_fb == 0) /* set the case-sensitive result in case strings end up * being the same otherwise */ res_fb = res_cs; } /* do we have a res_cs yet? */ else if (res_cs != 0) { res = res_cs; goto done; } /* next chars */ s1 = g_utf8_next_char (s1); s2 = g_utf8_next_char (s2); } /* mode number */ else { unsigned long n1, n2; if (res_fb == 0) { /* count number of leading zeros */ for (n1 = 0; *s1 == '0'; ++n1, ++s1) ; for (n2 = 0; *s2 == '0'; ++n2, ++s2) ; /* try to set a fallback to put less leading zeros first */ if (n1 > n2) res_fb = 1; else if (n1 < n2) res_fb = -1; if (n1 > 0) c1 = g_utf8_get_char (s1); if (n2 > 0) c2 = g_utf8_get_char (s2); } n1 = 0; while (g_unichar_isdigit (c1)) { int d; d = g_unichar_digit_value (c1); n1 *= 10; n1 += (unsigned long) d; s1 = g_utf8_next_char (s1); if (*s1) c1 = g_utf8_get_char (s1); else break; } n2 = 0; while (g_unichar_isdigit (c2)) { int d; d = g_unichar_digit_value (c2); n2 *= 10; n2 += (unsigned long) d; s2 = g_utf8_next_char (s2); if (*s2) c2 = g_utf8_get_char (s2); else break; } if (n1 > n2) { res = 1; goto done; } else if (n1 < n2) { res = -1; goto done; } /* back to string comparison */ is_string = TRUE; } } done: return (res != 0) ? res : res_fb; }