Esempio n. 1
0
bool _corto_delegate_compatible(
    corto_delegate _this,
    corto_type type)

{
    static corto_uint32 _methodId;
    corto_method _method;
    bool _result;
    corto_interface _abstract;

    _abstract = corto_interface(corto_typeof(_this));

    /* Determine methodId once, then cache it for subsequent calls. */
    if (!_methodId) {
        _methodId = corto_interface_resolveMethodId(_abstract, "compatible(type type)");
    }
    corto_assert(_methodId, "virtual 'compatible(type type)' not found in '%s'%s%s", corto_fullpath(NULL, _abstract), corto_lasterr() ? ": " : "", corto_lasterr() ? corto_lasterr() : "");

    /* Lookup method-object. */
    _method = corto_interface_resolveMethodById(_abstract, _methodId);
    corto_assert(_method != NULL, "unresolved method '%s::compatible(type type)@%d'", corto_idof(_this), _methodId);

    if (corto_function(_method)->kind == CORTO_PROCEDURE_CDECL) {
        _result = ((bool ___ (*)(corto_object, corto_type))((corto_function)_method)->fptr)(_this, type);
    } else {
        corto_call(corto_function(_method), &_result, _this, type);
    }
    
    return _result;
}
Esempio n. 2
0
/* Resolve dependency, decrease refcount */
static int g_itemResolveDependency(void* o, void* userData) {
    g_dependency dep;
    corto_depresolver data;

    dep = o;
    data = userData;

    if (!dep->processed) {
        switch(dep->kind) {
        case CORTO_DECLARED:
            dep->item->declareCount--;

            corto_assert(dep->item->declareCount >= 0, "negative declareCount for item '%s'.", corto_nameof(dep->item->o));

            if (!dep->item->declareCount) {
                corto_llInsert(data->toPrint, dep->item);
            }
            break;
        case CORTO_DEFINED:
            dep->item->defineCount--;

            corto_assert(dep->item->defineCount >= 0, "negative defineCount for item '%s'.", corto_nameof(dep->item->o));

            if (!dep->item->defineCount) {
                corto_llInsert(data->toPrint, dep->item);
            }
            break;
        }
    }

    dep->processed = TRUE;

    return 1;
}
Esempio n. 3
0
void cdiff_file_headerBegin(cdiff_file file) {
    corto_assert(file != NULL, "NULL specified for file");
    corto_assert(file->cur != NULL, "select element before starting header");
    corto_assert(file->writeTo != 2, "end body before start writing to header");

    file->writeTo = 1;
    file->writeBuffer = CORTO_BUFFER_INIT;
}
Esempio n. 4
0
void cdiff_file_bodyEnd(cdiff_file file) {
    corto_assert(file != NULL, "NULL specified for file");
    corto_assert(file->writeTo == 2, "not writing to body");

    file->cur->body = corto_buffer_str(&file->writeBuffer);

    file->writeTo = 0;
    file->isChanged = TRUE;
}
Esempio n. 5
0
void cdiff_file_headerEnd(cdiff_file file) {
    corto_assert(file != NULL, "NULL specified for file");
    corto_assert(file->writeTo == 1, "not writing to header");

    char *header = corto_buffer_str(&file->writeBuffer);
    if (!file->cur->header) {
        file->cur->header = header;
    } else if (strcmp(header, file->cur->header)) {
        corto_ptr_setstr(&file->cur->header, header);
        file->isChanged = TRUE;
    }

    file->writeTo = 0;
}
Esempio n. 6
0
int16_t cdiff_file_bodyBegin(cdiff_file file) {
    corto_assert(file != NULL, "NULL specified for file");
    corto_assert(file->cur != NULL, "select element before starting body");
    corto_assert(file->writeTo != 1, "end header before start writing to body");

    /* Test if body is already set */
    if (file->cur->body) {
        return 1;
    }

    file->writeBuffer = CORTO_BUFFER_INIT;
    file->writeTo = 2;

    return 0;
}
Esempio n. 7
0
void cdiff_file_write(
    cdiff_file file, 
    char *fmt, 
    ...) 
{
    corto_assert(file != NULL, "NULL specified for file");

    if (file->newLine && file->indent) {
        int i;
        for (i = 0; i < file->indent * 4; i++) {
            corto_buffer_appendstrn(&file->writeBuffer, " ", 1);
        }
    }

    va_list args;
    va_start(args, fmt);
    corto_buffer_vappend(&file->writeBuffer, fmt, args);
    va_end(args);

    /* If no element specified for writing, write to new text element. */
    if (!file->cur && file->isNew) {
        cdiff_elem *el = corto_calloc(sizeof(cdiff_elem));
        el->kind = CDIFF_TEXT;
        el->body = corto_buffer_str(&file->writeBuffer);
        if (!file->elements) {
            file->elements = corto_ll_new();
        }
        corto_ll_append(file->elements, el);
        file->writeBuffer = CORTO_BUFFER_INIT;
    }

    file->newLine = fmt[strlen(fmt) - 1] == '\n';
}
Esempio n. 8
0
static corto_int16 json_deserCollection(void* p, corto_type t, JSON_Value *v)
{
    corto_assert(t->kind == CORTO_COLLECTION, "not deserializing composite");
    corto_type elementType = corto_collection(t)->elementType;

    /* Deserialize elements */
    JSON_Array* a = json_value_get_array(v);
    if (!a) {
        corto_seterr("invalid array");
        goto error;
    }

    size_t count = json_array_get_count(a);
    size_t i;

    for (i = 0; i < count; i++) {
        void *elementPtr = json_deser_allocElem(p, corto_collection(t), i);
        JSON_Value *elem = json_array_get_value(a, i);
        if (json_deserType(elementPtr, elementType, elem)) {
            goto error;
        }
    }

    return 0;
error:
    return -1;
}
Esempio n. 9
0
void corto_valueSetValue(corto_value* val, corto_void* v) {
    switch(val->kind) {
    case CORTO_OBJECT:
        val->is.object.o = v; /* Dangerous, but allowed */
        break;
    case CORTO_BASE:
        val->is.base.v = v;
        break;
    case CORTO_MEMBER:
        val->is.member.v = v;
        break;
    case CORTO_CONSTANT:
        val->is.constant.v = v;
        break;
    case CORTO_ELEMENT:
        val->is.element.v = v;
        break;
    case CORTO_MAP_ELEMENT:
        val->is.mapElement.v = v;
        break;
    case CORTO_VALUE:
    case CORTO_MEM:
        val->is.value.v = v; // ??
        break;
    default:
        corto_assert(0, "corto_valueSetValue: invalid valueKind %d.", val->kind);
        break;
    }
}
Esempio n. 10
0
/* Resolve cycles for dependency */
static void g_itemResolveDependencyCycles(g_dependency dep, struct corto_depresolver_s* data) {
    corto_uint32 sp;

    /* If item is already marked, there is no need to investigate it further. */
    if (!dep->marked) {
        /* If dependency is not on stack, scan further, if on stack, a cycle is found. */
        if (!(sp = g_dependencyOnStack(dep, data))) {
            data->stack[data->sp] = dep;
            data->sp++;
            corto_assert(data->sp < CYCLE_DEPTH, "stack-bound overflow.");

            /* Forward item and mark it. */
            g_itemResolveCycles(dep->item, data);
            dep->marked = TRUE;
            data->sp--;
        /* If a cycle is found, look on the stack for a weak dependency. */
        } else {
            corto_uint32 i;

            for(i=sp-1; i<data->sp; i++) {
                /* Break first weak dependency */
                if (data->stack[i]->weak && data->stack[i]->dependency->declared) {
                    g_itemResolveDependency(data->stack[i], data);

                    /* This dependency is already weakened, it cannot be weakened again. */
                    data->stack[i]->weak = FALSE;
                    break;
                }
            }
        }
    }
}
Esempio n. 11
0
/* Walk members, look it up */
corto_int16 ast_Initializer_findMember(corto_serializer s, corto_value* v, void* userData) {
    corto_uint32 result;
    ast_Initializer_findMember_t* data;

    result = 0;
    data = userData;

    switch(v->kind) {
    case CORTO_MEMBER:
        if (v->is.member.t->id == (corto_uint32)-1) {
            result = corto_serializeValue(s, v, userData);
        } else {
            if ((data->lookForLocation >= 0) && ((corto_uint32)data->lookForLocation == data->count)) {
                data->m = v->is.member.t;
                data->id = data->count;
                goto found;
            } else if (data->lookForString && !strcmp(data->lookForString, corto_idof(v->is.member.t))) {
                data->m = v->is.member.t;
                data->id = data->count;
                if (data->current >= data->count) {
                    goto found;
                }
            }
            data->count++;
        }
        break;
    default:
        corto_assert(0, "invalid valueKind for member-callback.");
        break;
    }

    return result;
found:
    return -1;
}
Esempio n. 12
0
corto_int16 json_deserialize(corto_value *v, corto_string s)
{
    corto_assert(v != NULL, "NULL passed to json_deserialize");

    char *json = s;
    if ((json[0] != '{') && (json[1] != '[') && (json[0] != '[')) {
        corto_asprintf(&json, "{\"value\": %s}", json);
    }

    JSON_Value *jsonValue = json_parse_string(json);
    if (!jsonValue) {
        corto_seterr("invalid JSON '%s'", json);
        goto error;
    }

    corto_type type = corto_value_getType(v);

    if (type->kind == CORTO_PRIMITIVE) {
        JSON_Object* jsonObj = json_value_get_object(jsonValue);
        if (!jsonObj) {
            corto_seterr("json: invalid JSON for primitive value '%s'", json);
            goto error;
        }

        JSON_Value *jsonValue = json_object_get_value(jsonObj, "value");
        if (!jsonValue) {
            corto_seterr("json: missing 'value' field for primitive value '%s'", json);
            goto error;
        }
    }

    if (json_deserialize_from_JSON_Value(v, jsonValue)) {
        goto error;
    }

    if (json != s) {
        corto_dealloc(json);
    }

    return 0;
error:
    if (json != s) {
        corto_dealloc(json);
    }

    if (jsonValue) {
        json_value_free(jsonValue);
    }
    return -1;
}
Esempio n. 13
0
corto_object md_resolve(int level, corto_string name, corto_object *parent, md_parseData* data) {
    corto_assert(level >= 1 && level <= 6, "Level must be between 1 and 6");
    corto_object o = NULL, current = NULL;

    corto_object previous = NULL;
    if (level == 1) {
        previous = data->destination;
    } else {
        corto_uint32 i = level - 1;
        while (i && !(previous = md_Doc(data->headers[i]))) {
            i--;
        }
        previous = data->headers[i];
    }
    if (previous == NULL) {
        goto notFound;
    }

    if (corto_instanceof(md_Doc_o, previous)) {
        current = md_Doc(previous)->o;
    }

    if (parent) {
        *parent = previous;
    }

    if (current || (level == 1)) {
        o = corto_resolve(current, name);
        if (o == NULL) {
            goto notFound;
        }
        if (!md_isAncestor(current, o)) {
            o = NULL;
        }
    }

    /* Clean up the lower levels of the doc hierarchy */
    int i = 6;
    do {
        data->headers[i] = NULL;
    } while (i-- > level);

    return o;
notFound:
    return NULL;
}
Esempio n. 14
0
void cdiff_file_elemBegin(cdiff_file file, char *fmt, ...) {
    corto_assert(file != NULL, "NULL specified for file");

    if (!file->elements) {
        file->elements = corto_ll_new();
    }

    cdiff_elem *el = NULL;
    char *id = NULL;

    if (fmt) {
        va_list args;
        va_start(args, fmt);
        corto_vasprintf(&id, fmt, args);
        va_end(args);

        el = cdiff_file_elemFind(file->elements, id);
        if (!el && file->legacyElements) {
            el = cdiff_file_elemFind(file->legacyElements, id);
        }
    }

    if (!el) {
        el = malloc (sizeof(cdiff_elem));
        el->id = id;
        el->header = NULL;
        el->body = NULL;
        el->kind = id ? CDIFF_FUNCTION : CDIFF_TEXT;
        file->isChanged = true;

        if (!file->elements) {
            file->elements = corto_ll_new();
        }
        corto_ll_append(file->elements, el);
    } else {
        free(id);
    }

    file->cur = el;
    file->writeTo = 0;
}
Esempio n. 15
0
corto_bool json_deserPrimitive(void* p, corto_type t, JSON_Value *v)
{
    corto_assert(t->kind == CORTO_PRIMITIVE, "not deserializing primitive");

    corto_primitive ptype = corto_primitive(t);

    switch (ptype->kind) {
    case CORTO_BOOLEAN:
        if (json_deserBoolean(p, ptype, v)) {
            goto error;
        }
        break;
    case CORTO_CHARACTER:
        break;
    case CORTO_INTEGER:
    case CORTO_UINTEGER:
    case CORTO_FLOAT:
    case CORTO_BINARY:
        if (json_deserNumber(p, ptype, v)) {
            goto error;
        }
        break;
    case CORTO_TEXT:
        if (json_deserText(p, ptype, v)) {
            goto error;
        }
    case CORTO_ENUM:
    case CORTO_BITMASK:
        if (json_deserConstant(p, ptype, v)) {
            goto error;
        }
        break;
    }

    return 0;
error:
    return 0;
}
Esempio n. 16
0
/* Reverse list */
void corto_llReverse(corto_ll list) {
    corto_uint32 i, size = corto_llSize(list);
    corto_llNode start = list->first;
    corto_llNode end = list->last;
    corto_llNode ptr;

    for(i=0; i<size / 2; i++) {
        void *tmp = start->data;
        start->data = end->data;
        end->data = tmp;
        start = start->next;

        /* Do in-place reverse, find node that precedes 'end' */
        if (start != end) {
            ptr = start;
            while(ptr && (ptr->next != end)) {
                ptr = ptr->next;
            }
            corto_assert(ptr != NULL, "linked list corrupt");
            end = ptr;
        }
    }
}
Esempio n. 17
0
corto_int16 corto_valueExpr_getTypeForBinary(
    corto_type leftType,
    corto_bool t1ByRef,
    corto_type rightType,
    corto_bool t2ByRef,
    corto_operatorKind _operator,
    corto_type *operandType,
    corto_type *resultType)
{
    corto_type castType = NULL;
    corto_bool equal = FALSE;

    corto_assert(operandType != NULL, "NULL provided for out-parameter operandType");
    corto_assert(resultType != NULL, "NULL provided for out-parameter resultType");

    /* If operator is condition result type is a boolean */
    if (corto_valueExpr_isOperatorConditional(_operator)) {
        *resultType = corto_type(corto_bool_o);
    }

    /* Get leftType and rightType */
    if (!(leftType = corto_valueExpr_getType(leftType, NULL, FALSE))) {
        goto error;
    }

    if (!(rightType = corto_valueExpr_getType(rightType, leftType, t1ByRef))) {
        goto error;
    }

    if (!leftType) {
        leftType = rightType;
    }

    /* If objects are not scoped, verify whether they're equal */
    if (!corto_checkAttr(leftType, CORTO_ATTR_NAMED) && !corto_checkAttr(rightType, CORTO_ATTR_NAMED)) {
        if (corto_compare(leftType, rightType) == CORTO_EQ) {
            equal = TRUE;
        }
    } else {
        equal = leftType == rightType;
    }

    if (_operator == CORTO_DIV) {
        castType = corto_type(corto_float64_o);
    } else if (!equal) {
        /* Can only cast between primitive types */
        if ((leftType->kind == CORTO_PRIMITIVE ) && (rightType->kind == CORTO_PRIMITIVE)) {
            corto_primitive ltype = corto_primitive(leftType), rtype = corto_primitive(rightType);
            corto_int8 lscore, rscore;
            corto_int8 lCastScore, rCastScore;

            lscore = corto_valueExpr_getTypeScore(ltype);
            rscore = corto_valueExpr_getTypeScore(rtype);
            lCastScore = corto_valueExpr_getCastScore(ltype);
            rCastScore = corto_valueExpr_getCastScore(rtype);

            /* If expression is an assignment, always take type of lvalue.
             * Otherwise determine based on expressibility score which type to
             * cast to. */
            if (corto_valueExpr_isOperatorAssignment(_operator)) {
                if (lCastScore == rCastScore) {
                    if (ltype->width != rtype->width) {
                        castType = leftType;
                    }
                } else {
                    castType = leftType;
                }
            } else {
                if (lCastScore == rCastScore) {
                    if (ltype->width == rtype->width) {
                        /* If width and kind are equal, no conversion is required. */
                        if (lscore > rscore) {
                            *operandType = leftType;
                        } else if (lscore < rscore) {
                            *operandType = rightType;
                        }
                    } else {
                        /* If lvalue has a larger width than rvalue, cast rvalue to leftType (and vice versa) */
                        if (ltype->width > rtype->width) {
                            castType = leftType;
                        } else {
                            castType = rightType;
                        }
                    }

                /* If kinds do not match figure a cast is potentially needed. Figure out which type to cast to */
                } else {
                    if (lscore > rscore) {
                        castType = leftType;
                    } else {
                        castType = rightType;
                    }
                }
            }
        } else if (leftType->reference && rightType->reference) {
            castType = NULL;
            /* Check if types are compatible */

        } else if ((rightType->reference || (t2ByRef)) && !leftType->reference) {
            if (corto_type_castable(leftType, corto_object_o)) {
                castType = leftType;
            }
        } else {
            corto_seterr("cannot cast from '%s' to '%s'",
                    corto_fullpath(NULL, leftType),
                    corto_fullpath(NULL, rightType));
            goto error;
        }
    } else if ((rightType->reference || (t2ByRef)) && !leftType->reference) {
        if (corto_type_castable(leftType, corto_object_o)) {
            castType = leftType;
        }
    }

    if (!castType) {
        castType = leftType;
    }
    if (castType) {
        *operandType = castType;
    }
    if (!*resultType) {
        *resultType = *operandType;
    }

    return 0;
error:
    return -1;
}
Esempio n. 18
0
static corto_int16 json_deserComposite(void* p, corto_type t, JSON_Value *v)
{
    corto_assert(t->kind == CORTO_COMPOSITE, "not deserializing composite");

    if (json_value_get_type(v) != JSONObject) {
        corto_seterr("expected object, got %s", json_valueTypeToString(v));
        goto error;
    }

    JSON_Object* o = json_value_get_object(v);
    size_t count = json_object_get_count(o);
    size_t i;
    corto_bool isUnion = corto_interface(t)->kind == CORTO_UNION;
    corto_int32 discriminator = 0;
    corto_member unionMember = NULL;

    for (i = 0; i < count; i++) {
        const char* memberName = json_object_get_name(o, i);
        corto_member member_o;

        if (!strcmp(memberName, "super")) {
            JSON_Value* value = json_object_get_value(o, memberName);
            if (json_deserItem(p, corto_type(corto_interface(t)->base), value)) {
                goto error;
            }
        } else if (!strcmp(memberName, "_d") && isUnion) {
            JSON_Value* value = json_object_get_value(o, memberName);
            if (json_deserPrimitive(&discriminator, corto_union(t)->discriminator, value)) {
                goto error;
            }
            unionMember = corto_union_findCase(t, discriminator);
            if (!unionMember) {
                corto_seterr("discriminator '%d' invalid for union '%s'",
                    discriminator, corto_fullpath(NULL, t));
            }
        } else {
            member_o = corto_interface_resolveMember(t, (char*)memberName);

            /* Ensure that we're not resolving members from a base type */
            if (!member_o || (corto_parentof(member_o) != t)) {
                corto_seterr(
                    "cannot find member '%s' in type '%s'",
                    memberName,
                    corto_fullpath(NULL, t));
                goto error;
            }

            if (isUnion && (unionMember != member_o)) {
                corto_seterr(
                    "member '%s' does not match discriminator '%d' (expected member '%s')",
                    memberName,
                    discriminator,
                    corto_idof(unionMember));
                goto error;
            } else if (isUnion) {
                corto_int32 prev = *(corto_int32*)p;
                if (prev != discriminator) {
                    corto_member prevMember = corto_union_findCase(t, prev);
                    corto_deinitp(CORTO_OFFSET(p, prevMember->offset), prevMember->type);
                    memset(CORTO_OFFSET(p, member_o->offset), 0, member_o->type->size);
                }
                *(corto_int32*)p = discriminator;
            }

            if (!json_deserMustSkip(member_o, p)) {
                JSON_Value* value = json_object_get_value(o, memberName);
                void *offset = CORTO_OFFSET(p, member_o->offset);
                if (member_o->modifiers & CORTO_OBSERVABLE) {
                    offset = *(void**)offset;
                    if (json_deserType(offset, member_o->type, value)) {
                        goto error;
                    }
                } else {
                    if (member_o->modifiers & CORTO_OPTIONAL) {
                        if (*(void**)offset) {
                            corto_deinitp(*(void**)offset, member_o->type);
                            memset(*(void**)offset, 0, member_o->type->size);
                        } else {
                            *(void**)offset = corto_calloc(member_o->type->size);
                        }
                        offset = *(void**)offset;
                    }
                    if (json_deserItem(offset, member_o->type, value)) {
                        goto error;
                    }
                }
            }
        }
    }

    return 0;
error:
    return -1;
}
Esempio n. 19
0
void cdiff_file_indent(cdiff_file file) {
    corto_assert(file != NULL, "NULL specified for file");
    file->indent ++;
}
Esempio n. 20
0
void cdiff_file_dedent(cdiff_file file) {
    corto_assert(file != NULL, "NULL specified for file");
    corto_assert(file->indent != 0, "too many dedents");
    file->indent --;
}
Esempio n. 21
0
void cdiff_file_elemEnd(cdiff_file file) {
    corto_assert(file != NULL, "NULL specified for file");
    corto_assert(file->writeTo == 0, "finish header or body before closing element");
    file->cur = NULL;
}