Add rayman2 source files

This commit is contained in:
2024-09-18 02:33:44 +08:00
parent bcc093f8ed
commit fb036c54fd
14339 changed files with 2596224 additions and 0 deletions

View File

@@ -0,0 +1,374 @@
/*------------------------------------------------------------------------------
FILE : DynArray.c
CREATED : 97/12/02
AUTHOR : Catalin Cocos
CONTENTS: dynamic pointer array with sorting capabilities
------------------------------------------------------------------------------*/
#include "StdInc.h"
#include "DynArray.h"
/*------------------------------------------------------------------------------
DESC. : Creaton of a default array (allocation + default initialization)
CREATED : 97/12/02
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
LDT_tdst_DSArray* LDT_DSAr_new()
{
LDT_tdst_DSArray* pst_NewArray = malloc( sizeof(LDT_tdst_DSArray) ); /* allocate */
LDT_DSAr_Init( pst_NewArray );
return pst_NewArray;
}
/*------------------------------------------------------------------------------
DESC. : default initialization of an array - returns 1 if successful,
0 on error;
WARNING : This function should be called only once and prior to the use of
any other array functions.
CREATED : 97/12/02
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_DSAr_Init( LDT_tdst_DSArray* pst_Ar)
{
if( !pst_Ar ) return 0; /* NULL argument */
memset( pst_Ar, 0, sizeof( LDT_tdst_DSArray ) );
return 1; /* success */
}
/*------------------------------------------------------------------------------
DESC. : deletes an existing array
WARNING : this should only be called for dinamically allocated arrays.
CREATED : 97/12/02
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
void LDT_DSAr_delete( LDT_tdst_DSArray* pst_Ar )
{
if( !pst_Ar ) return;
LDT_DSAr_RemoveAll( pst_Ar );
free( pst_Ar );
}
/*------------------------------------------------------------------------------
DESC. : sets the array's size. - returns 1 if successful, 0 on error;
CREATED : 97/12/02
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_DSAr_SetSize( LDT_tdst_DSArray* pst_Ar, int nNewSize )
{
void** pNewData;
if(nNewSize < 0) return 0; /* wrong size input */
if (nNewSize == 0)
{
/* shrink to nothing */
if(pst_Ar->pData)
{
free( pst_Ar->pData );
pst_Ar->pData = NULL;
}
pst_Ar->nSize = pst_Ar->nMaxSize = 0;
}
else if (pst_Ar->pData == NULL)
{
int nNewMax = nNewSize;
if( nNewSize < pst_Ar->nGrowBy ) nNewMax = pst_Ar->nGrowBy;
/* create one with exact size */
pst_Ar->pData = malloc( nNewMax * sizeof(void*) );
if(!pst_Ar->pData ) return 0; /* allocation failed */
memset( pst_Ar->pData, 0, nNewMax * sizeof(void*) ); /* zero fill */
pst_Ar->nSize = nNewSize;
pst_Ar->nMaxSize = nNewMax;
}
else if (nNewSize <= pst_Ar->nMaxSize)
{
/* it fits */
if (nNewSize > pst_Ar->nSize)
/* initialize the new elements */
memset( &pst_Ar->pData[pst_Ar->nSize], 0,
(nNewSize-pst_Ar->nSize) * sizeof(void*));
pst_Ar->nSize = nNewSize;
}
else
{
/* Otherwise grow array */
int nNewMax;
if (nNewSize < pst_Ar->nMaxSize + pst_Ar->nGrowBy)
nNewMax = pst_Ar->nMaxSize + pst_Ar->nGrowBy; /* granularity */
else
nNewMax = nNewSize; /* no slush */
pNewData = realloc( pst_Ar->pData, nNewMax * sizeof(void*) );
if( !pNewData ) return 0; /* reallocation failed */
/* construct remaining elements */
memset( &pNewData[pst_Ar->nSize], 0,
(nNewSize-pst_Ar->nSize) * sizeof(void*));
pst_Ar->pData = pNewData;
pst_Ar->nSize = nNewSize;
pst_Ar->nMaxSize = nNewMax;
}
return 1; /* success */
}
/*------------------------------------------------------------------------------
DESC. : frees unused memory
CREATED : 97/12/02
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
void LDT_DSAr_FreeExtra( LDT_tdst_DSArray* pst_Ar)
{
void** pNewData;
if (pst_Ar->nSize != pst_Ar->nMaxSize)
{
/* shrink to desired size */
if( pst_Ar->nSize )
{
pNewData = realloc( pst_Ar->pData, pst_Ar->nSize * sizeof(void*) );
if( pNewData )
{
pst_Ar->pData = pNewData;
pst_Ar->nMaxSize = pst_Ar->nSize;
}
}
else
LDT_DSAr_SetSize( pst_Ar, 0 ); /* clean-up */
}
}
/*------------------------------------------------------------------------------
DESC. : Appends an array element. returns the index of the appended
element, or -1 on error
CREATED : 97/12/02
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_DSAr_Add( LDT_tdst_DSArray* pst_Ar, void* newElement)
{
if(!LDT_DSAr_SetSize( pst_Ar, pst_Ar->nSize+1 )) return -1;
pst_Ar->pData[pst_Ar->nSize-1] = newElement;
return pst_Ar->nSize-1;
}
/*------------------------------------------------------------------------------
DESC. : Inserts a new array element. Returns 1 on success, 0 on failure
CREATED : 97/12/02
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_DSAr_InsertAt(LDT_tdst_DSArray* pst_Ar, int nIndex, void* newElement )
{
if(nIndex < 0) return 0;
if (nIndex >= pst_Ar->nSize)
{
/* adding after the end of the array */
/* grow so nIndex is valid */
if(!LDT_DSAr_SetSize( pst_Ar, nIndex + 1)) return 0;
}
else
{
/* inserting in the middle of the array */
/* grow the array to new size */
if(!LDT_DSAr_SetSize( pst_Ar, pst_Ar->nSize + 1)) return 0;
/* shift old data up to fill gap */
memmove(pst_Ar->pData+nIndex+1, pst_Ar->pData+nIndex,
( pst_Ar->nSize - nIndex - 1 ) * sizeof(void*));
}
/* insert new value in the gap */
pst_Ar->pData[nIndex] = newElement;
return 1;
}
/*------------------------------------------------------------------------------
DESC. : removes an array element. Returns the element on success, NULL on failure
CREATED : 97/12/02
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
void* LDT_DSAr_RemoveAt(LDT_tdst_DSArray* pst_Ar, int nIndex )
{
int nMoveCount;
void * pRemoved;
if(nIndex < 0 || nIndex >= pst_Ar->nSize ) return NULL;
pRemoved = pst_Ar->pData[nIndex]; /* the removed element */
nMoveCount = pst_Ar->nSize - nIndex - 1;
memcpy(pst_Ar->pData+nIndex, pst_Ar->pData+nIndex+1, nMoveCount*sizeof(void*));
pst_Ar->nSize--;
return pRemoved;
}
/*------------------------------------------------------------------------------
DESC. : Inserts the elements of another array. Returns 1 on success,
0 on failure.
CREATED : 97/12/02
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_DSAr_InsertArrayAt(LDT_tdst_DSArray* pst_Ar, int nIndex, LDT_tdst_DSArray* pNewArray)
{
int nCount, nOldSize;
if(pNewArray == NULL || nIndex < 0) return 0;
nCount = pNewArray->nSize;
if (nCount > 0)
{
if (nIndex >= pst_Ar->nSize)
{
/* adding after the end of the array */
/* grow so nIndex is valid */
if(!LDT_DSAr_SetSize(pst_Ar, nIndex + nCount)) return 0;
}
else
{
/* inserting in the middle of the array */
nOldSize = pst_Ar->nSize;
/* grow it to new size */
if(!LDT_DSAr_SetSize( pst_Ar, nOldSize + nCount)) return 0;
/* shift old data up to fill gap */
memmove(pst_Ar->pData+nIndex+nCount, pst_Ar->pData+nIndex,
(nOldSize-nIndex) * sizeof(void*));
}
memcpy( pst_Ar->pData + nIndex, pNewArray->pData, nCount * sizeof(void*));
}
return 1;
}
/*------------------------------------------------------------------------------
DESC. : Sorts the array, using the comparison function
CREATED : 97/12/03
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
void LDT_DSAr_QSort( LDT_tdst_DSArray* pst_Ar )
{
if( pst_Ar->pfnCompare)
qsort( &pst_Ar->pData[0], pst_Ar->nSize, sizeof(void*),
(int (*)(const void *,const void *)) pst_Ar->pfnCompare );
}
/*------------------------------------------------------------------------------
DESC. : Adds an element in the array, in sorted position.
Returns the index of the added element, -1 on failure
On failure,if the <<position>> parameter is not NULL, it will
contain the index at which the element(or an equivalent) was found.
CREATED : 97/12/03
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_DSAr_SAdd( LDT_tdst_DSArray* pst_Ar, void* newElement, int AdmitDuplicates, int* position )
{
int iidx, idx = LDT_DSAr_Index( pst_Ar, newElement, &iidx );
if(position) *position = idx;
if(idx>=0 && ( !AdmitDuplicates || (newElement == pst_Ar->pData[idx]) ))
return -1;
else return ( LDT_DSAr_InsertAt(pst_Ar, iidx, newElement )? iidx: -1 );
}
/*------------------------------------------------------------------------------
DESC. : gets the index of a certain element. -1 if the element
(or an equivalent) is not found
CREATED : 97/12/03
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_DSAr_Index( LDT_tdst_DSArray* pst_Ar, void* newElement, int *p_iidx )
{
int hidx = pst_Ar->nSize-1, lidx = 0, cidx; /* , i, plus, minus; */
assert(pst_Ar->pfnCompare); /* the comparison function must exist*/
if(p_iidx) *p_iidx = 0;
if(!newElement) return -1;
if(hidx<0) return hidx;
while(hidx > lidx)
switch(pst_Ar->pfnCompare(&newElement,pst_Ar->pData+(cidx = (hidx+lidx)/2)))
{
case 0: hidx = lidx = cidx; break;
case -1: hidx = cidx; break;
default: lidx = cidx+1; break;
}
if(p_iidx) *p_iidx = lidx+1;
switch(pst_Ar->pfnCompare( &newElement, pst_Ar->pData+lidx ))
{
case 0:
/* for( i = 0, plus = pst_Ar->nSize-1-lidx, minus = lidx; plus>=0 || minus>=0; i++ )
{
if( plus>=i &&
(plus = pst_Ar->pfnCompare(&newElement,pst_Ar->pData+lidx+1)?-1:plus)>=0 &&
newElement == pst_Ar->pData[lidx+i])
{
lidx += i;
break;
}
if( minus>=i &&
(minus = pst_Ar->pfnCompare(&newElement,pst_Ar->pData+lidx-1 )?-1:minus)>=0 &&
newElement == pst_Ar->pData[lidx+i])
{
lidx -= i;
break;
}
} */
if(p_iidx) *p_iidx = lidx+1;
return lidx;
case -1:
if(p_iidx) (*p_iidx)--;
default:
return -1;
}
}
/*------------------------------------------------------------------------------
DESC. : gets the starting of an equivalence interval that includes the
<<idx>> index
CREATED : 97/12/03
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_DSAr_UpperBound( LDT_tdst_DSArray* pst_Ar, int idx)
{
void** pCrt;
int Midx = pst_Ar->nSize-1, lidx, hidx, cidx; /* the upper limit */
if(idx<0 || idx>=Midx ) return Midx; /* the item is out of bounds or the last in the array */
pCrt = pst_Ar->pData + (lidx = hidx = idx); /* this is the target */
/* if the last element of the array is <=> with the target, return its index (no use for further search)*/
if( !pst_Ar->pfnCompare( pCrt, pst_Ar->pData + Midx ) ) return Midx;
/* find the interval bound */
for(hidx ++; !pst_Ar->pfnCompare( pCrt,pst_Ar->pData + hidx );
lidx = hidx, cidx = idx+(hidx-idx)*2, hidx = ( cidx<Midx? cidx: Midx ));
hidx--;
while(hidx > lidx)
switch(pst_Ar->pfnCompare( pCrt, pst_Ar->pData +( cidx = (hidx+lidx+1)/2) ))
{
case -1: hidx = cidx-1; break;
default: lidx = cidx; break;
}
return lidx;
}
/*------------------------------------------------------------------------------
DESC. : gets the beginning of an equivalence interval that includes the
<<idx>> index
CREATED : 97/12/03
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_DSAr_LowerBound( LDT_tdst_DSArray* pst_Ar, int idx)
{
int lidx, hidx, cidx;
void** pCrt;
if(idx<=0 || idx>pst_Ar->nSize-1 ) return 0; /* the item is out of bounds or the last in the array */
pCrt = pst_Ar->pData + (lidx = hidx = idx); /* this is the target */
/* if the first element of the array is <=> with the target, return its index (no use for further search) */
if(!pst_Ar->pfnCompare( pCrt, pst_Ar->pData )) return 0;
/* find the interval bound */
for(lidx--; !pst_Ar->pfnCompare( pCrt, pst_Ar->pData + lidx );
hidx = lidx, cidx = idx-(idx-lidx)*2, lidx = (cidx>lidx? cidx: lidx) );
lidx++;
while(hidx > lidx)
switch(pst_Ar->pfnCompare( pCrt, pst_Ar->pData + (cidx = (hidx+lidx)/2) ) )
{
case 0: case -1: hidx = cidx; break;
default: lidx = cidx+1; break;
}
return lidx;
}

View File

@@ -0,0 +1,102 @@
/*------------------------------------------------------------------------------
FILE : Error.c
CREATED : 98/09/02
AUTHOR : Catalin Cocos
CONTENTS: LDT Error management
------------------------------------------------------------------------------*/
#include "StdInc.h"
#include "Error.h"
#include "Parser.h"
char LDT_ErrDesc[LDT_MAX_ERROR_DESCRIPTION +1];
FILE* pErrFile = NULL;
/*------------------------------------------------------------------------------
DESC. : initializes the error log file.
CREATED : 98/09/02
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
void InitErrFile()
{
static int count = 0;
pErrFile = fopen("LDT_ERR.log", count?"a+":"w");
count++;
if(pErrFile)
{
time_t strTime;
struct tm *newtime;
time( &strTime );
newtime = localtime( &strTime );
fprintf(pErrFile, "LDT error log session %u >>> %s \n", count, asctime( newtime ));
}
}
/*------------------------------------------------------------------------------
DESC. : Closes the eror log file
CREATED : 98/09/02
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
void CLoseErrFile()
{
if(pErrFile)
{
fprintf(pErrFile, "\n\n\n");
fclose(pErrFile);
}
pErrFile = NULL;
}
/*------------------------------------------------------------------------------
DESC. : Error treatment
CREATED : 98/09/02
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
void SignalError(int level, LDT_tdst_Link * pLink, int errorcode, char* szErrDesc, char* szSourceFile, int line)
{
char* buff = LDT_ErrDesc;
if(level > LDT_WARNING_LEVEL && level > LDT_ERROR_LEVEL) return;
buff += sprintf( buff,"\n%s\t(Level %u)\n" ,level>LDT_ERROR_LEVEL?"WARNING":"ERROR", level);
buff += sprintf( buff,"\nCODE :\t\t%i (%s)", errorcode, errorcode?"USER":"SYSTEM");
if(szErrDesc)
buff += sprintf( buff,"\nDESCRIPTION:\t%s\n", szErrDesc);
buff += sprintf( buff,"LOCATION:\t");
if(pLink)
{
buff += sprintf( buff,"(%s) ", (pLink->dwFlags & LDT_LF_FILE)?"FILE":"SECTION");
LDT_ComputeSectionName( pLink, buff);
buff+= strlen(buff);
}
else
if( g_FileDesc )
buff += sprintf( buff, "(FILE) %s", g_FileDesc->_pInfoMemFile->pName );
else
buff += sprintf( buff, "No information available" );
buff += sprintf( buff,"\nSOURCE FILE:\t %s\nLINE:\t\t %u\n",szSourceFile, line);
#ifdef LDT_LOG_ERRORS
if(pErrFile )
{
fprintf(pErrFile, LDT_ErrDesc );
fprintf(pErrFile, "\n");
}
#endif
#ifdef LDT_DISPLAY_ERRORS
#ifndef LDT_DISPLAY_WARNINGS
if(level > LDT_ERROR_LEVEL) return;
#endif
sprintf( buff,"\nPress 'Abort' to exit the application, 'Retry' to debug or 'Ignore' to continue.");
switch( MessageBox(NULL, LDT_ErrDesc, "LDT MESSAGE", MB_ABORTRETRYIGNORE |MB_TASKMODAL |MB_TOPMOST |
(level > LDT_ERROR_LEVEL?MB_ICONWARNING|MB_DEFBUTTON3:MB_ICONERROR|MB_DEFBUTTON2)))
{
case IDABORT: exit(errorcode); /* quit the application */
case IDRETRY: /* debug */
__asm
{
int 3h
};
}
#endif
}

View File

