update dev300-m58
[ooovba.git] / sal / typesconfig / typesconfig.c
blob4b28886cdef3900b2d4b5eef507738f1569d3dd4
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: typesconfig.c,v $
10 * $Revision: 1.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <errno.h>
34 #include <string.h>
36 #include <unistd.h>
37 #include <sys/types.h>
39 #include <stdarg.h>
41 #include <signal.h>
42 #include <setjmp.h>
44 #define printTypeSize(Type,Name) printf( "sizeof(%s)\t\t= %d\n", Name, (int) sizeof (Type) )
46 #define isSignedType(Type) (((Type)-1) < 0)
47 #define printTypeSign(Type,Name) printf( "%s\t\t= %s %s\n", Name, ( isSignedType(Type) ? "signed" : "unsigned" ), Name )
50 /*************************************************************************
52 |* IsBigEndian()
54 |* Beschreibung True, wenn CPU BigEndian ist
56 |* Ersterstellung EG 26.06.96
57 |* Letzte Aenderung
59 *************************************************************************/
60 int IsBigEndian()
62 long l = 1;
63 return ! *(char*)&l;
66 /*************************************************************************
68 |* Typdeclarations for memory access test functions
70 *************************************************************************/
71 typedef enum { t_char, t_short, t_int, t_long, t_double } Type;
72 typedef int (*TestFunc)( Type, void* );
75 /*************************************************************************
77 |* PrintArgs()
79 |* Beschreibung Testfunktion fuer variable Parameter
81 |* Ersterstellung EG 26.06.96
82 |* Letzte Aenderung
84 *************************************************************************/
85 void PrintArgs( int p, ... )
87 int value;
88 va_list ap;
90 va_start( ap, p );
92 printf( "value = %d", p );
94 while ( ( value = va_arg(ap, int) ) != 0 )
95 printf( " %d", value );
97 printf( "\n" );
98 va_end(ap);
101 /*************************************************************************
103 |* SignalHdl()
105 |* Beschreibung faengt SIGBUS und SIGSEGV in check() ab
107 |* Ersterstellung EG 26.06.96
108 |* Letzte Aenderung
110 *************************************************************************/
112 static sigjmp_buf jmpbuf;
113 static volatile sig_atomic_t hit;
115 void SignalHdl( int sig )
117 (void) sig; // ignored
118 hit = 1;
119 siglongjmp(jmpbuf, 0);
122 /*************************************************************************
124 |* check()
126 |* Beschreibung Testet MemoryZugriff (read/write)
128 |* Ersterstellung EG 26.06.96
129 |* Letzte Aenderung
131 *************************************************************************/
132 int check( TestFunc func, Type eT, void* p )
134 hit = 0;
135 if (sigsetjmp(jmpbuf, 1) == 0) {
136 struct sigaction sa;
137 sa.sa_handler = SignalHdl;
138 sigemptyset(&sa.sa_mask);
139 sa.sa_flags = 0;
140 if (sigaction(SIGBUS, &sa, NULL) != 0 ||
141 sigaction(SIGSEGV, &sa, NULL) != 0)
143 abort();
145 func(eT, p);
146 sa.sa_handler = SIG_DFL;
147 if (sigaction(SIGBUS, &sa, NULL) != 0 ||
148 sigaction(SIGSEGV, &sa, NULL) != 0)
150 abort();
153 return hit ? -1 : 0;
156 /*************************************************************************
158 |* GetAtAddress()
160 |* Beschreibung memory read access
162 |* Ersterstellung EG 26.06.96
163 |* Letzte Aenderung
165 *************************************************************************/
166 #if defined(IA64) || defined(ARM32)
168 int forceerror()
170 #if defined(ARM32)
171 // workaround for qemu-user
172 hit = 1;
173 #else
174 raise (SIGBUS);
175 #endif
176 return 1;
179 int GetAtAddress( Type eT, void* p )
181 switch ( eT )
183 case t_char: return *((char*)p);
184 case t_short: if ((long)p % sizeof(short)) return forceerror(); else return *((short*)p);
185 case t_int: if ((long)p % sizeof(int)) return forceerror(); else return *((int*)p);
186 case t_long: if ((long)p % sizeof(long)) return forceerror(); else return *((long*)p);
187 case t_double: if ((long)p % sizeof(double)) return forceerror(); else return *((double*)p);
189 abort();
192 #else
193 static int dummy(void* unused);
195 int GetAtAddress( Type eT, void* p )
197 switch ( eT )
199 case t_char: { char x = *(char*)p; return dummy(&x); }
200 case t_short: { short x = *(short*)p; return dummy(&x); }
201 case t_int: { int x = *(int*)p; return dummy(&x); }
202 case t_long: { long x = *(long*)p; return dummy(&x); }
203 case t_double: { double x = *(double*)p; return dummy(&x); }
205 abort();
208 int dummy(void* unused)
210 (void)unused;
211 return 0;
214 #endif
215 /*************************************************************************
217 |* SetAtAddress()
219 |* Beschreibung memory write access
221 |* Ersterstellung EG 26.06.96
222 |* Letzte Aenderung
224 *************************************************************************/
225 int SetAtAddress( Type eT, void* p )
227 switch ( eT )
229 case t_char: return *((char*)p) = 0;
230 case t_short: return *((short*)p) = 0;
231 case t_int: return *((int*)p) = 0;
232 case t_long: return *((long*)p) = 0;
233 case t_double: return *((double*)p)= 0;
235 abort();
238 char* TypeName( Type eT )
240 switch ( eT )
242 case t_char: return "char";
243 case t_short: return "short";
244 case t_int: return "int";
245 case t_long: return "long";
246 case t_double: return "double";
248 abort();
251 /*************************************************************************
253 |* Check(Get|Set)Access()
255 |* Beschreibung Testet MemoryZugriff (read/write)
256 |* Zugriffsverletzungen werden abgefangen
258 |* Ersterstellung EG 26.06.96
259 |* Letzte Aenderung
261 *************************************************************************/
262 int CheckGetAccess( Type eT, void* p )
264 int b;
265 b = -1 != check( (TestFunc)GetAtAddress, eT, p );
266 #if OSL_DEBUG_LEVEL > 1
267 fprintf( stderr,
268 "%s read %s at %p\n",
269 (b? "can" : "can not" ), TypeName(eT), p );
270 #endif
271 return b;
273 int CheckSetAccess( Type eT, void* p )
275 int b;
277 b = -1 != check( (TestFunc)SetAtAddress, eT, p );
278 #if OSL_DEBUG_LEVEL > 1
279 fprintf( stderr,
280 "%s write %s at %p\n",
281 (b? "can" : "can not" ), TypeName(eT), p );
282 #endif
283 return b;
286 /*************************************************************************
288 |* GetAlignment()
290 |* Beschreibung Bestimmt das Alignment verschiedener Typen
292 |* Ersterstellung EG 26.06.96
293 |* Letzte Aenderung
295 *************************************************************************/
296 int GetAlignment( Type eT )
298 char a[ 16*8 ];
299 long p = (long)(void*)a;
300 int i;
302 /* clear a[...] to set legal value for double access */
303 for ( i = 0; i < 16*8; i++ )
304 a[i] = 0;
306 p = ( p + 0xF ) & ~0xF;
307 for ( i = 1; i < 16; i++ )
308 if ( CheckGetAccess( eT, (void*)(p+i) ) )
309 return i;
310 return 0;
313 /*************************************************************************
315 |* struct Description
317 |* Beschreibung Beschreibt die Parameter der Architektur
319 |* Ersterstellung EG 26.06.96
320 |* Letzte Aenderung
322 *************************************************************************/
323 struct Description
325 int bBigEndian;
326 int nAlignment[3]; /* 2,4,8 */
329 /*************************************************************************
331 |* Description_Ctor()
333 |* Beschreibung Bestimmt die Parameter der Architektur
335 |* Ersterstellung EG 26.06.96
336 |* Letzte Aenderung
338 *************************************************************************/
339 void Description_Ctor( struct Description* pThis )
341 pThis->bBigEndian = IsBigEndian();
343 if ( sizeof(short) != 2 )
344 abort();
345 pThis->nAlignment[0] = GetAlignment( t_short );
346 if ( sizeof(int) != 4 )
347 abort();
348 pThis->nAlignment[1] = GetAlignment( t_int );
350 if ( sizeof(long) == 8 )
351 pThis->nAlignment[2] = GetAlignment( t_long );
352 else if ( sizeof(double) == 8 )
353 pThis->nAlignment[2] = GetAlignment( t_double );
354 else
355 abort();
358 /*************************************************************************
360 |* Description_Print()
362 |* Beschreibung Schreibt die Parameter der Architektur als Header
364 |* Ersterstellung EG 26.06.96
365 |* Letzte Aenderung
367 *************************************************************************/
368 void Description_Print( struct Description* pThis, char* name )
370 int i;
371 FILE* f = fopen( name, "w" );
372 if( ! f ) {
373 fprintf( stderr, "Unable to open file %s: %s\n", name, strerror( errno ) );
374 exit( 99 );
376 fprintf( f, "/* This file is autogenerated from the 'typesconfig' program\n * in the sal module\n */\n\n" );
378 /* Disabled for now in preference to big/little endian defines in <osl/endian.h> fa (2004-03-15) */
379 /* fprintf( f, "#define SAL_TYPES_%s\n", pThis->bBigEndian ? "BIGENDIAN" : "LITTLEENDIAN" ); */
381 for ( i = 0; i < 3; i++ )
382 fprintf( f, "#define SAL_TYPES_ALIGNMENT%d\t%d\n", 1 << (i+1), pThis->nAlignment[i] );
383 fprintf( f, "#define SAL_TYPES_SIZEOFSHORT\t%d\n", (int) sizeof( short ) );
384 fprintf( f, "#define SAL_TYPES_SIZEOFINT\t%d\n", (int) sizeof( int ) );
385 fprintf( f, "#define SAL_TYPES_SIZEOFLONG\t%d\n", (int) sizeof( long ) );
386 fprintf( f, "#define SAL_TYPES_SIZEOFLONGLONG\t%d\n", (int) sizeof( long long ) );
387 fprintf( f, "#define SAL_TYPES_SIZEOFPOINTER\t%d\n", (int) sizeof( void* ) );
389 /* Disabled for now, becuase OOo code assumes sizeof(double) == 8 and this is not
390 * likely to change any time soon. fa (2004-03-15)
392 /* fprintf( f, "#define SAL_TYPES_SIZEOFDOUBLE\t%d\n", sizeof( double ) );*/
394 fclose( f );
397 /*************************************************************************
399 |* InfoMemoryAccess()
401 |* Beschreibung Informeller Bytezugriffstest
403 |* Ersterstellung EG 26.06.96
404 |* Letzte Aenderung
406 *************************************************************************/
407 void InfoMemoryAccess( char* p )
409 if ( CheckGetAccess( t_char, p ) )
410 printf( "can read address %p\n", p );
411 else
412 printf( "cannot read address %p\n", p );
414 if ( CheckSetAccess( t_char, p ) )
415 printf( "can write address %p\n", p );
416 else
417 printf( "cannot write address %p\n", p );
420 /*************************************************************************
422 |* InfoMemoryTypeAccess()
424 |* Beschreibung Informeller Zugriffstest verschiedener Typen
426 |* Ersterstellung EG 15.08.96
427 |* Letzte Aenderung
429 *************************************************************************/
430 void InfoMemoryTypeAccess( Type eT )
432 char a[64];
433 int i;
435 /* clear a[...] to set legal value for double access */
436 for ( i = 0; i < 64; i++ )
437 a[i] = 0;
439 for ( i = 56; i >= 7; i >>= 1 )
441 if ( CheckGetAccess(eT, (long*)&a[i]) )
442 printf( "Access %s on %i-Aligned Address : OK\n", TypeName(eT), i / 7 );
443 else
444 printf( "Access %s on %i-Aligned Address : ERROR\n", TypeName(eT), i / 7 );
447 /************************************************************************
449 * Use C code to determine the characteristics of the building platform.
451 ************************************************************************/
452 int main( int argc, char* argv[] )
454 printTypeSign( char, "char" );
455 printTypeSign( short, "short" );
456 printTypeSign( int, "int" );
457 printTypeSign( long, "long" );
458 printTypeSign( long long, "long long" );
460 printTypeSize( short, "short" );
461 printTypeSize( int, "int" );
462 printTypeSize( long, "long" );
463 printTypeSize( long long, "long long" );
464 printTypeSize( float, "float" );
465 printTypeSize( double, "double" );
466 printTypeSize( void *, "void *" );
468 if ( IsBigEndian() )
469 printf( "BIGENDIAN (Sparc, RS6000, IP22, IP32, PowerPC(BE))\n" );
470 else
471 printf( "LITTLEENDIAN (Intel, x86-64, PowerPC(LE))\n" );
473 /* PrintArgs( 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 ); */
475 if ( argc > 1 )
477 struct Description description;
478 Description_Ctor( &description );
479 Description_Print( &description, argv[1] );
482 char* p = NULL;
483 InfoMemoryAccess( p );
484 p = (char*)&p;
485 InfoMemoryAccess( p );
486 InfoMemoryTypeAccess( t_short );
487 InfoMemoryTypeAccess( t_int );
488 InfoMemoryTypeAccess( t_long );
489 InfoMemoryTypeAccess( t_double );
492 exit( 0 );