Merge.
3 * =============================================================================
5 * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
6 * =============================================================================
8 * This program is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, version 3.0, as published by the
10 * Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to link the
21 * code of this program (as well as its derivative works) to "Half-Life 2," the
22 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
23 * by the Valve Corporation. You must obey the GNU General Public License in
24 * all respects for all other code used. Additionally, AlliedModders LLC grants
25 * this exception to all derivative works. AlliedModders LLC defines further
26 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
27 * or <http://www.sourcemod.net/license.php>.
36 #include <sm_platform.h>
37 #include "sm_stringutil.h"
38 #include "LibrarySys.h"
40 LibrarySystem g_LibSys;
46 #if defined PLATFORM_WINDOWS
48 #elif defined PLATFORM_POSIX
55 CLibrary::CLibrary(LibraryHandle me)
60 void CLibrary::CloseLibrary()
65 void *CLibrary::GetSymbolAddress(const char *symname)
67 #if defined PLATFORM_WINDOWS
68 return GetProcAddress(m_lib, symname);
69 #elif defined PLATFORM_POSIX
70 return dlsym(m_lib, symname);
80 CDirectory::CDirectory(const char *path)
82 #if defined PLATFORM_WINDOWS
83 char newpath[PLATFORM_MAX_PATH];
84 snprintf(newpath, sizeof(newpath), "%s\\*.*", path);
85 m_dir = FindFirstFileA(newpath, &m_fd);
88 m_fd.cFileName[0] = '\0';
90 #elif defined PLATFORM_POSIX
91 m_dir = opendir(path);
94 /* :TODO: we need to read past "." and ".."! */
96 snprintf(m_origpath, PLATFORM_MAX_PATH, "%s", path);
103 CDirectory::~CDirectory()
107 #if defined PLATFORM_WINDOWS
109 #elif defined PLATFORM_POSIX
115 void CDirectory::NextEntry()
117 #if defined PLATFORM_WINDOWS
118 if (FindNextFile(m_dir, &m_fd) == 0)
121 m_dir = INVALID_HANDLE_VALUE;
123 #elif defined PLATFORM_POSIX
124 if ((ep=readdir(m_dir)) == NULL)
132 bool CDirectory::IsEntryValid()
137 bool CDirectory::IsEntryDirectory()
139 #if defined PLATFORM_WINDOWS
140 return ((m_fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
141 #elif defined PLATFORM_LINUX
142 char temppath[PLATFORM_MAX_PATH];
143 snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
144 return g_LibSys.IsPathDirectory(temppath);
148 bool CDirectory::IsEntryFile()
150 #if defined PLATFORM_WINDOWS
151 return !(m_fd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE));
152 #elif defined PLATFORM_POSIX
153 char temppath[PLATFORM_MAX_PATH];
154 snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
155 return g_LibSys.IsPathFile(temppath);
159 const char *CDirectory::GetEntryName()
161 #if defined PLATFORM_WINDOWS
162 return m_fd.cFileName;
163 #elif defined PLATFORM_LINUX
164 return ep ? ep->d_name : "";
168 bool CDirectory::MoreFiles()
173 bool CDirectory::IsValid()
175 #if defined PLATFORM_WINDOWS
176 return (m_dir != INVALID_HANDLE_VALUE);
177 #elif defined PLATFORM_LINUX
178 return (m_dir != NULL);
183 /*************************
184 ** Library System Code **
185 *************************/
188 bool LibrarySystem::PathExists(const char *path)
190 #if defined PLATFORM_WINDOWS
191 DWORD attr = GetFileAttributesA(path);
193 return (attr != INVALID_FILE_ATTRIBUTES);
194 #elif defined PLATFORM_POSIX
197 return (stat(path, &s) == 0);
201 bool LibrarySystem::IsPathFile(const char *path)
203 #if defined PLATFORM_WINDOWS
204 DWORD attr = GetFileAttributes(path);
206 if (attr == INVALID_FILE_ATTRIBUTES)
211 if (attr & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE))
217 #elif defined PLATFORM_LINUX
220 if (stat(path, &s) != 0)
225 return S_ISREG(s.st_mode) ? true : false;
229 bool LibrarySystem::IsPathDirectory(const char *path)
231 #if defined PLATFORM_WINDOWS
232 DWORD attr = GetFileAttributes(path);
234 if (attr == INVALID_FILE_ATTRIBUTES)
239 if (attr & FILE_ATTRIBUTE_DIRECTORY)
244 #elif defined PLATFORM_LINUX
247 if (stat(path, &s) != 0)
252 if (S_ISDIR(s.st_mode))
261 IDirectory *LibrarySystem::OpenDirectory(const char *path)
263 CDirectory *dir = new CDirectory(path);
274 void LibrarySystem::GetPlatformError(char *error, size_t maxlength)
276 if (error && maxlength)
278 #if defined PLATFORM_WINDOWS
279 DWORD dw = GetLastError();
281 FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
284 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
288 #elif defined PLATFORM_POSIX
289 UTIL_Format(error, maxlength, "%s", strerror(errno));
294 void LibrarySystem::GetLoaderError(char *buffer, size_t maxlength)
296 #if defined PLATFORM_WINDOWS
297 GetPlatformError(buffer, maxlength);
298 #elif defined PLATFORM_POSIX
299 if (buffer != NULL && maxlength)
301 strncopy(buffer, dlerror(), maxlength);
306 void LibrarySystem::CloseDirectory(IDirectory *dir)
311 ILibrary *LibrarySystem::OpenLibrary(const char *path, char *error, size_t maxlength)
314 #if defined PLATFORM_WINDOWS
315 lib = LoadLibraryA(path);
316 #elif defined PLATFORM_POSIX
317 lib = dlopen(path, RTLD_NOW);
322 GetLoaderError(error, maxlength);
326 return new CLibrary(lib);
329 size_t LibrarySystem::PathFormat(char *buffer, size_t len, const char *fmt, ...)
333 size_t mylen = vsnprintf(buffer, len, fmt, ap);
339 buffer[mylen] = '\0';
342 for (size_t i=0; i<mylen; i++)
344 if (buffer[i] == PLATFORM_SEP_ALTCHAR)
346 buffer[i] = PLATFORM_SEP_CHAR;
353 const char *LibrarySystem::GetFileExtension(const char *filename)
357 len = strlen(filename);
359 /* Minimum string length for filename with ext would be 3; example: a.a */
367 for (size_t i = end; i <= end; i--)
369 if (filename[i] == PLATFORM_SEP_CHAR || filename[i] == PLATFORM_SEP_ALTCHAR)
374 if (filename[i] == '.' && i != end && i != 0)
376 return &filename[++i];
383 bool LibrarySystem::CreateFolder(const char *path)
385 #if defined PLATFORM_WINDOWS
386 return (mkdir(path) != -1);
387 #elif defined PLATFORM_POSIX
388 return (mkdir(path, 0775) != -1);
392 size_t LibrarySystem::GetFileFromPath(char *buffer, size_t maxlength, const char *path)
394 size_t length = strlen(path);
396 for (size_t i = length - 1;
397 i >= 0 && i <= length - 1;
401 #if defined PLATFORM_WINDOWS
406 return UTIL_Format(buffer, maxlength, "%s", &path[i+1]);
410 /* We scanned and found no path separator */
411 return UTIL_Format(buffer, maxlength, "%s", path);
414 bool LibrarySystem::FileTime(const char *path, FileTimeType type, time_t *pTime)
416 #ifdef PLATFORM_WINDOWS
418 if (_stat(path, &s) != 0)
419 #elif defined PLATFORM_POSIX
421 if (stat(path, &s) != 0)
427 if (type == FileTime_LastAccess)
431 else if (type == FileTime_Created)
435 else if (type == FileTime_LastChange)