int objects_hierarchyMain(int argc, char *argv[]) {

    /* Create an object in the global object hierarchy */
    corto_object *parent = corto_createChild(root_o, "parent", corto_void_o);
    if (!parent) {
        goto error;
    }

    /* Show information about the parent object */
    printInfo(parent);

    /* Create an object in the scope of the parent object */
    corto_object *child = corto_createChild(parent, "child", corto_void_o);
    if (!parent) {
        goto error;
    }

    /* Show information about the child object */
    printInfo(child);

    /* Delete both the parent and child object */
    if (corto_delete(parent)) {
        goto error;
    }

    return 0;
error:
    corto_error("error: %s", corto_lasterr());
    return -1;
}
Beispiel #2
0
cdiff_file cdiff_file_open (char* filename) {
    cdiff_file result = malloc(sizeof(struct cdiff_file_s));

    /* Store current working directory in case the application using this
     * function changes the cwd before closing the file. */
    corto_asprintf(&result->name, "%s/%s", corto_cwd(), filename);

    result->elements = NULL;
    result->legacyElements = NULL;
    result->isChanged = false;
    result->writeBuffer = CORTO_BUFFER_INIT;
    result->writeTo = 0;
    result->indent = 0;
    result->newLine = true;
    result->cur = NULL;

    char *source = corto_fileLoad(result->name);
    if (source) {
        result->isNew = false;

        /* Check for legacy */
        if (strstr(source, "$CORTO_GENERATED")) {
            if (strstr(source, "$begin") || strstr(source, "$header")) {
                result->legacyElements = cdiff_parseLegacy(source);
                if (!result->legacyElements) {
                    goto error;
                }

                result->isChanged = true;
                result->isNew = true;
            }
        }

        /* Parse file (only when not parsing legacy file) */
        if (!result->legacyElements) {
            result->elements = cdiff_parse(source);
            if (!result->elements) {
                goto error;
            }
        }

        free(source);

    } else {
        corto_lasterr(); /* silence warning */
        result->isNew = true;
    }

    return result;
error:
    if (source) {
        free(source);
    }
    return NULL;
}
Beispiel #3
0
int dynamic_structMain(int argc, char *argv[]) {

    /* Create a new struct */
    corto_struct Point = corto_declareChild(root_o, "Point", corto_struct_o);
    if (!Point) {
        goto error;
    }

    /* Create x member */
    corto_member x = corto_declareChild(Point, "x", corto_member_o);
    if (!x) {
        goto error;
    }
    if (!corto_checkState(x, CORTO_DEFINED)) {
        corto_setref(&x->type, corto_int32_o);
        if (corto_define(x)) {
            goto error;
        }
    }

    /* Create y member */
    corto_member y = corto_declareChild(Point, "y", corto_member_o);
    if (!y) {
        goto error;
    }
    if (!corto_checkState(y, CORTO_DEFINED)) {
        corto_setref(&y->type, corto_int32_o);
        if (corto_define(y)) {
            goto error;
        }
    }

    /* Finalize struct */
    if (corto_define(Point)) {
        goto error;
    }

    /* Create an instance of Point */
    corto_object p = corto_createChild(root_o, "p", Point);
    if (!p) {
        goto error;
    }

    *(corto_int32*)CORTO_OFFSET(p, x->offset) = 10;
    *(corto_int32*)CORTO_OFFSET(p, y->offset) = 20;

    printf("p = %s\n", corto_contentof(NULL, "text/corto", p));

    return 0;
error:
    corto_error("error: %s", corto_lasterr());
    return -1;
}
Beispiel #4
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;
}
Beispiel #5
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;
}
Beispiel #6
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;
}
Beispiel #7
0
corto_int16 cortotool_publish(int argc, char *argv[]) {
    corto_ll silent, mute, notag, dirs, majorarg, minorarg, patcharg;
    corto_uint32 major = 0, minor = 0, patch = 0;

    CORTO_UNUSED(argc);

    corto_argdata *data = corto_argparse(
      argv,
      (corto_argdata[]){
        {"$0", NULL, NULL}, /* Ignore 'publish' argument */
        {"--silent", &silent, NULL},
        {"--mute", &mute, NULL},
        {"--notag", &notag, NULL},
        {"$?*", &dirs, NULL},
        {"$+major", &majorarg, NULL},
        {"$|minor", &minorarg, NULL},
        {"$|patch", &patcharg, NULL},
        {NULL}
      }
    );

    if (!data) {
        corto_error("corto: %s", corto_lasterr());
        goto error;
    }

    if (dirs) {
        corto_string dir = corto_llGet(dirs, 0);
        if (corto_chdir(dir)) {
            corto_error("corto: %s", corto_lasterr());
            goto error;
        }
    }


    if (!corto_fileTest("./.corto")) {
        corto_error("corto: invalid project directory");
        goto error;
    }

    if (!notag) {
        corto_error(
            "corto: tagging of repository not yet supported "
            "(use --notag to just increase version)");
        goto error;
    }

    corto_string version = corto_fileLoad(".corto/version.txt");

    /* Patch version */
    if (version) {
        char *v = version;

        /* Parse major version */
        char *ptr = strchr(version, '.');
        if (ptr) {
            *ptr = '\0';
            major = atoi(v);
            v = ptr + 1;
        }

        /* Parse minor version */
        ptr = strchr(v, '.');
        if (ptr) {
            *ptr = '\0';
            minor = atoi(v);
            v = ptr + 1;
        }

        /* Parse patch version */
        patch = atoi(v);
    }

    if (majorarg) {
        major++;
    }
    if (minorarg) {
        minor++;
    }
    if (patcharg) {
        patch++;
    }

    FILE *f = fopen(".corto/version.txt", "w");
    if (!f) {
        corto_error("failed to open '.corto/version.txt' (check permissions)");
        goto error;
    }

    fprintf(f, "%u.%u.%u\n", major, minor, patch);
    fclose(f);

    corto_argclean(data);
    corto_dealloc(version);

    if (!silent) {
        corto_print("corto: version updated to %u.%u.%u", major, minor, patch);
    }

    return 0;
error:
    return -1;
}
Beispiel #8
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;
}
Beispiel #9
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;
}
Beispiel #10
0
/* Parse value */
static corto_int16 corto_string_deserParseValue(
    corto_string value,
    struct corto_string_deserIndexInfo* info,
    corto_string_deser_t* data)
{
    void *offset;
    if (corto_string_getDestinationPtr(info, data, &offset)) {
        corto_seterr("%s: %s", value, corto_lasterr());
        goto error;
    }

    /* No more elements where available in the index, meaning an excess element */
    if (!info) {
        corto_seterr("excess elements in scope @ '%s'", value);
        goto error;
    }

    /* Can typically occur when mixing short with default notation. */
    if (info->parsed) {
        corto_seterr("member '%s' is already parsed", corto_idof(info->m));
        goto error;
    }

    /* Only parse references and primitives */
    if (info->type->reference) {
        corto_object o = NULL;
        corto_uint32 index = 0;

        /* Resolve object */
        if (corto_string_deserParseAnonymousId(value, &index)) {
            if (!index) {
                if (data->isObject) {
                    o = data->out;
                    corto_claim(o);
                } else {
                    corto_seterr("cannot refer to self (<0>), not deserializing an object");
                    goto error;
                }
            } else if (data->anonymousObjects && (index <= corto_ll_size(data->anonymousObjects))) {
                o = corto_ll_get(data->anonymousObjects, index - 1);
                corto_claim(o);
            } else {
                corto_seterr("undefined anonymous identifier '%s'", value);
                goto error;
            }
        } else {
            o = corto_resolve(data->scope, value);
        }

        if (o || !strcmp(value, "null")) {
            if (offset) corto_ptr_setref(offset, o);
            if (o) corto_release(o);
        } else {
            corto_seterr("unresolved reference to '%s' for member '%s'", value,
                corto_fullpath(NULL, info->m));
            goto error;
        }
    } else

    /* Convert string to primitive value */
    if (offset && (info->type->kind == CORTO_PRIMITIVE)) {
        if (corto_primitive(info->type)->kind != CORTO_TEXT) {
            if (corto_ptr_cast(corto_primitive(corto_string_o), &value, corto_primitive(info->type), offset)) {
                goto error;
            }
        } else {
            corto_uint32 length;
            corto_string deserialized;

            if (strcmp(value, "null")) {
                length = strlen(value);
                deserialized = corto_alloc(length+1);
                memcpy(deserialized, value, length);
                deserialized[length] = '\0';
            } else {
                deserialized = NULL;
            }

            corto_ptr_setstr(offset, deserialized);
        }
    }

    /* Members are only parsed once */
    if (info->m) {
        info->parsed = TRUE;
    }

    return 0;
error:
    return -1;
}
int select_contentTypeMain(int argc, char *argv[]) {

    /* Create a Point type, so we have something to serialize to JSON */
    corto_struct Point = corto_declareChild(root_o, "Point", corto_struct_o);
    if (!Point) {
        goto error;
    }

    /* Create x member */
    corto_member x = corto_declareChild(Point, "x", corto_member_o);
    if (!x) {
        goto error;
    }
    if (!corto_checkState(x, CORTO_DEFINED)) {
        corto_setref(&x->type, corto_int32_o);
        if (corto_define(x)) {
            goto error;
        }
    }

    /* Create y member */
    corto_member y = corto_declareChild(Point, "y", corto_member_o);
    if (!y) {
        goto error;
    }
    if (!corto_checkState(y, CORTO_DEFINED)) {
        corto_setref(&y->type, corto_int32_o);
        if (corto_define(y)) {
            goto error;
        }
    }

    /* Finalize Point struct */
    if (corto_define(Point)) {
        goto error;
    }

    /* Create two instances of Point. */
    corto_object p1 = corto_declareChild(root_o, "p1", Point);
    if (!p1) {
        goto error;
    }

    if (!corto_checkState(p1, CORTO_DEFINED)) {
        *(corto_int32*)CORTO_OFFSET(p1, x->offset) = 10;
        *(corto_int32*)CORTO_OFFSET(p1, y->offset) = 10;
        if (corto_define(p1)) {
            goto error;
        }
    }

    corto_object p2 = corto_declareChild(root_o, "p2", Point);
    if (!p2) {
        goto error;
    }

    if (!corto_checkState(p2, CORTO_DEFINED)) {
        *(corto_int32*)CORTO_OFFSET(p2, x->offset) = 20;
        *(corto_int32*)CORTO_OFFSET(p2, y->offset) = 30;
        if (corto_define(p2)) {
            goto error;
        }
    }

    /* Select all instances of type Point, get value in JSON */
    corto_iter it;
    corto_int16 ret = corto_select("/", "*")
      .contentType("text/json")
      .type("/Point")
      .iter(&it);
    if (ret) {
        goto error;
    }

    while (corto_iterHasNext(&it)) {
        corto_result *r = corto_iterNext(&it);
        printf("id: %s, value: %s\n", r->id, corto_result_getText(r));
    }

    return 0;
error:
    corto_error("error: %s", corto_lasterr());
    return -1;
}
Beispiel #12
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;
}
Beispiel #13
0
 *
 * Only code written between the begin and end tags will be preserved
 * when the file is regenerated.
 */

