mirror of
https://github.com/irssi/irssi.git
synced 2024-12-04 14:46:39 -05:00
Replaced GList by adding prev/next pointers to LINE_REC. This should make
some things faster and take a bit less memory. Also fixed an evil memory leak. git-svn-id: http://svn.irssi.org/repos/irssi/trunk@1611 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
parent
dd37b9ca2c
commit
9eed52fa40
@ -57,7 +57,7 @@ static void remove_old_lines(TEXT_BUFFER_VIEW_REC *view)
|
||||
scrollback_lines+scrollback_burst_remove) {
|
||||
/* remove lines by line count */
|
||||
while (view->buffer->lines_count > scrollback_lines) {
|
||||
line = view->buffer->lines->data;
|
||||
line = view->buffer->first_line;
|
||||
if (line->info.time >= old_time ||
|
||||
scrollback_lines == 0) {
|
||||
/* too new line, don't remove yet - also
|
||||
|
@ -35,17 +35,19 @@
|
||||
|
||||
static void window_lastlog_clear(WINDOW_REC *window)
|
||||
{
|
||||
TEXT_BUFFER_VIEW_REC *view;
|
||||
GList *tmp, *next;
|
||||
TEXT_BUFFER_VIEW_REC *view;
|
||||
LINE_REC *line, *next;
|
||||
|
||||
screen_refresh_freeze();
|
||||
view = WINDOW_GUI(window)->view;
|
||||
for (tmp = textbuffer_view_get_lines(view); tmp != NULL; tmp = next) {
|
||||
LINE_REC *line = tmp->data;
|
||||
line = textbuffer_view_get_lines(view);
|
||||
|
||||
next = tmp->next;
|
||||
if (line->info.level & MSGLEVEL_LASTLOG)
|
||||
while (line != NULL) {
|
||||
next = line->next;
|
||||
|
||||
if (line->info.level & MSGLEVEL_LASTLOG)
|
||||
textbuffer_view_remove_line(view, line);
|
||||
line = next;
|
||||
}
|
||||
textbuffer_view_redraw(view);
|
||||
screen_refresh_thaw();
|
||||
@ -131,10 +133,8 @@ static void show_lastlog(const char *searchtext, GHashTable *optlist,
|
||||
else
|
||||
startline = NULL;
|
||||
|
||||
if (startline == NULL) {
|
||||
list = textbuffer_view_get_lines(WINDOW_GUI(window)->view);
|
||||
startline = list == NULL ? NULL : list->data;
|
||||
}
|
||||
if (startline == NULL)
|
||||
startline = textbuffer_view_get_lines(WINDOW_GUI(window)->view);
|
||||
|
||||
list = textbuffer_find_text(WINDOW_GUI(window)->view->buffer, startline,
|
||||
level, MSGLEVEL_LASTLOG,
|
||||
|
@ -74,13 +74,13 @@ static void scrollback_goto_line(int linenum)
|
||||
if (view->buffer->lines_count == 0)
|
||||
return;
|
||||
|
||||
textbuffer_view_scroll_line(view, view->buffer->lines->data);
|
||||
textbuffer_view_scroll_line(view, view->buffer->first_line);
|
||||
gui_window_scroll(active_win, linenum);
|
||||
}
|
||||
|
||||
static void scrollback_goto_time(const char *datearg, const char *timearg)
|
||||
{
|
||||
GList *tmp;
|
||||
LINE_REC *line;
|
||||
struct tm tm;
|
||||
time_t now, stamp;
|
||||
int day, month;
|
||||
@ -145,12 +145,10 @@ static void scrollback_goto_time(const char *datearg, const char *timearg)
|
||||
}
|
||||
|
||||
/* scroll to first line after timestamp */
|
||||
tmp = textbuffer_view_get_lines(WINDOW_GUI(active_win)->view);
|
||||
for (; tmp != NULL; tmp = tmp->next) {
|
||||
LINE_REC *rec = tmp->data;
|
||||
|
||||
if (rec->info.time >= stamp) {
|
||||
gui_window_scroll_line(active_win, rec);
|
||||
line = textbuffer_view_get_lines(WINDOW_GUI(active_win)->view);
|
||||
for (; line != NULL; line = line->next) {
|
||||
if (line->info.time >= stamp) {
|
||||
gui_window_scroll_line(active_win, line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -188,7 +186,7 @@ static void cmd_scrollback_home(const char *data)
|
||||
|
||||
buffer = WINDOW_GUI(active_win)->view->buffer;
|
||||
if (buffer->lines_count > 0)
|
||||
gui_window_scroll_line(active_win, buffer->lines->data);
|
||||
gui_window_scroll_line(active_win, buffer->first_line);
|
||||
}
|
||||
|
||||
/* SYNTAX: SCROLLBACK END */
|
||||
@ -200,7 +198,7 @@ static void cmd_scrollback_end(const char *data)
|
||||
if (view->bottom_startline == NULL)
|
||||
return;
|
||||
|
||||
textbuffer_view_scroll_line(view, view->bottom_startline->data);
|
||||
textbuffer_view_scroll_line(view, view->bottom_startline);
|
||||
gui_window_scroll(active_win, view->bottom_subline);
|
||||
}
|
||||
|
||||
|
@ -321,7 +321,7 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
|
||||
original if possible */
|
||||
static void textbuffer_view_init_bottom(TEXT_BUFFER_VIEW_REC *view)
|
||||
{
|
||||
GList *tmp;
|
||||
LINE_REC *line;
|
||||
int linecount, total;
|
||||
|
||||
if (view->empty_linecount == 0) {
|
||||
@ -331,12 +331,10 @@ static void textbuffer_view_init_bottom(TEXT_BUFFER_VIEW_REC *view)
|
||||
}
|
||||
|
||||
total = 0;
|
||||
tmp = g_list_last(view->buffer->lines);
|
||||
for (; tmp != NULL; tmp = tmp->prev) {
|
||||
LINE_REC *line = tmp->data;
|
||||
|
||||
line = textbuffer_line_last(view->buffer);
|
||||
for (; line != NULL; line = line->prev) {
|
||||
linecount = view_get_linecount(view, line);
|
||||
if (tmp == view->bottom_startline) {
|
||||
if (line == view->bottom_startline) {
|
||||
/* keep the old one, make sure that subline is ok */
|
||||
if (view->bottom_subline > linecount)
|
||||
view->bottom_subline = linecount;
|
||||
@ -347,7 +345,7 @@ static void textbuffer_view_init_bottom(TEXT_BUFFER_VIEW_REC *view)
|
||||
|
||||
total += linecount;
|
||||
if (total >= view->height) {
|
||||
view->bottom_startline = tmp;
|
||||
view->bottom_startline = line;
|
||||
view->bottom_subline = total - view->height;
|
||||
view->empty_linecount = 0;
|
||||
return;
|
||||
@ -355,20 +353,20 @@ static void textbuffer_view_init_bottom(TEXT_BUFFER_VIEW_REC *view)
|
||||
}
|
||||
|
||||
/* not enough lines so we must be at the beginning of the buffer */
|
||||
view->bottom_startline = view->buffer->lines;
|
||||
view->bottom_startline = view->buffer->first_line;
|
||||
view->bottom_subline = 0;
|
||||
view->empty_linecount = view->height - total;
|
||||
}
|
||||
|
||||
static void textbuffer_view_init_ypos(TEXT_BUFFER_VIEW_REC *view)
|
||||
{
|
||||
GList *tmp;
|
||||
LINE_REC *line;
|
||||
|
||||
g_return_if_fail(view != NULL);
|
||||
|
||||
view->ypos = -view->subline-1;
|
||||
for (tmp = view->startline; tmp != NULL; tmp = tmp->next)
|
||||
view->ypos += view_get_linecount(view, tmp->data);
|
||||
for (line = view->startline; line != NULL; line = line->next)
|
||||
view->ypos += view_get_linecount(view, line);
|
||||
}
|
||||
|
||||
/* Create new view. */
|
||||
@ -445,28 +443,26 @@ void textbuffer_view_set_default_indent(TEXT_BUFFER_VIEW_REC *view,
|
||||
view->longword_noindent = longword_noindent;
|
||||
}
|
||||
|
||||
static int view_get_linecount_all(TEXT_BUFFER_VIEW_REC *view, GList *lines)
|
||||
static int view_get_linecount_all(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
|
||||
{
|
||||
int linecount;
|
||||
|
||||
linecount = 0;
|
||||
while (lines != NULL) {
|
||||
linecount += view_get_linecount(view, lines->data);
|
||||
lines = lines->next;
|
||||
while (line != NULL) {
|
||||
linecount += view_get_linecount(view, line);
|
||||
line = line->next;
|
||||
}
|
||||
|
||||
return linecount;
|
||||
}
|
||||
|
||||
static void view_draw(TEXT_BUFFER_VIEW_REC *view, GList *line,
|
||||
static void view_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
|
||||
int subline, int ypos, int lines)
|
||||
{
|
||||
int linecount;
|
||||
|
||||
while (line != NULL && lines > 0) {
|
||||
LINE_REC *rec = line->data;
|
||||
|
||||
linecount = view_line_draw(view, rec, subline, ypos, lines);
|
||||
linecount = view_line_draw(view, line, subline, ypos, lines);
|
||||
ypos += linecount; lines -= linecount;
|
||||
|
||||
subline = 0;
|
||||
@ -486,13 +482,13 @@ static void view_draw(TEXT_BUFFER_VIEW_REC *view, GList *line,
|
||||
|
||||
static void view_draw_bottom(TEXT_BUFFER_VIEW_REC *view, int lines)
|
||||
{
|
||||
GList *line;
|
||||
LINE_REC *line;
|
||||
int ypos, maxline, subline, linecount;
|
||||
|
||||
maxline = view->height-lines;
|
||||
line = view->startline; ypos = -view->subline; subline = 0;
|
||||
while (line != NULL && ypos < maxline) {
|
||||
linecount = view_get_linecount(view, line->data);
|
||||
linecount = view_get_linecount(view, line);
|
||||
ypos += linecount;
|
||||
if (ypos > maxline) {
|
||||
subline = maxline-(ypos-linecount);
|
||||
@ -505,8 +501,8 @@ static void view_draw_bottom(TEXT_BUFFER_VIEW_REC *view, int lines)
|
||||
}
|
||||
|
||||
/* Returns number of lines actually scrolled */
|
||||
static int view_scroll(TEXT_BUFFER_VIEW_REC *view, GList **lines, int *subline,
|
||||
int scrollcount, int draw_nonclean)
|
||||
static int view_scroll(TEXT_BUFFER_VIEW_REC *view, LINE_REC **lines,
|
||||
int *subline, int scrollcount, int draw_nonclean)
|
||||
{
|
||||
int linecount, realcount, scroll_visible;
|
||||
|
||||
@ -520,7 +516,7 @@ static int view_scroll(TEXT_BUFFER_VIEW_REC *view, GList **lines, int *subline,
|
||||
scrollcount += *subline;
|
||||
*subline = 0;
|
||||
while (scrollcount > 0) {
|
||||
linecount = view_get_linecount(view, (*lines)->data);
|
||||
linecount = view_get_linecount(view, *lines);
|
||||
|
||||
if ((scroll_visible && *lines == view->bottom_startline) &&
|
||||
(scrollcount >= view->bottom_subline)) {
|
||||
@ -545,7 +541,7 @@ static int view_scroll(TEXT_BUFFER_VIEW_REC *view, GList **lines, int *subline,
|
||||
/* scroll up */
|
||||
while (scrollcount < 0 && (*lines)->prev != NULL) {
|
||||
*lines = (*lines)->prev;
|
||||
linecount = view_get_linecount(view, (*lines)->data);
|
||||
linecount = view_get_linecount(view, *lines);
|
||||
|
||||
realcount -= linecount;
|
||||
scrollcount += linecount;
|
||||
@ -595,7 +591,7 @@ void textbuffer_view_resize(TEXT_BUFFER_VIEW_REC *view, int width, int height)
|
||||
view->width = width;
|
||||
view->height = height;
|
||||
|
||||
if (view->buffer->lines == NULL) {
|
||||
if (view->buffer->first_line == NULL) {
|
||||
view->empty_linecount = height;
|
||||
return;
|
||||
}
|
||||
@ -603,8 +599,8 @@ void textbuffer_view_resize(TEXT_BUFFER_VIEW_REC *view, int width, int height)
|
||||
textbuffer_view_init_bottom(view);
|
||||
|
||||
/* check that we didn't scroll lower than bottom startline.. */
|
||||
if (g_list_find(view->bottom_startline->next,
|
||||
view->startline->data) != NULL) {
|
||||
if (textbuffer_line_exists_after(view->bottom_startline->next,
|
||||
view->startline)) {
|
||||
view->startline = view->bottom_startline;
|
||||
view->subline = view->bottom_subline;
|
||||
} else if (view->startline == view->bottom_startline &&
|
||||
@ -612,7 +608,7 @@ void textbuffer_view_resize(TEXT_BUFFER_VIEW_REC *view, int width, int height)
|
||||
view->subline = view->bottom_subline;
|
||||
} else {
|
||||
/* make sure the subline is still in allowed range */
|
||||
linecount = view_get_linecount(view, view->startline->data);
|
||||
linecount = view_get_linecount(view, view->startline);
|
||||
if (view->subline > linecount)
|
||||
view->subline = linecount;
|
||||
}
|
||||
@ -649,7 +645,7 @@ void textbuffer_view_clear(TEXT_BUFFER_VIEW_REC *view)
|
||||
|
||||
view->ypos = -1;
|
||||
view->bottom_startline = view->startline =
|
||||
g_list_last(view->buffer->lines);
|
||||
textbuffer_line_last(view->buffer);
|
||||
view->bottom_subline = view->subline =
|
||||
view->buffer->cur_line == NULL ? 0 :
|
||||
view_get_linecount(view, view->buffer->cur_line);
|
||||
@ -678,23 +674,14 @@ void textbuffer_view_scroll(TEXT_BUFFER_VIEW_REC *view, int lines)
|
||||
/* Scroll to specified line */
|
||||
void textbuffer_view_scroll_line(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
|
||||
{
|
||||
GList *tmp;
|
||||
|
||||
g_return_if_fail(view != NULL);
|
||||
|
||||
if (g_list_find(view->bottom_startline->next, line) != NULL) {
|
||||
if (textbuffer_line_exists_after(view->bottom_startline->next, line)) {
|
||||
view->startline = view->bottom_startline;
|
||||
view->subline = view->bottom_subline;
|
||||
} else {
|
||||
for (tmp = view->buffer->lines; tmp != NULL; tmp = tmp->next) {
|
||||
LINE_REC *rec = tmp->data;
|
||||
|
||||
if (rec == line) {
|
||||
view->startline = tmp;
|
||||
view->subline = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
view->startline = line;
|
||||
view->subline = 0;
|
||||
}
|
||||
|
||||
textbuffer_view_init_ypos(view);
|
||||
@ -752,11 +739,11 @@ static void view_insert_line(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
|
||||
|
||||
if (view->bottom_startline == NULL) {
|
||||
view->startline = view->bottom_startline =
|
||||
view->buffer->lines;
|
||||
view->buffer->first_line;
|
||||
}
|
||||
|
||||
if (view->buffer->cur_line != line &&
|
||||
g_list_find(view->bottom_startline, line) == NULL)
|
||||
!textbuffer_line_exists_after(view->bottom_startline, line))
|
||||
return;
|
||||
|
||||
linecount = view->cache->last_linecount;
|
||||
@ -850,11 +837,8 @@ static void view_bookmarks_check(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
|
||||
(GHFunc) bookmark_check_remove, &rec);
|
||||
|
||||
if (rec.remove_list != NULL) {
|
||||
GList *pos = g_list_find(view->buffer->lines, line);
|
||||
|
||||
new_line = pos == NULL || pos->prev == NULL ? NULL :
|
||||
(pos->next == NULL ? pos->prev->data :
|
||||
pos->next->data);
|
||||
new_line = line->prev == NULL ? NULL :
|
||||
(line->next == NULL ? line->prev : line->next);
|
||||
for (tmp = rec.remove_list; tmp != NULL; tmp = tmp->next) {
|
||||
g_hash_table_remove(view->bookmarks, tmp->data);
|
||||
if (new_line != NULL) {
|
||||
@ -869,20 +853,18 @@ static void view_bookmarks_check(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
|
||||
/* Return number of real lines `lines' list takes -
|
||||
stops counting when the height reaches the view height */
|
||||
static int view_get_lines_height(TEXT_BUFFER_VIEW_REC *view,
|
||||
GList *lines, int subline,
|
||||
LINE_REC *line, int subline,
|
||||
LINE_REC *skip_line)
|
||||
{
|
||||
int height, linecount;
|
||||
|
||||
height = -subline;
|
||||
while (lines != NULL && height < view->height) {
|
||||
LINE_REC *line = lines->data;
|
||||
|
||||
while (line != NULL && height < view->height) {
|
||||
if (line != skip_line) {
|
||||
linecount = view_get_linecount(view, line);
|
||||
height += linecount;
|
||||
}
|
||||
lines = lines->next;
|
||||
line = line->next;
|
||||
}
|
||||
|
||||
return height < view->height ? height : view->height;
|
||||
@ -899,22 +881,22 @@ static void view_remove_line(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
|
||||
/* the last line is being removed */
|
||||
LINE_REC *prevline;
|
||||
|
||||
prevline = view->buffer->lines->data == line ? NULL :
|
||||
g_list_last(view->bottom_startline)->data;
|
||||
prevline = view->buffer->first_line == line ? NULL :
|
||||
textbuffer_line_last(view->buffer);
|
||||
view->cache->last_linecount = prevline == NULL ? 0 :
|
||||
view_get_linecount(view, prevline);
|
||||
}
|
||||
|
||||
if (line == view->buffer->lines->data) {
|
||||
if (line == view->buffer->first_line) {
|
||||
/* first line in the buffer - this is the most commonly
|
||||
removed line.. */
|
||||
if (view->bottom_startline->data == line) {
|
||||
if (view->bottom_startline == line) {
|
||||
/* very small scrollback.. */
|
||||
view->bottom_startline = view->bottom_startline->next;
|
||||
view->bottom_subline = 0;
|
||||
}
|
||||
|
||||
if (view->startline->data == line) {
|
||||
if (view->startline == line) {
|
||||
/* removing the first line in screen */
|
||||
realcount = view_scroll(view, &view->startline,
|
||||
&view->subline,
|
||||
@ -922,7 +904,8 @@ static void view_remove_line(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
|
||||
view->ypos -= realcount;
|
||||
view->empty_linecount += linecount-realcount;
|
||||
}
|
||||
} else if (g_list_find(view->bottom_startline, line) != NULL) {
|
||||
} else if (textbuffer_line_exists_after(view->bottom_startline,
|
||||
line)) {
|
||||
realcount = view_scroll(view, &view->bottom_startline,
|
||||
&view->bottom_subline,
|
||||
-linecount, FALSE);
|
||||
@ -933,7 +916,7 @@ static void view_remove_line(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
|
||||
&view->subline, -linecount, TRUE);
|
||||
view->ypos -= linecount-realcount;
|
||||
} else {
|
||||
if (view->startline->data == line) {
|
||||
if (view->startline == line) {
|
||||
view->startline =
|
||||
view->startline->next != NULL ?
|
||||
view->startline->next :
|
||||
@ -1037,7 +1020,7 @@ void textbuffer_view_set_bookmark_bottom(TEXT_BUFFER_VIEW_REC *view,
|
||||
g_return_if_fail(name != NULL);
|
||||
|
||||
if (view->bottom_startline != NULL) {
|
||||
line = g_list_last(view->bottom_startline)->data;
|
||||
line = textbuffer_line_last(view->buffer);
|
||||
textbuffer_view_set_bookmark(view, name, line);
|
||||
}
|
||||
}
|
||||
|
@ -50,11 +50,11 @@ typedef struct {
|
||||
TEXT_BUFFER_CACHE_REC *cache;
|
||||
int ypos; /* cursor position - visible area is 0..height-1 */
|
||||
|
||||
GList *startline; /* line at the top of the screen */
|
||||
LINE_REC *startline; /* line at the top of the screen */
|
||||
int subline; /* number of "real lines" to skip from `startline' */
|
||||
|
||||
/* marks the bottom of the text buffer */
|
||||
GList *bottom_startline;
|
||||
LINE_REC *bottom_startline;
|
||||
int bottom_subline;
|
||||
|
||||
/* how many empty lines are in screen. a screenful when started
|
||||
@ -86,7 +86,7 @@ void textbuffer_view_resize(TEXT_BUFFER_VIEW_REC *view, int width, int height);
|
||||
void textbuffer_view_clear(TEXT_BUFFER_VIEW_REC *view);
|
||||
|
||||
#define textbuffer_view_get_lines(view) \
|
||||
((view)->buffer->lines)
|
||||
((view)->buffer->first_line)
|
||||
|
||||
/* Scroll the view up/down */
|
||||
void textbuffer_view_scroll(TEXT_BUFFER_VIEW_REC *view, int lines);
|
||||
|
@ -187,14 +187,23 @@ static LINE_REC *textbuffer_line_insert(TEXT_BUFFER_REC *buffer,
|
||||
{
|
||||
LINE_REC *line;
|
||||
|
||||
line = textbuffer_line_create(buffer);
|
||||
if (prev == buffer->cur_line) {
|
||||
buffer->cur_line = line;
|
||||
buffer->lines = g_list_append(buffer->lines, buffer->cur_line);
|
||||
line = textbuffer_line_create(buffer);
|
||||
line->prev = prev;
|
||||
if (prev == NULL) {
|
||||
line->next = buffer->first_line;
|
||||
if (buffer->first_line != NULL)
|
||||
buffer->first_line->prev = line;
|
||||
buffer->first_line = line;
|
||||
} else {
|
||||
buffer->lines = g_list_insert(buffer->lines, line,
|
||||
g_list_index(buffer->lines, prev)+1);
|
||||
line->prev = prev;
|
||||
line->next = prev->next;
|
||||
if (line->next != NULL)
|
||||
line->next->prev = line;
|
||||
prev->next = line;
|
||||
}
|
||||
|
||||
if (prev == buffer->cur_line)
|
||||
buffer->cur_line = line;
|
||||
buffer->lines_count++;
|
||||
|
||||
return line;
|
||||
@ -229,6 +238,28 @@ void textbuffer_line_unref_list(TEXT_BUFFER_REC *buffer, GList *list)
|
||||
}
|
||||
}
|
||||
|
||||
LINE_REC *textbuffer_line_last(TEXT_BUFFER_REC *buffer)
|
||||
{
|
||||
LINE_REC *line;
|
||||
|
||||
line = buffer->cur_line;
|
||||
if (line != NULL) {
|
||||
while (line->next != NULL)
|
||||
line = line->next;
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
int textbuffer_line_exists_after(LINE_REC *line, LINE_REC *search)
|
||||
{
|
||||
while (line != NULL) {
|
||||
if (line == search)
|
||||
return TRUE;
|
||||
line = line->next;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LINE_REC *textbuffer_append(TEXT_BUFFER_REC *buffer,
|
||||
const unsigned char *data, int len,
|
||||
LINE_INFO_REC *info)
|
||||
@ -264,11 +295,16 @@ void textbuffer_remove(TEXT_BUFFER_REC *buffer, LINE_REC *line)
|
||||
g_return_if_fail(buffer != NULL);
|
||||
g_return_if_fail(line != NULL);
|
||||
|
||||
buffer->lines = g_list_remove(buffer->lines, line);
|
||||
if (buffer->first_line == line)
|
||||
buffer->first_line = line->next;
|
||||
if (line->prev != NULL)
|
||||
line->prev->next = line->next;
|
||||
if (line->next != NULL)
|
||||
line->next->prev = line->prev;
|
||||
|
||||
if (buffer->cur_line == line) {
|
||||
buffer->cur_line = buffer->lines == NULL ? NULL :
|
||||
g_list_last(buffer->lines)->data;
|
||||
buffer->cur_line = line->next != NULL ?
|
||||
line->next : line->prev;
|
||||
}
|
||||
|
||||
buffer->lines_count--;
|
||||
@ -279,6 +315,7 @@ void textbuffer_remove(TEXT_BUFFER_REC *buffer, LINE_REC *line)
|
||||
void textbuffer_remove_all_lines(TEXT_BUFFER_REC *buffer)
|
||||
{
|
||||
GSList *tmp;
|
||||
LINE_REC *line;
|
||||
|
||||
g_return_if_fail(buffer != NULL);
|
||||
|
||||
@ -287,8 +324,11 @@ void textbuffer_remove_all_lines(TEXT_BUFFER_REC *buffer)
|
||||
g_slist_free(buffer->text_chunks);
|
||||
buffer->text_chunks = NULL;
|
||||
|
||||
g_list_free(buffer->lines);
|
||||
buffer->lines = NULL;
|
||||
while (buffer->first_line != NULL) {
|
||||
line = buffer->first_line->next;
|
||||
g_mem_chunk_free(line_chunk, buffer->first_line);
|
||||
buffer->first_line = line;
|
||||
}
|
||||
|
||||
buffer->cur_line = NULL;
|
||||
buffer->lines_count = 0;
|
||||
@ -365,7 +405,7 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline,
|
||||
#ifdef HAVE_REGEX_H
|
||||
regex_t preg;
|
||||
#endif
|
||||
GList *line, *tmp;
|
||||
LINE_REC *line;
|
||||
GList *matches;
|
||||
GString *str;
|
||||
|
||||
@ -386,25 +426,21 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline,
|
||||
matches = NULL;
|
||||
str = g_string_new(NULL);
|
||||
|
||||
line = g_list_find(buffer->lines, startline);
|
||||
if (line == NULL)
|
||||
line = buffer->lines;
|
||||
line = startline != NULL ? startline : buffer->first_line;
|
||||
|
||||
for (tmp = line; tmp != NULL; tmp = tmp->next) {
|
||||
LINE_REC *rec = tmp->data;
|
||||
|
||||
if ((rec->info.level & level) == 0 ||
|
||||
(rec->info.level & nolevel) != 0)
|
||||
for (; line != NULL; line = line->next) {
|
||||
if ((line->info.level & level) == 0 ||
|
||||
(line->info.level & nolevel) != 0)
|
||||
continue;
|
||||
|
||||
if (*text == '\0') {
|
||||
/* no search word, everything matches */
|
||||
textbuffer_line_ref(rec);
|
||||
matches = g_list_append(matches, rec);
|
||||
textbuffer_line_ref(line);
|
||||
matches = g_list_append(matches, line);
|
||||
continue;
|
||||
}
|
||||
|
||||
textbuffer_line2text(rec, FALSE, str);
|
||||
textbuffer_line2text(line, FALSE, str);
|
||||
|
||||
if (
|
||||
#ifdef HAVE_REGEX_H
|
||||
@ -415,8 +451,8 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline,
|
||||
case_sensitive ? strstr(str->str, text) != NULL :
|
||||
stristr(str->str, text) != NULL) {
|
||||
/* matched */
|
||||
textbuffer_line_ref(rec);
|
||||
matches = g_list_append(matches, rec);
|
||||
textbuffer_line_ref(line);
|
||||
matches = g_list_append(matches, line);
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_REGEX_H
|
||||
|
@ -1,10 +1,6 @@
|
||||
#ifndef __TEXTBUFFER_H
|
||||
#define __TEXTBUFFER_H
|
||||
|
||||
/* FIXME: Textbuffer code gets a lot faster in some points when I get rid of
|
||||
GList and make prev/next pointers directly in LINE_REC. However, this
|
||||
can still wait for a while until I get rid of GList entirely everywhere. */
|
||||
|
||||
#define LINE_TEXT_CHUNK_SIZE 16384
|
||||
|
||||
enum {
|
||||
@ -27,13 +23,15 @@ typedef struct {
|
||||
time_t time;
|
||||
} LINE_INFO_REC;
|
||||
|
||||
typedef struct {
|
||||
typedef struct _LINE_REC {
|
||||
/* text in the line. \0 means that the next char will be a
|
||||
color or command. <= 127 = color or if 8. bit is set, the
|
||||
first 7 bits are the command. See LINE_CMD_xxxx.
|
||||
|
||||
DO NOT ADD BLACK WITH \0\0 - this will break things. Use
|
||||
LINE_CMD_COLOR0 instead. */
|
||||
struct _LINE_REC *prev, *next;
|
||||
|
||||
unsigned char *text;
|
||||
unsigned char refcount;
|
||||
LINE_INFO_REC info;
|
||||
@ -47,7 +45,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
GSList *text_chunks;
|
||||
GList *lines;
|
||||
LINE_REC *first_line;
|
||||
int lines_count;
|
||||
|
||||
LINE_REC *cur_line;
|
||||
@ -65,6 +63,9 @@ void textbuffer_line_ref(LINE_REC *line);
|
||||
void textbuffer_line_unref(TEXT_BUFFER_REC *buffer, LINE_REC *line);
|
||||
void textbuffer_line_unref_list(TEXT_BUFFER_REC *buffer, GList *list);
|
||||
|
||||
LINE_REC *textbuffer_line_last(TEXT_BUFFER_REC *buffer);
|
||||
int textbuffer_line_exists_after(LINE_REC *line, LINE_REC *search);
|
||||
|
||||
/* Append text to buffer. When \0<EOL> is found at the END OF DATA, a new
|
||||
line is created. You must send the EOL command before you can do anything
|
||||
else with the buffer. */
|
||||
|
Loading…
Reference in New Issue
Block a user