path_map[new_key] = path_map[old_key];
if (path_map.find(old_key) != path_map.end()) path_map[new_key] = path_map[old_key];
static void switch_slashes(string & name);static bool base_to_uppercase(string& str, int count);// Wrap a few functionsinline int stat(const std::string &file_name, struct stat *buf){	return stat(file_name.c_str(),buf);}// Ugly hack for supporting different pathsstatic std::map<string, string> path_map;static std::map<string, string> stored_path_map;void store_system_paths(){	stored_path_map = path_map;}void reset_system_paths(){	path_map = stored_path_map;}void add_system_path(const string& key, const string& value){	path_map[key] = value;}void clone_system_path(const string& new_key, const string& old_key){	path_map[new_key] = path_map[old_key];}void clear_system_path(const string& key){	std::map<string, string>::iterator iter = path_map.find(key);	if (iter != path_map.end())		path_map.erase(iter);}/* *	Has a path been entered? */bool is_system_path_defined(const string& path)	{	return path_map.find(path) != path_map.end();	}/* *  Convert an exult path (e.g. "<DATA>/exult.flx") into a system path */string get_system_path(const string &path){	string new_path;	string::size_type pos;	string::size_type pos2;	#if defined(__MORPHOS__) || defined(AMIGA)  pos = path.find( "../" );  if( pos != string::npos )	  new_path = path.substr( 0, pos )+path.substr( pos+2 );  else	  new_path = path;  pos = new_path.find( "./" );  if( pos != string::npos )	  new_path = new_path.substr( 0, pos )+new_path.substr( pos+2 );  pos = new_path.find('>');  pos2 = new_path.find('<');  // If there is no separator, return the path as is  if(pos != string::npos && pos2 == 0)  {	  pos += 1;	  // See if we can translate this prefix	  string new_prefix(path_map[new_path.substr(0, pos).c_str()]);	  // If the prefix path is not recognised, return the path as is	  if(!new_prefix.empty())		  new_path = new_prefix + new_path.substr(pos);  }#else	pos = path.find('>');	pos2 = path.find('<');	// If there is no separator, return the path as is	if(pos == string::npos || pos2 != 0) {		new_path = path;	}	else	{		pos += 1;		// See if we can translate this prefix		string new_prefix(path_map[path.substr(0, pos).c_str()]);		// If the prefix path is not recognised, return the path as is		if(new_prefix.empty()) {			new_path = path;		} else {			new_path = new_prefix + path.substr(pos);		}	}#endif	switch_slashes(new_path);#ifdef WIN32	if (*(new_path.end()-1) == '/' || *(new_path.end()-1) == '\\') {		std::cerr << "Trailing slash in path: \"" << new_path << "\"" << std::endl << "...compensating, but go complain to Colourless anyway" << std::endl;		new_path += '.';	}#ifdef NO_WIN32_PATH_SPACES	pos = new_path.find('*');	pos2 = new_path.find('?');	string::size_type pos3 = new_path.find(' ');	// pos and pos2 will equal each other if neither is found	// and we'll only convert to short if a space is found	// really, we don't need to do this, but hey, you never know	if (pos == pos2 && pos3 != string::npos) {		int num_chars = GetShortPathName(new_path.c_str(), NULL, 0);		if (num_chars > 0) {			char *short_path = new char [num_chars+1];			GetShortPathName(new_path.c_str(), short_path, num_chars+1);			new_path = short_path;			delete [] short_path;		}		//else std::cerr << "Warning unable to get short path for: " << new_path << std::endl;	}#endif#endif	return new_path;}/* *	Convert a buffer to upper-case. * *	Output: ->original buffer, changed to upper case. */void to_uppercase(string &str){	for(string::iterator X = str.begin(); X != str.end(); ++X)	{#if (defined(BEOS) || defined(OPENBSD) || defined(CYGWIN) || defined(__MORPHOS__))		if ((*X >= 'a') && (*X <= 'z')) *X -= 32;#else		*X = std::toupper(*X);#endif         	}}string to_uppercase(const std::string &str){	string s(str);	to_uppercase(s);	return s;}/* *	Convert just the last 'count' parts of a filename to uppercase. *  returns false if there are less than 'count' parts */static bool base_to_uppercase(string& str, int count){	if (count <= 0) return true;	int todo = count;					// Go backwards.	string::reverse_iterator X;	for(X = str.rbegin(); X != str.rend(); ++X)		{					// Stop at separator.		if (*X == '/' || *X == '\\' || *X == ':')			todo--;		if (todo <= 0)			break;#if (defined(BEOS) || defined(OPENBSD) || defined(CYGWIN) || defined(__MORPHOS__))		if ((*X >= 'a') && (*X <= 'z')) *X -= 32;#else		*X = std::toupper(*X);#endif         	}	if (X == str.rend())		todo--; // start of pathname counts as separator too	// false if it didn't reach 'count' parts	return (todo <= 0);}static void switch_slashes(	string & name	){#ifdef WIN32	for(string::iterator X = name.begin(); X != name.end(); ++X)	{		if(*X == '/' )			*X =  '\\';	}#elif defined(MACOS)	// We use a component-wise algorithm (suggested by Yorick)	// Basically, split the path along the "/" seperators	// If a component is empty or '.', remove it. If it's '..', replace it	// with the empty string. convert all / to :	string::size_type	begIdx, endIdx;;	string	component;	string	new_name;		if( name.at(0) != '/' )		new_name = ":";		begIdx = name.find_first_not_of('/');	while( begIdx != string::npos )	{		endIdx = name.find_first_of('/', begIdx);		if( endIdx == std::string::npos )			component = name.substr(begIdx);		else			component = name.substr(begIdx, endIdx-begIdx);		if( component == ".." )			new_name += ":";		else if( !component.empty() && component != "." )		{			new_name += component;			if( endIdx != std::string::npos )				new_name += ":";		}		begIdx = name.find_first_not_of('/', endIdx);	}	name = new_name;#else	// do nothing#endif}