bool save(ColorPalette& palette, const QString& suggested_filename = QString()) { // Attempt to save with the existing file names if ( !suggested_filename.isEmpty() && attemptSave(palette, suggested_filename) ) return true; if ( attemptSave(palette, palette.fileName()) ) return true; // Set up the save directory QDir save_dir(save_path); if ( !save_dir.exists() && !QDir().mkdir(save_path) ) return false; // Attempt to save as (Name).gpl QString filename = palette.name()+".gpl"; if ( !save_dir.exists(filename) && attemptSave(palette, save_dir.absoluteFilePath(filename)) ) return true; // Get all of the files matching the pattern *.gpl save_dir.setNameFilters(QStringList() << "*.gpl"); save_dir.setFilter(QDir::Files); QStringList existing_files = save_dir.entryList(); // For all the files that match (Name)(Number).gpl, find the maximum (Number) QRegularExpression name_regex(QRegularExpression::escape(palette.name())+"([0-9]+)\\.gpl"); int max = 0; for ( const auto& existing_file : existing_files ) { QRegularExpressionMatch match = name_regex.match(existing_file); if ( match.hasMatch() ) { int num = match.captured(1).toInt(); if ( num > max ) max = num; } } return attemptSave(palette, save_dir.absoluteFilePath(QString("%1%2.gpl").arg(palette.name()).arg(max+1)) ); }
results_t parse_tree(std::istream* in){ auto trim = [](std::string str){ str.erase(0,str.find_first_not_of(' ')); str.erase(str.find_last_not_of(' ')+1); return str; }; if(in==nullptr) throw std::invalid_argument("Input file cannot be null pointer."); if(!in->good()) throw std::runtime_error("Input file cannot be read from."); results_t results; std::queue<std::pair<std::string,std::string>> players; std::string line; std::regex name_regex("(\\d*\\.?\\s*)?([A-Za-z \\-\\.]+)\\s*"); std::regex score_regex("(\\d)\\s*[\\-\\/]\\s*(\\d)\\s*|ret\\.?"); std::pair<std::string,std::string> opponents; bool first_opponent_set=false; bool burn_in = true; while(getline(*in,line)){ std::smatch m; if(std::regex_match(line,m,name_regex)){ // if line is a name std::string name = trim(m[2].str()); if(players.empty()){ // add to list of names if(first_opponent_set){ opponents.second = name; players.push(opponents); } else{ opponents.first = name; } first_opponent_set = !first_opponent_set; continue; } auto names = players.front(); if(!(match_name(name, names.first) || match_name(name, names.second))){ // if name is not the expected name if(burn_in){ // and we don't have full list of names yet. // add to list of names if(first_opponent_set){ opponents.second = name; players.push(opponents); } else{ opponents.first = name; } first_opponent_set = !first_opponent_set; } else{ throw std::runtime_error("Unexpected name '" + name+ "'." + "Expected '"+players.front().first+"'" + " OR '"+players.front().second+"'."); } } else{ // we have the expected name // ensure names.first is the winner if(!match_name(name,names.first)) swap(names.first,names.second); // Move forward in the list of expected players players.pop(); burn_in = false; // competitors must be known now std::string score_line; std::smatch sm; getline(*in,score_line); // Extract score from matches int score1=0,score2=0; while(std::regex_search(score_line,sm,score_regex)){ if(stoi(sm[1].str())>stoi(sm[2].str())){ score1++; } else{ score2++; } score_line=score_line.substr(sm[0].str().length()); } bool walkover=score_line=="wo"; if(score1+score2<1 && !walkover){ throw std::runtime_error("Expected score line. Got '"+score_line+"'"); } // Add outcome to list of results results.push_back(outcome_t(names.first,names.second,score1,score2,0)); // Add winner to competitors if(first_opponent_set){ opponents.second = names.first; players.push(opponents); } else{ opponents.first = names.first; } first_opponent_set = !first_opponent_set; } } else{ throw std::runtime_error("Expected name, got '"+line+"'"); } } return results; }