src: implement own btree
parent
5d3e174bda
commit
0ed273b7b6
|
@ -10,7 +10,7 @@ libtoml_dep = dependency(
|
||||||
|
|
||||||
exe = executable(
|
exe = executable(
|
||||||
'smeargle',
|
'smeargle',
|
||||||
['src/main.c', 'src/font.c', 'src/script.c'],
|
['src/main.c', 'src/node.c', 'src/font.c', 'src/script.c'],
|
||||||
dependencies: libtoml_dep,
|
dependencies: libtoml_dep,
|
||||||
install: true
|
install: true
|
||||||
)
|
)
|
31
src/font.c
31
src/font.c
|
@ -4,19 +4,15 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
|
|
||||||
void *fontdb;
|
int font_compare(const node_t *a, const node_t *b) {
|
||||||
|
const font_t *x = (const font_t *)a->data;
|
||||||
int font_compare(const void *a, const void *b) {
|
const font_t *y = (const font_t *)b->data;
|
||||||
const font_t *x = (const font_t *)a;
|
|
||||||
const font_t *y = (const font_t *)b;
|
|
||||||
|
|
||||||
return strcmp(x->name, y->name);
|
return strcmp(x->name, y->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
font_t *load_fonts(toml_table_t *table, const char *base_path) {
|
node_t *load_fonts(toml_table_t *table, const char *base_path) {
|
||||||
font_t *fonts = calloc(32, sizeof(font_t));
|
node_t *root = NULL;
|
||||||
font_t *fontptr = fonts;
|
|
||||||
fontdb = NULL;
|
|
||||||
|
|
||||||
// vast majority of projects should have only 1-2 fonts, but let's offer
|
// vast majority of projects should have only 1-2 fonts, but let's offer
|
||||||
// some room in case there's more.
|
// some room in case there's more.
|
||||||
|
@ -24,23 +20,24 @@ font_t *load_fonts(toml_table_t *table, const char *base_path) {
|
||||||
const char *key = toml_key_in(table, i);
|
const char *key = toml_key_in(table, i);
|
||||||
if (!key) break;
|
if (!key) break;
|
||||||
char fullname[200];
|
char fullname[200];
|
||||||
|
font_t font;
|
||||||
|
|
||||||
toml_datum_t filename = toml_string_in(table, key);
|
toml_datum_t filename = toml_string_in(table, key);
|
||||||
if (!filename.ok) {
|
if (!filename.ok) {
|
||||||
error("couldn't load font ", key);
|
error("couldn't load font ", key);
|
||||||
}
|
}
|
||||||
snprintf(fullname, 200, "%s/%s", base_path, filename.u.s);
|
snprintf(fullname, 200, "%s/%s", base_path, filename.u.s);
|
||||||
fonts[i] = font_create(key, fullname);
|
font = font_create(key, fullname);
|
||||||
|
root = node_insert(root, &font, font_compare);
|
||||||
tsearch((void *)fontptr, (void **)fontdb, font_compare);
|
|
||||||
fontptr++;
|
|
||||||
}
|
}
|
||||||
return fonts;
|
return root;
|
||||||
}
|
}
|
||||||
font_t *font_find(const char *key) {
|
font_t *font_find(node_t *root, const char *key) {
|
||||||
font_t *font = (font_t *)tfind(key, (void **)fontdb, font_compare);
|
font_t search = {.name = key};
|
||||||
|
node_t *node = node_search(root, &search, font_compare);
|
||||||
|
font_t *font = (font_t *)node->data;
|
||||||
|
|
||||||
if (!font) {
|
if (font == NULL) {
|
||||||
error("couldn't find requested font ", key);
|
error("couldn't find requested font ", key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
src/font.h
10
src/font.h
|
@ -1,6 +1,8 @@
|
||||||
#ifndef _SMEARGLE_FONT_H
|
#ifndef _SMEARGLE_FONT_H
|
||||||
#define _SMEARGLE_FONT_H
|
#define _SMEARGLE_FONT_H
|
||||||
|
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
typedef struct map_t {
|
typedef struct map_t {
|
||||||
const char *glyph;
|
const char *glyph;
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
|
@ -9,8 +11,8 @@ typedef struct map_t {
|
||||||
} map_t;
|
} map_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *name;
|
const char *name;
|
||||||
char *image_filename;
|
const char *image_filename;
|
||||||
unsigned char bits_per_pixel;
|
unsigned char bits_per_pixel;
|
||||||
unsigned int width;
|
unsigned int width;
|
||||||
unsigned int height;
|
unsigned int height;
|
||||||
|
@ -20,8 +22,8 @@ typedef struct {
|
||||||
|
|
||||||
extern void *fontdb;
|
extern void *fontdb;
|
||||||
|
|
||||||
font_t *load_fonts(toml_table_t *table, const char *base_path);
|
node_t *load_fonts(toml_table_t *table, const char *base_path);
|
||||||
font_t *font_find(const char *key);
|
font_t *font_find(node_t *root, const char *key);
|
||||||
font_t font_create(const char *name, const char *filename);
|
font_t font_create(const char *name, const char *filename);
|
||||||
void font_destroy(font_t font);
|
void font_destroy(font_t font);
|
||||||
unsigned int map_create(toml_table_t *table, map_t **map);
|
unsigned int map_create(toml_table_t *table, map_t **map);
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#include <toml.h>
|
#include <toml.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "node.h"
|
||||||
|
#include "font.h"
|
||||||
#include "script.h"
|
#include "script.h"
|
||||||
|
|
||||||
#define ERRBUFSZ 200
|
#define ERRBUFSZ 200
|
||||||
|
@ -40,7 +42,7 @@ int main(int argc, char **argv) {
|
||||||
if (!font) {
|
if (!font) {
|
||||||
error("couldn't find font table in ", argv[1]);
|
error("couldn't find font table in ", argv[1]);
|
||||||
}
|
}
|
||||||
font_t *fonts = load_fonts(font, base_path);
|
node_t *fonts = load_fonts(font, base_path);
|
||||||
|
|
||||||
toml_array_t *scripts = toml_array_in(conf, "script");
|
toml_array_t *scripts = toml_array_in(conf, "script");
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
|
node_t *node_create(void *data) {
|
||||||
|
node_t *temp = malloc(sizeof(node_t));
|
||||||
|
|
||||||
|
temp->data = data;
|
||||||
|
temp->left = temp->right = NULL;
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
node_t *node_search(node_t *root, void *data, node_comparator func) {
|
||||||
|
int cmp;
|
||||||
|
if (root == NULL) {
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
node_t *temp = node_create(data);
|
||||||
|
cmp = func(root, temp);
|
||||||
|
free(temp);
|
||||||
|
|
||||||
|
if (cmp == 0) {
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmp < 0) {
|
||||||
|
return node_search(root->left, data, func);
|
||||||
|
} else {
|
||||||
|
return node_search(root->right, data, func);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
node_t *node_insert(node_t *node, void *data, node_comparator func) {
|
||||||
|
if (node == NULL) {
|
||||||
|
return node_create(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
node_t *temp = node_create(data);
|
||||||
|
int cmp = func(node, temp);
|
||||||
|
free(temp);
|
||||||
|
|
||||||
|
if (cmp < 0) {
|
||||||
|
node->left = node_insert(node->left, data, func);
|
||||||
|
} else {
|
||||||
|
node->right = node_insert(node->right, data, func);
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
node_t *node_find_leftmost(node_t *root) {
|
||||||
|
if (root == NULL) {
|
||||||
|
return NULL;
|
||||||
|
} else if (root->left != NULL) {
|
||||||
|
return node_find_leftmost(root->left);
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
node_t *node_remove(node_t *root, void *data, node_comparator func) {
|
||||||
|
if (root == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
node_t *temp = node_create(data);
|
||||||
|
int cmp = func(root, temp);
|
||||||
|
free(temp);
|
||||||
|
|
||||||
|
if (cmp > 0) {
|
||||||
|
root->right = node_remove(root->right, data, func);
|
||||||
|
} else if (cmp < 0) {
|
||||||
|
root->left = node_remove(root->left, data, func);
|
||||||
|
} else {
|
||||||
|
if ((root->left == NULL) && (root->right == NULL)) {
|
||||||
|
free(root);
|
||||||
|
return NULL;
|
||||||
|
} else if ((root->left == NULL) || (root->right == NULL)) {
|
||||||
|
if (root->left == NULL) {
|
||||||
|
temp = root->right;
|
||||||
|
} else {
|
||||||
|
temp = root->left;
|
||||||
|
}
|
||||||
|
free(temp);
|
||||||
|
} else {
|
||||||
|
temp = node_find_leftmost(root->right);
|
||||||
|
root->data = temp->data;
|
||||||
|
root->right = node_remove(root->right, temp->data, func);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
#ifndef _SMEARGLE_NODE_H
|
||||||
|
#define _SMEARGLE_NODE_H
|
||||||
|
|
||||||
|
typedef struct node_t {
|
||||||
|
void *data;
|
||||||
|
struct node_t *left, *right;
|
||||||
|
} node_t;
|
||||||
|
|
||||||
|
typedef int(node_comparator)(const node_t *a, const node_t *b);
|
||||||
|
|
||||||
|
node_t *node_create(void *data);
|
||||||
|
node_t *node_search(node_t *root, void *data, node_comparator func);
|
||||||
|
node_t *node_insert(node_t *node, void *data, node_comparator func);
|
||||||
|
node_t *node_find_leftmost(node_t *root);
|
||||||
|
node_t *node_remove(node_t *root, void *data, node_comparator func);
|
||||||
|
|
||||||
|
#endif
|
|
@ -5,7 +5,7 @@
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
script_t script_create(toml_table_t *table, const char *base_path, font_t *fonts) {
|
script_t script_create(toml_table_t *table, const char *base_path, node_t *fonts) {
|
||||||
script_t script;
|
script_t script;
|
||||||
|
|
||||||
#define TOML_GET_KEY(var, key, func) toml_datum_t (var) = func(table, (key));\
|
#define TOML_GET_KEY(var, key, func) toml_datum_t (var) = func(table, (key));\
|
||||||
|
@ -29,7 +29,11 @@ script_t script_create(toml_table_t *table, const char *base_path, font_t *fonts
|
||||||
TOML_GET_KEY(little_endian, "little_endian", toml_bool_in)
|
TOML_GET_KEY(little_endian, "little_endian", toml_bool_in)
|
||||||
#undef TOML_GET_KEY
|
#undef TOML_GET_KEY
|
||||||
|
|
||||||
font_t *font = font_find(font_name.u.s);
|
node_t *node = font_find(fonts, font_name.u.s);
|
||||||
|
if (node == NULL) {
|
||||||
|
error("couldn't find font ", font_name.u.s);
|
||||||
|
}
|
||||||
|
font_t *font = node->data;
|
||||||
|
|
||||||
script.filename = filename.u.s;
|
script.filename = filename.u.s;
|
||||||
script.font = *font;
|
script.font = *font;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
|
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *name;
|
char *name;
|
||||||
|
@ -22,7 +23,7 @@ typedef struct {
|
||||||
bool little_endian;
|
bool little_endian;
|
||||||
} script_t;
|
} script_t;
|
||||||
|
|
||||||
script_t script_create(toml_table_t *table, const char *base_path, font_t *fonts);
|
script_t script_create(toml_table_t *table, const char *base_path, node_t *fonts);
|
||||||
void script_destroy(script_t script);
|
void script_destroy(script_t script);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <search.h>
|
|
||||||
|
|
||||||
static void error(const char *msg, const char *msg1) {
|
static void error(const char *msg, const char *msg1) {
|
||||||
fprintf(stderr, "Error: %s%s\n", msg, msg1 ? msg1 : "");
|
fprintf(stderr, "Error: %s%s\n", msg, msg1 ? msg1 : "");
|
||||||
|
|
Loading…
Reference in New Issue