summaryrefslogtreecommitdiff
path: root/src/read_cfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/read_cfg.c')
-rw-r--r--src/read_cfg.c291
1 files changed, 207 insertions, 84 deletions
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
}