408 lines
12 KiB
C
408 lines
12 KiB
C
/*------------------------------------------------------------------------------
|
|
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;
|
|
}
|
|
|