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