source: roaraudio/libroar/memmgr.c @ 5755:d61e5f9b4111

Last change on this file since 5755:d61e5f9b4111 was 5755:d61e5f9b4111, checked in by phi, 11 years ago

added roar_mm_strdup2()

File size: 9.2 KB
Line 
1//memmgr.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2012
5 *
6 *  This file is part of libroar a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  libroar is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 *  NOTE for everyone want's to change something and send patches:
25 *  read README and HACKING! There a addition information on
26 *  the license of this document you need to read before you send
27 *  any patches.
28 *
29 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
30 *  or libpulse*:
31 *  The libs libroaresd, libroararts and libroarpulse link this lib
32 *  and are therefore GPL. Because of this it may be illigal to use
33 *  them with any software that uses libesd, libartsc or libpulse*.
34 */
35
36#include "libroar.h"
37
38#ifdef ROAR_USE_MEMMGR
39#define NULL_BUFFER_CONST "RoarAudio"
40static char _libroar_null_buffer[] = NULL_BUFFER_CONST; // A byte sequense >= 8 byte.
41
42static inline void _libroar_null_buffer_check(void) {
43 if ( memcmp(_libroar_null_buffer, NULL_BUFFER_CONST, sizeof(_libroar_null_buffer)) != 0 )
44  roar_panic(ROAR_FATAL_ERROR_MEMORY_CORRUPTION_GUARD, NULL);
45 memcpy(_libroar_null_buffer, NULL_BUFFER_CONST, sizeof(_libroar_null_buffer));
46}
47#endif
48
49#define _err(x) do { roar_err_set((x)); return NULL; } while (0)
50
51#ifdef ROAR_USE_MEMMGR
52
53int     roar_mm_reset(void) {
54 // currently this does nothing.
55 // we need to free pools and such here later.
56 return 0;
57}
58
59ssize_t roar_mm_sizeof(void * buf) {
60 if ( buf == NULL ) {
61  roar_err_set(ROAR_ERROR_FAULT);
62  return -1;
63 }
64
65 if ( buf == _libroar_null_buffer_check )
66  return 0;
67
68 roar_err_set(ROAR_ERROR_NOTSUP);
69 return -1;
70}
71
72void * roar_mm_calloc(size_t nmemb, size_t size) {
73 void * ret;
74
75 if ( nmemb == 0 || size == 0 ) {
76  _libroar_null_buffer_check();
77  return _libroar_null_buffer;
78 }
79
80#ifdef ROAR_HAVE_CALLOC
81 roar_err_clear_all();
82 ret = calloc(nmemb, size);
83
84 if ( ret == NULL )
85  roar_err_update();
86
87 return ret;
88#else
89 ret = roar_mm_malloc(nmemb*size);
90 if ( ret == NULL )
91  return NULL;
92
93 memset(ret, 0, nmemb*size);
94
95 return ret;
96#endif
97}
98
99void * roar_mm_malloc(size_t size) {
100 void * ret;
101
102 if ( size == 0 ) {
103  _libroar_null_buffer_check();
104  return _libroar_null_buffer;
105 }
106
107#ifdef ROAR_HAVE_MALLOC
108 roar_err_clear_all();
109 ret = malloc(size);
110
111 if ( ret == NULL )
112  roar_err_update();
113
114 return ret;
115#elif defined(ROAR_HAVE_CALLOC)
116 return roar_mm_calloc(1, size);
117#elif defined(ROAR_HAVE_REALLOC)
118 return roar_mm_realloc(NULL, size);
119#else
120 _err(ROAR_ERROR_NOSYS);
121#endif
122}
123
124int    roar_mm_free(void *ptr) {
125
126 if ( ptr == _libroar_null_buffer ) {
127  _libroar_null_buffer_check();
128  return 0;
129 }
130
131#ifdef ROAR_HAVE_FREE
132 free(ptr);
133 return 0;
134#elif defined(ROAR_HAVE_REALLOC)
135 if ( roar_mm_realloc(ptr, 0) != _libroar_null_buffer )
136  return -1;
137 return 0;
138#else
139 roar_err_set(ROAR_ERROR_NOSYS);
140 return -1;
141#endif
142}
143
144void * roar_mm_realloc(void *ptr, size_t size) {
145 void * ret;
146#ifndef ROAR_HAVE_REALLOC
147 ssize_t len;
148#endif
149
150 if ( ptr == NULL )
151  return roar_mm_malloc(size);
152
153 if ( size == 0 ) {
154  roar_mm_free(ptr);
155  _libroar_null_buffer_check();
156  return _libroar_null_buffer;
157 }
158
159#ifdef ROAR_HAVE_REALLOC
160 roar_err_clear_all();
161 ret = realloc(ptr, size);
162
163 if ( ret == NULL )
164  roar_err_update();
165
166 return ret;
167#else
168 len = roar_mm_sizeof(ptr);
169 if ( len == -1 )
170  return NULL;
171
172 ret = roar_mm_malloc(size);
173 if ( ret == NULL )
174  return NULL;
175
176 memcpy(ret, ptr, len > (ssize_t)size ? size : len);
177
178 return ret;
179#endif
180}
181#endif
182
183void * roar_mm_memdup(const void * s, size_t len) {
184 void * ret;
185
186 if ( s == NULL )
187  _err(ROAR_ERROR_FAULT);
188
189#ifdef ROAR_USE_MEMMGR
190 if ( len == 0 ) {
191  _libroar_null_buffer_check();
192  return _libroar_null_buffer;
193 }
194#endif
195
196 ret = roar_mm_malloc(len);
197
198 if ( ret == NULL )
199  return NULL;
200
201 memcpy(ret, s, len);
202
203 return ret;
204}
205
206void roar_mm_free_retvoid(void *ptr) {
207 roar_mm_free(ptr);
208}
209
210#if defined(ROAR_USE_MEMMGR) || !defined(ROAR_HAVE_STRDUP)
211char * roar_mm_strdup(const char *s) {
212 void * ret;
213#ifndef ROAR_HAVE_STRDUP
214 ssize_t len;
215#endif
216
217 if ( s == NULL )
218  _err(ROAR_ERROR_FAULT);
219
220#ifdef ROAR_HAVE_STRDUP
221 roar_err_clear_all();
222 ret = strdup(s);
223
224 if ( ret == NULL )
225  roar_err_update();
226#else
227 len = roar_mm_strlen(s);
228 if ( len == -1 )
229  return NULL;
230
231 ret = roar_mm_memdup(s, len+1);
232#endif
233
234 return ret;
235}
236#endif
237
238#if defined(ROAR_USE_MEMMGR) || !defined(ROAR_HAVE_STRNDUP)
239char *roar_mm_strndup(const char *s, size_t n) {
240 void * ret;
241#ifndef ROAR_HAVE_STRNDUP
242 ssize_t len;
243#endif
244
245 if ( s == NULL )
246  _err(ROAR_ERROR_FAULT);
247
248#ifdef ROAR_USE_MEMMGR
249 if ( n == 0 ) {
250  _libroar_null_buffer_check();
251  return _libroar_null_buffer;
252 }
253#endif
254
255#ifdef ROAR_HAVE_STRNDUP
256 roar_err_clear_all();
257 ret = strndup(s, n);
258
259 if ( ret == NULL )
260  roar_err_update();
261#else
262 len = roar_mm_strnlen(s, n);
263 if ( len == -1 )
264  return NULL;
265
266 ret = roar_mm_memdup(s, len+1);
267#endif
268
269 return ret;
270}
271#endif
272
273char * roar_mm_strdup2(const char *s, const char *def) {
274 if ( s == NULL )
275  s = def;
276 if ( s == NULL ) {
277  roar_err_clear();
278  return NULL;
279 }
280
281 return roar_mm_strdup(s);
282}
283
284#ifndef ROAR_HAVE_STRLEN
285ssize_t roar_mm_strlen(const char *s) {
286 size_t ret = 0;
287
288 if ( s == NULL ) {
289  roar_err_set(ROAR_ERROR_FAULT);
290  return -1;
291 }
292
293 for (; *s != 0; s++, ret++);
294
295 return ret;
296}
297#endif
298
299ssize_t roar_mm_strnlen(const char *s, size_t maxlen) {
300 size_t ret = 0;
301
302 if ( s == NULL ) {
303  roar_err_set(ROAR_ERROR_FAULT);
304  return -1;
305 }
306
307#ifdef ROAR_HAVE_STRNLEN
308 ret = strnlen(s, maxlen);
309#else
310 for (; ret < maxlen && *s != 0; s++, ret++);
311#endif
312
313 if ( ret == maxlen ) {
314  roar_err_set(ROAR_ERROR_MSGSIZE);
315  return -1;
316 }
317
318 return ret;
319}
320
321
322#ifndef ROAR_HAVE_STRLCPY
323ssize_t roar_mm_strlcpy(char *dst, const char *src, size_t size) {
324 ssize_t len;
325
326 if ( dst == NULL || src == NULL ) {
327  roar_err_set(ROAR_ERROR_FAULT);
328  return -1;
329 }
330
331 if ( size == 0 )
332  return 0;
333
334 len = roar_mm_strlen(src);
335 if ( len == -1 )
336  return -1;
337
338 if ( len < (ssize_t)size ) {
339  memcpy(dst, src, len);
340  dst[len] = 0;
341 } else {
342  memcpy(dst, src, size - 1);
343  dst[size-1] = 0;
344 }
345
346 return len;
347}
348#endif
349
350#ifndef ROAR_HAVE_STRLCAT
351ssize_t roar_mm_strlcat(char *dst, const char *src, size_t size) {
352 ssize_t slen;
353 ssize_t dlen;
354 int err;
355
356 if ( dst == NULL || src == NULL ) {
357  roar_err_set(ROAR_ERROR_FAULT);
358  return -1;
359 }
360
361 if ( size == 0 )
362  return 0;
363
364 slen = roar_mm_strlen(src);
365 if ( slen == -1 )
366  return -1;
367
368 dlen = roar_mm_strnlen(dst, size);
369 err  = roar_error;
370 if ( dlen == -1 && err == ROAR_ERROR_MSGSIZE )
371  dlen = size;
372
373 if ( dlen == -1 )
374  return -1;
375
376 if ( (dlen + slen) < (ssize_t)size ) {
377  memcpy(dst+dlen, src, slen);
378  dst[dlen+slen] = 0;
379 } else if ( dlen != (ssize_t)size ) {
380  memcpy(dst+dlen, src, size-dlen-1);
381  dst[size-1] = 0;
382 }
383
384 return dlen+slen;
385}
386#endif
387
388#ifndef ROAR_HAVE_STRTOK_R
389char * roar_mm_strtok_r(char *str, const char *delim, char **saveptr) {
390 char * next;
391
392 if ( delim == NULL || saveptr == NULL ) {
393  roar_err_set(ROAR_ERROR_FAULT);
394  return NULL;
395 }
396
397 if ( delim[0] == 0 ) {
398  roar_err_set(ROAR_ERROR_NOTSUP);
399  return NULL;
400 }
401
402 if ( delim[1] != 0 ) {
403  roar_err_set(ROAR_ERROR_NOTSUP);
404  return NULL;
405 }
406
407 if ( str != NULL ) {
408  next = str;
409 } else {
410  next = *saveptr;
411 }
412
413 if ( next == NULL ) {
414  roar_err_set(ROAR_ERROR_NODATA);
415  return NULL;
416 }
417
418 *saveptr = strstr(next, delim);
419
420 if ( *saveptr != NULL ) {
421  **saveptr = 0;
422  (*saveptr)++;
423 }
424
425 return next;
426}
427#endif
428
429int roar_mm_strselcmp(const char *s1, const char *s2) {
430 register char a, b;
431
432 if ( s1 == s2 )
433  return 0;
434
435 if ( s1 == NULL || s2 == NULL )
436  return -1;
437
438 for (; ; s1++, s2++) {
439  a = *s1;
440  b = *s2;
441
442  if ( a == '*' ) {
443   s1++;
444   a = *s1;
445   if ( a == 0 ) {
446    if ( b == 0 ) {
447     return 1; // no match! ('*' does not mach no-chars)
448    } else {
449     return 0; // match! (string ends with '*' and something not EOS is in b)
450    }
451   } else {
452    for (; *s2 != 0 && *s2 != a; s2++);
453    if ( a != *s2 )
454     return 1; // no match! (did not find correct char)
455   }
456  } else if ( a == 0 || b == 0 ) {
457   if ( a == b ) {
458    return 0; // match!
459   } else {
460    return 1; // no match! (dffrent length)
461   }
462  } else if ( a != b ) {
463   return 1; // no match! (diffrent chars)
464  }
465 }
466
467 return -1;
468}
469
470ssize_t roar_mm_strseltok(const char *s1, char *s2, char ** tok, size_t toks) {
471 register char a, b;
472 size_t idx = 0;
473
474 if ( s1 == NULL || s2 == NULL )
475  return -1;
476
477 for (; ; s1++, s2++) {
478  a = *s1;
479  b = *s2;
480
481  if ( a == 0 || b == 0 ) {
482   if ( a == b ) {
483    return idx;
484   } else {
485    return -1;
486   }
487  } else if ( a == '*' ) {
488   s1++;
489   a = *s1;
490   if ( idx == toks )
491    return -1;
492
493   tok[idx] = s2;
494   idx++;
495
496   for (; *s2 != 0 && *s2 != a; s2++);
497
498   if ( a == 0 )
499    return idx;
500
501   if ( *s1 == 0 )
502    return -1;
503
504   *s2 = 0;
505  }
506 }
507
508 return -1;
509}
510
511//ll
Note: See TracBrowser for help on using the repository browser.