static gint camel_ustrncasecmp (const gchar *ps1, const gchar *ps2, gsize len) { gunichar u1, u2 = 0; const guchar *s1 = (const guchar *)ps1; const guchar *s2 = (const guchar *)ps2; CAMEL_SEARCH_COMPARE (s1, s2, NULL); u1 = camel_utf8_getc (&s1); u2 = camel_utf8_getc (&s2); while (len > 0 && u1 && u2) { u1 = g_unichar_tolower (u1); u2 = g_unichar_tolower (u2); if (u1 < u2) return -1; else if (u1 > u2) return 1; len--; u1 = camel_utf8_getc (&s1); u2 = camel_utf8_getc (&s2); } if (len == 0) return 0; /* end of one of the strings ? */ CAMEL_SEARCH_COMPARE (u1, u2, 0); /* if we have invalid utf8 sequence ? */ CAMEL_SEARCH_COMPARE (s1, s2, NULL); return 0; }
unsigned int levenshtein ( const char *needle, const char *haystack ) { unsigned int x, y, lastdiag, olddiag; size_t needlelen = g_utf8_strlen ( needle, -1 ); size_t haystacklen = g_utf8_strlen ( haystack, -1 ); unsigned int column[needlelen + 1]; for ( y = 0; y <= needlelen; y++ ) { column[y] = y; } for ( x = 1; x <= haystacklen; x++ ) { const char *needles = needle; column[0] = x; gunichar haystackc = g_utf8_get_char ( haystack ); if ( !config.case_sensitive ) { haystackc = g_unichar_tolower ( haystackc ); } for ( y = 1, lastdiag = x - 1; y <= needlelen; y++ ) { gunichar needlec = g_utf8_get_char ( needles ); if ( !config.case_sensitive ) { needlec = g_unichar_tolower ( needlec ); } olddiag = column[y]; column[y] = MIN3 ( column[y] + 1, column[y - 1] + 1, lastdiag + ( needlec == haystackc ? 0 : 1 ) ); lastdiag = olddiag; needles = g_utf8_next_char ( needles ); } haystack = g_utf8_next_char ( haystack ); } return column[needlelen]; }
static gint32 string_invariant_compare_char (gunichar2 c1, gunichar2 c2, gint32 options) { gint32 result; /* Ordinal can not be mixed with other options, and must return the difference, not only -1, 0, 1 */ if (options & CompareOptions_Ordinal) return (gint32) c1 - c2; if (options & CompareOptions_IgnoreCase) { GUnicodeType c1type, c2type; c1type = g_unichar_type (c1); c2type = g_unichar_type (c2); result = (gint32) (c1type != G_UNICODE_LOWERCASE_LETTER ? g_unichar_tolower(c1) : c1) - (c2type != G_UNICODE_LOWERCASE_LETTER ? g_unichar_tolower(c2) : c2); } else { /* * No options. Kana, symbol and spacing options don't * apply to the invariant culture. */ /* * FIXME: here we must use the information from c1type and c2type * to find out the proper collation, even on the InvariantCulture, the * sorting is not done by computing the unicode values, but their * actual sort order. */ result = (gint32) c1 - c2; } return ((result < 0) ? -1 : (result > 0) ? 1 : 0); }
static int camel_ustrcasecmp (const char *ps1, const char *ps2) { gunichar u1, u2 = 0; const unsigned char *s1 = (const unsigned char *)ps1; const unsigned char *s2 = (const unsigned char *)ps2; CAMEL_SEARCH_COMPARE (s1, s2, NULL); u1 = camel_utf8_getc(&s1); u2 = camel_utf8_getc(&s2); while (u1 && u2) { u1 = g_unichar_tolower (u1); u2 = g_unichar_tolower (u2); if (u1 < u2) return -1; else if (u1 > u2) return 1; u1 = camel_utf8_getc(&s1); u2 = camel_utf8_getc(&s2); } /* end of one of the strings ? */ CAMEL_SEARCH_COMPARE (u1, u2, 0); /* if we have invalid utf8 sequence ? */ CAMEL_SEARCH_COMPARE (s1, s2, NULL); return 0; }
const gchar * camel_ustrstrcase (const gchar *haystack, const gchar *needle) { gunichar *nuni, *puni; gunichar u; const guchar *p; g_return_val_if_fail (haystack != NULL, NULL); g_return_val_if_fail (needle != NULL, NULL); if (strlen (needle) == 0) return haystack; if (strlen (haystack) == 0) return NULL; puni = nuni = g_alloca (sizeof (gunichar) * strlen (needle)); p = (const guchar *) needle; while ((u = camel_utf8_getc (&p))) *puni++ = g_unichar_tolower (u); /* NULL means there was illegal utf-8 sequence */ if (!p) return NULL; p = (const guchar *)haystack; while ((u = camel_utf8_getc (&p))) { gunichar c; c = g_unichar_tolower (u); /* We have valid stripped gchar */ if (c == nuni[0]) { const guchar *q = p; gint npos = 1; while (nuni + npos < puni) { u = camel_utf8_getc (&q); if (!q || !u) return NULL; c = g_unichar_tolower (u); if (c != nuni[npos]) break; npos++; } if (nuni + npos == puni) return (const gchar *) p; } } return NULL; }
/* Copied from evolution-data-server/libedataserver/e-util.c: * e_util_utf8_strstrcase() */ const char * panel_g_utf8_strstrcase (const char *haystack, const char *needle) { gunichar *nuni; gunichar unival; gint nlen; const char *o, *p; if (haystack == NULL) return NULL; if (needle == NULL) return NULL; if (strlen (needle) == 0) return haystack; if (strlen (haystack) == 0) return NULL; nuni = g_alloca (sizeof (gunichar) * strlen (needle)); nlen = 0; for (p = _unicode_get_utf8 (needle, &unival); p && unival; p = _unicode_get_utf8 (p, &unival)) { nuni[nlen++] = g_unichar_tolower (unival); } /* NULL means there was illegal utf-8 sequence */ if (!p) return NULL; o = haystack; for (p = _unicode_get_utf8 (o, &unival); p && unival; p = _unicode_get_utf8 (p, &unival)) { gint sc; sc = g_unichar_tolower (unival); /* We have valid stripped char */ if (sc == nuni[0]) { const char *q = p; gint npos = 1; while (npos < nlen) { q = _unicode_get_utf8 (q, &unival); if (!q || !unival) return NULL; sc = g_unichar_tolower (unival); if (sc != nuni[npos]) break; npos++; } if (npos == nlen) { return o; } } o = p; } return NULL; }
static char *convert_sentence_case(const char *str) { int result_size = strlen(str) + 12; char *result = malloc(result_size); const char *r = str; char *w = result; while (*r) { int len; gunichar c = g_utf8_get_char(r); /* ensure there is room for at least 1 more character */ if (w - result + 7 > result_size) { int offset = w - result; result_size += max(6, 0.5 * result_size); result = realloc(result, result_size); w = result + offset; } if (r == str) len = g_unichar_to_utf8(g_unichar_toupper(c), w); else len = g_unichar_to_utf8(g_unichar_tolower(c), w); w += len; r = g_utf8_next_char(r); } *w = 0; return result; }
ObMenu* menu_new(const gchar *name, const gchar *title, gboolean allow_shortcut_selection, gpointer data) { ObMenu *self; self = g_slice_new0(ObMenu); self->name = g_strdup(name); self->data = data; self->shortcut = parse_shortcut(title, allow_shortcut_selection, &self->title, &self->shortcut_position, &self->shortcut_always_show); g_hash_table_replace(menu_hash, self->name, self); /* Each menu has a single more_menu. When the menu spills past what can fit on the screen, a new menu frame entry is created from this more_menu, and a new menu frame for the submenu is created for this menu, also pointing to the more_menu. This can be done multiple times using the same more_menu. more_menu->more_menu will always be NULL, since there is only 1 for each menu. */ self->more_menu = g_slice_new0(ObMenu); self->more_menu->name = _("More..."); self->more_menu->title = _("More..."); self->more_menu->data = data; self->more_menu->shortcut = g_unichar_tolower(g_utf8_get_char("M")); return self; }
/* converts str into utf8 GString in lowercase; * returns NULL if str is invalid utf8 string otherwise * returns newly allocated GString */ static GString * chars_to_unistring_lowercase (const gchar *pstr) { GString *res; gunichar unich; gchar *p, *str; if (pstr == NULL) return NULL; str = e_util_utf8_remove_accents (pstr); if (!str) return NULL; res = g_string_new (""); for (p = e_util_unicode_get_utf8 (str, &unich); p && unich; p = e_util_unicode_get_utf8 (p, &unich)) { g_string_append_unichar (res, g_unichar_tolower (unich)); } g_free (str); /* it was invalid unichar string */ if (p == NULL) { g_string_free (res, TRUE); return NULL; } return res; }
static void do_invert_case (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end) { GString *s = g_string_new (NULL); while (!gtk_text_iter_is_end (start) && !gtk_text_iter_equal (start, end)) { gunichar c, nc; c = gtk_text_iter_get_char (start); if (g_unichar_islower (c)) nc = g_unichar_toupper (c); else nc = g_unichar_tolower (c); g_string_append_unichar (s, nc); gtk_text_iter_forward_char (start); } gtk_text_buffer_delete_selection (buffer, TRUE, TRUE); gtk_text_buffer_insert_at_cursor (buffer, s->str, s->len); g_string_free (s, TRUE); }
/** * stripped_char: * * Returns a stripped version of @ch, removing any case, accentuation * mark, or any special mark on it. **/ static gunichar stripped_char (gunichar ch) { gunichar *decomp, retval; GUnicodeType utype; gsize dlen; utype = g_unichar_type (ch); switch (utype) { case G_UNICODE_CONTROL: case G_UNICODE_FORMAT: case G_UNICODE_UNASSIGNED: case G_UNICODE_COMBINING_MARK: /* Ignore those */ return 0; break; default: /* Convert to lowercase, fall through */ ch = g_unichar_tolower (ch); case G_UNICODE_LOWERCASE_LETTER: if ((decomp = g_unicode_canonical_decomposition (ch, &dlen))) { retval = decomp[0]; g_free (decomp); return retval; } break; } return 0; }
static char *convert_title_case(const char *str) { int result_size = strlen(str) + 12; char *result = malloc(result_size); const char *r = str; char *w = result; gboolean upcase_next = TRUE; while (*r) { int len; gunichar c = g_utf8_get_char(r); /* ensure there is room for at least 1 more character */ if (w - result + 7 > result_size) { int offset = w - result; result_size += max(6, 0.5 * result_size); result = realloc(result, result_size); w = result + offset; } if (upcase_next) len = g_unichar_to_utf8(g_unichar_toupper(c), w); else len = g_unichar_to_utf8(g_unichar_tolower(c), w); w += len; upcase_next = !g_unichar_isalnum(c) && c != '\''; r = g_utf8_next_char(r); } *w = 0; return result; }
gchar * gb_str_highlight_full (const gchar *str, const gchar *match, gboolean insensitive, GbHighlightType type) { const gchar *begin = "<u>"; const gchar *end = "</u>"; GString *ret; gunichar str_ch; gunichar match_ch; g_return_val_if_fail (str, NULL); g_return_val_if_fail (match, NULL); if (type == GB_HIGHLIGHT_BOLD) { begin = "<b>"; end = "</b>"; } ret = g_string_new (NULL); for (; *str; str = g_utf8_next_char (str)) { str_ch = g_utf8_get_char (str); match_ch = g_utf8_get_char (match); if ((str_ch == match_ch) || (insensitive && (g_unichar_tolower (str_ch) == g_unichar_tolower (match_ch)))) { g_string_append (ret, begin); g_string_append_unichar (ret, str_ch); g_string_append (ret, end); /* * TODO: We could seek to the next char and append in a batch. */ match = g_utf8_next_char (match); } else { g_string_append_unichar (ret, str_ch); } } return g_string_free (ret, FALSE); }
void SmkyManufacturerDatabase::setFistAndLastLetters(const std::string & firstLetters, const std::string & lastLetters, int minLength) { if (m_hunspell && m_lastHunspellResult) { m_hunspell->free_list(&m_lastHunspellResult, m_lastHunspellResultCount); m_lastHunspellResult = NULL; } m_lastFirstLastLetterResults.clear(); auto_g_free_array<gunichar> first16 = g_utf8_to_ucs4(firstLetters.c_str(), -1, NULL, NULL, NULL); auto_g_free_array<gunichar> last16 = g_utf8_to_ucs4(lastLetters.c_str(), -1, NULL, NULL, NULL); if (first16 && last16) { gunichar * p = first16; while (*p) *p = g_unichar_tolower(*p), ++p; p = last16; while (*p) *p = g_unichar_tolower(*p), ++p; for (std::map<std::string, int>::iterator iter = m_words.begin(); iter != m_words.end(); ++iter) { const std::string & word = iter->first; const char * wordStr = word.c_str(); gunichar firstLetter = g_unichar_tolower(g_utf8_get_char(wordStr)); if (wcschr(first16.as<wchar_t>(), (wchar_t) firstLetter)) { // first letter is a match! const char * next = wordStr; int wordLength = 1; while ((next = g_utf8_next_char(wordStr)) && *next) wordStr = next, ++wordLength; if (wordLength >= minLength) { gunichar lastLetter = g_unichar_tolower(g_utf8_get_char(wordStr)); if (wcschr(last16.as<wchar_t>(), (wchar_t) lastLetter)) { DEBUG_CALLBACK("First-last letter match: %s-%s -> %s", firstLetters.c_str(), lastLetters.c_str(), word.c_str()); m_lastFirstLastLetterResults.push_back(word.c_str()); } } else { DEBUG_CALLBACK("'%s' is discarded because it's too short: %d letters, %d min", word.c_str(), wordLength, minLength); } } } } }
unsigned int _pcre_ucp_othercase(const unsigned int c) { unsigned int oc = NOTACHAR; if ((oc = g_unichar_toupper(c)) != c) return oc; if ((oc = g_unichar_tolower(c)) != c) return oc; return c; }
static gunichar get_char (const char **str) { gunichar c = g_utf8_get_char (*str); *str = g_utf8_next_char (*str); #ifdef G_PLATFORM_WIN32 c = g_unichar_tolower (c); #endif return c; }
static const char* lookup_suffix_nodes( const char* buf, const char* nodes, guint32 n, const char* name ) { gunichar uchar; uchar = g_unichar_tolower( g_utf8_get_char( name ) ); /* binary search */ int upper = n, lower = 0; int middle = n/2; while( upper >= lower ) { const char* node =nodes + middle * 16; guint32 ch = VAL32(node, 0); if( uchar < ch ) upper = middle - 1; else if( uchar > ch ) lower = middle + 1; else /* uchar == ch */ { guint32 n_children = VAL32(node, 8); name =g_utf8_next_char(name); if( n_children > 0 ) { guint32 first_child_off; if( uchar == 0 ) return NULL; if( ! name || 0 == name[0] ) { guint32 offset = VAL32(node, 4); return offset ? buf + offset : NULL; } first_child_off = VAL32(node, 12); return lookup_suffix_nodes( buf, (buf + first_child_off), n_children, name ); } else { if( ! name || 0 == name[0] ) { guint32 offset = VAL32(node, 4); return offset ? buf + offset : NULL; } return NULL; } } middle = (upper + lower) / 2; } return NULL; }
/* Reverse suffix tree is used since mime.cache 1.1 (shared mime info 0.4) * Returns the address of the found "node", not mime-type. * FIXME: 1. Should be optimized with binary search * 2. Should consider weight of suffix nodes */ static const char* lookup_reverse_suffix_nodes( const char* buf, const char* nodes, guint32 n, const char* name, const char* suffix, const char** suffix_pos ) { const char *ret = NULL; const char *_suffix_pos = NULL, *cur_suffix_pos = (const char*)suffix + 1; const char* leaf_node = NULL; gunichar uchar; uchar = suffix ? g_unichar_tolower( g_utf8_get_char( suffix ) ) : 0; /* g_debug("%s: suffix= '%s'", name, suffix); */ int i; for( i = 0; i < n; ++i ) { const char* node =nodes + i * 12; guint32 ch = VAL32(node, 0); _suffix_pos = suffix; if( G_LIKELY( ch ) ) { if( ch == uchar ) { guint32 n_children = VAL32(node, 4); guint32 first_child_off = VAL32(node, 8); leaf_node = lookup_reverse_suffix_nodes( buf, buf + first_child_off, n_children, name, g_utf8_find_prev_char(name, suffix), &_suffix_pos ); if( leaf_node && _suffix_pos < cur_suffix_pos ) { ret = leaf_node; cur_suffix_pos = _suffix_pos; } } } else /* ch == 0 */ { /* guint32 weight = VAL32(node, 8); */ /* suffix is found in the tree! */ if( suffix < cur_suffix_pos ) { ret = node; cur_suffix_pos = suffix; } } } *suffix_pos = cur_suffix_pos; return ret; }
static gint key_press(guint keyval, gchar *commit_str, gchar *preedit_str) { gint length_passed, i; if(!gcomprisBoard) return FALSE; /* i suppose even numbers are passed through IM_context */ if ((commit_str == NULL) && (preedit_str == NULL)) return FALSE; gchar *string_passed; if (commit_str) string_passed = commit_str; else string_passed = preedit_str; length_passed = g_utf8_strlen(string_passed, -1); for (i=0; i < length_passed; i++){ gunichar ckey = \ g_unichar_tolower( g_utf8_get_char (string_passed) ); gunichar cright = \ g_unichar_tolower( g_utf8_get_char (right_letter) ); if (ckey == cright){ gamewon = TRUE; process_ok(); gc_im_reset(); return TRUE; } string_passed = g_utf8_next_char (string_passed); } return TRUE; }
static gchar * utf8_case_conv (const gchar *str, gssize len, gboolean upper) { gunichar *ustr; glong i, ulen; gchar *utf8; ustr = g_utf8_to_ucs4_fast (str, (glong) len, &ulen); for (i = 0; i < ulen; i++) ustr[i] = upper ? g_unichar_toupper (ustr[i]) : g_unichar_tolower (ustr[i]); utf8 = g_ucs4_to_utf8 (ustr, ulen, NULL, NULL, NULL); g_free (ustr); return utf8; }
static char* process_str (const char *str, gboolean xapian_esc, gboolean query_esc) { GString *gstr; char *norm, *cur; gboolean is_field, is_range_field; norm = g_utf8_normalize (str, -1, G_NORMALIZE_ALL); if (G_UNLIKELY(!norm)) { /* not valid utf8? */ char *u8; u8 = mu_str_utf8ify (str); norm = g_utf8_normalize (u8, -1, G_NORMALIZE_ALL); g_free (u8); } if (!norm) return NULL; /* msg-id needs some special care in queries */ if (query_esc && is_msgid_field (str)) return mu_str_process_msgid (str, TRUE); check_for_field (str, &is_field, &is_range_field); gstr = g_string_sized_new (strlen (norm)); for (cur = norm; cur && *cur; cur = g_utf8_next_char (cur)) { gunichar uc; uc = g_utf8_get_char (cur); if (xapian_esc) if (handle_esc_maybe (gstr, &cur, uc, query_esc, is_range_field)) continue; if (g_unichar_ismark(uc)) continue; if (!is_range_field) uc = g_unichar_tolower (uc); g_string_append_unichar (gstr, uc); } g_free (norm); return g_string_free (gstr, FALSE); }
static void output_c (GString *w, guint32 c, gint *type) { gint utf8len; gchar utf8[8]; if (!g_unichar_isalnum (c)) *type = CAMEL_SEARCH_WORD_COMPLEX | (*type & CAMEL_SEARCH_WORD_8BIT); else c = g_unichar_tolower (c); if (c > 0x80) *type |= CAMEL_SEARCH_WORD_8BIT; /* FIXME: use camel_utf8_putc */ utf8len = g_unichar_to_utf8 (c, utf8); utf8[utf8len] = 0; g_string_append (w, utf8); }
static int str_utf8_tolower (const char *text, char **out, size_t * remain) { gunichar uni; size_t left; uni = g_utf8_get_char_validated (text, -1); if (uni == (gunichar) (-1) || uni == (gunichar) (-2)) return 0; uni = g_unichar_tolower (uni); left = g_unichar_to_utf8 (uni, NULL); if (left >= *remain) return 0; left = g_unichar_to_utf8 (uni, *out); (*out) += left; (*remain) -= left; return 1; }
/* * g_unichar_tolower */ RESULT test_g_unichar_tolower () { if (g_unichar_tolower (0) != 0) return FAILED ("#0"); if (g_unichar_tolower ('A') != 'a') return FAILED ("#1"); if (g_unichar_tolower ('1') != '1') return FAILED ("#2"); if (g_unichar_tolower (0x1C5) != 0x1C6) return FAILED ("#3"); if (g_unichar_tolower (0x1F1) != 0x1F3) return FAILED ("#4"); if (g_unichar_tolower (0x1F2) != 0x1F3) return FAILED ("#5"); if (g_unichar_tolower (0xFFFF) != 0xFFFF) return FAILED ("#6"); return NULL; }
/** * gdk_keyval_convert_case: * @symbol: a keyval * @lower: (out): return location for lowercase version of @symbol * @upper: (out): return location for uppercase version of @symbol * * Obtains the upper- and lower-case versions of the keyval @symbol. * Examples of keyvals are #GDK_KEY_a, #GDK_KEY_Enter, #GDK_KEY_F1, etc. */ void gdk_keyval_convert_case (guint symbol, guint *lower, guint *upper) { guint xlower, xupper; xlower = symbol; xupper = symbol; /* Check for directly encoded 24-bit UCS characters: */ if ((symbol & 0xff000000) == 0x01000000) { if (lower) *lower = gdk_unicode_to_keyval (g_unichar_tolower (symbol & 0x00ffffff)); if (upper) *upper = gdk_unicode_to_keyval (g_unichar_toupper (symbol & 0x00ffffff)); return; } switch (symbol >> 8) { case 0: /* Latin 1 */ if ((symbol >= GDK_KEY_A) && (symbol <= GDK_KEY_Z)) xlower += (GDK_KEY_a - GDK_KEY_A); else if ((symbol >= GDK_KEY_a) && (symbol <= GDK_KEY_z)) xupper -= (GDK_KEY_a - GDK_KEY_A); else if ((symbol >= GDK_KEY_Agrave) && (symbol <= GDK_KEY_Odiaeresis)) xlower += (GDK_KEY_agrave - GDK_KEY_Agrave); else if ((symbol >= GDK_KEY_agrave) && (symbol <= GDK_KEY_odiaeresis)) xupper -= (GDK_KEY_agrave - GDK_KEY_Agrave); else if ((symbol >= GDK_KEY_Ooblique) && (symbol <= GDK_KEY_Thorn)) xlower += (GDK_KEY_oslash - GDK_KEY_Ooblique); else if ((symbol >= GDK_KEY_oslash) && (symbol <= GDK_KEY_thorn)) xupper -= (GDK_KEY_oslash - GDK_KEY_Ooblique); break; case 1: /* Latin 2 */ /* Assume the KeySym is a legal value (ignore discontinuities) */ if (symbol == GDK_KEY_Aogonek) xlower = GDK_KEY_aogonek; else if (symbol >= GDK_KEY_Lstroke && symbol <= GDK_KEY_Sacute) xlower += (GDK_KEY_lstroke - GDK_KEY_Lstroke); else if (symbol >= GDK_KEY_Scaron && symbol <= GDK_KEY_Zacute) xlower += (GDK_KEY_scaron - GDK_KEY_Scaron); else if (symbol >= GDK_KEY_Zcaron && symbol <= GDK_KEY_Zabovedot) xlower += (GDK_KEY_zcaron - GDK_KEY_Zcaron); else if (symbol == GDK_KEY_aogonek) xupper = GDK_KEY_Aogonek; else if (symbol >= GDK_KEY_lstroke && symbol <= GDK_KEY_sacute) xupper -= (GDK_KEY_lstroke - GDK_KEY_Lstroke); else if (symbol >= GDK_KEY_scaron && symbol <= GDK_KEY_zacute) xupper -= (GDK_KEY_scaron - GDK_KEY_Scaron); else if (symbol >= GDK_KEY_zcaron && symbol <= GDK_KEY_zabovedot) xupper -= (GDK_KEY_zcaron - GDK_KEY_Zcaron); else if (symbol >= GDK_KEY_Racute && symbol <= GDK_KEY_Tcedilla) xlower += (GDK_KEY_racute - GDK_KEY_Racute); else if (symbol >= GDK_KEY_racute && symbol <= GDK_KEY_tcedilla) xupper -= (GDK_KEY_racute - GDK_KEY_Racute); break; case 2: /* Latin 3 */ /* Assume the KeySym is a legal value (ignore discontinuities) */ if (symbol >= GDK_KEY_Hstroke && symbol <= GDK_KEY_Hcircumflex) xlower += (GDK_KEY_hstroke - GDK_KEY_Hstroke); else if (symbol >= GDK_KEY_Gbreve && symbol <= GDK_KEY_Jcircumflex) xlower += (GDK_KEY_gbreve - GDK_KEY_Gbreve); else if (symbol >= GDK_KEY_hstroke && symbol <= GDK_KEY_hcircumflex) xupper -= (GDK_KEY_hstroke - GDK_KEY_Hstroke); else if (symbol >= GDK_KEY_gbreve && symbol <= GDK_KEY_jcircumflex) xupper -= (GDK_KEY_gbreve - GDK_KEY_Gbreve); else if (symbol >= GDK_KEY_Cabovedot && symbol <= GDK_KEY_Scircumflex) xlower += (GDK_KEY_cabovedot - GDK_KEY_Cabovedot); else if (symbol >= GDK_KEY_cabovedot && symbol <= GDK_KEY_scircumflex) xupper -= (GDK_KEY_cabovedot - GDK_KEY_Cabovedot); break; case 3: /* Latin 4 */ /* Assume the KeySym is a legal value (ignore discontinuities) */ if (symbol >= GDK_KEY_Rcedilla && symbol <= GDK_KEY_Tslash) xlower += (GDK_KEY_rcedilla - GDK_KEY_Rcedilla); else if (symbol >= GDK_KEY_rcedilla && symbol <= GDK_KEY_tslash) xupper -= (GDK_KEY_rcedilla - GDK_KEY_Rcedilla); else if (symbol == GDK_KEY_ENG) xlower = GDK_KEY_eng; else if (symbol == GDK_KEY_eng) xupper = GDK_KEY_ENG; else if (symbol >= GDK_KEY_Amacron && symbol <= GDK_KEY_Umacron) xlower += (GDK_KEY_amacron - GDK_KEY_Amacron); else if (symbol >= GDK_KEY_amacron && symbol <= GDK_KEY_umacron) xupper -= (GDK_KEY_amacron - GDK_KEY_Amacron); break; case 6: /* Cyrillic */ /* Assume the KeySym is a legal value (ignore discontinuities) */ if (symbol >= GDK_KEY_Serbian_DJE && symbol <= GDK_KEY_Serbian_DZE) xlower -= (GDK_KEY_Serbian_DJE - GDK_KEY_Serbian_dje); else if (symbol >= GDK_KEY_Serbian_dje && symbol <= GDK_KEY_Serbian_dze) xupper += (GDK_KEY_Serbian_DJE - GDK_KEY_Serbian_dje); else if (symbol >= GDK_KEY_Cyrillic_YU && symbol <= GDK_KEY_Cyrillic_HARDSIGN) xlower -= (GDK_KEY_Cyrillic_YU - GDK_KEY_Cyrillic_yu); else if (symbol >= GDK_KEY_Cyrillic_yu && symbol <= GDK_KEY_Cyrillic_hardsign) xupper += (GDK_KEY_Cyrillic_YU - GDK_KEY_Cyrillic_yu); break; case 7: /* Greek */ /* Assume the KeySym is a legal value (ignore discontinuities) */ if (symbol >= GDK_KEY_Greek_ALPHAaccent && symbol <= GDK_KEY_Greek_OMEGAaccent) xlower += (GDK_KEY_Greek_alphaaccent - GDK_KEY_Greek_ALPHAaccent); else if (symbol >= GDK_KEY_Greek_alphaaccent && symbol <= GDK_KEY_Greek_omegaaccent && symbol != GDK_KEY_Greek_iotaaccentdieresis && symbol != GDK_KEY_Greek_upsilonaccentdieresis) xupper -= (GDK_KEY_Greek_alphaaccent - GDK_KEY_Greek_ALPHAaccent); else if (symbol >= GDK_KEY_Greek_ALPHA && symbol <= GDK_KEY_Greek_OMEGA) xlower += (GDK_KEY_Greek_alpha - GDK_KEY_Greek_ALPHA); else if (symbol >= GDK_KEY_Greek_alpha && symbol <= GDK_KEY_Greek_omega && symbol != GDK_KEY_Greek_finalsmallsigma) xupper -= (GDK_KEY_Greek_alpha - GDK_KEY_Greek_ALPHA); break; default: break; } if (lower) *lower = xlower; if (upper) *upper = xupper; }
gchar *strproper (gchar *s) { #if DISABLE_UTF8 gchar c; gchar *ptr; if (!s) return NULL; ptr = g_strdup(s); if (!ptr) return NULL; s = ptr; *s = toupper(*s); s++; while ((c = tolower(*s)) != '\0') *s++ = c; return ptr; #else gchar *ptr, *s1, *ptr1; gint len, first; gunichar c; if (!s) return NULL; len = 0; ptr = s; first = 1; while (*ptr) { c = g_utf8_get_char(ptr); if (first) { c = g_unichar_toupper(c); first = 0; } else c = g_unichar_tolower(c); len += g_unichar_to_utf8(c, NULL); ptr = g_utf8_next_char(ptr); } s1 = g_malloc(len + 1); if (!s1) return NULL; ptr = s; ptr1 = s1; first = 1; while (*ptr) { c = g_utf8_get_char(ptr); if (first) { c = g_unichar_toupper(c); first = 0; } else c = g_unichar_tolower(c); len = g_unichar_to_utf8(c, ptr1); ptr1 += len; ptr = g_utf8_next_char(ptr); } *ptr1 = '\0'; return s1; #endif }
static void search_text_changed_cb (GtkEntry *entry, TextSearch *tsearch) { GtkTextIter iter, siter, end; GtkTextBuffer *buffer; const gchar *search_text, *sptr; gboolean sensitive; buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tsearch->priv->view)); /* clean all previous search result */ gtk_text_buffer_get_bounds (buffer, &iter, &end); gtk_text_buffer_remove_tag_by_name (buffer, "search", &iter, &end); tsearch->priv->current_mark = NULL; if (tsearch->priv->search_marks) { GList *list; for (list = tsearch->priv->search_marks; list; list = list->next) gtk_text_buffer_delete_mark (buffer, GTK_TEXT_MARK (list->data)); g_list_free (tsearch->priv->search_marks); tsearch->priv->search_marks = NULL; } gtk_text_buffer_get_start_iter (buffer, &iter); search_text = gtk_entry_get_text (entry); if (!search_text || !*search_text) return; sensitive = gtk_toggle_button_get_active (tsearch->priv->search_sensitive); while (1) { gboolean high = TRUE; siter = iter; sptr = search_text; /* search for @search_text starting from the @siter position */ while (1) { gunichar c1, c2; c1 = gtk_text_iter_get_char (&siter); c2 = g_utf8_get_char (sptr); if (!sensitive) { c1 = g_unichar_tolower (c1); c2 = g_unichar_tolower (c2); } if (c1 != c2) { high = FALSE; break; } sptr = g_utf8_find_next_char (sptr, NULL); if (!sptr || !*sptr) break; if (! gtk_text_iter_forward_char (&siter)) { high = FALSE; break; } } if (high) { if (gtk_text_iter_forward_char (&siter)) { GtkTextMark *mark; gtk_text_buffer_apply_tag_by_name (buffer, "search", &iter, &siter); mark = gtk_text_buffer_create_mark (buffer, NULL, &iter, FALSE); tsearch->priv->search_marks = g_list_prepend (tsearch->priv->search_marks, mark); } iter = siter; } else { if (! gtk_text_iter_forward_char (&iter)) break; } } if (tsearch->priv->search_marks) { tsearch->priv->search_marks = g_list_reverse (tsearch->priv->search_marks); tsearch->priv->current_mark = tsearch->priv->search_marks; gtk_text_view_scroll_mark_onscreen (tsearch->priv->view, GTK_TEXT_MARK (tsearch->priv->current_mark->data)); } }
/** Examine an extension menu item and see if it needs to have an * accelerator key assigned to it. If so, find the first character * in the menu name that isn't already assigned as an accelerator in * the same menu, assign it to this item, and add it to the map of * already used accelerator keys. These maps are maintained per * path, so accelerator keys may be duplicated across different menus * but are guaranteed to be unique within any given menu. * * @param info A menu extension. * * @param table A hash table of accelerator maps. */ static void gnc_menu_additions_assign_accel (ExtensionInfo *info, GHashTable *table) { gchar *map, *new_map, *new_label, *start, buf[16]; const gchar *ptr; gunichar uni; gint len; gboolean map_allocated = FALSE; ENTER("Checking %s/%s [%s]", info->path, info->ae.label, info->ae.name); if (info->accel_assigned) { LEAVE("Already processed"); return; } /* Get map of used keys */ map = g_hash_table_lookup(table, info->path); if (map == NULL) { map = g_strdup(""); map_allocated = TRUE; } DEBUG("map '%s', path %s", map, info->path); for (ptr = info->ae.label; *ptr; ptr = g_utf8_next_char(ptr)) { uni = g_utf8_get_char(ptr); if (!g_unichar_isalpha(uni)) continue; uni = g_unichar_tolower(uni); len = g_unichar_to_utf8(uni, buf); buf[len] = '\0'; DEBUG("Testing character '%s'", buf); if (!g_utf8_strchr(map, -1, uni)) break; } if (ptr == NULL) { /* Ran out of characters. Nothing to do. */ info->accel_assigned = TRUE; if (map_allocated) { g_free(map); } LEAVE("All characters already assigned"); return; } /* Now build a new string in the form "<start>_<end>". */ start = g_strndup(info->ae.label, ptr - info->ae.label); DEBUG("start %p, len %ld, text '%s'", start, g_utf8_strlen(start, -1), start); new_label = g_strconcat(start, "_", ptr, (gchar *)NULL); g_free(start); DEBUG("label '%s' -> '%s'", info->ae.label, new_label); g_free((gchar *)info->ae.label); info->ae.label = new_label; /* Now build a new map. Old one freed automatically. */ new_map = g_strconcat(map, buf, (gchar *)NULL); DEBUG("map '%s' -> '%s'", map, new_map); g_hash_table_replace(table, info->path, new_map); info->accel_assigned = TRUE; if (map_allocated) { g_free(map); } LEAVE("assigned"); }
static unichar i_tolower(unichar c) { if (term_type == TERM_TYPE_UTF8) return g_unichar_tolower(c); return (c >= 0 && c <= 255) ? tolower(c) : c; }
static gunichar parse_shortcut(const gchar *label, gboolean allow_shortcut, gchar **strippedlabel, guint *position, gboolean *always_show) { gunichar shortcut = 0; *position = 0; *always_show = FALSE; g_assert(strippedlabel != NULL); if (label == NULL) { *strippedlabel = NULL; } else { gchar *i; gboolean escape; *strippedlabel = g_strdup(label); /* if allow_shortcut is false, then you can't use the '_', instead you have to just use the first valid character */ /* allow __ to escape an underscore */ i = *strippedlabel; do { escape = FALSE; i = strchr(i, '_'); if (i && *(i+1) == '_') { gchar *j; /* remove the escape '_' from the string */ for (j = i; *j != '\0'; ++j) *j = *(j+1); ++i; escape = TRUE; } } while (escape); if (allow_shortcut && i != NULL) { /* there is an underscore in the string */ /* you have to use a printable ascii character for shortcuts don't allow space either, so you can have like "a _ b" */ if (VALID_SHORTCUT(*(i+1))) { shortcut = g_unichar_tolower(g_utf8_get_char(i+1)); *position = i - *strippedlabel; *always_show = TRUE; /* remove the '_' from the string */ for (; *i != '\0'; ++i) *i = *(i+1); } else if (*(i+1) == '\0') { /* no default shortcut if the '_' is the last character (eg. "Exit_") for menu entries that you don't want to be executed by mistake */ *i = '\0'; } } else { /* there is no underscore, so find the first valid character to use instead */ for (i = *strippedlabel; *i != '\0'; ++i) if (VALID_SHORTCUT(*i)) { *position = i - *strippedlabel; shortcut = g_unichar_tolower(g_utf8_get_char(i)); break; } } } return shortcut; }