@@ -0,0 +1,297 @@
/*
**************************************************************************************************
* CPA_Ed_1 team *
* File Management *
**************************************************************************************************
*/
#include "Stdinc.h"
#include "File.h"
#include "Types.h"
#ifdef LDT_USE_SINGLE_FILE_BUFFER
char* GBuff = NULL;
unsigned long GBuffSize = 0;
#define GBuffMargin (1024*50) /* 50k above the file size */
#endif
/*
* OPEN a file for reading
* --------------------------------------------------------------
* _pInfoMemFile : the value returned
* _Name : Name of the file.
* Return : Error code(zero for none)
* --------------------------------------------------------------
* Conditions : If the file does not exist or cannot be found, the fopen call fails.
* --------------------------------------------------------------
* Comments : If succes, the pointer value not NULL
* A null pointer value indicates an error.
* If some errors occur, then all space are free
*/
//#define OVERLAPPED_
#ifdef OVERLAPPED_
#define OVERLAPPED_NO_BUFFERING
long f_OpenMem(LDT_tdst_MemFile **_pInfoMemFile,char* _Name)
{
long Err = LDT_EI_Err_None;
*_pInfoMemFile= (LDT_tdst_MemFile *)malloc(sizeof(LDT_tdst_MemFile));
if(*_pInfoMemFile)
{
HANDLE File;
(*_pInfoMemFile)->sPathLength = 0;
(*_pInfoMemFile)->pName= (char *)malloc(( strlen(_Name)+1 ));
strcpy((*_pInfoMemFile)->pName , _Name);
(*_pInfoMemFile)->pBuffer = NULL;
#ifdef OVERLAPPED_NO_BUFFERING
File = CreateFile( _Name, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED|FILE_FLAG_NO_BUFFERING, NULL);
#else
File = CreateFile( _Name, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
#endif
if(File != INVALID_HANDLE_VALUE)
{
(*_pInfoMemFile)->Size = GetFileSize( File, NULL);
if((*_pInfoMemFile)->Size)
{
DWORD BoundSize, VolumeSectorsize, SectorsPerCluster, NumberOfFreeClusters, TotalNumberOfClusters ;
char Drive[4] = "C:\\";
if(_Name[1] == ':') Drive[0] = _Name[0];
GetDiskFreeSpace(_Name[1] == ':'? Drive: NULL, &SectorsPerCluster, &VolumeSectorsize, &NumberOfFreeClusters, &TotalNumberOfClusters );
#ifdef OVERLAPPED_NO_BUFFERING
BoundSize = (*_pInfoMemFile)->Size + 5 + VolumeSectorsize;
BoundSize -= BoundSize%VolumeSectorsize;
(*_pInfoMemFile)->pBuffer= (char*)VirtualAlloc( NULL, BoundSize, MEM_COMMIT, PAGE_READWRITE );
#else
BoundSize = (*_pInfoMemFile)->Size + 5;
(*_pInfoMemFile)->pBuffer= (char*)malloc( BoundSize );
#endif
if((*_pInfoMemFile)->pBuffer)
{
OVERLAPPED overlapped;
overlapped.Offset = overlapped.OffsetHigh = 0;
overlapped.hEvent = CreateEvent( NULL, FALSE, FALSE, NULL);
ReadFile( File, (*_pInfoMemFile)->pBuffer, BoundSize, NULL, &overlapped);
WaitForSingleObject( overlapped.hEvent, INFINITE);
CloseHandle(overlapped.hEvent);
(*_pInfoMemFile)->Pos = 0;
strcpy((*_pInfoMemFile)->pBuffer+(*_pInfoMemFile)->Size , "\n\"\n\n");
}
else Err = LDT_EI_Err_Malloc;
}
else Err = LDT_EI_Err_SeekFile;
CloseHandle(File);
}
else Err = LDT_EI_Err_OpenFile;
}
else Err = LDT_EI_Err_Malloc;
if( Err != LDT_EI_Err_None && *_pInfoMemFile )
{
free((*_pInfoMemFile)->pName);
#ifndef LDT_USE_SINGLE_FILE_BUFFER
if((*_pInfoMemFile)->pBuffer) free((*_pInfoMemFile)->pBuffer);
#endif
free((*_pInfoMemFile));
*_pInfoMemFile = NULL;
}
return Err;
}
#else
long f_OpenMem(LDT_tdst_MemFile **_pInfoMemFile,char* _Name)
{
long Err = LDT_EI_Err_None;
FILE *pFile; /* Pointer of the file */
*_pInfoMemFile= (LDT_tdst_MemFile *)malloc(sizeof(LDT_tdst_MemFile));
if(*_pInfoMemFile)
{
(*_pInfoMemFile)->sPathLength = 0;
(*_pInfoMemFile)->pName= (char *)malloc(( strlen(_Name)+1 ));
strcpy((*_pInfoMemFile)->pName , _Name);
(*_pInfoMemFile)->pBuffer = NULL;
pFile = fopen(_Name, "rb");
if(pFile)
{
(*_pInfoMemFile)->Size = _filelength (_fileno(pFile));
if((*_pInfoMemFile)->Size)
{
#ifdef LDT_USE_SINGLE_FILE_BUFFER
if(GBuffSize < (*_pInfoMemFile)->Size)
{
if(GBuff) free(GBuff);
GBuff = malloc( GBuffSize = (*_pInfoMemFile)->Size + 5 + GBuffMargin);
}
(*_pInfoMemFile)->pBuffer = GBuff;
#else
(*_pInfoMemFile)->pBuffer= (char*) malloc(((*_pInfoMemFile)->Size + 5 ));
#endif
if((*_pInfoMemFile)->pBuffer)
{
if(fread((*_pInfoMemFile)->pBuffer,(*_pInfoMemFile)->Size,1,pFile))
{
(*_pInfoMemFile)->Pos = 0;
strcpy((*_pInfoMemFile)->pBuffer+(*_pInfoMemFile)->Size , "\n\"\n\n");
}
else Err = LDT_EI_Err_ReadFile;
}
else Err = LDT_EI_Err_Malloc;
}
else Err = LDT_EI_Err_SeekFile;
fclose(pFile);
}
else Err = LDT_EI_Err_OpenFile;
}
else Err = LDT_EI_Err_Malloc;
if( Err != LDT_EI_Err_None && *_pInfoMemFile )
{
free((*_pInfoMemFile)->pName);
#ifndef LDT_USE_SINGLE_FILE_BUFFER
if((*_pInfoMemFile)->pBuffer) free((*_pInfoMemFile)->pBuffer);
#endif
free((*_pInfoMemFile));
*_pInfoMemFile = NULL;
}
return Err;
}
#endif
/*
* READ a piece of file from memory
* --------------------------------------------------------------
* _PointerDest : Address of the destination
* _Size : size of data to move (in bytes)
* _pInfoMemFile : Source file address in memory
* Return : error code if <0 or the Size of data moved(for none error)
* --------------------------------------------------------------
* Conditions :
* --------------------------------------------------------------
* Comments : If succes, the return value are the Size of data moved
* A value<0 indicate an error
*/
long f_ReadMem(char * _PointerDest,size_t _Size,LDT_tdst_MemFile *_pInfoMemFile )
{
long Err;
/*if( (_pInfoMemFile->Pos < _pInfoMemFile->Size) && */
if (_pInfoMemFile->Size -_pInfoMemFile->Pos >= _Size)
{
if(_PointerDest == memmove(_PointerDest,_pInfoMemFile->pBuffer+_pInfoMemFile->Pos,_Size))
{
_pInfoMemFile->Pos += _Size;
return _Size;
}
else
Err = -LDT_EI_Err_MemMove;
}
else
Err = -LDT_EI_Err_NotEnoughDataForMove;
return Err;
}
/*
* CLOSE a file (in memory and stream)
* --------------------------------------------------------------
* _pInfoMemFile : Source file address in memory
* Return : error code
* --------------------------------------------------------------
* Conditions : close an open stream
* --------------------------------------------------------------
* Comments : fclose returns 0 if the stream is successfully closed
* return EOF to indicate an error..
* Return value must be int
*/
long f_CloseMem(LDT_tdst_MemFile *_pInfoMemFile)
{
#ifdef LDT_MULTITHREADED
#ifdef OVERLAPPED_NO_BUFFERING
VirtualFree( _pInfoMemFile->pBuffer, 0, MEM_RELEASE);
#else
free( _pInfoMemFile->pBuffer );
#endif
#else
#ifndef LDT_USE_SINGLE_FILE_BUFFER
free(_pInfoMemFile->pBuffer);
#endif
#endif
free(_pInfoMemFile->pName);
free(_pInfoMemFile);
return LDT_EI_Err_None;
}
/*
* SEEK a file in memory to a given position.
* --------------------------------------------------------------
* _File : File to seek.
* _Offset : Offset to seek.
* _Origin : SEEK_SET or SEEK_END.
* Return : error code
* --------------------------------------------------------------
* Conditions : The argument origin must be one of the following constant:
* -SEEK_CUR Current position of file pointer
* -SEEK_END End of file
* -SEEK_SET Beginning of file
* --------------------------------------------------------------
* Comments : If successful, fseek returns 0
* Return value must be long
*/
long f_SeekMem(LDT_tdst_MemFile *_pInfoMemFile ,long _Offset,int _Origin)
{
long Err;
Err = LDT_EI_Err_None;
switch (_Origin)
{
case SEEK_SET:
if(_Offset>=0 && _pInfoMemFile->Size >= (size_t)_Offset)
_pInfoMemFile->Pos = _Offset;
else
Err = LDT_EI_Err_SeekInMem;
break;
case SEEK_CUR:
if(_Offset>0 && ((_pInfoMemFile->Size-_pInfoMemFile->Pos) >= (size_t)_Offset) )
_pInfoMemFile->Pos += _Offset;
else if( _Offset<0 && (_pInfoMemFile->Pos >= (size_t)(-_Offset)))
_pInfoMemFile->Pos += _Offset;
else
Err = LDT_EI_Err_SeekInMem;
break;
case SEEK_END:
if(_Offset <= 0 && (_pInfoMemFile->Size >= (size_t)(-_Offset)))
_pInfoMemFile->Pos = _Offset+_pInfoMemFile->Size;
else
Err = LDT_EI_Err_SeekInMem;
break;
default:
Err = LDT_EI_Err_SeekInMem;
}
return Err;
}
long f_TellMem(LDT_tdst_MemFile *_pInfoMemFile )
{
return _pInfoMemFile->Pos;
}

View File

@@ -0,0 +1,217 @@
/*------------------------------------------------------------------------------
FILE : Hash.c
CREATED : 98/05/12
AUTHOR : Catalin Cocos
CONTENTS: variable size hash table implementation
------------------------------------------------------------------------------*/
#include "StdInc.h"
#include "Hash.h"
/*creation, initialization, deletion
--------------------------------------*/
/*------------------------------------------------------------------------------
DESC. : creates a new hash
INPUT : A) the dispersion function, with the following characteristics:
- input : pointer to a hash element, or NULL;
- output: > if input is NULL, the maximum index possible + 1
> else, the hash index.
B) the comparison function - similar with the one used for the LDT_tdst_DSArray
C) the element deletion function - used to delete the elements
OUTPUT : the newly created hash or NULL
CREATED : 98/05/12
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
LDT_tdst_DSHash* LDT_DSHs_new(int (* _pfnDispersion ) (void*),
int (* _pfnCompare)(const void**, const void** ),
void (* _pfnDelete) (void*) )
{
LDT_tdst_DSHash* pObj = (LDT_tdst_DSHash*) malloc( sizeof(LDT_tdst_DSHash) );
if( LDT_DSHs_Init( pObj, _pfnDispersion, _pfnCompare, _pfnDelete) )
return pObj; /* success */
free( pObj );
return NULL; /* failure */
}
/*------------------------------------------------------------------------------
DESC. : initializes an existing hash
INPUT : see above
OUTPUT : nonzero if successful
CREATED : 98/05/12
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_DSHs_Init(LDT_tdst_DSHash* pObj,
int (* _pfnDispersion ) (void*),
int (* _pfnCompare)(const void**, const void** ),
void (* _pfnDelete) (void*) )
{
int HashDimension;
if(!pObj || !_pfnDispersion || !_pfnCompare || !_pfnDelete ) return 0; /* invalid input */
HashDimension = _pfnDispersion(NULL);
if( !HashDimension ) return 0; /* bad dispersion function */
pObj->pfnDelete = _pfnDelete; /* set the deletion function */
pObj->pfnDispersion = _pfnDispersion; /* set the dispersion function */
pObj->pData = (LDT_tdst_DSArray*) malloc( HashDimension * sizeof(LDT_tdst_DSArray) ); /* allocate the needed memory */
for(HashDimension --; HashDimension>=0; HashDimension--)
{
LDT_DSAr_Init( pObj->pData + HashDimension ); /* initialize the dynamic arrays */
LDT_DSAr_SetSortMethod( pObj->pData + HashDimension, _pfnCompare );
}
return 1; /* success */
}
/*------------------------------------------------------------------------------
DESC. : deletes an existing array
INPUT : - the object
- an integer: DelElements; if non-zero, all elements are freed
(the pfnDelete is called for each element)
CREATED : 98/05/12
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
void LDT_DSHs_delete( LDT_tdst_DSHash* pObj, int DelElements)
{
if( pObj )
{
LDT_DSHs_Close( pObj, DelElements ); /* clean-up */
free( pObj ); /* deletion */
}
}
/*------------------------------------------------------------------------------
DESC. : sets the dynamic aray elements granularity
CREATED : 98/05/12
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
void LDT_DSHs_SetGranularity( LDT_tdst_DSHash* pObj, int _nGrowBy)
{
int HashDimension = pObj->pfnDispersion( NULL ) - 1 ;
for( ; HashDimension>=0; HashDimension--)
LDT_DSAr_SetGranularity( pObj->pData + HashDimension, _nGrowBy ); /* set the granularity for each array */
}
/* Clean up
-------------*/
/*------------------------------------------------------------------------------
DESC. : frees the unused memory
CREATED : 98/05/12
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
void LDT_DSHs_FreeExtra( LDT_tdst_DSHash* pObj )
{
int HashDimension = pObj->pfnDispersion( NULL ) - 1 ;
for( ; HashDimension>=0; HashDimension--)
LDT_DSAr_FreeExtra( pObj->pData + HashDimension );
}
/*------------------------------------------------------------------------------
DESC. : clears the hash, removing all the elements
INPUT : - the object
- an integer: DelElements; if non-zero, all elements are freed
(the pfnDelete is called for each element)
CREATED : 98/05/12
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
void LDT_DSHs_RemoveAll( LDT_tdst_DSHash* pObj, int DelElements)
{
LDT_tdst_DSArray* pCrtAr;
void** pData;
void (* Delete ) (void*) = pObj->pfnDelete;
int i;
int HashDimension = pObj->pfnDispersion( NULL ) - 1 ;
for( ; HashDimension>=0; HashDimension--)
{
pCrtAr = pObj->pData + HashDimension;
if(DelElements)
for(i = LDT_DSAr_GetUpperBound( pCrtAr ), pData = pCrtAr->pData; i>=0; i--)
Delete( pData[i]);
LDT_DSAr_RemoveAll( pCrtAr );
}
}
/*------------------------------------------------------------------------------
DESC. : clears the hash memory
INPUT : - the object
- an integer: DelElements; if non-zero, all elements are freed
(the pfnDelete is called for each element)
CREATED : 98/05/12
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
void LDT_DSHs_Close( LDT_tdst_DSHash* pObj, int DelElements )
{
LDT_DSHs_RemoveAll( pObj, DelElements );
free( pObj->pData );
pObj->pData = NULL;
}
/* Accessing elements
-----------------------*/
/*------------------------------------------------------------------------------
DESC. : gets the hash element matching the parameter
OUTPUT : the equivalent element in the hash, or NULL if none found
CREATED : 98/05/12
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
void* LDT_DSHs_GetEqOf( LDT_tdst_DSHash* pHash, void* pTgt)
{
LDT_tdst_DSArray* pArr;
if( !pTgt ) return NULL;
pArr = pHash->pData + pHash->pfnDispersion( pTgt ); /* get the array */
return LDT_DSAr_GetAt( pArr, LDT_DSAr_Index( pArr, pTgt, NULL )); /* get the element */
}
/*------------------------------------------------------------------------------
DESC. : removes the hash element matching the parameter
OUTPUT : the equivalent element removed, or NULL if none found
CREATED : 98/05/12
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
void* LDT_DSHs_RemoveEqOf( LDT_tdst_DSHash* pHash, void* pTgt )
{
LDT_tdst_DSArray* pArr;
if( !pTgt ) return NULL;
pArr = pHash->pData + pHash->pfnDispersion( pTgt ); /* get the array */
return LDT_DSAr_RemoveAt( pArr, LDT_DSAr_Index( pArr, pTgt, NULL ));/* remove the element */
}
/*------------------------------------------------------------------------------
DESC. : inserts the element in the hash table
INPUT : the hash;
the element to insert;
an integer specifying the action to perform if an equivalent element is found in the hash:
0 -> no action
1 -> delete the element if it is not needed (an equivalent is found)
OUTPUT : the element in the hash: the inserted element or the found equivalent.
CREATED : 98/05/12
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
void* LDT_DSHs_Insert( LDT_tdst_DSHash* pHash, void* pTgt, int del)
{
int position;
LDT_tdst_DSArray* pArr;
if( !pTgt ) return NULL;
pArr = pHash->pData + pHash->pfnDispersion( pTgt ); /* get the array */
if(LDT_DSAr_SAdd( pArr, pTgt, 0, &position ) < 0) /* try to insert the element */
{
/* insertion failed */
void* existing = LDT_DSAr_GetAt( pArr, position);
if( del && (existing != pTgt) )
pHash->pfnDelete (pTgt); /* delete the non-inserted element */
return existing;
}
return pTgt;
}

View File

