core/systems/PluginInfoDatabase.cpp
author David Anderson <dvander@alliedmods.net>
Wed Dec 13 11:10:02 2006 +0000 (2006-12-13)
changeset 205 b766f3af24bd
parent 203 c7f86f9e6f60
child 211 4c77142eaf36
permissions -rw-r--r--
Fixed bug with info database not reading back table properly
     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 }
    49 
    50 SMCParseResult CPluginInfoDatabase::MakeError(const char *fmt, ...)
    51 {
    52 	char buffer[512];
    53 	va_list ap;
    54 
    55 	va_start(ap, fmt);
    56 	vsnprintf(buffer, sizeof(buffer), fmt, ap);
    57 	va_end(ap);
    58 
    59 	m_errmsg = m_strtab->AddString(buffer);
    60 
    61 	return SMCParse_HaltFail;
    62 }
    63 
    64 unsigned int CPluginInfoDatabase::GetSettingsNum()
    65 {
    66 	return m_infodb_count;
    67 }
    68 
    69 PluginSettings *CPluginInfoDatabase::GetSettingsIfMatch(unsigned int index, const char *filename)
    70 {
    71 	BaseMemTable *memtab = m_strtab->GetMemTable();
    72 	int *table = (int *)memtab->GetAddress(m_infodb);
    73 
    74 	if (!table || index >= m_infodb_count)
    75 	{
    76 		return NULL;
    77 	}
    78 
    79 	PluginSettings *plugin = (PluginSettings *)memtab->GetAddress(table[index]);
    80 
    81 	const char *name = m_strtab->GetString(plugin->name);
    82 
    83 	if (!name)
    84 	{
    85 		return NULL;
    86 	}
    87 
    88 	if (!g_PluginMngr.TestAliasMatch(name, filename))
    89 	{
    90 		return NULL;
    91 	}
    92 
    93 	return plugin;
    94 }
    95 
    96 void CPluginInfoDatabase::GetOptionsForPlugin(PluginSettings *settings, unsigned int opt_num, const char **key, const char **val)
    97 {
    98 	PluginOpts *table = (PluginOpts *)m_strtab->GetMemTable()->GetAddress(settings->optarray);
    99 	if (!table)
   100 	{
   101 		*key = NULL;
   102 		*val = NULL;
   103 		return;
   104 	}
   105 
   106 	if (opt_num >= settings->opts_num)
   107 	{
   108 		*key = NULL;
   109 		*val = NULL;
   110 		return;
   111 	}
   112 
   113 	*key = m_strtab->GetString(table[opt_num].key);
   114 	*val = m_strtab->GetString(table[opt_num].val);
   115 }
   116 
   117 SMCParseResult CPluginInfoDatabase::ReadSMC_KeyValue(const char *key, 
   118 													 const char *value, 
   119 													 bool key_quotes, 
   120 													 bool value_quotes)
   121 {
   122 	if (cur_plugin != -1)
   123 	{
   124 		PluginSettings *plugin = (PluginSettings *)m_strtab->GetMemTable()->GetAddress(cur_plugin);
   125 		if (!in_options)
   126 		{
   127 			if (strcmp(key, "pause") == 0)
   128 			{
   129 				if (strcasecmp(value, "yes") == 0)
   130 				{
   131 					plugin->pause_val = true;
   132 				} else {
   133 					plugin->pause_val = false;
   134 				}
   135 			} else if (strcmp(key, "lifetime") == 0) {
   136 				if (strcasecmp(value, "private") == 0)
   137 				{
   138 					plugin->type_val = PluginType_Private;
   139 				} else if (strcasecmp(value, "mapsync") == 0) {
   140 					plugin->type_val = PluginType_MapUpdated;
   141 				} else if (strcasecmp(value, "maponly") == 0) {
   142 					plugin->type_val = PluginType_MapOnly;
   143 				} else if (strcasecmp(value, "global") == 0) {
   144 					plugin->type_val = PluginType_Global;
   145 				} else {
   146 					return MakeError("Unknown value for key \"lifetime\": \"%s\"", value);
   147 				}
   148 			} else {
   149 				return MakeError("Unknown property key: \"%s\"", key);
   150 			}
   151 		} else {
   152 			/* Cache every option, valid or not */
   153 			int keyidx = m_strtab->AddString(key);
   154 			int validx = m_strtab->AddString(value);
   155 			PluginOpts *table;
   156 			BaseMemTable *memtab = m_strtab->GetMemTable();
   157 			if (plugin->opts_num + 1 > plugin->opts_size)
   158 			{
   159 				unsigned int oldsize = plugin->opts_size;
   160 				if (oldsize == 0)
   161 				{
   162 					//right now we don't have many
   163 					plugin->opts_size = 2;
   164 				} else {
   165 					plugin->opts_size *= 2;
   166 				}
   167 				int newidx = memtab->CreateMem(plugin->opts_size * sizeof(PluginOpts), (void **)&table);
   168 				if (plugin->optarray != -1)
   169 				{
   170 					void *oldtable = memtab->GetAddress(plugin->optarray);
   171 					memcpy(table, oldtable, oldsize * sizeof(PluginOpts));
   172 				}
   173 				plugin->optarray = newidx;
   174 			} else {
   175 				table = (PluginOpts *)memtab->GetAddress(plugin->optarray);
   176 			}
   177 			PluginOpts *opt = &table[plugin->opts_num++];
   178 			opt->key = keyidx;
   179 			opt->val = validx;
   180 		}
   181 	} else if (in_plugins) {
   182 		return MakeError("Unknown property key: \"%s\"", key);
   183 	} else {
   184 		/* Ignore anything we don't know about! */
   185 	}
   186 
   187 	return SMCParse_Continue;
   188 }
   189 
   190 SMCParseResult CPluginInfoDatabase::ReadSMC_LeavingSection()
   191 {
   192 	if (in_plugins)
   193 	{
   194 		if (cur_plugin != -1)
   195 		{
   196 			if (in_options)
   197 			{
   198 				in_options = false;
   199 			} else {
   200 				/* If the plugin is ending, add it to the table */
   201 				BaseMemTable *memtab = m_strtab->GetMemTable();
   202 				int *table;
   203 				if (m_infodb_count + 1 > m_infodb_size)
   204 				{
   205 					unsigned int oldsize = m_infodb_size;
   206 					if (!m_infodb_size)
   207 					{
   208 						m_infodb_size = 8;
   209 					} else {
   210 						m_infodb_size *= 2;
   211 					}
   212 					int newidx = memtab->CreateMem(m_infodb_size, (void **)&table);
   213 					if (m_infodb != -1)
   214 					{
   215 						void *oldtable = (int *)memtab->GetAddress(m_infodb);
   216 						memcpy(table, oldtable, oldsize * sizeof(int));
   217 					}
   218 					m_infodb = newidx;
   219 				} else {
   220 					table = (int *)memtab->GetAddress(m_infodb);
   221 				}
   222 				/* Assign to table and scrap the current plugin */
   223 				table[m_infodb_count++] = cur_plugin;
   224 				cur_plugin = -1;
   225 			}
   226 		} else {
   227 			in_plugins = false;
   228 		}
   229 	}
   230 
   231 	return SMCParse_Continue;
   232 }
   233 
   234 SMCParseResult CPluginInfoDatabase::ReadSMC_NewSection(const char *name, bool opt_quotes)
   235 {
   236 	if (!in_plugins)
   237 	{
   238 		/* If we're not in the main Plugins section, and we don't get it for the name, error out */
   239 		if (strcmp(name, "Plugins") != 0)
   240 		{
   241 			return MakeError("Unknown root section: \"%s\"", name);
   242 		} else {
   243 			/* Otherwise set our states */
   244 			in_plugins = true;
   245 			cur_plugin = -1;
   246 			in_options = false;
   247 		}
   248 	} else {
   249 		if (cur_plugin == -1)
   250 		{
   251 			/* If we get a plugin node and we don't have a current plugin, create a new one */
   252 			PluginSettings *plugin;
   253 			cur_plugin = m_strtab->GetMemTable()->CreateMem(sizeof(PluginSettings), (void **)&plugin);
   254 			plugin->Init();
   255 			plugin->name = m_strtab->AddString(name);
   256 			in_options = false;
   257 		} else {
   258 			if (!in_options && strcmp(name, "Options") == 0)
   259 			{
   260 				in_options = true;
   261 			} else {
   262 				return MakeError("Unknown plugin sub-section: \"%s\"", name);
   263 			}
   264 		}
   265 	}
   266 
   267 	return SMCParse_Continue;
   268 }