X Tutup
#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
X Tutup