extensions/structs/extension.cpp
author Kyle Sanderson <kyle.leet@gmail.com>
Thu Jul 18 15:50:50 2013 -0400 (2013-07-18)
changeset 3950 d467a6526f8d
parent 2386 5700b0094285
permissions -rw-r--r--
Fixed accidental assignment in each of SDKTools and sp compiler (bug 5745, r=psychonic).
pred@2224
     1
/**
pred@2224
     2
 * vim: set ts=4 :
pred@2224
     3
 * =============================================================================
pred@2224
     4
 * SourceMod Sample Extension
pred@2224
     5
 * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
pred@2224
     6
 * =============================================================================
pred@2224
     7
 *
pred@2224
     8
 * This program is free software; you can redistribute it and/or modify it under
pred@2224
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
pred@2224
    10
 * Free Software Foundation.
pred@2224
    11
 * 
pred@2224
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
pred@2224
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
pred@2224
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
pred@2224
    15
 * details.
pred@2224
    16
 *
pred@2224
    17
 * You should have received a copy of the GNU General Public License along with
pred@2224
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
pred@2224
    19
 *
pred@2224
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
pred@2224
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
pred@2224
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
pred@2224
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
pred@2224
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
pred@2224
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
pred@2224
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
pred@2224
    27
 * or <http://www.sourcemod.net/license.php>.
pred@2224
    28
 *
pred@2224
    29
 * Version: $Id$
pred@2224
    30
 */
pred@2224
    31
pred@2224
    32
#include "extension.h"
pred@2224
    33
pred@2224
    34
/**
pred@2224
    35
 * @file extension.cpp
pred@2224
    36
 * @brief Implement extension code here.
pred@2224
    37
 */
pred@2224
    38
pred@2224
    39
Structs g_Structs;		/**< Global singleton for extension's main interface */
pred@2224
    40
pred@2224
    41
SMEXT_LINK(&g_Structs);
pred@2224
    42
pred@2224
    43
HandleType_t g_StructHandle = 0;
pred@2224
    44
StructHandler g_StructHandler;
pred@2224
    45
pred@2224
    46
IGameConfig *conf;
pred@2224
    47
pred@2224
    48
size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...)
pred@2224
    49
{
pred@2224
    50
	va_list ap;
pred@2224
    51
	va_start(ap, fmt);
pred@2224
    52
	size_t len = vsnprintf(buffer, maxlength, fmt, ap);
pred@2224
    53
	va_end(ap);
pred@2224
    54
pred@2224
    55
	if (len >= maxlength)
pred@2224
    56
	{
pred@2224
    57
		buffer[maxlength - 1] = '\0';
pred@2224
    58
		return (maxlength - 1);
pred@2224
    59
	}
pred@2224
    60
	else
pred@2224
    61
	{
pred@2224
    62
		return len;
pred@2224
    63
	}
pred@2224
    64
}
pred@2224
    65
pred@2224
    66
void Structs::SDK_OnAllLoaded()
pred@2224
    67
{
pred@2224
    68
	g_StructHandle = handlesys->CreateType("Struct", 
pred@2224
    69
		&g_StructHandler, 
pred@2224
    70
		0, 
pred@2224
    71
		NULL, 
pred@2224
    72
		NULL, 
pred@2224
    73
		myself->GetIdentity(), 
pred@2224
    74
		NULL);
pred@2224
    75
pred@2224
    76
	gameconfs->AddUserConfigHook("Structs", this);
pred@2224
    77
pred@2224
    78
	sharesys->AddNatives(myself, MyNatives);
pred@2224
    79
pred@2224
    80
pred@2224
    81
	char error[100];
dvander@2386
    82
	if (!gameconfs->LoadGameConfigFile("structs.gamedata", &conf, error, sizeof(error)))
pred@2224
    83
	{
pred@2224
    84
		g_pSM->LogError(myself, "Parsing Failed!");
pred@2224
    85
	}
pred@2224
    86
}
pred@2224
    87
pred@2224
    88
void Structs::SDK_OnUnload()
pred@2224
    89
{
pred@2224
    90
	handlesys->RemoveType(g_StructHandle, myself->GetIdentity());
dvander@2385
    91
	gameconfs->CloseGameConfigFile(conf);
pred@2224
    92
	gameconfs->RemoveUserConfigHook("Structs", this);
pred@2224
    93
}
pred@2224
    94
pred@2224
    95
