satsolver  0.17.2
util.c
Go to the documentation of this file.
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 /* bsd's qsort_r has different arguments, so we define our
102  own version in case we need to do some clever mapping
103 
104  see also: http://sources.redhat.com/ml/libc-alpha/2008-12/msg00003.html
105  */
106 #if defined(__GLIBC__)
107 
108 # if HAVE_QSORT_R || HAVE___QSORT_R
109 void
110 sat_sort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *compard)
111 {
112 # if HAVE_QSORT_R
113  qsort_r(base, nmemb, size, compar, compard);
114 # else
115  /* backported for SLE10-SP2 */
116  __qsort_r(base, nmemb, size, compar, compard);
117 # endif
118 
119 }
120 #else /* qsort_r or __qsort_r on glibc */
121 /* use own version of qsort if none available */
122 #include "qsort_r.c"
123 #endif
124 
125 #else /* not glibc */
126 
128  int (*compar)(const void *, const void *, void *);
129  void *compard;
130 };
131 
132 static int
133 sat_sort_helper(void *compard, const void *a, const void *b)
134 {
135  struct sat_sort_data *d = compard;
136  return (*d->compar)(a, b, d->compard);
137 }
138 
139 void
140 sat_sort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *compard)
141 {
142  struct sat_sort_data d;
143  d.compar = compar;
144  d.compard = compard;
145  qsort_r(base, nmemb, size, &d, sat_sort_helper);
146 }
147 
148 #endif
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 }
177 
178 char *
179 sat_dupappend(const char *str1, const char *str2, const char *str3)
180 {
181  char *str = sat_dupjoin(str1, str2, str3);
182  sat_free((void *)str1);
183  return str;
184 }
185 
186 int
187 sat_hex2bin(const char **strp, unsigned char *buf, int bufl)
188 {
189  const char *str = *strp;
190  int i;
191 
192  for (i = 0; i < bufl; i++)
193  {
194  int c = *str;
195  int d;
196  if (c >= '0' && c <= '9')
197  d = c - '0';
198  else if (c >= 'a' && c <= 'f')
199  d = c - ('a' - 10);
200  else if (c >= 'A' && c <= 'F')
201  d = c - ('A' - 10);
202  else
203  break;
204  c = *++str;
205  d <<= 4;
206  if (c >= '0' && c <= '9')
207  d |= c - '0';
208  else if (c >= 'a' && c <= 'f')
209  d |= c - ('a' - 10);
210  else if (c >= 'A' && c <= 'F')
211  d |= c - ('A' - 10);
212  else
213  break;
214  buf[i] = d;
215  ++str;
216  }
217  *strp = str;
218  return i;
219 }
220 
221 char *
222 sat_bin2hex(const unsigned char *buf, int l, char *str)
223 {
224  int i;
225  for (i = 0; i < l; i++, buf++)
226  {
227  int c = *buf >> 4;
228  *str++ = c < 10 ? c + '0' : c + ('a' - 10);
229  c = *buf & 15;
230  *str++ = c < 10 ? c + '0' : c + ('a' - 10);
231  }
232  *str = 0;
233  return str;
234 }
235 
236