static void DeleteAllClasses(EvalContext *ctx, const Rlist *list) { for (const Rlist *rp = list; rp != NULL; rp = rp->next) { if (CheckParseContext((char *) rp->item, CF_IDRANGE) != SYNTAX_TYPE_MATCH_OK) { return; // TODO: interesting course of action, but why is the check there in the first place? } if (EvalContextHeapContainsHard(ctx, (char *) rp->item)) { Log(LOG_LEVEL_ERR, "You cannot cancel a reserved hard class '%s' in post-condition classes", RlistScalarValue(rp)); } const char *string = (char *) (rp->item); Log(LOG_LEVEL_VERBOSE, "Cancelling class '%s'", string); EvalContextHeapPersistentRemove(string); EvalContextHeapRemoveSoft(ctx, CanonifyName(string)); EvalContextStackFrameAddNegated(ctx, CanonifyName(string)); } }
SyntaxTypeMatch CheckConstraintTypeMatch(const char *lval, Rval rval, DataType dt, const char *range, int level) { Rlist *rp; Item *checklist; /* Get type of lval */ switch (rval.type) { case RVAL_TYPE_SCALAR: switch (dt) { case CF_DATA_TYPE_STRING_LIST: case CF_DATA_TYPE_INT_LIST: case CF_DATA_TYPE_REAL_LIST: case CF_DATA_TYPE_CONTEXT_LIST: case CF_DATA_TYPE_OPTION_LIST: if (level == 0) { return SYNTAX_TYPE_MATCH_ERROR_GOT_SCALAR; } break; default: /* Only lists are incompatible with scalars */ break; } break; case RVAL_TYPE_LIST: switch (dt) { case CF_DATA_TYPE_STRING_LIST: case CF_DATA_TYPE_INT_LIST: case CF_DATA_TYPE_REAL_LIST: case CF_DATA_TYPE_CONTEXT_LIST: case CF_DATA_TYPE_OPTION_LIST: break; default: return SYNTAX_TYPE_MATCH_ERROR_GOT_LIST; } for (rp = (Rlist *) rval.item; rp != NULL; rp = rp->next) { SyntaxTypeMatch err = CheckConstraintTypeMatch(lval, rp->val, dt, range, 1); switch (err) { case SYNTAX_TYPE_MATCH_OK: case SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED: break; default: return err; } } return SYNTAX_TYPE_MATCH_OK; case RVAL_TYPE_FNCALL: /* Fn-like objects are assumed to be parameterized bundles in these... */ checklist = SplitString("bundlesequence,edit_line,edit_xml,usebundle,service_bundle,home_bundle", ','); if (!IsItemIn(checklist, lval)) { SyntaxTypeMatch err = CheckFnCallType(RvalFnCallValue(rval)->name, dt); DeleteItemList(checklist); return err; } DeleteItemList(checklist); return SYNTAX_TYPE_MATCH_OK; case RVAL_TYPE_CONTAINER: break; case RVAL_TYPE_NOPROMISEE: return SYNTAX_TYPE_MATCH_ERROR_GOT_NULL; } /* If we get here, we have a literal scalar type */ switch (dt) { case CF_DATA_TYPE_STRING: case CF_DATA_TYPE_STRING_LIST: return CheckParseString(lval, (const char *) rval.item, range); case CF_DATA_TYPE_INT: case CF_DATA_TYPE_INT_LIST: return CheckParseInt(lval, (const char *) rval.item, range); case CF_DATA_TYPE_REAL: case CF_DATA_TYPE_REAL_LIST: return CheckParseReal(lval, (const char *) rval.item, range); case CF_DATA_TYPE_BODY: case CF_DATA_TYPE_BUNDLE: case CF_DATA_TYPE_CONTAINER: break; case CF_DATA_TYPE_OPTION: case CF_DATA_TYPE_OPTION_LIST: return CheckParseOpts(RvalScalarValue(rval), range); case CF_DATA_TYPE_CONTEXT: case CF_DATA_TYPE_CONTEXT_LIST: return CheckParseContext((const char *) rval.item, range); case CF_DATA_TYPE_INT_RANGE: return CheckParseIntRange(lval, (const char *) rval.item, range); case CF_DATA_TYPE_REAL_RANGE: return CheckParseRealRange(lval, (char *) rval.item, range); default: ProgrammingError("Unknown (unhandled) datatype for lval = %s (CheckConstraintTypeMatch)", lval); break; } return SYNTAX_TYPE_MATCH_OK; }
SyntaxTypeMatch CheckConstraintTypeMatch(const char *lval, Rval rval, DataType dt, const char *range, int level) { Rlist *rp; Item *checklist; CfDebug(" ------------------------------------------------\n"); if (dt == DATA_TYPE_BUNDLE || dt == DATA_TYPE_BODY) { CfDebug(" - Checking inline constraint/arg %s[%s] => mappedval (bundle/body)\n", lval, CF_DATATYPES[dt]); } else { CfDebug(" - Checking inline constraint/arg %s[%s] => mappedval (%c) %s\n", lval, CF_DATATYPES[dt], rval.type, range); } CfDebug(" ------------------------------------------------\n"); /* Get type of lval */ switch (rval.type) { case RVAL_TYPE_SCALAR: switch (dt) { case DATA_TYPE_STRING_LIST: case DATA_TYPE_INT_LIST: case DATA_TYPE_REAL_LIST: case DATA_TYPE_CONTEXT_LIST: case DATA_TYPE_OPTION_LIST: if (level == 0) { return SYNTAX_TYPE_MATCH_ERROR_GOT_SCALAR; } break; default: /* Only lists are incompatible with scalars */ break; } break; case RVAL_TYPE_LIST: switch (dt) { case DATA_TYPE_STRING_LIST: case DATA_TYPE_INT_LIST: case DATA_TYPE_REAL_LIST: case DATA_TYPE_CONTEXT_LIST: case DATA_TYPE_OPTION_LIST: break; default: return SYNTAX_TYPE_MATCH_ERROR_GOT_LIST; } for (rp = (Rlist *) rval.item; rp != NULL; rp = rp->next) { SyntaxTypeMatch err = CheckConstraintTypeMatch(lval, (Rval) {rp->item, rp->type}, dt, range, 1); switch (err) { case SYNTAX_TYPE_MATCH_OK: case SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED: break; default: return err; } } return SYNTAX_TYPE_MATCH_OK; case RVAL_TYPE_FNCALL: /* Fn-like objects are assumed to be parameterized bundles in these... */ checklist = SplitString("bundlesequence,edit_line,edit_xml,usebundle,service_bundle", ','); if (!IsItemIn(checklist, lval)) { SyntaxTypeMatch err = CheckFnCallType(lval, ((FnCall *) rval.item)->name, dt, range); DeleteItemList(checklist); return err; } DeleteItemList(checklist); return SYNTAX_TYPE_MATCH_OK; default: break; } /* If we get here, we have a literal scalar type */ switch (dt) { case DATA_TYPE_STRING: case DATA_TYPE_STRING_LIST: return CheckParseString(lval, (const char *) rval.item, range); case DATA_TYPE_INT: case DATA_TYPE_INT_LIST: return CheckParseInt(lval, (const char *) rval.item, range); case DATA_TYPE_REAL: case DATA_TYPE_REAL_LIST: return CheckParseReal(lval, (const char *) rval.item, range); case DATA_TYPE_BODY: case DATA_TYPE_BUNDLE: CfDebug("Nothing to check for body reference\n"); break; case DATA_TYPE_OPTION: case DATA_TYPE_OPTION_LIST: return CheckParseOpts(lval, (const char *) rval.item, range); case DATA_TYPE_CONTEXT: case DATA_TYPE_CONTEXT_LIST: return CheckParseContext((const char *) rval.item, range); case DATA_TYPE_INT_RANGE: return CheckParseIntRange(lval, (const char *) rval.item, range); case DATA_TYPE_REAL_RANGE: return CheckParseRealRange(lval, (char *) rval.item, range); default: ProgrammingError("Unknown (unhandled) datatype for lval = %s (CheckConstraintTypeMatch)", lval); break; } CfDebug("end CheckConstraintTypeMatch---------\n"); return SYNTAX_TYPE_MATCH_OK; }