@@ -0,0 +1,932 @@
/*------------------------------------------------------------------------------
FILE : Interface.c
CREATED : 98/05/21
AUTHOR : Catalin Cocos
CONTENTS: user end functions
------------------------------------------------------------------------------*/
#include "StdInc.h"
#include "Interface.h"
#include "Register.h"
#include "Parser.h"
#include "Refs.h"
#include "Error.h"
#ifdef LDT_LOG_STATISTICS
int LogFileOpened = 0;
TimerStruct TotalFlushtime = {0};
TimerStruct Totalsolvetime = {0};
TimerStruct Totalreadtime = {0};
TimerStruct TotalPostprtime = {0};
unsigned TotalFileCount = 0, TotalNumLinks = 0;
double TotalFileSize = 0.;
#endif
#ifdef LDT_LOG_MEMORY
unsigned long g_allocsize = 0;
unsigned long g_Maxallocsize = 0;
unsigned long g_size;
void* g_palloc;
unsigned long g_allocCount = 0;
unsigned long g_reallocCount = 0;
unsigned long g_freeCount = 0;
#endif
int g_nInitialized = 0;
extern int g_isFileNameValid = 1;
LDT_tdst_Link *g_pGetFrom = NULL;
unsigned short g_usLinkingPerstincence;
/* Link-Value association array
----------------------------------*/
LDT_tdst_DSArray g_arLinkAssocTable;
/* Initialization/Closing functions
-------------------------------------*/
/*------------------------------------------------------------------------------
DESC. : initialization method can be called any number of times.
The method must be called before using the other module functions !!!!!!
OUTPUT : 0 if the module was already initialized, 1 otherwise
CREATED : 98/10/07
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_Initialize()
{
if( g_nInitialized ) return 0;
#ifdef LDT_USE_MMG /* initialization of the memory module */
LDT_fn_v_Mem_InitModule();
#endif /* LDT_USE_MMG */
#ifdef LDT_LOG_MEMORY
g_allocsize = 0;
g_Maxallocsize = 0;
g_allocCount = 0;
g_reallocCount = 0;
g_freeCount = 0;
#endif
#ifdef LDT_LOG_STATISTICS
TotalFileCount = 0;
TotalFileSize = 0.;
TotalNumLinks = 0;
TotalFlushtime.TimeCounter = 0;
Totalsolvetime.TimeCounter = 0;
Totalreadtime.TimeCounter = 0;
TotalPostprtime.TimeCounter = 0;
{
FILE* file = fopen("LDT.log", LogFileOpened++?"a+":"w");
time_t strTime;
struct tm *newtime;
time( &strTime );
newtime = localtime( &strTime );
fprintf(file, "===================================================================\n" );
fprintf(file, "LDT module initialized: %s", asctime( newtime ) );
fprintf(file, "===================================================================\n" );
fclose(file);
}
#endif
g_usLinkingPerstincence = 0; /* maximum linking perstincence */
/* initialize the section type registration table */
LDT_DSAr_Init( &g_ArSectionCallbacks );
LDT_DSAr_SetSortMethod( &g_ArSectionCallbacks, LDT_Compare_CallbackEntries);
LDT_DSAr_SetGranularity( &g_ArSectionCallbacks, 25 );
/* initialize the file type registration table */
LDT_DSAr_Init( &g_ArFileCallbacks );
LDT_DSAr_SetSortMethod( &g_ArFileCallbacks, LDT_Compare_CallbackEntries);
LDT_DSAr_SetGranularity( &g_ArFileCallbacks, 25 );
/* initialize the paths array */
LDT_DSAr_Init( &g_ArBaseDirectories );
/* initialize the paths array */
LDT_DSAr_Init( &g_ArPaths );
LDT_DSAr_SetSortMethod( &g_ArPaths, LDT_Compare_CallbackEntries);
LDT_DSAr_SetGranularity( &g_ArPaths, 25 );
/* initialize the path strings array */
LDT_DSAr_Init( &g_ArPathStrings );
LDT_DSAr_SetSortMethod( &g_ArPathStrings, LDT_Compare_Strings);
LDT_DSAr_SetGranularity( &g_ArPathStrings, 25 );
/* initialize the post-process registration table */
LDT_DSAr_Init( &g_ArSolvers );
LDT_DSAr_SetSortMethod( &g_ArSolvers, SortSolvers );
LDT_DSAr_SetGranularity( &g_ArSolvers, 25 );
/* contents initialization */
LDT_DSAr_Init( &TheFileDesc.arContents );
LDT_DSAr_SetSortMethod( &TheFileDesc.arContents, LDT_Compare_Positions );
LDT_DSAr_SetGranularity( &TheFileDesc.arContents, 100 );
/* contents initialization */
#ifdef LDT_LOG_STATISTICS
InitializeTimingEnvironment();
#endif
#ifdef LDT_MULTITHREADED
InitializeCriticalSection( &GReadExclusion );
#endif
/* initialize the parser */
InitParser();
/* first instance activated */
#ifdef LDT_LOG_ERRORS
InitErrFile();
#endif
/* initialize the link/value table */
LDT_DSAr_Init( &g_arLinkAssocTable );
LDT_DSAr_SetSortMethod( &g_arLinkAssocTable, LDT_Compare_LinkValues);
LDT_DSAr_SetGranularity( &g_arLinkAssocTable, 100 );
/* initialize the string array */
LDT_DSAr_Init( &g_ArFilenames );
LDT_DSAr_SetSortMethod( &g_ArFilenames, LDT_Compare_Strings);
LDT_DSAr_SetGranularity( &g_ArFilenames, 100 );
/* initialize the reference table */
LDT_DSAr_Init( &g_ArRefs );
LDT_DSAr_SetSortMethod( &g_ArRefs, LDT_Compare_Refs);
LDT_DSAr_SetGranularity( &g_ArRefs, 100 );
/* initialize the link table */
LDT_DSHs_Init(&g_HashLinks,
(int(*)(void*))LDT_Link_Dispersion,
LDT_Compare_Links,
(void(*)(void*))LDT_Delete_Link);
LDT_DSHs_SetGranularity( &g_HashLinks, 100 );
return (g_nInitialized = 1); /* the module was initialized */
}
/*------------------------------------------------------------------------------
DESC. : Closing method can be called any number of times.
OUTPUT : 0 if the module was already closed, 1 otherwise
CREATED : 98/05/21
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_Close()
{
if(!g_nInitialized) return 0;
/*_____________________________________________________________________________*/
LDT_FlushAndForget(0); /* load the unresolved refs and delete the internal linktable */
LDT_CleanUpRegistrations(); /* delete the registered stuff */
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
/* close the link table (deleting the existing links) */
LDT_DSHs_Close( &g_HashLinks, 1);
#ifdef LDT_MULTITHREADED
DeleteCriticalSection( &GReadExclusion );
#endif
#ifdef LDT_LOG_ERRORS
CLoseErrFile();
#endif
#ifdef LDT_LOG_STATISTICS
{
TimerStruct TempTimer;
FILE* file = fopen("LDT.log", LogFileOpened++?"a+":"w");
time_t strTime;
struct tm *newtime;
time( &strTime );
newtime = localtime( &strTime );
fprintf(file, "===================================================================\n" );
fprintf(file, "Totals:\n\n" );
fprintf(file, "Flush Time:\t\t%.3f\n", ReadTimer(&TotalFlushtime) );
fprintf(file, "Read Time:\t\t%.3f\n", ReadTimer(&Totalreadtime) );
#ifdef LDT_MULTITHREADED
fprintf(file, "Process Time:\t\t%.3f\n", ReadTimer(&Totalsolvetime) );
#else
TempTimer.TimeCounter = Totalsolvetime.TimeCounter - Totalreadtime.TimeCounter;
fprintf(file, "Process Time:\t\t%.3f\n", ReadTimer(&TempTimer));
#endif
fprintf(file, "Postprocess Time:\t%.3f\n", ReadTimer(&TotalPostprtime) );
#ifdef LDT_MULTITHREADED
{
TempTimer.TimeCounter = TotalPostprtime.TimeCounter + Totalsolvetime.TimeCounter + Totalreadtime.TimeCounter;
fprintf(file, "\nMultithreaded disk read performance:\n");
fprintf(file, "Useful Time:\t\t%.3f\n", ReadTimer(&TempTimer));
fprintf(file, "Absloute Time Gain:\t%.3f\n", ReadTimer(&TempTimer) - ReadTimer(&TotalFlushtime));
TempTimer.TimeCounter -= TotalFlushtime.TimeCounter;
fprintf(file, "Disk Read Savings: \t%.1f%%\n", (ReadTimer(&TempTimer))*100/ReadTimer(&Totalreadtime));
}
#endif
fprintf(file, "\nSections:\t\t%u", TotalNumLinks );
fprintf(file, "\nFiles:\t\t\t%u", TotalFileCount );
fprintf(file, "\nRead:\t\t\t%.3f MB\n\n", TotalFileSize/1024/1024 );
#ifdef LDT_LOG_MEMORY
fprintf(file, "\nMaximum Memory Used:\t%.3f MB\n", ((double)g_Maxallocsize)/1024/1024 );
fprintf(file, "\nMalloc Count:\t\t%u\n", g_allocCount );
fprintf(file, "Free Count:\t\t%u\n", g_freeCount );
fprintf(file, "Realloc Count:\t\t%u\n", g_reallocCount );
fprintf(file, "Memory Leaks:\t\t%.3f KB\n", ((double)g_allocsize)/1024 );
fprintf(file, "\nWarning, time estimation is affected by the memory measurements. \n\n");
#endif
fprintf(file, "LDT module closed: %s", asctime( newtime ) );
fprintf(file, "===================================================================\n" );
fprintf(file, "\n\n\n");
fclose(file);
}
#endif
#ifdef LDT_USE_MMG /* release the memory module */
LDT_fn_v_Mem_CloseModule();
#endif /* DMS_USE_MMG */
g_nInitialized = 0;
return 1;
}
/*------------------------------------------------------------------------------
DESC. : unregisters all registered types, paths and solvers - memory clean-up
CREATED : 98/09/22
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
void LDT_CleanUpRegistrations()
{
int i, j;
// if(InstanceCount)
// {
// ERRoR(0, NULL, 0, "All types and paths registrations are deleted during a loading session");
// return;
// }
if( g_nInitialized == 0 ) return;
/* close the section type registration table */
for( i = LDT_DSAr_GetUpperBound(&g_ArSectionCallbacks); i>=0; i--)
{
free(((LDT_tdst_CallbackEntry*)g_ArSectionCallbacks.pData[i])->szType);
free( g_ArSectionCallbacks.pData[i]);
}
LDT_DSAr_RemoveAll( &g_ArSectionCallbacks );
/* close the file type registration table */
for( i = LDT_DSAr_GetUpperBound(&g_ArFileCallbacks); i>=0; i--)
{
free(((LDT_tdst_CallbackEntry*)g_ArFileCallbacks.pData[i])->szType);
free( g_ArFileCallbacks.pData[i]);
}
LDT_DSAr_RemoveAll( &g_ArFileCallbacks );
/* close the post-process registration table */
{
LDT_tdst_DSArray* pRef;
for( i = LDT_DSAr_GetUpperBound(&g_ArSolvers); i>=0; i--)
{
pRef = (LDT_tdst_DSArray*)((tdst_Solver*)g_ArSolvers.pData[i])->hRef;
if(pRef)
for( j = LDT_DSAr_GetUpperBound(pRef); j>=0; j--)
free( pRef->pData[j]);
LDT_DSAr_delete( pRef );
free( g_ArSolvers.pData[i]);
}
}
LDT_DSAr_RemoveAll( &g_ArSolvers );
/* close the base paths table */
for( i = LDT_DSAr_GetUpperBound(&g_ArBaseDirectories); i>=0; i--)
free(g_ArBaseDirectories.pData[i]);
LDT_DSAr_RemoveAll(&g_ArBaseDirectories);
/* close the path table */
for( i = LDT_DSAr_GetUpperBound(&g_ArPaths); i>=0; i--)
{
LDT_DSAr_RemoveAll(&((LDT_tdst_TypePaths*)g_ArPaths.pData[i])->arPaths);
free( ((LDT_tdst_TypePaths*)g_ArPaths.pData[i])->szExtension );
free(g_ArPaths.pData[i]);
}
LDT_DSAr_RemoveAll(&g_ArPaths);
/* close the path strings table */
for( i = LDT_DSAr_GetUpperBound(&g_ArPathStrings); i>=0; i--)
free(g_ArPathStrings.pData[i]);
LDT_DSAr_RemoveAll(&g_ArPathStrings);
}
/* Link-Value association functions
-------------------------------------*/
/*------------------------------------------------------------------------------
DESC. : associates an userd-supplied value to a link
CREATED : 98/08/19
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
void LDT_SetLinkValue( LDT_tdst_Link* pLink, unsigned long value )
{
int idx, iidx;
idx = LDT_DSAr_Index( &g_arLinkAssocTable, (LDT_tdst_LinkValue*)&pLink, &iidx );
if( idx<0 )
{ /* the link is not present in the table */
LDT_tdst_LinkValue* pNewAssoc = malloc(sizeof(LDT_tdst_LinkValue));
pNewAssoc->pLink = pLink;
pNewAssoc->value = value;
LDT_DSAr_InsertAt( &g_arLinkAssocTable, iidx, pNewAssoc );
}
else
{
((LDT_tdst_LinkValue*)g_arLinkAssocTable.pData[idx])->value = value; /* link already present -> change the associated value */
#if defined(LDT_ERROR_TREATMENT) && ( LDT_WARNING_LEVEL >= 3 || LDT_ERROR_LEVEL >= 3)
ERRoR(3, pLink, 0, "Link associated value already present. The old value was overwritten.");
#endif
}
}
/*------------------------------------------------------------------------------
DESC. : retrieves the user-supplied value associated to the link
CREATED : 98/08/19
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
unsigned long LDT_GetLinkValue( LDT_tdst_Link* pLink )
{
int idx = LDT_DSAr_Index( &g_arLinkAssocTable, (LDT_tdst_LinkValue*)&pLink, NULL );
if(idx < 0)
{
#if defined(LDT_ERROR_TREATMENT) && ( LDT_WARNING_LEVEL >= 3 || LDT_ERROR_LEVEL >= 3)
ERRoR(3, pLink, 0, "No associated value available for this link.");
#endif
return 0;
}
return ((LDT_tdst_LinkValue*)LDT_DSAr_GetAt( &g_arLinkAssocTable, idx ))->value;
}
/*------------------------------------------------------------------------------
DESC. : retrieves and removes the user-supplied value associated to the link
CREATED : 98/09/31
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
unsigned long LDT_RemoveLinkValue( LDT_tdst_Link* pLink )
{
LDT_tdst_LinkValue* pAssoc;
unsigned long value;
int idx = LDT_DSAr_Index( &g_arLinkAssocTable, (LDT_tdst_LinkValue*)&pLink, NULL );
if(idx < 0)
{
#if defined(LDT_ERROR_TREATMENT) && ( LDT_WARNING_LEVEL >= 3 || LDT_ERROR_LEVEL >= 3)
ERRoR(3, pLink, 0, "No associated value available for this link.");
#endif
return 0;
}
pAssoc = (LDT_tdst_LinkValue*)LDT_DSAr_RemoveAt( &g_arLinkAssocTable, idx );
value = pAssoc->value;
free(pAssoc);
return value;
}
/* Loading functions
-------------------------------------*/
/*------------------------------------------------------------------------------
DESC. : Find a link
OUTPUT : The pointer to link ( NULL if not found )
-1 on error;
CREATED : 98/08/19
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
LDT_tdst_Link* LDT_GetLink( char *szSection )
{
LDT_tdst_Link *pLink, *pRetVal;
if( szSection==NULL)
return NULL;
pLink=LDT_CreateLinkFromReference( szSection );
pRetVal=LDT_DSHs_GetEqOf(&g_HashLinks, (void *)pLink);
LDT_Delete_Link( pLink );
#if defined(LDT_ERROR_TREATMENT) && ( LDT_WARNING_LEVEL >= 2 || LDT_ERROR_LEVEL >= 2)
if(!pRetVal)
ERRoR(2, NULL, 0, "No link matches this description.");
#endif
return pRetVal;
}
/*------------------------------------------------------------------------------
DESC. : Load a section
OUTPUT : The allocated object(can be NULL)
-1 on error;
CREATED : 98/05/22
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
void* LDT_LoadSection( char* szSection )
{
int errcode, level;
LDT_tdst_Link *Link = NULL;
g_pGetFrom=NULL; /* MP-for refs */
if(szSection) /* loading request */
{
Link = LDT_CreateLinkFromReference( szSection );/* normal call */
if( !Link ) return (void*)-1; /* error */
Link = LDT_DSHs_Insert( &g_HashLinks, Link, 1);
g_pGetFrom=Link; /* MP-for refs */
if( Link->dwFlags & LDT_LF_ALLOCATED )
return Link->pObject; /* the link was already processed */
g_isFileNameValid = 0;
errcode = Link->Type->Create( Link ); /* create the object */
g_isFileNameValid = 1;
if(errcode)
{
#if defined(LDT_ERROR_TREATMENT)
ERRoR(0, Link, errcode, "Unable to create associated object.");
#endif
return (void*)-1;
}
Link->dwFlags |= LDT_LF_ALLOCATED; /* set the corresponding flag */
AddReference( Link ); /* append the reference */
return Link->pObject;
}
if( g_FileDesc ) /* sub-section loading */
{
void* pObject;
LDT_tdst_CallbackEntry* Type = GetType( g_szType, LDT_REG_SECTION );
Link=LDT_Create_Link( g_szId, g_szParent, g_FileDesc->szFile, Type, g_usLinkingPerstincence, NULL, pParent[g_FileDesc->iLevel-1] );
Link=(LDT_tdst_Link *)LDT_DSHs_Insert( &g_HashLinks, (void *)Link, 1 );
pParent[ g_FileDesc->iLevel ]=Link;
g_CrtSection=Link;
if( Link->dwFlags&LDT_LF_LOADED )
{
pObject = Link->pObject; /* the link was already processed */
LDT_SkipSection();
if( Link->dwFlags & LDT_LF_VOLATILE)
free ( LDT_DSHs_RemoveEqOf( &g_HashLinks, Link)); /* remove volatile subsection*/
return pObject;
}
if( (Link->dwFlags & LDT_LF_ALLOCATED) == 0 )
{
errcode = Type->Create( Link );
if(errcode )
{
#if defined(LDT_ERROR_TREATMENT)
ERRoR(0, Link, errcode, "Unable to create associated object.");
#endif
return (void*)-1;
}
Link->dwFlags |= LDT_LF_ALLOCATED; /* the link was allocated */
}
level = g_FileDesc->iLevel - 1;
errcode = Type->Load( Link );
pObject = Link->pObject;
if(errcode)
{
#if defined(LDT_ERROR_TREATMENT)
ERRoR(0, Link, errcode, "Unable to load section. User error triggered in callback.");
#endif
pObject = (void*)-1;
}
else if(level != g_FileDesc->iLevel)
{
#if defined(LDT_ERROR_TREATMENT)
ERRoR(0, Link, 0, "Erroneous load callback. Failure to reach the section end mark! (premature return or subsections not treated)");
#endif
pObject = (void*)-1;
}
Link->dwFlags |= LDT_LF_LOADED; /* the link was loaded */
if( Link->dwFlags & LDT_LF_VOLATILE)
LDT_Delete_Link( LDT_DSHs_RemoveEqOf( &g_HashLinks, Link)); /* remove volatile subsection*/
return pObject;
}
#if defined(LDT_ERROR_TREATMENT)
ERRoR(0, NULL, 0, "Cannot Load Subsection. Called from outside any \"Load\" callback.");
#endif
return (void*)-1;
}
/*------------------------------------------------------------------------------
DESC. : Load a section
OUTPUT : pointer to the allocated object
( can be different from the received parameter -
if the section was previously allocated)
-1 on error;
CREATED : 98/05/22
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
void* LDT_LoadSectionAt( char* szSection, void* pSection )
{
int errcode, level;
LDT_tdst_Link *Link = NULL;
g_pGetFrom=NULL; /* MP-for refs */
if(szSection) /* loading request */
{
Link = LDT_CreateLinkFromReference( szSection );/* normal call */
if( !Link ) return (void*)-1; /* error */
Link = LDT_DSHs_Insert( &g_HashLinks, Link, 1);
g_pGetFrom=Link; /* MP-for refs */
if( Link->dwFlags & LDT_LF_ALLOCATED )
return Link->pObject; /* the link was already processed */
Link->pObject = pSection; /* copy the object */
#if defined(LDT_ERROR_TREATMENT) && ( LDT_WARNING_LEVEL >= 2 || LDT_ERROR_LEVEL >= 2)
if(!pSection)
ERRoR(2, Link, 0, "Associated object is set to NULL.");
#endif
Link->dwFlags |= LDT_LF_ALLOCATED; /* set the corresponding flag */
AddReference( Link ); /* append the reference */
return Link->pObject;
}
if( g_FileDesc ) /* sub-section loading */
{
void* pObject;
LDT_tdst_CallbackEntry* Type = GetType( g_szType, LDT_REG_SECTION );
Link=LDT_Create_Link( g_szId, g_szParent, g_FileDesc->szFile, Type, g_usLinkingPerstincence, NULL, pParent[g_FileDesc->iLevel-1] );
Link=(LDT_tdst_Link *)LDT_DSHs_Insert( &g_HashLinks, (void *)Link, 1 );
pParent[ g_FileDesc->iLevel ]=Link;
g_CrtSection=Link;
if( Link->dwFlags&LDT_LF_LOADED )
{
pObject = Link->pObject; /* the link was already processed */
LDT_SkipSection();
if( Link->dwFlags & LDT_LF_VOLATILE)
free ( LDT_DSHs_RemoveEqOf( &g_HashLinks, Link)); /* remove volatile subsection*/
return pObject;
}
if( (Link->dwFlags & LDT_LF_ALLOCATED) == 0 )
{
Link->pObject = pSection; /* copy the object */
#if defined(LDT_ERROR_TREATMENT) && ( LDT_WARNING_LEVEL >= 2 || LDT_ERROR_LEVEL >= 2)
if(!pSection)
ERRoR(2, Link, 0, "Associated object is set to NULL.");
#endif
Link->dwFlags |= LDT_LF_ALLOCATED; /* the link was allocated */
}
level = g_FileDesc->iLevel - 1;
errcode = Type->Load( Link );
pObject = Link->pObject;
if(errcode)
{
#if defined(LDT_ERROR_TREATMENT)
ERRoR(0, Link, errcode, "Unable to load section. User error triggered in callback.");
#endif
pObject = (void*)-1;
}
else if(level != g_FileDesc->iLevel)
{
#if defined(LDT_ERROR_TREATMENT)
ERRoR(0, Link, 0, "Erroneous load callback. Failure to reach the section end mark! (premature return or subsections not treated)");
#endif
pObject = (void*)-1;
}
Link->dwFlags |= LDT_LF_LOADED; /* the link was loaded */
if( Link->dwFlags & LDT_LF_VOLATILE)
LDT_Delete_Link( LDT_DSHs_RemoveEqOf( &g_HashLinks, Link)); /* remove volatile subsection*/
return pObject;
}
#if defined(LDT_ERROR_TREATMENT)
ERRoR(0, NULL, 0, "Cannot Load Subsection. Called from outside any \"Load\" callback.");
#endif
return (void*)-1;
}
#ifdef LDT_MULTITHREADED
HANDLE GReadCount; /* the number of files read from disk */
HANDLE GReadLimit; /* the number of available files */
HANDLE GFileLimit = NULL; /* the maximum number of files read in advance */
#pragma warning(disable: 4100)
/*------------------------------------------------------------------------------
DESC. : File Reading thread method
CREATED : 98/07/07
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
//unsigned int __stdcall DiskRead( void * p);
unsigned int __stdcall DiskRead( void * p)
{
LDT_tdst_Refs * pRefs;
LDT_tdst_MemFile* pFile;
unsigned int uiPos=0;
static char buffer[256];
int ok=1;
// SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE );
for(;;)
{
WaitForSingleObject( GReadLimit, INFINITE); /* wait to have the number of opened files less than the max allowed */
WaitForSingleObject( GFileLimit, INFINITE); /* wait to have at least one file available for reading */
EnterCriticalSection( &GReadExclusion );
if((pRefs = g_pFileToRead)==NULL)
{
LeaveCriticalSection( &GReadExclusion );
break;
}
g_pFileToRead = pRefs->p_NextReferencedFile;
LeaveCriticalSection( &GReadExclusion );
// SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
pFile = AccessFile( pRefs->szFile ); /* open the file */
// SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE );
pRefs->pFile = pFile;
ReleaseSemaphore( GReadCount, 1, NULL); /* the file was opened */
}
return 0;
}
#pragma warning(default: 4100)
#endif
void LDT_SetLinkingPersistence (unsigned short Level)
{
if( g_ArRefs.nSize )
LDT_Flush();
g_usLinkingPerstincence = Level;
}
void LDT_Forget(unsigned short Level)
{
int i, gap, maxValue, HashDimension;
LDT_tdst_DSArray* pCrtAr;
void** pData;
LDT_DSAr_RemoveAll( &g_ArRefs ); /* the reference table is empty at this point - no other closing procedure necessary*/
LDT_DSAr_RemoveAll( &TheFileDesc.arContents);
#ifdef LDT_USE_SINGLE_FILE_BUFFER
if(GBuff) free(GBuff);
GBuff = NULL;
GBuffSize = 0;
#endif
if(Level)
{ /* Partial clean-up. Not reccomended due to low speed performance */
/* delete the invalid associations from the link/value table */
for( i = gap = 0, maxValue = LDT_DSAr_GetSize(&g_arLinkAssocTable), pData = g_arLinkAssocTable.pData; i<maxValue; i++)
{
if(((short)(((LDT_tdst_LinkValue*)pData[i])->pLink->dwFlags)) >= Level )
{
free( pData[i]);
gap++;
}
else
pData[i-gap] = pData[i];
}
LDT_DSAr_SetSize(&g_arLinkAssocTable, maxValue - gap); /* adjust the size of the array */
/* delete the not needed links from the links hash table */
for(HashDimension = g_HashLinks.pfnDispersion( NULL ) - 1 ; HashDimension>=0; HashDimension--)
{
pCrtAr = g_HashLinks.pData + HashDimension;
pData = pCrtAr->pData;
for( i = gap = 0, maxValue = LDT_DSAr_GetSize(pCrtAr); i<maxValue; i++)
{
if(((short)(((LDT_tdst_Link*)pData[i])->dwFlags)) >= Level )
{
g_HashLinks.pfnDelete( pData[i]);
gap++;
}
else
pData[i-gap] = pData[i];
}
LDT_DSAr_SetSize(pCrtAr, maxValue - gap); /* adjust the size of the array */
}
}
else
{ /* Total clean-up. The normal operation */
/*------------------------------- delete the existing links and the related data ----------------------*/
/* close the link/value table(deleting all stored associations) */
for( i = LDT_DSAr_GetUpperBound(&g_arLinkAssocTable), pData = g_arLinkAssocTable.pData; i>=0; i--)
free( pData[i]);
LDT_DSAr_RemoveAll( &g_arLinkAssocTable );
/* close the string array (deleting all stored strings) */
for( i = LDT_DSAr_GetUpperBound(&g_ArFilenames), pData = g_ArFilenames.pData; i>=0; i--)
free( pData[i]);
LDT_DSAr_RemoveAll( &g_ArFilenames );
LDT_DSHs_RemoveAll( &g_HashLinks, 1);
}
}
/*------------------------------------------------------------------------------
DESC. : Reference solving function - performs loading & deletes the linktable afterwards
OUTPUT : zero on error, nonzero if successful;
CREATED : 98/05/24
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_FlushAndForget(unsigned short Level)
{
int ERR = LDT_Flush();
LDT_Forget( Level );
return ERR;
}
/*------------------------------------------------------------------------------
DESC. : Reference solving function - performs the loading
OUTPUT : zero on error, nonzero if successful;
CREATED : 98/05/24
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
extern unsigned char* g_ulPos;
int LDT_Flush()
{
static int FlushLaunched = 0;
int OK = 1, i;
#ifdef LDT_LOG_STATISTICS
unsigned CurrentLinks = 0;
TimerStruct FlushTime = TotalFlushtime;
TimerStruct SolveTime = Totalsolvetime;
TimerStruct Readtime = Totalreadtime;
TimerStruct Postprtime = TotalPostprtime ;
unsigned FileCount = TotalFileCount;
double FileSize = TotalFileSize;
{ /* count the number of links */
int HashDimension = g_HashLinks.pfnDispersion( NULL ) - 1 ;
for( ; HashDimension>=0; HashDimension--)
CurrentLinks += LDT_DSAr_GetSize( g_HashLinks.pData + HashDimension );
}
#endif
if(FlushLaunched)
{
#if defined(LDT_ERROR_TREATMENT)
ERRoR(0, NULL, 0, "Recursive call to LDT_Flush() not allowed. Call aborted. ");
#endif
return 0;
}
FlushLaunched = 1; /* sentinel */
#ifdef LDT_LOG_STATISTICS
StartTimer(&TotalFlushtime);
#endif
do
{
if(g_pFileToProcess)
{
#ifdef LDT_MULTITHREADED
unsigned thrdaddr; /* the read thread */
HANDLE Hthrd; /* the read thread */
GReadCount = CreateSemaphore( NULL, 0, LONG_MAX, NULL ); /* the number of files read from disk */
GFileLimit = CreateSemaphore( NULL, g_ArRefs.nSize, LONG_MAX, NULL ); /* the number of available files */
GReadLimit = CreateSemaphore( NULL, MAX_FILE_NO, LONG_MAX, NULL ); /* the maximum number of files read in advance */
InitializeCriticalSection( &GReadExclusion );
Hthrd = (void*)_beginthreadex(NULL, 0, DiskRead, NULL, 0, &thrdaddr); /* start the thread that reads files from disk */
#endif
/* processing */
for(;g_pFileToProcess;)
{
#ifdef LDT_MULTITHREADED
WaitForSingleObject( GReadCount, INFINITE);
// SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST );
#endif
#ifdef LDT_LOG_STATISTICS
StartTimer(&Totalsolvetime);
#endif
if( Solve(g_pFileToProcess) ) /* the effective loading */
{
#if defined(LDT_ERROR_TREATMENT) && ( LDT_WARNING_LEVEL >= 2 || LDT_ERROR_LEVEL >= 2)
ERRoR(2, NULL, 0, "Unable to satisfy all loading requests for the previous file.");
#endif
OK = 0; /* Error encountered */
}
#ifdef LDT_LOG_STATISTICS
StopTimer(&Totalsolvetime);
#endif
LDT_DSAr_RemoveAll(&g_pFileToProcess->Links);
#ifdef LDT_MULTITHREADED
// SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL );
ReleaseSemaphore( GReadLimit, 1, NULL); /* signal that the file was processed */
#endif
{
LDT_tdst_Refs * pRefs = g_pFileToProcess;
g_pFileToProcess = g_pFileToProcess->p_NextReferencedFile;
free( LDT_DSAr_RemoveAt( &g_ArRefs, LDT_DSAr_Index(&g_ArRefs, pRefs, NULL) ) );
}
}
#ifdef LDT_MULTITHREADED
ReleaseSemaphore( GReadLimit, 1, NULL ); /* allow the file reading thread to advance */
ReleaseSemaphore( GFileLimit, 1, NULL ); /* allow the file reading thread to advance */
WaitForSingleObject( Hthrd, INFINITE );
CloseHandle( Hthrd );
CloseHandle( GReadCount );
CloseHandle( GFileLimit );
CloseHandle( GReadLimit );
GFileLimit = NULL;
#endif
}
#ifdef LDT_LOG_STATISTICS
StartTimer(&TotalPostprtime);
#endif
/* post-process */
for( i=0; i<g_ArSolvers.nSize; i++ )
{
tdst_Solver *pSolver=(tdst_Solver *)LDT_DSAr_GetAt( &g_ArSolvers, i );
pSolver->Solve( pSolver->hRef );
}
#ifdef LDT_LOG_STATISTICS
StopTimer(&TotalPostprtime);
#endif
}
while(g_pFileToProcess);
#ifdef LDT_LOG_STATISTICS
StopTimer(&TotalFlushtime);
{ /* count the number of links */
TimerStruct TempTimer;
FILE* file = fopen("LDT.log", LogFileOpened++?"a+":"w");
time_t strTime;
struct tm *newtime;
unsigned NumLinks = 0;
int HashDimension = g_HashLinks.pfnDispersion( NULL ) - 1 ;
for( ; HashDimension>=0; HashDimension--)
NumLinks += LDT_DSAr_GetSize( g_HashLinks.pData + HashDimension );
TotalNumLinks += NumLinks - CurrentLinks;
FlushTime.TimeCounter = TotalFlushtime.TimeCounter - FlushTime.TimeCounter;
SolveTime.TimeCounter = Totalsolvetime.TimeCounter - SolveTime.TimeCounter;
Readtime.TimeCounter = Totalreadtime.TimeCounter - Readtime.TimeCounter;
Postprtime.TimeCounter = TotalPostprtime.TimeCounter - Postprtime.TimeCounter;
FileCount = TotalFileCount - FileCount;
FileSize = TotalFileSize - FileSize;
time( &strTime );
newtime = localtime( &strTime );
fprintf(file, "-------------------------------------------\n" );
fprintf(file, "Flush Stats:\n\n" );
fprintf(file, "Flush Time:\t\t%.3f\n", ReadTimer(&FlushTime) );
fprintf(file, "Read Time:\t\t%.3f\n", ReadTimer(&Readtime) );
#ifdef LDT_MULTITHREADED
fprintf(file, "Process Time:\t\t%.3f\n", ReadTimer(&SolveTime) );
#else
TempTimer.TimeCounter = SolveTime.TimeCounter - Readtime.TimeCounter;
fprintf(file, "Process Time:\t\t%.3f\n", ReadTimer(&TempTimer));
#endif
fprintf(file, "Postprocess Time:\t%.3f\n", ReadTimer(&Postprtime) );
#ifdef LDT_MULTITHREADED
{
TempTimer.TimeCounter = Postprtime.TimeCounter + SolveTime.TimeCounter + Readtime.TimeCounter;
fprintf(file, "\nMultithreaded disk read performance:\n");
fprintf(file, "Useful Time:\t\t%.3f\n", ReadTimer(&TempTimer));
fprintf(file, "Absloute Time Gain:\t%.3f\n", ReadTimer(&TempTimer) - ReadTimer(&FlushTime));
TempTimer.TimeCounter -= FlushTime.TimeCounter;
fprintf(file, "Disk Read Savings: \t%.1f%%\n", (ReadTimer(&TempTimer))*100/ReadTimer(&Readtime));
}
#endif
fprintf(file, "\nSections:\t\t%u", NumLinks - CurrentLinks );
fprintf(file, "\nFiles:\t\t\t%u", FileCount );
fprintf(file, "\nRead:\t\t\t%.3f MB\n\n", FileSize/1024/1024 );
fprintf(file, "-------------------------------------------\n" );
fprintf(file, "\n\n\n");
fclose(file);
}
#endif /* LDT_LOG_STATISTICS */
FlushLaunched = 0; /* sentinel removal */
return OK; /* return the error code */
}
/* In-callback link manipulation functions
-------------------------------------*/
void LDT_SetVolatileSubsection( LDT_tdst_Link* Link)
{
Link->dwFlags |= LDT_LF_VOLATILE;
}

