From b5dd0df1808429a3c0ed1f86256962512b8273f5 Mon Sep 17 00:00:00 2001 From: Louie Shprung Date: Tue, 13 Aug 2024 21:06:03 -0400 Subject: Working implementation for lua config --- src/draw.c | 26 +++++++------- src/group.c | 17 +++------ src/include/cache.h | 2 ++ src/include/draw.h | 5 ++- src/include/group.h | 3 ++ src/include/read_cfg.h | 6 ---- src/read_cfg.c | 70 +++++++++++++++++++++++++++++++------ src/windows/read_cfg.c | 93 -------------------------------------------------- 8 files changed, 86 insertions(+), 136 deletions(-) diff --git a/src/draw.c b/src/draw.c index 1775329..99b1a74 100644 --- a/src/draw.c +++ b/src/draw.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -40,7 +41,6 @@ int g_hover = 0; int *e_hover; int true_hover = 0; //0 = hovering on groups, 1 = hovering on entries GROUP **g; -ENTRY **e; int g_count; int g_offset = 0; int *e_offset; @@ -74,6 +74,10 @@ int main(int argc, char **argv){ print_help(argv[0]); return 1; } + // DEBUG + //for(i = 0; i < g_count; ++i) { + // group_debug(g[i]); + //} /* //Remove Empty Groups from the Array @@ -335,6 +339,7 @@ void fill_col(int mode){ //mode 1 = entry int i; + ENTRY **entries = get_gentries(g[g_hover]); WINDOW *col = (mode ? entry_win : group_win); int count = (mode ? get_ecount(g[g_hover]) : g_count); int offset = (mode ? e_offset[g_hover] : g_offset); @@ -343,15 +348,12 @@ void fill_col(int mode){ int max_y = HEIGHT-(6+GAP_SIZE); char *name; - mvwprintw(col, 0, 0, "i: %d\n", offset); - if(offset < 0) offset = 0; - for(i = 0+offset; i < count; i++){ if(ycoord >= max_y) break; //reached the bottom of the terminal window, stop drawing - name = (mode ? get_ename(e[i]) : get_gname(g[i])); + name = (mode ? get_ename(entries[i]) : get_gname(g[i])); //the name is too long, take the group to the trimming function - if(strlen(name) > max_len) name = trim_name(name, (mode ? get_epath(e[i]) : get_gname(g[i])), max_len); + if(strlen(name) > max_len) name = trim_name(name, (mode ? get_epath(entries[i]) : get_gname(g[i])), max_len); wmove(col, ycoord, 1); wprintw(col, "%s", name); ycoord++; @@ -427,7 +429,6 @@ void update_col(int mode, int y_hl, bool resize){ break; case 1: - e = get_gentries(g[g_hover]); fill_col(1); if(!resize) mvwchgat(entry_win, y_hl, 1, getmaxx(entry_win)-2, A_DIM, 1, NULL); else mvwchgat(entry_win, 1+e_hover[g_hover]-e_offset[g_hover], 1, getmaxx(entry_win)-2, A_DIM, (true_hover ? 2 : 1), NULL); @@ -483,7 +484,6 @@ void trav_col(int new_i){ mvwchgat(group_win, 1+g_hover-g_offset, 1, getmaxx(group_win)-2, A_NORMAL, 0, NULL); *focus = new_i; - //check offsets relating to new highlight, make sure highlight did not go oob while(*focus-*offset+5 > max_hl){ (*offset)++; @@ -517,6 +517,7 @@ void trav_col(int new_i){ } int locateChar(char input){ + ENTRY **entries = get_gentries(g[g_hover]); int location = (true_hover ? e_hover[g_hover] : g_hover); bool fold_case = get_case_sensitivity(); char first_char; @@ -526,7 +527,7 @@ int locateChar(char input){ if(true_hover){ //hovering on entries for(i = location+1; i < get_ecount(g[g_hover]); i++){ - first_char = get_ename(e[i])[0]; + first_char = get_ename(entries[i])[0]; if(fold_case && first_char >= 97 && first_char <= 122) first_char -= 32; if(input == first_char){ location = i; @@ -550,13 +551,12 @@ int locateChar(char input){ } char *get_launch(){ + ENTRY **entries = get_gentries(g[g_hover]); char *program = get_gprog(g[g_hover]); char *flags = get_gflags(g[g_hover]); - char *path = get_epath(e[e_hover[g_hover]]); + char *path = get_epath(entries[e_hover[g_hover]]); bool quotes = false; - char *full_command = malloc(sizeof(char) * BUF_LEN); - - full_command[0] = '\0'; + char *full_command = calloc(BUF_LEN, sizeof(char)); //if the entry is an executable file (doesn't have a launcher) if(!(strcmp(program, "./"))){ diff --git a/src/group.c b/src/group.c index edf4d7c..1d1ebd2 100644 --- a/src/group.c +++ b/src/group.c @@ -80,16 +80,9 @@ void set_ecount(GROUP *g, int new_count){ g->entry_count = new_count; } -/* -void group_debug(){ - GROUP *trav = groups_head; - - while(trav != NULL){ - entry_debug(trav->head); - printf("\tfrom group %s\n", trav->name); - trav = trav->next; - } - - return; +void group_debug(GROUP *g){ + printf("Entering group: %s\n", get_gname(g)); + printf("\tProgram: %s\n", get_gprog(g)); + printf("\tFlags: %s\n", get_gflags(g)); + printf("\tEntry Count: %d\n", get_ecount(g)); } -*/ diff --git a/src/include/cache.h b/src/include/cache.h index 894e4e1..701691f 100644 --- a/src/include/cache.h +++ b/src/include/cache.h @@ -1,6 +1,8 @@ #ifndef CACHE_H #define CACHE_H +#include + void save_to_cache(int g_count, int g_hover, int *e_hover, int *e_offset, int true_hover, char *cfg_name); void load_cache(int g_count, int *g_hover, int **e_hover, int **e_offset, int *true_hover, char *new_cfg_name); diff --git a/src/include/draw.h b/src/include/draw.h index 387ced3..022abe5 100644 --- a/src/include/draw.h +++ b/src/include/draw.h @@ -5,11 +5,14 @@ #define BUF_LEN 1024 +// currently selected group extern int g_hover; +// array of currently selected entries for each group extern int *e_hover; +// array of groups (as loaded from the config) extern struct group **g; -extern struct entry **e; +// returns the command to run for the current entry char *get_launch(); //functions that differ between os diff --git a/src/include/group.h b/src/include/group.h index dc74bcc..89a8422 100644 --- a/src/include/group.h +++ b/src/include/group.h @@ -27,4 +27,7 @@ int get_ecount(GROUP *g); void set_ecount(GROUP *g, int new_count); //for use in hiding entries +// print all group and entry information +void group_debug(GROUP *g); + #endif diff --git a/src/include/read_cfg.h b/src/include/read_cfg.h index fc40cc0..29a36e7 100644 --- a/src/include/read_cfg.h +++ b/src/include/read_cfg.h @@ -11,12 +11,6 @@ GROUP **cfg_interp(char *path, int *group_count); bool get_sort(); bool get_case_sensitivity(); void refer_to_doc(); -//void addme(char *path, char *group, bool force, char *name); -//int search_ch(char *str, char c); -//int search_last_ch(char *str, char c); -//int wild_cmp(char *wild, char *literal); -//char *strip_quotes(char *str); -//void error_mes(int ln, char *message); //functions that differ by os extern char sep; diff --git a/src/read_cfg.c b/src/read_cfg.c index b9ac8bc..97a76ff 100644 --- a/src/read_cfg.c +++ b/src/read_cfg.c @@ -24,9 +24,11 @@ //private //void check_line(char *buffer, char **options, int ln); //int check_option(char *arg, char **options); -int key_count(lua_State *L, int table_stack_index); // counts the number of keys in a table +int get_group_count(lua_State *L, int table_stack_index); // counts the number of valid groups +int get_entry_count(lua_State *L, int table_stack_index); // counts the number of valid entries for a group void add_groups(lua_State *L, int table_stack_index, GROUP ***g); void add_entries(lua_State *L, int table_stack_index, GROUP *g); +void stack_debug(lua_State *L); //turn on or off sorting (A-Z); On by default bool sort = true; @@ -80,7 +82,7 @@ GROUP **cfg_interp(char *path, int *group_count){ } // create the group array - *group_count = key_count(L, i); + *group_count = get_group_count(L, i); g = malloc(sizeof(GROUP *) * (*group_count)); // add each group (which also adds each entry to each group) @@ -102,22 +104,51 @@ void refer_to_doc(){ return; } -int key_count(lua_State *L, int table_stack_index) { +int get_group_count(lua_State *L, int table_stack_index) { int output = 0; + int entry_table_stack_index; + const char *group_name; lua_pushnil(L); while(lua_next(L, table_stack_index)) { // uses 'key' (at index -2) and 'value' (at index -1) - if(lua_type(L, -2) == LUA_TSTRING) ++output; - lua_pop(L, 1); + if(lua_type(L, -2) == LUA_TSTRING && lua_type(L, -1) == LUA_TTABLE) { + // check validity of this group + group_name = lua_tostring(L, -2); + if(group_name != NULL) { + // check that the Entries table for this group is not empty + lua_pushstring(L, "Entries"); + lua_gettable(L, -2); + entry_table_stack_index = lua_gettop(L); + if(lua_type(L, entry_table_stack_index) == LUA_TTABLE + && get_entry_count(L, entry_table_stack_index) > 0) + ++output; + } + } + // pop the top of the stack down to the key of the group + lua_pop(L, lua_gettop(L)-table_stack_index-1); } return output; } +int get_entry_count(lua_State *L, int table_stack_index) { + int i = 1; + int output = 0; + + do { + lua_rawgeti(L, table_stack_index, i); + if(lua_type(L, -1) == LUA_TSTRING) ++output; + ++i; + } while(lua_type(L, -1) != LUA_TNIL); + + return output; +} + void add_groups(lua_State *L, int table_stack_index, GROUP ***g) { const char *group_name; int entry_table_stack_index; + int entry_count; int i; lua_pushnil(L); @@ -130,20 +161,31 @@ void add_groups(lua_State *L, int table_stack_index, GROUP ***g) { if(group_name != NULL) { // push the Entries table on the stack (to get entry information) lua_pushstring(L, "Entries"); + // get table Groups.TABLE_NAME.Entries lua_gettable(L, -2); entry_table_stack_index = lua_gettop(L); + // check that 'Entries' is a table if(lua_type(L, entry_table_stack_index) != LUA_TTABLE) { printf("Error in config: 'Entries' should be Table, is actually %s\n", lua_typename(L, lua_type(L, entry_table_stack_index))); exit(1); } - (*g)[i] = create_group(group_name, key_count(L, entry_table_stack_index)); - // add entries to this group - add_entries(L, entry_table_stack_index, (*g)[i]); + + entry_count = get_entry_count(L, entry_table_stack_index); + // check that the group has at least 1 entry + if(entry_count <= 0) + printf("Skipping empty group '%s'\n", group_name); + + else { + (*g)[i] = create_group(group_name, entry_count); + // add entries to this group + add_entries(L, entry_table_stack_index, (*g)[i]); + } } } - lua_pop(L, 1); + // pop the top of the stack down to the key of the group + lua_pop(L, lua_gettop(L)-table_stack_index-1); ++i; } } @@ -166,7 +208,13 @@ void add_entries(lua_State *L, int table_stack_index, GROUP *g) { lua_pop(L, 1); ++i; } +} - // one last pop to pop the key off - lua_pop(L, 1); +void stack_debug(lua_State *L) { + int i; + + printf("DEBUGGING STACK:\n"); + for(i = 1; i <= lua_gettop(L); ++i) { + printf("\t%d - %s\n", i, lua_typename(L, lua_type(L, i))); + } } diff --git a/src/windows/read_cfg.c b/src/windows/read_cfg.c index 9fa721b..bb337f0 100644 --- a/src/windows/read_cfg.c +++ b/src/windows/read_cfg.c @@ -137,96 +137,3 @@ void mkconfig_wizard(char *path){ return; } - -//TODO augment to involve recurs -//TODO could use some cleanup... -void handle_fname(char *path, char *group, bool recurs, bool force, char *name, int ln){ - ENTRY *new; - char *search; //pointer for traversing path - char full_path_cpy[BUF_LEN]; - char relative_path_cpy[BUF_LEN]; - char arg_cpy[BUF_LEN]; - char auto_name[BUF_LEN]; - int plen = strlen(path); - char *dirname; - char *local_arg; //for use in addR - DIR *dp; - struct dirent *fname; - int i; - char *error_p; //helper for complex error messages - - assert(path != NULL && group != NULL); - - if(path[0] == '\0' || group[0] == '\0'){ - error_mes(ln, "Too few arguments for \"add\""); - return; - } - - //address potential quotes - strcpy(full_path_cpy, strip_quotes(path)); - - //don't check that the path arg is valid when forced - if(force) addme(full_path_cpy, group, force, name); - - //file is not recognized, perhaps it has a wildcard? - //TODO finish rewriting a more robust wildcard thingy - else if(access(full_path_cpy, F_OK) == -1){ - i = search_ch(full_path_cpy, '*'); - if(i > -1){ - //look for a directory - while(full_path_cpy[i] != sep && (i >= 0)){ - i--; - } - dirname = full_path_cpy; - strcpy(arg_cpy, full_path_cpy); - dirname[i+1] = '\0'; - dp = opendir(dirname); - - //the directory is real - if(dp != NULL){ - while(fname = readdir(dp)){ - relative_path_cpy[0] = '\0'; - strcat(relative_path_cpy, dirname); - strcat(relative_path_cpy, fname->d_name); - - //Windows cannot tell file types (TODO), so just add relatively indiscriminantly - if(!(wild_cmp(&arg_cpy[i+1], fname->d_name))) addme(relative_path_cpy, group, force, name); - - //if the recursive option was specified, run handle_fname on this directory, but for security reasons, do not consider directories that start with a '.' - else if(recurs && fname->d_name[0] != '.'){ - i = search_last_ch(arg_cpy, sep); - local_arg = &arg_cpy[i+1]; - strcat(relative_path_cpy, &sep); - strcat(relative_path_cpy, local_arg); - handle_fname(relative_path_cpy, group, 1, 0, NULL, ln); - } - } - - closedir(dp); - } - - //directory is not real, report error to the user - else if(!recurs){ - error_p = malloc(sizeof(char) * 1024); - sprintf(error_p, "\"%s\" bad path", dirname); - error_mes(ln, error_p); - free(error_p); - //printf("Error: \"%s\" bad path\n", dirname); - } - } - - //path is not real, report error to the user - else{ - error_p = malloc(sizeof(char) * 1024); - sprintf(error_p, "\"%s\" bad path", full_path_cpy); - error_mes(ln, error_p); - free(error_p); - } - } - - //file name is okay - //FIXME does not take into account whether the argument is a file (could be a directory, symlink, etc.) - else addme(full_path_cpy, group, force, name); - - return; -} -- cgit