static gboolean is_word_sep(gunichar c) { return (g_unichar_isspace(c) || g_unichar_ispunct(c)) && c != (gunichar)'\''; }
static int str_utf8_isspace (const char *text) { gunichar uni = g_utf8_get_char_validated (text, -1); return g_unichar_isspace (uni); }
static gboolean flags_from_string (GType type, const gchar *string, gint *flags_value) { GFlagsClass *fclass; gchar *endptr, *prevptr; guint i, j, ret, value; gchar *flagstr; GFlagsValue *fv; const gchar *flag; gunichar ch; gboolean eos; g_return_val_if_fail (G_TYPE_IS_FLAGS (type), 0); g_return_val_if_fail (string != 0, 0); ret = TRUE; value = strtoul (string, &endptr, 0); if (endptr != string) /* parsed a number */ *flags_value = value; else { fclass = g_type_class_ref (type); flagstr = g_strdup (string); for (value = i = j = 0; ; i++) { eos = flagstr[i] == '\0'; if (!eos && flagstr[i] != '|') continue; flag = &flagstr[j]; endptr = &flagstr[i]; if (!eos) { flagstr[i++] = '\0'; j = i; } /* trim spaces */ for (;;) { ch = g_utf8_get_char (flag); if (!g_unichar_isspace (ch)) break; flag = g_utf8_next_char (flag); } while (endptr > flag) { prevptr = g_utf8_prev_char (endptr); ch = g_utf8_get_char (prevptr); if (!g_unichar_isspace (ch)) break; endptr = prevptr; } if (endptr > flag) { *endptr = '\0'; fv = g_flags_get_value_by_name (fclass, flag); if (!fv) fv = g_flags_get_value_by_nick (fclass, flag); if (fv) value |= fv->value; else { ret = FALSE; break; } } if (eos) { *flags_value = value; break; } } g_free (flagstr); g_type_class_unref (fclass); } return ret; }
static ParseResult gimp_number_pair_entry_parse_text (GimpNumberPairEntry *entry, const gchar *text, gdouble *left_value, gdouble *right_value) { GimpNumberPairEntryPrivate *priv = GIMP_NUMBER_PAIR_ENTRY_GET_PRIVATE (entry); gdouble new_left_number; gdouble new_right_number; gboolean simplify = FALSE; gchar *end; /* try to parse a number */ new_left_number = strtod (text, &end); if (end == text) return PARSE_CLEAR; else text = end; /* skip over whitespace */ while (g_unichar_isspace (g_utf8_get_char (text))) text = g_utf8_next_char (text); /* check for a valid separator */ if (! gimp_number_pair_entry_valid_separator (entry, g_utf8_get_char (text))) return PARSE_INVALID; else text = g_utf8_next_char (text); /* try to parse another number */ new_right_number = strtod (text, &end); if (end == text) return PARSE_INVALID; else text = end; /* skip over whitespace */ while (g_unichar_isspace (g_utf8_get_char (text))) text = g_utf8_next_char (text); /* check for the simplification char */ if (g_utf8_get_char (text) == SIMPLIFICATION_CHAR) { simplify = priv->allow_simplification; text = g_utf8_next_char (text); } /* skip over whitespace */ while (g_unichar_isspace (g_utf8_get_char (text))) text = g_utf8_next_char (text); /* check for trailing garbage */ if (*text) return PARSE_INVALID; if (! gimp_number_pair_entry_numbers_in_range (entry, new_left_number, new_right_number)) return PARSE_INVALID; if (simplify && new_right_number != 0.0) { gimp_number_pair_entry_ratio_to_fraction (new_left_number / new_right_number, left_value, right_value); } else { *left_value = new_left_number; *right_value = new_right_number; } return PARSE_VALID; }
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; }
/* searhces for match inside value, if match is mixed case, hten use case-sensitive, else insensitive */ gboolean camel_search_header_match (const gchar *value, const gchar *match, camel_search_match_t how, camel_search_t type, const gchar *default_charset) { const gchar *name, *addr; const guchar *ptr; gint truth = FALSE, i; CamelInternetAddress *cia; gchar *v, *vdom, *mdom; gunichar c; ptr = (const guchar *)value; while ((c = camel_utf8_getc (&ptr)) && g_unichar_isspace (c)) value = (const gchar *)ptr; switch (type) { case CAMEL_SEARCH_TYPE_ENCODED: v = camel_header_decode_string (value, default_charset); /* FIXME: Find header charset */ truth = header_match (v, match, how); g_free (v); break; case CAMEL_SEARCH_TYPE_MLIST: /* Special mailing list old-version domain hack If one of the mailing list names doesn't have an @ in it, its old-style, so only match against the pre-domain part, which should be common */ vdom = strchr (value, '@'); mdom = strchr (match, '@'); if (mdom == NULL && vdom != NULL) { v = g_alloca (vdom-value+1); memcpy (v, value, vdom-value); v[vdom-value] = 0; value = (gchar *)v; } else if (mdom != NULL && vdom == NULL) { v = g_alloca (mdom-match+1); memcpy (v, match, mdom-match); v[mdom-match] = 0; match = (gchar *)v; } /* Falls through */ case CAMEL_SEARCH_TYPE_ASIS: truth = header_match (value, match, how); break; case CAMEL_SEARCH_TYPE_ADDRESS_ENCODED: case CAMEL_SEARCH_TYPE_ADDRESS: /* possible simple case to save some work if we can */ if (header_match (value, match, how)) return TRUE; /* Now we decode any addresses, and try asis matches on name and address parts */ cia = camel_internet_address_new (); if (type == CAMEL_SEARCH_TYPE_ADDRESS_ENCODED) camel_address_decode ((CamelAddress *)cia, value); else camel_address_unformat ((CamelAddress *)cia, value); for (i=0; !truth && camel_internet_address_get (cia, i, &name, &addr);i++) truth = (name && header_match (name, match, how)) || (addr && header_match (addr, match, how)); g_object_unref (cia); break; } return truth; }
static inline gboolean is_space (gunichar ch) { return g_unichar_isspace (ch) || ch == 0xfffc; }
/* * ui_readline_loop() * * g³ówna pêtla programu. wczytuje dane z klawiatury w miêdzyczasie * obs³uguj±c sieæ i takie tam. */ int ui_readline_loop(void) { char *line = my_readline(); char *rline = line; /* for freeing */ gchar *out, *p; gint len; if (!line) { /* Ctrl-D handler */ if (window_current->id == 0) { /* debug window */ window_switch(1); } else if (window_current->id == 1) { /* status window */ if (config_ctrld_quits) { return 0; } else { printf("\n"); } } else if (window_current->id > 1) { /* query window */ window_kill(window_current); } return 1; } len = strlen(line); if (G_LIKELY(len > 0)) { if (G_UNLIKELY(line[len - 1] == '\\')) { /* multi line handler */ GString *s = g_string_new_len(line, len-1); free(line); no_prompt = 1; rl_bind_key(9, rl_insert); while ((line = my_readline())) { if (!strcmp(line, ".")) break; g_string_append(s, line); g_string_append_len(s, "\r\n", 2); /* XXX */ free(line); } rl_bind_key(9, rl_complete); no_prompt = 0; if (line) { g_string_free(s, TRUE); free(line); return 1; } line = g_string_free(s, FALSE); } /* if no empty line and we save duplicate lines, add it to history */ if (config_history_savedups || !history_length || strcmp(line, history_get(history_length)->line)) add_history(line); } pager_lines = 0; /* now we can definitely recode */ out = ekg_recode_from_locale(line); if (G_LIKELY(line == rline)) free(rline); /* allocd by readline */ else g_free(line); /* allocd by us */ /* omit leading whitespace */ for (p = out; g_unichar_isspace(g_utf8_get_char(p)); p = g_utf8_next_char(p)); if (*p || config_send_white_lines) command_exec(window_current->target, window_current->session, out, 0); pager_lines = -1; g_free(out); return 1; }
static void e_name_western_reorder_asshole (ENameWestern *name, ENameWesternIdxs *idxs) { gchar *prefix; gchar *last; gchar *suffix; gchar *firstmidnick; gchar *newfull; gchar *comma; gchar *p; if (!e_name_western_detect_backwards (name, idxs)) return; /* * Convert * <Prefix> <Last name>, <First name> <Middle[+nick] name> <Suffix> * to * <Prefix> <First name> <Middle[+nick] name> <Last name> <Suffix> */ /* * Grab the prefix from the beginning. */ prefix = e_name_western_get_prefix_at_str (name->full); /* * Everything from the end of the prefix to the comma is the * last name. */ comma = g_utf8_strchr (name->full, -1, ','); if (comma == NULL) { g_free (prefix); return; } p = name->full + (prefix == NULL ? 0 : strlen (prefix)); while (g_unichar_isspace (g_utf8_get_char (p)) && *p != '\0') p = g_utf8_next_char (p); /* * Consider this case, "Br.Gate,Br. Gate,W". I know this is a damn * random name, but, I got this from the bug report of 317411. * * comma = ",Br.Gate,W" * prefix = "Br.Gate,Br." * p = " Gate,W" * comma - p < 0 and hence the crash. * * Actually, we don't have to put lot of intelligence in reordering such * screwedup names, just return. */ if (comma - p + 1 < 1) { g_free (prefix); return; } last = g_malloc0 (comma - p + 1); strncpy (last, p, comma - p); /* * Get the suffix off the end. */ suffix = e_name_western_get_suffix_at_str_end (name->full); /* * Firstmidnick is everything from the comma to the beginning * of the suffix. */ p = g_utf8_next_char (comma); while (g_unichar_isspace (g_utf8_get_char (p)) && *p != '\0') p = g_utf8_next_char (p); if (suffix != NULL) { gchar *q; /* * Point q at the beginning of the suffix. */ q = name->full + strlen (name->full) - strlen (suffix); q = g_utf8_prev_char (q); /* * Walk backwards until we hit the space which * separates the suffix from firstmidnick. */ while (!g_unichar_isspace (g_utf8_get_char (q)) && q > comma) q = g_utf8_prev_char (q); if ((q - p + 1) > 0) { firstmidnick = g_malloc0 (q - p + 1); strncpy (firstmidnick, p, q - p); } else firstmidnick = NULL; } else { firstmidnick = g_strdup (p); } /* * Create our new reordered version of the name. */ #define NULLSTR(a) ((a) == NULL ? "" : (a)) newfull = g_strdup_printf ( "%s %s %s %s", NULLSTR (prefix), NULLSTR (firstmidnick), NULLSTR (last), NULLSTR (suffix)); g_strstrip (newfull); g_free (name->full); name->full = newfull; g_free (prefix); g_free (firstmidnick); g_free (last); g_free (suffix); }
static void e_name_western_fixup (ENameWestern *name, ENameWesternIdxs *idxs) { /* * The middle and last names cannot be the same. */ if (idxs->middle_idx != -1 && idxs->middle_idx == idxs->last_idx) { idxs->middle_idx = -1; g_free (name->middle); name->middle = NULL; } /* * If we have a middle name and no last name, then we mistook * the last name for the middle name. */ if (idxs->last_idx == -1 && idxs->middle_idx != -1) { idxs->last_idx = idxs->middle_idx; name->last = name->middle; name->middle = NULL; idxs->middle_idx = -1; } /* * Check to see if we accidentally included the suffix in the * last name. */ if (idxs->suffix_idx != -1 && idxs->last_idx != -1 && idxs->suffix_idx < (idxs->last_idx + strlen (name->last))) { gchar *sfx; sfx = name->last + (idxs->suffix_idx - idxs->last_idx); if (sfx != NULL) { gchar *newlast; gchar *p; p = sfx; p = g_utf8_prev_char (p); while (g_unichar_isspace (g_utf8_get_char (p)) && p > name->last) p = g_utf8_prev_char (p); p = g_utf8_next_char (p); newlast = g_malloc0 (p - name->last + 1); strncpy (newlast, name->last, p - name->last); g_free (name->last); name->last = newlast; } } /* * If we have a prefix and a first name, but no last name, * then we need to assign the first name to the last name. * This way we get things like "Mr Friedman" correctly. */ if (idxs->first_idx != -1 && idxs->prefix_idx != -1 && idxs->last_idx == -1) { name->last = name->first; idxs->last_idx = idxs->first_idx; idxs->first_idx = -1; name->first = NULL; } if (idxs->middle_idx != -1) { CHECK_MIDDLE_NAME_FOR_CONJUNCTION ("&"); CHECK_MIDDLE_NAME_FOR_CONJUNCTION ("*"); CHECK_MIDDLE_NAME_FOR_CONJUNCTION ("|"); CHECK_MIDDLE_NAME_FOR_CONJUNCTION ("^"); CHECK_MIDDLE_NAME_FOR_CONJUNCTION ("&&"); CHECK_MIDDLE_NAME_FOR_CONJUNCTION ("||"); CHECK_MIDDLE_NAME_FOR_CONJUNCTION ("+"); CHECK_MIDDLE_NAME_FOR_CONJUNCTION ("-"); CHECK_MIDDLE_NAME_FOR_CONJUNCTION_CASE ("and"); CHECK_MIDDLE_NAME_FOR_CONJUNCTION_CASE ("or"); CHECK_MIDDLE_NAME_FOR_CONJUNCTION_CASE ("plus"); /* Spanish */ CHECK_MIDDLE_NAME_FOR_CONJUNCTION_CASE ("y"); /* German */ CHECK_MIDDLE_NAME_FOR_CONJUNCTION_CASE ("und"); /* Italian */ CHECK_MIDDLE_NAME_FOR_CONJUNCTION_CASE ("e"); /* Czech */ CHECK_MIDDLE_NAME_FOR_CONJUNCTION_CASE ("a"); /* Finnish */ CHECK_MIDDLE_NAME_FOR_CONJUNCTION_CASE ("ja"); /* French */ CHECK_MIDDLE_NAME_FOR_CONJUNCTION_CASE ("et"); /* Russian */ CHECK_MIDDLE_NAME_FOR_CONJUNCTION ("\xd0\x98"); /* u+0418 */ CHECK_MIDDLE_NAME_FOR_CONJUNCTION ("\xd0\xb8"); /* u+0438 */ } /* * Remove stray spaces and commas (although there don't seem * to be any in the test cases, they might show up later). */ e_name_western_cleanup_string (& name->prefix); e_name_western_cleanup_string (& name->first); e_name_western_cleanup_string (& name->middle); e_name_western_cleanup_string (& name->nick); e_name_western_cleanup_string (& name->last); e_name_western_cleanup_string (& name->suffix); /* * Make zero-length strings just NULL. */ e_name_western_zap_nil (& name->prefix, & idxs->prefix_idx); e_name_western_zap_nil (& name->first, & idxs->first_idx); e_name_western_zap_nil (& name->middle, & idxs->middle_idx); e_name_western_zap_nil (& name->nick, & idxs->nick_idx); e_name_western_zap_nil (& name->last, & idxs->last_idx); e_name_western_zap_nil (& name->suffix, & idxs->suffix_idx); }
static void e_name_western_extract_last (ENameWestern *name, ENameWesternIdxs *idxs) { gchar *word; gint idx = -1; gchar *last; idx = e_name_western_last_get_max_idx (name, idxs); /* * In the case where there is no preceding name element, the * name is either just a first name ("Nat", "John"), is a * single-element name ("Cher", which we treat as a first * name), or is just a last name. The only time we can * differentiate a last name alone from a single-element name * or a first name alone is if it's a complex last name ("de * Icaza", "van Josephsen"). So if there is no preceding name * element, we check to see whether or not the first part of * the name is the beginning of a complex name. If it is, * we subsume the entire string. If we accidentally subsume * the suffix, this will get fixed in the fixup routine. */ if (idx == -1) { word = e_name_western_get_words_at_idx (name->full, 0, 1); if (!e_name_western_is_complex_last_beginning (word)) { g_free (word); return; } name->last = g_strdup (name->full); idxs->last_idx = 0; return; } last = name->full + idx; /* Skip past the white space. */ while (g_unichar_isspace (g_utf8_get_char (last)) && *last != '\0') last = g_utf8_next_char (last); if (*last == '\0') return; word = e_name_western_get_words_at_idx (name->full, last - name->full, 1); e_name_western_cleanup_string (& word); if (e_name_western_word_is_suffix (word)) { g_free (word); return; } g_free (word); /* * Subsume the rest of the string into the last name. If we * accidentally include the prefix, it will get fixed later. * This is the only way to handle things like "Miguel de Icaza * Amozorrutia" without dropping data and forcing the user * to retype it. */ name->last = g_strdup (last); idxs->last_idx = last - name->full; }
static void e_name_western_extract_middle (ENameWestern *name, ENameWesternIdxs *idxs) { gchar *word; gchar *middle; /* * Middle names can only exist if you have a first name. */ if (idxs->first_idx == -1) return; middle = name->full + idxs->first_idx + strlen (name->first); if (*middle == '\0') return; middle = g_utf8_next_char (middle); if (*middle == '\0') return; /* * Search for the first space (or the terminating \0) */ while (g_unichar_isspace (g_utf8_get_char (middle)) && *middle != '\0') middle = g_utf8_next_char (middle); if (*middle == '\0') return; /* * Skip past the nickname, if it's there. */ if (*middle == '\"') { if (idxs->nick_idx == -1) return; middle = name->full + idxs->nick_idx + strlen (name->nick); middle = g_utf8_next_char (middle); while (g_unichar_isspace (g_utf8_get_char (middle)) && *middle != '\0') middle = g_utf8_next_char (middle); if (*middle == '\0') return; } /* * Make sure this isn't the beginning of a complex last name. */ word = e_name_western_get_words_at_idx (name->full, middle - name->full, 1); if (e_name_western_is_complex_last_beginning (word)) { g_free (word); return; } /* * Make sure this isn't a suffix. */ e_name_western_cleanup_string (& word); if (e_name_western_word_is_suffix (word)) { g_free (word); return; } /* * Make sure we didn't just grab a cute nickname. */ if (word[0] == '\"') { g_free (word); return; } idxs->middle_idx = middle - name->full; name->middle = word; }
static StfParseCellRes stf_parse_csv_cell (GString *text, Source_t *src, StfParseOptions_t *parseoptions) { char const *cur; gboolean saw_sep = FALSE; g_return_val_if_fail (src != NULL, STF_CELL_ERROR); g_return_val_if_fail (parseoptions != NULL, STF_CELL_ERROR); cur = src->position; g_return_val_if_fail (cur != NULL, STF_CELL_ERROR); /* Skip whitespace, but stop at line terminators. */ while (1) { int term_len; if (*cur == 0) { src->position = cur; return STF_CELL_EOF; } term_len = compare_terminator (cur, parseoptions); if (term_len) { src->position = cur + term_len; return STF_CELL_EOL; } if ((parseoptions->trim_spaces & TRIM_TYPE_LEFT) == 0) break; if (stf_parse_csv_is_separator (cur, parseoptions->sep.chr, parseoptions->sep.str)) break; if (!g_unichar_isspace (g_utf8_get_char (cur))) break; cur = g_utf8_next_char (cur); } if (g_utf8_get_char (cur) == parseoptions->stringindicator) { cur = g_utf8_next_char (cur); while (*cur) { gunichar uc = g_utf8_get_char (cur); cur = g_utf8_next_char (cur); if (uc == parseoptions->stringindicator) { if (parseoptions->indicator_2x_is_single && g_utf8_get_char (cur) == parseoptions->stringindicator) cur = g_utf8_next_char (cur); else { /* "field content"dropped-garbage, */ while (*cur && !compare_terminator (cur, parseoptions)) { char const *post = stf_parse_csv_is_separator (cur, parseoptions->sep.chr, parseoptions->sep.str); if (post) { cur = post; saw_sep = TRUE; break; } cur = g_utf8_next_char (cur); } break; } } g_string_append_unichar (text, uc); } /* We silently allow a missing terminating quote. */ } else { /* Unquoted field. */ while (*cur && !compare_terminator (cur, parseoptions)) { char const *post = stf_parse_csv_is_separator (cur, parseoptions->sep.chr, parseoptions->sep.str); if (post) { cur = post; saw_sep = TRUE; break; } g_string_append_unichar (text, g_utf8_get_char (cur)); cur = g_utf8_next_char (cur); } if (parseoptions->trim_spaces & TRIM_TYPE_RIGHT) { while (text->len) { const char *last = g_utf8_prev_char (text->str + text->len); if (!g_unichar_isspace (g_utf8_get_char (last))) break; g_string_truncate (text, last - text->str); } } } src->position = cur; if (saw_sep && parseoptions->duplicates) stf_parse_eat_separators (src, parseoptions); return saw_sep ? STF_CELL_FIELD_SEP : STF_CELL_FIELD_NO_SEP; }
gboolean gb_vim_execute (GtkSourceView *source_view, const gchar *line, GError **error) { GtkTextBuffer *buffer; g_autofree gchar *name_slice = NULL; const GbVimCommand *command; const gchar *command_name = line; const gchar *options; g_autofree gchar *all_options = NULL; gboolean result; g_return_val_if_fail (GTK_SOURCE_IS_VIEW (source_view), FALSE); g_return_val_if_fail (line, FALSE); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (source_view)); if (!GTK_SOURCE_IS_BUFFER (buffer)) { g_set_error (error, GB_VIM_ERROR, GB_VIM_ERROR_NOT_SOURCE_VIEW, _("vim mode requires GtkSourceView")); return FALSE; } for (options = line; *options; options = g_utf8_next_char (options)) { gunichar ch; ch = g_utf8_get_char (options); if (g_unichar_isspace (ch)) break; } if (g_unichar_isspace (g_utf8_get_char (options))) { command_name = name_slice = g_strndup (line, options - line); options = g_utf8_next_char (options); } command = lookup_command (command_name); if (command == NULL) { if (looks_like_search_and_replace (line)) return gb_vim_command_search (source_view, line, "", error); g_set_error (error, GB_VIM_ERROR, GB_VIM_ERROR_NOT_FOUND, _("Not an editor command: %s"), command_name); return FALSE; } if (command->options_sup) all_options = g_strconcat (options, " ", command->options_sup, NULL); else all_options = g_strdup (options); result = command->func (source_view, command_name, all_options, error); g_free (command->options_sup); return result; }
/*! shape() processes the information encapsulated by GR_ShapingInfo si and stores results in GR_*RenderInfo* pri. If the contents of pri are NULL the function must create a new instance of GR_*RenderInfo of the appropriate type and store the pointer in pri; it also must store pointer to this graphics instance in pri->m_pGraphics. If ri indicates that the text is justified, appropriate processing needs to be done This function is tied closely together to a class derrived from GR_RenderInfo which may contain caches of various data that will speed subsequent calls to prepareToRenderChars() and renderChars() */ bool GR_Graphics::shape(GR_ShapingInfo & si, GR_RenderInfo *& pri) { if(!si.m_pItem || si.m_pItem->getType() == GRScriptType_Void || !si.m_pFont) return false; if(!pri) { pri = new GR_XPRenderInfo(si.m_pItem->getType()); UT_return_val_if_fail(pri, false); pri->m_pGraphics = this; } GR_XPRenderInfo * pRI = (GR_XPRenderInfo *)pri; const GR_Font *pFont = si.m_pFont; // make sure that the buffers are of sufficient size ... if(si.m_iLength > pRI->m_iBufferSize) //buffer too small, reallocate { delete[] pRI->m_pChars; delete[] pRI->m_pWidths; pRI->m_pChars = new UT_UCS4Char[si.m_iLength + 1]; UT_return_val_if_fail(pRI->m_pChars, false); pRI->m_pWidths = new UT_sint32[si.m_iLength + 1]; UT_return_val_if_fail(pRI->m_pWidths, false); pRI->m_iBufferSize = si.m_iLength + 1; } pRI->m_iLength = si.m_iLength; pRI->m_iTotalLength = si.m_iLength; pRI->m_eScriptType = si.m_pItem->getType(); pRI->m_pItem = si.m_pItem; UT_UCS4Char glyph, current; UT_UCS4Char * dst_ptr = pRI->m_pChars; bool previousWasSpace = si.m_previousWasSpace; for(UT_sint32 i = 0; i < si.m_iLength; ++i, ++si.m_Text) { UT_return_val_if_fail(si.m_Text.getStatus() == UTIter_OK, false); current = si.m_Text.getChar(); if (si.m_TextTransform == GR_ShapingInfo::LOWERCASE) current = g_unichar_tolower(current); else if (si.m_TextTransform == GR_ShapingInfo::UPPERCASE) current = g_unichar_toupper(current); else if (si.m_TextTransform == GR_ShapingInfo::CAPITALIZE) { if (previousWasSpace) { current = g_unichar_toupper(current); } } // else si.m_TextTransform == GR_ShapingInfo::NONE previousWasSpace = g_unichar_isspace(current); if(si.m_iVisDir == UT_BIDI_RTL) glyph = s_getMirrorChar(current); else glyph = current; if(pFont->doesGlyphExist(glyph)) *dst_ptr++ = glyph; else { UT_UCS4Char t = s_remapGlyph(glyph); if(pFont->doesGlyphExist(t)) { *dst_ptr++ = t; } else { *dst_ptr++ = s_cDefaultGlyph; } } } pRI->m_eState = GRSR_BufferClean; if(pRI->isJustified()) justify(*pRI); // make sure that we invalidate the static buffers if we own them if(pRI->s_pOwner == pRI) pRI->s_pOwner = NULL; return true; }
void insert_index_marks(openttsd_message * msg, SPDDataMode ssml_mode) { GString *marked_text; char *pos; char character[6]; char character2[6]; gunichar u_char; int n = 0; int ret; int inside_tag = 0; marked_text = g_string_new(""); assert(msg != NULL); assert(msg->buf != NULL); log_msg2(5, "index_marking", "MSG before index marking: |%s|, ssml_mode=%d", msg->buf, ssml_mode); if (ssml_mode == SPD_DATA_TEXT) g_string_printf(marked_text, "<speak>"); pos = msg->buf; while (pos) { ret = read_utf8_char(pos, character); if (ret == 0 || (strlen(character) == 0)) break; u_char = g_utf8_get_char(character); if (u_char == '<') { if (ssml_mode == SPD_DATA_SSML) { inside_tag = 1; g_string_append_printf(marked_text, "%s", character); } else g_string_append_printf(marked_text, "<"); } else if (u_char == '>') { if (ssml_mode == SPD_DATA_SSML) { inside_tag = 0; g_string_append_printf(marked_text, "%s", character); } else g_string_append_printf(marked_text, ">"); } else if (u_char == '&') { if (ssml_mode == SPD_DATA_SSML) { g_string_append_printf(marked_text, "%s", character); } else { if (!inside_tag) g_string_append_printf(marked_text, "&"); } } else if (((u_char == '.') || (u_char == '?') || (u_char == '!')) && !inside_tag) { pos = g_utf8_find_next_char(pos, NULL); ret = read_utf8_char(pos, character2); if ((ret == 0) || (strlen(character2) == 0)) { g_string_append_printf(marked_text, "%s", character); log_msg2(6, "index_marking", "MSG altering 1: |%s|", marked_text->str); break; } u_char = g_utf8_get_char(character2); if ((g_unichar_isspace(u_char)) || (u_char == '<') || (u_char == '&')) { g_string_append_printf(marked_text, "%s" SD_MARK_HEAD "%d" SD_MARK_TAIL, character, n); n++; log_msg2(6, "index_marking", "MSG altering 2: |%s|", marked_text->str); continue; } else { g_string_append_printf(marked_text, "%s", character); // pos = g_utf8_find_prev_char(pos, NULL); log_msg2(6, "index_marking", "MSG altering 3: |%s|", marked_text->str); continue; } } else { g_string_append_printf(marked_text, "%s", character); } pos = g_utf8_find_next_char(pos, NULL); } if (ssml_mode == SPD_DATA_TEXT) g_string_append_printf(marked_text, "</speak>"); g_free(msg->buf); msg->buf = marked_text->str; g_string_free(marked_text, 0); log_msg2(5, "index_marking", "MSG after index marking: |%s|", msg->buf); }
static gboolean emfe_text_html_format (EMailFormatterExtension *extension, EMailFormatter *formatter, EMailFormatterContext *context, EMailPart *part, GOutputStream *stream, GCancellable *cancellable) { if (g_cancellable_is_cancelled (cancellable)) return FALSE; if (context->mode == E_MAIL_FORMATTER_MODE_RAW) { e_mail_formatter_format_text ( formatter, part, stream, cancellable); } else if (context->mode == E_MAIL_FORMATTER_MODE_PRINTING) { GOutputStream *decoded_stream; GString *string; gchar *pos; GList *tags, *iter; gboolean valid; gchar *tag; const gchar *document_end; gpointer data; gsize length; gint i; decoded_stream = g_memory_output_stream_new_resizable (); /* FORMATTER FIXME: See above */ e_mail_formatter_format_text ( formatter, part, decoded_stream, cancellable); data = g_memory_output_stream_get_data ( G_MEMORY_OUTPUT_STREAM (decoded_stream)); length = g_memory_output_stream_get_data_size ( G_MEMORY_OUTPUT_STREAM (decoded_stream)); string = g_string_new_len ((gchar *) data, length); g_object_unref (decoded_stream); if (!g_utf8_validate (string->str, -1, NULL)) { gchar *valid_utf8; valid_utf8 = e_util_utf8_make_valid (string->str); g_string_free (string, TRUE); string = g_string_new (valid_utf8); g_free (valid_utf8); } tags = NULL; pos = string->str; valid = FALSE; do { gchar *tmp; gchar *closing; gchar *opening; tmp = g_utf8_find_next_char (pos, NULL); pos = g_utf8_strchr (tmp, -1, '<'); if (!pos) break; opening = pos; closing = g_utf8_strchr (pos, -1, '>'); /* Find where the actual tag name begins */ while (tag = g_utf8_find_next_char (pos, NULL), tag != NULL) { gunichar c = g_utf8_get_char (tag); if (!g_unichar_isspace (c)) break; } if (g_ascii_strncasecmp (tag, "style", 5) == 0) { tags = g_list_append ( tags, get_tag (string->str, "style", opening, closing)); } else if (g_ascii_strncasecmp (tag, "script", 6) == 0) { tags = g_list_append ( tags, get_tag (string->str, "script", opening, closing)); } else if (g_ascii_strncasecmp (tag, "link", 4) == 0) { tags = g_list_append ( tags, get_tag (string->str, "link", opening, closing)); } else if (g_ascii_strncasecmp (tag, "body", 4) == 0) { valid = TRUE; break; } } while (pos); /* Something's wrong, let's write the entire HTML and hope * that WebKit can handle it */ if (!valid) { EMailFormatterContext c = { .part_list = context->part_list, .flags = context->flags, .mode = E_MAIL_FORMATTER_MODE_RAW, }; emfe_text_html_format ( extension, formatter, &c, part, stream, cancellable); return FALSE; } /* include the "body" as well -----v */ g_string_erase (string, 0, tag - string->str + 4); g_string_prepend (string, "<div "); for (iter = tags; iter; iter = iter->next) { if (iter->data) g_string_prepend (string, iter->data); } g_list_free_full (tags, g_free); document_end = NULL; /* We can probably use ASCII functions here */ if (g_strrstr (string->str, "</body>")) { document_end = ">ydob/<"; } if (g_strrstr (string->str, "</html>")) { if (document_end) { document_end = ">lmth/<>ydob/<"; } else { document_end = ">lmth/<"; } } if (document_end) { length = strlen (document_end); tag = string->str + string->len - 1; i = 0; valid = FALSE; while (i < length - 1) { gunichar c; c = g_utf8_get_char (tag); if (g_unichar_isspace (c)) { tag = g_utf8_find_prev_char (string->str, tag); continue; } c = g_unichar_tolower (c); if (c == document_end[i]) { tag = g_utf8_find_prev_char (string->str, tag); i++; valid = TRUE; continue; } tag = g_utf8_find_prev_char (string->str, tag); valid = FALSE; } } else { /* do not cut, if there is no end tag */ valid = FALSE; } if (valid) g_string_truncate (string, tag - string->str); g_output_stream_write_all ( stream, string->str, string->len, NULL, cancellable, NULL); g_string_free (string, TRUE); } else {
static gboolean find_end_element_char (gunichar ch, gpointer user_data) { return g_unichar_isspace (ch) || ch == '/' || ch == '>'; }
static gchar * get_tag (const gchar *utf8_string, const gchar *tag_name, gchar *opening, gchar *closing) { gchar *t; gunichar c; gboolean has_end; c = '\0'; t = g_utf8_find_prev_char (utf8_string, closing); while (t != opening) { c = g_utf8_get_char (t); if (!g_unichar_isspace (c)) break; } /* Not a pair tag */ if (c == '/') return g_strndup (opening, closing - opening + 1); t = closing; while (t) { c = g_utf8_get_char (t); if (c == '<') { if (t[1] == '!' && t[2] == '-' && t[3] == '-') { /* it's a comment start, read until the end of "-->" */ gchar *end = strstr (t + 4, "-->"); if (end) { t = end + 2; } else break; } else break; } t = g_utf8_find_next_char (t, NULL); } has_end = FALSE; do { c = g_utf8_get_char (t); if (c == '/') { has_end = TRUE; break; } if (c == '>') { has_end = FALSE; break; } t = g_utf8_find_next_char (t, NULL); } while (t); /* Broken HTML? */ if (!has_end) return NULL; do { c = g_utf8_get_char (t); if ((c != ' ') && (c != '/')) break; t = g_utf8_find_next_char (t, NULL); } while (t); /* tag_name is always ASCII */ if (g_ascii_strncasecmp (t, tag_name, strlen (tag_name)) == 0) { closing = g_utf8_strchr (t, -1, '>'); return g_strndup (opening, closing - opening + 1); } /* Broken HTML? */ return NULL; }
static gboolean is_word_sep(gunichar c) { return g_unichar_isspace(c) || g_unichar_ispunct(c); }
char *TextEdit::getScreenLine(const char *text, int max_width, size_t *res_length) const { g_assert(text); g_assert(text < bufend); g_assert(max_width > 0); g_assert(res_length); const char *cur = text; const char *res = text; int prev_width = 0; int cur_width = 0; size_t cur_length = 0; bool space = false; *res_length = 0; while (cur < bufend) { prev_width = cur_width; gunichar uc = g_utf8_get_char(cur); cur_width += onScreenWidth(uc, cur_width); cur_length++; if (prev_width > max_width) break; // possibly too long word if (cur_width > max_width && !*res_length) { *res_length = cur_length - 1; res = cur; } // end of line (paragraph on screen) found if (*cur == '\n') { *res_length = cur_length; return nextChar(cur); } if (g_unichar_isspace(uc)) space = true; else if (space) { /* Found start of a word and everything before that can fit into * a screen line. */ *res_length = cur_length - 1; res = cur; space = false; } cur = nextChar(cur); } /* Fix for very small max_width and characters wider that 1 cell. For * example, max_width = 1 and text = "W" where W is a wide character (2 * cells width) (or simply for tabs). In that case we can not draw anything * but we want to skip to another character. */ if (res == text) { *res_length = 1; res = nextChar(res); } return const_cast<char*>(res); }
static gboolean is_space(gunichar ch, gpointer user_data) { return g_unichar_isspace(ch); }
static GnomePrintJob *create_job(GnomePrintConfig *gpc) { GnomeFontFace *font_face; PangoFontDescription *font_desc; GtkTextIter start, end; gchar *text, *p; /* Get contents of TextBuffer */ GtkTextBuffer *buffer = pub->mw->buffer; gtk_text_buffer_get_bounds(buffer, &start, &end); text = g_strchomp(gtk_text_buffer_get_text(buffer, &start, &end, FALSE)); /* Initialize job */ job = gnome_print_job_new(gpc); gnome_print_job_get_page_size_from_config(gpc, &page_width, &page_height); gnome_print_config_get_length(gpc, (guchar *)GNOME_PRINT_KEY_PAGE_MARGIN_LEFT, &margin_left, NULL); gnome_print_config_get_length(gpc, (guchar *)GNOME_PRINT_KEY_PAGE_MARGIN_RIGHT, &margin_right, NULL); gnome_print_config_get_length(gpc, (guchar *)GNOME_PRINT_KEY_PAGE_MARGIN_TOP, &margin_top, NULL); gnome_print_config_get_length(gpc, (guchar *)GNOME_PRINT_KEY_PAGE_MARGIN_BOTTOM, &margin_bottom, NULL); /* g_print("margin_left = %f\n", margin_left); g_print("margin_right = %f\n", margin_right); g_print("margin_top = %f\n", margin_top); g_print("margin_bottom = %f\n", margin_bottom); margin_top = margin_left; margin_bottom = margin_left; */ /* Initialize font */ font_desc = gtk_widget_get_style(pub->mw->view)->font_desc; font_face = gnome_font_face_find_closest_from_pango_description(font_desc); font = gnome_font_face_get_font_default(font_face, FONT_SIZE); // pango_font_description_get_size(font_desc) / PANGO_SCALE); // g_print("PANGO_SCALE = %d\n", PANGO_SCALE); // g_print("font_size = %d\n", pango_font_description_get_size(font_desc)); line_height = gnome_font_get_size(font); tab_width = gnome_font_face_get_glyph_width(font_face, gnome_font_face_lookup_default(font_face, g_utf8_get_char(" "))) / 1000 * FONT_SIZE * get_current_tab_width(); DV( g_print("tab_width = %f\n", tab_width)); /* Draw texts to canvas */ gpx = gnome_print_job_get_context(job); gnome_print_beginpage(gpx, NULL); gnome_print_setfont(gpx, font); page_x = margin_left; // TODO RTL page_y = page_height - margin_top - line_height; gnome_print_moveto(gpx, page_x, page_y); gl = gnome_glyphlist_from_text_dumb(font, 0x000000ff, 0, 0, (guchar *)""); gl_width = 0; p = text; while (*p != '\0') { gunichar ch = g_utf8_get_char(p); gint glyph = gnome_font_lookup_default(font, ch); if (!glyph) { if (ch == '\n') { print_glyph_list(page_x + gl_width > page_width - margin_right); move_pen_to_newline(); DV( g_print("LF\n")); } else if (ch == '\t') { print_glyph_list(page_x + gl_width > page_width - margin_right); /* page_x = page_x + tab_width - ((page_x - margin_left) % tab_width); */ gdouble tmp_x = margin_left; do { tmp_x += tab_width; } while (tmp_x < page_x + 0.000001); // FIXME DV( g_print("HT ")); DV( g_print("%f -> %f\n", page_x, tmp_x)); page_x = tmp_x; gnome_print_moveto(gpx, page_x, page_y); /* } else if (ch == '\f') { DV( g_print("FF\n")); print_glyph_list(page_x + gl_width > page_width - margin_right); move_pen_to_nextpage(); */ } else { GnomeFont *tmp_font = find_proper_font(ch); GnomeFontFace *tmp_face = gnome_font_get_face(tmp_font); gdouble g_width; glyph = gnome_font_lookup_default(tmp_font, ch); g_width = gnome_font_face_get_glyph_width(tmp_face, glyph) / 1000 * FONT_SIZE; if (page_x + gl_width + g_width > page_width - margin_right) { if (g_unichar_iswide(ch)) { print_glyph_list(FALSE); move_pen_to_newline(); } else print_glyph_list(TRUE); } gnome_glyphlist_font(gl, tmp_font); gnome_glyphlist_glyph(gl, glyph); gnome_glyphlist_font(gl, font); gl_width += g_width; DV( g_print("** ")); } } else { // if (ch == ' ') { if (g_unichar_isspace(ch)) { DV( g_print("SP ")); DV( g_print("\n")); print_glyph_list(page_x + gl_width > page_width - margin_right); page_x += gnome_font_face_get_glyph_width(font_face, glyph) / 1000 * FONT_SIZE; gnome_print_moveto(gpx, page_x, page_y); } else { gdouble g_width = gnome_font_face_get_glyph_width(font_face, glyph) / 1000 * FONT_SIZE; if (page_x + gl_width + g_width > page_width - margin_right) { if (g_unichar_iswide(ch)) { print_glyph_list(FALSE); move_pen_to_newline(); } else print_glyph_list(TRUE); } gnome_glyphlist_glyph(gl, glyph); gl_width += g_width; DV( g_print("%02X ", glyph)); DV( g_print("%f (%f)\n", gl_width, gnome_font_get_glyph_width(font, glyph))); } } p = g_utf8_next_char(p); } print_glyph_list(page_x + gl_width > page_width - margin_right); DV( g_print("\n[EOT]\n")); gnome_print_showpage(gpx); gnome_print_context_close(gpx); g_object_unref(gpx); gnome_glyphlist_unref(gl); gnome_font_unref(font); gnome_font_face_unref(font_face); gnome_print_job_close(job); return job; }