SIS
Symmetric Index Structures
/Users/dbr/ma/src/bas/lml/exceptional.c
Go to the documentation of this file.
00001 #include "base.h"
00002 
00003 #define MALLOC_FREE_COUNT
00004 #define FOPEN_FCLOSE_COUNT
00005 //#define POINTER_MAP
00006 
00007 #ifdef MALLOC_FREE_COUNT
00008 static UINT numberOfPointers = 0;
00009 #endif
00010 
00011 #ifdef FOPEN_FCLOSE_COUNT
00012 static UINT numberOfFiles = 0;
00013 #endif
00014 
00015 #ifdef POINTER_MAP
00016 static void * * pointers = NULL;
00017 static UINT pointersStored = 0;
00018 static UINT pointersAlloced = 1024;
00019 static void PointerToNumber( void * ptr, U32 * p1, U32 * p2 );
00020 #endif
00021 
00022 void Throw( const S8 * msg ){
00023     printf( "%s\n", msg );
00024     exit( 1 );
00025 }
00026 
00027 void Verify(){
00028     #ifdef POINTER_MAP
00029     {
00030         UINT i;
00031         U32 p1, p2;
00032 
00033         for( i = 0; i < pointersStored; i++ ){
00034             if( pointers[i] != NULL ){
00035                 PointerToNumber( pointers[i], &p1, &p2 );
00036                 printf( "pointer %llu not freed: 0x%8x%8x\n", (U64)(i), p1, p2 );
00037             }
00038         }
00039         if( pointers != NULL ){
00040             free( pointers );
00041         }
00042     }
00043     #endif
00044 
00045     #ifdef MALLOC_FREE_COUNT
00046     if( numberOfPointers != 0 ){
00047         S8 msg[MAX_INPUT_STRING_SIZE];
00048         sprintf( msg, "Number of pointers that are not freed: %llu.", (U64)(numberOfPointers) );
00049         Throw( msg );
00050     }
00051     #endif
00052 
00053     #ifdef FOPEN_FCLOSE_COUNT
00054     if( numberOfFiles != 0 ){
00055         S8 msg[MAX_INPUT_STRING_SIZE];
00056         sprintf( msg, "Number of files that are not closed: %llu.", (U64)(numberOfFiles) );
00057         Throw( msg );
00058     }
00059     #endif
00060 }
00061 
00062 void * Malloc( U64 number, U64 size ){
00063     void * ptr;
00064 
00065     ptr = malloc( number*size );
00066     if( ptr == NULL ){
00067         Throw( "Not enough memory: malloc failed." );
00068     }
00069     #ifdef MALLOC_FREE_COUNT
00070     numberOfPointers++;
00071     #endif
00072 
00073     #ifdef POINTER_MAP
00074     {
00075         UINT i;
00076 
00077         if( pointers == NULL ){
00078             pointers = (void**)malloc( pointersAlloced * sizeof(void*) );
00079             if( pointers == NULL ){
00080                 Throw( "Not enough memory: malloc failed." );
00081             }
00082         }
00083         for( i = 0; i < pointersStored; i++ ){
00084             if( pointers[i] == NULL ){
00085                 pointers[i] = ptr;
00086                 break;
00087             }
00088         }
00089         if( i == pointersStored ){
00090             if( pointersStored == pointersAlloced ){
00091                 pointersAlloced *= 2;
00092                 pointers = (void**)realloc( pointers, pointersAlloced * sizeof(void*) );
00093                 if( pointers == NULL ){
00094                     Throw( "Not enough memory: realloc failed." );
00095                 }
00096             }
00097             pointers[pointersStored] = ptr;
00098             pointersStored++;
00099         }
00100     }
00101     #endif
00102 
00103     return ptr;
00104 }
00105 
00106 void Free( void * ptr ){
00107     #ifdef MALLOC_FREE_COUNT
00108     if( numberOfPointers == 0 ){
00109         Throw( "Cannot free a pointer: the number of pointers to free is 0." );
00110     }
00111     #endif
00112 
00113     free( ptr );
00114 
00115     #ifdef MALLOC_FREE_COUNT
00116     numberOfPointers--;
00117     #endif
00118 
00119     #ifdef POINTER_MAP
00120     {
00121         UINT i;
00122         U32 p1, p2;
00123 
00124         for( i = 0; i < pointersStored; i++ ){
00125             if( pointers[i] == ptr ){
00126                 pointers[i] = NULL;
00127                 break;
00128             }
00129         }
00130         if( i == pointersStored ){
00131             S8 msg[MAX_INPUT_STRING_SIZE];
00132             PointerToNumber( ptr, &p1, &p2 );
00133             sprintf( msg, "The pointer 0x%8x%8x is missing in the pointer map.", p1, p2 );
00134             Throw( msg );
00135         }
00136     }
00137     #endif
00138 }
00139 
00140 void * Realloc( void * ptr, U64 number, U64 size ){
00141     void * newPtr;
00142 
00143     if( number == 0 || size == 0 ){
00144         if( ptr != NULL ){
00145             free( ptr );
00146         }
00147         newPtr = malloc( 0 );
00148         if( newPtr == NULL ){
00149             Throw( "Not enough memory: malloc failed." );
00150         }
00151     }
00152     else{
00153         newPtr = realloc( ptr, number*size );
00154         if( newPtr == NULL ){
00155             Throw( "Not enough memory: realloc failed." );
00156         }
00157     }
00158 
00159     #ifdef POINTER_MAP
00160     {
00161         UINT i;
00162         U32 p1, p2;
00163 
00164         for( i = 0; i < pointersStored; i++ ){
00165             if( pointers[i] == ptr ){
00166                 pointers[i] = newPtr;
00167                 break;
00168             }
00169         }
00170         if( i == pointersStored ){
00171             S8 msg[MAX_INPUT_STRING_SIZE];
00172             PointerToNumber( ptr, &p1, &p2 );
00173             sprintf( msg, "The pointer 0x%8x%8x is missing in the pointer map.", p1, p2 );
00174             Throw( msg );
00175         }
00176     }
00177     #endif
00178 
00179     return newPtr;
00180 }
00181 
00182 void Fwrite( const void * ptr, UINT size, UINT number, FILE * fp ){
00183     if( fwrite( ptr, size, number, fp ) != number ){
00184         Throw( "Cannot write in file: fwrite failed." );
00185     }
00186 }
00187 
00188 void Fread( void * ptr, UINT size, UINT number, FILE * fp ){
00189     if( fread( ptr, size, number, fp ) != number ){
00190         Throw( "Cannot read from file: fread failed." );
00191     }
00192 }
00193 
00194 FILE * Fopen( const S8 * fileName, const S8 * mode ){
00195     FILE * fp;
00196 
00197     fp = fopen( fileName, mode );
00198     if( fp == NULL ){
00199         S8 msg[MAX_INPUT_STRING_SIZE];
00200         sprintf( msg, "Cannot open the file %s with mode %s: fopen failed.", fileName, mode );
00201         Throw( msg );
00202     }
00203     #ifdef FOPEN_FCLOSE_COUNT
00204     numberOfFiles++;
00205     #endif
00206     return fp;
00207 }
00208 
00209 void Fclose( FILE * fp ){
00210     #ifdef FOPEN_FCLOSE_COUNT
00211     if( numberOfFiles == 0 ){
00212         Throw( "Cannot close a file: the number of files to close is 0." );
00213     }
00214     #endif
00215     fclose( fp );
00216     #ifdef FOPEN_FCLOSE_COUNT
00217     numberOfFiles--;
00218     #endif
00219 }
00220 
00221 void Fseek( FILE * fp, SINT n, SINT offset ){
00222     if( fseek( fp, n, offset ) != 0 ){
00223         Throw( "Cannot read from file: fseek failed." );
00224     }
00225 }
00226 
00227 #define hashBase (257)
00228 
00229 UINT CodeUINT( UINT code, UINT value, UINT hashSize ){
00230     return CodeBytes( code, &value, sizeof(UINT), hashSize );
00231 }
00232 
00233 UINT CodeBytes( UINT code, const void * ptr, UINT size, UINT hashSize ){
00234     const U8 * data;
00235     UINT i;
00236 
00237     data = (const U8 *)(ptr);
00238     for( i = 0; i < size; i++ ){
00239         code = (code*hashBase + data[i]) % hashSize;
00240     }
00241     return code;
00242 }
00243 
00244 #ifdef POINTER_MAP
00245 static void PointerToNumber( void * ptr, U32 * p1, U32 * p2 ){
00246     U64 n;
00247 
00248     n = (U64)(ptr);
00249     n >>= 32;
00250     (*p1) = (U32)(n);
00251     n = (U64)(ptr);
00252     n <<= 32;
00253     n >>= 32;
00254     (*p2) = (U32)(n);
00255 }
00256 #endif
00257 
00258 void PrintLine( FILE * fp, UINT symbolSize, UINT encoding ){
00259     PrintString( fp, "\n", symbolSize, encoding );
00260 }
00261 
00262 void PrintString( FILE * fp, const S8 * str, UINT symbolSize, UINT encoding ){
00263     UINT i;
00264     mSymbolAndVariables( symbol )
00265 
00266     for( i = 0; str[i] != 0; i++ ){
00267         mSymbolAssignValue( symbol, str[i], symbolSize )
00268         PrintSymbol( symbol, fp, symbolSize, encoding );
00269     }
00270     fflush( fp );
00271 }
00272 
00273 void PrintSymbol( const void * symbol, FILE * fp, UINT symbolSize, UINT encoding ){
00274     UINT i;
00275     UINT nBytes = 0;
00276     U32 u32, mask, offset;
00277     U8 u8, m;
00278 
00279     if( encoding == ENCODING_PLAIN ){
00280         Fwrite( symbol, symbolSize, 1, fp );
00281         return;
00282     }
00283     u32 = (U32)SymbolToUINT( symbol, symbolSize );
00284     if( u32 <= 0x7F ){
00285         u8 = (U8)(u32);
00286         nBytes = 1;
00287     }
00288     else if( u32 <= 0x7FF ){
00289         nBytes = 2;
00290         m = 0xC0;
00291     }
00292     else if( u32 <= 0xFFFF ){
00293         nBytes = 3;
00294         m = 0xE0;
00295     }
00296     else if( u32 <= 0x1FFFFF ){
00297         nBytes = 4;
00298         m = 0xF0;
00299     }
00300     else if( u32 <= 0x3FFFFFF ){
00301         nBytes = 5;
00302         m = 0xF8;
00303     }
00304     else if( u32 <= 0x7FFFFFFF ){
00305         nBytes = 6;
00306         m = 0xFC;
00307     }
00308     else{
00309         S8 msg[MAX_INPUT_STRING_SIZE];
00310         sprintf( msg, "Illegal UTF-8 symbol 0x%8x", u32 );
00311         Throw( msg );
00312     }
00313     if( nBytes > 1 ){
00314         mask = 0x0000003F;
00315         offset = (nBytes - 1)*6;
00316         mask <<= offset;
00317         u8 = (U8)(((u32 & mask) >> offset) | m);
00318     }
00319     Fwrite( &u8, sizeof(U8), 1, fp );
00320     nBytes--;
00321     for( i = nBytes; i > 0; i-- ){
00322         mask = 0x0000003F;
00323         offset = (i - 1)*6;
00324         mask <<= offset;
00325         u8 = (U8)(((u32 & mask) >> offset) | 0x80);
00326         Fwrite( &u8, sizeof(U8), 1, fp );
00327     }
00328 }