gboolean biblio_detect_bibliography (GuBiblio* bc, GuEditor* ec) { gchar* content = NULL; gchar* bibfn = NULL; gchar** result = NULL; GMatchInfo *match_info; GRegex* bib_regex = NULL; gboolean state = FALSE; content = editor_grab_buffer (ec); bib_regex = g_regex_new ("^[^%]*\\\\bibliography{\\s*([^{}\\s]*)\\s*}", G_REGEX_MULTILINE, 0, NULL); if (g_regex_match (bib_regex, content, 0, &match_info)) { result = g_match_info_fetch_all (match_info); if (result[1]) { if (!STR_EQU (result[1] +strlen (result[1]) -4, ".bib")) bibfn = g_strconcat (result[1], ".bib", NULL); else bibfn = g_strdup (result[1]); state = editor_fileinfo_update_biblio (ec, bibfn); g_free (bibfn); } slog (L_INFO, "Detect bibliography file: %s\n", ec->bibfile); g_strfreev (result); } g_free (content); g_match_info_free (match_info); g_regex_unref (bib_regex); return state; }
static VALUE rg_fetch_all(VALUE self) { gchar **strings; strings = g_match_info_fetch_all(_SELF(self)); return STRV2RVAL_FREE(strings); }
GuSnippetInfo* snippets_parse (char* snippet) { gint i, start, end; GError* err = NULL; gchar** result = NULL; GRegex* regex = NULL; GMatchInfo* match_info = NULL; const gchar* holders[] = { "\\$([0-9]+)", "\\${([0-9]*):?([^}]*)}", "\\$(FILENAME)", "\\${(FILENAME)}", "\\$(BASENAME)", "\\${(BASENAME)}", "\\$(SELECTED_TEXT)", "\\${(SELECTED_TEXT)}" /* Anyway to combine these? */ }; GuSnippetInfo* info = snippet_info_new (snippet); for (i = 0; i < sizeof(holders) / sizeof(holders[0]); ++i) { if (! (regex = g_regex_new (holders[i], G_REGEX_DOTALL, 0, &err))) { slog (L_ERROR, "g_regex_new (): %s\n", err->message); g_error_free (err); return info; } g_regex_match (regex, snippet, 0, &match_info); while (g_match_info_matches (match_info)) { result = g_match_info_fetch_all (match_info); g_match_info_fetch_pos (match_info, 0, &start, &end); /* Convert start, end to UTF8 offset */ char* s_start = g_substr(snippet, 0, start); char* s_end = g_substr(snippet, 0, end); start = g_utf8_strlen(s_start, -1); end = g_utf8_strlen(s_end, -1); g_free(s_start); g_free(s_end); if (i < 2) { snippet_info_append_holder (info, atoi (result[1]), start, end -start, result[2]); } else { snippet_info_append_holder (info, -1, start, end -start, result[1]); } slog (L_DEBUG, "Placeholder: (%s, %s, %s)\n", result[0], result[1], result[2]); g_match_info_next (match_info, NULL); g_strfreev (result); } g_regex_unref (regex); g_match_info_free (match_info); } info->einfo = g_list_sort (info->einfo, snippet_info_pos_cmp); info->einfo_sorted = g_list_copy (info->einfo); info->einfo_sorted = g_list_sort (info->einfo_sorted, snippet_info_num_cmp); return info; }
static int regexp_match(struct objlist *obj,N_VALUE *inst,N_VALUE *rval,int argc,char **argv) { struct oregexp_local *local; GMatchInfo *info; int r; char *str, **match; str = (char *) argv[2]; rval->i = 0; _getobj(obj, "_local", inst, &local); if (local->regexp == NULL) { return 1; } del_array_element(local->array); if (str == NULL || str[0] == '\0') { return 1; } info = NULL; r = g_regex_match(local->regexp, str, 0, &info); if (! r) { g_match_info_free(info); return 1; } while (g_match_info_matches(info)) { match = g_match_info_fetch_all(info); arrayadd(local->array, &match); g_match_info_next(info, NULL); } g_match_info_free(info); rval->i = arraynum(local->array); return 0; }
G_MODULE_EXPORT void on_menu_docstat_activate(GtkWidget *widget, void *user) { gint i = 0; gchar* output = 0; gchar* cmd = 0; gchar** matched = NULL; GError* err = NULL; GMatchInfo* match_info; GRegex* regexs[TEXCOUNT_OUTPUT_LINES]; gchar* res[TEXCOUNT_OUTPUT_LINES] = { 0 }; /* TODO: can we deprecate this? */ const gchar* terms[] = { _("Words in text"), _("Words in headers"), _("Words in float captions"), _("Number of headers"), _("Number of floats"), _("Number of math inlines"), _("Number of math displayed") }; const gchar* terms_regex[] = { "Words in text: ([0-9]*)", "Words in headers: ([0-9]*)", "Words in float captions: ([0-9]*)", "Number of headers: ([0-9]*)", "Number of floats: ([0-9]*)", "Number of math inlines: ([0-9]*)", "Number of math displayed: ([0-9]*)" }; /* TODO: move to non gui class (latex perhaps) */ if (external_exists("texcount")) { /* Copy workfile to /tmp to remove any spaces in filename to avoid * segfaults */ gchar* tmpfile = g_strdup_printf("%s.state", g_active_editor->fdname); if (!utils_copy_file(g_active_editor->workfile, tmpfile, &err)) { slog(L_G_ERROR, "utils_copy_file (): %s\n", err->message); g_free(tmpfile); g_error_free(err); goto cleanup; } cmd = g_strdup_printf("texcount '%s'", tmpfile); Tuple2 result = utils_popen_r(cmd, NULL); for (i = 0; i < TEXCOUNT_OUTPUT_LINES; ++i) if (!(regexs[i] = g_regex_new(terms_regex[i], 0, 0, &err))) { slog(L_G_ERROR, "utils_copy_file (): %s\n", err->message); g_free(tmpfile); g_error_free(err); goto cleanup; } for (i = 0; i < TEXCOUNT_OUTPUT_LINES; ++i) { if (g_regex_match(regexs[i], result.second, 0, &match_info)) { matched = g_match_info_fetch_all(match_info); if (NULL == matched[1]) { slog(L_WARNING, "can't extract info: %s\n", terms[i]); res[i] = g_strdup("N/A"); } else { res[i] = g_strdup(matched[1]); } g_strfreev(matched); g_match_info_free(match_info); } } g_free(result.second); g_free(tmpfile); } else { cmd = NULL; slog(L_G_ERROR, "The 'texcount' utility could not be found.\n"); return; } gchararray items[6] = {"stats_words", "stats_head", "stats_float", "stats_nrhead", "stats_nrfloat", "stats_nrmath" }; int j = 0; GtkLabel *tmp; for (j = 0; j < 6; j++) { gchar *value = items[j]; tmp = GTK_LABEL(gtk_builder_get_object(gui->builder, value)); gtk_label_set_text(tmp, res[j]); } gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(gui->builder, "stats_filename")), tabmanagergui_get_labeltext(g_active_tab->page)); gtk_widget_show(gui->docstatswindow); return; cleanup: for (i = 0; i < TEXCOUNT_OUTPUT_LINES; ++i) { g_regex_unref(regexs[i]); g_free(res[i]); } g_free(cmd); g_free(output); }
static gchar * mud_trigger_parse(MudTrigger *self, const gchar *data) { gint state; gchar **matches; GString *ret, *reg_num; guint length, matches_length, i, j, num; length = strlen(data); if(length == 0) return NULL; ret = g_string_new(NULL); reg_num = NULL; matches = g_match_info_fetch_all(self->priv->info); matches_length = g_strv_length(matches); state = PARSE_STATE_TEXT; for(i = 0; i < length; i++) { switch(state) { case PARSE_STATE_TEXT: if(data[i] == '%' && i + 1 < length) state = PARSE_STATE_REGISTER; else ret = g_string_append_c(ret, data[i]); break; case PARSE_STATE_REGISTER: reg_num = g_string_new(NULL); j = i; while(TRUE) { if(j == length || data[j] != '%') break; ret = g_string_append_c(ret, data[j++]); } if(j == length) { if(data[j - 1] == '%') ret = g_string_append_c(ret, data[j - 1]); i = j; break; } for(; g_ascii_isdigit(data[j]) && j < length; j++) reg_num = g_string_append_c(reg_num, data[j]); if(reg_num->len == 0) // No number, not a register. { /* Append the % that got us here. */ ret = g_string_append_c(ret, '%'); i = j - 1; g_string_free(reg_num, TRUE); state = PARSE_STATE_TEXT; } else { i = j - 1; num = atol(reg_num->str); g_string_free(reg_num, TRUE); if(num >= matches_length) ret = g_string_append(ret, _("#Submatch Out of Range#")); else ret = g_string_append(ret, matches[num]); state = PARSE_STATE_TEXT; } break; } } if(matches_length != 0) g_strfreev(matches); return g_string_free(ret, (ret->len == 0) ); }