Exemplo n.º 1
0
static void test_copy_compare(void)
{
    JsonElement *bench = LoadTestFile("benchmark.json");
    assert_true(bench != NULL);

    JsonElement *copy = JsonCopy(bench);
    assert_true(copy != NULL);

    assert_int_equal(0, JsonCompare(copy, bench));

    JsonDestroy(bench);
    JsonDestroy(copy);
}
Exemplo n.º 2
0
JsonElement *RvalToJson(Rval rval)
{
    assert(rval.item);

    switch (rval.type)
    {
    case RVAL_TYPE_SCALAR:
        return JsonStringCreate(RvalScalarValue(rval));
    case RVAL_TYPE_LIST:
        return RlistToJson(RvalRlistValue(rval));
    case RVAL_TYPE_FNCALL:
        return FnCallToJson(RvalFnCallValue(rval));
    case RVAL_TYPE_CONTAINER:
        return JsonCopy(RvalContainerValue(rval));
    case RVAL_TYPE_NOPROMISEE:
        assert(false);
        return JsonObjectCreate(1);
    }

    assert(false);
    return NULL;
}
Exemplo n.º 3
0
Arquivo: rlist.c Projeto: cduclos/core
Rval RvalNew(const void *item, RvalType type)
{
    switch (type)
    {
    case RVAL_TYPE_SCALAR:
        return (Rval) { xstrdup(item), RVAL_TYPE_SCALAR };

    case RVAL_TYPE_FNCALL:
        return (Rval) { FnCallCopy(item), RVAL_TYPE_FNCALL };

    case RVAL_TYPE_LIST:
        return (Rval) { RlistCopy(item), RVAL_TYPE_LIST };

    case RVAL_TYPE_CONTAINER:
        return (Rval) { JsonCopy(item), RVAL_TYPE_CONTAINER };

    case RVAL_TYPE_NOPROMISEE:
        return ((Rval) {NULL, type});
    }

    assert(false);
    return ((Rval) { NULL, RVAL_TYPE_NOPROMISEE });
}
Exemplo n.º 4
0
Arquivo: expand.c Projeto: tzz/core
Rval ExpandPrivateRval(EvalContext *ctx, const char *ns, const char *scope, const void *rval_item, RvalType rval_type)
{
    Rval returnval;
    returnval.item = NULL;
    returnval.type = RVAL_TYPE_NOPROMISEE;

    switch (rval_type)
    {
    case RVAL_TYPE_SCALAR:
        {
            Buffer *buffer = BufferNew();
            ExpandScalar(ctx, ns, scope, rval_item, buffer);
            returnval = (Rval) { BufferClose(buffer),  RVAL_TYPE_SCALAR };
        }
        break;

    case RVAL_TYPE_LIST:
        returnval.item = ExpandList(ctx, ns, scope, rval_item, true);
        returnval.type = RVAL_TYPE_LIST;
        break;

    case RVAL_TYPE_FNCALL:
        returnval.item = ExpandFnCall(ctx, ns, scope, rval_item);
        returnval.type = RVAL_TYPE_FNCALL;
        break;

    case RVAL_TYPE_CONTAINER:
        returnval = RvalNew(JsonCopy(rval_item), RVAL_TYPE_CONTAINER);
        break;

    case RVAL_TYPE_NOPROMISEE:
        break;
    }

    return returnval;
}
Exemplo n.º 5
0
Rval RvalNewRewriter(const void *item, RvalType type, JsonElement *map)
{
    switch (type)
    {
    case RVAL_TYPE_SCALAR:
        if (NULL != map && JsonLength(map) > 0 &&       // do we have a rewrite map?
            (strstr(item, "$(") || strstr(item, "${"))) // are there unresolved variable references?
        {
            // TODO: replace with BufferSearchAndReplace when the
            // string_replace code is merged.
            // Sorry about the CF_BUFSIZE ugliness.
            int max_size = 10*CF_BUFSIZE+1;
            char *buffer_from = xmalloc(max_size);
            char *buffer_to = xmalloc(max_size);

            Buffer *format = BufferNew();
            strncpy(buffer_from, item, max_size);

            for (int iteration = 0; iteration < 10; iteration++)
            {
                bool replacement_made = false;
                int var_start = -1;
                char closing_brace = 0;
                for (int c = 0; c < buffer_from[c]; c++)
                {
                    printf("In %s at %i: '%s'\n", __func__, __LINE__, buffer_from);
                    if (buffer_from[c] == '$')
                    {
                        if (buffer_from[c+1] == '(')
                        {
                            closing_brace = ')';
                        }
                        else if (buffer_from[c+1] == '{')
                        {
                            closing_brace = '}';
                        }

                        if (closing_brace)
                        {
                            c++;
                            var_start = c-1;
                        }
                    }
                    else if (var_start >= 0 && buffer_from[c] == closing_brace)
                    {
                        char saved = buffer_from[c];
                        buffer_from[c] = '\0';
                        const char *repl = JsonObjectGetAsString(map, buffer_from + var_start + 2);
                        buffer_from[c] = saved;

                        if (repl)
                        {
                            // Before the replacement.
                            memcpy(buffer_to, buffer_from, var_start);

                            // The actual replacement.
                            int repl_len = strlen(repl);
                            memcpy(buffer_to + var_start, repl, repl_len);

                            // The text after.
                            strlcpy(buffer_to + var_start + repl_len, buffer_from + c + 1, max_size - var_start - repl_len);

                            // Reset location to immediately after the replacement.
                            c = var_start + repl_len - 1;
                            var_start = -1;
                            strcpy(buffer_from, buffer_to);
                            closing_brace = 0;
                            replacement_made = true;
                        }
                    }
                }

                if (!replacement_made)
                {
                    break;
                }
            }

            char *ret = xstrdup(buffer_to);

            BufferDestroy(format);
            free(buffer_to);
            free(buffer_from);

            return (Rval) { ret, RVAL_TYPE_SCALAR };
        }
        else
        {
            return (Rval) { xstrdup(item), RVAL_TYPE_SCALAR };
        }

    case RVAL_TYPE_FNCALL:
        return (Rval) { FnCallCopyRewriter(item, map), RVAL_TYPE_FNCALL };

    case RVAL_TYPE_LIST:
        return (Rval) { RlistCopyRewriter(item, map), RVAL_TYPE_LIST };

    case RVAL_TYPE_CONTAINER:
        return (Rval) { JsonCopy(item), RVAL_TYPE_CONTAINER };

    case RVAL_TYPE_NOPROMISEE:
        return ((Rval) {NULL, type});
    }

    assert(false);
    return ((Rval) { NULL, RVAL_TYPE_NOPROMISEE });
}
Exemplo n.º 6
0
// See fncall.c for the usage of allow_all_types.
Rlist *RlistAppendAllTypes(Rlist **start, const void *item, RvalType type, bool allow_all_types)
{
    Rlist *lp = *start;

    switch (type)
    {
    case RVAL_TYPE_SCALAR:
        return RlistAppendScalar(start, item);

    case RVAL_TYPE_FNCALL:
        break;

    case RVAL_TYPE_LIST:
        if (allow_all_types)
        {
            JsonElement* store = JsonArrayCreate(RlistLen(item));
            for (const Rlist *rp = item; rp; rp = rp->next)
            {
                JsonArrayAppendElement(store, RvalToJson(rp->val));
            }

            return RlistAppendRval(start, (Rval) { store, RVAL_TYPE_CONTAINER });
        }

        for (const Rlist *rp = item; rp; rp = rp->next)
        {
            lp = RlistAppendRval(start, RvalCopy(rp->val));
        }

        return lp;

    case RVAL_TYPE_CONTAINER:
        if (allow_all_types)
        {
            return RlistAppendRval(start, (Rval) { JsonCopy((JsonElement*) item), RVAL_TYPE_CONTAINER });
        }

        // note falls through!

    default:
        Log(LOG_LEVEL_DEBUG, "Cannot append %c to rval-list '%s'", type, (char *) item);
        return NULL;
    }

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

    rp->val  = RvalNew(item, type);
    rp->next = NULL;

    if (*start == NULL)
    {
        *start = rp;
    }
    else
    {
        for (lp = *start; lp->next != NULL; lp = lp->next)
        {
        }

        lp->next = rp;
    }

    return rp;
}
Exemplo n.º 7
0
/* Inserts an Rlist node with value #rval, right after the rlist node #node. */
void RlistInsertAfter(Rlist *node, Rval rval)
{
    assert(node != NULL);

    Rlist new_node = { .val  = rval,
                       .next = node->next };

    node->next = xmemdup(&new_node, sizeof(new_node));
}

