#include "pptable.h"
#include
#include
bool IsWordChar(const wxString &s, int strSize)
{
if(strSize) {
return s.find_first_of(wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_")) != wxString::npos;
} else {
return s.find_first_of(wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_")) != wxString::npos;
}
}
bool IsWordCharA(char c, int strSize)
{
if(strSize) {
return ((c >= 97 && c <= 122) ||// a-z
(c >= 65 && c <= 90) ||// A-Z
(c >= 48 && c <= 57) ||// 0-9
(c == '_'));
} else {
return ((c >= 97 && c <= 122) ||// a-z
(c >= 65 && c <= 90) ||// A-Z
(c == '_'));
}
}
std::string ReplaceWordA(const std::string &str, const std::string &word, const std::string &replaceWith)
{
char currChar;
char nextChar;
std::string currentWord;
std::string output;
output.reserve( str.length() * 2 );
for(size_t i=0; i i + 1 ) {
nextChar = str[i+1];
} else {
// we are at the end of buffer
nextChar = '\0';
}
currChar = str[i];
if(!IsWordCharA( currChar, currentWord.length() )) {
output += str[i];
currentWord.clear();
} else {
currentWord += currChar;
if(IsWordCharA(nextChar, currentWord.length())) {
// do nothing
} else if( !IsWordCharA(nextChar, currentWord.length()) && currentWord == word ) {
output += replaceWith;
currentWord.clear();
} else {
output += currentWord;
currentWord.clear();
}
}
}
return output;
}
// Helper string find metho
wxString ReplaceWord(const wxString &str, const wxString &word, const wxString &replaceWith)
{
wxString currChar;
wxString nextChar;
wxString currentWord;
wxString output;
for(size_t i=0; i i + 1 ) {
nextChar = str[i+1];
} else {
// we are at the end of buffer
nextChar = wxT('\0');
}
currChar = str[i];
if(!IsWordChar( currChar, currentWord.Length() )) {
output << str[i];
currentWord.Clear();
} else {
currentWord << currChar;
if(IsWordChar(nextChar, currentWord.Length())) {
// do nothing
} else if( !IsWordChar(nextChar, currentWord.Length()) && currentWord == word ) {
output << replaceWith;
currentWord.Clear();
} else {
output << currentWord;
currentWord.Clear();
}
}
}
return output;
}
wxArrayString TokenizeWords(const wxString &str)
{
wxString currChar;
wxString nextChar;
wxString currentWord;
wxArrayString outputArr;
wxString::const_iterator iter = str.begin();
for(; iter != str.end(); iter++) {
// Look ahead
if( (iter + 1) != str.end() ) {
nextChar = *(iter+1);
} else {
// we are at the end of buffer
nextChar = wxT('\0');
}
currChar = *iter;
if(!IsWordChar( currChar, currentWord.Length() )) {
currentWord.Clear();
} else {
currentWord << currChar;
if(IsWordChar(nextChar, currentWord.Length())) {
// do nothing
} else {
outputArr.Add(currentWord);
currentWord.Clear();
}
}
}
return outputArr;
}
static PPTable* ms_instance = NULL;
void PPToken::processArgs(const wxString &argsList)
{
args = wxStringTokenize(argsList, wxT(","), wxTOKEN_STRTOK);
// replace all occurances of 'arg' with %1, %2 etc
for(size_t i=0; i alreadyReplacedMacros;
// perform the squeeze 5 times max
for(size_t count=0; count < 5; count++) {
bool modified(false);
// get list of possible macros in the replacement
wxArrayString tmpWords = TokenizeWords(replacement);
wxArrayString words;
// make sure that a word is not been replaced more than once
// this will avoid recursion
// an example (taken from qglobal.h of the Qt library):
//
// #define qDebug QT_NO_QDEBUG_MACRO
// #define QT_NO_QDEBUG_MACRO if(1); else qDebug
//
for(size_t i=0; iToken(words.Item(i));
if(tok.flags & IsValid) {
if(tok.flags & IsFunctionLike) {
int where = replacement.Find(words.Item(i));
if(where != wxNOT_FOUND) {
wxString initList;
wxArrayString initListArr;
if(readInitList( replacement, where + words.Item(i).Length(), initList, initListArr )) {
tok.expandOnce(initListArr);
replacement.Remove(where, words.Item(i).Length() + initList.Length());
tok.replacement.Replace(wxT("##"), wxT(""));
replacement.insert(where, tok.replacement);
modified = true;
}
}
} else {
if(replacement.Replace(words.Item(i), tok.replacement)) {
modified = true;
}
}
}
}
if(!modified)
break;
}
replacement.Replace(wxT("##"), wxT(""));
}
bool PPToken::readInitList(const std::string& in, size_t from, std::string& initList, std::vector& initListArr)
{
if(in.length() < from) {
return false;
}
std::string tmpString = in.substr(from);
size_t start = tmpString.find('(');
if(start == std::string::npos ) {
return false;
}
// skip the open brace
tmpString = tmpString.substr(start+1);
for(size_t i=0; i::iterator iter = m_table.find(name);
if(iter == m_table.end()) {
return PPToken();
}
return iter->second;
}
void PPTable::Add(const PPToken& token)
{
if(token.name.IsEmpty())
return;
wxString name = token.name;
name.Trim().Trim(false);
std::map::iterator iter = m_table.find(name);
if(iter == m_table.end())
m_table[name] = token;
else {
// if the new token's replacement is empty and the current one is NOT empty,
// replace the two (we prefer empty replacements)
if(iter->second.flags & PPToken::IsOverridable && !iter->second.replacement.IsEmpty() && token.replacement.IsEmpty()) {
m_table[name] = token;
}
}
}
void PPTable::AddUsed(const wxString& name)
{
if(name.IsEmpty()) {
return;
}
m_namesUsed.insert(name);
}
void PPTable::Print(wxFFile &fp)
{
std::map::iterator iter = m_table.begin();
for(; iter != m_table.end(); iter++) {
iter->second.print(fp);
}
}
bool PPTable::Contains(const wxString& name)
{
std::map::iterator iter = m_table.find(name);
return iter != m_table.end();
}
wxString PPTable::Export()
{
wxString table;
std::map::iterator iter = m_table.begin();
for(; iter != m_table.end(); iter++) {
iter->second.squeeze();
wxString replacement = iter->second.replacement;
replacement.Trim().Trim(false);
// remove extra whitespaces
while(replacement.Replace(wxT(" "), wxT(" "))){}
if(replacement.IsEmpty()) {
table << iter->second.fullname() << wxT("\n");
} else if(iter->second.flags & PPToken::IsFunctionLike) {
table << iter->second.fullname() << wxT("=") << replacement << wxT("\n");
} else {
// macros with replacement but they are not in a form of a function
// we take only macros that thier replacement is not a number
long v(-1);
if(!replacement.ToLong(&v) && !replacement.ToLong(&v, 8) && !replacement.ToLong(&v, 16) && replacement.find(wxT('"')) == wxString::npos && !replacement.StartsWith(wxT("0x"))) {
table << iter->second.fullname() << wxT("=") << replacement << wxT("\n");
}
}
}
return table;
}
void PPTable::Squeeze()
{
std::map::iterator iter = m_table.begin();
for(; iter != m_table.end(); iter++) {
m_table[iter->first].squeeze();
}
}
void PPTable::Clear()
{
m_table.clear();
}
void PPTable::ClearNamesUsed()
{
m_namesUsed.clear();
}
bool CLReplacePattern(const wxString& in, const wxString& pattern, const wxString& replaceWith, wxString &outStr)
{
int where = pattern.Find(wxT("%0"));
if(where != wxNOT_FOUND) {
wxString replacement(replaceWith);
// a patterened expression
wxString searchFor = pattern.BeforeFirst(wxT('('));
where = in.Find(searchFor);
if(where == wxNOT_FOUND) {
return false;
}
wxString initList;
wxArrayString initListArr;
if(PPToken::readInitList(in, searchFor.Length() + where, initList, initListArr) == false)
return false;
outStr = in;
// update the 'replacement' with the actual values ( replace %0..%n)
for(size_t i=0; i initListArr;
if(PPToken::readInitList(in, repl.searchFor.length() + where, initList, initListArr) == false)
return false;
// update the 'replacement' with the actual values ( replace %0..%n)
replacement = repl.replaceWith;
char placeHolder[4];
for(size_t i=0; i