bool Structs::SDK_OnLoad( char *error, size_t maxlength, bool late )
pred@2224
    96
{
pred@2224
    97
	sharesys->AddInterface(myself, &g_StructManager);
pred@2224
    98
pred@2224
    99
	m_typeLookup.insert("int", Member_Int32);
pred@2224
   100
	m_typeLookup.insert("int*", Member_Int32Pointer);
pred@2224
   101
	m_typeLookup.insert("float", Member_Float);
pred@2224
   102
	m_typeLookup.insert("float*", Member_FloatPointer);
pred@2224
   103
	m_typeLookup.insert("char", Member_Char);
pred@2224
   104
	m_typeLookup.insert("char*", Member_CharPointer);
pred@2224
   105
	m_typeLookup.insert("Vector", Member_Vector);
pred@2224
   106
	m_typeLookup.insert("Vector*", Member_VectorPointer);
pred@2224
   107
	m_typeLookup.insert("ent", Member_EHandle);
pred@2224
   108
	m_typeLookup.insert("ent*", Member_EHandlePointer);
pred@2224
   109
pred@2224
   110
	return true;
pred@2224
   111
}
pred@2224
   112
pred@2224
   113
void Structs::ReadSMC_ParseStart()
pred@2224
   114
{
pred@2224
   115
	m_bInStruct = false;
pred@2224
   116
	m_currentStruct = NULL;
pred@2224
   117
	m_bInMember = false;
pred@2224
   118
	m_currentMember = NULL;
pred@2224
   119
}
pred@2224
   120
pred@2224
   121
SourceMod::SMCResult Structs::ReadSMC_NewSection( const SMCStates *states, const char *name )
pred@2224
   122
{
pred@2224
   123
	if (!m_bInStruct)
pred@2224
   124
	{
pred@2224
   125
		m_currentStruct = new StructInfo();
pred@2224
   126
		UTIL_Format(m_currentStruct->name, sizeof(m_currentStruct->name), "%s", name);
pred@2224
   127
		m_bInStruct = true;
pred@2224
   128
pred@2224
   129
		return SMCResult_Continue;
pred@2224
   130
	}
pred@2224
   131
pred@2224
   132
	if (!m_bInMember)
pred@2224
   133
	{
pred@2224
   134
		m_bInMember = true;
pred@2224
   135
		m_currentMember = new MemberInfo();
pred@2224
   136
		UTIL_Format(m_currentMember->name, sizeof(m_currentMember->name), "%s", name);
pred@2224
   137
pred@2224
   138
		return SMCResult_Continue;
pred@2224
   139
	}
pred@2224
   140
pred@2224
   141
	g_pSM->LogMessage(myself, "Cannot nest within a member: line: %i col: %i", states->line, states->col);
pred@2224
   142
pred@2224
   143
	return SMCResult_HaltFail;
pred@2224
   144
}
pred@2224
   145
pred@2224
   146
SourceMod::SMCResult Structs::ReadSMC_KeyValue( const SMCStates *states, const char *key, const char *value )
pred@2224
   147
{
pred@2224
   148
	if (!m_bInStruct)
pred@2224
   149
	{
pred@2224
   150
		//hrm..
pred@2224
   151
		g_pSM->LogMessage(myself, "Unknown value %s: line: %i col: %i", key, states->line, states->col);
pred@2224
   152
		return SMCResult_HaltFail;
pred@2224
   153
	}
pred@2224
   154
pred@2224
   155
	if (m_bInMember)
pred@2224
   156
	{
pred@2224
   157
		if (strcmp(key, "type") == 0)
pred@2224
   158
		{
pred@2224
   159
			MemberType *pType = m_typeLookup.retrieve(value);
pred@2224
   160
pred@2224
   161
			if (pType == NULL)
pred@2224
   162
			{
pred@2224
   163
				//invalid type
pred@2224
   164
				g_pSM->LogMessage(myself, "Invalid Type: line: %i col: %i", states->line, states->col);
pred@2224
   165
				return SMCResult_HaltFail;
pred@2224
   166
			}
pred@2224
   167
pred@2224
   168
			/* Note all 'int' types are assumed to be 32bit for the moment */
pred@2224
   169
			m_currentMember->type = *pType;
pred@2224
   170
		}
pred@2224
   171
		else if (strcmp(key, "size") == 0)
pred@2224
   172
		{
pred@2224
   173
			m_currentMember->size = atoi(value);
pred@2224
   174
		}
pred@2224
   175
#if defined WIN32
pred@2224
   176
		else if (strcmp(key, "windows") == 0)
pred@2224
   177
#else
pred@2224
   178
		else if (strcmp(key, "linux") == 0)
pred@2224
   179
#endif
pred@2224
   180
		{
pred@2224
   181
			m_currentMember->offset = atoi(value);
pred@2224
   182
		}
pred@2224
   183
	}
pred@2224
   184
	else
pred@2224
   185
	{
pred@2224
   186
		if (strcmp(key, "size") == 0)
pred@2224
   187
		{
pred@2224
   188
			m_currentStruct->size = atoi(value);
pred@2224
   189
		}
pred@2224
   190
	}
pred@2224
   191
pred@2224
   192
	return SMCResult_Continue;
pred@2224
   193
}
pred@2224
   194
