/* ::cortex::ic::program::assemble() */ cx_int16 ic_program_assemble(ic_program _this) { /* $begin(::cortex::ic::program::assemble) */ extern cx_bool CX_DEBUG_ENABLED; if (CX_DEBUG_ENABLED) { cx_string str = ic_program_str(_this); if (str) { printf("%s\n", str); cx_dealloc(str); } } _this->vmprogram = (cx_word)ic_vmAssemble(_this); if (!_this->vmprogram) { goto error; } if (CX_DEBUG_ENABLED) { cx_string str = cx_vmProgram_toString((cx_vmProgram)_this->vmprogram, NULL); if (str) { printf("%s\n", str); cx_dealloc(str); } } return 0; error: return -1; /* $end */ }
static void cx_lasterrorFree(void* tls) { if (tls) { cx_uint32 i; for (i = 0; i < 64; i++) { if (((cx_errThreadData*)tls)->lastError[i]) { cx_dealloc(((cx_errThreadData*)tls)->lastError[i]); } } cx_dealloc(tls); } }
/* Append string to serializer-result */ static cx_bool cx_ser_appendstr(cx_json_ser_t* data, cx_string fmt, ...) { char alloc[1024]; char *buff = alloc; va_list args; cx_uint32 memRequired; cx_uint32 result = TRUE; if (data) { va_list argcpy; va_copy(argcpy, args); va_start(args, fmt); memRequired = vsnprintf(buff, 1024, fmt, args); if (memRequired >= 1024) { buff = cx_malloc(memRequired + 1); vsprintf(buff, fmt, argcpy); } va_end(args); result = cx_ser_appendstrbuff(data, buff); if (buff != alloc) { cx_dealloc(buff); } } return result; }
static cx_int16 serializeText(cx_value *value, cx_string *out) { cx_type type = cx_valueType(value); cx_void *v = cx_valueValue(value); cx_primitiveKind kind = cx_primitive(type)->kind; if (kind == CX_CHARACTER || (kind == CX_TEXT && (*(cx_string *)v))) { cx_string raw; size_t length; int needEscape = 0; if (cx_convert(cx_primitive(type), v, cx_primitive(cx_string_o), &raw)) { goto error; } if (*raw == '@') { needEscape = 1; } length = stresc(NULL, 0, raw); *out = cx_malloc(length + 3 + needEscape); (*out)[0] = '"'; (*out)[1] = '@'; stresc(*out + 1 + needEscape, length, raw); (*out)[length + needEscape + 1] = '"'; (*out)[length + needEscape + 2] = '\0'; cx_dealloc(raw); } else { *out = cx_malloc(sizeof("null")); strcpy(*out, "null"); } return 0; error: return -1; }
static cx_int16 serializePrimitive(cx_serializer s, cx_value *v, void *userData) { CX_UNUSED(s); cx_type type = cx_valueType(v); cx_json_ser_t *data = userData; cx_int16 result; cx_string valueString; switch (cx_primitive(type)->kind) { case CX_BINARY: result = serializeBinary(v, &valueString); break; case CX_BITMASK: result = serializeBitmask(v, &valueString); break; case CX_BOOLEAN: result = serializeBoolean(v, &valueString); break; case CX_ENUM: result = serializeEnum(v, &valueString); break; case CX_CHARACTER: case CX_TEXT: result = serializeText(v, &valueString); break; case CX_UINTEGER: case CX_INTEGER: case CX_FLOAT: result = serializeNumber(v, &valueString); break; case CX_ALIAS: result = serializeAlias(v, &valueString); break; } if (result) { goto error; } if (!cx_ser_appendstr(data, "%s", valueString)) { goto finished; } cx_dealloc(valueString); return 0; finished: cx_dealloc(valueString); return 1; error: return -1; }
static int cx_appendStringAttr(cx_string key, cx_string value, void* userData) { size_t length; /* Escape value */ cx_string escapedValue = cx_malloc((length = stresc(NULL, 0, value)) + 1); stresc(escapedValue, length, value); if (!cx_ser_appendstr(userData, "\"%s\":\"%s\",", key, escapedValue)) { goto finished; } cx_dealloc(escapedValue); return 1; finished: cx_dealloc(escapedValue); return 0; }
/* ::cortex::web::DDPServer::Session::connected() */ cx_void web_DDPServer_Session_connected(web_DDPServer_Session _this) { /* $begin(::cortex::web::DDPServer::Session::connected) */ int msgLength = snprintf(NULL, 0, "{\"msg\":\"connected\",\"session\":\"%s\"}", cx_nameof(_this)); cx_string msg = cx_malloc(msgLength + 1); sprintf(msg, "{\"msg\":\"connected\",\"session\":\"%s\"}", cx_nameof(_this)); web_SockJsServer_Connection_send(_this->conn, msg); cx_dealloc(msg); /* $end */ }
/* ::cortex::lang::function::unbind(function object) */ cx_void cx_function_unbind(cx_function object) { /* $begin(::cortex::lang::function::unbind) */ cx_uint32 i; cx_callDestroy(object); /* Deinitialize parameters */ for(i=0; i<object->parameters.length; i++) { cx_dealloc(object->parameters.buffer[i].name); object->parameters.buffer[i].name = NULL; cx_free_ext(object, object->parameters.buffer[i].type, "Free function parameter-type."); object->parameters.buffer[i].type = NULL; } cx_dealloc(object->parameters.buffer); object->parameters.buffer = NULL; /* $end */ }
static cx_int16 serializeNumericWithPrefix(cx_value *value, cx_string *out, const char *prefix) { cx_string raw; cx_void *v = cx_valueValue(value); if (cx_convert(cx_primitive(cx_valueType(value)), v, cx_primitive(cx_string_o), &raw)) { goto error; } int length = snprintf(NULL, 0, "\"%s\" %s", prefix, raw); if (length < 0) { goto error; } *out = cx_malloc(length + 1); if (sprintf(*out, "\"%s %s\"", prefix, raw) < 0) { goto error; } cx_dealloc(raw); return 0; error: cx_dealloc(raw); return -1; }
static void cx_setLasterror(char* err) { cx_errThreadData* data; data = cx_getThreadData(); if (!data->echo && (data->count < MAX_ERRORS)) { if (data->lastError[data->count]) { cx_dealloc(data->lastError[data->count]); } data->lastError[data->count] = cx_strdup(err); data->count++; } }
/* Call exit-handlers */ static void cx_exit(void) { struct cx_exitHandler* h; if (cx_exitHandlers) { while((h = cx_llTakeFirst(cx_exitHandlers))) { h->handler(h->userData); cx_dealloc(h); } cx_llFree(cx_exitHandlers); cx_exitHandlers = NULL; } }
/* ::cortex::web::DDPServer::Session::pong(string id) */ cx_void web_DDPServer_Session_pong(web_DDPServer_Session _this, cx_string id) { /* $begin(::cortex::web::DDPServer::Session::pong) */ if (id) { int msgLength = snprintf(NULL, 0, "{\"msg\":\"pong\",\"id\":\"%s\"}", id); cx_string msg = cx_malloc(msgLength + 1); sprintf(msg, "{\"msg\":\"pong\",\"id\":\"%s\"}", id); web_SockJsServer_Connection_send(_this->conn, msg); cx_dealloc(msg); } else { web_SockJsServer_Connection_send(_this->conn, "{\"msg\":\"pong\"}"); } /* $end */ }
static cx_int16 serializeReference(cx_serializer s, cx_value *v, void *userData) { CX_UNUSED(s); cx_json_ser_t *data; void *o; cx_object object; cx_id id; data = userData; o = cx_valueValue(v); object = *(cx_object*)o; if (object) { if (cx_checkAttr(object, CX_ATTR_SCOPED) || (cx_valueObject(v) == object)) { cx_uint32 length; cx_fullname(object, id); /* Escape value */ cx_string escapedValue = cx_malloc((length = stresc(NULL, 0, id)) + 1); stresc(escapedValue, length, id); if (!cx_ser_appendstr(data, "\"@R %s\"", escapedValue)) { cx_dealloc(escapedValue); goto finished; } cx_dealloc(escapedValue); } else { cx_ser_appendstr(data, "\"anonymous\""); } } else { if (!cx_ser_appendstrbuff(data, "null")) { goto finished; } } return 0; finished: return 1; }
static void web_SockJsServer_open(web_SockJsServer _this, struct mg_connection *conn) { cx_string id = web_random(17); web_SockJsServer_Connection c = web_SockJsServer_Connection__declare(_this, id); cx_dealloc(id); c->conn = (cx_word)conn; if (web_SockJsServer_Connection__define(c, NULL)) { goto error; } conn->connection_param = c; if (_this->onOpen._parent.procedure) { cx_call(_this->onOpen._parent.procedure, NULL, _this->onOpen._parent.instance, c); } error:; }
/* Do metawalk on type */ cx_int16 cx_metaWalk(cx_serializer s, cx_type type, void* userData) { cx__object* o; cx_int16 result; /* Instantiate dummy-object */ o = cx_malloc(sizeof(cx__object) + type->size); /* alloca is dangerous here because objects can get large, causing stack overflows. */ memset(o, 0, sizeof(cx__object) + type->size); o->type = cx_type(type); o->refcount = 1; result = cx_serialize(s, CX_OFFSET(o, sizeof(cx__object)), userData); cx_dealloc(o); return result; }
/* ::cortex::lang::type::destruct() */ cx_void cx_type_destruct(cx_type _this) { /* $begin(::cortex::lang::type::destruct) */ cx_uint32 i; /* Free methods */ for(i=0; i<_this->metaprocedures.length; i++) { cx_free_ext(_this, _this->metaprocedures.buffer[i], "Remove method from vtable."); } if (_this->metaprocedures.buffer) { cx_dealloc(_this->metaprocedures.buffer); _this->metaprocedures.buffer = NULL; } /* $end */ }
/* ::cortex::web::SockJsServer::Connection::send(string msg) */ cx_void web_SockJsServer_Connection_send(web_SockJsServer_Connection _this, cx_string msg) { /* $begin(::cortex::web::SockJsServer::Connection::send) */ int escapedLength; cx_string sockJsMsg; /* Escape & pack message in SockJS header */ escapedLength = stresc(NULL, 0, msg); sockJsMsg = cx_malloc(escapedLength + strlen("a[\"\"]") + 1); sprintf(sockJsMsg, "a[\"%*s\"]", escapedLength, " "); stresc(sockJsMsg + 3, escapedLength, msg); mg_websocket_printf((struct mg_connection *)_this->conn, WEBSOCKET_OPCODE_TEXT, sockJsMsg); cx_dealloc(sockJsMsg); /* $end */ }
/* ::cortex::ic::program::getElement(storage base,node index) */ ic_element ic_program_getElement(ic_program _this, ic_storage base, ic_node index) { /* $begin(::cortex::ic::program::getElement) */ cx_id name; ic_element result; if (index) { cx_string elemStr = ic_node_str(index, NULL); sprintf(name, "%s[%s]", base->name, elemStr); cx_dealloc(elemStr); } else { sprintf(name, "*%s", base->name); } result = ic_element(ic_scope_lookupStorage(base->scope, name, FALSE)); if (!result) { result = ic_element__create(base, index); ic_scope_addStorage(_this->scope, ic_storage(result)); } return result; /* $end */ }
cx_err cx_logv(cx_err kind, unsigned int level, char* fmt, va_list arg, FILE* f) { char buff[CX_MAX_LOG + 1]; unsigned int written; size_t n = 0; cx_string alloc = NULL; cx_string msg = buff; va_list argcpy; va_copy(argcpy, arg); /* Make copy of arglist in * case vsnprintf needs to be called twice */ CX_UNUSED(level); if ((n = (vsnprintf(buff, CX_MAX_LOG, fmt, arg) + 1)) > CX_MAX_LOG) { alloc = cx_malloc(n + 2); vsnprintf(alloc, n, fmt, argcpy); msg = alloc; } n = strlen(msg); /* Set last error without \n */ cx_setLasterror(msg); strcat(msg, "\n"); n++; if (cx_getEcho() || ((kind == CX_CRITICAL) || (kind == CX_ASSERT))){ if ((written = fwrite(msg, 1, n, f)) != n) { fprintf(f, "Error in cx_logv: number of bytes written (%u)"\ " does not match length of message (%zu).\n", written, n); } } if (alloc) { cx_dealloc(alloc); } return kind; }
/* Write all parents to connection so that a reply is self-containing */ static int web_printParents(struct mg_connection *conn, cx_object o) { int result = 0; struct cx_serializer_s serializer = cx_json_ser(CX_PRIVATE, CX_NOT, CX_SERIALIZER_TRACE_NEVER); if (o) { cx_json_ser_t jsonData = {NULL, NULL, 0, 0, 0, TRUE, FALSE, FALSE, TRUE}; if (cx_parentof(o)) { result += web_printParents(conn, cx_parentof(o)); } if (result) { mg_printf_data(conn, ","); } cx_serialize(&serializer, o, &jsonData); mg_printf_data(conn, "%s\n", jsonData.buffer); cx_dealloc(jsonData.buffer); result++; } return result; }
/* ::cortex::ic::element::construct() */ cx_int16 ic_element_construct(ic_element _this) { /* $begin(::cortex::ic::element::construct) */ cx_id name; cx_collection type = cx_collection(_this->base->type); ic_storage(_this)->kind = IC_ELEMENT; cx_set(&ic_storage(_this)->type, type->elementType); cx_set(&ic_storage(_this)->base, _this->base); ic_storage(_this)->isReference = type->elementType->reference; if (_this->index) { cx_string elemStr = ic_node_str(_this->index, NULL); sprintf(name, "%s[%s]", _this->base->name, elemStr); cx_dealloc(elemStr); } else { sprintf(name, "*%s", _this->base->name); } ic_storage(_this)->name = cx_strdup(name); return ic_storage_construct(ic_storage(_this)); /* $end */ }
/* ::cortex::lang::function::stringToParameterSeq(string name,object scope) */ cx_parameterSeq cx_function_stringToParameterSeq(cx_string name, cx_object scope) { /* $begin(::cortex::lang::function::stringToParameterSeq) */ cx_parameterSeq result = {0, NULL}; cx_char* ptr; ptr = strchr(name, '('); if (!ptr) { cx_error("missing argumentlist in name for signature '%s'", name); goto error; } ptr++; /* Check if function has arguments */ if (*ptr != ')') { cx_int32 count = 0, i = 0; cx_id id; int flags = 0; /* Count number of parameters for function */ count = cx_signatureParamCount(name); if (count == -1) { goto error; } /* Allocate size for parameters */ result.length = count; result.buffer = cx_malloc(sizeof(cx_parameter) * count); memset(result.buffer, 0, sizeof(cx_parameter) * count); /* Parse arguments */ for(i=0; i<count; i++) { if (cx_signatureParamType(name, i, id, &flags)) { cx_error("error occurred while parsing type of parameter '%d' for signature '%s'", i, name); goto error; } /* Set reference */ result.buffer[i].passByReference = (flags & CX_PARAMETER_REFERENCE) != 0; /* Assign type */ result.buffer[i].type = cx_resolve_ext(NULL, scope, id, FALSE, "Resolve parameter-type for function"); if (!result.buffer[i].type) { cx_error("type '%s' of parameter %d in signature %s not found", id, i, name); goto error; } /* Validate whether reference is not redundantly applied */ if (result.buffer[i].passByReference && result.buffer[i].type->reference) { cx_id id; cx_error("redundant '&' qualifier for parameter %d, type '%s' is already a reference", i, cx_fullname(result.buffer[i].type, id)); goto error; } /* Parse name */ if (cx_signatureParamName(name, i, id)) { cx_error("error occurred while parsing name of argument '%s' for signature '%s'", name); goto error; } result.buffer[i].name = cx_strdup(id); } } return result; error: result.length = -1; cx_dealloc(result.buffer); result.buffer = NULL; return result; /* $end */ }
/* Serve a Cortex object */ static int web_serveObject(struct mg_connection *conn) { cx_object o = NULL; /* Resolve object based on URI */ o = cx_resolve(NULL, (cx_string)conn->uri + 2); if (!o) { mg_send_status(conn, 404); mg_printf_data(conn, "404: resource '%s' not found\n", conn->uri); } else { char option[6]; cx_bool value = 0; cx_bool meta = 0; cx_bool scope = 0; /* Set correct content type */ mg_send_header(conn, "Content-Type", "application/json; charset=utf-8"); /* Determine what to show */ mg_get_var(conn, "value", option, sizeof(option)); if (!strcmp(option, "true")) { value = TRUE; } mg_get_var(conn, "meta", option, sizeof(option)); if (!strcmp(option, "true")) { meta = TRUE; } mg_get_var(conn, "scope", option, sizeof(option)); if (!strcmp(option, "true")) { scope = TRUE; } if (!(value || meta || scope)) { value = TRUE; } { /* Serialize object-value to JSON */ struct cx_serializer_s serializer = cx_json_ser(CX_PRIVATE, CX_NOT, CX_SERIALIZER_TRACE_NEVER); if ((cx_typeof(o)->kind == CX_VOID) && (!meta && !scope)) { mg_printf_data(conn, "\n"); } else { mg_printf_data(conn, "["); /* Serialize metadata of parents */ if (meta) { if (web_printParents(conn, cx_parentof(o))) { mg_printf_data(conn, ","); } } /* Serialize value */ { cx_json_ser_t jsonData = {NULL, NULL, 0, 0, 0, meta, value, scope, TRUE}; cx_serialize(&serializer, o, &jsonData); mg_printf_data(conn, "%s", jsonData.buffer); cx_dealloc(jsonData.buffer); } mg_printf_data(conn, "]\n"); } } cx_free(o); } return MG_TRUE; }
/* Free values in collection */ static int cx_clearFreeValues(void* o, void* udata) { CX_UNUSED(udata); cx_dealloc(o); return 1; }