Completely remove string functions from config.cpp.

This commit is contained in:
Guillaume Melquiond 2005-02-20 21:45:22 +00:00
parent caf6d9cf5f
commit 2ab05941b5
32 changed files with 220 additions and 334 deletions

View file

@ -495,7 +495,7 @@ void terrain_builder::add_images_from_config(rule_imagelist& images, const confi
} else if((**img)["position"] == "vertical") {
std::vector<std::string> base = config::split((**img)["base"]);
std::vector<std::string> base = utils::split((**img)["base"]);
int basex = 0, basey = 0;
if(base.size() >= 2) {
@ -546,7 +546,7 @@ void terrain_builder::add_constraints(
void terrain_builder::add_constraint_item(std::vector<std::string> &list, const config& cfg, const std::string &item)
{
if(!cfg[item].empty()) {
std::vector<std::string> item_string = config::split(cfg[item]);
std::vector<std::string> item_string = utils::split(cfg[item]);
for(std::vector<std::string>::const_iterator itor = item_string.begin();
itor != item_string.end(); ++itor) {
@ -575,11 +575,11 @@ void terrain_builder::parse_mapstring(const std::string &mapstring,
int lineno = 0;
int x = 0;
const std::vector<std::string> &lines = config::split(mapstring, '\n', 0);
const std::vector<std::string> &lines = utils::split(mapstring, '\n', 0);
std::vector<std::string>::const_iterator line = lines.begin();
//Strips trailing empty lines
while(line != lines.end() && std::find_if(line->begin(),line->end(),config::notspace) == line->end()) {
while (line != lines.end() && std::find_if(line->begin(), line->end(), utils::notspace) == line->end()) {
line++;
}
//Break if there only are blank lines
@ -604,7 +604,7 @@ void terrain_builder::parse_mapstring(const std::string &mapstring,
while(lpos < line->size()) {
std::string types = line->substr(lpos, 4);
config::strip(types);
utils::strip(types);
//If there are numbers in the types string, consider it
//is an anchor
@ -641,7 +641,7 @@ void terrain_builder::add_rotated_rules(building_ruleset& rules, building_rule&
add_rule(rules, tpl);
} else {
const std::vector<std::string>& rot = config::split(rotations, ',');
const std::vector<std::string>& rot = utils::split(rotations, ',');
for(size_t angle = 0; angle < rot.size(); angle++) {
building_rule rule = rotate_rule(tpl, angle, rot);
@ -688,7 +688,7 @@ void terrain_builder::parse_config(const config &cfg)
loc.y = atoi((**tc)["y"].c_str());
}
if(!(**tc)["loc"].empty()) {
std::vector<std::string> sloc = config::split((**tc)["pos"]);
std::vector<std::string> sloc = utils::split((**tc)["pos"]);
if(sloc.size() == 2) {
loc.x = atoi(sloc[0].c_str());
loc.y = atoi(sloc[1].c_str());

View file

@ -137,7 +137,7 @@ void cave_map_generator::generate_chambers()
size_t min_xpos = 0, min_ypos = 0, max_xpos = width_, max_ypos = height_;
if(xpos != "") {
const std::vector<std::string>& items = config::split(xpos,'-');
const std::vector<std::string>& items = utils::split(xpos, '-');
if(items.empty() == false) {
min_xpos = atoi(items.front().c_str()) - 1;
max_xpos = atoi(items.back().c_str());
@ -145,7 +145,7 @@ void cave_map_generator::generate_chambers()
}
if(ypos != "") {
const std::vector<std::string>& items = config::split(ypos,'-');
const std::vector<std::string>& items = utils::split(ypos, '-');
if(items.empty() == false) {
min_ypos = atoi(items.front().c_str()) - 1;
max_ypos = atoi(items.back().c_str());

View file

@ -27,10 +27,11 @@
#include "game_events.hpp"
#include "gettext.hpp"
#include "log.hpp"
#include "serialization/preprocessor.hpp"
#include "util.hpp"
#include "wassert.hpp"
#include "wesconfig.h"
#include "serialization/preprocessor.hpp"
#include "serialization/string_utils.hpp"
#define ERR_CF lg::err(lg::config)
#define WRN_CF lg::warn(lg::config)
@ -290,7 +291,7 @@ void config::read(const std::string& data,
//we strip it away, since it simply indicates that this value is translatable.
if(value.empty() == false && std::count(value.begin(),value.end(),'_') == 1) {
std::string val = value;
if(strip(val) == "_") {
if (utils::strip(val) == "_") {
value = "";
translatable = true;
}
@ -319,8 +320,8 @@ void config::read(const std::string& data,
//see if this is a CSV list=CSV list style assignment (e.g. x,y=5,8)
std::vector<std::string> vars, values;
if(std::count(var.begin(),var.end(),',') > 0) {
vars = config::split(var);
values = config::split(value);
vars = utils::split(var);
values = utils::split(value);
} else {
vars.push_back(var);
values.push_back(value);
@ -352,7 +353,7 @@ void config::read(const std::string& data,
}
if(has_quotes == false) {
strip(value);
utils::strip(value);
}
if(n < vars.size()) {
@ -911,213 +912,13 @@ const config* config::find_child(const std::string& key,
return NULL;
}
std::string config::join(const std::vector<std::string>& v, char c)
{
std::stringstream str;
for(std::vector<std::string>::const_iterator i = v.begin(); i != v.end(); ++i) {
str << *i;
if(i+1 != v.end()) {
str << c;
}
}
return str.str();
}
std::vector<std::string> config::split(const std::string& val, char c, int flags)
{
std::vector<std::string> res;
std::string::const_iterator i1 = val.begin();
std::string::const_iterator i2 = val.begin();
while(i2 != val.end()) {
if(*i2 == c) {
std::string new_val(i1,i2);
if(flags & STRIP_SPACES)
strip(new_val);
if(!(flags & REMOVE_EMPTY) || !new_val.empty())
res.push_back(new_val);
++i2;
if(flags & STRIP_SPACES) {
while(i2 != val.end() && *i2 == ' ')
++i2;
}
i1 = i2;
} else {
++i2;
}
}
std::string new_val(i1,i2);
if(flags & STRIP_SPACES)
strip(new_val);
if(!(flags & REMOVE_EMPTY) || !new_val.empty())
res.push_back(new_val);
return res;
}
//identical to split(), except it does not split when it otherwise
//would if the previous character was identical to the parameter 'quote'.
//i.e. it does not split quoted commas.
//this method was added to make it possible to quote user input,
//particularly so commas in user input will not cause visual problems in menus.
//why not change split()? that would change the methods post condition.
std::vector<std::string> config::quoted_split(const std::string& val, char c, int flags, char quote)
{
std::vector<std::string> res;
std::string::const_iterator i1 = val.begin();
std::string::const_iterator i2 = val.begin();
while(i2 != val.end()) {
if(*i2 == quote) {
// ignore quoted character
++i2;
if(i2 != val.end()) ++i2;
} else if(*i2 == c) {
std::string new_val(i1,i2);
if(flags & STRIP_SPACES)
strip(new_val);
if(!(flags & REMOVE_EMPTY) || !new_val.empty())
res.push_back(new_val);
++i2;
if(flags & STRIP_SPACES) {
while(i2 != val.end() && *i2 == ' ')
++i2;
}
i1 = i2;
} else {
++i2;
}
}
std::string new_val(i1,i2);
if(flags & STRIP_SPACES)
strip(new_val);
if(!(flags & REMOVE_EMPTY) || !new_val.empty())
res.push_back(new_val);
return res;
}
std::pair<int,int> config::parse_range(const std::string& str)
{
const std::string::const_iterator dash = std::find(str.begin(),str.end(),'-');
const std::string a(str.begin(),dash);
const std::string b = dash != str.end() ? std::string(dash+1,str.end()) : a;
std::pair<int,int> res(atoi(a.c_str()),atoi(b.c_str()));
if(res.second < res.first)
res.second = res.first;
return res;
}
//make sure we regard '\r' and '\n' as a space, since Mac, Unix, and DOS
//all consider these differently.
bool config::notspace(char c) { return !portable_isspace(c); }
//prepend all special characters with a backslash
//special characters are:
//#@{}+-,\*
std::string& config::escape(std::string& str)
{
if(!str.empty()) {
std::string::size_type pos = 0;
do {
pos = str.find_first_of("#@{}+-,\\*",pos);
if(pos != std::string::npos) {
str.insert(pos,1,'\\');
pos += 2;
}
} while(pos < str.size() && pos != std::string::npos);
}
return str;
}
// remove all escape characters (backslash)
std::string& config::unescape(std::string& str)
{
std::string::size_type pos = 0;
do {
pos = str.find('\\',pos);
if(pos != std::string::npos) {
str.erase(pos,1);
++pos;
}
} while(pos < str.size() && pos != std::string::npos);
return str;
}
std::string& config::strip(std::string& str)
{
//if all the string contains is whitespace, then the whitespace may
//have meaning, so don't strip it
const std::string::iterator it=std::find_if(str.begin(),str.end(),notspace);
if(it == str.end())
return str;
str.erase(str.begin(),it);
str.erase(std::find_if(str.rbegin(),str.rend(),notspace).base(),str.end());
return str;
}
#if 0
bool config::has_value(const std::string& values, const std::string& val)
{
const std::vector<std::string>& vals = split(values);
return std::count(vals.begin(),vals.end(),val) > 0;
}
namespace {
bool not_id(char c)
{
return !isdigit(c) && !isalpha(c) && c != '.' && c != '_';
}
void do_interpolation(std::string& res, size_t npos, const string_map* m)
{
LOG_CF << "doing interpolation into '" << res << "': " << npos << "\n";
const std::string::iterator i = std::find(res.begin()+npos,res.end(),'$');
if(i == res.end() || i+1 == res.end()) {
return;
}
npos = i - res.begin();
const std::string::iterator end = std::find_if(i+1,res.end(),not_id);
const std::string key(i+1,end);
res.erase(i,end);
if(m != NULL) {
const string_map::const_iterator itor = m->find(key);
if(itor != m->end()) {
res.insert(npos,itor->second);
}
} else {
res.insert(npos,game_events::get_variable_const(key));
}
do_interpolation(res,npos,m);
}
}
std::string config::interpolate_variables_into_string(const std::string& str, const string_map* symbols)
{
std::string res = str;
do_interpolation(res,0,symbols);
//remove any pipes in the string, as they are used simply to seperate variables
res.erase(std::remove(res.begin(),res.end(),'|'),res.end());
return res;
}
#endif
void config::clear()
{

View file

@ -116,26 +116,6 @@ public:
void clear_children(const std::string& key);
void remove_child(const std::string& key, size_t index);
// REMOVE_EMPTY : remove empty elements
// STRIP_SPACES : strips leading and trailing blank spaces
enum { REMOVE_EMPTY = 0x01, STRIP_SPACES = 0x02 };
static std::vector<std::string> split(const std::string& val, char c=',', int flags = REMOVE_EMPTY | STRIP_SPACES);
static std::string join(const std::vector<std::string>& v, char c=',');
static std::vector<std::string> quoted_split(const std::string& val, char c=',',
int flags = REMOVE_EMPTY | STRIP_SPACES, char quote='\\');
static std::pair<int,int> parse_range(const std::string& str);
static bool notspace(char c);
static std::string& escape(std::string& str);
static std::string& unescape(std::string& str);
static std::string& strip(std::string& str);
static bool has_value(const std::string& values, const std::string& val);
//function which will interpolate variables, starting with '$' in the string 'str' with
//the equivalent symbols in the given symbol table. If 'symbols' is NULL, then game event
//variables will be used instead
static std::string interpolate_variables_into_string(const std::string& str, const string_map* symbols=NULL);
void clear();
bool empty() const;

View file

@ -351,7 +351,7 @@ void save_preview_pane::draw_contents()
// escape all special characters in filenames
std::string name = (*info_)[index_].name;
str << font::BOLD_TEXT << config::escape(name) << "\n" << time_buf;
str << font::BOLD_TEXT << utils::escape(name) << "\n" << time_buf;
const std::string& campaign_type = summary["campaign_type"];
if(summary["corrupt"] == "yes") {
@ -696,7 +696,7 @@ void unit_preview_pane::draw_contents()
const std::string text = details.str();
const std::vector<std::string> lines = config::split(text,'\n');
const std::vector<std::string> lines = utils::split(text, '\n');
SDL_Rect cur_area = area;
@ -770,7 +770,7 @@ void campaign_preview_pane::draw_contents()
/* description text */
const std::string& desc_text = font::word_wrap_text((*descriptions_)[index_].first,font::SIZE_SMALL,area.w-2*campaign_preview_border);
const std::vector<std::string> lines = config::split(desc_text,'\n');
const std::vector<std::string> lines = utils::split(desc_text, '\n');
SDL_Rect txt_area = { area.x+campaign_preview_border,area.y,0,0 };
for(std::vector<std::string>::const_iterator line = lines.begin(); line != lines.end(); ++line) {

View file

@ -546,7 +546,7 @@ std::string map_editor::load_map(const std::string filename) {
if (!load_successful) {
const std::string failed_msg = _("Load failed: ");
const std::string show_msg = failed_msg +
config::interpolate_variables_into_string(msg, &symbols);
utils::interpolate_variables_into_string(msg, &symbols);
gui::show_dialog(gui_, NULL, "", show_msg, gui::OK_ONLY);
throw load_map_exception();
}

View file

@ -82,7 +82,7 @@ int main(int argc, char** argv)
if(arg+1 != argc) {
++arg;
const std::string val(argv[arg]);
const std::vector<std::string> res = config::split(val,'x');
const std::vector<std::string> res = utils::split(val, 'x');
if(res.size() == 2) {
const int xres = lexical_cast_default<int>(res.front());
const int yres = lexical_cast_default<int>(res.back());

View file

@ -13,6 +13,7 @@
#include "../map.hpp"
#include "../config.hpp"
#include "../util.hpp"
#include "serialization/string_utils.hpp"
#include "map_manip.hpp"
@ -192,7 +193,7 @@ get_component(const gamemap &map, const gamemap::location &start_loc) {
std::string resize_map(const gamemap &map, const unsigned new_w,
const unsigned new_h, const gamemap::TERRAIN fill_with) {
std::string str_map = map.write();
std::vector<std::string> lines = config::split(str_map, '\n');
std::vector<std::string> lines = utils::split(str_map, '\n');
bool map_changed = false;
const unsigned old_w = (unsigned)map.x();
const unsigned old_h = (unsigned)map.y();
@ -209,7 +210,7 @@ std::string resize_map(const gamemap &map, const unsigned new_w,
map_changed = true;
}
if (map_changed) {
return config::join(lines, '\n');
return utils::join(lines, '\n');
}
else {
return "";
@ -222,7 +223,7 @@ std::string flip_map(const gamemap &map, const FLIP_AXIS axis) {
if (str_map == "") {
return str_map;
}
std::vector<std::string> lines = config::split(str_map, '\n');
std::vector<std::string> lines = utils::split(str_map, '\n');
std::vector<std::string> new_lines;
if (axis == FLIP_Y) {
if (is_even(lines[0].size())) {
@ -249,7 +250,7 @@ std::string flip_map(const gamemap &map, const FLIP_AXIS axis) {
else {
new_lines = lines;
}
return config::join(new_lines, '\n');
return utils::join(new_lines, '\n');
}
bool valid_mapdata(const std::string &data, const config &cfg) {

View file

@ -344,7 +344,7 @@ surface render_text(TTF_Font* font,const std::string& text, const SDL_Color& col
return surface();
// XXX Changed by erl, to not strip when rendering text. Works everywhere?
const std::vector<std::string> lines = config::split(text,'\n', config::REMOVE_EMPTY);
const std::vector<std::string> lines = utils::split(text, '\n', utils::REMOVE_EMPTY);
std::vector<surface> surfaces;
surfaces.reserve(lines.size());
size_t width = 0, height = 0;
@ -565,7 +565,7 @@ SDL_Rect draw_text(display* gui, const SDL_Rect& area, int size,
if(i1 != i2) {
std::string new_string(i1,i2);
config::unescape(new_string);
utils::unescape(new_string);
const SDL_Rect rect = draw_text_line(gui, area, sz, col, new_string, x, y, use_tooltips, text_style);
if(rect.w > res.w) {

View file

@ -392,7 +392,7 @@ game_controller::game_controller(int argc, char** argv, bool use_sound)
if(arg_+1 != argc_) {
++arg_;
const std::string val(argv_[arg_]);
const std::vector<std::string> res = config::split(val,'x');
const std::vector<std::string> res = utils::split(val, 'x');
if(res.size() == 2) {
const int xres = lexical_cast_default<int>(res.front());
const int yres = lexical_cast_default<int>(res.back());
@ -650,7 +650,7 @@ bool game_controller::play_multiplayer_mode()
continue;
}
std::vector<std::string> name_value = config::split(val,'=');
std::vector<std::string> name_value = utils::split(val, '=');
if(name_value.size() > 2) {
std::cerr << "invalid argument '" << val << "'\n";
return false;
@ -679,7 +679,7 @@ bool game_controller::play_multiplayer_mode()
} else if(last_digit && name_head == "--side") {
side_types[side] = value;
} else if(last_digit && name_head == "--parm") {
const std::vector<std::string> name_value = config::split(value,':');
const std::vector<std::string> name_value = utils::split(value, ':');
if(name_value.size() != 2) {
std::cerr << "argument to '" << name << "' must be in the format name:value\n";
return false;
@ -985,9 +985,9 @@ bool game_controller::new_campaign()
state_.scenario = campaign["first_scenario"];
const std::string difficulty_descriptions = campaign["difficulty_descriptions"];
std::vector<std::string> difficulty_options = config::split(difficulty_descriptions,';');
std::vector<std::string> difficulty_options = utils::split(difficulty_descriptions, ';');
const std::vector<std::string> difficulties = config::split(campaign["difficulties"]);
const std::vector<std::string> difficulties = utils::split(campaign["difficulties"]);
if(difficulties.empty() == false) {
if(difficulty_options.size() != difficulties.size()) {
@ -1058,7 +1058,7 @@ void game_controller::download_campaigns()
return;
}
const std::vector<std::string> items = config::split(host,':');
const std::vector<std::string> items = utils::split(host, ':');
host = items.front();
try {

View file

@ -301,7 +301,7 @@ bool event_handler::handle_event_command(const queued_event& event_info, const s
const std::string& type = cfg["type"];
const std::vector<std::string>& types = config::split(type);
const std::vector<std::string>& types = utils::split(type);
for(std::vector<std::string>::const_iterator i = types.begin(); i != types.end(); ++i) {
(*teams)[index].recruits().insert(*i);
preferences::encountered_units().insert(*i);
@ -321,7 +321,7 @@ bool event_handler::handle_event_command(const queued_event& event_info, const s
return rval;
const std::string& type = cfg["type"];
const std::vector<std::string>& types = config::split(type);
const std::vector<std::string>& types = utils::split(type);
for(std::vector<std::string>::const_iterator i = types.begin(); i != types.end(); ++i) {
(*teams)[index].recruits().erase(*i);
@ -338,7 +338,7 @@ bool event_handler::handle_event_command(const queued_event& event_info, const s
if(index >= teams->size())
return rval;
std::vector<std::string> recruit = config::split(cfg["recruit"]);
std::vector<std::string> recruit = utils::split(cfg["recruit"]);
if(recruit.size() == 1 && recruit.back() == "")
recruit.clear();
@ -461,8 +461,8 @@ bool event_handler::handle_event_command(const queued_event& event_info, const s
const game_data::unit_type_map::const_iterator itor = game_data_ptr->unit_types.find(type);
if(itor != game_data_ptr->unit_types.end()) {
unit dummy_unit(&itor->second,0,false,true,gender);
const std::vector<std::string> xvals = config::split(cfg["x"]);
const std::vector<std::string> yvals = config::split(cfg["y"]);
const std::vector<std::string> xvals = utils::split(cfg["x"]);
const std::vector<std::string> yvals = utils::split(cfg["y"]);
std::vector<gamemap::location> path;
gamemap::location src;
gamemap::location dst;
@ -493,19 +493,22 @@ bool event_handler::handle_event_command(const queued_event& event_info, const s
//setting a variable
else if(cmd == "set_variable") {
const std::string& name = config::interpolate_variables_into_string(cfg.get_attribute("name"));
const std::string& name = utils::interpolate_variables_into_string(
cfg.get_attribute("name"));
std::string& var = game_events::get_variable(name);
const std::string& value = cfg["value"];
if(value.empty() == false) {
var = value;
}
const std::string& format = config::interpolate_variables_into_string(cfg.get_attribute("format"));
const std::string& format = utils::interpolate_variables_into_string(
cfg.get_attribute("format"));
if(format.empty() == false) {
var = format;
}
const std::string& to_variable = config::interpolate_variables_into_string(cfg.get_attribute("to_variable"));
const std::string& to_variable = utils::interpolate_variables_into_string(
cfg.get_attribute("to_variable"));
if(to_variable.empty() == false) {
var = game_events::get_variable(to_variable);
}
@ -628,9 +631,9 @@ bool event_handler::handle_event_command(const queued_event& event_info, const s
else if(cmd == "role") {
//get a list of the types this unit can be
std::vector<std::string> types = config::split(cfg["type"]);
std::vector<std::string> types = utils::split(cfg["type"]);
std::vector<std::string> sides = config::split(cfg["side"]);
std::vector<std::string> sides = utils::split(cfg["side"]);
//iterate over all the types, and for each type, try to find
//a unit that matches
@ -977,7 +980,7 @@ bool event_handler::handle_event_command(const queued_event& event_info, const s
//if we're not replaying, or if we are replaying and there is no choice
//to be made, show the dialog.
if(get_replay_source().at_end() || options.empty()) {
const std::string msg = config::interpolate_variables_into_string(cfg["message"]);
const std::string msg = utils::interpolate_variables_into_string(cfg["message"]);
option_chosen = gui::show_dialog(*screen,surface,caption,msg,
options.empty() ? gui::MESSAGE : gui::OK_ONLY,
options.empty() ? NULL : &options);
@ -1127,7 +1130,8 @@ bool event_handler::handle_event_command(const queued_event& event_info, const s
}
else if(cmd == "unstore_unit") {
const config& var = game_events::get_variable_cfg(config::interpolate_variables_into_string(cfg.get_attribute("variable")));
const config& var = game_events::get_variable_cfg(
utils::interpolate_variables_into_string(cfg.get_attribute("variable")));
try {
const unit u(*game_data_ptr,var);
@ -1282,8 +1286,8 @@ bool filter_loc_impl(const gamemap::location& loc, const std::string& xloc,
const std::string& yloc)
{
if(std::find(xloc.begin(),xloc.end(),',') != xloc.end()) {
std::vector<std::string> xlocs = config::split(xloc);
std::vector<std::string> ylocs = config::split(yloc);
std::vector<std::string> xlocs = utils::split(xloc);
std::vector<std::string> ylocs = utils::split(yloc);
const int size = xlocs.size() < ylocs.size()?xlocs.size():ylocs.size();
for(int i = 0; i != size; ++i) {
@ -1540,7 +1544,7 @@ manager::manager(config& cfg, display& gui_, gamemap& map_,
used_items.clear();
const std::string& used = cfg["used_items"];
if(!used.empty()) {
const std::vector<std::string>& v = config::split(used);
const std::vector<std::string>& v = utils::split(used);
for(std::vector<std::string>::const_iterator i = v.begin(); i != v.end(); ++i) {
used_items.insert(*i);
}

View file

@ -208,7 +208,7 @@ player_info read_player(const game_data& data, const config* cfg)
const std::string& can_recruit_str = (*cfg)["can_recruit"];
if(can_recruit_str != "") {
const std::vector<std::string> can_recruit = config::split(can_recruit_str);
const std::vector<std::string> can_recruit = utils::split(can_recruit_str);
std::copy(can_recruit.begin(),can_recruit.end(),std::inserter(res.can_recruit,res.can_recruit.end()));
}

View file

@ -1,6 +1,7 @@
#include "global.hpp"
#include "gettext.hpp"
#include "serialization/string_utils.hpp"
#include <cstring>
@ -38,7 +39,6 @@ const char* dsgettext (const char * domainname, const char *msgid)
std::string vgettext (const char *msgid, const string_map& symbols)
{
const std::string orig(gettext(msgid));
const std::string msg = config::interpolate_variables_into_string(orig,
&symbols);
const std::string msg = utils::interpolate_variables_into_string(orig, &symbols);
return msg;
}

View file

@ -735,7 +735,7 @@ bool section_is_referenced(const std::string &section_id, const config &cfg) {
const config *toplevel = cfg.child("toplevel");
if (toplevel != NULL) {
const std::vector<std::string> toplevel_refs
= config::quoted_split((*toplevel)["sections"]);
= utils::quoted_split((*toplevel)["sections"]);
if (std::find(toplevel_refs.begin(), toplevel_refs.end(), section_id)
!= toplevel_refs.end()) {
return true;
@ -744,7 +744,7 @@ bool section_is_referenced(const std::string &section_id, const config &cfg) {
for (config::const_child_itors itors = cfg.child_range("section");
itors.first != itors.second; itors.first++) {
const std::vector<std::string> sections_refd
= config::quoted_split((*(*itors.first))["sections"]);
= utils::quoted_split((*(*itors.first))["sections"]);
if (std::find(sections_refd.begin(), sections_refd.end(), section_id)
!= sections_refd.end()) {
return true;
@ -757,7 +757,7 @@ bool topic_is_referenced(const std::string &topic_id, const config &cfg) {
const config *toplevel = cfg.child("toplevel");
if (toplevel != NULL) {
const std::vector<std::string> toplevel_refs
= config::quoted_split((*toplevel)["topics"]);
= utils::quoted_split((*toplevel)["topics"]);
if (std::find(toplevel_refs.begin(), toplevel_refs.end(), topic_id)
!= toplevel_refs.end()) {
return true;
@ -766,7 +766,7 @@ bool topic_is_referenced(const std::string &topic_id, const config &cfg) {
for (config::const_child_itors itors = cfg.child_range("section");
itors.first != itors.second; itors.first++) {
const std::vector<std::string> topics_refd
= config::quoted_split((*(*itors.first))["topics"]);
= utils::quoted_split((*(*itors.first))["topics"]);
if (std::find(topics_refd.begin(), topics_refd.end(), topic_id)
!= topics_refd.end()) {
return true;
@ -782,7 +782,7 @@ void parse_config_internal(const config *help_cfg, const config *section_cfg,
<< std::endl;
}
else if (section_cfg != NULL) {
const std::vector<std::string> sections = config::quoted_split((*section_cfg)["sections"]);
const std::vector<std::string> sections = utils::quoted_split((*section_cfg)["sections"]);
const std::string id = level == 0 ? "toplevel" : (*section_cfg)["id"];
if (level != 0) {
if (!is_valid_id(id)) {
@ -814,7 +814,7 @@ void parse_config_internal(const config *help_cfg, const config *section_cfg,
generate_sections((*section_cfg)["generator"]);
std::transform(generated_sections.begin(), generated_sections.end(),
std::back_inserter(sec.sections), create_section());
const std::vector<std::string> topics = config::quoted_split((*section_cfg)["topics"]);
const std::vector<std::string> topics = utils::quoted_split((*section_cfg)["topics"]);
// Find all topics in this section.
for (it = topics.begin(); it != topics.end(); it++) {
config const *topic_cfg = help_cfg->find_child("topic", "id", *it);
@ -1300,7 +1300,7 @@ struct terrain_topic_generator: topic_generator
}
string_map sm;
sm["terrains"] = alias_ss.str();
ss << config::interpolate_variables_into_string(
ss << utils::interpolate_variables_into_string(
_("This terrain acts as $terrains for movement and defense purposes."), &sm);
if (aliased_terrains.size() > 1)
ss << " " << _("The terrain with the best modifier is chosen automatically.");
@ -1386,7 +1386,7 @@ std::string generate_about_text() {
std::vector<std::string>::iterator it =
std::remove(res_lines.begin(), res_lines.end(), "");
std::vector<std::string> res_lines_rem(res_lines.begin(), it);
std::string text = config::join(res_lines_rem, '\n');
std::string text = utils::join(res_lines_rem, '\n');
return text;
}
@ -2449,7 +2449,7 @@ SDL_Color string_to_color(const std::string &s) {
std::vector<std::string> split_in_width(const std::string &s, const int font_size,
const unsigned width) {
std::string wrapped = font::word_wrap_text(s, font_size, width);
std::vector<std::string> parts = config::split(wrapped, '\n', 0);
std::vector<std::string> parts = utils::split(wrapped, '\n', 0);
return parts;
}

View file

@ -393,12 +393,12 @@ void gamemap::set_terrain(const gamemap::location& loc, gamemap::TERRAIN ter)
std::vector<gamemap::location> parse_location_range(const std::string& x, const std::string& y)
{
std::vector<gamemap::location> res;
const std::vector<std::string> xvals = config::split(x);
const std::vector<std::string> yvals = config::split(y);
const std::vector<std::string> xvals = utils::split(x);
const std::vector<std::string> yvals = utils::split(y);
for(unsigned int i = 0; i != minimum(xvals.size(),yvals.size()); ++i) {
const std::pair<int,int> xrange = config::parse_range(xvals[i]);
const std::pair<int,int> yrange = config::parse_range(yvals[i]);
const std::pair<int,int> xrange = utils::parse_range(xvals[i]);
const std::pair<int,int> yrange = utils::parse_range(yvals[i]);
for(int x = xrange.first; x <= xrange.second; ++x) {
for(int y = yrange.first; y <= yrange.second; ++y) {

View file

@ -30,7 +30,7 @@ std::string random_generate_map(const std::string& parms, const config* cfg)
{
//the first token is the name of the generator, tokens after
//that are arguments to the generator
std::vector<std::string> parameters = config::split(parms,' ');
std::vector<std::string> parameters = utils::split(parms, ' ');
util::scoped_ptr<map_generator> generator(create_map_generator(parameters.front(),cfg));
if(generator == NULL) {
ERR_CF << "could not find map generator '" << parameters.front() << "'\n";
@ -45,7 +45,7 @@ config random_generate_scenario(const std::string& parms, const config* cfg)
{
//the first token is the name of the generator, tokens after
//that are arguments to the generator
std::vector<std::string> parameters = config::split(parms,' ');
std::vector<std::string> parameters = utils::split(parms, ' ');
util::scoped_ptr<map_generator> generator(create_map_generator(parameters.front(),cfg));
if(generator == NULL) {
ERR_CF << "could not find map generator '" << parameters.front() << "'\n";
@ -526,7 +526,7 @@ gamemap::location place_village(const std::vector<std::vector<gamemap::TERRAIN>
std::string generate_name(const unit_race& name_generator, const std::string& id, std::string* base_name=NULL,
std::map<std::string,std::string>* additional_symbols=NULL)
{
const std::vector<std::string>& options = config::split(string_table[id]);
const std::vector<std::string>& options = utils::split(string_table[id]);
if(options.empty() == false) {
const size_t choice = rand()%options.size();
LOG_NG << "calling name generator...\n";
@ -546,7 +546,7 @@ std::string generate_name(const unit_race& name_generator, const std::string& id
(*additional_symbols)["name"] = name;
LOG_NG << "interpolation variables into '" << options[choice] << "'\n";
return config::interpolate_variables_into_string(options[choice],additional_symbols);
return utils::interpolate_variables_into_string(options[choice], additional_symbols);
}
return "";
@ -1007,7 +1007,7 @@ std::string default_generate_map(size_t width, size_t height, size_t island_size
}
if(direction != -1) {
const std::vector<std::string> items = config::split(convert_to_bridge);
const std::vector<std::string> items = utils::split(convert_to_bridge);
if(size_t(direction) < items.size() && items[direction].empty() == false) {
terrain[x][y] = items[direction][0];
}

View file

@ -633,7 +633,7 @@ void leader_list_manager::update_leader_list(int side_index)
}
if(!side["leader"].empty()) {
leaders_ = config::split(side["leader"]);
leaders_ = utils::split(side["leader"]);
}
const std::string default_leader = side["type"];
@ -747,7 +747,7 @@ void leader_preview_pane::draw_contents()
const config& side = *side_list_[selection_];
std::string faction = side["name"];
const std::string recruits = side["recruit"];
const std::vector<std::string> recruit_list = config::split(recruits);
const std::vector<std::string> recruit_list = utils::split(recruits);
std::ostringstream recruit_string;
if(faction[0] == font::IMAGE) {

View file

@ -786,7 +786,7 @@ lobby::RESULT mp_connect::process()
if ((**side)["type"] == "random" || (**side)["type"].empty()) {
// Choose a random leader type.
std::vector<std::string> types =
config::split((**side)["leader"]);
utils::split((**side)["leader"]);
if (!types.empty()) {
const int lchoice = rand() % types.size();
(**side)["type"] = types[lchoice];

View file

@ -1878,7 +1878,7 @@ gui::dialog_button_action::RESULT delete_recall_unit::button_pressed(int menu_se
if(message != "") {
string_map symbols;
symbols["noun"] = (u.gender() == unit_race::MALE ? _("him") : _("her"));
message = config::interpolate_variables_into_string(message,&symbols);
message = utils::interpolate_variables_into_string(message, &symbols);
const int res = gui::show_dialog(disp_,NULL,"",message,gui::YES_NO);
if(res != 0) {
@ -2310,7 +2310,7 @@ void turn_info::do_search(const std::string& new_search)
bool found = false;
gamemap::location loc = last_search_hit_;
//If this is a location search, just center on that location.
std::vector<std::string> args = config::split(last_search_,',');
std::vector<std::string> args = utils::split(last_search_, ',');
if(args.size() == 2) {
int x, y;
x = lexical_cast_default<int>(args[0], 0)-1;
@ -2361,7 +2361,7 @@ void turn_info::do_search(const std::string& new_search)
//Not found, inform the player
string_map symbols;
symbols["search"] = last_search_;
const std::string msg = config::interpolate_variables_into_string(
const std::string msg = utils::interpolate_variables_into_string(
_("Couldn't find label or unit containing the string '$search'."),&symbols);
gui::show_dialog(gui_,NULL,"",msg);
}

View file

@ -71,10 +71,10 @@ manager::manager()
set_show_haloes(prefs["show_haloes"] != "no");
std::vector<std::string> v;
v = config::split(prefs["encountered_units"]);
v = utils::split(prefs["encountered_units"]);
std::copy(v.begin(), v.end(),
std::inserter(encountered_units_set, encountered_units_set.begin()));
v = config::split(prefs["encountered_terrains"]);
v = utils::split(prefs["encountered_terrains"]);
std::copy(v.begin(), v.end(),
std::inserter(encountered_terrains_set, encountered_terrains_set.begin()));
}
@ -84,11 +84,11 @@ manager::~manager()
std::vector<std::string> v;
std::copy(encountered_units_set.begin(), encountered_units_set.end(), std::back_inserter(v));
prefs["encountered_units"] = config::join(v);
prefs["encountered_units"] = utils::join(v);
v.clear();
std::copy(encountered_terrains_set.begin(), encountered_terrains_set.end(),
std::back_inserter(v));
prefs["encountered_terrains"] = config::join(v);
prefs["encountered_terrains"] = utils::join(v);
encountered_units_set.clear();
encountered_terrains_set.clear();
try {

View file

@ -99,8 +99,8 @@ unit_race::unit_race() : ntraits_(0), chain_size_(0), not_living_(false)
unit_race::unit_race(const config& cfg) : name_(cfg["name"]), ntraits_(atoi(cfg["num_traits"].c_str())),
not_living_(cfg["not_living"] == "yes")
{
names_[MALE] = config::split(cfg["male_names"]);
names_[FEMALE] = config::split(cfg["female_names"]);
names_[MALE] = utils::split(cfg["male_names"]);
names_[FEMALE] = utils::split(cfg["female_names"]);
chain_size_ = atoi(cfg["markov_chain_size"].c_str());
if(chain_size_ <= 0)

View file

@ -13,6 +13,7 @@
*/
#include <cctype>
#include <sstream>
#include "serialization/string_utils.hpp"
@ -131,11 +132,108 @@ std::string interpolate_variables_into_string(std::string const &str, string_map
do_interpolation(res, 0, symbols);
//remove any pipes in the string, as they are used simply to seperate variables
res.erase(std::remove(res.begin(),res.end(),'|'),res.end());
res.erase(std::remove(res.begin(), res.end(), '|'), res.end());
return res;
}
//prepend all special characters with a backslash
//special characters are:
//#@{}+-,\*
std::string &escape(std::string &str)
{
std::string::size_type pos = 0;
do {
pos = str.find_first_of("#@{}+-,\\*", pos);
if (pos == std::string::npos)
break;
str.insert(pos, 1, '\\');
pos += 2;
} while (pos < str.size());
return str;
}
// remove all escape characters (backslash)
std::string &unescape(std::string &str)
{
std::string::size_type pos = 0;
do {
pos = str.find('\\', pos);
if (pos == std::string::npos)
break;
str.erase(pos, 1);
++pos;
} while (pos < str.size());
return str;
}
std::string join(std::vector< std::string > const &v, char c)
{
std::stringstream str;
for(std::vector< std::string >::const_iterator i = v.begin(); i != v.end(); ++i) {
str << *i;
if (i + 1 != v.end())
str << c;
}
return str.str();
}
//identical to split(), except it does not split when it otherwise
//would if the previous character was identical to the parameter 'quote'.
//i.e. it does not split quoted commas.
//this method was added to make it possible to quote user input,
//particularly so commas in user input will not cause visual problems in menus.
//why not change split()? that would change the methods post condition.
std::vector< std::string > quoted_split(std::string const &val, char c, int flags, char quote)
{
std::vector<std::string> res;
std::string::const_iterator i1 = val.begin();
std::string::const_iterator i2 = val.begin();
while (i2 != val.end()) {
if (*i2 == quote) {
// ignore quoted character
++i2;
if (i2 != val.end()) ++i2;
} else if (*i2 == c) {
std::string new_val(i1, i2);
if (flags & STRIP_SPACES)
strip(new_val);
if (!(flags & REMOVE_EMPTY) || !new_val.empty())
res.push_back(new_val);
++i2;
if (flags & STRIP_SPACES) {
while(i2 != val.end() && *i2 == ' ')
++i2;
}
i1 = i2;
} else {
++i2;
}
}
std::string new_val(i1, i2);
if (flags & STRIP_SPACES)
strip(new_val);
if (!(flags & REMOVE_EMPTY) || !new_val.empty())
res.push_back(new_val);
return res;
}
std::pair< int, int > parse_range(std::string const &str)
{
const std::string::const_iterator dash = std::find(str.begin(), str.end(), '-');
const std::string a(str.begin(), dash);
const std::string b = dash != str.end() ? std::string(dash + 1, str.end()) : a;
std::pair<int,int> res(atoi(a.c_str()), atoi(b.c_str()));
if (res.second < res.first)
res.second = res.first;
return res;
}
}

View file

@ -32,7 +32,7 @@ std::vector< std::string > split(std::string const &val, char c = ',', int flags
std::string join(std::vector< std::string > const &v, char c = ',');
std::vector< std::string > quoted_split(std::string const &val, char c= ',',
int flags = REMOVE_EMPTY | STRIP_SPACES, char quote = '\\');
std::pair< int, int > parse_range(const std::string& str);
std::pair< int, int > parse_range(std::string const &str);
bool notspace(char c);
std::string &escape(std::string &str);
std::string &unescape(std::string &str);

View file

@ -5,6 +5,7 @@
#include "../network.hpp"
#include "../util.hpp"
#include "../wassert.hpp"
#include "serialization/string_utils.hpp"
#include "SDL.h"
@ -367,7 +368,7 @@ void server::process_login(const network::connection sock, const config& data, c
//check the username is valid (all alpha-numeric or space)
std::string username = (*login)["username"];
config::strip(username);
utils::strip(username);
const int alnum = std::count_if(username.begin(),username.end(),isalnum);
const int spaces = std::count(username.begin(),username.end(),' ');
if((alnum + spaces != username.size()) || spaces == username.size() || username.empty()) {

View file

@ -94,7 +94,7 @@ team::team_info::team_info(const config& cfg)
const std::string& enemies_list = cfg["enemy"];
if(!enemies_list.empty()) {
std::vector<std::string> venemies = config::split(enemies_list);
std::vector<std::string> venemies = utils::split(enemies_list);
for(std::vector<std::string>::const_iterator i = venemies.begin(); i != venemies.end(); ++i) {
enemies.push_back(atoi(i->c_str()));
}
@ -156,7 +156,7 @@ team::team_info::team_info(const config& cfg)
village_value = atof(village_val.c_str());
}
std::vector<std::string> recruits = config::split(cfg["recruit"]);
std::vector<std::string> recruits = utils::split(cfg["recruit"]);
for(std::vector<std::string>::const_iterator i = recruits.begin(); i != recruits.end(); ++i) {
can_recruit.insert(*i);
}
@ -166,7 +166,7 @@ team::team_info::team_info(const config& cfg)
recruit_pattern = global_ai_params["recruitment_pattern"];
}
recruitment_pattern = config::split(recruit_pattern);
recruitment_pattern = utils::split(recruit_pattern);
//default recruitment pattern is to buy 2 fighters for every 1 archer
if(recruitment_pattern.empty()) {
@ -361,7 +361,7 @@ void team::set_time_of_day(int turn, const time_of_day& tod)
for(std::vector<config>::const_iterator i = info_.ai_params.begin(); i != info_.ai_params.end(); ++i) {
const std::string& time_of_day = (*i)["time_of_day"];
if(time_of_day.empty() == false) {
const std::vector<std::string>& times = config::split(time_of_day);
const std::vector<std::string>& times = utils::split(time_of_day);
if(std::count(times.begin(),times.end(),tod.id) == 0) {
continue;
}
@ -371,9 +371,9 @@ void team::set_time_of_day(int turn, const time_of_day& tod)
if(turns.empty() == false) {
bool matched = false;
const std::vector<std::string>& turns_list = config::split(turns);
const std::vector<std::string>& turns_list = utils::split(turns);
for(std::vector<std::string>::const_iterator j = turns_list.begin(); j != turns_list.end(); ++j) {
const std::pair<int,int> range = config::parse_range(*j);
const std::pair<int,int> range = utils::parse_range(*j);
if(turn >= range.first && turn <= range.second) {
matched = true;
break;

View file

@ -37,7 +37,7 @@ namespace {
_rect read_rect(const config& cfg) {
_rect rect = { 0, 0, 0, 0 };
const std::vector<std::string> items = config::split(cfg["rect"].c_str());
const std::vector<std::string> items = utils::split(cfg["rect"].c_str());
if(items.size() >= 1)
rect.x1 = atoi(items[0].c_str());
@ -67,7 +67,7 @@ namespace {
std::string resolve_rect(const std::string& rect_str) {
_rect rect = { 0, 0, 0, 0 };
std::stringstream resolved;
const std::vector<std::string> items = config::split(rect_str.c_str());
const std::vector<std::string> items = utils::split(rect_str.c_str());
if(items.size() >= 1) {
rect.x1 = compute(items[0], ref_rect.x1, ref_rect.x2);
resolved << rect.x1;
@ -411,7 +411,7 @@ theme::menu::menu() : context_(false)
theme::menu::menu(const config& cfg) : object(cfg), context_(cfg["is_context_menu"] == "true"),
title_(cfg["title"] + cfg["title_literal"]),
image_(cfg["image"]),
items_(config::split(cfg["items"]))
items_(utils::split(cfg["items"]))
{}
bool theme::menu::is_context() const { return context_; }

View file

@ -12,8 +12,9 @@
*/
#include "exploder_cutter.hpp"
#include "../filesystem.hpp"
#include "../sdl_utils.hpp"
#include "filesystem.hpp"
#include "sdl_utils.hpp"
#include "serialization/string_utils.hpp"
#include "SDL_image.h"
cutter::cutter() : verbose_(false)
@ -128,7 +129,7 @@ void cutter::add_sub_image(const surface &surf, surface_map &map, const config*
const cutter::mask& mask = masks_[name];
std::vector<std::string> pos = config::split((*config)["pos"]);
std::vector<std::string> pos = utils::split((*config)["pos"]);
if(pos.size() != 2)
throw exploder_failure("Invalid position " + (*config)["pos"]);

View file

@ -12,13 +12,13 @@
*/
#include "exploder_utils.hpp"
#include "../game_config.hpp"
#include "../config.hpp"
#include "game_config.hpp"
#include "serialization/string_utils.hpp"
#include <png.h>
exploder_point::exploder_point(const std::string &s)
{
std::vector<std::string> items = config::split(s);
std::vector<std::string> items = utils::split(s);
if(items.size() != 2) {
x = y = 0;
} else {
@ -29,7 +29,7 @@ exploder_point::exploder_point(const std::string &s)
exploder_rect::exploder_rect(const std::string &s)
{
std::vector<std::string> items = config::split(s);
std::vector<std::string> items = utils::split(s);
if(items.size() != 4) {
x = y = w = h = 0;
} else {

View file

@ -507,7 +507,7 @@ bool unit::matches_filter(const config& cfg) const
if(std::find(type.begin(),type.end(),',') != type.end() &&
std::search(type.begin(),type.end(),this_type.begin(),
this_type.end()) != type.end()) {
const std::vector<std::string>& vals = config::split(type);
const std::vector<std::string>& vals = utils::split(type);
if(std::find(vals.begin(),vals.end(),this_type) == vals.end()) {
return false;
@ -535,7 +535,7 @@ bool unit::matches_filter(const config& cfg) const
if(side.empty() == false && this->side() != atoi(side.c_str()))
{
if(std::find(side.begin(),side.end(),',') != side.end()) {
const std::vector<std::string>& vals = config::split(side);
const std::vector<std::string>& vals = utils::split(side);
std::ostringstream s;
s << (this->side());
@ -694,7 +694,7 @@ void unit::read(const game_data& data, const config& cfg)
}
}
overlays_ = config::split(cfg["overlays"]);
overlays_ = utils::split(cfg["overlays"]);
if(overlays_.size() == 1 && overlays_.front() == "") {
overlays_.clear();
}
@ -764,7 +764,7 @@ void unit::write(config& cfg) const
cfg.add_child("variables",variables_);
cfg.add_child("status",status_flags);
cfg["overlays"] = config::join(overlays_);
cfg["overlays"] = utils::join(overlays_);
cfg["user_description"] = description_;
cfg["description"] = underlying_description_;
@ -1005,7 +1005,7 @@ void unit::add_modification(const std::string& type,
//see if the effect only applies to certain unit types
const std::string& type_filter = (**i.first)["unit_type"];
if(type_filter.empty() == false) {
const std::vector<std::string>& types = config::split(type_filter);
const std::vector<std::string>& types = utils::split(type_filter);
if(std::find(types.begin(),types.end(),this->type().name()) == types.end()) {
continue;
}

View file

@ -146,7 +146,7 @@ attack_type::attack_type(const config& cfg)
if(dir == "") {
animation_.push_back(unit_animation(**an));
} else {
const std::vector<std::string>& directions = config::split(dir);
const std::vector<std::string>& directions = utils::split(dir);
for(std::vector<std::string>::const_iterator i = directions.begin(); i != directions.end(); ++i) {
const gamemap::location::DIRECTION d = gamemap::location::parse_direction(*i);
if(d != gamemap::location::NDIRECTIONS) {
@ -569,7 +569,7 @@ unit_type::unit_type(const config& cfg, const movement_type_map& mv_types,
gender_types_[unit_race::FEMALE] = new unit_type(*female_cfg,mv_types,races,traits);
}
const std::vector<std::string> genders = config::split(cfg["gender"]);
const std::vector<std::string> genders = utils::split(cfg["gender"]);
for(std::vector<std::string>::const_iterator i = genders.begin();
i != genders.end(); ++i) {
if(*i == "male") {
@ -591,7 +591,7 @@ unit_type::unit_type(const config& cfg, const movement_type_map& mv_types,
race_ = &dummy_race;
}
abilities_ = config::split(cfg_["ability"]);
abilities_ = utils::split(cfg_["ability"]);
//if the string was empty, split will give us one empty string in the list,
//remove it.
@ -868,7 +868,7 @@ std::vector<std::string> unit_type::advances_to() const
if(val == "null" || val == "")
return std::vector<std::string>();
else
return config::split(val);
return utils::split(val);
}
const std::string& unit_type::usage() const

View file

@ -192,7 +192,7 @@ void button::set_label(const std::string& val)
//if we have a list of items, use the first one that isn't an image
if (std::find(label_.begin(), label_.end(), COLUMN_SEPARATOR) != label_.end()) {
const std::vector<std::string>& items = config::split(label_, COLUMN_SEPARATOR);
const std::vector<std::string>& items = utils::split(label_, COLUMN_SEPARATOR);
const std::vector<std::string>::const_iterator i = std::find_if(items.begin(),items.end(),not_image);
if(i != items.end()) {
label_ = *i;

View file

@ -36,7 +36,7 @@ void menu::fill_items(const std::vector<std::string>& items, bool strip_spaces)
{
for(std::vector<std::string>::const_iterator item = items.begin();
item != items.end(); ++item) {
items_.push_back(config::quoted_split(*item, COLUMN_SEPARATOR, !strip_spaces));
items_.push_back(utils::quoted_split(*item, COLUMN_SEPARATOR, !strip_spaces));
//make sure there is always at least one item
if(items_.back().empty())
@ -64,7 +64,7 @@ void menu::create_help_strings()
if(std::find(j->begin(),j->end(),static_cast<char>(HELP_STRING_SEPARATOR)) == j->end()) {
help_.back().push_back("");
} else {
const std::vector<std::string>& items = config::split(*j,HELP_STRING_SEPARATOR,0);
const std::vector<std::string>& items = utils::split(*j, HELP_STRING_SEPARATOR, 0);
if(items.size() >= 2) {
*j = items.front();
help_.back().push_back(items.back());
@ -329,7 +329,7 @@ void menu::scroll(int)
namespace {
SDL_Rect item_size(const std::string& item) {
SDL_Rect res = {0,0,0,0};
std::vector<std::string> img_text_items = config::split(item, IMG_TEXT_SEPARATOR);
std::vector<std::string> img_text_items = utils::split(item, IMG_TEXT_SEPARATOR);
for (std::vector<std::string>::const_iterator it = img_text_items.begin();
it != img_text_items.end(); it++) {
if (res.w > 0 || res.h > 0) {
@ -406,7 +406,7 @@ void menu::draw_item(int item)
for(size_t i = 0; i != items_[item].size(); ++i) {
const int last_x = xpos;
std::string str = items_[item][i];
std::vector<std::string> img_text_items = config::split(str, IMG_TEXT_SEPARATOR);
std::vector<std::string> img_text_items = utils::split(str, IMG_TEXT_SEPARATOR);
for (std::vector<std::string>::const_iterator it = img_text_items.begin();
it != img_text_items.end(); it++) {
str = *it;