/*------------------------------------------------------------------------------ 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; }