Qore Programming Language  0.9.16
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 hashdecl QoreProgramLocation;
45 hashdecl QoreCallStack;
46 
49  friend hashdecl qore_es_private;
50  friend QoreXSinkException;
51 
52 private:
54  hashdecl 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  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 
286  std::string label;
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") :
301  }
302 };
303 
305 
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 hashdecl 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 
350 public:
353 
356 
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 
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 
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 
470  friend class qore_external_runtime_stack_location_helper_priv;
471 public:
473  DLLEXPORT QoreExternalStackLocation();
474 
477 
480 
482  DLLEXPORT virtual ~QoreExternalStackLocation();
483 
486 
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 
504 public:
507 
510 
513 
516 
519 
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
QoreExternalProgramLocationWrapper::get
const DLLLOCAL QoreProgramLocation & get() const
returns the source location
Definition: ExceptionSink.h:372
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
QoreExternalStackLocation::getStatement
virtual const DLLEXPORT AbstractStatement * getStatement() const
returns the statement for the call for internal Qore code
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...
QoreExternalProgramLocationWrapper::getFile
const DLLLOCAL std::string & getFile() const
returns the file name
Definition: ExceptionSink.h:377
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
QoreStackLocation::getLocation
virtual const DLLLOCAL QoreProgramLocation & getLocation() const =0
returns the source location of the element
ExceptionSink::getExceptionDesc
const DLLEXPORT QoreValue getExceptionDesc()
returns the description of the top exception
ExceptionSink::getExceptionArg
const DLLEXPORT QoreValue getExceptionArg()
returns the argument of the top exception
QoreStackLocation::getNext
virtual const DLLLOCAL QoreStackLocation * getNext() const
returns the next location in the stack or nullptr if there is none
Definition: ExceptionSink.h:443
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
QoreExternalProgramLocationWrapper::getLanguage
const DLLLOCAL std::string & getLanguage() const
returns the language
Definition: ExceptionSink.h:387
ExceptionSink::outOfMemory
DLLEXPORT void outOfMemory()
intended to be used to handle out of memory errors FIXME: not yet fully implemented
QoreStackLocation::getStatement
virtual const DLLLOCAL AbstractStatement * getStatement() const =0
returns the statement for the call for internal Qore code
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::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
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
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
QoreExternalProgramLocationWrapper::getSource
const DLLLOCAL std::string & getSource() const
returns the source
Definition: ExceptionSink.h:382
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
QoreSourceLocation::lang
std::string lang
the source language
Definition: ExceptionSink.h:292
QoreStackLocation::QoreStackLocation
DLLLOCAL QoreStackLocation()
constructor
ExceptionSink::getExceptionErr
const DLLEXPORT QoreValue getExceptionErr()
returns the error of the top exception
QoreExternalRuntimeStackLocationHelper::~QoreExternalRuntimeStackLocationHelper
DLLEXPORT ~QoreExternalRuntimeStackLocationHelper()
Restores the old runtime location.
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.
QoreStackLocation::getCallName
virtual const DLLLOCAL std::string & getCallName() const =0
returns the name of the function or method call
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
Stack location element abstract class.
Definition: ExceptionSink.h:410