Rval RvalNewRewriter(const void *item, RvalType type, JsonElement *map)
{
    switch (type)
    {
    case RVAL_TYPE_SCALAR:
        if (map != NULL && JsonLength(map) > 0 &&       // do we have a rewrite map?
            (strstr(item, "$(") || strstr(item, "${"))) // are there unresolved variable references?
        {
            // TODO: replace with BufferSearchAndReplace when the
            // string_replace code is merged.
            // Sorry about the CF_BUFSIZE ugliness.
            int max_size = 10*CF_BUFSIZE+1;
            char *buffer_from = xmalloc(max_size);
            char *buffer_to = xmalloc(max_size);

            Buffer *format = BufferNew();
            StringCopy(item, buffer_from, max_size);

            for (int iteration = 0; iteration < 10; iteration++)
            {
                bool replacement_made = false;
                int var_start = -1;
                char closing_brace = 0;
                for (int c = 0; c < buffer_from[c]; c++)
                {
                    if (buffer_from[c] == '$')
                    {
                        if (buffer_from[c+1] == '(')
                        {
                            closing_brace = ')';
                        }
                        else if (buffer_from[c+1] == '{')
                        {
                            closing_brace = '}';
                        }

                        if (closing_brace)
                        {
                            c++;
                            var_start = c-1;
                        }
                    }
                    else if (var_start >= 0 && buffer_from[c] == closing_brace)
                    {
                        char saved = buffer_from[c];
                        buffer_from[c] = '\0';
                        const char *repl = JsonObjectGetAsString(map, buffer_from + var_start + 2);
                        buffer_from[c] = saved;

                        if (repl)
                        {
                            // Before the replacement.
                            memcpy(buffer_to, buffer_from, var_start);

                            // The actual replacement.
                            int repl_len = strlen(repl);
                            memcpy(buffer_to + var_start, repl, repl_len);

                            // The text after.
                            strlcpy(buffer_to + var_start + repl_len, buffer_from + c + 1, max_size - var_start - repl_len);

                            // Reset location to immediately after the replacement.
                            c = var_start + repl_len - 1;
                            var_start = -1;
                            StringCopy(buffer_to, buffer_from, max_size);
                            closing_brace = 0;
                            replacement_made = true;
                        }
                    }
                }

                if (!replacement_made)
                {
                    break;
                }
            }

            char *ret = xstrdup(buffer_to);

            BufferDestroy(format);
            free(buffer_to);
            free(buffer_from);

            return (Rval) { ret, RVAL_TYPE_SCALAR };
        }
        else
        {
            return (Rval) { xstrdup(item), RVAL_TYPE_SCALAR };
        }

    case RVAL_TYPE_FNCALL:
        return (Rval) { FnCallCopyRewriter(item, map), RVAL_TYPE_FNCALL };

    case RVAL_TYPE_LIST:
        return (Rval) { RlistCopyRewriter(item, map), RVAL_TYPE_LIST };

    case RVAL_TYPE_CONTAINER:
        return (Rval) { JsonCopy(item), RVAL_TYPE_CONTAINER };

    case RVAL_TYPE_NOPROMISEE:
        return ((Rval) {NULL, type});
    }

    assert(false);
    return ((Rval) { NULL, RVAL_TYPE_NOPROMISEE });
}

Rval RvalNew(const void *item, RvalType type)
{
    return RvalNewRewriter(item, type, NULL);
}

Rval RvalCopyRewriter(Rval rval, JsonElement *map)
{
    return RvalNewRewriter(rval.item, rval.type, map);
}

Rval RvalCopy(Rval rval)
{
    return RvalNew(rval.item, rval.type);
}

/*******************************************************************/

Rlist *RlistCopyRewriter(const Rlist *rp, JsonElement *map)
{
    Rlist *start = NULL;

    while (rp != NULL)
    {
        RlistAppendRval(&start, RvalCopyRewriter(rp->val, map));
        rp = rp->next;
    }

    return start;
}