| 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
48 class ExceptionSink {
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
191 DLLEXPORT AbstractQoreNode* raiseException(QoreStringNode *err, QoreStringNode* desc);
192
194
204 DLLEXPORT AbstractQoreNode* raiseException(QoreStringNode *err, QoreStringNode* desc, QoreValue arg);
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
287 struct QoreSourceLocation {
288 std::string label;
289 int start_line,
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") :
302 label(label), start_line(start), end_line(end), source(source), offset(offset), code(code), lang(lang) {
303 }
304 };
305
307
309 struct QoreCallStackElement : public QoreSourceLocation {
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
351 class QoreExternalProgramLocationWrapper {
352 public:
354 DLLEXPORT QoreExternalProgramLocationWrapper();
355
357 DLLEXPORT QoreExternalProgramLocationWrapper(const QoreExternalProgramLocationWrapper&);
358
360 DLLEXPORT QoreExternalProgramLocationWrapper(QoreExternalProgramLocationWrapper&&);
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
367 DLLEXPORT ~QoreExternalProgramLocationWrapper();
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
412 class QoreStackLocation {
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
471 class QoreExternalStackLocation : public QoreStackLocation {
472 friend class qore_external_runtime_stack_location_helper_priv;
473 public:
475 DLLEXPORT QoreExternalStackLocation();
476
478 DLLEXPORT QoreExternalStackLocation(const QoreExternalStackLocation&);
479
481 DLLEXPORT QoreExternalStackLocation(QoreExternalStackLocation&&);
482
484 DLLEXPORT virtual ~QoreExternalStackLocation();
485
487 DLLLOCAL QoreExternalStackLocation& operator=(const QoreExternalStackLocation&) = delete;
488
490 DLLLOCAL QoreExternalStackLocation& operator=(QoreExternalStackLocation&&) = delete;
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
505 class QoreExternalRuntimeStackLocationHelper : public QoreExternalStackLocation {
506 public:
508 DLLEXPORT QoreExternalRuntimeStackLocationHelper();
509
511 DLLEXPORT QoreExternalRuntimeStackLocationHelper(const QoreExternalRuntimeStackLocationHelper&);
512
514 DLLEXPORT QoreExternalRuntimeStackLocationHelper(QoreExternalRuntimeStackLocationHelper&&);
515
517 DLLEXPORT ~QoreExternalRuntimeStackLocationHelper();
518
520 DLLLOCAL QoreExternalRuntimeStackLocationHelper& operator=(const QoreExternalRuntimeStackLocationHelper&) = delete;
521
523 DLLLOCAL QoreExternalRuntimeStackLocationHelper& operator=(QoreExternalRuntimeStackLocationHelper&&) = delete;
524
525 private:
526 class qore_external_runtime_stack_location_helper_priv* priv;
527 };
528
529 #endif
ExceptionSink::handleWarnings
DLLEXPORT void handleWarnings()
calls ExceptionSink::defaultWarningHandler() on all exceptions still present in the object and then d...
QoreSourceLocation::offset
unsigned offset
offset in source file (only used if source is not empty)
Definition: ExceptionSink.h:292
ExceptionSink::outOfMemory
DLLEXPORT void outOfMemory()
intended to be used to handle out of memory errors
ExceptionSink::getExceptionArg
DLLEXPORT const QoreValue getExceptionArg()
returns the argument of the top exception
QoreExternalStackLocation::operator=
DLLLOCAL QoreExternalStackLocation & operator=(const QoreExternalStackLocation &)=delete
no assignment operator
ExceptionSink::~ExceptionSink
DLLEXPORT ~ExceptionSink()
calls ExceptionSink::defaultExceptionHandler() on all exceptions still present in the object and then...
ExceptionSink::handleExceptions
DLLEXPORT void handleExceptions()
calls ExceptionSink::defaultExceptionHandler() on all exceptions still present in the object and then...
QoreExternalProgramLocationWrapper
returns a custom Qore program location for external modules to generate runtime exceptions with the s...
Definition: ExceptionSink.h:351
QoreStackLocation::getNext
virtual DLLLOCAL const QoreStackLocation * getNext() const
returns the next location in the stack or nullptr if there is none
Definition: ExceptionSink.h:445
QoreStackLocation::operator=
DLLLOCAL QoreStackLocation & operator=(const QoreStackLocation &)=default
default assignment operator
QoreStackLocation
Stack location element abstract class.
Definition: ExceptionSink.h:412
QoreSourceLocation::lang
std::string lang
the source language
Definition: ExceptionSink.h:294
ExceptionSink::raiseExceptionArg
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 ...
QoreExternalStackLocation
Stack location element abstract class for external binary modules.
Definition: ExceptionSink.h:471
QoreExternalProgramLocationWrapper::getFile
DLLLOCAL const std::string & getFile() const
returns the file name
Definition: ExceptionSink.h:379
QoreStackLocation::getCallType
virtual DLLLOCAL qore_call_t getCallType() const =0
returns the call type
QoreXSinkException
class for C++ exception based on an ExceptionSink object
Definition: QoreXSinkException.h:51
AbstractQoreNode
The base class for all value and parse types in Qore expression trees.
Definition: AbstractQoreNode.h:57
QoreExternalRuntimeStackLocationHelper::operator=
DLLLOCAL QoreExternalRuntimeStackLocationHelper & operator=(const QoreExternalRuntimeStackLocationHelper &)=delete
no assignment operator
QoreExternalProgramLocationWrapper::getStartLine
DLLEXPORT int getStartLine() const
returns the start line
QoreExternalProgramLocationWrapper::getEndLine
DLLEXPORT int getEndLine() const
returns the start line
QoreSourceLocation::label
std::string label
the code label name (source file if source not present)
Definition: ExceptionSink.h:288
QoreStackLocation::~QoreStackLocation
virtual DLLLOCAL ~QoreStackLocation()=default
virtual destructor
ExceptionSink::raiseException
DLLEXPORT AbstractQoreNode * raiseException(const char *err, const char *fmt,...)
appends a Qore-language exception to the list
ExceptionSink::raiseErrnoException
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...
ExceptionSink::getExceptionErr
DLLEXPORT const QoreValue getExceptionErr()
returns the error of the top exception
ExceptionSink::appendLastDescription
DLLEXPORT int appendLastDescription(const char *fmt,...)
appends a formatted string to the top exception description if the desc value is a string ...
QoreStringNode
Qore&#39;s string value type, reference counted, dynamically-allocated only.
Definition: QoreStringNode.h:50
QoreStackLocation::getCallName
virtual DLLLOCAL const std::string & getCallName() const =0
returns the name of the function or method call
QoreExternalProgramLocationWrapper::getSource
DLLLOCAL const std::string & getSource() const
returns the source
Definition: ExceptionSink.h:384
QoreStackLocation::getProgram
virtual DLLLOCAL QoreProgram * getProgram() const =0
returns the QoreProgram container
QoreExternalStackLocation::QoreExternalStackLocation
DLLEXPORT QoreExternalStackLocation()
create the object
QoreListNode
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition: QoreListNode.h:52
QoreSourceLocation::code
std::string code
the function or method call name; method calls in format class::name
Definition: ExceptionSink.h:293
QoreExternalStackLocation::~QoreExternalStackLocation
virtual DLLEXPORT ~QoreExternalStackLocation()
destroys the object
QoreExternalRuntimeStackLocationHelper::~QoreExternalRuntimeStackLocationHelper
DLLEXPORT ~QoreExternalRuntimeStackLocationHelper()
Restores the old runtime location.
QoreValue
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:267
QoreProgram
supports parsing and executing Qore-language code, reference counted, dynamically-allocated only ...
Definition: QoreProgram.h:127
ExceptionSink::clear
DLLEXPORT void clear()
deletes the exception list immediately
QoreStackLocation::QoreStackLocation
DLLLOCAL QoreStackLocation()
constructor
QoreExternalProgramLocationWrapper::QoreExternalProgramLocationWrapper
DLLEXPORT QoreExternalProgramLocationWrapper()
empty constructor; use set() to set the location
QoreSourceLocation::start_line
int start_line
the start line
Definition: ExceptionSink.h:289
ExceptionSink
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:48
QoreExternalRuntimeStackLocationHelper
Sets the stack location for external modules providing language support.
Definition: ExceptionSink.h:505
QoreStackLocation::getLocation
virtual DLLLOCAL const QoreProgramLocation & getLocation() const =0
returns the source location of the element
QoreCallStackElement::type
qore_call_t type
the call stack element type
Definition: ExceptionSink.h:310
QoreCallStack::add
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
QoreStackLocation::getStatement
virtual DLLLOCAL const AbstractStatement * getStatement() const =0
returns the statement for the call for internal Qore code
QoreSourceLocation::end_line
int end_line
the end line
Definition: ExceptionSink.h:289
QoreExternalStackLocation::getStatement
virtual DLLEXPORT const AbstractStatement * getStatement() const
returns the statement for the call for internal Qore code
ExceptionSink::isThreadExit
DLLEXPORT bool isThreadExit() const
returns true if thread_exit has been triggered
QoreExternalProgramLocationWrapper::getLanguage
DLLLOCAL const std::string & getLanguage() const
returns the language
Definition: ExceptionSink.h:389
ExceptionSink::raiseThreadExit
DLLEXPORT void raiseThreadExit()
sets the "thread_exit" flag; will cause the current thread to terminate
ExceptionSink::getExceptionDesc
DLLEXPORT const QoreValue getExceptionDesc()
returns the description of the top exception
ExceptionSink::ExceptionSink
DLLEXPORT ExceptionSink()
creates an empty ExceptionSink object
QoreSourceLocation
Qore source location; strings must be in the default encoding for the Qore process.
Definition: ExceptionSink.h:287
QoreExternalStackLocation::getProgram
virtual DLLEXPORT QoreProgram * getProgram() const
returns the QoreProgram container
QoreSourceLocation::source
std::string source
optional additional source file
Definition: ExceptionSink.h:291
QoreStackLocation::setNext
DLLLOCAL void setNext(const QoreStackLocation *next)
called when pushed on the stack to set the next location
Definition: ExceptionSink.h:440
QoreExternalRuntimeStackLocationHelper::QoreExternalRuntimeStackLocationHelper
DLLEXPORT QoreExternalRuntimeStackLocationHelper()
Sets the current runtime location.
ExceptionSink::isException
DLLEXPORT bool isException() const
returns true if at least one exception is present
QoreExternalProgramLocationWrapper::~QoreExternalProgramLocationWrapper
DLLEXPORT ~QoreExternalProgramLocationWrapper()
destructor; frees memory
QoreCallStack
Qore call stack.
Definition: ExceptionSink.h:328
ExceptionSink::assimilate
DLLEXPORT void assimilate(ExceptionSink *xs)
assimilates all entries of the "xs" argument by appending them to the internal list and deletes the "...
ExceptionSink::isEvent
DLLEXPORT bool isEvent() const
returns true if at least one exception is present or thread_exit has been triggered ...
QoreCallStackElement
call stack element; strings must be in the default encoding for the Qore process
Definition: ExceptionSink.h:309