static gchar * generate_crack_for_hixie76 (guint32 *out_number) { guint spaces, max, number, product, chars; GString *key; gchar ch; gint i; /* WTF. This hixie76 draft protocol screams "PHP developer" */ spaces = g_random_int_range (1, 12 + 1); max = 2147483647 / spaces; number = g_random_int_range (0, max); product = number * spaces; key = g_string_new (""); g_string_printf (key, "%u", product); chars = g_random_int_range (1, 12 + 1); for (i = 0; i < chars; i++) { do { ch = g_random_int_range (0x21, 0x7F); } while (g_ascii_isdigit (ch)); g_string_insert_c (key, g_random_int_range (0, key->len), ch); } for (i = 0; i < spaces; i++) g_string_insert_c (key, g_random_int_range (1, key->len - 1), ' '); *out_number = number; return g_string_free (key, FALSE); }
static char * menu_escape_underscores_and_prepend (const char *text) { GString *escaped_text; const char *src; int inserted; if (!text) return g_strdup (text); escaped_text = g_string_sized_new (strlen (text) + 1); g_string_printf (escaped_text, "_%s", text); src = text; inserted = 1; while (*src) { gunichar c; c = g_utf8_get_char (src); if (c == (gunichar)-1) { g_warning ("Invalid input string for underscore escaping"); return g_strdup (text); } else if (c == '_') { g_string_insert_c (escaped_text, src - text + inserted, '_'); inserted++; } src = g_utf8_next_char (src); } return g_string_free (escaped_text, FALSE); }
/* Add mode character to list sorted alphabetically */ static void mode_add_sorted(GString *str, char mode, const char *arg) { char *p; int updating, argpos = 0; /* check that mode isn't already set */ if (!HAS_MODE_ARG_SET(mode) && mode_is_set(str->str, mode)) return; updating = FALSE; for (p = str->str; *p != '\0' && *p != ' '; p++) { if (mode < *p) break; if (mode == *p) { updating = TRUE; break; } if (HAS_MODE_ARG_SET(*p)) argpos++; } /* .. GLib shouldn't fail when inserting at the end of the string */ if (!updating) { if (*p == '\0') g_string_append_c(str, mode); else g_string_insert_c(str, (int) (p-str->str), mode); } if (arg != NULL) mode_add_arg(str, argpos, updating, arg); }
static void handle_multi_line(struct web_session *session) { gsize count; char *str; gchar *value; str = session->current_header->str; if (str[0] != ' ' && str[0] != '\t') return; while (str[0] == ' ' || str[0] == '\t') str++; count = str - session->current_header->str; if (count > 0) { g_string_erase(session->current_header, 0, count); g_string_insert_c(session->current_header, 0, ' '); } value = g_hash_table_lookup(session->result.headers, session->result.last_key); if (value != NULL) { g_string_insert(session->current_header, 0, value); str = session->current_header->str; g_hash_table_replace(session->result.headers, g_strdup(session->result.last_key), g_strdup(str)); } }
/* Load a sub module. */ int module_load_sub(const char *path, const char *submodule, char **prefixes) { GString *full_path; char *exppath, *name, *rootmodule; int start, end, ret; g_return_val_if_fail(path != NULL, FALSE); g_return_val_if_fail(submodule != NULL, FALSE); exppath = convert_home(path); name = module_get_name(exppath, &start, &end); rootmodule = module_get_root(name, prefixes); g_free(name); full_path = g_string_new(exppath); if (strcmp(submodule, "core") == 0) g_string_insert(full_path, end, "_core"); else { g_string_insert_c(full_path, start, '_'); g_string_insert(full_path, start, submodule); } ret = module_load_full(full_path->str, rootmodule, submodule, start, end, NULL); g_string_free(full_path, TRUE); g_free(rootmodule); g_free(exppath); return ret; }
/* add argument to specified position */ static void mode_add_arg(GString *str, int pos, int updating, const char *arg) { char *p; for (p = str->str; *p != '\0'; p++) { if (*p != ' ') continue; if (pos == 0) break; pos--; } pos = (int) (p-str->str); if (updating && *p != '\0') { /* remove the old argument */ p++; while (*p != '\0' && *p != ' ') p++; g_string_erase(str, pos, (int) (p-str->str)-pos); } /* .. GLib shouldn't fail when inserting at the end of the string */ if (pos == str->len) { g_string_append_c(str, ' '); g_string_append(str, arg); } else { g_string_insert_c(str, pos, ' '); g_string_insert(str, pos+1, arg); } }
void gui_entry_insert_char(char chr) { g_string_insert_c(entry, pos, chr); pos++; entry_screenpos(); entry_update(); }
GString* g_string_prepend_c (GString *string, gchar c) { g_return_val_if_fail (string != NULL, NULL); return g_string_insert_c (string, 0, c); }
static void add_header_field(struct web_session *session) { gsize count; guint8 *pos; char *str; gchar *value; gchar *key; str = session->current_header->str; pos = memchr(str, ':', session->current_header->len); if (pos != NULL) { *pos = '\0'; pos++; key = g_strdup(str); /* remove preceding white spaces */ while (*pos == ' ') pos++; count = (char *) pos - str; g_string_erase(session->current_header, 0, count); value = g_hash_table_lookup(session->result.headers, key); if (value != NULL) { g_string_insert_c(session->current_header, 0, ' '); g_string_insert_c(session->current_header, 0, ';'); g_string_insert(session->current_header, 0, value); } str = session->current_header->str; g_hash_table_replace(session->result.headers, key, g_strdup(str)); g_free(session->result.last_key); session->result.last_key = g_strdup(key); } }
/* check for the clues */ static gboolean check_for_attachment_clues (GByteArray *msg_text) { GSettings *settings; gchar **clue_list; gboolean found = FALSE; settings = e_util_ref_settings ("org.gnome.evolution.plugin.attachment-reminder"); /* Get the list from GSettings */ clue_list = g_settings_get_strv (settings, CONF_KEY_ATTACH_REMINDER_CLUES); g_object_unref (settings); if (clue_list && clue_list[0]) { gint ii, jj, to; g_byte_array_append (msg_text, (const guint8 *) "\0", 1); censor_quoted_lines (msg_text); for (ii = 0; clue_list[ii] && !found; ii++) { GString *word; const gchar *clue = clue_list[ii]; if (!*clue) continue; word = g_string_new ("\""); to = word->len; g_string_append (word, clue); for (jj = word->len - 1; jj >= to; jj--) { if (word->str[jj] == '\\' || word->str[jj] == '\"') g_string_insert_c (word, jj, '\\'); } g_string_append_c (word, '\"'); found = camel_search_header_match ((const gchar *) msg_text->data, word->str, CAMEL_SEARCH_MATCH_WORD, CAMEL_SEARCH_TYPE_ASIS, NULL); g_string_free (word, TRUE); } } if (clue_list) { g_strfreev (clue_list); } return found; }
static void cli_info_pad_source (GString *sb, gint source_width, const gchar *source) { gint i, length; g_string_truncate (sb, 0); length = strlen (source); for (i = 0; i < (source_width - length); i++) { g_string_insert_c (sb, i, ' '); } g_string_insert (sb, i, source); }
gboolean cmd_insert_chars(struct cmdline* cmd, gchar c, gint n) { /* Right now this function is only used to insert spaces, so it's safe for UTF-8. */ if (n < 0) { g_warning("<0 in cmd_insert_chars"); action_queue(A_SEND_LOST); return FALSE; } int i; for (i = 0; i < n; i++) cmd->data = g_string_insert_c(cmd->data, cmd->pos, c); action_queue(A_SEND_CMD); return TRUE; }
/* Returned value needs to be free with g_free(). */ gchar *strEscape (const gchar *const s) { GString *str = g_string_new (s); register gint i = 0; gchar *ret; while (str->str[i] != '\0') { if (str->str[i] == '\\' || str->str[i] == '\'') g_string_insert_c (str, i++, '\\'); i++; } ret = str->str; g_string_free (str, FALSE); return (ret); }
static int module_load_prefixes(const char *path, const char *module, int start, int end, char **prefixes) { GString *realpath; int status, ok; /* load module_core */ realpath = g_string_new(path); g_string_insert(realpath, end, "_core"); /* Don't print the error message the first time, since the module may not have the core part at all. */ status = module_load_name(realpath->str, module, "core", TRUE); ok = status > 0; if (prefixes != NULL) { /* load all the "prefix modules", like the fe-common, irc, etc. part of the module */ while (*prefixes != NULL) { g_string_assign(realpath, path); g_string_insert_c(realpath, start, '_'); g_string_insert(realpath, start, *prefixes); status = module_load_name(realpath->str, module, *prefixes, TRUE); if (status > 0) ok = TRUE; prefixes++; } } if (!ok) { /* error loading module, print the error message */ g_string_assign(realpath, path); g_string_insert(realpath, end, "_core"); module_load_name(realpath->str, module, "core", FALSE); } g_string_free(realpath, TRUE); return ok; }
void tf_indent_multi_line(LogMessage *msg, gint argc, GString *argv[], GString *text) { gchar *p, *new_line; /* append the message text(s) to the template string */ append_args(argc, argv, text); /* look up the \n-s and insert a \t after them */ p = text->str; new_line = memchr(p, '\n', text->len); while(new_line) { if (*(gchar *)(new_line + 1) != '\t') { g_string_insert_c(text, new_line - p + 1, '\t'); } new_line = memchr(new_line + 1, '\n', p + text->len - new_line); } }
/* add argument to specified position */ static void mode_add_arg(GString *str, int pos, int updating, const char *arg) { char *p; for (p = str->str; *p != '\0'; p++) { if (*p != ' ') continue; if (pos == 0) break; pos--; } pos = (int) (p-str->str); if (updating && *p != '\0') { /* remove the old argument */ p++; while (*p != '\0' && *p != ' ') p++; g_string_erase(str, pos, (int) (p-str->str)-pos); } g_string_insert_c(str, pos, ' '); g_string_insert(str, pos+1, arg); }
static void start_element (GMarkupParseContext *context, const gchar *element_name, const gchar **names, const gchar **values, gpointer user_data, GError **error) { ParserData *data = (ParserData*)user_data; #ifdef G_ENABLE_DEBUG if (GTK_DEBUG_CHECK (BUILDER)) { GString *tags = g_string_new (""); int i; for (i = 0; names[i]; i++) g_string_append_printf (tags, "%s=\"%s\" ", names[i], values[i]); if (i) { g_string_insert_c (tags, 0, ' '); g_string_truncate (tags, tags->len - 1); } g_message ("<%s%s>", element_name, tags->str); g_string_free (tags, TRUE); } #endif if (!data->last_element && strcmp (element_name, "interface") != 0) { error_unhandled_tag (data, element_name, error); return; } data->last_element = element_name; if (data->subparser) { if (!subparser_start (context, element_name, names, values, data, error)) return; } if (strcmp (element_name, "requires") == 0) parse_requires (data, element_name, names, values, error); else if (strcmp (element_name, "object") == 0) parse_object (context, data, element_name, names, values, error); else if (strcmp (element_name, "template") == 0) parse_template (context, data, element_name, names, values, error); else if (data->requested_objects && !data->inside_requested_object) { /* If outside a requested object, simply ignore this tag */ } else if (strcmp (element_name, "child") == 0) parse_child (data, element_name, names, values, error); else if (strcmp (element_name, "property") == 0) parse_property (data, element_name, names, values, error); else if (strcmp (element_name, "signal") == 0) parse_signal (data, element_name, names, values, error); else if (strcmp (element_name, "interface") == 0) parse_interface (data, element_name, names, values, error); else if (strcmp (element_name, "menu") == 0) _gtk_builder_menu_start (data, element_name, names, values, error); else if (strcmp (element_name, "placeholder") == 0) { /* placeholder has no special treatmeant, but it needs an * if clause to avoid an error below. */ } else if (!parse_custom (context, element_name, names, values, data, error)) error_unhandled_tag (data, element_name, error); }
/* manual word completion - called when TAB is pressed */ char *word_complete(WINDOW_REC *window, const char *line, int *pos, int erase, int backward) { static int startpos = 0, wordlen = 0; int old_startpos, old_wordlen; GString *result; const char *cmdchars; char *word, *wordstart, *linestart, *ret, *data; int continue_complete, want_space, expand_escapes; g_return_val_if_fail(line != NULL, NULL); g_return_val_if_fail(pos != NULL, NULL); continue_complete = complist != NULL && *pos == last_line_pos && g_strcmp0(line, last_line) == 0; if (erase && !continue_complete) return NULL; old_startpos = startpos; old_wordlen = wordlen; if (!erase && continue_complete) { word = NULL; linestart = NULL; } else { char* old_wordstart; /* get the word we want to complete */ word = get_word_at(line, *pos, &wordstart); old_wordstart = wordstart; startpos = (int) (wordstart-line); wordlen = strlen(word); /* remove trailing spaces from linestart */ while (wordstart > line && isseparator_space(wordstart[-1])) wordstart--; /* unless everything was spaces */ if (old_wordstart > line && wordstart == line) wordstart = old_wordstart - 1; linestart = g_strndup(line, (int) (wordstart-line)); /* completions usually add space after the word, that makes things a bit harder. When continuing a completion "/msg nick1 "<tab> we have to cycle to nick2, etc. BUT if we start completion with "/msg "<tab>, we don't want to complete the /msg word, but instead complete empty word with /msg being in linestart. */ if (!erase && *pos > 0 && isseparator_space(line[*pos-1]) && (*linestart == '\0' || !isseparator_space(wordstart[-1]))) { char *old; old = linestart; /* we want to move word into linestart */ if (*linestart == '\0') { linestart = g_strdup(word); } else { GString *str = g_string_new(linestart); if (old_wordstart[-1] != str->str[str->len - 1]) { /* do not accidentally duplicate the word separator */ g_string_append_c(str, old_wordstart[-1]); } g_string_append(str, word); linestart = g_string_free(str, FALSE); } g_free(old); g_free(word); word = g_strdup(""); startpos = *linestart == '\0' ? 0 : strlen(linestart)+1; wordlen = 0; } } if (erase) { signal_emit("complete erase", 3, window, word, linestart); /* jump to next completion */ startpos = old_startpos; wordlen = old_wordlen; } if (continue_complete) { /* complete from old list */ if (backward) complist = complist->prev != NULL ? complist->prev : g_list_last(complist); else complist = complist->next != NULL ? complist->next : g_list_first(complist); want_space = last_want_space; } else { int keep_word = settings_get_bool("completion_keep_word"); /* get new completion list */ free_completions(); want_space = TRUE; signal_emit("complete word", 5, &complist, window, word, linestart, &want_space); last_want_space = want_space; if (complist != NULL) { /* Remove all nulls (from the signal) before doing further processing */ complist = g_list_remove_all(g_list_first(complist), NULL); if (keep_word) { complist = g_list_append(complist, g_strdup(word)); } if (backward) { complist = g_list_last(complist); if (keep_word) { complist = complist->prev; } } } } g_free(linestart); g_free(word); if (complist == NULL) return NULL; /* get the cmd char */ cmdchars = settings_get_str("cmdchars"); /* get the expand_escapes setting */ expand_escapes = settings_get_bool("expand_escapes"); /* escape if the word doesn't begin with '/' and expand_escapes are turned on */ data = strchr(cmdchars, *line) == NULL && expand_escapes ? escape_string_backslashes(complist->data) : g_strdup(complist->data); /* word completed */ *pos = startpos + strlen(data); /* replace the word in line - we need to return a full new line */ result = g_string_new(line); g_string_erase(result, startpos, wordlen); g_string_insert(result, startpos, data); if (want_space) { if (!isseparator(result->str[*pos])) g_string_insert_c(result, *pos, ' '); (*pos)++; } wordlen = strlen(data); last_line_pos = *pos; g_free_not_null(last_line); last_line = g_strdup(result->str); ret = result->str; g_string_free(result, FALSE); /* free the data */ g_free(data); return ret; }
static void record_chan_mode (session *sess, char sign, char mode, char *arg) { /* Somebody needed to acutally update sess->current_modes, needed to play nice with bouncers, and less mode calls. Also keeps modes up to date for scripts */ server *serv = sess->server; GString *current = g_string_new(sess->current_modes); gint mode_pos = -1; gchar *current_char = current->str; gint modes_length; gint argument_num = 0; gint argument_offset = 0; gint argument_length = 0; int i = 0; gchar *arguments_start; /* find out if the mode currently exists */ arguments_start = g_strstr_len(current->str , -1, " "); if (arguments_start) { modes_length = arguments_start - current->str; } else { modes_length = current->len; /* set this to the end of the modes */ arguments_start = current->str + current->len; } while (mode_pos == -1 && i < modes_length) { if (*current_char == mode) { mode_pos = i; } else { i++; current_char++; } } /* if the mode currently exists and has an arg, need to know where * (including leading space) */ if (mode_pos != -1 && mode_has_arg(serv, '+', mode)) { current_char = current->str; i = 0; while (i <= mode_pos) { if (mode_has_arg(serv, '+', *current_char)) argument_num++; current_char++; i++; } /* check through arguments for where to start */ current_char = arguments_start; i = 0; while (i < argument_num && *current_char != '\0') { if (*current_char == ' ') i++; if (i != argument_num) current_char++; } argument_offset = current_char - current->str; /* how long the existing argument is for this key * important for malloc and strncpy */ if (i == argument_num) { argument_length++; current_char++; while (*current_char != '\0' && *current_char != ' ') { argument_length++; current_char++; } } } /* two cases, adding and removing a mode, handled differently */ if (sign == '+') { if (mode_pos != -1) { /* if it already exists, only need to do something (change) * if there should be a param */ if (mode_has_arg(serv, sign, mode)) { /* leave the old space there */ current = g_string_erase(current, argument_offset+1, argument_length-1); current = g_string_insert(current, argument_offset+1, arg); free(sess->current_modes); sess->current_modes = g_string_free(current, FALSE); } } /* mode wasn't there before */ else { /* insert the new mode character */ current = g_string_insert_c(current, modes_length, mode); /* add the argument, with space if there is one */ if (mode_has_arg(serv, sign, mode)) { current = g_string_append_c(current, ' '); current = g_string_append(current, arg); } free(sess->current_modes); sess->current_modes = g_string_free(current, FALSE); } } else if (sign == '-' && mode_pos != -1) { /* remove the argument first if it has one*/ if (mode_has_arg(serv, '+', mode)) current = g_string_erase(current, argument_offset, argument_length); /* remove the mode character */ current = g_string_erase(current, mode_pos, 1); free(sess->current_modes); sess->current_modes = g_string_free(current, FALSE); } }
/* convert _underlined_, /italics/, and *bold* words (and phrases) to use real underlining or bolding */ char *expand_emphasis(WI_ITEM_REC *item, const char *text) { GString *str; char *ret; int pos; int emphasis_italics; g_return_val_if_fail(text != NULL, NULL); emphasis_italics = settings_get_bool("emphasis_italics"); str = g_string_new(text); for (pos = 0; pos < str->len; pos++) { char type, *bgn, *end; bgn = str->str + pos; if (*bgn == '*') type = 2; /* bold */ else if (*bgn == '/' && emphasis_italics) type = 29; /* italics */ else if (*bgn == '_') type = 31; /* underlined */ else continue; /* check that the beginning marker starts a word, and that the matching end marker ends a word */ if ((pos > 0 && bgn[-1] != ' ') || !ishighalnum(bgn[1])) continue; if ((end = strchr(bgn+1, *bgn)) == NULL) continue; if (!ishighalnum(end[-1]) || ishighalnum(end[1]) || end[1] == type || end[1] == '*' || end[1] == '_' || /* special case for italics to not emphasise common paths by skipping /.../.X */ (type == 29 && i_ispunct(end[1]) && ishighalnum(end[2]))) continue; if (IS_CHANNEL(item)) { /* check that this isn't a _nick_, we don't want to use emphasis on them. */ int found; char c; char *end2; /* check if _foo_ is a nick */ c = end[1]; end[1] = '\0'; found = nicklist_find(CHANNEL(item), bgn) != NULL; end[1] = c; if (found) continue; /* check if the whole 'word' (e.g. "_foo_^") is a nick in "_foo_^ ", end will be the second _, end2 the ^ */ end2 = end; while (isnickchar(end2[1])) end2++; c = end2[1]; end2[1] = '\0'; found = nicklist_find(CHANNEL(item), bgn) != NULL; end2[1] = c; if (found) continue; } /* allow only *word* emphasis, not *multiple words* */ if (!settings_get_bool("emphasis_multiword")) { char *c; for (c = bgn+1; c != end; c++) { if (!ishighalnum(*c)) break; } if (c != end) continue; } if (settings_get_bool("emphasis_replace")) { *bgn = *end = type; pos += (end-bgn); } else { g_string_insert_c(str, pos, type); pos += (end - bgn) + 2; g_string_insert_c(str, pos++, type); } } ret = str->str; g_string_free(str, FALSE); return ret; }
/* convert _underlined_ and *bold* words (and phrases) to use real underlining or bolding */ char *expand_emphasis(WI_ITEM_REC *item, const char *text) { GString *str; char *ret; int pos; g_return_val_if_fail(text != NULL, NULL); str = g_string_new(text); for (pos = 0; pos < str->len; pos++) { char type, *bgn, *end; bgn = str->str + pos; if (*bgn == '*') type = 2; /* bold */ else if (*bgn == '_') type = 31; /* underlined */ else continue; /* check that the beginning marker starts a word, and that the matching end marker ends a word */ if ((pos > 0 && !i_isspace(bgn[-1])) || !ishighalnum(bgn[1])) continue; if ((end = strchr(bgn+1, *bgn)) == NULL) continue; if (!ishighalnum(end[-1]) || ishighalnum(end[1]) || end[1] == type || end[1] == '*' || end[1] == '_') continue; if (IS_CHANNEL(item)) { /* check that this isn't a _nick_, we don't want to use emphasis on them. */ int found; char c; c = end[1]; end[1] = '\0'; found = nicklist_find(CHANNEL(item), bgn) != NULL; end[1] = c; if (found) continue; } /* allow only *word* emphasis, not *multiple words* */ if (!settings_get_bool("emphasis_multiword")) { char *c; for (c = bgn+1; c != end; c++) { if (!ishighalnum(*c)) break; } if (c != end) continue; } if (settings_get_bool("emphasis_replace")) { *bgn = *end = type; pos += (end-bgn); } else { g_string_insert_c(str, pos, type); pos += (end - bgn) + 2; g_string_insert_c(str, pos++, type); } } ret = str->str; g_string_free(str, FALSE); return ret; }
void put_chars(char *chars, unsigned int size, gboolean crlf_auto) { char *characters; int pos; GString *buffer_tmp; gchar *in_buffer; buffer_tmp = g_string_new(chars); /* If the auto CR LF mode on, read the buffer to add \r before \n */ if(crlf_auto) { in_buffer=buffer_tmp->str; in_buffer += size; for(pos=size; pos>0; pos--) { in_buffer--; if(*in_buffer=='\n' && *(in_buffer-1) != '\r') { g_string_insert_c(buffer_tmp, pos-1, '\r'); size += 1; } if(*in_buffer=='\r' && *(in_buffer+1) != '\n') { g_string_insert_c(buffer_tmp, pos, '\n'); size += 1; } } chars = buffer_tmp->str; } if(buffer == NULL) { i18n_printf(_("ERROR : Buffer is not initialized !\n")); return; } if(size > BUFFER_SIZE) { characters = chars + (size - BUFFER_SIZE); size = BUFFER_SIZE; } else characters = chars; if((size + pointer) >= BUFFER_SIZE) { memcpy(current_buffer, characters, BUFFER_SIZE - pointer); chars = characters + BUFFER_SIZE - pointer; pointer = size - (BUFFER_SIZE - pointer); memcpy(buffer, chars, pointer); current_buffer = buffer + pointer; overlapped = 1; } else { memcpy(current_buffer, characters, size); pointer += size; current_buffer += size; } if(write_func != NULL) write_func(characters, size); g_string_free(buffer_tmp, 1); }
static void start_element (GMarkupParseContext *context, const gchar *element_name, const gchar **names, const gchar **values, gpointer user_data, GError **error) { ParserData *data = (ParserData*)user_data; #ifdef GTK_ENABLE_DEBUG if (gtk_debug_flags & GTK_DEBUG_BUILDER) { GString *tags = g_string_new (""); int i; for (i = 0; names[i]; i++) g_string_append_printf (tags, "%s=\"%s\" ", names[i], values[i]); if (i) { g_string_insert_c (tags, 0, ' '); g_string_truncate (tags, tags->len - 1); } g_print ("<%s%s>\n", element_name, tags->str); g_string_free (tags, TRUE); } #endif if (!data->last_element && strcmp (element_name, "interface") != 0) { g_set_error (error, GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_UNHANDLED_TAG, _("Invalid root element: '%s'"), element_name); return; } data->last_element = element_name; if (data->subparser) if (!subparser_start (context, element_name, names, values, data, error)) return; if (strcmp (element_name, "requires") == 0) parse_requires (data, element_name, names, values, error); else if (strcmp (element_name, "object") == 0) parse_object (context, data, element_name, names, values, error); else if (data->requested_objects && !data->inside_requested_object) { /* If outside a requested object, simply ignore this tag */ return; } else if (strcmp (element_name, "child") == 0) parse_child (data, element_name, names, values, error); else if (strcmp (element_name, "property") == 0) parse_property (data, element_name, names, values, error); else if (strcmp (element_name, "signal") == 0) parse_signal (data, element_name, names, values, error); else if (strcmp (element_name, "interface") == 0) parse_interface (data, element_name, names, values, error); else if (strcmp (element_name, "placeholder") == 0) { /* placeholder has no special treatmeant, but it needs an * if clause to avoid an error below. */ } else if (!parse_custom (context, element_name, names, values, data, error)) g_set_error (error, GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_UNHANDLED_TAG, _("Unhandled tag: '%s'"), element_name); }
/* manual word completion - called when TAB is pressed */ char *word_complete(WINDOW_REC *window, const char *line, int *pos) { static int startpos = 0, wordlen = 0; GString *result; char *word, *wordstart, *linestart, *ret; int want_space; g_return_val_if_fail(line != NULL, NULL); g_return_val_if_fail(pos != NULL, NULL); if (complist != NULL && *pos == last_line_pos && strcmp(line, last_line) == 0) { /* complete from old list */ complist = complist->next != NULL ? complist->next : g_list_first(complist); want_space = last_want_space; } else { /* get new completion list */ free_completions(); /* get the word we want to complete */ word = get_word_at(line, *pos, &wordstart); startpos = (int) (wordstart-line); wordlen = strlen(word); /* get the start of line until the word we're completing */ if (isseparator(*line)) { /* empty space at the start of line */ if (wordstart == line) wordstart += strlen(wordstart); } else { while (wordstart > line && isseparator(wordstart[-1])) wordstart--; } linestart = g_strndup(line, (int) (wordstart-line)); /* completions usually add space after the word, that makes things a bit harder. When continuing a completion "/msg nick1 "<tab> we have to cycle to nick2, etc. BUT if we start completion with "/msg "<tab>, we don't want to complete the /msg word, but instead complete empty word with /msg being in linestart. */ if (*pos > 0 && line[*pos-1] == ' ') { char *old; old = linestart; linestart = *linestart == '\0' ? g_strdup(word) : g_strconcat(linestart, " ", word, NULL); g_free(old); g_free(word); word = g_strdup(""); startpos = strlen(linestart)+1; wordlen = 0; } want_space = TRUE; signal_emit("complete word", 5, &complist, window, word, linestart, &want_space); last_want_space = want_space; g_free(linestart); g_free(word); } if (complist == NULL) return NULL; /* word completed */ *pos = startpos+strlen(complist->data); /* replace the word in line - we need to return a full new line */ result = g_string_new(line); g_string_erase(result, startpos, wordlen); g_string_insert(result, startpos, complist->data); if (want_space) { if (!isseparator(result->str[*pos])) g_string_insert_c(result, *pos, ' '); (*pos)++; } wordlen = strlen(complist->data); last_line_pos = *pos; g_free_not_null(last_line); last_line = g_strdup(result->str); ret = result->str; g_string_free(result, FALSE); return ret; }