#include "test.h"

corto_void _test_Fullname_tc_null(test_Fullname this) {
/* $begin(::test::Fullname::tc_null) */
    corto_id id;

    id[0] = 'a';
    corto_string result = corto_fullname(NULL, id);
    test_assert(result == NULL);
    test_assert(id[0] == 'a');
    corto_string err = corto_lasterr();
    test_assert(err != NULL);
    test_assert(!strcmp(err, "no object provided"));

/* $end */
}

corto_void _test_Fullname_tc_nullBuffer(test_Fullname this) {
/* $begin(::test::Fullname::tc_nullBuffer) */

    corto_string result = corto_fullname(this, NULL);
    test_assert(result == NULL);
    corto_string err = corto_lasterr();
    test_assert(err != NULL);
    test_assert(!strcmp(err, "no buffer provided"));
Beispiel #14
0
int main(int argc, char* argv[]) {
    int i;
    corto_bool mute = FALSE;
    corto_bool startShell = FALSE;

    /* Parse debugging options before starting the core */
    for(i = 1; i < argc; i++) {
        if (*argv[i] == '-') {
            if (*(argv[i]+1) == 'd') {
                CORTO_DEBUG_ENABLED = TRUE;
            }else if (*(argv[i]+1) == 't') {
                CORTO_TRACE_OBJECT = argv[i + 1];
                i ++;
            }else if (*(argv[i]+1) == 'h') {
                cortotool_printUsage(FALSE);
                break;
            } else if (*(argv[i]+1) == 'v') {
                printf("%s\n", CORTO_VERSION);
            } else if (*(argv[i]+1) == '-') {
                if (!strcmp(argv[i], "--backtrace")) {
                    CORTO_BACKTRACE_ENABLED = TRUE;
                }
            }
        }
    }

    /* Start corto */
    corto_start();

    /* Parse arguments */
    if (argc == 1) {
        if (cortotool_shell(argc, argv)) {
            goto error;
        }
    } else {
        for(i=1; i<argc; i++) {
            if (*argv[i] == '-') {
                if (*(argv[i]+1) == 'd') {
                    /* Already handled */
                }else if (*(argv[i]+1) == 't') {
                    /* Already handled */
                    i ++;
                }else if (*(argv[i]+1) == 'h') {
                    /* Already handled */
                    break;
                } else if (*(argv[i]+1) == 'v') {
                    /* Already handled */
                } else if (*(argv[i]+1) == 'c') {
                    if (corto_loadComponent(argv[i + 1], 0, NULL)) {
                        corto_error("%s: %s", argv[i + 1], corto_lasterr());
                        goto error;
                    }
                    i++;
                } else if (*(argv[i]+1) == 'p') {
                    if (corto_load(argv[i + 1], 0, NULL)) {
                        corto_error("%s: %s", argv[i + 1], corto_lasterr());
                        goto error;
                    }
                    i++;
                } else if (*(argv[i]+1) == '-') {
                    if (!strcmp(argv[i] + 2, "version")) {
                        printf("corto version %s (%s) build %s\n\n",
                            CORTO_VERSION,
                            CORTO_PLATFORM_STRING,
                            corto_getBuild());
                    } else if (!strcmp(argv[i] + 2, "minor")) {
                        printf("%s.%s\n", CORTO_VERSION_MAJOR, CORTO_VERSION_MINOR);
                    } else if (!strcmp(argv[i] + 2, "help")) {
                        cortotool_printUsage(FALSE);
                    } else if (!strcmp(argv[i] + 2, "expert")) {
                        cortotool_printUsage(TRUE);
                    } else if (!strcmp(argv[i] + 2, "mute")) {
                        mute = TRUE;
                    } else if (!strcmp(argv[i] + 2, "backtrace")) {
                        /* Already handled */
                    } else {
                        corto_error("corto: unknown option '%s'", argv[i] + 2);
                        cortotool_printUsage(FALSE);
                        goto error;
                    }
                } else {
                    corto_error("corto: unknown option '%s'", argv[i] + 1);
                    cortotool_printUsage(FALSE);
                    goto error;
                }
            } else if (!strcmp(argv[i], "create")) {
                if (cortotool_create(argc-i, &argv[i])) {
                    goto error;
                }
                break;
            } else if (!strcmp(argv[i], "add")) {
                if (cortotool_add(argc-i, &argv[i])) {
                    goto error;
                }
                break;
            } else if (!strcmp(argv[i], "remove")) {
                if (cortotool_remove(argc-i, &argv[i])) {
                    goto error;
                }
                break;
            } else if (!strcmp(argv[i], "list")) {
                if (cortotool_list(argc-i, &argv[i])) {
                    goto error;
                }
                break;
            } else if (!strcmp(argv[i], "pp")) {
                if (cortotool_pp(argc-i, &argv[i])) {
                    goto error;
                }
                break;
            } else if (!strcmp(argv[i], "publish")) {
                if (cortotool_publish(argc-i, &argv[i])) {
                    goto error;
                }
                break;
            } else if (!strcmp(argv[i], "build")) {
                if (cortotool_build(argc-i, &argv[i])) {
                    goto error;
                }
                break;
            } else if (!strcmp(argv[i], "rebuild")) {
                if (cortotool_rebuild(argc-i, &argv[i])) {
                    goto error;
                }
                break;
            } else if (!strcmp(argv[i], "test")) {
                if (cortotool_test(argc-i, &argv[i])) {
                    goto error;
                }
                break;
            } else if (!strcmp(argv[i], "clean")) {
                if (cortotool_clean(argc-i, &argv[i])) {
                    goto error;
                }
                break;
            } else if (!strcmp(argv[i], "install")) {
                if (cortotool_install(argc-i, &argv[i])) {
                    goto error;
                }
                break;
            } else if (!strcmp(argv[i], "uninstall")) {
                if (cortotool_uninstall(argc-i, &argv[i])) {
                    goto error;
                }
                break;
            } else if (!strcmp(argv[i], "update")) {
                if (cortotool_update(argc-i, &argv[i])) {
                    goto error;
                }
                break;
            } else if (!strcmp(argv[i], "locate")) {
                if (cortotool_locate(argc-i, &argv[i])) {
                    goto error;
                }
                break;
            } else if (!strcmp(argv[i], "run")) {
                if (cortotool_run(argc-i, &argv[i])) {
                    goto error;
                }
                break;
            } else if (!strcmp(argv[i], "debug")) {
                if (cortotool_debug(argc-i, &argv[i])) {
                    goto error;
                }
                break;
            } else if (!strcmp(argv[i], "shell")) {
                startShell = TRUE;
            } else if (!strcmp(argv[1], "tar")) {
                if (cortotool_tar(argc-i, &argv[i])) {
                    goto error;
                }
                break;
            } else if (!strcmp(argv[1], "untar")) {
                if (cortotool_untar(argc-i, &argv[i])) {
                    goto error;
                }
                break;
            } else if (!strcmp(argv[1], "help")) {
                if (cortotool_help(argc-i, &argv[i])) {
                    goto error;
                }
                break;
            } else {
                if (corto_load(argv[i], argc-i, &argv[i])) {
                    if (!mute) {
                        if (corto_lasterr()) {
                            corto_error("corto: %s: %s", argv[i], corto_lasterr());
                        } else {
                            corto_error("corto: %s: input error", argv[i]);
                        }
                    }
                    goto error;
                }
                break;
            }
        }
    }

    if (startShell) {
        if (cortotool_shell(argc-i, &argv[i])) {
            goto error;
        }
    }

    /* Stop corto */
    corto_stop();
    return 0;
error:
    return -1;
}
Beispiel #15
0
const char* dDDS_lasterr() {
    return (const char*)corto_lasterr();
}
Beispiel #16
0
static void mqtt_onMessage(
    struct mosquitto *client,
    void *data,
    const struct mosquitto_message *msg)
{
    corto_id nameBuffer;
    char *name = nameBuffer;
    corto_object o = NULL;
    mqtt_Connector this = data;
    corto_bool isDelete = FALSE;

    /* If the payload has been serialized as a corto string, the typename is
     * potentially prefixed to the value */
    char *valueStr = strchr(msg->payload, '{');

    /* mqtt is the owner of this thread. This ensures that all subsequent create
     * update / delete actions are performed with the right owner. Ownership
     * ensures to not trigger on own updates, and to only forward data from
     * other connectors (or the application). */
    corto_object prevOwner = corto_setOwner(this);

    /* Remove topic from name, so that name is relative to mount point. */
    strcpy(name, msg->topic);
    if (this->topic) {
        name += strlen(this->topic) + 1;
    }

    char *lastElem = strrchr(name, '/');
    if (lastElem && !strcmp(lastElem, "/_d")) {
        *lastElem = '\0';
        isDelete = TRUE;
    }

    corto_debug("mqtt: %s: received '%s'", msg->topic, msg->payload);

    /* If object doesn't yet exist in the store, create it */
    if (!(o = corto_lookup(corto_mount(this)->mount, name)) && !isDelete) {
        corto_id buffer;
        corto_debug("mqtt: creating new object for '%s'", name);

        /* If the mount has been configured with a fixed type, use that type to
         * create a new object. Otherwise, look for type in payload. */
        if (corto_observer(this)->type) {
            strcpy(buffer, corto_observer(this)->type);
        } else {
            char *typeStr = strchr(msg->payload, '{');
            memcpy(buffer, msg->payload, typeStr - (char*)msg->payload);
            buffer[typeStr - (char*)msg->payload] = '\0';
        }

        /* Resolve type. If type wasn't yet loaded in corto, corto_resolve will
         * do a lookup on the package repository. If it doesn't exist there
         * either throw an error. Currently, the MQTT connector does not align
         * types. */
        corto_type type = corto_resolve(NULL, buffer);
        if (!type) {
            corto_error("mqtt: type '%s' not found", buffer);
            goto error;
        }

        corto_debug("mqtt: creating '%s' with type '%s'", name, buffer);

        /* Create a new object under the mountpoint. The name is derived from
         * the MQTT topic name. */
        o = corto_declareChild(corto_mount(this)->mount, name, type);
        if (!o) {
            corto_error("mqtt: failed to create object '%s'", name);
            goto error;
        }
    } else {
        corto_debug("mqtt: found '%s' for '%s'", corto_fullpath(NULL, o), name);
    }

    /* Only continue updating object when it is owned by mqtt */
    if (o && corto_owned(o)) {
        if (isDelete) {
            if (corto_delete(o)) {
                corto_error("mqtt: failed to delete '%s': %s", name, corto_lasterr());
            }
            corto_release(o);
        } else {
            /* Start updating object (takes a writelock) */
            if (!corto_updateBegin(o)) {
                /* Serialize value from JSON string */
                if (corto_fromcontent(o, "text/json", valueStr)) {
                    corto_error("mqtt: failed to deserialize for %s: %s (%s)\n",
                        name,
                        corto_lasterr(),
                        msg->payload);

                    /* If deserialization fails, cancel the update. No notification
                     * will be sent. */
                    corto_updateCancel(o);
                    goto error;
                }
                /* Successful update. Send notification and unlock object */
                if (corto_updateEnd(o)) {
                    corto_error("mqtt: failed to update '%s': %s", name, corto_lasterr());
                    goto error;
                }
            } else {
                /* For some reason, couldn't start updating object */
                corto_error("mqtt: failed to start updating '%s': %s", name, corto_lasterr());
                goto error;
            }
        }
    } else if (o) {
        corto_debug("mqtt: '%s' not owned by me (%s, defined = %d), ignoring",
            corto_fullpath(NULL, o),
            corto_ownerof(o) ? corto_fullpath(NULL, o) : "local",
            corto_checkState(o, CORTO_DEFINED));
    }

error:
    /* Restore previous owner */
    corto_setOwner(prevOwner);
}