pred@2224
   195
SourceMod::SMCResult Structs::ReadSMC_LeavingSection( const SMCStates *states )
pred@2224
   196
{
pred@2224
   197
	if (m_bInMember)
pred@2224
   198
	{
pred@2224
   199
		/** Check for missing or invalid parameters */
pred@2224
   200
		if (m_currentMember->type == Member_Unknown || m_currentMember->offset == -1)
pred@2224
   201
		{
pred@2224
   202
			g_pSM->LogMessage(myself, "Missing offset or type: line: %i col: %i", states->line, states->col);
pred@2224
   203
			return SMCResult_HaltFail;
pred@2224
   204
		}
pred@2224
   205
pred@2224
   206
		if (m_currentMember->size == -1)
pred@2224
   207
		{
pred@2224
   208
			switch (m_currentMember->type)
pred@2224
   209
			{
pred@2224
   210
				case Member_Float:
pred@2224
   211
				case Member_FloatPointer:
pred@2224
   212
				case Member_Vector:
pred@2224
   213
				case Member_VectorPointer:
pred@2224
   214
				case Member_EHandle:
pred@2224
   215
				case Member_EHandlePointer:
pred@2224
   216
				{
pred@2224
   217
					break;
pred@2224
   218
				}
pred@2224
   219
pred@2224
   220
				default:
pred@2224
   221
				{
pred@2224
   222
					g_pSM->LogMessage(myself, "Missing size: line: %i col: %i", states->line, states->col);
pred@2224
   223
					return SMCResult_HaltFail;
pred@2224
   224
				}
pred@2224
   225
			}
pred@2224
   226
		}
pred@2224
   227
pred@2224
   228
		/* Work out the int size */
pred@2224
   229
		if (m_currentMember->type == Member_Int32)
pred@2224
   230
		{
pred@2224
   231
			if (m_currentMember->size == 1)
pred@2224
   232
			{
pred@2224
   233
				m_currentMember->type = Member_Int8;
pred@2224
   234
			} 
pred@2224
   235
			else if (m_currentMember->size == 2)
pred@2224
   236
			{
pred@2224
   237
				m_currentMember->type = Member_Int16;
pred@2224
   238
			} 
pred@2224
   239
			else if (m_currentMember->size == 4)
pred@2224
   240
			{
pred@2224
   241
				m_currentMember->type = Member_Int32;
pred@2224
   242
			} 
pred@2224
   243
			else
pred@2224
   244
			{
pred@2224
   245
				g_pSM->LogMessage(myself, "Invalid int size %i: line: %i col: %i", m_currentMember->size, states->line, states->col);
pred@2224
   246
				return SMCResult_HaltFail;
pred@2224
   247
			}
pred@2224
   248
pred@2224
   249
		} 
pred@2224
   250
		else if (m_currentMember->type == Member_Int32)
pred@2224
   251
		{
pred@2224
   252
			if (m_currentMember->size == 1)
pred@2224
   253
			{
pred@2224
   254
				m_currentMember->type = Member_Int8Pointer;
pred@2224
   255
			} 
pred@2224
   256
			else if (m_currentMember->size == 2)
pred@2224
   257
			{
pred@2224
   258
				m_currentMember->type = Member_Int16Pointer;
pred@2224
   259
			} 
pred@2224
   260
			else if (m_currentMember->size == 4)
pred@2224
   261
			{
pred@2224
   262
				m_currentMember->type = Member_Int32Pointer;
pred@2224
   263
			} 
pred@2224
   264
			else
pred@2224
   265
			{
pred@2224
   266
				g_pSM->LogMessage(myself, "Invalid int size %i: line: %i col: %i", m_currentMember->size, states->line, states->col);
pred@2224
   267
				return SMCResult_HaltFail;
pred@2224
   268
			}
pred@2224
   269
		}
pred@2224
   270
pred@2224
   271
		m_currentStruct->AddMember(m_currentMember->name, m_currentMember);
pred@2224
   272
pred@2224
   273
		m_bInMember = false;
pred@2224
   274
		m_currentMember = NULL;
pred@2224
   275
pred@2224
   276
		return SMCResult_Continue;
pred@2224
   277
	}
pred@2224
   278
pred@2224
   279
	g_StructManager.AddStruct(m_currentStruct->name, m_currentStruct);
pred@2224
   280
pred@2224
   281
	m_bInStruct = false;
pred@2224
   282
	m_currentStruct = NULL;
pred@2224
   283
pred@2224
   284
	return SMCResult_Continue;
pred@2224
   285
}