current version
[opsoft_test.git] / gclib2 / modules / Misc / strings.cxx
blob7695a819c3bad041cdbefb8f2b2b18e7da6d1c03
1 /*
2 * (c) Oleg Puchinin 2006
3 * graycardinalster@gmail.com
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <string.h>
11 #include <stdarg.h>
12 #include <gclib2.h>
13 #define __export
15 /// Увеличить размер блока (с копированием).
16 __export char * gc_realloc (char * PTR, int old_size, int new_size)
18 int i;
19 char * S = (char *) malloc (new_size);
20 if (S == NULL)
21 return NULL;
23 i = (new_size >= old_size) ? old_size : new_size;
24 memcpy (S, PTR, i);
25 free (PTR);
26 return S;
29 /// Скопировать блок памяти.
30 __export void * memdup (void * PTR, int size)
32 char * Ret;
33 Ret = (char *) malloc (size);
34 memcpy (Ret, PTR, size);
35 return (void *) Ret;
38 /* 2005 */
39 /// Разбить текст строкой (аналог "split" perl'а).
40 __export int Dsplit(char * lpsz_String, char *ch, char ** outbuffer, int int_buffersize)
42 char * S;
43 int i;
45 i = 1;
46 --int_buffersize;
48 if(!lpsz_String)
49 return 0;
51 if(int_buffersize > 0) {
52 S = lpsz_String;
53 outbuffer[0] = S;
54 } else
55 return 0;
57 S = strstr(S,ch);
58 while(S && (int_buffersize--)) {
59 S[0] = 0;
60 ++S;
61 outbuffer[i] = S;
62 S = strstr(S,ch);
63 ++i;
65 return i;
68 /// lpsz_string =~ m/param1(.*)param2/
69 __export char * Dstrmid(char * lpsz_string,char * param1, char * param2)
71 char * Result;
72 char *S;
73 char *S2;
74 int int_strsize;
76 if(! strlen (param1))
77 return 0;
79 S = strstr (lpsz_string,param1);
80 if(! S)
81 return 0;
82 S += strlen (param1);
83 S2 = strstr (S,param2);
84 if(! S2)
85 return 0;
87 int_strsize = S2 - S;
88 if(! int_strsize)
89 return 0;
91 Result = (char *) malloc (int_strsize + 1);
92 memcpy (Result, S, int_strsize);
93 Result [int_strsize] = 0;
94 return Result;
97 /// Убить конец строки.
98 __export char * chomp (char * S)
100 char * str;
101 if (S == NULL)
102 return NULL;
103 str = strchrs (S, 13, 10, 0, 0);
104 if (str)
105 *str = 0;
106 return S;
109 /// Найти символ (с конца строки). d_len - исходной строки (если известна).
110 __export char * strchr_r (char * S, char ch, int d_len)
112 if (! d_len)
113 d_len = strlen (S);
115 S += d_len - 1;
116 while (d_len > 0) {
117 if (*S == ch)
118 break;
119 --S;
120 --d_len;
123 return S;
126 /// Найти один из символов.
127 __export char * strchrs (char *S, char ch, char ch2, char ch3, char ch4)
129 while (*S) {
130 if (*S == ch)
131 break;
133 if (*S == ch2)
134 break;
136 if (*S == ch3)
137 break;
139 if (*S == ch4)
140 break;
142 ++S;
145 if (*S == ch || *S == ch2 || *S == ch3 || *S == ch4)
146 return S;
148 return NULL;
151 /* 2006-05-25 */
152 /// Найти строку (с конца исходной).
153 __export char * Dstrstr_r (char *where, char * str)
155 char * S;
156 int len;
158 if (! where || ! str || strlen (where) == 0)
159 return NULL;
161 S = &where[strlen (where)];
162 len = strlen (str);
164 while (--S != where) {
165 if (! strncmp (S, str, len))
166 return S;
169 return NULL;
172 /// Посчитать Количество символов от from до to-1.
173 __export int Dsyms (char * from, char * to, char sym)
175 int count = 0;
176 do {
177 if (*from == sym)
178 ++count;
179 } while (++from != to);
180 return count;
183 /// Найти символ в буфере.
184 __export char * Dmemchr (char * from, int n, char ch)
186 while (n--) {
187 if (*from == ch)
188 return from;
189 ++from;
191 return NULL;
194 /// Скопировать не более n символов строки ptr.
195 __export char * Dstrndup (char *ptr, int n)
197 char *S;
198 char *buf;
200 if (ptr == NULL || n <= 0)
201 return NULL;
203 buf = (char *) malloc (n+1);
204 S = buf;
205 while (*ptr && n--) {
206 *S = *ptr;
207 ++S; ++ptr;
209 *S = '\0';
211 return buf;
214 /// Найти символ между ptr и end (включительно).
215 __export char * Dmid_strchr (char *ptr, char *end, char ch)
217 while (ptr <= end) {
218 if (*ptr == ch)
219 return ptr;
220 ++ptr;
222 return NULL;
225 /// Выбрать (с копирование памяти) строку между buf и end (включительно).
226 __export char * Dmid_getstr (char *buf, char *end)
228 char *S;
229 char *out;
230 int s_len;
232 if (! buf || ! end)
233 return NULL;
235 S = Dmid_strchr (buf, end, '\n');
236 if (! S)
237 S = end;
239 s_len = S-buf+1;
240 out = (char *) malloc (s_len+1);
241 memcpy (out, buf, s_len);
242 out[s_len] = '\0';
244 return out;
247 /// Получить рандомную строку на count символов.
248 __export char * Drand_str (char * buf, int count)
250 int i;
251 unsigned char ch;
253 if (! buf)
254 return NULL;
256 --count;
257 for (i = 0; i < count; ++i) {
258 ch = rand () % ('z' - 'a' - 1);
259 buf[i] = ch + 'a';
262 buf[i] = 0;
263 return buf;
266 /// Перевести число в строку (результат - новая LPSZ строка).
267 __export char * int2str (int i)
269 char buf[64];
270 sprintf (buf, "%i", i);
271 return strdup (buf);
274 /// Вернуть указатель на последний ноль строки.
275 __export char * stail (char *S)
277 if (! S)
278 return NULL;
279 return &S[strlen (S)];
282 /// Копировать строку. Результат - конец результирующей строки.
283 __export char * strmov (char *buf, char * S)
285 if (! buf || ! S)
286 return NULL;
287 strcpy (buf, S);
288 return buf+strlen (S);
291 __export char * strnmov (char *buf, char * S, int N)
293 int len;
295 if (! buf || ! S)
296 return NULL;
298 strncpy (buf, S, N);
299 len = strlen (S);
300 len = (len >= N) ? N : len;
301 buf[len] = '\0';
303 return &buf[len];
306 /// Убрать все начальные пробельные символы.
307 __export char * strip (char *str)
309 char *S;
310 if (! str)
311 return NULL;
312 S = str;
313 while (*S && (*S == '\t' || *S == ' '))
314 ++S;
315 if (S != str)
316 strcpy (str, S);
317 return str;
320 /// Убрать все конечные пробельные символы.
321 __export char * strip2 (char *str)
323 char *S;
324 if (! str)
325 return NULL;
326 S = stail (str);
327 --S;
328 while (S != str && (*S == ' ' || *S == '\t'))
329 --S;
330 ++S;
331 *S = '\0';
332 return str;
335 /// Кросс-платформенный аналог memmem (3)
336 __export char * Dmemmem (char *haystack, size_t haystacklen, char *needle, size_t needlelen)
338 char * ptr;
339 char * end;
341 if (! haystack || ! needle)
342 return NULL;
344 if (haystacklen < needlelen)
345 return NULL;
347 ptr = haystack;
348 end = &haystack[haystacklen] - needlelen + 1;
349 while (ptr != end && memcmp (ptr, needle, needlelen))
350 ++ptr;
352 if (ptr == end)
353 return NULL;
355 return ptr;
358 /// Найти блок между begin и last (включительно).
359 __export char * Dmid_memmem (char * begin, char * last, char * needle, int needlelen)
361 char * ptr;
363 if (! begin || ! needle)
364 return NULL;
366 if ((last - begin - 1) < needlelen)
367 return NULL;
369 last -= needlelen;
370 ++last;
371 ptr = begin;
372 while (ptr <= last && memcmp (ptr, needle, needlelen))
373 ++ptr;
375 if (ptr > last)
376 return NULL;
378 return ptr;
381 /// Создать новую форматированную строку (не более 511 символов).
382 __export char * Dsprintf (char * fmt, ...)
384 char m_buf[512];
385 va_list ap;
386 m_buf[511] = '\0';
387 va_start (ap, fmt);
388 vsnprintf (m_buf, 511, fmt, ap);
389 va_end (ap);
390 return strdup (m_buf);
393 __export char * strinsert (char * base, char *ptr, char *ins, int rewrite)
395 int ins_len;
396 int part1_len;
397 int part2_len;
398 char * m_buf;
399 char *S;
401 if (!base || !ptr || !ins)
402 return NULL;
404 ins_len = strlen (ins);
405 part1_len = ptr - base;
406 part2_len = strlen (&ptr[rewrite]);
408 m_buf = CNEW (char, ins_len + part1_len + part2_len + 1);
409 m_buf = CNEW (char, 4096);
410 m_buf[0] = '\0';
412 S = strnmov (m_buf, base, part1_len);
413 S = strmov (S, ins);
414 S = strmov (S, &ptr[rewrite]);
416 return m_buf;
419 __export char * strreplace (char * buf, char * oldstr, char * newstr)
421 List * m_list;
422 char * m_buf;
424 if (!buf || !oldstr || !newstr)
425 return NULL;
427 m_list = split (buf, oldstr);
428 if (! m_list)
429 return NULL;
430 m_buf = join (m_list, newstr);
431 m_list->foreach (free);
433 delete m_list;
434 return m_buf;