reman3/Rayman_X/cpa/tempgrp/ldt/Src/PARSER.BAK

814 lines
21 KiB
Plaintext

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