- rename to USE_OWN_QSORT, add bsd qsort_r helper
[platform/upstream/libsolv.git] / src / util.c
1 /*
2  * Copyright (c) 2007, Novell Inc.
3  *
4  * This program is licensed under the BSD license, read LICENSE.BSD
5  * for further information
6  */
7
8 #define _GNU_SOURCE
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <string.h>
14 #include <sys/time.h>
15
16 #include "util.h"
17
18 void
19 sat_oom(size_t num, size_t len)
20 {
21   if (num)
22     fprintf(stderr, "Out of memory allocating %zu*%zu bytes!\n", num, len);
23   else
24     fprintf(stderr, "Out of memory allocating %zu bytes!\n", len);
25   abort();
26   exit(1);
27 }
28
29 void *
30 sat_malloc(size_t len)
31 {
32   void *r = malloc(len ? len : 1);
33   if (!r)
34     sat_oom(0, len);
35   return r;
36 }
37
38 void *
39 sat_malloc2(size_t num, size_t len)
40 {
41   if (len && (num * len) / len != num)
42     sat_oom(num, len);
43   return sat_malloc(num * len);
44 }
45
46 void *
47 sat_realloc(void *old, size_t len)
48 {
49   if (old == 0)
50     old = malloc(len ? len : 1);
51   else
52     old = realloc(old, len ? len : 1);
53   if (!old)
54     sat_oom(0, len);
55   return old;
56 }
57
58 void *
59 sat_realloc2(void *old, size_t num, size_t len)
60 {
61   if (len && (num * len) / len != num)
62     sat_oom(num, len);
63   return sat_realloc(old, num * len);
64 }
65
66 void *
67 sat_calloc(size_t num, size_t len)
68 {
69   void *r;
70   if (num == 0 || len == 0)
71     r = malloc(1);
72   else
73     r = calloc(num, len);
74   if (!r)
75     sat_oom(num, len);
76   return r;
77 }
78
79 void *
80 sat_free(void *mem)
81 {
82   if (mem)
83     free(mem);
84   return 0;
85 }
86
87 unsigned int
88 sat_timems(unsigned int subtract)
89 {
90   struct timeval tv;
91   unsigned int r;
92
93   if (gettimeofday(&tv, 0))
94     return 0;
95   r = (((unsigned int)tv.tv_sec >> 16) * 1000) << 16;
96   r += ((unsigned int)tv.tv_sec & 0xffff) * 1000;
97   r += (unsigned int)tv.tv_usec / 1000;
98   return r - subtract;
99 }
100
101 #ifdef USE_OWN_QSORT
102 #include "qsort_r.c"
103 #else
104
105 /* bsd's qsort_r has different arguments, so we define our
106    own version in case we need to do some clever mapping
107  
108    see also: http://sources.redhat.com/ml/libc-alpha/2008-12/msg00003.html
109  */
110 #if defined(__GLIBC__)
111
112 void
113 sat_sort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *compard)
114 {
115 # if __GLIBC_PREREQ(2, 8)
116   qsort_r(base, nmemb, size, compar, compard);
117 # else
118   /* backported for SLE10-SP2 */
119   __qsort_r(base, nmemb, size, compar, compard);
120 # endif
121 }
122
123 #else
124
125 struct sat_sort_data {
126   int (*compar)(const void *, const void *, void *);
127   void *compard;
128 };
129
130 static int
131 sat_sort_helper(void *compard, const void *a, const void *b)
132 {
133   struct sat_sort_data *d = compard;
134   return (*d->compar)(a, b, d->compard);
135 }
136
137 void
138 sat_sort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *compard)
139 {
140   struct sat_sort_data d;
141   d.compar = compar;
142   d.compard = compard;
143   qsort_r(base, nmemb, size, &d, sat_sort_helper);
144 }
145
146 #endif
147
148 #endif  /* USE_OWN_QSORT */
149
150 char *
151 sat_dupjoin(const char *str1, const char *str2, const char *str3)
152 {
153   int l1, l2, l3;
154   char *s, *str;
155   l1 = str1 ? strlen(str1) : 0;
156   l2 = str2 ? strlen(str2) : 0;
157   l3 = str3 ? strlen(str3) : 0;
158   s = str = sat_malloc(l1 + l2 + l3 + 1);
159   if (l1)
160     {
161       strcpy(s, str1);
162       s += l1;
163     }
164   if (l2)
165     {
166       strcpy(s, str2);
167       s += l2;
168     }
169   if (l3)
170     {
171       strcpy(s, str3);
172       s += l3;
173     }
174   *s = 0;
175   return str;
176 }