| Qore Programming Language - C/C++ Library 0.9.10

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 - 2020 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 DLLEXPORT void outOfMemory();
239
241 DLLEXPORT void clear();
242
244 DLLEXPORT const QoreValue getExceptionErr();
245
247 DLLEXPORT const QoreValue getExceptionDesc();
248
250 DLLEXPORT const QoreValue getExceptionArg();
251
253
257 DLLEXPORT int appendLastDescription(const char* fmt, ...);
258
259 DLLLOCAL void raiseException(QoreException* e);
260 DLLLOCAL void raiseException(const QoreListNode* n);
261 DLLLOCAL QoreException* catchException();
262 DLLLOCAL QoreException* getException();
263 DLLLOCAL void overrideLocation(const QoreProgramLocation& loc);
264 DLLLOCAL void rethrow(QoreException* old);
265
266 DLLLOCAL static void defaultExceptionHandler(QoreException* e);
267 DLLLOCAL static void defaultWarningHandler(QoreException* e);
268
269 DLLLOCAL static void outputExceptionLocation(const char* fns, int start_line, int end_line, const char* srcs,
270 int offset, const char* langs, const char* types);
271 };
272
274 enum qore_call_t : signed char {
275 CT_UNUSED = -1,
276 CT_USER = 0,
277 CT_BUILTIN = 1,
278 CT_NEWTHREAD = 2,
279 CT_RETHROW = 3
280 };
281
283
285 struct QoreSourceLocation {
286 std::string label;
287 int start_line,
288 end_line;
289 std::string source;
290 unsigned offset = 0;
291 std::string code;
292 std::string lang;
293
294 DLLLOCAL QoreSourceLocation(const char* label, int start, int end, const char* code, const char* lang = "Qore") :
295 label(label), start_line(start), end_line(end), code(code), lang(lang) {
296 }
297
298 DLLLOCAL QoreSourceLocation(const char* label, int start, int end, const char* source, unsigned offset,
299 const char* code, const char* lang = "Qore") :
300 label(label), start_line(start), end_line(end), source(source), offset(offset), code(code), lang(lang) {
301 }
302 };
303
305
307 struct QoreCallStackElement : public QoreSourceLocation {
308 qore_call_t type;
309
310 DLLLOCAL QoreCallStackElement(qore_call_t type, const char* label, int start, int end, const char* code,
311 const char* lang = "Qore") :
312 QoreSourceLocation(label, start, end, code, lang), type(type) {
313 }
314
315 DLLLOCAL QoreCallStackElement(qore_call_t type, const char* label, int start, int end, const char* source,
316 unsigned offset, const char* code, const char* lang = "Qore") :
317 QoreSourceLocation(label, start, end, source, offset, code, lang), type(type) {
318 }
319 };
320
321 typedef std::vector<QoreCallStackElement> callstack_vec_t;
322
324
326 struct QoreCallStack : public callstack_vec_t {
328 DLLEXPORT void add(qore_call_t type, const char* label, int start, int end, const char* code,
329 const char* lang = "Qore");
330
332 DLLEXPORT void add(qore_call_t type, const char* label, int start, int end, const char* source,
333 unsigned offset, const char* code, const char* lang = "Qore");
334 };
335
336 static inline void alreadyDeleted(ExceptionSink *xsink, const char *cmeth) {
337 xsink->raiseException("OBJECT-ALREADY-DELETED", "the method %s() cannot be executed because the object has already been deleted", cmeth);
338 }
339
340 static inline void makeAccessDeletedObjectException(ExceptionSink *xsink, const char *mem, const char *cname) {
341 xsink->raiseException("OBJECT-ALREADY-DELETED", "attempt to access member '%s' of an already-deleted object of class '%s'", mem, cname);
342 }
343
344 static inline void makeAccessDeletedObjectException(ExceptionSink *xsink, const char *cname) {
345 xsink->raiseException("OBJECT-ALREADY-DELETED", "attempt to access an already-deleted object of class '%s'", cname);
346 }
347
349 class QoreExternalProgramLocationWrapper {
350 public:
352 DLLEXPORT QoreExternalProgramLocationWrapper();
353
355 DLLEXPORT QoreExternalProgramLocationWrapper(const QoreExternalProgramLocationWrapper&);
356
358 DLLEXPORT QoreExternalProgramLocationWrapper(QoreExternalProgramLocationWrapper&&);
359
361 DLLEXPORT QoreExternalProgramLocationWrapper(const char* file, int start_line, int end_line,
362 const char* source = nullptr, int offset = 0, const char* lang = nullptr);
363
365 DLLEXPORT ~QoreExternalProgramLocationWrapper();
366
368 DLLEXPORT void set(const char* file, int start_line, int end_line,
369 const char* source = nullptr, int offset = 0, const char* lang = nullptr);
370
372 DLLLOCAL const QoreProgramLocation& get() const {
373 return *loc;
374 }
375
377 DLLLOCAL const std::string& getFile() const {
378 return file_str;
379 }
380
382 DLLLOCAL const std::string& getSource() const {
383 return source_str;
384 }
385
387 DLLLOCAL const std::string& getLanguage() const {
388 return lang_str;
389 }
390
392 DLLEXPORT int getStartLine() const;
393
395 DLLEXPORT int getEndLine() const;
396
397 private:
398 // save strings for exceptions in case they are epheremal when this object is created
399 std::string file_str;
400 std::string source_str;
401 std::string lang_str;
402
403 // actual exception location
404 QoreProgramLocation* loc;
405 };
406
408
410 class QoreStackLocation {
411 public:
413 DLLLOCAL QoreStackLocation();
414
416 DLLLOCAL QoreStackLocation(const QoreStackLocation&) = default;
417
419 DLLLOCAL QoreStackLocation(QoreStackLocation&&) = default;
420
422 DLLLOCAL virtual ~QoreStackLocation() = default;
423
425 DLLLOCAL QoreStackLocation& operator=(const QoreStackLocation&) = default;
426
428 DLLLOCAL QoreStackLocation& operator=(QoreStackLocation&&) = default;
429
431
438 DLLLOCAL void setNext(const QoreStackLocation* next) {
439 stack_next = next;
440 }
441
443 DLLLOCAL virtual const QoreStackLocation* getNext() const {
444 return stack_next;
445 }
446
448 DLLLOCAL virtual QoreProgram* getProgram() const = 0;
449
451 DLLLOCAL virtual const AbstractStatement* getStatement() const = 0;
452
454 DLLLOCAL virtual const std::string& getCallName() const = 0;
455
457 DLLLOCAL virtual qore_call_t getCallType() const = 0;
458
460 DLLLOCAL virtual const QoreProgramLocation& getLocation() const = 0;
461
462 protected:
463 const QoreStackLocation* stack_next = nullptr;
464 };
465
467
469 class QoreExternalStackLocation : public QoreStackLocation {
470 friend class qore_external_runtime_stack_location_helper_priv;
471 public:
473 DLLEXPORT QoreExternalStackLocation();
474
476 DLLEXPORT QoreExternalStackLocation(const QoreExternalStackLocation&);
477
479 DLLEXPORT QoreExternalStackLocation(QoreExternalStackLocation&&);
480
482 DLLEXPORT virtual ~QoreExternalStackLocation();
483
485 DLLLOCAL QoreExternalStackLocation& operator=(const QoreExternalStackLocation&) = delete;
486
488 DLLLOCAL QoreExternalStackLocation& operator=(QoreExternalStackLocation&&) = delete;
489
491 DLLEXPORT virtual QoreProgram* getProgram() const;
492
494 DLLEXPORT virtual const AbstractStatement* getStatement() const;
495
496 private:
497 class qore_external_stack_location_priv* priv;
498 };
499
501
503 class QoreExternalRuntimeStackLocationHelper : public QoreExternalStackLocation {
504 public:
506 DLLEXPORT QoreExternalRuntimeStackLocationHelper();
507
509 DLLEXPORT QoreExternalRuntimeStackLocationHelper(const QoreExternalRuntimeStackLocationHelper&);
510
512 DLLEXPORT QoreExternalRuntimeStackLocationHelper(QoreExternalRuntimeStackLocationHelper&&);
513
515 DLLEXPORT ~QoreExternalRuntimeStackLocationHelper();
516
518 DLLLOCAL QoreExternalRuntimeStackLocationHelper& operator=(const QoreExternalRuntimeStackLocationHelper&) = delete;
519
521 DLLLOCAL QoreExternalRuntimeStackLocationHelper& operator=(QoreExternalRuntimeStackLocationHelper&&) = delete;
522
523 private:
524 class qore_external_runtime_stack_location_helper_priv* priv;
525 };
526
527 #endif
ExceptionSink::clear
DLLEXPORT void clear()
deletes the exception list immediately
QoreStackLocation::setNext
DLLLOCAL void setNext(const QoreStackLocation *next)
called when pushed on the stack to set the next location
Definition: ExceptionSink.h:438
QoreStackLocation::getProgram
virtual DLLLOCAL QoreProgram * getProgram() const =0
returns the QoreProgram container
QoreProgram
supports parsing and executing Qore-language code, reference counted, dynamically-allocated only
Definition: QoreProgram.h:126
QoreValue
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:262
QoreSourceLocation::code
std::string code
the function or method call name; method calls in format class::name
Definition: ExceptionSink.h:291
ExceptionSink::isEvent
DLLEXPORT bool isEvent() const
returns true if at least one exception is present or thread_exit has been triggered
QoreExternalProgramLocationWrapper::getStartLine
DLLEXPORT int getStartLine() const
returns the start line
QoreExternalProgramLocationWrapper::~QoreExternalProgramLocationWrapper
DLLEXPORT ~QoreExternalProgramLocationWrapper()
destructor; frees memory
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...
QoreExternalStackLocation::operator=
DLLLOCAL QoreExternalStackLocation & operator=(const QoreExternalStackLocation &)=delete
no assignment operator
QoreStackLocation::operator=
DLLLOCAL QoreStackLocation & operator=(const QoreStackLocation &)=default
default assignment operator
ExceptionSink::handleExceptions
DLLEXPORT void handleExceptions()
calls ExceptionSink::defaultExceptionHandler() on all exceptions still present in the object and then...
QoreSourceLocation::source
std::string source
optional additional source file
Definition: ExceptionSink.h:289
QoreXSinkException
class for C++ exception based on an ExceptionSink object
Definition: QoreXSinkException.h:51
ExceptionSink::ExceptionSink
DLLEXPORT ExceptionSink()
creates an empty ExceptionSink object
QoreListNode
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition: QoreListNode.h:52
QoreExternalProgramLocationWrapper
returns a custom Qore program location for external modules to generate runtime exceptions with the s...
Definition: ExceptionSink.h:349
QoreSourceLocation::offset
unsigned offset
offset in source file (only used if source is not empty)
Definition: ExceptionSink.h:290
ExceptionSink::appendLastDescription
DLLEXPORT int appendLastDescription(const char *fmt,...)
appends a formatted string to the top exception description if the desc value is a string
ExceptionSink::raiseThreadExit
DLLEXPORT void raiseThreadExit()
sets the "thread_exit" flag; will cause the current thread to terminate
QoreStackLocation::getCallName
virtual DLLLOCAL const std::string & getCallName() const =0
returns the name of the function or method call
ExceptionSink::outOfMemory
DLLEXPORT void outOfMemory()
intended to be used to handle out of memory errors FIXME: not yet fully implemented
QoreStackLocation::getNext
virtual DLLLOCAL const QoreStackLocation * getNext() const
returns the next location in the stack or nullptr if there is none
Definition: ExceptionSink.h:443
ExceptionSink::~ExceptionSink
DLLEXPORT ~ExceptionSink()
calls ExceptionSink::defaultExceptionHandler() on all exceptions still present in the object and then...
ExceptionSink::raiseException
DLLEXPORT AbstractQoreNode * raiseException(const char *err, const char *fmt,...)
appends a Qore-language exception to the list
QoreExternalStackLocation
Stack location element abstract class for external binary modules.
Definition: ExceptionSink.h:469
QoreExternalStackLocation::QoreExternalStackLocation
DLLEXPORT QoreExternalStackLocation()
create the object
QoreExternalProgramLocationWrapper::getLanguage
DLLLOCAL const std::string & getLanguage() const
returns the language
Definition: ExceptionSink.h:387
QoreStackLocation::getStatement
virtual DLLLOCAL const AbstractStatement * getStatement() const =0
returns the statement for the call for internal Qore code
QoreExternalProgramLocationWrapper::getEndLine
DLLEXPORT int getEndLine() const
returns the start line
ExceptionSink::assimilate
DLLEXPORT void assimilate(ExceptionSink *xs)
assimilates all entries of the "xs" argument by appending them to the internal list and deletes the "...
QoreExternalRuntimeStackLocationHelper::operator=
DLLLOCAL QoreExternalRuntimeStackLocationHelper & operator=(const QoreExternalRuntimeStackLocationHelper &)=delete
no assignment operator
QoreStackLocation::getCallType
virtual DLLLOCAL qore_call_t getCallType() const =0
returns the call type
ExceptionSink
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:48
ExceptionSink::handleWarnings
DLLEXPORT void handleWarnings()
calls ExceptionSink::defaultWarningHandler() on all exceptions still present in the object and then d...
QoreStackLocation::~QoreStackLocation
virtual DLLLOCAL ~QoreStackLocation()=default
virtual destructor
QoreExternalProgramLocationWrapper::getFile
DLLLOCAL const std::string & getFile() const
returns the file name
Definition: ExceptionSink.h:377
QoreSourceLocation
Qore source location; strings must be in the default encoding for the Qore process.
Definition: ExceptionSink.h:285
QoreExternalStackLocation::getProgram
virtual DLLEXPORT QoreProgram * getProgram() const
returns the QoreProgram container
QoreCallStack
Qore call stack.
Definition: ExceptionSink.h:326
QoreExternalProgramLocationWrapper::getSource
DLLLOCAL const std::string & getSource() const
returns the source
Definition: ExceptionSink.h:382
QoreExternalStackLocation::~QoreExternalStackLocation
virtual DLLEXPORT ~QoreExternalStackLocation()
destroys the object
QoreCallStackElement
call stack element; strings must be in the default encoding for the Qore process
Definition: ExceptionSink.h:307
ExceptionSink::raiseExceptionArg
DLLEXPORT AbstractQoreNode * raiseExceptionArg(const char *err, QoreValue arg, const char *fmt,...)
appends a Qore-language exception to the list, and sets the 'arg' member (this object takes over the ...
ExceptionSink::isException
DLLEXPORT bool isException() const
returns true if at least one exception is present
ExceptionSink::getExceptionErr
DLLEXPORT const QoreValue getExceptionErr()
returns the error of the top exception
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
ExceptionSink::getExceptionDesc
DLLEXPORT const QoreValue getExceptionDesc()
returns the description of the top exception
QoreSourceLocation::lang
std::string lang
the source language
Definition: ExceptionSink.h:292
QoreStackLocation::QoreStackLocation
DLLLOCAL QoreStackLocation()
constructor
ExceptionSink::getExceptionArg
DLLEXPORT const QoreValue getExceptionArg()
returns the argument of the top exception
QoreExternalStackLocation::getStatement
virtual DLLEXPORT const AbstractStatement * getStatement() const
returns the statement for the call for internal Qore code
QoreExternalRuntimeStackLocationHelper::~QoreExternalRuntimeStackLocationHelper
DLLEXPORT ~QoreExternalRuntimeStackLocationHelper()
Restores the old runtime location.
QoreExternalProgramLocationWrapper::get
DLLLOCAL const QoreProgramLocation & get() const
returns the source location
Definition: ExceptionSink.h:372
QoreSourceLocation::start_line
int start_line
the start line
Definition: ExceptionSink.h:287
ExceptionSink::isThreadExit
DLLEXPORT bool isThreadExit() const
returns true if thread_exit has been triggered
QoreStringNode
Qore's string value type, reference counted, dynamically-allocated only.
Definition: QoreStringNode.h:50
QoreExternalRuntimeStackLocationHelper
Sets the stack location for external modules providing language support.
Definition: ExceptionSink.h:503
AbstractQoreNode
The base class for all value and parse types in Qore expression trees.
Definition: AbstractQoreNode.h:54
QoreExternalProgramLocationWrapper::set
DLLEXPORT void set(const char *file, int start_line, int end_line, const char *source=nullptr, int offset=0, const char *lang=nullptr)
sets the program source location
QoreExternalProgramLocationWrapper::QoreExternalProgramLocationWrapper
DLLEXPORT QoreExternalProgramLocationWrapper()
empty constructor; use set() to set the location
QoreCallStackElement::type
qore_call_t type
the call stack element type
Definition: ExceptionSink.h:308
QoreExternalRuntimeStackLocationHelper::QoreExternalRuntimeStackLocationHelper
DLLEXPORT QoreExternalRuntimeStackLocationHelper()
Sets the current runtime location.
QoreSourceLocation::label
std::string label
the code label name (source file if source not present)
Definition: ExceptionSink.h:286
QoreSourceLocation::end_line
int end_line
the end line
Definition: ExceptionSink.h:288
QoreStackLocation::getLocation
virtual DLLLOCAL const QoreProgramLocation & getLocation() const =0
returns the source location of the element
QoreStackLocation
Stack location element abstract class.
Definition: ExceptionSink.h:410