rewrite PtrArray to UIntArray, logging updates

This commit is contained in:
Akos Horvath 2024-02-26 16:28:08 +01:00
parent a2384822d8
commit 0fefb31535
2 changed files with 169 additions and 65 deletions

View File

@ -1,13 +1,23 @@
#include "util.h" #include <fcntl.h>
#include "wm.h" #include <stdint.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h> #include <time.h>
#include <json-c/json_object.h>
#include <json-c/json_tokener.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <unistd.h>
#include <libgen.h>
#include <json-c/arraylist.h>
#include <json-c/json_object_iterator.h>
#include <json-c/json_util.h>
#include <json-c/json_object.h>
#include <json-c/json_tokener.h>
#include "util.h"
#include "client.h"
#include "wm.h"
static unsigned int node_id = 0; static unsigned int node_id = 0;
@ -124,6 +134,23 @@ void wm_node_type_to_str(NodeType type, char *buf, size_t bufsize)
} }
} }
NodeType wm_node_type_from_str(char *buf, size_t bufsize)
{
char *types[4] = {0};
types[NODE_CLIENT] = "NODE_CLIENT";
types[NODE_VERTICAL] = "NODE_VERTICAL";
types[NODE_HORIZONTAL] = "NODE_HORIZONTAL";
types[NODE_TAB] = "NODE_TAB";
for (size_t i = 0; i < 4; i++) {
if (strncmp(buf, types[i], bufsize) == 0)
return (NodeType)i;
}
fprintf(stderr, "wm: invalid node type string: %s. exiting\n", buf);
exit(1);
}
char* wm_treenode_to_str(TreeNode *node) char* wm_treenode_to_str(TreeNode *node)
{ {
assert(node); assert(node);
@ -166,9 +193,10 @@ char* wm_treenode_to_str(TreeNode *node)
return ret; return ret;
} }
PtrArray wm_nonempty_workspaces_to_strptrarray(Wm *wm) UIntArray* wm_nonempty_workspaces_to_strptrarray(Wm *wm)
{ {
PtrArray ret = wm_ptrarray_new(); _Static_assert(sizeof(uint64_t) == sizeof(uint64_t*), "static assert failed");
UIntArray *ret = wm_uintarray_new();
for (size_t i = 0; i < wm->smon->wscount; i++) { for (size_t i = 0; i < wm->smon->wscount; i++) {
TreeNode *node = wm->smon->workspaces[i].tree; TreeNode *node = wm->smon->workspaces[i].tree;
@ -179,11 +207,11 @@ PtrArray wm_nonempty_workspaces_to_strptrarray(Wm *wm)
.ws_index = i, .ws_index = i,
.str = wm_treenode_to_str(wm->smon->workspaces[i].tree) .str = wm_treenode_to_str(wm->smon->workspaces[i].tree)
}; };
wm_ptrarray_push(&ret, ws_str_with_index); wm_uintarray_push(ret, (uint64_t)ws_str_with_index);
} }
} }
DEBUG_PRINT("%s returning %ld\n", __func__, ret.size); DEBUG_PRINT("%s returning %ld\n", __func__, ret->size);
return ret; return ret;
} }
@ -193,34 +221,83 @@ void wm_log_state(Wm *wm, const char *prefixstr, const char* logfile)
RETURN_IF_NULL(prefixstr); RETURN_IF_NULL(prefixstr);
RETURN_IF_NULL(logfile); RETURN_IF_NULL(logfile);
FILE *fptr = fopen(logfile, "a"); UIntArray *ws_str = wm_nonempty_workspaces_to_strptrarray(wm);
if (!fptr) {
fprintf(stderr, "wm: could not open log file %s\n", logfile);
return;
}
PtrArray ws_str = wm_nonempty_workspaces_to_strptrarray(wm);
char str[128] = {0}; char str[128] = {0};
char prefix[WM_PREFIX_LEN + 32] = {0}; char prefix[WM_PREFIX_LEN + 32] = {0};
snprintf(prefix, sizeof(prefix), "%lu_%s", time(NULL), prefixstr); snprintf(prefix, sizeof(prefix), "%lu:%s", time(NULL), prefixstr);
json_object *log_entry_obj = json_object_new_object(); json_object *log_entry_obj = json_object_new_object();
json_object_object_add(log_entry_obj, prefix, json_object_new_object());
for (size_t i = 0; i < ws_str.size; i++) { for (size_t i = 0; i < ws_str->size; i++) {
WmWorkspaceToStrRet *ws_with_index = (WmWorkspaceToStrRet*)ws_str.ptrs[i]; WmWorkspaceToStrRet *ws_with_index = (WmWorkspaceToStrRet*)
wm_uintarray_at(ws_str, i);
snprintf(str, sizeof(str), "%ld", ws_with_index->ws_index); snprintf(str, sizeof(str), "%ld", ws_with_index->ws_index);
json_object_object_add(json_object_object_get(log_entry_obj, prefix), str, json_tokener_parse(ws_with_index->str)); json_object_object_add(log_entry_obj, str, json_tokener_parse(ws_with_index->str));
fprintf(fptr, "%s,\n", json_object_to_json_string_ext(log_entry_obj, JSON_C_TO_STRING_PRETTY));
free(ws_with_index->str); free(ws_with_index->str);
free(ws_with_index); free(ws_with_index);
} }
json_object_put(log_entry_obj); int fd = -1;
fflush(fptr); struct json_object *jobj = NULL;
fclose(fptr); if (access(logfile, F_OK) != 0) {
wm_ptrarray_free(&ws_str); fd = creat(logfile, 0644);
if (fd < 0) {
perror("creat");
goto ret;
}
jobj = json_object_new_object();
} else {
fd = open(logfile, O_RDWR);
if (fd < 0) {
perror("open");
goto ret;
}
jobj = json_object_from_fd(fd);
if (!jobj) {
const char *err = json_util_get_last_err();
fprintf(stderr, "wm: could not read json: %s\n", err);
// TODO maybe free
goto ret;
}
}
json_object_object_add(jobj, prefix, log_entry_obj);
int ret = close(fd);
if (ret < 0) {
perror("close");
goto ret;
}
ret = open(logfile, O_TRUNC | O_WRONLY);
if (ret < 0) {
perror("open");
goto ret;
}
json_object_to_fd(fd, jobj, JSON_C_TO_STRING_PRETTY);
ret = close(fd);
if (ret < 0) {
perror("close");
goto ret;
}
// TODO
wm_logentries_free(wm->log_entries);
wm->log_entries = wm_read_log(logfile);
ret:
json_object_put(jobj);
wm_uintarray_free(ws_str);
} }
TreeNode* wm_treenode_lmd(TreeNode *node) TreeNode* wm_treenode_lmd(TreeNode *node)
@ -671,45 +748,54 @@ void wm_nodearray_free(NodeArray *arr)
free(arr); free(arr);
} }
PtrArray wm_ptrarray_new() UIntArray* wm_uintarray_new()
{ {
PtrArray arr; UIntArray *arr = calloc(1, sizeof(UIntArray));
assert(arr);
arr.capacity = 10; arr->capacity = 10;
arr.ptrs = calloc(arr.capacity, sizeof(void*)); arr->elements = calloc(arr->capacity, sizeof(void*));
assert(arr.ptrs); assert(arr->elements);
arr.size = 0; arr->size = 0;
return arr; return arr;
} }
void wm_ptrarray_push(PtrArray *arr, void* ptr) uint64_t wm_uintarray_at(UIntArray *arr, size_t index)
{
assert(arr);
assert(index < arr->size);
return arr->elements[index];
}
void wm_uintarray_push(UIntArray *arr, uint64_t element)
{ {
assert(arr); assert(arr);
arr->size++; arr->size++;
if (arr->size >= arr->capacity) { if (arr->size >= arr->capacity) {
void* temp = calloc(arr->capacity, sizeof(void*)); void* temp = calloc(arr->capacity, sizeof(uint64_t));
assert(temp); assert(temp);
memcpy(temp, arr->ptrs, arr->capacity * sizeof(void*)); memcpy(temp, arr->elements, arr->capacity * sizeof(uint64_t));
free(arr->ptrs); free(arr->elements);
size_t old_capacity = arr->capacity; size_t old_capacity = arr->capacity;
arr->capacity = old_capacity * 2; arr->capacity = old_capacity * 2;
arr->ptrs = calloc(arr->capacity, sizeof(void*)); arr->elements = calloc(arr->capacity, sizeof(uint64_t));
assert(arr->ptrs); assert(arr->elements);
memcpy(arr->ptrs, temp, old_capacity * sizeof(void*)); memcpy(arr->elements, temp, old_capacity * sizeof(uint64_t));
free(temp); free(temp);
arr->ptrs[arr->size - 1] = ptr; arr->elements[arr->size - 1] = element;
return; return;
} }
arr->ptrs[arr->size - 1] = ptr; arr->elements[arr->size - 1] = element;
} }
bool wm_ptrarray_pop(PtrArray *arr, void **ret) bool wm_uintarray_pop(UIntArray *arr, uint64_t *ret)
{ {
DEBUG_PRINT("%s\n", __func__); DEBUG_PRINT("%s\n", __func__);
assert(arr); assert(arr);
@ -718,12 +804,12 @@ bool wm_ptrarray_pop(PtrArray *arr, void **ret)
if (arr->size == 0) if (arr->size == 0)
return false; return false;
*ret = arr->ptrs[arr->size - 1]; *ret = arr->elements[arr->size - 1];
arr->size--; arr->size--;
return true; return true;
} }
bool wm_ptrarray_pop_front(PtrArray *arr, void **ret) bool wm_uintarray_pop_front(UIntArray *arr, uint64_t *ret)
{ {
assert(arr); assert(arr);
assert(ret); assert(ret);
@ -731,14 +817,14 @@ bool wm_ptrarray_pop_front(PtrArray *arr, void **ret)
if (arr->size == 0) if (arr->size == 0)
return false; return false;
*ret = arr->ptrs[0]; *ret = arr->elements[0];
arr->size--; arr->size--;
memmove(arr->ptrs, arr->ptrs+1, arr->size * sizeof(void*)); memmove(arr->elements, arr->elements+1, arr->size * sizeof(uint64_t));
return true; return true;
} }
bool wm_ptrarray_remove(PtrArray *arr, size_t index) bool wm_uintarray_remove(UIntArray *arr, size_t index)
{ {
DEBUG_PRINT("%s\n", __func__); DEBUG_PRINT("%s\n", __func__);
assert(arr); assert(arr);
@ -754,21 +840,32 @@ bool wm_ptrarray_remove(PtrArray *arr, size_t index)
return true; return true;
} }
memmove(arr->ptrs + index, arr->ptrs + index+1, arr->size-1 * sizeof(void*)); memmove(arr->elements + index, arr->elements + index+1, arr->size-1 * sizeof(uint64_t));
return true; return true;
} }
void wm_ptrarray_free(PtrArray *arr) void wm_uintarray_free(UIntArray *arr)
{ {
// DEBUG_PRINT("%s\n", __func__); // DEBUG_PRINT("%s\n", __func__);
assert(arr); assert(arr);
RETURN_IF_NULL(arr->ptrs); RETURN_IF_NULL(arr->elements);
arr->capacity = 0; arr->capacity = 0;
arr->size = 0; arr->size = 0;
free(arr->ptrs); free(arr->elements);
arr->ptrs = NULL; arr->elements = NULL;
free(arr);
}
uint64_t wm_uintarray_2d_index(UIntArray *arr, size_t i, size_t j)
{
assert(arr);
return ((uint64_t**)arr->elements)[i][j];
}
} }
TreeNode* wm_treenode_ptr_find_focused_client_node(TreeNode *root) TreeNode* wm_treenode_ptr_find_focused_client_node(TreeNode *root)
@ -781,14 +878,14 @@ TreeNode* wm_treenode_ptr_find_focused_client_node(TreeNode *root)
NodeArray *visited = wm_nodearray_new(); NodeArray *visited = wm_nodearray_new();
wm_nodearray_push(visited, root); wm_nodearray_push(visited, root);
PtrArray queue = wm_ptrarray_new(); NodeArray *queue = wm_nodearray_new();
wm_ptrarray_push(&queue, root); wm_nodearray_push(queue, root);
while (queue.size > 0) { while (queue->size > 0) {
TreeNode *node; TreeNode *node;
if (!wm_ptrarray_pop_front(&queue, (void**)&node)) if (!wm_nodearray_pop_front(queue, &node))
goto ret; goto ret;
if (node->type == NODE_CLIENT && node->client && node->client->focused) { if (node->type == NODE_CLIENT && node->client && node->client->focused) {
@ -809,14 +906,14 @@ TreeNode* wm_treenode_ptr_find_focused_client_node(TreeNode *root)
if (!_visited) { if (!_visited) {
wm_nodearray_push(visited, child_node); wm_nodearray_push(visited, child_node);
wm_ptrarray_push(&queue, child_node); wm_nodearray_push(queue, child_node);
} }
} }
} }
ret: ret:
wm_nodearray_free(visited); wm_nodearray_free(visited);
wm_ptrarray_free(&queue); wm_nodearray_free(queue);
return ret; return ret;
} }

