annotate mcabber/src/hbuf.c @ 83:a95e2fc9ea6b

[/trunk] Changeset 97 by mikael * Fix non-ISO C89 compliant declaration
author mikael
date Sun, 17 Apr 2005 18:16:19 +0000
parents ff119bb11563
children 5647381a7dfb
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
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
3 *
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
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
22 #include <string.h>
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
23
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
24 #include "hbuf.h"
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
25
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
26
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
27 /* This is a private structure type */
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
28
75
ff119bb11563 [/trunk] Changeset 89 by mikael
mikael
parents: 71
diff changeset
29 #define PREFIX_LENGTH 32
71
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;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
32 char *ptr_end;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
33 guchar flags;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
34
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
35 // XXX This should certainly be a pointer, and be allocated only when needed
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
36 // (for ex. when HBB_FLAG_PERSISTENT is set).
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
37 struct { // hbuf_line_info
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
38 char *ptr_end_alloc;
75
ff119bb11563 [/trunk] Changeset 89 by mikael
mikael
parents: 71
diff changeset
39 char prefix[PREFIX_LENGTH];
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
40 } persist;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
41 } hbuf_block;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
42
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
43
75
ff119bb11563 [/trunk] Changeset 89 by mikael
mikael
parents: 71
diff changeset
44 // hbuf_add_line(p_hbuf, text, prefix, width)
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
45 // 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
46 // wrapped at this length.
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
47 //
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
48 // Note 1: Splitting according to width won't work if there are tabs; they
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
49 // should be expanded before.
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
50 // Note 2: width does not include the ending \0.
75
ff119bb11563 [/trunk] Changeset 89 by mikael
mikael
parents: 71
diff changeset
51 void hbuf_add_line(GList **p_hbuf, const char *text, const char *prefix,
ff119bb11563 [/trunk] Changeset 89 by mikael
mikael
parents: 71
diff changeset
52 unsigned int width)
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
53 {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
54 GList *hbuf = *p_hbuf;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
55 char *line, *cr, *end;
83
a95e2fc9ea6b [/trunk] Changeset 97 by mikael
mikael
parents: 75
diff changeset
56 hbuf_block *hbuf_block_elt;
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
57
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
58 if (!text) return;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
59
83
a95e2fc9ea6b [/trunk] Changeset 97 by mikael
mikael
parents: 75
diff changeset
60 hbuf_block_elt = g_new0(hbuf_block, 1);
75
ff119bb11563 [/trunk] Changeset 89 by mikael
mikael
parents: 71
diff changeset
61 if (prefix)
ff119bb11563 [/trunk] Changeset 89 by mikael
mikael
parents: 71
diff changeset
62 strncpy(hbuf_block_elt->persist.prefix, prefix, PREFIX_LENGTH-1);
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
63 if (!hbuf) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
64 hbuf_block_elt->ptr = g_new(char, HBB_BLOCKSIZE);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
65 hbuf_block_elt->flags = HBB_FLAG_ALLOC | HBB_FLAG_PERSISTENT;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
66 hbuf_block_elt->persist.ptr_end_alloc = hbuf_block_elt->ptr + HBB_BLOCKSIZE;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
67 *p_hbuf = g_list_append(*p_hbuf, hbuf_block_elt);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
68 } else {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
69 hbuf_block *hbuf_b_prev = g_list_last(hbuf)->data;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
70 hbuf_block_elt->ptr = hbuf_b_prev->ptr_end;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
71 hbuf_block_elt->flags = HBB_FLAG_PERSISTENT;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
72 hbuf_block_elt->persist.ptr_end_alloc = hbuf_b_prev->persist.ptr_end_alloc;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
73 *p_hbuf = g_list_append(*p_hbuf, hbuf_block_elt);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
74 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
75
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
76 if (strlen(text) >= HBB_BLOCKSIZE) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
77 // Too long
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
78 text = "[ERR:LINE_TOO_LONG]";
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
79 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
80 if (hbuf_block_elt->ptr + strlen(text) >= hbuf_block_elt->persist.ptr_end_alloc) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
81 // Too long for the current allocated bloc, we need another one
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
82 hbuf_block_elt->ptr = g_new0(char, HBB_BLOCKSIZE);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
83 hbuf_block_elt->flags = HBB_FLAG_ALLOC | HBB_FLAG_PERSISTENT;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
84 hbuf_block_elt->persist.ptr_end_alloc = hbuf_block_elt->ptr + HBB_BLOCKSIZE;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
85 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
86
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
87 line = hbuf_block_elt->ptr;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
88 // Ok, now we can copy the text..
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
89 strcpy(line, text);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
90 hbuf_block_elt->ptr_end = line + strlen(line) + 1;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
91 end = hbuf_block_elt->ptr_end;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
92
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
93 // Let's add non-persistent blocs if necessary
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
94 // - If there are '\n' in the string
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
95 // - If length > width (and width != 0)
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
96 cr = strchr(line, '\n');
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
97 while (cr || (width && strlen(line) > width)) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
98 hbuf_block *hbuf_b_prev = hbuf_block_elt;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
99
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
100 if (!width || (cr && (cr - line <= (int)width))) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
101 // Carriage return
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
102 *cr = 0;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
103 hbuf_block_elt->ptr_end = cr;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
104 // Create another persistent block
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
105 hbuf_block_elt = g_new0(hbuf_block, 1);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
106 hbuf_block_elt->ptr = hbuf_b_prev->ptr_end + 1; // == cr+1
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
107 hbuf_block_elt->ptr_end = end;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
108 hbuf_block_elt->flags = HBB_FLAG_PERSISTENT;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
109 hbuf_block_elt->persist.ptr_end_alloc = hbuf_b_prev->persist.ptr_end_alloc;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
110 *p_hbuf = g_list_append(*p_hbuf, hbuf_block_elt);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
111 line = hbuf_block_elt->ptr;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
112 } else {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
113 // We need to break where we can find a space char
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
114 char *br; // break pointer
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
115 for (br = line + width; br > line && *br != 32 && *br != 9; br--)
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
116 ;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
117 if (br <= line)
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
118 br = line + width;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
119 else
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
120 br++;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
121 hbuf_block_elt->ptr_end = br;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
122 // Create another block, non-persistent
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
123 hbuf_block_elt = g_new0(hbuf_block, 1);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
124 hbuf_block_elt->ptr = hbuf_b_prev->ptr_end; // == br
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
125 hbuf_block_elt->ptr_end = end;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
126 hbuf_block_elt->flags = 0;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
127 hbuf_block_elt->persist.ptr_end_alloc = hbuf_b_prev->persist.ptr_end_alloc;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
128 *p_hbuf = g_list_append(*p_hbuf, hbuf_block_elt);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
129 line = hbuf_block_elt->ptr;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
130 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
131 cr = strchr(line, '\n');
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
132 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
133 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
134
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
135 // hbuf_free()
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
136 // Destroys all hbuf list.
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
137 void hbuf_free(GList **p_hbuf)
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
138 {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
139 hbuf_block *hbuf_b_elt;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
140 GList *hbuf_elt;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
141 GList *first_elt = g_list_first(*p_hbuf);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
142
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
143 for (hbuf_elt = first_elt; hbuf_elt; hbuf_elt = g_list_next(hbuf_elt)) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
144 hbuf_b_elt = (hbuf_block*)(hbuf_elt->data);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
145 if (hbuf_b_elt->flags & HBB_FLAG_ALLOC) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
146 g_free(hbuf_b_elt->ptr);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
147 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
148 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
149
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
150 g_list_free(*p_hbuf);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
151 *p_hbuf = NULL;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
152 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
153
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
154 // hbuf_rebuild()
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
155 // Rebuild all hbuf list, with the new width.
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
156 // If width == 0, lines are not wrapped.
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
157 void hbuf_rebuild(GList **p_hbuf, unsigned int width)
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
158 {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
159 GList *first_elt, *curr_elt, *next_elt;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
160 hbuf_block *hbuf_b_curr, *hbuf_b_next;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
161
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
162 first_elt = g_list_first(*p_hbuf);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
163
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
164 // #1 Remove non-persistent blocks (ptr_end should be updated!)
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
165 curr_elt = first_elt;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
166 while (curr_elt) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
167 next_elt = g_list_next(curr_elt);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
168 // Last element?
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
169 if (!next_elt)
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
170 break;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
171 hbuf_b_curr = (hbuf_block*)(curr_elt->data);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
172 hbuf_b_next = (hbuf_block*)(next_elt->data);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
173 // Is next line not-persistent?
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
174 if (!(hbuf_b_next->flags & HBB_FLAG_PERSISTENT)) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
175 hbuf_b_curr->ptr_end = hbuf_b_next->ptr_end;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
176 g_list_delete_link(curr_elt, next_elt);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
177 next_elt = g_list_next(curr_elt);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
178 } else
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
179 curr_elt = next_elt;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
180 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
181 // #2 Go back to head and create non-persistent blocks when needed
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
182 if (width) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
183 char *line, *end;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
184 curr_elt = first_elt;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
185
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
186 while (curr_elt) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
187 hbuf_b_curr = (hbuf_block*)(curr_elt->data);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
188 line = hbuf_b_curr->ptr;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
189 if (strlen(line) > width) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
190 hbuf_block *hbuf_b_prev = hbuf_b_curr;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
191
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
192 // We need to break where we can find a space char
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
193 char *br; // break pointer
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
194 for (br = line + width; br > line && *br != 32 && *br != 9; br--)
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
195 ;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
196 if (br <= line)
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
197 br = line + width;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
198 else
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
199 br++;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
200 end = hbuf_b_curr->ptr_end;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
201 hbuf_b_curr->ptr_end = br;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
202 // Create another block, non-persistent
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
203 hbuf_b_curr = g_new0(hbuf_block, 1);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
204 hbuf_b_curr->ptr = hbuf_b_prev->ptr_end; // == br
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
205 hbuf_b_curr->ptr_end = end;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
206 hbuf_b_curr->flags = 0;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
207 hbuf_b_curr->persist.ptr_end_alloc = hbuf_b_prev->persist.ptr_end_alloc;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
208 /*
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
209 // Is there a better way?
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
210 if (g_list_next(curr_elt))
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
211 g_list_insert_before(*p_hbuf, curr_elt->next, hbuf_b_curr);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
212 else
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
213 *p_hbuf = g_list_append(*p_hbuf, hbuf_b_curr);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
214 */
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
215 // This is OK because insert_before(NULL) <==> append()
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
216 g_list_insert_before(*p_hbuf, curr_elt->next, hbuf_b_curr);
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
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
223 // hbuf_get_lines(hbuf, n, where)
75
ff119bb11563 [/trunk] Changeset 89 by mikael
mikael
parents: 71
diff changeset
224 // Returns an array of 2*n pointers (for n prefixes + n lines from hbuf)
ff119bb11563 [/trunk] Changeset 89 by mikael
mikael
parents: 71
diff changeset
225 // (prefix line 1, line 1, prefix line 2, line 2, etc.)
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
226 // (The first line will be the line currently pointed by hbuf)
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
227 // Note:The caller should free the array after use.
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
228 char **hbuf_get_lines(GList *hbuf, unsigned int n)
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
229 {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
230 unsigned int i;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
231
75
ff119bb11563 [/trunk] Changeset 89 by mikael
mikael
parents: 71
diff changeset
232 char **array = g_new0(char*, n*2);
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
233 char **array_elt = array;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
234
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
235 for (i=0 ; i < n ; i++) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
236 if (hbuf) {
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
237 hbuf_block *blk = (hbuf_block*)(hbuf->data);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
238 int maxlen;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
239 maxlen = blk->ptr_end - blk->ptr;
75
ff119bb11563 [/trunk] Changeset 89 by mikael
mikael
parents: 71
diff changeset
240 *array_elt++ = blk->persist.prefix;
71
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
241 *array_elt++ = g_strndup(blk->ptr, maxlen);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
242 hbuf = g_list_next(hbuf);
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
243 } else
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
244 *array_elt++ = NULL;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
245 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
246
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
247 return array;
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
248 }
1e9d4949bcfd [/trunk] Changeset 85 by mikael
mikael
parents:
diff changeset
249