41 DECLARE_EXPORT const MetaCategory* MetaCategory::firstCategory = NULL;
72 static bool init =
false;
75 logger <<
"Warning: Calling frepple::LibraryUtils::initialize() more "
76 <<
"than once." << endl;
90 #if defined(HAVE_SETLOCALE) || defined(_MSC_VER)
91 setlocale(LC_ALL,
"" );
95 xercesc::XMLPlatformUtils::Initialize();
103 "Dynamically load a module in memory.");
110 static char pathseperator =
'\\';
112 static char pathseperator =
'/';
117 int result = stat(filename.c_str(), &stat_p);
118 if (!result && (stat_p.st_mode & S_IREAD))
123 char * envvar = getenv(
"FREPPLE_HOME");
127 if (*fullname.rbegin() != pathseperator)
128 fullname += pathseperator;
129 fullname += filename;
130 result = stat(fullname.c_str(), &stat_p);
131 if (!result && (stat_p.st_mode & S_IREAD))
137 fullname = DATADIRECTORY;
138 if (*fullname.rbegin() != pathseperator)
139 fullname += pathseperator;
140 fullname.append(filename);
141 result = stat(fullname.c_str(), &stat_p);
142 if (!result && (stat_p.st_mode & S_IREAD))
148 fullname = LIBDIRECTORY;
149 if (*fullname.rbegin() != pathseperator)
150 fullname += pathseperator;
151 fullname +=
"frepple/";
152 fullname += filename;
153 result = stat(fullname.c_str(), &stat_p);
154 if (!result && (stat_p.st_mode & S_IREAD))
166 if (processorcores >= 1)
return processorcores;
172 GetSystemInfo(&sysinfo);
173 processorcores = sysinfo.dwNumberOfProcessors;
177 processorcores = sysconf(_SC_NPROCESSORS_ONLN);
180 if (processorcores<1) processorcores = 1;
181 return processorcores;
188 if (!logfilename.empty())
192 if (logfile.is_open()) logfile.close();
195 if (x.empty() || x ==
"+")
198 logger.rdbuf(cout.rdbuf());
203 if (x[0] !=
'+') logfile.open(x.c_str(), ios::out);
204 else logfile.open(x.c_str()+1, ios::app);
208 if (logfile.is_open()) logfile.close();
209 logfile.open(logfilename.c_str(), ios::app);
210 logger.rdbuf(logfile.is_open() ? logfile.rdbuf() : cout.rdbuf());
219 logger.rdbuf(logfile.rdbuf());
223 << __DATE__ <<
") at " <<
Date::now() << endl;
234 throw DataException(
"Error: No library name specified for loading");
240 UINT em = SetErrorMode(SEM_FAILCRITICALERRORS);
241 HINSTANCE handle = LoadLibraryEx(lib.c_str(),NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
242 if (!handle) handle = LoadLibraryEx(lib.c_str(), NULL, 0);
248 FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
261 reinterpret_cast<func
>(GetProcAddress(HMODULE(handle),
"initialize"));
267 FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
282 if (fullpath.empty())
285 void *handle = dlopen(fullpath.c_str(), RTLD_NOW | RTLD_GLOBAL);
286 const char *err = dlerror();
291 handle = dlopen(lib.c_str(), RTLD_NOW | RTLD_GLOBAL);
297 func inithandle = (func)(dlsym(handle,
"initialize"));
303 string x = (inithandle)(parameters);
304 if (x.empty())
throw DataException(
"Invalid module name returned");
307 moduleRegistry.insert(x);
312 bool def, creatorDefault f)
321 +
" not found when registering class " + b);
324 type = b.empty() ?
"unspecified" : b;
340 readController f, writeController w)
344 if (!gr.empty()) categoriesByGroupTag[
Keyword::hash(gr)] =
this;
349 type = a.empty() ?
"unspecified" : a;
351 group = gr.empty() ?
"unspecified" : gr;
357 firstCategory =
this;
361 while (i->nextCategory) i = i->nextCategory;
370 CategoryMap::const_iterator i = categoriesByTag.find(
Keyword::hash(c));
371 return (i!=categoriesByTag.end()) ? i->second : NULL;
378 CategoryMap::const_iterator i = categoriesByTag.find(h);
379 return (i!=categoriesByTag.end()) ? i->second : NULL;
386 CategoryMap::const_iterator i = categoriesByGroupTag.find(
Keyword::hash(c));
387 return (i!=categoriesByGroupTag.end()) ? i->second : NULL;
394 CategoryMap::const_iterator i = categoriesByGroupTag.find(h);
395 return (i!=categoriesByGroupTag.end()) ? i->second : NULL;
402 MetaCategory::ClassMap::const_iterator j = classes.find(
Keyword::hash(c));
403 return (j == classes.end()) ? NULL : j->second;
410 MetaCategory::ClassMap::const_iterator j = classes.find(h);
411 return (j == classes.end()) ? NULL : j->second;
417 for (
const MetaCategory *i = firstCategory; i; i = i->nextCategory)
418 if (i->writeFunction) i->writeFunction(i, o);
425 for (MetaCategory::CategoryMap::const_iterator i = MetaCategory::categoriesByTag.begin();
426 i != MetaCategory::categoriesByTag.end(); ++i)
429 MetaCategory::ClassMap::const_iterator j
431 if (j != i->second->classes.end())
return j->second;
440 logger <<
"Registered classes:" << endl;
442 for (MetaCategory::CategoryMap::const_iterator i = MetaCategory::categoriesByTag.begin();
443 i != MetaCategory::categoriesByTag.end(); ++i)
445 logger <<
" " << i->second->type << endl;
447 for (MetaCategory::ClassMap::const_iterator
448 j = i->second->classes.begin();
449 j != i->second->classes.end();
452 logger <<
" default ( = " << j->second->type <<
" )" << j->second << endl;
454 logger <<
" " << j->second->type << j->second << endl;
464 else if (!strcmp(x,
"A"))
return ADD;
465 else if (!strcmp(x,
"C"))
return CHANGE;
466 else if (!strcmp(x,
"R"))
return REMOVE;
482 for (list<Functor*>::const_iterator i = subscribers[a].begin();
483 i != subscribers[a].end(); ++i)
487 if (!(*i)->callback(v,a)) result =
false;
503 (
"Entity " + cat->
type +
" doesn't support REMOVE action");
506 (
"Entity " + cat->
type +
" doesn't support CHANGE action");
520 string t(*type ? type->
getString() :
"default");
569 if (!wild || !str)
return 1;
571 const char *cp = NULL, *mp = NULL;
573 while ((*str) && *wild !=
'*')
575 if (*wild != *str && *wild !=
'?')
586 if (!*++wild)
return 1;
590 else if (*wild == *str || *wild ==
'?')
602 while (*wild ==
'*') wild++;