From fe781e5ae7116733e5b335a0ac016af97266db5f Mon Sep 17 00:00:00 2001 From: Anastasis Grammenos Date: Mon, 8 Oct 2018 23:47:07 +0300 Subject: Way better Edit --- src/actionhelper.c | 26 +++++------ src/actionparser.c | 2 +- src/actions.c | 102 ++++++++++++++++++++++++----------------- src/ckutil.c | 6 +-- src/dblayer.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++-- src/dblayer.h | 6 ++- 6 files changed, 209 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/actionhelper.c b/src/actionhelper.c index 883229f..3e898af 100644 --- a/src/actionhelper.c +++ b/src/actionhelper.c @@ -15,6 +15,9 @@ #include #include "actionhelper.h" +#include "ckerrlog.h" + +ERRLOG(action); char add_err[STR_M] = ""; @@ -146,11 +149,8 @@ void add_make_link(const AddOpt *opt, const Conf *conf) { } } -edit_rc -edit_get_config_or_suggestions(cklist *args, char *ret) { +int edit_make_options(cklist *args) { UNUSED(args); - UNUSED(ret); - return ERC_ERR; } ListOpt list_make_options(cklist *args) { @@ -210,50 +210,48 @@ ListOpt list_make_options(cklist *args) { void print_INIT_result(int err) { if (!err) { - printf("Initialized empty ckdb.\n"); + HELP("Initialized empty ckdb."); } } void print_ADD_result(int err) { if (!err) { - printf("ckdb updated succesfully.\n"); + HELP("ckdb updated succesfully."); return; } - printf("Could not complete add transaction.\n"); + ERR("Could not complete add transaction."); } void print_DEL_result(int err) { if (!err) { - printf("succes\n"); + HELP("ckdb updated succesfully"); return; } - printf("Not Supported\n"); + ERR("Could not complete delete transaction"); } void print_EDIT_result(int err) { if (!err) { - printf("succes\n"); return; } - printf("failure\n"); } void print_LIST_result(int err) { if (!err) { return; } - printf("Wrong list arguments\n"); + ERR("Wrong list arguments"); } void print_SEARCH_result(int err) { if (err == 2) { - printf("No grep avaliable. Please make sure you have grep installed.\n"); + ERR("No grep avaliable. Please make sure you have grep installed."); return; } if (!err) { return; } - printf("Wrong search.\n"); + ERR("Wrong search."); } void print_HELP_result(int err) { diff --git a/src/actionparser.c b/src/actionparser.c index 25c7c19..7c1186a 100644 --- a/src/actionparser.c +++ b/src/actionparser.c @@ -332,7 +332,7 @@ void print_parser_error(UserOpt *opt) { sprintf(errStr, "Delete config or program\nUsage: %s ....", names); break; case PERR_EDIT_WRONG: - sprintf(errStr, "Edit config with $EDITOR\nUsage: %s ProgramName or configBasename (or both)", names); + sprintf(errStr, "Edit config with $EDITOR (%s)\nUsage: %s ProgramName [configBasename]", getenv("EDITOR"), names); break; case PERR_LIST_WRONG: sprintf(errStr, "List programs, configs and more\nUsage: %s value-to-list (or tree) [-t list-type] [-a]", names); diff --git a/src/actions.c b/src/actions.c index d5f9a29..4ff6816 100644 --- a/src/actions.c +++ b/src/actions.c @@ -102,7 +102,6 @@ int run_DEL(UserOpt * opt, Conf *conf) { } int run_EDIT(UserOpt *opt, Conf *conf) { - printf("Running %s\n", "edit"); DB db = open_DB(opt); if (db.ptr == NULL) { if (db.error == SQL_ERR_NO_TABLES) { @@ -112,31 +111,52 @@ int run_EDIT(UserOpt *opt, Conf *conf) { } list_rewind(opt->args); - char confPath[STR_M]; - if (list_size(opt->args) == 1) { - char confName[STR_M]; - int secret = 0; - if (edit_get_prime_config_from_program(&db, list_get(opt->args), confName, &secret) == 1) { - str_join_dirname_with_basename(confPath, secret ? conf->scrt_dir : conf->vc_dir, confName); - printf("%s\n", confPath); - } else { - PRINT_ERR("No primary config"); - close_DB(&db); - return 1; + char confPath[STR_L]; + char confName[STR_M]; + int secret = 0; + /* Since we are here, args have to be 1 or 2 */ + char *pName = list_get(opt->args); + if (!program_exists(&db, pName)) { + ERR("Program %s doesn't exist in the database.", pName); + goto error; + } + /* If there is no next argument */ + if (!list_next(opt->args)) { + /* If there is no primary config*/ + if (edit_get_prime_config_from_program(&db, pName, confName, &secret) == -1) { + /* If the program has only one config */ + if (get_config_number(&db, pName) == 1) { + if (edit_get_config(&db, pName, confName, NULL, &secret)) { + ERR("Coudln't find config file for %s", pName); + goto error; + } + } + /* If the program has many configs */ + else { + HELP("Ambiguous config. Please type the config name after the program."); + cklist *paths = list_make_new(); + edit_get_avaliable_paths(&db, paths, pName); + list_print(paths); + list_free(paths); + goto error; + } } - } else { - close_DB(&db); - char confName[STR_L]; - switch (edit_get_config_or_suggestions(opt->args, confName)) { - case ERC_OK: - return 0; - case ERC_ERR: - return 1; - case ERC_SUGGESTIONS: - return 1; + } + /* If there are more arguments */ + else { + char *cName = list_get(opt->args); + if (edit_get_config(&db, pName, confName, cName, &secret)) { + ERR("Program %s doesn't have a config named %s", pName, cName); + cklist *paths = list_make_new(); + edit_get_avaliable_paths(&db, paths, pName); + list_print(paths); + list_free(paths); + goto error; } } close_DB(&db); + str_join_dirname_with_basename(confPath, secret ? conf->scrt_dir : conf->vc_dir, confName); + HELP("Editing %s", confPath); char *editor = getenv("EDITOR"); char command[STR_L]; @@ -145,6 +165,9 @@ int run_EDIT(UserOpt *opt, Conf *conf) { strcat(command, confPath); system(command); return 0; + error: + close_DB(&db); + return 1; } int run_LIST(UserOpt *opt, Conf *conf) { @@ -157,45 +180,44 @@ int run_LIST(UserOpt *opt, Conf *conf) { return 1; } - cklist *list_type = list_make_new(); + cklist *the_list = list_make_new(); ListOpt listOpt = list_make_options(opt->args); if (listOpt.err) { - close_DB(&db); - list_free(list_type); - return 1; + goto error; } switch(listOpt._lt) { case LT_PATH: - list_get_paths(&db, list_type, listOpt.attr); + list_get_paths(&db, the_list, listOpt.attr); break; case LT_PROGRAM: - list_get_programs(&db, list_type); + list_get_programs(&db, the_list); break; case LT_TREE: - list_get_path_program_tree(&db, list_type, listOpt.attr); - list_print(list_type); - close_DB(&db); - list_free(list_type); - return 0; + list_get_path_program_tree(&db, the_list, listOpt.attr); + list_print(the_list); + goto close; case LT_NONE: - close_DB(&db); - list_free(list_type); - return 1; + goto error; } switch(listOpt._lst) { case LST_PLAIN: - list_print(list_type); + list_print(the_list); break; case LST_LISP: - list_print_lisp(list_type); + list_print_lisp(the_list); break; case LST_PYTHON: - list_print_python(list_type); + list_print_python(the_list); } + close: close_DB(&db); - list_free(list_type); + list_free(the_list); return 0; + error: + close_DB(&db); + list_free(the_list); + return 1; } FILE *popen(const char *command, const char *mode); diff --git a/src/ckutil.c b/src/ckutil.c index a477b36..9bfa139 100644 --- a/src/ckutil.c +++ b/src/ckutil.c @@ -97,13 +97,11 @@ int util_symlink_file(const char *path, const char* dest) { } void str_make_ck_config_name(char *ret, const char *path, - const char *progName) { + const char *progName) { char *basec = strdup(path); char *bname = basename(basec); - strcpy(ret, progName); - strcat(ret, "_"); - strcat(ret, bname); + str_join_dirname_with_basename(ret, progName, bname); free(basec); } diff --git a/src/dblayer.c b/src/dblayer.c index 8ec062c..4290a7a 100644 --- a/src/dblayer.c +++ b/src/dblayer.c @@ -12,6 +12,8 @@ * Give access to the database. * * -------------------------------------------------------------------------- */ +#include + #include "dblayer.h" #include "dbhelper.h" #include "ckutil.h" @@ -254,6 +256,13 @@ int get_program_id(DB *db, const char* name) { return id; } +int program_exists(DB *db, const char *pName) { + if (get_program_id(db, pName) == -1) { + return 0; + } + return 1; +} + int get_config_id(DB *db, const char* path) { sqlite3_stmt *stmt; int rc; @@ -281,7 +290,6 @@ int add_insert_relationship(DB *db, const int pid, const int cid) { return insert_to_rel_table(db, pid, cid); } - /* Returns the path of the found config via *ret */ int program_has_primary_config(DB *db, const int pid, char *ret, int *sec) { sqlite3_stmt *stmt; @@ -403,13 +411,116 @@ int edit_get_prime_config_from_program(DB *db, char *pName, char *ret, int *secr str_make_ck_config_name(confName, path, pName); strcpy(ret, confName); } - return 1; + return 0; } } } /* No prime config found */ - return 0; + return -1; +} + +int edit_get_config(DB *db, const char *pName, char *ret, const char *cName, int *sec) { + int pid = get_program_id(db, pName); + /* error */ + if (pid == -2) { + return -1; + } + + /* program exists */ + if (pid > -1) { + sqlite3_stmt *stmt; + int rc; + + char selection[STR_M] = COL_CONFIG_PATH; + strcat(selection, ", "); + strcat(selection, COL_CONFIG_SECRET); + char condition[STR_M] = TBL_PROGRAM; + strcat(condition, "."); + strcat(condition, COL_PROGRAM_ID); + + char sql[STR_L]; + dbh_form_query_select_from_joined_eq(sql, selection, condition); + + rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0); + sqlite3_bind_int(stmt, 1, pid); + if (rc != SQLITE_OK) { + return -2; + } + + int flag = -1; + while (sqlite3_step(stmt) == SQLITE_ROW) { + char confName[STR_M]; + if (cName) { + char *tmp = strdup((char *)sqlite3_column_text(stmt, 0)); + if (strcmp(cName, basename(tmp)) == 0) { + flag = 0; + char confName[STR_M]; + str_make_ck_config_name(confName, (char *)sqlite3_column_text(stmt, 0), pName); + strcpy(ret, confName); + if (sec) { + *sec = sqlite3_column_int(stmt, 1); + } + } + free(tmp); + } + else { + char confName[STR_M]; + str_make_ck_config_name(confName, (char *)sqlite3_column_text(stmt, 0), pName); + strcpy(ret, confName); + flag = 0; + if (sec) { + *sec = sqlite3_column_int(stmt, 1); + } + break; + } + } + sqlite3_finalize(stmt); + return flag; + } +} + +int edit_get_avaliable_paths(DB *db, cklist *ckl, const char* pName) { + int pid = get_program_id(db, pName); + /* error */ + if (pid == -2) { + return -1; + } + + /* program exists */ + if (pid > -1) { + sqlite3_stmt *stmt; + int rc; + + char selection[STR_M] = COL_CONFIG_PATH; + char condition[STR_M] = TBL_PROGRAM; + strcat(condition, "."); + strcat(condition, COL_PROGRAM_ID); + + char sql[STR_L]; + dbh_form_query_select_from_joined_eq(sql, selection, condition); + + rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0); + sqlite3_bind_int(stmt, 1, pid); + if (rc != SQLITE_OK) { + return -2; + } + + char name[STR_M] = ""; + strcat(name, pName); + strcat(name, ":"); + list_add(ckl, name); + while (sqlite3_step(stmt) == SQLITE_ROW) { + char *tmp = strdup((char *)sqlite3_column_text(stmt, 0)); + char entry[STR_M] = ""; + strcat(entry, "|- "); + strcat(entry, basename(tmp)); + list_add(ckl, entry); + free(tmp); + } + sqlite3_finalize(stmt); + return 0; + } } int list_get_paths(DB *db, cklist *ckl, int attr) { @@ -619,6 +730,19 @@ int get_program_relations(DB *db, int pid) { return count; } +int get_config_number(DB *db, char* pName) { + int pid = get_program_id(db, pName); + /* error */ + if (pid == -2) { + return -1; + } + + /* program exists */ + if (pid > -1) { + return get_program_relations(db, pid); + } +} + /* Removes the relationship of `cid` with the corresponding program. * Returns the program's pid on succes, negative integer otherwise. */ diff --git a/src/dblayer.h b/src/dblayer.h index cf01ccf..05ba5bd 100644 --- a/src/dblayer.h +++ b/src/dblayer.h @@ -41,7 +41,8 @@ extern int db_exists(const UserOpt *opt); * and the corresponding SQL error (NO_DB_FILE | NO_TABLES)*/ extern DB open_DB(const UserOpt *opt); -extern void close_DB(DB *DB); +extern void close_DB(DB *db); +extern int program_exists(DB *db, const char *pName); /********/ /* init */ @@ -63,6 +64,9 @@ extern int add_transaction_try(DB *db, const AddOpt * const opt); /********/ extern int edit_get_prime_config_from_program(DB *db, char *pName, char *ret, int *secret); +extern int get_config_number(DB *db, char *pName); +extern int edit_get_config(DB *db, const char *pName, char *ret, const char *cName, int *sec); +extern int edit_get_avaliable_paths(DB *db, cklist *ckl, const char* pName); /********/ /* list */ -- cgit v1.2.3