core/systems/PluginInfoDatabase.cpp
author Scott Ehlert <ds@alliedmods.net>
Thu Mar 22 21:50:20 2007 +0000 (2007-03-22)
changeset 653 ef60870067ff
parent 370 d3a484f98f6d
child 1231 17badaf66ce4
permissions -rw-r--r--
More consistency of some sort...

Oh god, what has possessed me to do this?
     1 /**
     2  * vim: set ts=4 :
     3  * ===============================================================
     4  * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
     5  * ===============================================================
     6  *
     7  * This file is not open source and may not be copied without explicit
     8  * written permission of AlliedModders LLC.  This file may not be redistributed 
     9  * in whole or significant part.
    10  * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
    11  *
    12  * Version: $Id$
    13  */
    14 
    15 #include <stdarg.h>
    16 #include <string.h>
    17 #include "PluginInfoDatabase.h"
    18 #include "PluginSys.h"
    19 
    20 void PluginSettings::Init()
    21 {
    22 	name = -1;
    23 	pause_val = false;
    24 	type_val = PluginType_MapUpdated;
    25 	optarray = -1;
    26 	opts_num = 0;
    27 	opts_size = 0;
    28 }
    29 
    30 /**
    31  * :TODO: write the logger, make these errors log instead of being static
    32  * NOTE: once we do that, we will have to change some code to ignore sections
    33  */
    34 
    35 CPluginInfoDatabase::CPluginInfoDatabase()
    36 {
    37 	m_strtab = NULL;
    38 	m_infodb_count = 0;
    39 	m_infodb_size = 0;
    40 	m_infodb = -1;
    41 }
    42 
    43 CPluginInfoDatabase::~CPluginInfoDatabase()
    44 {
    45 	delete m_strtab;
    46 }
    47 
    48 void CPluginInfoDatabase::ReadSMC_ParseStart()
    49 {
    50 	/* Create or reset our string table */
    51 	if (m_strtab)
    52 	{
    53 		m_strtab->Reset();
    54 	} else {
    55 		m_strtab = new BaseStringTable(1024);
    56 	}
    57 
    58 	/* Set our internal states to the beginning */
    59 	in_plugins = false;
    60 	cur_plugin = -1;
    61 	in_options = false;
    62 	m_infodb_size = 0;
    63 	m_infodb_count = 0;
    64 	m_infodb = -1;
    65 }
    66 
    67 SMCParseResult CPluginInfoDatabase::MakeError(const char *fmt, ...)
    68 {
    69 	char buffer[512];
    70 	va_list ap;
    71 
    72 	va_start(ap, fmt);
    73 	vsnprintf(buffer, sizeof(buffer), fmt, ap);
    74 	va_end(ap);
    75 
    76 	m_errmsg = m_strtab->AddString(buffer);
    77 
    78 	return SMCParse_HaltFail;
    79 }
    80 
    81 unsigned int CPluginInfoDatabase::GetSettingsNum()
    82 {
    83 	return m_infodb_count;
    84 }
    85 
    86 PluginSettings *CPluginInfoDatabase::GetSettingsIfMatch(unsigned int index, const char *filename)
    87 {
    88 	BaseMemTable *memtab = m_strtab->GetMemTable();
    89 	int *table = (int *)memtab->GetAddress(m_infodb);
    90 
    91 	if (!table || index >= m_infodb_count)
    92 	{
    93 		return NULL;
    94 	}
    95 
    96 	PluginSettings *plugin = (PluginSettings *)memtab->GetAddress(table[index]);
    97 
    98 	const char *name = m_strtab->GetString(plugin->name);
    99 
   100 	if (!name)
   101 	{
   102 		return NULL;
   103 	}
   104 
   105 	if (!g_PluginSys.TestAliasMatch(name, filename))
   106 	{
   107 		return NULL;
   108 	}
   109 
   110 	return plugin;
   111 }
   112 
   113 void CPluginInfoDatabase::GetOptionsForPlugin(PluginSettings *settings, unsigned int opt_num, const char **key, const char **val)
   114 {
   115 	PluginOpts *table = (PluginOpts *)m_strtab->GetMemTable()->GetAddress(settings->optarray);
   116 	if (!table)
   117 	{
   118 		*key = NULL;
   119 		*val = NULL;
   120 		return;
   121 	}
   122 
   123 	if (opt_num >= settings->opts_num)
   124 	{
   125 		*key = NULL;
   126 		*val = NULL;
   127 		return;
   128 	}
   129 
   130 	*key = m_strtab->GetString(table[opt_num].key);
   131 	*val = m_strtab->GetString(table[opt_num].val);
   132 }
   133 
   134 SMCParseResult CPluginInfoDatabase::ReadSMC_KeyValue(const char *key, 
   135 													 const char *value, 
   136 													 bool key_quotes, 
   137 													 bool value_quotes)
   138 {
   139 	if (cur_plugin != -1)
   140 	{
   141 		PluginSettings *plugin = (PluginSettings *)m_strtab->GetMemTable()->GetAddress(cur_plugin);
   142 		if (!in_options)
   143 		{
   144 			if (strcmp(key, "pause") == 0)
   145 			{
   146 				if (strcasecmp(value, "yes") == 0)
   147 				{
   148 					plugin->pause_val = true;
   149 				} else {
   150 					plugin->pause_val = false;
   151 				}
   152 			} else if (strcmp(key, "lifetime") == 0) {
   153 				if (strcasecmp(value, "private") == 0)
   154 				{
   155 					plugin->type_val = PluginType_Private;
   156 				} else if (strcasecmp(value, "mapsync") == 0) {
   157 					plugin->type_val = PluginType_MapUpdated;
   158 				} else if (strcasecmp(value, "maponly") == 0) {
   159 					plugin->type_val = PluginType_MapOnly;
   160 				} else if (strcasecmp(value, "global") == 0) {
   161 					plugin->type_val = PluginType_Global;
   162 				} else {
   163 					return MakeError("Unknown value for key \"lifetime\": \"%s\"", value);
   164 				}
   165 			} else {
   166 				return MakeError("Unknown property key: \"%s\"", key);
   167 			}
   168 		} else {
   169 			/* Cache every option, valid or not */
   170 			int keyidx = m_strtab->AddString(key);
   171 			int validx = m_strtab->AddString(value);
   172 			PluginOpts *table;
   173 			BaseMemTable *memtab = m_strtab->GetMemTable();
   174 			if (plugin->opts_num + 1 > plugin->opts_size)
   175 			{
   176 				unsigned int oldsize = plugin->opts_size;
   177 				if (oldsize == 0)
   178 				{
   179 					//right now we don't have many
   180 					plugin->opts_size = 2;
   181 				} else {
   182 					plugin->opts_size *= 2;
   183 				}
   184 				int newidx = memtab->CreateMem(plugin->opts_size * sizeof(PluginOpts), (void **)&table);
   185 				/* in case it resized */
   186 				plugin = (PluginSettings *)memtab->GetAddress(cur_plugin);
   187 				if (plugin->optarray != -1)
   188 				{
   189 					void *oldtable = memtab->GetAddress(plugin->optarray);
   190 					memcpy(table, oldtable, oldsize * sizeof(PluginOpts));
   191 				}
   192 				plugin->optarray = newidx;
   193 			} else {
   194 				table = (PluginOpts *)memtab->GetAddress(plugin->optarray);
   195 			}
   196 			PluginOpts *opt = &table[plugin->opts_num++];
   197 			opt->key = keyidx;
   198 			opt->val = validx;
   199 		}
   200 	} else if (in_plugins) {
   201 		return MakeError("Unknown property key: \"%s\"", key);
   202 	} else {
   203 		/* Ignore anything we don't know about! */
   204 	}
   205 
   206 	return SMCParse_Continue;
   207 }
   208 
   209 SMCParseResult CPluginInfoDatabase::ReadSMC_LeavingSection()
   210 {
   211 	if (in_plugins)
   212 	{
   213 		if (cur_plugin != -1)
   214 		{
   215 			if (in_options)
   216 			{
   217 				in_options = false;
   218 			} else {
   219 				/* If the plugin is ending, add it to the table */
   220 				BaseMemTable *memtab = m_strtab->GetMemTable();
   221 				int *table;
   222 				if (m_infodb_count + 1 > m_infodb_size)
   223 				{
   224 					unsigned int oldsize = m_infodb_size;
   225 					if (!m_infodb_size)
   226 					{
   227 						m_infodb_size = 8;
   228 					} else {
   229 						m_infodb_size *= 2;
   230 					}
   231 					int newidx = memtab->CreateMem(m_infodb_size, (void **)&table);
   232 					if (m_infodb != -1)
   233 					{
   234 						void *oldtable = (int *)memtab->GetAddress(m_infodb);
   235 						memcpy(table, oldtable, oldsize * sizeof(int));
   236 					}
   237 					m_infodb = newidx;
   238 				} else {
   239 					table = (int *)memtab->GetAddress(m_infodb);
   240 				}
   241 				/* Assign to table and scrap the current plugin */
   242 				table[m_infodb_count++] = cur_plugin;
   243 				cur_plugin = -1;
   244 			}
   245 		} else {
   246 			in_plugins = false;
   247 		}
   248 	}
   249 
   250 	return SMCParse_Continue;
   251 }
   252 
   253 SMCParseResult CPluginInfoDatabase::ReadSMC_NewSection(const char *name, bool opt_quotes)
   254 {
   255 	if (!in_plugins)
   256 	{
   257 		/* If we're not in the main Plugins section, and we don't get it for the name, error out */
   258 		if (strcmp(name, "Plugins") != 0)
   259 		{
   260 			return MakeError("Unknown root section: \"%s\"", name);
   261 		} else {
   262 			/* Otherwise set our states */
   263 			in_plugins = true;
   264 			cur_plugin = -1;
   265 			in_options = false;
   266 		}
   267 	} else {
   268 		if (cur_plugin == -1)
   269 		{
   270 			/* If we get a plugin node and we don't have a current plugin, create a new one */
   271 			PluginSettings *plugin;
   272 			cur_plugin = m_strtab->GetMemTable()->CreateMem(sizeof(PluginSettings), (void **)&plugin);
   273 			plugin->Init();
   274 			plugin->name = m_strtab->AddString(name);
   275 			in_options = false;
   276 		} else {
   277 			if (!in_options && strcmp(name, "Options") == 0)
   278 			{
   279 				in_options = true;
   280 			} else {
   281 				return MakeError("Unknown plugin sub-section: \"%s\"", name);
   282 			}
   283 		}
   284 	}
   285 
   286 	return SMCParse_Continue;
   287 }