1.1 --- a/core/systems/PluginSys.cpp Sat Dec 09 03:18:48 2006 +0000
1.2 +++ b/core/systems/PluginSys.cpp Sun Dec 10 09:19:59 2006 +0000
1.3 @@ -2,6 +2,7 @@
1.4 #include "PluginSys.h"
1.5 #include "LibrarySys.h"
1.6 #include "sourcemm_api.h"
1.7 +#include "CTextParsers.h"
1.8
1.9 CPluginManager g_PluginMngr;
1.10
1.11 @@ -288,9 +289,19 @@
1.12 * PLUGIN MANAGER *
1.13 ******************/
1.14
1.15 -void CPluginManager::RefreshOrLoadPlugins(const char *basedir)
1.16 +void CPluginManager::RefreshOrLoadPlugins(const char *config, const char *basedir)
1.17 {
1.18 - IDirectory *dir = g_LibSys.OpenDirectory(basedir);
1.19 + /* First read in the database of plugin settings */
1.20 + SMCParseError err;
1.21 + unsigned int line, col;
1.22 + if ((err=g_TextParse.ParseFile_SMC(config, &m_PluginInfo, &line, &col)) != SMCParse_Okay)
1.23 + {
1.24 + /* :TODO: log the error, don't bail out though */
1.25 + }
1.26 +
1.27 +
1.28 + //:TODO: move this to a separate recursive function and do stuff
1.29 + /*IDirectory *dir = g_LibSys.OpenDirectory(basedir);
1.30 while (dir->MoreFiles())
1.31 {
1.32 if (dir->IsEntryDirectory() && (strcmp(dir->GetEntryName(), "disabled") != 0))
1.33 @@ -300,7 +311,7 @@
1.34 RefreshOrLoadPlugins(basedir);
1.35 }
1.36 }
1.37 - g_LibSys.CloseDirectory(dir);
1.38 + g_LibSys.CloseDirectory(dir);*/
1.39 }
1.40
1.41 IPlugin *CPluginManager::LoadPlugin(const char *path, bool debug, PluginType type, char error[], size_t err_max)
1.42 @@ -446,6 +457,215 @@
1.43 }
1.44 }
1.45
1.46 +bool CPluginManager::TestAliasMatch(const char *alias, const char *localpath)
1.47 +{
1.48 + /* As an optimization, we do not call strlen, but compute the length in the first pass */
1.49 + size_t alias_len = 0;
1.50 + size_t local_len = 0;
1.51 +
1.52 + const char *ptr = alias;
1.53 + unsigned int alias_explicit_paths = 0;
1.54 + unsigned int alias_path_end = 0;
1.55 + while (*ptr != '\0')
1.56 + {
1.57 + if (*ptr == '\\' || *ptr == '/')
1.58 + {
1.59 + alias_explicit_paths++;
1.60 + alias_path_end = alias_len;
1.61 + }
1.62 + alias_len++;
1.63 + ptr++;
1.64 + }
1.65 +
1.66 + if (alias_path_end == alias_len - 1)
1.67 + {
1.68 + /* Trailing slash is totally invalid here */
1.69 + return false;
1.70 + }
1.71 +
1.72 + ptr = localpath;
1.73 + unsigned int local_explicit_paths = 0;
1.74 + unsigned int local_path_end = 0;
1.75 + while (*ptr != '\0')
1.76 + {
1.77 + if (*ptr == '\\' || *ptr == '/')
1.78 + {
1.79 + local_explicit_paths++;
1.80 + local_path_end = local_len;
1.81 + }
1.82 + local_len++;
1.83 + ptr++;
1.84 + }
1.85 +
1.86 + /* If the alias has more explicit paths than the real path,
1.87 + * no match will be possible.
1.88 + */
1.89 + if (alias_explicit_paths > local_explicit_paths)
1.90 + {
1.91 + return false;
1.92 + }
1.93 +
1.94 + if (alias_explicit_paths)
1.95 + {
1.96 + /* We need to find if the paths match now. For example, these should all match:
1.97 + * csdm csdm
1.98 + * csdm optional/csdm
1.99 + * csdm/ban optional/crab/csdm/ban
1.100 + */
1.101 + const char *aliasptr = alias;
1.102 + const char *localptr = localpath;
1.103 + bool match = true;
1.104 + do
1.105 + {
1.106 + if (*aliasptr != *localptr)
1.107 + {
1.108 + /* We have to knock one path off */
1.109 + local_explicit_paths--;
1.110 + if (alias_explicit_paths > local_explicit_paths)
1.111 + {
1.112 + /* Skip out if we're gonna have an impossible match */
1.113 + return false;
1.114 + }
1.115 + /* Eat up localptr tokens until we get a result */
1.116 + while (((localptr - localpath) < (int)local_path_end)
1.117 + && *localptr != '/'
1.118 + && *localptr != '\\')
1.119 + {
1.120 + localptr++;
1.121 + }
1.122 + /* Check if we hit the end of our searchable area.
1.123 + * This probably isn't possible because of the path
1.124 + * count check, but it's a good idea anyway.
1.125 + */
1.126 + if ((localptr - localpath) >= (int)local_path_end)
1.127 + {
1.128 + return false;
1.129 + } else {
1.130 + /* Consume the slash token */
1.131 + localptr++;
1.132 + }
1.133 + /* Reset the alias pointer so we can continue consuming */
1.134 + aliasptr = alias;
1.135 + match = false;
1.136 + continue;
1.137 + }
1.138 + /* Note:
1.139 + * This is safe because if localptr terminates early, aliasptr will too
1.140 + */
1.141 + do
1.142 + {
1.143 + /* We should never reach the end of the string because of this check. */
1.144 + bool aliasend = (aliasptr - alias) > (int)alias_path_end;
1.145 + bool localend = (localptr - localpath) > (int)local_path_end;
1.146 + if (aliasend || localend)
1.147 + {
1.148 + if (aliasend && localend)
1.149 + {
1.150 + /* we matched, and we can break out now */
1.151 + match = true;
1.152 + break;
1.153 + }
1.154 + /* Otherwise, we've hit the end somehow and rest won't match up. Break out. */
1.155 + match = false;
1.156 + break;
1.157 + }
1.158 +
1.159 + /* If we got here, it's safe to compare the next two tokens */
1.160 + if (*localptr != *aliasptr)
1.161 + {
1.162 + match = false;
1.163 + break;
1.164 + }
1.165 + localptr++;
1.166 + aliasptr++;
1.167 + } while (true);
1.168 + } while (!match);
1.169 + }
1.170 +
1.171 + /* If we got here, it's time to compare filenames */
1.172 + const char *aliasptr = alias;
1.173 + const char *localptr = localpath;
1.174 +
1.175 + if (alias_explicit_paths)
1.176 + {
1.177 + aliasptr = &alias[alias_path_end + 1];
1.178 + }
1.179 +
1.180 + if (local_explicit_paths)
1.181 + {
1.182 + localptr = &localpath[local_path_end + 1];
1.183 + }
1.184 +
1.185 + while (true)
1.186 + {
1.187 + if (*aliasptr == '*')
1.188 + {
1.189 + /* First, see if this is the last character */
1.190 + if (aliasptr - alias == alias_len - 1)
1.191 + {
1.192 + /* If so, there's no need to match anything else */
1.193 + return true;
1.194 + }
1.195 + /* Otherwise, we need to search for an appropriate matching sequence in local.
1.196 + * Note that we only need to search up to the next asterisk.
1.197 + */
1.198 + aliasptr++;
1.199 + bool match = true;
1.200 + const char *local_orig = localptr;
1.201 + do
1.202 + {
1.203 + match = true;
1.204 + while (*aliasptr != '\0' && *aliasptr != '*')
1.205 + {
1.206 + /* Since aliasptr is never '\0', localptr hitting the end will fail */
1.207 + if (*aliasptr != *localptr)
1.208 + {
1.209 + match = false;
1.210 + break;
1.211 + }
1.212 + aliasptr++;
1.213 + localptr++;
1.214 + }
1.215 + if (!match)
1.216 + {
1.217 + /* If we didn't get a match, we need to advance the search stream.
1.218 + * This will let us skip tokens while still searching for another match.
1.219 + */
1.220 + localptr = ++local_orig;
1.221 + /* Make sure we don't go out of bounds */
1.222 + if (*localptr == '\0')
1.223 + {
1.224 + break;
1.225 + }
1.226 + }
1.227 + } while (!match);
1.228 +
1.229 + if (!match)
1.230 + {
1.231 + return false;
1.232 + } else {
1.233 + /* If we got a match, move on to the next token */
1.234 + continue;
1.235 + }
1.236 + } else if (*aliasptr == '\0') {
1.237 + if (*localptr == '\0'
1.238 + ||
1.239 + strcmp(localptr, ".smx") == 0)
1.240 + {
1.241 + return true;
1.242 + } else {
1.243 + return false;
1.244 + }
1.245 + } else if (*aliasptr != *localptr) {
1.246 + return false;
1.247 + }
1.248 + aliasptr++;
1.249 + localptr++;
1.250 + }
1.251 +
1.252 + return true;
1.253 +}
1.254 +
1.255 CPluginManager::~CPluginManager()
1.256 {
1.257 //:TODO: we need a good way to free what we're holding