/[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

Annotation of /src/tools/strtools.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Wed Sep 5 17:11:21 2007 UTC (16 years, 6 months ago) by dpavlin
File size: 9634 byte(s)
import upstream CVS
1 dpavlin 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