示例#1
0
AbstractQoreNode* ParseObjectMethodReferenceNode::parseInitImpl(LocalVar* oflag, int pflag, int& lvids, const QoreTypeInfo*& typeInfo) {
   typeInfo = callReferenceTypeInfo;
   if (exp) {
      const QoreTypeInfo* argTypeInfo = 0;
      exp = exp->parseInit(oflag, pflag, lvids, argTypeInfo);

      if (argTypeInfo->hasType()) {
	 if (objectTypeInfo && argTypeInfo && !objectTypeInfo->parseAccepts(argTypeInfo)) {
	    // raise parse exception
	    QoreStringNode* desc = new QoreStringNode("invalid call; object expression gives ");
	    argTypeInfo->getThisType(*desc);
	    desc->concat(", but should resolve to an object to make a call with this syntax");
	    qore_program_private::makeParseException(getProgram(), "PARSE-TYPE-ERROR", desc);
	 }
	 else {
	    const QoreClass* n_qc = argTypeInfo->getUniqueReturnClass();
	    if (n_qc) {
	       bool m_priv = false;
	       m = qore_class_private::parseFindMethodTree(*const_cast<QoreClass*>(n_qc), method.c_str(), m_priv);
	       if (m) {
		  qc = n_qc;
		  if (m_priv && !qore_class_private::parseCheckPrivateClassAccess(*qc))
		     parseException("PARSE-ERROR", "method %s::%s() is private in this context, therefore a call reference cannot be taken", qc->getName(), method.c_str());
	       }
	       else
		  parseException("PARSE-ERROR", "method %s::%s() cannot be found", n_qc->getName(), method.c_str());
	    }
	 }
      }
   }
   return this;
}
示例#2
0
void VarRefFunctionCallBase::parseInitConstructorCall(const QoreProgramLocation& loc, LocalVar *oflag, int pflag, int &lvids, const QoreClass *qc) {
   if (qc) {
      // throw an exception if trying to instantiate a class with abstract method variants
      qore_class_private::parseCheckAbstractNew(*const_cast<QoreClass*>(qc));

      if (qore_program_private::parseAddDomain(getProgram(), qc->getDomain()))
	 parseException(loc, "ILLEGAL-CLASS-INSTANTIATION", "parse options do not allow access to the '%s' class", qc->getName());

      // FIXME: make common code with ScopedObjectCallNode
      const QoreMethod *constructor = qc ? qc->parseGetConstructor() : 0;
      const QoreTypeInfo *typeInfo;
      lvids += parseArgsVariant(loc, oflag, pflag, constructor ? constructor->getFunction() : 0, typeInfo);

      //printd(5, "VarRefFunctionCallBase::parseInitConstructorCall() this: %p constructor: %p variant: %p\n", this, constructor, variant);

      if (((constructor && constructor->parseIsPrivate()) || (variant && CONMV_const(variant)->isPrivate())) && !qore_class_private::parseCheckPrivateClassAccess(*qc)) {
	 if (variant)
	    parse_error(loc, "illegal external access to private constructor %s::constructor(%s)", qc->getName(), variant->getSignature()->getSignatureText());
	 else
	    parse_error(loc, "illegal external access to private constructor of class %s", qc->getName());
      }

      //printd(5, "VarRefFunctionCallBase::parseInitConstructorCall() this: %p class: %s (%p) constructor: %p function: %p variant: %p\n", this, qc->getName(), qc, constructor, constructor ? constructor->getFunction() : 0, variant);
   }

   if (pflag & PF_FOR_ASSIGNMENT)
      parse_error(loc, "variable new object instantiation will be assigned when the object is created; it is an error to make an additional assignment");
}
示例#3
0
/** 0 for success , -1 for out of range, other values for error */
int parseOPEN(const char *header, const char *content)
{
    int ret = 0, offset = 0;
    
    if (!header || strncmp(header, httpHeaderString,
                           strlen(httpHeaderString))) {
        return EINVAL;
    }
    
    offset += strlen(httpHeaderString);
    while (isspace(header[offset])) {
        offset++;
    }
    if (strncmp(header + offset, temporaryRedirectCode,
                strlen(temporaryRedirectCode)) ||
        !strstr(header, twoHundredOKCode)) {
        struct jsonException *exc = parseException(content);
        if (exc) {
            // If the exception is an IOException and it is because
            // the offset is out of the range, do not print out the exception
            if (!strcasecmp(exc->exception, "IOException") &&
                    strstr(exc->message, "out of the range")) {
                ret = -1;
            } else {
                ret = printJsonException(exc, PRINT_EXC_ALL,
                                       "Calling WEBHDFS (OPEN)");
            }
        } else {
            ret = EIO;
        }
    }
    return ret;
}
示例#4
0
/**
 * Check the header of response to see if it's 200 OK
 * 
 * @param header    Header information for checking
 * @param content   Stores exception information if there are errors
 * @param operation Indicate the operation for exception printing
 * @return 0 for success
 */
