sorta kinda working on strings for cmenu. being lazy

This commit is contained in:
Ivar Fatland
2026-07-23 00:18:08 +02:00
parent afda89797a
commit a7507bb431
6 changed files with 157 additions and 8 deletions
+2
View File
@@ -0,0 +1,2 @@
tag:
ctags --langmap=c:.c.h --languages=c -R .
+28 -8
View File
@@ -4,6 +4,8 @@
#include <stdint.h>
#include <stdbool.h>
#include "utf.h"
typedef struct Color {
uint8_t r, g, b;
} Color;
@@ -22,23 +24,41 @@ typedef enum Key {
Count_Key
} Key;
typedef uint32_t CodePoint;
bool KeyPressed(Key key);
bool InputGetNextPrintable(CodePoint const *out_key);
typedef struct Cell {
CodePoint character;
Color foreground;
Color background;
} Cell;
typedef struct Window {
int const width;
int const height;
CodePoint *characters;
Color *foreground;
Color *background;
int width;
int height;
Cell *cells;
} Window;
Window *WindowCreate();
typedef struct PlatformState {
Window *prev;
Window *curr;
} PlatformState;
// Options for the backend. These options don't necessarily apply for all platforms.
typedef struct PlatformOpts {
float window_width_fraction; // decide the width of the window as a fraction of the total resolution. for gui backends
float window_height_fraction; // decide the height of the window as a fraction of the total resolution. for gui backends
} PlatformOpts;
PlatformOpts WindowCreateOptsDefault();
Window *WindowCreate(PlatformOpts opts);
void WindowClear(Window *window, Color color);
void WindowFlip(Window *window);
void PlatformInit(PlatformOpts opts);
int PlatformGetWidth();
int PlatformGetHeight();
// TODO: the platform layer would really update the keys being pressed, and
// receive a diff in the form of actions. print this line from here and change
// colors at these points.
+43
View File
@@ -0,0 +1,43 @@
#include <stddef.h>
#include "str.h"
static bool intToIndex(String string, int i, size_t *out_index) {
int val = 0;
bool is_ok = true;
if (i >= 0) {
val = i;
} else {
val = string.size + 1 + i;
}
if (val < 0) {
val = 0;
is_ok = false;
} else if (val > string.size) {
val = string.size;
is_ok = false;
}
*out_index = val;
return is_ok;
}
bool StringSub(String string, int start, int end, String *out_substr) {
size_t start_index = 0;
bool start_ok = intToIndex(string, start, &start_index);
size_t end_index = 0;
bool end_ok = intToIndex(string, end, &end_index);
if (string.size == 0 || start_index >= end_index) {
out_substr->size=0;
out_substr->buffer=NULL;
return false;
}
out_substr->buffer = &string.buffer[start_index];
out_substr->size = end_index - start_index;
return start_ok && end_ok;
}
+10
View File
@@ -0,0 +1,10 @@
#include <stddef.h>
typedef struct String {
unsigned char const *buffer;
size_t size;
} String;
#define STRING(content) ((String){.buffer=#content, .size=sizeof(#content)-1})
bool StringSub(String string, int start, int end, String *out_substr);
+65
View File
@@ -0,0 +1,65 @@
#include <stddef.h>
#include "utf.h"
#include "str.h"
typedef struct Utf8Parser {
String str;
} Utf8Parser;
bool Utf8ParserNextCodePoint(Utf8Parser *this, CodePoint *out_codepoint) {
uitn8_t const flag_1_bytes = 0;
uint8_t const mask_1_bytes = 1 << 7;
uint8_t const flag_continuation = mask_1_bytes;
uint8_t const mask_continuation = (1 << 7) | (1 << 6);
uint8_t const flag_2_bytes = mask_continuation;
uint8_t const mask_2_bytes = (1 << 7) | (1 << 6) | (1 << 5);
uint8_t const flag_3_bytes = mask_2_bytes;
uint8_t const mask_3_bytes = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4);
uint8_t const flag_4_bytes = mask_3_bytes;
uint8_t const mask_4_bytes = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 3);
if (this->str.size == 0) {
*out_codepoint = 0;
return false;
}
if ((this->str.buffer[0] & mask_1_bytes) == flag_1_bytes) {
*out_codepoint = (CodePoint) str[0];
bool ok = StringSub(this->str, 1, -1, &this->str);
assert(ok && "has to be ok since the size is not 0");
return ok;
} else
}
// max must be less than or equal to the capacity of target.
bool CodePointsFromUtf8String(
uint8_t const *str,
CodePoint *target,
int max
) {
for (size_t i = 0; str[i] != '\0' && max > 0;) {
if ((str[i] & mask_1_bytes) == flag_1_bytes) {
*target = (CodePoint) str[i];
target += 1;
max -= 1;
i += 1;
} else
if ((str[i] & mask_2_bytes) == flag_2_bytes) {
} else
if ((str[i] & mask_3_bytes) == flag_3_bytes) {
} else
if ((str[i] & mask_4_bytes) == flag_4_bytes) {
} else {
false;
}
}
return true;
}
+9
View File
@@ -0,0 +1,9 @@
#ifndef UTF
#define UTF
typedef uint32_t CodePoint;
int CodePointsFromUtf8String(char const *str, CodePoint *target, unsigned int max);
#endif // UTF