GSList* prof_occurrences(const char *const needle, const char *const haystack, int offset, gboolean whole_word, GSList **result) { if (needle == NULL || haystack == NULL) { return *result; } if (g_str_has_prefix(&haystack[offset], needle)) { if (whole_word) { char *prev = g_utf8_prev_char(&haystack[offset]); char *next = g_utf8_next_char(&haystack[offset] + strlen(needle) - 1); gunichar prevu = g_utf8_get_char(prev); gunichar nextu = g_utf8_get_char(next); if (!g_unichar_isalnum(prevu) && !g_unichar_isalnum(nextu)) { *result = g_slist_append(*result, GINT_TO_POINTER(offset)); } } else { *result = g_slist_append(*result, GINT_TO_POINTER(offset)); } } if (haystack[offset+1] != '\0') { *result = prof_occurrences(needle, haystack, offset+1, whole_word, result); } return *result; }
static char * strstr_word (const char *haystack, const char *needle) { const char *hay = haystack; while (*hay) { char *n = strstr (hay, needle); gboolean failed = FALSE; if (n == NULL) return NULL; if (n != haystack) { char *prev = g_utf8_prev_char (n); if (g_unichar_isalnum (g_utf8_get_char (prev))) failed = TRUE; } if (! failed) { char *next = n + strlen (needle); if (*next && g_unichar_isalnum (g_utf8_get_char (next))) failed = TRUE; } if (! failed) return n; hay = g_utf8_next_char (hay); } return NULL; }
static gboolean search_elem_locate(GtkTextBuffer* buf, gint* pline, gint* poffset, CppElem* elem) { GtkTextIter iter; GtkTextIter limit; GtkTextIter ps; GtkTextIter pe; guint ch; gboolean full_matched; gboolean need_move_cursor; *pline = elem->sline - 1; *poffset = -1; gtk_text_buffer_get_iter_at_line(buf, &iter, *pline); limit = iter; gtk_text_iter_forward_to_line_end(&limit); need_move_cursor = TRUE; full_matched = FALSE; while( gtk_text_iter_forward_search(&iter, elem->name->buf, 0, &ps, &pe, &limit) ) { *poffset = gtk_text_iter_get_line_offset(&pe); gtk_text_buffer_select_range(buf, &pe, &ps); need_move_cursor = FALSE; if( gtk_text_iter_starts_line(&ps) ) { full_matched = TRUE; } else { iter = ps; gtk_text_iter_backward_char(&iter); ch = gtk_text_iter_get_char(&iter); if( !g_unichar_isalnum(ch) && ch!='_' ) full_matched = TRUE; } if( full_matched && !gtk_text_iter_ends_line(&pe) ) { iter = pe; gtk_text_iter_forward_char(&iter); ch = gtk_text_iter_get_char(&iter); if( g_unichar_isalnum(ch) || ch=='_' ) full_matched = FALSE; } if( full_matched ) break; iter = ps; gtk_text_iter_forward_char(&iter); } return need_move_cursor; }
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; }
/* allocates space and returns the index part of a string */ static char * _new_get_index(const char *_string) { if (!_string) return NULL; size_t size; gunichar u; char *string = NULL; if (g_ascii_isalnum(_string[0])) { size = sizeof(char); string = malloc(size+1); string[0] = g_ascii_toupper(_string[0]); } else { u = g_utf8_get_char_validated(_string, -1); if ((u != (gunichar)-1 || u != (gunichar)-2) && g_unichar_isalnum(u)) { u = g_unichar_toupper(u); size = g_unichar_to_utf8(u, NULL); string = malloc(size+1); g_unichar_to_utf8(u, string); } } if (string) string[size] = '\0'; return string; }
static int str_utf8_isalnum (const char *text) { gunichar uni; uni = g_utf8_get_char_validated (text, -1); return g_unichar_isalnum (uni); }
/** * hildon_helper_utf8_strstrcasedecomp_needle_stripped: * @haystack: a haystack where to search * @nuni: a needle to search for, already stripped with hildon_helper_strip_string() * * Heavily modified version of e_util_utf8_strstrcasedecomp(). As its * original version, it finds the first occurrence of @nuni in * @haystack. However, instead of stripping @nuni, it expect it to be * already stripped. See hildon_helper_strip_string(). * * This is done for performance reasons, since this search is done * several times for the same string @nuni, it is undesired to strip * it more than once. * * Also, the search is done as a prefix search, starting in the first * alphanumeric character after any non-alphanumeric one. Searching * for "aba" in "Abasto" will match, searching in "Moraba" will not, * and searching in "A tool (abacus)" will do. * * Returns: the first instance of @nuni in @haystack * * Since: 2.2.18 **/ const gchar * hildon_helper_utf8_strstrcasedecomp_needle_stripped (const gchar *haystack, const gunichar *nuni) { gunichar unival; gint nlen = 0; const gchar *o, *p; gunichar sc; if (haystack == NULL) return NULL; if (nuni == NULL) return NULL; if (strlen (haystack) == 0) return NULL; while (*(nuni + nlen) != 0) nlen++; if (nlen < 1) return haystack; for (p = get_next (haystack, &o, &sc, g_unichar_isalnum (nuni[0])); p && sc; p = get_next (p, &o, &sc, g_unichar_isalnum (nuni[0]))) { if (sc) { /* We have valid stripped gchar */ if (sc == nuni[0]) { const gchar *q = p; gint npos = 1; while (npos < nlen) { q = e_util_unicode_get_utf8 (q, &unival); if (!q || !unival) return NULL; sc = stripped_char (unival); if ((!sc) || (sc != nuni[npos])) break; npos++; } if (npos == nlen) { return o; } } } while (p) { sc = g_utf8_get_char (p); if (!g_unichar_isalnum (sc)) break; p = g_utf8_next_char (p); } } return NULL; }
/************************************************************************** Autocompletes the input line with a player or user name. Returns FALSE if there is no string to complete. **************************************************************************/ static bool chatline_autocomplete(GtkEditable *editable) { #define MAX_MATCHES 10 const char *name[MAX_MATCHES]; char buf[MAX_LEN_NAME * MAX_MATCHES]; gint pos; gchar *chars, *p, *prev; int num, i; size_t prefix_len; /* Part 1: get the string to complete. */ pos = gtk_editable_get_position(editable); chars = gtk_editable_get_chars(editable, 0, pos); p = chars + strlen(chars); while ((prev = g_utf8_find_prev_char(chars, p))) { if (!g_unichar_isalnum(g_utf8_get_char(prev))) { break; } p = prev; } /* p points to the start of the last word, or the start of the string. */ prefix_len = g_utf8_strlen(p, -1); if (0 == prefix_len) { /* Empty: nothing to complete, propagate the event. */ g_free(chars); return FALSE; } /* Part 2: compare with player and user names. */ num = check_player_or_user_name(p, name, MAX_MATCHES); if (1 == num) { gtk_editable_delete_text(editable, pos - prefix_len, pos); pos -= prefix_len; gtk_editable_insert_text(editable, name[0], strlen(name[0]), &pos); gtk_editable_set_position(editable, pos); g_free(chars); return TRUE; } else if (num > 1) { if (get_common_prefix(name, num, buf, sizeof(buf)) > prefix_len) { gtk_editable_delete_text(editable, pos - prefix_len, pos); pos -= prefix_len; gtk_editable_insert_text(editable, buf, strlen(buf), &pos); gtk_editable_set_position(editable, pos); } sz_strlcpy(buf, name[0]); for (i = 1; i < num; i++) { cat_snprintf(buf, sizeof(buf), ", %s", name[i]); } /* TRANS: comma-separated list of player/user names for completion */ output_window_printf(ftc_client, _("Suggestions: %s."), buf); } g_free(chars); return TRUE; }
gboolean html_engine_backward_word (HTMLEngine *e) { gboolean rv = FALSE; g_return_val_if_fail (e != NULL, FALSE); g_return_val_if_fail (HTML_IS_ENGINE (e), FALSE); html_engine_hide_cursor (e); while (!g_unichar_isalnum (html_cursor_get_prev_char (e->cursor)) && html_cursor_backward (e->cursor, e)) rv = TRUE; while (g_unichar_isalnum (html_cursor_get_prev_char (e->cursor)) && html_cursor_backward (e->cursor, e)) rv = TRUE; html_engine_update_focus_if_necessary (e, e->cursor->object, e->cursor->offset); html_engine_show_cursor (e); html_engine_update_selection_if_necessary (e); return rv; }
/** * gsc_utils_char_is_separator: * @ch: The character to check * * A separator is a character like (, an space etc. An _ is not a separator * * Returns TRUE if the ch is a separator */ gboolean gsc_utils_is_separator(const gunichar ch) { if (g_unichar_isprint(ch) && (g_unichar_isalnum(ch) || ch == g_utf8_get_char("_"))) { return FALSE; } return TRUE; }
static void text_move_cursor(Text *text, CursorMovement mv) { gchar *str = text_line_get_string(text->lines[text->cursor_row]); gchar *p = str; int curmax = text_get_line_strlen(text, text->cursor_row); if (text->cursor_pos > 0 && text->cursor_pos <= curmax) { int i; for (i = 0; i < text->cursor_pos; ++i) p = g_utf8_next_char (p); } if (WORD_START == mv && text->cursor_pos < 1) { if (text->cursor_row) { text->cursor_row--; text->cursor_pos = text_get_line_strlen(text, text->cursor_row); } return; } else if (WORD_END == mv && text->cursor_pos == curmax) { if (text->cursor_row < text->numlines - 1) { text->cursor_row++; text->cursor_pos = 0; } return; } while (!g_unichar_isalnum (g_utf8_get_char (p))) { p = (WORD_START == mv ? g_utf8_find_prev_char (str, p) : g_utf8_next_char (p)); if (p) text->cursor_pos += (WORD_START == mv ? -1 : 1); if (!p || !*p) return; if (!text->cursor_pos || text->cursor_pos == curmax) return; } while (g_unichar_isalnum (g_utf8_get_char (p))) { p = (WORD_START == mv ? g_utf8_find_prev_char (str, p) : g_utf8_next_char (p)); if (p) text->cursor_pos += (WORD_START == mv ? -1 : 1); if (!p || !*p) return; if (!text->cursor_pos || text->cursor_pos == curmax) return; } }
static inline gboolean is_symbol_char (gunichar ch) { switch (ch) { case '_': return TRUE; default: return g_unichar_isalnum (ch); } }
static gboolean match_is_word (const char *src, const GORegmatch *pm, gboolean bolp) { /* The empty string is not a word. */ if (pm->rm_so == pm->rm_eo) return FALSE; if (pm->rm_so > 0 || !bolp) { /* We get here when something actually preceded the match. */ gunichar c_pre = g_utf8_get_char (g_utf8_prev_char (src + pm->rm_so)); if (g_unichar_isalnum (c_pre)) return FALSE; } { gunichar c_post = g_utf8_get_char (src + pm->rm_eo); if (c_post != 0 && g_unichar_isalnum (c_post)) return FALSE; } return TRUE; }
static gboolean mousepad_util_iter_word_characters (const GtkTextIter *iter) { gunichar c; /* get the characters */ c = gtk_text_iter_get_char (iter); /* character we'd like to see in a word */ if (g_unichar_isalnum (c) || c == '_') return TRUE; return FALSE; }
/* takes an existing 'words' list, and converts it to another consisting of only simple words, with any punctuation etc stripped */ struct _camel_search_words * camel_search_words_simple (struct _camel_search_words *wordin) { gint i; const guchar *ptr, *start, *last; gint type = CAMEL_SEARCH_WORD_SIMPLE, all = 0; GPtrArray *list = g_ptr_array_new (); struct _camel_search_word *word; struct _camel_search_words *words; guint32 c; words = g_malloc0 (sizeof (*words)); for (i=0;i<wordin->len;i++) { if ((wordin->words[i]->type & CAMEL_SEARCH_WORD_COMPLEX) == 0) { word = g_malloc0 (sizeof (*word)); word->type = wordin->words[i]->type; word->word = g_strdup (wordin->words[i]->word); g_ptr_array_add (list, word); } else { ptr = (const guchar *) wordin->words[i]->word; start = last = ptr; do { c = camel_utf8_getc (&ptr); if (c == 0 || !g_unichar_isalnum (c)) { if (last > start) { word = g_malloc0 (sizeof (*word)); word->word = g_strndup ((gchar *) start, last-start); word->type = type; g_ptr_array_add (list, word); all |= type; type = CAMEL_SEARCH_WORD_SIMPLE; } start = ptr; } if (c > 0x80) type = CAMEL_SEARCH_WORD_8BIT; last = ptr; } while (c); } } words->len = list->len; words->words = (struct _camel_search_word **)list->pdata; words->type = all; g_ptr_array_free (list, FALSE); return words; }
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); }
/** * expr_name_validate: * @name: tentative name * * returns TRUE if the given name is valid, FALSE otherwise. */ gboolean expr_name_validate (const char *name) { const char *p; GnmValue *v; g_return_val_if_fail (name != NULL, FALSE); if (name[0] == 0) return FALSE; v = value_new_from_string (VALUE_BOOLEAN, name, NULL, TRUE); if (!v) v = value_new_from_string (VALUE_BOOLEAN, name, NULL, FALSE); if (v) { value_release (v); return FALSE; } /* Hmm... Now what? */ if (!g_unichar_isalpha (g_utf8_get_char (name)) && name[0] != '_') return FALSE; for (p = name; *p; p = g_utf8_next_char (p)) { if (!g_unichar_isalnum (g_utf8_get_char (p)) && p[0] != '_') return FALSE; } /* Make sure it's not A1 etc.*/ /* Note that we can't use our regular parsers */ /* since we also have to avoid names that may become */ /* sensible when the sheet size changes. */ if (!expr_name_validate_a1 (name)) return FALSE; /* What about R1C1? */ if (!expr_name_validate_r1c1 (name)) return FALSE; return TRUE; }
/** * get_next: * @p: a pointer to the string to search. * @o: a place to store the location of the next valid char. * @out: a place to store the next valid char. * @separators: whether to search only for alphanumeric strings * and skip any word separator. * * Gets the next character that is valid in our search scope, and * store it into @out. The next char, after @out is returned. * * Returns: the next point in the string @p where to continue the * string iteration. **/ static const gchar * get_next (const gchar *p, const gchar **o, gunichar *out, gboolean separators) { gunichar utf8; if (separators) { do { *o = p; p = e_util_unicode_get_utf8 (p, &utf8); *out = stripped_char (utf8); } while (p && utf8 && !g_unichar_isalnum (*out)); } else { *o = p; p = e_util_unicode_get_utf8 (p, &utf8); *out = stripped_char (utf8); } return p; }
static gboolean is_nonalnum (const gchar *str) { gunichar uchar; if (str == NULL) { return FALSE; } uchar = g_utf8_get_char (str); if (g_unichar_isalnum (uchar)) { return FALSE; } if (uchar == '!' || uchar == '?' || uchar == '.') { return FALSE; } return TRUE; }
static char * gal_view_generate_string (GalViewCollection *collection, GalView *view, int which) { char *ret_val; char *pointer; if (which == 1) ret_val = g_strdup(gal_view_get_title(view)); else ret_val = g_strdup_printf("%s_%d", gal_view_get_title(view), which); for (pointer = ret_val; *pointer; pointer = g_utf8_next_char(pointer)) { if (!g_unichar_isalnum(g_utf8_get_char(pointer))) { char *ptr = pointer; for (; ptr < g_utf8_next_char(pointer); *ptr = '_', ptr++) ; } } return ret_val; }
static gboolean is_stop_char (gunichar c) { switch (c) { case '_': return FALSE; case ')': case '(': case '&': case '*': case '{': case '}': case ' ': case '\t': case '[': case ']': case '=': case '"': case '\'': return TRUE; default: return !g_unichar_isalnum(c); } }
void *validate_value(gint value_id, gint input_type, void *value) { // Local variables guint base_type; guint capabilities; gboolean capability_check; gchar *conversion_buffer = NULL; // Used when converting between unicode character types gchar *decimal_point; GString *error_string; gchar input_char; gunichar input_char_unicode; gchar *input_ptr; struct lconv *locale_info; gboolean match_found; gint output_gint; gint *output_gint_ptr; gfloat output_gfloat; gfloat *output_gfloat_ptr; GString *output_gstring; guint output_guint; guint *output_guint_ptr; guint string_counter; gint string_length; gint string_max; guint string_min; gfloat value_max; gfloat value_min; // Initialise various things base_type = get_valid_fields_base_type(value_id); capabilities = get_valid_fields_capabilities(value_id); input_ptr = (gchar *) value; output_gstring = g_string_new(NULL); locale_info = localeconv(); decimal_point = locale_info->decimal_point; switch (base_type) { case V_CHAR: // * We're validating a char or string * // We can only validate string input for this type of value if (V_CHAR != input_type) { return NULL; } // Get the length of the input string string_max = get_valid_fields_max_value(value_id); string_min = get_valid_fields_min_value(value_id); string_length = g_utf8_strlen(input_ptr, -1); // If the length of the string isn't in the acceptable range, return NULL if (string_length < string_min) return NULL; if ((string_length > string_max) && (-1 != string_max)) // -1 for string_max means "no maximum limit" return NULL; if (0 == string_length) { // 0 length string, so we just return it return output_gstring; } // Sanitise each character of the input string for (string_counter = 0; string_counter < string_length; string_counter++) { // Get the next character input_char_unicode = g_utf8_get_char_validated(input_ptr, -1); if ((gunichar)-1 == input_char_unicode) { // The returned character was not a valid unicode character, so we indicate failure return NULL; } if ((gunichar)-2 == input_char_unicode) { // The returned character was not a valid unicode character, so we indicate failure return NULL; } // Convert the character to UTF-8 so we can process it conversion_buffer = g_ucs4_to_utf8(&input_char_unicode, 1, NULL, NULL, NULL); // Determine which character we're examining if (TRUE == g_unichar_isalnum(input_char_unicode)) { // It's a standard unicode alphanumeric character, so we accept it as is g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); } else { // * The input wasn't a standard alphanumic character, so check if it * // * is one of the characters in the capabilities list for this field * match_found = FALSE; capability_check = V_ANY_UNICHAR & capabilities; if (FALSE != capability_check) { // This field is allowed to have any valid unicode character if (TRUE == g_unichar_validate(input_char_unicode)) { // Yes, this is a valid unicode character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_SPACES & capabilities; if (FALSE != capability_check) { // This field is allowed to have spaces if (0 == g_strcmp0(" ", conversion_buffer)) { // Yes, this is a space character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_FULL_STOP & capabilities; if (FALSE != capability_check) { // This field is allowed to have full stops if (0 == g_strcmp0(".", conversion_buffer)) { // Yes, this is a full stop character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_HYPENS & capabilities; if (FALSE != capability_check) { // This field is allowed to have hypens if (0 == g_strcmp0("-", conversion_buffer)) { // Yes, this is a hypen character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_UNDERSCORES & capabilities; if (FALSE != capability_check) { // This field is allowed to have underscores if (0 == g_strcmp0("_", conversion_buffer)) { // Yes, this is an underscore character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_PATH_SEP & capabilities; if (FALSE != capability_check) { // This field is allowed to have path separator characters ('/', '\') if ((0 == g_strcmp0("/", conversion_buffer)) || (0 == g_strcmp0("\\", conversion_buffer))) { // Yes, this is a path separator character match_found = TRUE; output_gstring = g_string_append_c(output_gstring, G_DIR_SEPARATOR); // Output the OS correct version input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_EQUALS & capabilities; if (FALSE != capability_check) { // This field is allowed to have equals signs if (0 == g_strcmp0("=", conversion_buffer)) { // Yes, this is an equals sign character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_FORWARD_SLASHES & capabilities; if (FALSE != capability_check) { // This field is allowed to have forward slashes if (0 == g_strcmp0("/", conversion_buffer)) { // Yes, this is a forward slash character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_NEW_LINES & capabilities; if (FALSE != capability_check) { // This field is allowed to have new line characters if (0 == g_strcmp0("\n", conversion_buffer)) { // Yes, this is a new line character match_found = TRUE; output_gstring = g_string_append_c(output_gstring, '\n'); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_PLUSES & capabilities; if (FALSE != capability_check) { // This field is allowed to have pluses if (0 == g_strcmp0("+", conversion_buffer)) { // Yes, this is a plus character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_PERCENT & capabilities; if (FALSE != capability_check) { // This field is allowed to have the percent sign if (0 == g_strcmp0("%", conversion_buffer)) { // Yes, this is a percent sign match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_COLON & capabilities; if (FALSE != capability_check) { // This field is allowed to have colons if (0 == g_strcmp0(":", conversion_buffer)) { // Yes, this is a colon character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_AT & capabilities; if (FALSE != capability_check) { // This field is allowed to have the at symbol if (0 == g_strcmp0("@", conversion_buffer)) { // Yes, this is an at character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_QUESTION & capabilities; if (FALSE != capability_check) { // This field is allowed to have the question mark if (0 == g_strcmp0("?", conversion_buffer)) { // Yes, this is a question mark character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } capability_check = V_AMPERSAND & capabilities; if (FALSE != capability_check) { // This field is allowed to have the ampersand character if (0 == g_strcmp0("&", conversion_buffer)) { // Yes, this is an ampersand character match_found = TRUE; g_string_append_printf(output_gstring, "%s", conversion_buffer); input_ptr = g_utf8_find_next_char(input_ptr, NULL); continue; } } // The character we are checking is not in the list of valid inputs for this field if (FALSE == match_found) { g_free(conversion_buffer); g_string_free(output_gstring, TRUE); return NULL; } } } // Remove any leading and/or trailing white space output_gstring->str = g_strstrip(output_gstring->str); output_gstring->len = strlen(output_gstring->str); // Recheck the length of the output string if (output_gstring->len < string_min) { g_free(conversion_buffer); g_string_free(output_gstring, TRUE); return NULL; } // Free the memory used so far if (0 != string_length) { g_free(conversion_buffer); } // The string seems to be valid, so return it for use return output_gstring; break; case V_FLOAT_UNSIGNED: // * We're validating an unsigned float * // If we're working with string input, we need to convert it to a float first if (V_CHAR == input_type) { // * We're working with string input * // Get the length of the input string string_length = strlen((gchar *) value); // Sanitise each character of the input string for (string_counter = 0; string_counter < string_length; string_counter++) { input_char = ((gchar *) value)[string_counter]; // Check for decimal digits if (TRUE == g_ascii_isdigit(input_char)) { output_gstring = g_string_append_c(output_gstring, input_char); } else { // This field is allowed to have full stops. Is this character a full stop? if (0 == g_ascii_strncasecmp(".", &input_char, 1)) { // Yes, this is a full stop character output_gstring = g_string_append_c(output_gstring, *decimal_point); match_found = TRUE; continue; } // This field is allowed to have commas (equiv to full stop in some locales). Is this character a comma? if (0 == g_ascii_strncasecmp(",", &input_char, 1)) { // Yes, this is a comma character output_gstring = g_string_append_c(output_gstring, *decimal_point); match_found = TRUE; continue; } // The character we are checking is not in the list of valid inputs for this field if (FALSE == match_found) { g_string_free(output_gstring, TRUE); return NULL; } } } // Convert the string to a float output_gfloat = (gfloat) g_strtod(output_gstring->str, NULL); } else { // We're working with a float input, so just copy the value directly output_gfloat = *((gfloat *) value); } // Is the float value within the defined bounds? value_max = get_valid_fields_max_value(value_id); value_min = get_valid_fields_min_value(value_id); if ((output_gfloat < value_min) || (output_gfloat > value_max)) { // Value is out of bounds, so fail g_string_free(output_gstring, TRUE); return NULL; } // The value looks ok, so we copy it to newly allocated memory, to pass it back output_gfloat_ptr = g_try_new0(gfloat, 1); if (NULL == output_gfloat_ptr) { // Unable to allocate memory for the new value, so fail g_string_free(output_gstring, TRUE); return NULL; } *output_gfloat_ptr = output_gfloat; // Free the string memory allocated in this function g_string_free(output_gstring, TRUE); return output_gfloat_ptr; case V_INT_UNSIGNED: // * We're validating an unsigned integer * // If we're working with string input, we need to convert it to an integer first if (V_CHAR == input_type) { // * We're working with string input * // Get the length of the input string string_length = strlen((gchar *) value); // Sanitise each character of the input string for (string_counter = 0; string_counter < string_length; string_counter++) { input_char = ((gchar *) value)[string_counter]; // Check for decimal digits if (TRUE == g_ascii_isdigit(input_char)) { output_gstring = g_string_append_c(output_gstring, input_char); } else { // This wasn't a valid character g_string_free(output_gstring, TRUE); return NULL; } } // Convert the string to an integer output_guint = atoi(output_gstring->str); } else { // We're working with integer input, so just copy the value directly output_guint = *((guint *) value); } // Is the integer value within the defined bounds? value_max = get_valid_fields_max_value(value_id); value_min = get_valid_fields_min_value(value_id); if ((output_guint < value_min) || (output_guint > value_max)) { // Value is out of bounds, so fail g_string_free(output_gstring, TRUE); return NULL; } // The value looks ok, so we copy it to newly allocated memory, to pass it back output_guint_ptr = g_try_new0(guint, 1); if (NULL == output_guint_ptr) { // Unable to allocate memory for the new value, so fail g_string_free(output_gstring, TRUE); return NULL; } *output_guint_ptr = output_guint; // Free the string memory allocated in this function g_string_free(output_gstring, TRUE); return output_guint_ptr; case V_INT_SIGNED: // * We're validating a signed integer * // If we're working with string input, we need to convert it to an integer first if (V_CHAR == input_type) { // * We're working with string input * // Get the length of the input string string_length = strlen((gchar *) value); // Sanitise each character of the input string for (string_counter = 0; string_counter < string_length; string_counter++) { input_char = ((gchar *) value)[string_counter]; // Check for decimal digits if (TRUE == g_ascii_isdigit(input_char)) { output_gstring = g_string_append_c(output_gstring, input_char); } else { // * The input wasn't a standard digit character, so check if it * // * is one of the characters in the capabilities list for this field * match_found = FALSE; capability_check = V_HYPENS & capabilities; if (FALSE != capability_check) { // This field is allowed to have hypens if (0 == g_ascii_strncasecmp("-", &input_char, 1)) { // Yes, this is a hypen character match_found = TRUE; g_string_append_printf(output_gstring, "%s", "-"); } } // The character we are checking is not in the list of valid inputs for this field if (FALSE == match_found) { g_string_free(output_gstring, TRUE); return NULL; } } } // Convert the string to an integer output_gint = atoi(output_gstring->str); } else { // We're working with integer input, so just copy the value directly output_gint = *((gint *) value); } // Is the integer value within the defined bounds? value_max = get_valid_fields_max_value(value_id); value_min = get_valid_fields_min_value(value_id); if ((output_gint < value_min) || (output_gint > value_max)) { // Value is out of bounds, so fail g_string_free(output_gstring, TRUE); return NULL; } // The value looks ok, so we copy it to newly allocated memory, to pass it back output_gint_ptr = g_try_new0(gint, 1); if (NULL == output_gint_ptr) { // Unable to allocate memory for the new value, so fail g_string_free(output_gstring, TRUE); return NULL; } *output_gint_ptr = output_gint; // Free the string memory allocated in this function g_string_free(output_gstring, TRUE); return output_gint_ptr; case V_RESOLUTION: // * We're working with a resolution (text string) input. i.e. '1920x1200 pixels' * // Get the length of the input string string_length = strlen((gchar *) value); string_max = get_valid_fields_max_value(value_id); string_min = get_valid_fields_min_value(value_id); // If the length of the string isn't in the acceptable range, return NULL if ((string_length < string_min) || (string_length > string_max)) return NULL; // Sanitise each character of the input string for (string_counter = 0; string_counter < string_length; string_counter++) { input_char = ((gchar *) value)[string_counter]; // Check for decimal digits if (TRUE == g_ascii_isdigit(input_char)) { output_gstring = g_string_append_c(output_gstring, input_char); } else { match_found = FALSE; // This field is allowed to have the ' ' and 'x' characters . Is this character one of those? if (0 == g_ascii_strncasecmp(" ", &input_char, 1)) { // Yes, this is a space character, so we've already collected the required resolution // info and we can just return the resolution part of the string so far // Remove any leading and/or trailing white space output_gstring->str = g_strstrip(output_gstring->str); output_gstring->len = strlen(output_gstring->str); // Recheck the length of the output string if ((string_length < string_min) || (string_length > string_max)) return NULL; // The string seems to be valid, so return it for use return output_gstring; } if (0 == g_ascii_strncasecmp("x", &input_char, 1)) { // Yes, this is a 'x' character output_gstring = g_string_append_c(output_gstring, 'x'); match_found = TRUE; continue; } if (FALSE == match_found) { // This wasn't a valid character g_string_free(output_gstring, TRUE); return NULL; } } } // Remove any leading and/or trailing white space output_gstring->str = g_strstrip(output_gstring->str); output_gstring->len = strlen(output_gstring->str); // Recheck the length of the output string if ((string_length < string_min) || (string_length > string_max)) return NULL; // The string seems to be valid, so return it for use return output_gstring; case V_ZOOM: // * We're working with a zoom level. i.e. "100%" or "Fit to width" * // Get the length of the input string string_length = g_utf8_strlen((gchar *) value, -1); string_max = get_valid_fields_max_value(value_id); string_min = get_valid_fields_min_value(value_id); // If the length of the string isn't in the acceptable range, return NULL if ((string_length < string_min) || (string_length > string_max)) return NULL; // If the string is "Fit to width" or a localised version of it if ((0 == g_strcmp0("Fit to width", (gchar *) value)) || (0 == g_strcmp0(_("Fit to width"), (gchar *) value))) { // Yes, this is the "Fit to width" value output_gstring = g_string_assign(output_gstring, value); return output_gstring; } // * The incoming string isn't the "Fit to width" value, * // * so should only consist of decimal characters and '%' * // Sanitise each character of the input string for (string_counter = 0; string_counter < string_length; string_counter++) { input_char = ((gchar *) value)[string_counter]; // Check for decimal digits if (TRUE == g_ascii_isdigit(input_char)) { output_gstring = g_string_append_c(output_gstring, input_char); continue; } // Check for '%' character if (0 == g_ascii_strncasecmp("%", &input_char, 1)) { // Yes, this is a '%' character output_gstring = g_string_append_c(output_gstring, '%'); continue; } // This wasn't a valid character g_string_free(output_gstring, TRUE); return NULL; } return output_gstring; default: // Unknown value type, we should never get here error_string = g_string_new(NULL); g_string_printf(error_string, "%s ED119: %s - '%s'", _("Error"), _("Unknown value passed to validation function"), get_valid_fields_name(value_id)); display_warning(error_string->str); g_string_free(error_string, TRUE); return NULL; } // If we get here, then something went wrong! return NULL; }
static gboolean is_word_char (gunichar ch) { return g_unichar_isprint (ch) && (g_unichar_isalnum (ch) || ch == '_' || ch == ':' || ch == '.'); }
static gboolean cover_thumbnailer_get_title (CoverThumbnailer *cover, GFile *gfile, gchar **ret_title, gchar **ret_year) { gchar *basename; gboolean is_series; GMatchInfo *match_info; gint start_pos; gint end_pos; gchar *year = NULL; GString *title; const gchar *p; gboolean append_space; gunichar uchar; gboolean succeed; gchar *temp; g_return_val_if_fail (G_IS_FILE (gfile), FALSE); g_return_val_if_fail (ret_title != NULL, FALSE); g_return_val_if_fail (ret_year != NULL, FALSE); /* get the basename */ basename = g_file_get_basename (gfile); /* check if the title looks like a serie */ is_series = g_regex_match (cover->series_regex, basename, 0, &match_info); /* if this is not a serie, look for other filename crap */ if (is_series || g_regex_match (cover->abbrev_regex, basename, 0, &match_info)) { /* remove series or abbrev suffix from the filename */ if (g_match_info_fetch_pos (match_info, 0, &start_pos, NULL) && start_pos > 0) basename[start_pos] = '\0'; g_match_info_free (match_info); } /* for non-series, look for a year in the title */ if (!is_series && g_regex_match (cover->year_regex, basename, 0, &match_info)) { /* store year and remove the suffix from the title */ if (g_match_info_fetch_pos (match_info, 0, &start_pos, &end_pos) && start_pos >= 0 && end_pos > start_pos) { year = g_strndup (basename + start_pos, end_pos - start_pos); if (start_pos == 0) { temp = g_strdup (basename + end_pos); g_free (basename); basename = temp; } else { basename[start_pos] = '\0'; } } g_match_info_free (match_info); } /* append the possible title part of the filename */ title = g_string_sized_new (strlen (basename)); for (p = basename, append_space = FALSE; *p != '\0'; p = g_utf8_next_char (p)) { uchar = g_utf8_get_char (p); if (g_unichar_isalnum (uchar) || uchar == '\'' || uchar == '!') { if (append_space) { g_string_append_c (title, '+'); append_space = FALSE; } /* append the char */ g_string_append_unichar (title, uchar); } else if (title->len > 0) { /* start with a space next time we append a char */ append_space = TRUE; } } /* finalize */ g_free (basename); succeed = title->len > 1; *ret_title = g_string_free (title, !succeed); *ret_year = year; return succeed; }
static int i_isalnum(unichar c) { if (term_type == TERM_TYPE_UTF8) return (g_unichar_isalnum(c) || mk_wcwidth(c) == 0); return (c >= 0 && c <= 255) ? isalnum(c) : 0; }
static gint key_press(guint keyval, gchar *commit_str, gchar *preedit_str) { gchar *letter; gint i; LettersItem *item; gchar *str; gunichar unichar_letter; gint retval = TRUE; if(!gcomprisBoard) return FALSE; if (keyval){ g_warning("keyval %d", keyval); return TRUE; } if (preedit_str){ g_warning("preedit_str %s", preedit_str); /* show the preedit string on bottom of the window */ GcomprisProperties *properties = gc_prop_get (); gchar *text; PangoAttrList *attrs; gint cursor_pos; gtk_im_context_get_preedit_string (properties->context, &text, &attrs, &cursor_pos); if (!preedit_text) preedit_text = \ goo_canvas_text_new (goo_canvas_get_root_item(gcomprisBoard->canvas), "", BOARDWIDTH/2, BOARDHEIGHT - 100, -1, GTK_ANCHOR_N, "font", gc_skin_font_board_huge_bold, //"fill_color_rgba", 0xba00ffff, NULL); g_object_set (preedit_text, "text", text, "attributes", attrs, NULL); return TRUE; } /* commit str */ g_warning("commit_str %s", commit_str); str = commit_str; #if GLIB_CHECK_VERSION(2, 31, 0) g_mutex_lock (&items_lock); #else g_static_mutex_lock (&items_lock); #endif for (i=0; i < g_utf8_strlen(commit_str,-1); i++){ unichar_letter = g_utf8_get_char(str); str = g_utf8_next_char(str); if(!g_unichar_isalnum (unichar_letter)){ player_loose(); retval = FALSE; break; } letter = g_new0(gchar,6); g_unichar_to_utf8 (unichar_letter, letter); /* Force entered letter to the casing we expect * Children is to small to manage the caps lock key for now */ if (uppercase_only) { gchar *old = letter; letter = g_utf8_strup(old, -1); g_free(old); } else { gchar *old = letter; letter = g_utf8_strdown(old, -1); g_free(old); } if(item_on_focus==NULL) { for (i=0;i<items->len;i++) { item=g_ptr_array_index(items,i); g_assert (item!=NULL); if (strcmp(item->letter,letter)==0) { item_on_focus=item; break; } } } if(item_on_focus!=NULL) { if(strcmp(item_on_focus->letter, letter)==0) { gchar *tmpstr; item_on_focus->count++; g_free(item_on_focus->overword); tmpstr = g_utf8_strndup(item_on_focus->word, item_on_focus->count); /* Add the ZERO WIDTH JOINER to force joined char in Arabic and Hangul * http://en.wikipedia.org/wiki/Zero-width_joiner */ item_on_focus->overword = g_strdup_printf("%s%lc", tmpstr, 0x200D); g_free(tmpstr); g_object_set (item_on_focus->overwriteItem, "text", item_on_focus->overword, NULL); if (item_on_focus->count<g_utf8_strlen(item_on_focus->word,-1)) { g_free(item_on_focus->letter); item_on_focus->letter=g_utf8_strndup(item_on_focus->pos,1); item_on_focus->pos=g_utf8_find_next_char(item_on_focus->pos,NULL); } else { player_win(item_on_focus); item_on_focus=NULL; } } else { /* It is a loose : unselect the word and defocus */ g_free(item_on_focus->overword); item_on_focus->overword=g_strdup(" "); item_on_focus->count=0; g_free(item_on_focus->letter); item_on_focus->letter=g_utf8_strndup(item_on_focus->word,1); item_on_focus->pos=g_utf8_find_next_char(item_on_focus->word,NULL); g_object_set (item_on_focus->overwriteItem, "text", item_on_focus->overword, NULL); item_on_focus=NULL; g_free(letter); player_loose(); break; } } else { /* Anyway kid you clicked on the wrong key */ player_loose(); g_free(letter); break; } g_free(letter); } #if GLIB_CHECK_VERSION(2, 31, 0) g_mutex_unlock (&items_lock); #else g_static_mutex_unlock (&items_lock); #endif return retval; }
static gchar* vala_ccode_file_get_define_for_filename (const gchar* filename) { gchar* result = NULL; GString* _tmp0_; GString* define; const gchar* _tmp1_; gchar* _tmp2_; gchar* i; GString* _tmp20_; GString* _tmp21_; const gchar* _tmp22_; gchar* _tmp23_; g_return_val_if_fail (filename != NULL, NULL); _tmp0_ = g_string_new ("__"); define = _tmp0_; _tmp1_ = filename; _tmp2_ = g_strdup (_tmp1_); i = _tmp2_; while (TRUE) { const gchar* _tmp3_; gint _tmp4_; gint _tmp5_; const gchar* _tmp6_; gunichar _tmp7_ = 0U; gunichar c; gboolean _tmp8_ = FALSE; gunichar _tmp9_; gboolean _tmp10_ = FALSE; gboolean _tmp12_; const gchar* _tmp17_; const gchar* _tmp18_ = NULL; gchar* _tmp19_; _tmp3_ = i; _tmp4_ = strlen (_tmp3_); _tmp5_ = _tmp4_; if (!(_tmp5_ > 0)) { break; } _tmp6_ = i; _tmp7_ = string_get_char (_tmp6_, (glong) 0); c = _tmp7_; _tmp9_ = c; _tmp10_ = g_unichar_isalnum (_tmp9_); if (_tmp10_) { gunichar _tmp11_; _tmp11_ = c; _tmp8_ = _tmp11_ < ((gunichar) 0x80); } else { _tmp8_ = FALSE; } _tmp12_ = _tmp8_; if (_tmp12_) { GString* _tmp13_; gunichar _tmp14_; gunichar _tmp15_ = 0U; _tmp13_ = define; _tmp14_ = c; _tmp15_ = g_unichar_toupper (_tmp14_); g_string_append_unichar (_tmp13_, _tmp15_); } else { GString* _tmp16_; _tmp16_ = define; g_string_append_c (_tmp16_, '_'); } _tmp17_ = i; _tmp18_ = g_utf8_next_char (_tmp17_); _tmp19_ = g_strdup (_tmp18_); _g_free0 (i); i = _tmp19_; } _tmp20_ = define; g_string_append (_tmp20_, "__"); _tmp21_ = define; _tmp22_ = _tmp21_->str; _tmp23_ = g_strdup (_tmp22_); result = _tmp23_; _g_free0 (i); _g_string_free0 (define); return result; }
static void run_smartquotes(GtkTextBuffer *buffer) { GtkTextIter pos, nextpos; gunichar lastc = 0, c = 0, nextc; int balance[10] = {0}; /* max 10 levels of nesting. */ int curnesting = -1; gboolean insidetag = FALSE, closing; int quotes; /* this runs as the user is typing, so undo doesn't make much sense. gtk_text_buffer_begin_user_action(buffer); */ gtk_text_buffer_get_start_iter(buffer, &pos); while ((c = gtk_text_iter_get_char(&pos)) != 0) { nextpos = pos; gtk_text_iter_forward_char(&nextpos); nextc = gtk_text_iter_get_char(&nextpos); /*g_printf("ofs %d\n", gtk_text_iter_get_offset(&pos));*/ if (c == '<') insidetag = TRUE; else if (c == '>') insidetag = FALSE; quotes = count_quotes(c); if (insidetag || quotes == 0) { lastc = c; gtk_text_iter_forward_char(&pos); continue; } closing = (curnesting >= 0 && balance[curnesting] == quotes); if (quotes == 1 && g_unichar_isalnum(lastc) && (!closing || g_unichar_isalnum(nextc))) { /* an apostrophe. fix it up, but don't change nesting. */ /*g_print("n %d apos %c\n", curnesting, (char)c);*/ buffer_change_quote(buffer, &pos, &nextpos, c, UNICODE_RIGHTSINGLEQUOTE); } else if (closing) { /*g_print("n %d right %c\n", curnesting, (char)c);*/ buffer_change_quote(buffer, &pos, &nextpos, c, quotes == 1 ? UNICODE_RIGHTSINGLEQUOTE : UNICODE_RIGHTDOUBLEQUOTE); curnesting--; } else { /*g_print("n %d left %c\n", curnesting, (char)c);*/ buffer_change_quote(buffer, &pos, &nextpos, c, quotes == 1 ? UNICODE_LEFTSINGLEQUOTE : UNICODE_LEFTDOUBLEQUOTE); curnesting++; balance[curnesting] = quotes; } if (curnesting >= 9) { g_warning("too many nested quotes."); } lastc = c; gtk_text_iter_forward_char(&pos); } /* gtk_text_buffer_end_user_action(buffer); */ }
void autocomp_run(BluefishTextView * btv, gboolean user_requested) { GtkTextIter cursorpos, iter; BluefishTextView *master = BLUEFISH_TEXT_VIEW(btv->master); gint contextnum; gunichar uc; Tfound *found=NULL; Tfoundblock *fblock = NULL; /* needed for the special case to close generix xml tags based on the top of the blockstack, or to match conditional autocompletion strings */ if (G_UNLIKELY(!master->bflang || !master->bflang->st)) return; gtk_text_buffer_get_iter_at_mark(btv->buffer, &cursorpos, gtk_text_buffer_get_insert(btv->buffer)); iter = cursorpos; gtk_text_iter_set_line_offset(&iter, 0); scan_for_autocomp_prefix(master, &iter, &cursorpos, &contextnum); DBG_AUTOCOMP("autocomp_run, got possible match start at %d in context %d, cursor is at %d\n", gtk_text_iter_get_offset(&iter), contextnum, gtk_text_iter_get_offset(&cursorpos)); /* see if character at cursor is end or symbol */ uc = gtk_text_iter_get_char(&cursorpos); if (G_UNLIKELY(uc > NUMSCANCHARS)) return; /*identstate = g_array_index(master->bflang->st->contexts, Tcontext, contextnum).identstate;*/ if (!character_is_symbol(master->bflang->st,contextnum,uc)) { /* current character is not a symbol! */ DBG_AUTOCOMP("autocomp_run, character at cursor %d '%c' is not a symbol, return\n", uc, (char) uc); acwin_cleanup(btv); return; } /* see if we have enough characters */ if (!user_requested && gtk_text_iter_get_offset(&cursorpos) - gtk_text_iter_get_offset(&iter) < main_v->props.autocomp_min_prefix_len) { DBG_AUTOCOMP("autocomp_run, prefix len %d < autocomp_min_prefix_len (%d), abort!\n" , gtk_text_iter_get_offset(&cursorpos) - gtk_text_iter_get_offset(&iter) , main_v->props.autocomp_min_prefix_len); acwin_cleanup(btv); return; } if (g_array_index(master->bflang->st->contexts, Tcontext, contextnum).has_tagclose_from_blockstack) { found = get_foundcache_at_offset(btv, gtk_text_iter_get_offset(&cursorpos), NULL); if (found) { fblock = found->numblockchange < 0 ? pop_blocks(found->numblockchange, found->fblock) : found->fblock; if (fblock && fblock->start2_o != BF_OFFSET_UNDEFINED) { DBG_AUTOCOMP("abort offering closing tag: block has an end already\n"); fblock = NULL; } /* if (g_array_index(btv->bflang->st->matches, Tpattern, fblock->patternum).tagclose_from_blockstack) { gchar *start; gtk_text_buffer_get_iter_at_mark(buffer, &it1, fblock->start1); gtk_text_buffer_get_iter_at_mark(buffer, &it2, fblock->end1); gtk_text_iter_forward_char(&it1); start = gtk_text_buffer_get_text(buffer,&it1,&it2,TRUE); g_print("close tag %s\n",start); g_free(start); }*/ } } if ((user_requested || !gtk_text_iter_equal(&iter, &cursorpos)) && (g_array_index(master->bflang->st->contexts, Tcontext, contextnum).ac != NULL || (fblock && g_array_index(master->bflang->st->matches, Tpattern, fblock->patternum).tagclose_from_blockstack) ) ) { /* we have a prefix or it is user requested, and we have a context with autocompletion or we have blockstack-tag-auto-closing */ gchar *newprefix = NULL, *prefix, *closetag = NULL; GList *items = NULL, *items2 = NULL; gboolean free_items=FALSE; /*print_ac_items(g_array_index(btv->bflang->st->contexts,Tcontext, contextnum).ac); */ prefix = gtk_text_buffer_get_text(btv->buffer, &iter, &cursorpos, TRUE); if (fblock) { GString *tmpstr; gint plen; GtkTextIter it1; gtk_text_buffer_get_iter_at_offset(btv->buffer, &it1, fblock->start1_o); tmpstr = g_string_new("</"); while(gtk_text_iter_forward_char(&it1)) { gunichar uc = gtk_text_iter_get_char(&it1); if (!g_unichar_isalnum(uc) && uc != '_') { break; } g_string_append_c(tmpstr, uc); } g_string_append_c(tmpstr, '>'); closetag = g_string_free(tmpstr, FALSE); DBG_AUTOCOMP("closetag=%s, prefix=%s\n", closetag, prefix); plen = strlen(prefix); if (plen == strlen(closetag) || strncmp(closetag, prefix, plen) != 0) { g_free(closetag); closetag = NULL; } } if (g_array_index(master->bflang->st->contexts, Tcontext, contextnum).ac) { items = g_completion_complete(g_array_index(master->bflang->st->contexts, Tcontext, contextnum).ac, prefix, &newprefix); DBG_AUTOCOMP("got %d autocompletion items for prefix %s in context %d, newprefix=%s\n", g_list_length(items), prefix, contextnum, newprefix); if (G_UNLIKELY(g_array_index(master->bflang->st->contexts, Tcontext, contextnum).autocomplete_has_conditions)) { if (found==NULL) { found = get_foundcache_at_offset(btv, gtk_text_iter_get_offset(&cursorpos), NULL); } items = process_conditional_items(btv, found, contextnum, items); free_items=TRUE; } { GCompletion *compl = identifier_ac_get_completion(master, contextnum, FALSE); DBG_IDENTIFIER("got completion %p for context %d\n", compl, contextnum); if (compl) { gchar *newprefix2 = NULL; items2 = g_completion_complete(compl, prefix, &newprefix2); DBG_IDENTIFIER("got %d identifier_items for prefix %s, newprefix=%s\n", g_list_length(items2), prefix, newprefix2); if (!newprefix) newprefix = newprefix2; else g_free(newprefix2); } } } if (closetag || items2 || (items != NULL && (items->next != NULL || strcmp(items->data, prefix) != 0))) { /* do not popup if there are 0 items, and also not if there is 1 item which equals the prefix */ GtkTreeSelection *selection; GtkTreeIter it; gboolean below; gint numitems=0; /* create the GUI */ if (!btv->autocomp) { btv->autocomp = acwin_create(btv); } else { ACWIN(btv->autocomp)->in_fill=TRUE; g_free(ACWIN(btv->autocomp)->prefix); g_free(ACWIN(btv->autocomp)->newprefix); ACWIN(btv->autocomp)->prefix = NULL; ACWIN(btv->autocomp)->newprefix = NULL; gtk_list_store_clear(ACWIN(btv->autocomp)->store); } ACWIN(btv->autocomp)->contextnum = contextnum; ACWIN(btv->autocomp)->prefix = g_strdup(prefix); if (newprefix) { ACWIN(btv->autocomp)->newprefix = g_strdup(newprefix); } acwin_calculate_window_size(ACWIN(btv->autocomp), items, items2, closetag, &numitems); below = acwin_position_at_cursor(btv); acwin_fill_tree(ACWIN(btv->autocomp), items, items2, closetag, !below, numitems); gtk_widget_show(ACWIN(btv->autocomp)->win); selection = gtk_tree_view_get_selection(ACWIN(btv->autocomp)->tree); if (below) { DBG_AUTOCOMP("autocomp_run, popup-below, get first iter for selection\n"); gtk_tree_model_get_iter_first(GTK_TREE_MODEL(ACWIN(btv->autocomp)->store), &it); } else { GtkTreePath *path; DBG_AUTOCOMP("autocomp_run, popup-above, select last iter and scroll max down\n"); gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(ACWIN(btv->autocomp)->store), &it, NULL, gtk_tree_model_iter_n_children(GTK_TREE_MODEL (ACWIN(btv->autocomp)->store), NULL) - 1); path = gtk_tree_model_get_path(GTK_TREE_MODEL(ACWIN(btv->autocomp)->store), &it); gtk_tree_view_scroll_to_cell(ACWIN(btv->autocomp)->tree, path, NULL, FALSE, 1.0, 1.0); gtk_tree_path_free(path); } /* this forces that selection changed will be called two lines below*/ gtk_tree_selection_unselect_all(selection); ACWIN(btv->autocomp)->in_fill=FALSE; DBG_AUTOCOMP("call select_iter on autocomp window\n"); gtk_tree_selection_select_iter(selection, &it); g_free(closetag); } else { acwin_cleanup(btv); } if (free_items) { g_list_free(items); } g_free(newprefix); g_free(prefix); } else { DBG_AUTOCOMP("no autocompletion data for context %d (ac=%p), or no prefix\n", contextnum, g_array_index(master->bflang->st->contexts, Tcontext, contextnum).ac); acwin_cleanup(btv); } }
gchar * donna_sort_get_utf8_collate_key (const gchar *str, gssize _len, gboolean dot_first, gboolean special_first, gboolean natural_order) { GString *result; GString *append; const gchar *p; const gchar *prev; const gchar *end; gsize len; gchar *collate_key; gchar c; gint digits; gint leading_zeros; if (_len < 0) len = strlen (str); else len = (gsize) _len; result = g_string_sized_new (len * 2); append = g_string_sized_new (0); end = str + len; p = str; /* store a character so we can check/invalidate the key if options change */ c = donna_sort_get_options_char (dot_first, special_first, natural_order); g_string_append_c (result, c); if (special_first) { const gchar *s = str; gboolean prefix = FALSE; for ( ; s < end; s = g_utf8_next_char (s)) { gunichar uc; uc = g_utf8_get_char (s); if (!g_unichar_isalnum (uc)) { if (!prefix && *s != '.') prefix = TRUE; } else { if (prefix) { /* adding the string itself and not a collate_key * so that ! comes before - */ g_string_append_len (result, str, s - str); g_string_append (result, COLLATION_SENTINEL "\1"); p += s - str; } break; } } } /* No need to use utf8 functions, since we're only looking for ascii chars */ for (prev = p; p < end; ++p) { switch (*p) { case '.': if (!dot_first && p == str) break; if (prev != p) { collate_key = g_utf8_collate_key (prev, p - prev); g_string_append (result, collate_key); g_free (collate_key); } g_string_append (result, COLLATION_SENTINEL "\1"); /* skip the dot */ prev = p + 1; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (!natural_order) break; if (prev != p) { collate_key = g_utf8_collate_key (prev, p - prev); g_string_append (result, collate_key); g_free (collate_key); } g_string_append (result, COLLATION_SENTINEL "\2"); prev = p; /* write d-1 colons */ if (*p == '0') { leading_zeros = 1; digits = 0; } else { leading_zeros = 0; digits = 1; } while (++p < end) { if (*p == '0' && !digits) ++leading_zeros; else if (g_ascii_isdigit (*p)) ++digits; else { /* count an all-zero sequence as one digit plus leading * zeros */ if (!digits) { ++digits; --leading_zeros; } break; } } while (digits > 1) { g_string_append_c (result, ':'); --digits; } if (leading_zeros > 0) { g_string_append_c (append, (char) leading_zeros); prev += leading_zeros; } /* write the number itself */ g_string_append_len (result, prev, p - prev); prev = p; --p; /* go one step back to avoid disturbing outer loop */ break; default: /* other characters just accumulate */ break; } } if (prev != p) { collate_key = g_utf8_collate_key (prev, p - prev); g_string_append (result, collate_key); g_free (collate_key); } g_string_append (result, append->str); g_string_free (append, TRUE); return g_string_free (result, FALSE); }