simplify logging, add util functions

This commit is contained in:
Akos Horvath 2024-04-12 11:45:11 +02:00
parent e261a7b518
commit f5a134aedc

View File

@ -1,3 +1,4 @@
#include <X11/Xlib.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdint.h> #include <stdint.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -259,6 +260,9 @@ void wm_log_state(Wm *wm, const char *prefixstr, const char* logfile)
json_object *log_entry_obj = wm_state_to_json_object(wm); json_object *log_entry_obj = wm_state_to_json_object(wm);
LogEntry *new_entry = wm_json_obj_to_logentry(prefix, log_entry_obj);
wm_uintarray_push(wm->log_entries, (uint64_t)new_entry);
int fd = -1; int fd = -1;
struct json_object *jobj = NULL; struct json_object *jobj = NULL;
@ -326,10 +330,6 @@ void wm_log_state(Wm *wm, const char *prefixstr, const char* logfile)
goto ret; goto ret;
} }
// TODO
wm_logentries_free(wm->log_entries);
wm->log_entries = wm_read_log(logfile);
ret: ret:
json_object_put(jobj); json_object_put(jobj);
} }
@ -607,8 +607,8 @@ void wm_logentries_calculate_distances(UIntArray *log_entries, TreeNode *curr_tr
UpdateCostFunction update_cost_function) UpdateCostFunction update_cost_function)
{ {
TreeEditDistanceCosts costs = (TreeEditDistanceCosts) { TreeEditDistanceCosts costs = (TreeEditDistanceCosts) {
.insert_cost = 3, .insert_cost = 10,
.remove_cost = 100, .remove_cost = 20,
.update_cost_function = update_cost_function, .update_cost_function = update_cost_function,
}; };
@ -627,7 +627,7 @@ void wm_logentries_calculate_distances(UIntArray *log_entries, TreeNode *curr_tr
void wm_treenode_print(TreeNode *node) void wm_treenode_print(TreeNode *node)
{ {
char *str = wm_treenode_to_str(node); char *str = wm_treenode_to_str(node);
DEBUG_PRINT("%s\n", str); fprintf(stderr, "%s\n", str);
free(str); free(str);
} }
@ -749,7 +749,6 @@ static void recursive_mkdir(char *path, mode_t mode)
void wm_logfile_init(const char *path) void wm_logfile_init(const char *path)
{ {
if (access(path, F_OK) == 0) return; if (access(path, F_OK) == 0) return;
char *dup = strdup(path); char *dup = strdup(path);
@ -783,9 +782,73 @@ void wm_logfile_init(const char *path)
free(dup); free(dup);
} }
LogEntry *wm_json_obj_to_logentry(const char *key, struct json_object *jobj)
{
LogEntry *ret = calloc(1, sizeof(LogEntry));
ret->workspaces = wm_nodearray_new();
struct json_object_iterator ws_iter = json_object_iter_begin(jobj);
struct json_object_iterator ws_iter_end = json_object_iter_end(jobj);
const char *ws_name = NULL;
struct json_object *ws_value = NULL;
int i = 0;
char *dup = strdup(key);
char *token = strtok((char*)dup, ":");
while(token != NULL) {
i++;
switch (i) {
case 1:
// TODO
ret->timestamp = atol(token);
break;
case 2:
strncpy(ret->function_name, token, 128);
break;
case 3:
if (strncmp(token, "after", strlen("after")) == 0)
ret->after = true;
else {
fprintf(stderr, "wm: encountered invalid token %s\n. exiting.",
token);
abort();
}
break;
default:
fprintf(stderr, "wm: encountered invalid token %s\n. exiting.",
token);
abort();
}
token = strtok(NULL, ":");
}
while (!json_object_iter_equal(&ws_iter, &ws_iter_end)) {
ws_name = json_object_iter_peek_name(&ws_iter);
ws_value = json_object_iter_peek_value(&ws_iter);
int ws_index = atoi(ws_name);
while (ret->workspaces->size < ws_index) {
wm_nodearray_push(ret->workspaces, NULL);
}
wm_nodearray_push(ret->workspaces, wm_json_obj_to_treenode(ws_value));
json_object_iter_next(&ws_iter);
}
free(dup);
return ret;
}
/* UIntArray<LogEntry*> */ /* UIntArray<LogEntry*> */
UIntArray* wm_read_log(const char* filename) UIntArray* wm_read_log(const char* filename)
{ {
DEBUG_PRINT("%s\n", __func__);
_Static_assert(sizeof(LogEntry*) == sizeof(uint64_t), ""); _Static_assert(sizeof(LogEntry*) == sizeof(uint64_t), "");
// TODO maybe prealloc // TODO maybe prealloc
UIntArray* ret = wm_uintarray_new(); UIntArray* ret = wm_uintarray_new();
@ -814,67 +877,11 @@ UIntArray* wm_read_log(const char* filename)
struct json_object_iterator iter = json_object_iter_begin(jobj); struct json_object_iterator iter = json_object_iter_begin(jobj);
struct json_object_iterator iter_end = json_object_iter_end(jobj); struct json_object_iterator iter_end = json_object_iter_end(jobj);
const char *ws_name = NULL;
struct json_object *ws_value = NULL;
struct json_object_iterator ws_iter = json_object_iter_init_default();
struct json_object_iterator ws_iter_end = json_object_iter_init_default();
while (!json_object_iter_equal(&iter, &iter_end)) { while (!json_object_iter_equal(&iter, &iter_end)) {
// TODO maybe prealloc
LogEntry *entry = calloc(1, sizeof(LogEntry));
entry->workspaces = wm_nodearray_new();
name = json_object_iter_peek_name(&iter); name = json_object_iter_peek_name(&iter);
value = json_object_iter_peek_value(&iter); value = json_object_iter_peek_value(&iter);
int i = 0; LogEntry *entry = wm_json_obj_to_logentry(name, value);
char *token = strtok((char*)name, ":");
while(token != NULL) {
i++;
switch (i) {
case 1:
// TODO
entry->timestamp = atol(token);
break;
case 2:
strncpy(entry->function_name, token, 128);
break;
case 3:
if (strncmp(token, "after", strlen("after")) == 0)
entry->after = true;
else {
fprintf(stderr, "wm: encountered invalid token %s\n. exiting.",
token);
abort();
}
break;
default:
fprintf(stderr, "wm: encountered invalid token %s\n. exiting.",
token);
abort();
}
token = strtok(NULL, ":");
}
ws_iter = json_object_iter_begin(value);
ws_iter_end = json_object_iter_end(value);
while (!json_object_iter_equal(&ws_iter, &ws_iter_end)) {
ws_name = json_object_iter_peek_name(&ws_iter);
ws_value = json_object_iter_peek_value(&ws_iter);
int ws_index = atoi(ws_name);
while (entry->workspaces->size < ws_index) {
wm_nodearray_push(entry->workspaces, NULL);
}
wm_nodearray_push(entry->workspaces, wm_json_obj_to_treenode(ws_value));
json_object_iter_next(&ws_iter);
}
wm_uintarray_push(ret, (uint64_t)entry); wm_uintarray_push(ret, (uint64_t)entry);
json_object_iter_next(&iter); json_object_iter_next(&iter);
@ -1041,6 +1048,34 @@ TreeNode* wm_treenode_remove_client(Wm *wm, TreeNode *root, Client *client)
TreeNode *node = client_node->parent; TreeNode *node = client_node->parent;
if (node->type == NODE_TAB) {
size_t client_node_index = wm_treenode_find_index(node, client_node);
assert(client_node_index != SIZE_MAX);
wm_treenode_free(client_node);
wm_nodearray_remove(node->children, client_node_index);
if (node->children->size == 0) {
XDestroyWindow(wm->display, node->tab_frame);
// node is root node, dont free it
if (!node->parent) return NULL;
wm_treenode_free(node);
size_t node_index = wm_treenode_find_index(node->parent, node);
if (node_index != SIZE_MAX)
wm_nodearray_remove(node->parent->children, node_index);
return NULL;
}
return node->children->nodes[0];
}
for (size_t i = 0; i < node->children->size; i++) { for (size_t i = 0; i < node->children->size; i++) {
if (node->children->nodes[i]->type == NODE_CLIENT && if (node->children->nodes[i]->type == NODE_CLIENT &&
node->children->nodes[i]->client != client) { node->children->nodes[i]->client != client) {
@ -1184,9 +1219,6 @@ bool wm_nodearray_remove(NodeArray *arr, size_t index)
DEBUG_PRINT("%s\n", __func__); DEBUG_PRINT("%s\n", __func__);
assert(arr); assert(arr);
if (!arr)
return false;
if (index >= arr->size) if (index >= arr->size)
return false; return false;
@ -1195,11 +1227,24 @@ bool wm_nodearray_remove(NodeArray *arr, size_t index)
return true; return true;
} }
memmove(arr->nodes + index, arr->nodes + index+1, arr->size-1 * sizeof(TreeNode*)); arr->size--;
if (arr->size == 0) return true;
memmove(arr->nodes + index, arr->nodes + index + 1, (arr->size - index) * sizeof(TreeNode*));
return true; return true;
} }
bool wm_nodearray_contains(NodeArray *arr, TreeNode *node)
{
for (size_t i = 0; i < arr->size; i++)
if (arr->nodes[i] == node)
return true;
return false;
}
void wm_nodearray_free(NodeArray *arr) void wm_nodearray_free(NodeArray *arr)
{ {
assert(arr); assert(arr);
@ -1443,6 +1488,14 @@ NodeArray *wm_treenode_find_client_nodes(TreeNode *root)
return ret; return ret;
} }
size_t wm_treenode_find_index(TreeNode *parent, TreeNode* child)
{
for (size_t i = 0; i < parent->children->size; i++)
if (parent->children->nodes[i] == child) return i;
return SIZE_MAX;
}
NodeArray* wm_all_nodes_to_array(TreeNode *root) NodeArray* wm_all_nodes_to_array(TreeNode *root)
{ {
DEBUG_PRINT("%s\n", __func__); DEBUG_PRINT("%s\n", __func__);