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