Qore Programming Language  0.9.4.6
ModuleInfo.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3  ModuleInfo.h
4 
5  Qore Programming Language
6 
7  Copyright (C) 2003 - 2019 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
37 extern "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 
64 hashdecl version_list_t : public std::vector<int> {
65 protected:
66  QoreString ver;
67 
68 public:
69  DLLLOCAL version_list_t() {
70  }
71 
72  DLLLOCAL version_list_t(const char* v) {
73  set(v);
74  }
75 
76  DLLLOCAL char set(const char* v);
77 
78  DLLLOCAL version_list_t& operator=(const char* v) {
79  set(v);
80  return *this;
81  }
82 
83  DLLLOCAL const char* operator*() const {
84  return ver.getBuffer();
85  }
86 };
87 
88 class QoreAbstractModule {
89 private:
90  // not implemented
91  DLLLOCAL QoreAbstractModule(const QoreAbstractModule&);
92  DLLLOCAL QoreAbstractModule& operator=(const QoreAbstractModule&);
93 
94 protected:
95  QoreString filename,
96  name,
97  desc,
98  author,
99  url,
100  license,
101  orig_name;
102 
103  // link to associated modules (originals with reinjection, etc)
104  QoreAbstractModule* prev = nullptr,
105  * next = nullptr;
106 
107  bool priv : 1,
108  injected : 1,
109  reinjected : 1;
110 
111  DLLLOCAL QoreHashNode* getHashIntern(bool with_filename = true) const;
112 
113  DLLLOCAL virtual void addToProgramImpl(QoreProgram* pgm, ExceptionSink& xsink) const = 0;
114 
115  DLLLOCAL void set(const char* d, const char* v, const char* a, const char* u, const QoreString& l) {
116  desc = d;
117  author = a;
118  url = u;
119  license = l;
120  version_list = v;
121  }
122 
123 public:
124  version_list_t version_list;
125  // list of dependent modules to reexport
126  name_vec_t rmod;
127 
128  // for binary modules
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) {
132  q_normalize_path(filename, cwd);
133  }
134 
135  // for user modules
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) {
139  q_normalize_path(filename, cwd);
140  }
141 
142  DLLLOCAL virtual ~QoreAbstractModule() {
143  //printd(5, "QoreAbstractModule::~QoreAbstractModule() this: %p name: %s\n", this, name.getBuffer());
144  if (next) {
145  assert(next->prev == this);
146  next->prev = prev;
147  }
148  if (prev) {
149  assert(prev->next == this);
150  prev->next = next;
151  }
152  }
153 
154  DLLLOCAL const char* getName() const {
155  return name.getBuffer();
156  }
157 
158  DLLLOCAL const char* getFileName() const {
159  return filename.getBuffer();
160  }
161 
162  DLLLOCAL const QoreString& getFileNameStr() const {
163  return filename;
164  }
165 
166  DLLLOCAL const char* getDesc() const {
167  return desc.getBuffer();
168  }
169 
170  DLLLOCAL const char* getVersion() const {
171  return* version_list;
172  }
173 
174  DLLLOCAL const char* getURL() const {
175  return url.getBuffer();
176  }
177 
178  DLLLOCAL const char* getOrigName() const {
179  return orig_name.empty() ? 0 : orig_name.getBuffer();
180  }
181 
182  DLLLOCAL void resetName() {
183  assert(!orig_name.empty());
184  name = orig_name;
185  orig_name.clear();
186  }
187 
188  DLLLOCAL bool isInjected() const {
189  return injected;
190  }
191 
192  DLLLOCAL bool isReInjected() const {
193  return reinjected;
194  }
195 
196  DLLLOCAL void addModuleReExport(const char* m) {
197  rmod.push_back(m);
198  }
199 
200  DLLLOCAL void reexport(ExceptionSink& xsink, QoreProgram* pgm) const;
201 
202  DLLLOCAL void addToProgram(QoreProgram* pgm, ExceptionSink& xsink) const {
203  addToProgramImpl(pgm, xsink);
204  if (!xsink)
205  reexport(xsink, pgm);
206  }
207 
208  DLLLOCAL bool equalTo(const QoreAbstractModule* m) const {
209  assert(name == m->name);
210  return filename == m->filename;
211  }
212 
213  DLLLOCAL bool isPath(const char* p) const {
214  return filename == p;
215  }
216 
217  DLLLOCAL void rename(const QoreString& n) {
218  assert(orig_name.empty());
219  name = n;
220  }
221 
222  DLLLOCAL void setOrigName(const char* n) {
223  assert(orig_name.empty());
224  orig_name = n;
225  }
226 
227  DLLLOCAL bool isPrivate() const {
228  return priv;
229  }
230 
231  DLLLOCAL void setPrivate(bool p = true) {
232  assert(priv != p);
233  priv = p;
234  }
235 
236  DLLLOCAL void setLink(QoreAbstractModule* n) {
237  //printd(5, "AbstractQoreModule::setLink() n: %p '%s'\n", n, n->getName());
238  assert(!next);
239  assert(!n->prev);
240  next = n;
241  n->prev = this;
242  }
243 
244  DLLLOCAL QoreAbstractModule* getNext() const {
245  return next;
246  }
247 
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;
252 };
253 
254 // list/dequeue of strings
255 typedef std::deque<std::string> strdeque_t;
256 
258 
262 protected:
263  typedef std::set<std::string> strset_t;
264 
265  strdeque_t dlist;
266  strset_t dset;
267 
268 public:
269  DLLLOCAL void addDirList(const char* str);
270 
271  DLLLOCAL bool push_back(const std::string &str) {
272  if (dset.find(str) != dset.end()) {
273  return false;
274  }
275  dlist.push_back(str);
276  dset.insert(str);
277  return true;
278  }
279 
280  DLLLOCAL bool empty() const {
281  return dlist.empty();
282  }
283 
284  DLLLOCAL strdeque_t::const_iterator begin() const {
285  return dlist.begin();
286  }
287 
288  DLLLOCAL strdeque_t::const_iterator end() const {
289  return dlist.end();
290  }
291 
292  DLLLOCAL void appendPath(QoreString& str) const {
293  if (dlist.empty()) {
294  str.concat("<empty>");
295  return;
296  }
297  for (strdeque_t::const_iterator i = dlist.begin(), e = dlist.end(); i != e; ++i) {
298  str.concat((*i).c_str());
299  str.concat(':');
300  }
301  str.terminate(str.size() - 1);
302  }
303 };
304 
305 class QoreModuleContextHelper : public QoreModuleContext {
306 public:
307  DLLLOCAL QoreModuleContextHelper(const char* name, QoreProgram* pgm, ExceptionSink& xsink);
308  DLLLOCAL ~QoreModuleContextHelper();
309 };
310 
311 class QoreModuleDefContextHelper : public QoreModuleDefContext {
312 protected:
313  QoreModuleDefContext* old;
314 
315 public:
316  DLLLOCAL QoreModuleDefContextHelper() : old(set_module_def_context(this)) {
317  }
318 
319  DLLLOCAL ~QoreModuleDefContextHelper() {
320  set_module_def_context(old);
321  }
322 };
323 
324 class QoreUserModuleDefContextHelper;
325 class QoreUserModule;
326 
327 typedef std::set<std::string> strset_t;
328 typedef std::map<std::string, strset_t> md_map_t;
329 
330 class ModMap {
331 private:
332  DLLLOCAL ModMap(const ModMap &);
333  DLLLOCAL ModMap& operator=(const ModMap&);
334 
335 protected:
336  md_map_t map;
337 
338 public:
339  DLLLOCAL ModMap() {
340  }
341 
342  DLLLOCAL ~ModMap() {
343  }
344 
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())
350  return true;
351  i->second.insert(r);
352  return false;
353  }
354 
355  DLLLOCAL md_map_t::iterator begin() {
356  return map.begin();
357  }
358 
359  DLLLOCAL md_map_t::iterator end() {
360  return map.end();
361  }
362 
363  DLLLOCAL md_map_t::iterator find(const char* n) {
364  return map.find(n);
365  }
366 
367  DLLLOCAL md_map_t::iterator find(const std::string& n) {
368  return map.find(n);
369  }
370 
371  DLLLOCAL void erase(md_map_t::iterator i) {
372  map.erase(i);
373  }
374 
375  DLLLOCAL void clear() {
376  map.clear();
377  }
378 
379  DLLLOCAL bool empty() const {
380  return map.empty();
381  }
382 
383 #ifdef DEBUG
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) {
387  QoreString str("[");
388  for (strset_t::iterator si = i->second.begin(), se = i->second.end(); si != se; ++si)
389  str.sprintf("'%s',", (*si).c_str());
390  str.concat("]");
391 
392  printd(0, " + %s '%s' -> %s\n", name, i->first.c_str(), str.getBuffer());
393  }
394  }
395 #endif
396 };
397 
398 class QoreModuleManager {
399  friend class QoreAbstractModule;
400 
401 private:
402  // not implemented
403  DLLLOCAL QoreModuleManager(const QoreModuleManager&);
404  // not implemented
405  DLLLOCAL QoreModuleManager& operator=(const QoreModuleManager&);
407  DLLLOCAL QoreAbstractModule* loadSeparatedModule(
408  ExceptionSink& xsink,
409  ExceptionSink& wsink,
410  const QoreString& path,
411  const char* feature,
412  QoreProgram* tpgm,
413  bool reexport = false,
414  QoreProgram* pgm = nullptr,
415  QoreProgram* path_pgm = nullptr,
416  unsigned load_opt = QMLO_NONE,
417  int warning_mask = QP_WARN_MODULES);
418 
419 protected:
420  // recursive mutex; initialized in init()
421  QoreThreadLock* mutex;
422 
423  // user module dependency map: module -> dependents
424  ModMap md_map;
425  // user module dependent map: dependent -> module
426  ModMap rmd_map;
427 
428  // module blacklist
429  typedef std::map<const char*, const char*, ltstr> bl_map_t;
430  bl_map_t mod_blacklist;
431 
432  // module hash
433  typedef std::map<const char*, QoreAbstractModule*, ltstr> module_map_t;
434  module_map_t map;
435 
436  // set of user modules with no dependencies
437  strset_t umset;
438 
439  // list of module directories
440  UniqueDirectoryList moduleDirList;
441 
442  DLLLOCAL QoreAbstractModule* findModuleUnlocked(const char* name) {
443  module_map_t::iterator i = map.find(name);
444  return i == map.end() ? 0 : i->second;
445  }
446 
447  DLLLOCAL void loadModuleIntern(const char* name, QoreProgram* pgm, ExceptionSink& xsink) {
448  AutoLocker sl(mutex); // make sure checking and loading are atomic
449 
450  loadModuleIntern(xsink, xsink, name, pgm);
451  }
452 
453  DLLLOCAL void loadModuleIntern(ExceptionSink& xsink, ExceptionSink& wsink, const char* name, QoreProgram* pgm,
454  bool reexport = false, mod_op_e op = MOD_OP_NONE, version_list_t* version = nullptr,
455  const char* src = nullptr, QoreProgram* mpgm = nullptr, unsigned load_opt = QMLO_NONE,
456  int warning_mask = QP_WARN_MODULES);
457 
458  DLLLOCAL QoreAbstractModule* loadBinaryModuleFromPath(ExceptionSink& xsink, const char* path, const char* feature = 0, QoreProgram* pgm = 0, bool reexport = false);
459  DLLLOCAL QoreAbstractModule* loadUserModuleFromPath(ExceptionSink& xsink, ExceptionSink& wsink, const char* path,
460  const char* feature = nullptr, QoreProgram* tpgm = nullptr, bool reexport = false, QoreProgram* pgm = nullptr,
461  QoreProgram* path_pgm = nullptr, unsigned load_opt = QMLO_NONE, int warning_mask = QP_WARN_MODULES);
462  DLLLOCAL QoreAbstractModule* loadUserModuleFromSource(ExceptionSink& xsink, ExceptionSink& wsink, const char* path,
463  const char* feature, QoreProgram* tpgm, const char* src, bool reexport, QoreProgram* pgm = nullptr,
464  int warning_mask = QP_WARN_MODULES);
465  DLLLOCAL QoreAbstractModule* setupUserModule(ExceptionSink& xsink, std::unique_ptr<QoreUserModule>& mi,
466  QoreUserModuleDefContextHelper& qmd, unsigned load_opt = QMLO_NONE, int warning_mask = QP_WARN_MODULES);
467 
468  DLLLOCAL void reinjectModule(QoreAbstractModule* mi);
469  DLLLOCAL void delOrig(QoreAbstractModule* mi);
470  DLLLOCAL void getUniqueName(QoreString& nname, const char* name, const char* prefix);
471 
472 public:
473  DLLLOCAL QoreModuleManager() : mutex(0) {
474  }
475 
476  DLLLOCAL ~QoreModuleManager() {
477  delete mutex;
478  }
479 
480  DLLLOCAL void init(bool se);
481  DLLLOCAL void delUser();
482  DLLLOCAL void cleanup();
483 
484  DLLLOCAL void issueParseCmd(const QoreProgramLocation* loc, const char* mname, const QoreString& cmd);
485 
486  DLLLOCAL void issueRuntimeCmd(const char* mname, QoreProgram* pgm, const QoreString& cmd, ExceptionSink* xsink);
487 
488  DLLLOCAL void addModule(QoreAbstractModule* m) {
489  assert(map.find(m->getName()) == map.end());
490  map.insert(module_map_t::value_type(m->getName(), m));
491  }
492 
493  DLLLOCAL QoreAbstractModule* findModule(const char* name) {
494  AutoLocker al(mutex);
495  return findModuleUnlocked(name);
496  }
497 
498  DLLLOCAL void parseLoadModule(ExceptionSink& xsink, ExceptionSink& wsink, const char* name, QoreProgram* pgm,
499  bool reexport = false);
500  DLLLOCAL int runTimeLoadModule(ExceptionSink& xsink, ExceptionSink& wsink, const char* name, QoreProgram* pgm,
501  QoreProgram* mpgm = nullptr, unsigned load_opt = QMLO_NONE, int warning_mask = QP_WARN_MODULES,
502  bool reexport = false);
503 
504  DLLLOCAL QoreHashNode* getModuleHash();
505  DLLLOCAL QoreListNode* getModuleList();
506 
507  DLLLOCAL void addModuleDir(const char* dir) {
508  OptLocker al(mutex);
509  moduleDirList.push_back(dir);
510  }
511 
512  DLLLOCAL void addModuleDirList(const char* strlist) {
513  OptLocker al(mutex);
514  moduleDirList.addDirList(strlist);
515  }
516 
517  DLLLOCAL void addStandardModulePaths();
518 
519  DLLLOCAL void registerUserModuleFromSource(const char* name, const char* src, QoreProgram *pgm, ExceptionSink& xsink);
520 
521  DLLLOCAL void trySetUserModuleDependency(const QoreAbstractModule* mi) {
522  if (!mi->isUser())
523  return;
524 
525  const char* old_name = get_user_module_context_name();
526  if (old_name)
527  setUserModuleDependency(mi->getName(), old_name);
528  trySetUserModule(mi->getName());
529  }
530 
531  DLLLOCAL void trySetUserModule(const char* name) {
532  md_map_t::iterator i = md_map.find(name);
533  if (i == md_map.end()) {
534  umset.insert(name);
535  //printd(5, "QoreModuleManager::trySetUserModule('%s') UMSET SET: rmd_map: empty\n", name);
536  }
537 #ifdef DEBUG
538  /*
539  else {
540  QoreString str("[");
541  for (strset_t::iterator si = i->second.begin(), se = i->second.end(); si != se; ++si)
542  str.sprintf("'%s',", (*si).c_str());
543  str.concat("]");
544  //printd(5, "QoreModuleManager::trySetUserModule('%s') UMSET NOT SET: md_map: %s\n", name, str.getBuffer());
545  }
546  */
547 #endif
548  }
549 
550  DLLLOCAL void setUserModuleDependency(const char* name, const char* dep) {
551  //printd(5, "QoreModuleManager::setUserModuleDependency('%s' -> '%s')\n", name, dep);
552  if (md_map.addDep(name, dep))
553  return;
554  rmd_map.addDep(dep, name);
555 
556  strset_t::iterator ui = umset.find(name);
557  if (ui != umset.end()) {
558  umset.erase(ui);
559  //printd(5, "QoreModuleManager::setUserModuleDependency('%s' -> '%s') REMOVED '%s' FROM UMMSET\n", name, dep, name);
560  }
561  }
562 
563  DLLLOCAL void removeUserModuleDependency(const char* name, const char* orig_name = 0) {
564  //printd(5, "QoreModuleManager::removeUserModuleDependency() name: '%s' orig: '%s'\n", name, orig_name ? orig_name : "n/a");
565  md_map_t::iterator i = rmd_map.find(name);
566  if (i == rmd_map.end() && orig_name)
567  i = rmd_map.find(orig_name);
568  if (i != rmd_map.end()) {
569  // remove dependents
570  for (strset_t::iterator si = i->second.begin(), se = i->second.end(); si != se; ++si) {
571  md_map_t::iterator di = md_map.find(*si);
572  assert(di != md_map.end());
573 
574  strset_t::iterator dsi = di->second.find(i->first);
575  assert(dsi != di->second.end());
576  di->second.erase(dsi);
577  if (di->second.empty()) {
578  //printd(5, "QoreModuleManager::removeUserModuleDependency('%s') '%s' now empty, ADDING TO UMMSET: '%s'\n", name, i->first.c_str(), (*si).c_str());
579  //md_map.erase(di);
580  assert(umset.find(*si) == umset.end());
581  umset.insert(*si);
582  }
583  }
584  // remove from dep map
585  rmd_map.erase(i);
586  }
587 
588  i = md_map.find(name);
589  if (i != md_map.end())
590  md_map.erase(i);
591  if (orig_name) {
592  i = md_map.find(orig_name);
593  if (i != md_map.end())
594  md_map.erase(i);
595  }
596  }
597 };
598 
599 DLLLOCAL extern QoreModuleManager QMM;
600 
601 class QoreBuiltinModule : public QoreAbstractModule {
602 protected:
603  unsigned api_major, api_minor;
604  qore_module_init_t module_init;
605  qore_module_ns_init_t module_ns_init;
606  qore_module_delete_t module_delete;
607  qore_module_parse_cmd_t module_parse_cmd;
608  const void* dlptr;
609 
610  DLLLOCAL virtual void addToProgramImpl(QoreProgram* pgm, ExceptionSink& xsink) const override;
611 
612 public:
613  DLLLOCAL QoreBuiltinModule(const char* cwd, const char* fn, const char* n, const char* d, const char* v, const char* a, const char* u, const QoreString& l, unsigned major, unsigned minor, qore_module_init_t init, qore_module_ns_init_t ns_init, qore_module_delete_t del, qore_module_parse_cmd_t pcmd, const void* p) : QoreAbstractModule(cwd, fn, n, d, v, a, u, l), api_major(major), api_minor(minor), module_init(init), module_ns_init(ns_init), module_delete(del), module_parse_cmd(pcmd), dlptr(p) {
614  }
615 
616  DLLLOCAL virtual ~QoreBuiltinModule() {
617  printd(5, "QoreBuiltinModule::~QoreBuiltinModule() '%s': %s calling module_delete: %p\n", name.getBuffer(), filename.getBuffer(), module_delete);
618  module_delete();
619  // we do not close binary modules because we may have thread local data that needs to be
620  // destroyed when exit() is called
621  }
622 
623  DLLLOCAL unsigned getAPIMajor() const {
624  return api_major;
625  }
626 
627  DLLLOCAL unsigned getAPIMinor() const {
628  return api_minor;
629  }
630 
631  DLLLOCAL virtual bool isBuiltin() const override {
632  return true;
633  }
634 
635  DLLLOCAL virtual bool isUser() const override {
636  return false;
637  }
638 
639  DLLLOCAL QoreHashNode* getHash(bool with_filename = true) const override;
640 
641  DLLLOCAL const void* getPtr() const {
642  return dlptr;
643  }
644 
645  DLLLOCAL virtual void issueModuleCmd(const QoreProgramLocation* loc, const QoreString& cmd, ExceptionSink* xsink) override;
646 };
647 
648 class QoreUserModule : public QoreAbstractModule {
649 protected:
650  QoreProgram* pgm;
651  AbstractQoreNode* del = nullptr; // deletion closure / call reference
652 
653  DLLLOCAL virtual void addToProgramImpl(QoreProgram* pgm, ExceptionSink& xsink) const override;
654 
655 public:
656  DLLLOCAL QoreUserModule(const char* cwd, const char* fn, const char* n, QoreProgram* p, unsigned load_opt,
657  int warning_mask = QP_WARN_MODULES) : QoreAbstractModule(cwd, fn, n, load_opt), pgm(p) {
658  }
659 
660  DLLLOCAL void set(const char* d, const char* v, const char* a, const char* u, const QoreString& l, AbstractQoreNode* dl) {
661  QoreAbstractModule::set(d, v, a, u, l);
662  del = dl;
663  }
664 
665  DLLLOCAL QoreProgram* getProgram() const {
666  return pgm;
667  }
668 
669  DLLLOCAL virtual ~QoreUserModule();
670 
671  DLLLOCAL virtual bool isBuiltin() const override {
672  return false;
673  }
674 
675  DLLLOCAL virtual bool isUser() const override {
676  return true;
677  }
678 
679  DLLLOCAL virtual QoreHashNode* getHash(bool with_filename = true) const override {
680  return getHashIntern(with_filename);
681  }
682 
683  DLLLOCAL virtual void issueModuleCmd(const QoreProgramLocation* loc, const QoreString& cmd, ExceptionSink* xsink) override {
684  if (xsink) {
685  xsink->raiseException(*loc, "PARSE-COMMAND-ERROR", "module '%s' loaded from '%s' is a user module; only builtin modules can support parse commands",
686  name.c_str(), filename.c_str());
687  }
688  }
689 };
690 
691 class QoreUserModuleDefContextHelper : public QoreModuleDefContextHelper {
692 public:
693  DLLLOCAL QoreUserModuleDefContextHelper(const char* name, QoreProgram* p, ExceptionSink& xs);
694 
695  DLLLOCAL ~QoreUserModuleDefContextHelper() {
696  const char* name = set_user_module_context_name(old_name);
697 
698  if (xsink && !dup)
699  QMM.removeUserModuleDependency(name);
700  }
701 
702  DLLLOCAL void setDuplicate() {
703  assert(!dup);
704  dup = true;
705  }
706 
707  DLLLOCAL void setNameInit(const char* name);
708 
709  DLLLOCAL void close();
710 
711 protected:
712  const char* old_name;
713 
714  qore_program_private* pgm;
715  int64 po;
716 
717  ExceptionSink& xsink;
718  bool dup;
719 };
720 
721 #endif
void(* qore_module_delete_t)()
signature of the module destructor function
Definition: ModuleManager.h:75
DLLEXPORT bool empty() const
returns true if the string is empty, false if not
This is the hash or associative list container type in Qore, dynamically allocated only...
Definition: QoreHashNode.h:50
DLLEXPORT int sprintf(const char *fmt,...)
this will concatentate a formatted string to the existing string according to the format string and t...
The base class for all value and parse types in Qore expression trees.
Definition: AbstractQoreNode.h:54
void(* qore_module_ns_init_t)(QoreNamespace *root_ns, QoreNamespace *qore_ns)
signature of the module namespace change/delta function
Definition: ModuleManager.h:72
DLLEXPORT AbstractQoreNode * raiseException(const char *err, const char *fmt,...)
appends a Qore-language exception to the list
void(* qore_module_parse_cmd_t)(const QoreString &cmd, ExceptionSink *xsink)
signature of the module parse command function
Definition: ModuleManager.h:78
non-thread-safe unique list of strings of directory names
Definition: ModuleInfo.h:261
Qore&#39;s string type supported by the QoreEncoding class.
Definition: QoreString.h:81
DLLEXPORT const char * getBuffer() const
returns the string&#39;s buffer; this data should not be changed
DLLEXPORT QoreProgram * getProgram()
returns the current QoreProgram
DLLEXPORT void concat(const QoreString *str, ExceptionSink *xsink)
concatenates a string and converts encodings if necessary
provides a safe and exception-safe way to hold locks in Qore, only to be used on the stack...
Definition: QoreThreadLock.h:128
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition: QoreListNode.h:52
provides a safe and exception-safe way to hold optional locks in Qore, only to be used on the stack...
Definition: QoreThreadLock.h:300
supports parsing and executing Qore-language code, reference counted, dynamically-allocated only ...
Definition: QoreProgram.h:126
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:46
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
list of version numbers in order of importance (i.e. 1.2.3 = 1, 2, 3)
Definition: ModuleInfo.h:64
DLLEXPORT void terminate(qore_size_t size)
terminates the string at byte position "size", the string is reallocated if necessary ...
provides a mutually-exclusive thread lock
Definition: QoreThreadLock.h:47
DLLEXPORT void q_normalize_path(QoreString &path, const char *cwd=0)
normalizes the given path for the current platform in place (makes absolute, removes "...
DLLEXPORT void clear()
reset string to zero length; memory is not deallocated; string encoding does not change ...
DLLEXPORT qore_size_t size() const
returns number of bytes in the string (not including the null pointer)
QoreStringNode *(* qore_module_init_t)()
signature of the module constructor/initialization function
Definition: ModuleManager.h:69