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))
        );
    }
Example #2
0
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;
}