You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
823 lines
28 KiB
823 lines
28 KiB
#include <assert.h>
|
|
#include <iostream.h>
|
|
#include "IComp.Hxx"
|
|
|
|
extern bool fgMethodAttribute;
|
|
extern bool fgMethodParameter;
|
|
|
|
bool CompareBuffer( char* pBuff1, char* pBuff2, unsigned long nLen);
|
|
bool CompareBufferNoCase( char* pBuff1, char* pBuff2, unsigned long nLen);
|
|
void WriteLine(HANDLE file, char* pBuff, int nLen);
|
|
void TokenizeAttributes( char* pBuf, unsigned long nCnt, CAutoArray<ATTRINFO>* pList );
|
|
|
|
extern unsigned long g_ulAppRetVal;
|
|
extern bool fgParamNames;
|
|
extern bool fgParamTypes;
|
|
extern bool fgParamNameCase;
|
|
extern bool fgParamTypeCase;
|
|
|
|
CCompareInterface::CCompareInterface( char* pCurBuf,
|
|
char* pRefBuf,
|
|
HANDLE fileDiff,
|
|
char* pszIntName,
|
|
BLOCK_TYPE blockType,
|
|
char* pszMethodAttr)
|
|
{
|
|
_pCurBuf = pCurBuf;
|
|
_pRefBuf = pRefBuf;
|
|
_fileDiff = fileDiff;
|
|
_pszIntName = pszIntName;
|
|
_blockType = blockType;
|
|
_pszMethodAttr = pszMethodAttr;
|
|
|
|
_pCurList = new CAutoArray<LINEINFO>;
|
|
_pRefList = new CAutoArray<LINEINFO>;
|
|
|
|
|
|
CreateLineIndex(_pCurList, _pCurBuf);
|
|
CreateLineIndex(_pRefList, _pRefBuf);
|
|
|
|
_bFirstTime = true;
|
|
}
|
|
|
|
CCompareInterface::~CCompareInterface()
|
|
{
|
|
delete _pCurList;
|
|
delete _pRefList;
|
|
}
|
|
|
|
void CCompareInterface::FindAdditionsAndChanges( )
|
|
{
|
|
long lIdx;
|
|
long lTmp;
|
|
LINEINFO lineCur;
|
|
LINEINFO lineRef;
|
|
|
|
bool bRetVal = false;
|
|
|
|
//check for additions and alterations
|
|
for ( lIdx = 0; lIdx< (int)_pCurList->Size(); lIdx++)
|
|
{
|
|
_pCurList->GetAt( lIdx, &lineCur );
|
|
|
|
//get the real name of the method or property
|
|
char* pszMethodName = new char[lineCur.ulParamStart-lineCur.ulMethodNameStart+1];
|
|
|
|
for (lTmp=lineCur.ulMethodNameStart; lTmp<(long)lineCur.ulParamStart; lTmp++)
|
|
{
|
|
pszMethodName[lTmp-lineCur.ulMethodNameStart] = _pCurBuf[lTmp];
|
|
}
|
|
pszMethodName[lTmp-lineCur.ulMethodNameStart] = 0;
|
|
|
|
lstrcpy( _szLogBuff, _pszIntName);
|
|
lstrcat( _szLogBuff, "::" );
|
|
lstrcat( _szLogBuff, pszMethodName );
|
|
|
|
for ( lTmp=0; lTmp<_pRefList->Size(); lTmp++ )
|
|
{
|
|
_pRefList->GetAt( lTmp, &lineRef );
|
|
|
|
//compare the names of two methods to find if they are comparable
|
|
//in respect to other aspects of their declarations.
|
|
if ((!lineRef.fUsed)&&
|
|
( CompareBuffer( pszMethodName,
|
|
&_pRefBuf[lineRef.ulMethodNameStart],
|
|
max( lineCur.ulParamStart-lineCur.ulMethodNameStart, lineRef.ulParamStart-lineRef.ulMethodNameStart) )))
|
|
{
|
|
// if the names are the same, now compare the return values. If they are not the same, then the method is
|
|
// modified from its original version.
|
|
if ( !CompareBuffer( &_pCurBuf[lineCur.ulNameStart],
|
|
&_pRefBuf[lineRef.ulNameStart],
|
|
max( lineCur.ulMethodNameStart-lineCur.ulNameStart, lineRef.ulMethodNameStart-lineRef.ulNameStart) ))
|
|
{
|
|
bRetVal = true;
|
|
}
|
|
|
|
//compare attribute block
|
|
if (( fgMethodAttribute ) &&
|
|
((lineCur.ulAttrEnd-lineCur.ulAttrStart != lineRef.ulAttrEnd-lineRef.ulAttrStart) ||
|
|
( !CompareBuffer( &_pCurBuf[lineCur.ulAttrStart], &_pRefBuf[lineRef.ulAttrStart],
|
|
max(lineCur.ulAttrEnd-lineCur.ulAttrStart, lineRef.ulAttrEnd-lineRef.ulAttrStart)))) )
|
|
{
|
|
// since we know the attributes have changed, analyze the type of change
|
|
CompareMethodAttributes( &lineRef, &lineCur );
|
|
}
|
|
|
|
//compare parameter block
|
|
if (( fgMethodParameter ) &&
|
|
((lineCur.ulParamEnd-lineCur.ulParamStart != lineRef.ulParamEnd-lineRef.ulParamStart) ||
|
|
( !CompareBuffer( &_pCurBuf[lineCur.ulParamStart], &_pRefBuf[lineRef.ulParamStart],
|
|
max(lineCur.ulParamEnd-lineCur.ulParamStart, lineRef.ulParamEnd-lineRef.ulParamStart)))) )
|
|
{
|
|
CompareMethodParameters( &lineRef, &lineCur );
|
|
}
|
|
|
|
//we have found the method that matches, move on to the next
|
|
//method name on the current block.
|
|
lineRef.fUsed = true;
|
|
_pRefList->Set( lTmp, lineRef );
|
|
break;
|
|
}
|
|
}
|
|
|
|
//write the results that were found from this comparison,
|
|
//if this was a different line
|
|
if ( bRetVal || (lTmp == _pRefList->Size()) )
|
|
{
|
|
char* pszBuff = new char[128];
|
|
|
|
EnsureTitle( TRUE );
|
|
|
|
if ( bRetVal )
|
|
{
|
|
lstrcpy( pszBuff, _szLogBuff );
|
|
lstrcat( pszBuff, " - Return value or call type has changed " );
|
|
WriteLine( _fileDiff, pszBuff, -1);
|
|
bRetVal = false;
|
|
g_ulAppRetVal |= CHANGE_RETVALCHANGE;
|
|
}
|
|
|
|
if (lTmp == _pRefList->Size()) //this is a new nethod
|
|
{
|
|
lstrcpy( pszBuff, _szLogBuff );
|
|
lstrcat( pszBuff, " - Is a new method " );
|
|
WriteLine(_fileDiff, pszBuff,-1);
|
|
|
|
if ( _blockType== BLK_DISPINT )
|
|
g_ulAppRetVal |= CHANGE_METHODONDISPINT;
|
|
else
|
|
g_ulAppRetVal |= CHANGE_METHODONINT;
|
|
}
|
|
delete [] pszBuff;
|
|
}
|
|
|
|
delete [] pszMethodName;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// bMode == TRUE --> Addition / Change
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
CCompareInterface::EnsureTitle( BOOL bAddition )
|
|
{
|
|
char szBuff[256];
|
|
|
|
if ( _bFirstTime )
|
|
{
|
|
//write the header.
|
|
if ( _blockType== BLK_DISPINT )
|
|
lstrcpy( szBuff, "\nDispinterface " );
|
|
else
|
|
lstrcpy( szBuff, "\nInterface " );
|
|
|
|
lstrcat( szBuff, _pszIntName );
|
|
lstrcat( szBuff, "\n------------------------------------\n");
|
|
if ( bAddition )
|
|
{
|
|
lstrcat( szBuff, "Additions / Changes:" );
|
|
}
|
|
|
|
WriteLine( _fileDiff, szBuff, -1);
|
|
|
|
_bFirstTime = false;
|
|
}
|
|
}
|
|
//
|
|
// Walk through the unmarked elements of the reference block index. These are the
|
|
// entries that do not exist in the current block.
|
|
//
|
|
void CCompareInterface::FindRemovals( )
|
|
{
|
|
long lIdx;
|
|
long lTmp;
|
|
LINEINFO lineRef;
|
|
char* szBuff = new char[128];
|
|
bool bFirstRemoval = true;
|
|
|
|
for ( lIdx=0; lIdx< (int)_pRefList->Size(); lIdx++ )
|
|
{
|
|
//get the record
|
|
_pRefList->GetAt( lIdx, &lineRef);
|
|
|
|
//is the record marked ?
|
|
if (!lineRef.fUsed)
|
|
{
|
|
//get the real name of the interface
|
|
char* pszMethodName = new char[lineRef.ulParamStart-lineRef.ulMethodNameStart+1];
|
|
int nIdx;
|
|
|
|
for (lTmp=lineRef.ulMethodNameStart, nIdx=0; lTmp<(long)lineRef.ulParamStart; lTmp++, nIdx++)
|
|
{
|
|
pszMethodName[nIdx] = _pRefBuf[lTmp];
|
|
}
|
|
|
|
pszMethodName[nIdx] = 0; //terminate the string
|
|
|
|
// if this is the first removal, then add the word Removals
|
|
EnsureTitle( FALSE );
|
|
|
|
//write the header.
|
|
if ( _blockType== BLK_DISPINT )
|
|
g_ulAppRetVal |= CHANGE_REMOVEFROMDISPINT;
|
|
else
|
|
g_ulAppRetVal |= CHANGE_REMOVEFROMINT;
|
|
|
|
if ( bFirstRemoval)
|
|
{
|
|
WriteLine( _fileDiff, "Removals : ", -1);
|
|
bFirstRemoval = false;
|
|
}
|
|
|
|
lstrcpy( szBuff, _pszIntName);
|
|
lstrcat( szBuff, "::");
|
|
lstrcat( szBuff, pszMethodName);
|
|
lstrcat( szBuff, " has been removed.");
|
|
WriteLine( _fileDiff, szBuff, -1);
|
|
|
|
delete [] pszMethodName;
|
|
}
|
|
}
|
|
|
|
delete [] szBuff;
|
|
}
|
|
|
|
void CCompareInterface::CreateLineIndex( CAutoArray<LINEINFO>* pList, char* pBuf )
|
|
{
|
|
LINEINFO lineinfo = {0};
|
|
|
|
unsigned long ulIdx=0;
|
|
unsigned long ulLastSpace = 0;
|
|
char chSearch = '['; //initially look for the opening attribute char.
|
|
unsigned int uBrCnt = 0;
|
|
unsigned int uParCnt = 0;
|
|
|
|
//go until the end of the buffer, it is null terminated.
|
|
while ( pBuf[ulIdx] != 0)
|
|
{
|
|
if ( pBuf[ulIdx] == chSearch )
|
|
{
|
|
//depending on what we were looking for,
|
|
//we can decide what to look for next.
|
|
switch (chSearch)
|
|
{
|
|
case '[':
|
|
uBrCnt++;
|
|
if ( uBrCnt == 1 )
|
|
{
|
|
lineinfo.ulAttrStart = ulIdx;
|
|
chSearch = ']';
|
|
}
|
|
break;
|
|
|
|
case ']':
|
|
uBrCnt --;
|
|
if ( uBrCnt == 0 )
|
|
{
|
|
lineinfo.ulAttrEnd = ulIdx;
|
|
lineinfo.ulNameStart = ulIdx+2;
|
|
chSearch = '(';
|
|
}
|
|
break;
|
|
|
|
case '(':
|
|
uParCnt++;
|
|
if (uParCnt==1)
|
|
{
|
|
lineinfo.ulNameEnd = ulIdx-1;
|
|
lineinfo.ulParamStart = ulIdx;
|
|
lineinfo.ulMethodNameStart = ulLastSpace+1;
|
|
chSearch = ')';
|
|
}
|
|
break;
|
|
|
|
case ')':
|
|
uParCnt--;
|
|
if ( uParCnt == 0 )
|
|
{
|
|
lineinfo.ulParamEnd = ulIdx;
|
|
chSearch = '[';
|
|
|
|
//completed the cycle, add this record to the list
|
|
pList->Append(lineinfo);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch ( pBuf[ulIdx] )
|
|
{
|
|
case '(':
|
|
uParCnt++;
|
|
break;
|
|
|
|
case ')':
|
|
uParCnt--;
|
|
break;
|
|
|
|
case '[':
|
|
uBrCnt++;
|
|
break;
|
|
|
|
case ']':
|
|
uBrCnt--;
|
|
break;
|
|
|
|
case ' ':
|
|
ulLastSpace = ulIdx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
ulIdx++;
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void
|
|
CCompareInterface::CompareMethodAttributes( LINEINFO* pRef,
|
|
LINEINFO* pCur )
|
|
{
|
|
long l,
|
|
k;
|
|
long curBase = (pCur->ulAttrStart)+1;
|
|
long refBase = (pRef->ulAttrStart)+1;
|
|
ATTRINFO attrRef;
|
|
ATTRINFO attrCur;
|
|
|
|
CAutoArray<ATTRINFO>* pCurList = new CAutoArray<ATTRINFO>;
|
|
CAutoArray<ATTRINFO>* pRefList = new CAutoArray<ATTRINFO>;
|
|
|
|
TokenizeAttributes( &_pRefBuf[refBase], pRef->ulAttrEnd-refBase, pRefList );
|
|
TokenizeAttributes( &_pCurBuf[curBase], pCur->ulAttrEnd-curBase, pCurList );
|
|
|
|
//let's find the ones that are new
|
|
for ( l=0; l < pCurList->Size(); l++ )
|
|
{
|
|
pCurList->GetAt( l, &attrCur);
|
|
|
|
for ( k=0; k < pRefList->Size(); k++ )
|
|
{
|
|
pRefList->GetAt( k, &attrRef );
|
|
|
|
if ( (!attrRef.fUsed ) &&
|
|
CompareBuffer( &_pCurBuf[curBase + attrCur.ulAttrStart],
|
|
&_pRefBuf[refBase + attrRef.ulAttrStart],
|
|
max( attrCur.ulAttrLength, attrRef.ulAttrLength)) )
|
|
{
|
|
// found the same attribute in the reference attributes, it is not a new
|
|
// attribute
|
|
attrRef.fUsed = true;
|
|
pRefList->Set( k, attrRef );
|
|
|
|
attrCur.fUsed = true;
|
|
pCurList->Set( l, attrCur );
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( k == pRefList->Size() )
|
|
{
|
|
// this is a new attribute.
|
|
// if we find this attribute name in the list, then we are breaking the compat
|
|
if ( IsAttributeBreaker( _pszMethodAttr,
|
|
_pCurBuf+curBase+attrCur.ulAttrStart,
|
|
attrCur.ulAttrLength ) )
|
|
{
|
|
EnsureTitle(TRUE);
|
|
WriteAttrChangeString( _pCurBuf,
|
|
curBase+attrCur.ulAttrStart,
|
|
attrCur.ulAttrLength,
|
|
"' attribute was added");
|
|
}
|
|
}
|
|
}
|
|
|
|
// Whatever is left in the reference array as not used are removals.
|
|
for ( l=0; l < pRefList->Size(); l++ )
|
|
{
|
|
pRefList->GetAt( l, &attrRef);
|
|
|
|
if ( !attrRef.fUsed )
|
|
{
|
|
// if we find this attribute name in the list, then we are breaking the compat
|
|
if ( IsAttributeBreaker( _pszMethodAttr,
|
|
_pRefBuf+refBase+attrRef.ulAttrStart,
|
|
attrRef.ulAttrLength ) )
|
|
{
|
|
// breaker attribute
|
|
EnsureTitle(TRUE);
|
|
WriteAttrChangeString( _pRefBuf,
|
|
refBase+attrRef.ulAttrStart,
|
|
attrRef.ulAttrLength,
|
|
"' attribute was removed");
|
|
}
|
|
}
|
|
}
|
|
|
|
delete pCurList;
|
|
delete pRefList;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// The attribute list contains the buffer that is read from the INI file.
|
|
// Each attribute name is a string that is terminated by a NULL character. At
|
|
// the very end, after the last attribute, there is an additional NULL.
|
|
//----------------------------------------------------------------------------
|
|
BOOL
|
|
CCompareInterface::IsAttributeBreaker( char * pszAttrList, char * pszAttr, unsigned long ulAttrLen )
|
|
{
|
|
unsigned long ulStrLen;
|
|
unsigned long ulIdx = 0; // index to the big buffer.
|
|
|
|
// until we reach the very end.
|
|
// if we can not get into the loop below, it means that there are no
|
|
// attributes that are considered breaking
|
|
while (pszAttrList[ulIdx] != NULL)
|
|
{
|
|
ulStrLen = lstrlen(&pszAttrList[ulIdx]);
|
|
|
|
// if the lengths and the contents are the same, then this attribute
|
|
// is a breaker attribute
|
|
if ((ulStrLen == ulAttrLen) &&
|
|
(CompareBuffer(&pszAttrList[ulIdx], pszAttr, ulStrLen)))
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
// increment the index, to point to the next string in the buffer
|
|
ulIdx += ulStrLen + 1;
|
|
}
|
|
|
|
// if we reach here, it means that we could not find the attribute in the list
|
|
// this is NOT a breaker attribute
|
|
return FALSE;
|
|
}
|
|
|
|
void
|
|
CCompareInterface::WriteAttrChangeString(char* pBuf,
|
|
unsigned long ulAttrStart,
|
|
unsigned long ulAttrLength,
|
|
char* szChangeType)
|
|
{
|
|
unsigned long k;
|
|
char szBuff[256];
|
|
char * pszAttrName = new char[ulAttrLength+1];
|
|
|
|
//copy the attribute name into the buffer
|
|
for (k = 0; k < ulAttrLength; k++)
|
|
pszAttrName[k] = *(pBuf + ulAttrStart + k);
|
|
|
|
pszAttrName[k] = 0; //terminate
|
|
|
|
lstrcpy(szBuff, _szLogBuff);
|
|
lstrcat(szBuff, " - '");
|
|
lstrcat(szBuff, pszAttrName);
|
|
lstrcat(szBuff, szChangeType);
|
|
|
|
WriteLine(_fileDiff, szBuff, -1);
|
|
g_ulAppRetVal |= CHANGE_ATTRCHANGE;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
CCompareInterface::CompareMethodParameters( LINEINFO* pRef, LINEINFO* pCur)
|
|
{
|
|
long l;
|
|
long k;
|
|
long curBase = (pCur->ulParamStart)+1;
|
|
long refBase = (pRef->ulParamStart)+1;
|
|
|
|
PARAMINFO paramRef;
|
|
PARAMINFO paramCur;
|
|
|
|
CAutoArray<PARAMINFO>* pCurList = NULL;
|
|
CAutoArray<PARAMINFO>* pRefList = NULL;
|
|
|
|
bool bNameChange,
|
|
bTypeChange,
|
|
bReplaced;
|
|
char szBuff[512] = {0};
|
|
char szType[64] = {0};
|
|
char szName[64] = {0};
|
|
|
|
|
|
pCurList = new CAutoArray<PARAMINFO>;
|
|
pRefList = new CAutoArray<PARAMINFO>;
|
|
|
|
assert( pCurList );
|
|
assert( pRefList );
|
|
|
|
// start by tokenizing the parameters
|
|
TokenizeParameters( &_pRefBuf[refBase], pRef->ulParamEnd-refBase, pRefList);
|
|
TokenizeParameters( &_pCurBuf[curBase], pCur->ulParamEnd-curBase, pCurList);
|
|
|
|
// parameters have to match one to one.
|
|
for ( l=0; l<pRefList->Size(); l++ )
|
|
{
|
|
bTypeChange = bNameChange = bReplaced = false;
|
|
|
|
pCurList->GetAt( l, ¶mCur);
|
|
pRefList->GetAt( l, ¶mRef);
|
|
|
|
// is this parameter touched before, because of a replacement catch?
|
|
// if that is the case we should only check if the reference parameter was replaced
|
|
if ( paramCur.fUsed )
|
|
{
|
|
bTypeChange = bNameChange = true;
|
|
goto ReplaceCheck;
|
|
}
|
|
|
|
// compare the types
|
|
if ( fgParamTypes )
|
|
{
|
|
//
|
|
// Only go through comparison if the type does not contain a _MIDL_ word in it.
|
|
//
|
|
char szTypeRef[64] = {0};
|
|
lstrcpyn( szTypeRef,
|
|
_pRefBuf+refBase+paramRef.ulTypeStart,
|
|
max(63, paramRef.ulTypeLength));
|
|
|
|
if ( !strstr(szTypeRef, "_MIDL_") )
|
|
{
|
|
// if the lengths are different bail out immediately, without text comparison.
|
|
if ( paramRef.ulTypeLength == paramCur.ulTypeLength )
|
|
{
|
|
//compare the contents, check if we want case sensitive or not.
|
|
if ( fgParamTypeCase )
|
|
bTypeChange = !CompareBuffer( _pRefBuf+refBase+paramRef.ulTypeStart,
|
|
_pCurBuf+curBase+paramCur.ulTypeStart,
|
|
max( paramRef.ulTypeLength, paramCur.ulTypeLength) );
|
|
else
|
|
bTypeChange = !CompareBufferNoCase( _pRefBuf+refBase+paramRef.ulTypeStart,
|
|
_pCurBuf+curBase+paramCur.ulTypeStart,
|
|
max( paramRef.ulTypeLength, paramCur.ulTypeLength) );
|
|
}
|
|
else
|
|
bTypeChange = true;
|
|
}
|
|
else
|
|
{
|
|
// if one of the types contains a _MIDL_, then the other MUST too.
|
|
char szTypeCur[64] = {0};
|
|
lstrcpyn( szTypeCur,
|
|
_pCurBuf+curBase+paramCur.ulTypeStart,
|
|
max(63, paramCur.ulTypeLength));
|
|
|
|
// if the string does NOT contain _MIDL_ than there was a change.
|
|
if ( !strstr(szTypeCur, "_MIDL_") )
|
|
{
|
|
bTypeChange = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if ( fgParamNames )
|
|
{
|
|
char szNameRef[64] = {0};
|
|
|
|
//
|
|
// If the name of one parameter contains a _MIDL_ keyword, then only make sure the
|
|
// other name contains the _MIDL_ too. No need to match strings.
|
|
//
|
|
lstrcpyn( szNameRef, _pRefBuf+refBase+paramRef.ulNameStart, max(63, paramRef.ulNameLength));
|
|
|
|
if (!strstr(szNameRef, "_MIDL_"))
|
|
{
|
|
// if the lengths are different bail out immediately, without text comparison.
|
|
if ( paramRef.ulNameLength == paramCur.ulNameLength )
|
|
{
|
|
//compare the contents, check if we want case sensitive or not.
|
|
if ( fgParamNameCase )
|
|
bNameChange = !CompareBuffer( _pRefBuf+refBase+paramRef.ulNameStart,
|
|
_pCurBuf+curBase+paramCur.ulNameStart,
|
|
max( paramRef.ulNameLength, paramCur.ulNameLength) );
|
|
else
|
|
bNameChange = !CompareBuffer( _pRefBuf+refBase+paramRef.ulNameStart,
|
|
_pCurBuf+curBase+paramCur.ulNameStart,
|
|
max( paramRef.ulNameLength, paramCur.ulNameLength) );
|
|
}
|
|
else
|
|
bNameChange = true;
|
|
}
|
|
else
|
|
{
|
|
char szNameCur[64] = {0};
|
|
|
|
// only make sure the current name also has the _MIDL_ keyword.
|
|
lstrcpyn( szNameCur, _pCurBuf+curBase+paramCur.ulNameStart, max(63, paramCur.ulNameLength));
|
|
|
|
if (!strstr( szNameCur, "_MIDL_"))
|
|
{
|
|
bNameChange = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
ReplaceCheck:
|
|
// if there was a change in the parameter, find out if this parameter is moved to another location
|
|
// in the parameter list. We look for an exact match in this case, since this is only additional
|
|
// information
|
|
if ( bNameChange || bTypeChange )
|
|
{
|
|
PARAMINFO paramTmp;
|
|
|
|
for ( k=0; k< pCurList->Size(); k++ )
|
|
{
|
|
pCurList->GetAt( k, ¶mTmp );
|
|
|
|
if ( ( !paramTmp.fUsed ) &&
|
|
( paramTmp.ulParamLength == paramCur.ulParamLength ) &&
|
|
( CompareBuffer( _pRefBuf+refBase+paramRef.ulTypeStart,
|
|
_pCurBuf+curBase+paramTmp.ulTypeStart,
|
|
paramTmp.ulParamLength) ) )
|
|
{
|
|
// we have found the parameter at another location.
|
|
bReplaced = true;
|
|
|
|
// we will only report the replacement, to simplify
|
|
bTypeChange = false;
|
|
bNameChange = false;
|
|
|
|
// mark the parameter in the current list as touched, so that
|
|
// whatever parameter we check in the reference list does not get
|
|
// processed against this. ( perf. )
|
|
paramTmp.fUsed = true;
|
|
pCurList->Set( k, paramTmp );
|
|
}
|
|
}
|
|
}
|
|
|
|
// if we found the parameter at the same location
|
|
if ( bReplaced || bNameChange || bTypeChange )
|
|
{
|
|
EnsureTitle(TRUE);
|
|
|
|
g_ulAppRetVal |= CHANGE_PARAMCHANGE;
|
|
|
|
// we copy the type and the name. The lengths are +1 since the function requires
|
|
// us to calculate the NULL character too.
|
|
|
|
lstrcpyn( szType, _pRefBuf+refBase+paramRef.ulTypeStart, paramRef.ulTypeLength+1 );
|
|
|
|
if ( paramRef.ulNameStart )
|
|
lstrcpyn( szName, _pRefBuf+refBase+paramRef.ulNameStart, paramRef.ulNameLength+1 );
|
|
|
|
// fill the string with ' - Parameter xx', so that we can add the change type
|
|
lstrcpy( szBuff, _szLogBuff);
|
|
lstrcat( szBuff, " - Parameter " );
|
|
lstrcat( szBuff, szType );
|
|
lstrcat( szBuff, " ");
|
|
lstrcat( szBuff, szName );
|
|
|
|
// if replaced, then name and type change flags are false.
|
|
if ( bReplaced )
|
|
{
|
|
// output replacement information
|
|
lstrcat( szBuff, " has been replaced" );
|
|
}
|
|
else
|
|
{
|
|
// was this parameter removed
|
|
if ( bNameChange && bTypeChange )
|
|
{
|
|
// output information that shows the name change
|
|
lstrcat( szBuff, " has been removed");
|
|
}
|
|
else
|
|
{
|
|
if ( bNameChange )
|
|
{
|
|
// output information that shows the name change
|
|
lstrcat( szBuff, " name has been modified");
|
|
|
|
// for name only changes, mark the parameter as used.
|
|
paramCur.fUsed = true;
|
|
pCurList->Set( l, paramCur );
|
|
}
|
|
|
|
if ( bTypeChange )
|
|
{
|
|
// output information that shows the type change.
|
|
lstrcat( szBuff, " type has been modified");
|
|
}
|
|
}
|
|
}
|
|
|
|
WriteLine(_fileDiff, szBuff, -1);
|
|
}
|
|
else
|
|
{
|
|
// mark the parameter, everything is OK, move on.
|
|
paramCur.fUsed = true;
|
|
pCurList->Set( l, paramCur );
|
|
}
|
|
}
|
|
|
|
// find the parameters that were added.
|
|
for ( l=0; l<pCurList->Size(); l++ )
|
|
{
|
|
pCurList->GetAt( l, ¶mCur);
|
|
|
|
// if this parameter was not used, then it means that it was added.
|
|
if ( !paramCur.fUsed )
|
|
{
|
|
EnsureTitle(TRUE);
|
|
|
|
g_ulAppRetVal |= CHANGE_PARAMCHANGE;
|
|
|
|
// copy the parameter name as a whole
|
|
lstrcpyn( szName, _pCurBuf+curBase+paramCur.ulTypeStart, paramCur.ulParamLength+1 );
|
|
|
|
// fill the string with ' - Parameter xx', so that we can add the change type
|
|
lstrcpy( szBuff, _szLogBuff);
|
|
lstrcat( szBuff, " - Parameter " );
|
|
lstrcat( szBuff, szName );
|
|
lstrcat( szBuff, " was added");
|
|
WriteLine( _fileDiff, szBuff, -1);
|
|
|
|
}
|
|
}
|
|
|
|
delete pCurList;
|
|
delete pRefList;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
CCompareInterface::TokenizeParameters( char* pBuf,
|
|
unsigned long nCnt,
|
|
CAutoArray<PARAMINFO>* pList )
|
|
{
|
|
unsigned long i,j;
|
|
PARAMINFO paramInfo;
|
|
bool bInBracket = false;
|
|
|
|
paramInfo.ulTypeStart = 0;
|
|
|
|
for( i=0; i<=nCnt ; i++ )
|
|
{
|
|
// since we are coming from left, and going right, we will first see the
|
|
// opening and then the closing bracket
|
|
if ( pBuf[i] == '[' )
|
|
bInBracket = true;
|
|
if ( pBuf[i] == ']' )
|
|
bInBracket = false;
|
|
|
|
// if we reached a comma that was not inside a bracket, or reached the end
|
|
// and the end is an opening parenthesis
|
|
if ( ((pBuf[i] == ',') && !bInBracket ) || ( i == nCnt ) )
|
|
{
|
|
paramInfo.ulParamLength = i - paramInfo.ulTypeStart;
|
|
paramInfo.fUsed = false;
|
|
|
|
// digest the type and name here ! ! !
|
|
for ( j = paramInfo.ulTypeStart+paramInfo.ulParamLength-1; j > 0 ; j-- )
|
|
{
|
|
// go from the end of the parameter, towards the beginning,
|
|
// searching for a space character, or the beginning of the parameter block
|
|
if ( *(pBuf + j) == ' ')
|
|
{
|
|
paramInfo.ulNameStart = j + 1;
|
|
paramInfo.ulTypeLength = j - paramInfo.ulTypeStart;
|
|
paramInfo.ulNameLength = paramInfo.ulTypeStart + paramInfo.ulParamLength - paramInfo.ulNameStart;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// we could not find a parameter when we parsed through, it means a void..
|
|
// double check for void
|
|
if (( j==0 ) && ( *pBuf == 'v' ) && (*(pBuf+1) == 'o'))
|
|
{
|
|
paramInfo.ulTypeStart = 0;
|
|
paramInfo.ulTypeLength = 4;
|
|
paramInfo.ulParamLength = 4;
|
|
paramInfo.ulNameStart = 0;
|
|
paramInfo.ulNameLength = 0;
|
|
|
|
pList->Append( paramInfo );
|
|
}
|
|
else
|
|
{
|
|
// we should never ever reach zero.
|
|
if ( j==0 )
|
|
assert( false );
|
|
|
|
pList->Append( paramInfo );
|
|
|
|
// skip over the comma
|
|
i++;
|
|
|
|
// the name starts next to the space
|
|
paramInfo.ulTypeStart = i+1;
|
|
}
|
|
}
|
|
}
|
|
}
|