View File

@ -2,6 +2,7 @@
#define UTIL_H #define UTIL_H
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <json-c/json.h> #include <json-c/json.h>
@ -30,10 +31,10 @@ typedef struct {
} NodeArray; } NodeArray;
typedef struct { typedef struct {
void **ptrs; uint64_t *elements;
size_t size; size_t size;
size_t capacity; size_t capacity;
} PtrArray; } UIntArray;
typedef struct { typedef struct {
int x; int x;
@ -79,15 +80,21 @@ void wm_treenode_remove_node(Wm *wm, TreeNode *root, TreeNode *node);
int wm_get_node_index(TreeNode *parent, unsigned int node_id); int wm_get_node_index(TreeNode *parent, unsigned int node_id);
void wm_tree_to_DOT(TreeNode *root, const char *filename); void wm_tree_to_DOT(TreeNode *root, const char *filename);
void wm_node_type_to_str(NodeType type, char *buf, size_t bufsize); void wm_node_type_to_str(NodeType type, char *buf, size_t bufsize);
UIntArray* wm_nonempty_workspaces_to_strptrarray(Wm *wm);
NodeType wm_node_type_from_str(char *buf, size_t bufsize);
char* wm_treenode_to_str(TreeNode *node); char* wm_treenode_to_str(TreeNode *node);
void wm_treenode_print(TreeNode *node); void wm_treenode_print(TreeNode *node);
PtrArray wm_ptrarray_new(); UIntArray* wm_uintarray_new();
void wm_ptrarray_push(PtrArray *arr, void* ptr); uint64_t wm_uintarray_at(UIntArray *arr, size_t index);
bool wm_ptrarray_pop(PtrArray *arr, void **ret); void wm_uintarray_set(UIntArray *arr, size_t index, uint64_t value);
bool wm_ptrarray_pop_front(PtrArray *arr, void **ret); void wm_uintarray_push(UIntArray *arr, uint64_t element);
bool wm_ptrarray_remove(PtrArray *arr, size_t index); bool wm_uintarray_pop(UIntArray *arr, uint64_t *ret);
void wm_ptrarray_free(PtrArray *arr); bool wm_uintarray_pop_front(UIntArray *arr, uint64_t *ret);
bool wm_uintarray_remove(UIntArray *arr, size_t index);
void wm_uintarray_free(UIntArray *arr);
uint64_t wm_uintarray_2d_index(UIntArray *arr, size_t i, size_t j);
TreeNode* wm_treenode_ptr_find_focused_client_node(TreeNode *root); TreeNode* wm_treenode_ptr_find_focused_client_node(TreeNode *root);
TreeNode* wm_treenode_ptr_find_client_node(TreeNode *root, Client *client); TreeNode* wm_treenode_ptr_find_client_node(TreeNode *root, Client *client);
NodeArray* wm_treenode_find_client_nodes(TreeNode *root); NodeArray* wm_treenode_find_client_nodes(TreeNode *root);