start documentation
This commit is contained in:
parent
6463faf8b6
commit
d9d49f58bc
10
README.md
10
README.md
@ -1,3 +1,11 @@
|
|||||||
# libflint
|
# libflint
|
||||||
|
|
||||||
My personal library of common C data structures and algorithms.
|
My personal library of common C data structures and algorithms. Supports Linux, OpenBSD, and FreeBSD.
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
Extensive documentation can be found [here](https://docs.fputs.com/libflint/index.html)
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
Building on Linux requires `libbsd`.
|
4
build.sh
4
build.sh
@ -1,8 +1,10 @@
|
|||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
# For building outside of CLion
|
||||||
|
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
cd build
|
cd build
|
||||||
cmake ..
|
cmake ..
|
||||||
make
|
make
|
||||||
cp compile_commands.json ..
|
cp compile_commands.json ..
|
||||||
cd
|
cd
|
||||||
|
BIN
docs/flinty.jpg
Normal file
BIN
docs/flinty.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
19
docs/index.md
Normal file
19
docs/index.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# libflint
|
||||||
|
|
||||||
|
`libflint` is a library of common C data structures and algorithms, designed to be as agnostic as possible for its
|
||||||
|
users.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
The only requirement is `libbsd`. This should be available on all major Linux distros. If building on a bsd, then
|
||||||
|
|
||||||
|
## Memory Management
|
||||||
|
|
||||||
|
The parts of this library that create data structures pass all responsibility of memory management to the user. This
|
||||||
|
is clearly documented in the individual module's documentation.
|
||||||
|
|
||||||
|
## Why 'libflint'?
|
||||||
|
|
||||||
|
`libflint` is named after my dog Flint, who passed away in 2021. I miss you, buddy.
|
||||||
|
|
||||||
|
![flint](flinty.jpg)
|
202
docs/lfbinarytree.md
Normal file
202
docs/lfbinarytree.md
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
# lfbinarytree
|
||||||
|
|
||||||
|
Binary tree with standard leaf operations
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Create the tree. The user is responsible for memory management of the `BinTree` struct.
|
||||||
|
|
||||||
|
```c
|
||||||
|
BinTree *tree = malloc(sizeof(BinTree));
|
||||||
|
```
|
||||||
|
|
||||||
|
After the tree is created, init it. The second argument on `bintree_init()` is an optional memory freeing function pointer
|
||||||
|
with signature `void (*destroy)(void *data)`. Use `free()` from the stdlib if you are creating the data with `malloc()`.
|
||||||
|
If allocation of your data is more complex, you can pass your own memory deallocation function as long as it fits the
|
||||||
|
signature.
|
||||||
|
|
||||||
|
In this example, we are passing `NULL` because all memory will be stack allocated.
|
||||||
|
|
||||||
|
```c
|
||||||
|
bintree_init(tree, NULL);
|
||||||
|
int root = 0;
|
||||||
|
int l1 = 1;
|
||||||
|
int l2 = 2;
|
||||||
|
int r1 = 12;
|
||||||
|
int r2 = 200;
|
||||||
|
```
|
||||||
|
|
||||||
|
Next lets insert our data into the tree. The insert functions signature is `bintree_ins_...(tree, parent, data)`. If you
|
||||||
|
are inserting data at the root of the tree, you may use either `bintree_ins_left()` or `bintree_ins_right()` as long as
|
||||||
|
`NULL` is passed as the parent argument.
|
||||||
|
|
||||||
|
```c
|
||||||
|
bintree_ins_left(tree, NULL, &root);
|
||||||
|
bintree_ins_left(tree, tree->root, &l1);
|
||||||
|
bintree_ins_left(tree, tree->root->left, &l2);
|
||||||
|
bintree_ins_right(tree, tree->root->left, &r2);
|
||||||
|
bintree_ins_right(tree, tree->root, &r1);
|
||||||
|
bintree_ins_right(tree, tree->root->right, &r2);
|
||||||
|
bintree_ins_left(tree, tree->root->right, &l1);
|
||||||
|
```
|
||||||
|
|
||||||
|
We can use `bintree_debug_print(tree)` to print a graphical representation of the tree to `stdout`
|
||||||
|
```plaintext
|
||||||
|
└──0
|
||||||
|
├──1
|
||||||
|
│ ├──2
|
||||||
|
│ └──200
|
||||||
|
└──12
|
||||||
|
├──1
|
||||||
|
└──200
|
||||||
|
```
|
||||||
|
|
||||||
|
To cleanup the tree, first destroy the nodes. If you passed a deallocation function, it will be called on
|
||||||
|
the data member of each node before the node itself is freed. `bintree_destroy()` does not free the tree itself, just the
|
||||||
|
nodes inside of it, hence we must also call `free()` on the tree.
|
||||||
|
|
||||||
|
```c
|
||||||
|
bintree_destroy(tree);
|
||||||
|
free(tree);
|
||||||
|
tree = NULL;
|
||||||
|
```
|
||||||
|
|
||||||
|
Here is the entire example:
|
||||||
|
|
||||||
|
```c
|
||||||
|
BinTree *tree = malloc(sizeof(BinTree));
|
||||||
|
bintree_init(tree, NULL);
|
||||||
|
|
||||||
|
int root = 0;
|
||||||
|
int l1 = 1;
|
||||||
|
int l2 = 2;
|
||||||
|
int r1 = 12;
|
||||||
|
int r2 = 200;
|
||||||
|
|
||||||
|
bintree_ins_left(tree, NULL, &root);
|
||||||
|
bintree_ins_left(tree, tree->root, &l1);
|
||||||
|
bintree_ins_left(tree, tree->root->left, &l2);
|
||||||
|
bintree_ins_right(tree, tree->root->left, &r2);
|
||||||
|
bintree_ins_right(tree, tree->root, &r1);
|
||||||
|
bintree_ins_right(tree, tree->root->right, &r2);
|
||||||
|
bintree_ins_left(tree, tree->root->right, &l1);
|
||||||
|
|
||||||
|
bintree_debug_print(tree);
|
||||||
|
|
||||||
|
bintree_destroy(tree);
|
||||||
|
free(tree);
|
||||||
|
tree = NULL;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Structs
|
||||||
|
|
||||||
|
### BinTree
|
||||||
|
|
||||||
|
Binary tree struct
|
||||||
|
|
||||||
|
```c
|
||||||
|
typedef struct {
|
||||||
|
int size;
|
||||||
|
int (*compare)(const void *a, const void *b);
|
||||||
|
void (*destroy)(void *data);
|
||||||
|
struct BinTreeNode *root;
|
||||||
|
} BinTree;
|
||||||
|
```
|
||||||
|
|
||||||
|
Members:
|
||||||
|
|
||||||
|
- `size`: How many nodes the tree contains
|
||||||
|
- `compare`: Comparison function between data in two nodes. Currently not used for anything
|
||||||
|
- `destroy`: Optional deallocation function for data inside a node. Typical usage is `NULL` for stack allocated data and `free()` for data created with `malloc()`
|
||||||
|
- `root`: The root node of the tree
|
||||||
|
|
||||||
|
### BinTreeNode
|
||||||
|
|
||||||
|
Node of the tree
|
||||||
|
|
||||||
|
```c
|
||||||
|
typedef struct BinTreeNode {
|
||||||
|
void *data;
|
||||||
|
struct BinTreeNode *left;
|
||||||
|
struct BinTreeNode *right;
|
||||||
|
} BinTreeNode;
|
||||||
|
```
|
||||||
|
|
||||||
|
Members:
|
||||||
|
- `data`: void pointer to data the node contains
|
||||||
|
- `left`: left facing leaf of the node
|
||||||
|
- `right`: right facing leaf of the node
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
### bintree_init
|
||||||
|
|
||||||
|
Initialize the binary tree. User is responsible for freeing memory with `bintree_destroy()`.
|
||||||
|
|
||||||
|
```c
|
||||||
|
void bintree_init(BinTree *tree, void (*destroy)(void *data))
|
||||||
|
```
|
||||||
|
|
||||||
|
### bintree_destroy
|
||||||
|
|
||||||
|
Destroys the nodes inside a tree and calls the deallaction function on the data if one was provided. Does not deallocate the tree itself, that is left to the user
|
||||||
|
|
||||||
|
```c
|
||||||
|
void bintree_destroy(BinTree *tree)
|
||||||
|
```
|
||||||
|
|
||||||
|
### bintree_ins_left
|
||||||
|
|
||||||
|
Creates a new node containing `data` and inserts it as the left child of `node`
|
||||||
|
|
||||||
|
```c
|
||||||
|
int bintree_ins_left(BinTree *tree, BinTreeNode *node, void *data)
|
||||||
|
```
|
||||||
|
|
||||||
|
### bintree_ins_right
|
||||||
|
|
||||||
|
Creates a new node containing `data` and inserts it as the right child of `node`.
|
||||||
|
|
||||||
|
```c
|
||||||
|
int bintree_ins_right(BinTree *tree, BinTreeNode *node, void *data)
|
||||||
|
```
|
||||||
|
|
||||||
|
### bintree_rem_left
|
||||||
|
|
||||||
|
Removes and deallocates the left child node of `node`. Calls the deallocation function on the data if one was provided
|
||||||
|
|
||||||
|
```c
|
||||||
|
void bintree_rem_left(BinTree *tree, BinTreeNode *node)
|
||||||
|
```
|
||||||
|
|
||||||
|
### bintree_rem_right
|
||||||
|
|
||||||
|
Removes and deallocates the right child node of `node`. Calls the deallocation function on the data if one was provided
|
||||||
|
|
||||||
|
```c
|
||||||
|
void bintree_rem_right(BinTree *tree, BinTreeNode *node)
|
||||||
|
```
|
||||||
|
|
||||||
|
### bintree_debug_print
|
||||||
|
|
||||||
|
Prints a representation of the tree to stdout. Gets very messy with large trees
|
||||||
|
|
||||||
|
```c
|
||||||
|
void bintree_debug_print(BinTree *tree)
|
||||||
|
```
|
||||||
|
|
||||||
|
### bintree_is_eob
|
||||||
|
|
||||||
|
Utility macro that checks if the node is the End Of Branch
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define bintree_is_eob(node) ((node) == NULL)
|
||||||
|
```
|
||||||
|
|
||||||
|
### bintree_is_leaf
|
||||||
|
|
||||||
|
Utility macro that checks if a node has children
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define bintree_is_leaf(node) ((node)->left == NULL && (node)->right == NULL)
|
||||||
|
```
|
8
docs/lfbool.md
Normal file
8
docs/lfbool.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# lfbool
|
||||||
|
|
||||||
|
Macro representation of truthy values
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define LFTRUE 1
|
||||||
|
#define LFFALSE 0
|
||||||
|
```
|
88
docs/lfinput.md
Normal file
88
docs/lfinput.md
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
# lfinput
|
||||||
|
|
||||||
|
I/O module to assist with consuming data from files
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
### get_input
|
||||||
|
|
||||||
|
Reads a file at `path` and returns the contents as a single string. The string is allocated inside the function and
|
||||||
|
the user is responsible for freeing it when finished.
|
||||||
|
|
||||||
|
```c
|
||||||
|
char *get_input(const char *path);
|
||||||
|
|
||||||
|
/* Usage */
|
||||||
|
char *str = get_input("/home/evan/textfile");
|
||||||
|
free(str);
|
||||||
|
```
|
||||||
|
|
||||||
|
### get_lines
|
||||||
|
|
||||||
|
Reads a file at `path` and returns the contents as an array of strings. The newline character `\n` is used as the
|
||||||
|
delimiter to determine where the file is split. The user is responsible for cleaning up the memory using `del_lines()`.
|
||||||
|
`lsz` is set to the number of lines in the array.
|
||||||
|
|
||||||
|
```c
|
||||||
|
char **get_lines(const char *path, size_t *lsz);
|
||||||
|
|
||||||
|
/* Usage */
|
||||||
|
size_t sz = 0;
|
||||||
|
char **lines = get_lines("/home/evan/textfile", &sz);
|
||||||
|
for (size_t i = 0; i < sz; i++) {
|
||||||
|
printf("%s\n", lines[i]);
|
||||||
|
}
|
||||||
|
del_lines(lines);
|
||||||
|
```
|
||||||
|
|
||||||
|
### del_lines
|
||||||
|
|
||||||
|
Frees all memory used by `get_lines()`
|
||||||
|
|
||||||
|
```c
|
||||||
|
void del_lines(char **lines);
|
||||||
|
```
|
||||||
|
|
||||||
|
### get_ints
|
||||||
|
Reads a file at `path` and returns the contents as an array of integers. The file is assumed to be a newline seperated
|
||||||
|
list of integers and nothing else.
|
||||||
|
|
||||||
|
The newline character `\n` is used as the delimiter to determine where the file is split. The user is responsible for
|
||||||
|
cleaning up the memory using `free()`. `lsz` is set to the number of lines in the array.
|
||||||
|
|
||||||
|
```c
|
||||||
|
int *get_ints(const char *path, size_t *lsz);
|
||||||
|
|
||||||
|
/* Usage */
|
||||||
|
int *nums = get_ints("/home/evan/intfile");
|
||||||
|
for (size_t i = 0; i < sz; i++) {
|
||||||
|
printf("%d\n", nums[i]);
|
||||||
|
}
|
||||||
|
free(nums);
|
||||||
|
```
|
||||||
|
|
||||||
|
### split
|
||||||
|
|
||||||
|
Takes a string `s` and splits it into an array of strings based on the delimiter. `s` is left unchanged. The user is
|
||||||
|
responsible for cleaning up the memory of the split using `del_split()`. `sp_sz` is set to the size of the split.
|
||||||
|
|
||||||
|
```c
|
||||||
|
char **split(char *s, size_t *lsz, const char *delim)
|
||||||
|
|
||||||
|
/* Usage */
|
||||||
|
size_t sp_sz = 0;
|
||||||
|
char **sp = split("Split on whitespace", &sp_sz, " ");
|
||||||
|
printf("%s\n", sp[0]); // Prints "Split"
|
||||||
|
```
|
||||||
|
|
||||||
|
### del_split
|
||||||
|
|
||||||
|
Frees all memory used by `split()`. Just like `split`, it does not touch the original string
|
||||||
|
```c
|
||||||
|
void del_split(char **sp);
|
||||||
|
|
||||||
|
/* Usage */
|
||||||
|
size_t sp_sz = 0;
|
||||||
|
char **sp = split("Delete Me!", &sp_sz, " ");
|
||||||
|
void del_split(char **sp);
|
||||||
|
```
|
3
docs/lflinkedlist.md
Normal file
3
docs/lflinkedlist.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# lflinkedlist
|
||||||
|
|
||||||
|
Coming soon
|
3
docs/lfmath.md
Normal file
3
docs/lfmath.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# lfmath
|
||||||
|
|
||||||
|
Coming soon
|
3
docs/lfset.md
Normal file
3
docs/lfset.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# lfset
|
||||||
|
|
||||||
|
Coming soon
|
3
docs/lfstack.md
Normal file
3
docs/lfstack.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# lfstack
|
||||||
|
|
||||||
|
Coming soon
|
16
docs/lfutility.md
Normal file
16
docs/lfutility.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# lfutility
|
||||||
|
|
||||||
|
Utility code that does not fit anywhere else
|
||||||
|
|
||||||
|
## Structs
|
||||||
|
|
||||||
|
### Point
|
||||||
|
|
||||||
|
Representation of a point on a two dimensional grid
|
||||||
|
|
||||||
|
```c
|
||||||
|
typedef struct {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
} Point;
|
||||||
|
```
|
16
mkdocs.yml
Normal file
16
mkdocs.yml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
site_name: libflint
|
||||||
|
site_url: https://example.com
|
||||||
|
theme:
|
||||||
|
name: readthedocs
|
||||||
|
nav:
|
||||||
|
- 'index.md'
|
||||||
|
- 'Modules':
|
||||||
|
- 'Boolean': 'lfbool.md'
|
||||||
|
- 'Input': 'lfinput.md'
|
||||||
|
- 'Math': 'lfmath.md'
|
||||||
|
- 'Utility': 'lfutility.md'
|
||||||
|
- 'Data Structures':
|
||||||
|
- 'Binary Tree': 'lfbinarytree.md'
|
||||||
|
- 'Linked List': 'lflinkedlist.md'
|
||||||
|
- 'Set': 'lfset.md'
|
||||||
|
- 'Stack': 'lfstack.md'
|
Loading…
x
Reference in New Issue
Block a user