View File

@@ -0,0 +1,356 @@
/*------------------------------------------------------------------------------
FILE : Link.c
CREATED : 19/05/97
AUTHOR : Catalin Cocos
CONTENTS: linktable/position functions
------------------------------------------------------------------------------*/
#include "StdInc.h"
#include "Register.h"
#include "Parser.h"
/* Globals
-------------*/
tdst_DSHash g_HashLinks; /* the linktable */
tdst_DSArray g_ArRefs; /* thereferences, grouped by file */
tdst_DSArray g_ArFilenames; /* thefilename strings */
int InstanceCount = 0; /* init counter */
char LDT_EMPTY_STR[1] = {0};
/*------------------------------------------------------------------------------
DESC. : computes the dispersion value for a link
CREATED : 98/05/19
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_Link_Dispersion( LDT_tdst_Link* pObj )
{
char* szName;
unsigned char pHashVal = 0;
if( !pObj ) return 256;
szName = (pObj->dwFlags & LDT_LF_FILE)? pObj->szFile: pObj->szName;
while(*szName) pHashVal = (unsigned char) ( (pHashVal<<5) + pHashVal + *szName++);
return pHashVal;
/*/
unsigned long pHashVal = 0;
if( !pObj ) return 65536;
szName = (pObj->dwFlags & LDT_LF_FILE)? pObj->szFile: pObj->szName;
while(*szName) pHashVal = ((pHashVal<<7) + pHashVal + *szName++);
return (unsigned short)pHashVal;*/
}
/*------------------------------------------------------------------------------
DESC. : Compares two links
CREATED : 98/05/19
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_Compare_Links(const void** _pA, const void** _pB)
{
LDT_tdst_Link* A = (LDT_tdst_Link*) *_pA;
LDT_tdst_Link* B = (LDT_tdst_Link*) *_pB;
int Result = A->szFile - B->szFile;
if(Result == 0)
{
Result = A->Type - B->Type;
if(Result == 0)
{
Result = strcmp( A->szParent, B->szParent);
if(Result == 0)
Result = strcmp( A->szName, B->szName );
}
}
if( Result<0 ) return -1;
return Result;
}
/*------------------------------------------------------------------------------
DESC. : creates a link record, given its description
CREATED : 98/05/21
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
LDT_tdst_Link* LDT_CreateLinkFromReference( char* szSection ) /* the section description */
{
unsigned long dwFlags = 0;
LDT_tdst_CallbackEntry* Type;
LDT_tdst_Link* Link = NULL;
char *szType, *szParent = NULL, *szName = NULL, *szFile = NULL;
/* convert the input string to lower case */
char *sz=szSection;
for( ; *sz; sz++ )
if( ( *sz>='A') && ( *sz<='Z' ) )
*sz+='a'-'A';
szParent = strchr( szSection, '^'); /* get the parent description */
szType = strrchr( szSection, '^'); /* get the section type name */
/* get the section type */
if(!szType)
{
/* the reference is to a file */
dwFlags = LDT_LF_FILE;
if((szType = strrchr( szSection, '.' )) != NULL)
szType++;
Type = GetType( szType, LDT_REG_FILE );
szType = NULL;
}
else
{
/* the reference is to a section */
szName = strrchr(szType, ':'); /* get the section name */
if(szName) *szName++ = 0;
*szType = 0;
Type = GetType( szType+1, LDT_REG_SECTION);
if( szType == szParent ) szParent = NULL;
else *szParent++ = 0;
}
/* get the name of the file (in which the section is located) */
if( *szSection == '*')/* the current file */
{
if( g_FileDesc ) szFile = g_FileDesc->szFile; /* we are inside a file, all correct */
}
else
{ /* an absolute path */
int iidx, idx = DSAr_Index( &g_ArFilenames, szSection, &iidx );
if(idx>=0) szFile = g_ArFilenames.pData[idx]; /* we have it in the string table */
else
{ /* the filename is not present in the string table - it is added now */
strcpy( szFile = (char*) malloc( strlen(szSection) + 1 ), szSection);
DSAr_InsertAt(&g_ArFilenames, iidx, szFile );
}
}
if( szFile )
{
/* we have a valid section description */
Link= (LDT_tdst_Link *) malloc( sizeof( LDT_tdst_Link ) );
if( szName && *szName)
{
Link->szName=(char*) malloc( strlen( szName ) +1 );
strcpy( Link->szName, szName );
}
else Link->szName=LDT_EMPTY_STR;
if( szParent )
{
Link->szParent=(char*) malloc( strlen( szParent) +1 );
strcpy( Link->szParent, szParent );
}
else Link->szParent=LDT_EMPTY_STR;
Link->szFile = szFile;
Link->Type = Type;
Link->dwFlags = dwFlags;
Link->pObject = NULL;
Link->pParent = g_CrtSection;
}
if( szType) *( szType ) = '^';
if( szName ) *( szName-1 ) = ':';
if( szParent) *( szParent -1 ) = '^';
return Link;
}
/*------------------------------------------------------------------------------
DESC. : creates a link record
CREATED : 98/05/21
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
LDT_tdst_Link* LDT_Create_Link( char* szName, /* the section name */
char* szParent, /* the section parent */
char* szFile, /* the file containing the section - stored in a string table */
LDT_tdst_CallbackEntry* Type,
unsigned long dwFlags, /* flags */
void* pObject, /* the allocated memory structure or NULL */
LDT_tdst_Link* pParent) /* the section that requested the loading */
{
LDT_tdst_Link *Link;
if (!Type) return NULL;
Link = (LDT_tdst_Link *) malloc( sizeof( LDT_tdst_Link ) );
if( szName && *szName )
{
Link->szName=(char*) malloc( strlen( szName ) +1 );
strcpy( Link->szName, szName );
}
else Link->szName=LDT_EMPTY_STR;
if( szParent && *szParent )
{
Link->szParent=(char*) malloc( strlen( szParent) +1 );
strcpy( Link->szParent, szParent );
}
else Link->szParent=LDT_EMPTY_STR;
Link->szFile = szFile;
Link->Type = Type;
Link->dwFlags = dwFlags;
Link->pObject = pObject;
Link->pParent = pParent;
return Link;
}
/*------------------------------------------------------------------------------
DESC. : destroys a link record
CREATED : 98/05/21
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
void LDT_Delete_Link( LDT_tdst_Link *Link )
{
if( Link->szName != LDT_EMPTY_STR ) free( Link->szName );
if( Link->szParent != LDT_EMPTY_STR ) free( Link->szParent );
free(Link);
}
/*------------------------------------------------------------------------------
DESC. : deletes an existing array
CREATED : 98/05/19
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_Compare_Positions(const void** _pA, const void** _pB)
{
LDT_tdst_Position* A = (LDT_tdst_Position*) *_pA;
LDT_tdst_Position* B = (LDT_tdst_Position*) *_pB;
int Result = strcmp( A->szName, B->szName );
if(Result == 0)
{
Result = A->Type - B->Type ;
if(Result == 0)
Result = strcmp( A->szParent, B->szParent);
}
if( Result<0 ) return -1;
return Result;
}
/*------------------------------------------------------------------------------
DESC. : creates a section position record
CREATED : 98/05/19
AUTHOR : Mircea Petrescu
MODIFIED: Catalin Cocos 98/05/22
------------------------------------------------------------------------------*/
LDT_tdst_Position *LDT_Create_Position( char *szName,
char *szParent,
LDT_tdst_CallbackEntry* Type,
unsigned short uwFlags,
unsigned long ulPos,
unsigned long nLine,
int iLevel
)
{
LDT_tdst_Position *pos= (LDT_tdst_Position *) malloc( sizeof( LDT_tdst_Position ) );
if( szName )
{
pos->szName=(char*) malloc( strlen( szName ) +1 );
strcpy( pos->szName, szName );
}
else pos->szName=LDT_EMPTY_STR;
if( szParent )
{
pos->szParent=(char*) malloc( strlen( szParent) +1 );
strcpy( pos->szParent, szParent );
}
else pos->szParent=LDT_EMPTY_STR;
pos->Type = Type;
pos->uwFlags=uwFlags;
pos->dwPos=ulPos;
pos->nLine = nLine;
pos->iLevel=iLevel;
return pos;
}
/*------------------------------------------------------------------------------
DESC. : destroys a section position record
CREATED : 98/05/19
AUTHOR : Mircea Petrescu
------------------------------------------------------------------------------*/
void LDT_Delete_Position( LDT_tdst_Position *pos )
{
if( pos->szName != LDT_EMPTY_STR ) free( pos->szName );
if( pos->szParent != LDT_EMPTY_STR ) free( pos->szParent );
free( pos );
}
/*------------------------------------------------------------------------------
DESC. : Compares two names
CREATED : 98/05/22
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_Compare_Strings(const void** _pA, const void** _pB)
{
int Result = strcmp( (char*)(*_pA), (char*)(*_pB) );
if( Result<0 ) return -1;
return Result;
}
/* Reference - related */
/*------------------------------------------------------------------------------
DESC. : Adds a reference in the reference structure
CREATED : 98/05/22
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
void AddReference( LDT_tdst_Link* pLink )
{
int idx, position;
tdst_DSArray* pRefs;
idx = DSAr_Index( &g_ArRefs, (LDT_tdst_Refs*) pLink, &position );
if( idx<0 )
{
LDT_tdst_Refs* pNewRef = (LDT_tdst_Refs*) malloc( sizeof(LDT_tdst_Refs));
pNewRef->szFile = pLink->szFile;
pRefs = &(pNewRef->Links);
DSAr_Init( pRefs );
DSAr_SetSortMethod( pRefs, LDT_Compare_Links );
#ifdef LDT_MULTITHREADED
pNewRef->pFile = NULL;
EnterCriticalSection( &GReadExclusion );
#endif
DSAr_InsertAt( &g_ArRefs, idx = position, pNewRef );
#ifdef LDT_MULTITHREADED
ReleaseSemaphore( GFileLimit, 1, NULL ); /* a new file is available for reading */
LeaveCriticalSection( &GReadExclusion );
#endif
}
pRefs = &( ((LDT_tdst_Refs*)g_ArRefs.pData[idx])->Links); /* the reference collection */
if( pLink->dwFlags & LDT_LF_FILE )
{
/* the whole file is to be added */
DSAr_RemoveAll( pRefs ); /* remove all the existing references */
DSAr_Add( pRefs, pLink ); /* add the unique reference to the file */
}
else
{
if(DSAr_GetSize( pRefs ) && (((LDT_tdst_Link*)pRefs->pData[0])->dwFlags & LDT_LF_FILE ) )
return;
DSAr_SAdd( pRefs, pLink, 0, NULL );
}
}
/*------------------------------------------------------------------------------
DESC. : Compares two refs
CREATED : 98/05/22
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_Compare_Refs(const void** _pA, const void** _pB)
{
int Result = ((LDT_tdst_Refs*)*_pA)->szFile - ((LDT_tdst_Refs*)*_pB)->szFile;
if( Result<0 ) return -1;
return Result;
}

View File

@@ -0,0 +1,407 @@
/*------------------------------------------------------------------------------
FILE : Link.c
CREATED : 98/05/19
AUTHOR : Catalin Cocos
CONTENTS: linktable/position functions
------------------------------------------------------------------------------*/
#include "StdInc.h"
#include "Register.h"
#include "Parser.h"
#include "Error.h"
/* Globals
-------------*/
LDT_tdst_DSHash g_HashLinks; /* the linktable */
LDT_tdst_DSArray g_ArRefs; /* the references, grouped by file */
LDT_tdst_DSArray g_ArFilenames; /* the filename strings */
LDT_tdst_Refs* g_pFileToProcess = NULL; /* the file to load */
LDT_tdst_Refs* g_pLastFileQueued = NULL; /* the last fiel referenced */
#ifdef LDT_MULTITHREADED
LDT_tdst_Refs* g_pFileToRead = NULL; /* the file to read */
#endif
extern unsigned short g_usLinkingPerstincence;
char LDT_EMPTY_STR[1] = {0};
/*------------------------------------------------------------------------------
DESC. : methods to allow external access to the list of filenames
CREATED : 98/05/19
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_GetReferencedFilesNumber()
{
return g_ArFilenames.nSize;
}
const char* LDT_GetReferencedFile(int idx)
{
return (const char*) LDT_DSAr_GetAt(&g_ArFilenames, idx);
}
/*------------------------------------------------------------------------------
DESC. : computes the dispersion value for a link
CREATED : 98/05/19
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
#pragma warning ( disable: 4244)
int LDT_Link_Dispersion( LDT_tdst_Link* pObj )
{
char* szName;
unsigned char pHashVal = 0;
if( !pObj ) return 256;
szName = (pObj->dwFlags & LDT_LF_FILE)? pObj->szFile: pObj->szName;
// while(*szName) pHashVal = (unsigned char) ( (pHashVal<<5) + pHashVal + *szName++);
/* hash computing is CASE INSENSITIVE */
while(*szName)
pHashVal += (unsigned char) ( (pHashVal<<5) | 0xDF&*szName++);
return pHashVal;
}
#pragma warning ( default: 4244)
/*------------------------------------------------------------------------------
DESC. : Compares two links
CREATED : 98/05/19
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_Compare_Links(const void** _pA, const void** _pB)
{
LDT_tdst_Link* A = (LDT_tdst_Link*) *_pA;
LDT_tdst_Link* B = (LDT_tdst_Link*) *_pB;
int Result = A->szFile - B->szFile;
if(Result == 0)
{
Result = A->Type - B->Type;
if(Result == 0)
{
Result = stricmp( A->szParent, B->szParent);
if(Result == 0)
Result = stricmp( A->szName, B->szName );
}
}
if( Result<0 ) return -1;
return Result;
}
/*------------------------------------------------------------------------------
DESC. : Compares two links
CREATED : 98/08/27
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_Compare_LinkValues(const void** _pA, const void** _pB)
{
long Result = ((LDT_tdst_LinkValue*)*_pA)->pLink - ((LDT_tdst_LinkValue*)*_pB)->pLink;
if( Result<0 ) return -1;
return Result;
}
/*------------------------------------------------------------------------------
DESC. : creates a link record, given its description
CREATED : 98/05/21
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
LDT_tdst_Link* LDT_CreateLinkFromReference( char* szSection ) /* the section description */
{
unsigned long dwFlags = g_usLinkingPerstincence;
LDT_tdst_CallbackEntry* Type;
LDT_tdst_Link* Link = NULL;
char *szType, *szParent = NULL, *szName = NULL, *szFile = NULL;
/* cut the ':^' from the section desc.*/
char *sz=szSection;
int delta = 0;
for( ; *sz; sz++ )
if( *sz == ':' && (sz[1] == '^' || !sz[1]))
delta--;
else sz[delta]=*sz;
sz[delta]=0;
szParent = strchr( szSection, '^'); /* get the parent description */
szType = strrchr( szSection, '^'); /* get the section type name */
/* get the section type */
if(!szType)
{
/* the reference is to a file */
dwFlags |= LDT_LF_FILE;
if((szType = strrchr( szSection, '.' )) != NULL)
szType++;
Type = GetType( szType, LDT_REG_FILE );
szType = NULL;
}
else
{
/* the reference is to a section */
szName = strrchr(szType, ':'); /* get the section name */
if(szName) *szName++ = 0;
*szType = 0;
Type = GetType( szType+1, LDT_REG_SECTION);
if( szType == szParent ) szParent = NULL;
else *szParent++ = 0;
}
/* get the name of the file (in which the section is located) */
if( *szSection == '*')/* the current file */
{
if( g_FileDesc ) szFile = g_FileDesc->szFile; /* we are inside a file, all correct */
}
else
{ /* an absolute path */
int iidx, idx = LDT_DSAr_Index( &g_ArFilenames, szSection, &iidx );
if(idx>=0) szFile = g_ArFilenames.pData[idx]; /* we have it in the string table */
else
{ /* the filename is not present in the string table - it is added now */
strcpy( szFile = (char*) malloc( strlen(szSection) + 1 ), szSection);
LDT_DSAr_InsertAt(&g_ArFilenames, iidx, szFile );
}
}
if( szFile )
{
/* we have a valid section description */
Link= (LDT_tdst_Link *) malloc( sizeof( LDT_tdst_Link ) );
if( szName && *szName)
{
Link->szName=(char*) malloc( strlen( szName ) +1 );
strcpy( Link->szName, szName );
}
else Link->szName=LDT_EMPTY_STR;
if( szParent )
{
Link->szParent=(char*) malloc( strlen( szParent) +1 );
strcpy( Link->szParent, szParent );
}
else Link->szParent=LDT_EMPTY_STR;
Link->szFile = szFile;
Link->Type = Type;
Link->dwFlags = dwFlags;
Link->pObject = NULL;
Link->pParent = g_CrtSection;
Link->wUnsolvedRefs = 0; /* MP - postprocess */
}
#if defined(LDT_ERROR_TREATMENT)
else
ERRoR(0, NULL, 0, "Unable to create Link. Invalid Link Description");
#endif
if( szType) *( szType ) = '^';
if( szName ) *( szName-1 ) = ':';
if( szParent) *( szParent -1 ) = '^';
return Link;
}
/*------------------------------------------------------------------------------
DESC. : creates a link record
CREATED : 98/05/21
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
LDT_tdst_Link* LDT_Create_Link( char* szName, /* the section name */
char* szParent, /* the section parent */
char* szFile, /* the file containing the section - stored in a string table */
LDT_tdst_CallbackEntry* Type,
unsigned long dwFlags, /* flags */
void* pObject, /* the allocated memory structure or NULL */
LDT_tdst_Link* pParent) /* the section that requested the loading */
{
LDT_tdst_Link *Link;
if (!Type) return NULL;
Link = (LDT_tdst_Link *) malloc( sizeof( LDT_tdst_Link ) );
if( szName && *szName )
{
Link->szName=(char*) malloc( strlen( szName ) +1 );
strcpy( Link->szName, szName );
}
else Link->szName=LDT_EMPTY_STR;
if( szParent && *szParent )
{
Link->szParent=(char*) malloc( strlen( szParent) +1 );
strcpy( Link->szParent, szParent );
}
else Link->szParent=LDT_EMPTY_STR;
Link->szFile = szFile;
Link->Type = Type;
Link->dwFlags = dwFlags;
Link->pObject = pObject;
Link->pParent = pParent;
Link->wUnsolvedRefs = 0; /* MP - postprocess */
return Link;
}
/*------------------------------------------------------------------------------
DESC. : destroys a link record
CREATED : 98/05/21
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
void LDT_Delete_Link( LDT_tdst_Link *Link )
{
if( Link->szName != LDT_EMPTY_STR ) free( Link->szName );
if( Link->szParent != LDT_EMPTY_STR ) free( Link->szParent );
free(Link);
}
/*------------------------------------------------------------------------------
DESC. : deletes an existing array
CREATED : 98/05/19
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_Compare_Positions(const void** _pA, const void** _pB)
{
LDT_tdst_Position* A = (LDT_tdst_Position*) *_pA;
LDT_tdst_Position* B = (LDT_tdst_Position*) *_pB;
int Result = A->Type - B->Type ;
if(Result == 0)
{
Result = stricmp( A->szParent, B->szParent);
if(Result == 0)
Result = stricmp( A->szName, B->szName );
}
if( Result<0 ) return -1;
return Result;
}
/*------------------------------------------------------------------------------
DESC. : creates a section position record
CREATED : 98/05/19
AUTHOR : Mircea Petrescu
MODIFIED: Catalin Cocos 98/05/22
------------------------------------------------------------------------------*/
LDT_tdst_Position *LDT_Create_Position( char *szName,
char *szParent,
LDT_tdst_CallbackEntry* Type,
unsigned short uwFlags,
unsigned long ulPos,
unsigned long nLine,
int iLevel
)
{
LDT_tdst_Position *pos= (LDT_tdst_Position *) malloc( sizeof( LDT_tdst_Position ) );
if( szName )
{
pos->szName=(char*) malloc( strlen( szName ) +1 );
strcpy( pos->szName, szName );
}
else pos->szName=LDT_EMPTY_STR;
if( szParent )
{
pos->szParent=(char*) malloc( strlen( szParent) +1 );
strcpy( pos->szParent, szParent );
}
else pos->szParent=LDT_EMPTY_STR;
pos->Type = Type;
pos->uwFlags=uwFlags;
pos->dwPos=ulPos;
pos->nLine = nLine;
pos->iLevel=iLevel;
return pos;
}
/*------------------------------------------------------------------------------
DESC. : destroys a section position record
CREATED : 98/05/19
AUTHOR : Mircea Petrescu
------------------------------------------------------------------------------*/
void LDT_Delete_Position( LDT_tdst_Position *pos )
{
if( pos->szName != LDT_EMPTY_STR ) free( pos->szName );
if( pos->szParent != LDT_EMPTY_STR ) free( pos->szParent );
free( pos );
}
/*------------------------------------------------------------------------------
DESC. : Compares two names
CREATED : 98/05/22
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_Compare_Strings(const void** _pA, const void** _pB)
{
int Result = stricmp( (char*)(*_pA), (char*)(*_pB) );
if( Result<0 ) return -1;
return Result;
}
/* Reference - related */
/*------------------------------------------------------------------------------
DESC. : Adds a reference in the reference structure
CREATED : 98/05/22
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
void AddReference( LDT_tdst_Link* pLink )
{
int idx, position;
LDT_tdst_DSArray* pRefs;
idx = LDT_DSAr_Index( &g_ArRefs, (LDT_tdst_Refs*) pLink, &position );
if( idx<0 )
{
LDT_tdst_Refs* pNewRef = (LDT_tdst_Refs*) malloc( sizeof(LDT_tdst_Refs));
pNewRef->p_NextReferencedFile = NULL; /* this is the last file referenced */
pNewRef->szFile = pLink->szFile;
pRefs = &(pNewRef->Links);
LDT_DSAr_Init( pRefs );
LDT_DSAr_SetSortMethod( pRefs, LDT_Compare_Links );
LDT_DSAr_SetGranularity( pRefs, 50 );
LDT_DSAr_InsertAt( &g_ArRefs, idx = position, pNewRef );
if(g_pFileToProcess) g_pLastFileQueued->p_NextReferencedFile = pNewRef; /* insert the reference in the list of files to load... */
else g_pFileToProcess = pNewRef;
g_pLastFileQueued = pNewRef;
#ifdef LDT_MULTITHREADED
EnterCriticalSection( &GReadExclusion );
if(!g_pFileToRead)
g_pFileToRead = pNewRef;
LeaveCriticalSection( &GReadExclusion );
pNewRef->pFile = NULL;
if(GFileLimit)
ReleaseSemaphore( GFileLimit, 1, NULL ); /* a new file is available for reading */
#endif
}
pRefs = &( ((LDT_tdst_Refs*)g_ArRefs.pData[idx])->Links); /* the reference collection */
if( pLink->dwFlags & LDT_LF_FILE )
{
/* the whole file is to be added */
LDT_DSAr_RemoveAll( pRefs ); /* remove all the existing references */
LDT_DSAr_Add( pRefs, pLink ); /* add the unique reference to the file */
}
else
{
if(LDT_DSAr_GetSize( pRefs ) && (((LDT_tdst_Link*)pRefs->pData[0])->dwFlags & LDT_LF_FILE ) )
return;
LDT_DSAr_SAdd( pRefs, pLink, 0, NULL );
}
}
/*------------------------------------------------------------------------------
DESC. : Compares two refs
CREATED : 98/05/22
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_Compare_Refs(const void** _pA, const void** _pB)
{
int Result = ((LDT_tdst_Refs*)*_pA)->szFile - ((LDT_tdst_Refs*)*_pB)->szFile;
if( Result<0 ) return -1;
return Result;
}

View File

@@ -0,0 +1,136 @@
/*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
* Mem.c
* Managment of memory.
* CPA_Ed_1 team
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
/*
*=================================================================================================
* Includes.
*=================================================================================================
*/
/* conditional compilation */
#ifdef LDT_USE_MMG
#include "StdInc.h"
#if !defined(U64)
#define __DeclareGlobalVariableMmgLDT_h__
#define __DeclareGlobalVariableErrLDT_h__
#include "Mem.h"
#include "ErrLDT.h" /* ERM */
#include "MmgLDT.h" /* MMG */
#undef __DeclareGlobalVariableMmgLDT_h__
#undef __DeclareGlobalVariableErrLDT_h__
#endif /* U64 */
/*
*-------------------------------------------------------------------------------------------------
* malloc
*-------------------------------------------------------------------------------------------------
*/
void* LDT_malloc_Mmg(size_t _size)
{
void* _Pointer;
Mmg_M_SetModeAlloc4Ch(LDT, E_ucDynamic, C_ucMmgDefaultChannel);
_Pointer = Mmg_fn_p_vAlloc4Ch(_size, C_ucMmgDefaultChannel);
if(Erm_M_uwCheckError(Mmg, C_ucErmDefaultChannel))
Erm_M_ClearLastError(C_ucErmDefaultChannel);
if(_Pointer == NULL){};
return _Pointer;
}
/*
*-------------------------------------------------------------------------------------------------
* realloc
*-------------------------------------------------------------------------------------------------
*/
void *LDT_realloc_Mmg(void * _PointerSrc, size_t _Size)
{
Mmg_M_SetModeAlloc4Ch(LDT, E_ucDynamic, C_ucMmgDefaultChannel);
_PointerSrc = Mmg_fn_p_vRealloc4Ch(_PointerSrc, _Size , C_ucMmgDefaultChannel);
if(Erm_M_uwCheckError(Mmg, C_ucErmDefaultChannel))
Erm_M_ClearLastError(C_ucErmDefaultChannel);
if(_PointerSrc == NULL) { };
return _PointerSrc;
}
/*
*-------------------------------------------------------------------------------------------------
* free
*-------------------------------------------------------------------------------------------------
*/
void LDT_free_Mmg(void *_Pointer)
{
if(_Pointer)
{
Mmg_M_SetModeAlloc4Ch(LDT, E_ucDynamic, C_ucMmgDefaultChannel);
if(Erm_M_uwCheckError(Mmg, C_ucErmDefaultChannel))
Erm_M_ClearLastError(C_ucErmDefaultChannel);
Mmg_fn_vFree4Ch(_Pointer, C_ucMmgDefaultChannel);
_Pointer = NULL;
}
}
/*
*-------------------------------------------------------------------------------------------------
* Init of memory managment.
*-------------------------------------------------------------------------------------------------
*/
void LDT_fn_v_Mem_InitModule(void)
{
static char s_cFirstInit = 1;
/* Must init only one time error module (in case of multiple script init/close) */
if(s_cFirstInit == 1)
{
Erm_M_InitErrMsg(LDT);
s_cFirstInit = 0;
}
Mmg_M_InitMmg(LDT);
}
/*
*-------------------------------------------------------------------------------------------------
* Close.
*-------------------------------------------------------------------------------------------------
*/
void LDT_fn_v_Mem_CloseModule(void)
{
Mmg_fn_v_StopMmg(Erm_M_ucGiveModuleId(LDT));
}
/*
*-------------------------------------------------------------------------------------------------
* Init of memory managment.
* Use of MMG and ERM modules.
* _p_ulMemorySize : Address of unsigned long size for blocs. Size if 0 for a dynamic malloc.
*-------------------------------------------------------------------------------------------------
*/
void LDT_fn_v_Mem_InitWithMemLevel(unsigned long *_p_ulMemorySize)
{
unsigned char ucIndex;
for(ucIndex = 0; ucIndex < E_ucLDTMaxBlocksNb; ucIndex++)
{
Mmg_M_InitBlockV5_1_0(LDT, ucIndex, *_p_ulMemorySize,200000);
_p_ulMemorySize++;
}
}
#endif /* LDT_USE_MMG */

