14 #define GAUDI_PLUGIN_SERVICE_V1
39 constexpr
struct is_space_t {
40 bool operator()(
int i )
const {
return std::isspace( i ); }
66 }
else if (
dest != value ) {
68 ": " +
dest +
" != " + value );
74 void operator()(
const char c ) {
83 name.push_back(
'_' );
86 name.push_back(
'r' );
89 name.push_back(
'p' );
106 namespace PluginService {
120 abi::__cxa_demangle(
id.c_str(),
nullptr,
nullptr, &status ), free );
121 if ( !realname )
return id;
124 std::regex{
"std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >( (?=>))?" },
130 auto _guard = std::scoped_lock{ ::registrySingletonMutex };
138 auto _guard = std::scoped_lock{
m_mutex };
141 #if defined( _WIN32 )
142 const char* envVar =
"PATH";
143 const char sep =
';';
145 const char* envVar =
"LD_LIBRARY_PATH";
146 const char sep =
':';
148 char* search_path = ::getenv( envVar );
152 std::string::size_type pos = 0;
153 std::string::size_type newpos = 0;
154 while ( pos != std::string::npos ) {
157 newpos =
path.find( sep, pos );
158 if ( newpos != std::string::npos ) {
159 dirName =
path.substr( pos, newpos - pos );
162 dirName =
path.substr( pos );
167 DIR* dir = opendir( dirName.
c_str() );
169 struct dirent* entry;
170 while ( ( entry = readdir( dir ) ) ) {
173 std::string::size_type extpos =
name.find(
".components" );
174 if ( ( extpos != std::string::npos ) && ( ( extpos + 11 ) ==
name.size() ) ) {
178 stat( fullPath.
c_str(), &buf );
179 if ( !S_ISREG( buf.st_mode ) )
continue;
185 int factoriesCount = 0;
192 if (
line.empty() ||
line[0] ==
'#' )
continue;
194 if (
line.substr( 0, 4 ) ==
"v1::" )
199 auto pos =
line.find(
':' );
200 if ( pos == std::string::npos ) {
207 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES
210 if ( fact != old_name ) {
232 auto _guard = std::scoped_lock{
m_mutex };
234 auto entry = facts.
find(
id );
235 if ( entry == facts.
end() ) {
240 if ( !entry->second.ptr ) entry->second.
ptr = factory;
241 factoryInfoSetHelper( entry->second.type,
type,
"type",
id );
242 factoryInfoSetHelper( entry->second.rtype, rtype,
"return type",
id );
243 factoryInfoSetHelper( entry->second.className, className,
"class",
id );
245 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES
248 if (
id != old_name )
251 return entry->second;
255 auto _guard = std::scoped_lock{
m_mutex };
257 auto f = facts.
find(
id );
258 if ( f != facts.
end() ) {
259 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES
261 if (
props.find(
"ReflexName" ) !=
props.end() )
265 f->second.className +
"' instead" );
267 if ( !f->second.ptr ) {
268 if ( !dlopen( f->second.library.c_str(), RTLD_LAZY | RTLD_GLOBAL ) ) {
269 logger().
warning(
"cannot load " + f->second.library +
" for factory " +
id );
270 char* dlmsg = dlerror();
274 f = facts.
find(
id );
276 if ( f->second.type ==
type )
return f->second.
ptr;
284 auto _guard = std::scoped_lock{
m_mutex };
287 auto f = facts.
find(
id );
288 return ( f != facts.
end() ) ? f->second : unknown;
292 auto _guard = std::scoped_lock{
m_mutex };
294 auto f = facts.
find(
id );
300 auto _guard = std::scoped_lock{
m_mutex };
303 if ( f.second.ptr )
l.insert( f.first );
309 static const char* levels[] = {
"DEBUG : ",
"INFO : ",
"WARNING: ",
"ERROR : " };
313 static auto s_logger = std::make_unique<Logger>();
320 using namespace Details;
322 if ( debugLevel > 1 )
324 else if ( debugLevel > 0 )
331 using namespace Details;