summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am4
-rw-r--r--src/draw.c55
-rw-r--r--src/entry.c84
-rw-r--r--src/group.c190
-rw-r--r--src/include/cache.h2
-rw-r--r--src/include/draw.h5
-rw-r--r--src/include/entry.h18
-rw-r--r--src/include/group.h29
-rw-r--r--src/include/read_cfg.h15
-rw-r--r--src/read_cfg.c738
-rw-r--r--src/unix/read_cfg.c210
-rw-r--r--src/windows/draw.c4
-rw-r--r--src/windows/read_cfg.c204
13 files changed, 518 insertions, 1040 deletions
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/draw.c b/src/draw.c
index 15a9289..3412185 100644
--- a/src/draw.c
+++ b/src/draw.c
@@ -1,3 +1,4 @@
+#include <assert.h>
#include <getopt.h>
#include <stdbool.h>
#include <stdio.h>
@@ -40,9 +41,7 @@ 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 e_count;
int g_offset = 0;
int *e_offset;
@@ -70,15 +69,23 @@ 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;
}
+ // DEBUG
+ //for(i = 0; i < g_count; ++i) {
+ // group_debug(g[i]);
+ //}
+ //return 0;
+ /*
//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){
@@ -90,7 +97,7 @@ int main(int argc, char **argv){
e_hover = calloc(g_count, sizeof(int));
e_offset = calloc(g_count, sizeof(int));
- //load cached data
+ // load cached data
load_cache(g_count, &g_hover, &e_hover, &e_offset, &true_hover, cfg_path);
//reopen stdout for drawing menu
@@ -125,6 +132,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 +159,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):
@@ -207,7 +215,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){
@@ -332,8 +340,9 @@ 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 ? 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;
@@ -342,10 +351,10 @@ void fill_col(int mode){
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++;
@@ -421,8 +430,6 @@ 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);
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 +471,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
@@ -478,7 +485,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)++;
@@ -512,16 +518,17 @@ 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;
if(fold_case && input >= 97 && input <= 122) input -= 32;
if(true_hover){ //hovering on entries
- for(i = location+1; i < e_count; i++){
- first_char = get_ename(e[i])[0];
+ for(i = location+1; i < get_ecount(g[g_hover]); i++){
+ 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;
@@ -545,33 +552,25 @@ 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]]);
- bool quotes = get_gquotes(g[g_hover]);
- char *full_command = malloc(sizeof(char) * BUF_LEN);
-
- full_command[0] = '\0';
+ char *path = get_epath(entries[e_hover[g_hover]]);
+ 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;
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 <unistd.h>
#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..95d8605 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;
@@ -183,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;
@@ -194,14 +55,19 @@ 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);
}
-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,27 +80,9 @@ 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;
-
- 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 <stdbool.h>
+
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/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 <stdbool.h>
+
#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..bad33a5 100644
--- a/src/include/group.h
+++ b/src/include/group.h
@@ -1,40 +1,33 @@
#ifndef GROUP_H
#define GROUP_H
-typedef struct group GROUP;
-
-GROUP *create_group(char *new_name);
+#include <stdbool.h>
-void group_add(char *gname, ENTRY *addme);
+#include "entry.h"
-void group_rm(GROUP *g);
-
-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);
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);
-void set_gflags(GROUP *g, char *p);
+void set_gflags(GROUP *g, const 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
+// 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 df3e5bd..1337e32 100644
--- a/src/include/read_cfg.h
+++ b/src/include/read_cfg.h
@@ -1,23 +1,18 @@
#ifndef READ_CFG_H
#define READ_CFG_H
+#include <stdbool.h>
+
+#include "group.h"
+
#define BUF_LEN 1024
-bool cfg_interp(char *path);
-bool get_sort();
-bool get_case_sensitivity();
+GROUP **cfg_interp(char *path, int *group_count);
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;
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 f757d6b..6c334ac 100644
--- a/src/read_cfg.c
+++ b/src/read_cfg.c
@@ -1,4 +1,7 @@
#include <assert.h>
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@@ -19,87 +22,87 @@
#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);
-
-//turn on or off sorting (A-Z); On by default
+//void check_line(char *buffer, char **options, int ln);
+//int check_option(char *arg, char **options);
+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)
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
-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);
- //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)){
- i++;
- check_line(buffer, options, i);
+ // 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) {
+ printf("Error: could not load configuration \"%s\"\n", path);
+ lua_error(L);
+ exit(1);
}
- //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]));
- }
+ // 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);
+
+ // open Settings table
+ lua_getglobal(L, "Settings");
+ // stack now contains: -1 => Settings
+ if(lua_type(L, -1) == LUA_TTABLE) {
+ // parse settings
+ get_settings(L);
+ }
+ lua_pop(L, 1);
+ // empty stack
+
+ // open Groups table
+ lua_getglobal(L, "Groups");
+ // 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);
}
- //END DEBUG
- */
-
- fclose(fp);
- return true;
-}
-bool get_sort(){
- return sort;
-}
+ // create the group array
+ *group_count = get_group_count(L);
+ if(*group_count <= 0) {
+ printf("Error: No Groups!\n");
+ g = NULL;
+ }
+ else {
+ g = malloc(sizeof(GROUP *) * (*group_count));
-bool get_case_sensitivity(){
- return fold_case;
+ // add each group (which also adds each entry to each group)
+ add_groups(L, &g);
+ }
+ lua_close(L);
+ return g;
}
void refer_to_doc(){
@@ -107,409 +110,298 @@ 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;
-}
+void get_settings(lua_State *L) {
+ // stack now contains: -1 => table
-int search_ch(char *str, char c){
- int i = 0;
+ bool *setting_vars[] = {
+ &sort
+ };
- while(str[i] != '\0'){
- if(str[i] == c) return i;
- i++;
- }
+ char *setting_strings[] = {
+ "sort"
+ };
- return -1;
-}
+ int count = 1;
+ int i;
-int search_last_ch(char *str, char c){
- int i = 0;
- int last_i = -1;
+ // looking at table Settings
- while(str[i] != '\0'){
- if(str[i] == c) last_i = i;
- i++;
+ // check if autoAlias is set
+ for(i = 0; i < count; ++i) {
+ lua_pushstring(L, setting_strings[i]);
+ // 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
}
-
- return last_i;
}
-//return 0 if match, 1 if not
-//TODO only supports one wildcard per entry
-int wild_cmp(char *wild, char *literal){
- 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--;
+int get_group_count(lua_State *L) {
+ int output = 0;
+
+ // 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");
+ // 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");
+ // 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
}
-
- return 0;
+ 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.)
- return 0;
+ return output;
}
-
-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;
+int get_entry_count(lua_State *L) {
+ int output = 0;
+
+ // 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.)
- 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;
+ return output;
}
-//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++;
-
- }
+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
+ int entry_count;
+ 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
+
+ // 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");
+ // 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");
+ // 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);
}
- *arg_p = '\0';
-
- }
-
- 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;
+ entry_count = get_entry_count(L);
- 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;
+ // check that the group has at least 1 entry
+ 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);
- 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;
+ // sort the entries if necessary
+ if(sort) {
+ 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);
}
- if(j < e_count){
- set_hide(e[j], true);
- set_ecount(g[i], get_ecount(g[i])-1);
+ // add entries to this group
+ 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");
+ // 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));
}
- 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);
+ 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");
+ // 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
- 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);
+ ++count;
}
- 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);
-
+ }
}
-
+ lua_pop(L, 2);
+ // stack now contains: -1 => key; -2 => table
+ ++i;
}
-
- return;
+ // 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
}
-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;
+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
+
+ // 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) {
+ // 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;
+ }
+ }
+ lua_pop(L, 2);
+ // stack now contains: -1 => key; -2 => table
}
-
- 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;
+ // stack now contains: -1 => table (when lua_next returns 0 it pops the key
}
+void stack_debug(lua_State *L) {
+ 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;
+ printf("DEBUGGING STACK:\n");
+ for(i = 1; i <= lua_gettop(L); ++i) {
+ printf("\t%d - %s", i, lua_typename(L, lua_type(L, i)));
- case ' ':
- if(*(p-1) != ' ' && !stop){
- *p = *rpath;
- *p++;
- }
+ switch(lua_type(L, i)) {
+ case LUA_TSTRING:
+ printf(" - %s\n", lua_tostring(L, i));
break;
-
- case '.':
- last_dot = p;
+
+ //case LUA_TTABLE:
+ // printf("\n");
+ // table_debug(L, 2);
+ // break;
default:
- if(!stop){
- *p = *rpath;
- *p++;
- }
+ printf("\n");
}
- *rpath++;
}
-
- //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;
}
+// 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
+}
diff --git a/src/unix/read_cfg.c b/src/unix/read_cfg.c
index b40dd48..602c750 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");
@@ -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]");
@@ -137,97 +147,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;
-}
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'){
diff --git a/src/windows/read_cfg.c b/src/windows/read_cfg.c
index f973759..79e56b7 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");
@@ -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]");
@@ -137,96 +150,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;
-}