]> git.lizzy.rs Git - nothing.git/blob - src/ui/history.c
(#478) replace all calloc instance with nth_calloc
[nothing.git] / src / ui / history.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
4
5 #include "history.h"
6 #include "str.h"
7 #include "system/error.h"
8 #include "system/lt.h"
9 #include "system/nth_alloc.h"
10
11 struct History
12 {
13     Lt *lt;
14
15     char **buffer;
16     size_t begin;
17     size_t capacity;
18     size_t cursor;
19 };
20
21 History *create_history(size_t capacity)
22 {
23     Lt *lt = create_lt();
24     if (lt == NULL) {
25         return NULL;
26     }
27
28     History *history = PUSH_LT(
29         lt,
30         nth_alloc(sizeof(History)),
31         free);
32     if (history == NULL) {
33         throw_error(ERROR_TYPE_LIBC);
34         RETURN_LT(lt, NULL);
35     }
36     history->lt = lt;
37
38     history->capacity = capacity;
39     history->begin = 0;
40     history->cursor = 0;
41
42     history->buffer = PUSH_LT(lt, nth_calloc(capacity, sizeof(char*)), free);
43     if (history->buffer == NULL) {
44         throw_error(ERROR_TYPE_LIBC);
45         RETURN_LT(lt, NULL);
46     }
47
48     return history;
49 }
50
51 void destroy_history(History *history)
52 {
53     assert(history);
54
55     for (size_t i = 0; i < history->capacity; ++i) {
56         if (history->buffer[i] != NULL) {
57             free(history->buffer[i]);
58         }
59     }
60
61     RETURN_LT0(history->lt);
62 }
63
64 int history_push(History *history, const char *command)
65 {
66     assert(history);
67     assert(command);
68
69     const size_t next_begin = (history->begin + 1) % history->capacity;
70
71     if (history->buffer[history->begin] != NULL) {
72         free(history->buffer[history->begin]);
73     }
74
75     history->buffer[history->begin] = string_duplicate(command, NULL);
76
77     if (history->buffer[history->begin] == NULL) {
78         return -1;
79     }
80
81     history->begin = next_begin;
82     history->cursor = next_begin;
83
84     return 0;
85 }
86
87 const char *history_current(History *history)
88 {
89     assert(history);
90     return history->buffer[history->cursor];
91 }
92
93 void history_prev(History *history)
94 {
95     assert(history);
96     if (history->cursor == 0) {
97         history->cursor = history->capacity - 1;
98     } else {
99         history->cursor--;
100     }
101 }
102
103 void history_next(History *history)
104 {
105     assert(history);
106     history->cursor = (history->cursor + 1) % history->capacity;
107 }