Ew! No spaces in filenames.
authorDavid Anderson <dvander@alliedmods.net>
Sun Aug 17 18:27:51 2008 +0000 (2008-08-17)
changeset 2230e650c36ac67b
parent 2229 698a4b4f1061
child 2231 f13eb5a31226
Ew! No spaces in filenames.
tools/gamedata md5/Makefile
tools/gamedata md5/TextParsers.cpp
tools/gamedata md5/TextParsers.h
tools/gamedata md5/main.cpp
tools/gamedata md5/main.h
tools/gamedata md5/md5.cpp
tools/gamedata md5/md5.h
tools/gamedata md5/msvc9/gamedatamd5.sln
tools/gamedata md5/msvc9/gamedatamd5.vcproj
tools/gamedata md5/sm_memtable.cpp
tools/gamedata md5/sm_memtable.h
tools/gamedata_md5/Makefile
tools/gamedata_md5/TextParsers.cpp
tools/gamedata_md5/TextParsers.h
tools/gamedata_md5/main.cpp
tools/gamedata_md5/main.h
tools/gamedata_md5/md5.cpp
tools/gamedata_md5/md5.h
tools/gamedata_md5/msvc9/gamedatamd5.sln
tools/gamedata_md5/msvc9/gamedatamd5.vcproj
tools/gamedata_md5/sm_memtable.cpp
tools/gamedata_md5/sm_memtable.h
     1.1 --- a/tools/gamedata md5/Makefile	Fri Aug 15 17:21:48 2008 +0000
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,74 +0,0 @@
     1.4 -# (C)2004-2008 SourceMod Development Team
     1.5 -# Makefile written by David "BAILOPAN" Anderson
     1.6 -
     1.7 -
     1.8 -#####################################
     1.9 -### EDIT BELOW FOR OTHER PROJECTS ###
    1.10 -#####################################
    1.11 -
    1.12 -OBJECTS = main.cpp TextParsers.cpp sm_memtable.cpp md5.cpp
    1.13 -
    1.14 -##############################################
    1.15 -### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
    1.16 -##############################################
    1.17 -
    1.18 -C_OPT_FLAGS = -DNDEBUG -O3 -funroll-loops -pipe -fno-strict-aliasing
    1.19 -C_DEBUG_FLAGS = -D_DEBUG -DDEBUG -g -ggdb3
    1.20 -C_GCC4_FLAGS = -fvisibility=hidden
    1.21 -CPP_GCC4_FLAGS = -fvisibility-inlines-hidden
    1.22 -CPP = gcc-4.1
    1.23 -
    1.24 -BINARY = gamedatamd5
    1.25 -
    1.26 -INCLUDE += -I. -I../../public -I../../public/sourcepawn
    1.27 -
    1.28 -CFLAGS += -D_LINUX -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp \
    1.29 -	-D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp -Wall -Werror \
    1.30 -	-Wno-uninitialized -mfpmath=sse -msse -DHAVE_STDINT_H -DSM_DEFAULT_THREADER -m32
    1.31 -CPPFLAGS += -Wno-non-virtual-dtor -fno-exceptions -fno-rtti
    1.32 -
    1.33 -################################################
    1.34 -### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ###
    1.35 -################################################
    1.36 -
    1.37 -ifeq "$(DEBUG)" "true"
    1.38 -	BIN_DIR = Debug
    1.39 -	CFLAGS += $(C_DEBUG_FLAGS)
    1.40 -else
    1.41 -	BIN_DIR = Release
    1.42 -	CFLAGS += $(C_OPT_FLAGS)
    1.43 -endif
    1.44 -
    1.45 -GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1)
    1.46 -ifeq "$(GCC_VERSION)" "4"
    1.47 -	CFLAGS += $(C_GCC4_FLAGS)
    1.48 -	CPPFLAGS += $(CPP_GCC4_FLAGS)
    1.49 -endif
    1.50 -
    1.51 -OBJ_LINUX := $(OBJECTS:%vm_engine.cpp=$(BIN_DIR)/%vm_engine.o)
    1.52 -OBJ_LINUX := $(OBJ_LINUX:%.cpp=$(BIN_DIR)/%.o)
    1.53 -OBJ_LINUX := $(OBJ_LINUX:%.c=$(BIN_DIR)/%.o)
    1.54 -
    1.55 -$(BIN_DIR)/%vm_engine.o: %vm_engine.cpp
    1.56 -	$(CPP) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
    1.57 -
    1.58 -$(BIN_DIR)/%.o: %.cpp
    1.59 -	$(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
    1.60 -
    1.61 -$(BIN_DIR)/%.o: %.c
    1.62 -	$(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $<
    1.63 -
    1.64 -all:
    1.65 -	mkdir -p $(BIN_DIR)
    1.66 -	$(MAKE) -f Makefile sourcemod
    1.67 -
    1.68 -sourcemod: $(OBJ_LINUX)
    1.69 -	$(CPP) $(INCLUDE) $(OBJ_LINUX) $(LINK) -m32 -lstdc++ -o$(BIN_DIR)/$(BINARY)
    1.70 -
    1.71 -debug:
    1.72 -	$(MAKE) -f Makefile all DEBUG=true
    1.73 -
    1.74 -default: all
    1.75 -
    1.76 -clean:
    1.77 -	rm -rf $(BIN_DIR)/$(BINARY)
     2.1 --- a/tools/gamedata md5/TextParsers.cpp	Fri Aug 15 17:21:48 2008 +0000
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,1082 +0,0 @@
     2.4 -/**
     2.5 - * vim: set ts=4 :
     2.6 - * =============================================================================
     2.7 - * SourceMod
     2.8 - * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
     2.9 - * =============================================================================
    2.10 - *
    2.11 - * This program is free software; you can redistribute it and/or modify it under
    2.12 - * the terms of the GNU General Public License, version 3.0, as published by the
    2.13 - * Free Software Foundation.
    2.14 - * 
    2.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
    2.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    2.17 - * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    2.18 - * details.
    2.19 - *
    2.20 - * You should have received a copy of the GNU General Public License along with
    2.21 - * this program.  If not, see <http://www.gnu.org/licenses/>.
    2.22 - *
    2.23 - * As a special exception, AlliedModders LLC gives you permission to link the
    2.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
    2.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    2.26 - * by the Valve Corporation.  You must obey the GNU General Public License in
    2.27 - * all respects for all other code used.  Additionally, AlliedModders LLC grants
    2.28 - * this exception to all derivative works.  AlliedModders LLC defines further
    2.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    2.30 - * or <http://www.sourcemod.net/license.php>.
    2.31 - *
    2.32 - * Version: $Id$
    2.33 - */
    2.34 -
    2.35 -#include <stdio.h>
    2.36 -#include <ctype.h>
    2.37 -#include <wctype.h>
    2.38 -#include <string.h>
    2.39 -#include <stdlib.h>
    2.40 -#include <assert.h>
    2.41 -#include "TextParsers.h"
    2.42 -//#include "ShareSys.h"
    2.43 -//#include "sm_stringutil.h"
    2.44 -//#include "LibrarySys.h"
    2.45 -
    2.46 -TextParsers g_TextParser;
    2.47 -ITextParsers *textparsers = &g_TextParser;
    2.48 -
    2.49 -static int g_ini_chartable1[255] = {0};
    2.50 -static int g_ws_chartable[255] = {0};
    2.51 -
    2.52 -bool TextParsers::IsWhitespace(const char *stream)
    2.53 -{
    2.54 -	return g_ws_chartable[(unsigned)*stream] == 1;
    2.55 -}
    2.56 -
    2.57 -TextParsers::TextParsers()
    2.58 -{
    2.59 -	g_ini_chartable1[(unsigned)'_'] = 1;
    2.60 -	g_ini_chartable1[(unsigned)'-'] = 1;
    2.61 -	g_ini_chartable1[(unsigned)','] = 1;
    2.62 -	g_ini_chartable1[(unsigned)'+'] = 1;
    2.63 -	g_ini_chartable1[(unsigned)'.'] = 1;
    2.64 -	g_ini_chartable1[(unsigned)'$'] = 1;
    2.65 -	g_ini_chartable1[(unsigned)'?'] = 1;
    2.66 -	g_ini_chartable1[(unsigned)'/'] = 1;
    2.67 -	g_ws_chartable[(unsigned)'\n'] = 1;
    2.68 -	g_ws_chartable[(unsigned)'\v'] = 1;
    2.69 -	g_ws_chartable[(unsigned)'\r'] = 1;
    2.70 -	g_ws_chartable[(unsigned)'\t'] = 1;
    2.71 -	g_ws_chartable[(unsigned)'\f'] = 1;
    2.72 -	g_ws_chartable[(unsigned)' '] = 1;
    2.73 -}
    2.74 -
    2.75 -unsigned int TextParsers::GetUTF8CharBytes(const char *stream)
    2.76 -{
    2.77 -	return _GetUTF8CharBytes(stream);
    2.78 -}
    2.79 -
    2.80 -/**
    2.81 - * Character streams
    2.82 - */
    2.83 -
    2.84 -struct CharStream
    2.85 -{
    2.86 -	const char *curpos;
    2.87 -};
    2.88 -
    2.89 -bool CharStreamReader(void *stream, char *buffer, size_t maxlength, unsigned int *read)
    2.90 -{
    2.91 -	CharStream *srdr = (CharStream *)stream;
    2.92 -
    2.93 -	const char *ptr = srdr->curpos;
    2.94 -	for (size_t i=0; i<maxlength; i++)
    2.95 -	{
    2.96 -		if (*ptr == '\0')
    2.97 -		{
    2.98 -			break;
    2.99 -		}
   2.100 -		*buffer++ = *ptr++;
   2.101 -	}
   2.102 -
   2.103 -	*read = ptr - srdr->curpos;
   2.104 -
   2.105 -	srdr->curpos = ptr;
   2.106 -
   2.107 -	return true;
   2.108 -}
   2.109 -
   2.110 -SMCError TextParsers::ParseString_SMC(const char *stream, 
   2.111 -					 ITextListener_SMC *smc,
   2.112 -					 SMCStates *states)
   2.113 -{
   2.114 -	CharStream srdr = { stream };
   2.115 -
   2.116 -	return ParseStream_SMC(&srdr, CharStreamReader, smc, states);
   2.117 -}
   2.118 -
   2.119 -/**
   2.120 - * File streams
   2.121 - */
   2.122 -
   2.123 -bool FileStreamReader(void *stream, char *buffer, size_t maxlength, unsigned int *read)
   2.124 -{
   2.125 -	size_t num = fread(buffer, 1, maxlength, (FILE *)stream);
   2.126 -
   2.127 -	*read = static_cast<unsigned int>(num);
   2.128 -
   2.129 -	if (num == 0 && feof((FILE *)stream))
   2.130 -	{
   2.131 -		return true;
   2.132 -	}
   2.133 -
   2.134 -	return (ferror((FILE *)stream) == 0);
   2.135 -}
   2.136 -
   2.137 -SMCError TextParsers::ParseFile_SMC(const char *file, ITextListener_SMC *smc, SMCStates *states)
   2.138 -{
   2.139 -	FILE *fp = fopen(file, "rt");
   2.140 -
   2.141 -	if (!fp)
   2.142 -	{
   2.143 -		if (states != NULL)
   2.144 -		{
   2.145 -			states->line = 0;
   2.146 -			states->col = 0;
   2.147 -		}
   2.148 -		return SMCError_StreamOpen;
   2.149 -	}
   2.150 -
   2.151 -	SMCError result = ParseStream_SMC(fp, FileStreamReader, smc, states);
   2.152 -
   2.153 -	fclose(fp);
   2.154 -
   2.155 -	return result;
   2.156 -}
   2.157 -
   2.158 -SMCError TextParsers::ParseSMCFile(const char *file,
   2.159 -								   ITextListener_SMC *smc_listener,
   2.160 -								   SMCStates *states,
   2.161 -								   char *buffer,
   2.162 -								   size_t maxsize)
   2.163 -{
   2.164 -	const char *errstr;
   2.165 -	FILE *fp = fopen(file, "rt");
   2.166 -
   2.167 -	if (fp == NULL)
   2.168 -	{
   2.169 -		char error[256] = "unknown";
   2.170 -		if (states != NULL)
   2.171 -		{
   2.172 -			states->line = 0;
   2.173 -			states->col = 0;
   2.174 -		}
   2.175 -		//g_LibSys.GetPlatformError(error, sizeof(error));
   2.176 -		UTIL_Format(buffer, maxsize, "File could not be opened: %s", error);
   2.177 -		return SMCError_StreamOpen;
   2.178 -	}
   2.179 -
   2.180 -	SMCError result = ParseStream_SMC(fp, FileStreamReader, smc_listener, states);
   2.181 -
   2.182 -	fclose(fp);
   2.183 -
   2.184 -	errstr = GetSMCErrorString(result);
   2.185 -	UTIL_Format(buffer, maxsize, "%s", errstr != NULL ? errstr : "Unknown error");
   2.186 -
   2.187 -	return result;
   2.188 -}
   2.189 -
   2.190 -/** 
   2.191 - * Raw parsing of streams with helper functions
   2.192 - */
   2.193 -
   2.194 -struct StringInfo
   2.195 -{
   2.196 -	StringInfo() : quoted(false), ptr(NULL), end(NULL), special(false) { }
   2.197 -	bool quoted;
   2.198 -	char *ptr;
   2.199 -	char *end;
   2.200 -	bool special;
   2.201 -};
   2.202 -
   2.203 -const char *FixupString(StringInfo &data)
   2.204 -{
   2.205 -	if (!data.ptr)
   2.206 -	{
   2.207 -		return NULL;
   2.208 -	}
   2.209 -
   2.210 -	if (data.quoted)
   2.211 -	{
   2.212 -		data.ptr++;
   2.213 -	}
   2.214 -#if defined _DEBUG
   2.215 -	else {
   2.216 -		/* A string will never have beginning whitespace because we ignore it in the stream.
   2.217 -		 * Furthermore, if there is trailing whitespace, the end ptr will point to it, so it is valid
   2.218 -		 * to overwrite!  Lastly, the last character must be whitespace or a comment/invalid character.
   2.219 -		 */
   2.220 - 	}
   2.221 -#endif
   2.222 -
   2.223 -	/* Do some extra work on strings that have special quoted characters. */
   2.224 -	if (data.special)
   2.225 -	{
   2.226 -		char *outptr = data.ptr;
   2.227 -		size_t len = data.end - data.ptr;
   2.228 -		if (len >= 2)
   2.229 -		{
   2.230 -			for (size_t i=0; i<len; i++)
   2.231 -			{
   2.232 -				if (data.ptr[i] == '\\' && i < len - 1)
   2.233 -				{
   2.234 -					/* Resolve the next character. */
   2.235 -					i++;
   2.236 -					if (data.ptr[i] == 'n')
   2.237 -					{
   2.238 -						data.ptr[i] = '\n';
   2.239 -					} else if (data.ptr[i] == 't') {
   2.240 -						data.ptr[i] = '\t';
   2.241 -					} else if (data.ptr[i] == 'r') {
   2.242 -						data.ptr[i] = '\r';
   2.243 -					} else if (data.ptr[i] != '\\'
   2.244 -						&& data.ptr[i] != '"') {
   2.245 -						/* This character is invalid, so go back one */
   2.246 -						i--;
   2.247 -					}
   2.248 -				}
   2.249 -				*outptr++ = data.ptr[i];
   2.250 -			}
   2.251 -			*outptr = '\0';
   2.252 -		}
   2.253 -	}
   2.254 -
   2.255 -	if (data.end)
   2.256 -	{
   2.257 -		*(data.end) = '\0';
   2.258 -	}
   2.259 -
   2.260 -	return data.ptr;
   2.261 -}
   2.262 -
   2.263 -const char *rotate(StringInfo info[3])
   2.264 -{
   2.265 -	if (info[2].ptr != NULL)
   2.266 -	{
   2.267 -		return info[2].ptr;
   2.268 -	}
   2.269 -
   2.270 -	if (info[0].ptr != NULL)
   2.271 -	{
   2.272 -		info[2] = info[1];
   2.273 -		info[1] = info[0];
   2.274 -		info[0] = StringInfo();
   2.275 -	}
   2.276 -	
   2.277 -	return NULL;
   2.278 -}
   2.279 -
   2.280 -void scrap(StringInfo info[3])
   2.281 -{
   2.282 -	info[2] = StringInfo();
   2.283 -	info[1] = StringInfo();
   2.284 -	info[0] = StringInfo();
   2.285 -}
   2.286 -
   2.287 -void reloc(StringInfo &data, unsigned int bytes)
   2.288 -{
   2.289 -	if (data.ptr)
   2.290 -	{
   2.291 -		data.ptr -= bytes;
   2.292 -	}
   2.293 -	if (data.end)
   2.294 -	{
   2.295 -		data.end -= bytes;
   2.296 -	}
   2.297 -}
   2.298 -
   2.299 -char *lowstring(StringInfo info[3])
   2.300 -{
   2.301 -	for (int i=2; i>=0; i--)
   2.302 -	{
   2.303 -		if (info[i].ptr)
   2.304 -		{
   2.305 -			return info[i].ptr;
   2.306 -		}
   2.307 -	}
   2.308 -
   2.309 -	return NULL;
   2.310 -}
   2.311 -
   2.312 -SMCError TextParsers::ParseStream_SMC(void *stream, 
   2.313 -								   STREAMREADER srdr, 
   2.314 -								   ITextListener_SMC *smc, 
   2.315 -								   SMCStates *pStates)
   2.316 -{
   2.317 -	char *reparse_point = NULL;
   2.318 -	char in_buf[4096];
   2.319 -	char *parse_point = in_buf;
   2.320 -	char *line_begin = in_buf;
   2.321 -	unsigned int read;
   2.322 -	unsigned int curlevel = 0;
   2.323 -	bool in_quote = false;
   2.324 -	bool ignoring = false;
   2.325 -	bool eol_comment = false;
   2.326 -	bool ml_comment = false;
   2.327 -	unsigned int i;
   2.328 -	SMCError err = SMCError_Okay;
   2.329 -	SMCResult res;
   2.330 -	SMCStates states;
   2.331 -	char c;
   2.332 -
   2.333 -	StringInfo strings[3];
   2.334 -	StringInfo emptystring;
   2.335 -
   2.336 -	states.line = 1;
   2.337 -	states.col = 0;
   2.338 -
   2.339 -	smc->ReadSMC_ParseStart();
   2.340 -
   2.341 -	/**
   2.342 -	 * The stream reader reads in as much as it can fill the buffer with.
   2.343 -	 * It then processes the buffer.  If the buffer cannot be fully processed, for example, 
   2.344 -	 * a line is left hanging with no newline, then the contents of the buffer is shifted 
   2.345 -	 * down, and the buffer is filled from the stream reader again.
   2.346 -	 *
   2.347 -	 * What makes this particularly annoying is that we cache pointers everywhere, so when 
   2.348 -	 * the shifting process takes place, all those pointers must be shifted as well.
   2.349 -	 */
   2.350 -	while (srdr(stream, parse_point, sizeof(in_buf) - (parse_point - in_buf) - 1, &read))
   2.351 -	{
   2.352 -		if (!read)
   2.353 -		{
   2.354 -			break;
   2.355 -		}
   2.356 -
   2.357 -		/* Check for BOM markings, which is only relevant on the first line.
   2.358 -		 * Not worth it, but it could be moved out of the loop.
   2.359 -		 */
   2.360 -		if (states.line == 1 && 
   2.361 -			in_buf[0] == (char)0xEF && 
   2.362 -			in_buf[1] == (char)0xBB && 
   2.363 -			in_buf[2] == (char)0xBF)
   2.364 -		{
   2.365 -			/* Move EVERYTHING down :\ */
   2.366 -			memmove(in_buf, &in_buf[3], read - 3);
   2.367 -			read -= 3;
   2.368 -		}
   2.369 -
   2.370 -		if (reparse_point)
   2.371 -		{
   2.372 -			read += (parse_point - reparse_point);
   2.373 -			parse_point = reparse_point;
   2.374 -			reparse_point = NULL;
   2.375 -		}
   2.376 -
   2.377 -		for (i=0; i<read; i++)
   2.378 -		{
   2.379 -			c = parse_point[i];
   2.380 -			if (c == '\n')
   2.381 -			{
   2.382 -				/* If we got a newline, there's a lot of things that could have happened in the interim.
   2.383 -				 * First, let's make sure the staged strings are rotated.
   2.384 -				 */
   2.385 -				if (strings[0].ptr)
   2.386 -				{
   2.387 -					strings[0].end = &parse_point[i];
   2.388 -					if (rotate(strings) != NULL)
   2.389 -					{
   2.390 -						err = SMCError_InvalidTokens;
   2.391 -						goto failed;
   2.392 -					}
   2.393 -				}
   2.394 -
   2.395 -				/* Next, let's clear some line-based values that may no longer have meaning */
   2.396 -				eol_comment = false;
   2.397 -				in_quote = false;
   2.398 -				if (ignoring && !ml_comment)
   2.399 -				{
   2.400 -					ignoring = false;
   2.401 -				}
   2.402 -
   2.403 -				/* Pass the raw line onto the listener.  We terminate the line so the receiver 
   2.404 -				 * doesn't get tons of useless info.  We restore the newline after.
   2.405 -				 */
   2.406 -				parse_point[i] = '\0';
   2.407 -				if ((res=smc->ReadSMC_RawLine(&states, line_begin)) != SMCResult_Continue)
   2.408 -				{
   2.409 -					err = (res == SMCResult_HaltFail) ? SMCError_Custom : SMCError_Okay;
   2.410 -					goto failed;
   2.411 -				}
   2.412 -				parse_point[i] = '\n';
   2.413 -
   2.414 -				/* Now we check the sanity of our staged strings! */
   2.415 -				if (strings[2].ptr)
   2.416 -				{
   2.417 -					if (!curlevel)
   2.418 -					{
   2.419 -						err = SMCError_InvalidProperty1;
   2.420 -						goto failed;
   2.421 -					}
   2.422 -					/* Assume the next string is a property and pass the info on. */
   2.423 -					if ((res=smc->ReadSMC_KeyValue(
   2.424 -						&states,
   2.425 -						FixupString(strings[2]),
   2.426 -						FixupString(strings[1]))) != SMCResult_Continue)
   2.427 -					{
   2.428 -						err = (res == SMCResult_HaltFail) ? SMCError_Custom : SMCError_Okay;
   2.429 -						goto failed;
   2.430 -					}
   2.431 -					scrap(strings);
   2.432 -				}
   2.433 -
   2.434 -				/* Change the states for the next line */
   2.435 -				states.col = 0;
   2.436 -				states.line++;
   2.437 -				line_begin = &parse_point[i+1];		//Note: safe because this gets relocated later
   2.438 -			} 
   2.439 -			else if (ignoring) 
   2.440 -			{
   2.441 -				if (in_quote)
   2.442 -				{
   2.443 -					/* If i was 0, we could have reparsed, so make sure there's no buffer underrun */
   2.444 -					if ((&parse_point[i] != in_buf) && c == '"' && parse_point[i-1] != '\\')
   2.445 -					{
   2.446 -						/* If we reached a quote in an ignore phase,
   2.447 -						 * we're staging a string and we must rotate it out.
   2.448 -						 */
   2.449 -						in_quote = false;
   2.450 -						ignoring = false;
   2.451 -						/* Set our info */
   2.452 -						strings[0].end = &parse_point[i];
   2.453 -						strings[0].quoted = true;
   2.454 -						if (rotate(strings) != NULL)
   2.455 -						{
   2.456 -							/* If we rotated too many strings, there was too much crap on one line */
   2.457 -							err = SMCError_InvalidTokens;
   2.458 -							goto failed;
   2.459 -						}
   2.460 -					} 
   2.461 -					else if (c == '\\') 
   2.462 -					{
   2.463 -						strings[0].special = true;
   2.464 -						if (i == (read - 1))
   2.465 -						{
   2.466 -							reparse_point = &parse_point[i];
   2.467 -							break;
   2.468 -						}
   2.469 -					}
   2.470 -				} 
   2.471 -				else if (ml_comment) 
   2.472 -				{
   2.473 -					if (c == '*')
   2.474 -					{
   2.475 -						/* Check if we need to get more input first */
   2.476 -						if (i == read - 1)
   2.477 -						{
   2.478 -							reparse_point = &parse_point[i];
   2.479 -							break;
   2.480 -						}
   2.481 -						if (parse_point[i+1] == '/')
   2.482 -						{
   2.483 -							ml_comment = false;
   2.484 -							ignoring = false;
   2.485 -							/* We should not be staging anything right now. */
   2.486 -							assert(strings[0].ptr == NULL);
   2.487 -							/* Advance the input stream so we don't choke on this token */
   2.488 -							i++;
   2.489 -							states.col++;
   2.490 -						}
   2.491 -					}
   2.492 -				}
   2.493 -			} 
   2.494 -			else 
   2.495 -			{
   2.496 -				/* Check if we're whitespace or not */
   2.497 -				if (!g_ws_chartable[(unsigned)c])
   2.498 -				{
   2.499 -					bool restage = false;
   2.500 -					/* Check various special tokens:
   2.501 -					 * ;
   2.502 -					 * //
   2.503 -					 * / *
   2.504 -					 * {
   2.505 -					 * }
   2.506 -					 */
   2.507 -					if (c == ';' || c == '/')
   2.508 -					{
   2.509 -						/* If it's a line-based comment (that is, ; or //)
   2.510 -						 * we will need to scrap everything until the end of the line.
   2.511 -						 */
   2.512 -						if (c == '/')
   2.513 -						{
   2.514 -							if (i == read - 1)
   2.515 -							{
   2.516 -								/* If we reached the end of the look-ahead, we need to re-check our input.
   2.517 -								 * Breaking out will force this to be the new reparse point!
   2.518 -								 */
   2.519 -								reparse_point = &parse_point[i];
   2.520 -								break;
   2.521 -							}
   2.522 -							if (parse_point[i + 1] == '/')
   2.523 -							{
   2.524 -								/* standard comment */
   2.525 -								ignoring = true;
   2.526 -								eol_comment = true;
   2.527 -								restage = true;
   2.528 -							} 
   2.529 -							else if (parse_point[i+1] == '*') 
   2.530 -							{
   2.531 -								/* inline comment - start ignoring */
   2.532 -								ignoring = true;
   2.533 -								ml_comment = true;
   2.534 -								/* yes, we restage, meaning that:
   2.535 -								 * STR/ *stuff* /ING  (space because ml comments don't nest in C++)
   2.536 -								 * will not generate 'STRING', but rather 'STR' and 'ING'.
   2.537 -								 * This should be a rare occurrence and is done here for convenience.
   2.538 -								 */
   2.539 -								restage = true;
   2.540 -							}
   2.541 -						} 
   2.542 -						else 
   2.543 -						{
   2.544 -							ignoring = true;
   2.545 -							eol_comment = true;
   2.546 -							restage = true;
   2.547 -						}
   2.548 -					} 
   2.549 -					else if (c == '{') 
   2.550 -					{
   2.551 -						/* If we are staging a string, we must rotate here */
   2.552 -						if (strings[0].ptr)
   2.553 -						{
   2.554 -							/* We have unacceptable tokens on this line */
   2.555 -							if (rotate(strings) != NULL)
   2.556 -							{
   2.557 -								err = SMCError_InvalidSection1;
   2.558 -								goto failed;
   2.559 -							}
   2.560 -						}
   2.561 -						/* Sections must always be alone */
   2.562 -						if (strings[2].ptr != NULL)
   2.563 -						{
   2.564 -							err = SMCError_InvalidSection1;
   2.565 -							goto failed;
   2.566 -						} 
   2.567 -						else if (strings[1].ptr == NULL)
   2.568 -						{
   2.569 -							err = SMCError_InvalidSection2;
   2.570 -							goto failed;
   2.571 -						}
   2.572 -						if ((res=smc->ReadSMC_NewSection(&states, FixupString(strings[1])))
   2.573 -							!= SMCResult_Continue)
   2.574 -						{
   2.575 -							err = (res == SMCResult_HaltFail) ? SMCError_Custom : SMCError_Okay;
   2.576 -							goto failed;
   2.577 -						}
   2.578 -						strings[1] = emptystring;
   2.579 -						curlevel++;
   2.580 -					} 
   2.581 -					else if (c == '}') 
   2.582 -					{
   2.583 -						/* Unlike our matching friend, this can be on the same line as something prior */
   2.584 -						if (rotate(strings) != NULL)
   2.585 -						{
   2.586 -							err = SMCError_InvalidSection3;
   2.587 -							goto failed;
   2.588 -						}
   2.589 -						if (strings[2].ptr)
   2.590 -						{
   2.591 -							if (!curlevel)
   2.592 -							{
   2.593 -								err = SMCError_InvalidProperty1;
   2.594 -								goto failed;
   2.595 -							}
   2.596 -							if ((res=smc->ReadSMC_KeyValue(
   2.597 -											&states,
   2.598 -											FixupString(strings[2]),
   2.599 -											FixupString(strings[1])))
   2.600 -								!= SMCResult_Continue)
   2.601 -							{
   2.602 -								err = (res == SMCResult_HaltFail) ? SMCError_Custom : SMCError_Okay;
   2.603 -								goto failed;
   2.604 -							}
   2.605 -						} 
   2.606 -						else if (strings[1].ptr) 
   2.607 -						{
   2.608 -							err = SMCError_InvalidSection3;
   2.609 -							goto failed;
   2.610 -						} 
   2.611 -						else if (!curlevel) 
   2.612 -						{
   2.613 -							err = SMCError_InvalidSection4;
   2.614 -							goto failed;
   2.615 -						}
   2.616 -						/* Now it's safe to leave the section */
   2.617 -						scrap(strings);
   2.618 -						if ((res=smc->ReadSMC_LeavingSection(&states)) != SMCResult_Continue)
   2.619 -						{
   2.620 -							err = (res == SMCResult_HaltFail) ? SMCError_Custom : SMCError_Okay;
   2.621 -							goto failed;
   2.622 -						}
   2.623 -						curlevel--;
   2.624 -					} 
   2.625 -					else if (c == '"') 
   2.626 -					{
   2.627 -						/* If we get a quote mark, we always restage, but we need to do it beforehand */
   2.628 -						if (strings[0].ptr)
   2.629 -						{
   2.630 -							strings[0].end = &parse_point[i];
   2.631 -							if (rotate(strings) != NULL)
   2.632 -							{
   2.633 -								err = SMCError_InvalidTokens;
   2.634 -								goto failed;
   2.635 -							}
   2.636 -						}
   2.637 -						strings[0].ptr = &parse_point[i];
   2.638 -						in_quote = true;
   2.639 -						ignoring = true;
   2.640 -					} 
   2.641 -					else if (!strings[0].ptr) 
   2.642 -					{
   2.643 -						/* If we have no string, we must start one */
   2.644 -						strings[0].ptr = &parse_point[i];
   2.645 -					}
   2.646 -					if (restage && strings[0].ptr)
   2.647 -					{
   2.648 -						strings[0].end = &parse_point[i];
   2.649 -						if (rotate(strings) != NULL)
   2.650 -						{
   2.651 -							err = SMCError_InvalidTokens;
   2.652 -							goto failed;
   2.653 -						}
   2.654 -					}
   2.655 -				} 
   2.656 -				else 
   2.657 -				{
   2.658 -					/* If we're eating a string and get whitespace, we need to restage.
   2.659 -					 * (Note that if we are quoted, this is being ignored)
   2.660 -					 */
   2.661 -					if (strings[0].ptr)
   2.662 -					{
   2.663 -						/*
   2.664 -						 * The specification says the second string in a pair does not need to be quoted.
   2.665 -						 * Thus, we check if there's already a string on the stack.
   2.666 -						 * If there's a newline, we always rotate so the newline has an empty starter.
   2.667 -						 */
   2.668 -						if (!strings[1].ptr)
   2.669 -						{
   2.670 -							/* There's no string, so we must move this one down and eat up another */
   2.671 -							strings[0].end = &parse_point[i];
   2.672 -							rotate(strings);
   2.673 -						} 
   2.674 -						else if (!strings[1].quoted) 
   2.675 -						{
   2.676 -							err = SMCError_InvalidTokens;
   2.677 -							goto failed;
   2.678 -						}
   2.679 -					}
   2.680 -				}
   2.681 -			}
   2.682 -
   2.683 -			/* Advance which token we're on */
   2.684 -			states.col++;
   2.685 -		}
   2.686 -
   2.687 -		if (line_begin != in_buf)
   2.688 -		{
   2.689 -			/* The line buffer has advanced, so it's safe to copy N bytes back to the beginning.
   2.690 -			 * What's N?  N is the lowest point we're currently relying on.
   2.691 -			 */
   2.692 -			char *stage = lowstring(strings);
   2.693 -			if (!stage || stage > line_begin)
   2.694 -			{
   2.695 -				stage = line_begin;
   2.696 -			}
   2.697 -			unsigned int bytes = read - (stage - parse_point);
   2.698 -
   2.699 -			/* It is now safe to delete everything before the staged point */
   2.700 -			memmove(in_buf, stage, bytes);
   2.701 -
   2.702 -			/* Calculate the number of bytes in the new buffer */
   2.703 -			bytes = stage - in_buf;
   2.704 -			/* Relocate all the cached pointers to our new base */
   2.705 -			line_begin -= bytes;
   2.706 -			reloc(strings[0], bytes);
   2.707 -			reloc(strings[1], bytes);
   2.708 -			reloc(strings[2], bytes);
   2.709 -			if (reparse_point)
   2.710 -			{
   2.711 -				reparse_point -= bytes;
   2.712 -			}
   2.713 -			if (parse_point)
   2.714 -			{
   2.715 -				parse_point = &parse_point[read];
   2.716 -				parse_point -= bytes;
   2.717 -			}
   2.718 -		} 
   2.719 -		else if (read == sizeof(in_buf) - 1) 
   2.720 -		{
   2.721 -			err = SMCError_TokenOverflow;
   2.722 -			goto failed;
   2.723 -		}
   2.724 -	}
   2.725 -
   2.726 -	/* If we're done parsing and there are tokens left over... */
   2.727 -	if (curlevel)
   2.728 -	{
   2.729 -		err = SMCError_InvalidSection5;
   2.730 -		goto failed;
   2.731 -	} 
   2.732 -	else if (strings[0].ptr || strings[1].ptr) 
   2.733 -	{
   2.734 -		err = SMCError_InvalidTokens;
   2.735 -		goto failed;
   2.736 -	}
   2.737 -	
   2.738 -	smc->ReadSMC_ParseEnd(false, false);
   2.739 -	
   2.740 -	if (pStates != NULL)
   2.741 -	{
   2.742 -		*pStates = states;
   2.743 -	}
   2.744 -
   2.745 -	return SMCError_Okay;
   2.746 -
   2.747 -failed:
   2.748 -	if (pStates != NULL)
   2.749 -	{
   2.750 -		*pStates = states;
   2.751 -	}
   2.752 -
   2.753 -	smc->ReadSMC_ParseEnd(true, (err == SMCError_Custom));
   2.754 -
   2.755 -	return err;
   2.756 -}
   2.757 -
   2.758 -
   2.759 -/**
   2.760 - * INI parser 
   2.761 - */
   2.762 -
   2.763 -bool TextParsers::ParseFile_INI(const char *file, ITextListener_INI *ini_listener, unsigned int *line, unsigned int *col)
   2.764 -{
   2.765 -	FILE *fp = fopen(file, "rt");
   2.766 -	unsigned int curline = 0;
   2.767 -	unsigned int curtok;
   2.768 -	size_t len;
   2.769 -
   2.770 -	if (!fp)
   2.771 -	{
   2.772 -		if (line)
   2.773 -		{
   2.774 -			*line = 0;
   2.775 -		}
   2.776 -
   2.777 -		return false;
   2.778 -	}
   2.779 -
   2.780 -	char buffer[2048];
   2.781 -	char *ptr, *save_ptr;
   2.782 -	bool in_quote;
   2.783 -
   2.784 -	while (!feof(fp))
   2.785 -	{
   2.786 -		curline++;
   2.787 -		curtok = 0;
   2.788 -		buffer[0] = '\0';
   2.789 -		if (fgets(buffer, sizeof(buffer), fp) == NULL)
   2.790 -		{
   2.791 -			break;
   2.792 -		}
   2.793 -
   2.794 -		//:TODO: this will only run once, so find a nice way to move it out of the while loop
   2.795 -		/* If this is the first line, check the first three bytes for BOM */
   2.796 -		if (curline == 1 && 
   2.797 -			buffer[0] == (char)0xEF && 
   2.798 -			buffer[1] == (char)0xBB && 
   2.799 -			buffer[2] == (char)0xBF)
   2.800 -		{
   2.801 -			/* We have a UTF-8 marked file... skip these bytes */
   2.802 -			ptr = &buffer[3];
   2.803 -		} else {
   2.804 -			ptr = buffer;
   2.805 -		}
   2.806 -
   2.807 -		/***************************************************
   2.808 -		 * We preprocess the string before parsing tokens! *
   2.809 -		 ***************************************************/
   2.810 -
   2.811 -		/* First strip beginning whitespace */
   2.812 -		while (*ptr != '\0' && g_ws_chartable[(unsigned)*ptr] != 0)
   2.813 -		{
   2.814 -			ptr++;
   2.815 -		}
   2.816 -
   2.817 -		len = strlen(ptr);
   2.818 -
   2.819 -		if (!len)
   2.820 -		{
   2.821 -			continue;
   2.822 -		}
   2.823 -
   2.824 -		/* Now search for comment characters */
   2.825 -		in_quote = false;
   2.826 -		save_ptr = ptr;
   2.827 -		for (size_t i=0; i<len; i++,ptr++)
   2.828 -		{
   2.829 -			if (!in_quote)
   2.830 -			{
   2.831 -				switch (*ptr)
   2.832 -				{
   2.833 -				case '"':
   2.834 -					{
   2.835 -						in_quote = true;
   2.836 -						break;
   2.837 -					}
   2.838 -				case ';':
   2.839 -					{
   2.840 -						/* Stop the loop */
   2.841 -						len = i;
   2.842 -						/* Terminate the string here */
   2.843 -						*ptr = '\0';
   2.844 -						break;
   2.845 -					}
   2.846 -				}
   2.847 -			} else {
   2.848 -				if (*ptr == '"')
   2.849 -				{
   2.850 -					in_quote = false;
   2.851 -				}
   2.852 -			}
   2.853 -		}
   2.854 -
   2.855 -		if (!len)
   2.856 -		{
   2.857 -			continue;
   2.858 -		}
   2.859 -
   2.860 -		ptr = save_ptr;
   2.861 -
   2.862 -		/* Lastly, strip ending whitespace off */
   2.863 -		for (size_t i=len-1; i>=0 && i<len; i--)
   2.864 -		{
   2.865 -			if (g_ws_chartable[(unsigned)ptr[i]])
   2.866 -			{
   2.867 -				ptr[i] = '\0';
   2.868 -				len--;
   2.869 -			} else {
   2.870 -				break;
   2.871 -			}
   2.872 -		}
   2.873 -
   2.874 -		if (!len)
   2.875 -		{
   2.876 -			continue;
   2.877 -		}
   2.878 -
   2.879 -		if (!ini_listener->ReadINI_RawLine(ptr, &curtok))
   2.880 -		{
   2.881 -			goto event_failed;
   2.882 -		}
   2.883 -
   2.884 -		if (*ptr == '[')
   2.885 -		{
   2.886 -			bool invalid_tokens = false;
   2.887 -			bool got_bracket = false;
   2.888 -			bool extra_tokens = false;
   2.889 -			char c;
   2.890 -			bool alnum;
   2.891 -			wchar_t wc;
   2.892 -
   2.893 -			for (size_t i=1; i<len; i++)
   2.894 -			{
   2.895 -				c = ptr[i];
   2.896 -				alnum = false;
   2.897 -
   2.898 -				if (c & (1<<7))
   2.899 -				{
   2.900 -					if (mbtowc(&wc, &ptr[i], len-i) != -1)
   2.901 -					{
   2.902 -						alnum = (iswalnum(wc) != 0);
   2.903 -						i += _GetUTF8CharBytes(&ptr[i]) - 1;
   2.904 -					}
   2.905 -				} else {
   2.906 -					alnum = (isalnum(c) != 0) || (g_ini_chartable1[(unsigned)c] != 0);
   2.907 -				}
   2.908 -				if (!alnum)
   2.909 -				{
   2.910 -					/* First check - is this a bracket? */
   2.911 -					if (c == ']')
   2.912 -					{
   2.913 -						/* Yes! */
   2.914 -						got_bracket = true;
   2.915 -						/* If this isn't the last character... */
   2.916 -						if (i != len - 1)
   2.917 -						{
   2.918 -							extra_tokens = true;
   2.919 -						}
   2.920 -						/* terminate */
   2.921 -						ptr[i] = '\0';
   2.922 -						break;
   2.923 -					} else {
   2.924 -						/* n...No! Continue copying. */
   2.925 -						invalid_tokens = true;
   2.926 -					}
   2.927 -				}
   2.928 -			}
   2.929 -
   2.930 -			/* Tell the handler */
   2.931 -			if (!ini_listener->ReadINI_NewSection(&ptr[1], invalid_tokens, got_bracket, extra_tokens, &curtok))
   2.932 -			{
   2.933 -				goto event_failed;
   2.934 -			}
   2.935 -		} else {
   2.936 -			char *key_ptr = ptr;
   2.937 -			char *val_ptr = NULL;
   2.938 -			char c;
   2.939 -			size_t first_space = 0;
   2.940 -			bool invalid_tokens = false;
   2.941 -			bool equal_token = false;
   2.942 -			bool quotes = false;
   2.943 -			bool alnum;
   2.944 -			wchar_t wc;
   2.945 -
   2.946 -			for (size_t i=0; i<len; i++)
   2.947 -			{
   2.948 -				c = ptr[i];
   2.949 -				alnum = false;
   2.950 -				/* is this an invalid char? */
   2.951 -				if (c & (1<<7))
   2.952 -				{
   2.953 -					if (mbtowc(&wc, &ptr[i], len-i) != -1)
   2.954 -					{
   2.955 -						alnum = (iswalnum(wc) != 0);
   2.956 -						i += _GetUTF8CharBytes(&ptr[i]) - 1;
   2.957 -					}
   2.958 -				} else {
   2.959 -					alnum = (isalnum(c) != 0) || (g_ini_chartable1[(unsigned)c] != 0);
   2.960 -				}
   2.961 -
   2.962 -				if (!alnum)
   2.963 -				{
   2.964 -					if (g_ws_chartable[(unsigned)c])
   2.965 -					{
   2.966 -						/* if it's a space, keep track of the first occurring space */
   2.967 -						if (!first_space)
   2.968 -						{
   2.969 -							first_space = i;
   2.970 -						}
   2.971 -					} else {
   2.972 -						if (c == '=')
   2.973 -						{
   2.974 -							/* if it's an equal sign, we're done with the key */
   2.975 -							if (first_space)
   2.976 -							{
   2.977 -								/* remove excess whitespace */
   2.978 -								key_ptr[first_space] = '\0';
   2.979 -							} else {
   2.980 -								/* remove the equal sign */
   2.981 -								key_ptr[i] = '\0';
   2.982 -							}
   2.983 -							if (ptr[++i] != '\0')
   2.984 -							{
   2.985 -								/* If this isn't the end, set next pointer */
   2.986 -								val_ptr = &ptr[i];
   2.987 -							}
   2.988 -							equal_token = true;
   2.989 -							break;
   2.990 -						} else {
   2.991 -							/* Mark that we got something invalid! */
   2.992 -							invalid_tokens = true;
   2.993 -							first_space = 0;
   2.994 -						}
   2.995 -					}
   2.996 -				}
   2.997 -			}
   2.998 -
   2.999 -			/* Now we need to parse the value, if any */
  2.1000 -			if (val_ptr)
  2.1001 -			{
  2.1002 -				/* eat up spaces! there shouldn't be any h*/
  2.1003 -				while ((*val_ptr != '\0') && g_ws_chartable[(unsigned)*val_ptr] != 0)
  2.1004 -				{
  2.1005 -					val_ptr++;
  2.1006 -				}
  2.1007 -				if (*val_ptr == '\0')
  2.1008 -				{
  2.1009 -					val_ptr = NULL;
  2.1010 -					goto skip_value;
  2.1011 -				}
  2.1012 -				/* Do we have an initial quote? If so, the parsing rules change! */
  2.1013 -				if (*val_ptr == '"' && *val_ptr != '\0')
  2.1014 -				{
  2.1015 -					len = strlen(val_ptr);
  2.1016 -					if (val_ptr[len-1] == '"')
  2.1017 -					{
  2.1018 -						/* Strip quotes! */
  2.1019 -						val_ptr[--len] = '\0';
  2.1020 -						val_ptr++;
  2.1021 -						quotes = true;
  2.1022 -					}
  2.1023 -				}
  2.1024 -			}
  2.1025 -skip_value:
  2.1026 -			/* We're done! */
  2.1027 -			curtok = val_ptr - buffer;
  2.1028 -			if (!ini_listener->ReadINI_KeyValue(key_ptr, val_ptr, invalid_tokens, equal_token, quotes, &curtok))
  2.1029 -			{
  2.1030 -				curtok = 0;
  2.1031 -				goto event_failed;
  2.1032 -			}
  2.1033 -		}
  2.1034 -	}
  2.1035 -
  2.1036 -	if (line)
  2.1037 -	{
  2.1038 -		*line = curline;
  2.1039 -	}
  2.1040 -
  2.1041 -	fclose(fp);
  2.1042 -
  2.1043 -	return true;
  2.1044 -
  2.1045 -event_failed:
  2.1046 -	if (line)
  2.1047 -	{
  2.1048 -		*line = curline;
  2.1049 -	}
  2.1050 -
  2.1051 -	if (col)
  2.1052 -	{
  2.1053 -		*col = curtok;
  2.1054 -	}
  2.1055 -
  2.1056 -	fclose(fp);
  2.1057 -
  2.1058 -	return false;
  2.1059 -}
  2.1060 -
  2.1061 -const char *TextParsers::GetSMCErrorString(SMCError err)
  2.1062 -{
  2.1063 -	static const char *s_errors[] = 
  2.1064 -	{
  2.1065 -		NULL,
  2.1066 -		"Stream failed to open",
  2.1067 -		"Stream returned read error",
  2.1068 -		NULL,
  2.1069 -		"Un-quoted section has invalid tokens",
  2.1070 -		"Section declared without header",
  2.1071 -		"Section declared with unknown tokens",
  2.1072 -		"Section ending without a matching section beginning",
  2.1073 -		"Section beginning without a matching ending",
  2.1074 -		"Line contained too many invalid tokens",
  2.1075 -		"Token buffer overflowed",
  2.1076 -		"A property was declared outside of a section",
  2.1077 -	};
  2.1078 -
  2.1079 -	if (err < SMCError_Okay || err > SMCError_InvalidProperty1)
  2.1080 -	{
  2.1081 -		return NULL;
  2.1082 -	}
  2.1083 -
  2.1084 -	return s_errors[err];
  2.1085 -}
     3.1 --- a/tools/gamedata md5/TextParsers.h	Fri Aug 15 17:21:48 2008 +0000
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,87 +0,0 @@
     3.4 -/**
     3.5 - * vim: set ts=4 :
     3.6 - * =============================================================================
     3.7 - * SourceMod
     3.8 - * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
     3.9 - * =============================================================================
    3.10 - *
    3.11 - * This program is free software; you can redistribute it and/or modify it under
    3.12 - * the terms of the GNU General Public License, version 3.0, as published by the
    3.13 - * Free Software Foundation.
    3.14 - * 
    3.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
    3.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    3.17 - * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    3.18 - * details.
    3.19 - *
    3.20 - * You should have received a copy of the GNU General Public License along with
    3.21 - * this program.  If not, see <http://www.gnu.org/licenses/>.
    3.22 - *
    3.23 - * As a special exception, AlliedModders LLC gives you permission to link the
    3.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
    3.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    3.26 - * by the Valve Corporation.  You must obey the GNU General Public License in
    3.27 - * all respects for all other code used.  Additionally, AlliedModders LLC grants
    3.28 - * this exception to all derivative works.  AlliedModders LLC defines further
    3.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    3.30 - * or <http://www.sourcemod.net/license.php>.
    3.31 - *
    3.32 - * Version: $Id$
    3.33 - */
    3.34 -
    3.35 -#ifndef _INCLUDE_SOURCEMOD_TEXTPARSERS_H_
    3.36 -#define _INCLUDE_SOURCEMOD_TEXTPARSERS_H_
    3.37 -
    3.38 -#include "ITextParsers.h"
    3.39 -#include "main.h"
    3.40 -
    3.41 -using namespace SourceMod;
    3.42 -
    3.43 -/**
    3.44 - * @param void *			IN: Stream pointer
    3.45 - * @param char *			IN/OUT: Stream buffer
    3.46 - * @param size_t			IN: Maximum size of buffer
    3.47 - * @param unsigned int *	OUT: Number of bytes read (0 = end of stream)
    3.48 - * @return					True on success, false on failure
    3.49 - */
    3.50 -typedef bool (*STREAMREADER)(void *, char *, size_t, unsigned int *);
    3.51 -
    3.52 -class TextParsers : public ITextParsers
    3.53 -{
    3.54 -public:
    3.55 -	TextParsers();
    3.56 -public:
    3.57 -	bool ParseFile_INI(const char *file, 
    3.58 -		ITextListener_INI *ini_listener,
    3.59 -		unsigned int *line,
    3.60 -		unsigned int *col);
    3.61 -
    3.62 -	SMCError ParseFile_SMC(const char *file, 
    3.63 -		ITextListener_SMC *smc_listener, 
    3.64 -		SMCStates *states);
    3.65 -
    3.66 -	SMCError ParseSMCFile(const char *file,
    3.67 -			ITextListener_SMC *smc_listener,
    3.68 -			SMCStates *states,
    3.69 -			char *buffer,
    3.70 -			size_t maxsize);
    3.71 -
    3.72 -	unsigned int GetUTF8CharBytes(const char *stream);
    3.73 -
    3.74 -	const char *GetSMCErrorString(SMCError err);
    3.75 -	bool IsWhitespace(const char *stream);
    3.76 -private:
    3.77 -	SMCError ParseString_SMC(const char *stream, 
    3.78 -		ITextListener_SMC *smc,
    3.79 -		SMCStates *states);
    3.80 -	SMCError ParseStream_SMC(void *stream, 
    3.81 -		STREAMREADER srdr,
    3.82 -		ITextListener_SMC *smc,
    3.83 -		SMCStates *states);
    3.84 -
    3.85 -};
    3.86 -
    3.87 -extern TextParsers g_TextParser;
    3.88 -
    3.89 -#endif //_INCLUDE_SOURCEMOD_TEXTPARSERS_H_
    3.90 -
     4.1 --- a/tools/gamedata md5/main.cpp	Fri Aug 15 17:21:48 2008 +0000
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,45 +0,0 @@
     4.4 -#include "main.h"
     4.5 -#include <stdarg.h>
     4.6 -
     4.7 -BuildMD5ableBuffer g_MD5Builder;
     4.8 -
     4.9 -int main(int argc, char **argv)
    4.10 -{
    4.11 -	SMCStates states;
    4.12 -	SMCError error;
    4.13 -
    4.14 -	if (argc < 2)
    4.15 -	{
    4.16 -		fprintf(stderr, "Usage: <file>\n");
    4.17 -		return -1;
    4.18 -	}
    4.19 -
    4.20 -	error = g_TextParser.ParseFile_SMC(argv[1], &g_MD5Builder, &states);
    4.21 -
    4.22 -	if (error == SMCError_Okay)
    4.23 -	{
    4.24 -		printf("%s", g_MD5Builder.GetMD5String());
    4.25 -		return 0;
    4.26 -	}
    4.27 -
    4.28 -	fprintf(stderr, "Failed to parse file, Error %i at line %i and col %i\n", error, states.line, states.col);
    4.29 -	return -1;
    4.30 -}
    4.31 -
    4.32 -size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...)
    4.33 -{
    4.34 -	va_list ap;
    4.35 -	va_start(ap, fmt);
    4.36 -	size_t len = vsnprintf(buffer, maxlength, fmt, ap);
    4.37 -	va_end(ap);
    4.38 -
    4.39 -	if (len >= maxlength)
    4.40 -	{
    4.41 -		buffer[maxlength - 1] = '\0';
    4.42 -		return (maxlength - 1);
    4.43 -	}
    4.44 -	else
    4.45 -	{
    4.46 -		return len;
    4.47 -	}
    4.48 -}
     5.1 --- a/tools/gamedata md5/main.h	Fri Aug 15 17:21:48 2008 +0000
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,88 +0,0 @@
     5.4 -#ifndef _INCLUDE_GAMEDATAMD5_MAIN_H_
     5.5 -#define _INCLUDE_GAMEDATAMD5_MAIN_H_
     5.6 -
     5.7 -#include "TextParsers.h"
     5.8 -#include "sm_memtable.h"
     5.9 -#include "md5.h"
    5.10 -
    5.11 -using namespace SourceMod;
    5.12 -
    5.13 -size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...);
    5.14 -
    5.15 -class BuildMD5ableBuffer : public ITextListener_SMC
    5.16 -{
    5.17 -public:
    5.18 -
    5.19 -	BuildMD5ableBuffer()
    5.20 -	{
    5.21 -		stringTable = new BaseStringTable(2048);
    5.22 -		md5[0] = 0;
    5.23 -		md5String[0] = 0;
    5.24 -	}
    5.25 -
    5.26 -	~BuildMD5ableBuffer()
    5.27 -	{
    5.28 -		delete stringTable;
    5.29 -	}
    5.30 -
    5.31 -	void ReadSMC_ParseStart()
    5.32 -	{
    5.33 -		checksum = MD5();
    5.34 -	}
    5.35 -
    5.36 -	SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
    5.37 -	{
    5.38 -		stringTable->AddString(key);
    5.39 -		stringTable->AddString(value);
    5.40 -
    5.41 -		return SMCResult_Continue;
    5.42 -	}
    5.43 -
    5.44 -	SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name)
    5.45 -	{
    5.46 -		stringTable->AddString(name);
    5.47 -
    5.48 -		return SMCResult_Continue;
    5.49 -	}
    5.50 -
    5.51 -	void ReadSMC_ParseEnd(bool halted, bool failed)
    5.52 -	{
    5.53 -		if (halted || failed)
    5.54 -		{
    5.55 -			return;
    5.56 -		}
    5.57 -
    5.58 -		void *data = stringTable->GetMemTable()->GetAddress(0);
    5.59 -
    5.60 -		if (data != NULL)
    5.61 -		{
    5.62 -			checksum.update((unsigned char *)data, stringTable->GetMemTable()->GetActualMemUsed());
    5.63 -		}
    5.64 -
    5.65 -		checksum.finalize();
    5.66 -
    5.67 -		checksum.hex_digest(md5String);
    5.68 -		checksum.raw_digest(md5);
    5.69 -
    5.70 -		stringTable->Reset();
    5.71 -	}
    5.72 -
    5.73 -	unsigned char * GetMD5()
    5.74 -	{
    5.75 -		return md5;
    5.76 -	}
    5.77 -
    5.78 -	unsigned char * GetMD5String()
    5.79 -	{
    5.80 -		return (unsigned char *)&md5String[0];
    5.81 -	}
    5.82 -
    5.83 -private:
    5.84 -	MD5 checksum;
    5.85 -	unsigned char md5[16];
    5.86 -	char md5String[33];
    5.87 -	BaseStringTable *stringTable;
    5.88 -};
    5.89 -
    5.90 -
    5.91 -#endif // _INCLUDE_GAMEDATAMD5_MAIN_H_
     6.1 --- a/tools/gamedata md5/md5.cpp	Fri Aug 15 17:21:48 2008 +0000
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,485 +0,0 @@
     6.4 -// MD5.CC - source code for the C++/object oriented translation and 
     6.5 -//          modification of MD5.
     6.6 -
     6.7 -// Translation and modification (c) 1995 by Mordechai T. Abzug 
     6.8 -
     6.9 -// This translation/ modification is provided "as is," without express or 
    6.10 -// implied warranty of any kind.
    6.11 -
    6.12 -// The translator/ modifier does not claim (1) that MD5 will do what you think 
    6.13 -// it does; (2) that this translation/ modification is accurate; or (3) that 
    6.14 -// this software is "merchantible."  (Language for this disclaimer partially 
    6.15 -// copied from the disclaimer below).
    6.16 -
    6.17 -/* based on:
    6.18 -
    6.19 -   MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
    6.20 -   MDDRIVER.C - test driver for MD2, MD4 and MD5
    6.21 -
    6.22 -
    6.23 -   Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
    6.24 -rights reserved.
    6.25 -
    6.26 -License to copy and use this software is granted provided that it
    6.27 -is identified as the "RSA Data Security, Inc. MD5 Message-Digest
    6.28 -Algorithm" in all material mentioning or referencing this software
    6.29 -or this function.
    6.30 -
    6.31 -License is also granted to make and use derivative works provided
    6.32 -that such works are identified as "derived from the RSA Data
    6.33 -Security, Inc. MD5 Message-Digest Algorithm" in all material
    6.34 -mentioning or referencing the derived work.
    6.35 -
    6.36 -RSA Data Security, Inc. makes no representations concerning either
    6.37 -the merchantability of this software or the suitability of this
    6.38 -software for any particular purpose. It is provided "as is"
    6.39 -without express or implied warranty of any kind.
    6.40 -
    6.41 -These notices must be retained in any copies of any part of this
    6.42 -documentation and/or software.
    6.43 -
    6.44 - */
    6.45 -
    6.46 -#include "md5.h"
    6.47 -
    6.48 -#include <assert.h>
    6.49 -#include <string.h>
    6.50 -
    6.51 -// MD5 simple initialization method
    6.52 -
    6.53 -MD5::MD5(){
    6.54 -
    6.55 -  init();
    6.56 -
    6.57 -}
    6.58 -
    6.59 -
    6.60 -// MD5 block update operation. Continues an MD5 message-digest
    6.61 -// operation, processing another message block, and updating the
    6.62 -// context.
    6.63 -
    6.64 -void MD5::update (uint1 *input, uint4 input_length) {
    6.65 -
    6.66 -  uint4 input_index, buffer_index;
    6.67 -  uint4 buffer_space;                // how much space is left in buffer
    6.68 -
    6.69 -  if (finalized){  // so we can't update!
    6.70 -    /*cerr << "MD5::update:  Can't update a finalized digest!" << endl;*/
    6.71 -    return;
    6.72 -  }
    6.73 -
    6.74 -  // Compute number of bytes mod 64
    6.75 -  buffer_index = (unsigned int)((count[0] >> 3) & 0x3F);
    6.76 -
    6.77 -  // Update number of bits
    6.78 -  if (  (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) )
    6.79 -    count[1]++;
    6.80 -
    6.81 -  count[1] += ((uint4)input_length >> 29);
    6.82 -
    6.83 -
    6.84 -  buffer_space = 64 - buffer_index;  // how much space is left in buffer
    6.85 -
    6.86 -  // Transform as many times as possible.
    6.87 -  if (input_length >= buffer_space) { // ie. we have enough to fill the buffer
    6.88 -    // fill the rest of the buffer and transform
    6.89 -    memcpy (buffer + buffer_index, input, buffer_space);
    6.90 -    transform (buffer);
    6.91 -
    6.92 -    // now, transform each 64-byte piece of the input, bypassing the buffer
    6.93 -    for (input_index = buffer_space; input_index + 63 < input_length; 
    6.94 -	 input_index += 64)
    6.95 -      transform (input+input_index);
    6.96 -
    6.97 -    buffer_index = 0;  // so we can buffer remaining
    6.98 -  }
    6.99 -  else
   6.100 -    input_index=0;     // so we can buffer the whole input
   6.101 -
   6.102 -
   6.103 -  // and here we do the buffering:
   6.104 -  memcpy(buffer+buffer_index, input+input_index, input_length-input_index);
   6.105 -}
   6.106 -
   6.107 -
   6.108 -
   6.109 -// MD5 update for files.
   6.110 -// Like above, except that it works on files (and uses above as a primitive.)
   6.111 -
   6.112 -void MD5::update(FILE *file){
   6.113 -
   6.114 -  unsigned char buffer[1024];
   6.115 -  int len;
   6.116 -
   6.117 -  while ((len=fread(buffer, 1, 1024, file)))
   6.118 -    update(buffer, len);
   6.119 -
   6.120 -  fclose (file);
   6.121 -
   6.122 -}
   6.123 -
   6.124 -
   6.125 -// MD5 finalization. Ends an MD5 message-digest operation, writing the
   6.126 -// the message digest and zeroizing the context.
   6.127 -
   6.128 -
   6.129 -void MD5::finalize (){
   6.130 -
   6.131 -  unsigned char bits[8];
   6.132 -  unsigned int index, padLen;
   6.133 -  static uint1 PADDING[64]={
   6.134 -    0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   6.135 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   6.136 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
   6.137 -    };
   6.138 -
   6.139 -  if (finalized){
   6.140 -   /* cerr << "MD5::finalize:  Already finalized this digest!" << endl;*/
   6.141 -    return;
   6.142 -  }
   6.143 -
   6.144 -  // Save number of bits
   6.145 -  encode (bits, count, 8);
   6.146 -
   6.147 -  // Pad out to 56 mod 64.
   6.148 -  index = (uint4) ((count[0] >> 3) & 0x3f);
   6.149 -  padLen = (index < 56) ? (56 - index) : (120 - index);
   6.150 -  update (PADDING, padLen);
   6.151 -
   6.152 -  // Append length (before padding)
   6.153 -  update (bits, 8);
   6.154 -
   6.155 -  // Store state in digest
   6.156 -  encode (digest, state, 16);
   6.157 -
   6.158 -  // Zeroize sensitive information
   6.159 -  memset (buffer, 0, sizeof(*buffer));
   6.160 -
   6.161 -  finalized=1;
   6.162 -
   6.163 -}
   6.164 -
   6.165 -
   6.166 -
   6.167 -
   6.168 -MD5::MD5(FILE *file){
   6.169 -
   6.170 -  init();  // must be called be all constructors
   6.171 -  update(file);
   6.172 -  finalize ();
   6.173 -}
   6.174 -
   6.175 -unsigned char *MD5::raw_digest(){
   6.176 -
   6.177 -  uint1 *s = new uint1[16];
   6.178 -
   6.179 -  if (!finalized){
   6.180 -/*    cerr << "MD5::raw_digest:  Can't get digest if you haven't "<<
   6.181 -      "finalized the digest!" <<endl;*/
   6.182 -    return ( (unsigned char*) "");
   6.183 -  }
   6.184 -
   6.185 -  memcpy(s, digest, 16);
   6.186 -  return s;
   6.187 -}
   6.188 -
   6.189 -unsigned char *MD5::raw_digest(unsigned char buffer[16])
   6.190 -{
   6.191 -	if (!finalized)
   6.192 -	{
   6.193 -		return ( (unsigned char*) "");
   6.194 -	}
   6.195 -
   6.196 -	 memcpy(buffer, digest, 16);
   6.197 -	 return buffer;
   6.198 -}
   6.199 -
   6.200 -
   6.201 -
   6.202 -char *MD5::hex_digest(){
   6.203 -
   6.204 -  int i;
   6.205 -  char *s= new char[33];
   6.206 -
   6.207 -  if (!finalized){
   6.208 -/*    cerr << "MD5::hex_digest:  Can't get digest if you haven't "<<
   6.209 -      "finalized the digest!" <<endl;*/
   6.210 -    return "";
   6.211 -  }
   6.212 -
   6.213 -  for (i=0; i<16; i++)
   6.214 -    sprintf(s+i*2, "%02x", digest[i]);
   6.215 -
   6.216 -  s[32]='\0';
   6.217 -
   6.218 -  return s;
   6.219 -}
   6.220 -
   6.221 -
   6.222 -char *MD5::hex_digest(char buffer[33]){
   6.223 -
   6.224 -  int i;
   6.225 -
   6.226 -  if (!finalized)
   6.227 -  {
   6.228 -	 /* cerr << "MD5::hex_digest:  Can't get digest if you haven't "<<
   6.229 -      "finalized the digest!" <<endl;*/
   6.230 -    return "";
   6.231 -  }
   6.232 -
   6.233 -  for (i=0; i<16; i++)
   6.234 -    sprintf(buffer+i*2, "%02x", digest[i]);
   6.235 -
   6.236 -  buffer[32]='\0';
   6.237 -
   6.238 -  return buffer;
   6.239 -}
   6.240 -
   6.241 -
   6.242 -// PRIVATE METHODS:
   6.243 -
   6.244 -
   6.245 -
   6.246 -void MD5::init(){
   6.247 -  finalized=0;  // we just started!
   6.248 -
   6.249 -  // Nothing counted, so count=0
   6.250 -  count[0] = 0;
   6.251 -  count[1] = 0;
   6.252 -
   6.253 -  // Load magic initialization constants.
   6.254 -  state[0] = 0x67452301;
   6.255 -  state[1] = 0xefcdab89;
   6.256 -  state[2] = 0x98badcfe;
   6.257 -  state[3] = 0x10325476;
   6.258 -}
   6.259 -
   6.260 -
   6.261 -
   6.262 -// Constants for MD5Transform routine.
   6.263 -// Although we could use C++ style constants, defines are actually better,
   6.264 -// since they let us easily evade scope clashes.
   6.265 -
   6.266 -#define S11 7
   6.267 -#define S12 12
   6.268 -#define S13 17
   6.269 -#define S14 22
   6.270 -#define S21 5
   6.271 -#define S22 9
   6.272 -#define S23 14
   6.273 -#define S24 20
   6.274 -#define S31 4
   6.275 -#define S32 11
   6.276 -#define S33 16
   6.277 -#define S34 23
   6.278 -#define S41 6
   6.279 -#define S42 10
   6.280 -#define S43 15
   6.281 -#define S44 21
   6.282 -
   6.283 -
   6.284 -
   6.285 -
   6.286 -// MD5 basic transformation. Transforms state based on block.
   6.287 -void MD5::transform (uint1 block[64]){
   6.288 -
   6.289 -  uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
   6.290 -
   6.291 -  decode (x, block, 64);
   6.292 -
   6.293 -  assert(!finalized);  // not just a user error, since the method is private
   6.294 -
   6.295 -  /* Round 1 */
   6.296 -  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
   6.297 -  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
   6.298 -  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
   6.299 -  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
   6.300 -  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
   6.301 -  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
   6.302 -  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
   6.303 -  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
   6.304 -  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
   6.305 -  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
   6.306 -  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
   6.307 -  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
   6.308 -  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
   6.309 -  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
   6.310 -  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
   6.311 -  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
   6.312 -
   6.313 - /* Round 2 */
   6.314 -  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
   6.315 -  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
   6.316 -  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
   6.317 -  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
   6.318 -  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
   6.319 -  GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
   6.320 -  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
   6.321 -  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
   6.322 -  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
   6.323 -  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
   6.324 -  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
   6.325 -  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
   6.326 -  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
   6.327 -  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
   6.328 -  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
   6.329 -  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
   6.330 -
   6.331 -  /* Round 3 */
   6.332 -  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
   6.333 -  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
   6.334 -  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
   6.335 -  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
   6.336 -  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
   6.337 -  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
   6.338 -  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
   6.339 -  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
   6.340 -  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
   6.341 -  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
   6.342 -  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
   6.343 -  HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
   6.344 -  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
   6.345 -  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
   6.346 -  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
   6.347 -  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
   6.348 -
   6.349 -  /* Round 4 */
   6.350 -  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
   6.351 -  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
   6.352 -  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
   6.353 -  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
   6.354 -  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
   6.355 -  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
   6.356 -  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
   6.357 -  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
   6.358 -  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
   6.359 -  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
   6.360 -  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
   6.361 -  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
   6.362 -  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
   6.363 -  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
   6.364 -  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
   6.365 -  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
   6.366 -
   6.367 -  state[0] += a;
   6.368 -  state[1] += b;
   6.369 -  state[2] += c;
   6.370 -  state[3] += d;
   6.371 -
   6.372 -  // Zeroize sensitive information.
   6.373 -  memset ( (uint1 *) x, 0, sizeof(x));
   6.374 -
   6.375 -}
   6.376 -
   6.377 -
   6.378 -
   6.379 -// Encodes input (UINT4) into output (unsigned char). Assumes len is
   6.380 -// a multiple of 4.
   6.381 -void MD5::encode (uint1 *output, uint4 *input, uint4 len) {
   6.382 -
   6.383 -  unsigned int i, j;
   6.384 -
   6.385 -  for (i = 0, j = 0; j < len; i++, j += 4) {
   6.386 -    output[j]   = (uint1)  (input[i] & 0xff);
   6.387 -    output[j+1] = (uint1) ((input[i] >> 8) & 0xff);
   6.388 -    output[j+2] = (uint1) ((input[i] >> 16) & 0xff);
   6.389 -    output[j+3] = (uint1) ((input[i] >> 24) & 0xff);
   6.390 -  }
   6.391 -}
   6.392 -
   6.393 -
   6.394 -
   6.395 -
   6.396 -// Decodes input (unsigned char) into output (UINT4). Assumes len is
   6.397 -// a multiple of 4.
   6.398 -void MD5::decode (uint4 *output, uint1 *input, uint4 len){
   6.399 -
   6.400 -  unsigned int i, j;
   6.401 -
   6.402 -  for (i = 0, j = 0; j < len; i++, j += 4)
   6.403 -    output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
   6.404 -      (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
   6.405 -}
   6.406 -
   6.407 -
   6.408 -
   6.409 -
   6.410 -
   6.411 -// Note: Replace "for loop" with standard memcpy if possible.
   6.412 -void MD5::memcpy (uint1 *output, uint1 *input, uint4 len){
   6.413 -
   6.414 -  unsigned int i;
   6.415 -
   6.416 -  for (i = 0; i < len; i++)
   6.417 -    output[i] = input[i];
   6.418 -}
   6.419 -
   6.420 -
   6.421 -
   6.422 -// Note: Replace "for loop" with standard memset if possible.
   6.423 -void MD5::memset (uint1 *output, uint1 value, uint4 len){
   6.424 -
   6.425 -  unsigned int i;
   6.426 -
   6.427 -  for (i = 0; i < len; i++)
   6.428 -    output[i] = value;
   6.429 -}
   6.430 -
   6.431 -
   6.432 -
   6.433 -// ROTATE_LEFT rotates x left n bits.
   6.434 -
   6.435 -inline unsigned int MD5::rotate_left  (uint4 x, uint4 n){
   6.436 -  return (x << n) | (x >> (32-n))  ;
   6.437 -}
   6.438 -
   6.439 -
   6.440 -
   6.441 -
   6.442 -// F, G, H and I are basic MD5 functions.
   6.443 -
   6.444 -inline unsigned int MD5::F            (uint4 x, uint4 y, uint4 z){
   6.445 -  return (x & y) | (~x & z);
   6.446 -}
   6.447 -
   6.448 -inline unsigned int MD5::G            (uint4 x, uint4 y, uint4 z){
   6.449 -  return (x & z) | (y & ~z);
   6.450 -}
   6.451 -
   6.452 -inline unsigned int MD5::H            (uint4 x, uint4 y, uint4 z){
   6.453 -  return x ^ y ^ z;
   6.454 -}
   6.455 -
   6.456 -inline unsigned int MD5::I            (uint4 x, uint4 y, uint4 z){
   6.457 -  return y ^ (x | ~z);
   6.458 -}
   6.459 -
   6.460 -
   6.461 -
   6.462 -// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
   6.463 -// Rotation is separate from addition to prevent recomputation.
   6.464 -
   6.465 -
   6.466 -inline void MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
   6.467 -		    uint4  s, uint4 ac){
   6.468 - a += F(b, c, d) + x + ac;
   6.469 - a = rotate_left (a, s) +b;
   6.470 -}
   6.471 -
   6.472 -inline void MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
   6.473 -		    uint4 s, uint4 ac){
   6.474 - a += G(b, c, d) + x + ac;
   6.475 - a = rotate_left (a, s) +b;
   6.476 -}
   6.477 -
   6.478 -inline void MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
   6.479 -		    uint4 s, uint4 ac){
   6.480 - a += H(b, c, d) + x + ac;
   6.481 - a = rotate_left (a, s) +b;
   6.482 -}
   6.483 -
   6.484 -inline void MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
   6.485 -			     uint4 s, uint4 ac){
   6.486 - a += I(b, c, d) + x + ac;
   6.487 - a = rotate_left (a, s) +b;
   6.488 -}
     7.1 --- a/tools/gamedata md5/md5.h	Fri Aug 15 17:21:48 2008 +0000
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,106 +0,0 @@
     7.4 -// MD5.CC - source code for the C++/object oriented translation and 
     7.5 -//          modification of MD5.
     7.6 -
     7.7 -// Translation and modification (c) 1995 by Mordechai T. Abzug 
     7.8 -
     7.9 -// This translation/ modification is provided "as is," without express or 
    7.10 -// implied warranty of any kind.
    7.11 -
    7.12 -// The translator/ modifier does not claim (1) that MD5 will do what you think 
    7.13 -// it does; (2) that this translation/ modification is accurate; or (3) that 
    7.14 -// this software is "merchantible."  (Language for this disclaimer partially 
    7.15 -// copied from the disclaimer below).
    7.16 -
    7.17 -/* based on:
    7.18 -
    7.19 -   MD5.H - header file for MD5C.C
    7.20 -   MDDRIVER.C - test driver for MD2, MD4 and MD5
    7.21 -
    7.22 -   Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
    7.23 -rights reserved.
    7.24 -
    7.25 -License to copy and use this software is granted provided that it
    7.26 -is identified as the "RSA Data Security, Inc. MD5 Message-Digest
    7.27 -Algorithm" in all material mentioning or referencing this software
    7.28 -or this function.
    7.29 -
    7.30 -License is also granted to make and use derivative works provided
    7.31 -that such works are identified as "derived from the RSA Data
    7.32 -Security, Inc. MD5 Message-Digest Algorithm" in all material
    7.33 -mentioning or referencing the derived work.
    7.34 -
    7.35 -RSA Data Security, Inc. makes no representations concerning either
    7.36 -the merchantability of this software or the suitability of this
    7.37 -software for any particular purpose. It is provided "as is"
    7.38 -without express or implied warranty of any kind.
    7.39 -
    7.40 -These notices must be retained in any copies of any part of this
    7.41 -documentation and/or software.
    7.42 -
    7.43 -*/
    7.44 -
    7.45 -#include <stdio.h>
    7.46 -//#include <fstream.h>
    7.47 -//#include <iostream.h>
    7.48 -
    7.49 -class MD5 {
    7.50 -
    7.51 -public:
    7.52 -// methods for controlled operation:
    7.53 -  MD5              ();  // simple initializer
    7.54 -  void  update     (unsigned char *input, unsigned int input_length);
    7.55 -  void  update     (FILE *file);
    7.56 -  void  finalize   ();
    7.57 -
    7.58 -// constructors for special circumstances.  All these constructors finalize
    7.59 -// the MD5 context.
    7.60 -  MD5              (unsigned char *string); // digest string, finalize
    7.61 -  MD5              (FILE *file);            // digest file, close, finalize
    7.62 -
    7.63 -// methods to acquire finalized result
    7.64 -  unsigned char    *raw_digest ();  // digest as a 16-byte binary array
    7.65 -  unsigned char		*raw_digest(unsigned char buffer[16]);
    7.66 -  char *            hex_digest ();  // digest as a 33-byte ascii-hex string
    7.67 -  char *			hex_digest (char buffer[33]); //same as above, passing buffer
    7.68 -
    7.69 -
    7.70 -
    7.71 -private:
    7.72 -
    7.73 -// first, some types:
    7.74 -  typedef unsigned       int uint4; // assumes integer is 4 words long
    7.75 -  typedef unsigned short int uint2; // assumes short integer is 2 words long
    7.76 -  typedef unsigned      char uint1; // assumes char is 1 word long
    7.77 -
    7.78 -// next, the private data:
    7.79 -  uint4 state[4];
    7.80 -  uint4 count[2];     // number of *bits*, mod 2^64
    7.81 -  uint1 buffer[64];   // input buffer
    7.82 -  uint1 digest[16];
    7.83 -  uint1 finalized;
    7.84 -
    7.85 -// last, the private methods, mostly static:
    7.86 -  void init             ();               // called by all constructors
    7.87 -  void transform        (uint1 *buffer);  // does the real update work.  Note 
    7.88 -                                          // that length is implied to be 64.
    7.89 -
    7.90 -  static void encode    (uint1 *dest, uint4 *src, uint4 length);
    7.91 -  static void decode    (uint4 *dest, uint1 *src, uint4 length);
    7.92 -  static void memcpy    (uint1 *dest, uint1 *src, uint4 length);
    7.93 -  static void memset    (uint1 *start, uint1 val, uint4 length);
    7.94 -
    7.95 -  static inline uint4  rotate_left (uint4 x, uint4 n);
    7.96 -  static inline uint4  F           (uint4 x, uint4 y, uint4 z);
    7.97 -  static inline uint4  G           (uint4 x, uint4 y, uint4 z);
    7.98 -  static inline uint4  H           (uint4 x, uint4 y, uint4 z);
    7.99 -  static inline uint4  I           (uint4 x, uint4 y, uint4 z);
   7.100 -  static inline void   FF  (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
   7.101 -			    uint4 s, uint4 ac);
   7.102 -  static inline void   GG  (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
   7.103 -			    uint4 s, uint4 ac);
   7.104 -  static inline void   HH  (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
   7.105 -			    uint4 s, uint4 ac);
   7.106 -  static inline void   II  (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
   7.107 -			    uint4 s, uint4 ac);
   7.108 -
   7.109 -};
     8.1 --- a/tools/gamedata md5/msvc9/gamedatamd5.sln	Fri Aug 15 17:21:48 2008 +0000
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,20 +0,0 @@
     8.4 -
     8.5 -Microsoft Visual Studio Solution File, Format Version 10.00
     8.6 -# Visual Studio 2008
     8.7 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gamedatamd5", "gamedatamd5.vcproj", "{E1C96598-E1AC-4928-8930-F8B6CD245B12}"
     8.8 -EndProject
     8.9 -Global
    8.10 -	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    8.11 -		Debug|Win32 = Debug|Win32
    8.12 -		Release|Win32 = Release|Win32
    8.13 -	EndGlobalSection
    8.14 -	GlobalSection(ProjectConfigurationPlatforms) = postSolution
    8.15 -		{E1C96598-E1AC-4928-8930-F8B6CD245B12}.Debug|Win32.ActiveCfg = Debug|Win32
    8.16 -		{E1C96598-E1AC-4928-8930-F8B6CD245B12}.Debug|Win32.Build.0 = Debug|Win32
    8.17 -		{E1C96598-E1AC-4928-8930-F8B6CD245B12}.Release|Win32.ActiveCfg = Release|Win32
    8.18 -		{E1C96598-E1AC-4928-8930-F8B6CD245B12}.Release|Win32.Build.0 = Release|Win32
    8.19 -	EndGlobalSection
    8.20 -	GlobalSection(SolutionProperties) = preSolution
    8.21 -		HideSolutionNode = FALSE
    8.22 -	EndGlobalSection
    8.23 -EndGlobal
     9.1 --- a/tools/gamedata md5/msvc9/gamedatamd5.vcproj	Fri Aug 15 17:21:48 2008 +0000
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,219 +0,0 @@
     9.4 -<?xml version="1.0" encoding="UTF-8"?>
     9.5 -<VisualStudioProject
     9.6 -	ProjectType="Visual C++"
     9.7 -	Version="9.00"
     9.8 -	Name="gamedatamd5"
     9.9 -	ProjectGUID="{E1C96598-E1AC-4928-8930-F8B6CD245B12}"
    9.10 -	Keyword="Win32Proj"
    9.11 -	TargetFrameworkVersion="0"
    9.12 -	>
    9.13 -	<Platforms>
    9.14 -		<Platform
    9.15 -			Name="Win32"
    9.16 -		/>
    9.17 -	</Platforms>
    9.18 -	<ToolFiles>
    9.19 -	</ToolFiles>
    9.20 -	<Configurations>
    9.21 -		<Configuration
    9.22 -			Name="Debug|Win32"
    9.23 -			OutputDirectory="Debug"
    9.24 -			IntermediateDirectory="Debug"
    9.25 -			ConfigurationType="1"
    9.26 -			CharacterSet="2"
    9.27 -			>
    9.28 -			<Tool
    9.29 -				Name="VCPreBuildEventTool"
    9.30 -			/>
    9.31 -			<Tool
    9.32 -				Name="VCCustomBuildTool"
    9.33 -			/>
    9.34 -			<Tool
    9.35 -				Name="VCXMLDataGeneratorTool"
    9.36 -			/>
    9.37 -			<Tool
    9.38 -				Name="VCWebServiceProxyGeneratorTool"
    9.39 -			/>
    9.40 -			<Tool
    9.41 -				Name="VCMIDLTool"
    9.42 -			/>
    9.43 -			<Tool
    9.44 -				Name="VCCLCompilerTool"
    9.45 -				Optimization="0"
    9.46 -				AdditionalIncludeDirectories="../../../public;../../../public/sourcepawn"
    9.47 -				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
    9.48 -				MinimalRebuild="true"
    9.49 -				BasicRuntimeChecks="3"
    9.50 -				RuntimeLibrary="1"
    9.51 -				UsePrecompiledHeader="0"
    9.52 -				WarningLevel="3"
    9.53 -				Detect64BitPortabilityProblems="false"
    9.54 -				DebugInformationFormat="4"
    9.55 -			/>
    9.56 -			<Tool
    9.57 -				Name="VCManagedResourceCompilerTool"
    9.58 -			/>
    9.59 -			<Tool
    9.60 -				Name="VCResourceCompilerTool"
    9.61 -			/>
    9.62 -			<Tool
    9.63 -				Name="VCPreLinkEventTool"
    9.64 -			/>
    9.65 -			<Tool
    9.66 -				Name="VCLinkerTool"
    9.67 -				LinkIncremental="2"
    9.68 -				GenerateDebugInformation="true"
    9.69 -				SubSystem="1"
    9.70 -				TargetMachine="1"
    9.71 -			/>
    9.72 -			<Tool
    9.73 -				Name="VCALinkTool"
    9.74 -			/>
    9.75 -			<Tool
    9.76 -				Name="VCManifestTool"
    9.77 -			/>
    9.78 -			<Tool
    9.79 -				Name="VCXDCMakeTool"
    9.80 -			/>
    9.81 -			<Tool
    9.82 -				Name="VCBscMakeTool"
    9.83 -			/>
    9.84 -			<Tool
    9.85 -				Name="VCFxCopTool"
    9.86 -			/>
    9.87 -			<Tool
    9.88 -				Name="VCAppVerifierTool"
    9.89 -			/>
    9.90 -			<Tool
    9.91 -				Name="VCPostBuildEventTool"
    9.92 -			/>
    9.93 -		</Configuration>
    9.94 -		<Configuration
    9.95 -			Name="Release|Win32"
    9.96 -			OutputDirectory="Release"
    9.97 -			IntermediateDirectory="Release"
    9.98 -			ConfigurationType="1"
    9.99 -			>
   9.100 -			<Tool
   9.101 -				Name="VCPreBuildEventTool"
   9.102 -			/>
   9.103 -			<Tool
   9.104 -				Name="VCCustomBuildTool"
   9.105 -			/>
   9.106 -			<Tool
   9.107 -				Name="VCXMLDataGeneratorTool"
   9.108 -			/>
   9.109 -			<Tool
   9.110 -				Name="VCWebServiceProxyGeneratorTool"
   9.111 -			/>
   9.112 -			<Tool
   9.113 -				Name="VCMIDLTool"
   9.114 -			/>
   9.115 -			<Tool
   9.116 -				Name="VCCLCompilerTool"
   9.117 -				AdditionalIncludeDirectories="../../../public;../../../public/sourcepawn"
   9.118 -				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
   9.119 -				RuntimeLibrary="0"
   9.120 -				UsePrecompiledHeader="0"
   9.121 -				WarningLevel="3"
   9.122 -				Detect64BitPortabilityProblems="false"
   9.123 -				DebugInformationFormat="3"
   9.124 -			/>
   9.125 -			<Tool
   9.126 -				Name="VCManagedResourceCompilerTool"
   9.127 -			/>
   9.128 -			<Tool
   9.129 -				Name="VCResourceCompilerTool"
   9.130 -			/>
   9.131 -			<Tool
   9.132 -				Name="VCPreLinkEventTool"
   9.133 -			/>
   9.134 -			<Tool
   9.135 -				Name="VCLinkerTool"
   9.136 -				LinkIncremental="2"
   9.137 -				GenerateDebugInformation="true"
   9.138 -				SubSystem="1"
   9.139 -				OptimizeReferences="2"
   9.140 -				EnableCOMDATFolding="2"
   9.141 -				TargetMachine="1"
   9.142 -			/>
   9.143 -			<Tool
   9.144 -				Name="VCALinkTool"
   9.145 -			/>
   9.146 -			<Tool
   9.147 -				Name="VCManifestTool"
   9.148 -			/>
   9.149 -			<Tool
   9.150 -				Name="VCXDCMakeTool"
   9.151 -			/>
   9.152 -			<Tool
   9.153 -				Name="VCBscMakeTool"
   9.154 -			/>
   9.155 -			<Tool
   9.156 -				Name="VCFxCopTool"
   9.157 -			/>
   9.158 -			<Tool
   9.159 -				Name="VCAppVerifierTool"
   9.160 -			/>
   9.161 -			<Tool
   9.162 -				Name="VCPostBuildEventTool"
   9.163 -			/>
   9.164 -		</Configuration>
   9.165 -	</Configurations>
   9.166 -	<References>
   9.167 -	</References>
   9.168 -	<Files>
   9.169 -		<Filter
   9.170 -			Name="Header Files"
   9.171 -			Filter="h;hpp;hxx;hm;inl;inc;xsd"
   9.172 -			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
   9.173 -			>
   9.174 -			<File
   9.175 -				RelativePath="..\main.h"
   9.176 -				>
   9.177 -			</File>
   9.178 -			<File
   9.179 -				RelativePath="..\md5.h"
   9.180 -				>
   9.181 -			</File>
   9.182 -			<File
   9.183 -				RelativePath="..\sm_memtable.h"
   9.184 -				>
   9.185 -			</File>
   9.186 -			<File
   9.187 -				RelativePath="..\TextParsers.h"
   9.188 -				>
   9.189 -			</File>
   9.190 -		</Filter>
   9.191 -		<Filter
   9.192 -			Name="Resource Files"
   9.193 -			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
   9.194 -			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
   9.195 -			>
   9.196 -		</Filter>
   9.197 -		<Filter
   9.198 -			Name="Source Files"
   9.199 -			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
   9.200 -			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
   9.201 -			>
   9.202 -			<File
   9.203 -				RelativePath="..\main.cpp"
   9.204 -				>
   9.205 -			</File>
   9.206 -			<File
   9.207 -				RelativePath="..\md5.cpp"
   9.208 -				>
   9.209 -			</File>
   9.210 -			<File
   9.211 -				RelativePath="..\sm_memtable.cpp"
   9.212 -				>
   9.213 -			</File>
   9.214 -			<File
   9.215 -				RelativePath="..\TextParsers.cpp"
   9.216 -				>
   9.217 -			</File>
   9.218 -		</Filter>
   9.219 -	</Files>
   9.220 -	<Globals>
   9.221 -	</Globals>
   9.222 -</VisualStudioProject>
    10.1 --- a/tools/gamedata md5/sm_memtable.cpp	Fri Aug 15 17:21:48 2008 +0000
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,112 +0,0 @@
    10.4 -/**
    10.5 - * vim: set ts=4 :
    10.6 - * =============================================================================
    10.7 - * SourceMod
    10.8 - * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    10.9 - * =============================================================================
   10.10 - *
   10.11 - * This program is free software; you can redistribute it and/or modify it under
   10.12 - * the terms of the GNU General Public License, version 3.0, as published by the
   10.13 - * Free Software Foundation.
   10.14 - * 
   10.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
   10.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   10.17 - * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   10.18 - * details.
   10.19 - *
   10.20 - * You should have received a copy of the GNU General Public License along with
   10.21 - * this program.  If not, see <http://www.gnu.org/licenses/>.
   10.22 - *
   10.23 - * As a special exception, AlliedModders LLC gives you permission to link the
   10.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
   10.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   10.26 - * by the Valve Corporation.  You must obey the GNU General Public License in
   10.27 - * all respects for all other code used.  Additionally, AlliedModders LLC grants
   10.28 - * this exception to all derivative works.  AlliedModders LLC defines further
   10.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   10.30 - * or <http://www.sourcemod.net/license.php>.
   10.31 - *
   10.32 - * Version: $Id$
   10.33 - */
   10.34 -
   10.35 -#include <string.h>
   10.36 -#include <malloc.h>
   10.37 -#include "sm_memtable.h"
   10.38 -
   10.39 -BaseMemTable::BaseMemTable(unsigned int init_size)
   10.40 -{
   10.41 -	membase = (unsigned char *)malloc(init_size);
   10.42 -	size = init_size;
   10.43 -	tail = 0;
   10.44 -}
   10.45 -
   10.46 -BaseMemTable::~BaseMemTable()
   10.47 -{
   10.48 -	free(membase);
   10.49 -	membase = NULL;
   10.50 -}
   10.51 -
   10.52 -int BaseMemTable::CreateMem(unsigned int addsize, void **addr)
   10.53 -{
   10.54 -	int idx = (int)tail;
   10.55 -
   10.56 -	while (tail + addsize >= size)
   10.57 -	{
   10.58 -		size *= 2;
   10.59 -		membase = (unsigned char *)realloc(membase, size);
   10.60 -	}
   10.61 -
   10.62 -	tail += addsize;
   10.63 -
   10.64 -	if (addr)
   10.65 -	{
   10.66 -		*addr = (void *)&membase[idx];
   10.67 -	}
   10.68 -
   10.69 -	return idx;
   10.70 -}
   10.71 -
   10.72 -void *BaseMemTable::GetAddress(int index)
   10.73 -{
   10.74 -	if (index < 0 || (unsigned int)index >= tail)
   10.75 -	{
   10.76 -		return NULL;
   10.77 -	}
   10.78 -
   10.79 -	return &membase[index];
   10.80 -}
   10.81 -
   10.82 -void BaseMemTable::Reset()
   10.83 -{
   10.84 -	tail = 0;
   10.85 -}
   10.86 -
   10.87 -BaseStringTable::BaseStringTable(unsigned int init_size) : m_table(init_size)
   10.88 -{
   10.89 -}
   10.90 -
   10.91 -BaseStringTable::~BaseStringTable()
   10.92 -{
   10.93 -}
   10.94 -
   10.95 -int BaseStringTable::AddString(const char *string)
   10.96 -{
   10.97 -	size_t len = strlen(string) + 1;
   10.98 -	int idx;
   10.99 -	char *addr;
  10.100 -
  10.101 -	idx = m_table.CreateMem(len, (void **)&addr);
  10.102 -	strcpy(addr, string);
  10.103 -
  10.104 -	return idx;
  10.105 -}
  10.106 -
  10.107 -/*const char *BaseStringTable::GetString(int str)
  10.108 -{
  10.109 -	return (const char *)m_table.GetAddress(str);
  10.110 -}*/
  10.111 -
  10.112 -void BaseStringTable::Reset()
  10.113 -{
  10.114 -	m_table.Reset();
  10.115 -}
    11.1 --- a/tools/gamedata md5/sm_memtable.h	Fri Aug 15 17:21:48 2008 +0000
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,114 +0,0 @@
    11.4 -/**
    11.5 - * vim: set ts=4 :
    11.6 - * =============================================================================
    11.7 - * SourceMod
    11.8 - * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    11.9 - * =============================================================================
   11.10 - *
   11.11 - * This program is free software; you can redistribute it and/or modify it under
   11.12 - * the terms of the GNU General Public License, version 3.0, as published by the
   11.13 - * Free Software Foundation.
   11.14 - * 
   11.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
   11.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   11.17 - * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   11.18 - * details.
   11.19 - *
   11.20 - * You should have received a copy of the GNU General Public License along with
   11.21 - * this program.  If not, see <http://www.gnu.org/licenses/>.
   11.22 - *
   11.23 - * As a special exception, AlliedModders LLC gives you permission to link the
   11.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
   11.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   11.26 - * by the Valve Corporation.  You must obey the GNU General Public License in
   11.27 - * all respects for all other code used.  Additionally, AlliedModders LLC grants
   11.28 - * this exception to all derivative works.  AlliedModders LLC defines further
   11.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   11.30 - * or <http://www.sourcemod.net/license.php>.
   11.31 - *
   11.32 - * Version: $Id$
   11.33 - */
   11.34 -
   11.35 -#ifndef _INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_
   11.36 -#define _INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_
   11.37 -
   11.38 -class BaseMemTable
   11.39 -{
   11.40 -public:
   11.41 -	BaseMemTable(unsigned int init_size);
   11.42 -	~BaseMemTable();
   11.43 -public:
   11.44 -	/**
   11.45 -	 * Allocates 'size' bytes of memory.
   11.46 -	 * Optionally outputs the address through 'addr'.
   11.47 -	 * Returns an index >= 0 on success, < 0 on failure.
   11.48 -	 */
   11.49 -	int CreateMem(unsigned int size, void **addr);
   11.50 -
   11.51 -	/**
   11.52 -	 * Given an index into the memory table, returns its address.
   11.53 -	 * Returns NULL if invalid.
   11.54 -	 */
   11.55 -	void *GetAddress(int index);
   11.56 -
   11.57 -	/**
   11.58 -	 * Scraps the memory table.  For caching purposes, the memory 
   11.59 -	 * is not freed, however subsequent calls to CreateMem() will 
   11.60 -	 * begin at the first index again.
   11.61 -	 */
   11.62 -	void Reset();
   11.63 -
   11.64 -	inline unsigned int GetMemUsage()
   11.65 -	{
   11.66 -		return size;
   11.67 -	}
   11.68 -
   11.69 -	inline unsigned int GetActualMemUsed()
   11.70 -	{
   11.71 -		return tail;
   11.72 -	}
   11.73 -
   11.74 -private:
   11.75 -	unsigned char *membase;
   11.76 -	unsigned int size;
   11.77 -	unsigned int tail;
   11.78 -};
   11.79 -
   11.80 -class BaseStringTable
   11.81 -{
   11.82 -public:
   11.83 -	BaseStringTable(unsigned int init_size);
   11.84 -	~BaseStringTable();
   11.85 -public:
   11.86 -	/** 
   11.87 -	 * Adds a string to the string table and returns its index.
   11.88 -	 */
   11.89 -	int AddString(const char *string);
   11.90 -
   11.91 -	/**
   11.92 -	 * Given an index into the string table, returns the associated string.
   11.93 -	 */
   11.94 -	inline const char *GetString(int str)
   11.95 -	{
   11.96 -		return (const char *)m_table.GetAddress(str);
   11.97 -	}
   11.98 -
   11.99 -	/**
  11.100 -	 * Scraps the string table.  For caching purposes, the memory
  11.101 -	 * is not freed, however subsequent calls to AddString() will 
  11.102 -	 * begin at the first index again.
  11.103 -	 */
  11.104 -	void Reset();
  11.105 -
  11.106 -	/**
  11.107 -	 * Returns the parent BaseMemTable that this string table uses.
  11.108 -	 */
  11.109 -	inline BaseMemTable *GetMemTable()
  11.110 -	{
  11.111 -		return &m_table;
  11.112 -	}
  11.113 -private:
  11.114 -	BaseMemTable m_table;
  11.115 -};
  11.116 -
  11.117 -#endif //_INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/tools/gamedata_md5/Makefile	Sun Aug 17 18:27:51 2008 +0000
    12.3 @@ -0,0 +1,74 @@
    12.4 +# (C)2004-2008 SourceMod Development Team
    12.5 +# Makefile written by David "BAILOPAN" Anderson
    12.6 +
    12.7 +
    12.8 +#####################################
    12.9 +### EDIT BELOW FOR OTHER PROJECTS ###
   12.10 +#####################################
   12.11 +
   12.12 +OBJECTS = main.cpp TextParsers.cpp sm_memtable.cpp md5.cpp
   12.13 +
   12.14 +##############################################
   12.15 +### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
   12.16 +##############################################
   12.17 +
   12.18 +C_OPT_FLAGS = -DNDEBUG -O3 -funroll-loops -pipe -fno-strict-aliasing
   12.19 +C_DEBUG_FLAGS = -D_DEBUG -DDEBUG -g -ggdb3
   12.20 +C_GCC4_FLAGS = -fvisibility=hidden
   12.21 +CPP_GCC4_FLAGS = -fvisibility-inlines-hidden
   12.22 +CPP = gcc-4.1
   12.23 +
   12.24 +BINARY = gamedatamd5
   12.25 +
   12.26 +INCLUDE += -I. -I../../public -I../../public/sourcepawn
   12.27 +
   12.28 +CFLAGS += -D_LINUX -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp \
   12.29 +	-D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp -Wall -Werror \
   12.30 +	-Wno-uninitialized -mfpmath=sse -msse -DHAVE_STDINT_H -DSM_DEFAULT_THREADER -m32
   12.31 +CPPFLAGS += -Wno-non-virtual-dtor -fno-exceptions -fno-rtti
   12.32 +
   12.33 +################################################
   12.34 +### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ###
   12.35 +################################################
   12.36 +
   12.37 +ifeq "$(DEBUG)" "true"
   12.38 +	BIN_DIR = Debug
   12.39 +	CFLAGS += $(C_DEBUG_FLAGS)
   12.40 +else
   12.41 +	BIN_DIR = Release
   12.42 +	CFLAGS += $(C_OPT_FLAGS)
   12.43 +endif
   12.44 +
   12.45 +GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1)
   12.46 +ifeq "$(GCC_VERSION)" "4"
   12.47 +	CFLAGS += $(C_GCC4_FLAGS)
   12.48 +	CPPFLAGS += $(CPP_GCC4_FLAGS)
   12.49 +endif
   12.50 +
   12.51 +OBJ_LINUX := $(OBJECTS:%vm_engine.cpp=$(BIN_DIR)/%vm_engine.o)
   12.52 +OBJ_LINUX := $(OBJ_LINUX:%.cpp=$(BIN_DIR)/%.o)
   12.53 +OBJ_LINUX := $(OBJ_LINUX:%.c=$(BIN_DIR)/%.o)
   12.54 +
   12.55 +$(BIN_DIR)/%vm_engine.o: %vm_engine.cpp
   12.56 +	$(CPP) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
   12.57 +
   12.58 +$(BIN_DIR)/%.o: %.cpp
   12.59 +	$(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
   12.60 +
   12.61 +$(BIN_DIR)/%.o: %.c
   12.62 +	$(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $<
   12.63 +
   12.64 +all:
   12.65 +	mkdir -p $(BIN_DIR)
   12.66 +	$(MAKE) -f Makefile sourcemod
   12.67 +
   12.68 +sourcemod: $(OBJ_LINUX)
   12.69 +	$(CPP) $(INCLUDE) $(OBJ_LINUX) $(LINK) -m32 -lstdc++ -o$(BIN_DIR)/$(BINARY)
   12.70 +
   12.71 +debug:
   12.72 +	$(MAKE) -f Makefile all DEBUG=true
   12.73 +
   12.74 +default: all
   12.75 +
   12.76 +clean:
   12.77 +	rm -rf $(BIN_DIR)/$(BINARY)
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/tools/gamedata_md5/TextParsers.cpp	Sun Aug 17 18:27:51 2008 +0000
    13.3 @@ -0,0 +1,1082 @@
    13.4 +/**
    13.5 + * vim: set ts=4 :
    13.6 + * =============================================================================
    13.7 + * SourceMod
    13.8 + * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    13.9 + * =============================================================================
   13.10 + *
   13.11 + * This program is free software; you can redistribute it and/or modify it under
   13.12 + * the terms of the GNU General Public License, version 3.0, as published by the
   13.13 + * Free Software Foundation.
   13.14 + * 
   13.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
   13.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   13.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   13.18 + * details.
   13.19 + *
   13.20 + * You should have received a copy of the GNU General Public License along with
   13.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
   13.22 + *
   13.23 + * As a special exception, AlliedModders LLC gives you permission to link the
   13.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
   13.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   13.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
   13.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
   13.28 + * this exception to all derivative works.  AlliedModders LLC defines further
   13.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   13.30 + * or <http://www.sourcemod.net/license.php>.
   13.31 + *
   13.32 + * Version: $Id$
   13.33 + */
   13.34 +
   13.35 +#include <stdio.h>
   13.36 +#include <ctype.h>
   13.37 +#include <wctype.h>
   13.38 +#include <string.h>
   13.39 +#include <stdlib.h>
   13.40 +#include <assert.h>
   13.41 +#include "TextParsers.h"
   13.42 +//#include "ShareSys.h"
   13.43 +//#include "sm_stringutil.h"
   13.44 +//#include "LibrarySys.h"
   13.45 +
   13.46 +TextParsers g_TextParser;
   13.47 +ITextParsers *textparsers = &g_TextParser;
   13.48 +
   13.49 +static int g_ini_chartable1[255] = {0};
   13.50 +static int g_ws_chartable[255] = {0};
   13.51 +
   13.52 +bool TextParsers::IsWhitespace(const char *stream)
   13.53 +{
   13.54 +	return g_ws_chartable[(unsigned)*stream] == 1;
   13.55 +}
   13.56 +
   13.57 +TextParsers::TextParsers()
   13.58 +{
   13.59 +	g_ini_chartable1[(unsigned)'_'] = 1;
   13.60 +	g_ini_chartable1[(unsigned)'-'] = 1;
   13.61 +	g_ini_chartable1[(unsigned)','] = 1;
   13.62 +	g_ini_chartable1[(unsigned)'+'] = 1;
   13.63 +	g_ini_chartable1[(unsigned)'.'] = 1;
   13.64 +	g_ini_chartable1[(unsigned)'$'] = 1;
   13.65 +	g_ini_chartable1[(unsigned)'?'] = 1;
   13.66 +	g_ini_chartable1[(unsigned)'/'] = 1;
   13.67 +	g_ws_chartable[(unsigned)'\n'] = 1;
   13.68 +	g_ws_chartable[(unsigned)'\v'] = 1;
   13.69 +	g_ws_chartable[(unsigned)'\r'] = 1;
   13.70 +	g_ws_chartable[(unsigned)'\t'] = 1;
   13.71 +	g_ws_chartable[(unsigned)'\f'] = 1;
   13.72 +	g_ws_chartable[(unsigned)' '] = 1;
   13.73 +}
   13.74 +
   13.75 +unsigned int TextParsers::GetUTF8CharBytes(const char *stream)
   13.76 +{
   13.77 +	return _GetUTF8CharBytes(stream);
   13.78 +}
   13.79 +
   13.80 +/**
   13.81 + * Character streams
   13.82 + */
   13.83 +
   13.84 +struct CharStream
   13.85 +{
   13.86 +	const char *curpos;
   13.87 +};
   13.88 +
   13.89 +bool CharStreamReader(void *stream, char *buffer, size_t maxlength, unsigned int *read)
   13.90 +{
   13.91 +	CharStream *srdr = (CharStream *)stream;
   13.92 +
   13.93 +	const char *ptr = srdr->curpos;
   13.94 +	for (size_t i=0; i<maxlength; i++)
   13.95 +	{
   13.96 +		if (*ptr == '\0')
   13.97 +		{
   13.98 +			break;
   13.99 +		}
  13.100 +		*buffer++ = *ptr++;
  13.101 +	}
  13.102 +
  13.103 +	*read = ptr - srdr->curpos;
  13.104 +
  13.105 +	srdr->curpos = ptr;
  13.106 +
  13.107 +	return true;
  13.108 +}
  13.109 +
  13.110 +SMCError TextParsers::ParseString_SMC(const char *stream, 
  13.111 +					 ITextListener_SMC *smc,
  13.112 +					 SMCStates *states)
  13.113 +{
  13.114 +	CharStream srdr = { stream };
  13.115 +
  13.116 +	return ParseStream_SMC(&srdr, CharStreamReader, smc, states);
  13.117 +}
  13.118 +
  13.119 +/**
  13.120 + * File streams
  13.121 + */
  13.122 +
  13.123 +bool FileStreamReader(void *stream, char *buffer, size_t maxlength, unsigned int *read)
  13.124 +{
  13.125 +	size_t num = fread(buffer, 1, maxlength, (FILE *)stream);
  13.126 +
  13.127 +	*read = static_cast<unsigned int>(num);
  13.128 +
  13.129 +	if (num == 0 && feof((FILE *)stream))
  13.130 +	{
  13.131 +		return true;
  13.132 +	}
  13.133 +
  13.134 +	return (ferror((FILE *)stream) == 0);
  13.135 +}
  13.136 +
  13.137 +SMCError TextParsers::ParseFile_SMC(const char *file, ITextListener_SMC *smc, SMCStates *states)
  13.138 +{
  13.139 +	FILE *fp = fopen(file, "rt");
  13.140 +
  13.141 +	if (!fp)
  13.142 +	{
  13.143 +		if (states != NULL)
  13.144 +		{
  13.145 +			states->line = 0;
  13.146 +			states->col = 0;
  13.147 +		}
  13.148 +		return SMCError_StreamOpen;
  13.149 +	}
  13.150 +
  13.151 +	SMCError result = ParseStream_SMC(fp, FileStreamReader, smc, states);
  13.152 +
  13.153 +	fclose(fp);
  13.154 +
  13.155 +	return result;
  13.156 +}
  13.157 +
  13.158 +SMCError TextParsers::ParseSMCFile(const char *file,
  13.159 +								   ITextListener_SMC *smc_listener,
  13.160 +								   SMCStates *states,
  13.161 +								   char *buffer,
  13.162 +								   size_t maxsize)
  13.163 +{
  13.164 +	const char *errstr;
  13.165 +	FILE *fp = fopen(file, "rt");
  13.166 +
  13.167 +	if (fp == NULL)
  13.168 +	{
  13.169 +		char error[256] = "unknown";
  13.170 +		if (states != NULL)
  13.171 +		{
  13.172 +			states->line = 0;
  13.173 +			states->col = 0;
  13.174 +		}
  13.175 +		//g_LibSys.GetPlatformError(error, sizeof(error));
  13.176 +		UTIL_Format(buffer, maxsize, "File could not be opened: %s", error);
  13.177 +		return SMCError_StreamOpen;
  13.178 +	}
  13.179 +
  13.180 +	SMCError result = ParseStream_SMC(fp, FileStreamReader, smc_listener, states);
  13.181 +
  13.182 +	fclose(fp);
  13.183 +
  13.184 +	errstr = GetSMCErrorString(result);
  13.185 +	UTIL_Format(buffer, maxsize, "%s", errstr != NULL ? errstr : "Unknown error");
  13.186 +
  13.187 +	return result;
  13.188 +}
  13.189 +
  13.190 +/** 
  13.191 + * Raw parsing of streams with helper functions
  13.192 + */
  13.193 +
  13.194 +struct StringInfo
  13.195 +{
  13.196 +	StringInfo() : quoted(false), ptr(NULL), end(NULL), special(false) { }
  13.197 +	bool quoted;
  13.198 +	char *ptr;
  13.199 +	char *end;
  13.200 +	bool special;
  13.201 +};
  13.202 +
  13.203 +const char *FixupString(StringInfo &data)
  13.204 +{
  13.205 +	if (!data.ptr)
  13.206 +	{
  13.207 +		return NULL;
  13.208 +	}
  13.209 +
  13.210 +	if (data.quoted)
  13.211 +	{
  13.212 +		data.ptr++;
  13.213 +	}
  13.214 +#if defined _DEBUG
  13.215 +	else {
  13.216 +		/* A string will never have beginning whitespace because we ignore it in the stream.
  13.217 +		 * Furthermore, if there is trailing whitespace, the end ptr will point to it, so it is valid
  13.218 +		 * to overwrite!  Lastly, the last character must be whitespace or a comment/invalid character.
  13.219 +		 */
  13.220 + 	}
  13.221 +#endif
  13.222 +
  13.223 +	/* Do some extra work on strings that have special quoted characters. */
  13.224 +	if (data.special)
  13.225 +	{
  13.226 +		char *outptr = data.ptr;
  13.227 +		size_t len = data.end - data.ptr;
  13.228 +		if (len >= 2)
  13.229 +		{
  13.230 +			for (size_t i=0; i<len; i++)
  13.231 +			{
  13.232 +				if (data.ptr[i] == '\\' && i < len - 1)
  13.233 +				{
  13.234 +					/* Resolve the next character. */
  13.235 +					i++;
  13.236 +					if (data.ptr[i] == 'n')
  13.237 +					{
  13.238 +						data.ptr[i] = '\n';
  13.239 +					} else if (data.ptr[i] == 't') {
  13.240 +						data.ptr[i] = '\t';
  13.241 +					} else if (data.ptr[i] == 'r') {
  13.242 +						data.ptr[i] = '\r';
  13.243 +					} else if (data.ptr[i] != '\\'
  13.244 +						&& data.ptr[i] != '"') {
  13.245 +						/* This character is invalid, so go back one */
  13.246 +						i--;
  13.247 +					}
  13.248 +				}
  13.249 +				*outptr++ = data.ptr[i];
  13.250 +			}
  13.251 +			*outptr = '\0';
  13.252 +		}
  13.253 +	}
  13.254 +
  13.255 +	if (data.end)
  13.256 +	{
  13.257 +		*(data.end) = '\0';
  13.258 +	}
  13.259 +
  13.260 +	return data.ptr;
  13.261 +}
  13.262 +
  13.263 +const char *rotate(StringInfo info[3])
  13.264 +{
  13.265 +	if (info[2].ptr != NULL)
  13.266 +	{
  13.267 +		return info[2].ptr;
  13.268 +	}
  13.269 +
  13.270 +	if (info[0].ptr != NULL)
  13.271 +	{
  13.272 +		info[2] = info[1];
  13.273 +		info[1] = info[0];
  13.274 +		info[0] = StringInfo();
  13.275 +	}
  13.276 +	
  13.277 +	return NULL;
  13.278 +}
  13.279 +
  13.280 +void scrap(StringInfo info[3])
  13.281 +{
  13.282 +	info[2] = StringInfo();
  13.283 +	info[1] = StringInfo();
  13.284 +	info[0] = StringInfo();
  13.285 +}
  13.286 +
  13.287 +void reloc(StringInfo &data, unsigned int bytes)
  13.288 +{
  13.289 +	if (data.ptr)
  13.290 +	{
  13.291 +		data.ptr -= bytes;
  13.292 +	}
  13.293 +	if (data.end)
  13.294 +	{
  13.295 +		data.end -= bytes;
  13.296 +	}
  13.297 +}
  13.298 +
  13.299 +char *lowstring(StringInfo info[3])
  13.300 +{
  13.301 +	for (int i=2; i>=0; i--)
  13.302 +	{
  13.303 +		if (info[i].ptr)
  13.304 +		{
  13.305 +			return info[i].ptr;
  13.306 +		}
  13.307 +	}
  13.308 +
  13.309 +	return NULL;
  13.310 +}
  13.311 +
  13.312 +SMCError TextParsers::ParseStream_SMC(void *stream, 
  13.313 +								   STREAMREADER srdr, 
  13.314 +								   ITextListener_SMC *smc, 
  13.315 +								   SMCStates *pStates)
  13.316 +{
  13.317 +	char *reparse_point = NULL;
  13.318 +	char in_buf[4096];
  13.319 +	char *parse_point = in_buf;
  13.320 +	char *line_begin = in_buf;
  13.321 +	unsigned int read;
  13.322 +	unsigned int curlevel = 0;
  13.323 +	bool in_quote = false;
  13.324 +	bool ignoring = false;
  13.325 +	bool eol_comment = false;
  13.326 +	bool ml_comment = false;
  13.327 +	unsigned int i;
  13.328 +	SMCError err = SMCError_Okay;
  13.329 +	SMCResult res;
  13.330 +	SMCStates states;
  13.331 +	char c;
  13.332 +
  13.333 +	StringInfo strings[3];
  13.334 +	StringInfo emptystring;
  13.335 +
  13.336 +	states.line = 1;
  13.337 +	states.col = 0;
  13.338 +
  13.339 +	smc->ReadSMC_ParseStart();
  13.340 +
  13.341 +	/**
  13.342 +	 * The stream reader reads in as much as it can fill the buffer with.
  13.343 +	 * It then processes the buffer.  If the buffer cannot be fully processed, for example, 
  13.344 +	 * a line is left hanging with no newline, then the contents of the buffer is shifted 
  13.345 +	 * down, and the buffer is filled from the stream reader again.
  13.346 +	 *
  13.347 +	 * What makes this particularly annoying is that we cache pointers everywhere, so when 
  13.348 +	 * the shifting process takes place, all those pointers must be shifted as well.
  13.349 +	 */
  13.350 +	while (srdr(stream, parse_point, sizeof(in_buf) - (parse_point - in_buf) - 1, &read))
  13.351 +	{
  13.352 +		if (!read)
  13.353 +		{
  13.354 +			break;
  13.355 +		}
  13.356 +
  13.357 +		/* Check for BOM markings, which is only relevant on the first line.
  13.358 +		 * Not worth it, but it could be moved out of the loop.
  13.359 +		 */
  13.360 +		if (states.line == 1 && 
  13.361 +			in_buf[0] == (char)0xEF && 
  13.362 +			in_buf[1] == (char)0xBB && 
  13.363 +			in_buf[2] == (char)0xBF)
  13.364 +		{
  13.365 +			/* Move EVERYTHING down :\ */
  13.366 +			memmove(in_buf, &in_buf[3], read - 3);
  13.367 +			read -= 3;
  13.368 +		}
  13.369 +
  13.370 +		if (reparse_point)
  13.371 +		{
  13.372 +			read += (parse_point - reparse_point);
  13.373 +			parse_point = reparse_point;
  13.374 +			reparse_point = NULL;
  13.375 +		}
  13.376 +
  13.377 +		for (i=0; i<read; i++)
  13.378 +		{
  13.379 +			c = parse_point[i];
  13.380 +			if (c == '\n')
  13.381 +			{
  13.382 +				/* If we got a newline, there's a lot of things that could have happened in the interim.
  13.383 +				 * First, let's make sure the staged strings are rotated.
  13.384 +				 */
  13.385 +				if (strings[0].ptr)
  13.386 +				{
  13.387 +					strings[0].end = &parse_point[i];
  13.388 +					if (rotate(strings) != NULL)
  13.389 +					{
  13.390 +						err = SMCError_InvalidTokens;
  13.391 +						goto failed;
  13.392 +					}
  13.393 +				}
  13.394 +
  13.395 +				/* Next, let's clear some line-based values that may no longer have meaning */
  13.396 +				eol_comment = false;
  13.397 +				in_quote = false;
  13.398 +				if (ignoring && !ml_comment)
  13.399 +				{
  13.400 +					ignoring = false;
  13.401 +				}
  13.402 +
  13.403 +				/* Pass the raw line onto the listener.  We terminate the line so the receiver 
  13.404 +				 * doesn't get tons of useless info.  We restore the newline after.
  13.405 +				 */
  13.406 +				parse_point[i] = '\0';
  13.407 +				if ((res=smc->ReadSMC_RawLine(&states, line_begin)) != SMCResult_Continue)
  13.408 +				{
  13.409 +					err = (res == SMCResult_HaltFail) ? SMCError_Custom : SMCError_Okay;
  13.410 +					goto failed;
  13.411 +				}
  13.412 +				parse_point[i] = '\n';
  13.413 +
  13.414 +				/* Now we check the sanity of our staged strings! */
  13.415 +				if (strings[2].ptr)
  13.416 +				{
  13.417 +					if (!curlevel)
  13.418 +					{
  13.419 +						err = SMCError_InvalidProperty1;
  13.420 +						goto failed;
  13.421 +					}
  13.422 +					/* Assume the next string is a property and pass the info on. */
  13.423 +					if ((res=smc->ReadSMC_KeyValue(
  13.424 +						&states,
  13.425 +						FixupString(strings[2]),
  13.426 +						FixupString(strings[1]))) != SMCResult_Continue)
  13.427 +					{
  13.428 +						err = (res == SMCResult_HaltFail) ? SMCError_Custom : SMCError_Okay;
  13.429 +						goto failed;
  13.430 +					}
  13.431 +					scrap(strings);
  13.432 +				}
  13.433 +
  13.434 +				/* Change the states for the next line */
  13.435 +				states.col = 0;
  13.436 +				states.line++;
  13.437 +				line_begin = &parse_point[i+1];		//Note: safe because this gets relocated later
  13.438 +			} 
  13.439 +			else if (ignoring) 
  13.440 +			{
  13.441 +				if (in_quote)
  13.442 +				{
  13.443 +					/* If i was 0, we could have reparsed, so make sure there's no buffer underrun */
  13.444 +					if ((&parse_point[i] != in_buf) && c == '"' && parse_point[i-1] != '\\')
  13.445 +					{
  13.446 +						/* If we reached a quote in an ignore phase,
  13.447 +						 * we're staging a string and we must rotate it out.
  13.448 +						 */
  13.449 +						in_quote = false;
  13.450 +						ignoring = false;
  13.451 +						/* Set our info */
  13.452 +						strings[0].end = &parse_point[i];
  13.453 +						strings[0].quoted = true;
  13.454 +						if (rotate(strings) != NULL)
  13.455 +						{
  13.456 +							/* If we rotated too many strings, there was too much crap on one line */
  13.457 +							err = SMCError_InvalidTokens;
  13.458 +							goto failed;
  13.459 +						}
  13.460 +					} 
  13.461 +					else if (c == '\\') 
  13.462 +					{
  13.463 +						strings[0].special = true;
  13.464 +						if (i == (read - 1))
  13.465 +						{
  13.466 +							reparse_point = &parse_point[i];
  13.467 +							break;
  13.468 +						}
  13.469 +					}
  13.470 +				} 
  13.471 +				else if (ml_comment) 
  13.472 +				{
  13.473 +					if (c == '*')
  13.474 +					{
  13.475 +						/* Check if we need to get more input first */
  13.476 +						if (i == read - 1)
  13.477 +						{
  13.478 +							reparse_point = &parse_point[i];
  13.479 +							break;
  13.480 +						}
  13.481 +						if (parse_point[i+1] == '/')
  13.482 +						{
  13.483 +							ml_comment = false;
  13.484 +							ignoring = false;
  13.485 +							/* We should not be staging anything right now. */
  13.486 +							assert(strings[0].ptr == NULL);
  13.487 +							/* Advance the input stream so we don't choke on this token */
  13.488 +							i++;
  13.489 +							states.col++;
  13.490 +						}
  13.491 +					}
  13.492 +				}
  13.493 +			} 
  13.494 +			else 
  13.495 +			{
  13.496 +				/* Check if we're whitespace or not */
  13.497 +				if (!g_ws_chartable[(unsigned)c])
  13.498 +				{
  13.499 +					bool restage = false;
  13.500 +					/* Check various special tokens:
  13.501 +					 * ;
  13.502 +					 * //
  13.503 +					 * / *
  13.504 +					 * {
  13.505 +					 * }
  13.506 +					 */
  13.507 +					if (c == ';' || c == '/')
  13.508 +					{
  13.509 +						/* If it's a line-based comment (that is, ; or //)
  13.510 +						 * we will need to scrap everything until the end of the line.
  13.511 +						 */
  13.512 +						if (c == '/')
  13.513 +						{
  13.514 +							if (i == read - 1)
  13.515 +							{
  13.516 +								/* If we reached the end of the look-ahead, we need to re-check our input.
  13.517 +								 * Breaking out will force this to be the new reparse point!
  13.518 +								 */
  13.519 +								reparse_point = &parse_point[i];
  13.520 +								break;
  13.521 +							}
  13.522 +							if (parse_point[i + 1] == '/')
  13.523 +							{
  13.524 +								/* standard comment */
  13.525 +								ignoring = true;
  13.526 +								eol_comment = true;
  13.527 +								restage = true;
  13.528 +							} 
  13.529 +							else if (parse_point[i+1] == '*') 
  13.530 +							{
  13.531 +								/* inline comment - start ignoring */
  13.532 +								ignoring = true;
  13.533 +								ml_comment = true;
  13.534 +								/* yes, we restage, meaning that:
  13.535 +								 * STR/ *stuff* /ING  (space because ml comments don't nest in C++)
  13.536 +								 * will not generate 'STRING', but rather 'STR' and 'ING'.
  13.537 +								 * This should be a rare occurrence and is done here for convenience.
  13.538 +								 */
  13.539 +								restage = true;
  13.540 +							}
  13.541 +						} 
  13.542 +						else 
  13.543 +						{
  13.544 +							ignoring = true;
  13.545 +							eol_comment = true;
  13.546 +							restage = true;
  13.547 +						}
  13.548 +					} 
  13.549 +					else if (c == '{') 
  13.550 +					{
  13.551 +						/* If we are staging a string, we must rotate here */
  13.552 +						if (strings[0].ptr)
  13.553 +						{
  13.554 +							/* We have unacceptable tokens on this line */
  13.555 +							if (rotate(strings) != NULL)
  13.556 +							{
  13.557 +								err = SMCError_InvalidSection1;
  13.558 +								goto failed;
  13.559 +							}
  13.560 +						}
  13.561 +						/* Sections must always be alone */
  13.562 +						if (strings[2].ptr != NULL)
  13.563 +						{
  13.564 +							err = SMCError_InvalidSection1;
  13.565 +							goto failed;
  13.566 +						} 
  13.567 +						else if (strings[1].ptr == NULL)
  13.568 +						{
  13.569 +							err = SMCError_InvalidSection2;
  13.570 +							goto failed;
  13.571 +						}
  13.572 +						if ((res=smc->ReadSMC_NewSection(&states, FixupString(strings[1])))
  13.573 +							!= SMCResult_Continue)
  13.574 +						{
  13.575 +							err = (res == SMCResult_HaltFail) ? SMCError_Custom : SMCError_Okay;
  13.576 +							goto failed;
  13.577 +						}
  13.578 +						strings[1] = emptystring;
  13.579 +						curlevel++;
  13.580 +					} 
  13.581 +					else if (c == '}') 
  13.582 +					{
  13.583 +						/* Unlike our matching friend, this can be on the same line as something prior */
  13.584 +						if (rotate(strings) != NULL)
  13.585 +						{
  13.586 +							err = SMCError_InvalidSection3;
  13.587 +							goto failed;
  13.588 +						}
  13.589 +						if (strings[2].ptr)
  13.590 +						{
  13.591 +							if (!curlevel)
  13.592 +							{
  13.593 +								err = SMCError_InvalidProperty1;
  13.594 +								goto failed;
  13.595 +							}
  13.596 +							if ((res=smc->ReadSMC_KeyValue(
  13.597 +											&states,
  13.598 +											FixupString(strings[2]),
  13.599 +											FixupString(strings[1])))
  13.600 +								!= SMCResult_Continue)
  13.601 +							{
  13.602 +								err = (res == SMCResult_HaltFail) ? SMCError_Custom : SMCError_Okay;
  13.603 +								goto failed;
  13.604 +							}
  13.605 +						} 
  13.606 +						else if (strings[1].ptr) 
  13.607 +						{
  13.608 +							err = SMCError_InvalidSection3;
  13.609 +							goto failed;
  13.610 +						} 
  13.611 +						else if (!curlevel) 
  13.612 +						{
  13.613 +							err = SMCError_InvalidSection4;
  13.614 +							goto failed;
  13.615 +						}
  13.616 +						/* Now it's safe to leave the section */
  13.617 +						scrap(strings);
  13.618 +						if ((res=smc->ReadSMC_LeavingSection(&states)) != SMCResult_Continue)
  13.619 +						{
  13.620 +							err = (res == SMCResult_HaltFail) ? SMCError_Custom : SMCError_Okay;
  13.621 +							goto failed;
  13.622 +						}
  13.623 +						curlevel--;
  13.624 +					} 
  13.625 +					else if (c == '"') 
  13.626 +					{
  13.627 +						/* If we get a quote mark, we always restage, but we need to do it beforehand */
  13.628 +						if (strings[0].ptr)
  13.629 +						{
  13.630 +							strings[0].end = &parse_point[i];
  13.631 +							if (rotate(strings) != NULL)
  13.632 +							{
  13.633 +								err = SMCError_InvalidTokens;
  13.634 +								goto failed;
  13.635 +							}
  13.636 +						}
  13.637 +						strings[0].ptr = &parse_point[i];
  13.638 +						in_quote = true;
  13.639 +						ignoring = true;
  13.640 +					} 
  13.641 +					else if (!strings[0].ptr) 
  13.642 +					{
  13.643 +						/* If we have no string, we must start one */
  13.644 +						strings[0].ptr = &parse_point[i];
  13.645 +					}
  13.646 +					if (restage && strings[0].ptr)
  13.647 +					{
  13.648 +						strings[0].end = &parse_point[i];
  13.649 +						if (rotate(strings) != NULL)
  13.650 +						{
  13.651 +							err = SMCError_InvalidTokens;
  13.652 +							goto failed;
  13.653 +						}
  13.654 +					}
  13.655 +				} 
  13.656 +				else 
  13.657 +				{
  13.658 +					/* If we're eating a string and get whitespace, we need to restage.
  13.659 +					 * (Note that if we are quoted, this is being ignored)
  13.660 +					 */
  13.661 +					if (strings[0].ptr)
  13.662 +					{
  13.663 +						/*
  13.664 +						 * The specification says the second string in a pair does not need to be quoted.
  13.665 +						 * Thus, we check if there's already a string on the stack.
  13.666 +						 * If there's a newline, we always rotate so the newline has an empty starter.
  13.667 +						 */
  13.668 +						if (!strings[1].ptr)
  13.669 +						{
  13.670 +							/* There's no string, so we must move this one down and eat up another */
  13.671 +							strings[0].end = &parse_point[i];
  13.672 +							rotate(strings);
  13.673 +						} 
  13.674 +						else if (!strings[1].quoted) 
  13.675 +						{
  13.676 +							err = SMCError_InvalidTokens;
  13.677 +							goto failed;
  13.678 +						}
  13.679 +					}
  13.680 +				}
  13.681 +			}
  13.682 +
  13.683 +			/* Advance which token we're on */
  13.684 +			states.col++;
  13.685 +		}
  13.686 +
  13.687 +		if (line_begin != in_buf)
  13.688 +		{
  13.689 +			/* The line buffer has advanced, so it's safe to copy N bytes back to the beginning.
  13.690 +			 * What's N?  N is the lowest point we're currently relying on.
  13.691 +			 */
  13.692 +			char *stage = lowstring(strings);
  13.693 +			if (!stage || stage > line_begin)
  13.694 +			{
  13.695 +				stage = line_begin;
  13.696 +			}
  13.697 +			unsigned int bytes = read - (stage - parse_point);
  13.698 +
  13.699 +			/* It is now safe to delete everything before the staged point */
  13.700 +			memmove(in_buf, stage, bytes);
  13.701 +
  13.702 +			/* Calculate the number of bytes in the new buffer */
  13.703 +			bytes = stage - in_buf;
  13.704 +			/* Relocate all the cached pointers to our new base */
  13.705 +			line_begin -= bytes;
  13.706 +			reloc(strings[0], bytes);
  13.707 +			reloc(strings[1], bytes);
  13.708 +			reloc(strings[2], bytes);
  13.709 +			if (reparse_point)
  13.710 +			{
  13.711 +				reparse_point -= bytes;
  13.712 +			}
  13.713 +			if (parse_point)
  13.714 +			{
  13.715 +				parse_point = &parse_point[read];
  13.716 +				parse_point -= bytes;
  13.717 +			}
  13.718 +		} 
  13.719 +		else if (read == sizeof(in_buf) - 1) 
  13.720 +		{
  13.721 +			err = SMCError_TokenOverflow;
  13.722 +			goto failed;
  13.723 +		}
  13.724 +	}
  13.725 +
  13.726 +	/* If we're done parsing and there are tokens left over... */
  13.727 +	if (curlevel)
  13.728 +	{
  13.729 +		err = SMCError_InvalidSection5;
  13.730 +		goto failed;
  13.731 +	} 
  13.732 +	else if (strings[0].ptr || strings[1].ptr) 
  13.733 +	{
  13.734 +		err = SMCError_InvalidTokens;
  13.735 +		goto failed;
  13.736 +	}
  13.737 +	
  13.738 +	smc->ReadSMC_ParseEnd(false, false);
  13.739 +	
  13.740 +	if (pStates != NULL)
  13.741 +	{
  13.742 +		*pStates = states;
  13.743 +	}
  13.744 +
  13.745 +	return SMCError_Okay;
  13.746 +
  13.747 +failed:
  13.748 +	if (pStates != NULL)
  13.749 +	{
  13.750 +		*pStates = states;
  13.751 +	}
  13.752 +
  13.753 +	smc->ReadSMC_ParseEnd(true, (err == SMCError_Custom));
  13.754 +
  13.755 +	return err;
  13.756 +}
  13.757 +
  13.758 +
  13.759 +/**
  13.760 + * INI parser 
  13.761 + */
  13.762 +
  13.763 +bool TextParsers::ParseFile_INI(const char *file, ITextListener_INI *ini_listener, unsigned int *line, unsigned int *col)
  13.764 +{
  13.765 +	FILE *fp = fopen(file, "rt");
  13.766 +	unsigned int curline = 0;
  13.767 +	unsigned int curtok;
  13.768 +	size_t len;
  13.769 +
  13.770 +	if (!fp)
  13.771 +	{
  13.772 +		if (line)
  13.773 +		{
  13.774 +			*line = 0;
  13.775 +		}
  13.776 +
  13.777 +		return false;
  13.778 +	}
  13.779 +
  13.780 +	char buffer[2048];
  13.781 +	char *ptr, *save_ptr;
  13.782 +	bool in_quote;
  13.783 +
  13.784 +	while (!feof(fp))
  13.785 +	{
  13.786 +		curline++;
  13.787 +		curtok = 0;
  13.788 +		buffer[0] = '\0';
  13.789 +		if (fgets(buffer, sizeof(buffer), fp) == NULL)
  13.790 +		{
  13.791 +			break;
  13.792 +		}
  13.793 +
  13.794 +		//:TODO: this will only run once, so find a nice way to move it out of the while loop
  13.795 +		/* If this is the first line, check the first three bytes for BOM */
  13.796 +		if (curline == 1 && 
  13.797 +			buffer[0] == (char)0xEF && 
  13.798 +			buffer[1] == (char)0xBB && 
  13.799 +			buffer[2] == (char)0xBF)
  13.800 +		{
  13.801 +			/* We have a UTF-8 marked file... skip these bytes */
  13.802 +			ptr = &buffer[3];
  13.803 +		} else {
  13.804 +			ptr = buffer;
  13.805 +		}
  13.806 +
  13.807 +		/***************************************************
  13.808 +		 * We preprocess the string before parsing tokens! *
  13.809 +		 ***************************************************/
  13.810 +
  13.811 +		/* First strip beginning whitespace */
  13.812 +		while (*ptr != '\0' && g_ws_chartable[(unsigned)*ptr] != 0)
  13.813 +		{
  13.814 +			ptr++;
  13.815 +		}
  13.816 +
  13.817 +		len = strlen(ptr);
  13.818 +
  13.819 +		if (!len)
  13.820 +		{
  13.821 +			continue;
  13.822 +		}
  13.823 +
  13.824 +		/* Now search for comment characters */
  13.825 +		in_quote = false;
  13.826 +		save_ptr = ptr;
  13.827 +		for (size_t i=0; i<len; i++,ptr++)
  13.828 +		{
  13.829 +			if (!in_quote)
  13.830 +			{
  13.831 +				switch (*ptr)
  13.832 +				{
  13.833 +				case '"':
  13.834 +					{
  13.835 +						in_quote = true;
  13.836 +						break;
  13.837 +					}
  13.838 +				case ';':
  13.839 +					{
  13.840 +						/* Stop the loop */
  13.841 +						len = i;
  13.842 +						/* Terminate the string here */
  13.843 +						*ptr = '\0';
  13.844 +						break;
  13.845 +					}
  13.846 +				}
  13.847 +			} else {
  13.848 +				if (*ptr == '"')
  13.849 +				{
  13.850 +					in_quote = false;
  13.851 +				}
  13.852 +			}
  13.853 +		}
  13.854 +
  13.855 +		if (!len)
  13.856 +		{
  13.857 +			continue;
  13.858 +		}
  13.859 +
  13.860 +		ptr = save_ptr;
  13.861 +
  13.862 +		/* Lastly, strip ending whitespace off */
  13.863 +		for (size_t i=len-1; i>=0 && i<len; i--)
  13.864 +		{
  13.865 +			if (g_ws_chartable[(unsigned)ptr[i]])
  13.866 +			{
  13.867 +				ptr[i] = '\0';
  13.868 +				len--;
  13.869 +			} else {
  13.870 +				break;
  13.871 +			}
  13.872 +		}
  13.873 +
  13.874 +		if (!len)
  13.875 +		{
  13.876 +			continue;
  13.877 +		}
  13.878 +
  13.879 +		if (!ini_listener->ReadINI_RawLine(ptr, &curtok))
  13.880 +		{
  13.881 +			goto event_failed;
  13.882 +		}
  13.883 +
  13.884 +		if (*ptr == '[')
  13.885 +		{
  13.886 +			bool invalid_tokens = false;
  13.887 +			bool got_bracket = false;
  13.888 +			bool extra_tokens = false;
  13.889 +			char c;
  13.890 +			bool alnum;
  13.891 +			wchar_t wc;
  13.892 +
  13.893 +			for (size_t i=1; i<len; i++)
  13.894 +			{
  13.895 +				c = ptr[i];
  13.896 +				alnum = false;
  13.897 +
  13.898 +				if (c & (1<<7))
  13.899 +				{
  13.900 +					if (mbtowc(&wc, &ptr[i], len-i) != -1)
  13.901 +					{
  13.902 +						alnum = (iswalnum(wc) != 0);
  13.903 +						i += _GetUTF8CharBytes(&ptr[i]) - 1;
  13.904 +					}
  13.905 +				} else {
  13.906 +					alnum = (isalnum(c) != 0) || (g_ini_chartable1[(unsigned)c] != 0);
  13.907 +				}
  13.908 +				if (!alnum)
  13.909 +				{
  13.910 +					/* First check - is this a bracket? */
  13.911 +					if (c == ']')
  13.912 +					{
  13.913 +						/* Yes! */
  13.914 +						got_bracket = true;
  13.915 +						/* If this isn't the last character... */
  13.916 +						if (i != len - 1)
  13.917 +						{
  13.918 +							extra_tokens = true;
  13.919 +						}
  13.920 +						/* terminate */
  13.921 +						ptr[i] = '\0';
  13.922 +						break;
  13.923 +					} else {
  13.924 +						/* n...No! Continue copying. */
  13.925 +						invalid_tokens = true;
  13.926 +					}
  13.927 +				}
  13.928 +			}
  13.929 +
  13.930 +			/* Tell the handler */
  13.931 +			if (!ini_listener->ReadINI_NewSection(&ptr[1], invalid_tokens, got_bracket, extra_tokens, &curtok))
  13.932 +			{
  13.933 +				goto event_failed;
  13.934 +			}
  13.935 +		} else {
  13.936 +			char *key_ptr = ptr;
  13.937 +			char *val_ptr = NULL;
  13.938 +			char c;
  13.939 +			size_t first_space = 0;
  13.940 +			bool invalid_tokens = false;
  13.941 +			bool equal_token = false;
  13.942 +			bool quotes = false;
  13.943 +			bool alnum;
  13.944 +			wchar_t wc;
  13.945 +
  13.946 +			for (size_t i=0; i<len; i++)
  13.947 +			{
  13.948 +				c = ptr[i];
  13.949 +				alnum = false;
  13.950 +				/* is this an invalid char? */
  13.951 +				if (c & (1<<7))
  13.952 +				{
  13.953 +					if (mbtowc(&wc, &ptr[i], len-i) != -1)
  13.954 +					{
  13.955 +						alnum = (iswalnum(wc) != 0);
  13.956 +						i += _GetUTF8CharBytes(&ptr[i]) - 1;
  13.957 +					}
  13.958 +				} else {
  13.959 +					alnum = (isalnum(c) != 0) || (g_ini_chartable1[(unsigned)c] != 0);
  13.960 +				}
  13.961 +
  13.962 +				if (!alnum)
  13.963 +				{
  13.964 +					if (g_ws_chartable[(unsigned)c])
  13.965 +					{
  13.966 +						/* if it's a space, keep track of the first occurring space */
  13.967 +						if (!first_space)
  13.968 +						{
  13.969 +							first_space = i;
  13.970 +						}
  13.971 +					} else {
  13.972 +						if (c == '=')
  13.973 +						{
  13.974 +							/* if it's an equal sign, we're done with the key */
  13.975 +							if (first_space)
  13.976 +							{
  13.977 +								/* remove excess whitespace */
  13.978 +								key_ptr[first_space] = '\0';
  13.979 +							} else {
  13.980 +								/* remove the equal sign */
  13.981 +								key_ptr[i] = '\0';
  13.982 +							}
  13.983 +							if (ptr[++i] != '\0')
  13.984 +							{
  13.985 +								/* If this isn't the end, set next pointer */
  13.986 +								val_ptr = &ptr[i];
  13.987 +							}
  13.988 +							equal_token = true;
  13.989 +							break;
  13.990 +						} else {
  13.991 +							/* Mark that we got something invalid! */
  13.992 +							invalid_tokens = true;
  13.993 +							first_space = 0;
  13.994 +						}
  13.995 +					}
  13.996 +				}
  13.997 +			}
  13.998 +
  13.999 +			/* Now we need to parse the value, if any */
 13.1000 +			if (val_ptr)
 13.1001 +			{
 13.1002 +				/* eat up spaces! there shouldn't be any h*/
 13.1003 +				while ((*val_ptr != '\0') && g_ws_chartable[(unsigned)*val_ptr] != 0)
 13.1004 +				{
 13.1005 +					val_ptr++;
 13.1006 +				}
 13.1007 +				if (*val_ptr == '\0')
 13.1008 +				{
 13.1009 +					val_ptr = NULL;
 13.1010 +					goto skip_value;
 13.1011 +				}
 13.1012 +				/* Do we have an initial quote? If so, the parsing rules change! */
 13.1013 +				if (*val_ptr == '"' && *val_ptr != '\0')
 13.1014 +				{
 13.1015 +					len = strlen(val_ptr);
 13.1016 +					if (val_ptr[len-1] == '"')
 13.1017 +					{
 13.1018 +						/* Strip quotes! */
 13.1019 +						val_ptr[--len] = '\0';
 13.1020 +						val_ptr++;
 13.1021 +						quotes = true;
 13.1022 +					}
 13.1023 +				}
 13.1024 +			}
 13.1025 +skip_value:
 13.1026 +			/* We're done! */
 13.1027 +			curtok = val_ptr - buffer;
 13.1028 +			if (!ini_listener->ReadINI_KeyValue(key_ptr, val_ptr, invalid_tokens, equal_token, quotes, &curtok))
 13.1029 +			{
 13.1030 +				curtok = 0;
 13.1031 +				goto event_failed;
 13.1032 +			}
 13.1033 +		}
 13.1034 +	}
 13.1035 +
 13.1036 +	if (line)
 13.1037 +	{
 13.1038 +		*line = curline;
 13.1039 +	}
 13.1040 +
 13.1041 +	fclose(fp);
 13.1042 +
 13.1043 +	return true;
 13.1044 +
 13.1045 +event_failed:
 13.1046 +	if (line)
 13.1047 +	{
 13.1048 +		*line = curline;
 13.1049 +	}
 13.1050 +
 13.1051 +	if (col)
 13.1052 +	{
 13.1053 +		*col = curtok;
 13.1054 +	}
 13.1055 +
 13.1056 +	fclose(fp);
 13.1057 +
 13.1058 +	return false;
 13.1059 +}
 13.1060 +
 13.1061 +const char *TextParsers::GetSMCErrorString(SMCError err)
 13.1062 +{
 13.1063 +	static const char *s_errors[] = 
 13.1064 +	{
 13.1065 +		NULL,
 13.1066 +		"Stream failed to open",
 13.1067 +		"Stream returned read error",
 13.1068 +		NULL,
 13.1069 +		"Un-quoted section has invalid tokens",
 13.1070 +		"Section declared without header",
 13.1071 +		"Section declared with unknown tokens",
 13.1072 +		"Section ending without a matching section beginning",
 13.1073 +		"Section beginning without a matching ending",
 13.1074 +		"Line contained too many invalid tokens",
 13.1075 +		"Token buffer overflowed",
 13.1076 +		"A property was declared outside of a section",
 13.1077 +	};
 13.1078 +
 13.1079 +	if (err < SMCError_Okay || err > SMCError_InvalidProperty1)
 13.1080 +	{
 13.1081 +		return NULL;
 13.1082 +	}
 13.1083 +
 13.1084 +	return s_errors[err];
 13.1085 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/tools/gamedata_md5/TextParsers.h	Sun Aug 17 18:27:51 2008 +0000
    14.3 @@ -0,0 +1,87 @@
    14.4 +/**
    14.5 + * vim: set ts=4 :
    14.6 + * =============================================================================
    14.7 + * SourceMod
    14.8 + * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    14.9 + * =============================================================================
   14.10 + *
   14.11 + * This program is free software; you can redistribute it and/or modify it under
   14.12 + * the terms of the GNU General Public License, version 3.0, as published by the
   14.13 + * Free Software Foundation.
   14.14 + * 
   14.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
   14.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   14.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   14.18 + * details.
   14.19 + *
   14.20 + * You should have received a copy of the GNU General Public License along with
   14.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
   14.22 + *
   14.23 + * As a special exception, AlliedModders LLC gives you permission to link the
   14.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
   14.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   14.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
   14.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
   14.28 + * this exception to all derivative works.  AlliedModders LLC defines further
   14.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   14.30 + * or <http://www.sourcemod.net/license.php>.
   14.31 + *
   14.32 + * Version: $Id$
   14.33 + */
   14.34 +
   14.35 +#ifndef _INCLUDE_SOURCEMOD_TEXTPARSERS_H_
   14.36 +#define _INCLUDE_SOURCEMOD_TEXTPARSERS_H_
   14.37 +
   14.38 +#include "ITextParsers.h"
   14.39 +#include "main.h"
   14.40 +
   14.41 +using namespace SourceMod;
   14.42 +
   14.43 +/**
   14.44 + * @param void *			IN: Stream pointer
   14.45 + * @param char *			IN/OUT: Stream buffer
   14.46 + * @param size_t			IN: Maximum size of buffer
   14.47 + * @param unsigned int *	OUT: Number of bytes read (0 = end of stream)
   14.48 + * @return					True on success, false on failure
   14.49 + */
   14.50 +typedef bool (*STREAMREADER)(void *, char *, size_t, unsigned int *);
   14.51 +
   14.52 +class TextParsers : public ITextParsers
   14.53 +{
   14.54 +public:
   14.55 +	TextParsers();
   14.56 +public:
   14.57 +	bool ParseFile_INI(const char *file, 
   14.58 +		ITextListener_INI *ini_listener,
   14.59 +		unsigned int *line,
   14.60 +		unsigned int *col);
   14.61 +
   14.62 +	SMCError ParseFile_SMC(const char *file, 
   14.63 +		ITextListener_SMC *smc_listener, 
   14.64 +		SMCStates *states);
   14.65 +
   14.66 +	SMCError ParseSMCFile(const char *file,
   14.67 +			ITextListener_SMC *smc_listener,
   14.68 +			SMCStates *states,
   14.69 +			char *buffer,
   14.70 +			size_t maxsize);
   14.71 +
   14.72 +	unsigned int GetUTF8CharBytes(const char *stream);
   14.73 +
   14.74 +	const char *GetSMCErrorString(SMCError err);
   14.75 +	bool IsWhitespace(const char *stream);
   14.76 +private:
   14.77 +	SMCError ParseString_SMC(const char *stream, 
   14.78 +		ITextListener_SMC *smc,
   14.79 +		SMCStates *states);
   14.80 +	SMCError ParseStream_SMC(void *stream, 
   14.81 +		STREAMREADER srdr,
   14.82 +		ITextListener_SMC *smc,
   14.83 +		SMCStates *states);
   14.84 +
   14.85 +};
   14.86 +
   14.87 +extern TextParsers g_TextParser;
   14.88 +
   14.89 +#endif //_INCLUDE_SOURCEMOD_TEXTPARSERS_H_
   14.90 +
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/tools/gamedata_md5/main.cpp	Sun Aug 17 18:27:51 2008 +0000
    15.3 @@ -0,0 +1,45 @@
    15.4 +#include "main.h"
    15.5 +#include <stdarg.h>
    15.6 +
    15.7 +BuildMD5ableBuffer g_MD5Builder;
    15.8 +
    15.9 +int main(int argc, char **argv)
   15.10 +{
   15.11 +	SMCStates states;
   15.12 +	SMCError error;
   15.13 +
   15.14 +	if (argc < 2)
   15.15 +	{
   15.16 +		fprintf(stderr, "Usage: <file>\n");
   15.17 +		return -1;
   15.18 +	}
   15.19 +
   15.20 +	error = g_TextParser.ParseFile_SMC(argv[1], &g_MD5Builder, &states);
   15.21 +
   15.22 +	if (error == SMCError_Okay)
   15.23 +	{
   15.24 +		printf("%s", g_MD5Builder.GetMD5String());
   15.25 +		return 0;
   15.26 +	}
   15.27 +
   15.28 +	fprintf(stderr, "Failed to parse file, Error %i at line %i and col %i\n", error, states.line, states.col);
   15.29 +	return -1;
   15.30 +}
   15.31 +
   15.32 +size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...)
   15.33 +{
   15.34 +	va_list ap;
   15.35 +	va_start(ap, fmt);
   15.36 +	size_t len = vsnprintf(buffer, maxlength, fmt, ap);
   15.37 +	va_end(ap);
   15.38 +
   15.39 +	if (len >= maxlength)
   15.40 +	{
   15.41 +		buffer[maxlength - 1] = '\0';
   15.42 +		return (maxlength - 1);
   15.43 +	}
   15.44 +	else
   15.45 +	{
   15.46 +		return len;
   15.47 +	}
   15.48 +}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/tools/gamedata_md5/main.h	Sun Aug 17 18:27:51 2008 +0000
    16.3 @@ -0,0 +1,88 @@
    16.4 +#ifndef _INCLUDE_GAMEDATAMD5_MAIN_H_
    16.5 +#define _INCLUDE_GAMEDATAMD5_MAIN_H_
    16.6 +
    16.7 +#include "TextParsers.h"
    16.8 +#include "sm_memtable.h"
    16.9 +#include "md5.h"
   16.10 +
   16.11 +using namespace SourceMod;
   16.12 +
   16.13 +size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...);
   16.14 +
   16.15 +class BuildMD5ableBuffer : public ITextListener_SMC
   16.16 +{
   16.17 +public:
   16.18 +
   16.19 +	BuildMD5ableBuffer()
   16.20 +	{
   16.21 +		stringTable = new BaseStringTable(2048);
   16.22 +		md5[0] = 0;
   16.23 +		md5String[0] = 0;
   16.24 +	}
   16.25 +
   16.26 +	~BuildMD5ableBuffer()
   16.27 +	{
   16.28 +		delete stringTable;
   16.29 +	}
   16.30 +
   16.31 +	void ReadSMC_ParseStart()
   16.32 +	{
   16.33 +		checksum = MD5();
   16.34 +	}
   16.35 +
   16.36 +	SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
   16.37 +	{
   16.38 +		stringTable->AddString(key);
   16.39 +		stringTable->AddString(value);
   16.40 +
   16.41 +		return SMCResult_Continue;
   16.42 +	}
   16.43 +
   16.44 +	SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name)
   16.45 +	{
   16.46 +		stringTable->AddString(name);
   16.47 +
   16.48 +		return SMCResult_Continue;
   16.49 +	}
   16.50 +
   16.51 +	void ReadSMC_ParseEnd(bool halted, bool failed)
   16.52 +	{
   16.53 +		if (halted || failed)
   16.54 +		{
   16.55 +			return;
   16.56 +		}
   16.57 +
   16.58 +		void *data = stringTable->GetMemTable()->GetAddress(0);
   16.59 +
   16.60 +		if (data != NULL)
   16.61 +		{
   16.62 +			checksum.update((unsigned char *)data, stringTable->GetMemTable()->GetActualMemUsed());
   16.63 +		}
   16.64 +
   16.65 +		checksum.finalize();
   16.66 +
   16.67 +		checksum.hex_digest(md5String);
   16.68 +		checksum.raw_digest(md5);
   16.69 +
   16.70 +		stringTable->Reset();
   16.71 +	}
   16.72 +
   16.73 +	unsigned char * GetMD5()
   16.74 +	{
   16.75 +		return md5;
   16.76 +	}
   16.77 +
   16.78 +	unsigned char * GetMD5String()
   16.79 +	{
   16.80 +		return (unsigned char *)&md5String[0];
   16.81 +	}
   16.82 +
   16.83 +private:
   16.84 +	MD5 checksum;
   16.85 +	unsigned char md5[16];
   16.86 +	char md5String[33];
   16.87 +	BaseStringTable *stringTable;
   16.88 +};
   16.89 +
   16.90 +
   16.91 +#endif // _INCLUDE_GAMEDATAMD5_MAIN_H_
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/tools/gamedata_md5/md5.cpp	Sun Aug 17 18:27:51 2008 +0000
    17.3 @@ -0,0 +1,485 @@
    17.4 +// MD5.CC - source code for the C++/object oriented translation and 
    17.5 +//          modification of MD5.
    17.6 +
    17.7 +// Translation and modification (c) 1995 by Mordechai T. Abzug 
    17.8 +
    17.9 +// This translation/ modification is provided "as is," without express or 
   17.10 +// implied warranty of any kind.
   17.11 +
   17.12 +// The translator/ modifier does not claim (1) that MD5 will do what you think 
   17.13 +// it does; (2) that this translation/ modification is accurate; or (3) that 
   17.14 +// this software is "merchantible."  (Language for this disclaimer partially 
   17.15 +// copied from the disclaimer below).
   17.16 +
   17.17 +/* based on:
   17.18 +
   17.19 +   MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
   17.20 +   MDDRIVER.C - test driver for MD2, MD4 and MD5
   17.21 +
   17.22 +
   17.23 +   Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
   17.24 +rights reserved.
   17.25 +
   17.26 +License to copy and use this software is granted provided that it
   17.27 +is identified as the "RSA Data Security, Inc. MD5 Message-Digest
   17.28 +Algorithm" in all material mentioning or referencing this software
   17.29 +or this function.
   17.30 +
   17.31 +License is also granted to make and use derivative works provided
   17.32 +that such works are identified as "derived from the RSA Data
   17.33 +Security, Inc. MD5 Message-Digest Algorithm" in all material
   17.34 +mentioning or referencing the derived work.
   17.35 +
   17.36 +RSA Data Security, Inc. makes no representations concerning either
   17.37 +the merchantability of this software or the suitability of this
   17.38 +software for any particular purpose. It is provided "as is"
   17.39 +without express or implied warranty of any kind.
   17.40 +
   17.41 +These notices must be retained in any copies of any part of this
   17.42 +documentation and/or software.
   17.43 +
   17.44 + */
   17.45 +
   17.46 +#include "md5.h"
   17.47 +
   17.48 +#include <assert.h>
   17.49 +#include <string.h>
   17.50 +
   17.51 +// MD5 simple initialization method
   17.52 +
   17.53 +MD5::MD5(){
   17.54 +
   17.55 +  init();
   17.56 +
   17.57 +}
   17.58 +
   17.59 +
   17.60 +// MD5 block update operation. Continues an MD5 message-digest
   17.61 +// operation, processing another message block, and updating the
   17.62 +// context.
   17.63 +
   17.64 +void MD5::update (uint1 *input, uint4 input_length) {
   17.65 +
   17.66 +  uint4 input_index, buffer_index;
   17.67 +  uint4 buffer_space;                // how much space is left in buffer
   17.68 +
   17.69 +  if (finalized){  // so we can't update!
   17.70 +    /*cerr << "MD5::update:  Can't update a finalized digest!" << endl;*/
   17.71 +    return;
   17.72 +  }
   17.73 +
   17.74 +  // Compute number of bytes mod 64
   17.75 +  buffer_index = (unsigned int)((count[0] >> 3) & 0x3F);
   17.76 +
   17.77 +  // Update number of bits
   17.78 +  if (  (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) )
   17.79 +    count[1]++;
   17.80 +
   17.81 +  count[1] += ((uint4)input_length >> 29);
   17.82 +
   17.83 +
   17.84 +  buffer_space = 64 - buffer_index;  // how much space is left in buffer
   17.85 +
   17.86 +  // Transform as many times as possible.
   17.87 +  if (input_length >= buffer_space) { // ie. we have enough to fill the buffer
   17.88 +    // fill the rest of the buffer and transform
   17.89 +    memcpy (buffer + buffer_index, input, buffer_space);
   17.90 +    transform (buffer);
   17.91 +
   17.92 +    // now, transform each 64-byte piece of the input, bypassing the buffer
   17.93 +    for (input_index = buffer_space; input_index + 63 < input_length; 
   17.94 +	 input_index += 64)
   17.95 +      transform (input+input_index);
   17.96 +
   17.97 +    buffer_index = 0;  // so we can buffer remaining
   17.98 +  }
   17.99 +  else
  17.100 +    input_index=0;     // so we can buffer the whole input
  17.101 +
  17.102 +
  17.103 +  // and here we do the buffering:
  17.104 +  memcpy(buffer+buffer_index, input+input_index, input_length-input_index);
  17.105 +}
  17.106 +
  17.107 +
  17.108 +
  17.109 +// MD5 update for files.
  17.110 +// Like above, except that it works on files (and uses above as a primitive.)
  17.111 +
  17.112 +void MD5::update(FILE *file){
  17.113 +
  17.114 +  unsigned char buffer[1024];
  17.115 +  int len;
  17.116 +
  17.117 +  while ((len=fread(buffer, 1, 1024, file)))
  17.118 +    update(buffer, len);
  17.119 +
  17.120 +  fclose (file);
  17.121 +
  17.122 +}
  17.123 +
  17.124 +
  17.125 +// MD5 finalization. Ends an MD5 message-digest operation, writing the
  17.126 +// the message digest and zeroizing the context.
  17.127 +
  17.128 +
  17.129 +void MD5::finalize (){
  17.130 +
  17.131 +  unsigned char bits[8];
  17.132 +  unsigned int index, padLen;
  17.133 +  static uint1 PADDING[64]={
  17.134 +    0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  17.135 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  17.136 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  17.137 +    };
  17.138 +
  17.139 +  if (finalized){
  17.140 +   /* cerr << "MD5::finalize:  Already finalized this digest!" << endl;*/
  17.141 +    return;
  17.142 +  }
  17.143 +
  17.144 +  // Save number of bits
  17.145 +  encode (bits, count, 8);
  17.146 +
  17.147 +  // Pad out to 56 mod 64.
  17.148 +  index = (uint4) ((count[0] >> 3) & 0x3f);
  17.149 +  padLen = (index < 56) ? (56 - index) : (120 - index);
  17.150 +  update (PADDING, padLen);
  17.151 +
  17.152 +  // Append length (before padding)
  17.153 +  update (bits, 8);
  17.154 +
  17.155 +  // Store state in digest
  17.156 +  encode (digest, state, 16);
  17.157 +
  17.158 +  // Zeroize sensitive information
  17.159 +  memset (buffer, 0, sizeof(*buffer));
  17.160 +
  17.161 +  finalized=1;
  17.162 +
  17.163 +}
  17.164 +
  17.165 +
  17.166 +
  17.167 +
  17.168 +MD5::MD5(FILE *file){
  17.169 +
  17.170 +  init();  // must be called be all constructors
  17.171 +  update(file);
  17.172 +  finalize ();
  17.173 +}
  17.174 +
  17.175 +unsigned char *MD5::raw_digest(){
  17.176 +
  17.177 +  uint1 *s = new uint1[16];
  17.178 +
  17.179 +  if (!finalized){
  17.180 +/*    cerr << "MD5::raw_digest:  Can't get digest if you haven't "<<
  17.181 +      "finalized the digest!" <<endl;*/
  17.182 +    return ( (unsigned char*) "");
  17.183 +  }
  17.184 +
  17.185 +  memcpy(s, digest, 16);
  17.186 +  return s;
  17.187 +}
  17.188 +
  17.189 +unsigned char *MD5::raw_digest(unsigned char buffer[16])
  17.190 +{
  17.191 +	if (!finalized)
  17.192 +	{
  17.193 +		return ( (unsigned char*) "");
  17.194 +	}
  17.195 +
  17.196 +	 memcpy(buffer, digest, 16);
  17.197 +	 return buffer;
  17.198 +}
  17.199 +
  17.200 +
  17.201 +
  17.202 +char *MD5::hex_digest(){
  17.203 +
  17.204 +  int i;
  17.205 +  char *s= new char[33];
  17.206 +
  17.207 +  if (!finalized){
  17.208 +/*    cerr << "MD5::hex_digest:  Can't get digest if you haven't "<<
  17.209 +      "finalized the digest!" <<endl;*/
  17.210 +    return "";
  17.211 +  }
  17.212 +
  17.213 +  for (i=0; i<16; i++)
  17.214 +    sprintf(s+i*2, "%02x", digest[i]);
  17.215 +
  17.216 +  s[32]='\0';
  17.217 +
  17.218 +  return s;
  17.219 +}
  17.220 +
  17.221 +
  17.222 +char *MD5::hex_digest(char buffer[33]){
  17.223 +
  17.224 +  int i;
  17.225 +
  17.226 +  if (!finalized)
  17.227 +  {
  17.228 +	 /* cerr << "MD5::hex_digest:  Can't get digest if you haven't "<<
  17.229 +      "finalized the digest!" <<endl;*/
  17.230 +    return "";
  17.231 +  }
  17.232 +
  17.233 +  for (i=0; i<16; i++)
  17.234 +    sprintf(buffer+i*2, "%02x", digest[i]);
  17.235 +
  17.236 +  buffer[32]='\0';
  17.237 +
  17.238 +  return buffer;
  17.239 +}
  17.240 +
  17.241 +
  17.242 +// PRIVATE METHODS:
  17.243 +
  17.244 +
  17.245 +
  17.246 +void MD5::init(){
  17.247 +  finalized=0;  // we just started!
  17.248 +
  17.249 +  // Nothing counted, so count=0
  17.250 +  count[0] = 0;
  17.251 +  count[1] = 0;
  17.252 +
  17.253 +  // Load magic initialization constants.
  17.254 +  state[0] = 0x67452301;
  17.255 +  state[1] = 0xefcdab89;
  17.256 +  state[2] = 0x98badcfe;
  17.257 +  state[3] = 0x10325476;
  17.258 +}
  17.259 +
  17.260 +
  17.261 +
  17.262 +// Constants for MD5Transform routine.
  17.263 +// Although we could use C++ style constants, defines are actually better,
  17.264 +// since they let us easily evade scope clashes.
  17.265 +
  17.266 +#define S11 7
  17.267 +#define S12 12
  17.268 +#define S13 17
  17.269 +#define S14 22
  17.270 +#define S21 5
  17.271 +#define S22 9
  17.272 +#define S23 14
  17.273 +#define S24 20
  17.274 +#define S31 4
  17.275 +#define S32 11
  17.276 +#define S33 16
  17.277 +#define S34 23
  17.278 +#define S41 6
  17.279 +#define S42 10
  17.280 +#define S43 15
  17.281 +#define S44 21
  17.282 +
  17.283 +
  17.284 +
  17.285 +
  17.286 +// MD5 basic transformation. Transforms state based on block.
  17.287 +void MD5::transform (uint1 block[64]){
  17.288 +
  17.289 +  uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
  17.290 +
  17.291 +  decode (x, block, 64);
  17.292 +
  17.293 +  assert(!finalized);  // not just a user error, since the method is private
  17.294 +
  17.295 +  /* Round 1 */
  17.296 +  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
  17.297 +  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
  17.298 +  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
  17.299 +  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
  17.300 +  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
  17.301 +  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
  17.302 +  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
  17.303 +  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
  17.304 +  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
  17.305 +  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
  17.306 +  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
  17.307 +  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
  17.308 +  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
  17.309 +  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
  17.310 +  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
  17.311 +  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
  17.312 +
  17.313 + /* Round 2 */
  17.314 +  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
  17.315 +  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
  17.316 +  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
  17.317 +  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
  17.318 +  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
  17.319 +  GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
  17.320 +  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
  17.321 +  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
  17.322 +  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
  17.323 +  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
  17.324 +  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
  17.325 +  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
  17.326 +  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
  17.327 +  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
  17.328 +  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
  17.329 +  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
  17.330 +
  17.331 +  /* Round 3 */
  17.332 +  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
  17.333 +  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
  17.334 +  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
  17.335 +  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
  17.336 +  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
  17.337 +  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
  17.338 +  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
  17.339 +  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
  17.340 +  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
  17.341 +  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
  17.342 +  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
  17.343 +  HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
  17.344 +  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
  17.345 +  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
  17.346 +  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
  17.347 +  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
  17.348 +
  17.349 +  /* Round 4 */
  17.350 +  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
  17.351 +  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
  17.352 +  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
  17.353 +  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
  17.354 +  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
  17.355 +  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
  17.356 +  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
  17.357 +  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
  17.358 +  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
  17.359 +  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
  17.360 +  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
  17.361 +  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
  17.362 +  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
  17.363 +  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
  17.364 +  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
  17.365 +  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
  17.366 +
  17.367 +  state[0] += a;
  17.368 +  state[1] += b;
  17.369 +  state[2] += c;
  17.370 +  state[3] += d;
  17.371 +
  17.372 +  // Zeroize sensitive information.
  17.373 +  memset ( (uint1 *) x, 0, sizeof(x));
  17.374 +
  17.375 +}
  17.376 +
  17.377 +
  17.378 +
  17.379 +// Encodes input (UINT4) into output (unsigned char). Assumes len is
  17.380 +// a multiple of 4.
  17.381 +void MD5::encode (uint1 *output, uint4 *input, uint4 len) {
  17.382 +
  17.383 +  unsigned int i, j;
  17.384 +
  17.385 +  for (i = 0, j = 0; j < len; i++, j += 4) {
  17.386 +    output[j]   = (uint1)  (input[i] & 0xff);
  17.387 +    output[j+1] = (uint1) ((input[i] >> 8) & 0xff);
  17.388 +    output[j+2] = (uint1) ((input[i] >> 16) & 0xff);
  17.389 +    output[j+3] = (uint1) ((input[i] >> 24) & 0xff);
  17.390 +  }
  17.391 +}
  17.392 +
  17.393 +
  17.394 +
  17.395 +
  17.396 +// Decodes input (unsigned char) into output (UINT4). Assumes len is
  17.397 +// a multiple of 4.
  17.398 +void MD5::decode (uint4 *output, uint1 *input, uint4 len){
  17.399 +
  17.400 +  unsigned int i, j;
  17.401 +
  17.402 +  for (i = 0, j = 0; j < len; i++, j += 4)
  17.403 +    output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
  17.404 +      (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
  17.405 +}
  17.406 +
  17.407 +
  17.408 +
  17.409 +
  17.410 +
  17.411 +// Note: Replace "for loop" with standard memcpy if possible.
  17.412 +void MD5::memcpy (uint1 *output, uint1 *input, uint4 len){
  17.413 +
  17.414 +  unsigned int i;
  17.415 +
  17.416 +  for (i = 0; i < len; i++)
  17.417 +    output[i] = input[i];
  17.418 +}
  17.419 +
  17.420 +
  17.421 +
  17.422 +// Note: Replace "for loop" with standard memset if possible.
  17.423 +void MD5::memset (uint1 *output, uint1 value, uint4 len){
  17.424 +
  17.425 +  unsigned int i;
  17.426 +
  17.427 +  for (i = 0; i < len; i++)
  17.428 +    output[i] = value;
  17.429 +}
  17.430 +
  17.431 +
  17.432 +
  17.433 +// ROTATE_LEFT rotates x left n bits.
  17.434 +
  17.435 +inline unsigned int MD5::rotate_left  (uint4 x, uint4 n){
  17.436 +  return (x << n) | (x >> (32-n))  ;
  17.437 +}
  17.438 +
  17.439 +
  17.440 +
  17.441 +
  17.442 +// F, G, H and I are basic MD5 functions.
  17.443 +
  17.444 +inline unsigned int MD5::F            (uint4 x, uint4 y, uint4 z){
  17.445 +  return (x & y) | (~x & z);
  17.446 +}
  17.447 +
  17.448 +inline unsigned int MD5::G            (uint4 x, uint4 y, uint4 z){
  17.449 +  return (x & z) | (y & ~z);
  17.450 +}
  17.451 +
  17.452 +inline unsigned int MD5::H            (uint4 x, uint4 y, uint4 z){
  17.453 +  return x ^ y ^ z;
  17.454 +}
  17.455 +
  17.456 +inline unsigned int MD5::I            (uint4 x, uint4 y, uint4 z){
  17.457 +  return y ^ (x | ~z);
  17.458 +}
  17.459 +
  17.460 +
  17.461 +
  17.462 +// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
  17.463 +// Rotation is separate from addition to prevent recomputation.
  17.464 +
  17.465 +
  17.466 +inline void MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
  17.467 +		    uint4  s, uint4 ac){
  17.468 + a += F(b, c, d) + x + ac;
  17.469 + a = rotate_left (a, s) +b;
  17.470 +}
  17.471 +
  17.472 +inline void MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
  17.473 +		    uint4 s, uint4 ac){
  17.474 + a += G(b, c, d) + x + ac;
  17.475 + a = rotate_left (a, s) +b;
  17.476 +}
  17.477 +
  17.478 +inline void MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
  17.479 +		    uint4 s, uint4 ac){
  17.480 + a += H(b, c, d) + x + ac;
  17.481 + a = rotate_left (a, s) +b;
  17.482 +}
  17.483 +
  17.484 +inline void MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
  17.485 +			     uint4 s, uint4 ac){
  17.486 + a += I(b, c, d) + x + ac;
  17.487 + a = rotate_left (a, s) +b;
  17.488 +}
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/tools/gamedata_md5/md5.h	Sun Aug 17 18:27:51 2008 +0000
    18.3 @@ -0,0 +1,106 @@
    18.4 +// MD5.CC - source code for the C++/object oriented translation and 
    18.5 +//          modification of MD5.
    18.6 +
    18.7 +// Translation and modification (c) 1995 by Mordechai T. Abzug 
    18.8 +
    18.9 +// This translation/ modification is provided "as is," without express or 
   18.10 +// implied warranty of any kind.
   18.11 +
   18.12 +// The translator/ modifier does not claim (1) that MD5 will do what you think 
   18.13 +// it does; (2) that this translation/ modification is accurate; or (3) that 
   18.14 +// this software is "merchantible."  (Language for this disclaimer partially 
   18.15 +// copied from the disclaimer below).
   18.16 +
   18.17 +/* based on:
   18.18 +
   18.19 +   MD5.H - header file for MD5C.C
   18.20 +   MDDRIVER.C - test driver for MD2, MD4 and MD5
   18.21 +
   18.22 +   Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
   18.23 +rights reserved.
   18.24 +
   18.25 +License to copy and use this software is granted provided that it
   18.26 +is identified as the "RSA Data Security, Inc. MD5 Message-Digest
   18.27 +Algorithm" in all material mentioning or referencing this software
   18.28 +or this function.
   18.29 +
   18.30 +License is also granted to make and use derivative works provided
   18.31 +that such works are identified as "derived from the RSA Data
   18.32 +Security, Inc. MD5 Message-Digest Algorithm" in all material
   18.33 +mentioning or referencing the derived work.
   18.34 +
   18.35 +RSA Data Security, Inc. makes no representations concerning either
   18.36 +the merchantability of this software or the suitability of this
   18.37 +software for any particular purpose. It is provided "as is"
   18.38 +without express or implied warranty of any kind.
   18.39 +
   18.40 +These notices must be retained in any copies of any part of this
   18.41 +documentation and/or software.
   18.42 +
   18.43 +*/
   18.44 +
   18.45 +#include <stdio.h>
   18.46 +//#include <fstream.h>
   18.47 +//#include <iostream.h>
   18.48 +
   18.49 +class MD5 {
   18.50 +
   18.51 +public:
   18.52 +// methods for controlled operation:
   18.53 +  MD5              ();  // simple initializer
   18.54 +  void  update     (unsigned char *input, unsigned int input_length);
   18.55 +  void  update     (FILE *file);
   18.56 +  void  finalize   ();
   18.57 +
   18.58 +// constructors for special circumstances.  All these constructors finalize
   18.59 +// the MD5 context.
   18.60 +  MD5              (unsigned char *string); // digest string, finalize
   18.61 +  MD5              (FILE *file);            // digest file, close, finalize
   18.62 +
   18.63 +// methods to acquire finalized result
   18.64 +  unsigned char    *raw_digest ();  // digest as a 16-byte binary array
   18.65 +  unsigned char		*raw_digest(unsigned char buffer[16]);
   18.66 +  char *            hex_digest ();  // digest as a 33-byte ascii-hex string
   18.67 +  char *			hex_digest (char buffer[33]); //same as above, passing buffer
   18.68 +
   18.69 +
   18.70 +
   18.71 +private:
   18.72 +
   18.73 +// first, some types:
   18.74 +  typedef unsigned       int uint4; // assumes integer is 4 words long
   18.75 +  typedef unsigned short int uint2; // assumes short integer is 2 words long
   18.76 +  typedef unsigned      char uint1; // assumes char is 1 word long
   18.77 +
   18.78 +// next, the private data:
   18.79 +  uint4 state[4];
   18.80 +  uint4 count[2];     // number of *bits*, mod 2^64
   18.81 +  uint1 buffer[64];   // input buffer
   18.82 +  uint1 digest[16];
   18.83 +  uint1 finalized;
   18.84 +
   18.85 +// last, the private methods, mostly static:
   18.86 +  void init             ();               // called by all constructors
   18.87 +  void transform        (uint1 *buffer);  // does the real update work.  Note 
   18.88 +                                          // that length is implied to be 64.
   18.89 +
   18.90 +  static void encode    (uint1 *dest, uint4 *src, uint4 length);
   18.91 +  static void decode    (uint4 *dest, uint1 *src, uint4 length);
   18.92 +  static void memcpy    (uint1 *dest, uint1 *src, uint4 length);
   18.93 +  static void memset    (uint1 *start, uint1 val, uint4 length);
   18.94 +
   18.95 +  static inline uint4  rotate_left (uint4 x, uint4 n);
   18.96 +  static inline uint4  F           (uint4 x, uint4 y, uint4 z);
   18.97 +  static inline uint4  G           (uint4 x, uint4 y, uint4 z);
   18.98 +  static inline uint4  H           (uint4 x, uint4 y, uint4 z);
   18.99 +  static inline uint4  I           (uint4 x, uint4 y, uint4 z);
  18.100 +  static inline void   FF  (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
  18.101 +			    uint4 s, uint4 ac);
  18.102 +  static inline void   GG  (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
  18.103 +			    uint4 s, uint4 ac);
  18.104 +  static inline void   HH  (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
  18.105 +			    uint4 s, uint4 ac);
  18.106 +  static inline void   II  (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
  18.107 +			    uint4 s, uint4 ac);
  18.108 +
  18.109 +};
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/tools/gamedata_md5/msvc9/gamedatamd5.sln	Sun Aug 17 18:27:51 2008 +0000
    19.3 @@ -0,0 +1,20 @@
    19.4 +
    19.5 +Microsoft Visual Studio Solution File, Format Version 10.00
    19.6 +# Visual Studio 2008
    19.7 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gamedatamd5", "gamedatamd5.vcproj", "{E1C96598-E1AC-4928-8930-F8B6CD245B12}"
    19.8 +EndProject
    19.9 +Global
   19.10 +	GlobalSection(SolutionConfigurationPlatforms) = preSolution
   19.11 +		Debug|Win32 = Debug|Win32
   19.12 +		Release|Win32 = Release|Win32
   19.13 +	EndGlobalSection
   19.14 +	GlobalSection(ProjectConfigurationPlatforms) = postSolution
   19.15 +		{E1C96598-E1AC-4928-8930-F8B6CD245B12}.Debug|Win32.ActiveCfg = Debug|Win32
   19.16 +		{E1C96598-E1AC-4928-8930-F8B6CD245B12}.Debug|Win32.Build.0 = Debug|Win32
   19.17 +		{E1C96598-E1AC-4928-8930-F8B6CD245B12}.Release|Win32.ActiveCfg = Release|Win32
   19.18 +		{E1C96598-E1AC-4928-8930-F8B6CD245B12}.Release|Win32.Build.0 = Release|Win32
   19.19 +	EndGlobalSection
   19.20 +	GlobalSection(SolutionProperties) = preSolution
   19.21 +		HideSolutionNode = FALSE
   19.22 +	EndGlobalSection
   19.23 +EndGlobal
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/tools/gamedata_md5/msvc9/gamedatamd5.vcproj	Sun Aug 17 18:27:51 2008 +0000
    20.3 @@ -0,0 +1,219 @@
    20.4 +<?xml version="1.0" encoding="UTF-8"?>
    20.5 +<VisualStudioProject
    20.6 +	ProjectType="Visual C++"
    20.7 +	Version="9.00"
    20.8 +	Name="gamedatamd5"
    20.9 +	ProjectGUID="{E1C96598-E1AC-4928-8930-F8B6CD245B12}"
   20.10 +	Keyword="Win32Proj"
   20.11 +	TargetFrameworkVersion="0"
   20.12 +	>
   20.13 +	<Platforms>
   20.14 +		<Platform
   20.15 +			Name="Win32"
   20.16 +		/>
   20.17 +	</Platforms>
   20.18 +	<ToolFiles>
   20.19 +	</ToolFiles>
   20.20 +	<Configurations>
   20.21 +		<Configuration
   20.22 +			Name="Debug|Win32"
   20.23 +			OutputDirectory="Debug"
   20.24 +			IntermediateDirectory="Debug"
   20.25 +			ConfigurationType="1"
   20.26 +			CharacterSet="2"
   20.27 +			>
   20.28 +			<Tool
   20.29 +				Name="VCPreBuildEventTool"
   20.30 +			/>
   20.31 +			<Tool
   20.32 +				Name="VCCustomBuildTool"
   20.33 +			/>
   20.34 +			<Tool
   20.35 +				Name="VCXMLDataGeneratorTool"
   20.36 +			/>
   20.37 +			<Tool
   20.38 +				Name="VCWebServiceProxyGeneratorTool"
   20.39 +			/>
   20.40 +			<Tool
   20.41 +				Name="VCMIDLTool"
   20.42 +			/>
   20.43 +			<Tool
   20.44 +				Name="VCCLCompilerTool"
   20.45 +				Optimization="0"
   20.46 +				AdditionalIncludeDirectories="../../../public;../../../public/sourcepawn"
   20.47 +				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
   20.48 +				MinimalRebuild="true"
   20.49 +				BasicRuntimeChecks="3"
   20.50 +				RuntimeLibrary="1"
   20.51 +				UsePrecompiledHeader="0"
   20.52 +				WarningLevel="3"
   20.53 +				Detect64BitPortabilityProblems="false"
   20.54 +				DebugInformationFormat="4"
   20.55 +			/>
   20.56 +			<Tool
   20.57 +				Name="VCManagedResourceCompilerTool"
   20.58 +			/>
   20.59 +			<Tool
   20.60 +				Name="VCResourceCompilerTool"
   20.61 +			/>
   20.62 +			<Tool
   20.63 +				Name="VCPreLinkEventTool"
   20.64 +			/>
   20.65 +			<Tool
   20.66 +				Name="VCLinkerTool"
   20.67 +				LinkIncremental="2"
   20.68 +				GenerateDebugInformation="true"
   20.69 +				SubSystem="1"
   20.70 +				TargetMachine="1"
   20.71 +			/>
   20.72 +			<Tool
   20.73 +				Name="VCALinkTool"
   20.74 +			/>
   20.75 +			<Tool
   20.76 +				Name="VCManifestTool"
   20.77 +			/>
   20.78 +			<Tool
   20.79 +				Name="VCXDCMakeTool"
   20.80 +			/>
   20.81 +			<Tool
   20.82 +				Name="VCBscMakeTool"
   20.83 +			/>
   20.84 +			<Tool
   20.85 +				Name="VCFxCopTool"
   20.86 +			/>
   20.87 +			<Tool
   20.88 +				Name="VCAppVerifierTool"
   20.89 +			/>
   20.90 +			<Tool
   20.91 +				Name="VCPostBuildEventTool"
   20.92 +			/>
   20.93 +		</Configuration>
   20.94 +		<Configuration
   20.95 +			Name="Release|Win32"
   20.96 +			OutputDirectory="Release"
   20.97 +			IntermediateDirectory="Release"
   20.98 +			ConfigurationType="1"
   20.99 +			>
  20.100 +			<Tool
  20.101 +				Name="VCPreBuildEventTool"
  20.102 +			/>
  20.103 +			<Tool
  20.104 +				Name="VCCustomBuildTool"
  20.105 +			/>
  20.106 +			<Tool
  20.107 +				Name="VCXMLDataGeneratorTool"
  20.108 +			/>
  20.109 +			<Tool
  20.110 +				Name="VCWebServiceProxyGeneratorTool"
  20.111 +			/>
  20.112 +			<Tool
  20.113 +				Name="VCMIDLTool"
  20.114 +			/>
  20.115 +			<Tool
  20.116 +				Name="VCCLCompilerTool"
  20.117 +				AdditionalIncludeDirectories="../../../public;../../../public/sourcepawn"
  20.118 +				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
  20.119 +				RuntimeLibrary="0"
  20.120 +				UsePrecompiledHeader="0"
  20.121 +				WarningLevel="3"
  20.122 +				Detect64BitPortabilityProblems="false"
  20.123 +				DebugInformationFormat="3"
  20.124 +			/>
  20.125 +			<Tool
  20.126 +				Name="VCManagedResourceCompilerTool"
  20.127 +			/>
  20.128 +			<Tool
  20.129 +				Name="VCResourceCompilerTool"
  20.130 +			/>
  20.131 +			<Tool
  20.132 +				Name="VCPreLinkEventTool"
  20.133 +			/>
  20.134 +			<Tool
  20.135 +				Name="VCLinkerTool"
  20.136 +				LinkIncremental="2"
  20.137 +				GenerateDebugInformation="true"
  20.138 +				SubSystem="1"
  20.139 +				OptimizeReferences="2"
  20.140 +				EnableCOMDATFolding="2"
  20.141 +				TargetMachine="1"
  20.142 +			/>
  20.143 +			<Tool
  20.144 +				Name="VCALinkTool"
  20.145 +			/>
  20.146 +			<Tool
  20.147 +				Name="VCManifestTool"
  20.148 +			/>
  20.149 +			<Tool
  20.150 +				Name="VCXDCMakeTool"
  20.151 +			/>
  20.152 +			<Tool
  20.153 +				Name="VCBscMakeTool"
  20.154 +			/>
  20.155 +			<Tool
  20.156 +				Name="VCFxCopTool"
  20.157 +			/>
  20.158 +			<Tool
  20.159 +				Name="VCAppVerifierTool"
  20.160 +			/>
  20.161 +			<Tool
  20.162 +				Name="VCPostBuildEventTool"
  20.163 +			/>
  20.164 +		</Configuration>
  20.165 +	</Configurations>
  20.166 +	<References>
  20.167 +	</References>
  20.168 +	<Files>
  20.169 +		<Filter
  20.170 +			Name="Header Files"
  20.171 +			Filter="h;hpp;hxx;hm;inl;inc;xsd"
  20.172 +			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
  20.173 +			>
  20.174 +			<File
  20.175 +				RelativePath="..\main.h"
  20.176 +				>
  20.177 +			</File>
  20.178 +			<File
  20.179 +				RelativePath="..\md5.h"
  20.180 +				>
  20.181 +			</File>
  20.182 +			<File
  20.183 +				RelativePath="..\sm_memtable.h"
  20.184 +				>
  20.185 +			</File>
  20.186 +			<File
  20.187 +				RelativePath="..\TextParsers.h"
  20.188 +				>
  20.189 +			</File>
  20.190 +		</Filter>
  20.191 +		<Filter
  20.192 +			Name="Resource Files"
  20.193 +			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
  20.194 +			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
  20.195 +			>
  20.196 +		</Filter>
  20.197 +		<Filter
  20.198 +			Name="Source Files"
  20.199 +			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
  20.200 +			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
  20.201 +			>
  20.202 +			<File
  20.203 +				RelativePath="..\main.cpp"
  20.204 +				>
  20.205 +			</File>
  20.206 +			<File
  20.207 +				RelativePath="..\md5.cpp"
  20.208 +				>
  20.209 +			</File>
  20.210 +			<File
  20.211 +				RelativePath="..\sm_memtable.cpp"
  20.212 +				>
  20.213 +			</File>
  20.214 +			<File
  20.215 +				RelativePath="..\TextParsers.cpp"
  20.216 +				>
  20.217 +			</File>
  20.218 +		</Filter>
  20.219 +	</Files>
  20.220 +	<Globals>
  20.221 +	</Globals>
  20.222 +</VisualStudioProject>
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/tools/gamedata_md5/sm_memtable.cpp	Sun Aug 17 18:27:51 2008 +0000
    21.3 @@ -0,0 +1,112 @@
    21.4 +/**
    21.5 + * vim: set ts=4 :
    21.6 + * =============================================================================
    21.7 + * SourceMod
    21.8 + * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    21.9 + * =============================================================================
   21.10 + *
   21.11 + * This program is free software; you can redistribute it and/or modify it under
   21.12 + * the terms of the GNU General Public License, version 3.0, as published by the
   21.13 + * Free Software Foundation.
   21.14 + * 
   21.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
   21.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   21.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   21.18 + * details.
   21.19 + *
   21.20 + * You should have received a copy of the GNU General Public License along with
   21.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
   21.22 + *
   21.23 + * As a special exception, AlliedModders LLC gives you permission to link the
   21.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
   21.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   21.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
   21.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
   21.28 + * this exception to all derivative works.  AlliedModders LLC defines further
   21.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   21.30 + * or <http://www.sourcemod.net/license.php>.
   21.31 + *
   21.32 + * Version: $Id$
   21.33 + */
   21.34 +
   21.35 +#include <string.h>
   21.36 +#include <malloc.h>
   21.37 +#include "sm_memtable.h"
   21.38 +
   21.39 +BaseMemTable::BaseMemTable(unsigned int init_size)
   21.40 +{
   21.41 +	membase = (unsigned char *)malloc(init_size);
   21.42 +	size = init_size;
   21.43 +	tail = 0;
   21.44 +}
   21.45 +
   21.46 +BaseMemTable::~BaseMemTable()
   21.47 +{
   21.48 +	free(membase);
   21.49 +	membase = NULL;
   21.50 +}
   21.51 +
   21.52 +int BaseMemTable::CreateMem(unsigned int addsize, void **addr)
   21.53 +{
   21.54 +	int idx = (int)tail;
   21.55 +
   21.56 +	while (tail + addsize >= size)
   21.57 +	{
   21.58 +		size *= 2;
   21.59 +		membase = (unsigned char *)realloc(membase, size);
   21.60 +	}
   21.61 +
   21.62 +	tail += addsize;
   21.63 +
   21.64 +	if (addr)
   21.65 +	{
   21.66 +		*addr = (void *)&membase[idx];
   21.67 +	}
   21.68 +
   21.69 +	return idx;
   21.70 +}
   21.71 +
   21.72 +void *BaseMemTable::GetAddress(int index)
   21.73 +{
   21.74 +	if (index < 0 || (unsigned int)index >= tail)
   21.75 +	{
   21.76 +		return NULL;
   21.77 +	}
   21.78 +
   21.79 +	return &membase[index];
   21.80 +}
   21.81 +
   21.82 +void BaseMemTable::Reset()
   21.83 +{
   21.84 +	tail = 0;
   21.85 +}
   21.86 +
   21.87 +BaseStringTable::BaseStringTable(unsigned int init_size) : m_table(init_size)
   21.88 +{
   21.89 +}
   21.90 +
   21.91 +BaseStringTable::~BaseStringTable()
   21.92 +{
   21.93 +}
   21.94 +
   21.95 +int BaseStringTable::AddString(const char *string)
   21.96 +{
   21.97 +	size_t len = strlen(string) + 1;
   21.98 +	int idx;
   21.99 +	char *addr;
  21.100 +
  21.101 +	idx = m_table.CreateMem(len, (void **)&addr);
  21.102 +	strcpy(addr, string);
  21.103 +
  21.104 +	return idx;
  21.105 +}
  21.106 +
  21.107 +/*const char *BaseStringTable::GetString(int str)
  21.108 +{
  21.109 +	return (const char *)m_table.GetAddress(str);
  21.110 +}*/
  21.111 +
  21.112 +void BaseStringTable::Reset()
  21.113 +{
  21.114 +	m_table.Reset();
  21.115 +}
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/tools/gamedata_md5/sm_memtable.h	Sun Aug 17 18:27:51 2008 +0000
    22.3 @@ -0,0 +1,114 @@
    22.4 +/**
    22.5 + * vim: set ts=4 :
    22.6 + * =============================================================================
    22.7 + * SourceMod
    22.8 + * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    22.9 + * =============================================================================
   22.10 + *
   22.11 + * This program is free software; you can redistribute it and/or modify it under
   22.12 + * the terms of the GNU General Public License, version 3.0, as published by the
   22.13 + * Free Software Foundation.
   22.14 + * 
   22.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
   22.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   22.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   22.18 + * details.
   22.19 + *
   22.20 + * You should have received a copy of the GNU General Public License along with
   22.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
   22.22 + *
   22.23 + * As a special exception, AlliedModders LLC gives you permission to link the
   22.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
   22.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   22.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
   22.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
   22.28 + * this exception to all derivative works.  AlliedModders LLC defines further
   22.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   22.30 + * or <http://www.sourcemod.net/license.php>.
   22.31 + *
   22.32 + * Version: $Id$
   22.33 + */
   22.34 +
   22.35 +#ifndef _INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_
   22.36 +#define _INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_
   22.37 +
   22.38 +class BaseMemTable
   22.39 +{
   22.40 +public:
   22.41 +	BaseMemTable(unsigned int init_size);
   22.42 +	~BaseMemTable();
   22.43 +public:
   22.44 +	/**
   22.45 +	 * Allocates 'size' bytes of memory.
   22.46 +	 * Optionally outputs the address through 'addr'.
   22.47 +	 * Returns an index >= 0 on success, < 0 on failure.
   22.48 +	 */
   22.49 +	int CreateMem(unsigned int size, void **addr);
   22.50 +
   22.51 +	/**
   22.52 +	 * Given an index into the memory table, returns its address.
   22.53 +	 * Returns NULL if invalid.
   22.54 +	 */
   22.55 +	void *GetAddress(int index);
   22.56 +
   22.57 +	/**
   22.58 +	 * Scraps the memory table.  For caching purposes, the memory 
   22.59 +	 * is not freed, however subsequent calls to CreateMem() will 
   22.60 +	 * begin at the first index again.
   22.61 +	 */
   22.62 +	void Reset();
   22.63 +
   22.64 +	inline unsigned int GetMemUsage()
   22.65 +	{
   22.66 +		return size;
   22.67 +	}
   22.68 +
   22.69 +	inline unsigned int GetActualMemUsed()
   22.70 +	{
   22.71 +		return tail;
   22.72 +	}
   22.73 +
   22.74 +private:
   22.75 +	unsigned char *membase;
   22.76 +	unsigned int size;
   22.77 +	unsigned int tail;
   22.78 +};
   22.79 +
   22.80 +class BaseStringTable
   22.81 +{
   22.82 +public:
   22.83 +	BaseStringTable(unsigned int init_size);
   22.84 +	~BaseStringTable();
   22.85 +public:
   22.86 +	/** 
   22.87 +	 * Adds a string to the string table and returns its index.
   22.88 +	 */
   22.89 +	int AddString(const char *string);
   22.90 +
   22.91 +	/**
   22.92 +	 * Given an index into the string table, returns the associated string.
   22.93 +	 */
   22.94 +	inline const char *GetString(int str)
   22.95 +	{
   22.96 +		return (const char *)m_table.GetAddress(str);
   22.97 +	}
   22.98 +
   22.99 +	/**
  22.100 +	 * Scraps the string table.  For caching purposes, the memory
  22.101 +	 * is not freed, however subsequent calls to AddString() will 
  22.102 +	 * begin at the first index again.
  22.103 +	 */
  22.104 +	void Reset();
  22.105 +
  22.106 +	/**
  22.107 +	 * Returns the parent BaseMemTable that this string table uses.
  22.108 +	 */
  22.109 +	inline BaseMemTable *GetMemTable()
  22.110 +	{
  22.111 +		return &m_table;
  22.112 +	}
  22.113 +private:
  22.114 +	BaseMemTable m_table;
  22.115 +};
  22.116 +
  22.117 +#endif //_INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_