comparison mcabber/src/hbuf.c @ 942:c6bd42119c31

Make hbuf_add_line() UTF-8 aware
author Mikael Berthe <mikael@lilotux.net>
date Sat, 15 Jul 2006 12:28:42 +0200
parents fc6aaa223650
children 9ac0d166a85b
comparison
equal deleted inserted replaced
941:518e7c17a79e 942:c6bd42119c31
52 // Note 2: width does not include the ending \0. 52 // Note 2: width does not include the ending \0.
53 void hbuf_add_line(GList **p_hbuf, const char *text, time_t timestamp, 53 void hbuf_add_line(GList **p_hbuf, const char *text, time_t timestamp,
54 guint prefix_flags, guint width) 54 guint prefix_flags, guint width)
55 { 55 {
56 GList *hbuf = *p_hbuf; 56 GList *hbuf = *p_hbuf;
57 char *line, *cr, *end; 57 GList *curr_elt;
58 hbuf_block *hbuf_block_elt; 58 char *line, *end;
59 hbuf_block *hbuf_block_elt, *hbuf_b_curr;
59 60
60 if (!text) return; 61 if (!text) return;
61 62
62 hbuf_block_elt = g_new0(hbuf_block, 1); 63 hbuf_block_elt = g_new0(hbuf_block, 1);
63 hbuf_block_elt->prefix.timestamp = timestamp; 64 hbuf_block_elt->prefix.timestamp = timestamp;
95 // Ok, now we can copy the text.. 96 // Ok, now we can copy the text..
96 strcpy(line, text); 97 strcpy(line, text);
97 hbuf_block_elt->ptr_end = line + strlen(line) + 1; 98 hbuf_block_elt->ptr_end = line + strlen(line) + 1;
98 end = hbuf_block_elt->ptr_end; 99 end = hbuf_block_elt->ptr_end;
99 100
101 curr_elt = g_list_last(hbuf);
102
100 // Let's add non-persistent blocs if necessary 103 // Let's add non-persistent blocs if necessary
101 // - If there are '\n' in the string 104 // - If there are '\n' in the string
102 // - If length > width (and width != 0) 105 // - If length > width (and width != 0)
103 cr = strchr(line, '\n'); 106 while (curr_elt) {
104 while (cr || (width && strlen(line) > width)) { 107 hbuf_block *hbuf_b_prev;
105 hbuf_block *hbuf_b_prev = hbuf_block_elt; 108 char *c, *end;
106 109 char *br = NULL; // break pointer
107 if (!width || (cr && (cr - line <= (int)width))) { 110 char *cr = NULL; // CR pointer
108 // Carriage return 111 unsigned int cur_w = 0;
109 *cr = 0; 112
110 hbuf_block_elt->ptr_end = cr; 113 // We want to break where we can find a space char or a CR
111 // Create another persistent block 114
112 hbuf_block_elt = g_new0(hbuf_block, 1); 115 hbuf_b_curr = (hbuf_block*)(curr_elt->data);
113 hbuf_block_elt->ptr = hbuf_b_prev->ptr_end + 1; // == cr+1 116 hbuf_b_prev = hbuf_b_curr;
114 hbuf_block_elt->ptr_end = end; 117 c = hbuf_b_curr->ptr;
115 hbuf_block_elt->flags = HBB_FLAG_PERSISTENT; 118
116 hbuf_block_elt->ptr_end_alloc = hbuf_b_prev->ptr_end_alloc; 119 while (*c && (!width || cur_w <= width)) {
117 *p_hbuf = g_list_append(*p_hbuf, hbuf_block_elt); 120 if (*c == '\n') {
118 line = hbuf_block_elt->ptr; 121 br = cr = c;
119 } else { 122 *c = 0;
120 // We need to break where we can find a space char 123 break;
121 char *br; // break pointer 124 }
122 for (br = line + width; br > line && *br != 32 && *br != 9; br--) 125 if (iswblank(get_char(c)))
123 ; 126 br = c;
124 if (br <= line) 127 cur_w += get_char_width(c);
125 br = line + width; 128 c = next_char(c);
129 }
130
131 if (cr || (*c && cur_w > width)) {
132 if (!br || br == hbuf_b_curr->ptr)
133 br = c;
126 else 134 else
127 br++; 135 br = next_char(br);
128 hbuf_block_elt->ptr_end = br; 136 end = hbuf_b_curr->ptr_end;
129 // Create another block, non-persistent 137 hbuf_b_curr->ptr_end = br;
130 hbuf_block_elt = g_new0(hbuf_block, 1); 138 // Create another block
131 hbuf_block_elt->ptr = hbuf_b_prev->ptr_end; // == br 139 hbuf_b_curr = g_new0(hbuf_block, 1);
132 hbuf_block_elt->ptr_end = end; 140 // The block must be persistent after a CR
133 hbuf_block_elt->flags = 0; 141 if (cr) {
134 hbuf_block_elt->ptr_end_alloc = hbuf_b_prev->ptr_end_alloc; 142 hbuf_b_curr->ptr = hbuf_b_prev->ptr_end + 1; // == cr+1
135 *p_hbuf = g_list_append(*p_hbuf, hbuf_block_elt); 143 hbuf_b_curr->flags = HBB_FLAG_PERSISTENT;
136 line = hbuf_block_elt->ptr; 144 } else {
137 } 145 hbuf_b_curr->ptr = hbuf_b_prev->ptr_end; // == br
138 cr = strchr(line, '\n'); 146 hbuf_b_curr->flags = 0;
147 }
148 hbuf_b_curr->ptr_end = end;
149 hbuf_b_curr->ptr_end_alloc = hbuf_b_prev->ptr_end_alloc;
150 // This is OK because insert_before(NULL) == append():
151 *p_hbuf = g_list_insert_before(*p_hbuf, curr_elt->next, hbuf_b_curr);
152 }
153 curr_elt = g_list_next(curr_elt);
139 } 154 }
140 } 155 }
141 156
142 // hbuf_free() 157 // hbuf_free()
143 // Destroys all hbuf list. 158 // Destroys all hbuf list.