[Scummvm-cvs-logs] SF.net SVN: scummvm:[47355] tools/trunk

tdhs at users.sourceforge.net tdhs at users.sourceforge.net
Mon Jan 18 16:40:49 CET 2010


Revision: 47355
          http://scummvm.svn.sourceforge.net/scummvm/?rev=47355&view=rev
Author:   tdhs
Date:     2010-01-18 15:40:49 +0000 (Mon, 18 Jan 2010)

Log Message:
-----------
Removed Mohawk tool specific String class and migrated to Common::String.

Modified Paths:
--------------
    tools/trunk/Makefile.common
    tools/trunk/common/scummsys.h
    tools/trunk/engines/mohawk/mohawk_file.cpp
    tools/trunk/engines/mohawk/mohawk_file.h
    tools/trunk/engines/mohawk/util.h

Added Paths:
-----------
    tools/trunk/common/hash-str.h
    tools/trunk/common/hashmap.cpp
    tools/trunk/common/hashmap.h
    tools/trunk/common/memorypool.cpp
    tools/trunk/common/memorypool.h

Removed Paths:
-------------
    tools/trunk/engines/mohawk/utils/str.cpp
    tools/trunk/engines/mohawk/utils/str.h

Modified: tools/trunk/Makefile.common
===================================================================
--- tools/trunk/Makefile.common	2010-01-18 07:21:54 UTC (rev 47354)
+++ tools/trunk/Makefile.common	2010-01-18 15:40:49 UTC (rev 47355)
@@ -85,7 +85,10 @@
 
 UTILS := \
 	common/file.o \
+	common/hashmap.o \
 	common/md5.o \
+	common/memorypool.o \
+	common/str.o \
 	common/util.o \
 	sound/adpcm.o \
 	sound/audiostream.o \
@@ -134,7 +137,9 @@
 deriven_OBJS := \
 	engines/mohawk/deriven.o \
 	engines/mohawk/mohawk_file.o \
-	engines/mohawk/utils/str.o \
+	common/hashmap.o \
+	common/memorypool.o \
+	common/str.o \
 	engines/mohawk/utils/file.o \
 	engines/mohawk/utils/adpcm.o \
 	engines/mohawk/utils/audiostream.o \
@@ -168,7 +173,9 @@
 extract_mohawk_OBJS := \
 	engines/mohawk/extract_mohawk.o \
 	engines/mohawk/mohawk_file.o \
-	engines/mohawk/utils/str.o \
+	common/hashmap.o \
+	common/memorypool.o \
+	common/str.o \
 	engines/mohawk/utils/file.o \
 	engines/mohawk/utils/adpcm.o \
 	engines/mohawk/utils/audiostream.o \

Added: tools/trunk/common/hash-str.h
===================================================================
--- tools/trunk/common/hash-str.h	                        (rev 0)
+++ tools/trunk/common/hash-str.h	2010-01-18 15:40:49 UTC (rev 47355)
@@ -0,0 +1,88 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ */
+
+#ifndef COMMON_HASH_STR_H
+#define COMMON_HASH_STR_H
+
+#include "common/hashmap.h"
+#include "common/str.h"
+
+namespace Common {
+
+uint hashit(const char *str);
+uint hashit_lower(const char *str);	// Generate a hash based on the lowercase version of the string
+inline uint hashit(const String &str) { return hashit(str.c_str()); }
+inline uint hashit_lower(const String &str) { return hashit_lower(str.c_str()); }
+
+
+// FIXME: The following functors obviously are not consistently named
+
+struct CaseSensitiveString_EqualTo {
+	bool operator()(const String& x, const String& y) const { return x.equals(y); }
+};
+
+struct CaseSensitiveString_Hash {
+	uint operator()(const String& x) const { return hashit(x.c_str()); }
+};
+
+
+struct IgnoreCase_EqualTo {
+	bool operator()(const String& x, const String& y) const { return x.equalsIgnoreCase(y); }
+};
+
+struct IgnoreCase_Hash {
+	uint operator()(const String& x) const { return hashit_lower(x.c_str()); }
+};
+
+
+
+// Specalization of the Hash functor for String objects.
+// We do case sensitve hashing here, because that is what
+// the default EqualTo is compatible with. If one wants to use
+// case insensitve hashing, then only because one wants to use
+// IgnoreCase_EqualTo, and then one has to specify a custom
+// hash anyway.
+template <>
+struct Hash<String> {
+	uint operator()(const String& s) const {
+		return hashit(s.c_str());
+	}
+};
+
+template <>
+struct Hash<const char *> {
+	uint operator()(const char *s) const {
+		return hashit(s);
+	}
+};
+
+// String map -- by default case insensitive
+typedef HashMap<String, String, IgnoreCase_Hash, IgnoreCase_EqualTo> StringMap;
+
+
+
+}	// End of namespace Common
+
+
+#endif


Property changes on: tools/trunk/common/hash-str.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: tools/trunk/common/hashmap.cpp
===================================================================
--- tools/trunk/common/hashmap.cpp	                        (rev 0)
+++ tools/trunk/common/hashmap.cpp	2010-01-18 15:40:49 UTC (rev 47355)
@@ -0,0 +1,112 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+// The hash map (associative array) implementation in this file is
+// based on the PyDict implementation of CPython. The erase() method
+// is based on example code in the Wikipedia article on Hash tables.
+
+#include "common/hashmap.h"
+
+namespace Common {
+
+// Hash function for strings, taken from CPython.
+uint hashit(const char *p) {
+	uint hash = *p << 7;
+	byte c;
+	int size = 0;
+	while ((c = *p++)) {
+		hash = (1000003 * hash) ^ c;
+		size++;
+	}
+	return hash ^ size;
+}
+
+// Like hashit, but converts every char to lowercase before hashing.
+uint hashit_lower(const char *p) {
+	uint hash = tolower(*p) << 7;
+	byte c;
+	int size = 0;
+	while ((c = *p++)) {
+		hash = (1000003 * hash) ^ tolower(c);
+		size++;
+	}
+	return hash ^ size;
+}
+
+#ifdef DEBUG_HASH_COLLISIONS
+static double
+	g_collisions = 0,
+	g_dummyHits = 0,
+	g_lookups = 0,
+	g_collPerLook = 0,
+	g_capacity = 0,
+	g_size = 0;
+static int g_max_capacity = 0, g_max_size = 0;
+static int g_totalHashmaps = 0;
+static int g_stats[4] = {0,0,0,0};
+
+void updateHashCollisionStats(int collisions, int dummyHits, int lookups, int arrsize, int nele) {
+	g_collisions += collisions;
+	g_lookups += lookups;
+	g_dummyHits += dummyHits;
+	if (lookups)
+		g_collPerLook += (double)collisions / (double)lookups;
+	g_capacity += arrsize;
+	g_size += nele;
+	g_totalHashmaps++;
+
+	if (3*nele <= 2*8)
+		g_stats[0]++;
+	if (3*nele <= 2*16)
+		g_stats[1]++;
+	if (3*nele <= 2*32)
+		g_stats[2]++;
+	if (3*nele <= 2*64)
+		g_stats[3]++;
+
+	g_max_capacity = MAX(g_max_capacity, arrsize);
+	g_max_size = MAX(g_max_size, nele);
+
+	fprintf(stdout, "%d hashmaps: colls %.1f; dummies hit %.1f, lookups %.1f; ratio %.3f%%; size %f (max: %d); capacity %f (max: %d)\n",
+		g_totalHashmaps,
+		g_collisions / g_totalHashmaps,
+		g_dummyHits / g_totalHashmaps,
+		g_lookups / g_totalHashmaps,
+		100 * g_collPerLook / g_totalHashmaps,
+		g_size / g_totalHashmaps, g_max_size,
+		g_capacity / g_totalHashmaps, g_max_capacity);
+	fprintf(stdout, "  %d less than %d; %d less than %d; %d less than %d; %d less than %d\n",
+			g_stats[0], 2*8/3,
+			g_stats[1],2*16/3,
+			g_stats[2],2*32/3,
+			g_stats[3],2*64/3);
+
+	// TODO:
+	// * Should record the maximal size of the map during its lifetime, not that at its death
+	// * Should do some statistics: how many maps are less than 2/3*8, 2/3*16, 2/3*32, ...
+}
+#endif
+
+}	// End of namespace Common


