#include #include #include #include #include #include #include #include #include "RegEx.h" using namespace std; typedef vector VECSTRING; int main(int argc, char* argv[]) { int total = 0, hit = 0, miss = 0, stacks = 0, i; vector re; vector::iterator at; set fileList; map > stacked; set missList; DIR* dir; struct timeval start = {}, end = {}; // Define our REs // //re.push_back(CRegEx("(.*?)([ ._-]done[ ._-]?0?[1-3])()(\\.[^.]+)$")); re.push_back(CRegEx("(.*?)([ ._-]?(?:cd|p(?:ar)t)[ ._-]?0?[1-3])(.*?)(\\.[^.]+)$")); //re.push_back(CRegEx("(.*?)([ ._-]?p(?:ar)t[ ._-]?0?[1-3])(.*?)(\\.[^.]+)$")); //re.push_back(CRegEx("(.*?)([ ._-]?[a-c])()(\\.[^.]+)$")); re.push_back(CRegEx("(.*?)([ ._-]?[a-c])([ ._-]?.*?)(\\.[^.]+)$")); //re.push_back(CRegEx("(.*?)([ ._-]?[1-3])()(\\.[^.]+)$")); // re.push_back(CRegEx(".*([1-3])[.-]")); // Compile REs for (at = re.begin(); at != re.end(); at++) { at->SetOptions(PCRE_CASELESS); at->Compile(); } // Load + sort filelist if (NULL != (dir = opendir("."))) { struct dirent* file; while (NULL != (file = readdir(dir))) if (file->d_type & DT_REG) fileList.insert(file->d_name); closedir(dir); } gettimeofday(&start, NULL); set::iterator file1 = fileList.begin(); // The magic... while (file1 != fileList.end()) { string stackName; vector filesInStack; vector::iterator expr = re.begin(); size_t offset = 0; // cout << "file1: " << *file1 << endl; while (expr != re.end()) { // cout << "expr: " << expr->GetPattern() << endl; if (expr->Match(*file1, offset) && expr->GetSubstringCount() == 4) { string Title1 = expr->GetSubstring(0), Volume1 = expr->GetSubstring(1), Ignore1 = expr->GetSubstring(2), Extension1 = expr->GetSubstring(3); if (offset) { int subStart = expr->GetSubstringStart(1); // cout << "offset1: " << offset << endl; // cout << "subStringStart1: " << subStart << endl; Title1 = file1->substr(0,subStart); // cout << "Reconstructed Title1: " << Title1 << endl; } // else // cout << "Title1: " << Title1 << endl; // cout << "Volume1: " << Volume1 << endl; // cout << "Ignore1: " << Ignore1 << endl; // cout << "Extension1: " << Extension1 << endl; set::iterator file2 = file1; file2++; while (file2 != fileList.end()) { // cout << "file2: " << *file2 << endl; if (expr->Match(*file2, offset) && expr->GetSubstringCount() == 4) { string Title2 = expr->GetSubstring(0), Volume2 = expr->GetSubstring(1), Ignore2 = expr->GetSubstring(2), Extension2 = expr->GetSubstring(3); if (offset) { int subStart = expr->GetSubstringStart(1); // cout << "offset2: " << offset << endl; // cout << "subStringStart2: " << subStart << endl; Title2 = file2->substr(0, subStart); // cout << "Reconstructed Title2: " << Title2 << endl; } // else // cout << "Title2: " << Title2 << endl; // cout << "Volume2: " << Volume2 << endl; // cout << "Ignore2: " << Ignore2 << endl; // cout << "Extension2: " << Extension2 << endl; if (Title1 == Title2) { if (Volume1 != Volume2) { if (Ignore1 == Ignore2 && Extension1 == Extension2) { // cout << "stack!\n" << endl; if (filesInStack.size() == 0) { stackName = Title1+Extension1; filesInStack.push_back(*file1); } filesInStack.push_back(*file2); file1++; } else // Eh...sequel? { // get out to the mainloop somehow... expr = re.end(); break; } } else if (Ignore1 != Ignore2) // Early match try again with offset { offset = expr->GetSubstringStart(2); break; } else // sequel, bail { expr = re.end(); break; } } else // On to next file { expr = re.end(); break; } } else // No match { expr++; break; } file2++; } if (file2 == fileList.end()) expr = re.end(); } else // No match { offset = 0; expr++; } } if (filesInStack.size() > 1) // we have a stack stacked.insert(make_pair(stackName, filesInStack)); else stacked.insert(make_pair(*file1, vector())); file1++; } gettimeofday(&end, NULL); // Print our results map >::iterator it = stacked.begin(); while (it != stacked.end()) { cout << it->first << "\n\t\t"; if (it->second.size()) { cout << "( "; vector::iterator it2 = it->second.begin(); while (it2 != it->second.end()) { hit++; cout << *it2++ << ", "; } cout << ")\n"; } else cout << "( FAIL )\n"; it++; } // Fun stats total = fileList.size(); miss = total-hit; cout << "----------------------------------------------\n" "Stats:\n\ntotal: " << fileList.size() << " hit: " << hit << " (" << hit/(float)total*100 << "%)" << " miss: " << miss << " (" << miss/(float)total*100 << "%)" << " stacked: " << stacked.size() << endl; cout << "time: " << (float)(end.tv_sec - start.tv_sec) + ((end.tv_usec - start.tv_usec) / 1000000.f) << endl; cout << "Expressions:\n"; for (at = re.begin(); at != re.end(); at++) cout << "\t" << at->GetPattern() << endl; return 0; }