Skip to content

Commit

Permalink
Fix MSVC build for plugin feature
Browse files Browse the repository at this point in the history
  • Loading branch information
mgreter committed Mar 5, 2015
1 parent c8bf428 commit 95535d0
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 40 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ ifeq ($(UNAME),Darwin)
LDFLAGS += -stdlib=libc++
endif

ifneq (MinGW,$(UNAME))
LDLIBS += -ldl
endif

ifneq ($(BUILD),shared)
BUILD = static
endif
Expand Down
2 changes: 1 addition & 1 deletion plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// gcc: g++ -shared plugin.cpp -o plugin.so -fPIC -Llib -lsass
// mingw: g++ -shared plugin.cpp -o plugin.dll -Llib -lsass

union Sass_Value* ADDCALL call_fn_foo(const union Sass_Value* s_args, void* cookie)
union Sass_Value* call_fn_foo(const union Sass_Value* s_args, void* cookie)
{
// we actually abuse the void* to store an "int"
return sass_make_number((intptr_t)cookie, "px");
Expand Down
76 changes: 49 additions & 27 deletions plugins.cpp
Original file line number Diff line number Diff line change
@@ -1,35 +1,22 @@
#ifdef _WIN32
#include <windows.h>
#ifdef UNICODE
#define STDCOUT std::wcout
#define STDSTR std::wstring
#else
#define STDCOUT std::cout
#define STDSTR std::string
#endif
#else
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <dlfcn.h>
#endif

#include <string>
#include <iostream>
#include "output.hpp"
#include "plugins.hpp"
#include "sass_functions.h"

#define npos string::npos

namespace Sass {

Plugins::Plugins(void)
{
}
Plugins::~Plugins(void)
{
}
Plugins::Plugins(void) { }
Plugins::~Plugins(void) { }

// check if plugin is compatible with this version
// plugins may be linked static against libsass
Expand Down Expand Up @@ -80,15 +67,15 @@ namespace Sass {
{
// print debug message to stderr (should not happen)
cerr << "failed loading 'libsass_support' in <" << path << ">" << endl;
// if (const char* dlsym_error = dlerror()) cerr << dlsym_error << endl;
if (const char* dlsym_error = dlerror()) cerr << dlsym_error << endl;
CLOSE_LIB(plugin);
}
}
else
{
// print debug message to stderr (should not happen)
cerr << "failed loading plugin <" << path << ">" << endl;
// if (const char* dlopen_error = dlerror()) cerr << dlopen_error << endl;
if (const char* dlopen_error = dlerror()) cerr << dlopen_error << endl;
}

return false;
Expand All @@ -97,20 +84,55 @@ namespace Sass {

size_t Plugins::load_plugins(const string& path)
{

// count plugins
size_t loaded = 0;
#ifdef _WIN32

WIN32_FIND_DATA data;
string find(path + "\\*.dll");
#ifdef _WIN32

HANDLE hFile = FindFirstFile(find.c_str(), &data);
if (hFile == INVALID_HANDLE_VALUE) return -1;
try
{

while (true)
// use wchar (utf16)
WIN32_FIND_DATAW data;
// trailing slash is guaranteed
string globsrch(path + "*.dll");
// convert to wide chars (utf16) for system call
wstring wglobsrch(UTF_8::convert_to_utf16(globsrch));
HANDLE hFile = FindFirstFileW(wglobsrch.c_str(), &data);
// check if system called returned a result
// ToDo: maybe we should print a debug message
if (hFile == INVALID_HANDLE_VALUE) return -1;

// read directory
while (true)
{
try
{
// the system will report the filenames with wide chars (utf16)
string entry = UTF_8::convert_from_utf16(data.cFileName);
// check if file ending matches exactly
if (!ends_with(entry, ".dll")) continue;
// load the plugin and increase counter
if (load_plugin(path + entry)) ++ loaded;
// check if there should be more entries
if (GetLastError() == ERROR_NO_MORE_FILES) break;
// load next entry (check for return type)
if (!FindNextFileW(hFile, &data)) break;
}
catch (...)
{
// report the error to the console (should not happen)
// seems like we got strange data from the system call?
cerr << "filename in plugin path has invalid utf8?" << endl;
}
}
}
catch (utf8::invalid_utf8)
{
if (load_plugin(path + "/" + data.cFileName)) ++ loaded;
if (GetLastError() == ERROR_NO_MORE_FILES) break;
if (!FindNextFile(hFile, &data)) break;
// report the error to the console (should not happen)
// implementors should make sure to provide valid utf8
cerr << "plugin path contains invalid utf8" << endl;
}

#else
Expand All @@ -120,7 +142,7 @@ namespace Sass {
if((dp = opendir(path.c_str())) == NULL) return -1;
while ((dirp = readdir(dp)) != NULL) {
if (!ends_with(dirp->d_name, ".so")) continue;
if (load_plugin(path + "/" + dirp->d_name)) ++ loaded;
if (load_plugin(path + dirp->d_name)) ++ loaded;
}
closedir(dp);

Expand Down
20 changes: 20 additions & 0 deletions plugins.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,28 @@

#include <string>
#include <vector>
#include "utf8_string.hpp"
#include "sass_functions.h"

#ifdef _WIN32

#define LOAD_LIB(var, path) HMODULE var = LoadLibraryW(UTF_8::convert_to_utf16(path).c_str())
#define LOAD_LIB_WCHR(var, path_wide_str) HMODULE var = LoadLibraryW(path_wide_str.c_str())
#define LOAD_LIB_FN(type, var, name) type var = (type) GetProcAddress(plugin, name)
#define CLOSE_LIB(var) FreeLibrary(var)

#ifndef dlerror
#define dlerror() 0
#endif

#else

#define LOAD_LIB(var, path) void* var = dlopen(path.c_str(), RTLD_LAZY)
#define LOAD_LIB_FN(type, var, name) type var = (type) dlsym(plugin, name)
#define CLOSE_LIB(var) dlclose(var)

#endif

namespace Sass {

using namespace std;
Expand Down
12 changes: 0 additions & 12 deletions sass.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,12 @@
#define ADDCALL
#endif

#define LOAD_LIB(var, path) HMODULE var = LoadLibrary(path.c_str())
#define LOAD_LIB_FN(type, var, name) type var = (type) GetProcAddress(plugin, name)
#define CLOSE_LIB(var) FreeLibrary(var)

#ifndef dlerror
#define dlerror() 0
#endif

#else /* _WIN32 not defined. */

/* Define with no value on non-Windows OSes. */
#define ADDAPI
#define ADDCALL

#define LOAD_LIB(var, path) void* var = dlopen(path.c_str(), RTLD_LAZY)
#define LOAD_LIB_FN(type, var, name) type var = (type) dlsym(plugin, name)
#define CLOSE_LIB(var) dlclose(var)

#endif

#ifndef LIBSASS_VERSION
Expand Down
1 change: 1 addition & 0 deletions utf8_string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define SASS_UTF8_STRING_H

#include <string>
#include "utf8.h"

namespace Sass {
namespace UTF_8 {
Expand Down

0 comments on commit 95535d0

Please sign in to comment.