1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/core/systems/PluginInfoDatabase.cpp Sun Dec 10 09:19:59 2006 +0000
1.3 @@ -0,0 +1,266 @@
1.4 +#include <stdarg.h>
1.5 +#include <string.h>
1.6 +#include "PluginInfoDatabase.h"
1.7 +#include "PluginSys.h"
1.8 +
1.9 +void PluginSettings::Init()
1.10 +{
1.11 + name = -1;
1.12 + pause_val = false;
1.13 + type_val = PluginType_MapUpdated;
1.14 + optarray = -1;
1.15 + opts_num = 0;
1.16 + opts_size = 0;
1.17 +}
1.18 +
1.19 +/**
1.20 + * :TODO: write the logger, make these errors log instead of being static
1.21 + * NOTE: once we do that, we will have to change some code to ignore sections
1.22 + */
1.23 +
1.24 +CPluginInfoDatabase::CPluginInfoDatabase()
1.25 +{
1.26 + m_strtab = NULL;
1.27 + m_infodb_count = 0;
1.28 + m_infodb_size = 0;
1.29 + m_infodb = -1;
1.30 +}
1.31 +
1.32 +CPluginInfoDatabase::~CPluginInfoDatabase()
1.33 +{
1.34 + delete m_strtab;
1.35 +}
1.36 +
1.37 +void CPluginInfoDatabase::ReadSMC_ParseStart()
1.38 +{
1.39 + /* Create or reset our string table */
1.40 + if (m_strtab)
1.41 + {
1.42 + m_strtab->Reset();
1.43 + } else {
1.44 + m_strtab = new BaseStringTable(1024);
1.45 + }
1.46 +
1.47 + /* Set our internal states to the beginning */
1.48 + in_plugins = false;
1.49 + cur_plugin = -1;
1.50 + in_options = false;
1.51 +}
1.52 +
1.53 +SMCParseResult CPluginInfoDatabase::MakeError(const char *fmt, ...)
1.54 +{
1.55 + char buffer[512];
1.56 + va_list ap;
1.57 +
1.58 + va_start(ap, fmt);
1.59 + vsnprintf(buffer, sizeof(buffer), fmt, ap);
1.60 + va_end(ap);
1.61 +
1.62 + m_errmsg = m_strtab->AddString(buffer);
1.63 +
1.64 + return SMCParse_HaltFail;
1.65 +}
1.66 +
1.67 +unsigned int CPluginInfoDatabase::GetSettingsNum()
1.68 +{
1.69 + return m_infodb_count;
1.70 +}
1.71 +
1.72 +PluginSettings *CPluginInfoDatabase::GetSettingsIfMatch(unsigned int index, const char *filename)
1.73 +{
1.74 + BaseMemTable *memtab = m_strtab->GetMemTable();
1.75 + PluginSettings *table = (PluginSettings *)memtab->GetAddress(m_infodb);
1.76 +
1.77 + if (!table || index >= m_infodb_count)
1.78 + {
1.79 + return NULL;
1.80 + }
1.81 +
1.82 + const char *name = m_strtab->GetString(table[index].name);
1.83 +
1.84 + if (!name)
1.85 + {
1.86 + return NULL;
1.87 + }
1.88 +
1.89 + if (!g_PluginMngr.TestAliasMatch(name, filename))
1.90 + {
1.91 + return NULL;
1.92 + }
1.93 +
1.94 + return &table[index];
1.95 +}
1.96 +
1.97 +void CPluginInfoDatabase::GetOptionsForPlugin(PluginSettings *settings, unsigned int opt_num, const char **key, const char **val)
1.98 +{
1.99 + PluginOpts *table = (PluginOpts *)m_strtab->GetMemTable()->GetAddress(settings->optarray);
1.100 + if (!table)
1.101 + {
1.102 + *key = NULL;
1.103 + *val = NULL;
1.104 + return;
1.105 + }
1.106 +
1.107 + if (opt_num >= settings->opts_num)
1.108 + {
1.109 + *key = NULL;
1.110 + *val = NULL;
1.111 + return;
1.112 + }
1.113 +
1.114 + *key = m_strtab->GetString(table[opt_num].key);
1.115 + *val = m_strtab->GetString(table[opt_num].val);
1.116 +}
1.117 +
1.118 +SMCParseResult CPluginInfoDatabase::ReadSMC_KeyValue(const char *key,
1.119 + const char *value,
1.120 + bool key_quotes,
1.121 + bool value_quotes)
1.122 +{
1.123 + if (cur_plugin != -1)
1.124 + {
1.125 + PluginSettings *plugin = (PluginSettings *)m_strtab->GetMemTable()->GetAddress(cur_plugin);
1.126 + if (!in_options)
1.127 + {
1.128 + if (strcmp(key, "pause") == 0)
1.129 + {
1.130 + if (strcasecmp(value, "yes") == 0)
1.131 + {
1.132 + plugin->pause_val = true;
1.133 + } else {
1.134 + plugin->pause_val = false;
1.135 + }
1.136 + } else if (strcmp(key, "lifetime") == 0) {
1.137 + if (strcasecmp(value, "private") == 0)
1.138 + {
1.139 + plugin->type_val = PluginType_Private;
1.140 + } else if (strcasecmp(value, "mapsync") == 0) {
1.141 + plugin->type_val = PluginType_MapUpdated;
1.142 + } else if (strcasecmp(value, "maponly") == 0) {
1.143 + plugin->type_val = PluginType_MapOnly;
1.144 + } else if (strcasecmp(value, "global") == 0) {
1.145 + plugin->type_val = PluginType_Global;
1.146 + } else {
1.147 + return MakeError("Unknown value for key \"lifetime\": \"%s\"", value);
1.148 + }
1.149 + } else {
1.150 + return MakeError("Unknown property key: \"%s\"", key);
1.151 + }
1.152 + } else {
1.153 + /* Cache every option, valid or not */
1.154 + int keyidx = m_strtab->AddString(key);
1.155 + int validx = m_strtab->AddString(value);
1.156 + PluginOpts *table;
1.157 + BaseMemTable *memtab = m_strtab->GetMemTable();
1.158 + if (plugin->opts_num + 1 > plugin->opts_size)
1.159 + {
1.160 + unsigned int oldsize = plugin->opts_size;
1.161 + if (oldsize == 0)
1.162 + {
1.163 + //right now we don't have many
1.164 + plugin->opts_size = 2;
1.165 + } else {
1.166 + plugin->opts_size *= 2;
1.167 + }
1.168 + int newidx = memtab->CreateMem(plugin->opts_size * sizeof(PluginOpts), (void **)&table);
1.169 + if (plugin->optarray != -1)
1.170 + {
1.171 + void *oldtable = memtab->GetAddress(plugin->optarray);
1.172 + memcpy(table, oldtable, oldsize * sizeof(PluginOpts));
1.173 + }
1.174 + plugin->optarray = newidx;
1.175 + } else {
1.176 + table = (PluginOpts *)memtab->GetAddress(plugin->optarray);
1.177 + }
1.178 + PluginOpts *opt = &table[plugin->opts_num++];
1.179 + opt->key = keyidx;
1.180 + opt->val = validx;
1.181 + }
1.182 + } else if (in_plugins) {
1.183 + return MakeError("Unknown property key: \"%s\"", key);
1.184 + } else {
1.185 + /* Ignore anything we don't know about! */
1.186 + }
1.187 +
1.188 + return SMCParse_Continue;
1.189 +}
1.190 +
1.191 +SMCParseResult CPluginInfoDatabase::ReadSMC_LeavingSection()
1.192 +{
1.193 + if (in_plugins)
1.194 + {
1.195 + if (cur_plugin == -1)
1.196 + {
1.197 + if (in_options)
1.198 + {
1.199 + in_options = false;
1.200 + } else {
1.201 + /* If the plugin is ending, add it to the table */
1.202 + BaseMemTable *memtab = m_strtab->GetMemTable();
1.203 + int *table;
1.204 + if (m_infodb_count + 1 > m_infodb_size)
1.205 + {
1.206 + unsigned int oldsize = m_infodb_size;
1.207 + if (!m_infodb_size)
1.208 + {
1.209 + m_infodb_size = 8;
1.210 + } else {
1.211 + m_infodb_size *= 2;
1.212 + }
1.213 + int newidx = memtab->CreateMem(m_infodb_size, (void **)&table);
1.214 + if (m_infodb != -1)
1.215 + {
1.216 + void *oldtable = (int *)memtab->GetAddress(m_infodb);
1.217 + memcpy(table, oldtable, oldsize * sizeof(int));
1.218 + }
1.219 + m_infodb = newidx;
1.220 + } else {
1.221 + table = (int *)memtab->GetAddress(m_infodb);
1.222 + }
1.223 + /* Assign to table and scrap the current plugin */
1.224 + table[m_infodb_count++] = cur_plugin;
1.225 + cur_plugin = -1;
1.226 + }
1.227 + } else {
1.228 + in_plugins = false;
1.229 + }
1.230 + }
1.231 +
1.232 + return SMCParse_Continue;
1.233 +}
1.234 +
1.235 +SMCParseResult CPluginInfoDatabase::ReadSMC_NewSection(const char *name, bool opt_quotes)
1.236 +{
1.237 + if (!in_plugins)
1.238 + {
1.239 + /* If we're not in the main Plugins section, and we don't get it for the name, error out */
1.240 + if (strcmp(name, "Plugins") != 0)
1.241 + {
1.242 + return MakeError("Unknown root section: \"%s\"", name);
1.243 + } else {
1.244 + /* Otherwise set our states */
1.245 + in_plugins = true;
1.246 + cur_plugin = -1;
1.247 + in_options = false;
1.248 + }
1.249 + } else {
1.250 + if (cur_plugin == -1)
1.251 + {
1.252 + /* If we get a plugin node and we don't have a current plugin, create a new one */
1.253 + PluginSettings *plugin;
1.254 + cur_plugin = m_strtab->GetMemTable()->CreateMem(sizeof(PluginSettings), (void **)&plugin);
1.255 + plugin->Init();
1.256 + plugin->name = m_strtab->AddString(name);
1.257 + in_options = false;
1.258 + } else {
1.259 + if (!in_options && strcmp(name, "Options") == 0)
1.260 + {
1.261 + in_options = true;
1.262 + } else {
1.263 + return MakeError("Unknown plugin sub-section: \"%s\"", name);
1.264 + }
1.265 + }
1.266 + }
1.267 +
1.268 + return SMCParse_Continue;
1.269 +}