From a23c315905c126667f13091989ca2879b5337582 Mon Sep 17 00:00:00 2001 From: Louie Shprung Date: Sun, 4 Aug 2024 17:19:08 -0400 Subject: Hello lua --- src/Makefile.am | 4 ++-- src/read_cfg.c | 21 +++++++++++++++++++++ src/unix/read_cfg.c | 6 +++--- src/windows/read_cfg.c | 4 ++-- 4 files changed, 28 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 80a550c..7fbb284 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,8 +3,8 @@ EXTRA_DIST = include unix windows bin_PROGRAMS = terminal-media-launcher terminal_media_launcher_SOURCES = cache.c draw.c read_cfg.c group.c entry.c $(PLATFORM)/cache.c $(PLATFORM)/draw.c $(PLATFORM)/read_cfg.c -terminal_media_launcher_LDADD = @CURSES_LIBS@ -terminal_media_launcher_CPPFLAGS = @CURSES_CFLAGS@ +terminal_media_launcher_LDADD = @CURSES_LIBS@ @LUA_LIB@ +terminal_media_launcher_CPPFLAGS = @CURSES_CFLAGS@ @LUA_INCLUDE@ if WINDOWS PLATFORM=windows diff --git a/src/read_cfg.c b/src/read_cfg.c index f757d6b..fa8a424 100644 --- a/src/read_cfg.c +++ b/src/read_cfg.c @@ -1,4 +1,6 @@ #include +#include +#include #include #include #include @@ -43,12 +45,31 @@ bool cfg_interp(char *path){ int i=0; int j; + // check if file path exists fp = fopen(path, "r"); if(fp == NULL){ printf("Error: Invalid Configuration Path \"%s\"\n", path); return false; } + fclose(fp); + + // load lua configuration + lua_State *L = luaL_newstate(); + int config_load_status = luaL_dofile(L, path); + if(config_load_status != 0) { + printf("Error: could not load configuration \"%s\"\nis there a syntax error?\n", path); + return false; + } + + // demo + lua_getglobal(L, "Message"); + const char *message = lua_tostring(L, -1); + printf("message: %s\n", message); + + lua_close(L); + return true; + /* --- Old code --- */ //build the options array char **options = malloc(sizeof(char *) * OPTION_CNT); options[0] = "add"; diff --git a/src/unix/read_cfg.c b/src/unix/read_cfg.c index b40dd48..4e58863 100644 --- a/src/unix/read_cfg.c +++ b/src/unix/read_cfg.c @@ -20,8 +20,8 @@ char *find_config(){ int check_count = 2; int i; - sprintf(choices[0], "%s%c.config%cterminal-media-launcher%cconfig", home, sep, sep, sep); - sprintf(choices[1], "%s%c.terminal-media-launcher%cconfig", home, sep, sep); + sprintf(choices[0], "%s%c.config%cterminal-media-launcher%cconfig.lua", home, sep, sep, sep); + sprintf(choices[1], "%s%c.terminal-media-launcher%cconfig.lua", home, sep, sep); for(i = 0; i < check_count; i++){ strcpy(path, choices[i]); @@ -69,7 +69,7 @@ void mkconfig_wizard(char *path){ sprintf(path, "%s%c.config%cterminal-media-launcher%c", home, sep, sep, sep); mkdir(path, 0755); - sprintf(path, "%s%c.config%cterminal-media-launcher%cconfig", home, sep, sep, sep); + sprintf(path, "%s%c.config%cterminal-media-launcher%cconfig.lua", home, sep, sep, sep); //open file for writing, make sure non-NULL fp = fopen(path, "w"); diff --git a/src/windows/read_cfg.c b/src/windows/read_cfg.c index f973759..9fa721b 100644 --- a/src/windows/read_cfg.c +++ b/src/windows/read_cfg.c @@ -20,7 +20,7 @@ char *find_config(){ char choices[check_count][BUF_LEN]; int i; - sprintf(choices[0], "%s%cterminal-media-launcher%cconfig", appdata, sep, sep); + sprintf(choices[0], "%s%cterminal-media-launcher%cconfig.lua", appdata, sep, sep); for(i = 0; i < check_count; i++){ strcpy(path, choices[i]); @@ -72,7 +72,7 @@ void mkconfig_wizard(char *path){ sprintf(path, "%s%cterminal-media-launcher%c", appdata, sep, sep); mkdir(path); - sprintf(path, "%s%cterminal-media-launcher%cconfig", appdata, sep, sep); + sprintf(path, "%s%cterminal-media-launcher%cconfig.lua", appdata, sep, sep); //open file for writing, make sure non-NULL fp = fopen(path, "w"); -- cgit From a18a8b783d71859e01c550b0acf6e0cefbef0d9f Mon Sep 17 00:00:00 2001 From: Louie Shprung Date: Wed, 7 Aug 2024 22:34:44 -0400 Subject: Working demo for loading groups and entries from lua config --- src/include/read_cfg.h | 2 ++ src/read_cfg.c | 44 ++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 42 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/include/read_cfg.h b/src/include/read_cfg.h index df3e5bd..a76e55e 100644 --- a/src/include/read_cfg.h +++ b/src/include/read_cfg.h @@ -1,6 +1,8 @@ #ifndef READ_CFG_H #define READ_CFG_H +#include + #define BUF_LEN 1024 bool cfg_interp(char *path); diff --git a/src/read_cfg.c b/src/read_cfg.c index fa8a424..940630b 100644 --- a/src/read_cfg.c +++ b/src/read_cfg.c @@ -55,16 +55,51 @@ bool cfg_interp(char *path){ // load lua configuration lua_State *L = luaL_newstate(); - int config_load_status = luaL_dofile(L, path); + int config_load_status = luaL_loadfile(L, path); if(config_load_status != 0) { printf("Error: could not load configuration \"%s\"\nis there a syntax error?\n", path); return false; } + // set up base configuration variables + // TODO set helper variables and functions (e.g., so that Groups table doesn't need to be manually created in the user's config) + //lua_newtable(L); + //lua_setglobal(L, "Groups"); + lua_pcall(L, 0, 0, 0); + // demo - lua_getglobal(L, "Message"); - const char *message = lua_tostring(L, -1); - printf("message: %s\n", message); + lua_getglobal(L, "Groups"); + i = lua_gettop(L); + // add each group + const char *group_name; + lua_pushnil(L); + while(lua_next(L, i)) { + // the key is index -2, value is -1 + if(lua_type(L, -2) != LUA_TSTRING) continue; // skip if invalid key + group_name = lua_tostring(L, -2); + group_add(group_name, NULL); + // add each entry + if(lua_type(L, -1) != LUA_TTABLE) continue; // skip if invalid value + lua_pushstring(L, "Entries"); + lua_gettable(L, -2); + j = lua_gettop(L); + lua_pushnil(L); + while(lua_next(L, j)) { + if(lua_type(L, -1) != LUA_TSTRING) continue; // skip if invalid value + handle_fname(lua_tostring(L, -1), group_name, false, true, NULL, -1); + lua_pop(L, 1); + } + lua_pop(L, 2); + } + + //lua_getfield(L, -1, "Pictures"); + //lua_getfield(L, -1, "Entries"); + //lua_rawgeti(L, -1, 1); + //printf("message: %d\n", (int)lua_tonumber(L, -1)); + //lua_rawgeti(L, -2, 2); + //printf("message: %d\n", (int)lua_tonumber(L, -1)); + //lua_rawgeti(L, -3, 3); + //printf("message: %d\n", (int)lua_tonumber(L, -1)); lua_close(L); return true; @@ -89,6 +124,7 @@ bool cfg_interp(char *path){ //Read each line of "config" while(fgets(buffer, BUF_LEN, fp)){ + printf("%d\n", i); i++; check_line(buffer, options, i); } -- cgit From 9e999c82f830f48ebabc72338ef721154acd116a Mon Sep 17 00:00:00 2001 From: Louie Shprung Date: Wed, 7 Aug 2024 22:59:45 -0400 Subject: Small improvement towards setting launchers, but the current group class makes this a headache --- src/read_cfg.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/read_cfg.c b/src/read_cfg.c index 940630b..549393b 100644 --- a/src/read_cfg.c +++ b/src/read_cfg.c @@ -78,8 +78,16 @@ bool cfg_interp(char *path){ if(lua_type(L, -2) != LUA_TSTRING) continue; // skip if invalid key group_name = lua_tostring(L, -2); group_add(group_name, NULL); - // add each entry + // check for a launcher if(lua_type(L, -1) != LUA_TTABLE) continue; // skip if invalid value + lua_pushstring(L, "Launcher"); + lua_gettable(L, -2); + if(lua_type(L, -1) == LUA_TSTRING) { + // FIXME the groups '''API''' I built might need some improvements in order for this to not be a headache + //set_gprog(GROUP *g, lua_tostring(L, -1)) + } + lua_pop(L, 1); + // add each entry lua_pushstring(L, "Entries"); lua_gettable(L, -2); j = lua_gettop(L); -- cgit From 85596300cc45d73bd3335d8c802b7c590fb1e1d2 Mon Sep 17 00:00:00 2001 From: Louie Shprung Date: Thu, 8 Aug 2024 21:24:54 -0400 Subject: Allow standard library in config --- src/read_cfg.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/read_cfg.c b/src/read_cfg.c index 549393b..a931a11 100644 --- a/src/read_cfg.c +++ b/src/read_cfg.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -55,9 +56,11 @@ bool cfg_interp(char *path){ // load lua configuration lua_State *L = luaL_newstate(); - int config_load_status = luaL_loadfile(L, path); + luaL_openlibs(L); // allow for standard library to be used + int config_load_status = luaL_dofile(L, path); if(config_load_status != 0) { - printf("Error: could not load configuration \"%s\"\nis there a syntax error?\n", path); + printf("Error: could not load configuration \"%s\"\n", path); + lua_error(L); return false; } @@ -65,11 +68,15 @@ bool cfg_interp(char *path){ // TODO set helper variables and functions (e.g., so that Groups table doesn't need to be manually created in the user's config) //lua_newtable(L); //lua_setglobal(L, "Groups"); - lua_pcall(L, 0, 0, 0); + //lua_pcall(L, 0, 0, 0); // demo lua_getglobal(L, "Groups"); i = lua_gettop(L); + if(lua_type(L, i) != LUA_TTABLE) { + printf("Error in config: 'Groups' should be Table, is actually %s\n", lua_typename(L, lua_type(L, i))); + return 1; + } // add each group const char *group_name; lua_pushnil(L); -- cgit From 4e68f637300c0e360d49f8f672d0675d42da0d1f Mon Sep 17 00:00:00 2001 From: Louie Shprung Date: Sun, 11 Aug 2024 17:49:28 -0400 Subject: (Currently broken) reimplementation of group and entry --- src/draw.c | 27 ++- src/entry.c | 84 +------- src/group.c | 173 ++-------------- src/include/entry.h | 18 +- src/include/group.h | 24 +-- src/include/read_cfg.h | 17 +- src/read_cfg.c | 551 ++++++------------------------------------------- src/unix/read_cfg.c | 94 --------- 8 files changed, 121 insertions(+), 867 deletions(-) (limited to 'src') diff --git a/src/draw.c b/src/draw.c index 15a9289..1775329 100644 --- a/src/draw.c +++ b/src/draw.c @@ -42,7 +42,6 @@ int true_hover = 0; //0 = hovering on groups, 1 = hovering on entries GROUP **g; ENTRY **e; int g_count; -int e_count; int g_offset = 0; int *e_offset; @@ -70,15 +69,18 @@ int main(int argc, char **argv){ //Fill Groups //read the contents of the cfg file; print help message if invalid - if(!cfg_interp(cfg_path)){ + g = cfg_interp(cfg_path, &g_count); + if(g == NULL) { print_help(argv[0]); return 1; } + /* //Remove Empty Groups from the Array clean_groups(); g = get_groups(); //retrieve results of cfg_interp g_count = get_gcount(); //retrieve number of groups in g (only do this after removing empty groups) + */ //check that there are is at least one valid group if(g_count == 0){ @@ -91,7 +93,7 @@ int main(int argc, char **argv){ e_offset = calloc(g_count, sizeof(int)); //load cached data - load_cache(g_count, &g_hover, &e_hover, &e_offset, &true_hover, cfg_path); + //load_cache(g_count, &g_hover, &e_hover, &e_offset, &true_hover, cfg_path); //reopen stdout for drawing menu freopen("/dev/tty", "w", stdout); @@ -125,6 +127,7 @@ int main(int argc, char **argv){ update_display(true); //drawing is done, now run a while loop to receive input (ESC ends this loop) + input = 0; while(input != 27){ input = getch(); @@ -151,12 +154,12 @@ int main(int argc, char **argv){ case KEY_NPAGE: //case KEY_SDOWN: - trav_col((true_hover ? e_count : g_count)-1); + trav_col((true_hover ? get_ecount(g[g_hover]) : g_count)-1); break; case KEY_F(3): //jump to random group/entry - trav_col(rand() % (true_hover ? e_count : g_count)); + trav_col(rand() % (true_hover ? get_ecount(g[g_hover]) : g_count)); break; case KEY_F(5): @@ -333,13 +336,16 @@ void fill_col(int mode){ int i; WINDOW *col = (mode ? entry_win : group_win); - int count = (mode ? e_count : g_count); + int count = (mode ? get_ecount(g[g_hover]) : g_count); int offset = (mode ? e_offset[g_hover] : g_offset); int max_len = getmaxx(col)-2; //longest possible string length that can be displayed in the window int ycoord = 1; 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])); @@ -421,8 +427,7 @@ void update_col(int mode, int y_hl, bool resize){ break; case 1: - e_count = get_ecount(g[g_hover]); - e = get_entries(get_ghead(g[g_hover]), e_count); + 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); @@ -464,7 +469,7 @@ void switch_col(){ void trav_col(int new_i){ int *focus = (true_hover ? &(e_hover[g_hover]) : &g_hover); //make it easy to know which column we are looking at int *offset = (true_hover ? &(e_offset[g_hover]) : &g_offset); - int count = (true_hover ? e_count : g_count); + int count = (true_hover ? get_ecount(g[g_hover]) : g_count); int max_hl = HEIGHT-(3+GAP_SIZE); //for some reason, this works int min_hl = 5; int oob_flag = 0; //0 = none, 1 = bottom, 2 = top @@ -520,7 +525,7 @@ int locateChar(char input){ if(fold_case && input >= 97 && input <= 122) input -= 32; if(true_hover){ //hovering on entries - for(i = location+1; i < e_count; i++){ + for(i = location+1; i < get_ecount(g[g_hover]); i++){ first_char = get_ename(e[i])[0]; if(fold_case && first_char >= 97 && first_char <= 122) first_char -= 32; if(input == first_char){ @@ -548,7 +553,7 @@ char *get_launch(){ char *program = get_gprog(g[g_hover]); char *flags = get_gflags(g[g_hover]); char *path = get_epath(e[e_hover[g_hover]]); - bool quotes = get_gquotes(g[g_hover]); + bool quotes = false; char *full_command = malloc(sizeof(char) * BUF_LEN); full_command[0] = '\0'; diff --git a/src/entry.c b/src/entry.c index 6dc5699..dceb424 100644 --- a/src/entry.c +++ b/src/entry.c @@ -7,18 +7,15 @@ #include #include "include/entry.h" -#include "include/group.h" #include "include/read_cfg.h" typedef struct entry{ char name[BUF_LEN]; char path[BUF_LEN]; bool path_force; - bool hidden; - struct entry *next; } ENTRY; -ENTRY *create_entry(char *new_name, char *new_path, bool force){ +ENTRY *create_entry(const char *new_name, const char *new_path, const bool force){ ENTRY *new; new = malloc(sizeof(ENTRY)); @@ -26,85 +23,15 @@ ENTRY *create_entry(char *new_name, char *new_path, bool force){ strcpy(new->name, new_name); strcpy(new->path, new_path); new->path_force = force; - new->hidden = false; - new->next = NULL; return new; } -void entry_rm(ENTRY *e, ENTRY *prev){ - assert(e != NULL); - if(prev != NULL) prev->next = e->next; //maintain linked structure - free(e); -} - -void clear_entries(ENTRY *head){ - ENTRY *temp; - - while(head != NULL){ - temp = head; - head = head->next; - free(temp); - } - - return; -} - -//returns 0 if in the middle, 1 if new head, 2 if new tail, or 3 if both new head and tail -//TODO this is kind of a stupid way of handling things -int entry_add(ENTRY *head, ENTRY *tail, ENTRY *add){ - assert(add != NULL); - ENTRY *ahead; - - //Empty group (no need to sort) - if(head == NULL) return 3; - - //add is the new tail - if(!get_sort() || strcmp(tail->name, add->name) <= 0){ - tail->next = add; - return 2; - } - - //add is the new head - if(strcmp(add->name, head->name) <= 0){ - add->next = head; - return 1; - } - - ahead = head->next; - - while(ahead != NULL){ - if(strcmp(head->name, add->name) <= 0 && strcmp(add->name, ahead->name) <= 0) break; - head = head->next; - ahead = ahead->next; - } - - head->next = add; - add->next = ahead; - - return 0; -} - -ENTRY **get_entries(ENTRY *head, int count){ - ENTRY **arr = malloc(sizeof(ENTRY *) * count); - ENTRY *trav = head; - int i = 0; - - while(i < count){ - if(!trav->hidden){ - arr[i] = trav; - i++; - } - trav = trav->next; - } - - return arr; -} - char *get_ename(ENTRY *e){ assert(e != NULL); return e->name; } + char *get_epath(ENTRY *e){ assert(e != NULL); return e->path; @@ -115,11 +42,7 @@ bool get_eforce(ENTRY *e){ return e->path_force; } -void set_hide(ENTRY *e, bool status){ - assert(e != NULL); - e->hidden = true; -} - +/* void entry_debug(ENTRY *trav){ while(trav != NULL){ @@ -129,3 +52,4 @@ void entry_debug(ENTRY *trav){ return; } +*/ diff --git a/src/group.c b/src/group.c index 0c0d5a0..edf4d7c 100644 --- a/src/group.c +++ b/src/group.c @@ -13,166 +13,27 @@ typedef struct group{ char name[BUF_LEN]; char program[BUF_LEN]; char flags[BUF_LEN]; - struct entry *head; - struct entry *tail; - struct group *next; + struct entry **entries; int entry_count; - bool launcher_quotes; //set by a group option whether or not the launcher should be wrapped by quotes + //bool launcher_quotes; //set by a group option whether or not the launcher should be wrapped by quotes } GROUP; -GROUP *groups_head; -GROUP *gp; //pointer to remember last group that was looked at int group_count = 0; int total_count = 0; -GROUP *create_group(char *new_name){ +GROUP *create_group(const char *new_name, const int entry_count){ GROUP *new = malloc(sizeof(GROUP)); strcpy(new->name, new_name); //by default, group name is equivalent to the path strcpy(new->program, "./"); //by default, launch an entry by executing it new->flags[0] = '\0'; //by default, no command line flags - new->head = NULL; - new->tail = NULL; - new->next = NULL; - new->entry_count = 0; - new->launcher_quotes = true; + new->entries = malloc(sizeof(ENTRY *) * entry_count); + new->entry_count = entry_count; group_count++; return new; } -//add an entry to a group or add a new empty group -//FIXME maybe make this function part of a seperate file to handle a tree (AVL?) -//for now, simple linked list implementation -void group_add(char *gname, ENTRY *addme){ - int i; - GROUP *new; - GROUP *last = NULL; //last element in an existing group list (NULL to start) - - //only adding a new group - if(addme == NULL){ - gp = groups_head; - while(gp != NULL){ - if(!(strcmp(gp->name, gname))){ - printf("config error: %s is already a group!\n", gname); - return; - } - - last = gp; - gp = gp->next; - } - } - - //The previous group is not the same as the new group to add to - if(!(gp != NULL && (!(strcmp(gp->name, gname))))){ - gp = groups_head; - while(gp != NULL){ - //gname matches groups[i]'s name, add entry here - if(!(strcmp(gp->name, gname))) break; - - last = gp; - gp = gp->next; - } - } - - //was unable to find a matching existing group - //need to create new group to insert the entry into - if(gp == NULL){ - new = create_group(gname); - - //first group - if(last == NULL) groups_head = new; - - //add to the end of the groups - else last->next = new; - - gp = new; - } - - //add the entry to the list of entries in the group - if(addme != NULL){ - i = entry_add(gp->head, gp->tail, addme); - switch(i){ - case 1: - gp->head = addme; - break; - - case 2: - gp->tail = addme; - break; - - case 3: - gp->head = addme; - gp->tail = addme; - break; - - } - - gp->entry_count++; - total_count++; - } - - return; -} - -void group_rm(GROUP *g){ - - clear_entries(g->head); - - free(g); - group_count--; - return; -} - -void clean_groups(){ - GROUP *dummy_head; - GROUP *trav; - GROUP *hold; - - if(group_count == 0){ - printf("Error: no groups! "); - refer_to_doc(); - exit(0); - } - - else{ - dummy_head = create_group("dummy"); - dummy_head->next = groups_head; - trav = dummy_head; - - while(trav != NULL){ - //found empty group for removal - if(trav->next != NULL && trav->next->entry_count < 1){ - printf("Omitting empty group \"%s\"\n", trav->next->name); - hold = trav->next; - trav->next = trav->next->next; - group_rm(hold); - } - else trav = trav->next; - } - } - - //ensure groups->head is still correct - groups_head = dummy_head->next; - group_rm(dummy_head); - return; - -} - - -GROUP **get_groups(){ - GROUP **arr = malloc(sizeof(GROUP *) * group_count); - GROUP *trav = groups_head; - int i; - - for(i = 0; i < group_count; i++){ - arr[i] = trav; - trav = trav->next; - } - - return arr; -} - char *get_gname(GROUP *g){ assert(g != NULL); return g->name; @@ -199,9 +60,14 @@ void set_gflags(GROUP *g, char *p){ strcpy(g->flags, p); } -ENTRY *get_ghead(GROUP *g){ +ENTRY **get_gentries(GROUP *g) { + assert(g != NULL); + return g->entries; +} + +void set_gentry(GROUP *g, int entry_index, ENTRY *new_entry) { assert(g != NULL); - return g->head; + g->entries[entry_index] = new_entry; } int get_ecount(GROUP *g){ @@ -214,19 +80,7 @@ void set_ecount(GROUP *g, int new_count){ g->entry_count = new_count; } -void set_gquotes(GROUP *g, bool b){ - assert(g != NULL); - g->launcher_quotes = b; -} - -bool get_gquotes(GROUP *g){ - return g->launcher_quotes; -} - -int get_gcount(){ - return group_count; -} - +/* void group_debug(){ GROUP *trav = groups_head; @@ -238,3 +92,4 @@ void group_debug(){ return; } +*/ diff --git a/src/include/entry.h b/src/include/entry.h index 51e43ca..a46dc46 100644 --- a/src/include/entry.h +++ b/src/include/entry.h @@ -1,17 +1,11 @@ +#include + #ifndef ENTRY_H #define ENTRY_H typedef struct entry ENTRY; -ENTRY *create_entry(char *new_name, char *new_path, bool force); - -void entry_rm(ENTRY *e, ENTRY *prev); - -void clear_entries(ENTRY *head); - -int entry_add(ENTRY *head, ENTRY *tail, ENTRY *add); - -ENTRY **get_entries(ENTRY *head, int count); +ENTRY *create_entry(const char *new_name, const char *new_path, const bool force); char *get_ename(ENTRY *e); @@ -19,10 +13,4 @@ char *get_epath(ENTRY *e); bool get_eforce(ENTRY *e); -void set_hide(ENTRY *e, bool status); - -bool get_hide(ENTRY *e); - -void entry_debug(ENTRY *trav); - #endif diff --git a/src/include/group.h b/src/include/group.h index ab6f409..dc74bcc 100644 --- a/src/include/group.h +++ b/src/include/group.h @@ -1,17 +1,13 @@ #ifndef GROUP_H #define GROUP_H -typedef struct group GROUP; - -GROUP *create_group(char *new_name); - -void group_add(char *gname, ENTRY *addme); +#include -void group_rm(GROUP *g); +#include "entry.h" -void clean_groups(); //remove empty groups from linked list +typedef struct group GROUP; -GROUP **get_groups(); +GROUP *create_group(const char *new_name, const int entry_count); char *get_gname(GROUP *g); @@ -23,18 +19,12 @@ char *get_gflags(GROUP *g); void set_gflags(GROUP *g, char *p); -ENTRY *get_ghead(GROUP *g); +ENTRY **get_gentries(GROUP *g); + +void set_gentry(GROUP *g, int entry_index, ENTRY *new_entry); int get_ecount(GROUP *g); void set_ecount(GROUP *g, int new_count); //for use in hiding entries -void set_gquotes(GROUP *g, bool b); - -bool get_gquotes(GROUP *g); - -int get_gcount(); - -void group_debug(); //debug function to output all groups - #endif diff --git a/src/include/read_cfg.h b/src/include/read_cfg.h index a76e55e..fc40cc0 100644 --- a/src/include/read_cfg.h +++ b/src/include/read_cfg.h @@ -3,23 +3,24 @@ #include +#include "group.h" + #define BUF_LEN 1024 -bool cfg_interp(char *path); +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); +//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; char *find_config(); void mkconfig_wizard(char *path); -void handle_fname(char *path, char *group, bool recurs, bool force, char *name, int ln); #endif diff --git a/src/read_cfg.c b/src/read_cfg.c index a931a11..b9ac8bc 100644 --- a/src/read_cfg.c +++ b/src/read_cfg.c @@ -22,9 +22,11 @@ #define OPTION_CNT 14 //private -void check_line(char *buffer, char **options, int ln); -int check_option(char *arg, char **options); -char *autoAlias(char *path); +//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 +void add_groups(lua_State *L, int table_stack_index, GROUP ***g); +void add_entries(lua_State *L, int table_stack_index, GROUP *g); //turn on or off sorting (A-Z); On by default bool sort = true; @@ -36,21 +38,20 @@ bool hr = false; bool fold_case = true; //return false if invalid path -bool cfg_interp(char *path){ +GROUP **cfg_interp(char *path, int *group_count){ FILE *fp; char buffer[BUF_LEN]; GROUP **g; - ENTRY **e; - int count; - int e_count; - int i=0; + const char *group_name; + //ENTRY **e; + int i; int j; // check if file path exists fp = fopen(path, "r"); if(fp == NULL){ printf("Error: Invalid Configuration Path \"%s\"\n", path); - return false; + return NULL; } fclose(fp); @@ -61,7 +62,7 @@ bool cfg_interp(char *path){ if(config_load_status != 0) { printf("Error: could not load configuration \"%s\"\n", path); lua_error(L); - return false; + exit(1); } // set up base configuration variables @@ -75,95 +76,17 @@ bool cfg_interp(char *path){ i = lua_gettop(L); if(lua_type(L, i) != LUA_TTABLE) { printf("Error in config: 'Groups' should be Table, is actually %s\n", lua_typename(L, lua_type(L, i))); - return 1; - } - // add each group - const char *group_name; - lua_pushnil(L); - while(lua_next(L, i)) { - // the key is index -2, value is -1 - if(lua_type(L, -2) != LUA_TSTRING) continue; // skip if invalid key - group_name = lua_tostring(L, -2); - group_add(group_name, NULL); - // check for a launcher - if(lua_type(L, -1) != LUA_TTABLE) continue; // skip if invalid value - lua_pushstring(L, "Launcher"); - lua_gettable(L, -2); - if(lua_type(L, -1) == LUA_TSTRING) { - // FIXME the groups '''API''' I built might need some improvements in order for this to not be a headache - //set_gprog(GROUP *g, lua_tostring(L, -1)) - } - lua_pop(L, 1); - // add each entry - lua_pushstring(L, "Entries"); - lua_gettable(L, -2); - j = lua_gettop(L); - lua_pushnil(L); - while(lua_next(L, j)) { - if(lua_type(L, -1) != LUA_TSTRING) continue; // skip if invalid value - handle_fname(lua_tostring(L, -1), group_name, false, true, NULL, -1); - lua_pop(L, 1); - } - lua_pop(L, 2); + exit(1); } - //lua_getfield(L, -1, "Pictures"); - //lua_getfield(L, -1, "Entries"); - //lua_rawgeti(L, -1, 1); - //printf("message: %d\n", (int)lua_tonumber(L, -1)); - //lua_rawgeti(L, -2, 2); - //printf("message: %d\n", (int)lua_tonumber(L, -1)); - //lua_rawgeti(L, -3, 3); - //printf("message: %d\n", (int)lua_tonumber(L, -1)); + // create the group array + *group_count = key_count(L, i); + g = malloc(sizeof(GROUP *) * (*group_count)); + // add each group (which also adds each entry to each group) + add_groups(L, i, &g); lua_close(L); - return true; - - /* --- Old code --- */ - //build the options array - char **options = malloc(sizeof(char *) * OPTION_CNT); - options[0] = "add"; - options[1] = "addF"; - options[2] = "addGroup"; - options[3] = "addName"; - options[4] = "addNameF"; - options[5] = "addR"; - options[6] = "autoAlias"; - options[7] = "foldCase"; - options[8] = "hide"; - options[9] = "hideFile"; - options[10] = "setFlags"; - options[11] = "setLauncher"; - options[12] = "setLauncherRaw"; - options[13] = "sort"; - - //Read each line of "config" - while(fgets(buffer, BUF_LEN, fp)){ - printf("%d\n", i); - i++; - check_line(buffer, options, i); - } - - //cleanup - free(options); - - /* - //DEBUG: test to see if the list was added to properly - g = get_groups(); - count = get_gcount(); - for(i = 0; i < count; i++){ - printf("Looking at group %s\n", get_gname(g[i])); - e_count = get_ecount(g[i]); - e = get_entries(get_ghead(g[i]), e_count); - for(j = 0; j < e_count; j++){ - printf("\t%s\n", get_ename(e[j])); - } - } - //END DEBUG - */ - - fclose(fp); - return true; + return g; } bool get_sort(){ @@ -179,409 +102,71 @@ void refer_to_doc(){ return; } -void addme(char *path, char *group, bool force, char *name){ - ENTRY *new; - char auto_name[BUF_LEN]; - - //check if a name was given as argument - if(name != NULL){ - //strip quotes from the name - name = strip_quotes(name); - new = create_entry(name, path, force); - } - - //check if autoAlias is on. If it is, go to the autoAlias function - else if(hr){ - strcpy(auto_name, autoAlias(path)); - new = create_entry(auto_name, path, force); - } - - else new = create_entry(path, path, force); - if(new != NULL) group_add(group, new); - - return; -} - -int search_ch(char *str, char c){ - int i = 0; - - while(str[i] != '\0'){ - if(str[i] == c) return i; - i++; - } - - return -1; -} - -int search_last_ch(char *str, char c){ - int i = 0; - int last_i = -1; +int key_count(lua_State *L, int table_stack_index) { + int output = 0; - while(str[i] != '\0'){ - if(str[i] == c) last_i = i; - i++; + 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); } - return last_i; + return output; } -//return 0 if match, 1 if not -//TODO only supports one wildcard per entry -int wild_cmp(char *wild, char *literal){ +void add_groups(lua_State *L, int table_stack_index, GROUP ***g) { + const char *group_name; + int entry_table_stack_index; int i; - - while(*wild != '\0'){ - //traverse until wildcard - if(*wild != '*'){ - if(*wild != *literal) return 1; - wild++; - literal++; - } - - //found wildcard, find the end of both names and comapre from the back - else{ - i = 0; - wild++; - while(*wild != '\0'){ - i++; - wild++; - } - while(*literal != '\0'){ - literal++; - } - - while(i > 0){ - wild--; - literal--; - if(*wild != *literal) return 1; - i--; - } - - return 0; - } - } - - return 0; -} - - -char *strip_quotes(char *str){ - char *stripped_str = malloc(sizeof(char) * BUF_LEN); - - if(str[0] == '"'){ - stripped_str = &str[1]; - stripped_str[strlen(stripped_str) - 1] = '\0'; - return stripped_str; - } - - return str; -} - -void error_mes(int ln, char *message){ - - assert(message != NULL); - - printf("Configuration File Error:\nOn line %d: %s\n\n", ln, message); - - return; -} - -//TODO add support for "addR" recursive adding (still needs work...) -//TODO add support for "alias" option -//TODO add support for "hide" option -void check_line(char *buffer, char **options, int ln){ - char *delims = " \t\n"; - char *tok = strtok(buffer, delims); - char args[MAX_ARGS][BUF_LEN]; - GROUP **g; - ENTRY **e; - char *tok_p; - char *arg_p; - int g_count; - int e_count; - int search_res; - int i, j; - char *error_p; //helper for complex error messages - - //ensure line is not blank or commented out - if(tok != NULL && tok[0] != '#' && tok[0] != '\0'){ - //initialize args to 0 - for(i = 0; i < MAX_ARGS; i++){ - args[i][0] = '\0'; - } - - i = 0; - //record all arguments in the line - while(tok != NULL){ - if(i >= MAX_ARGS){ - error_mes(ln, "Too many arguments"); - return; - } - strcpy(args[i], tok); - //handle if an argument has spaces and is wrapped in quotes - if(tok[0] == '"'){ - arg_p = &args[i][0]; - tok_p = &tok[1]; - - while(*tok_p != '"'){ - switch(*tok_p){ - - - case '\0': - tok = strtok(NULL, delims); - tok_p = &tok[0]; - *arg_p = ' '; - arg_p++; - break; - case '\\': - tok_p++; - - default: - *arg_p = *tok_p; - tok_p++; - arg_p++; - - } + lua_pushnil(L); + i = 0; + while(lua_next(L, table_stack_index)) { + // uses 'key' (at index -2) and 'value' (at index -1) + // looking at Groups.TABLE_NAME + if(lua_type(L, -2) == LUA_TSTRING && lua_type(L, -1) == LUA_TTABLE) { + group_name = lua_tostring(L, -2); + 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); } - - *arg_p = '\0'; - + (*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]); } - - tok = strtok(NULL, delims); - i++; - } - - //optimally check which option was specified - search_res = check_option(args[0], options); - - switch(search_res){ - - case 0: //add - //add entry(ies) to a group: first arg is the file(s), second arg is the group to add to - //TODO add sorting functionality - handle_fname(args[1], args[2], 0, 0, NULL, ln); - break; - - case 1: //addF - //force add entry to a group: first arg is the file(s), second arg is the group to add to - handle_fname(args[1], args[2], 0, 1, NULL, ln); - break; - - case 2: //addGroup - //create a new group - group_add(strip_quotes(args[1]), NULL); - break; - - case 3: //addName - //add entry to a group: first arg is the name, second arg is the file, and third arg is the group to add to - handle_fname(args[2], args[3], 0, 0, args[1], ln); - break; - - case 4: //addNameF - //same as addName, but with force on - handle_fname(args[2], args[3], 0, 1, args[1], ln); - break; - - case 5: //addR - //recursively add: that is, also search directories in the given path - //NOTE: experimental - handle_fname(args[1], args[2], 1, 0, NULL, ln); - break; - - case 6: //autoAlias - if(!(strcmp(args[1], "on"))) hr = true; - else if(!(strcmp(args[1], "off"))) hr = false; - break; - - case 7: //foldCase (case insensitive) - if(!(strcmp(args[1], "on"))) fold_case = true; - else if(!(strcmp(args[1], "off"))) fold_case = false; - break; - - //TODO consider having this call handle_fname instead so that '*' can be used - case 8: //hide - case 9: //hideFile - //args[2] is referring to a group - g = get_groups(); - g_count = get_gcount(); - - //look for matching existing group - for(i = 0; i < g_count; i++){ - if(!(strcmp(get_gname(g[i]), args[2]))) break; - } - - if(i < g_count){ - e_count = get_ecount(g[i]); - e = get_entries(get_ghead(g[i]), e_count); - - for(j = 0; j < e_count; j++){ - if(!strcmp((search_res == 8 ? get_ename(e[j]) : get_epath(e[j])), strip_quotes(args[1]))) break; - } - - if(j < e_count){ - set_hide(e[j], true); - set_ecount(g[i], get_ecount(g[i])-1); - } - else{ - error_p = malloc(sizeof(char) * 1024); - sprintf(error_p, "Entry \"%s\" does not exist", args[1]); - error_mes(ln, error_p); - free(error_p); - } - } - - else{ - error_p = malloc(sizeof(char) * 1024); - sprintf(error_p, "Group \"%s\" does not exist", args[2]); - error_mes(ln, error_p); - free(error_p); - } - break; - - case 10: //setFlags - //args[1] is referring to a group - g = get_groups(); - g_count = get_gcount(); - - //look for matching existing group - for(i = 0; i < g_count; i++){ - if(!(strcmp(get_gname(g[i]), args[1]))) break; - } - - //set a group's launcher flags (like ./program -f file for fullscreen) - //assert that a matching group was found - if(i < g_count) set_gflags(g[i], strip_quotes(args[2])); - else{ - error_p = malloc(sizeof(char) * 1024); - sprintf(error_p, "Group \"%s\" does not exist", args[1]); - error_mes(ln, error_p); - free(error_p); - } - break; - - case 11: //setLauncher - case 12: //setLauncherRaw - //args[1] is referring to a group - g = get_groups(); - g_count = get_gcount(); - - //look for matching existing group - for(i = 0; i < g_count; i++){ - if(!(strcmp(get_gname(g[i]), args[1]))) break; - } - - //set a group's launcher (this requires pulling down the existing groups and finding the one that args[1] mentions) - //assert that a matching group was found - if(i < g_count){ - set_gprog(g[i], strip_quotes(args[2])); - if(search_res == 12) set_gquotes(g[i], false); //FIXME don't forget to change this line if adding more options!!! - } - else{ - error_p = malloc(sizeof(char) * 1024); - sprintf(error_p, "Group \"%s\" does not exist", args[1]); - error_mes(ln, error_p); - free(error_p); - } - break; - - case 13: //sort - if(!(strcmp(args[1], "on"))) sort = true; - else if(!(strcmp(args[1], "off"))) sort = false; - break; - - default: - error_p = malloc(sizeof(char) * 1024); - sprintf(error_p, "Unknown config option \"%s\"", args[0]); - error_mes(ln, error_p); - free(error_p); - } - - } - - return; -} - -int check_option(char *arg, char **options){ - int min = 0; - int max = OPTION_CNT-1; - int hover; - int comp_res; - - while(max - min > 1){ - hover = min + (max-min)/2; - comp_res = strcmp(arg, options[hover]); - - if(comp_res > 0) min = hover; - else if(comp_res < 0) max = hover; - else return hover; + lua_pop(L, 1); + ++i; } - - if(max == OPTION_CNT-1 && strcmp(arg, options[max]) == 0) return max; - else if(min == 0 && strcmp(arg, options[min]) == 0) return min; - - return -1; } +void add_entries(lua_State *L, int table_stack_index, GROUP *g) { + const char *entry_name; + int i; -char *autoAlias(char *path){ - char *hr_name = malloc(sizeof(char) * BUF_LEN); - char *p = hr_name; - char *rpath; //necessary so as not to touch the actual path - char *last_dot = NULL; //used to trim the file extension (if there is one) - bool stop = false; //stop when you don't want to add a series of chars to the output - - //get to the relative path name - rpath = strrchr(path, sep); - if(rpath == NULL) rpath = path; - else rpath++; - - while(*rpath != '\0'){ - switch(*rpath){ - case '(': - stop = true; - break; - - case ')': - stop = false; - break; - - case '-': - case '_': - if(*(p-1) != ' ' && !stop){ - *p = ' '; - *p++; - } - break; - - case ' ': - if(*(p-1) != ' ' && !stop){ - *p = *rpath; - *p++; - } - break; - - case '.': - last_dot = p; - - default: - if(!stop){ - *p = *rpath; - *p++; - } + lua_pushnil(L); + i = 0; + while(lua_next(L, table_stack_index)) { + // uses 'key' (at index -2) and 'value' (at index -1) + // looking at Groups.TABLE_NAME.Entries[i] + if(lua_type(L, -1) == LUA_TSTRING) { + entry_name = lua_tostring(L, -1); + if(entry_name != NULL) { + set_gentry(g, i, create_entry(entry_name, entry_name, true)); + } } - *rpath++; + lua_pop(L, 1); + ++i; } - - //close the name - if(last_dot != NULL) *last_dot = '\0'; - else if(*path == '"') *(p-1) = '\0'; //close early to avoid including closing quote - else *p = '\0'; - return hr_name; + // one last pop to pop the key off + lua_pop(L, 1); } - - - diff --git a/src/unix/read_cfg.c b/src/unix/read_cfg.c index 4e58863..6f75ddc 100644 --- a/src/unix/read_cfg.c +++ b/src/unix/read_cfg.c @@ -137,97 +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); - - //check if path is a file (and not a directory/symlink/etc.) and regex matches - if(fname->d_type == DT_REG && !(wild_cmp(&arg_cpy[i+1], fname->d_name))) addme(relative_path_cpy, group, force, name); - - //if the recursive option was specified and the path is a directory, run handle_fname on this directory, but for security reasons, do not consider directories that start with a '.' - else if(recurs && fname->d_type == DT_DIR && 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{ - 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 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(-) (limited to 'src') 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 From f00cf908fdcdff676e95e563b2a93e2d4af05bc7 Mon Sep 17 00:00:00 2001 From: Louie Shprung Date: Wed, 14 Aug 2024 14:16:54 -0400 Subject: Compile on Windows --- src/windows/draw.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/windows/draw.c b/src/windows/draw.c index 3b06b9f..cbc565f 100644 --- a/src/windows/draw.c +++ b/src/windows/draw.c @@ -6,10 +6,10 @@ #include "../include/group.h" void launch(){ + ENTRY **e = 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]]); - bool quotes = get_gquotes(g[g_hover]); char file[BUF_LEN]; char params[BUF_LEN]; @@ -24,9 +24,7 @@ void launch(){ } else{ - if(quotes) strcat(file, "\""); strcat(file, program); - if(quotes) strcat(file, "\""); params[0] = '\0'; if(flags[0] != '\0'){ -- cgit From 243853cd1692c56cae8642dd6bb35c3c75ff54f7 Mon Sep 17 00:00:00 2001 From: Louie Shprung Date: Wed, 14 Aug 2024 16:32:54 -0400 Subject: Working support for setting launcher --- src/group.c | 2 +- src/include/group.h | 2 +- src/read_cfg.c | 14 ++++++++++++-- 3 files changed, 14 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/group.c b/src/group.c index 1d1ebd2..e5c3373 100644 --- a/src/group.c +++ b/src/group.c @@ -44,7 +44,7 @@ char *get_gprog(GROUP *g){ return g->program; } -void set_gprog(GROUP *g, char *p){ +void set_gprog(GROUP *g, const char *p){ assert(g != NULL); strcpy(g->program, p); return; diff --git a/src/include/group.h b/src/include/group.h index 89a8422..751b629 100644 --- a/src/include/group.h +++ b/src/include/group.h @@ -13,7 +13,7 @@ char *get_gname(GROUP *g); char *get_gprog(GROUP *g); -void set_gprog(GROUP *g, char *p); +void set_gprog(GROUP *g, const char *p); char *get_gflags(GROUP *g); diff --git a/src/read_cfg.c b/src/read_cfg.c index 97a76ff..d9491bb 100644 --- a/src/read_cfg.c +++ b/src/read_cfg.c @@ -147,7 +147,8 @@ int get_entry_count(lua_State *L, int table_stack_index) { void add_groups(lua_State *L, int table_stack_index, GROUP ***g) { const char *group_name; - int entry_table_stack_index; + int group_table_index; // index of Groups.TABLE_NAME + int entry_table_stack_index; // index of Groups.TABLE_NAME.Entries int entry_count; int i; @@ -158,12 +159,13 @@ void add_groups(lua_State *L, int table_stack_index, GROUP ***g) { // looking at Groups.TABLE_NAME if(lua_type(L, -2) == LUA_TSTRING && lua_type(L, -1) == LUA_TTABLE) { group_name = lua_tostring(L, -2); + group_table_index = lua_gettop(L); 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); + lua_gettable(L, group_table_index); entry_table_stack_index = lua_gettop(L); // check that 'Entries' is a table @@ -182,6 +184,14 @@ void add_groups(lua_State *L, int table_stack_index, GROUP ***g) { // add entries to this group add_entries(L, entry_table_stack_index, (*g)[i]); } + + // set the launcher, if applicable + lua_pushstring(L, "Launcher"); + lua_gettable(L, group_table_index); + printf("Found launcher: %s\n", lua_tostring(L, -1)); + if(lua_type(L, -1) == LUA_TSTRING) { + set_gprog((*g)[i], lua_tostring(L, -1)); + } } } // pop the top of the stack down to the key of the group -- cgit From 9adae33d5ffa4a72771266ba127f9ccc9b4b5221 Mon Sep 17 00:00:00 2001 From: Louie Shprung Date: Wed, 14 Aug 2024 16:51:06 -0400 Subject: Working support for setting launcher flags --- src/group.c | 2 +- src/include/group.h | 2 +- src/read_cfg.c | 8 +++++++- 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/group.c b/src/group.c index e5c3373..95d8605 100644 --- a/src/group.c +++ b/src/group.c @@ -55,7 +55,7 @@ char *get_gflags(GROUP *g){ return g->flags; } -void set_gflags(GROUP *g, char *p){ +void set_gflags(GROUP *g, const char *p){ assert(g != NULL); strcpy(g->flags, p); } diff --git a/src/include/group.h b/src/include/group.h index 751b629..bad33a5 100644 --- a/src/include/group.h +++ b/src/include/group.h @@ -17,7 +17,7 @@ void set_gprog(GROUP *g, const char *p); char *get_gflags(GROUP *g); -void set_gflags(GROUP *g, char *p); +void set_gflags(GROUP *g, const char *p); ENTRY **get_gentries(GROUP *g); diff --git a/src/read_cfg.c b/src/read_cfg.c index d9491bb..05146aa 100644 --- a/src/read_cfg.c +++ b/src/read_cfg.c @@ -188,10 +188,16 @@ void add_groups(lua_State *L, int table_stack_index, GROUP ***g) { // set the launcher, if applicable lua_pushstring(L, "Launcher"); lua_gettable(L, group_table_index); - printf("Found launcher: %s\n", lua_tostring(L, -1)); if(lua_type(L, -1) == LUA_TSTRING) { set_gprog((*g)[i], lua_tostring(L, -1)); } + + // set the launcher flags, if applicable + lua_pushstring(L, "Flags"); + lua_gettable(L, group_table_index); + if(lua_type(L, -1) == LUA_TSTRING) { + set_gflags((*g)[i], lua_tostring(L, -1)); + } } } // pop the top of the stack down to the key of the group -- cgit From 002e6c5aac88cc931b838884f9ad21348f2f5641 Mon Sep 17 00:00:00 2001 From: Louie Shprung Date: Fri, 16 Aug 2024 16:39:39 -0400 Subject: Fix potential group allocation index incrementation issue --- src/draw.c | 2 +- src/read_cfg.c | 40 ++++++++++++++++++++++------------------ 2 files changed, 23 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/draw.c b/src/draw.c index 99b1a74..91476e3 100644 --- a/src/draw.c +++ b/src/draw.c @@ -214,7 +214,7 @@ bool *handle_args(int argc, char **argv, char **cfg_path){ {"version", no_argument, NULL, 'v'}, {0, 0, 0, 0} }; - bool *flags_set = calloc(FLAG_COUNT, sizeof(bool)); + bool *flags_set = calloc(FLAG_COUNT+1, sizeof(bool)); int i = 0; while(opt != -1){ diff --git a/src/read_cfg.c b/src/read_cfg.c index 05146aa..a6c20a7 100644 --- a/src/read_cfg.c +++ b/src/read_cfg.c @@ -83,10 +83,13 @@ GROUP **cfg_interp(char *path, int *group_count){ // create the group array *group_count = get_group_count(L, i); - g = malloc(sizeof(GROUP *) * (*group_count)); + if(*group_count <= 0) g = NULL; + else { + g = malloc(sizeof(GROUP *) * (*group_count)); - // add each group (which also adds each entry to each group) - add_groups(L, i, &g); + // add each group (which also adds each entry to each group) + add_groups(L, i, &g); + } lua_close(L); return g; } @@ -170,7 +173,7 @@ void add_groups(lua_State *L, int table_stack_index, GROUP ***g) { // 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))); + printf("Error in config: in group '%s': 'Entries' should be Table, is actually %s\n", group_name, lua_typename(L, lua_type(L, entry_table_stack_index))); exit(1); } @@ -183,26 +186,27 @@ void add_groups(lua_State *L, int table_stack_index, GROUP ***g) { (*g)[i] = create_group(group_name, entry_count); // add entries to this group add_entries(L, entry_table_stack_index, (*g)[i]); - } - // set the launcher, if applicable - lua_pushstring(L, "Launcher"); - lua_gettable(L, group_table_index); - if(lua_type(L, -1) == LUA_TSTRING) { - set_gprog((*g)[i], lua_tostring(L, -1)); - } - - // set the launcher flags, if applicable - lua_pushstring(L, "Flags"); - lua_gettable(L, group_table_index); - if(lua_type(L, -1) == LUA_TSTRING) { - set_gflags((*g)[i], lua_tostring(L, -1)); + // set the launcher, if applicable + lua_pushstring(L, "Launcher"); + lua_gettable(L, group_table_index); + if(lua_type(L, -1) == LUA_TSTRING) { + set_gprog((*g)[i], lua_tostring(L, -1)); + } + + // set the launcher flags, if applicable + lua_pushstring(L, "Flags"); + lua_gettable(L, group_table_index); + if(lua_type(L, -1) == LUA_TSTRING) { + set_gflags((*g)[i], lua_tostring(L, -1)); + } + + ++i; } } } // pop the top of the stack down to the key of the group lua_pop(L, lua_gettop(L)-table_stack_index-1); - ++i; } } -- cgit From 9c330fafe8ce65acbb0980d3e51af3696135099d Mon Sep 17 00:00:00 2001 From: Louie Shprung Date: Fri, 16 Aug 2024 17:22:37 -0400 Subject: Sorting working for entries --- src/read_cfg.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/read_cfg.c b/src/read_cfg.c index a6c20a7..b084b2c 100644 --- a/src/read_cfg.c +++ b/src/read_cfg.c @@ -24,6 +24,7 @@ //private //void check_line(char *buffer, char **options, int ln); //int check_option(char *arg, char **options); +void get_settings(lua_State *L, int table_stack_index); // gets settings from Settings global variable 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); @@ -31,6 +32,7 @@ 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 +// TODO allow specifying whether to sort groups or entries (or both, or none) bool sort = true; //set to true to automatically try to create a human readable name for an entry @@ -73,7 +75,15 @@ GROUP **cfg_interp(char *path, int *group_count){ //lua_setglobal(L, "Groups"); //lua_pcall(L, 0, 0, 0); - // demo + // open Settings table + lua_getglobal(L, "Settings"); + i = lua_gettop(L); + if(lua_type(L, i) == LUA_TTABLE) { + // parse settings + get_settings(L, i); + } + + // open Groups table lua_getglobal(L, "Groups"); i = lua_gettop(L); if(lua_type(L, i) != LUA_TTABLE) { @@ -107,6 +117,34 @@ void refer_to_doc(){ return; } +void get_settings(lua_State *L, int table_stack_index) { + bool *setting_vars[] = { + &hr, + &fold_case, + &sort + }; + + char *setting_strings[] = { + "autoAlias", + "foldCase", + "sort" + }; + + int count = 3; + int i; + + // looking at table Settings + + // check if autoAlias is set + for(i = 0; i < count; ++i) { + lua_pushstring(L, setting_strings[i]); + lua_gettable(L, table_stack_index); + if(lua_type(L, -1) == LUA_TBOOLEAN) { + *(setting_vars[i]) = lua_toboolean(L, -1); + } + } +} + int get_group_count(lua_State *L, int table_stack_index) { int output = 0; int entry_table_stack_index; @@ -155,6 +193,11 @@ void add_groups(lua_State *L, int table_stack_index, GROUP ***g) { int entry_count; int i; + // sort the groups, if necessary + //if(sort) { + // luaL_dostring(L, "table.sort(Groups)"); + //} + lua_pushnil(L); i = 0; while(lua_next(L, table_stack_index)) { @@ -184,6 +227,13 @@ void add_groups(lua_State *L, int table_stack_index, GROUP ***g) { else { (*g)[i] = create_group(group_name, entry_count); + + // sort the entries if necessary + if(sort) { + lua_pushfstring(L, "table.sort(Groups['%s'].Entries)", group_name); + luaL_dostring(L, lua_tostring(L, -1)); + } + // add entries to this group add_entries(L, entry_table_stack_index, (*g)[i]); -- cgit From 70a15daa4367e072268f4302a68b6f73f6acf6c5 Mon Sep 17 00:00:00 2001 From: Louie Shprung Date: Fri, 16 Aug 2024 18:43:36 -0400 Subject: Support for sorting entries --- src/draw.c | 1 + src/read_cfg.c | 108 ++++++++++++++++++++++++++++++++------------------------- 2 files changed, 61 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/draw.c b/src/draw.c index 91476e3..53185cb 100644 --- a/src/draw.c +++ b/src/draw.c @@ -78,6 +78,7 @@ int main(int argc, char **argv){ //for(i = 0; i < g_count; ++i) { // group_debug(g[i]); //} + //return 0; /* //Remove Empty Groups from the Array diff --git a/src/read_cfg.c b/src/read_cfg.c index b084b2c..f29fe88 100644 --- a/src/read_cfg.c +++ b/src/read_cfg.c @@ -31,7 +31,7 @@ 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 +//turn on or off sorting for entries (A-Z); On by default // TODO allow specifying whether to sort groups or entries (or both, or none) bool sort = true; @@ -82,6 +82,7 @@ GROUP **cfg_interp(char *path, int *group_count){ // parse settings get_settings(L, i); } + lua_pop(L, lua_gettop(L)); // open Groups table lua_getglobal(L, "Groups"); @@ -93,7 +94,10 @@ GROUP **cfg_interp(char *path, int *group_count){ // create the group array *group_count = get_group_count(L, i); - if(*group_count <= 0) g = NULL; + if(*group_count <= 0) { + printf("Error: No Groups!\n"); + g = NULL; + } else { g = malloc(sizeof(GROUP *) * (*group_count)); @@ -146,30 +150,34 @@ void get_settings(lua_State *L, int table_stack_index) { } int get_group_count(lua_State *L, int table_stack_index) { + int i = 1; int output = 0; + int group_table_stack_index; 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 && lua_type(L, -1) == LUA_TTABLE) { + do { + lua_rawgeti(L, table_stack_index, i); + group_table_stack_index = lua_gettop(L); + if(lua_type(L, group_table_stack_index) == LUA_TTABLE) { // check validity of this group - group_name = lua_tostring(L, -2); + lua_pushstring(L, "name"); + lua_gettable(L, group_table_stack_index); + group_name = lua_tostring(L, -1); if(group_name != NULL) { // check that the Entries table for this group is not empty lua_pushstring(L, "Entries"); - lua_gettable(L, -2); + lua_gettable(L, group_table_stack_index); 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); - } + ++i; + } while(lua_type(L, group_table_stack_index) != LUA_TNIL); + lua_pop(L, lua_gettop(L)-table_stack_index-1); return output; } @@ -183,35 +191,38 @@ int get_entry_count(lua_State *L, int table_stack_index) { ++i; } while(lua_type(L, -1) != LUA_TNIL); + lua_pop(L, lua_gettop(L)-table_stack_index-1); return output; } void add_groups(lua_State *L, int table_stack_index, GROUP ***g) { const char *group_name; - int group_table_index; // index of Groups.TABLE_NAME + int group_table_stack_index; // index of Groups.TABLE_NAME int entry_table_stack_index; // index of Groups.TABLE_NAME.Entries int entry_count; - int i; + char sort_cmd_lua[BUF_LEN]; // used to store the lua call to table.sort + int i = 1; // index in lua table + int count = 0; // index in C struct // sort the groups, if necessary - //if(sort) { - // luaL_dostring(L, "table.sort(Groups)"); - //} - - lua_pushnil(L); - i = 0; - while(lua_next(L, table_stack_index)) { - // uses 'key' (at index -2) and 'value' (at index -1) - // looking at Groups.TABLE_NAME - if(lua_type(L, -2) == LUA_TSTRING && lua_type(L, -1) == LUA_TTABLE) { - group_name = lua_tostring(L, -2); - group_table_index = lua_gettop(L); + if(sort) { + luaL_dostring(L, "table.sort(Groups)"); + } + + do { + lua_rawgeti(L, table_stack_index, i); + group_table_stack_index = lua_gettop(L); + if(lua_type(L, group_table_stack_index) == LUA_TTABLE) { + // check validity of this group + lua_pushstring(L, "name"); + lua_gettable(L, group_table_stack_index); + group_name = lua_tostring(L, -1); 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, group_table_index); + // get table Groups[i].Entries + lua_gettable(L, group_table_stack_index); entry_table_stack_index = lua_gettop(L); // check that 'Entries' is a table @@ -226,58 +237,59 @@ void add_groups(lua_State *L, int table_stack_index, GROUP ***g) { printf("Skipping empty group '%s'\n", group_name); else { - (*g)[i] = create_group(group_name, entry_count); + (*g)[count] = create_group(group_name, entry_count); // sort the entries if necessary if(sort) { - lua_pushfstring(L, "table.sort(Groups['%s'].Entries)", group_name); - luaL_dostring(L, lua_tostring(L, -1)); + sprintf(sort_cmd_lua, "table.sort(Groups[%d].Entries)", i); + luaL_dostring(L, sort_cmd_lua); } // add entries to this group - add_entries(L, entry_table_stack_index, (*g)[i]); + add_entries(L, entry_table_stack_index, (*g)[count]); // set the launcher, if applicable lua_pushstring(L, "Launcher"); - lua_gettable(L, group_table_index); + lua_gettable(L, group_table_stack_index); if(lua_type(L, -1) == LUA_TSTRING) { - set_gprog((*g)[i], lua_tostring(L, -1)); + set_gprog((*g)[count], lua_tostring(L, -1)); } // set the launcher flags, if applicable lua_pushstring(L, "Flags"); - lua_gettable(L, group_table_index); + lua_gettable(L, group_table_stack_index); if(lua_type(L, -1) == LUA_TSTRING) { - set_gflags((*g)[i], lua_tostring(L, -1)); + set_gflags((*g)[count], lua_tostring(L, -1)); } - ++i; + ++count; } } } - // pop the top of the stack down to the key of the group - lua_pop(L, lua_gettop(L)-table_stack_index-1); - } + ++i; + } while(lua_type(L, group_table_stack_index) != LUA_TNIL); + + lua_pop(L, lua_gettop(L)-table_stack_index-1); } void add_entries(lua_State *L, int table_stack_index, GROUP *g) { const char *entry_name; - int i; + int i = 1; // index in lua table + int count = 0; // index in C struct - lua_pushnil(L); - i = 0; - while(lua_next(L, table_stack_index)) { - // uses 'key' (at index -2) and 'value' (at index -1) - // looking at Groups.TABLE_NAME.Entries[i] + do { + lua_rawgeti(L, table_stack_index, i); if(lua_type(L, -1) == LUA_TSTRING) { entry_name = lua_tostring(L, -1); if(entry_name != NULL) { - set_gentry(g, i, create_entry(entry_name, entry_name, true)); + set_gentry(g, count, create_entry(entry_name, entry_name, true)); + ++count; } } - lua_pop(L, 1); ++i; - } + } while(lua_type(L, -1) != LUA_TNIL); + + lua_pop(L, lua_gettop(L)-table_stack_index-1); } void stack_debug(lua_State *L) { -- cgit From 996d3097cfa00363f16ff972b6da347b65ead23f Mon Sep 17 00:00:00 2001 From: Louie Shprung Date: Sat, 17 Aug 2024 14:50:07 -0400 Subject: Remove foldcase and hr options --- src/draw.c | 2 +- src/include/read_cfg.h | 2 -- src/read_cfg.c | 20 +------------------- 3 files changed, 2 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/draw.c b/src/draw.c index 53185cb..4dd5d75 100644 --- a/src/draw.c +++ b/src/draw.c @@ -520,7 +520,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(); + bool fold_case = true; char first_char; int i; diff --git a/src/include/read_cfg.h b/src/include/read_cfg.h index 29a36e7..1337e32 100644 --- a/src/include/read_cfg.h +++ b/src/include/read_cfg.h @@ -8,8 +8,6 @@ #define BUF_LEN 1024 GROUP **cfg_interp(char *path, int *group_count); -bool get_sort(); -bool get_case_sensitivity(); void refer_to_doc(); //functions that differ by os diff --git a/src/read_cfg.c b/src/read_cfg.c index f29fe88..3b8d24a 100644 --- a/src/read_cfg.c +++ b/src/read_cfg.c @@ -35,12 +35,6 @@ void stack_debug(lua_State *L); // TODO allow specifying whether to sort groups or entries (or both, or none) bool sort = true; -//set to true to automatically try to create a human readable name for an entry -bool hr = false; - -//turn foldCase (insensitive case searching) on or off; On by default -bool fold_case = true; - //return false if invalid path GROUP **cfg_interp(char *path, int *group_count){ FILE *fp; @@ -108,14 +102,6 @@ GROUP **cfg_interp(char *path, int *group_count){ return g; } -bool get_sort(){ - return sort; -} - -bool get_case_sensitivity(){ - return fold_case; -} - void refer_to_doc(){ printf("Refer to documentation on how to create terminal-media-launcher config file\n"); return; @@ -123,18 +109,14 @@ void refer_to_doc(){ void get_settings(lua_State *L, int table_stack_index) { bool *setting_vars[] = { - &hr, - &fold_case, &sort }; char *setting_strings[] = { - "autoAlias", - "foldCase", "sort" }; - int count = 3; + int count = 1; int i; // looking at table Settings -- cgit From ca77091d63b3600b7a3829db8ae24c765c65440d Mon Sep 17 00:00:00 2001 From: Louie Shprung Date: Mon, 19 Aug 2024 20:44:56 -0400 Subject: Ability to set entry attributes --- src/read_cfg.c | 291 ++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 207 insertions(+), 84 deletions(-) (limited to 'src') diff --git a/src/read_cfg.c b/src/read_cfg.c index 3b8d24a..6c334ac 100644 --- a/src/read_cfg.c +++ b/src/read_cfg.c @@ -24,12 +24,13 @@ //private //void check_line(char *buffer, char **options, int ln); //int check_option(char *arg, char **options); -void get_settings(lua_State *L, int table_stack_index); // gets settings from Settings global variable -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 get_settings(lua_State *L); // gets settings from Settings global variable +int get_group_count(lua_State *L); // counts the number of valid groups +int get_entry_count(lua_State *L); // counts the number of valid entries for a group +void add_groups(lua_State *L, GROUP ***g); +void add_entries(lua_State *L, GROUP *g); void stack_debug(lua_State *L); +void table_debug(lua_State *L, int print_depth); //turn on or off sorting for entries (A-Z); On by default // TODO allow specifying whether to sort groups or entries (or both, or none) @@ -55,6 +56,7 @@ GROUP **cfg_interp(char *path, int *group_count){ // load lua configuration lua_State *L = luaL_newstate(); + // new lua stack luaL_openlibs(L); // allow for standard library to be used int config_load_status = luaL_dofile(L, path); if(config_load_status != 0) { @@ -71,23 +73,24 @@ GROUP **cfg_interp(char *path, int *group_count){ // open Settings table lua_getglobal(L, "Settings"); - i = lua_gettop(L); - if(lua_type(L, i) == LUA_TTABLE) { + // stack now contains: -1 => Settings + if(lua_type(L, -1) == LUA_TTABLE) { // parse settings - get_settings(L, i); + get_settings(L); } - lua_pop(L, lua_gettop(L)); + lua_pop(L, 1); + // empty stack // open Groups table lua_getglobal(L, "Groups"); - i = lua_gettop(L); - if(lua_type(L, i) != LUA_TTABLE) { - printf("Error in config: 'Groups' should be Table, is actually %s\n", lua_typename(L, lua_type(L, i))); + // stack now contains: -1 => Groups + if(lua_type(L, -1) != LUA_TTABLE) { + printf("Error in config: 'Groups' should be Table, is actually %s\n", lua_typename(L, lua_type(L, -1))); exit(1); } // create the group array - *group_count = get_group_count(L, i); + *group_count = get_group_count(L); if(*group_count <= 0) { printf("Error: No Groups!\n"); g = NULL; @@ -96,7 +99,7 @@ GROUP **cfg_interp(char *path, int *group_count){ g = malloc(sizeof(GROUP *) * (*group_count)); // add each group (which also adds each entry to each group) - add_groups(L, i, &g); + add_groups(L, &g); } lua_close(L); return g; @@ -107,7 +110,9 @@ void refer_to_doc(){ return; } -void get_settings(lua_State *L, int table_stack_index) { +void get_settings(lua_State *L) { + // stack now contains: -1 => table + bool *setting_vars[] = { &sort }; @@ -124,60 +129,87 @@ void get_settings(lua_State *L, int table_stack_index) { // check if autoAlias is set for(i = 0; i < count; ++i) { lua_pushstring(L, setting_strings[i]); - lua_gettable(L, table_stack_index); + // stack now contains: -1 => setting_string; -2 => table + lua_gettable(L, -2); + // stack now contains: -1 => string_value; -2 => table if(lua_type(L, -1) == LUA_TBOOLEAN) { *(setting_vars[i]) = lua_toboolean(L, -1); } + lua_pop(L, 1); + // stack now contains: -1 => table } } -int get_group_count(lua_State *L, int table_stack_index) { - int i = 1; +int get_group_count(lua_State *L) { int output = 0; - int group_table_stack_index; - int entry_table_stack_index; - const char *group_name; - do { - lua_rawgeti(L, table_stack_index, i); - group_table_stack_index = lua_gettop(L); - if(lua_type(L, group_table_stack_index) == LUA_TTABLE) { - // check validity of this group + // stack now contains: -1 => table + lua_pushnil(L); + // stack now contains: -1 => nil; -2 => table + while (lua_next(L, -2)) { + // stack now contains: -1 => value; -2 => key; -3 => table + // copy the key so that lua_tostring does not modify the original + lua_pushvalue(L, -2); + // stack now contains: -1 => key; -2 => value; -3 => key; -4 => table + if(lua_type(L, -1) == LUA_TNUMBER && lua_type(L, -2) == LUA_TTABLE) { lua_pushstring(L, "name"); - lua_gettable(L, group_table_stack_index); - group_name = lua_tostring(L, -1); - if(group_name != NULL) { + // stack now contains: -1 => "name"; -2 => key; -3 => value; -4 => key; -5 => table + lua_gettable(L, -3); + // stack now contains: -1 => name; -2 => key; -3 => value; -4 => key; -5 => table + if(lua_type(L, -1) == LUA_TSTRING) { // check that the Entries table for this group is not empty lua_pushstring(L, "Entries"); - lua_gettable(L, group_table_stack_index); - 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) + // stack now contains: -1 => "Entries"; -2 => name; -3 => key; -4 => value; -5 => key; -6 => table + lua_gettable(L, -4); + // stack now contains: -1 => Entries; -2 => name; -3 => key; -4 => value; -5 => key; -6 => table + if(lua_type(L, -1) == LUA_TTABLE && get_entry_count(L) > 0) ++output; + lua_pop(L, 1); + // stack now contains: -1 => name; -2 => key; -3 => value; -4 => key; -5 => table } + lua_pop(L, 1); + // stack now contains: -1 => key; -2 => value; -3 => key; -4 => table } - ++i; - } while(lua_type(L, group_table_stack_index) != LUA_TNIL); + lua_pop(L, 2); + // stack now contains: -1 => key; -2 => table + } + // stack now contains: -1 => table (when lua_next returns 0 it pops the key + // but does not push anything.) - 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 get_entry_count(lua_State *L) { 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); + // stack now contains: -1 => table + lua_pushnil(L); + // stack now contains: -1 => nil; -2 => table + while (lua_next(L, -2)) { + // stack now contains: -1 => value; -2 => key; -3 => table + // copy the key so that lua_tostring does not modify the original + lua_pushvalue(L, -2); + // stack now contains: -1 => key; -2 => value; -3 => key; -4 => table + if(lua_type(L, -1) == LUA_TNUMBER && lua_type(L, -2) == LUA_TTABLE) { + // check that the entry has a valid name + lua_pushstring(L, "name"); + // stack now contains: -1 => "name"; -2 => key; -3 => value; -4 => key; -5 => table + lua_gettable(L, -3); + // stack now contains: -1 => name; -2 => key; -3 => value; -4 => key; -5 => table + if(lua_type(L, -1) == LUA_TSTRING) ++output; + lua_pop(L, 1); + // stack now contains: -1 => key; -2 => value; -3 => key; -4 => table + } + lua_pop(L, 2); + // stack now contains: -1 => key; -2 => table + } + // stack now contains: -1 => table (when lua_next returns 0 it pops the key + // but does not push anything.) - lua_pop(L, lua_gettop(L)-table_stack_index-1); return output; } -void add_groups(lua_State *L, int table_stack_index, GROUP ***g) { +void add_groups(lua_State *L, GROUP ***g) { const char *group_name; int group_table_stack_index; // index of Groups.TABLE_NAME int entry_table_stack_index; // index of Groups.TABLE_NAME.Entries @@ -186,92 +218,136 @@ void add_groups(lua_State *L, int table_stack_index, GROUP ***g) { int i = 1; // index in lua table int count = 0; // index in C struct - // sort the groups, if necessary - if(sort) { - luaL_dostring(L, "table.sort(Groups)"); - } - - do { - lua_rawgeti(L, table_stack_index, i); - group_table_stack_index = lua_gettop(L); - if(lua_type(L, group_table_stack_index) == LUA_TTABLE) { - // check validity of this group + // stack now contains: -1 => table + lua_pushnil(L); + // stack now contains: -1 => nil; -2 => table + while (lua_next(L, -2)) { + // stack now contains: -1 => value; -2 => key; -3 => table + // copy the key so that lua_tostring does not modify the original + lua_pushvalue(L, -2); + // stack now contains: -1 => key; -2 => value; -3 => key; -4 => table + if(lua_type(L, -1) == LUA_TNUMBER && lua_type(L, -2) == LUA_TTABLE) { lua_pushstring(L, "name"); - lua_gettable(L, group_table_stack_index); + // stack now contains: -1 => "name"; -2 => key; -3 => value; -4 => key; -5 => table + lua_gettable(L, -3); + // stack now contains: -1 => name; -2 => key; -3 => value; -4 => key; -5 => table group_name = lua_tostring(L, -1); + lua_pop(L, 1); + // stack now contains: -1 => key; -2 => value; -3 => key; -4 => table if(group_name != NULL) { // push the Entries table on the stack (to get entry information) lua_pushstring(L, "Entries"); - - // get table Groups[i].Entries - lua_gettable(L, group_table_stack_index); - 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: in group '%s': 'Entries' should be Table, is actually %s\n", group_name, lua_typename(L, lua_type(L, entry_table_stack_index))); + // stack now contains: -1 => "Entries"; -2 => key; -3 => value; -4 => key; -5 => table + lua_gettable(L, -3); + // stack now contains: -1 => Entries; -2 => key; -3 => value; -4 => key; -5 => table + if(lua_type(L, -1) != LUA_TTABLE) { + printf("Error in config: in group '%s': 'Entries' should be Table, is actually %s\n", group_name, lua_typename(L, lua_type(L, -1))); exit(1); } - entry_count = get_entry_count(L, entry_table_stack_index); + entry_count = get_entry_count(L); + // check that the group has at least 1 entry - if(entry_count <= 0) + if(entry_count <= 0) { printf("Skipping empty group '%s'\n", group_name); - + lua_pop(L, 1); + // stack now contains: -1 => key; -2 => value; -3 => key; -4 => table + } else { (*g)[count] = create_group(group_name, entry_count); // sort the entries if necessary if(sort) { - sprintf(sort_cmd_lua, "table.sort(Groups[%d].Entries)", i); + sprintf(sort_cmd_lua, "table.sort(Groups[%d].Entries, function(a, b) return a.name < b.name end)", i); luaL_dostring(L, sort_cmd_lua); } // add entries to this group - add_entries(L, entry_table_stack_index, (*g)[count]); + add_entries(L, (*g)[count]); + lua_pop(L, 1); + // stack now contains: -1 => key; -2 => value; -3 => key; -4 => table // set the launcher, if applicable lua_pushstring(L, "Launcher"); - lua_gettable(L, group_table_stack_index); + // stack now contains: -1 => "Launcher"; -2 => key; -3 => value; -4 => key; -5 => table + lua_gettable(L, -3); + // stack now contains: -1 => Launcher; -2 => key; -3 => value; -4 => key; -5 => table if(lua_type(L, -1) == LUA_TSTRING) { set_gprog((*g)[count], lua_tostring(L, -1)); } + lua_pop(L, 1); + // stack now contains: -1 => key; -2 => value; -3 => key; -4 => table // set the launcher flags, if applicable lua_pushstring(L, "Flags"); - lua_gettable(L, group_table_stack_index); + // stack now contains: -1 => "Flags"; -2 => key; -3 => value; -4 => key; -5 => table + lua_gettable(L, -3); + // stack now contains: -1 => Flags; -2 => key; -3 => value; -4 => key; -5 => table if(lua_type(L, -1) == LUA_TSTRING) { set_gflags((*g)[count], lua_tostring(L, -1)); } + lua_pop(L, 1); + // stack now contains: -1 => key; -2 => value; -3 => key; -4 => table ++count; } } } + lua_pop(L, 2); + // stack now contains: -1 => key; -2 => table ++i; - } while(lua_type(L, group_table_stack_index) != LUA_TNIL); - - lua_pop(L, lua_gettop(L)-table_stack_index-1); + } + // stack now contains: -1 => table (when lua_next returns 0 it pops the key + // but does not push anything.) + // Pop table + lua_pop(L, 1); + // Stack is now the same as it was on entry to this function } -void add_entries(lua_State *L, int table_stack_index, GROUP *g) { +void add_entries(lua_State *L, GROUP *g) { const char *entry_name; + const char *entry_path; + int entry_table_stack_index; int i = 1; // index in lua table int count = 0; // index in C struct - do { - lua_rawgeti(L, table_stack_index, i); - if(lua_type(L, -1) == LUA_TSTRING) { + // stack now contains: -1 => table + lua_pushnil(L); + // stack now contains: -1 => nil; -2 => table + while (lua_next(L, -2)) { + // stack now contains: -1 => value; -2 => key; -3 => table + // copy the key so that lua_tostring does not modify the original + lua_pushvalue(L, -2); + // stack now contains: -1 => key; -2 => value; -3 => key; -4 => table + if(lua_type(L, -1) == LUA_TNUMBER && lua_type(L, -2) == LUA_TTABLE) { + // check that the entry has a valid name + lua_pushstring(L, "name"); + // stack now contains: -1 => "name"; -2 => key; -3 => value; -4 => key; -5 => table + lua_gettable(L, -3); + // stack now contains: -1 => name; -2 => key; -3 => value; -4 => key; -5 => table entry_name = lua_tostring(L, -1); + lua_pop(L, 1); + // stack now contains: -1 => key; -2 => value; -3 => key; -4 => table + if(entry_name != NULL) { - set_gentry(g, count, create_entry(entry_name, entry_name, true)); + // get this entry's path, if applicable + lua_pushstring(L, "path"); + // stack now contains: -1 => "path"; -2 => key; -3 => value; -4 => key; -5 => table + lua_gettable(L, -3); + // stack now contains: -1 => path; -2 => key; -3 => value; -4 => key; -5 => table + if(lua_type(L, -1) == LUA_TSTRING) entry_path = lua_tostring(L, -1); + else entry_path = entry_name; + lua_pop(L, 1); + // stack now contains: -1 => key; -2 => value; -3 => key; -4 => table + + set_gentry(g, count, create_entry(entry_name, entry_path, true)); ++count; } } - ++i; - } while(lua_type(L, -1) != LUA_TNIL); - - lua_pop(L, lua_gettop(L)-table_stack_index-1); + lua_pop(L, 2); + // stack now contains: -1 => key; -2 => table + } + // stack now contains: -1 => table (when lua_next returns 0 it pops the key } void stack_debug(lua_State *L) { @@ -279,6 +355,53 @@ void stack_debug(lua_State *L) { 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))); + printf("\t%d - %s", i, lua_typename(L, lua_type(L, i))); + + switch(lua_type(L, i)) { + case LUA_TSTRING: + printf(" - %s\n", lua_tostring(L, i)); + break; + + //case LUA_TTABLE: + // printf("\n"); + // table_debug(L, 2); + // break; + + default: + printf("\n"); + } + } +} + +// FIXME WIP debugging function +void table_debug(lua_State *L, int print_depth) { + int i; + + // stack now contains: -1 => table + lua_pushnil(L); + // stack now contains: -1 => nil; -2 => table + while (lua_next(L, -2)) { + // stack now contains: -1 => value; -2 => key; -3 => table + // copy the key so that lua_tostring does not modify the original + lua_pushvalue(L, -2); + // stack now contains: -1 => key; -2 => value; -3 => key; -4 => table + const char *key = lua_tostring(L, -1); + const char *value = lua_typename(L, lua_type(L, -2)); + for(i = 0; i < print_depth; ++i) { + printf("\t"); + } + printf("%s => %s", key, value); + if(lua_type(L, -2) == LUA_TSTRING) { + printf(" - %s", lua_tostring(L, -2)); + } + printf("\n"); + // pop value + copy of key, leaving original key + lua_pop(L, 2); + // stack now contains: -1 => key; -2 => table } + // stack now contains: -1 => table (when lua_next returns 0 it pops the key + // but does not push anything.) + // Pop table + lua_pop(L, 1); + // Stack is now the same as it was on entry to this function } -- cgit From c53c16b6e606e16c7db492d05a8ed56574aaf3f9 Mon Sep 17 00:00:00 2001 From: Louie Shprung Date: Fri, 30 Aug 2024 14:31:39 -0400 Subject: Update default configurations --- src/unix/read_cfg.c | 110 +++++++++++++++++++++++++++---------------------- src/windows/read_cfg.c | 107 ++++++++++++++++++++++++++--------------------- 2 files changed, 120 insertions(+), 97 deletions(-) (limited to 'src') diff --git a/src/unix/read_cfg.c b/src/unix/read_cfg.c index 6f75ddc..602c750 100644 --- a/src/unix/read_cfg.c +++ b/src/unix/read_cfg.c @@ -78,56 +78,66 @@ void mkconfig_wizard(char *path){ exit(1); } - //write to file - fprintf(fp, "# This file was auto-generated by terminal-media-launcher. See docs/terminal-media-launcher-config.md or terminal-media-launcher-config(5) for documentation\n" - "# The default launcher is set to \"xdg-open\" which will open files based on the relevant default application set through xdg\n\n" - "# Recursively add files from %s%cMusic%c to Music group\n" - "addGroup Music\n" - "setLauncher Music xdg-open\n", home, sep, sep); - fprintf(fp, "addR %s%cMusic%c*.aac Music\n", home, sep, sep); - fprintf(fp, "addR %s%cMusic%c*.aiff Music\n", home, sep, sep); - fprintf(fp, "addR %s%cMusic%c*.alac Music\n", home, sep, sep); - fprintf(fp, "addR %s%cMusic%c*.au Music\n", home, sep, sep); - fprintf(fp, "addR %s%cMusic%c*.flac Music\n", home, sep, sep); - fprintf(fp, "addR %s%cMusic%c*.m4a Music\n", home, sep, sep); - fprintf(fp, "addR %s%cMusic%c*.mp3 Music\n", home, sep, sep); - fprintf(fp, "addR %s%cMusic%c*.ogg Music\n", home, sep, sep); - fprintf(fp, "addR %s%cMusic%c*.pcm Music\n", home, sep, sep); - fprintf(fp, "addR %s%cMusic%c*.wav Music\n", home, sep, sep); - fprintf(fp, "addR %s%cMusic%c*.wma Music\n\n", home, sep, sep); - fprintf(fp, "# Recursively add files from %s%cPictures%c to Pictures group\n" - "addGroup Pictures\n" - "setLauncher Pictures xdg-open\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.epi Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.eps Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.eps2 Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.eps3 Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.epsf Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.epsi Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.ept Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.gif Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.gfa Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.giff Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.jpeg Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.jpg Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.png Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.svg Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.svgz Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.tif Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.tiff Pictures\n\n", home, sep, sep); - fprintf(fp, "# Recursively add files from %s%cVideos%c to Videos group\n" - "addGroup Videos\n" - "setLauncher Videos xdg-open\n", home, sep, sep); - fprintf(fp, "addR %s%cVideos%c*.asf Videos\n", home, sep, sep); - fprintf(fp, "addR %s%cVideos%c*.avi Videos\n", home, sep, sep); - fprintf(fp, "addR %s%cVideos%c*.flv Videos\n", home, sep, sep); - fprintf(fp, "addR %s%cVideos%c*.mk3d Videos\n", home, sep, sep); - fprintf(fp, "addR %s%cVideos%c*.mkv Videos\n", home, sep, sep); - fprintf(fp, "addR %s%cVideos%c*.mov Videos\n", home, sep, sep); - fprintf(fp, "addR %s%cVideos%c*.mp4 Videos\n", home, sep, sep); - fprintf(fp, "addR %s%cVideos%c*.qt Videos\n", home, sep, sep); - fprintf(fp, "addR %s%cVideos%c*.webm Videos\n", home, sep, sep); - fprintf(fp, "addR %s%cVideos%c*.wmv Videos\n", home, sep, sep); + fprintf(fp, + "-- This file was auto-generated by terminal-media-launcher. See docs/terminal-media-launcher-config.md or terminal-media-launcher-config(5) for documentation\n" + "-- The default launcher is set to \"xdg-open\" which will open files based on the relevant default application set through xdg\n\n" + "local lfs = require \"lfs\"\n" + "\n" + "local function addGroup(name, launcher, flags)\n" + " assert(type(name) == \"string\")\n" + "\n" + " -- create Groups table if needed\n" + " if Groups == nil then\n" + " Groups = {}\n" + " end\n" + "\n" + " local new_group = {}\n" + " new_group.name = name\n" + " new_group.Entries = {}\n" + " if launcher ~= nil then\n" + " new_group.Launcher = launcher\n" + " end\n" + " if flags ~= nil then\n" + " new_group.Flags = flags\n" + " end\n" + "\n" + " table.insert(Groups, new_group)\n" + " return new_group\n" + "end\n" + "\n" + "local function addEntries(parentGroup, startDir, filePattern, recursive)\n" + " -- recursive arg is a boolean for whether or not to descend into subdirectories (false by default)\n" + " assert(type(parentGroup) == \"table\")\n" + " assert(type(parentGroup.Entries) == \"table\")\n" + " assert(type(startDir) == \"string\")\n" + " assert(type(filePattern) == \"string\")\n" + "\n" + " for file in lfs.dir(startDir) do\n" + " local fullFilePath = startDir .. \"/\" .. file\n" + " if file ~= \".\" and file ~= \"..\" then\n" + " -- descend into subdirectory if recursive is set to true\n" + " if lfs.attributes(fullFilePath).mode == \"directory\" and recursive == true then\n" + " addEntries(parentGroup, fullFilePath, filePattern, recursive)\n" + " elseif lfs.attributes(fullFilePath).mode == \"file\" then\n" + " if string.match(file, filePattern) then\n" + " table.insert(parentGroup.Entries, {\n" + " name = file,\n" + " path = fullFilePath\n" + " })\n" + " end\n" + " end\n" + " end\n" + " end\n" + "end\n" + "\n" + "local music = addGroup(\"Music\", \"xdg-open\")\n" + "addEntries(music, os.getenv(\"HOME\") .. \"/Music\", \".*\", true)\n" + "\n" + "local pictures = addGroup(\"Pictures\", \"xdg-open\")\n" + "addEntries(pictures, os.getenv(\"HOME\") .. \"/Pictures\", \".*\", true)\n" + "\n" + "local videos = addGroup(\"Videos\", \"xdg-open\")\n" + "addEntries(videos, os.getenv(\"HOME\") .. \"/Videos\", \".*\", true)\n"); fclose(fp); printf("done\nIt is highly recommended to further tweak the configuration file! [press any key to continue]"); diff --git a/src/windows/read_cfg.c b/src/windows/read_cfg.c index bb337f0..79e56b7 100644 --- a/src/windows/read_cfg.c +++ b/src/windows/read_cfg.c @@ -81,53 +81,66 @@ void mkconfig_wizard(char *path){ exit(1); } - fprintf(fp, "# This file was auto-generated by terminal-media-launcher. See docs\\terminal-media-launcher-config.md or terminal-media-launcher-config(5) for documentation\n" - "# By default, no launcher is specified for any group. When no launcher is specified on the Windows build of terminal-media-launcher, media files will be opened with their default application.\n" - "# It is generally recommended to specify a launcher for groups containing media files using the \"setLauncher\" command\n\n" - "# Recursively add files from %s%cMusic%c to Music group\n" - "addGroup Music\n", home, sep, sep); - fprintf(fp, "addR %s%cMusic%c*.aac Music\n", home, sep, sep); - fprintf(fp, "addR %s%cMusic%c*.aiff Music\n", home, sep, sep); - fprintf(fp, "addR %s%cMusic%c*.alac Music\n", home, sep, sep); - fprintf(fp, "addR %s%cMusic%c*.au Music\n", home, sep, sep); - fprintf(fp, "addR %s%cMusic%c*.flac Music\n", home, sep, sep); - fprintf(fp, "addR %s%cMusic%c*.m4a Music\n", home, sep, sep); - fprintf(fp, "addR %s%cMusic%c*.mp3 Music\n", home, sep, sep); - fprintf(fp, "addR %s%cMusic%c*.ogg Music\n", home, sep, sep); - fprintf(fp, "addR %s%cMusic%c*.pcm Music\n", home, sep, sep); - fprintf(fp, "addR %s%cMusic%c*.wav Music\n", home, sep, sep); - fprintf(fp, "addR %s%cMusic%c*.wma Music\n\n", home, sep, sep); - fprintf(fp, "# Recursively add files from %s%cPictures%c to Pictures group\n" - "addGroup Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.epi Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.eps Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.eps2 Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.eps3 Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.epsf Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.epsi Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.ept Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.gif Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.gfa Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.giff Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.jpeg Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.jpg Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.png Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.svg Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.svgz Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.tif Pictures\n", home, sep, sep); - fprintf(fp, "addR %s%cPictures%c*.tiff Pictures\n\n", home, sep, sep); - fprintf(fp, "# Recursively add files from %s%cVideos%c to Videos group\n" - "addGroup Videos\n", home, sep, sep); - fprintf(fp, "addR %s%cVideos%c*.asf Videos\n", home, sep, sep); - fprintf(fp, "addR %s%cVideos%c*.avi Videos\n", home, sep, sep); - fprintf(fp, "addR %s%cVideos%c*.flv Videos\n", home, sep, sep); - fprintf(fp, "addR %s%cVideos%c*.mk3d Videos\n", home, sep, sep); - fprintf(fp, "addR %s%cVideos%c*.mkv Videos\n", home, sep, sep); - fprintf(fp, "addR %s%cVideos%c*.mov Videos\n", home, sep, sep); - fprintf(fp, "addR %s%cVideos%c*.mp4 Videos\n", home, sep, sep); - fprintf(fp, "addR %s%cVideos%c*.qt Videos\n", home, sep, sep); - fprintf(fp, "addR %s%cVideos%c*.webm Videos\n", home, sep, sep); - fprintf(fp, "addR %s%cVideos%c*.wmv Videos\n", home, sep, sep); + fprintf(fp, + "-- This file was auto-generated by terminal-media-launcher. See docs\\terminal-media-launcher-config.md or terminal-media-launcher-config(5) for documentation\n" + "-- By default, no launcher is specified for any group. When no launcher is specified on the Windows build of terminal-media-launcher, media files will be opened with their default application.\n\n" + "local lfs = require \"lfs\"\n" + "\n" + "local function addGroup(name, launcher, flags)\n" + " assert(type(name) == \"string\")\n" + "\n" + " -- create Groups table if needed\n" + " if Groups == nil then\n" + " Groups = {}\n" + " end\n" + "\n" + " local new_group = {}\n" + " new_group.name = name\n" + " new_group.Entries = {}\n" + " if launcher ~= nil then\n" + " new_group.Launcher = launcher\n" + " end\n" + " if flags ~= nil then\n" + " new_group.Flags = flags\n" + " end\n" + "\n" + " table.insert(Groups, new_group)\n" + " return new_group\n" + "end\n" + "\n" + "local function addEntries(parentGroup, startDir, filePattern, recursive)\n" + " -- recursive arg is a boolean for whether or not to descend into subdirectories (false by default)\n" + " assert(type(parentGroup) == \"table\")\n" + " assert(type(parentGroup.Entries) == \"table\")\n" + " assert(type(startDir) == \"string\")\n" + " assert(type(filePattern) == \"string\")\n" + "\n" + " for file in lfs.dir(startDir) do\n" + " local fullFilePath = startDir .. \"\\\\\" .. file\n" + " if file ~= \".\" and file ~= \"..\" then\n" + " -- descend into subdirectory if recursive is set to true\n" + " if lfs.attributes(fullFilePath).mode == \"directory\" and recursive == true then\n" + " addEntries(parentGroup, fullFilePath, filePattern, recursive)\n" + " elseif lfs.attributes(fullFilePath).mode == \"file\" then\n" + " if string.match(file, filePattern) then\n" + " table.insert(parentGroup.Entries, {\n" + " name = file,\n" + " path = fullFilePath\n" + " })\n" + " end\n" + " end\n" + " end\n" + " end\n" + "end\n" + "\n" + "local music = addGroup(\"Music\")\n" + "addEntries(music, os.getenv(\"USERPROFILE\") .. \"\\\\Music\", \".*\", true)\n" + "\n" + "local pictures = addGroup(\"Pictures\")\n" + "addEntries(pictures, os.getenv(\"USERPROFILE\") .. \"\\\\Pictures\", \".*\", true)\n" + "\n" + "local videos = addGroup(\"Videos\")\n" + "addEntries(videos, os.getenv(\"USERPROFILE\") .. \"\\\\Videos\", \".*\", true)\n"); fclose(fp); printf("done\nIt is highly recommended to further tweak the configuration file! [press any key to continue]"); -- cgit From a77f5393a584338561f217d3f87832e910bf937a Mon Sep 17 00:00:00 2001 From: Louie Shprung Date: Fri, 30 Aug 2024 14:36:35 -0400 Subject: Reenable caching --- src/draw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/draw.c b/src/draw.c index 4dd5d75..7303ff6 100644 --- a/src/draw.c +++ b/src/draw.c @@ -97,8 +97,8 @@ int main(int argc, char **argv){ e_hover = calloc(g_count, sizeof(int)); e_offset = calloc(g_count, sizeof(int)); - //load cached data - //load_cache(g_count, &g_hover, &e_hover, &e_offset, &true_hover, cfg_path); + // load cached data + load_cache(g_count, &g_hover, &e_hover, &e_offset, &true_hover, cfg_path); //reopen stdout for drawing menu freopen("/dev/tty", "w", stdout); -- cgit From a3d9eb21789bf3587f176e6d155d610b8bc69dab Mon Sep 17 00:00:00 2001 From: Louie Shprung Date: Fri, 30 Aug 2024 14:49:00 -0400 Subject: Remove quotes from get_launch --- src/draw.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'src') diff --git a/src/draw.c b/src/draw.c index 7303ff6..3412185 100644 --- a/src/draw.c +++ b/src/draw.c @@ -556,28 +556,21 @@ char *get_launch(){ char *program = get_gprog(g[g_hover]); char *flags = get_gflags(g[g_hover]); char *path = get_epath(entries[e_hover[g_hover]]); - bool quotes = false; char *full_command = calloc(BUF_LEN, sizeof(char)); //if the entry is an executable file (doesn't have a launcher) if(!(strcmp(program, "./"))){ - strcat(full_command, "\""); strcat(full_command, path); - strcat(full_command, "\""); } else{ - if(quotes) strcat(full_command, "\""); strcat(full_command, program); - if(quotes) strcat(full_command, "\""); if(flags[0] !='\0'){ strcat(full_command, " "); strcat(full_command, flags); } strcat(full_command, " "); - strcat(full_command, "\""); strcat(full_command, path); - strcat(full_command, "\""); } return full_command; -- cgit