Property changes on: tools/trunk/common/hashmap.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: tools/trunk/common/hashmap.h
===================================================================
--- tools/trunk/common/hashmap.h	                        (rev 0)
+++ tools/trunk/common/hashmap.h	2010-01-18 15:40:49 UTC (rev 47355)
@@ -0,0 +1,597 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+// The hash map (associative array) implementation in this file is
+// based on the PyDict implementation of CPython.
+
+#ifndef COMMON_HASHMAP_H
+#define COMMON_HASHMAP_H
+
+#include "common/func.h"
+#include "common/str.h"
+#include "common/util.h"
+
+#define USE_HASHMAP_MEMORY_POOL
+#ifdef USE_HASHMAP_MEMORY_POOL
+#include "common/memorypool.h"
+#endif
+
+namespace Common {
+
+// The sgi IRIX MIPSpro Compiler has difficulties with nested templates. 
+// This and the other __sgi conditionals below work around these problems.
+#ifdef __sgi
+template<class T> class IteratorImpl;
+#endif
+
+// Enable the following #define if you want to check how many collisions the
+// code produces (many collisions indicate either a bad hash function, or a
+// hash table that is too small).
+//#define DEBUG_HASH_COLLISIONS
+
+
+/**
+ * HashMap<Key,Val> maps objects of type Key to objects of type Val.
+ * For each used Key type, we need an "uint hashit(Key,uint)" function
+ * that computes a hash for the given Key object and returns it as an
+ * an integer from 0 to hashsize-1, and also an "equality functor".
+ * that returns true if if its two arguments are to be considered
+ * equal. Also, we assume that "=" works on Val objects for assignment.
+ *
+ * If aa is an HashMap<Key,Val>, then space is allocated each time aa[key] is
+ * referenced, for a new key. If the object is const, then an assertion is
+ * triggered instead. Hence if you are not sure whether a key is contained in
+ * the map, use contains() first to check for its presence.
+ */
+template<class Key, class Val, class HashFunc = Hash<Key>, class EqualFunc = EqualTo<Key> >
+class HashMap {
+private:
+#if defined (PALMOS_MODE)
+public:
+#endif
+
+	typedef HashMap<Key, Val, HashFunc, EqualFunc> HM_t;
+
+	struct Node {
+		const Key _key;
+		Val _value;
+		explicit Node(const Key &key) : _key(key), _value() {}
+		Node() : _key(), _value() {}
+	};
+
+	enum {
+		HASHMAP_PERTURB_SHIFT = 5,
+		HASHMAP_MIN_CAPACITY = 16,
+
+		// The quotient of the next two constants controls how much the
+		// internal storage of the hashmap may fill up before being
+		// increased automatically.
+		// Note: the quotient of these two must be between and different
+		// from 0 and 1.
+		HASHMAP_LOADFACTOR_NUMERATOR = 2,
+		HASHMAP_LOADFACTOR_DENOMINATOR = 3,
+
+		HASHMAP_MEMORYPOOL_SIZE = HASHMAP_MIN_CAPACITY * HASHMAP_LOADFACTOR_NUMERATOR / HASHMAP_LOADFACTOR_DENOMINATOR
+	};
+
+
+	ObjectPool<Node, HASHMAP_MEMORYPOOL_SIZE> _nodePool;
+
+	Node **_storage;	///< hashtable of size arrsize.
+	uint _mask;		///< Capacity of the HashMap minus one; must be a power of two of minus one
+	uint _size;
+	uint _deleted; ///< Number of deleted elements (_dummyNodes)
+
+	HashFunc _hash;
+	EqualFunc _equal;
+
+	/** Default value, returned by the const getVal. */
+	const Val _defaultVal;
+
+	/** Dummy node, used as marker for erased objects. */
+	#define HASHMAP_DUMMY_NODE	((Node *)1)
+
+#ifdef DEBUG_HASH_COLLISIONS
+	mutable int _collisions, _lookups, _dummyHits;
+#endif
+
+	Node *allocNode(const Key &key) {
+		return new (_nodePool) Node(key);
+	}
+
+	void freeNode(Node *node) {
+		if (node && node != HASHMAP_DUMMY_NODE)
+			_nodePool.deleteChunk(node);
+	}
+
+	void assign(const HM_t &map);
+	int lookup(const Key &key) const;
+	int lookupAndCreateIfMissing(const Key &key);
+	void expandStorage(uint newCapacity);
+
+#ifndef __sgi
+	template<class T> friend class IteratorImpl;
+#endif
+
+	/**
+	 * Simple HashMap iterator implementation.
+	 */
+	template<class NodeType>
+	class IteratorImpl {
+		friend class HashMap;
+#ifdef __sgi
+		template<class T> friend class Common::IteratorImpl;
+#else
+		template<class T> friend class IteratorImpl;
+#endif
+	protected:
+		typedef const HashMap hashmap_t;
+
+		uint _idx;
+		hashmap_t *_hashmap;
+
+	protected:
+		IteratorImpl(uint idx, hashmap_t *hashmap) : _idx(idx), _hashmap(hashmap) {}
+
+		NodeType *deref() const {
+			assert(_hashmap != 0);
+			assert(_idx <= _hashmap->_mask);
+			Node *node = _hashmap->_storage[_idx];
+			assert(node != 0);
+			assert(node != HASHMAP_DUMMY_NODE);
+			return node;
+		}
+
+	public:
+		IteratorImpl() : _idx(0), _hashmap(0) {}
+		template<class T>
+		IteratorImpl(const IteratorImpl<T> &c) : _idx(c._idx), _hashmap(c._hashmap) {}
+
+		NodeType &operator*() const { return *deref(); }
+		NodeType *operator->() const { return deref(); }
+
+		bool operator==(const IteratorImpl &iter) const { return _idx == iter._idx && _hashmap == iter._hashmap; }
+		bool operator!=(const IteratorImpl &iter) const { return !(*this == iter); }
+
+		IteratorImpl &operator++() {
+			assert(_hashmap);
+			do {
+				_idx++;
+			} while (_idx <= _hashmap->_mask && (_hashmap->_storage[_idx] == 0 || _hashmap->_storage[_idx] == HASHMAP_DUMMY_NODE));
+			if (_idx > _hashmap->_mask)
+				_idx = (uint)-1;
+
+			return *this;
+		}
+
+		IteratorImpl operator++(int) {
+			IteratorImpl old = *this;
+			operator ++();
+			return old;
+		}
+	};
+
+public:
+	typedef IteratorImpl<Node> iterator;
+	typedef IteratorImpl<const Node> const_iterator;
+
+	HashMap();
+	HashMap(const HM_t &map);
+	~HashMap();
+
+	HM_t &operator=(const HM_t &map) {
+		if (this == &map)
+			return *this;
+
+		// Remove the previous content and ...
+		clear();
+		delete[] _storage;
+		// ... copy the new stuff.
+		assign(map);
+		return *this;
+	}
+
+	bool contains(const Key &key) const;
+
+	Val &operator[](const Key &key);
+	const Val &operator[](const Key &key) const;
+
+	Val &getVal(const Key &key);
+	const Val &getVal(const Key &key) const;
+	const Val &getVal(const Key &key, const Val &defaultVal) const;
+	void setVal(const Key &key, const Val &val);
+
+	void clear(bool shrinkArray = 0);
+
+	void erase(const Key &key);
+
+	uint size() const { return _size; }
+
+	iterator	begin() {
+		// Find and return the first non-empty entry
+		for (uint ctr = 0; ctr <= _mask; ++ctr) {
+			if (_storage[ctr] && _storage[ctr] != HASHMAP_DUMMY_NODE)
+				return iterator(ctr, this);
+		}
+		return end();
+	}
+	iterator	end() {
+		return iterator((uint)-1, this);
+	}
+
+	const_iterator	begin() const {
+		// Find and return the first non-empty entry
+		for (uint ctr = 0; ctr <= _mask; ++ctr) {
+			if (_storage[ctr] && _storage[ctr] != HASHMAP_DUMMY_NODE)
+				return const_iterator(ctr, this);
+		}
+		return end();
+	}
+	const_iterator	end() const {
+		return const_iterator((uint)-1, this);
+	}
+
+	iterator	find(const Key &key) {
+		uint ctr = lookup(key);
+		if (_storage[ctr])
+			return iterator(ctr, this);
+		return end();
+	}
+
+	const_iterator	find(const Key &key) const {
+		uint ctr = lookup(key);
+		if (_storage[ctr])
+			return const_iterator(ctr, this);
+		return end();
+	}
+
+	// TODO: insert() method?
+
+	bool empty() const {
+		return (_size == 0);
+	}
+};
+
+//-------------------------------------------------------
+// HashMap functions
+
+/**
+ * Base constructor, creates an empty hashmap.
+ */
+template<class Key, class Val, class HashFunc, class EqualFunc>
+HashMap<Key, Val, HashFunc, EqualFunc>::HashMap()
+//
+// We have to skip _defaultVal() on PS2 to avoid gcc 3.2.2 ICE
+//
+#ifdef __PLAYSTATION2__
+	{
+#else
+	: _defaultVal() {
+#endif
+	_mask = HASHMAP_MIN_CAPACITY - 1;
+	_storage = new Node *[HASHMAP_MIN_CAPACITY];
+	assert(_storage != NULL);
+	memset(_storage, 0, HASHMAP_MIN_CAPACITY * sizeof(Node *));
+
+	_size = 0;
+	_deleted = 0;
+
+#ifdef DEBUG_HASH_COLLISIONS
+	_collisions = 0;
+	_lookups = 0;
+	_dummyHits = 0;
+#endif
+}
+
+/**
+ * Copy constructor, creates a full copy of the given hashmap.
+ * We must provide a custom copy constructor as we use pointers
+ * to heap buffers for the internal storage.
+ */
+template<class Key, class Val, class HashFunc, class EqualFunc>
+HashMap<Key, Val, HashFunc, EqualFunc>::HashMap(const HM_t &map) :
+	_defaultVal() {
+#ifdef DEBUG_HASH_COLLISIONS
+	_collisions = 0;
+	_lookups = 0;
+	_dummyHits = 0;
+#endif
+	assign(map);
+}
+
+/**
+ * Destructor, frees all used memory.
+ */
+template<class Key, class Val, class HashFunc, class EqualFunc>
+HashMap<Key, Val, HashFunc, EqualFunc>::~HashMap() {
+	for (uint ctr = 0; ctr <= _mask; ++ctr)
+	  freeNode(_storage[ctr]);
+
+	delete[] _storage;
+#ifdef DEBUG_HASH_COLLISIONS
+	extern void updateHashCollisionStats(int, int, int, int, int);
+	updateHashCollisionStats(_collisions, _dummyHits, _lookups, _mask+1, _size);
+#endif
+}
+
+/**
+ * Internal method for assigning the content of another HashMap
+ * to this one.
+ *
+ * @note We do *not* deallocate the previous storage here -- the caller is
+ *       responsible for doing that!
+ */
+template<class Key, class Val, class HashFunc, class EqualFunc>
+void HashMap<Key, Val, HashFunc, EqualFunc>::assign(const HM_t &map) {
+	_mask = map._mask;
+	_storage = new Node *[_mask+1];
+	assert(_storage != NULL);
+	memset(_storage, 0, (_mask+1) * sizeof(Node *));
+
+	// Simply clone the map given to us, one by one.
+	_size = 0;
+	_deleted = 0;
+	for (uint ctr = 0; ctr <= _mask; ++ctr) {
+		if (map._storage[ctr] == HASHMAP_DUMMY_NODE) {
+			_storage[ctr] = HASHMAP_DUMMY_NODE;
+			_deleted++;
+		} else if (map._storage[ctr] != NULL) {
+			_storage[ctr] = allocNode(map._storage[ctr]->_key);
+			_storage[ctr]->_value = map._storage[ctr]->_value;
+			_size++;
+		}
+	}
+	// Perform a sanity check (to help track down hashmap corruption)
+	assert(_size == map._size);
+	assert(_deleted == map._deleted);
+}
+
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+void HashMap<Key, Val, HashFunc, EqualFunc>::clear(bool shrinkArray) {
+	for (uint ctr = 0; ctr <= _mask; ++ctr) {
+		freeNode(_storage[ctr]);
+		_storage[ctr] = NULL;
+	}
+
+#ifdef USE_HASHMAP_MEMORY_POOL
+	_nodePool.freeUnusedPages();
+#endif
+
+	if (shrinkArray && _mask >= HASHMAP_MIN_CAPACITY) {
+		delete[] _storage;
+
+		_mask = HASHMAP_MIN_CAPACITY;
+		_storage = new Node *[HASHMAP_MIN_CAPACITY];
+		assert(_storage != NULL);
+		memset(_storage, 0, HASHMAP_MIN_CAPACITY * sizeof(Node *));
+	}
+
+	_size = 0;
+	_deleted = 0;
+}
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+void HashMap<Key, Val, HashFunc, EqualFunc>::expandStorage(uint newCapacity) {
+	assert(newCapacity > _mask+1);
+
+#ifndef NDEBUG
+	const uint old_size = _size;
+#endif
+	const uint old_mask = _mask;
+	Node **old_storage = _storage;
+
+	// allocate a new array
+	_size = 0;
+	_deleted = 0;
+	_mask = newCapacity - 1;
+	_storage = new Node *[newCapacity];
+	assert(_storage != NULL);
+	memset(_storage, 0, newCapacity * sizeof(Node *));
+
+	// rehash all the old elements
+	for (uint ctr = 0; ctr <= old_mask; ++ctr) {
+		if (old_storage[ctr] == NULL || old_storage[ctr] == HASHMAP_DUMMY_NODE)
+			continue;
+
+		// Insert the element from the old table into the new table.
+		// Since we know that no key exists twice in the old table, we
+		// can do this slightly better than by calling lookup, since we
+		// don't have to call _equal().
+		const uint hash = _hash(old_storage[ctr]->_key);
+		uint idx = hash & _mask;
+		for (uint perturb = hash; _storage[idx] != NULL && _storage[idx] != HASHMAP_DUMMY_NODE; perturb >>= HASHMAP_PERTURB_SHIFT) {
+			idx = (5 * idx + perturb + 1) & _mask;
+		}
+
+		_storage[idx] = old_storage[ctr];
+		_size++;
+	}
+
+	// Perform a sanity check: Old number of elements should match the new one!
+	// This check will fail if some previous operation corrupted this hashmap.
+	assert(_size == old_size);
+
+	delete[] old_storage;
+
+	return;
+}
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+int HashMap<Key, Val, HashFunc, EqualFunc>::lookup(const Key &key) const {
+	const uint hash = _hash(key);
+	uint ctr = hash & _mask;
+	for (uint perturb = hash; ; perturb >>= HASHMAP_PERTURB_SHIFT) {
+		if (_storage[ctr] == NULL)
+			break;
+		if (_storage[ctr] == HASHMAP_DUMMY_NODE) {
+#ifdef DEBUG_HASH_COLLISIONS
+			_dummyHits++;
+#endif
+		} else if (_equal(_storage[ctr]->_key, key))
+			break;
+
+		ctr = (5 * ctr + perturb + 1) & _mask;
+
+#ifdef DEBUG_HASH_COLLISIONS
+		_collisions++;
+#endif
+	}
+
+#ifdef DEBUG_HASH_COLLISIONS
+	_lookups++;
+	fprintf(stderr, "collisions %d, dummies hit %d, lookups %d, ratio %f in HashMap %p; size %d num elements %d\n",
+		_collisions, _dummyHits, _lookups, ((double) _collisions / (double)_lookups),
+		(const void *)this, _mask+1, _size);
+#endif
+
+	return ctr;
+}
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+int HashMap<Key, Val, HashFunc, EqualFunc>::lookupAndCreateIfMissing(const Key &key) {
+	const uint hash = _hash(key);
+	uint ctr = hash & _mask;
+	const uint NONE_FOUND = _mask + 1;
+	uint first_free = NONE_FOUND;
+	bool found = false;
+	for (uint perturb = hash; ; perturb >>= HASHMAP_PERTURB_SHIFT) {
+		if (_storage[ctr] == NULL)
+			break;
+		if (_storage[ctr] == HASHMAP_DUMMY_NODE) {
+#ifdef DEBUG_HASH_COLLISIONS
+			_dummyHits++;
+#endif
+			if (first_free != _mask + 1)
+				first_free = ctr;
+		} else if (_equal(_storage[ctr]->_key, key)) {
+			found = true;
+			break;
+		}
+
+		ctr = (5 * ctr + perturb + 1) & _mask;
+
+#ifdef DEBUG_HASH_COLLISIONS
+		_collisions++;
+#endif
+	}
+
+#ifdef DEBUG_HASH_COLLISIONS
+	_lookups++;
+	fprintf(stderr, "collisions %d, dummies hit %d, lookups %d, ratio %f in HashMap %p; size %d num elements %d\n",
+		_collisions, _dummyHits, _lookups, ((double) _collisions / (double)_lookups),
+		(const void *)this, _mask+1, _size);
+#endif
+
+	if (!found && first_free != _mask + 1)
+		ctr = first_free;
+
+	if (!found) {
+		if (_storage[ctr])
+			_deleted--;
+		_storage[ctr] = allocNode(key);
+		assert(_storage[ctr] != NULL);
+		_size++;
+
+		// Keep the load factor below a certain threshold.
+		// Deleted nodes are also counted
+		uint capacity = _mask + 1;
+		if ((_size + _deleted) * HASHMAP_LOADFACTOR_DENOMINATOR >
+		        capacity * HASHMAP_LOADFACTOR_NUMERATOR) {
+			capacity = capacity < 500 ? (capacity * 4) : (capacity * 2);
+			expandStorage(capacity);
+			ctr = lookup(key);
+			assert(_storage[ctr] != NULL);
+		}
+	}
+
+	return ctr;
+}
+
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+bool HashMap<Key, Val, HashFunc, EqualFunc>::contains(const Key &key) const {
+	uint ctr = lookup(key);
+	return (_storage[ctr] != NULL);
+}
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+Val &HashMap<Key, Val, HashFunc, EqualFunc>::operator[](const Key &key) {
+	return getVal(key);
+}
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+const Val &HashMap<Key, Val, HashFunc, EqualFunc>::operator[](const Key &key) const {
+	return getVal(key);
+}
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+Val &HashMap<Key, Val, HashFunc, EqualFunc>::getVal(const Key &key) {
+	uint ctr = lookupAndCreateIfMissing(key);
+	assert(_storage[ctr] != NULL);
+	return _storage[ctr]->_value;
+}
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+const Val &HashMap<Key, Val, HashFunc, EqualFunc>::getVal(const Key &key) const {
+	return getVal(key, _defaultVal);
+}
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+const Val &HashMap<Key, Val, HashFunc, EqualFunc>::getVal(const Key &key, const Val &defaultVal) const {
+	uint ctr = lookup(key);
+	if (_storage[ctr] != NULL)
+		return _storage[ctr]->_value;
+	else
+		return defaultVal;
+}
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+void HashMap<Key, Val, HashFunc, EqualFunc>::setVal(const Key &key, const Val &val) {
+	uint ctr = lookupAndCreateIfMissing(key);
+	assert(_storage[ctr] != NULL);
+	_storage[ctr]->_value = val;
+}
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+void HashMap<Key, Val, HashFunc, EqualFunc>::erase(const Key &key) {
+
+	uint ctr = lookup(key);
+	if (_storage[ctr] == NULL)
+		return;
+
+	// If we remove a key, we replace it with a dummy node.
+	freeNode(_storage[ctr]);
+	_storage[ctr] = HASHMAP_DUMMY_NODE;
+	_size--;
+	_deleted++;
+	return;
+}
+
+#undef HASHMAP_DUMMY_NODE
+
+}	// End of namespace Common
+
+#endif


Property changes on: tools/trunk/common/hashmap.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: tools/trunk/common/memorypool.cpp
===================================================================
--- tools/trunk/common/memorypool.cpp	                        (rev 0)
+++ tools/trunk/common/memorypool.cpp	2010-01-18 15:40:49 UTC (rev 47355)
@@ -0,0 +1,183 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/memorypool.h"
+#include "common/util.h"
+
+namespace Common {
+
+enum {
+	INITIAL_CHUNKS_PER_PAGE = 8
+};
+
+static size_t adjustChunkSize(size_t chunkSize) {
+	// You must at least fit the pointer in the node (technically unneeded considering the next rounding statement)
+	chunkSize = MAX(chunkSize, sizeof(void*));
+	// There might be an alignment problem on some platforms when trying to load a void* on a non natural boundary
+	// so we round to the next sizeof(void*)
+	chunkSize = (chunkSize + sizeof(void*) - 1) & (~(sizeof(void*) - 1));
+
+	return chunkSize;
+}
+
+
+MemoryPool::MemoryPool(size_t chunkSize)
+	: _chunkSize(adjustChunkSize(chunkSize)) {
+
+	_next = NULL;
+
+	_chunksPerPage = INITIAL_CHUNKS_PER_PAGE;
+}
+
+MemoryPool::~MemoryPool() {
+#if 0
+	freeUnusedPages();
+	if (!_pages.empty())
+		warning("Memory leak found in pool");
+#endif
+
+	for (size_t i = 0; i < _pages.size(); ++i)
+		::free(_pages[i].start);
+}
+
+void MemoryPool::allocPage() {
+	Page page;
+
+	// Allocate a new page
+	page.numChunks = _chunksPerPage;
+	assert(page.numChunks * _chunkSize < 16*1024*1024);	// Refuse to allocate pages bigger than 16 MB
+
+	page.start = ::malloc(page.numChunks * _chunkSize);
+	assert(page.start);
+	_pages.push_back(page);
+
+
+	// Next time, we'll allocate a page twice as big as this one.
+	_chunksPerPage *= 2;
+
+	// Add the page to the pool of free chunk
+	addPageToPool(page);
+}
+
+void MemoryPool::addPageToPool(const Page &page) {
+
+	// Add all chunks of the new page to the linked list (pool) of free chunks
+	void *current = page.start;
+	for (size_t i = 1; i < page.numChunks; ++i) {
+		void *next    = ((char*)current + _chunkSize);
+		*(void **)current = next;
+
+		current = next;
+	}
+
+	// Last chunk points to the old _next
+	*(void**)current = _next;
+
+	// From now on, the first free chunk is the first chunk of the new page
+	_next = page.start;
+}
+
+void *MemoryPool::allocChunk() {
+	if (!_next)	// No free chunks left? Allocate a new page
+		allocPage();
+
+	assert(_next);
+	void *result = _next;
+	_next = *(void**)result;
+	return result;
+}
+
+void MemoryPool::freeChunk(void *ptr) {
+	// Add the chunk back to (the start of) the list of free chunks
+	*(void**)ptr = _next;
+	_next = ptr;
+}
+
+// Technically not compliant C++ to compare unrelated pointers. In practice...
+bool MemoryPool::isPointerInPage(void *ptr, const Page &page) {
+	return (ptr >= page.start) && (ptr < (char*)page.start + page.numChunks * _chunkSize);
+}
+
+void MemoryPool::freeUnusedPages() {
+	//std::sort(_pages.begin(), _pages.end());
+	Array<size_t> numberOfFreeChunksPerPage;
+	numberOfFreeChunksPerPage.resize(_pages.size());
+	for (size_t i = 0; i < numberOfFreeChunksPerPage.size(); ++i) {
+		numberOfFreeChunksPerPage[i] = 0;
+	}
+
+	// Compute for each page how many chunks in it are still in use.
+	void *iterator = _next;
+	while (iterator) {
+		// TODO: This should be a binary search (requiring us to keep _pages sorted)
+		for (size_t i = 0; i < _pages.size(); ++i) {
+			if (isPointerInPage(iterator, _pages[i])) {
+				++numberOfFreeChunksPerPage[i];
+				break;
+			}
+		}
+		iterator = *(void**)iterator;
+	}
+
+	// Free all pages which are not in use.
+	size_t freedPagesCount = 0;
+	for (size_t i = 0; i < _pages.size(); ++i)  {
+		if (numberOfFreeChunksPerPage[i] == _pages[i].numChunks) {
+			// Remove all chunks of this page from the list of free chunks
+			void **iter2 = &_next;
+			while (*iter2) {
+				if (isPointerInPage(*iter2, _pages[i]))
+					*iter2 = **(void***)iter2;
+				else
+					iter2 = *(void***)iter2;
+			}
+			::free(_pages[i].start);
+			++freedPagesCount;
+			_pages[i].start = NULL;
+		}
+	}
+
+//	printf("freed %d pages out of %d\n", (int)freedPagesCount, (int)_pages.size());
+
+	// Remove all now unused pages
+	size_t newSize = 0;
+	for (size_t i = 0; i < _pages.size(); ++i) {
+		if (_pages[i].start != NULL) {
+			if (newSize != i)
+				_pages[newSize] = _pages[i];
+			++newSize;
+		}
+	}
+	_pages.resize(newSize);
+
+	// Reset _chunksPerPage
+	_chunksPerPage = INITIAL_CHUNKS_PER_PAGE;
+	for (size_t i = 0; i < _pages.size(); ++i) {
+		if (_chunksPerPage < _pages[i].numChunks)
+			_chunksPerPage = _pages[i].numChunks;
+	}
+}
+
+}	// End of namespace Common


Property changes on: tools/trunk/common/memorypool.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: tools/trunk/common/memorypool.h
===================================================================
--- tools/trunk/common/memorypool.h	                        (rev 0)
+++ tools/trunk/common/memorypool.h	2010-01-18 15:40:49 UTC (rev 47355)
@@ -0,0 +1,166 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef COMMON_MEMORYPOOL_H
+#define COMMON_MEMORYPOOL_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+
+
+namespace Common {
+
+/**
+ * This class provides a pool of memory 'chunks' of identical size.
+ * The size of a chunk is determined when creating the memory pool.
+ *
+ * Using a memory pool may yield better performance and memory usage
+ * when allocating and deallocating many memory blocks of equal size.
+ * E.g. the Common::String class uses a memory pool for the refCount
+ * variables (each the size of an int) it allocates for each string
+ * instance.
+ */
+class MemoryPool {
+protected:
+	MemoryPool(const MemoryPool&);
+	MemoryPool& operator=(const MemoryPool&);
+
+	struct Page {
+		void *start;
+		size_t numChunks;
+	};
+
+	const size_t	_chunkSize;
+	Array<Page>		_pages;
+	void			*_next;
+	size_t			_chunksPerPage;
+
+	void	allocPage();
+	void	addPageToPool(const Page &page);
+	bool	isPointerInPage(void *ptr, const Page &page);
+
+public:
+	/**
+	 * Constructor for a memory pool with the given chunk size.
+	 * @param chunkSize		the chunk size of this memory pool
+	 */
+	MemoryPool(size_t chunkSize);
+	~MemoryPool();
+
+	/**
+	 * Allocate a new chunk from the memory pool.
+	 */
+	void	*allocChunk();
+	/**
+	 * Return a chunk to the memory pool. The given pointer must have
+	 * been obtained from calling the allocChunk() method of the very
+	 * same MemoryPool instance. Passing any other pointer (e.g. to
+	 * a chunk from another MemoryPool, or a malloc'ed memory block)
+	 * will lead to undefined behavior and may result in a crash (if
+	 * you are lucky) or in silent data corruption.
+	 */
+	void	freeChunk(void *ptr);
+
+	/**
+	 * Perform garbage collection. The memory pool stores all the
+	 * chunks it manages in memory 'pages' obtained via the classic
+	 * memory allocation APIs (i.e. malloc/free). Ordinarily, once
+	 * a page has been allocated, it won't be released again during
+	 * the life time of the memory pool. The exception is when this
+	 * method is called.
+	 */
+	void	freeUnusedPages();
+
+	/**
+	 * Return the chunk size used by this memory pool.
+	 */
+	size_t	getChunkSize() const { return _chunkSize; }
+};
+
+/**
+ * This is a memory pool which already contains in itself some storage
+ * space for a fixed number of chunks. Thus if the memory pool is only
+ * lightly used, no malloc() calls have to be made at all.
+ */
+template<size_t CHUNK_SIZE, size_t NUM_INTERNAL_CHUNKS = 32>
+class FixedSizeMemoryPool : public MemoryPool {
+private:
+	enum {
+		REAL_CHUNK_SIZE = (CHUNK_SIZE + sizeof(void*) - 1) & (~(sizeof(void*) - 1))
+	};
+
+	byte	_storage[NUM_INTERNAL_CHUNKS * REAL_CHUNK_SIZE];
+public:
+	FixedSizeMemoryPool() : MemoryPool(CHUNK_SIZE) {
+		assert(REAL_CHUNK_SIZE == _chunkSize);
+		// Insert some static storage
+		Page internalPage = { _storage, NUM_INTERNAL_CHUNKS };
+		addPageToPool(internalPage);
+	}
+};
+
+// Ensure NUM_INTERNAL_CHUNKS == 0 results in a compile error
+template<size_t CHUNK_SIZE>
+class FixedSizeMemoryPool<CHUNK_SIZE,0> : public MemoryPool {
+public:
+	FixedSizeMemoryPool() : MemoryPool(CHUNK_SIZE) {}
+};
+
+/**
+ * A memory pool for C++ objects.
+ */
+template<class T, size_t NUM_INTERNAL_CHUNKS = 32>
+class ObjectPool : public FixedSizeMemoryPool<sizeof(T), NUM_INTERNAL_CHUNKS> {
+public:
+	/**
+	 * Return the memory chunk used as storage for the given object back
+	 * to the pool, after calling its destructor.
+	 */
+	void deleteChunk(T *ptr) {
+		ptr->~T();
+		this->freeChunk(ptr);
+	}
+};
+
+}	// End of namespace Common
+
+/**
+ * A custom placement new operator, using an arbitrary MemoryPool.
+ *
+ * This *should* work with all C++ implementations, but may not.
+ *
+ * For details on using placement new for custom allocators, see e.g.
+ * <http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.14>
+ */
+inline void* operator new(size_t nbytes, Common::MemoryPool& pool) {
+	assert(nbytes <= pool.getChunkSize());
+	return pool.allocChunk();
+}
+
+inline void operator delete(void* p, Common::MemoryPool& pool) {
+	pool.freeChunk(p);
+}
+
+#endif


Property changes on: tools/trunk/common/memorypool.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Modified: tools/trunk/common/scummsys.h
===================================================================
--- tools/trunk/common/scummsys.h	2010-01-18 07:21:54 UTC (rev 47354)
+++ tools/trunk/common/scummsys.h	2010-01-18 15:40:49 UTC (rev 47355)
@@ -97,8 +97,10 @@
  */
 #if defined(__GNUC__)
 	#define GCC_PACK __attribute__((packed))
+	#define GCC_PRINTF(x,y) __attribute__((format(printf, x, y)))
 #else
 	#define GCC_PACK
+	#define GCC_PRINTF(x,y)
 #endif
 
 #ifndef ARRAYSIZE

Modified: tools/trunk/engines/mohawk/mohawk_file.cpp
===================================================================
--- tools/trunk/engines/mohawk/mohawk_file.cpp	2010-01-18 07:21:54 UTC (rev 47354)
+++ tools/trunk/engines/mohawk/mohawk_file.cpp	2010-01-18 15:40:49 UTC (rev 47355)
@@ -28,6 +28,21 @@
 		   | (uint16)((high >> 8) | (high << 8));
 }
 
