NEWS: Welcome to my new homepage! <3

Code cleanup - poet - A terminal-based blogging interface

poet

A terminal-based blogging interface
git clone git://192.168.2.2/poet
Log | Files | Refs | README

commit 2d3131c25602e96d239c8cae6fa1f9f1d132a14d
parent 9e3340b32018b3c616013e6aec8c1ad6f5c77023
Author: typable <contact@typable.dev>
Date:   Mon, 27 May 2024 15:09:33 +0200

Code cleanup

Diffstat:
MMakefile | 2+-
Asrc/edit.c | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/edit.h | 7+++++++
Msrc/main.c | 125+++++++++++++++----------------------------------------------------------------
Msrc/post.c | 15+--------------
Asrc/post.h | 25+++++++++++++++++++++++++
6 files changed, 151 insertions(+), 117 deletions(-)

diff --git a/Makefile b/Makefile @@ -5,7 +5,7 @@ install: build rm poet build: - cc -o poet -lpq -lterm -Wall -Wextra -Werror -pedantic src/main.c src/util.c + cc -o poet -lpq -lterm -Wall -Wextra -Werror -pedantic src/main.c src/util.c src/post.c src/edit.c clean: rm poet diff --git a/src/edit.c b/src/edit.c @@ -0,0 +1,94 @@ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include "util.h" +#include "post.h" + +#define DELIMITER "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n" + +int edit_read(char *filename, post_t **post) { + char *content = util_read_file(filename); + int len = strlen(content); + int delimiter_start = 0; + for (int i = 0; i < len; i++) { + if (strncmp(content + i, DELIMITER, strlen(DELIMITER)) == 0) { + delimiter_start = i; + break; + } + } + int delimiter_end = delimiter_start + strlen(DELIMITER); + char head[delimiter_start + 1]; + memcpy(head, content, delimiter_start); + head[delimiter_start] = '\0'; + char *body = malloc(sizeof(char) * (len - delimiter_end + 1)); + memcpy(body, content + delimiter_end, len - delimiter_end); + body[len - delimiter_end] = '\0'; + free(content); + *post = malloc(sizeof(post_t)); + post_init(*post); + int line_nr = 0; + int line_start = 0; + for (int i = 0; i < (int) strlen(head); i++) { + char c = head[i]; + if (c == '\n') { + int line_end = i; + if (i > 0 && head[i - 1] == '\r') { + line_end--; + } + char *line = malloc(sizeof(char) * (line_end - line_start + 1)); + memcpy(line, head + line_start, line_end - line_start); + line[line_end - line_start] = '\0'; + switch (line_nr) { + case 0: { + (*post)->title = line; + break; + } + case 1: { + (*post)->summary = line; + break; + } + case 2: { + if (strcmp(line, "true") == 0) { + (*post)->is_public = malloc(sizeof(bool)); + *(*post)->is_public = true; + } + else { + (*post)->is_public = malloc(sizeof(bool)); + *(*post)->is_public = false; + } + free(line); + break; + } + default: + free(line); + break; + } + line_start = i + 1; + line_nr++; + } + } + (*post)->content = body; + remove(filename); + return 0; +} + +int edit_write(char *filename, post_t *post) { + FILE *fp = fopen(filename, "aw+"); + char title[500]; + snprintf(title, 500, "%s\r\n", post->title); + fwrite(title, sizeof(char), strlen(title), fp); + char summary[500]; + snprintf(summary, 500, "%s\r\n", post->summary); + fwrite(summary, sizeof(char), strlen(summary), fp); + char is_public[500]; + snprintf(is_public, 500, "%s\r\n", *post->is_public ? "true" : "false"); + fwrite(is_public, sizeof(char), strlen(is_public), fp); + fwrite(DELIMITER, sizeof(char), strlen(DELIMITER), fp); + int content_len = strlen(post->content) + 2; + char content[content_len]; + snprintf(content, content_len, "%s", post->content); + fwrite(content, sizeof(char), strlen(content), fp); + fclose(fp); + return 0; +} diff --git a/src/edit.h b/src/edit.h @@ -0,0 +1,7 @@ +#pragma once + +#include "post.h" + +int edit_read(char *filename, post_t **post); +int edit_write(char *filename, post_t *post); + diff --git a/src/main.c b/src/main.c @@ -1,105 +1,20 @@ -#include <libterm.h> #include <stdio.h> +#include <stdlib.h> +#include <libterm.h> #include "util.h" -#include "post.c" +#include "post.h" +#include "edit.h" #define UNUSED(x) (void)(x) -#define DELIMITER "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n" char *POET_DB = NULL; -int post_read(char *filename, post_t **post) { - char *content = util_read_file(filename); - int len = strlen(content); - int delimiter_start = 0; - for (int i = 0; i < len; i++) { - if (strncmp(content + i, DELIMITER, strlen(DELIMITER)) == 0) { - delimiter_start = i; - break; - } - } - int delimiter_end = delimiter_start + strlen(DELIMITER); - char head[delimiter_start + 1]; - memcpy(head, content, delimiter_start); - head[delimiter_start] = '\0'; - char *body = malloc(sizeof(char) * (len - delimiter_end + 1)); - memcpy(body, content + delimiter_end, len - delimiter_end); - body[len - delimiter_end] = '\0'; - free(content); - *post = malloc(sizeof(post_t)); - post_init(*post); - int line_nr = 0; - int line_start = 0; - for (int i = 0; i < (int) strlen(head); i++) { - char c = head[i]; - if (c == '\n') { - int line_end = i; - if (i > 0 && head[i - 1] == '\r') { - line_end--; - } - char *line = malloc(sizeof(char) * (line_end - line_start + 1)); - memcpy(line, head + line_start, line_end - line_start); - line[line_end - line_start] = '\0'; - switch (line_nr) { - case 0: { - (*post)->title = line; - break; - } - case 1: { - (*post)->summary = line; - break; - } - case 2: { - if (strcmp(line, "true") == 0) { - (*post)->is_public = malloc(sizeof(bool)); - *(*post)->is_public = true; - } - else { - (*post)->is_public = malloc(sizeof(bool)); - *(*post)->is_public = false; - } - free(line); - break; - } - default: - free(line); - break; - } - line_start = i + 1; - line_nr++; - } - } - (*post)->content = body; - remove(filename); - return 0; -} - -int post_write(char *filename, post_t *post) { - FILE *fp = fopen(filename, "aw+"); - char title[500]; - snprintf(title, 500, "%s\r\n", post->title); - fwrite(title, sizeof(char), strlen(title), fp); - char summary[500]; - snprintf(summary, 500, "%s\r\n", post->summary); - fwrite(summary, sizeof(char), strlen(summary), fp); - char is_public[500]; - snprintf(is_public, 500, "%s\r\n", *post->is_public ? "true" : "false"); - fwrite(is_public, sizeof(char), strlen(is_public), fp); - fwrite(DELIMITER, sizeof(char), strlen(DELIMITER), fp); - int content_len = strlen(post->content) + 2; - char content[content_len]; - snprintf(content, content_len, "%s", post->content); - fwrite(content, sizeof(char), strlen(content), fp); - fclose(fp); - return 0; -} - -bool post_edit(int id) { +bool do_edit_post(int id) { post_t *post = db_post_get(POET_DB, id); char filename[100]; snprintf(filename, 100, "poet-%d.md", post->id); - post_write(filename, post); + edit_write(filename, post); term_write("\x1b[?25h"); term_flush(); char *editor = getenv("EDITOR"); @@ -112,16 +27,28 @@ bool post_edit(int id) { term_write("\x1b[?25l"); term_flush(); post_t *changes = NULL; - post_read(filename, &changes); + edit_read(filename, &changes); bool changed = post_changed(post, changes); if (changed) { db_post_update(POET_DB, id, post, changes); } - free(changes); + post_free(changes); post_free(post); return changed; } +bool do_toggle_post(int id) { + post_t *post = db_post_get(POET_DB, id); + post_t *changes = malloc(sizeof(post_t)); + post_init(changes); + changes->is_public = malloc(sizeof(bool)); + *changes->is_public = !*post->is_public; + db_post_update(POET_DB, post->id, post, changes); + post_free(changes); + post_free(post); + return true; +} + int main(void) { POET_DB = getenv("POET_DB"); if (POET_DB == NULL) { @@ -203,7 +130,7 @@ int main(void) { break; } case 'i': { - if (post_edit(post_result->result[index].id)) { + if (do_edit_post(post_result->result[index].id)) { update = true; render = true; } @@ -222,16 +149,10 @@ int main(void) { break; } case 'x': { - post_t *post = &post_result->result[index]; - post_t *changes = malloc(sizeof(post_t)); - post_init(changes); - changes->is_public = malloc(sizeof(bool)); - *changes->is_public = !*post->is_public; - if (db_post_update(POET_DB, post->id, post, changes)) { - render = true; + if (do_toggle_post(post_result->result[index].id)) { update = true; + render = true; } - free(changes); break; } case 'g': { diff --git a/src/post.c b/src/post.c @@ -5,20 +5,7 @@ #include <libpq-fe.h> #include "util.h" - -typedef struct { - int id; - char *title; - char *summary; - char *content; - char *date; - bool *is_public; -} post_t; - -typedef struct { - post_t *result; - int len; -} post_result_t; +#include "post.h" void post_init(post_t *post) { post->title = NULL; diff --git a/src/post.h b/src/post.h @@ -0,0 +1,25 @@ +#pragma once + +#include <stdbool.h> + +typedef struct { + int id; + char *title; + char *summary; + char *content; + char *date; + bool *is_public; +} post_t; + +typedef struct { + post_t *result; + int len; +} post_result_t; + +void post_init(post_t *post); +void post_free(post_t *post); +void post_result_free(post_result_t *post_result); +bool post_changed(post_t *post, post_t *changes); +post_result_t *db_post_search(char *db, char *title); +post_t *db_post_get(char *db, int id); +bool db_post_update(char *db, int id, post_t *post, post_t *changes);