Exemple #1
0
void ScopePushThis()
{
    static const char RVAL_TYPE_STACK = 'k';

    Scope *op = ScopeGet(NULL, "this");
    if (!op)
    {
        return;
    }

    int frame_index = RlistLen(CF_STCK);
    char name[CF_MAXVARSIZE];
    snprintf(name, CF_MAXVARSIZE, "this_%d", frame_index + 1);
    free(op->scope);
    free(op->ns);
    op->scope = xstrdup(name);

    Rlist *rp = xmalloc(sizeof(Rlist));

    rp->next = CF_STCK;
    rp->item = op;
    rp->type = RVAL_TYPE_STACK;
    CF_STCK = rp;

    ScopeNew(NULL, "this");
}
Exemple #2
0
void ScopeSetCurrent(const char *name)
{
    Scope *scope = ScopeGet(name);
    if (!scope)
    {
        scope = ScopeNew(name);
    }

    SCOPE_CURRENT = scope;
}
Exemple #3
0
void ScopePutMatch(int index, const char *value)
{
    if (!SCOPE_MATCH)
    {
        SCOPE_MATCH = ScopeNew("match");
    }
    Scope *ptr = SCOPE_MATCH;

    char lval[4] = { 0 };
    snprintf(lval, 3, "%d", index);

    Rval rval = (Rval) { value, RVAL_TYPE_SCALAR };

    CfAssoc *assoc = HashLookupElement(ptr->hashtable, lval);

    if (assoc)
    {
        if (CompareVariableValue(rval, assoc) == 0)
        {
            /* Identical value, keep as is */
        }
        else
        {
            /* Different value, bark and replace */
            if (!UnresolvedVariables(assoc, RVAL_TYPE_SCALAR))
            {
                CfOut(OUTPUT_LEVEL_INFORM, "", " !! Duplicate selection of value for variable \"%s\" in scope %s", lval, ptr->scope);
            }
            RvalDestroy(assoc->rval);
            assoc->rval = RvalCopy(rval);
            assoc->dtype = DATA_TYPE_STRING;
            CfDebug("Stored \"%s\" in context %s\n", lval, "match");
        }
    }
    else
    {
        if (!HashInsertElement(ptr->hashtable, lval, rval, DATA_TYPE_STRING))
        {
            ProgrammingError("Hash table is full");
        }
    }
}
Exemple #4
0
void ScopeCopy(const char *new_ns, const char *new_scopename, const Scope *old_scope)
/*
 * Thread safe
 */
{
    ScopeNew(new_ns, new_scopename);

    if (!ThreadLock(cft_vscope))
    {
        Log(LOG_LEVEL_ERR, "Could not lock VSCOPE");
        return;
    }

    if (old_scope)
    {
        Scope *np = ScopeGet(new_ns, new_scopename);
        HashCopy(np->hashtable, old_scope->hashtable);
    }

    ThreadUnlock(cft_vscope);
}
Exemple #5
0
void ScopeCopy(const char *new_scopename, const Scope *old_scope)
/*
 * Thread safe
 */
{
    CfDebug("\n*\nCopying scope data %s to %s\n*\n", old_scope->scope, new_scopename);

    ScopeNew(new_scopename);

    if (!ThreadLock(cft_vscope))
    {
        CfOut(OUTPUT_LEVEL_ERROR, "", "!! Could not lock VSCOPE");
        return;
    }

    if (old_scope)
    {
        Scope *np = ScopeGet(new_scopename);
        HashCopy(np->hashtable, old_scope->hashtable);
    }

    ThreadUnlock(cft_vscope);
}
Exemple #6
0
bool EvalContextVariablePut(EvalContext *ctx, VarRef lval, Rval rval, DataType type)
{
    Scope *ptr;
    const Rlist *rp;
    CfAssoc *assoc;

    if (rval.type == RVAL_TYPE_SCALAR)
    {
        CfDebug("AddVariableHash(%s.%s=%s (%s) rtype=%c)\n", lval.scope, lval.lval, (const char *) rval.item, CF_DATATYPES[type],
                rval.type);
    }
    else
    {
        CfDebug("AddVariableHash(%s.%s=(list) (%s) rtype=%c)\n", lval.scope, lval.lval, CF_DATATYPES[type], rval.type);
    }

    if (lval.lval == NULL || lval.scope == NULL)
    {
        CfOut(OUTPUT_LEVEL_ERROR, "", "scope.value = %s.%s", lval.scope, lval.lval);
        ProgrammingError("Bad variable or scope in a variable assignment, should not happen - forgotten to register a function call in fncall.c?");
    }

    if (rval.item == NULL)
    {
        CfDebug("No value to assignment - probably a parameter in an unused bundle/body\n");
        return false;
    }

    if (strlen(lval.lval) > CF_MAXVARSIZE)
    {
        char *lval_str = VarRefToString(lval);
        CfOut(OUTPUT_LEVEL_ERROR, "", "Variable %s cannot be added because its length exceeds the maximum length allowed: %d", lval_str, CF_MAXVARSIZE);
        free(lval_str);
        return false;
    }

/* If we are not expanding a body template, check for recursive singularities */

    if (strcmp(lval.scope, "body") != 0)
    {
        switch (rval.type)
        {
        case RVAL_TYPE_SCALAR:

            if (StringContainsVar((char *) rval.item, lval.lval))
            {
                CfOut(OUTPUT_LEVEL_ERROR, "", "Scalar variable %s.%s contains itself (non-convergent): %s", lval.scope, lval.lval,
                      (char *) rval.item);
                return false;
            }
            break;

        case RVAL_TYPE_LIST:

            for (rp = rval.item; rp != NULL; rp = rp->next)
            {
                if (StringContainsVar((char *) rp->item, lval.lval))
                {
                    CfOut(OUTPUT_LEVEL_ERROR, "", "List variable %s contains itself (non-convergent)", lval.lval);
                    return false;
                }
            }
            break;

        default:
            break;
        }
    }

    ptr = ScopeGet(lval.scope);
    if (!ptr)
    {
        ptr = ScopeNew(lval.scope);
        if (!ptr)
        {
            return false;
        }
    }

// Look for outstanding lists in variable rvals

    if (THIS_AGENT_TYPE == AGENT_TYPE_COMMON)
    {
        Rlist *listvars = NULL;

        if (ScopeGetCurrent() && strcmp(ScopeGetCurrent()->scope, "this") != 0)
        {
            MapIteratorsFromRval(ScopeGetCurrent()->scope, &listvars, rval);

            if (listvars != NULL)
            {
                CfOut(OUTPUT_LEVEL_ERROR, "", " !! Redefinition of variable \"%s\" (embedded list in RHS) in context \"%s\"",
                      lval.lval, ScopeGetCurrent()->scope);
            }

            RlistDestroy(listvars);
        }
    }

    assoc = HashLookupElement(ptr->hashtable, lval.lval);

    if (assoc)
    {
        if (CompareVariableValue(rval, assoc) == 0)
        {
            /* Identical value, keep as is */
        }
        else
        {
            /* Different value, bark and replace */
            if (!UnresolvedVariables(assoc, rval.type))
            {
                CfOut(OUTPUT_LEVEL_INFORM, "", " !! Duplicate selection of value for variable \"%s\" in scope %s", lval.lval, ptr->scope);
            }
            RvalDestroy(assoc->rval);
            assoc->rval = RvalCopy(rval);
            assoc->dtype = type;
            CfDebug("Stored \"%s\" in context %s\n", lval.lval, lval.scope);
        }
    }
    else
    {
        if (!HashInsertElement(ptr->hashtable, lval.lval, rval, type))
        {
            ProgrammingError("Hash table is full");
        }
    }

    CfDebug("Added Variable %s in scope %s with value (omitted)\n", lval.lval, lval.scope);
    return true;
}
Exemple #7
0
bool EvalContextVariablePut(EvalContext *ctx, VarRef lval, Rval rval, DataType type)
{
    assert(type != DATA_TYPE_NONE);

    if (lval.lval == NULL || lval.scope == NULL)
    {
        ProgrammingError("Bad variable or scope in a variable assignment. scope.value = %s.%s", lval.scope, lval.lval);
    }

    if (rval.item == NULL)
    {
        return false;
    }

    if (strlen(lval.lval) > CF_MAXVARSIZE)
    {
        char *lval_str = VarRefToString(lval, true);
        Log(LOG_LEVEL_ERR, "Variable '%s'' cannot be added because its length exceeds the maximum length allowed '%d' characters", lval_str, CF_MAXVARSIZE);
        free(lval_str);
        return false;
    }

    // If we are not expanding a body template, check for recursive singularities
    if (strcmp(lval.scope, "body") != 0)
    {
        switch (rval.type)
        {
        case RVAL_TYPE_SCALAR:
            if (StringContainsVar((char *) rval.item, lval.lval))
            {
                Log(LOG_LEVEL_ERR, "Scalar variable '%s.%s' contains itself (non-convergent), value '%s'", lval.scope, lval.lval,
                      (char *) rval.item);
                return false;
            }
            break;

        case RVAL_TYPE_LIST:
            for (const Rlist *rp = rval.item; rp != NULL; rp = rp->next)
            {
                if (StringContainsVar(rp->item, lval.lval))
                {
                    Log(LOG_LEVEL_ERR, "List variable '%s' contains itself (non-convergent)", lval.lval);
                    return false;
                }
            }
            break;

        default:
            break;
        }
    }
    else
    {
        assert(STACK_FRAME_TYPE_BODY == LastStackFrame(ctx, 0)->type);
    }

    Scope *put_scope = ScopeGet(lval.scope);
    if (!put_scope)
    {
        put_scope = ScopeNew(lval.scope);
        if (!put_scope)
        {
            return false;
        }
    }

// Look for outstanding lists in variable rvals

    if (THIS_AGENT_TYPE == AGENT_TYPE_COMMON)
    {
        Rlist *listvars = NULL;
        Rlist *scalars = NULL; // TODO what do we do with scalars?

        if (ScopeGetCurrent() && strcmp(ScopeGetCurrent()->scope, "this") != 0)
        {
            MapIteratorsFromRval(ctx, ScopeGetCurrent()->scope, &listvars, &scalars, rval);

            if (listvars != NULL)
            {
                Log(LOG_LEVEL_ERR, "Redefinition of variable '%s' (embedded list in RHS) in context '%s'",
                      lval.lval, ScopeGetCurrent()->scope);
            }

            RlistDestroy(listvars);
            RlistDestroy(scalars);
        }
    }

    // FIX: lval is stored with array params as part of the lval for legacy reasons.
    char *final_lval = VarRefToString(lval, false);

    CfAssoc *assoc = HashLookupElement(put_scope->hashtable, final_lval);
    if (assoc)
    {
        if (CompareVariableValue(rval, assoc) != 0)
        {
            /* Different value, bark and replace */
            if (!UnresolvedVariables(assoc, rval.type))
            {
                Log(LOG_LEVEL_INFO, "Replaced value of variable '%s' in scope '%s'", lval.lval, put_scope->scope);
            }
            RvalDestroy(assoc->rval);
            assoc->rval = RvalCopy(rval);
            assoc->dtype = type;
        }
    }
    else
    {
        if (!HashInsertElement(put_scope->hashtable, final_lval, rval, type))
        {
            ProgrammingError("Hash table is full");
        }
    }

    free(final_lval);
    return true;
}