Qore Programming Language 2.2.0
Loading...
Searching...
No Matches
ModuleInfo.h
1/* -*- mode: c++; indent-tabs-mode: nil -*- */
2/*
3 ModuleInfo.h
4
5 Qore Programming Language
6
7 Copyright (C) 2003 - 2025 Qore Technologies, s.r.o.
8
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the "Software"),
11 to deal in the Software without restriction, including without limitation
12 the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 and/or sell copies of the Software, and to permit persons to whom the
14 Software is furnished to do so, subject to the following conditions:
15
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 DEALINGS IN THE SOFTWARE.
26
27 Note that the Qore library is released under a choice of three open-source
28 licenses: MIT (as above), LGPL 2+, or GPL 2+; see README-LICENSE for more
29 information.
30*/
31
32#ifndef _QORE_MODULEINFO_H
33
34#define _QORE_MODULEINFO_H
35
36#ifdef NEED_DLFCN_WRAPPER
37extern "C" {
38#endif
39#include <dlfcn.h>
40#ifdef NEED_DLFCN_WRAPPER
41}
42#endif
43
44#include <string>
45#include <map>
46#include <deque>
47#include <memory>
48#include <vector>
49
50// parse options set while parsing the module's header (init & del)
51#define MOD_HEADER_PO (PO_LOCKDOWN & ~(PO_NO_MODULES | PO_NO_REFLECTION))
52
53// initial user module parse options
54#define USER_MOD_PO (PO_NO_TOP_LEVEL_STATEMENTS | PO_REQUIRE_PROTOTYPES | PO_REQUIRE_OUR | PO_IN_MODULE)
55
56// module load options
57#define QMLO_NONE 0
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)
63
65hashdecl version_list_t : public std::vector<int> {
66protected:
67 QoreString ver;
68
69public:
70 DLLLOCAL version_list_t() {
71 }
72
73 DLLLOCAL version_list_t(const char* v) {
74 set(v);
75 }
76
77 DLLLOCAL char set(const char* v);
78
79 DLLLOCAL version_list_t& operator=(const char* v) {
80 set(v);
81 return *this;
82 }
83
84 DLLLOCAL const char* operator*() const {
85 return ver.c_str();
86 }
87};
88
89class QoreAbstractModule {
90public:
91 version_list_t version_list;
92 // list of dependent modules to reexport
93 name_vec_t rmod;
94
95 // for binary modules
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) {
99 q_normalize_path(filename, cwd);
100 }
101
102 // for user modules
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) {
108 q_normalize_path(filename, cwd);
109 }
110
111 DLLLOCAL virtual ~QoreAbstractModule() {
112 //printd(5, "QoreAbstractModule::~QoreAbstractModule() this: %p name: %s\n", this, name.c_str());
113 if (next) {
114 assert(next->prev == this);
115 next->prev = prev;
116 }
117 if (prev) {
118 assert(prev->next == this);
119 prev->next = next;
120 }
121 }
122
123 DLLLOCAL const char* getName() const {
124 return name.c_str();
125 }
126
127 DLLLOCAL const char* getFileName() const {
128 return filename.c_str();
129 }
130
131 DLLLOCAL const QoreString& getFileNameStr() const {
132 return filename;
133 }
134
135 DLLLOCAL const char* getDesc() const {
136 return desc.c_str();
137 }
138
139 DLLLOCAL const char* getVersion() const {
140 return* version_list;
141 }
142
143 DLLLOCAL const char* getURL() const {
144 return url.c_str();
145 }
146
147 DLLLOCAL const char* getOrigName() const {
148 return orig_name.empty() ? nullptr : orig_name.c_str();
149 }
150
151 DLLLOCAL void resetName() {
152 assert(!orig_name.empty());
153 name = orig_name;
154 orig_name.clear();
155 }
156
157 DLLLOCAL bool isInjected() const {
158 return injected;
159 }
160
161 DLLLOCAL bool isReInjected() const {
162 return reinjected;
163 }
164
165 DLLLOCAL void addModuleReExport(const char* m) {
166 rmod.push_back(m);
167 }
168
169 DLLLOCAL void reexport(ExceptionSink& xsink, QoreProgram* pgm) const;
170
171 DLLLOCAL void addToProgram(QoreProgram* pgm, ExceptionSink& xsink) const {
172 addToProgramImpl(pgm, xsink);
173 if (!xsink)
174 reexport(xsink, pgm);
175 }
176
177 DLLLOCAL bool equalTo(const QoreAbstractModule* m) const {
178 assert(name == m->name);
179 return filename == m->filename;
180 }
181
182 DLLLOCAL bool isPath(const char* p) const {
183 return filename == p;
184 }
185
186 DLLLOCAL void rename(const QoreString& n) {
187 assert(orig_name.empty());
188 name = n;
189 }
190
191 DLLLOCAL void setOrigName(const char* n) {
192 assert(orig_name.empty());
193 orig_name = n;
194 }
195
196 DLLLOCAL bool isPrivate() const {
197 return priv;
198 }
199
200 DLLLOCAL void setPrivate(bool p = true) {
201 assert(priv != p);
202 priv = p;
203 }
204
205 DLLLOCAL void setLink(QoreAbstractModule* n) {
206 //printd(5, "AbstractQoreModule::setLink() n: %p '%s'\n", n, n->getName());
207 assert(!next);
208 assert(!n->prev);
209 next = n;
210 n->prev = this;
211 }
212
213 DLLLOCAL QoreAbstractModule* getNext() const {
214 return next;
215 }
216
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)
221 = 0;
222
223protected:
224 QoreString filename,
225 name,
226 desc,
227 author,
228 url,
229 license,
230 path,
231 orig_name;
232
233 // link to associated modules (originals with reinjection, etc)
234 QoreAbstractModule* prev = nullptr,
235 * next = nullptr;
236
237 bool priv : 1,
238 injected : 1,
239 reinjected : 1;
240
241 DLLLOCAL QoreHashNode* getHashIntern(bool with_filename = true) const;
242
243 DLLLOCAL virtual void addToProgramImpl(QoreProgram* pgm, ExceptionSink& xsink) const = 0;
244
245 DLLLOCAL void set(const char* d, const char* v, const char* a, const char* u, const QoreString& l) {
246 desc = d;
247 author = a;
248 url = u;
249 license = l;
250 version_list = v;
251 }
252
253private:
254 // not implemented
255 QoreAbstractModule(const QoreAbstractModule&) = delete;
256 QoreAbstractModule& operator=(const QoreAbstractModule&) = delete;
257};
258
259// list/dequeue of strings
260typedef std::deque<std::string> strdeque_t;
261
263
267protected:
268 typedef std::set<std::string> strset_t;
269
270 strdeque_t dlist;
271 strset_t dset;
272
273public:
274 DLLLOCAL void addDirList(const char* str);
275
276 DLLLOCAL bool push_back(const std::string &str) {
277 if (dset.find(str) != dset.end()) {
278 return false;
279 }
280 dlist.push_back(str);
281 dset.insert(str);
282 return true;
283 }
284
285 DLLLOCAL bool empty() const {
286 return dlist.empty();
287 }
288
289 DLLLOCAL strdeque_t::const_iterator begin() const {
290 return dlist.begin();
291 }
292
293 DLLLOCAL strdeque_t::const_iterator end() const {
294 return dlist.end();
295 }
296
297 DLLLOCAL void appendPath(QoreString& str) const {
298 if (dlist.empty()) {
299 str.concat("<empty>");
300 return;
301 }
302 for (strdeque_t::const_iterator i = dlist.begin(), e = dlist.end(); i != e; ++i) {
303 str.concat((*i).c_str());
304 str.concat(':');
305 }
306 str.terminate(str.size() - 1);
307 }
308};
309
310class QoreModuleContextHelper : public QoreModuleContext {
311public:
312 DLLLOCAL QoreModuleContextHelper(const char* name, QoreProgram* pgm, ExceptionSink& xsink);
313 DLLLOCAL ~QoreModuleContextHelper();
314};
315
316class QoreModuleDefContextHelper : public QoreModuleDefContext {
317protected:
318 QoreModuleDefContext* old;
319
320public:
321 DLLLOCAL QoreModuleDefContextHelper() : old(set_module_def_context(this)) {
322 }
323
324 DLLLOCAL ~QoreModuleDefContextHelper() {
325 set_module_def_context(old);
326 }
327};
328
329class QoreUserModuleDefContextHelper;
330class QoreUserModule;
331
332typedef std::set<std::string> strset_t;
333typedef std::map<std::string, strset_t> md_map_t;
334
335class ModMap {
336private:
337 DLLLOCAL ModMap(const ModMap &);
338 DLLLOCAL ModMap& operator=(const ModMap&);
339
340protected:
341 md_map_t map;
342
343public:
344 DLLLOCAL ModMap() {
345 }
346
347 DLLLOCAL ~ModMap() {
348 }
349
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()) {
355 return true;
356 }
357 i->second.insert(r);
358 return false;
359 }
360
361 DLLLOCAL md_map_t::iterator begin() {
362 return map.begin();
363 }
364
365 DLLLOCAL md_map_t::iterator end() {
366 return map.end();
367 }
368
369 DLLLOCAL md_map_t::iterator find(const char* n) {
370 return map.find(n);
371 }
372
373 DLLLOCAL md_map_t::iterator find(const std::string& n) {
374 return map.find(n);
375 }
376
377 DLLLOCAL void erase(md_map_t::iterator i) {
378 map.erase(i);
379 }
380
381 DLLLOCAL void clear() {
382 map.clear();
383 }
384
385 DLLLOCAL bool empty() const {
386 return map.empty();
387 }
388
389#ifdef DEBUG
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) {
393 QoreString str("[");
394 for (strset_t::iterator si = i->second.begin(), se = i->second.end(); si != se; ++si)
395 str.sprintf("'%s',", (*si).c_str());
396 str.concat("]");
397
398 printd(0, " + %s '%s' -> %s\n", name, i->first.c_str(), str.c_str());
399 }
400 }
401#endif
402};
403
404hashdecl DLHelper {
405 void* ptr;
406
407 DLLLOCAL DLHelper(void* p) : ptr(p) {
408 }
409
410 DLLLOCAL ~DLHelper() {
411 if (ptr)
412 dlclose(ptr);
413 }
414
415 DLLLOCAL void* release() {
416 void* rv = ptr;
417 ptr = nullptr;
418 return rv;
419 }
420};
421
422class QoreModuleManager {
423 friend class QoreAbstractModule;
424 friend class ModuleLoadMapHelper;
425
426public:
427 DLLLOCAL QoreModuleManager() {
428 }
429
430 DLLLOCAL ~QoreModuleManager() {
431 }
432
433 DLLLOCAL void init(bool se);
434 DLLLOCAL void delUser();
435 DLLLOCAL void cleanup();
436
437 DLLLOCAL void issueParseCmd(const QoreProgramLocation* loc, const char* mname, const QoreString& cmd);
438
439 DLLLOCAL int issueRuntimeCmd(const char* mname, QoreProgram* pgm, const QoreString& cmd, ExceptionSink* xsink);
440
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));
444 //printd(5, "QoreModuleManager::addModule() m: %p '%s'\n", m, m->getName());
445 }
446
447 DLLLOCAL QoreAbstractModule* findModule(const char* name) {
448 AutoLocker al(mutex);
449 return findModuleUnlocked(name);
450 }
451
452 DLLLOCAL int parseLoadModule(ExceptionSink& xsink, ExceptionSink& wsink, const char* name, QoreProgram* pgm,
453 bool reexport = false);
454 DLLLOCAL int runTimeLoadModule(ExceptionSink& xsink, ExceptionSink& wsink, const char* name, QoreProgram* pgm,
455 QoreProgram* mpgm = nullptr, unsigned load_opt = QMLO_NONE, int warning_mask = QP_WARN_MODULES,
456 bool reexport = false, qore_binary_module_desc_t mod_desc_func = nullptr);
457
458 DLLLOCAL QoreHashNode* getModuleHash();
459 DLLLOCAL QoreListNode* getModuleList();
460
461 DLLLOCAL void addModuleDir(const char* dir) {
462 AutoLocker al(mutex);
463 moduleDirList.push_back(dir);
464 }
465
466 DLLLOCAL void addModuleDirList(const char* strlist) {
467 AutoLocker al(mutex);
468 moduleDirList.addDirList(strlist);
469 }
470
471 DLLLOCAL void addStandardModulePaths();
472
473 DLLLOCAL void registerUserModuleFromSource(const char* name, const char* src, QoreProgram* pgm,
474 ExceptionSink& xsink);
475
476 DLLLOCAL void trySetUserModuleDependency(const QoreAbstractModule* mi) {
477 if (!mi->isUser())
478 return;
479
480 const char* old_name = get_module_context_name();
481 if (old_name)
482 setUserModuleDependency(mi->getName(), old_name);
483 trySetUserModule(mi->getName());
484 }
485
486 DLLLOCAL void trySetUserModule(const char* name) {
487 md_map_t::iterator i = md_map.find(name);
488 if (i == md_map.end()) {
489 umset.insert(name);
490 //printd(5, "QoreModuleManager::trySetUserModule('%s') UMSET SET: rmd_map: empty\n", name);
491 }
492#ifdef DEBUG
493 /*
494 else {
495 QoreString str("[");
496 for (strset_t::iterator si = i->second.begin(), se = i->second.end(); si != se; ++si)
497 str.sprintf("'%s',", (*si).c_str());
498 str.concat("]");
499 //printd(5, "QoreModuleManager::trySetUserModule('%s') UMSET NOT SET: md_map: %s\n", name, str.c_str());
500 }
501 */
502#endif
503 }
504
505 DLLLOCAL void setUserModuleDependency(const char* name, const char* dep) {
506 //printd(5, "QoreModuleManager::setUserModuleDependency('%s' -> '%s')\n", name, dep);
507 if (md_map.addDep(name, dep))
508 return;
509 rmd_map.addDep(dep, name);
510
511 strset_t::iterator ui = umset.find(name);
512 if (ui != umset.end()) {
513 umset.erase(ui);
514 //printd(5, "QoreModuleManager::setUserModuleDependency('%s' -> '%s') REMOVED '%s' FROM UMMSET\n", name,
515 // dep, name);
516 }
517 }
518
519 DLLLOCAL void removeUserModuleDependency(const char* name, const char* orig_name = 0) {
520 //printd(5, "QoreModuleManager::removeUserModuleDependency() name: '%s' orig: '%s'\n", name,
521 // orig_name ? orig_name : "n/a");
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()) {
526 // remove dependents
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());
530
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()) {
535 //printd(5, "QoreModuleManager::removeUserModuleDependency('%s') '%s' now empty, ADDING TO "
536 // "UMMSET: '%s'\n", name, i->first.c_str(), (*si).c_str());
537 //md_map.erase(di);
538 assert(umset.find(*si) == umset.end());
539 umset.insert(*si);
540 }
541 }
542 // remove from dep map
543 rmd_map.erase(i);
544 }
545
546 i = md_map.find(name);
547 if (i != md_map.end())
548 md_map.erase(i);
549 if (orig_name) {
550 i = md_map.find(orig_name);
551 if (i != md_map.end())
552 md_map.erase(i);
553 }
554 }
555
556 DLLLOCAL int addModuleToBlacklist(const char* name, const char* msg);
557
558private:
559 // not implemented
560 DLLLOCAL QoreModuleManager(const QoreModuleManager&);
561 // not implemented
562 DLLLOCAL QoreModuleManager& operator=(const QoreModuleManager&);
564 DLLLOCAL QoreAbstractModule* loadSeparatedModule(
565 ExceptionSink& xsink,
566 ExceptionSink& wsink,
567 const char* path,
568 const char* feature,
569 QoreProgram* tpgm,
570 bool reexport = false,
571 QoreProgram* pgm = nullptr,
572 QoreProgram* path_pgm = nullptr,
573 unsigned load_opt = QMLO_NONE,
574 int warning_mask = QP_WARN_MODULES);
575
576 typedef std::map<std::string, int> module_load_map_t;
577 QoreCondition module_load_cond;
578 // map feature names to TIDs when module initialization is in progress
579 module_load_map_t module_load_map;
580 // number of threads waiting on module_load_set
581 int module_load_waiting = 0;
582
583protected:
584 // mutex for atomicity
585 QoreThreadLock mutex;
586
587 // user module dependency map: module -> dependents
588 ModMap md_map;
589 // user module dependent map: dependent -> module
590 ModMap rmd_map;
591
592 // module blacklist
593 typedef std::map<const char*, const char*, ltstr> bl_map_t;
594 bl_map_t mod_blacklist;
595
596 // module hash
597 typedef std::map<const char*, QoreAbstractModule*, ltstr> module_map_t;
598 module_map_t map;
599
600 // set of user modules with no dependencies
601 strset_t umset;
602
603 // list of module directories
604 UniqueDirectoryList moduleDirList;
605
606 DLLLOCAL QoreAbstractModule* findModuleUnlocked(const char* name) {
607 module_map_t::iterator i = map.find(name);
608 return i == map.end() ? 0 : i->second;
609 }
610
611 DLLLOCAL QoreAbstractModule* loadModuleIntern(const char* name, QoreProgram* pgm, ExceptionSink& xsink) {
612 AutoLocker sl(mutex); // make sure checking and loading are atomic
613
614 return loadModuleIntern(xsink, xsink, name, pgm);
615 }
616
617 DLLLOCAL QoreAbstractModule* loadModuleIntern(ExceptionSink& xsink, ExceptionSink& wsink, const char* name,
618 QoreProgram* pgm, bool reexport = false, mod_op_e op = MOD_OP_NONE, version_list_t* version = nullptr,
619 const char* src = nullptr, QoreProgram* mpgm = nullptr, unsigned load_opt = QMLO_NONE,
620 int warning_mask = QP_WARN_MODULES, qore_binary_module_desc_t mod_desc_func = nullptr);
621
622 DLLLOCAL QoreAbstractModule* loadBinaryModuleFromPath(ExceptionSink& xsink, const char* path,
623 const char* feature = nullptr, QoreProgram* pgm = nullptr, bool reexport = false,
624 qore_binary_module_desc_t mod_desc = nullptr);
625
626 DLLLOCAL QoreAbstractModule* loadBinaryModuleFromDesc(ExceptionSink& xsink, DLHelper* dlh,
627 QoreModuleInfo& mod_info, const char* path, const char* feature = nullptr, QoreProgram* pgm = nullptr,
628 bool reexport = false);
629
630 DLLLOCAL QoreAbstractModule* loadUserModuleFromPath(ExceptionSink& xsink, ExceptionSink& wsink, const char* path,
631 const char* feature = nullptr, QoreProgram* tpgm = nullptr, bool reexport = false,
632 QoreProgram* pgm = nullptr, QoreProgram* path_pgm = nullptr, unsigned load_opt = QMLO_NONE,
633 int warning_mask = QP_WARN_MODULES);
634
635 DLLLOCAL QoreAbstractModule* loadUserModuleFromSource(ExceptionSink& xsink, ExceptionSink& wsink,
636 const char* path, const char* feature, QoreProgram* tpgm, const char* src, bool reexport,
637 QoreProgram* pgm = nullptr, int warning_mask = QP_WARN_MODULES);
638
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);
641
642 DLLLOCAL void reinjectModule(QoreAbstractModule* mi);
643 DLLLOCAL void delOrig(QoreAbstractModule* mi);
644 DLLLOCAL void getUniqueName(QoreString& nname, const char* name, const char* prefix);
645
646 DLLLOCAL int checkBlacklist(ExceptionSink& xsink, const char* name);
647};
648
649DLLLOCAL extern QoreModuleManager QMM;
650
651class QoreBuiltinModule : public QoreAbstractModule {
652protected:
653 unsigned api_major, api_minor;
654 qore_module_init_t module_init;
655 qore_module_ns_init_t module_ns_init;
656 qore_module_delete_t module_delete;
657 qore_module_parse_cmd_t module_parse_cmd;
658 QoreHashNode* info;
659 const void* dlptr;
660
661 DLLLOCAL virtual void addToProgramImpl(QoreProgram* pgm, ExceptionSink& xsink) const override;
662
663public:
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,
667 qore_module_parse_cmd_t pcmd, const void* p, QoreHashNode* info = nullptr)
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) {
670 }
671
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);
675 module_delete();
676 // we do not close binary modules because we may have thread local data that needs to be
677 // destroyed when exit() is called
678 }
679
680 DLLLOCAL unsigned getAPIMajor() const {
681 return api_major;
682 }
683
684 DLLLOCAL unsigned getAPIMinor() const {
685 return api_minor;
686 }
687
688 DLLLOCAL virtual bool isBuiltin() const override {
689 return true;
690 }
691
692 DLLLOCAL virtual bool isUser() const override {
693 return false;
694 }
695
696 DLLLOCAL QoreHashNode* getHash(bool with_filename = true) const override;
697
698 DLLLOCAL const void* getPtr() const {
699 return dlptr;
700 }
701
702 DLLLOCAL virtual void issueModuleCmd(const QoreProgramLocation* loc, const QoreString& cmd, ExceptionSink* xsink)
703 override;
704};
705
706class QoreUserModule : public QoreAbstractModule {
707protected:
708 QoreProgram* pgm;
709 AbstractQoreNode* del = nullptr; // deletion closure / call reference
710
711 DLLLOCAL virtual void addToProgramImpl(QoreProgram* pgm, ExceptionSink& xsink) const override;
712
713public:
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) {
717 //printd(5, "QoreUserModule::QoreUserModule() this: %p name: %s\n", this, name.c_str());
718 }
719
720 DLLLOCAL void set(const char* d, const char* v, const char* a, const char* u, const QoreString& l,
721 AbstractQoreNode* dl) {
722 QoreAbstractModule::set(d, v, a, u, l);
723 del = dl;
724 }
725
726 DLLLOCAL QoreProgram* getProgram() const {
727 return pgm;
728 }
729
730 DLLLOCAL virtual ~QoreUserModule();
731
732 DLLLOCAL virtual bool isBuiltin() const override {
733 return false;
734 }
735
736 DLLLOCAL virtual bool isUser() const override {
737 return true;
738 }
739
740 DLLLOCAL virtual QoreHashNode* getHash(bool with_filename = true) const override {
741 return getHashIntern(with_filename);
742 }
743
744 DLLLOCAL virtual void issueModuleCmd(const QoreProgramLocation* loc, const QoreString& cmd,
745 ExceptionSink* xsink) override {
746 if (xsink) {
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());
749 }
750 }
751};
752
753class QoreModuleNameContextHelper {
754public:
755 DLLLOCAL QoreModuleNameContextHelper(const char* name) : old_name(set_module_context_name(name)) {
756 }
757
758 DLLLOCAL ~QoreModuleNameContextHelper() {
759 set_module_context_name(old_name);
760 }
761
762protected:
763 const char* old_name;
764};
765
766class QoreUserModuleDefContextHelper : public QoreModuleDefContextHelper {
767public:
768 DLLLOCAL QoreUserModuleDefContextHelper(const char* name, const char* path, QoreProgram* p, ExceptionSink& xs);
769
770 DLLLOCAL ~QoreUserModuleDefContextHelper() {
771 const char* name = set_module_context_name(old_name);
772 set_module_context_path(old_path);
773
774 if (xsink && !dup) {
775 QMM.removeUserModuleDependency(name);
776 }
777 }
778
779 DLLLOCAL void setDuplicate() {
780 assert(!dup);
781 dup = true;
782 }
783
784 DLLLOCAL void setNameInit(const char* name);
785
786 DLLLOCAL void close();
787
788protected:
789 const char* old_name;
790 const char* old_path;
791
792 qore_program_private* pgm;
793 int64 po;
794
795 ExceptionSink& xsink;
796 bool dup;
797};
798
799class ModuleLoadMapHelper {
800public:
801 DLLLOCAL ModuleLoadMapHelper(const char* feature);
802 DLLLOCAL ~ModuleLoadMapHelper();
803
804private:
805 QoreModuleManager::module_load_map_t::iterator i;
806};
807
808#endif
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