Mercurial > ~mikael > mcabber > hg
comparison mcabber/src/hbuf.c @ 1141:5be2408a6534
Add option "max_history_blocks"
author | Mikael Berthe <mikael@lilotux.net> |
---|---|
date | Tue, 06 Feb 2007 00:21:42 +0100 |
parents | b5bcc223cf51 |
children | e802ec0c02d2 |
comparison
equal
deleted
inserted
replaced
1140:800bb1e9019c | 1141:5be2408a6534 |
---|---|
105 } | 105 } |
106 curr_elt = g_list_next(curr_elt); | 106 curr_elt = g_list_next(curr_elt); |
107 } | 107 } |
108 } | 108 } |
109 | 109 |
110 // hbuf_add_line(p_hbuf, text, prefix_flags, width) | 110 // hbuf_add_line(p_hbuf, text, prefix_flags, width, maxhbufblocks) |
111 // Add a line to the given buffer. If width is not null, then lines are | 111 // Add a line to the given buffer. If width is not null, then lines are |
112 // wrapped at this length. | 112 // wrapped at this length. |
113 // maxhbufblocks is the maximum number of hbuf blocks we can allocate. If | |
114 // null, there is no limit. If non-null, it should be >= 2. | |
113 // | 115 // |
114 // Note 1: Splitting according to width won't work if there are tabs; they | 116 // Note 1: Splitting according to width won't work if there are tabs; they |
115 // should be expanded before. | 117 // should be expanded before. |
116 // Note 2: width does not include the ending \0. | 118 // Note 2: width does not include the ending \0. |
117 void hbuf_add_line(GList **p_hbuf, const char *text, time_t timestamp, | 119 void hbuf_add_line(GList **p_hbuf, const char *text, time_t timestamp, |
118 guint prefix_flags, guint width) | 120 guint prefix_flags, guint width, guint maxhbufblocks) |
119 { | 121 { |
120 GList *curr_elt; | 122 GList *curr_elt; |
121 char *line, *end; | 123 char *line; |
122 hbuf_block *hbuf_block_elt; | 124 hbuf_block *hbuf_block_elt; |
123 | 125 |
124 if (!text) return; | 126 if (!text) return; |
125 | 127 |
126 hbuf_block_elt = g_new0(hbuf_block, 1); | 128 hbuf_block_elt = g_new0(hbuf_block, 1); |
147 text = "[ERR:LINE_TOO_LONG]"; | 149 text = "[ERR:LINE_TOO_LONG]"; |
148 hbuf_block_elt->prefix.flags |= HBB_PREFIX_INFO; | 150 hbuf_block_elt->prefix.flags |= HBB_PREFIX_INFO; |
149 } | 151 } |
150 if (hbuf_block_elt->ptr + strlen(text) >= hbuf_block_elt->ptr_end_alloc) { | 152 if (hbuf_block_elt->ptr + strlen(text) >= hbuf_block_elt->ptr_end_alloc) { |
151 // Too long for the current allocated bloc, we need another one | 153 // Too long for the current allocated bloc, we need another one |
152 hbuf_block_elt->ptr = g_new0(char, HBB_BLOCKSIZE); | 154 if (!maxhbufblocks) { |
155 // No limit, let's allocate a new block | |
156 hbuf_block_elt->ptr = g_new0(char, HBB_BLOCKSIZE); | |
157 } else { | |
158 GList *hbuf_head, *hbuf_elt; | |
159 hbuf_block *hbuf_b_elt; | |
160 guint n = 0; | |
161 hbuf_head = g_list_first(*p_hbuf); | |
162 // We need at least 2 allocated blocks | |
163 if (maxhbufblocks == 1) | |
164 maxhbufblocks = 2; | |
165 // Let's count the number of allocated areas | |
166 for (hbuf_elt = hbuf_head; hbuf_elt; hbuf_elt = g_list_next(hbuf_elt)) { | |
167 hbuf_b_elt = (hbuf_block*)(hbuf_elt->data); | |
168 if (hbuf_b_elt->flags & HBB_FLAG_ALLOC) | |
169 n++; | |
170 } | |
171 // If we can't allocate a new area, reuse the previous block(s) | |
172 if (n < maxhbufblocks) { | |
173 hbuf_block_elt->ptr = g_new0(char, HBB_BLOCKSIZE); | |
174 } else { | |
175 // Let's use an old block, and free the extra blocks if needed | |
176 char *allocated_block = NULL; | |
177 while (n >= maxhbufblocks) { | |
178 /* --- */ | |
179 int start_of_block = 1; | |
180 for (hbuf_elt = hbuf_head; hbuf_elt; hbuf_elt = hbuf_head) { | |
181 hbuf_b_elt = (hbuf_block*)(hbuf_elt->data); | |
182 if (hbuf_b_elt->flags & HBB_FLAG_ALLOC) { | |
183 if (start_of_block-- == 0) | |
184 break; | |
185 if (n == maxhbufblocks) | |
186 allocated_block = hbuf_b_elt->ptr; | |
187 else | |
188 g_free(hbuf_b_elt->ptr); | |
189 } | |
190 g_free(hbuf_b_elt); | |
191 hbuf_head = *p_hbuf = g_list_delete_link(hbuf_head, hbuf_elt); | |
192 } | |
193 n--; | |
194 /* --- */ | |
195 } | |
196 memset(allocated_block, 0, HBB_BLOCKSIZE); | |
197 hbuf_block_elt->ptr = allocated_block; | |
198 } | |
199 } | |
153 hbuf_block_elt->flags = HBB_FLAG_ALLOC | HBB_FLAG_PERSISTENT; | 200 hbuf_block_elt->flags = HBB_FLAG_ALLOC | HBB_FLAG_PERSISTENT; |
154 hbuf_block_elt->ptr_end_alloc = hbuf_block_elt->ptr + HBB_BLOCKSIZE; | 201 hbuf_block_elt->ptr_end_alloc = hbuf_block_elt->ptr + HBB_BLOCKSIZE; |
155 } | 202 } |
156 | 203 |
157 line = hbuf_block_elt->ptr; | 204 line = hbuf_block_elt->ptr; |
158 // Ok, now we can copy the text.. | 205 // Ok, now we can copy the text.. |
159 strcpy(line, text); | 206 strcpy(line, text); |
160 hbuf_block_elt->ptr_end = line + strlen(line) + 1; | 207 hbuf_block_elt->ptr_end = line + strlen(line) + 1; |
161 end = hbuf_block_elt->ptr_end; | |
162 | 208 |
163 curr_elt = g_list_last(*p_hbuf); | 209 curr_elt = g_list_last(*p_hbuf); |
164 | 210 |
165 // Wrap lines and handle CRs ('\n') | 211 // Wrap lines and handle CRs ('\n') |
166 do_wrap(p_hbuf, curr_elt, width); | 212 do_wrap(p_hbuf, curr_elt, width); |