static void mqtt_onConnect( struct mosquitto *client, void *data, int rc) { /* Subscribe to topic when connected to the broker */ mqtt_Connector this = data; if (rc != 0) { corto_error("mqtt: unable to connect to %s", this->host); } else { corto_id topic; strcpy(topic, this->topic); corto_ok("mqtt: connected to %s", this->host); /* Subscribe to subtree of mountpoint */ if (*topic && strcmp(topic, "/")) { strcat(topic, "/#"); } else { strcpy(topic, "#"); } corto_trace("mqtt: subscribing to %s", topic); if (mosquitto_subscribe(client, 0, topic, 1)) { corto_error("mqtt: failed to subscribe for topic"); } corto_ok("mqtt: subscribed to %s", topic); } }
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; }
corto_int16 cortotool_language(char *language) { if (!generators) { generators = corto_llNew(); } if (!attributes) { attributes = corto_llNew(); } if (!strcmp(language, "c")) { corto_llAppend(generators, "c_project"); corto_llAppend(generators, "c_type"); corto_llAppend(generators, "c_interface"); corto_llAppend(generators, "c_meta"); corto_llAppend(generators, "c_api"); corto_llAppend(attributes, "c=src"); corto_llAppend(attributes, "h=include"); } else if (!strcmp(language, "cpp")) { corto_llAppend(generators, "cpp_class"); corto_llAppend(generators, "c_type"); corto_llAppend(generators, "c_meta"); corto_llAppend(attributes, "c=src"); corto_llAppend(attributes, "h=include"); } else { corto_error("corto: unknown language '%s'", language); goto error; } return 0; error: return -1; }
/* Remove object */ void corto_llRemove(corto_ll list, void* o) { corto_llNode node, prev; corto_bool found = FALSE; prev = 0; node = list->first; while(node) { if (node->data == o) { found = TRUE; if (prev) { prev->next = node->next; if (!prev->next) { list->last = prev; } } else { list->first = node->next; if (!node->next) { list->last = list->first; } } free(node); break; } prev = node; node = node->next; } list->size--; if (!found) { corto_error("ll::remove: list does not contain %p", o); } }
corto_int16 corto_ser_initCollection(corto_serializer s, corto_value* v, void* userData) { corto_type t; void* o; t = corto_valueType(v); o = corto_valueValue(v); switch(corto_collection(t)->kind) { case CORTO_ARRAY: /* Serialize elements */ if (corto_serializeElements(s, v, userData)) { goto error; } break; case CORTO_SEQUENCE: ((corto_objectseq*)o)->buffer = NULL; ((corto_objectseq*)o)->length = 0; break; case CORTO_LIST: *(corto_ll*)o = corto_llNew(); break; case CORTO_MAP: /**(corto_rbtree*)o = corto_rbtreeNew(t);*/ break; default: corto_error("invalid collection object!"); goto error; break; } return 0; error: return -1; }
static int cortotool_addDirToMonitor(corto_string dir, corto_ll monitorList) { corto_id cortoDir, srcDir; sprintf(cortoDir, "%s/.corto", dir); sprintf(srcDir, "%s/src", dir); corto_ll files = corto_opendir(srcDir); if (!files || !corto_fileTest(cortoDir)) { corto_error("'%s' isn't a valid project directory", dir); goto error; } corto_iter iter = corto_ll_iter(files); while (corto_iter_hasNext(&iter)) { corto_id srcFile; corto_string file = corto_iter_next(&iter); sprintf(srcFile, "%s/src/%s", dir, file); corto_fileMonitor *mon = cortotool_monitorNew(srcFile, dir); corto_ll_append(monitorList, mon); } corto_closedir(files); return 0; error: return -1; }
/* Register a filetype */ int corto_load_register(corto_string ext, corto_loadAction handler, void* userData) { struct corto_fileHandler* h; /* Check if extension is already registered */ corto_mutexLock(&corto_adminLock); if ((h = corto_lookupExt(ext))) { if (h->load != handler) { corto_error("corto_load_register: extension '%s' is already registered with another loader.", ext); abort(); goto error; } } else { h = corto_alloc(sizeof(struct corto_fileHandler)); h->ext = ext; h->load = handler; h->userData = userData; if (!fileHandlers) { fileHandlers = corto_ll_new(); } corto_ll_append(fileHandlers, h); } corto_mutexUnlock(&corto_adminLock); return 0; error: return -1; }
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; }
/* Sleep */ void corto_sleep(unsigned int sec, unsigned int nanosec) { struct timespec sleepTime; sleepTime.tv_sec = sec; sleepTime.tv_nsec = nanosec; if (nanosleep(&sleepTime, NULL)) { corto_error("nanosleep failed: %s", strerror(errno)); } }
char* corto_value_exprStr(corto_value* v, char* buffer, unsigned int length) { corto_member m; corto_value* parents[CORTO_MAX_INHERITANCE_DEPTH]; corto_int32 parentCount, i; corto_value* vptr; *buffer = '\0'; /* Collect parents */ parentCount = 0; vptr = v; do{ if (vptr->kind != CORTO_OBJECT) { parents[parentCount] = vptr; parentCount++; } }while((vptr = vptr->parent)); /* Put name of member or branch in buffer */ for(i=parentCount-1; i>=0; i--) { vptr = parents[i]; m = NULL; switch(vptr->kind) { case CORTO_LITERAL: case CORTO_VALUE: case CORTO_MEM: break; case CORTO_BASE: break; case CORTO_MEMBER: m = vptr->is.member.t; break; case CORTO_ELEMENT: sprintf(buffer, "%s[%d]", buffer, vptr->is.element.t.index); m = NULL; break; default: corto_trace("corto_value_exprStr: unhandled '%s'", corto_valueKindString[vptr->kind]); m = NULL; goto error; } if (m) { if ((strlen(buffer) + strlen(corto_idof(m)) + 1) >= length) { corto_error("buffer passed to corto_strving is too short for member name"); } else { strcat(buffer, "."); strcat(buffer, corto_idof(m)); } } } return buffer; error: return NULL; }
void corto_seterrv(char *fmt, va_list args) { char *err = NULL; if (fmt) { corto_vasprintf(&err, fmt, args); } corto_setLasterror(err); if (fmt && (CORTO_DEBUG_ENABLED || CORTO_OPERATIONAL)) { if (CORTO_OPERATIONAL == 1) { corto_error("error raised while starting up: %s", err); } else if (CORTO_OPERATIONAL){ corto_error("error raised while shutting down: %s", err); } else { corto_error("debug: %s", err); } corto_backtrace(stderr); } corto_dealloc(err); }
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; }
corto_int16 cortotool_test(int argc, char *argv[]) { corto_string testCase = NULL; if (argc > 1) { if (corto_chdir(argv[1])) { corto_error("corto: can't change to directory '%s'", argv[1]); goto error; } if (argc > 2) { testCase = argv[2]; } } if (corto_fileTest("test")) { corto_int8 ret = 0, sig = 0, err = 0; corto_pid pid = corto_procrun("corto", (char*[]){"corto", "build", "test", "--silent", NULL});
corto_int16 _corto_delegate_bind(corto_function object) { /* $begin(::corto::lang::delegate::bind) */ corto_object parent = corto_parentof(object); if (corto_class_instanceof(corto_interface_o, corto_typeof(parent))) { corto_interface type = corto_interface(corto_typeof(parent)); corto_id functionName; corto_member m = NULL; /* Get function name, lookup delegate, assign function */ corto_signatureName(corto_nameof(object), functionName); if (corto_checkState(corto_type_o, CORTO_DEFINED) && (m = corto_interface_resolveMember(type, functionName)) && (m->type->kind == CORTO_COMPOSITE) && (corto_interface(m->type)->kind == CORTO_DELEGATE)) { if (corto_delegate_instanceof(corto_delegate(m->type), object)) { /* Bind instance of function is a method */ if (corto_procedure(corto_typeof(object))->kind == CORTO_METHOD) { corto_setref(&((corto_delegatedata *) CORTO_OFFSET(parent, m->offset))->instance, parent); } /* Bind procedure */ corto_setref(&((corto_delegatedata *) CORTO_OFFSET(parent, m->offset))->procedure, object); } else { /* If there is a member that corresponds to a delegate but has a non matching * signature, always report error */ corto_id id1, id2; corto_error("member '%s' of delegate type '%s' does not match signature of '%s'", corto_nameof(m), corto_fullname(m->type, id1), corto_fullname(object, id2)); goto error; } } } return 0; error: return -1; /* $end */ }
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", ¬ag, 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; }
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; }
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); }
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; }