Qore Programming Language - C/C++ Library  1.0.8
ExceptionSink.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3  ExceptionSink.h
4 
5  Qore Programming Language ExceptionSink class definition
6 
7  Copyright (C) 2003 - 2021 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_EXCEPTIONSINK_H
33 
34 #define _QORE_EXCEPTIONSINK_H
35 
36 #include <cstdarg>
37 #include <cstdio>
38 #include <string>
39 #include <vector>
40 
41 // forward references
42 class QoreException;
43 class QoreXSinkException;
44 struct QoreProgramLocation;
45 struct QoreCallStack;
46 
49  friend struct qore_es_private;
50  friend QoreXSinkException;
51 
52 private:
54  struct qore_es_private* priv;
55 
57  DLLLOCAL ExceptionSink(const ExceptionSink&);
58 
60  DLLLOCAL ExceptionSink& operator=(const ExceptionSink&);
61 
62 public:
64  DLLEXPORT ExceptionSink();
65 
67  DLLEXPORT ~ExceptionSink();
68 
70  DLLEXPORT void handleExceptions();
71 
73  DLLEXPORT void handleWarnings();
74 
76  DLLEXPORT bool isEvent() const;
77 
79  DLLEXPORT bool isThreadExit() const;
80 
82  DLLEXPORT bool isException() const;
83 
85 
91  DLLEXPORT operator bool () const;
92 
94 
99  DLLEXPORT AbstractQoreNode* raiseException(const char *err, const char *fmt, ...);
100 
102 
108  DLLEXPORT AbstractQoreNode* raiseErrnoException(const char *err, int en, const char *fmt, ...);
109 
111 
117  DLLEXPORT AbstractQoreNode* raiseErrnoException(const char *err, int en, QoreStringNode* desc);
118 
120 
126  DLLEXPORT AbstractQoreNode* raiseExceptionArg(const char* err, QoreValue arg, const char* fmt, ...);
127 
129 
135  DLLEXPORT AbstractQoreNode* raiseExceptionArg(const char* err, QoreValue arg, QoreStringNode* desc);
136 
138 
148  DLLEXPORT AbstractQoreNode* raiseExceptionArg(const char* err, QoreValue arg, QoreStringNode* desc, const QoreCallStack& stack);
149 
151 
162  DLLEXPORT AbstractQoreNode* raiseExceptionArg(const QoreProgramLocation& loc, const char* err, QoreValue arg, QoreStringNode* desc, const QoreCallStack& stack);
163 
165 
175  DLLEXPORT AbstractQoreNode* raiseExceptionArg(const QoreProgramLocation& loc, const char* err, QoreValue arg, QoreStringNode* desc);
176 
178 
183  DLLEXPORT AbstractQoreNode* raiseException(const char *err, QoreStringNode* desc);
184 
186 
192 
194 
205 
207 
215  DLLEXPORT void raiseException(const QoreProgramLocation& loc, const char* err, QoreValue arg, QoreValue desc);
216 
218 
226  DLLEXPORT void raiseException(const QoreProgramLocation& loc, const char* err, QoreValue arg, const char* fmt, ...);
227 
229  DLLEXPORT void raiseThreadExit();
230 
232  DLLEXPORT void assimilate(ExceptionSink *xs);
233 
235  DLLEXPORT void assimilate(ExceptionSink &xs);
236 
238 
240  DLLEXPORT void outOfMemory();
241 
243  DLLEXPORT void clear();
244 
246  DLLEXPORT const QoreValue getExceptionErr();
247 
249  DLLEXPORT const QoreValue getExceptionDesc();
250 
252  DLLEXPORT const QoreValue getExceptionArg();
253 
255 
259  DLLEXPORT int appendLastDescription(const char* fmt, ...);
260 
261  DLLLOCAL void raiseException(QoreException* e);
262  DLLLOCAL void raiseException(const QoreListNode* n);
263  DLLLOCAL QoreException* catchException();
264  DLLLOCAL QoreException* getException();
265  DLLLOCAL void overrideLocation(const QoreProgramLocation& loc);
266  DLLLOCAL void rethrow(QoreException* old);
267 
268  DLLLOCAL static void defaultExceptionHandler(QoreException* e);
269  DLLLOCAL static void defaultWarningHandler(QoreException* e);
270 
271  DLLLOCAL static void outputExceptionLocation(const char* fns, int start_line, int end_line, const char* srcs,
272  int offset, const char* langs, const char* types);
273 };
274 
276 enum qore_call_t : signed char {
277  CT_UNUSED = -1,
278  CT_USER = 0,
279  CT_BUILTIN = 1,
280  CT_NEWTHREAD = 2,
281  CT_RETHROW = 3
282 };
283 
285 
288  std::string label;
290  end_line;
291  std::string source;
292  unsigned offset = 0;
293  std::string code;
294  std::string lang;
295 
296  DLLLOCAL QoreSourceLocation(const char* label, int start, int end, const char* code, const char* lang = "Qore") :
297  label(label), start_line(start), end_line(end), code(code), lang(lang) {
298  }
299 
300  DLLLOCAL QoreSourceLocation(const char* label, int start, int end, const char* source, unsigned offset,
301  const char* code, const char* lang = "Qore") :
303  }
304 };
305 
307 
310  qore_call_t type;
311 
312  DLLLOCAL QoreCallStackElement(qore_call_t type, const char* label, int start, int end, const char* code,
313  const char* lang = "Qore") :
314  QoreSourceLocation(label, start, end, code, lang), type(type) {
315  }
316 
317  DLLLOCAL QoreCallStackElement(qore_call_t type, const char* label, int start, int end, const char* source,
318  unsigned offset, const char* code, const char* lang = "Qore") :
319  QoreSourceLocation(label, start, end, source, offset, code, lang), type(type) {
320  }
321 };
322 
323 typedef std::vector<QoreCallStackElement> callstack_vec_t;
324 
326 
328 struct QoreCallStack : public callstack_vec_t {
330  DLLEXPORT void add(qore_call_t type, const char* label, int start, int end, const char* code,
331  const char* lang = "Qore");
332 
334  DLLEXPORT void add(qore_call_t type, const char* label, int start, int end, const char* source,
335  unsigned offset, const char* code, const char* lang = "Qore");
336 };
337 
338 static inline void alreadyDeleted(ExceptionSink *xsink, const char *cmeth) {
339  xsink->raiseException("OBJECT-ALREADY-DELETED", "the method %s() cannot be executed because the object has already been deleted", cmeth);
340 }
341 
342 static inline void makeAccessDeletedObjectException(ExceptionSink *xsink, const char *mem, const char *cname) {
343  xsink->raiseException("OBJECT-ALREADY-DELETED", "attempt to access member '%s' of an already-deleted object of class '%s'", mem, cname);
344 }
345 
346 static inline void makeAccessDeletedObjectException(ExceptionSink *xsink, const char *cname) {
347  xsink->raiseException("OBJECT-ALREADY-DELETED", "attempt to access an already-deleted object of class '%s'", cname);
348 }
349 
352 public:
355 
358 
361 
363  DLLEXPORT QoreExternalProgramLocationWrapper(const char* file, int start_line, int end_line,
364  const char* source = nullptr, int offset = 0, const char* lang = nullptr);
365 
368 
370  DLLEXPORT void set(const char* file, int start_line, int end_line,
371  const char* source = nullptr, int offset = 0, const char* lang = nullptr);
372 
374  DLLLOCAL const QoreProgramLocation& get() const {
375  return *loc;
376  }
377 
379  DLLLOCAL const std::string& getFile() const {
380  return file_str;
381  }
382 
384  DLLLOCAL const std::string& getSource() const {
385  return source_str;
386  }
387 
389  DLLLOCAL const std::string& getLanguage() const {
390  return lang_str;
391  }
392 
394  DLLEXPORT int getStartLine() const;
395 
397  DLLEXPORT int getEndLine() const;
398 
399 private:
400  // save strings for exceptions in case they are epheremal when this object is created
401  std::string file_str;
402  std::string source_str;
403  std::string lang_str;
404 
405  // actual exception location
406  QoreProgramLocation* loc;
407 };
408 
410 
413 public:
415  DLLLOCAL QoreStackLocation();
416 
418  DLLLOCAL QoreStackLocation(const QoreStackLocation&) = default;
419 
421  DLLLOCAL QoreStackLocation(QoreStackLocation&&) = default;
422 
424  DLLLOCAL virtual ~QoreStackLocation() = default;
425 
427  DLLLOCAL QoreStackLocation& operator=(const QoreStackLocation&) = default;
428 
430  DLLLOCAL QoreStackLocation& operator=(QoreStackLocation&&) = default;
431 
433 
440  DLLLOCAL void setNext(const QoreStackLocation* next) {
441  stack_next = next;
442  }
443 
445  DLLLOCAL virtual const QoreStackLocation* getNext() const {
446  return stack_next;
447  }
448 
450  DLLLOCAL virtual QoreProgram* getProgram() const = 0;
451 
453  DLLLOCAL virtual const AbstractStatement* getStatement() const = 0;
454 
456  DLLLOCAL virtual const std::string& getCallName() const = 0;
457 
459  DLLLOCAL virtual qore_call_t getCallType() const = 0;
460 
462  DLLLOCAL virtual const QoreProgramLocation& getLocation() const = 0;
463 
464 protected:
465  const QoreStackLocation* stack_next = nullptr;
466 };
467 
469 
472  friend class qore_external_runtime_stack_location_helper_priv;
473 public:
475  DLLEXPORT QoreExternalStackLocation();
476 
479 
482 
484  DLLEXPORT virtual ~QoreExternalStackLocation();
485 
488 
491 
493  DLLEXPORT virtual QoreProgram* getProgram() const;
494 
496  DLLEXPORT virtual const AbstractStatement* getStatement() const;
497 
498 private:
499  class qore_external_stack_location_priv* priv;
500 };
501 
503 
506 public:
509 
512 
515 
518 
521 
524 
525 private:
526  class qore_external_runtime_stack_location_helper_priv* priv;
527 };
528 
529 #endif
DLLEXPORT void handleWarnings()
calls ExceptionSink::defaultWarningHandler() on all exceptions still present in the object and then d...
unsigned offset
offset in source file (only used if source is not empty)
Definition: ExceptionSink.h:292
DLLEXPORT void outOfMemory()
intended to be used to handle out of memory errors
DLLEXPORT const QoreValue getExceptionArg()
returns the argument of the top exception
DLLLOCAL QoreExternalStackLocation & operator=(const QoreExternalStackLocation &)=delete
no assignment operator
DLLEXPORT ~ExceptionSink()
calls ExceptionSink::defaultExceptionHandler() on all exceptions still present in the object and then...
DLLEXPORT void handleExceptions()
calls ExceptionSink::defaultExceptionHandler() on all exceptions still present in the object and then...
returns a custom Qore program location for external modules to generate runtime exceptions with the s...
Definition: ExceptionSink.h:351
virtual DLLLOCAL const QoreStackLocation * getNext() const
returns the next location in the stack or nullptr if there is none
Definition: ExceptionSink.h:445
DLLLOCAL QoreStackLocation & operator=(const QoreStackLocation &)=default
default assignment operator
Stack location element abstract class.
Definition: ExceptionSink.h:412
std::string lang
the source language
Definition: ExceptionSink.h:294
DLLEXPORT AbstractQoreNode * raiseExceptionArg(const char *err, QoreValue arg, const char *fmt,...)
appends a Qore-language exception to the list, and sets the &#39;arg&#39; member (this object takes over the ...
Stack location element abstract class for external binary modules.
Definition: ExceptionSink.h:471
DLLLOCAL const std::string & getFile() const
returns the file name
Definition: ExceptionSink.h:379
virtual DLLLOCAL qore_call_t getCallType() const =0
returns the call type
class for C++ exception based on an ExceptionSink object
Definition: QoreXSinkException.h:51
The base class for all value and parse types in Qore expression trees.
Definition: AbstractQoreNode.h:57
DLLLOCAL QoreExternalRuntimeStackLocationHelper & operator=(const QoreExternalRuntimeStackLocationHelper &)=delete
no assignment operator
DLLEXPORT int getStartLine() const
returns the start line
DLLEXPORT int getEndLine() const
returns the start line
std::string label
the code label name (source file if source not present)
Definition: ExceptionSink.h:288
virtual DLLLOCAL ~QoreStackLocation()=default
virtual destructor
DLLEXPORT AbstractQoreNode * raiseException(const char *err, const char *fmt,...)
appends a Qore-language exception to the list
DLLEXPORT AbstractQoreNode * raiseErrnoException(const char *err, int en, const char *fmt,...)
appends a Qore-language exception to the list and appends the result of strerror(errno) to the descri...
DLLEXPORT const QoreValue getExceptionErr()
returns the error of the top exception
DLLEXPORT int appendLastDescription(const char *fmt,...)
appends a formatted string to the top exception description if the desc value is a string ...
Qore&#39;s string value type, reference counted, dynamically-allocated only.
Definition: QoreStringNode.h:50
virtual DLLLOCAL const std::string & getCallName() const =0
returns the name of the function or method call
DLLLOCAL const std::string & getSource() const
returns the source
Definition: ExceptionSink.h:384
virtual DLLLOCAL QoreProgram * getProgram() const =0
returns the QoreProgram container
DLLEXPORT QoreExternalStackLocation()
create the object
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition: QoreListNode.h:52
std::string code
the function or method call name; method calls in format class::name
Definition: ExceptionSink.h:293
virtual DLLEXPORT ~QoreExternalStackLocation()
destroys the object
DLLEXPORT ~QoreExternalRuntimeStackLocationHelper()
Restores the old runtime location.
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:267
supports parsing and executing Qore-language code, reference counted, dynamically-allocated only ...
Definition: QoreProgram.h:127
DLLEXPORT void clear()
deletes the exception list immediately
DLLLOCAL QoreStackLocation()
constructor
DLLEXPORT QoreExternalProgramLocationWrapper()
empty constructor; use set() to set the location
int start_line
the start line
Definition: ExceptionSink.h:289
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:48
Sets the stack location for external modules providing language support.
Definition: ExceptionSink.h:505
virtual DLLLOCAL const QoreProgramLocation & getLocation() const =0
returns the source location of the element
qore_call_t type
the call stack element type
Definition: ExceptionSink.h:310
DLLEXPORT void add(qore_call_t type, const char *label, int start, int end, const char *code, const char *lang="Qore")
add an element to the end of the stack trace
virtual DLLLOCAL const AbstractStatement * getStatement() const =0
returns the statement for the call for internal Qore code
int end_line
the end line
Definition: ExceptionSink.h:289
virtual DLLEXPORT const AbstractStatement * getStatement() const
returns the statement for the call for internal Qore code
DLLEXPORT bool isThreadExit() const
returns true if thread_exit has been triggered
DLLLOCAL const std::string & getLanguage() const
returns the language
Definition: ExceptionSink.h:389
DLLEXPORT void raiseThreadExit()
sets the "thread_exit" flag; will cause the current thread to terminate
DLLEXPORT const QoreValue getExceptionDesc()
returns the description of the top exception
DLLEXPORT ExceptionSink()
creates an empty ExceptionSink object
Qore source location; strings must be in the default encoding for the Qore process.
Definition: ExceptionSink.h:287
virtual DLLEXPORT QoreProgram * getProgram() const
returns the QoreProgram container
std::string source
optional additional source file
Definition: ExceptionSink.h:291
DLLLOCAL void setNext(const QoreStackLocation *next)
called when pushed on the stack to set the next location
Definition: ExceptionSink.h:440
DLLEXPORT QoreExternalRuntimeStackLocationHelper()
Sets the current runtime location.
DLLEXPORT bool isException() const
returns true if at least one exception is present
DLLEXPORT ~QoreExternalProgramLocationWrapper()
destructor; frees memory
Qore call stack.
Definition: ExceptionSink.h:328
DLLEXPORT void assimilate(ExceptionSink *xs)
assimilates all entries of the "xs" argument by appending them to the internal list and deletes the "...
DLLEXPORT bool isEvent() const
returns true if at least one exception is present or thread_exit has been triggered ...
call stack element; strings must be in the default encoding for the Qore process
Definition: ExceptionSink.h:309