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. |