void ArgTemplate(FnCall *fp, const FnCallArg *argtemplate, Rlist *realargs) { int argnum, i; Rlist *rp = fp->args; char id[CF_BUFSIZE], output[CF_BUFSIZE]; const FnCallType *fn = FnCallTypeGet(fp->name); snprintf(id, CF_MAXVARSIZE, "built-in FnCall %s-arg", fp->name); for (argnum = 0; rp != NULL && argtemplate[argnum].pattern != NULL; argnum++) { if (rp->type != RVAL_TYPE_FNCALL) { /* Nested functions will not match to lval so don't bother checking */ SyntaxTypeMatch err = CheckConstraintTypeMatch(id, (Rval) {rp->item, rp->type}, argtemplate[argnum].dtype, argtemplate[argnum].pattern, 1); if (err != SYNTAX_TYPE_MATCH_OK && err != SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED) { FatalError("in %s: %s", id, SyntaxTypeMatchToString(err)); } } rp = rp->next; } if (argnum != RlistLen(realargs) && !fn->varargs) { snprintf(output, CF_BUFSIZE, "Argument template mismatch handling function %s(", fp->name); RlistShow(stderr, realargs); fprintf(stderr, ")\n"); for (i = 0, rp = realargs; i < argnum; i++) { printf(" arg[%d] range %s\t", i, argtemplate[i].pattern); if (rp != NULL) { RvalShow(stdout, (Rval) {rp->item, rp->type}); rp = rp->next; } else { printf(" ? "); } printf("\n"); } FatalError("Bad arguments"); } for (rp = realargs; rp != NULL; rp = rp->next) { CfDebug("finalarg: %s\n", (char *) rp->item); } CfDebug("End ArgTemplate\n"); }
static FnCallResult CallFunction(EvalContext *ctx, FnCall *fp, Rlist *expargs) { Rlist *rp = fp->args; const FnCallType *fncall_type = FnCallTypeGet(fp->name); int argnum = 0; for (argnum = 0; rp != NULL && fncall_type->args[argnum].pattern != NULL; argnum++) { if (rp->val.type != RVAL_TYPE_FNCALL) { /* Nested functions will not match to lval so don't bother checking */ SyntaxTypeMatch err = CheckConstraintTypeMatch(fp->name, rp->val, fncall_type->args[argnum].dtype, fncall_type->args[argnum].pattern, 1); if (err != SYNTAX_TYPE_MATCH_OK && err != SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED) { FatalError(ctx, "In function '%s', '%s'", fp->name, SyntaxTypeMatchToString(err)); } } rp = rp->next; } char output[CF_BUFSIZE]; if (argnum != RlistLen(expargs) && !(fncall_type->options & FNCALL_OPTION_VARARG)) { snprintf(output, CF_BUFSIZE, "Argument template mismatch handling function %s(", fp->name); RlistShow(stderr, expargs); fprintf(stderr, ")\n"); rp = expargs; for (int i = 0; i < argnum; i++) { printf(" arg[%d] range %s\t", i, fncall_type->args[i].pattern); if (rp != NULL) { RvalShow(stdout, rp->val); rp = rp->next; } else { printf(" ? "); } printf("\n"); } FatalError(ctx, "Bad arguments"); } return (*fncall_type->impl) (ctx, fp, expargs); }
void BannerSubBundle(Bundle *bp, Rlist *params) { CfOut(OUTPUT_LEVEL_VERBOSE, "", "\n"); CfOut(OUTPUT_LEVEL_VERBOSE, "", " * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n"); if (VERBOSE || DEBUG) { printf("%s> BUNDLE %s", VPREFIX, bp->name); } if (params && (VERBOSE || DEBUG)) { printf("("); RlistShow(stdout, params); printf(" )\n"); } else { if (VERBOSE || DEBUG) printf("\n"); } CfOut(OUTPUT_LEVEL_VERBOSE, "", " * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n"); CfOut(OUTPUT_LEVEL_VERBOSE, "", "\n"); }
void ScopeAugment(EvalContext *ctx, const Bundle *bp, const Rlist *arguments) { if (RlistLen(bp->args) != RlistLen(arguments)) { CfOut(OUTPUT_LEVEL_ERROR, "", "While constructing scope \"%s\"\n", bp->name); fprintf(stderr, "Formal = "); RlistShow(stderr, bp->args); fprintf(stderr, ", Actual = "); RlistShow(stderr, arguments); fprintf(stderr, "\n"); FatalError(ctx, "Augment scope, formal and actual parameter mismatch is fatal"); } for (const Rlist *rpl = bp->args, *rpr = arguments; rpl != NULL; rpl = rpl->next, rpr = rpr->next) { const char *lval = rpl->item; CfOut(OUTPUT_LEVEL_VERBOSE, "", " ? Augment scope %s with %s (%c)\n", bp->name, lval, rpr->type); // CheckBundleParameters() already checked that there is no namespace collision // By this stage all functions should have been expanded, so we only have scalars left if (IsNakedVar(rpr->item, '@')) { DataType vtype; char qnaked[CF_MAXVARSIZE]; char naked[CF_BUFSIZE]; GetNaked(naked, rpr->item); if (IsQualifiedVariable(naked) && strchr(naked, CF_NS) == NULL) { snprintf(qnaked, CF_MAXVARSIZE, "%s%c%s", bp->ns, CF_NS, naked); } Rval retval; EvalContextVariableGet(ctx, (VarRef) { NULL, bp->name, qnaked }, &retval, &vtype); switch (vtype) { case DATA_TYPE_STRING_LIST: case DATA_TYPE_INT_LIST: case DATA_TYPE_REAL_LIST: ScopeNewList(ctx, (VarRef) { NULL, bp->name, lval }, RvalCopy((Rval) { retval.item, RVAL_TYPE_LIST}).item, DATA_TYPE_STRING_LIST); break; default: CfOut(OUTPUT_LEVEL_ERROR, "", " !! List parameter \"%s\" not found while constructing scope \"%s\" - use @(scope.variable) in calling reference", qnaked, bp->name); ScopeNewScalar(ctx, (VarRef) { NULL, bp->name, lval }, rpr->item, DATA_TYPE_STRING); break; } } else { switch(rpr->type) { case RVAL_TYPE_SCALAR: ScopeNewScalar(ctx, (VarRef) { NULL, bp->name, lval }, rpr->item, DATA_TYPE_STRING); break; case RVAL_TYPE_FNCALL: { FnCall *subfp = rpr->item; Promise *pp = NULL; // This argument should really get passed down. Rval rval = FnCallEvaluate(ctx, subfp, pp).rval; if (rval.type == RVAL_TYPE_SCALAR) { ScopeNewScalar(ctx, (VarRef) { NULL, bp->name, lval }, rval.item, DATA_TYPE_STRING); } else { CfOut(OUTPUT_LEVEL_ERROR, "", "Only functions returning scalars can be used as arguments"); } } break; default: ProgrammingError("An argument neither a scalar nor a list seemed to appear. Impossible"); } } } /* Check that there are no danglers left to evaluate in the hash table itself */ { Scope *ptr = ScopeGet(bp->name); AssocHashTableIterator i = HashIteratorInit(ptr->hashtable); CfAssoc *assoc = NULL; while ((assoc = HashIteratorNext(&i))) { Rval retval = ExpandPrivateRval(ctx, bp->name, assoc->rval); // Retain the assoc, just replace rval RvalDestroy(assoc->rval); assoc->rval = retval; } } return; }
void ScopeAugment(EvalContext *ctx, const Bundle *bp, const Promise *pp, const Rlist *arguments) { if (RlistLen(bp->args) != RlistLen(arguments)) { Log(LOG_LEVEL_ERR, "While constructing scope '%s'", bp->name); fprintf(stderr, "Formal = "); RlistShow(stderr, bp->args); fprintf(stderr, ", Actual = "); RlistShow(stderr, arguments); fprintf(stderr, "\n"); FatalError(ctx, "Augment scope, formal and actual parameter mismatch is fatal"); } const Bundle *pbp = NULL; if (pp != NULL) { pbp = PromiseGetBundle(pp); } for (const Rlist *rpl = bp->args, *rpr = arguments; rpl != NULL; rpl = rpl->next, rpr = rpr->next) { const char *lval = rpl->item; Log(LOG_LEVEL_VERBOSE, "Augment scope '%s' with variable '%s' (type: %c)", bp->name, lval, rpr->type); // CheckBundleParameters() already checked that there is no namespace collision // By this stage all functions should have been expanded, so we only have scalars left if (IsNakedVar(rpr->item, '@')) { DataType vtype; char naked[CF_BUFSIZE]; GetNaked(naked, rpr->item); Rval retval; if (pbp != NULL) { VarRef *ref = VarRefParseFromBundle(naked, pbp); EvalContextVariableGet(ctx, ref, &retval, &vtype); VarRefDestroy(ref); } else { VarRef *ref = VarRefParseFromBundle(naked, bp); EvalContextVariableGet(ctx, ref, &retval, &vtype); VarRefDestroy(ref); } switch (vtype) { case DATA_TYPE_STRING_LIST: case DATA_TYPE_INT_LIST: case DATA_TYPE_REAL_LIST: { VarRef *ref = VarRefParseFromBundle(lval, bp); EvalContextVariablePut(ctx, ref, (Rval) { retval.item, RVAL_TYPE_LIST}, DATA_TYPE_STRING_LIST); VarRefDestroy(ref); } break; default: { Log(LOG_LEVEL_ERR, "List parameter '%s' not found while constructing scope '%s' - use @(scope.variable) in calling reference", naked, bp->name); VarRef *ref = VarRefParseFromBundle(lval, bp); EvalContextVariablePut(ctx, ref, (Rval) { rpr->item, RVAL_TYPE_SCALAR }, DATA_TYPE_STRING); VarRefDestroy(ref); } break; } } else { switch(rpr->type) { case RVAL_TYPE_SCALAR: { VarRef *ref = VarRefParseFromBundle(lval, bp); EvalContextVariablePut(ctx, ref, (Rval) { rpr->item, RVAL_TYPE_SCALAR }, DATA_TYPE_STRING); VarRefDestroy(ref); } break; case RVAL_TYPE_FNCALL: { FnCall *subfp = rpr->item; Rval rval = FnCallEvaluate(ctx, subfp, pp).rval; if (rval.type == RVAL_TYPE_SCALAR) { VarRef *ref = VarRefParseFromBundle(lval, bp); EvalContextVariablePut(ctx, ref, (Rval) { rval.item, RVAL_TYPE_SCALAR }, DATA_TYPE_STRING); VarRefDestroy(ref); } else { Log(LOG_LEVEL_ERR, "Only functions returning scalars can be used as arguments"); } } break; default: ProgrammingError("An argument neither a scalar nor a list seemed to appear. Impossible"); } } } /* Check that there are no danglers left to evaluate in the hash table itself */ return; }