/[LeafOK_CVS]/lbbs/src/str_process.c
ViewVC logotype

Contents of /lbbs/src/str_process.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.22 - (show annotations)
Fri Oct 31 06:04:17 2025 UTC (4 months, 2 weeks ago) by sysadm
Branch: MAIN
Changes since 1.21: +15 -3 lines
Content type: text/x-csrc
Fix bug

1 /***************************************************************************
2 str_process.c - description
3 -------------------
4 Copyright : (C) 2004-2025 by Leaflet
5 Email : leaflet@leafok.com
6 ***************************************************************************/
7
8 /***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 3 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
17 #include "common.h"
18 #include "log.h"
19 #include "str_process.h"
20 #include <ctype.h>
21 #include <stdio.h>
22 #include <string.h>
23
24 int str_length(const char *str, int skip_ctrl_seq)
25 {
26 int i;
27 char c;
28 int ret = 0;
29
30 for (i = 0; str[i] != '\0'; i++)
31 {
32 c = str[i];
33
34 if (c == '\r' || c == '\7') // skip
35 {
36 continue;
37 }
38
39 if (skip_ctrl_seq && c == '\033' && str[i + 1] == '[') // Skip control sequence
40 {
41 for (i = i + 2; isdigit(str[i]) || str[i] == ';' || str[i] == '?'; i++)
42 ;
43
44 if (str[i] == 'm') // valid
45 {
46 // skip
47 }
48 else if (isalpha(str[i]))
49 {
50 // unsupported ANSI CSI command
51 }
52 else
53 {
54 i--;
55 }
56
57 continue;
58 }
59
60 // Process UTF-8 Chinese characters
61 if (c & 0x80) // head of multi-byte character
62 {
63 c = (c & 0x70) << 1;
64 while (c & 0x80)
65 {
66 i++;
67 c = (c & 0x7f) << 1;
68 }
69
70 ret += 2;
71 }
72 else
73 {
74 ret++;
75 }
76 }
77
78 return ret;
79 }
80
81 int split_line(const char *buffer, int max_display_len, int *p_eol, int *p_display_len, int skip_ctrl_seq)
82 {
83 int i;
84 *p_eol = 0;
85 *p_display_len = 0;
86 char c;
87
88 for (i = 0; buffer[i] != '\0'; i++)
89 {
90 c = buffer[i];
91
92 if (c == '\r' || c == '\7') // skip
93 {
94 continue;
95 }
96
97 if (skip_ctrl_seq && c == '\033' && buffer[i + 1] == '[') // Skip control sequence
98 {
99 i += 2;
100 while (buffer[i] != '\0' && buffer[i] != 'm')
101 {
102 i++;
103 }
104 continue;
105 }
106
107 if (c & 0x80) // head of multi-byte character
108 {
109 if (*p_display_len + 2 > max_display_len)
110 {
111 break;
112 }
113
114 c = (c & 0x70) << 1;
115 while (c & 0x80)
116 {
117 i++;
118 c = (c & 0x7f) << 1;
119 }
120
121 (*p_display_len) += 2;
122 }
123 else
124 {
125 if (*p_display_len + 1 > max_display_len)
126 {
127 break;
128 }
129 (*p_display_len)++;
130
131 // \n is regarded as 1 character wide in terminal editor, which is different from Web version
132 if (c == '\n')
133 {
134 i++;
135 *p_eol = 1;
136 break;
137 }
138 }
139 }
140
141 return i;
142 }
143
144 long split_data_lines(const char *p_buf, int max_display_len, long *p_line_offsets, long line_offsets_count,
145 int skip_ctrl_seq, int *p_line_widths)
146 {
147 int line_cnt = 0;
148 int len;
149 int end_of_line = 0;
150 int display_len = 0;
151
152 p_line_offsets[line_cnt] = 0L;
153
154 do
155 {
156 len = split_line(p_buf, max_display_len, &end_of_line, &display_len, skip_ctrl_seq);
157
158 if (p_line_widths)
159 {
160 p_line_widths[line_cnt] = display_len;
161 }
162
163 // Exceed max_line_cnt
164 if (line_cnt + 1 >= line_offsets_count)
165 {
166 // log_error("Line count %d reaches limit %d\n", line_cnt + 1, line_offsets_count);
167 return line_cnt;
168 }
169
170 p_line_offsets[line_cnt + 1] = p_line_offsets[line_cnt] + len;
171 line_cnt++;
172 p_buf += len;
173 } while (p_buf[0] != '\0');
174
175 return line_cnt;
176 }
177
178 int str_filter(char *buffer, int skip_ctrl_seq)
179 {
180 int i;
181 int j;
182
183 for (i = 0, j = 0; buffer[i] != '\0'; i++)
184 {
185 if (buffer[i] == '\r' || buffer[i] == '\7') // skip
186 {
187 continue;
188 }
189
190 if (skip_ctrl_seq && buffer[i] == '\033' && buffer[i + 1] == '[') // Skip control sequence
191 {
192 i += 2;
193 while (buffer[i] != '\0' && buffer[i] != 'm')
194 {
195 i++;
196 }
197 continue;
198 }
199
200 buffer[j] = buffer[i];
201 j++;
202 }
203
204 buffer[j] = '\0';
205
206 return j;
207 }

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1