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 {
159 return filename.
c_str();
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 {
179 return orig_name.
empty() ? nullptr : orig_name.
c_str();
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.c_str());
401 DLLLOCAL DLHelper(
void* p) : ptr(p) {
404 DLLLOCAL ~DLHelper() {
409 DLLLOCAL
void* release() {
416 class QoreModuleManager {
417 friend class QoreAbstractModule;
418 friend class ModuleLoadMapHelper;
421 DLLLOCAL QoreModuleManager() {
424 DLLLOCAL ~QoreModuleManager() {
427 DLLLOCAL
void init(
bool se);
428 DLLLOCAL
void delUser();
429 DLLLOCAL
void cleanup();
431 DLLLOCAL
void issueParseCmd(
const QoreProgramLocation* loc,
const char* mname,
const QoreString& cmd);
435 DLLLOCAL
void addModule(QoreAbstractModule* m) {
436 assert(map.find(m->getName()) == map.end());
437 map.insert(module_map_t::value_type(m->getName(), m));
441 DLLLOCAL QoreAbstractModule* findModule(
const char* name) {
443 return findModuleUnlocked(name);
447 bool reexport =
false);
449 QoreProgram* mpgm =
nullptr,
unsigned load_opt = QMLO_NONE,
int warning_mask = QP_WARN_MODULES,
455 DLLLOCAL
void addModuleDir(
const char* dir) {
457 moduleDirList.push_back(dir);
460 DLLLOCAL
void addModuleDirList(
const char* strlist) {
462 moduleDirList.addDirList(strlist);
465 DLLLOCAL
void addStandardModulePaths();
467 DLLLOCAL
void registerUserModuleFromSource(
const char* name,
const char* src,
QoreProgram *pgm,
ExceptionSink& xsink);
469 DLLLOCAL
void trySetUserModuleDependency(
const QoreAbstractModule* mi) {
473 const char* old_name = get_module_context_name();
475 setUserModuleDependency(mi->getName(), old_name);
476 trySetUserModule(mi->getName());
479 DLLLOCAL
void trySetUserModule(
const char* name) {
480 md_map_t::iterator i = md_map.find(name);
481 if (i == md_map.end()) {
498 DLLLOCAL
void setUserModuleDependency(
const char* name,
const char* dep) {
500 if (md_map.addDep(name, dep))
502 rmd_map.addDep(dep, name);
504 strset_t::iterator ui = umset.find(name);
505 if (ui != umset.end()) {
511 DLLLOCAL
void removeUserModuleDependency(
const char* name,
const char* orig_name = 0) {
513 md_map_t::iterator i = rmd_map.find(name);
514 if (i == rmd_map.end() && orig_name)
515 i = rmd_map.find(orig_name);
516 if (i != rmd_map.end()) {
518 for (strset_t::iterator si = i->second.begin(), se = i->second.end(); si != se; ++si) {
519 md_map_t::iterator di = md_map.find(*si);
520 assert(di != md_map.end());
522 strset_t::iterator dsi = di->second.find(i->first);
523 assert(dsi != di->second.end());
524 di->second.erase(dsi);
525 if (di->second.empty()) {
528 assert(umset.find(*si) == umset.end());
536 i = md_map.find(name);
537 if (i != md_map.end())
540 i = md_map.find(orig_name);
541 if (i != md_map.end())
548 DLLLOCAL QoreModuleManager(
const QoreModuleManager&);
550 DLLLOCAL QoreModuleManager& operator=(
const QoreModuleManager&);
552 DLLLOCAL QoreAbstractModule* loadSeparatedModule(
558 bool reexport =
false,
561 unsigned load_opt = QMLO_NONE,
562 int warning_mask = QP_WARN_MODULES);
564 typedef std::map<std::string, int> module_load_map_t;
567 module_load_map_t module_load_map;
569 int module_load_waiting = 0;
581 typedef std::map<const char*, const char*, ltstr> bl_map_t;
582 bl_map_t mod_blacklist;
585 typedef std::map<const char*, QoreAbstractModule*, ltstr> module_map_t;
594 DLLLOCAL QoreAbstractModule* findModuleUnlocked(
const char* name) {
595 module_map_t::iterator i = map.find(name);
596 return i == map.end() ? 0 : i->second;
602 return loadModuleIntern(xsink, xsink, name, pgm);
606 bool reexport =
false, mod_op_e op = MOD_OP_NONE,
version_list_t* version =
nullptr,
607 const char* src =
nullptr,
QoreProgram* mpgm =
nullptr,
unsigned load_opt = QMLO_NONE,
610 DLLLOCAL QoreAbstractModule* loadBinaryModuleFromPath(
ExceptionSink& xsink,
const char* path,
611 const char* feature =
nullptr,
QoreProgram* pgm =
nullptr,
bool reexport =
false,
614 DLLLOCAL QoreAbstractModule* loadBinaryModuleFromDesc(
ExceptionSink& xsink, DLHelper* dlh,
616 bool reexport =
false);
619 const char* feature =
nullptr,
QoreProgram* tpgm =
nullptr,
bool reexport =
false,
QoreProgram* pgm =
nullptr,
620 QoreProgram* path_pgm =
nullptr,
unsigned load_opt = QMLO_NONE,
int warning_mask = QP_WARN_MODULES);
624 int warning_mask = QP_WARN_MODULES);
626 DLLLOCAL QoreAbstractModule* setupUserModule(
ExceptionSink& xsink, std::unique_ptr<QoreUserModule>& mi,
627 QoreUserModuleDefContextHelper& qmd,
unsigned load_opt = QMLO_NONE,
int warning_mask = QP_WARN_MODULES);
629 DLLLOCAL
void reinjectModule(QoreAbstractModule* mi);
630 DLLLOCAL
void delOrig(QoreAbstractModule* mi);
631 DLLLOCAL
void getUniqueName(
QoreString& nname,
const char* name,
const char* prefix);
634 DLLLOCAL
extern QoreModuleManager QMM;
636 class QoreBuiltinModule :
public QoreAbstractModule {
638 unsigned api_major, api_minor;
649 DLLLOCAL QoreBuiltinModule(
const char* cwd,
const char* fn,
const char* n,
const char* d,
const char* v,
653 : QoreAbstractModule(cwd, fn, n, d, v, a, u, l), api_major(major), api_minor(minor), module_init(init),
654 module_ns_init(ns_init), module_delete(del), module_parse_cmd(pcmd), info(info), dlptr(p) {
657 DLLLOCAL
virtual ~QoreBuiltinModule() {
658 printd(5,
"QoreBuiltinModule::~QoreBuiltinModule() '%s': %s calling module_delete: %p\n", name.c_str(),
659 filename.
c_str(), module_delete);
665 DLLLOCAL
unsigned getAPIMajor()
const {
669 DLLLOCAL
unsigned getAPIMinor()
const {
673 DLLLOCAL
virtual bool isBuiltin()
const override {
677 DLLLOCAL
virtual bool isUser()
const override {
681 DLLLOCAL
QoreHashNode* getHash(
bool with_filename =
true)
const override;
683 DLLLOCAL
const void* getPtr()
const {
687 DLLLOCAL
virtual void issueModuleCmd(
const QoreProgramLocation* loc,
const QoreString& cmd,
ExceptionSink* xsink)
override;
690 class QoreUserModule :
public QoreAbstractModule {
698 DLLLOCAL QoreUserModule(
const char* cwd,
const char* fn,
const char* n,
QoreProgram* p,
unsigned load_opt,
699 int warning_mask = QP_WARN_MODULES) : QoreAbstractModule(cwd, fn, n, load_opt), pgm(p) {
703 QoreAbstractModule::set(d, v, a, u, l);
711 DLLLOCAL
virtual ~QoreUserModule();
713 DLLLOCAL
virtual bool isBuiltin()
const override {
717 DLLLOCAL
virtual bool isUser()
const override {
721 DLLLOCAL
virtual QoreHashNode* getHash(
bool with_filename =
true)
const override {
722 return getHashIntern(with_filename);
725 DLLLOCAL
virtual void issueModuleCmd(
const QoreProgramLocation* loc,
const QoreString& cmd,
ExceptionSink* xsink)
override {
727 xsink->
raiseException(*loc,
"PARSE-COMMAND-ERROR",
"module '%s' loaded from '%s' is a user module; only builtin modules can support parse commands",
728 name.c_str(), filename.
c_str());
733 class QoreModuleNameContextHelper {
735 DLLLOCAL QoreModuleNameContextHelper(
const char* name) : old_name(set_module_context_name(name)) {
738 DLLLOCAL ~QoreModuleNameContextHelper() {
739 set_module_context_name(old_name);
743 const char* old_name;
746 class QoreUserModuleDefContextHelper :
public QoreModuleDefContextHelper {
750 DLLLOCAL ~QoreUserModuleDefContextHelper() {
751 const char* name = set_module_context_name(old_name);
754 QMM.removeUserModuleDependency(name);
757 DLLLOCAL
void setDuplicate() {
762 DLLLOCAL
void setNameInit(
const char* name);
764 DLLLOCAL
void close();
767 const char* old_name;
769 qore_program_private* pgm;
776 class ModuleLoadMapHelper {
778 DLLLOCAL ModuleLoadMapHelper(
const char* feature);
779 DLLLOCAL ~ModuleLoadMapHelper();
782 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:48
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:127
Qore's string type supported by the QoreEncoding class.
Definition: QoreString.h:93
DLLEXPORT void clear()
reset string to zero length; memory is not deallocated; string encoding does not change
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)
DLLEXPORT bool empty() const
returns true if the string is empty, false if not
DLLEXPORT const char * c_str() const
returns the string's buffer; this data should not be changed
provides a mutually-exclusive thread lock
Definition: QoreThreadLock.h:49
non-thread-safe unique list of strings of directory names
Definition: ModuleInfo.h:261
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:64