rewrite PtrArray to UIntArray, logging updates
This commit is contained in:
parent
a2384822d8
commit
0fefb31535
211
src/util.c
211
src/util.c
@ -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;
|
||||
}
|
||||
|
||||
|
23
src/util.h
23
src/util.h
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user