+Common::String MohawkFile::tag2string(uint32 tag) {
+	char str[5];
+	str[0] = (char)(tag >> 24);
+	str[1] = (char)(tag >> 16);
+	str[2] = (char)(tag >> 8);
+	str[3] = (char)tag;
+	str[4] = '\0';
+	// Replace non-printable chars by dot
+	for (int i = 0; i < 4; ++i) {
+		if (!isprint(str[i]))
+			str[i] = '.';
+	}
+	return Common::String(str);
+}
+
 MohawkFile::MohawkFile() {
 	_mhk = NULL;
 	_curFile = Common::String::emptyString;

Modified: tools/trunk/engines/mohawk/mohawk_file.h
===================================================================
--- tools/trunk/engines/mohawk/mohawk_file.h	2010-01-18 07:21:54 UTC (rev 47354)
+++ tools/trunk/engines/mohawk/mohawk_file.h	2010-01-18 15:40:49 UTC (rev 47355)
@@ -23,7 +23,7 @@
 #ifndef MOHAWK_FILE_H
 #define MOHAWK_FILE_H
 
-#include "utils/str.h"
+#include "common/str.h"
 #include "utils/stream.h"
 
 // Main FourCC's
@@ -116,6 +116,8 @@
 #define ID_BBOX MKID_BE('BBOX') // Boxes? (CSWorld, CSAmtrak)
 #define ID_SYSX MKID_BE('SYSX') // MIDI Sysex
 
+#define tag2str(x)	MohawkFile::tag2string(x).c_str()
+
 struct MohawkOutputStream {
 	Common::SeekableSubReadStream *stream;
 	uint32 tag;
@@ -183,6 +185,8 @@
 	virtual MohawkOutputStream getRawData(uint32 tag, uint16 id);
 	virtual MohawkOutputStream getNextFile();
 
+	static Common::String tag2string(uint32 tag);
+
 protected:
 	Common::SeekableReadStream *_mhk;
 	TypeTable _typeTable;

Modified: tools/trunk/engines/mohawk/util.h
===================================================================
--- tools/trunk/engines/mohawk/util.h	2010-01-18 07:21:54 UTC (rev 47354)
+++ tools/trunk/engines/mohawk/util.h	2010-01-18 15:40:49 UTC (rev 47355)
@@ -23,11 +23,8 @@
 #ifndef UTIL_H
 #define UTIL_H
 
-#include <assert.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#include "common/scummsys.h"
+
 #include <sys/stat.h>
 
 #if !defined(_MSC_VER)
@@ -39,24 +36,6 @@
 #include <process.h>
 #endif
 
-
-/*
- * Some useful types
- */
-
-typedef unsigned char byte;
-typedef unsigned char uint8;
-typedef unsigned short uint16;
-typedef signed char int8;
-typedef signed short int16;
-#ifdef __amigaos4__
-#include <exec/types.h>
-#include <stdlib.h>
-#else
-typedef unsigned int uint32;
-typedef signed int int32;
-#endif
-
 typedef uint32 uint;
 
 /*
@@ -102,16 +81,12 @@
  * GCC specific stuff
  */
 #if defined(__GNUC__)
-        #define GCC_PACK __attribute__((packed))
-        #define NORETURN __attribute__((__noreturn__))
-        #define GCC_PRINTF(x,y) __attribute__((format(printf, x, y)))
+	#define GCC_PACK __attribute__((packed))
+	#define NORETURN __attribute__((__noreturn__))
 #else
-        #define GCC_PACK
-        #define GCC_PRINTF(x,y)
+	#define GCC_PACK
 #endif
 
-#define ARRAYSIZE(x) ((int)(sizeof(x) / sizeof(x[0])))
-
 #if defined(INVERSE_MKID)
 #define MKID_BE(a) ((uint32) \
 		(((a) >> 24) & 0x000000FF) | \

Deleted: tools/trunk/engines/mohawk/utils/str.cpp
===================================================================
--- tools/trunk/engines/mohawk/utils/str.cpp	2010-01-18 07:21:54 UTC (rev 47354)
+++ tools/trunk/engines/mohawk/utils/str.cpp	2010-01-18 15:40:49 UTC (rev 47355)
@@ -1,621 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#include "str.h"
-#include "util.h"
-
-//#include "engines/mohawk/utils/str.h"
-//#include "engines/mohawk/utils/util.h"
-
-#if !defined(__SYMBIAN32__)
-#include <new>
-#endif
-
-
-namespace Common {
-
-#if !(defined(PALMOS_ARM) || defined(PALMOS_DEBUG) || defined(__GP32__))
-const String String::emptyString;
-#else
-const char *String::emptyString = "";
-#endif
-
-static uint32 computeCapacity(uint32 len) {
-	// By default, for the capacity we use the next multiple of 32
-	return ((len + 32 - 1) & ~0x1F);
-}
-
-String::String(const char *str) : _size(0), _str(_storage) {
-	if (str == 0) {
-		_storage[0] = 0;
-		_size = 0;
-	} else
-		initWithCStr(str, strlen(str));
-}
-
-String::String(const char *str, uint32 len) : _size(0), _str(_storage) {
-	initWithCStr(str, len);
-}
-
-String::String(const char *beginP, const char *endP) : _size(0), _str(_storage) {
-	assert(endP >= beginP);
-	initWithCStr(beginP, endP - beginP);
-}
-
-void String::initWithCStr(const char *str, uint32 len) {
-	assert(str);
-
-	// Init _storage member explicitly (ie. without calling its constructor)
-	// for GCC 2.95.x compatibility (see also tracker item #1602879).
-	_storage[0] = 0;
-
-	_size = len;
-
-	if (len >= _builtinCapacity) {
-		// Not enough internal storage, so allocate more
-		_extern._capacity = computeCapacity(len+1);
-		_str = (char *)malloc(_extern._capacity);
-		assert(_str != 0);
-	}
-
-	// Copy the string into the storage area
-	memmove(_str, str, len);
-	_str[len] = 0;
-}
-
-String::String(const String &str)
- : _size(str._size) {
-	if (str.isStorageIntern()) {
-		// String in internal storage: just copy it
-		memcpy(_storage, str._storage, _builtinCapacity);
-		_str = _storage;
-	} else {
-		// String in external storage
-		_extern._capacity = str._extern._capacity;
-		_str = str._str;
-	}
-	assert(_str != 0);
-}
-
-String::String(char c)
-: _size(0), _str(_storage) {
-
-	_storage[0] = c;
-	_storage[1] = 0;
-
-	// TODO/FIXME: There is no reason for the following check -- we *do*
-	// allow strings to contain 0 bytes!
-	_size = (c == 0) ? 0 : 1;
-}
-
-String::~String() {
-}
-
-void String::makeUnique() {
-	ensureCapacity(_size, true);
-}
-
-/**
- * Ensure that enough storage is available to store at least new_size
- * characters plus a null byte. In addition, if we currently share
- * the storage with another string, unshare it, so that we can safely
- * write to the storage.
- */
-void String::ensureCapacity(uint32 new_size, bool keep_old) {
-	bool isShared = false;
-	uint32 curCapacity, newCapacity;
-	char *newStorage;
-
-	if (isStorageIntern()) {
-		isShared = false;
-		curCapacity = _builtinCapacity;
-	} else {
-		curCapacity = _extern._capacity;
-	}
-
-	// Special case: If there is enough space, and we do not share
-	// the storage, then there is nothing to do.
-	if (!isShared && new_size < curCapacity)
-		return;
-
-	if (isShared && new_size < _builtinCapacity) {
-		// We share the storage, but there is enough internal storage: Use that.
-		newStorage = _storage;
-		newCapacity = _builtinCapacity;
-	} else {
-		// We need to allocate storage on the heap!
-
-		// Compute a suitable new capacity limit
-		newCapacity = MAX(curCapacity * 2, computeCapacity(new_size+1));
-
-		// Allocate new storage
-		newStorage = (char *)malloc(newCapacity);
-		assert(newStorage);
-	}
-
-	// Copy old data if needed, elsewise reset the new storage.
-	if (keep_old) {
-		assert(_size < newCapacity);
-		memcpy(newStorage, _str, _size + 1);
-	} else {
-		_size = 0;
-		newStorage[0] = 0;
-	}
-
-	// ... in favor of the new storage
-	_str = newStorage;
-
-	if (!isStorageIntern()) {
-		// Set the ref count & capacity if we use an external storage.
-		// It is important to do this *after* copying any old content,
-		// else we would override data that has not yet been copied!
-		_extern._capacity = newCapacity;
-	}
-}
-
-String& String::operator  =(const char *str) {
-	uint32 len = strlen(str);
-	ensureCapacity(len, false);
-	_size = len;
-	memmove(_str, str, len + 1);
-	return *this;
-}
-
-String &String::operator  =(const String &str) {
-	if (&str == this)
-		return *this;
-
-	if (str.isStorageIntern()) {
-		_size = str._size;
-		_str = _storage;
-		memcpy(_str, str._str, _size + 1);
-	} else {
-		_extern._capacity = str._extern._capacity;
-		_size = str._size;
-		_str = str._str;
-	}
-
-	return *this;
-}
-
-String& String::operator  =(char c) {
-	_str = _storage;
-	_size = 1;
-	_str[0] = c;
-	_str[1] = 0;
-	return *this;
-}
-
-String &String::operator +=(const char *str) {
-	int len = strlen(str);
-	if (len > 0) {
-		ensureCapacity(_size + len, true);
-
-		memcpy(_str + _size, str, len + 1);
-		_size += len;
-	}
-	return *this;
-}
-
-String &String::operator +=(const String &str) {
-	int len = str._size;
-	if (len > 0) {
-		ensureCapacity(_size + len, true);
-
-		memcpy(_str + _size, str._str, len + 1);
-		_size += len;
-	}
-	return *this;
-}
-
-String &String::operator +=(char c) {
-	ensureCapacity(_size + 1, true);
-
-	_str[_size++] = c;
-	_str[_size] = 0;
-
-	return *this;
-}
-
-bool String::hasPrefix(const char *x) const {
-	assert(x != 0);
-	// Compare x with the start of _str.
-	const char *y = c_str();
-	while (*x && *x == *y) {
-		++x;
-		++y;
-	}
-	// It's a prefix, if and only if all letters in x are 'used up' before
-	// _str ends.
-	return *x == 0;
-}
-
-bool String::hasSuffix(const char *x) const {
-	assert(x != 0);
-	// Compare x with the end of _str.
-	const uint32 x_size = strlen(x);
-	if (x_size > _size)
-		return false;
-	const char *y = c_str() + _size - x_size;
-	while (*x && *x == *y) {
-		++x;
-		++y;
-	}
-	// It's a suffix, if and only if all letters in x are 'used up' before
-	// _str ends.
-	return *x == 0;
-}
-
-bool String::contains(const char *x) const {
-	assert(x != 0);
-	return strstr(c_str(), x) != NULL;
-}
-
-bool String::contains(char x) const {
-	return strchr(c_str(), x) != NULL;
-}
-
-bool String::matchString(const char *pat, bool pathMode) const {
-	return Common::matchString(c_str(), pat, pathMode);
-}
-
-bool String::matchString(const String &pat, bool pathMode) const {
-	return Common::matchString(c_str(), pat.c_str(), pathMode);
-}
-
-void String::deleteLastChar() {
-	if (_size > 0)
-		deleteChar(_size - 1);
-}
-
-void String::deleteChar(uint32 p) {
-	assert(p < _size);
-
-	makeUnique();
-	while (p++ < _size)
-		_str[p-1] = _str[p];
-	_size--;
-}
-
-void String::clear() {
-	_size = 0;
-	_str = _storage;
-	_storage[0] = 0;
-}
-
-void String::setChar(char c, uint32 p) {
-	assert(p <= _size);
-
-	makeUnique();
-	_str[p] = c;
-}
-
-void String::insertChar(char c, uint32 p) {
-	assert(p <= _size);
-
-	ensureCapacity(_size + 1, true);
-	_size++;
-	for (uint32 i = _size; i > p; --i)
-		_str[i] = _str[i-1];
-	_str[p] = c;
-}
-
-void String::toLowercase() {
-	makeUnique();
-	for (uint32 i = 0; i < _size; ++i)
-		_str[i] = tolower(_str[i]);
-}
-
-void String::toUppercase() {
-	makeUnique();
-	for (uint32 i = 0; i < _size; ++i)
-		_str[i] = toupper(_str[i]);
-}
-
-void String::trim() {
-	if (_size == 0)
-		return;
-
-	makeUnique();
-
-	// Trim trailing whitespace
-	while (_size >= 1 && isspace(_str[_size-1]))
-		_size--;
-	_str[_size] = 0;
-
-	// Trim leading whitespace
-	char *t = _str;
-	while (isspace(*t))
-		t++;
-
-	if (t != _str) {
-		_size -= t - _str;
-		memmove(_str, t, _size + 1);
-	}
-}
-
-#pragma mark -
-
-bool String::operator ==(const String &x) const {
-	return equals(x);
-}
-
-bool String::operator ==(const char *x) const {
-	assert(x != 0);
-	return equals(x);
-}
-
-bool String::operator !=(const String &x) const {
-	return !equals(x);
-}
-
-bool String::operator !=(const char *x) const {
-	assert(x != 0);
-	return !equals(x);
-}
-
-bool String::operator < (const String &x) const {
-	return compareTo(x) < 0;
-}
-
-bool String::operator <= (const String &x) const {
-	return compareTo(x) <= 0;
-}
-
-bool String::operator > (const String &x) const {
-	return compareTo(x) > 0;
-}
-
-bool String::operator >= (const String &x) const {
-	return compareTo(x) >= 0;
-}
-
-#pragma mark -
-
-bool operator == (const char* y, const String &x) {
-	return (x == y);
-}
-
-bool operator != (const char* y, const String &x) {
-	return x != y;
-}
-
-#pragma mark -
-
-bool String::equals(const String &x) const {
-	return (0 == compareTo(x));
-}
-
-bool String::equals(const char *x) const {
-	assert(x != 0);
-	return (0 == compareTo(x));
-}
-
-bool String::equalsIgnoreCase(const String &x) const {
-	return (0 == compareToIgnoreCase(x));
-}
-
-bool String::equalsIgnoreCase(const char *x) const {
-	assert(x != 0);
-	return (0 == compareToIgnoreCase(x));
-}
-
-int String::compareTo(const String &x) const {
-	return compareTo(x.c_str());
-}
-
-int String::compareTo(const char *x) const {
-	assert(x != 0);
-	return strcmp(c_str(), x);
-}
-
-int String::compareToIgnoreCase(const String &x) const {
-	return compareToIgnoreCase(x.c_str());
-}
-
-int String::compareToIgnoreCase(const char *x) const {
-	assert(x != 0);
-	return scumm_stricmp(c_str(), x);
-}
-
-#pragma mark -
-
-String operator +(const String &x, const String &y) {
-	String temp(x);
-	temp += y;
-	return temp;
-}
-
-String operator +(const char *x, const String &y) {
-	String temp(x);
-	temp += y;
-	return temp;
-}
-
-String operator +(const String &x, const char *y) {
-	String temp(x);
-	temp += y;
-	return temp;
-}
-
-String operator +(char x, const String &y) {
-	String temp(x);
-	temp += y;
-	return temp;
-}
-
-String operator +(const String &x, char y) {
-	String temp(x);
-	temp += y;
-	return temp;
-}
-
-char *ltrim(char *t) {
-	while (isspace(*t))
-		t++;
-	return t;
-}
-
-char *rtrim(char *t) {
-	int l = strlen(t) - 1;
-	while (l >= 0 && isspace(t[l]))
-		t[l--] = 0;
-	return t;
-}
-
-char *trim(char *t) {
-	return rtrim(ltrim(t));
-}
-
-Common::String lastPathComponent(const Common::String &path, const char sep) {
-	const char *str = path.c_str();
-	const char *last = str + path.size();
-
-	// Skip over trailing slashes
-	while (last > str && *(last-1) == sep)
-		--last;
-
-	// Path consisted of only slashes -> return empty string
-	if (last == str)
-		return Common::String();
-
-	// Now scan the whole component
-	const char *first = last - 1;
-	while (first >= str && *first != sep)
-		--first;
-
-	if (*first == sep)
-		first++;
-
-	return Common::String(first, last);
-}
-
-Common::String normalizePath(const Common::String &path, const char sep) {
-	if (path.empty())
-		return path;
-
-	const char *cur = path.c_str();
-	Common::String result;
-
-	// If there is a leading slash, preserve that:
-	if (*cur == sep) {
-		result += sep;
-		while (*cur == sep)
-			++cur;
-	}
-
-	// Scan till the end of the String
-	while (*cur != 0) {
-		const char *start = cur;
-
-		// Scan till the next path separator resp. the end of the string
-		while (*cur != sep && *cur != 0)
-			cur++;
-
-		const Common::String component(start, cur);
-
-		// Skip empty components and dot components, add all others
-		if (!component.empty() && component != ".") {
-			// Add a separator before the component, unless the result
-			// string already ends with one (which happens only if the
-			// path *starts* with a separator).
-			if (!result.empty() && result.lastChar() != sep)
-				result += sep;
-
-			// Add the component
-			result += component;
-		}
-
-		// Skip over separator chars
-		while (*cur == sep)
-			cur++;
-	}
-
-	return result;
-}
-
-bool matchString(const char *str, const char *pat, bool pathMode) {
-	assert(str);
-	assert(pat);
-
-	const char *p = 0;
-	const char *q = 0;
-
-	for (;;) {
-		if (pathMode && *str == '/') {
-			p = 0;
-			q = 0;
-			if (*pat == '?')
-				return false;
-		}
-
-		switch (*pat) {
-		case '*':
-			// Record pattern / string possition for backtracking
-			p = ++pat;
-			q = str;
-			// If pattern ended with * -> match
-			if (!*pat)
-				return true;
-			break;
-
-		default:
-			if (*pat != *str) {
-				if (p) {
-					// No match, oops -> try to backtrack
-					pat = p;
-					str = ++q;
-					if (!*str)
-						return !*pat;
-					break;
-				}
-				else
-					return false;
-			}
-			// fallthrough
-		case '?':
-			if (!*str)
-				return !*pat;
-			pat++;
-			str++;
-		}
-	}
-}
-
-String tag2string(uint32 tag) {
-	char str[5];
-	str[0] = (char)(tag >> 24);
-	str[1] = (char)(tag >> 16);
-	str[2] = (char)(tag >> 8);
-	str[3] = (char)tag;
-	str[4] = '\0';
-	// Replace non-printable chars by dot
-	for (int i = 0; i < 4; ++i) {
-		if (!isprint(str[i]))
-			str[i] = '.';
-	}
-	return Common::String(str);
-}
-
-}	// End of namespace Common

Deleted: tools/trunk/engines/mohawk/utils/str.h
===================================================================
--- tools/trunk/engines/mohawk/utils/str.h	2010-01-18 07:21:54 UTC (rev 47354)
+++ tools/trunk/engines/mohawk/utils/str.h	2010-01-18 15:40:49 UTC (rev 47355)
@@ -1,332 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#ifndef COMMON_STRING_H
-#define COMMON_STRING_H
-
-#include "common/array.h"
-
-namespace Common {
-
-/**
- * Simple string class for ScummVM. Provides automatic storage managment,
- * and overloads several operators in a 'natural' fashion, mimicking
- * the std::string class. Even provides simple iterators.
- *
- * This class tries to avoid allocating lots of small blocks on the heap,
- * since that is inefficient on several platforms supported by ScummVM.
- * Instead, small strings are stored 'inside' the string object (i.e. on
- * the stack, for stack allocated objects), and only for strings exceeding
- * a certain length do we allocate a buffer on the heap.
- */
-class String {
-protected:
-	/**
-	 * The size of the internal storage. Increasing this means less heap
-	 * allocations are needed, at the cost of more stack memory usage,
-	 * and of course lots of wasted memory. Empirically, 90% or more of
-	 * all String instances are less than 32 chars long. If a platform
-	 * is very short on stack space, it would be possible to lower this.
-	 * A value of 24 still seems acceptable, though considerably worse,
-	 * while 16 seems to be the lowest you want to go... Anything lower
-	 * than 8 makes no sense, since that's the size of member _extern
-	 * (on 32 bit machines; 12 bytes on systems with 64bit pointers).
-	 */
-	static const uint32 _builtinCapacity = 32 - sizeof(uint32) - sizeof(char*);
-
-	/**
-	 * Length of the string. Stored to avoid having to call strlen
-	 * a lot. Yes, we limit ourselves to strings shorter than 4GB --
-	 * on purpose :-).
-	 */
-	uint32		_size;
-
-	/**
-	 * Pointer to the actual string storage. Either points to _storage,
-	 * or to a block allocated on the heap via malloc.
-	 */
-	char		*_str;
-
-
-	union {
-		/**
-		 * Internal string storage.
-		 */
-		char _storage[_builtinCapacity];
-		/**
-		 * External string storage data -- the capacity of the string
-		 * _str points to.
-		 */
-		struct {
-			uint32		_capacity;
-		} _extern;
-	};
-
-	inline bool isStorageIntern() const {
-		return _str == _storage;
-	}
-
-public:
-#if !(defined(PALMOS_ARM) || defined(PALMOS_DEBUG) || defined(__GP32__))
-	static const String emptyString;
-#else
-	static const char *emptyString;
-#endif
-
-	/** Construct a new empty string. */
-	String() : _size(0), _str(_storage) { _storage[0] = 0; }
-
-	/** Construct a new string from the given NULL-terminated C string. */
-	String(const char *str);
-
-	/** Construct a new string containing exactly len characters read from address str. */
-	String(const char *str, uint32 len);
-
-	/** Construct a new string containing the characters between beginP (including) and endP (excluding). */
-	String(const char *beginP, const char *endP);
-
-	/** Construct a copy of the given string. */
-	String(const String &str);
-
-	/** Construct a string consisting of the given character. */
-	explicit String(char c);
-
-	~String();
-
-	String &operator  =(const char *str);
-	String &operator  =(const String &str);
-	String &operator  =(char c);
-	String &operator +=(const char *str);
-	String &operator +=(const String &str);
-	String &operator +=(char c);
-
-	bool operator ==(const String &x) const;
-	bool operator ==(const char *x) const;
-	bool operator !=(const String &x) const;
-	bool operator !=(const char *x) const;
-
-	bool operator <(const String &x) const;
-	bool operator <=(const String &x) const;
-	bool operator >(const String &x) const;
-	bool operator >=(const String &x) const;
-
-	bool equals(const String &x) const;
-	bool equalsIgnoreCase(const String &x) const;
-	int compareTo(const String &x) const;	// strcmp clone
-	int compareToIgnoreCase(const String &x) const;	// stricmp clone
-
-	bool equals(const char *x) const;
-	bool equalsIgnoreCase(const char *x) const;
-	int compareTo(const char *x) const;	// strcmp clone
-	int compareToIgnoreCase(const char *x) const;	// stricmp clone
-
-	bool hasSuffix(const char *x) const;
-	bool hasPrefix(const char *x) const;
-
-	bool contains(const char *x) const;
-	bool contains(char x) const;
-
-	/**
-	 * Simple DOS-style pattern matching function (understands * and ? like used in DOS).
-	 * Taken from exult/files/listfiles.cc
-	 *
-	 * Token meaning:
-	 *		"*": any character, any amount of times.
-	 *		"?": any character, only once.
-	 *
-	 * Example strings/patterns:
-	 *		String: monkey.s01	 Pattern: monkey.s??	=> true
-	 *		String: monkey.s101	 Pattern: monkey.s??	=> false
-	 *		String: monkey.s99	 Pattern: monkey.s?1	=> false
-	 *		String: monkey.s101	 Pattern: monkey.s*		=> true
-	 *		String: monkey.s99	 Pattern: monkey.s*1	=> false
-	 *
-	 * @param str Text to be matched against the given pattern.
-	 * @param pat Glob pattern.
-	 * @param pathMode Whether to use path mode, i.e., whether slashes must be matched explicitly.
-	 *
-	 * @return true if str matches the pattern, false otherwise.
-	 */
-	bool matchString(const char *pat, bool pathMode = false) const;
-	bool matchString(const String &pat, bool pathMode = false) const;
-
-
-	inline const char *c_str() const		{ return _str; }
-	inline uint size() const				{ return _size; }
-
-	inline bool empty() const	{ return (_size == 0); }
-	char lastChar() const	{ return (_size > 0) ? _str[_size-1] : 0; }
-
-	char operator[](int idx) const {
-		assert(_str && idx >= 0 && idx < (int)_size);
-		return _str[idx];
-	}
-
-	/** Remove the last character from the string. */
-	void deleteLastChar();
-
-	/** Remove the character at position p from the string. */
-	void deleteChar(uint32 p);
-
-	/** Set character c at position p, replacing the previous character there. */
-	void setChar(char c, uint32 p);
-
-	/** Set character c at position p. */
-	void insertChar(char c, uint32 p);
-
-	/** Clears the string, making it empty. */
-	void clear();
-
-	/** Convert all characters in the string to lowercase. */
-	void toLowercase();
-
-	/** Convert all characters in the string to uppercase. */
-	void toUppercase();
-
-	/**
-	 * Removes trailing and leading whitespaces. Uses isspace() to decide
-	 * what is whitespace and what not.
-	 */
-	void trim();
-
-public:
-	typedef char *        iterator;
-	typedef const char *  const_iterator;
-
-	iterator		begin() {
-		return _str;
-	}
-
-	iterator		end() {
-		return begin() + size();
-	}
-
-	const_iterator	begin() const {
-		return _str;
-	}
-
-	const_iterator	end() const {
-		return begin() + size();
-	}
-
-protected:
-	void makeUnique();
-	void ensureCapacity(uint32 new_size, bool keep_old);
-	void initWithCStr(const char *str, uint32 len);
-};
-
-// Append two strings to form a new (temp) string
-String operator +(const String &x, const String &y);
-
-String operator +(const char *x, const String &y);
-String operator +(const String &x, const char *y);
-
-String operator +(const String &x, char y);
-String operator +(char x, const String &y);
-
-// Some useful additional comparison operators for Strings
-bool operator == (const char *x, const String &y);
-bool operator != (const char *x, const String &y);
-
-// Utility functions to remove leading and trailing whitespaces
-extern char *ltrim(char *t);
-extern char *rtrim(char *t);
-extern char *trim(char *t);
-
-
-/**
- * Returns the last component of a given path.
- *
- * Examples:
- *			/foo/bar.txt would return 'bar.txt'
- *			/foo/bar/    would return 'bar'
- *			/foo/./bar//    would return 'bar'
- *
- * @param path the path of which we want to know the last component
- * @param sep character used to separate path components
- * @return The last component of the path.
- */
-Common::String lastPathComponent(const Common::String &path, const char sep);
-
-/**
- * Normalize a gien path to a canonical form. In particular:
- * - trailing separators are removed:  /foo/bar/ -> /foo/bar
- * - double separators (= empty components) are removed:   /foo//bar -> /foo/bar
- * - dot components are removed:  /foo/./bar -> /foo/bar
- *
- * @todo remove double dot components:  /foo/baz/../bar -> /foo/bar
- *
- * @param path	the path to normalize
- * @param sep	the separator token (usually '/' on Unix-style systems, or '\\' on Windows based stuff)
- * @return	the normalized path
- */
-Common::String normalizePath(const Common::String &path, const char sep);
-
-
-/**
- * Simple DOS-style pattern matching function (understands * and ? like used in DOS).
- * Taken from exult/files/listfiles.cc
- *
- * Token meaning:
- *		"*": any character, any amount of times.
- *		"?": any character, only once.
- *
- * Example strings/patterns:
- *		String: monkey.s01	 Pattern: monkey.s??	=> true
- *		String: monkey.s101	 Pattern: monkey.s??	=> false
- *		String: monkey.s99	 Pattern: monkey.s?1	=> false
- *		String: monkey.s101	 Pattern: monkey.s*		=> true
- *		String: monkey.s99	 Pattern: monkey.s*1	=> false
- *
- * @param str Text to be matched against the given pattern.
- * @param pat Glob pattern.
- * @param pathMode Whether to use path mode, i.e., whether slashes must be matched explicitly.
- *
- * @return true if str matches the pattern, false otherwise.
- */
-bool matchString(const char *str, const char *pat, bool pathMode = false);
-
-/**
- * Take a 32 bit value and turn it into a four character string, where each of
- * the four bytes is turned into one character. Most significant byte is printed
- * first.
- */
-String tag2string(uint32 tag);
-#define tag2str(x)	Common::tag2string(x).c_str()
-
-
-class StringList : public Array<String> {
-public:
-	void push_back(const char *str) {
-		Array<String>::push_back(str);
-	}
-
-	void push_back(const String &str) {
-		Array<String>::push_back(str);
-	}
-};
-
-}	// End of namespace Common
-
-#endif


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list