core/systems/PluginSys.cpp
changeset 203 c7f86f9e6f60
parent 197 dd30d3d6a51f
child 209 fae1894d884c
     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