Qore Programming Language  0.9.3.2
ModuleInfo.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3  ModuleInfo.h
4 
5  Qore Programming Language
6 
7  Copyright (C) 2003 - 2018 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 
503  DLLLOCAL QoreHashNode* getModuleHash();
504  DLLLOCAL QoreListNode* getModuleList();
505 
506  DLLLOCAL void addModuleDir(const char* dir) {
507  OptLocker al(mutex);
508  moduleDirList.push_back(dir);
509  }
510 
511  DLLLOCAL void addModuleDirList(const char* strlist) {
512  OptLocker al(mutex);
513  moduleDirList.addDirList(strlist);
514  }
515 
516  DLLLOCAL void addStandardModulePaths();
517 
518  DLLLOCAL void registerUserModuleFromSource(const char* name, const char* src, QoreProgram *pgm, ExceptionSink& xsink);
519 
520  DLLLOCAL void trySetUserModuleDependency(const QoreAbstractModule* mi) {
521  if (!mi->isUser())
522  return;
523 
524  const char* old_name = get_user_module_context_name();
525  if (old_name)
526  setUserModuleDependency(mi->getName(), old_name);
527  trySetUserModule(mi->getName());
528  }
529 
530  DLLLOCAL void trySetUserModule(const char* name) {
531  md_map_t::iterator i = md_map.find(name);
532  if (i == md_map.end()) {
533  umset.insert(name);
534  //printd(5, "QoreModuleManager::trySetUserModule('%s') UMSET SET: rmd_map: empty\n", name);
535  }
536 #ifdef DEBUG
537  /*
538  else {
539  QoreString str("[");
540  for (strset_t::iterator si = i->second.begin(), se = i->second.end(); si != se; ++si)
541  str.sprintf("'%s',", (*si).c_str());
542  str.concat("]");
543  //printd(5, "QoreModuleManager::trySetUserModule('%s') UMSET NOT SET: md_map: %s\n", name, str.getBuffer());
544  }
545  */
546 #endif
547  }
548 
549  DLLLOCAL void setUserModuleDependency(const char* name, const char* dep) {
550  //printd(5, "QoreModuleManager::setUserModuleDependency('%s' -> '%s')\n", name, dep);
551  if (md_map.addDep(name, dep))
552  return;
553  rmd_map.addDep(dep, name);
554 
555  strset_t::iterator ui = umset.find(name);
556  if (ui != umset.end()) {
557  umset.erase(ui);
558  //printd(5, "QoreModuleManager::setUserModuleDependency('%s' -> '%s') REMOVED '%s' FROM UMMSET\n", name, dep, name);
559  }
560  }
561 
562  DLLLOCAL void removeUserModuleDependency(const char* name, const char* orig_name = 0) {
563  //printd(5, "QoreModuleManager::removeUserModuleDependency() name: '%s' orig: '%s'\n", name, orig_name ? orig_name : "n/a");
564  md_map_t::iterator i = rmd_map.find(name);
565  if (i == rmd_map.end() && orig_name)
566  i = rmd_map.find(orig_name);
567  if (i != rmd_map.end()) {
568  // remove dependents
569  for (strset_t::iterator si = i->second.begin(), se = i->second.end(); si != se; ++si) {
570  md_map_t::iterator di = md_map.find(*si);
571  assert(di != md_map.end());
572 
573  strset_t::iterator dsi = di->second.find(i->first);
574  assert(dsi != di->second.end());
575  di->second.erase(dsi);
576  if (di->second.empty()) {
577  //printd(5, "QoreModuleManager::removeUserModuleDependency('%s') '%s' now empty, ADDING TO UMMSET: '%s'\n", name, i->first.c_str(), (*si).c_str());
578  //md_map.erase(di);
579  assert(umset.find(*si) == umset.end());
580  umset.insert(*si);
581  }
582  }
583  // remove from dep map
584  rmd_map.erase(i);
585  }
586 
587  i = md_map.find(name);
588  if (i != md_map.end())
589  md_map.erase(i);
590  if (orig_name) {
591  i = md_map.find(orig_name);
592  if (i != md_map.end())
593  md_map.erase(i);
594  }
595  }
596 };
597 
598 DLLLOCAL extern QoreModuleManager QMM;
599 
600 class QoreBuiltinModule : public QoreAbstractModule {
601 protected:
602  unsigned api_major, api_minor;
603  qore_module_init_t module_init;
604  qore_module_ns_init_t module_ns_init;
605  qore_module_delete_t module_delete;
606  qore_module_parse_cmd_t module_parse_cmd;
607  const void* dlptr;
608 
609  DLLLOCAL virtual void addToProgramImpl(QoreProgram* pgm, ExceptionSink& xsink) const override;
610 
611 public:
612  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) {
613  }
614 
615  DLLLOCAL virtual ~QoreBuiltinModule() {
616  printd(5, "QoreBuiltinModule::~QoreBuiltinModule() '%s': %s calling module_delete: %p\n", name.getBuffer(), filename.getBuffer(), module_delete);
617  module_delete();
618  // we do not close binary modules because we may have thread local data that needs to be
619  // destroyed when exit() is called
620  }
621 
622  DLLLOCAL unsigned getAPIMajor() const {
623  return api_major;
624  }
625 
626  DLLLOCAL unsigned getAPIMinor() const {
627  return api_minor;
628  }
629 
630  DLLLOCAL virtual bool isBuiltin() const override {
631  return true;
632  }
633 
634  DLLLOCAL virtual bool isUser() const override {
635  return false;
636  }
637 
638  DLLLOCAL QoreHashNode* getHash(bool with_filename = true) const override;
639 
640  DLLLOCAL const void* getPtr() const {
641  return dlptr;
642  }
643 
644  DLLLOCAL virtual void issueModuleCmd(const QoreProgramLocation* loc, const QoreString& cmd, ExceptionSink* xsink) override;
645 };
646 
647 class QoreUserModule : public QoreAbstractModule {
648 protected:
649  QoreProgram* pgm;
650  AbstractQoreNode* del = nullptr; // deletion closure / call reference
651 
652  DLLLOCAL virtual void addToProgramImpl(QoreProgram* pgm, ExceptionSink& xsink) const override;
653 
654 public:
655  DLLLOCAL QoreUserModule(const char* cwd, const char* fn, const char* n, QoreProgram* p, unsigned load_opt,
656  int warning_mask = QP_WARN_MODULES) : QoreAbstractModule(cwd, fn, n, load_opt), pgm(p) {
657  }
658 
659  DLLLOCAL void set(const char* d, const char* v, const char* a, const char* u, const QoreString& l, AbstractQoreNode* dl) {
660  QoreAbstractModule::set(d, v, a, u, l);
661  del = dl;
662  }
663 
664  DLLLOCAL QoreProgram* getProgram() const {
665  return pgm;
666  }
667 
668  DLLLOCAL virtual ~QoreUserModule();
669 
670  DLLLOCAL virtual bool isBuiltin() const override {
671  return false;
672  }
673 
674  DLLLOCAL virtual bool isUser() const override {
675  return true;
676  }
677 
678  DLLLOCAL virtual QoreHashNode* getHash(bool with_filename = true) const override {
679  return getHashIntern(with_filename);
680  }
681 
682  DLLLOCAL virtual void issueModuleCmd(const QoreProgramLocation* loc, const QoreString& cmd, ExceptionSink* xsink) override {
683  if (xsink) {
684  xsink->raiseException(*loc, "PARSE-COMMAND-ERROR", "module '%s' loaded from '%s' is a user module; only builtin modules can support parse commands",
685  name.c_str(), filename.c_str());
686  }
687  }
688 };
689 
690 class QoreUserModuleDefContextHelper : public QoreModuleDefContextHelper {
691 public:
692  DLLLOCAL QoreUserModuleDefContextHelper(const char* name, QoreProgram* p, ExceptionSink& xs);
693 
694  DLLLOCAL ~QoreUserModuleDefContextHelper() {
695  const char* name = set_user_module_context_name(old_name);
696 
697  if (xsink && !dup)
698  QMM.removeUserModuleDependency(name);
699  }
700 
701  DLLLOCAL void setDuplicate() {
702  assert(!dup);
703  dup = true;
704  }
705 
706  DLLLOCAL void setNameInit(const char* name);
707 
708  DLLLOCAL void close();
709 
710 protected:
711  const char* old_name;
712 
713  qore_program_private* pgm;
714  int64 po;
715 
716  ExceptionSink& xsink;
717  bool dup;
718 };
719 
720 #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