commit cursetree

This commit is contained in:
Emile Clark-Boman 2025-09-27 20:46:05 +10:00
parent 7f4f9941de
commit 9b0e752b8a
8 changed files with 95 additions and 37 deletions

47
flake.nix Normal file
View file

@ -0,0 +1,47 @@
{
description = "devshell-cursetree";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
};
outputs = inputs @ {
self,
nixpkgs,
}: let
defaultSystems = ["aarch64-darwin" "aarch64-linux" "i686-linux" "x86_64-darwin" "x86_64-linux"];
forAllSystems = f:
nixpkgs.lib.genAttrs defaultSystems (system:
f system (import nixpkgs {
inherit system;
overlays = builtins.attrValues self.overlays;
}));
in {
overlays.default = final: prev: {};
devShells = forAllSystems (
system: pkgs: let
lib = pkgs.lib;
in {
default = pkgs.mkShell {
packages = with pkgs; [
gnumake
gcc
# Language/Development Tooling
clang-tools
bear # clang compile_commands.json
valgrind
];
};
}
);
checks = self.packages;
packages = forAllSystems (system: pkgs: rec {
default = cursetree;
cursetree = pkgs.cursetree;
});
};
}

View file

@ -1,7 +1,15 @@
#ifndef _CURSETREE__SHARED_H
#define _CURSETREE__SHARED_H
/* Standard success/failure status codes. */
#define OK (0)
#define ERR (1)
/* Initial row and column coordinates. */
#define ROW0 1
#define COL0 1
typedef unsigned short pos;
typedef unsigned char glyph;
#endif /* _CURSETREE__SHARED_H */

6
src/ansi.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef CURSETREE_ANSI_H
#define CURSETREE_ANSI_H
#endif /* CURSETREE_ANSI_H */

View file

@ -6,22 +6,19 @@
#include "term.h"
int main(void) {
struct ct_term *const term = (struct ct_term *)malloc(sizeof(struct ct_term));
if (getterm(term)) {
perror("getterm");
endterm(term);
exit(1);
}
struct ct_term *const term;
int retv = OK;
if (stashterm(&term)) {
perror("saveterm");
exit(ERR);
}
if (termsize(term)) {
perror("termsize");
endterm(term);
exit(1);
retv = ERR;
goto end;
}
printf("\e[2J\e[1;1H");
char *line = (char *)malloc(sizeof(char) * (term->cols + 1));
memset(line, 'X', term->cols);
line[term->cols] = '\0';
@ -29,8 +26,10 @@ int main(void) {
for (int i=0; i < term->rows; i++) {
printf("%s", line);
}
printf("\n");
sleep(3);
endterm(term);
end:
resetterm(term);
return 0;
}

View file

@ -4,23 +4,23 @@
#include "_ct_shared.h"
#include "surface.h"
#define ALLOC_ROW(w) ((char *)calloc(w, sizeof(char)))
#define ALLOC_COLS(w) ((glyph *)calloc(w, sizeof(glyph)))
/* Allocates a new 2D surface buffer with ROWS=h, COLS=w.
* Returns NULL on failure and sets errno, otherwise
* a pointer to the new buffer is returned.
*/
static inline __attribute__((malloc, warn_unused_result)) char **
static inline __attribute__((malloc, warn_unused_result)) glyph **
sfbuf(const pos w, const pos h) {
char **buf;
glyph **buf;
pos i;
buf = (char **)malloc(sizeof(char *) * h);
buf = (glyph **)malloc(sizeof(glyph *) * h);
if (buf == NULL)
return buf;
for (i = 0; i < w; i++) {
buf[i] = ALLOC_ROW(w);
buf[i] = ALLOC_COLS(w);
if (buf[i] == NULL)
goto fail;
}
@ -43,7 +43,7 @@ fail:
static inline int sfsetw(const pos w1, surface *const s) {
void *ptr;
pos i, w0 = s->w;
char **row;
glyph **row;
errno = 0; // sanity check
@ -54,11 +54,11 @@ static inline int sfsetw(const pos w1, surface *const s) {
}
for (i = 0, row = s->buf; i < s->h; i++, row++) {
ptr = (void *)reallocarray(*row, w1, sizeof(char));
ptr = (void *)reallocarray(*row, w1, sizeof(glyph));
if (ptr == NULL) {
return errno;
}
*row = (char *)ptr;
*row = (glyph *)ptr;
}
s->w = w1;
@ -73,7 +73,7 @@ static inline int sfsetw(const pos w1, surface *const s) {
static inline int sfseth(const pos h1, surface *const s) {
void *ptr;
pos i, h0 = s->h;
char **row;
glyph **row;
errno = 0; // sanity check
@ -91,18 +91,18 @@ static inline int sfseth(const pos h1, surface *const s) {
}
// use ptr to avoid losing unfreed s->buf
ptr = (void *)reallocarray(s->buf, h1, sizeof(char));
ptr = (void *)reallocarray(s->buf, h1, sizeof(glyph));
if (ptr == NULL)
return errno;
// ENOMEM X_X
s->buf = (char **)ptr;
s->buf = (glyph **)ptr;
s->h = h1;
// height increased (alloc bottom rows)
if (h1 > h0) {
for (i = h0, row = s->buf; i < h1; i++, row++) {
*row = ALLOC_ROW(s->w);
*row = ALLOC_COLS(s->w);
if (*row == NULL)
return errno;
}
@ -135,7 +135,7 @@ int sfresize(const pos w1, const pos h1, surface *const s) {
__attribute__((malloc, warn_unused_result)) surface *sfalloc(const pos x, const pos y, const pos w, const pos h) {
surface *s;
char **buf = sfbuf(w, h);
glyph **buf = sfbuf(w, h);
if (buf == NULL)
return NULL;
@ -155,7 +155,7 @@ __attribute__((malloc, warn_unused_result)) surface *sfalloc(const pos x, const
void sffree(surface *const s) {
pos i;
char **row;
glyph **row;
for (i=0, row=s->buf; i < s->h; i++, row++) {
free(*row);
}

View file

@ -1,15 +1,11 @@
#ifndef _CURSETREE_SURFACE_H
#define _CURSETREE_SURFACE_H
/* Initial row and column coordinates */
#define ROW0 1
#define COL0 1
typedef unsigned short pos;
#include "_ct_shared.h"
typedef struct ct_surface {
pos x, y, w, h;
char **buf;
glyph **buf;
pos vcx, vcy; /* virtual cursor position */
} surface;

View file

@ -6,7 +6,7 @@
#include "_ct_shared.h"
#include "term.h"
int stashterm(const struct ct_term **const term) {
int stashterm(struct ct_term **const term) {
struct ct_term *t = (struct ct_term *)malloc(sizeof(struct ct_term));
t->fd = open("/dev/tty", O_RDONLY);

View file

@ -1,18 +1,20 @@
#ifndef _CURSETREE_TERM_H
#define _CURSETREE_TERM_H
#include "termios.h"
#include <termios.h>
#include "_ct_shared.h"
struct ct_term {
int fd;
unsigned short cols;
unsigned short rows;
pos cols;
pos rows;
struct termios termios0;
struct termios termios;
};
int stashterm(const struct ct_term **const term);
int stashterm(struct ct_term **const term);
void resetterm(struct ct_term *const term);
int termsize(struct ct_term *const term);