126 lines
2.5 KiB
C
126 lines
2.5 KiB
C
#include <hikari/input_buffer.h>
|
|
|
|
#include <assert.h>
|
|
#include <ctype.h>
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
|
|
#include <hikari/utf8.h>
|
|
|
|
static bool
|
|
is_empty(struct hikari_input_buffer *input_buffer)
|
|
{
|
|
size_t pos = input_buffer->pos;
|
|
|
|
assert(pos == 0 ? input_buffer->buffer[0] == '\0' : true);
|
|
|
|
return pos == 0;
|
|
}
|
|
|
|
static bool
|
|
current_char(struct hikari_input_buffer *input_buffer, char *current)
|
|
{
|
|
size_t pos = input_buffer->pos;
|
|
|
|
if (is_empty(input_buffer)) {
|
|
return false;
|
|
} else {
|
|
*current = input_buffer->buffer[pos - 1];
|
|
return true;
|
|
}
|
|
}
|
|
|
|
struct hikari_input_buffer *
|
|
hikari_input_buffer_init(
|
|
struct hikari_input_buffer *input_buffer, char *content)
|
|
{
|
|
strncpy(input_buffer->buffer, content, sizeof(input_buffer->buffer) - 1);
|
|
|
|
input_buffer->pos =
|
|
strnlen(input_buffer->buffer, sizeof(input_buffer->buffer));
|
|
|
|
return input_buffer;
|
|
}
|
|
|
|
void
|
|
hikari_input_buffer_add_char(
|
|
struct hikari_input_buffer *input_buffer, char input)
|
|
{
|
|
if (input_buffer->pos == sizeof(input_buffer->buffer) - 1) {
|
|
return;
|
|
}
|
|
|
|
input_buffer->buffer[input_buffer->pos] = input;
|
|
input_buffer->pos++;
|
|
}
|
|
|
|
void
|
|
hikari_input_buffer_add_utf32_char(
|
|
struct hikari_input_buffer *input_buffer, uint32_t codepoint)
|
|
{
|
|
size_t length = utf8_chsize(codepoint);
|
|
|
|
if (input_buffer->pos + length > sizeof(input_buffer->buffer) - 1) {
|
|
return;
|
|
}
|
|
|
|
utf8_encode(&input_buffer->buffer[input_buffer->pos], length, codepoint);
|
|
input_buffer->pos += length;
|
|
}
|
|
|
|
void
|
|
hikari_input_buffer_remove_char(struct hikari_input_buffer *input_buffer)
|
|
{
|
|
if (is_empty(input_buffer)) {
|
|
return;
|
|
}
|
|
|
|
input_buffer->pos--;
|
|
input_buffer->buffer[input_buffer->pos] = '\0';
|
|
}
|
|
|
|
void
|
|
hikari_input_buffer_remove_word(struct hikari_input_buffer *input_buffer)
|
|
{
|
|
if (is_empty(input_buffer)) {
|
|
return;
|
|
}
|
|
|
|
for (;;) {
|
|
hikari_input_buffer_remove_char(input_buffer);
|
|
|
|
char current;
|
|
bool has_char = current_char(input_buffer, ¤t);
|
|
|
|
if (!has_char || isspace(current)) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
hikari_input_buffer_clear(struct hikari_input_buffer *input_buffer)
|
|
{
|
|
memset(input_buffer->buffer, 0, sizeof(input_buffer->buffer));
|
|
input_buffer->pos = 0;
|
|
}
|
|
|
|
void
|
|
hikari_input_buffer_replace(
|
|
struct hikari_input_buffer *input_buffer, char *content)
|
|
{
|
|
hikari_input_buffer_clear(input_buffer);
|
|
char *c = content;
|
|
|
|
for (int i = 0; i < sizeof(input_buffer->buffer) && *c != '\0'; i++) {
|
|
hikari_input_buffer_add_char(input_buffer, *c);
|
|
c++;
|
|
}
|
|
}
|
|
|
|
char *
|
|
hikari_input_buffer_read(struct hikari_input_buffer *input_buffer)
|
|
{
|
|
return input_buffer->buffer;
|
|
}
|