View File

@@ -0,0 +1,813 @@
/*------------------------------------------------------------------------------
FILE : Parser.c
CREATED : 98/05/17
AUTHOR : Mircea Petrescu
CONTENTS: parsing structures, variables & functions
------------------------------------------------------------------------------*/
#include <string.h>
#include "StdInc.h"
#include "File.h"
#include "DynArray.h"
#include "Parser.h"
#include "Register.h"
#include "Link.h"
#ifdef LDT_MULTITHREADED
CRITICAL_SECTION GReadExclusion;
#endif
#define FALSE 0
#define TRUE 1
/* Valid characters in a word */
char tbl[256];
/* variables used for in place break into words */
char g_lastChar=0;
int g_lastIndex=-1;
int parseLen[256], parseCount;
unsigned char* parsePos[256];
/* for in-place word break */
unsigned char* g_ulPos=0;
unsigned long g_ulBeginLineMark; /* last begin of line found */
/* variables for building a complete section name (in case of subsections) */
char g_szType[512]="";
char g_szName[512]="";
char g_szParent[512]="";
char g_szId[512]="";
LDT_tdst_FileDesc TheFileDesc, *g_FileDesc=NULL;
LDT_tdst_Link *g_CrtSection=NULL;
/*------------------------------------------------------------------------------
DESC. : initializes character classes for parsing
CREATED : 98/05/17
AUTHOR : Mircea Petrescu
------------------------------------------------------------------------------*/
void InitParser( void )
{
char sztmp[]=":^!%&*+-<=>?_|~\\QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890";
int i;
for( i=0; i<128; i++ )
tbl[i]= (char)(( strchr( sztmp, (char)i )!=NULL )?1:0 );
for( i=128; i<255; i++ )
tbl[i]= 1;
tbl[255]=0;
tbl[(unsigned char )'\"']=2;
tbl[(unsigned char )'[']=3;
tbl[(unsigned char )']']=4;
tbl[(unsigned char )'$']=5;
tbl[(unsigned char )'{']=6;
tbl[(unsigned char )'}']=7;
tbl[(unsigned char )';']=8;
tbl[(unsigned char )'\n']=9;
}
/*------------------------------------------------------------------------------
DESC. : access function for word #i in current line
CREATED : 98/05/17
AUTHOR : Mircea Petrescu
MODIFIED: Catalin Cocos
------------------------------------------------------------------------------*/
char *LDT_szGetParam( int i )
{
if( (i<0) || (i>parseCount) )
return NULL;
if( g_FileDesc->iLastIndex!=-1 )
*g_ulPos=g_FileDesc->chLastChar;
g_ulPos = parsePos[i]+parseLen[i];
g_FileDesc->chLastChar = *g_ulPos;
*g_ulPos = 0;
g_FileDesc->iLastIndex = i;
return (char *) parsePos[i];
}
/*------------------------------------------------------------------------------
DESC. : actualize section name and level in file @ begin section
CREATED : 98/05/17
AUTHOR : Mircea Petrescu
------------------------------------------------------------------------------*/
void BeginSection( void )
{
char *szName=LDT_szGetParam( 0 );
char *szId;
if( g_szParent[0]!=0 )
strcat( g_szParent, "^" );
strcat( g_szParent, g_szName );
strcpy( g_szName, szName );
szId=strchr( g_szName, ':' );
if( szId )
{
strcpy( g_szId, szId+1 );
*szId=0;
strcpy( g_szType, g_szName );
*szId=':';
}
else
{
g_szId[0]=0;
strcpy( g_szType, szName );
}
if( !(g_FileDesc->uwLoadType) )
/* construct file contents in case not loading all file */
{
DSAr_Add( &g_FileDesc->arContents,
(void *) LDT_Create_Position( g_szId, g_szParent, GetType( g_szType, LDT_REG_SECTION ),
g_FileDesc->uwFlags, g_ulBeginLineMark, g_FileDesc->iLineNumber,
g_FileDesc->iLevel )
);
}
g_FileDesc->iLevel++;
}
/*------------------------------------------------------------------------------
DESC. : actualize section name and level in file @ end section
CREATED : 98/05/17
AUTHOR : Mircea Petrescu
------------------------------------------------------------------------------*/
void EndSection( void )
{
char *szTmp, *szTmp1;
int erase=0;
g_FileDesc->iLevel--;
szTmp=strrchr( g_szParent, '^' ); /* get last child in parent xxx:xx^xxx:xx^XXX:XX */
if( szTmp ) /* if we have a child ( parent is not xxx:xx )*/
{
*szTmp=0; /* cut it from parent */
szTmp++;
}
else {
szTmp=g_szParent; /* only one section name */
erase=1; /* so erase it after we extract child */
}
strcpy( g_szName, szTmp ); /* CC - moved this line here !!! the copy is always needed /// paste it to current section name */
szTmp1=strchr( szTmp, ':' ); /* current name in szTmp */
if( szTmp1 )
{
strcpy( g_szId, szTmp1+1 ); /* split it in Type:Id */
*szTmp1=0;
}
else g_szId[0]=0;
strcpy( g_szType, szTmp );
if( erase )
g_szParent[0]=0;
if( g_FileDesc->iLevel==0 ) /* adjust for file level */
{
g_szName[0]=0;
g_szParent[0]=0;
g_CrtSection=NULL;
}
}
/*------------------------------------------------------------------------------
DESC. : split a line in the component words
CREATED : 98/06/29
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int bConvertToLowerCase=0;
void GetWords( LDT_tdst_MemFile* pMemFile, unsigned char* buffer, int bSeek )
{
int i = 0;
if( bSeek )
{
while( buffer[i] != '\n' ) i++;
pMemFile->Pos = buffer +i +1 - (unsigned char *)pMemFile->pBuffer;
return;
}
for(;;)
{
while( tbl[buffer[i]] == 0 ) i++;
switch( tbl[buffer[i]] )
{
case 2: /* a string */
i++;
parsePos[parseCount]= buffer + i;
while( buffer[i] != '\"') i++;
parseLen[parseCount] = buffer +i -parsePos[parseCount];
parseCount++;
i++;
break;
case 3: /* a format specifier -- ignore */
while( buffer[i] != ']' && buffer[i] != '\n' ) i++;
if(buffer[i] == ']') i++;
break;
case 8: /* comment - skip the rest of the line */
while( buffer[i] != '\n') i++;
case 9: /* end of line */
pMemFile->Pos = buffer +i +1 - (unsigned char *)pMemFile->pBuffer;
return;
default: /* an usual word */
parsePos[parseCount]= buffer + i;
if( bConvertToLowerCase )
while( tbl[buffer[i]] == 1 )
{
if( buffer[i]>='A' && buffer[i]<='Z' )
buffer[i] += 'a'-'A';
i++;
}
else
while( tbl[buffer[i]] == 1 ) i++;
parseLen[parseCount] = buffer +i -parsePos[parseCount];
parseCount++;
break;
}
}
}
LDT_tdeParseResult fn_e_ParseLine( int bSeek )
{
LDT_tdst_MemFile* pMemFile = g_FileDesc->_pInfoMemFile;
unsigned char *buffer;
parseCount=0; /* no words */
bConvertToLowerCase = 0; /* no lowercase conversion*/
if( g_FileDesc->iLastIndex!=-1 )
{ /* sentinel - restores the previously requested word */
*g_ulPos = g_FileDesc->chLastChar;
g_FileDesc->iLastIndex=-1;
}
for( ;; )
{
int i = 0;
if(pMemFile->Pos >= pMemFile->Size) /* the end of file was reached*/
return (g_FileDesc->iLevel? ParseResult_EOF: ParseResult_EndSection);
buffer=(unsigned char *)pMemFile->pBuffer+pMemFile->Pos; /* the line buffer */
g_FileDesc->iLineNumber++; /* incrementing the line number */
while( tbl[buffer[i]] == 0 ) i++; /* skipping the blank spaces */
g_ulBeginLineMark=pMemFile->Pos + i; /* the beginning of the line */
switch( tbl[buffer[i]] )
{
case 1: /* an entry */
GetWords(pMemFile, buffer +i, bSeek);
return ParseResult_Entry;
case 5: /* directive */
bConvertToLowerCase = 1; /* to lowercase */
GetWords(pMemFile, buffer +i +1, bSeek);
bConvertToLowerCase = 0;
if(!parseCount) break;
switch(*((long*)LDT_szGetParam( 0 )))
{
case 'crof': g_FileDesc->uwFlags|=LDT_uw_Anl_ForceAnalyse; break; /* "ForceAnalyse" */
case 'fdne': g_FileDesc->uwFlags&=~LDT_uw_Anl_ForceAnalyse; break; /* "EndForceAnalyse" */
case 'ston': g_FileDesc->uwFlags|=LDT_uw_Anl_NotSaveSection; break; /* "NotSaveSection" */
case 'ndne': g_FileDesc->uwFlags&=~LDT_uw_Anl_NotSaveSection; break;/* "EndNotSaveSection"*/
case 'ctes': /* "SetCurrentFileLong" || "SetCurrentFileDouble" */
if( parseCount != 3 ) break; // TODO : Signal ERROR
i = atoi( LDT_szGetParam( 1 ) );
if( i<0 || i>7 ) break;
if( strcmp( LDT_szGetParam( 0 ), "setcurrentfiledouble" ) )
g_FileDesc->ulValues[i]=(unsigned long)atol( LDT_szGetParam( 2 ) );
else
g_FileDesc->dValues[i]=(double)atof( LDT_szGetParam( 2 ) );
break;
case 'mmoc': /* "Comments" */
for(g_FileDesc->uwFlags|=LDT_uw_Anl_Comments;;) /* parse the file until the "EndComments" directive is found or EOF is reached */
{
i = 0;
if(pMemFile->Pos >= pMemFile->Size) /* the end of file was reached*/
return (g_FileDesc->iLevel? ParseResult_EOF: ParseResult_EndSection);
buffer=(unsigned char *)pMemFile->pBuffer+pMemFile->Pos; /* the line buffer */
g_FileDesc->iLineNumber++; /* incrementing the line number */
while( tbl[buffer[i]] == 0 ) i++; /* skipping the blank spaces */
g_ulBeginLineMark=pMemFile->Pos + i; /* the beginning of the line */
if(tbl[buffer[i]] == 5)
{
bConvertToLowerCase = 1;
GetWords(pMemFile, buffer +i +1, bSeek);
bConvertToLowerCase = 0;
if(parseCount && (!strcmp( LDT_szGetParam( 0 ), "endcomments" )))
g_FileDesc->uwFlags&=~LDT_uw_Anl_Comments;
break;
}
else
{
while( tbl[buffer[i]] != 9 ) i++; /* skip the line */
pMemFile->Pos = buffer +i +1 - (unsigned char*)pMemFile->pBuffer;
}
}
}
break;
case 6: /* begin of section */
bConvertToLowerCase = 1; /* to lowercase */
GetWords(pMemFile, buffer +i +1, 0);
BeginSection();
return ParseResult_BeginSection;
case 7: /* end of section */
GetWords( pMemFile, buffer +i +1, bSeek);
EndSection();
return ParseResult_EndSection;
case 8: /* a comment */
while( tbl[buffer[i]] != 9 ) i++; /* skip the line */
case 9: /* an empty line */
pMemFile->Pos = buffer +i +1 - (unsigned char*)pMemFile->pBuffer;
break;
}
}
}
/*------------------------------------------------------------------------------
DESC. : get next entry in section ( or begin/end section )
CREATED : 98/05/17
AUTHOR : Mircea Petrescu
------------------------------------------------------------------------------*/
LDT_tdeParseResult LDT_GetNextEntry( void )
{
return fn_e_ParseLine(0);
}
/*------------------------------------------------------------------------------
DESC. : various access functions for callbacks
CREATED : 98/05/17
AUTHOR : Mircea Petrescu
------------------------------------------------------------------------------*/
char *LDT_szGetSectionName()
{
return g_szId;
}
char *LDT_szGetSectionType()
{
return g_szType;
}
char *LDT_szGetEntryName()
{
return LDT_szGetParam(0);
}
int LDT_iGetNbParams()
{
return parseCount;
}
/*------------------------------------------------------------------------------
DESC. : various access functions for file values
CREATED : 98/05/17
AUTHOR : Mircea Petrescu
------------------------------------------------------------------------------*/
unsigned long LDT_GetFileLong( int i )
{
if( !g_FileDesc )
return 0;
return g_FileDesc->ulValues[i];
}
double LDT_GetFileDouble( int i )
{
if( !g_FileDesc )
return (double)0.0;
return g_FileDesc->dValues[i];
}
void LDT_SetFileLong( int i, unsigned long ul )
{
if( !g_FileDesc )
return;
g_FileDesc->ulValues[i]=ul;
}
void LDT_SetFileDouble( int i, double d )
{
if( !g_FileDesc )
return;
g_FileDesc->dValues[i]=d;
}
/*------------------------------------------------------------------------------
DESC. : opens a file and fills in the FileDesc
CREATED : 98/05/17
AUTHOR : Mircea Petrescu
MODIFIED: Catalin Cocos
------------------------------------------------------------------------------*/
int OpenFileDesc( char* szFile, LDT_tdst_MemFile* pFile )
{
int i;
if( !pFile )
return -1;
TheFileDesc.szFile=szFile;
TheFileDesc._pInfoMemFile = pFile;
/* CC : contents initialization -> start */
DSAr_Init( &TheFileDesc.arContents );
DSAr_SetSortMethod( &TheFileDesc.arContents, LDT_Compare_Positions );
DSAr_SetGranularity( &TheFileDesc.arContents, 50 );
/* CC : contents initialization -> end */
TheFileDesc.iLevel=0;
TheFileDesc.iLineNumber=0;
TheFileDesc.iLastIndex=-1;
TheFileDesc.chLastChar=0;
TheFileDesc.uwFlags=0;
TheFileDesc.uwLoadType=0; /* CC : Loading Type */
for( i=0; i<256; i++ )
TheFileDesc.ulValues[i]=0;
for( i=0; i<8; i++ )
TheFileDesc.dValues[i]=0.0;
g_FileDesc=&TheFileDesc;
g_szName[0]=0;
g_szParent[0]=0;
return 0;
}
/*------------------------------------------------------------------------------
DESC. : closes a file and fills in the FileDesc
CREATED : 98/05/17
AUTHOR : Mircea Petrescu
------------------------------------------------------------------------------*/
void CloseFileDesc( void )
{
int idx;
LDT_M_File_Close( TheFileDesc._pInfoMemFile );
#ifdef LDT_MULTITHREADED
ReleaseSemaphore( GReadLimit, 1, NULL); /* signal that the file was closed */
#endif
/* CC : contents clean-up -> start */
for(idx = DSAr_GetUpperBound( &TheFileDesc.arContents); idx>=0; idx--)
free( TheFileDesc.arContents.pData[idx] );
DSAr_RemoveAll( &TheFileDesc.arContents );
/* CC : contents clean-up -> end */
g_FileDesc=NULL;
}
/*------------------------------------------------------------------------------
DESC. : positions a file and fills in the FileDesc
CREATED : 98/05/17
AUTHOR : Mircea Petrescu
------------------------------------------------------------------------------*/
void PositionFile( LDT_tdst_Position *pos )
{
LDT_M_File_Seek( TheFileDesc._pInfoMemFile, pos->dwPos, SEEK_SET );
g_ulBeginLineMark=pos->dwPos;
TheFileDesc.iLineNumber=pos->nLine;
TheFileDesc.iLevel=pos->iLevel;
TheFileDesc.uwFlags=pos->uwFlags;
TheFileDesc.iLastIndex=-1;
TheFileDesc.chLastChar=0;
fn_e_ParseLine( 0 ); /* read the begin section line */
}
LDT_tdst_Link *pParent[100];
/*------------------------------------------------------------------------------
DESC. : default create - does nothing
CREATED : 98/05/17
AUTHOR : Mircea Petrescu
------------------------------------------------------------------------------*/
int LDT_Default_NULL_Create(LDT_tdst_Link *link)
{
link->pObject = NULL;
return 0;
}
/*------------------------------------------------------------------------------
DESC. : skipping a section
CREATED : 98/05/17
AUTHOR : Mircea Petrescu
------------------------------------------------------------------------------*/
void SkipSection( )
{
LDT_tdeParseResult result;
int iLevel=g_FileDesc->iLevel;
do{
result=fn_e_ParseLine( 0 );
}while ((g_FileDesc->iLevel>=iLevel)&&(result !=ParseResult_EOF) );
}
/*------------------------------------------------------------------------------
DESC. : default loading
CREATED : 98/05/17
AUTHOR : Mircea Petrescu
------------------------------------------------------------------------------*/
int LDT_Default_Load( LDT_tdst_Link *_Link )
{
LDT_tdeParseResult result;
_Link=_Link;
do{
result=LDT_GetNextEntry();
if( result== ParseResult_BeginSection )
LDT_LoadSection( NULL );
}while ( result!=ParseResult_EndSection );
return 0;
}
/*------------------------------------------------------------------------------
DESC. : load the whole file
CREATED : 98/05/17
AUTHOR : Mircea Petrescu
------------------------------------------------------------------------------*/
int LoadAllFile( LDT_tdst_Link *link )
{
int ERRoR = 0;
TheFileDesc.uwLoadType=1; /* CC : load-all-file flag */
g_CrtSection=pParent[0]= link;
if(( link->dwFlags&LDT_LF_LOADED ) == 0)
{
/* CC ...allowing file closure ->start*/
if(( link->dwFlags&LDT_LF_ALLOCATED ) == 0)
{
ERRoR=link->Type->Create( link ); /* the Type is always !NULL */
link->dwFlags |= LDT_LF_ALLOCATED; /* the link was allocated */
}
if(!ERRoR)
{
ERRoR = link->Type->Load( link );
link->dwFlags |= LDT_LF_LOADED; /* the link was loaded */
}
/* CC ...allowing file closure ->end*/
}
return ERRoR;
}
/*------------------------------------------------------------------------------
DESC. : loads a list of delayed references ( corresponding to a file )
CREATED : 98/05/17
AUTHOR : Mircea Petrescu
MODIFIED: Catalin Cocos
------------------------------------------------------------------------------*/
int Solve( LDT_tdst_Refs *refs )
{
LDT_tdst_MemFile* pFile;
char bAllFile=0;
LDT_tdst_Link *link = NULL, *link1, TmpLink;
LDT_tdeParseResult result;
LDT_tdst_CallbackEntry *Type;
int ERRoR = 0;
if( DSAr_GetSize( &refs->Links )==1 )
{
link=(LDT_tdst_Link*)DSAr_GetAt( &refs->Links, 0 );
if( link->dwFlags& LDT_LF_FILE )
bAllFile=1;
}
pParent[0]=NULL;
#ifdef LDT_MULTITHREADED
pFile = refs->pFile;
#else
LDT_M_File_OpenRead(pFile, refs->szFile);
#endif
if( OpenFileDesc( refs->szFile, pFile )) /* open the file */
return -1;
if( bAllFile ) ERRoR = LoadAllFile( link ); /* load all file */
else /* load a list of sections */
{
do{
result=fn_e_ParseLine( 1 );
switch( result )
{
case ParseResult_BeginSection:
{
int index;
Type = GetType( g_szType, LDT_REG_SECTION );
TmpLink.szFile = refs->szFile;
TmpLink.szParent = g_szParent;
TmpLink.szName = g_szId;
TmpLink.Type = Type;
index=DSAr_Index( &refs->Links, &TmpLink, NULL );
if( index!=-1 )
{
link1=(LDT_tdst_Link *)DSAr_GetAt( &refs->Links, index );
DSAr_RemoveAt( &refs->Links, index );
pParent[ g_FileDesc->iLevel ]=link1;
g_CrtSection=link1;
ERRoR=Type->Load( link1 );
if(!ERRoR)
link1->dwFlags |= LDT_LF_LOADED; /* the link was loaded */
else
return -1;
}
}
default:
break;
}
}while ( (result !=ParseResult_EOF)&&(DSAr_GetSize(&refs->Links)>0) );
if(DSAr_GetSize(&refs->Links)>0)
DSAr_QSort( &g_FileDesc->arContents );
while( DSAr_GetSize(&refs->Links)>0 )
{
LDT_tdst_Position pos, *p;
int index=DSAr_GetUpperBound( &refs->Links );
link1=(LDT_tdst_Link *)DSAr_GetAt( &refs->Links, index );
if( link1->dwFlags&LDT_LF_FILE ) /* all file requested */
{
int i;
/* reset the file */
if( g_FileDesc->iLastIndex!=-1 )
{ /* sentinel - restores the previously requested word */
*g_ulPos = g_FileDesc->chLastChar;
g_FileDesc->iLastIndex=-1;
}
LDT_M_File_Seek( TheFileDesc._pInfoMemFile, 0, SEEK_SET );
TheFileDesc.iLevel=0;
TheFileDesc.iLineNumber=0;
TheFileDesc.iLastIndex=-1;
TheFileDesc.chLastChar=0;
TheFileDesc.uwFlags=0;
for( i=0; i<8; i++ )
{
TheFileDesc.ulValues[i]=0;
TheFileDesc.dValues[i]=0.0;
}
ERRoR = LoadAllFile( link1 ); /* load all file */
CloseFileDesc(); /* close the file */
return ERRoR;
}
DSAr_RemoveAt( &refs->Links, index );
pos.szName=link1->szName;
pos.szParent=link1->szParent;
pos.Type=link1->Type;
index=DSAr_Index( &g_FileDesc->arContents, (void *)&pos, NULL );
if( index<0 )
{
ERRoR = -1;
break;
}
p=(LDT_tdst_Position *)DSAr_GetAt( &g_FileDesc->arContents, index );
PositionFile( p );
g_CrtSection=link1;
pParent[g_FileDesc->iLevel]=link1;
if( (index=link1->Type->Load( link1 )) <0 ) return index;
}
}
CloseFileDesc(); /* close the file */
return ERRoR;
}
/*------------------------------------------------------------------------------
DESC. : loads a subsection
CREATED : 98/05/17
AUTHOR : Mircea Petrescu
------------------------------------------------------------------------------*/
int GetSubSection( LDT_tdst_Link *link )
{
g_CrtSection=link;
pParent[g_FileDesc->iLevel]=link;
return link->Type->Load( link );
}
/*------------------------------------------------------------------------------
DESC. : breaks a reference name in file, parent, type, id
CREATED : 98/05/17
AUTHOR : Mircea Petrescu
------------------------------------------------------------------------------*/
void LDT_SplitSectionName( char *szSection, char *szFile, char *szParent, char *szType, char *szId )
{
char *szP, *szI, *szT;
strcpy( szFile, szSection );
szT=strrchr( szFile, '^' );
*szT=0;
szT++;
szI=strrchr( szT, ':' );
if( szI )
{
*szI=0;
szI++;
strcpy( szId, szI );
}
else szId[0]=0;
strcpy( szType, szT );
szP=strchr( szFile, '^' );
if( szP )
{
*szP=0;
szP++;
strcpy( szParent, szP );
}
else szParent[0]=0;
}
/*------------------------------------------------------------------------------
DESC. : computes name of current section and returns length of file name
CREATED : 98/05/17
AUTHOR : Mircea Petrescu
------------------------------------------------------------------------------*/
int LDT_ComputeSectionName( char *buffer )
{
LDT_tdst_Link* link=g_CrtSection;
int i=strlen( link->szFile );
strcpy( buffer, link->szFile);
if( link->szParent[0] )
{
strcat( buffer, "^" );
strcat( buffer, link->szParent );
}
strcat( buffer, "^" );
strcat( buffer, link->Type->szType );
if( link->szName[0] )
{
strcat( buffer, ":" );
strcat( buffer, link->szName );
}
return i;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,381 @@
/*------------------------------------------------------------------------------
FILE : Register.c
CREATED : 98/05/19
AUTHOR : Catalin Cocos
CONTENTS: callback registering structures & functions
------------------------------------------------------------------------------*/
#include "StdInc.h"
#include "Register.h"
#include "Interface.h"
#include "Error.h"
#include "Refs.h"
/* Globals
-------------*/
extern int g_nInitialized;
LDT_tdst_DSArray g_ArSectionCallbacks; /* the section callbacks */
LDT_tdst_DSArray g_ArFileCallbacks; /* the file callbacks */
LDT_tdst_DSArray g_ArPaths; /* the paths */
LDT_tdst_DSArray g_ArPathStrings; /* the path strings */
LDT_tdst_DSArray g_ArBaseDirectories; /* the base paths */
LDT_tdst_CallbackEntry Default_Type = { ".*", LDT_Default_NULL_Create, LDT_Default_Load};
/* Functions
-------------*/
/*------------------------------------------------------------------------------
DESC. : compares two callback registration entries
CREATED : 98/05/12
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_Compare_CallbackEntries(const void** _pA, const void** _pB)
{
int Result = stricmp(((LDT_tdst_CallbackEntry*) *_pA)->szType,
((LDT_tdst_CallbackEntry*) *_pB)->szType );
if(Result < 0) return -1;
return Result;
}
/*------------------------------------------------------------------------------
DESC. : registers a type
INPUT : the type;
the pointer to the create callback;
pointer to the load callback;
Registering mode:
LDT_REG_SECTION - registers section callbacks
LDT_REG_FILE - registers file callbacks
OUTPUT : non-zero if successful, 0 if the type is already registered or
if the paramters are invalid
CREATED : 98/05/12
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_RegisterType(char* szType, int (*_Create) ( LDT_tdst_Link* ),
int (*_Load) ( LDT_tdst_Link* ),
int Mode)
{
// char *sz;
LDT_tdst_DSArray* pAr;
LDT_tdst_CallbackEntry* pNewEntry, *pOldEntry;
int position;
if( !g_nInitialized ) return 0; /* table not initialized */
if( !szType || !_Create || !_Load ) return 0; /* invalid parameters */
pAr = (Mode == LDT_REG_SECTION)? &g_ArSectionCallbacks: &g_ArFileCallbacks; /* select the array*/
/* convert to lower case */
// sz=szType;
// for( ; *sz; sz++ )
// if( ( *sz>='A') && ( *sz<='Z' ) )
// *sz+='a'-'A';
/* create the new entry */
pNewEntry = malloc( sizeof(LDT_tdst_CallbackEntry));
pNewEntry->szType = szType;
pNewEntry->Create = _Create;
pNewEntry->Load = _Load;
if( LDT_DSAr_SAdd( pAr, pNewEntry, 0, &position) < 0 )
{
/* insertion failed */
#if defined(LDT_ERROR_TREATMENT)
pOldEntry = LDT_DSAr_GetAt( pAr, position );
if( (pOldEntry->Create != _Create) || (pOldEntry->Load != _Load) )
ERRoR(0, NULL, 0, "Type already registered. Registration failed.");
#endif
free( pNewEntry );
return 0;
}
strcpy( pNewEntry->szType = malloc( strlen(szType) + 1 ), szType ); /* copy the type string*/
return 1;
}
/*------------------------------------------------------------------------------
DESC. : returns a pointer to the type or NULL if the type is not registered;
the parameters have the same signification as in the above function
CREATED : 98/05/12
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
LDT_tdst_CallbackEntry* LDT_IsTypeRegistered( char* szType, int Mode)
{
LDT_tdst_DSArray* pAr;
/* convert to lower case */
// char *sz;
// sz=szType;
// for( ; *sz; sz++ )
// if( ( *sz>='A') && ( *sz<='Z' ) )
// *sz+='a'-'A';
if( !g_nInitialized ) return NULL; /* table not initialized */
if( !szType) return NULL; /* invalid parameter */
pAr = (Mode == LDT_REG_SECTION)? &g_ArSectionCallbacks: &g_ArFileCallbacks;
return LDT_DSAr_GetAt(pAr, LDT_DSAr_Index( pAr, (LDT_tdst_CallbackEntry*)&szType, NULL ));
}
/*------------------------------------------------------------------------------
DESC. : returns a pointer to the type or the default type if the type is not registered;
the parameters have the same signification as in the above function
CREATED : 98/05/12
NOTE : the input string MUST BE LOWERCASE
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
LDT_tdst_CallbackEntry* GetType( char* szType, int Mode)
{
LDT_tdst_DSArray* pAr;
LDT_tdst_CallbackEntry* pType;
if(!g_nInitialized || !szType)
return &Default_Type;
pAr = (Mode == LDT_REG_SECTION)? &g_ArSectionCallbacks: &g_ArFileCallbacks;
pType = LDT_DSAr_GetAt(pAr, LDT_DSAr_Index( pAr, (LDT_tdst_CallbackEntry*)&szType, NULL ));
if( !pType )
{
#if defined(LDT_ERROR_TREATMENT) && ( LDT_WARNING_LEVEL >= 3 || LDT_ERROR_LEVEL >= 3)
char buffer [300];
sprintf(buffer, "The type \"%s\" (%s) is not registered. The default callback will be used.", szType, (Mode == LDT_REG_SECTION)?"SECTION":"FILE");
ERRoR((Mode == LDT_REG_SECTION)?3:4, NULL, 0, buffer );
#endif
return &Default_Type;
}
return pType;
}
/*------------------------------------------------------------------------------
DESC. : unregisters an existing type
OUTPUT : non-zero if successful, 0 on error
CREATED : 98/05/12
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_UnregisterType( char* szType, int Mode)
{
// char *sz;
int idx;
LDT_tdst_DSArray* pAr;
LDT_tdst_CallbackEntry TestEntry, *pDelEntry;
if( !g_nInitialized || !szType ) return 1; /* no opened session or invalid type */
/* convert to lower case */
// sz=szType;
// for( ; *sz; sz++ )
// if( ( *sz>='A') && ( *sz<='Z' ) )
// *sz+='a'-'A';
TestEntry.szType = szType;
pAr = (Mode == LDT_REG_SECTION)? &g_ArSectionCallbacks: &g_ArFileCallbacks; /* select the array*/
idx = LDT_DSAr_Index( pAr, &TestEntry, NULL );
if( idx < 0) return 1; /* not found */
/* solve all references before proceeding */
if(!LDT_Flush()) return 0; /* if the flush failed, return */
/* remove & delete the entry */
pDelEntry = LDT_DSAr_RemoveAt( pAr, idx );
free( pDelEntry->szType );
free( pDelEntry );
return 1;
}
/*------------------------------------------------------------------------------
DESC. : registers a Base Directory - if present the base directories will
always prefix the paths
INPUT : the base directory
OUTPUT : 0 if successful, !0 on error
CREATED : 98/09/24
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_AddBaseDirectory( char* szPath )
{
// char *sz;
char path[_MAX_PATH];
int i;
if( !g_nInitialized || !szPath ) return 1; /* no opened session or invalid parameters */
/* Get the path */
while (*szPath == ' ') szPath ++;
strcpy( path, szPath );
for( i = strlen(path)-1; i>=0 && path[i] == ' '; i--) path[i] = 0;
if(path[strlen(path)-1] != '\\') strcat( path, "\\");
/* convert file path string to lower case */
// sz=path;
// for( ; *sz; sz++ )
// if( ( *sz>='A') && ( *sz<='Z' ) )
// *sz+='a'-'A';
/* add the file path to the base directories list */
LDT_DSAr_Add( &g_ArBaseDirectories, strcpy( malloc( strlen(path) +1 ), path));
return 0;
}
/*------------------------------------------------------------------------------
DESC. : registers a Path
INPUT : the path, the file types extensions(without the leading'.'), separated by spaces
OUTPUT : 0 if successful, !0 on error
CREATED : 98/05/12
AUTHOR : Catalin Cocos
------------------------------------------------------------------------------*/
int LDT_RegisterPath( char* szPath, char* szFileTypes )
{
char *sz, * szNewPath;
char buffer[_MAX_EXT];
char path[_MAX_PATH];
int i, idx, iidx;
LDT_tdst_TypePaths Dummy;
Dummy.szExtension = buffer;
if( !g_nInitialized || !szPath || !szFileTypes ) return 1; /* no opened session or invalid parameters */
/* Get the path */
while (*szPath == ' ') szPath ++;
strcpy( path, szPath );
for( i = strlen(path)-1; i>=0 && path[i] == ' '; i--) path[i] = 0;
if(path[strlen(path)-1] != '\\') strcat( path, "\\");
/* convert file path string to lower case */
// sz=path;
// for( ; *sz; sz++ )
// if( ( *sz>='A') && ( *sz<='Z' ) )
// *sz+='a'-'A';
/* add the file path to the path collection */
idx = LDT_DSAr_Index( &g_ArPathStrings, path, &iidx);
if( idx<0 )
/* insert the new path */
LDT_DSAr_InsertAt(&g_ArPathStrings, iidx, strcpy( szNewPath = malloc( strlen(path) +1), path));
else
/* we already have it */
szNewPath = g_ArPathStrings.pData[idx];
/* convert file type string to lower case */
// sz=szFileTypes;
// for( ; *sz; sz++ )
// if( ( *sz>='A') && ( *sz<='Z' ) )
// *sz+='a'-'A';
sz=szFileTypes;
while ( *sz )
{
int cnt = 0;
while (*sz == ' ') sz++;
for(; *sz!=' ' && *sz ; sz++, cnt++ )
buffer[cnt] = *sz;
buffer[cnt] = 0;
if(*buffer)
{
/* we have a valid file type */
int idx,iidx;
idx = LDT_DSAr_Index( &g_ArPaths, &Dummy, &iidx );
if(idx<0)
{
/* type not registered before */
LDT_tdst_TypePaths* pPath = malloc( sizeof(LDT_tdst_TypePaths));
strcpy( pPath->szExtension = malloc( strlen(buffer) + 1 ), buffer);
LDT_DSAr_Init(&pPath->arPaths);
LDT_DSAr_SetGranularity(&pPath->arPaths, 10);
LDT_DSAr_Add(&pPath->arPaths, szNewPath);
LDT_DSAr_InsertAt( &g_ArPaths, iidx, pPath );
}
else
/* type already present */
LDT_DSAr_Add(&((LDT_tdst_TypePaths*)g_ArPaths.pData[idx])->arPaths, szNewPath);
}
}
return 0;
}
#ifdef LDT_LOG_STATISTICS
/* Log/stat stuff
-------------------*/
unsigned TimerStartCount = 0;
unsigned TimerStopCount = 0;
LONGLONG Frequency;
LONGLONG TimingOverhead = 0;
LONGLONG StartOverhead = 0;
LONGLONG StopOverhead = 0;
void InitializeTimingEnvironment()
{
LARGE_INTEGER li;
LONGLONG tmpli;
int i;
TimerStruct time, dummy;
QueryPerformanceFrequency( &li );
Frequency = li.QuadPart; /* the clock frequency */
InitTimer( &time );
for( i = 0; i<32768; i++) /* 2^15 */
{
StartTimer( &time );
StopTimer( &time );
}
TimingOverhead = Int64ShraMod32(time.TimeCounter, 15); /* the timing overhead */
InitTimer( &time );
for( i = 0; i<32768; i++) /* 2^15 */
{
StartTimer( &time );
StartTimer( &dummy );
StopTimer( &time );
}
tmpli = time.TimeCounter;
InitTimer( &time );
InitTimer( &dummy );
for( i = 0; i<32768; i++) /* 2^15 */
{
StartTimer( &time );
StartTimer( &dummy );
StopTimer( &dummy );
StopTimer( &time );
}
StartOverhead = Int64ShraMod32(tmpli , 15); /* the stoptiming overhead */
StopOverhead = Int64ShraMod32(time.TimeCounter - tmpli , 15); /* the stoptiming overhead */
InitTimer( &time );
InitTimer( &dummy );
StartTimer( &time );
StartTimer( &dummy );
StopTimer( &dummy );
StopTimer( &time );
}
void InitTimer(TimerStruct* time)
{
time->TimeCounter = 0;
}
void StartTimer(TimerStruct* time)
{
time->LastStartCount = ++TimerStartCount;
time->LastStopCount = TimerStopCount;
QueryPerformanceCounter((LARGE_INTEGER*)&time->LastValue);
}
void StopTimer(TimerStruct* time)
{
LARGE_INTEGER li;
QueryPerformanceCounter(&li);
time->TimeCounter += li.QuadPart
- time->LastValue
- TimingOverhead
- (TimerStartCount-time->LastStartCount)*StartOverhead
- (TimerStopCount-time->LastStopCount)*StopOverhead;
TimerStopCount++;
}
double ReadTimer(TimerStruct* time)
{
return ((double)time->TimeCounter)/Frequency;
}
#endif

