32 #ifndef _QORE_MODULEINFO_H 34 #define _QORE_MODULEINFO_H 36 #ifdef NEED_DLFCN_WRAPPER 40 #ifdef NEED_DLFCN_WRAPPER 51 #define MOD_HEADER_PO (PO_LOCKDOWN & ~PO_NO_MODULES) 54 #define USER_MOD_PO (PO_NO_TOP_LEVEL_STATEMENTS | PO_REQUIRE_PROTOTYPES | PO_REQUIRE_OUR | PO_IN_MODULE) 58 #define QMLO_INJECT (1 << 0) 59 #define QMLO_REINJECT (1 << 1) 60 #define QMLO_PRIVATE (1 << 2) 61 #define QMLO_RELOAD (1 << 3) 76 DLLLOCAL
char set(
const char* v);
83 DLLLOCAL
const char* operator*()
const {
88 class QoreAbstractModule {
91 DLLLOCAL QoreAbstractModule(
const QoreAbstractModule&);
92 DLLLOCAL QoreAbstractModule& operator=(
const QoreAbstractModule&);
104 QoreAbstractModule* prev =
nullptr,
111 DLLLOCAL
QoreHashNode* getHashIntern(
bool with_filename =
true)
const;
115 DLLLOCAL
void set(
const char* d,
const char* v,
const char* a,
const char* u,
const QoreString& l) {
129 DLLLOCAL QoreAbstractModule(
const char* cwd,
const char* fn,
const char* n,
const char* d,
const char* v,
130 const char* a,
const char* u,
const QoreString& l) : filename(fn), name(n), desc(d), author(a), url(u),
131 license(l), priv(
false), injected(
false), reinjected(
false), version_list(v) {
136 DLLLOCAL QoreAbstractModule(
const char* cwd,
const char* fn,
const char* n,
unsigned load_opt) :
137 filename(fn), name(n), priv(load_opt & QMLO_PRIVATE), injected(load_opt & QMLO_INJECT),
138 reinjected(load_opt & QMLO_REINJECT) {
142 DLLLOCAL
virtual ~QoreAbstractModule() {
145 assert(next->prev ==
this);
149 assert(prev->next ==
this);
154 DLLLOCAL
const char* getName()
const {
158 DLLLOCAL
const char* getFileName()
const {
162 DLLLOCAL
const QoreString& getFileNameStr()
const {
166 DLLLOCAL
const char* getDesc()
const {
170 DLLLOCAL
const char* getVersion()
const {
171 return* version_list;
174 DLLLOCAL
const char* getURL()
const {
178 DLLLOCAL
const char* getOrigName()
const {
182 DLLLOCAL
void resetName() {
183 assert(!orig_name.
empty());
188 DLLLOCAL
bool isInjected()
const {
192 DLLLOCAL
bool isReInjected()
const {
196 DLLLOCAL
void addModuleReExport(
const char* m) {
203 addToProgramImpl(pgm, xsink);
205 reexport(xsink, pgm);
208 DLLLOCAL
bool equalTo(
const QoreAbstractModule* m)
const {
209 assert(name == m->name);
210 return filename == m->filename;
213 DLLLOCAL
bool isPath(
const char* p)
const {
214 return filename == p;
218 assert(orig_name.
empty());
222 DLLLOCAL
void setOrigName(
const char* n) {
223 assert(orig_name.
empty());
227 DLLLOCAL
bool isPrivate()
const {
231 DLLLOCAL
void setPrivate(
bool p =
true) {
236 DLLLOCAL
void setLink(QoreAbstractModule* n) {
244 DLLLOCAL QoreAbstractModule* getNext()
const {
248 DLLLOCAL
virtual bool isBuiltin()
const = 0;
249 DLLLOCAL
virtual bool isUser()
const = 0;
250 DLLLOCAL
virtual QoreHashNode* getHash(
bool with_filename =
true)
const = 0;
251 DLLLOCAL
virtual void issueModuleCmd(
const QoreProgramLocation* loc,
const QoreString& cmd,
ExceptionSink* xsink) = 0;
255 typedef std::deque<std::string> strdeque_t;
263 typedef std::set<std::string> strset_t;
269 DLLLOCAL
void addDirList(
const char* str);
271 DLLLOCAL
bool push_back(
const std::string &str) {
272 if (dset.find(str) != dset.end()) {
275 dlist.push_back(str);
280 DLLLOCAL
bool empty()
const {
281 return dlist.empty();
284 DLLLOCAL strdeque_t::const_iterator begin()
const {
285 return dlist.begin();
288 DLLLOCAL strdeque_t::const_iterator end()
const {
292 DLLLOCAL
void appendPath(
QoreString& str)
const {
297 for (strdeque_t::const_iterator i = dlist.begin(), e = dlist.end(); i != e; ++i) {
305 class QoreModuleContextHelper :
public QoreModuleContext {
308 DLLLOCAL ~QoreModuleContextHelper();
311 class QoreModuleDefContextHelper :
public QoreModuleDefContext {
313 QoreModuleDefContext* old;
316 DLLLOCAL QoreModuleDefContextHelper() : old(set_module_def_context(
this)) {
319 DLLLOCAL ~QoreModuleDefContextHelper() {
320 set_module_def_context(old);
324 class QoreUserModuleDefContextHelper;
325 class QoreUserModule;
327 typedef std::set<std::string> strset_t;
328 typedef std::map<std::string, strset_t> md_map_t;
332 DLLLOCAL ModMap(
const ModMap &);
333 DLLLOCAL ModMap& operator=(
const ModMap&);
345 DLLLOCAL
bool addDep(
const char* l,
const char* r) {
346 md_map_t::iterator i = map.lower_bound(l);
347 if (i == map.end() || i->first != l)
348 i = map.insert(i, md_map_t::value_type(l, strset_t()));
349 else if (i->second.find(r) != i->second.end())
355 DLLLOCAL md_map_t::iterator begin() {
359 DLLLOCAL md_map_t::iterator end() {
363 DLLLOCAL md_map_t::iterator find(
const char* n) {
367 DLLLOCAL md_map_t::iterator find(
const std::string& n) {
371 DLLLOCAL
void erase(md_map_t::iterator i) {
375 DLLLOCAL
void clear() {
379 DLLLOCAL
bool empty()
const {
384 DLLLOCAL
void show(
const char* name) {
385 printf(
"ModMap '%s':\n", name);
386 for (md_map_t::iterator i = map.begin(), e = map.end(); i != e; ++i) {
388 for (strset_t::iterator si = i->second.begin(), se = i->second.end(); si != se; ++si)
389 str.
sprintf(
"'%s',", (*si).c_str());
392 printd(0,
" + %s '%s' -> %s\n", name, i->first.c_str(), str.
getBuffer());
398 class QoreModuleManager {
399 friend class QoreAbstractModule;
403 DLLLOCAL QoreModuleManager(
const QoreModuleManager&);
405 DLLLOCAL QoreModuleManager& operator=(
const QoreModuleManager&);
407 DLLLOCAL QoreAbstractModule* loadSeparatedModule(
413 bool reexport =
false,
416 unsigned load_opt = QMLO_NONE,
417 int warning_mask = QP_WARN_MODULES);
429 typedef std::map<const char*, const char*, ltstr> bl_map_t;
430 bl_map_t mod_blacklist;
433 typedef std::map<const char*, QoreAbstractModule*, ltstr> module_map_t;
442 DLLLOCAL QoreAbstractModule* findModuleUnlocked(
const char* name) {
443 module_map_t::iterator i = map.find(name);
444 return i == map.end() ? 0 : i->second;
450 loadModuleIntern(xsink, xsink, name, pgm);
454 bool reexport =
false, mod_op_e op = MOD_OP_NONE,
version_list_t* version =
nullptr,
455 const char* src =
nullptr,
QoreProgram* mpgm =
nullptr,
unsigned load_opt = QMLO_NONE,
456 int warning_mask = QP_WARN_MODULES);
458 DLLLOCAL QoreAbstractModule* loadBinaryModuleFromPath(
ExceptionSink& xsink,
const char* path,
const char* feature = 0,
QoreProgram* pgm = 0,
bool reexport =
false);
460 const char* feature =
nullptr,
QoreProgram* tpgm =
nullptr,
bool reexport =
false,
QoreProgram* pgm =
nullptr,
461 QoreProgram* path_pgm =
nullptr,
unsigned load_opt = QMLO_NONE,
int warning_mask = QP_WARN_MODULES);
464 int warning_mask = QP_WARN_MODULES);
465 DLLLOCAL QoreAbstractModule* setupUserModule(
ExceptionSink& xsink, std::unique_ptr<QoreUserModule>& mi,
466 QoreUserModuleDefContextHelper& qmd,
unsigned load_opt = QMLO_NONE,
int warning_mask = QP_WARN_MODULES);
468 DLLLOCAL
void reinjectModule(QoreAbstractModule* mi);
469 DLLLOCAL
void delOrig(QoreAbstractModule* mi);
470 DLLLOCAL
void getUniqueName(
QoreString& nname,
const char* name,
const char* prefix);
473 DLLLOCAL QoreModuleManager() : mutex(0) {
476 DLLLOCAL ~QoreModuleManager() {
480 DLLLOCAL
void init(
bool se);
481 DLLLOCAL
void delUser();
482 DLLLOCAL
void cleanup();
484 DLLLOCAL
void issueParseCmd(
const QoreProgramLocation* loc,
const char* mname,
const QoreString& cmd);
488 DLLLOCAL
void addModule(QoreAbstractModule* m) {
489 assert(map.find(m->getName()) == map.end());
490 map.insert(module_map_t::value_type(m->getName(), m));
493 DLLLOCAL QoreAbstractModule* findModule(
const char* name) {
495 return findModuleUnlocked(name);
499 bool reexport =
false);
501 QoreProgram* mpgm =
nullptr,
unsigned load_opt = QMLO_NONE,
int warning_mask = QP_WARN_MODULES,
502 bool reexport =
false);
507 DLLLOCAL
void addModuleDir(
const char* dir) {
509 moduleDirList.push_back(dir);
512 DLLLOCAL
void addModuleDirList(
const char* strlist) {
514 moduleDirList.addDirList(strlist);
517 DLLLOCAL
void addStandardModulePaths();
519 DLLLOCAL
void registerUserModuleFromSource(
const char* name,
const char* src,
QoreProgram *pgm,
ExceptionSink& xsink);
521 DLLLOCAL
void trySetUserModuleDependency(
const QoreAbstractModule* mi) {
525 const char* old_name = get_user_module_context_name();
527 setUserModuleDependency(mi->getName(), old_name);
528 trySetUserModule(mi->getName());
531 DLLLOCAL
void trySetUserModule(
const char* name) {
532 md_map_t::iterator i = md_map.find(name);
533 if (i == md_map.end()) {
550 DLLLOCAL
void setUserModuleDependency(
const char* name,
const char* dep) {
552 if (md_map.addDep(name, dep))
554 rmd_map.addDep(dep, name);
556 strset_t::iterator ui = umset.find(name);
557 if (ui != umset.end()) {
563 DLLLOCAL
void removeUserModuleDependency(
const char* name,
const char* orig_name = 0) {
565 md_map_t::iterator i = rmd_map.find(name);
566 if (i == rmd_map.end() && orig_name)
567 i = rmd_map.find(orig_name);
568 if (i != rmd_map.end()) {
570 for (strset_t::iterator si = i->second.begin(), se = i->second.end(); si != se; ++si) {
571 md_map_t::iterator di = md_map.find(*si);
572 assert(di != md_map.end());
574 strset_t::iterator dsi = di->second.find(i->first);
575 assert(dsi != di->second.end());
576 di->second.erase(dsi);
577 if (di->second.empty()) {
580 assert(umset.find(*si) == umset.end());
588 i = md_map.find(name);
589 if (i != md_map.end())
592 i = md_map.find(orig_name);
593 if (i != md_map.end())
599 DLLLOCAL
extern QoreModuleManager QMM;
601 class QoreBuiltinModule :
public QoreAbstractModule {
603 unsigned api_major, api_minor;
613 DLLLOCAL QoreBuiltinModule(
const char* cwd,
const char* fn,
const char* n,
const char* d,
const char* v,
const char* a,
const char* u,
const QoreString& l,
unsigned major,
unsigned minor,
qore_module_init_t init,
qore_module_ns_init_t ns_init,
qore_module_delete_t del,
qore_module_parse_cmd_t pcmd,
const void* p) : QoreAbstractModule(cwd, fn, n, d, v, a, u, l), api_major(major), api_minor(minor), module_init(init), module_ns_init(ns_init), module_delete(del), module_parse_cmd(pcmd), dlptr(p) {
616 DLLLOCAL
virtual ~QoreBuiltinModule() {
617 printd(5,
"QoreBuiltinModule::~QoreBuiltinModule() '%s': %s calling module_delete: %p\n", name.getBuffer(), filename.getBuffer(), module_delete);
623 DLLLOCAL
unsigned getAPIMajor()
const {
627 DLLLOCAL
unsigned getAPIMinor()
const {
631 DLLLOCAL
virtual bool isBuiltin()
const override {
635 DLLLOCAL
virtual bool isUser()
const override {
639 DLLLOCAL
QoreHashNode* getHash(
bool with_filename =
true)
const override;
641 DLLLOCAL
const void* getPtr()
const {
645 DLLLOCAL
virtual void issueModuleCmd(
const QoreProgramLocation* loc,
const QoreString& cmd,
ExceptionSink* xsink)
override;
648 class QoreUserModule :
public QoreAbstractModule {
656 DLLLOCAL QoreUserModule(
const char* cwd,
const char* fn,
const char* n,
QoreProgram* p,
unsigned load_opt,
657 int warning_mask = QP_WARN_MODULES) : QoreAbstractModule(cwd, fn, n, load_opt), pgm(p) {
661 QoreAbstractModule::set(d, v, a, u, l);
669 DLLLOCAL
virtual ~QoreUserModule();
671 DLLLOCAL
virtual bool isBuiltin()
const override {
675 DLLLOCAL
virtual bool isUser()
const override {
679 DLLLOCAL
virtual QoreHashNode* getHash(
bool with_filename =
true)
const override {
680 return getHashIntern(with_filename);
683 DLLLOCAL
virtual void issueModuleCmd(
const QoreProgramLocation* loc,
const QoreString& cmd,
ExceptionSink* xsink)
override {
685 xsink->
raiseException(*loc,
"PARSE-COMMAND-ERROR",
"module '%s' loaded from '%s' is a user module; only builtin modules can support parse commands",
686 name.c_str(), filename.c_str());
691 class QoreUserModuleDefContextHelper :
public QoreModuleDefContextHelper {
695 DLLLOCAL ~QoreUserModuleDefContextHelper() {
696 const char* name = set_user_module_context_name(old_name);
699 QMM.removeUserModuleDependency(name);
702 DLLLOCAL
void setDuplicate() {
707 DLLLOCAL
void setNameInit(
const char* name);
709 DLLLOCAL
void close();
712 const char* old_name;
714 qore_program_private* pgm;
void(* qore_module_delete_t)()
signature of the module destructor function
Definition: ModuleManager.h:75
DLLEXPORT bool empty() const
returns true if the string is empty, false if not
This is the hash or associative list container type in Qore, dynamically allocated only...
Definition: QoreHashNode.h:50
DLLEXPORT int sprintf(const char *fmt,...)
this will concatentate a formatted string to the existing string according to the format string and t...
The base class for all value and parse types in Qore expression trees.
Definition: AbstractQoreNode.h:54
void(* qore_module_ns_init_t)(QoreNamespace *root_ns, QoreNamespace *qore_ns)
signature of the module namespace change/delta function
Definition: ModuleManager.h:72
DLLEXPORT AbstractQoreNode * raiseException(const char *err, const char *fmt,...)
appends a Qore-language exception to the list
void(* qore_module_parse_cmd_t)(const QoreString &cmd, ExceptionSink *xsink)
signature of the module parse command function
Definition: ModuleManager.h:78
non-thread-safe unique list of strings of directory names
Definition: ModuleInfo.h:261
Qore's string type supported by the QoreEncoding class.
Definition: QoreString.h:81
DLLEXPORT const char * getBuffer() const
returns the string's buffer; this data should not be changed
DLLEXPORT QoreProgram * getProgram()
returns the current QoreProgram
DLLEXPORT void concat(const QoreString *str, ExceptionSink *xsink)
concatenates a string and converts encodings if necessary
provides a safe and exception-safe way to hold locks in Qore, only to be used on the stack...
Definition: QoreThreadLock.h:128
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition: QoreListNode.h:52
provides a safe and exception-safe way to hold optional locks in Qore, only to be used on the stack...
Definition: QoreThreadLock.h:300
supports parsing and executing Qore-language code, reference counted, dynamically-allocated only ...
Definition: QoreProgram.h:126
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:46
std::vector< std::string > name_vec_t
vector of parameter names for parameter lists
Definition: common.h:257
long long int64
64bit integer type, cannot use int64_t here since it breaks the API on some 64-bit systems due to equ...
Definition: common.h:260
list of version numbers in order of importance (i.e. 1.2.3 = 1, 2, 3)
Definition: ModuleInfo.h:64
DLLEXPORT void terminate(qore_size_t size)
terminates the string at byte position "size", the string is reallocated if necessary ...
provides a mutually-exclusive thread lock
Definition: QoreThreadLock.h:47
DLLEXPORT void q_normalize_path(QoreString &path, const char *cwd=0)
normalizes the given path for the current platform in place (makes absolute, removes "...
DLLEXPORT void clear()
reset string to zero length; memory is not deallocated; string encoding does not change ...
DLLEXPORT qore_size_t size() const
returns number of bytes in the string (not including the null pointer)
QoreStringNode *(* qore_module_init_t)()
signature of the module constructor/initialization function
Definition: ModuleManager.h:69