annotate mcabber/src/hbuf.c @ 403:17aa60c6dc63

Allow a different server name than the jid domain name Sync libjabber with upstream (centericq). The libjabber patch is from Ian Johannesen. This allows connecting to Google Talk, for example.
author Mikael Berthe <mikael@lilotux.net>
date Sat, 27 Aug 2005 11:21:27 +0200
parents f8f3c7493457
children d580e87c11ed
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
1 /*
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
2 * hbuf.c -- History buffer implementation
393
f8f3c7493457 Whitespace cleanup
Mikael Berthe <mikael@lilotux.net>
parents: 392
diff changeset
3 *
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
4 * Copyright (C) 2005 Mikael Berthe <bmikael@lists.lilotux.net>
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
5 *
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
6 * This program is free software; you can redistribute it and/or modify
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
7 * it under the terms of the GNU General Public License as published by
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
8 * the Free Software Foundation; either version 2 of the License, or (at
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
9 * your option) any later version.
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
10 *
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
11 * This program is distributed in the hope that it will be useful, but
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
14 * General Public License for more details.
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
15 *
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
16 * You should have received a copy of the GNU General Public License
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
17 * along with this program; if not, write to the Free Software
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
19 * USA
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
20 */
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
21
370
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
22 #define _GNU_SOURCE /* We need glibc for strptime */
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
23 #include <string.h>
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
24
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
25 #include "hbuf.h"
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
26
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
27
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
28 /* This is a private structure type */
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
29
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
30 typedef struct {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
31 char *ptr;
182
f7b03201877a [/trunk] Changeset 194 by mikael
mikael
parents: 153
diff changeset
32 char *ptr_end; // beginning of the block
f7b03201877a [/trunk] Changeset 194 by mikael
mikael
parents: 153
diff changeset
33 char *ptr_end_alloc; // end of the current persistent block
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
34 guchar flags;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
35
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
36 // XXX This should certainly be a pointer, and be allocated only when needed
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
37 // (for ex. when HBB_FLAG_PERSISTENT is set).
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
38 struct { // hbuf_line_info
184
b5aa2b9c425a [/trunk] Changeset 196 by mikael
mikael
parents: 182
diff changeset
39 time_t timestamp;
b5aa2b9c425a [/trunk] Changeset 196 by mikael
mikael
parents: 182
diff changeset
40 guchar flags;
b5aa2b9c425a [/trunk] Changeset 196 by mikael
mikael
parents: 182
diff changeset
41 } prefix;
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
42 } hbuf_block;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
43
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
44
184
b5aa2b9c425a [/trunk] Changeset 196 by mikael
mikael
parents: 182
diff changeset
45 // hbuf_add_line(p_hbuf, text, prefix_flags, width)
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
46 // Add a line to the given buffer. If width is not null, then lines are
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
47 // wrapped at this length.
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
48 //
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
49 // Note 1: Splitting according to width won't work if there are tabs; they
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
50 // should be expanded before.
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
51 // Note 2: width does not include the ending \0.
184
b5aa2b9c425a [/trunk] Changeset 196 by mikael
mikael
parents: 182
diff changeset
52 void hbuf_add_line(GList **p_hbuf, const char *text, time_t timestamp,
b5aa2b9c425a [/trunk] Changeset 196 by mikael
mikael
parents: 182
diff changeset
53 guint prefix_flags, guint width)
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
54 {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
55 GList *hbuf = *p_hbuf;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
56 char *line, *cr, *end;
83
a95e2fc9ea6b [/trunk] Changeset 97 by mikael
mikael
parents: 75
diff changeset
57 hbuf_block *hbuf_block_elt;
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
58
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
59 if (!text) return;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
60
83
a95e2fc9ea6b [/trunk] Changeset 97 by mikael
mikael
parents: 75
diff changeset
61 hbuf_block_elt = g_new0(hbuf_block, 1);
184
b5aa2b9c425a [/trunk] Changeset 196 by mikael
mikael
parents: 182
diff changeset
62 hbuf_block_elt->prefix.timestamp = timestamp;
b5aa2b9c425a [/trunk] Changeset 196 by mikael
mikael
parents: 182
diff changeset
63 hbuf_block_elt->prefix.flags = prefix_flags;
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
64 if (!hbuf) {
390
468c9cac2798 Minor changes to hbuf.c
Mikael Berthe <mikael@lilotux.net>
parents: 370
diff changeset
65 hbuf_block_elt->ptr = g_new(char, HBB_BLOCKSIZE);
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
66 hbuf_block_elt->flags = HBB_FLAG_ALLOC | HBB_FLAG_PERSISTENT;
182
f7b03201877a [/trunk] Changeset 194 by mikael
mikael
parents: 153
diff changeset
67 hbuf_block_elt->ptr_end_alloc = hbuf_block_elt->ptr + HBB_BLOCKSIZE;
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
68 *p_hbuf = g_list_append(*p_hbuf, hbuf_block_elt);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
69 } else {
392
6329c9601704 Speed up hbuf_add_line()
Mikael Berthe <mikael@lilotux.net>
parents: 390
diff changeset
70 // Set p_hbuf to the end of the list, to speed up history loading
6329c9601704 Speed up hbuf_add_line()
Mikael Berthe <mikael@lilotux.net>
parents: 390
diff changeset
71 // (or CPU time will be used by g_list_last() for each line)
6329c9601704 Speed up hbuf_add_line()
Mikael Berthe <mikael@lilotux.net>
parents: 390
diff changeset
72 hbuf = *p_hbuf = g_list_last(*p_hbuf);
6329c9601704 Speed up hbuf_add_line()
Mikael Berthe <mikael@lilotux.net>
parents: 390
diff changeset
73 hbuf_block *hbuf_b_prev = hbuf->data;
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
74 hbuf_block_elt->ptr = hbuf_b_prev->ptr_end;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
75 hbuf_block_elt->flags = HBB_FLAG_PERSISTENT;
182
f7b03201877a [/trunk] Changeset 194 by mikael
mikael
parents: 153
diff changeset
76 hbuf_block_elt->ptr_end_alloc = hbuf_b_prev->ptr_end_alloc;
392
6329c9601704 Speed up hbuf_add_line()
Mikael Berthe <mikael@lilotux.net>
parents: 390
diff changeset
77 g_list_append(*p_hbuf, hbuf_block_elt);
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
78 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
79
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
80 if (strlen(text) >= HBB_BLOCKSIZE) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
81 // Too long
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
82 text = "[ERR:LINE_TOO_LONG]";
197
c289e3c39c48 [/trunk] Changeset 209 by mikael
mikael
parents: 189
diff changeset
83 hbuf_block_elt->prefix.flags |= HBB_PREFIX_INFO;
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
84 }
182
f7b03201877a [/trunk] Changeset 194 by mikael
mikael
parents: 153
diff changeset
85 if (hbuf_block_elt->ptr + strlen(text) >= hbuf_block_elt->ptr_end_alloc) {
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
86 // Too long for the current allocated bloc, we need another one
390
468c9cac2798 Minor changes to hbuf.c
Mikael Berthe <mikael@lilotux.net>
parents: 370
diff changeset
87 hbuf_block_elt->ptr = g_new0(char, HBB_BLOCKSIZE);
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
88 hbuf_block_elt->flags = HBB_FLAG_ALLOC | HBB_FLAG_PERSISTENT;
182
f7b03201877a [/trunk] Changeset 194 by mikael
mikael
parents: 153
diff changeset
89 hbuf_block_elt->ptr_end_alloc = hbuf_block_elt->ptr + HBB_BLOCKSIZE;
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
90 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
91
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
92 line = hbuf_block_elt->ptr;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
93 // Ok, now we can copy the text..
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
94 strcpy(line, text);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
95 hbuf_block_elt->ptr_end = line + strlen(line) + 1;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
96 end = hbuf_block_elt->ptr_end;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
97
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
98 // Let's add non-persistent blocs if necessary
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
99 // - If there are '\n' in the string
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
100 // - If length > width (and width != 0)
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
101 cr = strchr(line, '\n');
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
102 while (cr || (width && strlen(line) > width)) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
103 hbuf_block *hbuf_b_prev = hbuf_block_elt;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
104
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
105 if (!width || (cr && (cr - line <= (int)width))) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
106 // Carriage return
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
107 *cr = 0;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
108 hbuf_block_elt->ptr_end = cr;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
109 // Create another persistent block
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
110 hbuf_block_elt = g_new0(hbuf_block, 1);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
111 hbuf_block_elt->ptr = hbuf_b_prev->ptr_end + 1; // == cr+1
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
112 hbuf_block_elt->ptr_end = end;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
113 hbuf_block_elt->flags = HBB_FLAG_PERSISTENT;
182
f7b03201877a [/trunk] Changeset 194 by mikael
mikael
parents: 153
diff changeset
114 hbuf_block_elt->ptr_end_alloc = hbuf_b_prev->ptr_end_alloc;
392
6329c9601704 Speed up hbuf_add_line()
Mikael Berthe <mikael@lilotux.net>
parents: 390
diff changeset
115 g_list_append(*p_hbuf, hbuf_block_elt);
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
116 line = hbuf_block_elt->ptr;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
117 } else {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
118 // We need to break where we can find a space char
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
119 char *br; // break pointer
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
120 for (br = line + width; br > line && *br != 32 && *br != 9; br--)
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
121 ;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
122 if (br <= line)
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
123 br = line + width;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
124 else
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
125 br++;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
126 hbuf_block_elt->ptr_end = br;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
127 // Create another block, non-persistent
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
128 hbuf_block_elt = g_new0(hbuf_block, 1);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
129 hbuf_block_elt->ptr = hbuf_b_prev->ptr_end; // == br
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
130 hbuf_block_elt->ptr_end = end;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
131 hbuf_block_elt->flags = 0;
182
f7b03201877a [/trunk] Changeset 194 by mikael
mikael
parents: 153
diff changeset
132 hbuf_block_elt->ptr_end_alloc = hbuf_b_prev->ptr_end_alloc;
392
6329c9601704 Speed up hbuf_add_line()
Mikael Berthe <mikael@lilotux.net>
parents: 390
diff changeset
133 g_list_append(*p_hbuf, hbuf_block_elt);
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
134 line = hbuf_block_elt->ptr;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
135 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
136 cr = strchr(line, '\n');
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
137 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
138 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
139
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
140 // hbuf_free()
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
141 // Destroys all hbuf list.
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
142 void hbuf_free(GList **p_hbuf)
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
143 {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
144 hbuf_block *hbuf_b_elt;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
145 GList *hbuf_elt;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
146 GList *first_elt = g_list_first(*p_hbuf);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
147
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
148 for (hbuf_elt = first_elt; hbuf_elt; hbuf_elt = g_list_next(hbuf_elt)) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
149 hbuf_b_elt = (hbuf_block*)(hbuf_elt->data);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
150 if (hbuf_b_elt->flags & HBB_FLAG_ALLOC) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
151 g_free(hbuf_b_elt->ptr);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
152 }
390
468c9cac2798 Minor changes to hbuf.c
Mikael Berthe <mikael@lilotux.net>
parents: 370
diff changeset
153 g_free(hbuf_b_elt);
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
154 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
155
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
156 g_list_free(*p_hbuf);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
157 *p_hbuf = NULL;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
158 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
159
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
160 // hbuf_rebuild()
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
161 // Rebuild all hbuf list, with the new width.
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
162 // If width == 0, lines are not wrapped.
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
163 void hbuf_rebuild(GList **p_hbuf, unsigned int width)
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
164 {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
165 GList *first_elt, *curr_elt, *next_elt;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
166 hbuf_block *hbuf_b_curr, *hbuf_b_next;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
167
150
5647381a7dfb [/trunk] Changeset 162 by mikael
mikael
parents: 83
diff changeset
168 // *p_hbuf needs to be the head of the list
5647381a7dfb [/trunk] Changeset 162 by mikael
mikael
parents: 83
diff changeset
169 first_elt = *p_hbuf = g_list_first(*p_hbuf);
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
170
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
171 // #1 Remove non-persistent blocks (ptr_end should be updated!)
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
172 curr_elt = first_elt;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
173 while (curr_elt) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
174 next_elt = g_list_next(curr_elt);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
175 // Last element?
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
176 if (!next_elt)
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
177 break;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
178 hbuf_b_curr = (hbuf_block*)(curr_elt->data);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
179 hbuf_b_next = (hbuf_block*)(next_elt->data);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
180 // Is next line not-persistent?
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
181 if (!(hbuf_b_next->flags & HBB_FLAG_PERSISTENT)) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
182 hbuf_b_curr->ptr_end = hbuf_b_next->ptr_end;
390
468c9cac2798 Minor changes to hbuf.c
Mikael Berthe <mikael@lilotux.net>
parents: 370
diff changeset
183 g_free(hbuf_b_next);
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
184 g_list_delete_link(curr_elt, next_elt);
393
f8f3c7493457 Whitespace cleanup
Mikael Berthe <mikael@lilotux.net>
parents: 392
diff changeset
185 } else
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
186 curr_elt = next_elt;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
187 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
188 // #2 Go back to head and create non-persistent blocks when needed
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
189 if (width) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
190 char *line, *end;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
191 curr_elt = first_elt;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
192
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
193 while (curr_elt) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
194 hbuf_b_curr = (hbuf_block*)(curr_elt->data);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
195 line = hbuf_b_curr->ptr;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
196 if (strlen(line) > width) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
197 hbuf_block *hbuf_b_prev = hbuf_b_curr;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
198
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
199 // We need to break where we can find a space char
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
200 char *br; // break pointer
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
201 for (br = line + width; br > line && *br != 32 && *br != 9; br--)
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
202 ;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
203 if (br <= line)
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
204 br = line + width;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
205 else
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
206 br++;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
207 end = hbuf_b_curr->ptr_end;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
208 hbuf_b_curr->ptr_end = br;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
209 // Create another block, non-persistent
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
210 hbuf_b_curr = g_new0(hbuf_block, 1);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
211 hbuf_b_curr->ptr = hbuf_b_prev->ptr_end; // == br
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
212 hbuf_b_curr->ptr_end = end;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
213 hbuf_b_curr->flags = 0;
182
f7b03201877a [/trunk] Changeset 194 by mikael
mikael
parents: 153
diff changeset
214 hbuf_b_curr->ptr_end_alloc = hbuf_b_prev->ptr_end_alloc;
150
5647381a7dfb [/trunk] Changeset 162 by mikael
mikael
parents: 83
diff changeset
215 // This is OK because insert_before(NULL) == append():
5647381a7dfb [/trunk] Changeset 162 by mikael
mikael
parents: 83
diff changeset
216 *p_hbuf = g_list_insert_before(*p_hbuf, curr_elt->next, hbuf_b_curr);
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
217 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
218 curr_elt = g_list_next(curr_elt);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
219 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
220 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
221 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
222
189
4f3975f1b852 [/trunk] Changeset 201 by mikael
mikael
parents: 184
diff changeset
223 // hbuf_previous_persistent()
4f3975f1b852 [/trunk] Changeset 201 by mikael
mikael
parents: 184
diff changeset
224 // Returns the previous persistent block (line). If the given line is
4f3975f1b852 [/trunk] Changeset 201 by mikael
mikael
parents: 184
diff changeset
225 // persistent, then it is returned.
4f3975f1b852 [/trunk] Changeset 201 by mikael
mikael
parents: 184
diff changeset
226 // This function is used for example when resizing a buffer. If the top of the
4f3975f1b852 [/trunk] Changeset 201 by mikael
mikael
parents: 184
diff changeset
227 // screen is on a non-persistent block, then a screen resize could destroy this
4f3975f1b852 [/trunk] Changeset 201 by mikael
mikael
parents: 184
diff changeset
228 // line...
4f3975f1b852 [/trunk] Changeset 201 by mikael
mikael
parents: 184
diff changeset
229 GList *hbuf_previous_persistent(GList *l_line)
4f3975f1b852 [/trunk] Changeset 201 by mikael
mikael
parents: 184
diff changeset
230 {
4f3975f1b852 [/trunk] Changeset 201 by mikael
mikael
parents: 184
diff changeset
231 hbuf_block *hbuf_b_elt;
4f3975f1b852 [/trunk] Changeset 201 by mikael
mikael
parents: 184
diff changeset
232
4f3975f1b852 [/trunk] Changeset 201 by mikael
mikael
parents: 184
diff changeset
233 while (l_line) {
4f3975f1b852 [/trunk] Changeset 201 by mikael
mikael
parents: 184
diff changeset
234 hbuf_b_elt = (hbuf_block*)l_line->data;
4f3975f1b852 [/trunk] Changeset 201 by mikael
mikael
parents: 184
diff changeset
235 if (hbuf_b_elt->flags & HBB_FLAG_PERSISTENT)
4f3975f1b852 [/trunk] Changeset 201 by mikael
mikael
parents: 184
diff changeset
236 return l_line;
4f3975f1b852 [/trunk] Changeset 201 by mikael
mikael
parents: 184
diff changeset
237 l_line = g_list_previous(l_line);
4f3975f1b852 [/trunk] Changeset 201 by mikael
mikael
parents: 184
diff changeset
238 }
4f3975f1b852 [/trunk] Changeset 201 by mikael
mikael
parents: 184
diff changeset
239
4f3975f1b852 [/trunk] Changeset 201 by mikael
mikael
parents: 184
diff changeset
240 return NULL;
4f3975f1b852 [/trunk] Changeset 201 by mikael
mikael
parents: 184
diff changeset
241 }
4f3975f1b852 [/trunk] Changeset 201 by mikael
mikael
parents: 184
diff changeset
242
368
da50f08ea058 Update hbuf_get_lines() comment
Mikael Berthe <mikael@lilotux.net>
parents: 197
diff changeset
243 // hbuf_get_lines(hbuf, n)
370
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
244 // Returns an array of n hbb_line pointers
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
245 // (The first line will be the line currently pointed by hbuf)
368
da50f08ea058 Update hbuf_get_lines() comment
Mikael Berthe <mikael@lilotux.net>
parents: 197
diff changeset
246 // Note: The caller should free the array and the text pointers after use.
184
b5aa2b9c425a [/trunk] Changeset 196 by mikael
mikael
parents: 182
diff changeset
247 hbb_line **hbuf_get_lines(GList *hbuf, unsigned int n)
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
248 {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
249 unsigned int i;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
250
184
b5aa2b9c425a [/trunk] Changeset 196 by mikael
mikael
parents: 182
diff changeset
251 hbb_line **array = g_new0(hbb_line*, n);
b5aa2b9c425a [/trunk] Changeset 196 by mikael
mikael
parents: 182
diff changeset
252 hbb_line **array_elt = array;
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
253
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
254 for (i=0 ; i < n ; i++) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
255 if (hbuf) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
256 hbuf_block *blk = (hbuf_block*)(hbuf->data);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
257 int maxlen;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
258 maxlen = blk->ptr_end - blk->ptr;
184
b5aa2b9c425a [/trunk] Changeset 196 by mikael
mikael
parents: 182
diff changeset
259 *array_elt = (hbb_line*)g_new(hbb_line, 1);
b5aa2b9c425a [/trunk] Changeset 196 by mikael
mikael
parents: 182
diff changeset
260 (*array_elt)->timestamp = blk->prefix.timestamp;
b5aa2b9c425a [/trunk] Changeset 196 by mikael
mikael
parents: 182
diff changeset
261 (*array_elt)->flags = blk->prefix.flags;
b5aa2b9c425a [/trunk] Changeset 196 by mikael
mikael
parents: 182
diff changeset
262 (*array_elt)->text = g_strndup(blk->ptr, maxlen);
b5aa2b9c425a [/trunk] Changeset 196 by mikael
mikael
parents: 182
diff changeset
263
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
264 hbuf = g_list_next(hbuf);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
265 } else
184
b5aa2b9c425a [/trunk] Changeset 196 by mikael
mikael
parents: 182
diff changeset
266 break;
b5aa2b9c425a [/trunk] Changeset 196 by mikael
mikael
parents: 182
diff changeset
267
b5aa2b9c425a [/trunk] Changeset 196 by mikael
mikael
parents: 182
diff changeset
268 array_elt++;
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
269 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
270
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
271 return array;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
272 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
273
370
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
274 // hbuf_search(hbuf, direction, string)
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
275 // Look backward/forward for a line containing string in the history buffer
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
276 // Search starts at hbuf, and goes forward if direction == 1, backward if -1
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
277 GList *hbuf_search(GList *hbuf, int direction, const char *string)
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
278 {
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
279 hbuf_block *blk;
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
280
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
281 for (;;) {
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
282 if (direction > 0)
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
283 hbuf = g_list_next(hbuf);
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
284 else
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
285 hbuf = g_list_previous(hbuf);
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
286
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
287 if (!hbuf) break;
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
288
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
289 blk = (hbuf_block*)(hbuf->data);
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
290 // XXX blk->ptr is (maybe) not really correct, because the match should
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
291 // not be after ptr_end. We should check that...
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
292 if (strcasestr(blk->ptr, string))
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
293 break;
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
294 }
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
295
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
296 return hbuf;
dd9e2eb52916 Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents: 368
diff changeset
297 }