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; }
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"); }
/** 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; }
/** * 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; }
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; }
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; } }
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; }
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; }
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; }
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; }
/** * 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; }