Ejemplo n.º 1
0
static int corto_selectParse(corto_selectData *data) {
	char *ptr, *start, ch;
	int op = 0;

	ptr = data->expr;
	for (; (ch = *ptr); data->program[op].start = ptr, ptr++) {
		start = ptr;
		switch(ch) {
		case '.':
			if (ptr[1] == '.') {
				data->program[op].token = TOKEN_PARENT;
				ptr++;
			} else {
				data->program[op].token = TOKEN_TREE;
			}
			break;
		case ':':
			if (ptr[1] == ':') {
				data->program[op].token = TOKEN_SCOPE;
				ptr++;
			} else {
				corto_seterr("invalid usage of ':'");
				goto error;
			}
			break;
		default:
			while((ch = *ptr++) && (isalnum(ch) || (ch == '*') || (ch == '?'))) {}
			ptr--; /* Go back one character to adjust for lookahead of one */
			int len = ptr - start;
			if (len) {
				if (len == 1) {
					if (*(ptr - 1) == '?') {
						data->program[op].token = TOKEN_WILDCARD;
					} else if (*(ptr - 1) == '*') {
						data->program[op].token = TOKEN_ASTERISK;
					} else {
						data->program[op].token = TOKEN_IDENTIFIER;
					}
				} else {
					data->program[op].token = TOKEN_IDENTIFIER;
				}
			} else {
				corto_seterr("invalid character '%c", ch);
				goto error;
			}
			break;
		}
		data->program[op].start = start;
		if (++op == CORTO_SELECT_MAX_OP) {
			corto_seterr("expression is too long");
			goto error;
		}
	}

	data->programSize = op;

	return 0;
error:
	return -1;
}
Ejemplo n.º 2
0
corto_int16 corto_ptr_binaryOp(corto_type type, corto_operatorKind operator, void *operand1, void *operand2, void *result) {
    if (type->kind == CORTO_PRIMITIVE) {
        corto__binaryOperator impl = corto_binaryOps[corto_primitive(type)->convertId][operator];
        if (impl) {
            impl(operand1, operand2, result);
        } else {
            corto_seterr("binary operator '%s' is not implemented for type '%s'",
              corto_idof(corto_enum_constant(corto_operatorKind_o, operator)),
              corto_fullpath(NULL, type));
            goto error;
        }
    } else if (operator == CORTO_ASSIGN) {
        corto_ptr_copy(operand1, type, operand2);
        if (result && result != operand1) {
            corto_ptr_copy(result, type, operand1);
        }
    } else {
        corto_seterr("invalid operand for non-scalar type");
        goto error;
    }

    return 0;
error:
    return -1;
}
Ejemplo n.º 3
0
corto_int16 json_deserReference(void* p, corto_type t, JSON_Value* v)
{
    switch(json_value_get_type(v)) {
    case JSONString: {
        const char* reference = json_value_get_string(v);
        corto_object o = corto_resolve(NULL, (corto_string)reference);
        if (!o) {
            corto_error("unresolved reference \"%s\"", reference);
            goto error;
        }

        if (!corto_instanceof(t, o)) {
            corto_error("%s is not an instance of %s", reference, corto_idof(t));
        }

        corto_setref(p, o);
        corto_release(o);
        break;
    }
    case JSONObject: {
        JSON_Object* obj = json_value_get_object(v);

        JSON_Value* type = json_object_get_value(obj, "type");
        if (json_value_get_type(type) != JSONString) {
            corto_seterr("type parameter of anonymous object must be a string");
            goto error;
        }
        corto_type cortoType = corto_resolve(NULL, (char*)json_value_get_string(type));
        if (!cortoType) {
            corto_seterr("type '%s' not found for anonymous object", json_value_get_string(type));
            goto error;
        }

        corto_object cortoObj = *(corto_object*)p;
        if (!cortoObj || (corto_typeof(cortoObj) != cortoType)) {
            cortoObj = corto_create(cortoType);
            corto_setref(p, cortoObj);
            corto_release(cortoObj);
        }
        corto_release(cortoType);

        JSON_Value* value = json_object_get_value(obj, "value");
        if (json_deserType(cortoObj, cortoType, value)) {
            goto error;
        }
        break;
    }
    case JSONNull:
        corto_setref(p, NULL);
        break;
    default:
        corto_seterr("expected string, null or object (reference), got %s", json_valueTypeToString(v));
        break;
    }

    return 0;
error:
    return -1;
}
Ejemplo n.º 4
0
/* Run a command for multiple projects */
corto_int16 cortotool_runcmd(
    corto_ll dirs, char *argv[], corto_bool silent, corto_bool mute)
{
    corto_iter iter;
    corto_id cwd;
    corto_int8 ret = 0;

    strcpy(cwd, corto_cwd());

    if (dirs) {
        iter = corto_llIter(dirs);
    }

    do {
        corto_pid pid = 0;
        corto_int32 sig = 0;

        if (dirs) {
            corto_string dir = corto_iterNext(&iter);

            /* Change working directory to project */
            if (corto_chdir(dir)) {
                goto error;
            }
        }

        if (mute) {
            pid = corto_procrunRedirect(argv[0], argv,
                                        stdin, NULL, NULL);
        } else if (silent) {
            pid = corto_procrunRedirect(argv[0], argv,
                                        stdin, NULL, stderr);
        } else {
            pid = corto_procrun(argv[0], argv);
        }

        if (!pid) {
            corto_seterr("failed to start process %s", argv[0]);
            goto error;
        }

        if ((sig = corto_procwait(pid, &ret)) || ret) {
            corto_seterr("%s failed (%s %d)", argv[0],
                         sig ? "signal" : "returncode", sig ? sig : ret);
            goto error;
        }

        /* Reset to previous CWD if there is more than one project to build */
        corto_chdir(cwd);

    } while (dirs && corto_iterHasNext(&iter));

    return 0;
error:
    return -1;
}
Ejemplo n.º 5
0
corto_int16 corto_value_memberExpr(corto_value *val, corto_string member, corto_value *out) {
    corto_type t = corto_value_typeof(val);
    corto_object o = corto_value_objectof(val);
    void *ptr = corto_value_ptrof(val);

    corto_id tokens;
    strncpy(tokens, member, sizeof(corto_id));

    char *cur = tokens, *prev = tokens;
    do {
        if (cur && (cur = strchr(cur + 1, '.'))) *cur = '\0';

        if (!corto_instanceof(corto_interface_o, t)) {
            corto_seterr(
                "cannot get member from a non-composite value (type is '%s')",
                corto_fullpath(NULL, t));
            goto error;
        }

        if (!strcmp(prev, "super")) {
            if (!(t = (corto_type)corto_interface(t)->base)) {
                corto_seterr("super unpexpected: interface '%s' does not have a base",
                    corto_fullpath(NULL, t));
                goto error;
            } else {
                *out = corto_value_base(ptr, t);
            }
        } else {
            corto_member m = corto_interface_resolveMember(t, prev);
            if (!m) {
                corto_seterr(
                    "unresolved member '%s' in type '%s'",
                    prev,
                    corto_fullpath(NULL, t));
                goto error;
            }

            ptr = CORTO_OFFSET(ptr, m->offset);
            t = m->type;

            *out = corto_value_member(o, m, ptr);
        }

        prev = cur + 1;
    } while (cur);

    return 0;
error:
    return -1;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
0
corto_int16 corto_value_ptrset(corto_value *val, void *ptr) {
    switch(val->kind) {
    case CORTO_OBJECT:
        val->is.object.o = ptr;
        break;
    case CORTO_BASE:
        val->is.base.v = ptr;
        break;
    case CORTO_VALUE:
    case CORTO_MEM:
        val->is.value.v = ptr;
        break;
    case CORTO_MEMBER:
        val->is.member.v = ptr;
        break;
    case CORTO_CONSTANT:
        val->is.constant.v = ptr;
        break;
    case CORTO_ELEMENT:
        val->is.element.v = ptr;
        break;
    case CORTO_MAP_ELEMENT:
        val->is.mapElement.v = ptr;
        break;
    case CORTO_LITERAL:
        corto_seterr("cannot set pointer for literal");
        goto error;
    default:
        corto_critical("corto_value_ptrset: invalid corto_valueKind(%d).", val->kind);
        break;
    }
    return 0;
error:
    return -1;
}
Ejemplo n.º 8
0
static corto_int16 json_deserType(void *p, corto_type t, JSON_Value *v)
{
    switch (t->kind) {
    case CORTO_VOID:
        /* Nothing to deserialize */
        break;
    case CORTO_PRIMITIVE:
        if (json_deserPrimitive(p, t, v)) {
            goto error;
        }
        break;
    case CORTO_COMPOSITE:
        if (json_deserComposite(p, t, v)) {
            goto error;
        }
        break;
    case CORTO_COLLECTION:
        if (json_deserCollection(p, t, v)) {
            goto error;
        }
        break;
    default:
        corto_seterr(
            "unsupported type, can't serialize JSON");
        break;
    }

    return 0;
error:
    return -1;
}
Ejemplo n.º 9
0
static corto_type corto_valueExpr_getType(corto_type src, corto_type target, corto_bool targetIsRef) {
    corto_type result = src;

    if (!src) {
        if (target) {
            if (target->reference) {
                result = target;
            } else if ((target->kind == CORTO_PRIMITIVE) && (corto_primitive(target)->kind == CORTO_TEXT)) {
                result = corto_type(corto_string_o);
            } else {
                if (targetIsRef) {
                    result = target;
                } else {
                    corto_seterr(
                      "invalid usage of null with non-string and non-reference type '%s'",
                      corto_fullpath(NULL, target));
                    goto error;
                }
            }
        } else {
            result = corto_void_o;
        }
    } else if ((target && (target->kind == CORTO_VOID) && target->reference)) {
        result = corto_object_o;
    }

    return result;
error:
    return NULL;
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
0
void* _dDDS_getEntity(corto_object o, corto_type type) {
    void* result = NULL;

    if (o && corto_instanceof(type, o)) {
        result = corto_olsGet(o, DDDS_ENTITY_HANDLE);
        if (!result) {
            corto_seterr("%s contains an invalid handle",
              corto_fullpath(NULL, o));
        }
    } else {
        corto_seterr("%s is not of type %s",
          corto_fullpath(NULL, o),
          corto_fullpath(NULL, type));
    }

    return result;
}
Ejemplo n.º 12
0
static corto_dl corto_load_validLibrary(corto_string fileName, corto_string *build_out) {
    corto_dl result = NULL;
    corto_string ___ (*build)(void);
    corto_string ___ (*library)(void);

    if (build_out) {
        *build_out = NULL;
    }

    if (!(result = corto_dlOpen(fileName))) {
        corto_seterr("%s", corto_dlError());
        goto error;
    }

    /* Lookup build function */
    build = (corto_string ___ (*)(void))corto_dlProc(result, "corto_getBuild");
    library = (corto_string ___ (*)(void))corto_dlProc(result, "corto_getLibrary");

    /* Validate version */
    if (build && strcmp(build(), corto_getBuild())) {
        corto_seterr(
          "corto: library '%s' links with conflicting corto library\n"
          "  links with: '%s' (%s)\n"
          "  current:    '%s' (%s)\n",
          fileName, library ? library() : "???", build(), corto_getLibrary(), corto_getBuild());
        /* Library is linked with different Corto version */
        if (build_out) {
            *build_out = corto_strdup(build());
        }
        goto error;
    } else if (build) {
        corto_debug(
          "loader: '%s' links with correct corto library\n  build:   '%s'\n  library: '%s'\n",
          fileName, build(), library());
    } else {
        corto_trace("loader: found '%s' which doesn't link with corto", fileName);
    }

    /* If no build function is available, the library is not linked with
     * Corto, and probably represents a --nocorto package */

    return result;
error:
    if (result) corto_dlClose(result);
    return NULL;
}
Ejemplo n.º 13
0
static int corto_selectValidate(corto_selectData *data) {
	int op;
	corto_selectToken t, tprev = TOKEN_NONE;
	for (op = 0; op < data->programSize; op++) {
		t = data->program[op].token;
		switch(t) {
		case TOKEN_IDENTIFIER:
			switch(tprev) {
			case TOKEN_IDENTIFIER:
			case TOKEN_ASTERISK:
			case TOKEN_WILDCARD:
			case TOKEN_PARENT:
				goto error;
			default: break;
			}
			break;
		case TOKEN_SCOPE:
			switch(tprev) {
			case TOKEN_SCOPE:
				goto error;
			default: break;
			}
			break;
		case TOKEN_TREE:
		case TOKEN_PARENT:
			switch(tprev) {
			case TOKEN_TREE:
			case TOKEN_PARENT:
				goto error;
			default: break;
			}
			break;
		case TOKEN_WILDCARD:
		case TOKEN_ASTERISK:
			switch(tprev) {
			case TOKEN_IDENTIFIER:
			case TOKEN_PARENT:
			case TOKEN_ASTERISK:
			case TOKEN_WILDCARD:
				goto error;
			default: break;
			}
			break;
		default:
			break;
		}
		tprev = t;
	}

	return 0;
error:
	corto_seterr("unexpected '%s' after '%s'", 
		corto_selectTokenStr(t),
		corto_selectTokenStr(tprev));
	return -1;
}
Ejemplo n.º 14
0
/* Load from a dynamic library */
static int corto_load_fromDl(corto_dl dl, char *fileName, int argc, char *argv[]) {
    int (*proc)(int argc, char* argv[]);

    corto_debug("loader: invoke cortomain of '%s' with %d arguments", fileName, argc);

    /* Lookup main function */
    proc = (int(*)(int,char*[]))corto_dlProc(dl, "cortomain");
    if (proc) {
        /* Call main */
        if (proc(argc, argv)) {
            if (!corto_lasterr()) {
                corto_seterr("cortomain failed");
            }
            goto error;
        }
    } else {
        corto_string ___ (*build)(void);

        /* Lookup build function */
        build = (corto_string ___ (*)(void))corto_dlProc(dl, "corto_getBuild");
        if (build) {
            corto_seterr("library '%s' linked with corto but does not have a cortomain",
                fileName);
            goto error;
        }
    }

    /* Add library to libraries list */
    corto_mutexLock (&corto_adminLock);
    if (!libraries) {
        libraries = corto_ll_new();
    }

    corto_ll_insert(libraries, dl);
    corto_mutexUnlock (&corto_adminLock);

    corto_debug("loader: loaded '%s'", fileName);

    return 0;
error:
    return -1;
}
Ejemplo n.º 15
0
corto_int16 corto_secure_registerLock(corto_secure_lock lock) {
    if (corto_secure_mainThread == corto_threadSelf()) {
        corto_int16 depth = corto_secure_getObjectDepth(lock->mount);
        if (depth >= CORTO_MAX_SCOPE_DEPTH) {
            corto_seterr("invalid identifier for mount-member of lock");
            goto error;
        }
        if (!corto_secure_locks[depth]) {
            corto_secure_locks[depth] = corto_ll_new();
        }
        corto_ll_append(corto_secure_locks[depth], lock);
    } else {
        corto_seterr("locks can only be created in mainthread");
        goto error;
    }

    return 0;
error:
    return -1;
}
Ejemplo n.º 16
0
corto_function corto_valueFunction(corto_value* val) {
    corto_function result;

    switch(val->kind) {
    case CORTO_OBJECT:
        if (corto_class_instanceof(corto_procedure_o, corto_typeof(val->is.object.o))) {
            result = val->is.object.o;
        } else {
            corto_seterr("object '%s' in value is not a function",
                corto_fullpath(NULL, val->is.object.o));
            result = NULL;
        }
        break;
    default:
       corto_seterr("value does not represent a function");
       result = NULL;
       break;
    }

    return result;
}
Ejemplo n.º 17
0
corto_int16 corto_select(corto_object scope, corto_string expr, corto_iter *iter_out) {
	corto_selectData *data = corto_selectDataGet();
	CORTO_UNUSED(scope);

	strcpy(data->expr, expr);

	iter_out->hasNext = corto_selectHasNext;
	iter_out->next = corto_selectNext;

	if (corto_selectParse(data)) {
		corto_seterr("select '%s' failed: %s", expr, corto_lasterr());
		goto error;
	}

	if (corto_selectValidate(data)) {
		corto_seterr("select '%s' failed: %s", expr, corto_lasterr());
		goto error;
	}

	return 0;
error:
	return -1;
}
Ejemplo n.º 18
0
/*
 * Load a Corto library
 * Receives the absolute path to the lib<name>.so file.
 */
static int corto_loadLibrary(corto_string fileName, corto_bool validated, corto_dl *dl_out, int argc, char* argv[]) {
    corto_dl dl = NULL;
    corto_string build = NULL;

    corto_seterr(NULL);
    if (!validated) {
        dl = corto_load_validLibrary(fileName, &build);
    } else {
        dl = corto_dlOpen(fileName);
    }

    if (!dl) {
        if (build) {
            corto_seterr("%s: uses a different corto build (%s)", fileName, build);
        } else {
            if (corto_lasterr()) {
                corto_seterr("%s", corto_lasterr());
            } else {
                corto_seterr("%s: %s", fileName, corto_dlError());
            }
        }
        goto error;
    }

    if (corto_load_fromDl(dl, fileName, argc, argv)) {
        goto error;
    }

    if (dl_out) {
        *dl_out = dl;
    }

    return 0;
error:
    if (dl) corto_dlClose(dl);
    return -1;
}
Ejemplo n.º 19
0
static corto_int16 json_deserBoolean(void* o, corto_primitive t, JSON_Value *v)
{
    CORTO_UNUSED(t);

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

    *(corto_bool *)o = json_value_get_boolean(v);

    return 0;
error:
    return -1;
}
Ejemplo n.º 20
0
corto_int16 corto_value_fromcontent(corto_value *v, corto_string contentType, corto_string content) {
    corto_contentType ct = corto_loadContentType(contentType);
    if (!ct) {
        corto_seterr("unknown contentType '%s'", contentType);
        goto error;
    }

    if (ct->toValue(v, (corto_word)content)) {
        goto error;
    }

    return 0;
error:
    return -1;
}
Ejemplo n.º 21
0
static corto_int16 json_deserText(void* p, corto_primitive t, JSON_Value *v)
{
    const char *s = json_value_get_string(v);
    CORTO_UNUSED(t);

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

    corto_setstr(p, (corto_string)s);

    return 0;
error:
    return -1;
}
Ejemplo n.º 22
0
corto_string corto_value_contentof(corto_value *v, corto_string contentType) {
    corto_contentType ct = corto_loadContentType(contentType);
    corto_string result;

    if (!ct) {
        corto_seterr("unknown contentType '%s'", contentType);
        goto error;
    }

    if (!(result = (corto_string)ct->fromValue(v))) {
        goto error;
    }

    return result;
error:
    return NULL;
}
Ejemplo n.º 23
0
corto_int16 corto_binaryOperator(corto_type type, corto_operatorKind operator, void *operand1, void *operand2, void *result) {
    if (type->kind == CORTO_PRIMITIVE) {
        corto__binaryOperator impl = corto_binaryOps[corto_primitive(type)->convertId][operator];
        if (impl) {
            impl(operand1, operand2, result);
        } else {
            corto_seterr("binary operator '%s' is not implemented for type '%s'",
              corto_idof(corto_enum_constant(corto_operatorKind_o, operator)),
              corto_fullpath(NULL, type));
            goto error;
        }
    }

    return 0;
error:
    return -1;
}
Ejemplo n.º 24
0
static corto_int16 json_deserConstant(void* p, corto_primitive t, JSON_Value *v)
{
    const char *s = json_value_get_string(v);
    CORTO_UNUSED(t);

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

    if (corto_convert(corto_string_o, (corto_string*)&s, t, p)) {
        goto error;
    }

    return 0;
error:
    return -1;
}
Ejemplo n.º 25
0
static corto_int16 json_deserNumber(void* o, corto_primitive t, JSON_Value *v)
{

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

    corto_float64 number = json_value_get_number(v);
    corto_convert(
        corto_primitive(corto_float64_o),
        &number,
        t,
        o);

    return 0;
error:
    return -1;
}
Ejemplo n.º 26
0
int tc_lookupAllWalk(corto_object o, void *ctx) {
    CORTO_UNUSED(ctx);
    corto_id id;
    corto_object r;

    corto_path(id, NULL, o, "/");
    r = corto_lookup(NULL, id);

    /* Set errormessage to ease debugging */
    if (!r) corto_seterr("failed to lookup %s", id);
    test_assert(r != NULL);
    test_assert(r == o);
    corto_release(r);

    corto_objectseq scope = corto_scopeClaim(o);
    int i;
    for (i = 0; i < scope.length; i ++) {
        tc_lookupAllWalk(scope.buffer[i], NULL);
    }
    corto_scopeRelease(scope);

    return 1;
}
Ejemplo n.º 27
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;
}
Ejemplo n.º 28
0
/* Deserialize string in object */
corto_string corto_string_deser(corto_string str, corto_string_deser_t* data) {
    corto_char *ptr;
    corto_bool createdNew = FALSE;

    {
        corto_id buffer;
        corto_char *bptr, ch;

        /* Parse typename that potentially precedes string */
        bptr = buffer;
        ptr = str;
        while((ch = *ptr) && (ch != '{')) {
            if (!((ch == ' ') || (ch == '\n') || (ch == '\t'))) {
                *bptr = ch;
                bptr++;
            }
            ptr++;
        }
        *bptr = '\0';

        /* If no type is found, reset ptr */
        if ((ch != '{') || (ptr == str)) {
            ptr = str;
        } else {
            corto_object type;

            /* If no out is provided create an object of the specified type */
            if ((bptr != buffer)) {
                type = corto_resolve(NULL, buffer);
                if (type) {
                    if (data->type && (type != data->type)) {
                        corto_seterr(
                          "type of object ('%s') does not match string ('%s')",
                          corto_fullpath(NULL, data->type),
                          corto_fullpath(NULL, type));
                        corto_release(type);
                        goto error;
                    }
                    if (corto_instanceof(corto_type(corto_type_o), type)) {
                        if (!data->out) {
                            data->out = corto_declare(type);
                            createdNew = TRUE;
                        }
                        data->type = type;
                    } else {
                        corto_seterr("'%s' is not a type", buffer);
                        corto_release(type);
                        goto error;
                    }
                    corto_release(type);
                } else {
                    corto_seterr("unknown type '%s'", buffer);
                    goto error;
                }
            } else {
                type = data->type;
            }

            if (type && (corto_type(type)->kind == CORTO_PRIMITIVE)) {
                ptr++;
            }
        }
    }

    data->current = 0;
    data->index = NULL;
    data->ptr = data->out;
    data->anonymousObjects = NULL;
    data->allocValue = NULL;
    data->allocUdata = NULL;

    if (data->out && data->isObject) {
        if (!data->type) {
            data->type = corto_typeof(data->out);
        } else if (!corto_instanceofType(corto_typeof(data->out), data->type)) {
            corto_seterr("object '%s' of type '%s' is not an instance of type '%s'",
                corto_fullpath(NULL, data->out),
                corto_fullpath(NULL, corto_typeof(data->out)),
                corto_fullpath(NULL, data->type));
            goto error;
        }
    }

    if (!data->type) {
        corto_seterr("no type provided for '%s'", str);
        goto error;
    }
    
    if (data->type->kind == CORTO_PRIMITIVE) {
        ptr = corto_string_deserParse(ptr, NULL, data);
    } else {
        ptr = corto_string_deserParseScope(ptr, NULL, data);
        if (ptr) {
            ptr ++;
        }
    }

    if (!ptr) {
        if (!corto_lasterr()) {
            corto_seterr("failed to deserialize '%s'", str);
        } else {
            corto_seterr("failed to deserialize '%s': %s", str, corto_lasterr());
        }
        goto error;
    }

    if (data->anonymousObjects) {
        corto_ll_free(data->anonymousObjects);
    }

    return ptr;
error:
    if (data->out) {
        if (createdNew) {
            corto_release(data->out);
        }
        data->out = NULL;
    }
    return NULL;
}
Ejemplo n.º 29
0
/* Parse string */
static corto_string corto_string_deserParse(
    corto_string str,
    struct corto_string_deserIndexInfo* info,
    corto_string_deser_t* data)
{
    corto_char ch;
    corto_char *ptr, *bptr, *nonWs;
    corto_char buffer[CORTO_STRING_DESER_TOKEN_MAX]; /* TODO: dangerous in a recursive function */
    corto_bool proceed, excess;
    struct corto_string_deserIndexInfo* memberInfo;

    CORTO_UNUSED(info);

    ptr = str;
    bptr = buffer;
    nonWs = bptr;
    proceed = TRUE;
    excess = FALSE;
    memberInfo = NULL;

    if (info) {
        memberInfo = corto_string_deserIndexNext(data);
    }

    /* If ptr == NULL, an error has occurred. If proceed == FALSE, this function
     * has finished processing the current value. */
    while(ptr && (ch = *ptr) && proceed) {
        switch(ch) {
        case '=': /* Explicit member assignment */
            excess = FALSE;
            if (buffer == bptr) {
                corto_seterr("missing member identifier");
                goto error;
            } else {
                *nonWs = '\0';
                memberInfo = corto_string_deserIndexLookup(buffer, data);
                bptr = buffer;
                nonWs = bptr;
                if (!memberInfo) {
                    corto_seterr("member '%s' not found in type '%s'", buffer, corto_fullpath(NULL, data->type));
                    goto error;
                }
                break;
            }

        case '{': /* Scope open */
            if (bptr == buffer) {
                if (!(ptr = corto_string_deserParseScope(
                    ptr,
                    memberInfo,
                    data))) {
                    goto error;
                }
            } else {
                *bptr = '\0';
                if (!(ptr = corto_string_parseAnonymous(
                    ptr,
                    buffer,
                    memberInfo,
                    data))) {
                    goto error;
                }
                bptr = buffer;
            }
            break;

        case '}': /* Scope close and end of value */
            if (buffer != bptr) {
                *nonWs = '\0';
                if (memberInfo && (data->type->kind != CORTO_PRIMITIVE)) {
                    if (corto_string_deserParseValue(buffer, memberInfo, data)) {
                        goto error;
                    }
                    bptr = buffer;
                    nonWs = bptr;
                }
            }
            proceed = FALSE;
            ptr--;
            break;

        case '(':
            /* If a value is being parsed, the '(' is part of an argument list.
             * Parse up until the matching ')' */
            if (bptr != buffer) {
                char *start = ptr;

                /* Parse until matching '} */
                do {
                    *bptr = ch;
                    bptr++;
                    ptr++;
                } while((ch = *ptr) && (ch == ')'));

                ptr--;
                nonWs = bptr;

                /* ptr must always end with a '}' */
                if (*ptr != ')') {
                    corto_seterr("missing ')' at '%s' (%s)", start, ptr);
                    goto error;
                }
            }


        case '"':
            if (!(ptr = corto_string_deserParseString(ptr, buffer, &bptr))) {
                goto error;
            }
            nonWs = bptr;
            ptr--;
            break;
        case '\'':
            if (!(ptr = corto_string_deserParseCharacter(ptr+1, buffer))) {
                goto error;
            }
            *(++bptr) = '\0';
            nonWs = bptr;
            break;

        case '\n':
        case '\t':
        case ' ':
            if (bptr != buffer) {
                *bptr = ch;
                bptr++;
            }
            break;

        case ',': /* End of value */
            if (buffer != bptr) {
                *nonWs = '\0';
                if (corto_string_deserParseValue(buffer, memberInfo ? memberInfo : info, data)) {
                    goto error;
                }
                bptr = buffer;
                nonWs = bptr;
            }

            /* If memberInfo contains a member, get next member, otherwise it contains
             * an element. The same information applies to each element therefore it is only present
             * once in the index. */
            if (memberInfo) {
                if (memberInfo->m) {
                    memberInfo = corto_string_deserIndexNext(data);
                    if (!memberInfo) {
                        excess = TRUE;
                    }
                }
                data->current++;
            } else {
                /* A comma without memberInfo means that a discriminator of a
                 * union was parsed */
                proceed = FALSE;
            }
            break;
        default:
            *bptr = ch;
            bptr++;
            nonWs = bptr;
            break;
        }
        if (ptr && *ptr) ptr++;
    }

    if (bptr != buffer) {
        struct corto_string_deserIndexInfo info;
        *nonWs = '\0';
        info.type = data->type;
        info.parsed = FALSE;
        info.m = NULL;
        if (corto_string_deserParseValue(buffer, &info, data)) {
            goto error;
        }
    }

    if (excess) {
        corto_seterr("excess elements in string");
        goto error;
    }

    return ptr;
error:
    return NULL;
}
Ejemplo n.º 30
0
static corto_string corto_string_parseAnonymous(
    corto_string str,
    corto_string value,
    struct corto_string_deserIndexInfo *info,
    corto_string_deser_t *data)
{
    corto_object o = NULL;
    char *ptr = str;
    char *valuePtr = value;
    corto_uint32 index = 0;
    void *offset;

    if (corto_string_getDestinationPtr(info, data, &offset)) {
        corto_seterr("%s: %s", str, corto_lasterr());
        goto error;
    }

    /* Check if this is a 'named' anonymous object in which case it is
     * prefixed with <[id]> */
    if ((valuePtr = corto_string_deserParseAnonymousId(valuePtr, &index))) {
        if (data->anonymousObjects && (index <= corto_ll_size(data->anonymousObjects))) {
            if (!*valuePtr) {
                o = corto_ll_get(data->anonymousObjects, index - 1);
                corto_claim(o);
            } else {
                /* If the <n> is followed up with more data, a new anonymous
                 * object is being created while one existed already with the
                 * specified number */
                corto_seterr("identifier <%d> is already defined (%s)", index, value);
                goto error;
            }
        }
    } else {
        valuePtr = value;
    }

    /* If no object has been referenced, create an anonymous object */
    if (!o && *valuePtr) {
        corto_object type = corto_resolve(NULL, valuePtr);
        if (!type) {
            corto_seterr("unresolved type '%s'", valuePtr);
            goto error;
        }

        if (offset) {
            o = *(corto_object*)offset;
            if (!o || (type != corto_typeof(o))) {
                if (!corto_instanceof(corto_type_o, type)) {
                    corto_seterr("'%s' is not a type", corto_fullpath(NULL, type));
                    goto error;
                }

                o = corto_declare(type);
                if (!o) {
                    corto_seterr("failed to declare %s: %s",
                        value,
                        corto_lasterr());
                    goto error;
                }
            } else {
                corto_claim(o);
            }
        }

        corto_string_deser_t privateData = {
            .out = data->out, // Preserve original out to determine ownership
            .ptr = o,
            .type = type,
            .anonymousObjects = data->anonymousObjects,
            .scope = data->scope,
            .isObject = data->isObject
        };

        if (corto_type(type)->kind == CORTO_PRIMITIVE) {
            ptr ++;
            if (!(ptr = corto_string_deserParse(ptr, NULL, &privateData))) {
                goto error;
            }
        } else {
            if (!(ptr = corto_string_deserParseScope(ptr, NULL, &privateData))) {
                goto error;
            }
        }

        if (o) {
            if (corto_define(o)) {
                goto error;
            }
            data->anonymousObjects = privateData.anonymousObjects;

            if (!data->anonymousObjects) {
                data->anonymousObjects = corto_ll_new();
            }

            corto_ll_append(data->anonymousObjects, o);
        }
    }

    if (offset) corto_ptr_setref(offset, o);
    if (o) corto_release(o);

    return ptr;
error:
    if (o) corto_release(o);
    return NULL;
}