- /* ucl_init.c -- initialization of the UCL library 
-   
-    This file is part of the UCL data compression library. 
-   
-    Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer 
-    All Rights Reserved. 
-   
-    The UCL library is free software; you can redistribute it and/or 
-    modify it under the terms of the GNU General Public License as 
-    published by the Free Software Foundation; either version 2 of 
-    the License, or (at your option) any later version. 
-   
-    The UCL library is distributed in the hope that it will be useful, 
-    but WITHOUT ANY WARRANTY; without even the implied warranty of 
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
-    GNU General Public License for more details. 
-   
-    You should have received a copy of the GNU General Public License 
-    along with the UCL library; see the file COPYING. 
-    If not, write to the Free Software Foundation, Inc., 
-    59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
-   
-    Markus F.X.J. Oberhumer 
-    <markus@oberhumer.com> 
-    http://www.oberhumer.com/opensource/ucl/ 
-  */ 
-   
-   
- #include "ucl_conf.h" 
-   
-   
- /*********************************************************************** 
- // Runtime check of the assumptions about the size of builtin types, 
- // memory model, byte order and other low-level constructs. 
- // 
- // We are really paranoid here - UCL should either fail 
- // at startup or not at all. 
- // 
- // Because of inlining much of this evaluates to nothing at compile time. 
- // 
- // And while many of the tests seem highly obvious and redundant they are 
- // here to catch compiler/optimizer bugs. Yes, these do exist. 
- ************************************************************************/ 
-   
- static ucl_bool schedule_insns_bug(void);   /* avoid inlining */ 
- static ucl_bool strength_reduce_bug(int *); /* avoid inlining */ 
-   
-   
- #if 0 || defined(UCL_DEBUG) 
- #include <stdio.h> 
- static ucl_bool __ucl_assert_fail(const char *s, unsigned line) 
- { 
- #if defined(__palmos__) 
-     printf("UCL assertion failed in line %u: '%s'\n",- line ,- s );
 
- #else 
-     fprintf(- stderr ,"UCL assertion failed in line %u: '%s'\n",- line ,- s );
 
- #endif 
-     return 0; 
- } 
- #  define __ucl_assert(x)   ((x) ? 1 : __ucl_assert_fail(#x,__LINE__)) 
- #else 
- #  define __ucl_assert(x)   ((x) ? 1 : 0) 
- #endif 
-   
-   
- /*********************************************************************** 
- // basic_check - compile time assertions 
- ************************************************************************/ 
-   
- #if 1 
-   
- #undef ACCCHK_ASSERT 
- #define ACCCHK_ASSERT(expr)     ACC_COMPILE_TIME_ASSERT_HEADER(expr) 
-   
- #include "acc/acc_chk.ch" 
-   
-     ACCCHK_ASSERT_IS_SIGNED_T(ucl_int) 
-     ACCCHK_ASSERT_IS_UNSIGNED_T(ucl_uint) 
-   
-     ACCCHK_ASSERT_IS_SIGNED_T(ucl_int32) 
-     ACCCHK_ASSERT_IS_UNSIGNED_T(ucl_uint32) 
-     ACCCHK_ASSERT((UCL_UINT32_C(1) << (int)(8*sizeof(UCL_UINT32_C(1))-1)) > 0) 
-   
-     ACCCHK_ASSERT_IS_UNSIGNED_T(ucl_uintptr_t) 
-     ACCCHK_ASSERT(sizeof(ucl_uintptr_t) >= sizeof(ucl_voidp)) 
-   
- #endif 
- #undef ACCCHK_ASSERT 
-   
-   
- /*********************************************************************** 
- // 
- ************************************************************************/ 
-   
- static ucl_bool ptr_check(void) 
- { 
-     ucl_bool r = 1; 
-     int i; 
-     unsigned char _wrkmem[10 * sizeof(ucl_bytep) + sizeof(ucl_align_t)]; 
-     ucl_bytep wrkmem; 
-     ucl_bytepp dict; 
-     unsigned char x[4 * sizeof(ucl_align_t)]; 
-     long d; 
-     ucl_align_t a; 
-   
-     for (i = 0; i < (int) sizeof(x); i++) 
-         x[i] = UCL_BYTE(i); 
-   
-     wrkmem = UCL_PTR_ALIGN_UP((ucl_bytep)_wrkmem, sizeof(ucl_align_t)); 
-   
-     dict = (ucl_bytepp) (ucl_voidp) wrkmem; 
-   
-     d = (long) ((const ucl_bytep) dict - (const ucl_bytep) _wrkmem); 
-     r &= __ucl_assert(d >= 0); 
-     r &= __ucl_assert(d < (long) sizeof(ucl_align_t)); 
-   
-     /* this may seem obvious, but some compilers incorrectly inline memset */ 
-     r &= __ucl_assert(a.a_ushort == USHRT_MAX); 
-     r &= __ucl_assert(a.a_uint == UINT_MAX); 
-     r &= __ucl_assert(a.a_ulong == ULONG_MAX); 
-     r &= __ucl_assert(a.a_ucl_uint == UCL_UINT_MAX); 
-   
-     /* sanity check of the memory model */ 
-     if (r == 1) 
-     { 
-         for (i = 0; i < 8; i++) 
-             r &= __ucl_assert((const ucl_voidp) (&dict[i]) == (const ucl_voidp) (&wrkmem[i * sizeof(ucl_bytep)])); 
-     } 
-   
-     /* check that NULL == 0 */ 
-     r &= __ucl_assert(a.a_char_p == NULL); 
-     r &= __ucl_assert(a.a_ucl_bytep == NULL); 
-   
-     /* check that the pointer constructs work as expected */ 
-     if (r == 1) 
-     { 
-         unsigned k = 1; 
-         const unsigned n = (unsigned) sizeof(ucl_uint32); 
-         ucl_bytep p0; 
-         ucl_bytep p1; 
-   
-         k += __ucl_align_gap(&x[k],n); 
-         p0 = (ucl_bytep) &x[k]; 
- #if defined(PTR_LINEAR) 
-         r &= __ucl_assert((PTR_LINEAR(p0) & (n-1)) == 0); 
- #else 
-         r &= __ucl_assert(n == 4); 
-         r &= __ucl_assert(PTR_ALIGNED_4(p0)); 
- #endif 
-   
-         r &= __ucl_assert(k >= 1); 
-         p1 = (ucl_bytep) &x[1]; 
-         r &= __ucl_assert(PTR_GE(p0,p1)); 
-   
-         r &= __ucl_assert(k < 1u+n); 
-         p1 = (ucl_bytep) &x[1+n]; 
-         r &= __ucl_assert(PTR_LT(p0,p1)); 
-   
-         /* now check that aligned memory access doesn't core dump */ 
-         if (r == 1) 
-         { 
-             ucl_uint32 v0, v1; 
-             v0 = * (ucl_uint32p) (ucl_voidp) &x[k]; 
-             v1 = * (ucl_uint32p) (ucl_voidp) &x[k+n]; 
-             r &= __ucl_assert(v0 > 0); 
-             r &= __ucl_assert(v1 > 0); 
-         } 
-     } 
-   
-     return r; 
- } 
-   
-   
- /*********************************************************************** 
- // 
- ************************************************************************/ 
-   
- UCL_PUBLIC(int) 
- _ucl_config_check(void) 
- { 
-     ucl_bool r = 1; 
-     int i; 
-     union { 
-         ucl_uint32 a; 
-         unsigned short b; 
-         ucl_uint32 aa[4]; 
-         unsigned char x[4*sizeof(ucl_align_t)]; 
-     } u; 
-   
-     u.a = 0; u.b = 0; 
-     for (i = 0; i < (int) sizeof(u.x); i++) 
-         u.x[i] = UCL_BYTE(i); 
-   
- #if defined(ACC_ENDIAN_BIG_ENDIAN) || defined(ACC_ENDIAN_LITTLE_ENDIAN) 
-     if (r == 1) 
-     { 
- #  if defined(ACC_ENDIAN_BIG_ENDIAN) 
-         ucl_uint32 a = u.a >> (8 * sizeof(u.a) - 32); 
-         unsigned short b = u.b >> (8 * sizeof(u.b) - 16); 
-         r &= __ucl_assert(a == UCL_UINT32_C(0x00010203)); 
-         r &= __ucl_assert(b == 0x0001); 
- #  endif 
- #  if defined(ACC_ENDIAN_LITTLE_ENDIAN) 
-         ucl_uint32 a = (ucl_uint32) (u.a & UCL_UINT32_C(0xffffffff)); 
-         unsigned short b = (unsigned short) (u.b & 0xffff); 
-         r &= __ucl_assert(a == UCL_UINT32_C(0x03020100)); 
-         r &= __ucl_assert(b == 0x0100); 
- #  endif 
-     } 
- #endif 
-   
-     /* check that unaligned memory access works as expected */ 
- #if defined(UA_GET2) || defined(UA_SET2) 
-     if (r == 1) 
-     { 
-         unsigned short b[4]; 
-         for (i = 0; i < 4; i++) 
-             b[i] = UA_GET2(&u.x[i]); 
- #  if defined(ACC_ENDIAN_LITTLE_ENDIAN) 
-         r &= __ucl_assert(b[0] == 0x0100); 
-         r &= __ucl_assert(b[1] == 0x0201); 
-         r &= __ucl_assert(b[2] == 0x0302); 
-         r &= __ucl_assert(b[3] == 0x0403); 
- #  endif 
- #  if defined(ACC_ENDIAN_BIG_ENDIAN) 
-         r &= __ucl_assert(b[0] == 0x0001); 
-         r &= __ucl_assert(b[1] == 0x0102); 
-         r &= __ucl_assert(b[2] == 0x0203); 
-         r &= __ucl_assert(b[3] == 0x0304); 
- #  endif 
-     } 
- #endif 
-   
- #if defined(UA_GET4) || defined(UA_SET4) 
-     if (r == 1) 
-     { 
-         ucl_uint32 a[4]; 
-         for (i = 0; i < 4; i++) 
-             a[i] = UA_GET4(&u.x[i]); 
- #  if defined(ACC_ENDIAN_LITTLE_ENDIAN) 
-         r &= __ucl_assert(a[0] == UCL_UINT32_C(0x03020100)); 
-         r &= __ucl_assert(a[1] == UCL_UINT32_C(0x04030201)); 
-         r &= __ucl_assert(a[2] == UCL_UINT32_C(0x05040302)); 
-         r &= __ucl_assert(a[3] == UCL_UINT32_C(0x06050403)); 
- #  endif 
- #  if defined(ACC_ENDIAN_BIG_ENDIAN) 
-         r &= __ucl_assert(a[0] == UCL_UINT32_C(0x00010203)); 
-         r &= __ucl_assert(a[1] == UCL_UINT32_C(0x01020304)); 
-         r &= __ucl_assert(a[2] == UCL_UINT32_C(0x02030405)); 
-         r &= __ucl_assert(a[3] == UCL_UINT32_C(0x03040506)); 
- #  endif 
-     } 
- #endif 
-   
-     /* check the ucl_adler32() function */ 
-     if (r == 1) 
-     { 
-         ucl_uint32 adler; 
-         adler = ucl_adler32(0, NULL, 0); 
-         adler = ucl_adler32(adler, ucl_copyright(), 195); 
-         r &= __ucl_assert(adler == UCL_UINT32_C(0x52ca3a75)); 
-     } 
-   
-     /* check for the gcc schedule-insns optimization bug */ 
-     if (r == 1) 
-     { 
-         r &= __ucl_assert(!schedule_insns_bug()); 
-     } 
-   
-     /* check for the gcc strength-reduce optimization bug */ 
-     if (r == 1) 
-     { 
-         static int x[3]; 
-         static unsigned xn = 3; 
-         register unsigned j; 
-   
-         for (j = 0; j < xn; j++) 
-             x[j] = (int)j - 3; 
-         r &= __ucl_assert(!strength_reduce_bug(x)); 
-     } 
-   
-     /* now for the low-level pointer checks */ 
-     if (r == 1) 
-     { 
-         r &= ptr_check(); 
-     } 
-   
-     ACC_UNUSED(u); 
-     return r == 1 ? UCL_E_OK : UCL_E_ERROR; 
- } 
-   
-   
- static ucl_bool schedule_insns_bug(void) 
- { 
- #if defined(__UCL_CHECKER) 
-     /* for some reason checker complains about uninitialized memory access */ 
-     return 0; 
- #else 
-     const int clone[] = {1, 2, 0}; 
-     const int *q; 
-     q = clone; 
-     return (*q) ? 0 : 1; 
- #endif 
- } 
-   
-   
- static ucl_bool strength_reduce_bug(int *x) 
- { 
- #if 1 && (ACC_CC_DMC || ACC_CC_SYMANTECC || ACC_CC_ZORTECHC) 
-     return 0; 
- #else 
-     return x[0] != -3 || x[1] != -2 || x[2] != -1; 
- #endif 
- } 
-   
-   
- /*********************************************************************** 
- // 
- ************************************************************************/ 
-   
- int __ucl_init_done = 0; 
-   
- UCL_PUBLIC(int) 
- __ucl_init2(ucl_uint32 v, int s1, int s2, int s3, int s4, int s5, 
-                           int s6, int s7, int s8, int s9) 
- { 
-     int r; 
-   
- #if (ACC_CC_MSC && ((_MSC_VER) < 700)) 
- #else 
- #include "acc/acc_chk.ch" 
- #undef ACCCHK_ASSERT 
- #endif 
-   
-     __ucl_init_done = 1; 
-   
-     if (v == 0) 
-         return UCL_E_ERROR; 
-   
-     r = (s1 == -1 || s1 == (int) sizeof(short)) && 
-         (s2 == -1 || s2 == (int) sizeof(int)) && 
-         (s3 == -1 || s3 == (int) sizeof(long)) && 
-         (s4 == -1 || s4 == (int) sizeof(ucl_uint32)) && 
-         (s5 == -1 || s5 == (int) sizeof(ucl_uint)) && 
-         (s6 == -1 || s6 > 0) && 
-         (s7 == -1 || s7 == (int) sizeof(char *)) && 
-         (s8 == -1 || s8 == (int) sizeof(ucl_voidp)) && 
-         (s9 == -1 || s9 == (int) sizeof(ucl_compress_t)); 
-     if (!r) 
-         return UCL_E_ERROR; 
-   
-     r = _ucl_config_check(); 
-     if (r != UCL_E_OK) 
-         return r; 
-   
-     return r; 
- } 
-   
-   
- #include "ucl_dll.ch" 
-   
-   
- /* 
- vi:ts=4:et 
- */ 
-