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 "wm.h"
#include <fcntl.h>
#include <stdint.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <json-c/json_object.h>
#include <json-c/json_tokener.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.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;
@ -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)
{
assert(node);
@ -166,9 +193,10 @@ char* wm_treenode_to_str(TreeNode *node)
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++) {
TreeNode *node = wm->smon->workspaces[i].tree;
@ -179,11 +207,11 @@ PtrArray wm_nonempty_workspaces_to_strptrarray(Wm *wm)
.ws_index = i,
.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;
}
@ -193,34 +221,83 @@ void wm_log_state(Wm *wm, const char *prefixstr, const char* logfile)
RETURN_IF_NULL(prefixstr);
RETURN_IF_NULL(logfile);
FILE *fptr = fopen(logfile, "a");
if (!fptr) {
fprintf(stderr, "wm: could not open log file %s\n", logfile);
return;
}
PtrArray ws_str = wm_nonempty_workspaces_to_strptrarray(wm);
UIntArray *ws_str = wm_nonempty_workspaces_to_strptrarray(wm);
char str[128] = {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_object_add(log_entry_obj, prefix, json_object_new_object());
for (size_t i = 0; i < ws_str.size; i++) {
WmWorkspaceToStrRet *ws_with_index = (WmWorkspaceToStrRet*)ws_str.ptrs[i];
for (size_t i = 0; i < ws_str->size; i++) {
WmWorkspaceToStrRet *ws_with_index = (WmWorkspaceToStrRet*)
wm_uintarray_at(ws_str, i);
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));
fprintf(fptr, "%s,\n", json_object_to_json_string_ext(log_entry_obj, JSON_C_TO_STRING_PRETTY));
json_object_object_add(log_entry_obj, str, json_tokener_parse(ws_with_index->str));
free(ws_with_index->str);
free(ws_with_index);
}
json_object_put(log_entry_obj);
fflush(fptr);
fclose(fptr);
wm_ptrarray_free(&ws_str);
int fd = -1;
struct json_object *jobj = NULL;
if (access(logfile, F_OK) != 0) {
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)
@ -671,45 +748,54 @@ void wm_nodearray_free(NodeArray *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.ptrs = calloc(arr.capacity, sizeof(void*));
assert(arr.ptrs);
arr.size = 0;
arr->capacity = 10;
arr->elements = calloc(arr->capacity, sizeof(void*));
assert(arr->elements);
arr->size = 0;
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);
arr->size++;
if (arr->size >= arr->capacity) {
void* temp = calloc(arr->capacity, sizeof(void*));
void* temp = calloc(arr->capacity, sizeof(uint64_t));
assert(temp);
memcpy(temp, arr->ptrs, arr->capacity * sizeof(void*));
free(arr->ptrs);
memcpy(temp, arr->elements, arr->capacity * sizeof(uint64_t));
free(arr->elements);
size_t old_capacity = arr->capacity;
arr->capacity = old_capacity * 2;
arr->ptrs = calloc(arr->capacity, sizeof(void*));
assert(arr->ptrs);
memcpy(arr->ptrs, temp, old_capacity * sizeof(void*));
arr->elements = calloc(arr->capacity, sizeof(uint64_t));
assert(arr->elements);
memcpy(arr->elements, temp, old_capacity * sizeof(uint64_t));
free(temp);
arr->ptrs[arr->size - 1] = ptr;
arr->elements[arr->size - 1] = element;
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__);
assert(arr);
@ -718,12 +804,12 @@ bool wm_ptrarray_pop(PtrArray *arr, void **ret)
if (arr->size == 0)
return false;
*ret = arr->ptrs[arr->size - 1];
*ret = arr->elements[arr->size - 1];
arr->size--;
return true;
}
bool wm_ptrarray_pop_front(PtrArray *arr, void **ret)
bool wm_uintarray_pop_front(UIntArray *arr, uint64_t *ret)
{
assert(arr);
assert(ret);
@ -731,14 +817,14 @@ bool wm_ptrarray_pop_front(PtrArray *arr, void **ret)
if (arr->size == 0)
return false;
*ret = arr->ptrs[0];
*ret = arr->elements[0];
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;
}
bool wm_ptrarray_remove(PtrArray *arr, size_t index)
bool wm_uintarray_remove(UIntArray *arr, size_t index)
{
DEBUG_PRINT("%s\n", __func__);
assert(arr);
@ -754,21 +840,32 @@ bool wm_ptrarray_remove(PtrArray *arr, size_t index)
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;
}
void wm_ptrarray_free(PtrArray *arr)
void wm_uintarray_free(UIntArray *arr)
{
// DEBUG_PRINT("%s\n", __func__);
assert(arr);
RETURN_IF_NULL(arr->ptrs);
RETURN_IF_NULL(arr->elements);
arr->capacity = 0;
arr->size = 0;
free(arr->ptrs);
arr->ptrs = NULL;
free(arr->elements);
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)
@ -781,14 +878,14 @@ TreeNode* wm_treenode_ptr_find_focused_client_node(TreeNode *root)
NodeArray *visited = wm_nodearray_new();
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;
if (!wm_ptrarray_pop_front(&queue, (void**)&node))
if (!wm_nodearray_pop_front(queue, &node))
goto ret;
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) {
wm_nodearray_push(visited, child_node);
wm_ptrarray_push(&queue, child_node);
wm_nodearray_push(queue, child_node);
}
}
}
ret:
wm_nodearray_free(visited);
wm_ptrarray_free(&queue);
wm_nodearray_free(queue);
return ret;
}

View File

@ -2,6 +2,7 @@
#define UTIL_H
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <json-c/json.h>
@ -30,10 +31,10 @@ typedef struct {
} NodeArray;
typedef struct {
void **ptrs;
uint64_t *elements;
size_t size;
size_t capacity;
} PtrArray;
} UIntArray;
typedef struct {
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);
void wm_tree_to_DOT(TreeNode *root, const char *filename);
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);
void wm_treenode_print(TreeNode *node);
PtrArray wm_ptrarray_new();
void wm_ptrarray_push(PtrArray *arr, void* ptr);
bool wm_ptrarray_pop(PtrArray *arr, void **ret);
bool wm_ptrarray_pop_front(PtrArray *arr, void **ret);
bool wm_ptrarray_remove(PtrArray *arr, size_t index);
void wm_ptrarray_free(PtrArray *arr);
UIntArray* wm_uintarray_new();
uint64_t wm_uintarray_at(UIntArray *arr, size_t index);
void wm_uintarray_set(UIntArray *arr, size_t index, uint64_t value);
void wm_uintarray_push(UIntArray *arr, uint64_t element);
bool wm_uintarray_pop(UIntArray *arr, uint64_t *ret);
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_client_node(TreeNode *root, Client *client);
NodeArray* wm_treenode_find_client_nodes(TreeNode *root);