GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, int level, int nolevel, const char *text, int before, int after, int regexp, int fullword, int case_sensitive) { #ifdef HAVE_REGEX_H regex_t preg; #endif LINE_REC *line, *pre_line; GList *matches; GString *str; int i, match_after, line_matched; char * (*match_func)(const char *, const char *); g_return_val_if_fail(buffer != NULL, NULL); g_return_val_if_fail(text != NULL, NULL); if (regexp) { #ifdef HAVE_REGEX_H int flags = REG_EXTENDED | REG_NOSUB | (case_sensitive ? 0 : REG_ICASE); if (regcomp(&preg, text, flags) != 0) return NULL; #else return NULL; #endif } matches = NULL; match_after = 0; str = g_string_new(NULL); line = startline != NULL ? startline : buffer->first_line; if (fullword) match_func = case_sensitive ? strstr_full : stristr_full; else match_func = case_sensitive ? strstr : stristr; for (; line != NULL; line = line->next) { line_matched = (line->info.level & level) != 0 && (line->info.level & nolevel) == 0; if (*text != '\0') { textbuffer_line2text(line, FALSE, str); if (line_matched) line_matched = #ifdef HAVE_REGEX_H regexp ? regexec(&preg, str->str, 0, NULL, 0) == 0 : #endif match_func(str->str, text) != NULL; } if (line_matched) { /* add the -before lines */ pre_line = line; for (i = 0; i < before; i++) { if (pre_line->prev == NULL || g_list_find(matches, pre_line->prev) != NULL) break; pre_line = pre_line->prev; } for (; pre_line != line; pre_line = pre_line->next) matches = g_list_append(matches, pre_line); match_after = after; } if (line_matched || match_after > 0) { /* matched */ matches = g_list_append(matches, line); if ((!line_matched && --match_after == 0) || (line_matched && match_after == 0 && before > 0)) matches = g_list_append(matches, NULL); } } #ifdef HAVE_REGEX_H if (regexp) regfree(&preg); #endif g_string_free(str, TRUE); return matches; }
static void show_lastlog(const char *searchtext, GHashTable *optlist, int start, int count, FILE *fhandle) { WINDOW_REC *window; LINE_REC *startline; GList *list, *tmp; GString *line; char *str; int level, before, after, len, date = FALSE; level = cmd_options_get_level("lastlog", optlist); if (level == -1) return; /* error in options */ if (level == 0) level = MSGLEVEL_ALL; if (g_hash_table_lookup(optlist, "clear") != NULL) { textbuffer_view_remove_lines_by_level(WINDOW_GUI(active_win)->view, MSGLEVEL_LASTLOG); if (*searchtext == '\0') return; } /* which window's lastlog to look at? */ window = active_win; str = g_hash_table_lookup(optlist, "window"); if (str != NULL) { window = is_numeric(str, '\0') ? window_find_refnum(atoi(str)) : window_find_item(NULL, str); if (window == NULL) { printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_REFNUM_NOT_FOUND, str); return; } } if (g_hash_table_lookup(optlist, "new") != NULL) startline = textbuffer_view_get_bookmark(WINDOW_GUI(window)->view, "lastlog_last_check"); else if (g_hash_table_lookup(optlist, "away") != NULL) startline = textbuffer_view_get_bookmark(WINDOW_GUI(window)->view, "lastlog_last_away"); else startline = NULL; if (startline == NULL) startline = textbuffer_view_get_lines(WINDOW_GUI(window)->view); str = g_hash_table_lookup(optlist, "#"); if (str != NULL) { before = after = atoi(str); } else { str = g_hash_table_lookup(optlist, "before"); before = str == NULL ? 0 : *str != '\0' ? atoi(str) : DEFAULT_LASTLOG_BEFORE; str = g_hash_table_lookup(optlist, "after"); if (str == NULL) str = g_hash_table_lookup(optlist, "a"); after = str == NULL ? 0 : *str != '\0' ? atoi(str) : DEFAULT_LASTLOG_AFTER; } if (g_hash_table_lookup(optlist, "date") != NULL) date = TRUE; list = textbuffer_find_text(WINDOW_GUI(window)->view->buffer, startline, level, MSGLEVEL_LASTLOG, searchtext, before, after, g_hash_table_lookup(optlist, "regexp") != NULL, g_hash_table_lookup(optlist, "word") != NULL, g_hash_table_lookup(optlist, "case") != NULL); len = g_list_length(list); if (count <= 0) tmp = list; else { int pos = len-count-start; if (pos < 0) pos = 0; tmp = pos > len ? NULL : g_list_nth(list, pos); len = g_list_length(tmp); } if (g_hash_table_lookup(optlist, "count") != NULL) { printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_LASTLOG_COUNT, len); g_list_free(list); return; } if (len > MAX_LINES_WITHOUT_FORCE && fhandle == NULL && g_hash_table_lookup(optlist, "force") == NULL) { printformat_window(active_win, MSGLEVEL_CLIENTNOTICE|MSGLEVEL_LASTLOG, TXT_LASTLOG_TOO_LONG, len); g_list_free(list); return; } if (fhandle == NULL && g_hash_table_lookup(optlist, "-") == NULL) printformat(NULL, NULL, MSGLEVEL_LASTLOG, TXT_LASTLOG_START); line = g_string_new(NULL); while (tmp != NULL && (count < 0 || count > 0)) { LINE_REC *rec = tmp->data; if (rec == NULL) { if (tmp->next == NULL) break; if (fhandle != NULL) { fwrite("--\n", 3, 1, fhandle); } else { printformat_window(active_win, MSGLEVEL_LASTLOG, TXT_LASTLOG_SEPARATOR); } tmp = tmp->next; continue; } /* get the line text */ textbuffer_line2text(rec, fhandle == NULL, line); if (!settings_get_bool("timestamps")) { struct tm *tm = localtime(&rec->info.time); char timestamp[10]; g_snprintf(timestamp, sizeof(timestamp), "%02d:%02d ", tm->tm_hour, tm->tm_min); g_string_prepend(line, timestamp); } if (date == TRUE) prepend_date(window, rec, line); /* write to file/window */ if (fhandle != NULL) { fwrite(line->str, line->len, 1, fhandle); fputc('\n', fhandle); } else { printtext_window(active_win, MSGLEVEL_LASTLOG, "%s", line->str); } count--; tmp = tmp->next; } g_string_free(line, TRUE); if (fhandle == NULL && g_hash_table_lookup(optlist, "-") == NULL) printformat(NULL, NULL, MSGLEVEL_LASTLOG, TXT_LASTLOG_END); textbuffer_view_set_bookmark_bottom(WINDOW_GUI(window)->view, "lastlog_last_check"); g_list_free(list); }
GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, int level, int nolevel, const char *text, int before, int after, int regexp, int fullword, int case_sensitive) { Regex *preg; LINE_REC *line, *pre_line; GList *matches; GString *str; int i, match_after, line_matched; char * (*match_func)(const char *, const char *); g_return_val_if_fail(buffer != NULL, NULL); g_return_val_if_fail(text != NULL, NULL); preg = NULL; if (regexp) { preg = i_regex_new(text, case_sensitive ? 0 : G_REGEX_CASELESS, 0, NULL); if (preg == NULL) return NULL; } matches = NULL; match_after = 0; str = g_string_new(NULL); line = startline != NULL ? startline : buffer->first_line; if (fullword) match_func = case_sensitive ? strstr_full : stristr_full; else match_func = case_sensitive ? strstr : stristr; for (; line != NULL; line = line->next) { line_matched = (line->info.level & level) != 0 && (line->info.level & nolevel) == 0; if (*text != '\0') { textbuffer_line2text(line, FALSE, str); if (line_matched) { line_matched = regexp ? i_regex_match(preg, str->str, 0, NULL) : match_func(str->str, text) != NULL; } } if (line_matched) { /* add the -before lines */ pre_line = line; for (i = 0; i < before; i++) { if (pre_line->prev == NULL || g_list_nth_data(matches, 0) == pre_line->prev || g_list_nth_data(matches, 1) == pre_line->prev) break; pre_line = pre_line->prev; } for (; pre_line != line; pre_line = pre_line->next) matches = g_list_prepend(matches, pre_line); match_after = after; } if (line_matched || match_after > 0) { /* matched */ matches = g_list_prepend(matches, line); if ((!line_matched && --match_after == 0) || (line_matched && match_after == 0 && before > 0)) matches = g_list_prepend(matches, NULL); } } matches = g_list_reverse(matches); if (preg != NULL) i_regex_unref(preg); g_string_free(str, TRUE); return matches; }