/[pearpc]/src/tools/strtools.cc
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /src/tools/strtools.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations)
Wed Sep 5 17:11:21 2007 UTC (11 years, 10 months ago) by dpavlin
File size: 9634 byte(s)
import upstream CVS
1 /*
2 * HT Editor
3 * strtools.cc
4 *
5 * Copyright (C) 1999-2002 Stefan Weyergraf
6 * Copyright (C) 1999-2003 Sebastian Biallas (sb@biallas.net)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "atom.h"
23 #include "debug.h"
24 #include "except.h"
25 #include "snprintf.h"
26 #include "stream.h"
27 #include "strtools.h"
28 #include "system/types.h"
29
30 #include <cctype>
31 #include <cstdarg>
32 #include <cstdlib>
33 #include <cstring>
34
35 char hexchars[17]="0123456789abcdef";
36
37 char *ht_strdup(const char *str)
38 {
39 if (str) {
40 int len = strlen(str)+1;
41 char *s = (char*)malloc(len);
42 memmove(s, str, len);
43 return s;
44 } else {
45 return NULL;
46 }
47 }
48
49
50 /**
51 * Like ht_strdup but dups a maximum of |maxlen| characters of |str|.
52 * @returns new string
53 */
54 char *ht_strndup(const char *str, size_t maxlen)
55 {
56 maxlen ++;
57 if (str) {
58 uint len = strlen(str)+1;
59 len = MIN(len, maxlen);
60 char *s = (char*)malloc(len);
61 memmove(s, str, len);
62 s[len-1] = 0;
63 return s;
64 } else {
65 return NULL;
66 }
67 }
68
69 /**
70 * Like strcpy but copies a maximum of |maxlen| characters
71 * (including trailing zero).
72 * The operation is performed in a way that the trailing zero
73 * is always written if maxlen is > 0.
74 * @returns number of characters copied (without trailing zero)
75 */
76 int ht_strncpy(char *s1, const char *s2, size_t maxlen)
77 {
78 if (maxlen <= 0) return 0;
79 char *os1 = s1;
80 while (maxlen && *s2) {
81 *s1 = *s2;
82 maxlen--;
83 s1++;
84 }
85 s1[-1] = 0;
86 return s1-os1-1;
87 }
88
89 int ht_strncmp(const char *s1, const char *s2, size_t max)
90 {
91 if (!s1) return s2 ? -1 : 0;
92 if (!s2) return s1 ? 1 : 0;
93 while (max--) {
94 if (!*s1) return *s2 ? -1 : 0;
95 if (!*s2) return *s1 ? 1 : 0;
96 if (*s1>*s2) {
97 return 1;
98 } else if (*s1<*s2) {
99 return -1;
100 }
101 s1++;s2++;
102 }
103 return 0;
104 }
105
106 int ht_strnicmp(const char *s1, const char *s2, size_t max)
107 {
108 if (!s1) return s2 ? -1 : 0;
109 if (!s2) return s1 ? 1 : 0;
110 while (max--) {
111 if (!*s1) return *s2 ? -1 : 0;
112 if (!*s2) return *s1 ? 1 : 0;
113 char c1=tolower(*s1), c2=tolower(*s2);
114 if (c1>c2) {
115 return 1;
116 } else if (c1<c2) {
117 return -1;
118 }
119 s1++;s2++;
120 }
121 return 0;
122 }
123
124 int ht_stricmp(const char *s1, const char *s2)
125 {
126 if (!s1) return s2 ? -1 : 0;
127 if (!s2) return s1 ? 1 : 0;
128 while (1) {
129 if (!*s1) return *s2 ? -1 : 0;
130 if (!*s2) return *s1 ? 1 : 0;
131 char c1=tolower(*s1), c2=tolower(*s2);
132 if (c1>c2) {
133 return 1;
134 } else if (c1<c2) {
135 return -1;
136 }
137 s1++;s2++;
138 }
139 return 0;
140 }
141
142 int strccomm(const char *s1, const char *s2)
143 {
144 if (!s1 || !s2) return 0;
145 int r=0;
146 while (*s1 && *s2 && (*s1==*s2)) { s1++; s2++; r++; }
147 return r;
148 }
149
150 int strcicomm(const char *s1, const char *s2)
151 {
152 if (!s1 || !s2) return 0;
153 int r=0;
154 while (*s1 && *s2 && (tolower(*s1)==tolower(*s2))) { s1++; s2++; r++; }
155 return r;
156 }
157
158 int escape_special_str(char *result, int resultmaxlen, const char *s, const char *specialchars, bool bit7)
159 {
160 return escape_special(result, resultmaxlen, s, strlen(s), specialchars, bit7);
161 }
162
163 int escape_special(char *result, int resultmaxlen, const void *S, int len, const char *specialchars, bool bit7)
164 {
165 byte *s = (byte*)S;
166 if (!s) return 0;
167 char *old = result;
168 if (!specialchars) specialchars="";
169 while (len--) {
170 if (*s && strchr(specialchars, *s)) {
171 *result++='\\';
172 if (--resultmaxlen<2) break;
173 *result++=*s;
174 if (--resultmaxlen<2) break;
175 } else if (*s<32 || (bit7 && (*s>0x7f)) || *s=='\\') {
176 *result++='\\';
177 if (--resultmaxlen<2) break;
178 switch (*s) {
179 case '\0':
180 *result++='0';
181 break;
182 case '\a':
183 *result++='a';
184 break;
185 case '\b':
186 *result++='b';
187 break;
188 case '\e':
189 *result++='e';
190 break;
191 case '\f':
192 *result++='f';
193 break;
194 case '\n':
195 *result++='n';
196 break;
197 case '\r':
198 *result++='r';
199 break;
200 case '\t':
201 *result++='t';
202 break;
203 case '\v':
204 *result++='v';
205 break;
206 case '\\':
207 *result++='\\';
208 break;
209 case '\"':
210 *result++='"';
211 break;
212 default:
213 *result++='x';
214 if (--resultmaxlen<2) break;
215 *result++=hexchars[((*s & 0xf0) >> 4)];
216 if (--resultmaxlen<2) break;
217 *result++=hexchars[(*s & 0x0f)];
218 }
219 if (--resultmaxlen<2) break;
220 } else {
221 *result++ = *s;
222 if (--resultmaxlen<2) break;
223 }
224 s++;
225 }
226 *result = 0;
227 return result-old;
228 }
229
230 int unescape_special_str(char *result, int resultmaxlen, const char *s)
231 {
232 int l=unescape_special(result, resultmaxlen-1, s);
233 result[l]=0;
234 return l;
235 }
236
237 int unescape_special(void *Result, int resultmaxlen, const char *s)
238 {
239 char *result = (char*)Result;
240 char *old = result;
241 while (s && *s) {
242 if (*s == '\\') {
243 s++;
244 switch (*s) {
245 case '0':
246 *result++='\0';
247 break;
248 case 'a':
249 *result++='\a';
250 break;
251 case 'b':
252 *result++='\b';
253 break;
254 case 'e':
255 *result++='\e';
256 break;
257 case 'f':
258 *result++='\f';
259 break;
260 case 'n':
261 *result++='\n';
262 break;
263 case 'r':
264 *result++='\r';
265 break;
266 case 't':
267 *result++='\t';
268 break;
269 case 'v':
270 *result++='\v';
271 break;
272 case '\\':
273 *result++='\\';
274 break;
275 case '\"':
276 *result++='"';
277 break;
278 case 'x':
279 s++;
280 byte v=hexdigit(*s)*16;
281 s++;
282 v+=hexdigit(*s);
283 *result++=(char)v;
284 }
285 if (!--resultmaxlen) break;
286 } else {
287 *result++ = *s;
288 if (!--resultmaxlen) break;
289 }
290 s++;
291 }
292 return result-old;
293 }
294
295 int bin2str(char *result, const void *S, int len)
296 {
297 byte *s = (byte*)S;
298 while (len--) {
299 // if (*s<32) *result=' '; else *result=*s;
300 if (*s==0) *result=' '; else *result=*s;
301 result++;
302 s++;
303 }
304 *result=0;
305 return len;
306 }
307
308 void wide_char_to_multi_byte(char *result, const byte *Unicode, int maxlen)
309 {
310 if (!maxlen) return;
311 struct doof {
312 char c1;
313 char c2;
314 };
315 doof *unicode = (doof*)Unicode;
316 for (int i=0; i<maxlen-1; i++) {
317 if (unicode->c2) {
318 *result++ = '?';
319 } else {
320 if (!unicode->c1) break;
321 *result++ = unicode->c1;
322 }
323 unicode++;
324 }
325 *result=0;
326 }
327
328 void memdowncase(byte *buf, int len)
329 {
330 for (int i=0; i<len; i++) {
331 if ((buf[i]>='A') && (buf[i]<='Z')) buf[i]+=32;
332 }
333 }
334
335 byte *ht_memmem(const byte *haystack, int haystack_len, const byte *needle, int needle_len)
336 {
337 while (haystack_len && (haystack_len >= needle_len)) {
338 if (memcmp(haystack, needle, needle_len) == 0) return (byte*)haystack;
339 haystack++;
340 haystack_len--;
341 }
342 return NULL;
343 }
344
345 /* common string parsing functions */
346 void whitespaces(const char *&str)
347 {
348 while ((unsigned char)*str<=32) {
349 if (!*str) return;
350 str++;
351 }
352 }
353
354 void non_whitespaces(const char *&str)
355 {
356 while ((unsigned char)*str>32) {
357 str++;
358 }
359 }
360
361 bool waitforchar(const char *&str, char b)
362 {
363 while (*str != b) {
364 if (!*str) return false;
365 str++;
366 }
367 return true;
368 }
369
370 static bool bnstr2int(const char *&str, uint64 &u64, int base)
371 {
372 u64 = 0;
373 uint64 ubase = base;
374 int i = 0;
375 do {
376 int c = hexdigit(*str);
377 if ((c == -1) || (c >= base)) return (i == 0) ? false : true;
378 u64 *= ubase;
379 u64 += c;
380 str++;
381 i++;
382 } while (*str);
383 return true;
384 }
385
386 bool parseIntStr(const char *&str, uint64 &u64, int defaultbase)
387 {
388 int base = defaultbase;
389 if ((base == 10) && strncmp("0x", str, 2) == 0) {
390 str += 2;
391 base = 16;
392 }
393 return bnstr2int(str, u64, base);
394 }
395
396 /* hex/string functions */
397 int hexdigit(char a)
398 {
399 if ((a>='0') && (a<='9')) {
400 return a-'0';
401 } else if ((a>='a') && (a<='f')) {
402 return a-'a'+10;
403 } else if ((a>='A') && (a<='F')) {
404 return a-'A'+10;
405 }
406 return -1;
407 }
408
409 bool hexb_ex(uint8 &result, const char *s)
410 {
411 int v, w;
412 v = hexdigit(s[0]);
413 w = hexdigit(s[1]);
414 if ((v < 0) || (w < 0)) return false;
415 result = (v<<4) | w;
416 return true;
417 }
418
419 bool hexw_ex(uint16 &result, const char *s)
420 {
421 uint8 v, w;
422 if (!hexb_ex(v, s) || !hexb_ex(w, s+2)) return false;
423 result = (v<<8) | w;
424 return true;
425 }
426
427 bool hexd_ex(uint32 &result, const char *s)
428 {
429 uint16 v, w;
430 if (!hexw_ex(v, s) || !hexw_ex(w, s+4)) return false;
431 result = (v<<16) | w;
432 return true;
433 }
434
435 char *mkhexb(char *buf, uint8 d)
436 {
437 *buf++=hexchars[(d>>4)&0xf];
438 *buf++=hexchars[d&0xf];
439 return buf;
440 }
441
442 char *mkhexw(char *buf, uint16 d)
443 {
444 *buf++=hexchars[(d>>12)&0xf];
445 *buf++=hexchars[(d>>8)&0xf];
446 *buf++=hexchars[(d>>4)&0xf];
447 *buf++=hexchars[d&0xf];
448 return buf;
449 }
450
451 char *mkhexd(char *buf, uint32 d)
452 {
453 *buf++=hexchars[(d>>28)&0xf];
454 *buf++=hexchars[(d>>24)&0xf];
455 *buf++=hexchars[(d>>20)&0xf];
456 *buf++=hexchars[(d>>16)&0xf];
457 *buf++=hexchars[(d>>12)&0xf];
458 *buf++=hexchars[(d>>8)&0xf];
459 *buf++=hexchars[(d>>4)&0xf];
460 *buf++=hexchars[d&0xf];
461 return buf;
462 }
463
464 char *mkhexq(char *buf, uint64 u)
465 {
466 *buf++ = hexchars[(u>>60)&0xf];
467 *buf++ = hexchars[(u>>56)&0xf];
468 *buf++ = hexchars[(u>>52)&0xf];
469 *buf++ = hexchars[(u>>48)&0xf];
470 *buf++ = hexchars[(u>>44)&0xf];
471 *buf++ = hexchars[(u>>40)&0xf];
472 *buf++ = hexchars[(u>>36)&0xf];
473 *buf++ = hexchars[(u>>32)&0xf];
474 *buf++ = hexchars[(u>>28)&0xf];
475 *buf++ = hexchars[(u>>24)&0xf];
476 *buf++ = hexchars[(u>>20)&0xf];
477 *buf++ = hexchars[(u>>16)&0xf];
478 *buf++ = hexchars[(u>>12)&0xf];
479 *buf++ = hexchars[(u>>8)&0xf];
480 *buf++ = hexchars[(u>>4)&0xf];
481 *buf++ = hexchars[(u>>0)&0xf];
482 return buf;
483 }

  ViewVC Help
Powered by ViewVC 1.1.26