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)
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), 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 filename(fn), name(n), priv(load_opt & QMLO_PRIVATE), injected(load_opt & QMLO_INJECT),
105 reinjected(load_opt & QMLO_REINJECT) {
109 DLLLOCAL
virtual ~QoreAbstractModule() {
112 assert(next->prev ==
this);
116 assert(prev->next ==
this);
121 DLLLOCAL
const char* getName()
const {
125 DLLLOCAL
const char* getFileName()
const {
126 return filename.c_str();
129 DLLLOCAL
const QoreString& getFileNameStr()
const {
133 DLLLOCAL
const char* getDesc()
const {
137 DLLLOCAL
const char* getVersion()
const {
138 return* version_list;
141 DLLLOCAL
const char* getURL()
const {
145 DLLLOCAL
const char* getOrigName()
const {
146 return orig_name.empty() ? nullptr : orig_name.c_str();
149 DLLLOCAL
void resetName() {
150 assert(!orig_name.empty());
155 DLLLOCAL
bool isInjected()
const {
159 DLLLOCAL
bool isReInjected()
const {
163 DLLLOCAL
void addModuleReExport(
const char* m) {
170 addToProgramImpl(pgm, xsink);
172 reexport(xsink, pgm);
175 DLLLOCAL
bool equalTo(
const QoreAbstractModule* m)
const {
176 assert(name == m->name);
177 return filename == m->filename;
180 DLLLOCAL
bool isPath(
const char* p)
const {
181 return filename == p;
185 assert(orig_name.empty());
189 DLLLOCAL
void setOrigName(
const char* n) {
190 assert(orig_name.empty());
194 DLLLOCAL
bool isPrivate()
const {
198 DLLLOCAL
void setPrivate(
bool p =
true) {
203 DLLLOCAL
void setLink(QoreAbstractModule* n) {
211 DLLLOCAL QoreAbstractModule* getNext()
const {
215 DLLLOCAL
virtual bool isBuiltin()
const = 0;
216 DLLLOCAL
virtual bool isUser()
const = 0;
217 DLLLOCAL
virtual QoreHashNode* getHash(
bool with_filename =
true)
const = 0;
218 DLLLOCAL
virtual void issueModuleCmd(
const QoreProgramLocation* loc,
const QoreString& cmd,
ExceptionSink* xsink)
231 QoreAbstractModule* prev =
nullptr,
238 DLLLOCAL
QoreHashNode* getHashIntern(
bool with_filename =
true)
const;
242 DLLLOCAL
void set(
const char* d,
const char* v,
const char* a,
const char* u,
const QoreString& l) {
252 QoreAbstractModule(
const QoreAbstractModule&) =
delete;
253 QoreAbstractModule& operator=(
const QoreAbstractModule&) =
delete;
257typedef std::deque<std::string> strdeque_t;
265 typedef std::set<std::string> strset_t;
271 DLLLOCAL
void addDirList(
const char* str);
273 DLLLOCAL
bool push_back(
const std::string &str) {
274 if (dset.find(str) != dset.end()) {
277 dlist.push_back(str);
282 DLLLOCAL
bool empty()
const {
283 return dlist.empty();
286 DLLLOCAL strdeque_t::const_iterator begin()
const {
287 return dlist.begin();
290 DLLLOCAL strdeque_t::const_iterator end()
const {
294 DLLLOCAL
void appendPath(
QoreString& str)
const {
299 for (strdeque_t::const_iterator i = dlist.begin(), e = dlist.end(); i != e; ++i) {
307class QoreModuleContextHelper :
public QoreModuleContext {
310 DLLLOCAL ~QoreModuleContextHelper();
313class QoreModuleDefContextHelper :
public QoreModuleDefContext {
315 QoreModuleDefContext* old;
318 DLLLOCAL QoreModuleDefContextHelper() : old(set_module_def_context(this)) {
321 DLLLOCAL ~QoreModuleDefContextHelper() {
322 set_module_def_context(old);
326class QoreUserModuleDefContextHelper;
329typedef std::set<std::string> strset_t;
330typedef std::map<std::string, strset_t> md_map_t;
334 DLLLOCAL ModMap(
const ModMap &);
335 DLLLOCAL ModMap& operator=(
const ModMap&);
347 DLLLOCAL
bool addDep(
const char* l,
const char* r) {
348 md_map_t::iterator i = map.lower_bound(l);
349 if (i == map.end() || i->first != l) {
350 i = map.insert(i, md_map_t::value_type(l, strset_t()));
351 }
else if (i->second.find(r) != i->second.end()) {
358 DLLLOCAL md_map_t::iterator begin() {
362 DLLLOCAL md_map_t::iterator end() {
366 DLLLOCAL md_map_t::iterator find(
const char* n) {
370 DLLLOCAL md_map_t::iterator find(
const std::string& n) {
374 DLLLOCAL
void erase(md_map_t::iterator i) {
378 DLLLOCAL
void clear() {
382 DLLLOCAL
bool empty()
const {
387 DLLLOCAL
void show(
const char* name) {
388 printf(
"ModMap '%s':\n", name);
389 for (md_map_t::iterator i = map.begin(), e = map.end(); i != e; ++i) {
391 for (strset_t::iterator si = i->second.begin(), se = i->second.end(); si != se; ++si)
392 str.sprintf(
"'%s',", (*si).c_str());
395 printd(0,
" + %s '%s' -> %s\n", name, i->first.c_str(), str.c_str());
404 DLLLOCAL DLHelper(
void* p) : ptr(p) {
407 DLLLOCAL ~DLHelper() {
412 DLLLOCAL
void* release() {
419class QoreModuleManager {
420 friend class QoreAbstractModule;
421 friend class ModuleLoadMapHelper;
424 DLLLOCAL QoreModuleManager() {
427 DLLLOCAL ~QoreModuleManager() {
430 DLLLOCAL
void init(
bool se);
431 DLLLOCAL
void delUser();
432 DLLLOCAL
void cleanup();
434 DLLLOCAL
void issueParseCmd(
const QoreProgramLocation* loc,
const char* mname,
const QoreString& cmd);
438 DLLLOCAL
void addModule(QoreAbstractModule* m) {
439 assert(map.find(m->getName()) == map.end());
440 map.insert(module_map_t::value_type(m->getName(), m));
444 DLLLOCAL QoreAbstractModule* findModule(
const char* name) {
446 return findModuleUnlocked(name);
450 bool reexport =
false);
452 QoreProgram* mpgm =
nullptr,
unsigned load_opt = QMLO_NONE,
int warning_mask = QP_WARN_MODULES,
458 DLLLOCAL
void addModuleDir(
const char* dir) {
460 moduleDirList.push_back(dir);
463 DLLLOCAL
void addModuleDirList(
const char* strlist) {
465 moduleDirList.addDirList(strlist);
468 DLLLOCAL
void addStandardModulePaths();
470 DLLLOCAL
void registerUserModuleFromSource(
const char* name,
const char* src,
QoreProgram* pgm,
473 DLLLOCAL
void trySetUserModuleDependency(
const QoreAbstractModule* mi) {
477 const char* old_name = get_module_context_name();
479 setUserModuleDependency(mi->getName(), old_name);
480 trySetUserModule(mi->getName());
483 DLLLOCAL
void trySetUserModule(
const char* name) {
484 md_map_t::iterator i = md_map.find(name);
485 if (i == md_map.end()) {
502 DLLLOCAL
void setUserModuleDependency(
const char* name,
const char* dep) {
504 if (md_map.addDep(name, dep))
506 rmd_map.addDep(dep, name);
508 strset_t::iterator ui = umset.find(name);
509 if (ui != umset.end()) {
516 DLLLOCAL
void removeUserModuleDependency(
const char* name,
const char* orig_name = 0) {
519 md_map_t::iterator i = rmd_map.find(name);
520 if (i == rmd_map.end() && orig_name)
521 i = rmd_map.find(orig_name);
522 if (i != rmd_map.end()) {
524 for (strset_t::iterator si = i->second.begin(), se = i->second.end(); si != se; ++si) {
525 md_map_t::iterator di = md_map.find(*si);
526 assert(di != md_map.end());
528 strset_t::iterator dsi = di->second.find(i->first);
529 assert(dsi != di->second.end());
530 di->second.erase(dsi);
531 if (di->second.empty()) {
535 assert(umset.find(*si) == umset.end());
543 i = md_map.find(name);
544 if (i != md_map.end())
547 i = md_map.find(orig_name);
548 if (i != md_map.end())
555 DLLLOCAL QoreModuleManager(
const QoreModuleManager&);
557 DLLLOCAL QoreModuleManager& operator=(
const QoreModuleManager&);
559 DLLLOCAL QoreAbstractModule* loadSeparatedModule(
565 bool reexport =
false,
568 unsigned load_opt = QMLO_NONE,
569 int warning_mask = QP_WARN_MODULES);
571 typedef std::map<std::string, int> module_load_map_t;
574 module_load_map_t module_load_map;
576 int module_load_waiting = 0;
588 typedef std::map<const char*, const char*, ltstr> bl_map_t;
589 bl_map_t mod_blacklist;
592 typedef std::map<const char*, QoreAbstractModule*, ltstr> module_map_t;
601 DLLLOCAL QoreAbstractModule* findModuleUnlocked(
const char* name) {
602 module_map_t::iterator i = map.find(name);
603 return i == map.end() ? 0 : i->second;
609 return loadModuleIntern(xsink, xsink, name, pgm);
614 const char* src =
nullptr,
QoreProgram* mpgm =
nullptr,
unsigned load_opt = QMLO_NONE,
617 DLLLOCAL QoreAbstractModule* loadBinaryModuleFromPath(
ExceptionSink& xsink,
const char* path,
618 const char* feature =
nullptr,
QoreProgram* pgm =
nullptr,
bool reexport =
false,
621 DLLLOCAL QoreAbstractModule* loadBinaryModuleFromDesc(
ExceptionSink& xsink, DLHelper* dlh,
623 bool reexport =
false);
626 const char* feature =
nullptr,
QoreProgram* tpgm =
nullptr,
bool reexport =
false,
628 int warning_mask = QP_WARN_MODULES);
631 const char* path,
const char* feature,
QoreProgram* tpgm,
const char* src,
bool reexport,
632 QoreProgram* pgm =
nullptr,
int warning_mask = QP_WARN_MODULES);
634 DLLLOCAL QoreAbstractModule* setupUserModule(
ExceptionSink& xsink, std::unique_ptr<QoreUserModule>& mi,
635 QoreUserModuleDefContextHelper& qmd,
unsigned load_opt = QMLO_NONE,
int warning_mask = QP_WARN_MODULES);
637 DLLLOCAL
void reinjectModule(QoreAbstractModule* mi);
638 DLLLOCAL
void delOrig(QoreAbstractModule* mi);
639 DLLLOCAL
void getUniqueName(
QoreString& nname,
const char* name,
const char* prefix);
642DLLLOCAL
extern QoreModuleManager QMM;
644class QoreBuiltinModule :
public QoreAbstractModule {
646 unsigned api_major, api_minor;
657 DLLLOCAL QoreBuiltinModule(
const char* cwd,
const char* fn,
const char* n,
const char* d,
const char* v,
658 const char* a,
const char* u,
const QoreString& l,
unsigned major,
unsigned minor,
661 : QoreAbstractModule(cwd, fn, n, d, v, a, u, l), api_major(major), api_minor(minor), module_init(init),
662 module_ns_init(ns_init), module_delete(del), module_parse_cmd(pcmd), info(info), dlptr(p) {
665 DLLLOCAL
virtual ~QoreBuiltinModule() {
666 printd(5,
"QoreBuiltinModule::~QoreBuiltinModule() '%s': %s calling module_delete: %p\n", name.c_str(),
667 filename.c_str(), module_delete);
673 DLLLOCAL
unsigned getAPIMajor()
const {
677 DLLLOCAL
unsigned getAPIMinor()
const {
681 DLLLOCAL
virtual bool isBuiltin()
const override {
685 DLLLOCAL
virtual bool isUser()
const override {
689 DLLLOCAL
QoreHashNode* getHash(
bool with_filename =
true)
const override;
691 DLLLOCAL
const void* getPtr()
const {
695 DLLLOCAL
virtual void issueModuleCmd(
const QoreProgramLocation* loc,
const QoreString& cmd,
ExceptionSink* xsink)
699class QoreUserModule :
public QoreAbstractModule {
707 DLLLOCAL QoreUserModule(
const char* cwd,
const char* fn,
const char* n,
QoreProgram* p,
unsigned load_opt,
708 int warning_mask = QP_WARN_MODULES) : QoreAbstractModule(cwd, fn, n, load_opt), pgm(p) {
711 DLLLOCAL
void set(
const char* d,
const char* v,
const char* a,
const char* u,
const QoreString& l,
713 QoreAbstractModule::set(d, v, a, u, l);
721 DLLLOCAL
virtual ~QoreUserModule();
723 DLLLOCAL
virtual bool isBuiltin()
const override {
727 DLLLOCAL
virtual bool isUser()
const override {
731 DLLLOCAL
virtual QoreHashNode* getHash(
bool with_filename =
true)
const override {
732 return getHashIntern(with_filename);
735 DLLLOCAL
virtual void issueModuleCmd(
const QoreProgramLocation* loc,
const QoreString& cmd,
738 xsink->
raiseException(*loc,
"PARSE-COMMAND-ERROR",
"module '%s' loaded from '%s' is a user module; only "
739 "builtin modules can support parse commands", name.c_str(), filename.c_str());
744class QoreModuleNameContextHelper {
746 DLLLOCAL QoreModuleNameContextHelper(
const char* name) : old_name(set_module_context_name(name)) {
749 DLLLOCAL ~QoreModuleNameContextHelper() {
750 set_module_context_name(old_name);
754 const char* old_name;
757class QoreUserModuleDefContextHelper :
public QoreModuleDefContextHelper {
761 DLLLOCAL ~QoreUserModuleDefContextHelper() {
762 const char* name = set_module_context_name(old_name);
765 QMM.removeUserModuleDependency(name);
768 DLLLOCAL
void setDuplicate() {
773 DLLLOCAL
void setNameInit(
const char* name);
775 DLLLOCAL
void close();
778 const char* old_name;
780 qore_program_private* pgm;
787class ModuleLoadMapHelper {
789 DLLLOCAL ModuleLoadMapHelper(
const char* feature);
790 DLLLOCAL ~ModuleLoadMapHelper();
793 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:72
QoreStringNode *(* qore_module_init_t)()
signature of the module constructor/initialization function
Definition: ModuleManager.h:69
void(* qore_binary_module_desc_t)(QoreModuleInfo &mod_info)
Module description function.
Definition: ModuleManager.h:112
void(* qore_module_parse_cmd_t)(const QoreString &cmd, ExceptionSink *xsink)
signature of the module parse command function
Definition: ModuleManager.h:78
void(* qore_module_delete_t)()
signature of the module destructor function
Definition: ModuleManager.h:75
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:50
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:263
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
DLLEXPORT QoreProgram * getProgram()
returns the current QoreProgram
Qore module info.
Definition: ModuleManager.h:88
list of version numbers in order of importance (i.e. 1.2.3 = 1, 2, 3)
Definition: ModuleInfo.h:65