summaryrefslogtreecommitdiff
path: root/tools/ucl/src/ucl_init.c
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2005-11-27 23:41:55 +0000
committerJens Arnold <amiconn@rockbox.org>2005-11-27 23:41:55 +0000
commit7c21a96e9afa3408ca0b459a392275aa0ae77608 (patch)
tree9933c4012631b53e72478b14db6315dfcaba5c32 /tools/ucl/src/ucl_init.c
parentf04577377d879d040ef046c38f6ab18b84a51341 (diff)
downloadrockbox-7c21a96e9afa3408ca0b459a392275aa0ae77608.tar.gz
rockbox-7c21a96e9afa3408ca0b459a392275aa0ae77608.zip
Initial check-in of (stripped-down) UCL data compression library v 1.01
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8087 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'tools/ucl/src/ucl_init.c')
-rw-r--r--tools/ucl/src/ucl_init.c500
1 files changed, 500 insertions, 0 deletions
diff --git a/tools/ucl/src/ucl_init.c b/tools/ucl/src/ucl_init.c
new file mode 100644
index 0000000000..4798acae97
--- /dev/null
+++ b/tools/ucl/src/ucl_init.c
@@ -0,0 +1,500 @@
1/* ucl_init.c -- initialization of the UCL library
2
3 This file is part of the UCL data compression library.
4
5 Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
6 All Rights Reserved.
7
8 The UCL library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of
11 the License, or (at your option) any later version.
12
13 The UCL library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with the UCL library; see the file COPYING.
20 If not, write to the Free Software Foundation, Inc.,
21 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
23 Markus F.X.J. Oberhumer
24 <markus@oberhumer.com>
25 http://www.oberhumer.com/opensource/ucl/
26 */
27
28
29#include "ucl_conf.h"
30#include "ucl_util.h"
31#include <stdio.h>
32
33
34#if 0
35# define IS_SIGNED(type) (((type) (1ul << (8 * sizeof(type) - 1))) < 0)
36# define IS_UNSIGNED(type) (((type) (1ul << (8 * sizeof(type) - 1))) > 0)
37#else
38# define IS_SIGNED(type) (((type) (-1)) < ((type) 0))
39# define IS_UNSIGNED(type) (((type) (-1)) > ((type) 0))
40#endif
41
42
43/***********************************************************************
44// Runtime check of the assumptions about the size of builtin types,
45// memory model, byte order and other low-level constructs.
46//
47// We are really paranoid here - UCL should either fail (or crash)
48// at startup or not at all.
49//
50// Because of inlining much of these functions evaluates to nothing.
51************************************************************************/
52
53static ucl_bool schedule_insns_bug(void); /* avoid inlining */
54static ucl_bool strength_reduce_bug(int *); /* avoid inlining */
55
56
57#if 0 || defined(UCL_DEBUG)
58static ucl_bool __ucl_assert_fail(const char *s, unsigned line)
59{
60#if defined(__palmos__)
61 printf("UCL assertion failed in line %u: '%s'\n",line,s);
62#else
63 fprintf(stderr,"UCL assertion failed in line %u: '%s'\n",line,s);
64#endif
65 return 0;
66}
67# define __ucl_assert(x) ((x) ? 1 : __ucl_assert_fail(#x,__LINE__))
68#else
69# define __ucl_assert(x) ((x) ? 1 : 0)
70#endif
71
72
73/***********************************************************************
74// The next two functions should get completely optimized out of existance.
75// Some assertions are redundant - but included for clarity.
76************************************************************************/
77
78static ucl_bool basic_integral_check(void)
79{
80 ucl_bool r = 1;
81 ucl_bool sanity;
82
83 /* paranoia */
84 r &= __ucl_assert(CHAR_BIT == 8);
85 r &= __ucl_assert(sizeof(char) == 1);
86 r &= __ucl_assert(sizeof(short) >= 2);
87 r &= __ucl_assert(sizeof(long) >= 4);
88 r &= __ucl_assert(sizeof(int) >= sizeof(short));
89 r &= __ucl_assert(sizeof(long) >= sizeof(int));
90
91 r &= __ucl_assert(sizeof(ucl_uint32) >= 4);
92 r &= __ucl_assert(sizeof(ucl_uint32) >= sizeof(unsigned));
93#if defined(__UCL_STRICT_16BIT)
94 r &= __ucl_assert(sizeof(ucl_uint) == 2);
95#else
96 r &= __ucl_assert(sizeof(ucl_uint) >= 4);
97 r &= __ucl_assert(sizeof(ucl_uint) >= sizeof(unsigned));
98#endif
99
100#if defined(SIZEOF_UNSIGNED)
101 r &= __ucl_assert(SIZEOF_UNSIGNED == sizeof(unsigned));
102#endif
103#if defined(SIZEOF_UNSIGNED_LONG)
104 r &= __ucl_assert(SIZEOF_UNSIGNED_LONG == sizeof(unsigned long));
105#endif
106#if defined(SIZEOF_UNSIGNED_SHORT)
107 r &= __ucl_assert(SIZEOF_UNSIGNED_SHORT == sizeof(unsigned short));
108#endif
109#if !defined(__UCL_IN_MINIUCL)
110#if defined(SIZEOF_SIZE_T)
111 r &= __ucl_assert(SIZEOF_SIZE_T == sizeof(size_t));
112#endif
113#endif
114
115 /* assert the signedness of our integral types */
116 sanity = IS_UNSIGNED(unsigned short) && IS_UNSIGNED(unsigned) &&
117 IS_UNSIGNED(unsigned long) &&
118 IS_SIGNED(short) && IS_SIGNED(int) && IS_SIGNED(long);
119 if (sanity)
120 {
121 r &= __ucl_assert(IS_UNSIGNED(ucl_uint32));
122 r &= __ucl_assert(IS_UNSIGNED(ucl_uint));
123 r &= __ucl_assert(IS_SIGNED(ucl_int32));
124 r &= __ucl_assert(IS_SIGNED(ucl_int));
125
126 r &= __ucl_assert(INT_MAX == UCL_STYPE_MAX(sizeof(int)));
127 r &= __ucl_assert(UINT_MAX == UCL_UTYPE_MAX(sizeof(unsigned)));
128 r &= __ucl_assert(LONG_MAX == UCL_STYPE_MAX(sizeof(long)));
129 r &= __ucl_assert(ULONG_MAX == UCL_UTYPE_MAX(sizeof(unsigned long)));
130 r &= __ucl_assert(SHRT_MAX == UCL_STYPE_MAX(sizeof(short)));
131 r &= __ucl_assert(USHRT_MAX == UCL_UTYPE_MAX(sizeof(unsigned short)));
132 r &= __ucl_assert(UCL_UINT32_MAX == UCL_UTYPE_MAX(sizeof(ucl_uint32)));
133 r &= __ucl_assert(UCL_UINT_MAX == UCL_UTYPE_MAX(sizeof(ucl_uint)));
134#if !defined(__UCL_IN_MINIUCL)
135 r &= __ucl_assert(SIZE_T_MAX == UCL_UTYPE_MAX(sizeof(size_t)));
136#endif
137 }
138
139 return r;
140}
141
142
143static ucl_bool basic_ptr_check(void)
144{
145 ucl_bool r = 1;
146 ucl_bool sanity;
147
148 r &= __ucl_assert(sizeof(char *) >= sizeof(int));
149 r &= __ucl_assert(sizeof(ucl_byte *) >= sizeof(char *));
150
151 r &= __ucl_assert(sizeof(ucl_voidp) == sizeof(ucl_byte *));
152 r &= __ucl_assert(sizeof(ucl_voidp) == sizeof(ucl_voidpp));
153 r &= __ucl_assert(sizeof(ucl_voidp) == sizeof(ucl_bytepp));
154 r &= __ucl_assert(sizeof(ucl_voidp) >= sizeof(ucl_uint));
155
156 r &= __ucl_assert(sizeof(ucl_ptr_t) == sizeof(ucl_voidp));
157 r &= __ucl_assert(sizeof(ucl_ptr_t) >= sizeof(ucl_uint));
158
159 r &= __ucl_assert(sizeof(ucl_ptrdiff_t) >= 4);
160 r &= __ucl_assert(sizeof(ucl_ptrdiff_t) >= sizeof(ptrdiff_t));
161
162#if defined(SIZEOF_CHAR_P)
163 r &= __ucl_assert(SIZEOF_CHAR_P == sizeof(char *));
164#endif
165#if defined(SIZEOF_PTRDIFF_T)
166 r &= __ucl_assert(SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t));
167#endif
168
169 /* assert the signedness of our integral types */
170 sanity = IS_UNSIGNED(unsigned short) && IS_UNSIGNED(unsigned) &&
171 IS_UNSIGNED(unsigned long) &&
172 IS_SIGNED(short) && IS_SIGNED(int) && IS_SIGNED(long);
173 if (sanity)
174 {
175 r &= __ucl_assert(IS_UNSIGNED(ucl_ptr_t));
176 r &= __ucl_assert(IS_SIGNED(ucl_ptrdiff_t));
177 r &= __ucl_assert(IS_SIGNED(ucl_sptr_t));
178 }
179
180 return r;
181}
182
183
184/***********************************************************************
185//
186************************************************************************/
187
188static ucl_bool ptr_check(void)
189{
190 ucl_bool r = 1;
191 int i;
192 char _wrkmem[10 * sizeof(ucl_byte *) + sizeof(ucl_align_t)];
193 ucl_bytep wrkmem;
194 ucl_bytepp dict;
195 unsigned char x[4 * sizeof(ucl_align_t)];
196 long d;
197 ucl_align_t a;
198 ucl_align_t u;
199
200 for (i = 0; i < (int) sizeof(x); i++)
201 x[i] = UCL_BYTE(i);
202
203 wrkmem = UCL_PTR_ALIGN_UP((ucl_byte *)_wrkmem,sizeof(ucl_align_t));
204
205#if 0
206 dict = (ucl_bytepp) wrkmem;
207#else
208 /* Avoid a compiler warning on architectures that
209 * do not allow unaligned access. */
210 u.a_ucl_bytep = wrkmem; dict = u.a_ucl_bytepp;
211#endif
212
213 d = (long) ((const ucl_bytep) dict - (const ucl_bytep) _wrkmem);
214 r &= __ucl_assert(d >= 0);
215 r &= __ucl_assert(d < (long) sizeof(ucl_align_t));
216
217 memset(&a,0xff,sizeof(a));
218 r &= __ucl_assert(a.a_ushort == USHRT_MAX);
219 r &= __ucl_assert(a.a_uint == UINT_MAX);
220 r &= __ucl_assert(a.a_ulong == ULONG_MAX);
221 r &= __ucl_assert(a.a_ucl_uint == UCL_UINT_MAX);
222
223 /* sanity check of the memory model */
224 if (r == 1)
225 {
226 for (i = 0; i < 8; i++)
227 r &= __ucl_assert((const ucl_voidp) (&dict[i]) == (const ucl_voidp) (&wrkmem[i * sizeof(ucl_byte *)]));
228 }
229
230 /* check BZERO8_PTR and that NULL == 0 */
231 memset(&a,0,sizeof(a));
232 r &= __ucl_assert(a.a_char_p == NULL);
233 r &= __ucl_assert(a.a_ucl_bytep == NULL);
234 r &= __ucl_assert(NULL == (void*)0);
235 if (r == 1)
236 {
237 for (i = 0; i < 10; i++)
238 dict[i] = wrkmem;
239 BZERO8_PTR(dict+1,sizeof(dict[0]),8);
240 r &= __ucl_assert(dict[0] == wrkmem);
241 for (i = 1; i < 9; i++)
242 r &= __ucl_assert(dict[i] == NULL);
243 r &= __ucl_assert(dict[9] == wrkmem);
244 }
245
246 /* check that the pointer constructs work as expected */
247 if (r == 1)
248 {
249 unsigned k = 1;
250 const unsigned n = (unsigned) sizeof(ucl_uint32);
251 ucl_byte *p0;
252 ucl_byte *p1;
253
254 k += __ucl_align_gap(&x[k],n);
255 p0 = (ucl_bytep) &x[k];
256#if defined(PTR_LINEAR)
257 r &= __ucl_assert((PTR_LINEAR(p0) & (n-1)) == 0);
258#else
259 r &= __ucl_assert(n == 4);
260 r &= __ucl_assert(PTR_ALIGNED_4(p0));
261#endif
262
263 r &= __ucl_assert(k >= 1);
264 p1 = (ucl_bytep) &x[1];
265 r &= __ucl_assert(PTR_GE(p0,p1));
266
267 r &= __ucl_assert(k < 1+n);
268 p1 = (ucl_bytep) &x[1+n];
269 r &= __ucl_assert(PTR_LT(p0,p1));
270
271 /* now check that aligned memory access doesn't core dump */
272 if (r == 1)
273 {
274 ucl_uint32 v0, v1;
275#if 0
276 v0 = * (ucl_uint32 *) &x[k];
277 v1 = * (ucl_uint32 *) &x[k+n];
278#else
279 /* Avoid compiler warnings on architectures that
280 * do not allow unaligned access. */
281 u.a_uchar_p = &x[k];
282 v0 = *u.a_ucl_uint32_p;
283 u.a_uchar_p = &x[k+n];
284 v1 = *u.a_ucl_uint32_p;
285#endif
286 r &= __ucl_assert(v0 > 0);
287 r &= __ucl_assert(v1 > 0);
288 }
289 }
290
291 return r;
292}
293
294
295/***********************************************************************
296//
297************************************************************************/
298
299UCL_PUBLIC(int)
300_ucl_config_check(void)
301{
302 ucl_bool r = 1;
303 int i;
304 union {
305 ucl_uint32 a;
306 unsigned short b;
307 ucl_uint32 aa[4];
308 unsigned char x[4*sizeof(ucl_align_t)];
309 } u;
310
311#if 0
312 /* paranoia - the following is guaranteed by definition anyway */
313 r &= __ucl_assert((const void *)&u == (const void *)&u.a);
314 r &= __ucl_assert((const void *)&u == (const void *)&u.b);
315 r &= __ucl_assert((const void *)&u == (const void *)&u.x[0]);
316 r &= __ucl_assert((const void *)&u == (const void *)&u.aa[0]);
317#endif
318
319 r &= basic_integral_check();
320 r &= basic_ptr_check();
321 if (r != 1)
322 return UCL_E_ERROR;
323
324 u.a = 0; u.b = 0;
325 for (i = 0; i < (int) sizeof(u.x); i++)
326 u.x[i] = UCL_BYTE(i);
327
328#if 0
329 /* check if the compiler correctly casts signed to unsigned */
330 r &= __ucl_assert( (int) (unsigned char) ((char) -1) == 255);
331#endif
332
333 /* check UCL_BYTE_ORDER */
334#if defined(UCL_BYTE_ORDER)
335 if (r == 1)
336 {
337# if (UCL_BYTE_ORDER == UCL_LITTLE_ENDIAN)
338 ucl_uint32 a = (ucl_uint32) (u.a & UCL_UINT32_C(0xffffffff));
339 unsigned short b = (unsigned short) (u.b & 0xffff);
340 r &= __ucl_assert(a == UCL_UINT32_C(0x03020100));
341 r &= __ucl_assert(b == 0x0100);
342# elif (UCL_BYTE_ORDER == UCL_BIG_ENDIAN)
343 ucl_uint32 a = u.a >> (8 * sizeof(u.a) - 32);
344 unsigned short b = u.b >> (8 * sizeof(u.b) - 16);
345 r &= __ucl_assert(a == UCL_UINT32_C(0x00010203));
346 r &= __ucl_assert(b == 0x0001);
347# else
348# error "invalid UCL_BYTE_ORDER"
349# endif
350 }
351#endif
352
353 /* check that unaligned memory access works as expected */
354#if defined(UCL_UNALIGNED_OK_2)
355 r &= __ucl_assert(sizeof(short) == 2);
356 if (r == 1)
357 {
358 unsigned short b[4];
359
360 for (i = 0; i < 4; i++)
361 b[i] = * (const unsigned short *) &u.x[i];
362
363# if (UCL_BYTE_ORDER == UCL_LITTLE_ENDIAN)
364 r &= __ucl_assert(b[0] == 0x0100);
365 r &= __ucl_assert(b[1] == 0x0201);
366 r &= __ucl_assert(b[2] == 0x0302);
367 r &= __ucl_assert(b[3] == 0x0403);
368# elif (UCL_BYTE_ORDER == UCL_BIG_ENDIAN)
369 r &= __ucl_assert(b[0] == 0x0001);
370 r &= __ucl_assert(b[1] == 0x0102);
371 r &= __ucl_assert(b[2] == 0x0203);
372 r &= __ucl_assert(b[3] == 0x0304);
373# endif
374 }
375#endif
376
377#if defined(UCL_UNALIGNED_OK_4)
378 r &= __ucl_assert(sizeof(ucl_uint32) == 4);
379 if (r == 1)
380 {
381 ucl_uint32 a[4];
382
383 for (i = 0; i < 4; i++)
384 a[i] = * (const ucl_uint32 *) &u.x[i];
385
386# if (UCL_BYTE_ORDER == UCL_LITTLE_ENDIAN)
387 r &= __ucl_assert(a[0] == UCL_UINT32_C(0x03020100));
388 r &= __ucl_assert(a[1] == UCL_UINT32_C(0x04030201));
389 r &= __ucl_assert(a[2] == UCL_UINT32_C(0x05040302));
390 r &= __ucl_assert(a[3] == UCL_UINT32_C(0x06050403));
391# elif (UCL_BYTE_ORDER == UCL_BIG_ENDIAN)
392 r &= __ucl_assert(a[0] == UCL_UINT32_C(0x00010203));
393 r &= __ucl_assert(a[1] == UCL_UINT32_C(0x01020304));
394 r &= __ucl_assert(a[2] == UCL_UINT32_C(0x02030405));
395 r &= __ucl_assert(a[3] == UCL_UINT32_C(0x03040506));
396# endif
397 }
398#endif
399
400#if defined(UCL_ALIGNED_OK_4)
401 r &= __ucl_assert(sizeof(ucl_uint32) == 4);
402#endif
403
404 /* check the ucl_adler32() function */
405 if (r == 1)
406 {
407 ucl_uint32 adler;
408 adler = ucl_adler32(0, NULL, 0);
409 adler = ucl_adler32(adler, ucl_copyright(), 186);
410 r &= __ucl_assert(adler == UCL_UINT32_C(0x47fb39fc));
411 }
412
413 /* check for the gcc schedule-insns optimization bug */
414 if (r == 1)
415 {
416 r &= __ucl_assert(!schedule_insns_bug());
417 }
418
419 /* check for the gcc strength-reduce optimization bug */
420 if (r == 1)
421 {
422 static int x[3];
423 static unsigned xn = 3;
424 register unsigned j;
425
426 for (j = 0; j < xn; j++)
427 x[j] = (int)j - 3;
428 r &= __ucl_assert(!strength_reduce_bug(x));
429 }
430
431 /* now for the low-level pointer checks */
432 if (r == 1)
433 {
434 r &= ptr_check();
435 }
436
437 return r == 1 ? UCL_E_OK : UCL_E_ERROR;
438}
439
440
441static ucl_bool schedule_insns_bug(void)
442{
443#if defined(__UCL_CHECKER)
444 /* for some reason checker complains about uninitialized memory access */
445 return 0;
446#else
447 const int clone[] = {1, 2, 0};
448 const int *q;
449 q = clone;
450 return (*q) ? 0 : 1;
451#endif
452}
453
454
455static ucl_bool strength_reduce_bug(int *x)
456{
457 return x[0] != -3 || x[1] != -2 || x[2] != -1;
458}
459
460
461/***********************************************************************
462//
463************************************************************************/
464
465int __ucl_init_done = 0;
466
467UCL_PUBLIC(int)
468__ucl_init2(ucl_uint32 v, int s1, int s2, int s3, int s4, int s5,
469 int s6, int s7, int s8, int s9)
470{
471 int r;
472
473 __ucl_init_done = 1;
474
475 if (v == 0)
476 return UCL_E_ERROR;
477
478 r = (s1 == -1 || s1 == (int) sizeof(short)) &&
479 (s2 == -1 || s2 == (int) sizeof(int)) &&
480 (s3 == -1 || s3 == (int) sizeof(long)) &&
481 (s4 == -1 || s4 == (int) sizeof(ucl_uint32)) &&
482 (s5 == -1 || s5 == (int) sizeof(ucl_uint)) &&
483 (s6 == -1 || s6 > 0) &&
484 (s7 == -1 || s7 == (int) sizeof(char *)) &&
485 (s8 == -1 || s8 == (int) sizeof(ucl_voidp)) &&
486 (s9 == -1 || s9 == (int) sizeof(ucl_compress_t));
487 if (!r)
488 return UCL_E_ERROR;
489
490 r = _ucl_config_check();
491 if (r != UCL_E_OK)
492 return r;
493
494 return r;
495}
496
497
498/*
499vi:ts=4:et
500*/