reman3/Rayman_X/cpa/Appli/MngData5/Src/ModifLst.cpp

601 lines
17 KiB
C++

/*
=======================================================================================
Name :ModifLst.cpp
Author :vincent lhullier Date :23/07/97
Description :manage list of modifications
=======================================================================================
Modification -> Author : Date :
Description :
=======================================================================================
*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include "stdafx.h"
#include "IniData.h"
#include "ModifLst.h"
#include "SCR.h"
#include "dlgmodif.h"
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*
=======================================================================================
Globals
=======================================================================================
*/
tdstModif *g_p_stLastModif = NULL;
tdstModif *g_p_stFirstModif = NULL;
long g_lNumberOfModifs = 0;
long g_lNumberOfChildModifs = 0;
long g_lNumberOfFatherModifs = 0;
/*
=======================================================================================
Functions to decompose modif name
=======================================================================================
*/
/*
----------------------------------------------------------------------------------------
Description : extract from a modif name the filename and short filename
_p_stModif -> modif
szFileName -> string to store filename
szShortFileName -> string to store short name
Returns (BOOL) TRUE if section modified is the file, FALSE if it's a section in the
file
----------------------------------------------------------------------------------------
*/
BOOL fn_bGetModifiedFile( tdstModif *_p_stModif, char *_szFileName, char *_szShortFileName )
{
char *p_szEnd;
BOOL bResult;
strcpy( _szFileName, _p_stModif->szName );
p_szEnd = strchr( _szFileName, '^' );
if (p_szEnd != NULL)
*p_szEnd = 0;
bResult = ( p_szEnd == NULL );
p_szEnd = strrchr( _szFileName, '\\');
if (p_szEnd == NULL)
p_szEnd = _szFileName;
else
p_szEnd++;
strcpy( _szShortFileName, p_szEnd );
return bResult;
}
/*
----------------------------------------------------------------------------------------
Description : find in modif first child modif of given father modif
_p_stFather -> father of modif searched
Returns (tdstModif ) a child modif
----------------------------------------------------------------------------------------
*/
tdstModif *fn_p_stGetChildModif( tdstModif *_p_stFather )
{
tdstModif *p_stChild = g_p_stFirstModif;
while (p_stChild != NULL)
{
if (p_stChild->p_stFather == _p_stFather)
return p_stChild;
p_stChild = p_stChild->p_stNext;
}
return NULL;
}
/*
----------------------------------------------------------------------------------------
Description : return number of children of a section modification
_p_stFather -> father
Returns (long ) number of children
----------------------------------------------------------------------------------------
*/
long fn_lNumberOfChildModif( tdstModif *_p_stFather )
{
long lNumber = 0;
tdstModif *p_stChild = g_p_stFirstModif;
tdstModif *p_stFather;
while (p_stChild != NULL)
{
p_stFather = p_stChild->p_stFather;
while (p_stFather != NULL)
{
if (p_stFather == _p_stFather )
{
lNumber++;
break;
}
p_stFather = p_stFather->p_stFather;
}
p_stChild = p_stChild->p_stNext;
}
return lNumber;
}
/*
----------------------------------------------------------------------------------------
Description : delete a modification on a section and restore all modification on
subsection of this section
----------------------------------------------------------------------------------------
*/
void fn_vRestoreSubModif(tdstModif *_p_stModif )
{
tdstModif *p_stSubModif = g_p_stFirstModif;
while (p_stSubModif != NULL)
{
if (p_stSubModif->p_stFather == _p_stModif)
{
p_stSubModif->p_stFather = NULL;
g_lNumberOfChildModifs--;
g_lNumberOfFatherModifs++;
}
p_stSubModif = p_stSubModif->p_stNext;
}
//fn_lDeleteModif( _p_stModif, FALSE );
}
/*
---------------------------------------------------------------------------------------
delete a modif from list
---------------------------------------------------------------------------------------
*/
long fn_lDeleteModif( tdstModif *_p_stModif, BOOL _bDeleteChild )
{
tdstModif *p_stChild;
long lDeleted = 0;
if (_p_stModif == NULL)
return 0;
// free all child modification
if (_bDeleteChild)
while ( (p_stChild = fn_p_stGetChildModif( _p_stModif )) != NULL)
lDeleted += fn_lDeleteModif( p_stChild, _bDeleteChild );
//deallocate memory for name
free (_p_stModif->szName );
// keep link between modification
if (_p_stModif == g_p_stFirstModif )
g_p_stFirstModif = _p_stModif->p_stNext;
if (_p_stModif == g_p_stLastModif)
g_p_stLastModif = _p_stModif->p_stPrevious;
if (_p_stModif->p_stPrevious != NULL)
_p_stModif->p_stPrevious->p_stNext = _p_stModif->p_stNext;
if (_p_stModif->p_stNext != NULL)
_p_stModif->p_stNext->p_stPrevious = _p_stModif->p_stPrevious;
//deallocate memory for modif
if (_p_stModif->p_stFather == NULL)
g_lNumberOfFatherModifs--;
else
g_lNumberOfChildModifs--;
g_lNumberOfModifs--;
free( _p_stModif );
return lDeleted + 1;
}
/*
---------------------------------------------------------------------------------------
delete all modif in list
---------------------------------------------------------------------------------------
*/
void fn_vDeleteAllModifs( void )
{
tdstModif *p_stModif = g_p_stFirstModif;
while (p_stModif != NULL)
{
fn_lDeleteModif( p_stModif, FALSE );
p_stModif = g_p_stFirstModif;
}
g_lNumberOfFatherModifs = g_lNumberOfChildModifs = g_lNumberOfModifs = 0;
}
/*
---------------------------------------------------------------------------------------
search for a modification in the same file
---------------------------------------------------------------------------------------
*/
tdstModif *fnp_stGetModifInFile( char *_szFileName, BOOL _bChild, BOOL _bAll )
{
tdstModif *p_stModif = g_p_stFirstModif;
size_t xSize = strlen( _szFileName );
while (p_stModif != NULL)
{
if (
((_bChild) || (p_stModif->p_stFather == NULL)) &&
((_bAll) || (!p_stModif->bConflict)) &&
(strnicmp(p_stModif->szName, _szFileName, xSize ) == 0)
)
break;
p_stModif = p_stModif->p_stNext;
}
return p_stModif;
}
/*
---------------------------------------------------------------------------------------
delete all modif that are in a given file
returns nuumber of modif deleted from list
---------------------------------------------------------------------------------------
*/
int fn_iDeleteAllModifForAFile( char *_szFileName )
{
int iIndex = 0;
tdstModif *p_stModif = fnp_stGetModifInFile( _szFileName, TRUE, TRUE );
while (p_stModif != NULL)
{
iIndex ++;
fn_lDeleteModif( p_stModif, TRUE );
p_stModif = fnp_stGetModifInFile( _szFileName, TRUE, TRUE );
}
return iIndex;
}
/*
---------------------------------------------------------------------------------------
Mark all modif that are in a given file
returns number of modif deleted from list
---------------------------------------------------------------------------------------
*/
int fn_iMarkAllModifForAFile( char *_szFileName )
{
int iIndex = 0;
tdstModif *p_stModif = fnp_stGetModifInFile( _szFileName, TRUE, FALSE );
while (p_stModif != NULL)
{
iIndex ++;
p_stModif->bConflict = TRUE;
p_stModif = fnp_stGetModifInFile( _szFileName, TRUE, FALSE );
}
return iIndex;
}
/*
----------------------------------------------------------------------------------------
Description : get first not marked modification
Returns (tdstModif ) first not marked modification
----------------------------------------------------------------------------------------
*/
tdstModif *fn_p_stGetFirstNotMarkedModif( void )
{
tdstModif *p_stModif;
p_stModif = g_p_stFirstModif;
while ( (p_stModif != NULL) && ((p_stModif->bConflict) || (p_stModif->p_stFather != NULL)) )
p_stModif = p_stModif->p_stNext;
return p_stModif;
}
/*
---------------------------------------------------------------------------------------
delete modif file
---------------------------------------------------------------------------------------
*/
BOOL fn_bDeleteModifFile( void )
{
char szTxtFullName[ MAX_PATH ];
char szBakFullName[ MAX_PATH ];
sprintf( szTxtFullName, "%s\\%s", g_stIniData.szLocalPath, g_stIniData.szModifFile );
strcpy ( szBakFullName, szTxtFullName );
strcpy( strrchr( szBakFullName, '.'), ".bak" );
if (_access( szTxtFullName, 0) == 0)
{
if (_access( szBakFullName, 0) == 0)
remove( szBakFullName );
return MoveFile( szTxtFullName, szBakFullName);
}
return TRUE;
}
/*
---------------------------------------------------------------------------------------
rewrite modif file with all modif that are always in file
---------------------------------------------------------------------------------------
*/
void fn_vWriteModifInFile( BOOL _bDelete )
{
char szFullName[ MAX_PATH ];
FILE *hpFile;
tdstModif *p_stModif = g_p_stFirstModif;
tdstModif *p_stDeleteModif;
fn_bDeleteModifFile();
sprintf( szFullName, "%s\\%s", g_stIniData.szLocalPath, g_stIniData.szModifFile );
hpFile = fopen( szFullName, "wt" );
while ( p_stModif != NULL )
{
fprintf( hpFile, "(%c)%s\n", *g_a_szModifName[ p_stModif->cType ], p_stModif->szName );
p_stDeleteModif = p_stModif;
p_stModif = p_stModif->p_stNext;
if (_bDelete)
fn_lDeleteModif (p_stDeleteModif, FALSE);
}
fclose( hpFile );
}
/*
---------------------------------------------------------------------------------------
function that read file where Modification list was saved.
returns number of modification
---------------------------------------------------------------------------------------
*/
int fn_iReadModificationFile( void )
{
char szFullName[ MAX_PATH ];
char szLine[1024];
char *p_szEnd;
FILE *hpFile;
tdstModif *p_stModif;
char *p_szLine;
long lCurrentLine = 0;
/* emptied list before reading file */
fn_vDeleteAllModifs();
/* building full name of modif file */
sprintf( szFullName, "%s\\%s", g_stIniData.szLocalPath, g_stIniData.szModifFile );
/* open file */
if ( (hpFile = fopen( szFullName, "rt" ) ) == NULL )
return 0;
/* for each line */
while (fgets(szLine, 1023, hpFile) != NULL)
{
lCurrentLine++;
/* go to last character, swap \r\n char */
p_szEnd = szLine + strlen(szLine) - 1;
while (
(p_szEnd != szLine - 1) &&
(
(isspace(*p_szEnd)) ||
(*p_szEnd == '\n') ||
(*p_szEnd == '\r')
)
)
*p_szEnd--;
*(++p_szEnd) = 0;
if (strlen(szLine) == 0)
continue;
/* create a new modif */
p_stModif = (tdstModif *) malloc (sizeof(tdstModif));
p_stModif->lLine = lCurrentLine;
p_stModif->bConflict = FALSE;
p_stModif->p_stFather = NULL;
if ( *(p_szLine = szLine) == '(' )
{
switch( *(p_szLine + 1) )
{
case C_ModifChar_cAdd: p_stModif->cType = C_ModifType_cAdd; break;
case C_ModifChar_cRebuild: p_stModif->cType = C_ModifType_cRebuild; break;
case C_ModifChar_cModif: p_stModif->cType = C_ModifType_cModif; break;
case C_ModifChar_cDelete: p_stModif->cType = C_ModifType_cDelete; break;
}
p_szLine += 3;
}
else
p_stModif->cType = C_ModifType_cModif;
if (strnicmp( p_szLine, "GameData\\", 9) == 0)
p_szLine += 9;
p_stModif->szName = (char *) malloc (strlen( p_szLine ) + 1);
strcpy( p_stModif->szName, p_szLine );
p_stModif->p_stNext = NULL;
p_stModif->p_stPrevious = g_p_stLastModif;
/* add it in modif list */
if (g_p_stFirstModif == NULL)
g_p_stFirstModif = p_stModif;
else
g_p_stLastModif->p_stNext = p_stModif;
g_p_stLastModif = p_stModif;
g_lNumberOfModifs ++;
}
g_lNumberOfFatherModifs = g_lNumberOfModifs;
g_lNumberOfChildModifs = 0;
/* close file */
fclose( hpFile );
/* clean modif list : delete all redondant modifications */
fn_vCleanModifList();
return g_lNumberOfModifs;
}
/*
---------------------------------------------------------------------------------------
update modification file
delete it, rewrite it with all modif that causes conflict
display conflict if there's some
---------------------------------------------------------------------------------------
*/
void fn_vUpdateModifFile( void )
{
/* delete modif file */
fn_bDeleteModifFile();
fn_vWriteModifInFile( FALSE );
}
/*
----------------------------------------------------------------------------------------
Description : delete all redondant modification such as a modified sub section when
it's parent section is modified too
----------------------------------------------------------------------------------------
*/
char g_aa_cComposedType[5][5] =
{
/* Destroy , Add , Rebuild , Modif , Delete */
{ C_ModifType_cError, C_ModifType_cAdd , C_ModifType_cError , C_ModifType_cError, C_ModifType_cError }, /* Destroy */
{ C_ModifType_cError, C_ModifType_cError, C_ModifType_cAdd , C_ModifType_cAdd , C_ModifType_cDestroy}, /* Add */
{ C_ModifType_cError, C_ModifType_cError, C_ModifType_cRebuild, C_ModifType_cModif, C_ModifType_cDelete }, /* Rebuild */
{ C_ModifType_cError, C_ModifType_cError, C_ModifType_cRebuild, C_ModifType_cModif, C_ModifType_cDelete }, /* Modif */
{ C_ModifType_cError, C_ModifType_cModif, C_ModifType_cError , C_ModifType_cError, C_ModifType_cError } /* Delete */
};
char *g_a_szModifName[5] =
{
"Destroyed",
"Added",
"Rebuild",
"Modified",
"Deleted"
};
void fn_vCleanModifList( void )
{
tdstModif *p_stModif = g_p_stFirstModif;
tdstModif *p_stOtherModif;
char cNextChar;
char cNewType;
long lNumberOfErrors = 0;
char **d_szError = NULL;
long lError;
long lCurrentFatherLength, lFatherLength;
/*
* First : find all error and all double notification
*/
while ( p_stModif != NULL )
{
p_stOtherModif = p_stModif->p_stNext;
while (p_stOtherModif != NULL)
{
if ( stricmp( p_stOtherModif->szName, p_stModif->szName ) == 0)
{
p_stOtherModif->bConflict = TRUE;
p_stOtherModif->cPrevType = p_stModif->cType;
cNewType = g_aa_cComposedType[ p_stModif->cType ][ p_stOtherModif->cType ];
if (cNewType != C_ModifType_cError)
p_stModif->cType = cNewType;
}
p_stOtherModif = p_stOtherModif->p_stNext;
}
do
{
p_stModif = p_stModif->p_stNext;
} while ( (p_stModif != NULL) && (p_stModif->bConflict) );
}
/* count eventual errors */
p_stModif = g_p_stFirstModif;
while (p_stModif != NULL)
{
if (p_stModif->bConflict)
{
cNewType = g_aa_cComposedType[ p_stModif->cPrevType ][ p_stModif->cType ];
if (cNewType == C_ModifType_cError)
lNumberOfErrors++;
}
p_stModif = p_stModif->p_stNext;
}
if (lNumberOfErrors)
d_szError = (char **) malloc( lNumberOfErrors * sizeof(char *) );
/* get errors and delete eventual doublon */
p_stModif = g_p_stFirstModif;
lError = 0;
while (p_stModif != NULL)
{
p_stOtherModif = p_stModif->p_stNext;
if (p_stModif->bConflict)
{
cNewType = g_aa_cComposedType[ p_stModif->cPrevType ][ p_stModif->cType ];
if (cNewType == C_ModifType_cError)
{
d_szError[ lError] = (char *) malloc ( strlen( p_stModif->szName) + 100 );
sprintf( d_szError[lError] , "(Line %4d) %s section has been %s after being %s", p_stModif->lLine, p_stModif->szName, g_a_szModifName[ p_stModif->cType ], g_a_szModifName[ p_stModif->cPrevType ] );
lError++;
}
fn_lDeleteModif( p_stModif, FALSE );
}
p_stModif = p_stOtherModif;
}
/* build section / sous section hierarchy */
p_stModif = g_p_stFirstModif;
while (p_stModif != NULL)
{
lCurrentFatherLength = 0;
p_stOtherModif = g_p_stFirstModif;
while (p_stOtherModif != NULL)
{
if (p_stOtherModif != p_stModif)
{
lFatherLength = strlen( p_stOtherModif->szName );
if ( (lFatherLength > lCurrentFatherLength) && strnicmp( p_stOtherModif->szName, p_stModif->szName, lFatherLength ) == 0)
{
cNextChar = p_stModif->szName[lFatherLength];
if (cNextChar == SCR_CC_c_Cfg_NameSeparator)
{
if (lCurrentFatherLength != 0)
{
g_lNumberOfFatherModifs--;
g_lNumberOfChildModifs++;
}
lCurrentFatherLength = lFatherLength;
p_stModif->p_stFather = p_stOtherModif;
}
}
}
p_stOtherModif = p_stOtherModif->p_stNext;
}
p_stModif = p_stModif->p_stNext;
}
/* delete eventual destroyed modif */
p_stModif = g_p_stFirstModif;
while (p_stModif != NULL)
{
if (p_stModif->cType == C_ModifType_cDestroy)
{
fn_lDeleteModif( p_stModif, TRUE );
p_stModif = g_p_stFirstModif;
}
else
p_stModif = p_stModif->p_stNext;
}
/*
* display error if that happens
*/
if (lNumberOfErrors )
{
CModifListErrorDlg oErrorDlg( lNumberOfErrors, d_szError );
oErrorDlg.DoModal();
for ( lError = 0; lError < lNumberOfErrors; lError++)
free ( d_szError[ lError ] );
free ( d_szError );
}
}