Qore Programming Language 1.19.1
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 - 2023 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)
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), 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 filename(fn), name(n), priv(load_opt & QMLO_PRIVATE), injected(load_opt & QMLO_INJECT),
105 reinjected(load_opt & QMLO_REINJECT) {
106 q_normalize_path(filename, cwd);
107 }
108
109 DLLLOCAL virtual ~QoreAbstractModule() {
110 //printd(5, "QoreAbstractModule::~QoreAbstractModule() this: %p name: %s\n", this, name.c_str());
111 if (next) {
112 assert(next->prev == this);
113 next->prev = prev;
114 }
115 if (prev) {
116 assert(prev->next == this);
117 prev->next = next;
118 }
119 }
120
121 DLLLOCAL const char* getName() const {
122 return name.c_str();
123 }
124
125 DLLLOCAL const char* getFileName() const {
126 return filename.c_str();
127 }
128
129 DLLLOCAL const QoreString& getFileNameStr() const {
130 return filename;
131 }
132
133 DLLLOCAL const char* getDesc() const {
134 return desc.c_str();
135 }
136
137 DLLLOCAL const char* getVersion() const {
138 return* version_list;
139 }
140
141 DLLLOCAL const char* getURL() const {
142 return url.c_str();
143 }
144
145 DLLLOCAL const char* getOrigName() const {
146 return orig_name.empty() ? nullptr : orig_name.c_str();
147 }
148
149 DLLLOCAL void resetName() {
150 assert(!orig_name.empty());
151 name = orig_name;
152 orig_name.clear();
153 }
154
155 DLLLOCAL bool isInjected() const {
156 return injected;
157 }
158
159 DLLLOCAL bool isReInjected() const {
160 return reinjected;
161 }
162
163 DLLLOCAL void addModuleReExport(const char* m) {
164 rmod.push_back(m);
165 }
166
167 DLLLOCAL void reexport(ExceptionSink& xsink, QoreProgram* pgm) const;
168
169 DLLLOCAL void addToProgram(QoreProgram* pgm, ExceptionSink& xsink) const {
170 addToProgramImpl(pgm, xsink);
171 if (!xsink)
172 reexport(xsink, pgm);
173 }
174
175 DLLLOCAL bool equalTo(const QoreAbstractModule* m) const {
176 assert(name == m->name);
177 return filename == m->filename;
178 }
179
180 DLLLOCAL bool isPath(const char* p) const {
181 return filename == p;
182 }
183
184 DLLLOCAL void rename(const QoreString& n) {
185 assert(orig_name.empty());
186 name = n;
187 }
188
189 DLLLOCAL void setOrigName(const char* n) {
190 assert(orig_name.empty());
191 orig_name = n;
192 }
193
194 DLLLOCAL bool isPrivate() const {
195 return priv;
196 }
197
198 DLLLOCAL void setPrivate(bool p = true) {
199 assert(priv != p);
200 priv = p;
201 }
202
203 DLLLOCAL void setLink(QoreAbstractModule* n) {
204 //printd(5, "AbstractQoreModule::setLink() n: %p '%s'\n", n, n->getName());
205 assert(!next);
206 assert(!n->prev);
207 next = n;
208 n->prev = this;
209 }
210
211 DLLLOCAL QoreAbstractModule* getNext() const {
212 return next;
213 }
214
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)
219 = 0;
220
221protected:
222 QoreString filename,
223 name,
224 desc,
225 author,
226 url,
227 license,
228 orig_name;
229
230 // link to associated modules (originals with reinjection, etc)
231 QoreAbstractModule* prev = nullptr,
232 * next = nullptr;
233
234 bool priv : 1,
235 injected : 1,
236 reinjected : 1;
237
238 DLLLOCAL QoreHashNode* getHashIntern(bool with_filename = true) const;
239
240 DLLLOCAL virtual void addToProgramImpl(QoreProgram* pgm, ExceptionSink& xsink) const = 0;
241
242 DLLLOCAL void set(const char* d, const char* v, const char* a, const char* u, const QoreString& l) {
243 desc = d;
244 author = a;
245 url = u;
246 license = l;
247 version_list = v;
248 }
249
250private:
251 // not implemented
252 QoreAbstractModule(const QoreAbstractModule&) = delete;
253 QoreAbstractModule& operator=(const QoreAbstractModule&) = delete;
254};
255
256// list/dequeue of strings
257typedef std::deque<std::string> strdeque_t;
258
260
264protected:
265 typedef std::set<std::string> strset_t;
266
267 strdeque_t dlist;
268 strset_t dset;
269
270public:
271 DLLLOCAL void addDirList(const char* str);
272
273 DLLLOCAL bool push_back(const std::string &str) {
274 if (dset.find(str) != dset.end()) {
275 return false;
276 }
277 dlist.push_back(str);
278 dset.insert(str);
279 return true;
280 }
281
282 DLLLOCAL bool empty() const {
283 return dlist.empty();
284 }
285
286 DLLLOCAL strdeque_t::const_iterator begin() const {
287 return dlist.begin();
288 }
289
290 DLLLOCAL strdeque_t::const_iterator end() const {
291 return dlist.end();
292 }
293
294 DLLLOCAL void appendPath(QoreString& str) const {
295 if (dlist.empty()) {
296 str.concat("<empty>");
297 return;
298 }
299 for (strdeque_t::const_iterator i = dlist.begin(), e = dlist.end(); i != e; ++i) {
300 str.concat((*i).c_str());
301 str.concat(':');
302 }
303 str.terminate(str.size() - 1);
304 }
305};
306
307class QoreModuleContextHelper : public QoreModuleContext {
308public:
309 DLLLOCAL QoreModuleContextHelper(const char* name, QoreProgram* pgm, ExceptionSink& xsink);
310 DLLLOCAL ~QoreModuleContextHelper();
311};
312
313class QoreModuleDefContextHelper : public QoreModuleDefContext {
314protected:
315 QoreModuleDefContext* old;
316
317public:
318 DLLLOCAL QoreModuleDefContextHelper() : old(set_module_def_context(this)) {
319 }
320
321 DLLLOCAL ~QoreModuleDefContextHelper() {
322 set_module_def_context(old);
323 }
324};
325
326class QoreUserModuleDefContextHelper;
327class QoreUserModule;
328
329typedef std::set<std::string> strset_t;
330typedef std::map<std::string, strset_t> md_map_t;
331
332class ModMap {
333private:
334 DLLLOCAL ModMap(const ModMap &);
335 DLLLOCAL ModMap& operator=(const ModMap&);
336
337protected:
338 md_map_t map;
339
340public:
341 DLLLOCAL ModMap() {
342 }
343
344 DLLLOCAL ~ModMap() {
345 }
346
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()) {
352 return true;
353 }
354 i->second.insert(r);
355 return false;
356 }
357
358 DLLLOCAL md_map_t::iterator begin() {
359 return map.begin();
360 }
361
362 DLLLOCAL md_map_t::iterator end() {
363 return map.end();
364 }
365
366 DLLLOCAL md_map_t::iterator find(const char* n) {
367 return map.find(n);
368 }
369
370 DLLLOCAL md_map_t::iterator find(const std::string& n) {
371 return map.find(n);
372 }
373
374 DLLLOCAL void erase(md_map_t::iterator i) {
375 map.erase(i);
376 }
377
378 DLLLOCAL void clear() {
379 map.clear();
380 }
381
382 DLLLOCAL bool empty() const {
383 return map.empty();
384 }
385
386#ifdef DEBUG
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) {
390 QoreString str("[");
391 for (strset_t::iterator si = i->second.begin(), se = i->second.end(); si != se; ++si)
392 str.sprintf("'%s',", (*si).c_str());
393 str.concat("]");
394
395 printd(0, " + %s '%s' -> %s\n", name, i->first.c_str(), str.c_str());
396 }
397 }
398#endif
399};
400
401hashdecl DLHelper {
402 void* ptr;
403
404 DLLLOCAL DLHelper(void* p) : ptr(p) {
405 }
406
407 DLLLOCAL ~DLHelper() {
408 if (ptr)
409 dlclose(ptr);
410 }
411
412 DLLLOCAL void* release() {
413 void* rv = ptr;
414 ptr = nullptr;
415 return rv;
416 }
417};
418
419class QoreModuleManager {
420 friend class QoreAbstractModule;
421 friend class ModuleLoadMapHelper;
422
423public:
424 DLLLOCAL QoreModuleManager() {
425 }
426
427 DLLLOCAL ~QoreModuleManager() {
428 }
429
430 DLLLOCAL void init(bool se);
431 DLLLOCAL void delUser();
432 DLLLOCAL void cleanup();
433
434 DLLLOCAL void issueParseCmd(const QoreProgramLocation* loc, const char* mname, const QoreString& cmd);
435
436 DLLLOCAL void issueRuntimeCmd(const char* mname, QoreProgram* pgm, const QoreString& cmd, ExceptionSink* xsink);
437
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));
441 //printd(5, "QoreModuleManager::addModule() m: %p '%s'\n", m, m->getName());
442 }
443
444 DLLLOCAL QoreAbstractModule* findModule(const char* name) {
445 AutoLocker al(mutex);
446 return findModuleUnlocked(name);
447 }
448
449 DLLLOCAL int parseLoadModule(ExceptionSink& xsink, ExceptionSink& wsink, const char* name, QoreProgram* pgm,
450 bool reexport = false);
451 DLLLOCAL int runTimeLoadModule(ExceptionSink& xsink, ExceptionSink& wsink, const char* name, QoreProgram* pgm,
452 QoreProgram* mpgm = nullptr, unsigned load_opt = QMLO_NONE, int warning_mask = QP_WARN_MODULES,
453 bool reexport = false, qore_binary_module_desc_t mod_desc_func = nullptr);
454
455 DLLLOCAL QoreHashNode* getModuleHash();
456 DLLLOCAL QoreListNode* getModuleList();
457
458 DLLLOCAL void addModuleDir(const char* dir) {
459 AutoLocker al(mutex);
460 moduleDirList.push_back(dir);
461 }
462
463 DLLLOCAL void addModuleDirList(const char* strlist) {
464 AutoLocker al(mutex);
465 moduleDirList.addDirList(strlist);
466 }
467
468 DLLLOCAL void addStandardModulePaths();
469
470 DLLLOCAL void registerUserModuleFromSource(const char* name, const char* src, QoreProgram* pgm,
471 ExceptionSink& xsink);
472
473 DLLLOCAL void trySetUserModuleDependency(const QoreAbstractModule* mi) {
474 if (!mi->isUser())
475 return;
476
477 const char* old_name = get_module_context_name();
478 if (old_name)
479 setUserModuleDependency(mi->getName(), old_name);
480 trySetUserModule(mi->getName());
481 }
482
483 DLLLOCAL void trySetUserModule(const char* name) {
484 md_map_t::iterator i = md_map.find(name);
485 if (i == md_map.end()) {
486 umset.insert(name);
487 //printd(5, "QoreModuleManager::trySetUserModule('%s') UMSET SET: rmd_map: empty\n", name);
488 }
489#ifdef DEBUG
490 /*
491 else {
492 QoreString str("[");
493 for (strset_t::iterator si = i->second.begin(), se = i->second.end(); si != se; ++si)
494 str.sprintf("'%s',", (*si).c_str());
495 str.concat("]");
496 //printd(5, "QoreModuleManager::trySetUserModule('%s') UMSET NOT SET: md_map: %s\n", name, str.c_str());
497 }
498 */
499#endif
500 }
501
502 DLLLOCAL void setUserModuleDependency(const char* name, const char* dep) {
503 //printd(5, "QoreModuleManager::setUserModuleDependency('%s' -> '%s')\n", name, dep);
504 if (md_map.addDep(name, dep))
505 return;
506 rmd_map.addDep(dep, name);
507
508 strset_t::iterator ui = umset.find(name);
509 if (ui != umset.end()) {
510 umset.erase(ui);
511 //printd(5, "QoreModuleManager::setUserModuleDependency('%s' -> '%s') REMOVED '%s' FROM UMMSET\n", name,
512 // dep, name);
513 }
514 }
515
516 DLLLOCAL void removeUserModuleDependency(const char* name, const char* orig_name = 0) {
517 //printd(5, "QoreModuleManager::removeUserModuleDependency() name: '%s' orig: '%s'\n", name,
518 // orig_name ? orig_name : "n/a");
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()) {
523 // remove dependents
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());
527
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()) {
532 //printd(5, "QoreModuleManager::removeUserModuleDependency('%s') '%s' now empty, ADDING TO "
533 // "UMMSET: '%s'\n", name, i->first.c_str(), (*si).c_str());
534 //md_map.erase(di);
535 assert(umset.find(*si) == umset.end());
536 umset.insert(*si);
537 }
538 }
539 // remove from dep map
540 rmd_map.erase(i);
541 }
542
543 i = md_map.find(name);
544 if (i != md_map.end())
545 md_map.erase(i);
546 if (orig_name) {
547 i = md_map.find(orig_name);
548 if (i != md_map.end())
549 md_map.erase(i);
550 }
551 }
552
553private:
554 // not implemented
555 DLLLOCAL QoreModuleManager(const QoreModuleManager&);
556 // not implemented
557 DLLLOCAL QoreModuleManager& operator=(const QoreModuleManager&);
559 DLLLOCAL QoreAbstractModule* loadSeparatedModule(
560 ExceptionSink& xsink,
561 ExceptionSink& wsink,
562 const char* path,
563 const char* feature,
564 QoreProgram* tpgm,
565 bool reexport = false,
566 QoreProgram* pgm = nullptr,
567 QoreProgram* path_pgm = nullptr,
568 unsigned load_opt = QMLO_NONE,
569 int warning_mask = QP_WARN_MODULES);
570
571 typedef std::map<std::string, int> module_load_map_t;
572 QoreCondition module_load_cond;
573 // map feature names to TIDs when module initialization is in progress
574 module_load_map_t module_load_map;
575 // number of threads waiting on module_load_set
576 int module_load_waiting = 0;
577
578protected:
579 // mutex for atomicity
580 QoreThreadLock mutex;
581
582 // user module dependency map: module -> dependents
583 ModMap md_map;
584 // user module dependent map: dependent -> module
585 ModMap rmd_map;
586
587 // module blacklist
588 typedef std::map<const char*, const char*, ltstr> bl_map_t;
589 bl_map_t mod_blacklist;
590
591 // module hash
592 typedef std::map<const char*, QoreAbstractModule*, ltstr> module_map_t;
593 module_map_t map;
594
595 // set of user modules with no dependencies
596 strset_t umset;
597
598 // list of module directories
599 UniqueDirectoryList moduleDirList;
600
601 DLLLOCAL QoreAbstractModule* findModuleUnlocked(const char* name) {
602 module_map_t::iterator i = map.find(name);
603 return i == map.end() ? 0 : i->second;
604 }
605
606 DLLLOCAL QoreAbstractModule* loadModuleIntern(const char* name, QoreProgram* pgm, ExceptionSink& xsink) {
607 AutoLocker sl(mutex); // make sure checking and loading are atomic
608
609 return loadModuleIntern(xsink, xsink, name, pgm);
610 }
611
612 DLLLOCAL QoreAbstractModule* loadModuleIntern(ExceptionSink& xsink, ExceptionSink& wsink, const char* name,
613 QoreProgram* pgm, bool reexport = false, mod_op_e op = MOD_OP_NONE, version_list_t* version = nullptr,
614 const char* src = nullptr, QoreProgram* mpgm = nullptr, unsigned load_opt = QMLO_NONE,
615 int warning_mask = QP_WARN_MODULES, qore_binary_module_desc_t mod_desc_func = nullptr);
616
617 DLLLOCAL QoreAbstractModule* loadBinaryModuleFromPath(ExceptionSink& xsink, const char* path,
618 const char* feature = nullptr, QoreProgram* pgm = nullptr, bool reexport = false,
619 qore_binary_module_desc_t mod_desc = nullptr);
620
621 DLLLOCAL QoreAbstractModule* loadBinaryModuleFromDesc(ExceptionSink& xsink, DLHelper* dlh,
622 QoreModuleInfo& mod_info, const char* path, const char* feature = nullptr, QoreProgram* pgm = nullptr,
623 bool reexport = false);
624
625 DLLLOCAL QoreAbstractModule* loadUserModuleFromPath(ExceptionSink& xsink, ExceptionSink& wsink, const char* path,
626 const char* feature = nullptr, QoreProgram* tpgm = nullptr, bool reexport = false,
627 QoreProgram* pgm = nullptr, QoreProgram* path_pgm = nullptr, unsigned load_opt = QMLO_NONE,
628 int warning_mask = QP_WARN_MODULES);
629
630 DLLLOCAL QoreAbstractModule* loadUserModuleFromSource(ExceptionSink& xsink, ExceptionSink& wsink,
631 const char* path, const char* feature, QoreProgram* tpgm, const char* src, bool reexport,
632 QoreProgram* pgm = nullptr, int warning_mask = QP_WARN_MODULES);
633
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);
636
637 DLLLOCAL void reinjectModule(QoreAbstractModule* mi);
638 DLLLOCAL void delOrig(QoreAbstractModule* mi);
639 DLLLOCAL void getUniqueName(QoreString& nname, const char* name, const char* prefix);
640};
641
642DLLLOCAL extern QoreModuleManager QMM;
643
644class QoreBuiltinModule : public QoreAbstractModule {
645protected:
646 unsigned api_major, api_minor;
647 qore_module_init_t module_init;
648 qore_module_ns_init_t module_ns_init;
649 qore_module_delete_t module_delete;
650 qore_module_parse_cmd_t module_parse_cmd;
651 QoreHashNode* info;
652 const void* dlptr;
653
654 DLLLOCAL virtual void addToProgramImpl(QoreProgram* pgm, ExceptionSink& xsink) const override;
655
656public:
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,
660 qore_module_parse_cmd_t pcmd, const void* p, QoreHashNode* info = nullptr)
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) {
663 }
664
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);
668 module_delete();
669 // we do not close binary modules because we may have thread local data that needs to be
670 // destroyed when exit() is called
671 }
672
673 DLLLOCAL unsigned getAPIMajor() const {
674 return api_major;
675 }
676
677 DLLLOCAL unsigned getAPIMinor() const {
678 return api_minor;
679 }
680
681 DLLLOCAL virtual bool isBuiltin() const override {
682 return true;
683 }
684
685 DLLLOCAL virtual bool isUser() const override {
686 return false;
687 }
688
689 DLLLOCAL QoreHashNode* getHash(bool with_filename = true) const override;
690
691 DLLLOCAL const void* getPtr() const {
692 return dlptr;
693 }
694
695 DLLLOCAL virtual void issueModuleCmd(const QoreProgramLocation* loc, const QoreString& cmd, ExceptionSink* xsink)
696 override;
697};
698
699class QoreUserModule : public QoreAbstractModule {
700protected:
701 QoreProgram* pgm;
702 AbstractQoreNode* del = nullptr; // deletion closure / call reference
703
704 DLLLOCAL virtual void addToProgramImpl(QoreProgram* pgm, ExceptionSink& xsink) const override;
705
706public:
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) {
709 }
710
711 DLLLOCAL void set(const char* d, const char* v, const char* a, const char* u, const QoreString& l,
712 AbstractQoreNode* dl) {
713 QoreAbstractModule::set(d, v, a, u, l);
714 del = dl;
715 }
716
717 DLLLOCAL QoreProgram* getProgram() const {
718 return pgm;
719 }
720
721 DLLLOCAL virtual ~QoreUserModule();
722
723 DLLLOCAL virtual bool isBuiltin() const override {
724 return false;
725 }
726
727 DLLLOCAL virtual bool isUser() const override {
728 return true;
729 }
730
731 DLLLOCAL virtual QoreHashNode* getHash(bool with_filename = true) const override {
732 return getHashIntern(with_filename);
733 }
734
735 DLLLOCAL virtual void issueModuleCmd(const QoreProgramLocation* loc, const QoreString& cmd,
736 ExceptionSink* xsink) override {
737 if (xsink) {
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());
740 }
741 }
742};
743
744class QoreModuleNameContextHelper {
745public:
746 DLLLOCAL QoreModuleNameContextHelper(const char* name) : old_name(set_module_context_name(name)) {
747 }
748
749 DLLLOCAL ~QoreModuleNameContextHelper() {
750 set_module_context_name(old_name);
751 }
752
753protected:
754 const char* old_name;
755};
756
757class QoreUserModuleDefContextHelper : public QoreModuleDefContextHelper {
758public:
759 DLLLOCAL QoreUserModuleDefContextHelper(const char* name, QoreProgram* p, ExceptionSink& xs);
760
761 DLLLOCAL ~QoreUserModuleDefContextHelper() {
762 const char* name = set_module_context_name(old_name);
763
764 if (xsink && !dup)
765 QMM.removeUserModuleDependency(name);
766 }
767
768 DLLLOCAL void setDuplicate() {
769 assert(!dup);
770 dup = true;
771 }
772
773 DLLLOCAL void setNameInit(const char* name);
774
775 DLLLOCAL void close();
776
777protected:
778 const char* old_name;
779
780 qore_program_private* pgm;
781 int64 po;
782
783 ExceptionSink& xsink;
784 bool dup;
785};
786
787class ModuleLoadMapHelper {
788public:
789 DLLLOCAL ModuleLoadMapHelper(const char* feature);
790 DLLLOCAL ~ModuleLoadMapHelper();
791
792private:
793 QoreModuleManager::module_load_map_t::iterator i;
794};
795
796#endif
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