static const QoreStringNode* get_string_header_node(ExceptionSink* xsink, QoreHashNode& h, const char* header, bool allow_multiple = false) {
   AbstractQoreNode* n = h.getKeyValue(header);
   if (!n)
      return 0;

   qore_type_t t = get_node_type(n);
   if (t == NT_STRING)
      return reinterpret_cast<const QoreStringNode*>(n);
   assert(t == NT_LIST);
   if (!allow_multiple) {
      xsink->raiseException("HTTP-HEADER-ERROR", "multiple \"%s\" headers received in HTTP message", header);
      return 0;
   }
   // convert list to a comma-separated string
   QoreListNode* l = reinterpret_cast<QoreListNode*>(n);
   // get first list entry
   n = l->retrieve_entry(0);
   assert(get_node_type(n) == NT_STRING);
   QoreStringNode* rv = reinterpret_cast<QoreStringNode*>(n)->copy();
   for (size_t i = 1; i < l->size(); ++i) {
      n = l->retrieve_entry(i);
      assert(get_node_type(n) == NT_STRING);
      rv->concat(',');
      rv->concat(reinterpret_cast<QoreStringNode*>(n));
   }
   // dereference old list and save reference to return value in header hash
   h.setKeyValue(header, rv, xsink);
   return rv;
}
ExpressionStatement::ExpressionStatement(int start_line, int end_line, AbstractQoreNode *v) : AbstractStatement(start_line, end_line), exp(v) {
   // if it is a global variable declaration, then do not register
   if (exp->getType() == NT_VARREF) {
      VarRefNode *vr = reinterpret_cast<VarRefNode *>(exp);
      // used by QoreProgram to detect invalid top-level statements
      is_declaration = !vr->has_effect();
      // used in parsing to eliminate noops from the parse tree
      is_parse_declaration = !vr->stayInTree();
      return;
   }

   QoreListNode *l = exp->getType() == NT_LIST ? reinterpret_cast<QoreListNode *>(exp) : 0;
   if (l && l->isVariableList()) {
      is_declaration = true;
      is_parse_declaration = reinterpret_cast<VarRefNode *>(l->retrieve_entry(0))->getType() == VT_GLOBAL ? true : false;
      return;
   }

   is_declaration = false;
   is_parse_declaration = false;
}
Exemple #3
0
// static member function
void ExceptionSink::defaultExceptionHandler(QoreException* e) {
   ExceptionSink xsink;

   QoreString nstr;
   {
      DateTime now;
      now.setNow();
      now.format(nstr, "YYYY-MM-DD HH:mm:SS.xx Dy Z (z)");
   }

   unsigned ecnt = 0;

   while (e) {
      //printd(5, "ExceptionSink::defaultExceptionHandler() cs size=%d\n", cs->size());
      printe("unhandled QORE %s exception thrown in TID %d at %s", e->type == ET_USER ? "User" : "System", gettid(), nstr.getBuffer());

      QoreListNode *cs = e->callStack;
      bool found = false;
      if (cs->size()) {
	 // find first non-rethrow element
	 unsigned i = 0;
	 
	 QoreHashNode *h;
	 while (true) {
	    h = reinterpret_cast<QoreHashNode *>(cs->retrieve_entry(i));
	    assert(h);	    
	    if ((reinterpret_cast<QoreBigIntNode *>(h->getKeyValue("typecode")))->val != CT_RETHROW)
	       break;
	    i++;
	    if (i == cs->size())
	       break;
	 }

	 if (i < cs->size()) {
	    found = true;
	    QoreStringNode *func = reinterpret_cast<QoreStringNode *>(h->getKeyValue("function"));
	    QoreStringNode *type = reinterpret_cast<QoreStringNode *>(h->getKeyValue("type"));

	    printe(" in %s() (%s:%d", func->getBuffer(), e->file.c_str(), e->start_line);

	    if (e->start_line == e->end_line) {
	       if (!e->source.empty())
	          printe(", source %s:%d", e->source.c_str(), e->start_line + e->offset);
	    }
	    else {
               printe("-%d", e->end_line);
	       if (!e->source.empty())
                  printe(", source %s:%d-%d", e->source.c_str(), e->start_line + e->offset, e->end_line + e->offset);
	    }
	    printe(", %s code)\n", type->getBuffer());
	 }
      }

      if (!found) {
	 if (!e->file.empty()) {
	    printe(" at %s:", e->file.c_str());
	    if (e->start_line == e->end_line) {
	       if (!e->start_line) {
		  printe("<init>");
		  if (!e->source.empty())
		     printe(" (source %s)", e->source.c_str());
	       }
	       else {
		  printe("%d", e->start_line);
                  if (!e->source.empty())
                     printe(" (source %s:%d)", e->source.c_str(), e->start_line + e->offset);
	       }
	    }
	    else {
	       printe("%d-%d", e->start_line, e->end_line);
               if (!e->source.empty())
                  printe(" (source %s:%d-%d)", e->source.c_str(), e->start_line + e->offset, e->end_line + e->offset);
	    }
	 }
	 else if (e->start_line) {
	    if (e->start_line == e->end_line) {
	       if (!e->start_line)
		  printe(" at <init>");
	       else
		  printe(" on line %d", e->start_line);
	    }
	    else
	       printe(" on lines %d through %d", e->start_line, e->end_line);
	 }
	 printe("\n");
      }
      
      if (e->type == ET_SYSTEM) {
	 QoreStringNode* err = reinterpret_cast<QoreStringNode *>(e->err);
	 QoreStringNode* desc = reinterpret_cast<QoreStringNode *>(e->desc);
	 printe("%s: %s\n", err->getBuffer(), desc->getBuffer());
      }
      else {
	 bool hdr = false;

	 if (e->err) {
	    if (e->err->getType() == NT_STRING) {
	       QoreStringNode *err = reinterpret_cast<QoreStringNode *>(e->err);
	       printe("%s", err->getBuffer());
	    }
	    else {
	       QoreNodeAsStringHelper str(e->err, FMT_NORMAL, &xsink);
	       printe("EXCEPTION: %s", str->getBuffer());
	       hdr = true;
	    }
	 }
	 else
	    printe("EXCEPTION");
	 
	 if (e->desc) {
	    if (e->desc->getType() == NT_STRING) {
	       QoreStringNode *desc = reinterpret_cast<QoreStringNode *>(e->desc);
	       printe("%s%s", hdr ? ", desc: " : ": ", desc->getBuffer());
	    }
	    else {
	       QoreNodeAsStringHelper str(e->desc, FMT_NORMAL, &xsink);
	       printe(", desc: %s", str->getBuffer());
	       hdr = true;
	    }
	 }
	 
	 if (e->arg) {
	    if (e->arg->getType() == NT_STRING) {
	       QoreStringNode *arg = reinterpret_cast<QoreStringNode *>(e->arg);
	       printe("%s%s", hdr ? ", arg: " : "", arg->getBuffer());
	    }
	    else {
	       QoreNodeAsStringHelper str (e->arg, FMT_NORMAL, &xsink);
	       printe(", arg: %s", str->getBuffer());
	    }
	 }
	 printe("\n");
      }

      if (cs->size()) {
	 printe("call stack:\n");
	 for (unsigned i = 0; i < cs->size(); i++) {
	    int pos = cs->size() - i;
	    QoreHashNode* h = reinterpret_cast<QoreHashNode*>(cs->retrieve_entry(i));
	    QoreStringNode* strtype = reinterpret_cast<QoreStringNode*>(h->getKeyValue("type"));
	    const char* type = strtype->getBuffer();
	    int typecode = (int)reinterpret_cast<QoreBigIntNode*>(h->getKeyValue("typecode"))->val;
	    if (!strcmp(type, "new-thread"))
	       printe(" %2d: *thread start*\n", pos);
	    else {
	       QoreStringNode* fn = reinterpret_cast<QoreStringNode*>(h->getKeyValue("file"));
	       const char* fns = fn && !fn->empty() ? fn->getBuffer() : 0;
	       int start_line = (int)reinterpret_cast<QoreBigIntNode*>(h->getKeyValue("line"))->val;
	       int end_line = (int)reinterpret_cast<QoreBigIntNode*>(h->getKeyValue("endline"))->val;

	       QoreStringNode* src = reinterpret_cast<QoreStringNode*>(h->getKeyValue("source"));
	       const char* srcs = src && !src->empty() ? src->getBuffer() : 0;
	       int offset = (int)reinterpret_cast<QoreBigIntNode*>(h->getKeyValue("offset"))->val;

	       printe(" %2d: ", pos);

	       if (typecode == CT_RETHROW) {
	          printe("RETHROW at ");
	          if (fn) {
	             printe("%s:", fn->getBuffer());
	          }
	          else
	             printe("line");
	          printe("%d", start_line);
                  if (srcs)
                     printe(" (source %s:%d)", srcs, offset + start_line);
	       }
	       else {
	          QoreStringNode* fs = reinterpret_cast<QoreStringNode *>(h->getKeyValue("function"));
		  printe("%s() (", fs->getBuffer());
		  if (fns) {
		     if (start_line == end_line) {
			if (!start_line)
			   printe("%s:<init>", fns);
			else {
                           printe("%s:%d", fns, start_line);
			   if (srcs)
			      printe(" (source %s:%d)", srcs, start_line + offset);
			}
		     }
		     else {
			printe("%s:%d-%d", fns, start_line, end_line);
                        if (srcs)
                           printe(" (source %s:%d-%d)", srcs, start_line + offset, end_line + offset);
		     }
		  }
		  else {
		     if (start_line == end_line) {
			if (!start_line)
			   printe("<init>");
			else
			   printe("line %d", start_line);
		     }
		     else
			printe("line %d - %d", start_line, end_line);
		  }
		  printe(", %s code)", type);
	       }
	       printe("\n");
	    }
	 }
      }
      e = e->next;
      if (e) {
	 ++ecnt;
	 if (ecnt == Q_MAX_EXCEPTIONS) {
	    printe("*** maximum exception count reached (%d); supressing further output\n", ecnt);
	    break;
	 }
	 printe("chained exception:\n");
      }
   }
}