Qore Programming Language  0.9.0
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 - 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_EXCEPTIONSINK_H
33 
34 #define _QORE_EXCEPTIONSINK_H
35 
36 #include <cstdarg>
37 #include <cstdio>
38 #include <string>
39 #include <vector>
40 
41 class QoreException;
42 hashdecl QoreProgramLocation;
43 hashdecl QoreCallStack;
44 
47  friend hashdecl qore_es_private;
48 
49 private:
51  hashdecl qore_es_private *priv;
52 
54  DLLLOCAL ExceptionSink(const ExceptionSink&);
55 
57  DLLLOCAL ExceptionSink& operator=(const ExceptionSink&);
58 
59 public:
61  DLLEXPORT ExceptionSink();
62 
64  DLLEXPORT ~ExceptionSink();
65 
67  DLLEXPORT void handleExceptions();
68 
70  DLLEXPORT void handleWarnings();
71 
73  DLLEXPORT bool isEvent() const;
74 
76  DLLEXPORT bool isThreadExit() const;
77 
79  DLLEXPORT bool isException() const;
80 
82 
88  DLLEXPORT operator bool () const;
89 
91 
96  DLLEXPORT AbstractQoreNode* raiseException(const char *err, const char *fmt, ...);
97 
99 
105  DLLEXPORT AbstractQoreNode* raiseErrnoException(const char *err, int en, const char *fmt, ...);
106 
108 
114  DLLEXPORT AbstractQoreNode* raiseErrnoException(const char *err, int en, QoreStringNode* desc);
115 
117 
123  DLLEXPORT AbstractQoreNode* raiseExceptionArg(const char* err, QoreValue arg, const char* fmt, ...);
124 
126 
132  DLLEXPORT AbstractQoreNode* raiseExceptionArg(const char* err, QoreValue arg, QoreStringNode* desc);
133 
135 
145  DLLEXPORT AbstractQoreNode* raiseExceptionArg(const char* err, QoreValue arg, QoreStringNode* desc, const QoreCallStack& stack);
146 
148 
159  DLLEXPORT AbstractQoreNode* raiseExceptionArg(const QoreProgramLocation& loc, const char* err, QoreValue arg, QoreStringNode* desc, const QoreCallStack& stack);
160 
162 
172  DLLEXPORT AbstractQoreNode* raiseExceptionArg(const QoreProgramLocation& loc, const char* err, QoreValue arg, QoreStringNode* desc);
173 
175 
180  DLLEXPORT AbstractQoreNode* raiseException(const char *err, QoreStringNode* desc);
181 
183 
189 
191 
199  DLLEXPORT void raiseException(const QoreProgramLocation& loc, const char* err, QoreValue arg, QoreValue desc);
200 
202 
210  DLLEXPORT void raiseException(const QoreProgramLocation& loc, const char* err, QoreValue arg, const char* fmt, ...);
211 
213  DLLEXPORT void raiseThreadExit();
214 
216  DLLEXPORT void assimilate(ExceptionSink *xs);
217 
219  DLLEXPORT void assimilate(ExceptionSink &xs);
220 
222  DLLEXPORT void outOfMemory();
223 
225  DLLEXPORT void clear();
226 
228  DLLEXPORT const QoreValue getExceptionErr();
229 
231  DLLEXPORT const QoreValue getExceptionDesc();
232 
234  DLLEXPORT const QoreValue getExceptionArg();
235 
237 
241  DLLEXPORT int appendLastDescription(const char* fmt, ...);
242 
243  DLLLOCAL void raiseException(QoreException* e);
244  DLLLOCAL void raiseException(const QoreListNode* n);
245  DLLLOCAL QoreException* catchException();
246  DLLLOCAL QoreException* getException();
247  DLLLOCAL void overrideLocation(const QoreProgramLocation& loc);
248  DLLLOCAL void rethrow(QoreException* old);
249 
250  DLLLOCAL static void defaultExceptionHandler(QoreException* e);
251  DLLLOCAL static void defaultWarningHandler(QoreException* e);
252 
253  DLLLOCAL static void outputExceptionLocation(const char* fns, int start_line, int end_line, const char* srcs,
254  int offset, const char* langs, const char* types);
255 };
256 
258 enum qore_call_t : signed char {
259  CT_UNUSED = -1,
260  CT_USER = 0,
261  CT_BUILTIN = 1,
262  CT_NEWTHREAD = 2,
263  CT_RETHROW = 3
264 };
265 
267 
270  std::string label;
272  end_line;
273  std::string source;
274  unsigned offset = 0;
275  std::string code;
276  std::string lang;
277 
278  DLLLOCAL QoreSourceLocation(const char* label, int start, int end, const char* code, const char* lang = "Qore") :
279  label(label), start_line(start), end_line(end), code(code), lang(lang) {
280  }
281 
282  DLLLOCAL QoreSourceLocation(const char* label, int start, int end, const char* source, unsigned offset,
283  const char* code, const char* lang = "Qore") :
285  }
286 };
287 
289 
292  qore_call_t type;
293 
294  DLLLOCAL QoreCallStackElement(qore_call_t type, const char* label, int start, int end, const char* code,
295  const char* lang = "Qore") :
296  QoreSourceLocation(label, start, end, code, lang), type(type) {
297  }
298 
299  DLLLOCAL QoreCallStackElement(qore_call_t type, const char* label, int start, int end, const char* source,
300  unsigned offset, const char* code, const char* lang = "Qore") :
301  QoreSourceLocation(label, start, end, source, offset, code, lang), type(type) {
302  }
303 };
304 
305 typedef std::vector<QoreCallStackElement> callstack_vec_t;
306 
308 
310 hashdecl QoreCallStack : public callstack_vec_t {
311  DLLLOCAL void add(qore_call_t type, const char* label, int start, int end, const char* code,
312  const char* lang = "Qore") {
313  push_back(QoreCallStackElement(type, label, start, end, code, lang));
314  }
315 
316  DLLLOCAL void add(qore_call_t type, const char* label, int start, int end, const char* source,
317  unsigned offset, const char* code, const char* lang = "Qore") {
318  push_back(QoreCallStackElement(type, label, start, end, source, offset, code, lang));
319  }
320 };
321 
322 static inline void alreadyDeleted(ExceptionSink *xsink, const char *cmeth) {
323  xsink->raiseException("OBJECT-ALREADY-DELETED", "the method %s() cannot be executed because the object has already been deleted", cmeth);
324 }
325 
326 static inline void makeAccessDeletedObjectException(ExceptionSink *xsink, const char *mem, const char *cname) {
327  xsink->raiseException("OBJECT-ALREADY-DELETED", "attempt to access member '%s' of an already-deleted object of class '%s'", mem, cname);
328 }
329 
330 static inline void makeAccessDeletedObjectException(ExceptionSink *xsink, const char *cname) {
331  xsink->raiseException("OBJECT-ALREADY-DELETED", "attempt to access an already-deleted object of class '%s'", cname);
332 }
333 
336 public:
339 
342 
345 
347  DLLEXPORT QoreExternalProgramLocationWrapper(const char* file, int start_line, int end_line,
348  const char* source = nullptr, int offset = 0, const char* lang = nullptr);
349 
352 
354  DLLEXPORT void set(const char* file, int start_line, int end_line,
355  const char* source = nullptr, int offset = 0, const char* lang = nullptr);
356 
358  DLLEXPORT const QoreProgramLocation& get() const {
359  return *loc;
360  }
361 
363  DLLEXPORT const std::string& getFile() const {
364  return file_str;
365  }
366 
368  DLLEXPORT const std::string& getSource() const {
369  return source_str;
370  }
371 
373  DLLEXPORT const std::string& getLanguage() const {
374  return lang_str;
375  }
376 
378  DLLEXPORT int getStartLine() const;
379 
381  DLLEXPORT int getEndLine() const;
382 
383 private:
384  // save strings for exceptions in case they are epheremal when this object is created
385  std::string file_str;
386  std::string source_str;
387  std::string lang_str;
388 
389  // actual exception location
390  QoreProgramLocation* loc;
391 };
392 
394 
397 public:
399  DLLLOCAL QoreStackLocation();
400 
402  DLLLOCAL QoreStackLocation(const QoreStackLocation&) = default;
403 
405  DLLLOCAL QoreStackLocation(QoreStackLocation&&) = default;
406 
408  DLLLOCAL virtual ~QoreStackLocation() = default;
409 
411  DLLLOCAL QoreStackLocation& operator=(const QoreStackLocation&) = default;
412 
414  DLLLOCAL QoreStackLocation& operator=(QoreStackLocation&&) = default;
415 
417 
424  DLLLOCAL void setNext(const QoreStackLocation* next) {
425  stack_next = next;
426  }
427 
429  DLLLOCAL virtual const QoreStackLocation* getNext() const {
430  return stack_next;
431  }
432 
434  DLLLOCAL virtual QoreProgram* getProgram() const = 0;
435 
437  DLLLOCAL virtual const AbstractStatement* getStatement() const = 0;
438 
440  DLLLOCAL virtual const std::string& getCallName() const = 0;
441 
443  DLLLOCAL virtual qore_call_t getCallType() const = 0;
444 
446  DLLLOCAL virtual const QoreProgramLocation& getLocation() const = 0;
447 
448 protected:
449  const QoreStackLocation* stack_next = nullptr;
450 };
451 
453 
456  friend class qore_external_runtime_stack_location_helper_priv;
457 public:
459  DLLEXPORT QoreExternalStackLocation();
460 
463 
466 
468  DLLEXPORT virtual ~QoreExternalStackLocation();
469 
472 
475 
477  DLLEXPORT virtual QoreProgram* getProgram() const;
478 
480  DLLEXPORT virtual const AbstractStatement* getStatement() const;
481 
482 private:
483  class qore_external_stack_location_priv* priv;
484 };
485 
487 
490 public:
493 
496 
499 
502 
505 
508 
509 private:
510  class qore_external_runtime_stack_location_helper_priv* priv;
511 };
512 
513 #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:274
DLLEXPORT const std::string & getFile() const
returns the file name
Definition: ExceptionSink.h:363
DLLEXPORT void outOfMemory()
intended to be used to handle out of memory errors FIXME: not yet fully implemented ...
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:335
virtual DLLLOCAL const QoreStackLocation * getNext() const
returns the next location in the stack or nullptr if there is none
Definition: ExceptionSink.h:429
DLLLOCAL QoreStackLocation & operator=(const QoreStackLocation &)=default
default assignment operator
Stack location element abstract class.
Definition: ExceptionSink.h:396
std::string lang
the source language
Definition: ExceptionSink.h:276
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:455
virtual DLLLOCAL qore_call_t getCallType() const =0
returns the call type
The base class for all value and parse types in Qore expression trees.
Definition: AbstractQoreNode.h:54
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:270
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
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:275
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:262
supports parsing and executing Qore-language code, reference counted, dynamically-allocated only ...
Definition: QoreProgram.h:126
DLLEXPORT void clear()
deletes the exception list immediately
DLLLOCAL QoreStackLocation()
constructor
DLLEXPORT QoreExternalProgramLocationWrapper()
empty constructor; use set() to set the location
DLLEXPORT const std::string & getLanguage() const
returns the language
Definition: ExceptionSink.h:373
int start_line
the start line
Definition: ExceptionSink.h:271
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:46
Sets the stack location for external modules providing language support.
Definition: ExceptionSink.h:489
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:292
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:271
virtual DLLEXPORT const AbstractStatement * getStatement() const
returns the statement for the call for internal Qore code
DLLEXPORT const std::string & getSource() const
returns the source
Definition: ExceptionSink.h:368
DLLEXPORT bool isThreadExit() const
returns true if thread_exit has been triggered
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:269
virtual DLLEXPORT QoreProgram * getProgram() const
returns the QoreProgram container
std::string source
optional additional source file
Definition: ExceptionSink.h:273
DLLLOCAL void setNext(const QoreStackLocation *next)
called when pushed on the stack to set the next location
Definition: ExceptionSink.h:424
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:310
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:291