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 | PO_NO_REFLECTION))
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)
62#define QMLO_FROM_PARSE (1 << 4)
77 DLLLOCAL
char set(
const char* v);
84 DLLLOCAL
const char* operator*()
const {
89class QoreAbstractModule {
96 DLLLOCAL QoreAbstractModule(
const char* cwd,
const char* fn,
const char* n,
const char* d,
const char* v,
97 const char* a,
const char* u,
const QoreString& l) : filename(fn), name(n), desc(d), author(a), url(u),
98 license(l), path(fn), priv(false), injected(false), reinjected(false), version_list(v) {
103 DLLLOCAL QoreAbstractModule(
const char* cwd,
const char* fn,
const char* n,
unsigned load_opt,
104 const char* path =
nullptr) :
105 filename(fn), name(n), path(path ? path : fn), priv(load_opt & QMLO_PRIVATE),
106 injected(load_opt & QMLO_INJECT),
107 reinjected(load_opt & QMLO_REINJECT) {
111 DLLLOCAL
virtual ~QoreAbstractModule() {
114 assert(next->prev ==
this);
118 assert(prev->next ==
this);
123 DLLLOCAL
const char* getName()
const {
127 DLLLOCAL
const char* getFileName()
const {
128 return filename.c_str();
131 DLLLOCAL
const QoreString& getFileNameStr()
const {
135 DLLLOCAL
const char* getDesc()
const {
139 DLLLOCAL
const char* getVersion()
const {
140 return* version_list;
143 DLLLOCAL
const char* getURL()
const {
147 DLLLOCAL
const char* getOrigName()
const {
148 return orig_name.empty() ? nullptr : orig_name.c_str();
151 DLLLOCAL
void resetName() {
152 assert(!orig_name.empty());
157 DLLLOCAL
bool isInjected()
const {
161 DLLLOCAL
bool isReInjected()
const {
165 DLLLOCAL
void addModuleReExport(
const char* m) {
172 addToProgramImpl(pgm, xsink);
174 reexport(xsink, pgm);
177 DLLLOCAL
bool equalTo(
const QoreAbstractModule* m)
const {
178 assert(name == m->name);
179 return filename == m->filename;
182 DLLLOCAL
bool isPath(
const char* p)
const {
183 return filename == p;
187 assert(orig_name.empty());
191 DLLLOCAL
void setOrigName(
const char* n) {
192 assert(orig_name.empty());
196 DLLLOCAL
bool isPrivate()
const {
200 DLLLOCAL
void setPrivate(
bool p =
true) {
205 DLLLOCAL
void setLink(QoreAbstractModule* n) {
213 DLLLOCAL QoreAbstractModule* getNext()
const {
217 DLLLOCAL
virtual bool isBuiltin()
const = 0;
218 DLLLOCAL
virtual bool isUser()
const = 0;
219 DLLLOCAL
virtual QoreHashNode* getHash(
bool with_filename =
true)
const = 0;
220 DLLLOCAL
virtual void issueModuleCmd(
const QoreProgramLocation* loc,
const QoreString& cmd,
ExceptionSink* xsink)
234 QoreAbstractModule* prev =
nullptr,
241 DLLLOCAL
QoreHashNode* getHashIntern(
bool with_filename =
true)
const;
245 DLLLOCAL
void set(
const char* d,
const char* v,
const char* a,
const char* u,
const QoreString& l) {
255 QoreAbstractModule(
const QoreAbstractModule&) =
delete;
256 QoreAbstractModule& operator=(
const QoreAbstractModule&) =
delete;
260typedef std::deque<std::string> strdeque_t;
268 typedef std::set<std::string> strset_t;
274 DLLLOCAL
void addDirList(
const char* str);
276 DLLLOCAL
bool push_back(
const std::string &str) {
277 if (dset.find(str) != dset.end()) {
280 dlist.push_back(str);
285 DLLLOCAL
bool empty()
const {
286 return dlist.empty();
289 DLLLOCAL strdeque_t::const_iterator begin()
const {
290 return dlist.begin();
293 DLLLOCAL strdeque_t::const_iterator end()
const {
297 DLLLOCAL
void appendPath(
QoreString& str)
const {
302 for (strdeque_t::const_iterator i = dlist.begin(), e = dlist.end(); i != e; ++i) {
310class QoreModuleContextHelper :
public QoreModuleContext {
313 DLLLOCAL ~QoreModuleContextHelper();
316class QoreModuleDefContextHelper :
public QoreModuleDefContext {
318 QoreModuleDefContext* old;
321 DLLLOCAL QoreModuleDefContextHelper() : old(set_module_def_context(this)) {
324 DLLLOCAL ~QoreModuleDefContextHelper() {
325 set_module_def_context(old);
329class QoreUserModuleDefContextHelper;
332typedef std::set<std::string> strset_t;
333typedef std::map<std::string, strset_t> md_map_t;
337 DLLLOCAL ModMap(
const ModMap &);
338 DLLLOCAL ModMap& operator=(
const ModMap&);
350 DLLLOCAL
bool addDep(
const char* l,
const char* r) {
351 md_map_t::iterator i = map.lower_bound(l);
352 if (i == map.end() || i->first != l) {
353 i = map.insert(i, md_map_t::value_type(l, strset_t()));
354 }
else if (i->second.find(r) != i->second.end()) {
361 DLLLOCAL md_map_t::iterator begin() {
365 DLLLOCAL md_map_t::iterator end() {
369 DLLLOCAL md_map_t::iterator find(
const char* n) {
373 DLLLOCAL md_map_t::iterator find(
const std::string& n) {
377 DLLLOCAL
void erase(md_map_t::iterator i) {
381 DLLLOCAL
void clear() {
385 DLLLOCAL
bool empty()
const {
390 DLLLOCAL
void show(
const char* name) {
391 printf(
"ModMap '%s':\n", name);
392 for (md_map_t::iterator i = map.begin(), e = map.end(); i != e; ++i) {
394 for (strset_t::iterator si = i->second.begin(), se = i->second.end(); si != se; ++si)
395 str.sprintf(
"'%s',", (*si).c_str());
398 printd(0,
" + %s '%s' -> %s\n", name, i->first.c_str(), str.c_str());
407 DLLLOCAL DLHelper(
void* p) : ptr(p) {
410 DLLLOCAL ~DLHelper() {
415 DLLLOCAL
void* release() {
422class QoreModuleManager {
423 friend class QoreAbstractModule;
424 friend class ModuleLoadMapHelper;
427 DLLLOCAL QoreModuleManager() {
430 DLLLOCAL ~QoreModuleManager() {
433 DLLLOCAL
void init(
bool se);
434 DLLLOCAL
void delUser();
435 DLLLOCAL
void cleanup();
437 DLLLOCAL
void issueParseCmd(
const QoreProgramLocation* loc,
const char* mname,
const QoreString& cmd);
441 DLLLOCAL
void addModule(QoreAbstractModule* m) {
442 assert(map.find(m->getName()) == map.end());
443 map.insert(module_map_t::value_type(m->getName(), m));
447 DLLLOCAL QoreAbstractModule* findModule(
const char* name) {
449 return findModuleUnlocked(name);
453 bool reexport =
false);
455 QoreProgram* mpgm =
nullptr,
unsigned load_opt = QMLO_NONE,
int warning_mask = QP_WARN_MODULES,
461 DLLLOCAL
void addModuleDir(
const char* dir) {
463 moduleDirList.push_back(dir);
466 DLLLOCAL
void addModuleDirList(
const char* strlist) {
468 moduleDirList.addDirList(strlist);
471 DLLLOCAL
void addStandardModulePaths();
473 DLLLOCAL
void registerUserModuleFromSource(
const char* name,
const char* src,
QoreProgram* pgm,
476 DLLLOCAL
void trySetUserModuleDependency(
const QoreAbstractModule* mi) {
480 const char* old_name = get_module_context_name();
482 setUserModuleDependency(mi->getName(), old_name);
483 trySetUserModule(mi->getName());
486 DLLLOCAL
void trySetUserModule(
const char* name) {
487 md_map_t::iterator i = md_map.find(name);
488 if (i == md_map.end()) {
505 DLLLOCAL
void setUserModuleDependency(
const char* name,
const char* dep) {
507 if (md_map.addDep(name, dep))
509 rmd_map.addDep(dep, name);
511 strset_t::iterator ui = umset.find(name);
512 if (ui != umset.end()) {
519 DLLLOCAL
void removeUserModuleDependency(
const char* name,
const char* orig_name = 0) {
522 md_map_t::iterator i = rmd_map.find(name);
523 if (i == rmd_map.end() && orig_name)
524 i = rmd_map.find(orig_name);
525 if (i != rmd_map.end()) {
527 for (strset_t::iterator si = i->second.begin(), se = i->second.end(); si != se; ++si) {
528 md_map_t::iterator di = md_map.find(*si);
529 assert(di != md_map.end());
531 strset_t::iterator dsi = di->second.find(i->first);
532 assert(dsi != di->second.end());
533 di->second.erase(dsi);
534 if (di->second.empty()) {
538 assert(umset.find(*si) == umset.end());
546 i = md_map.find(name);
547 if (i != md_map.end())
550 i = md_map.find(orig_name);
551 if (i != md_map.end())
556 DLLLOCAL
int addModuleToBlacklist(
const char* name,
const char* msg);
560 DLLLOCAL QoreModuleManager(
const QoreModuleManager&);
562 DLLLOCAL QoreModuleManager& operator=(
const QoreModuleManager&);
564 DLLLOCAL QoreAbstractModule* loadSeparatedModule(
570 bool reexport =
false,
573 unsigned load_opt = QMLO_NONE,
574 int warning_mask = QP_WARN_MODULES);
576 typedef std::map<std::string, int> module_load_map_t;
579 module_load_map_t module_load_map;
581 int module_load_waiting = 0;
593 typedef std::map<const char*, const char*, ltstr> bl_map_t;
594 bl_map_t mod_blacklist;
597 typedef std::map<const char*, QoreAbstractModule*, ltstr> module_map_t;
606 DLLLOCAL QoreAbstractModule* findModuleUnlocked(
const char* name) {
607 module_map_t::iterator i = map.find(name);
608 return i == map.end() ? 0 : i->second;
614 return loadModuleIntern(xsink, xsink, name, pgm);
619 const char* src =
nullptr,
QoreProgram* mpgm =
nullptr,
unsigned load_opt = QMLO_NONE,
622 DLLLOCAL QoreAbstractModule* loadBinaryModuleFromPath(
ExceptionSink& xsink,
const char* path,
623 const char* feature =
nullptr,
QoreProgram* pgm =
nullptr,
bool reexport =
false,
626 DLLLOCAL QoreAbstractModule* loadBinaryModuleFromDesc(
ExceptionSink& xsink, DLHelper* dlh,
628 bool reexport =
false);
631 const char* feature =
nullptr,
QoreProgram* tpgm =
nullptr,
bool reexport =
false,
633 int warning_mask = QP_WARN_MODULES);
636 const char* path,
const char* feature,
QoreProgram* tpgm,
const char* src,
bool reexport,
637 QoreProgram* pgm =
nullptr,
int warning_mask = QP_WARN_MODULES);
639 DLLLOCAL QoreAbstractModule* setupUserModule(
ExceptionSink& xsink, std::unique_ptr<QoreUserModule>& mi,
640 QoreUserModuleDefContextHelper& qmd,
unsigned load_opt = QMLO_NONE,
int warning_mask = QP_WARN_MODULES);
642 DLLLOCAL
void reinjectModule(QoreAbstractModule* mi);
643 DLLLOCAL
void delOrig(QoreAbstractModule* mi);
644 DLLLOCAL
void getUniqueName(
QoreString& nname,
const char* name,
const char* prefix);
646 DLLLOCAL
int checkBlacklist(
ExceptionSink& xsink,
const char* name);
649DLLLOCAL
extern QoreModuleManager QMM;
651class QoreBuiltinModule :
public QoreAbstractModule {
653 unsigned api_major, api_minor;
664 DLLLOCAL QoreBuiltinModule(
const char* cwd,
const char* fn,
const char* n,
const char* d,
const char* v,
665 const char* a,
const char* u,
const QoreString& l,
unsigned major,
unsigned minor,
668 : QoreAbstractModule(cwd, fn, n, d, v, a, u, l), api_major(major), api_minor(minor), module_init(init),
669 module_ns_init(ns_init), module_delete(del), module_parse_cmd(pcmd), info(info), dlptr(p) {
672 DLLLOCAL
virtual ~QoreBuiltinModule() {
673 printd(5,
"QoreBuiltinModule::~QoreBuiltinModule() '%s': %s calling module_delete: %p\n", name.c_str(),
674 filename.c_str(), module_delete);
680 DLLLOCAL
unsigned getAPIMajor()
const {
684 DLLLOCAL
unsigned getAPIMinor()
const {
688 DLLLOCAL
virtual bool isBuiltin()
const override {
692 DLLLOCAL
virtual bool isUser()
const override {
696 DLLLOCAL
QoreHashNode* getHash(
bool with_filename =
true)
const override;
698 DLLLOCAL
const void* getPtr()
const {
702 DLLLOCAL
virtual void issueModuleCmd(
const QoreProgramLocation* loc,
const QoreString& cmd,
ExceptionSink* xsink)
706class QoreUserModule :
public QoreAbstractModule {
714 DLLLOCAL QoreUserModule(
const char* cwd,
const char* fn,
const char* n,
QoreProgram* p,
unsigned load_opt,
715 int warning_mask = QP_WARN_MODULES,
const char* path =
nullptr)
716 : QoreAbstractModule(cwd, fn, n, load_opt, path), pgm(p) {
720 DLLLOCAL
void set(
const char* d,
const char* v,
const char* a,
const char* u,
const QoreString& l,
722 QoreAbstractModule::set(d, v, a, u, l);
730 DLLLOCAL
virtual ~QoreUserModule();
732 DLLLOCAL
virtual bool isBuiltin()
const override {
736 DLLLOCAL
virtual bool isUser()
const override {
740 DLLLOCAL
virtual QoreHashNode* getHash(
bool with_filename =
true)
const override {
741 return getHashIntern(with_filename);
744 DLLLOCAL
virtual void issueModuleCmd(
const QoreProgramLocation* loc,
const QoreString& cmd,
747 xsink->
raiseException(*loc,
"PARSE-COMMAND-ERROR",
"module '%s' loaded from '%s' is a user module; only "
748 "builtin modules can support parse commands", name.c_str(), filename.c_str());
753class QoreModuleNameContextHelper {
755 DLLLOCAL QoreModuleNameContextHelper(
const char* name) : old_name(set_module_context_name(name)) {
758 DLLLOCAL ~QoreModuleNameContextHelper() {
759 set_module_context_name(old_name);
763 const char* old_name;
766class QoreUserModuleDefContextHelper :
public QoreModuleDefContextHelper {
770 DLLLOCAL ~QoreUserModuleDefContextHelper() {
771 const char* name = set_module_context_name(old_name);
772 set_module_context_path(old_path);
775 QMM.removeUserModuleDependency(name);
779 DLLLOCAL
void setDuplicate() {
784 DLLLOCAL
void setNameInit(
const char* name);
786 DLLLOCAL
void close();
789 const char* old_name;
790 const char* old_path;
792 qore_program_private* pgm;
799class ModuleLoadMapHelper {
801 DLLLOCAL ModuleLoadMapHelper(
const char* feature);
802 DLLLOCAL ~ModuleLoadMapHelper();
805 QoreModuleManager::module_load_map_t::iterator i;
void(* qore_module_ns_init_t)(QoreNamespace *root_ns, QoreNamespace *qore_ns)
signature of the module namespace change/delta function
Definition ModuleManager.h:81
QoreStringNode *(* qore_module_init_t)()
signature of the module constructor/initialization function
Definition ModuleManager.h:75
void(* qore_binary_module_desc_t)(QoreModuleInfo &mod_info)
Module description function.
Definition ModuleManager.h:125
void(* qore_module_parse_cmd_t)(const QoreString &cmd, ExceptionSink *xsink)
signature of the module parse command function
Definition ModuleManager.h:87
void(* qore_module_delete_t)()
signature of the module destructor function
Definition ModuleManager.h:84
DLLEXPORT void q_normalize_path(QoreString &path, const char *cwd=0)
normalizes the given path for the current platform in place (makes absolute, removes "....
The base class for all value and parse types in Qore expression trees.
Definition AbstractQoreNode.h:57
provides a safe and exception-safe way to hold locks in Qore, only to be used on the stack,...
Definition QoreThreadLock.h:136
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition ExceptionSink.h:50
DLLEXPORT AbstractQoreNode * raiseException(const char *err, const char *fmt,...)
appends a Qore-language exception to the list
a thread condition class implementing a wrapper for pthread_cond_t
Definition QoreCondition.h:45
This is the hash or associative list container type in Qore, dynamically allocated only,...
Definition QoreHashNode.h:51
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition QoreListNode.h:52
supports parsing and executing Qore-language code, reference counted, dynamically-allocated only
Definition QoreProgram.h:128
Qore's string type supported by the QoreEncoding class.
Definition QoreString.h:93
DLLEXPORT const char * c_str() const
returns the string's buffer; this data should not be changed
DLLEXPORT void terminate(size_t size)
terminates the string at byte position "size", the string is reallocated if necessary
DLLEXPORT void concat(const QoreString *str, ExceptionSink *xsink)
concatenates a string and converts encodings if necessary
DLLEXPORT size_t size() const
returns number of bytes in the string (not including the null pointer)
provides a mutually-exclusive thread lock
Definition QoreThreadLock.h:49
non-thread-safe unique list of strings of directory names
Definition ModuleInfo.h:266
std::vector< std::string > name_vec_t
vector of parameter names for parameter lists
Definition common.h:263
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:266
DLLEXPORT QoreProgram * getProgram()
returns the current QoreProgram
Qore module info.
Definition ModuleManager.h:97
list of version numbers in order of importance (i.e. 1.2.3 = 1, 2, 3)
Definition ModuleInfo.h:65