static int checkHeader(const char *header, const char *content,
                       const char *operation)
{
    char *result = NULL;
    const char delims[] = ":";
    char *savepter;
    int ret = 0;
    
    if (!header || strncmp(header, "HTTP/", strlen("HTTP/"))) {
        return EINVAL;
    }
    if (!(strstr(header, twoHundredOKCode)) ||
       !(result = strstr(header, "Content-Length"))) {
        struct jsonException *exc = parseException(content);
        if (exc) {
            ret = printJsonException(exc, PRINT_EXC_ALL,
                                       "Calling WEBHDFS (%s)", operation);
        } else {
            ret = EIO;
        }
        return ret;
    }
    result = strtok_r(result, delims, &savepter);
    result = strtok_r(NULL, delims, &savepter);
    while (isspace(*result)) {
        result++;
    }
    // Content-Length should be equal to 0,
    // and the string should be "0\r\nServer"
    if (strncmp(result, "0\r\n", 3)) {
        ret = EIO;
    }
    return ret;
}
示例#5
0
AbstractQoreNode* UnresolvedStaticMethodCallReferenceNode::parseInit(LocalVar* oflag, int pflag, int& lvids, const QoreTypeInfo*& typeInfo) {
   typeInfo = callReferenceTypeInfo;

   QoreClass* qc = qore_root_ns_private::parseFindScopedClassWithMethod(*scope, false);
   if (!qc) {
      // see if this is a function call to a function defined in a namespace
      const QoreFunction* f = qore_root_ns_private::parseResolveFunction(*scope);
      if (f) {
	 LocalFunctionCallReferenceNode* fr = new LocalFunctionCallReferenceNode(f);
         deref();
         return fr->parseInit(oflag, pflag, lvids, typeInfo);
      }
      parse_error("reference to undefined class '%s' in '%s()'", scope->get(scope->size() - 2), scope->ostr);
      return this;
   }

   const QoreMethod* qm = 0;
   // try to find a pointer to a non-static method if parsing in the class' context
   // and bare references are enabled
   if (oflag && parse_check_parse_option(PO_ALLOW_BARE_REFS) && oflag->getTypeInfo()->getUniqueReturnClass()->parseCheckHierarchy(qc)) {
      bool m_priv = false;
      qm = qore_class_private::parseFindMethodTree(*qc, scope->getIdentifier(), m_priv);
      assert(!qm || !qm->isStatic());
   }
   if (!qm) {
      bool m_priv = false;
      qm = qore_class_private::parseFindStaticMethodTree(*qc, scope->getIdentifier(), m_priv);
      if (!qm) {
	 parseException("INVALID-METHOD", "class '%s' has no static method '%s'", qc->getName(), scope->getIdentifier());
	 return this;
      }
      assert(qm->isStatic());
   }

   // check class capabilities against parse options
   if (qore_program_private::parseAddDomain(getProgram(), qc->getDomain())) {
      parseException("class '%s' implements capabilities that are not allowed by current parse options", qc->getName());
      return this;
   }

   AbstractQoreNode* rv = qm->isStatic() ? new LocalStaticMethodCallReferenceNode(qm) : new LocalMethodCallReferenceNode(qm);
   deref();
   return rv;
}
示例#6
0
ContextStatement::ContextStatement(int start_line, int end_line, char *n, AbstractQoreNode *expr, class ContextModList *mods, class StatementBlock *cd) : AbstractStatement(start_line, end_line) {
   name = n;
   exp = expr;
   code = cd;
   lvars = 0;
   where_exp = sort_ascending = sort_descending = 0;
   if (mods) {
      for (cxtmod_list_t::iterator i = mods->begin(); i != mods->end(); i++) {
	 switch ((*i)->type) {
	    case CM_WHERE_NODE:
	       if (!where_exp) {
		  where_exp = (*i)->c.exp;
		  (*i)->c.exp = 0;
	       }
	       else
		  parseException("CONTEXT-PARSE-ERROR", "multiple where conditions found for context statement!");
	       break;
	    case CM_SORT_ASCENDING:
	       if (!sort_ascending && !sort_descending) {
		  sort_ascending = (*i)->c.exp;
		  (*i)->c.exp = 0;
	       }
	       else
		  parseException("CONTEXT-PARSE-ERROR", "multiple sort conditions found for context statement!");
	       break;
	    case CM_SORT_DESCENDING:
	       if (!sort_descending && !sort_ascending) {
		  sort_descending = (*i)->c.exp;
		  (*i)->c.exp = 0;
	       }
	       else
		  parseException("CONTEXT-PARSE-ERROR", "multiple sort conditions found for context statement!");
	       break;
	 }
      }
      delete mods;
   }
}
示例#7
0
void TopLevelStatementBlock::parseInit(int64 po) {
   QORE_TRACE("TopLevelStatementBlock::parseInit");

   //printd(5, "TopLevelStatementBlock::parseInit(rns=%p) first=%d\n", &rns, first);

   if (!first && lvars) {
      // push already-registered local variables on the stack
      for (unsigned i = 0; i < lvars->size(); ++i)
         push_top_level_local_var(lvars->lv[i], loc);
   }

   // resolve global variables before initializing the top-level statements
   qore_root_ns_private::parseResolveGlobalVars();
   int lvids = parseInitIntern(0, PF_TOP_LEVEL, hwm);

   //printd(5, "TopLevelStatementBlock::parseInit(rns=%p) first=%d, lvids=%d\n", &rns, first, lvids);

   if (!first && lvids) {
      parseException("ILLEGAL-TOP-LEVEL-LOCAL-VARIABLE", "local variables declared with 'my' in the top-level block of a Program object can only be declared in the very first code block parsed");
      // discard variables immediately
      for (int i = 0; i < lvids; ++i)
	 pop_local_var();
   }
   
   // now initialize root namespace and functions before local variables are popped off the stack
   qore_root_ns_private::parseInit();

   if (first) {
      // if parsing a module, then initialize the init function
      QoreModuleDefContext* qmd = get_module_def_context();
      if (qmd)
	 qmd->parseInit();

      // this call will pop all local vars off the stack
      setupLVList(lvids);
      first = false;
   }
   else if (lvars) {
      for (unsigned i = 0; i < lvars->size(); ++i)
	 pop_local_var();
   }

   assert(!getVStack());

   //printd(5, "TopLevelStatementBlock::parseInitTopLevel(this=%p): done (lvars=%p, %d vars, vstack = %p)\n", this, lvars, lvids, getVStack());
   return;
}
示例#8
0
LocalVar* push_local_var(const char* name, const QoreProgramLocation& loc, const QoreTypeInfo* typeInfo, bool is_arg, int n_refs, bool top_level) {
   QoreProgram* pgm = getProgram();

   LocalVar* lv = pgm->createLocalVar(name, typeInfo);

   QoreString ls;
   loc.toString(ls);
   //printd(5, "push_local_var() lv: %p name: %s type: %s %s\n", lv, name, typeInfo->getName(), ls.getBuffer());

   bool found_block = false;
   // check stack for duplicate entries
   bool avs = parse_check_parse_option(PO_ASSUME_LOCAL);
   if (is_arg) {
      lv->parseAssigned();
      if (pgm->checkWarning(QP_WARN_DUPLICATE_LOCAL_VARS | QP_WARN_DUPLICATE_BLOCK_VARS) || avs) {
         VNode* vnode = getVStack();
         while (vnode) {
            if (!found_block && vnode->isBlockStart())
               found_block = true;
            if (!strcmp(vnode->getName(), name)) {
	       if (!found_block) {
		  QoreStringNode* desc = new QoreStringNodeMaker("local variable '%s' was already declared in the same block", name);
		  if (avs) {
		     vnode->appendLocation(*desc);
		     parseException(loc, "PARSE-ERRPR", desc);
		  }
		  else {
		     vnode->appendLocation(*desc);
                     qore_program_private::makeParseWarning(getProgram(), loc, QP_WARN_DUPLICATE_BLOCK_VARS, "DUPLICATE-BLOCK-VARIABLE", desc);
		  }
	       }
	       else if (top_level || !vnode->isTopLevel()) {
		  QoreStringNode* desc = new QoreStringNodeMaker("local variable '%s' was already declared in this lexical scope", name);
		  vnode->appendLocation(*desc);
		  qore_program_private::makeParseWarning(getProgram(), loc, QP_WARN_DUPLICATE_LOCAL_VARS, "DUPLICATE-LOCAL-VARIABLE", desc);
	       }
	       break;
	    }
            vnode = vnode->nextSearch();
         }
      }
   }
   
   //printd(5, "push_local_var(): pushing var %s\n", name);
   new VNode(lv, &loc, n_refs, top_level);
   return lv;
}
示例#9
0
int parseDnWRITE(const char *header, const char *content)
{
    int ret = 0;
    if (header == NULL || header[0] == '\0' ||
                         strncmp(header, "HTTP/", strlen("HTTP/"))) {
        return EINVAL;
    }
    if (!(strstr(header, twoHundredOneCreatedCode))) {
        struct jsonException *exc = parseException(content);
        if (exc) {
            ret = printJsonException(exc, PRINT_EXC_ALL,
                                     "Calling WEBHDFS (WRITE(DataNode))");
        } else {
            ret = EIO;
        }
    }
    return ret;
}
示例#10
0
AbstractQoreNode* VarRefNode::parseInitIntern(LocalVar *oflag, int pflag, int &lvids, const QoreTypeInfo *typeInfo, bool is_new) {
   if (pflag & PF_CONST_EXPRESSION)
      parseException("ILLEGAL-VARIABLE-REFERENCE", "variable reference '%s' used illegally in an expression executed at parse time to initialize a constant value", name.ostr);

   //printd(5, "VarRefNode::parseInitIntern() this: %p '%s' type: %d %p '%s'\n", this, name.ostr, type, typeInfo, typeInfo->getName());
   // if it is a new variable being declared
   if (type == VT_LOCAL || type == VT_CLOSURE || type == VT_LOCAL_TS) {
      if (!ref.id) {
	 ref.id = push_local_var(name.ostr, loc, typeInfo, true, is_new ? 1 : 0, pflag & PF_TOP_LEVEL);
	 ++lvids;
      }
      //printd(5, "VarRefNode::parseInitIntern() this: %p local var '%s' declared (id: %p)\n", this, name.ostr, ref.id);
   }
   else if (type != VT_GLOBAL) {
      assert(type == VT_UNRESOLVED);
      // otherwise reference must be resolved
      resolve(typeInfo);
   }

   return this;
}
示例#11
0
/**
 * Check if the header contains correct information
 * ("307 TEMPORARY_REDIRECT" and "Location")
 * 
 * @param header    Header for parsing
 * @param content   Contains exception information 
 *                  if the remote operation failed
 * @param operation Specify the remote operation when printing out exception
 * @return 0 for success
 */
static int checkRedirect(const char *header,
                         const char *content, const char *operation)
{
    const char *locTag = "Location";
    int ret = 0, offset = 0;
    
    // The header must start with "HTTP/1.1"
    if (!header || strncmp(header, httpHeaderString,
                           strlen(httpHeaderString))) {
        return EINVAL;
    }
    
    offset += strlen(httpHeaderString);
    while (isspace(header[offset])) {
        offset++;
    }
    // Looking for "307 TEMPORARY_REDIRECT" in header
    if (strncmp(header + offset, temporaryRedirectCode,
                strlen(temporaryRedirectCode))) {
        // Process possible exception information
        struct jsonException *exc = parseException(content);
        if (exc) {
            ret = printJsonException(exc, PRINT_EXC_ALL,
                                     "Calling WEBHDFS (%s)", operation);
        } else {
            ret = EIO;
        }
        return ret;
    }
    // Here we just simply check if header contains "Location" tag,
    // detailed processing is in parseDnLoc
    if (!(strstr(header, locTag))) {
        ret = EIO;
    }
    return ret;
}