922 lines
No EOL
19 KiB
C++
922 lines
No EOL
19 KiB
C++
#include "stdafx.h";
|
|
|
|
#if 0
|
|
bool bCharIsSpace(char _c)
|
|
{
|
|
return (
|
|
(_c == ' ') ||
|
|
(_c == 10) ||
|
|
(_c == 13) ||
|
|
(_c == '\t')
|
|
);
|
|
}
|
|
|
|
|
|
|
|
void RemoveAllRedundentSpaces(char* pWord)
|
|
{
|
|
Restart:
|
|
int i = 0;
|
|
while(pWord[i] != 0)
|
|
{
|
|
if (bCharIsSpace(pWord[i]))
|
|
{
|
|
if (bCharIsSpace(pWord[i+1]))
|
|
{
|
|
int copyto = i;
|
|
int copyfrom = i+1;
|
|
while(TRUE)
|
|
{
|
|
char c = pWord[copyfrom++];
|
|
pWord[copyto++] = c;
|
|
if (c == 0)
|
|
{
|
|
goto Restart;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
i++;
|
|
}
|
|
|
|
i = 0;
|
|
while(pWord[i] != 0)
|
|
{
|
|
if (bCharIsSpace(pWord[i]))
|
|
{
|
|
pWord[i] = ' ';
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
|
|
void CleanupWord(char* pWord)
|
|
{
|
|
int index = (int)(strlen(pWord))-1;
|
|
while(pWord[index] == ' ') pWord[index--] = 0;
|
|
}
|
|
|
|
void CleanupArgType(char* pWord)
|
|
{
|
|
// Don't change the order of these tests !!!
|
|
|
|
// Look for "="
|
|
int i = 0;
|
|
while(pWord[i] != 0)
|
|
{
|
|
if (pWord[i] == '=')
|
|
{
|
|
pWord[i] = 0;
|
|
break;
|
|
}
|
|
i++;
|
|
}
|
|
|
|
// Look for "volatile"
|
|
i=0;
|
|
while(pWord[i] != 0)
|
|
{
|
|
if (!strncmp(&pWord[i], "volatile", 8))
|
|
{
|
|
pWord[i+8] = 0;
|
|
return;
|
|
}
|
|
i++;
|
|
}
|
|
|
|
// Look for "__restrict"
|
|
i=0;
|
|
while(pWord[i] != 0)
|
|
{
|
|
if (!strncmp(&pWord[i], "__restrict", 10))
|
|
{
|
|
pWord[i+10] = 0;
|
|
return;
|
|
}
|
|
i++;
|
|
}
|
|
|
|
// Look for "restrict"
|
|
i=0;
|
|
while(pWord[i] != 0)
|
|
{
|
|
if (!strncmp(&pWord[i], "restrict", 8))
|
|
{
|
|
pWord[i+8] = 0;
|
|
return;
|
|
}
|
|
i++;
|
|
}
|
|
|
|
// Look for "&, *, >"
|
|
i=0;
|
|
while(pWord[i] != 0)
|
|
{
|
|
if (
|
|
(pWord[i] == '&') ||
|
|
(pWord[i] == '*') ||
|
|
(pWord[i] == '>')
|
|
)
|
|
{
|
|
char tchar = pWord[i];
|
|
pWord[i+1] = 0;
|
|
if (i>0)
|
|
{
|
|
if (bCharIsSpace(pWord[i-1]))
|
|
{
|
|
i--;
|
|
while ((i>0) && (bCharIsSpace(pWord[i])))
|
|
{
|
|
i--;
|
|
}
|
|
pWord[i+1] = tchar;
|
|
pWord[i+2] = 0;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
i++;
|
|
}
|
|
|
|
// Treat spaces
|
|
int len = (int)strlen(pWord);
|
|
for (i=0; i<len; i++)
|
|
{
|
|
if (bCharIsSpace(pWord[i]))
|
|
{
|
|
int iFirstSpace = i;
|
|
while (bCharIsSpace(pWord[i++]));
|
|
if(i>=len)
|
|
{
|
|
return;
|
|
}
|
|
if ((pWord[i] != '*') && (pWord[i] != '&') && (pWord[i] != '>'))
|
|
{
|
|
pWord[iFirstSpace] = 0;
|
|
}
|
|
else
|
|
{
|
|
pWord[iFirstSpace] = pWord[i];
|
|
pWord[iFirstSpace+1] = 0;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void HideQualifiers(char* Word)
|
|
{
|
|
int index=-1;
|
|
if (!strncmp(Word, "const", 5))
|
|
{
|
|
index = 5;
|
|
}
|
|
if (!strncmp(Word, "static", 6))
|
|
{
|
|
index = 6;
|
|
}
|
|
if (!strncmp(Word, "unsigned", 8))
|
|
{
|
|
index = 8;
|
|
}
|
|
if (!strncmp(Word, "signed", 6))
|
|
{
|
|
index = 6;
|
|
}
|
|
if (index>0)
|
|
{
|
|
while(bCharIsSpace(Word[index]))
|
|
{
|
|
Word[index] = '$';
|
|
index++;
|
|
}
|
|
}
|
|
}
|
|
|
|
void RestoreQualifiers(char* Word)
|
|
{
|
|
int index=-1;
|
|
if (!strncmp(Word, "const", 5))
|
|
{
|
|
index = 5;
|
|
}
|
|
if (!strncmp(Word, "static", 6))
|
|
{
|
|
index = 6;
|
|
}
|
|
if (!strncmp(Word, "unsigned", 8))
|
|
{
|
|
index = 8;
|
|
}
|
|
if (!strncmp(Word, "signed", 6))
|
|
{
|
|
index = 6;
|
|
}
|
|
if (index>0)
|
|
{
|
|
while(Word[index] == '$')
|
|
{
|
|
Word[index] = ' ';
|
|
index++;
|
|
}
|
|
}
|
|
}
|
|
|
|
void FullArgCleanup(char *_Word)
|
|
{
|
|
RemoveAllRedundentSpaces(_Word);
|
|
HideQualifiers(_Word);
|
|
CleanupArgType(_Word);
|
|
CleanupWord(_Word);
|
|
RestoreQualifiers(_Word);
|
|
if (!strcmp(_Word, "...")) *_Word = 0;
|
|
if (!strcmp(_Word, "void")) *_Word = 0;
|
|
}
|
|
|
|
FunctionArg::FunctionArg()
|
|
{
|
|
m_szArgType = NULL;
|
|
m_szArgName = NULL;
|
|
m_pNext = NULL;
|
|
}
|
|
|
|
FunctionArg::~FunctionArg()
|
|
{
|
|
if (m_szArgType) MemoryHandler::Free (m_szArgType);
|
|
if (m_szArgName) MemoryHandler::Free (m_szArgName);
|
|
}
|
|
|
|
Function::Function()
|
|
{
|
|
m_szType = NULL;
|
|
m_szName = NULL;
|
|
m_pArgs = NULL;
|
|
m_pNext = NULL;
|
|
m_szClassName = NULL;
|
|
}
|
|
|
|
Function::~Function()
|
|
{
|
|
if (m_szType) MemoryHandler::Free(m_szType);
|
|
if (m_szName) MemoryHandler::Free(m_szName);
|
|
if (m_szClassName) MemoryHandler::Free(m_szClassName);
|
|
|
|
FunctionArg* pArg = m_pArgs;
|
|
while(pArg)
|
|
{
|
|
FunctionArg* pDel = pArg;
|
|
pArg = pArg->m_pNext;
|
|
delete pDel;
|
|
}
|
|
}
|
|
|
|
FunctionArg& Function::AddArg()
|
|
{
|
|
if (m_pArgs == NULL)
|
|
{
|
|
m_pArgs = new FunctionArg();
|
|
return *m_pArgs;
|
|
}
|
|
|
|
FunctionArg* pArg = m_pArgs;
|
|
while(pArg->m_pNext)
|
|
{
|
|
pArg = pArg->m_pNext;
|
|
}
|
|
pArg->m_pNext = new FunctionArg();
|
|
return *pArg->m_pNext;
|
|
}
|
|
|
|
int Function::iGetArgCount()
|
|
{
|
|
FunctionArg* pArg = m_pArgs;
|
|
int iArgIndex = 0;
|
|
while (pArg)
|
|
{
|
|
iArgIndex++;
|
|
pArg = pArg->m_pNext;
|
|
}
|
|
return iArgIndex;
|
|
}
|
|
|
|
char* Function::szGetArgName(unsigned __int32 _uiArgIndex)
|
|
{
|
|
FunctionArg* pArg = m_pArgs;
|
|
__int32 uiArgIndex = 0;
|
|
while (pArg)
|
|
{
|
|
if (uiArgIndex == _uiArgIndex)
|
|
{
|
|
return pArg->m_szArgName;
|
|
}
|
|
pArg = pArg->m_pNext;
|
|
uiArgIndex++;
|
|
}
|
|
|
|
assert(uiArgIndex == 0);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
ParseCPP::~ParseCPP()
|
|
{
|
|
Function* pf = m_pFunctions;
|
|
while (pf)
|
|
{
|
|
Function* pDel = pf;
|
|
pf = pf->m_pNext;
|
|
delete pDel;
|
|
}
|
|
}
|
|
|
|
Function& ParseCPP::AddFunction()
|
|
{
|
|
if (m_pFunctions == NULL)
|
|
{
|
|
m_pFunctions = new Function();
|
|
return *m_pFunctions;
|
|
}
|
|
|
|
Function* pfunc = m_pFunctions;
|
|
while(pfunc->m_pNext)
|
|
{
|
|
pfunc = pfunc->m_pNext;
|
|
}
|
|
pfunc->m_pNext = new Function();
|
|
return *pfunc->m_pNext;
|
|
}
|
|
|
|
|
|
ParseCPP::ParseCPP()
|
|
{
|
|
/*
|
|
#define TEST_ARGTYPE(_str) strcpy(Test,_str);FullArgCleanup(Test);
|
|
char Test[256];
|
|
|
|
|
|
TEST_ARGTYPE("int volatile nvint")
|
|
TEST_ARGTYPE("int volatile ")
|
|
TEST_ARGTYPE("const char * restrict filename")
|
|
TEST_ARGTYPE("const char * restrict")
|
|
TEST_ARGTYPE("const char * __restrict filename")
|
|
TEST_ARGTYPE("const char * __restrict")
|
|
TEST_ARGTYPE("const char * __restrict hop = 2")
|
|
TEST_ARGTYPE("const int")
|
|
TEST_ARGTYPE("const int zob")
|
|
TEST_ARGTYPE("const char* zob ")
|
|
TEST_ARGTYPE("const char* ")
|
|
TEST_ARGTYPE("const char * zob ")
|
|
TEST_ARGTYPE("const char * ")
|
|
TEST_ARGTYPE("char* toto ")
|
|
TEST_ARGTYPE("char* ")
|
|
TEST_ARGTYPE("char * toto ")
|
|
TEST_ARGTYPE("char * ")
|
|
TEST_ARGTYPE("char &toto ")
|
|
TEST_ARGTYPE("char &")
|
|
TEST_ARGTYPE("char&")
|
|
TEST_ARGTYPE("int zob = 2")
|
|
TEST_ARGTYPE("int zob= 2")
|
|
TEST_ARGTYPE("int")
|
|
TEST_ARGTYPE("int=2")
|
|
TEST_ARGTYPE("int =2")
|
|
TEST_ARGTYPE("unsigned int =2")
|
|
TEST_ARGTYPE("unsigned int zob=2")
|
|
TEST_ARGTYPE("template <zob> zob ")
|
|
*/
|
|
|
|
m_pFunctions = NULL;
|
|
}
|
|
|
|
|
|
bool bIsCPPInstruction(const char* pString)
|
|
{
|
|
if (!strcmp(pString, "if")) // if() instruction
|
|
{
|
|
return TRUE;
|
|
}
|
|
if (!strcmp(pString, "for")) // for() instruction
|
|
{
|
|
return TRUE;
|
|
}
|
|
if (!strcmp(pString, "while")) // while() instruction
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
bool bIsLyNMacro(const char* pString)
|
|
{
|
|
if (!strcmp(pString, "TEST"))
|
|
{
|
|
return TRUE;
|
|
}
|
|
if (!strcmp(pString, "MEM_Check"))
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void ParseCPP::RetrieveArgs(TextBuffer &buf, Function& func, unsigned __int32 uiOpenParenthesisOffset, unsigned __int32 uiClosingParenthesisOffset)
|
|
{
|
|
char SkipSpaces[6] = {'\t', '\r', ' ', 10, 13, 0};
|
|
char ArgNameDelimiter[12] = {'(', '>', '<', '*', '&', '\t', '\r', ' ', ',', 10, 13, 0};
|
|
|
|
buf.uiReadOffset = uiOpenParenthesisOffset+ 1;
|
|
|
|
|
|
while (buf.uiReadOffset < uiClosingParenthesisOffset)
|
|
{
|
|
if (!buf.SkipCharacters(1, SkipSpaces))
|
|
{
|
|
Error::Log("Error looking for function args");
|
|
int iBreakPointHere = 0; // chiure
|
|
return;
|
|
}
|
|
|
|
unsigned __int32 uiLastOfs = buf.uiReadOffset;
|
|
char CommaOrParenthesis[3] = {')', ',', 0};
|
|
if (buf.FindOneChar(1, CommaOrParenthesis))
|
|
{
|
|
bool bLastArgReached = buf.GetChar() == ')';
|
|
unsigned __int32 uiNextSearch = buf.uiReadOffset + 1;
|
|
buf.uiReadOffset--;
|
|
if (!buf.SkipCharacters(-1, SkipSpaces))
|
|
{
|
|
Error::Log("Error looking for function args");
|
|
int iBreakPointHere = 0; // chiure
|
|
return;
|
|
}
|
|
unsigned __int32 uiEndArg = buf.uiReadOffset;
|
|
|
|
if (!buf.FindOneChar(-1, ArgNameDelimiter))
|
|
{
|
|
Error::Log("Error looking for function args");
|
|
int iBreakPointHere = 0; // chiure
|
|
return;
|
|
}
|
|
|
|
buf.uiReadOffset++;
|
|
|
|
|
|
if (buf.uiReadOffset < uiLastOfs)
|
|
{
|
|
Error::Log("Error looking for function args");
|
|
int iBreakPointHere = 0; // chiure
|
|
return;
|
|
}
|
|
|
|
unsigned __int32 uiTypeNameSize = buf.uiReadOffset - uiLastOfs;
|
|
assert(buf.uiReadOffset >= uiLastOfs);
|
|
if (uiTypeNameSize == 0)
|
|
{
|
|
if (!strncmp(buf.GetAdrs(), "...", 3)) // special case for va_lists handling: no need to look for arg name or arg trype
|
|
{
|
|
return;
|
|
}
|
|
if (!strncmp(buf.GetAdrs(), "void", 4)) // special case for "void" arg type
|
|
{
|
|
return;
|
|
}
|
|
if (bIsCPPInstruction(func.m_szName)) return;
|
|
if (bIsLyNMacro(func.m_szName)) return;
|
|
|
|
Error::Log("Error looking for function args");
|
|
int iBreakPointHere = 0; // chiure
|
|
return;
|
|
}
|
|
FunctionArg& arg = func.AddArg();
|
|
arg.m_szArgType = (char*)MemoryHandler::Alloc(uiTypeNameSize + 1);
|
|
memset(arg.m_szArgType, 0, uiTypeNameSize + 1);
|
|
memcpy(arg.m_szArgType, &buf.pAdrs[uiLastOfs], uiTypeNameSize);
|
|
FullArgCleanup(arg.m_szArgType);
|
|
|
|
uiEndArg++;
|
|
unsigned __int32 uiArgNameSize = uiEndArg - buf.uiReadOffset;
|
|
assert(uiEndArg >= buf.uiReadOffset);
|
|
if (uiArgNameSize == 0)
|
|
{
|
|
Error::Log("Error looking for function args");
|
|
int iBreakPointHere = 0; // chiure
|
|
return;
|
|
}
|
|
arg.m_szArgName = (char*)MemoryHandler::Alloc(uiArgNameSize + 1);
|
|
memset(arg.m_szArgName, 0, uiArgNameSize + 1);
|
|
memcpy(arg.m_szArgName, &buf.pAdrs[buf.uiReadOffset], uiArgNameSize);
|
|
|
|
if (bLastArgReached)
|
|
{
|
|
break;
|
|
}
|
|
|
|
buf.uiReadOffset = uiNextSearch;
|
|
}
|
|
}
|
|
|
|
if (func.m_szClassName && func.m_szName)
|
|
{
|
|
char funcFullName[256];
|
|
sprintf_s(funcFullName, 255, "%s::%s", func.m_szClassName, func.m_szName);
|
|
WriteHTML::AddFunction(funcFullName);
|
|
FuncArgs2HTML(func.m_szClassName, func.m_szName);
|
|
WriteHTML::EndFunction();
|
|
}
|
|
}
|
|
|
|
void ParseCPP::RetrieveArgsTypes(TextBuffer &buf, Function& func, unsigned __int32 uiOpenParenthesisOffset, unsigned __int32 uiClosingParenthesisOffset)
|
|
{
|
|
char SkipSpaces[6] = {'\t', '\r', ' ', 10, 13, 0};
|
|
char ArgNameDelimiter[12] = {'(', '>', '<', '*', '&', '\t', '\r', ' ', ',', 10, 13, 0};
|
|
char BetweenArgsDelimiter[3] = {'(', ',', 0};
|
|
|
|
buf.uiReadOffset = uiOpenParenthesisOffset+ 1;
|
|
|
|
|
|
while (buf.uiReadOffset < uiClosingParenthesisOffset)
|
|
{
|
|
if (!buf.SkipCharacters(1, SkipSpaces))
|
|
{
|
|
Error::Log("Error looking for function args");
|
|
int iBreakPointHere = 0; // chiure
|
|
return;
|
|
}
|
|
|
|
unsigned __int32 uiLastOfs = buf.uiReadOffset;
|
|
char CommaOrParenthesis[3] = {')', ',', 0};
|
|
if (buf.FindOneChar(1, CommaOrParenthesis))
|
|
{
|
|
bool bLastArgReached = buf.GetChar() == ')';
|
|
unsigned __int32 uiNextSearch = buf.uiReadOffset + 1;
|
|
buf.uiReadOffset--;
|
|
if (!buf.SkipCharacters(-1, SkipSpaces))
|
|
{
|
|
Error::Log("Error looking for function args");
|
|
int iBreakPointHere = 0; // chiure
|
|
return;
|
|
}
|
|
unsigned __int32 uiEndArg = buf.uiReadOffset; // last character before coma or parenthesis
|
|
|
|
if (!buf.FindOneChar(-1, BetweenArgsDelimiter))
|
|
{
|
|
Error::Log("Error looking for function args");
|
|
int iBreakPointHere = 0; // chiure
|
|
return;
|
|
}
|
|
|
|
buf.uiReadOffset++;
|
|
|
|
|
|
buf.SkipCharacters(1, SkipSpaces);
|
|
|
|
if (buf.uiReadOffset < uiLastOfs)
|
|
{
|
|
Error::Log("Error looking for function args");
|
|
int iBreakPointHere = 0; // chiure
|
|
return;
|
|
}
|
|
|
|
unsigned __int32 uiStartArg = buf.uiReadOffset; // first character after coma or parenthesis
|
|
int iCandSize = uiEndArg - uiStartArg;
|
|
if (iCandSize >= 0)
|
|
{
|
|
char* szTypeCandidate = (char*)MemoryHandler::Alloc(iCandSize + 2);
|
|
memset(szTypeCandidate, 0, iCandSize + 2);
|
|
memcpy(szTypeCandidate, &buf.pAdrs[uiStartArg], iCandSize + 1);
|
|
FullArgCleanup(szTypeCandidate);
|
|
if (*szTypeCandidate != 0)
|
|
{
|
|
FunctionArg& arg = func.AddArg();
|
|
arg.m_szArgType = szTypeCandidate;
|
|
}
|
|
}
|
|
|
|
buf.uiReadOffset = uiNextSearch;
|
|
}
|
|
}
|
|
}
|
|
|
|
void ParseCPP::RetrieveNames(TextBuffer &buf, unsigned __int32 uiClosingParenthesisOffset)
|
|
{
|
|
char SkipSpaces[6] = {'\t', '\r', ' ', 10, 13, 0};
|
|
char Delimiters[10] = {'\t', '\r', ' ', 10, 13, '*', '&', '>', ':', 0};
|
|
bool bLookForClassName = FALSE;
|
|
unsigned __int32 uiOpenParenthesisOffset = buf.uiReadOffset--;
|
|
|
|
if (buf.SkipCharacters(-1, SkipSpaces))
|
|
{
|
|
OffsetInTextBuffer uiStartOfWord(buf.uiReadOffset, &buf);
|
|
if (buf.FindOneChar(-1, Delimiters))
|
|
{
|
|
if ((buf.pAdrs[buf.uiReadOffset] == ':') && (buf.pAdrs[buf.uiReadOffset-1] == ':'))
|
|
{
|
|
bLookForClassName = TRUE;
|
|
}
|
|
OffsetInTextBuffer uiPotentialClassName(buf.uiReadOffset-2, &buf);
|
|
OffsetInTextBuffer uiEndOfWord(buf.uiReadOffset+1, &buf);
|
|
unsigned __int32 iSize = uiStartOfWord.value - uiEndOfWord.value + 2;
|
|
if (iSize == 0)
|
|
{
|
|
Error::Log("Null length function name");
|
|
int iBreakPointHere = 0; // chiure
|
|
return;
|
|
}
|
|
Function& func = AddFunction();
|
|
func.m_szName = (char*)MemoryHandler::Alloc(iSize);
|
|
memset(func.m_szName, 0, iSize);
|
|
memcpy(func.m_szName, &buf.pAdrs[uiEndOfWord.value], iSize - 1);
|
|
if (bLookForClassName)
|
|
{
|
|
buf.uiReadOffset = uiPotentialClassName.value;
|
|
if (buf.FindOneChar(-1, Delimiters))
|
|
{
|
|
buf.uiReadOffset++;
|
|
if (uiPotentialClassName.value > buf.uiReadOffset)
|
|
{
|
|
unsigned __int32 uiClassNameSize = uiPotentialClassName.value - buf.uiReadOffset + 1;
|
|
func.m_szClassName = (char*)MemoryHandler::Alloc(uiClassNameSize + 1);
|
|
memset(func.m_szClassName, 0, uiClassNameSize + 1);
|
|
memcpy(func.m_szClassName, buf.GetAdrs(), uiClassNameSize);
|
|
}
|
|
else
|
|
{
|
|
if ((*buf.GetAdrs() == ':') && (*(buf.GetAdrs()+1) == ':'))
|
|
{
|
|
return;
|
|
}
|
|
Error::Log("Bad class name length");
|
|
int iBreakPointHere = 0; // chiure
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
RetrieveArgs(buf, func, uiOpenParenthesisOffset, uiClosingParenthesisOffset);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
bool ParseCPP::bFoundPotentialFunction(TextBuffer &buf, unsigned __int32 _uiMinOffset)
|
|
{
|
|
char SkipSpaces[6] = {'\t', '\r', ' ', 10, 13, 0};
|
|
|
|
if (!buf.FindOneChar(1, ")"))
|
|
{
|
|
return FALSE;
|
|
}
|
|
unsigned __int32 uiClosingParenthesisOffset = buf.uiReadOffset++;
|
|
|
|
if (!buf.SkipCharacters(1, SkipSpaces))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (buf.GetChar() != '{')
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
unsigned __int32 uiOpenBracketOffset = buf.uiReadOffset;
|
|
buf.uiReadOffset = uiClosingParenthesisOffset;
|
|
|
|
char* pDelimiter = buf.FindCorrespondingDelimiter(-1, ')', '(');
|
|
if ((!pDelimiter) ||(buf.uiReadOffset <= _uiMinOffset))
|
|
{
|
|
Error::Log("no matching opening parenthesis found");
|
|
int iBreakPointHere = 0;
|
|
buf.uiReadOffset = uiClosingParenthesisOffset + 1;
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
RetrieveNames(buf, uiClosingParenthesisOffset);
|
|
buf.uiReadOffset = uiOpenBracketOffset;
|
|
if (!buf.FindCorrespondingDelimiter(1, '{', '}'))
|
|
{
|
|
Error::Log("no matching bracket found");
|
|
int iBreakPointHere = 0;
|
|
return TRUE;
|
|
}
|
|
buf.uiReadOffset++;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void ParseCPP::ScanFile(const char* _szFileName)
|
|
{
|
|
//_szFileName = "c:\\dbg.txt";
|
|
WriteHTML::SetTargetFile(0);
|
|
WriteHTML::AddFile(_szFileName);
|
|
printf("ParseCPP Scanning file %s...\n", _szFileName);
|
|
TextBuffer buf(_szFileName);
|
|
buf.CleanupCPPComments();
|
|
|
|
char SkipSpaces[6] = {'\t', '\r', ' ', 10, 13, 0};
|
|
|
|
while(bFoundPotentialFunction(buf, buf.uiReadOffset));
|
|
}
|
|
|
|
void ParseCPP::PrintAll()
|
|
{
|
|
Function* pf = m_pFunctions;
|
|
while (pf)
|
|
{
|
|
printf("\n\n********** function found **********\n");
|
|
if (pf->m_szClassName)
|
|
{
|
|
printf("\t%s::%s\n", pf->m_szClassName, pf->m_szName);
|
|
}
|
|
else
|
|
{
|
|
printf("\t%s\n", pf->m_szName);
|
|
}
|
|
FunctionArg* pArg = pf->m_pArgs;
|
|
while (pArg)
|
|
{
|
|
printf("\t\tArg type: %s Arg Name: %s\n", pArg->m_szArgType, pArg->m_szArgName);
|
|
pArg = pArg->m_pNext;
|
|
}
|
|
pf = pf->m_pNext;
|
|
}
|
|
}
|
|
|
|
bool ParseCPP::bFunctionExists(const char* _szClass, const char* _szFunc)
|
|
{
|
|
Function* pf = m_pFunctions;
|
|
while (pf)
|
|
{
|
|
if (!strcmp(pf->m_szName, _szFunc))
|
|
{
|
|
if (pf->m_szClassName)
|
|
{
|
|
if (!strcmp(pf->m_szClassName, _szClass))
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
int iBreakPointHere = 0; // same function name found, but not in same class. it that intended?
|
|
}
|
|
pf = pf->m_pNext;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
const char* ParseCPP::szGetArgName(const char* _szClass, const char* _szFunc, __int32 _argIndex)
|
|
{
|
|
Function* pf = m_pFunctions;
|
|
while (pf)
|
|
{
|
|
if (!strcmp(pf->m_szName, _szFunc))
|
|
{
|
|
if (pf->m_szClassName)
|
|
{
|
|
if (!strcmp(pf->m_szClassName, _szClass))
|
|
{
|
|
FunctionArg* pArg = pf->m_pArgs;
|
|
__int32 uiArgIndex = 0;
|
|
while (pArg)
|
|
{
|
|
if (uiArgIndex == _argIndex)
|
|
{
|
|
return pArg->m_szArgName;
|
|
}
|
|
pArg = pArg->m_pNext;
|
|
uiArgIndex++;
|
|
}
|
|
int iBreakPointHere = 0; // arg index does not exist
|
|
}
|
|
}
|
|
int iBreakPointHere = 0; // same function name found, but not in same class. it that intended?
|
|
}
|
|
pf = pf->m_pNext;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
void ParseCPP::FuncArgs2HTML(const char* _szClass, const char* _szFunc)
|
|
{
|
|
Function* pf = m_pFunctions;
|
|
while (pf)
|
|
{
|
|
if (!strcmp(pf->m_szName, _szFunc))
|
|
{
|
|
if (pf->m_szClassName && _szClass)
|
|
{
|
|
if (!strcmp(pf->m_szClassName, _szClass))
|
|
{
|
|
FunctionArg* pArg = pf->m_pArgs;
|
|
while (pArg)
|
|
{
|
|
if (pArg->m_szArgType && pArg->m_szArgName)
|
|
{
|
|
char argdata[512];
|
|
strcpy_s(argdata, 512, pArg->m_szArgType);
|
|
strcat_s(argdata, 512, " ");
|
|
strcat_s(argdata, 512, pArg->m_szArgName);
|
|
WriteHTML::AddFunctionArg(argdata);
|
|
}
|
|
pArg = pArg->m_pNext;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
pf = pf->m_pNext;
|
|
}
|
|
}
|
|
|
|
|
|
static int DBG_AreFunctionsIdenticalIterCount = 0;
|
|
bool ParseCPP::AreFunctionsIdentical(Function& f1, Function& f2)
|
|
{
|
|
if (!strcmp(f1.m_szName, "Shadow_CopyBranches"))
|
|
{
|
|
int bp=0;
|
|
}
|
|
FunctionArg* pArg1 = f1.m_pArgs; // origin : Scanned H
|
|
FunctionArg* pArg2 = f2.m_pArgs; // origin : Scanned CPP
|
|
|
|
DBG_AreFunctionsIdenticalIterCount++;
|
|
if (DBG_AreFunctionsIdenticalIterCount == 251)
|
|
{
|
|
int aa=0;
|
|
}
|
|
while (pArg1)
|
|
{
|
|
if (!pArg2)
|
|
{
|
|
return FALSE; // different arg count
|
|
}
|
|
|
|
if ((pArg1->m_szArgType) && (pArg2->m_szArgType))
|
|
{
|
|
FullArgCleanup(pArg1->m_szArgType);
|
|
FullArgCleanup(pArg2->m_szArgType);
|
|
if (strcmp(pArg1->m_szArgType, pArg2->m_szArgType))
|
|
{
|
|
return FALSE; // different arg type
|
|
}
|
|
}
|
|
pArg1 = pArg1->m_pNext;
|
|
pArg2 = pArg2->m_pNext;
|
|
}
|
|
if (pArg2)
|
|
{
|
|
return FALSE; // different arg count
|
|
}
|
|
return TRUE; // identical
|
|
}
|
|
|
|
static int GetClosestFunctionIterCount = 0;
|
|
Function* ParseCPP::GetClosestFunction(const char* _szClassName, const char* _szFuncName, TextBuffer &buf, unsigned __int32 uiOpenParenthesisOffset, unsigned __int32 uiClosingParenthesisOffset)
|
|
{
|
|
GetClosestFunctionIterCount++;
|
|
if (GetClosestFunctionIterCount == 170)
|
|
{
|
|
int aa = 0;
|
|
}
|
|
Function func;
|
|
func.m_szClassName = (char*)MemoryHandler::Alloc(strlen(_szClassName) + 1);
|
|
strcpy(func.m_szClassName, _szClassName);
|
|
func.m_szName = (char*)MemoryHandler::Alloc(strlen(_szFuncName) + 1);
|
|
strcpy(func.m_szName, _szFuncName);
|
|
|
|
RetrieveArgsTypes(buf, func, uiOpenParenthesisOffset, uiClosingParenthesisOffset);
|
|
|
|
Function* pf = m_pFunctions;
|
|
Function* pBest = NULL;
|
|
Function* pNear = NULL; // for debug only
|
|
while (pf)
|
|
{
|
|
if ((pf->m_szClassName) && (!strcmp(_szClassName, pf->m_szClassName)))
|
|
{
|
|
if ((pf->m_szName) && (!strcmp(_szFuncName, pf->m_szName)))
|
|
{
|
|
if (!pNear) pNear = pf;
|
|
if (AreFunctionsIdentical(func, *pf))
|
|
{
|
|
assert(pf->iGetArgCount() == func.iGetArgCount());
|
|
if (pBest != NULL)
|
|
{
|
|
Error::Log("Several functions fit in CPP for function %s\n", pf->m_szName);
|
|
int iBreakPoint = 0; // several functionsthat fit!
|
|
}
|
|
pBest = pf;
|
|
}
|
|
}
|
|
}
|
|
pf = pf->m_pNext;
|
|
}
|
|
/* if (!pBest)
|
|
{
|
|
assert(!pNear); // oOps, no function found
|
|
}*/
|
|
return pBest;
|
|
}
|
|
#endif
|