Mercurial > ~mikael > mcabber > hg
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. |