View File

@@ -0,0 +1,160 @@
#include <stdinc.h>
#include <stdarg.h>
#include "LDT.h"
#include "refs.h"
#include "DynArray.h"
#include "Error.h"
extern LDT_tdst_Link *g_pGetFrom;
extern int g_nInitialized;
LDT_tdst_DSArray g_ArSolvers;
int SortRefs( const void **A, const void **B )
{
tdst_Ref *pA, *pB;
pA=(tdst_Ref *)*A;
pB=(tdst_Ref *)*B;
if( pA->iType<pB->iType)
return 1;
else if( pA->iType>pB->iType)
return -1;
return 0;
}
int SortSolvers( const void **A, const void **B )
{
tdst_Solver *pA, *pB;
pA=(tdst_Solver *)*A;
pB=(tdst_Solver *)*B;
if( pA->iPriority<pB->iPriority)
return -1;
else if( pA->iPriority>pB->iPriority)
return 1;
return 0;
}
HREF LDT_CreateRefsTable( )
{
LDT_tdst_DSArray* pRef=LDT_DSAr_new();
LDT_DSAr_SetGranularity( pRef, 50 );
LDT_DSAr_SetSortMethod( pRef, SortRefs );
return (HREF)pRef;
}
void LDT_AddToRefsTable( HREF hRef, LDT_tdst_Link* pObj, int iType, short xCount, ... )
{
LDT_tdst_DSArray* pRef=(LDT_tdst_DSArray *)hRef;
tdst_Ref *pSt=(tdst_Ref *)malloc( sizeof(tdst_Ref) );
pSt->pObject=pObj;
pSt->pGetFrom=g_pGetFrom;
pSt->iType=iType;
pSt->xCount=xCount;
if( xCount )
{
int i;
va_list vaList;
pSt->pVal=(long *)malloc( xCount*sizeof( long ) );
va_start( vaList, xCount );
for( i=0; i<xCount; i++ )
pSt->pVal[i]=va_arg( vaList, long );
va_end( vaList );
}
else pSt->pVal=NULL;
pObj->wUnsolvedRefs++;
LDT_DSAr_SAdd( pRef, (void *)pSt, 1, NULL );
}
long pValues[128];
int LDT_GetRefFromTable( HREF hRef, LDT_tdst_Link **pObj, LDT_tdst_Link **pGetFrom, int *iType, short *xCount, long **pVal )
{
LDT_tdst_DSArray* pRef=(LDT_tdst_DSArray *)hRef;
int i=LDT_DSAr_GetUpperBound( pRef ), ii;
tdst_Ref *pSt;
if( i==-1 )
return -1;
for( ii=i; (ii>=0) && (pSt=(tdst_Ref *)LDT_DSAr_GetAt( pRef, ii ))->pGetFrom && pSt->pGetFrom->wUnsolvedRefs; ii--);
if( ii<0 ) /* circular refs - problem ! */
return -2;
if( ii!=i ) /* swap */
{
void *pTemp=LDT_DSAr_GetAt( pRef, i );
LDT_DSAr_SetAt( pRef, ii, pTemp );
}
LDT_DSAr_SetSize( pRef, i );
*pObj=pSt->pObject;
if( pSt->pGetFrom )
*pGetFrom=pSt->pGetFrom;
else *pGetFrom=NULL;
*iType=pSt->iType;
*xCount=pSt->xCount;
if(pSt->xCount)
{
memcpy(pValues, pSt->pVal, pSt->xCount*sizeof(long));
*pVal=pValues;
free(pSt->pVal);
}
else
*pVal = NULL;
pSt->pObject->wUnsolvedRefs--;
free( pSt );
return 0;
}
#pragma warning( disable:4100 )
void LDT_FreeRefValues( long *p )
{
// free( p ); the function is here only for backwards compatibility
}
#pragma warning( default:4100 )
HREF LDT_RegisterSolver( void(* Solve)(HREF), int iPri )
{
tdst_Solver *pSolver;
if(!g_nInitialized )
{
#if defined(LDT_ERROR_TREATMENT)
ERRoR(0, NULL, 0, "Call LDT_Initialize prior to solver registration !");
#endif
return NULL;
}
pSolver=(tdst_Solver *)malloc( sizeof(tdst_Solver) );
pSolver->Solve=Solve;
pSolver->iPriority=iPri;
if( LDT_DSAr_SAdd( &g_ArSolvers, (void *)pSolver, 0, NULL ) <0 )
{
#if defined(LDT_ERROR_TREATMENT)
ERRoR(0, NULL, 0, "Solver registration failed. The priority slot is in use. Please choose a different priority number.");
#endif
free (pSolver);
return NULL;
}
pSolver->hRef=LDT_CreateRefsTable();
return pSolver->hRef;
}