aboutsummaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2022-10-25 00:32:48 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2022-10-25 00:32:48 -0400
commitd05b24aca2ea509c5294c8b64ec9334abe68a8b6 (patch)
tree34fbf9b75909c01aebb597748e60c934fd5e29d9 /main.c
parent2d13c00b959515f61db1f4a92cca1a32ab0c4f90 (diff)
downloadsayeth-d05b24aca2ea509c5294c8b64ec9334abe68a8b6.tar.gz
Break project up into separate files
Diffstat (limited to 'main.c')
-rw-r--r--main.c337
1 files changed, 17 insertions, 320 deletions
diff --git a/main.c b/main.c
index 911b313..ada0c16 100644
--- a/main.c
+++ b/main.c
@@ -1,47 +1,23 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
-#include <stdarg.h>
#include <unistd.h>
-#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <limits.h>
#include "config.h"
-
-#define INPUT_BUFSIZ 4096
-#define DATA_BUFSIZ 8192
-#define DRIVERS_ALLOC_DEFAULT 128
-
-size_t START_Y_BOX = 0;
-size_t START_Y_CARET = 0;
-size_t START_Y_DATA = 0;
-const char *A_TAB = " ";
-char wspace = ' ';
-char box_top_left = '\0';
-char box_top = '\0';
-char box_top_right = '\0';
-char box_side = '\0';
-char box_bottom_left = '\0';
-char box_bottom = '\0';
-char box_bottom_right = '\0';
-
-struct Driver {
- char *name;
- size_t box_indent;
- char *box_elements;
- size_t caret_pos;
- size_t caret_indent;
- size_t caret_attached;
- char *caret;
- size_t data_indent;
- char *data;
-};
-struct Driver **drivers = NULL;
-size_t drivers_alloc = DRIVERS_ALLOC_DEFAULT;
-size_t drivers_used = 0;
-
-
+#include "sayeth.h"
+
+extern char wspace;
+extern struct Driver **drivers;
+extern size_t drivers_alloc;
+extern size_t drivers_used;
+
+/***
+ * Repeat a character
+ * @param ch character to repeat
+ * @param limit number of times to repeat
+ */
void repchar(char ch, size_t limit) {
while (limit > 0) {
putc(ch, stdout);
@@ -49,6 +25,11 @@ void repchar(char ch, size_t limit) {
}
}
+/***
+ * Find the longest line in a string
+ * @param s the string
+ * @return longest line
+ */
size_t get_longest_line(char *s) {
size_t *lengths;
size_t len;
@@ -89,81 +70,6 @@ size_t get_longest_line(char *s) {
return longest;
}
-void box_draw_top(size_t y, size_t longest) {
- repchar(wspace, y);
- repchar(box_top_left, 1);
- repchar(box_top, longest);
- repchar(box_top_right, 1);
-}
-
-void box_draw_bottom(size_t y, size_t longest) {
- repchar(wspace, y);
- repchar(box_bottom_left, 1);
- repchar(box_bottom, longest);
- repchar(box_bottom_right, 1);
-}
-
-void box_draw_next_line(size_t y) {
- repchar(wspace, y);
- repchar(box_side, 1);
-}
-
-void box_draw_end_line(size_t longest, size_t len) {
- repchar(wspace, longest - len);
- repchar(box_side, 1);
-}
-
-int boxprintf(const char *fmt, ...) {
- int count;
- va_list list;
- va_start(list, fmt);
- size_t len = 0;
- char data[INPUT_BUFSIZ] = {0};
- char output[INPUT_BUFSIZ] = {0};
- count = vsnprintf(data, sizeof(data) - 1, fmt, list);
-
- // convert tabs to spaces
- for (size_t i = 0, n = 0; i < strlen(data) && n < sizeof(output); i++, n++) {
- if (data[i] == '\t') {
- strcat(&output[n], A_TAB);
- n = n + strlen(A_TAB) - 1;
- continue;
- }
- output[n] = data[i];
- }
-
- size_t longest = get_longest_line(output);
-
- box_draw_top(START_Y_BOX, longest);
- puts("");
-
- for (size_t i = 0; i < strlen(output); i++) {
- if (i == strlen(output) - 1) {
- box_draw_end_line(longest, len);
- continue;
- }
-
- if (len == 0) {
- box_draw_next_line(START_Y_BOX);
- }
-
- if (output[i] == '\n') {
- box_draw_end_line(longest, len);
- putc('\n', stdout);
- len = 0;
- continue;
- }
-
- putc(output[i], stdout);
-
- len++;
- }
- puts("");
- box_draw_bottom(START_Y_BOX, longest);
-
- va_end(list);
- return count;
-}
void usage(char *prog) {
printf("usage: %s [-d driver_name] [-w] [-] {input}\n"
@@ -175,213 +81,6 @@ void usage(char *prog) {
"input A quoted string\n", prog);
}
-void caret_draw(char *data, size_t indent, size_t attached) {
- if (!strlen(data))
- return;
-
- if (!attached)
- repchar(wspace, START_Y_BOX);
-
- for (size_t i = 0; i < strlen(data); i++) {
- if (data[i] == '\\' && isalpha(data[i + 1])) {
- i++;
- switch (data[i]) {
- case 'n':
- putc('\n', stdout);
- if (i == strlen(data) - 1)
- continue;
- repchar(wspace, indent);
- continue;
- default:
- continue;
- }
- }
- putc(data[i], stdout);
- }
-}
-
-
-struct Driver *driver_load(char *filename) {
- FILE *fp = NULL;
- struct Driver *driver = NULL;
-
- driver = calloc(1, sizeof(*driver));
- if (!driver) {
- return NULL;
- }
-
- fp = fopen(filename, "r");
- if (!fp) {
- return NULL;
- }
-
- for (size_t i = 0; i < 9; i++) {
- char buf[INPUT_BUFSIZ] = {0};
- ssize_t lastpos = ftell(fp);
- if (fgets(buf, sizeof(buf) - 1, fp) == NULL) {
- break;
- }
- if (!strlen(buf) || buf[0] == '#') {
- i--;
- continue;
- }
- buf[strlen(buf) - 1] = '\0';
- switch (i) {
- case 0:
- driver->name = strdup(buf);
- if (!driver->name) {
- fclose(fp);
- return NULL;
- }
- break;
- case 1:
- driver->box_indent = strtol(buf, NULL, 10);
- break;
- case 2:
- driver->box_elements = strdup(buf);
- if (!driver->box_elements) {
- fclose(fp);
- return NULL;
- }
- break;
- case 3:
- driver->caret_pos = strtol(buf, NULL, 10);
- break;
- case 4:
- driver->caret_indent = strtol(buf, NULL, 10);
- break;
- case 5:
- driver->caret_attached = strtol(buf, NULL, 10);
- break;
- case 6:
- driver->caret = strdup(buf);
- if (!driver->caret) {
- fclose(fp);
- return NULL;
- }
- break;
- case 7:
- driver->data_indent = strtol(buf, 0, 10);
- break;
- case 8:
- driver->data = calloc(DATA_BUFSIZ, sizeof(*driver->data));
- if (!driver->data) {
- fclose(fp);
- return NULL;
- }
- // rewind to beginning of the data section
- fseek(fp, lastpos, SEEK_SET);
- fread(driver->data, 1, DATA_BUFSIZ - 1, fp);
- break;
- default:
- break;
- }
- }
- fclose(fp);
- return driver;
-}
-
-int driver_register(struct Driver *driver) {
- if (!drivers) {
- drivers = calloc(drivers_alloc, sizeof(**drivers));
- }
-
- if (drivers_used > drivers_alloc) {
- struct Driver **tmp;
- drivers_alloc += DRIVERS_ALLOC_DEFAULT;
- tmp = realloc(drivers, (sizeof(**drivers) * drivers_alloc));
- if (!tmp) {
- return -1;
- }
- drivers = tmp;
-
- for (size_t i = drivers_used; i < drivers_alloc; i++) {
- drivers[i] = calloc(1, sizeof(*drivers[i]));
- if (!drivers[i])
- return -2;
- }
- }
-
- drivers[drivers_used] = calloc(1, sizeof(*drivers[0]));
- if (!drivers[drivers_used])
- return -2;
- memcpy(drivers[drivers_used], driver, sizeof(*drivers[0]));
- drivers_used++;
- return 0;
-}
-
-void drivers_free() {
- for (size_t i = 0; i < drivers_alloc; i++) {
- if (drivers[i]) {
- if (drivers[i]->name)
- free(drivers[i]->name);
- if (drivers[i]->data)
- free(drivers[i]->data);
- if (drivers[i]->caret)
- free(drivers[i]->caret);
- if (drivers[i]->box_elements)
- free(drivers[i]->box_elements);
- free(drivers[i]);
- }
- }
- free(drivers);
-}
-
-void data_draw(char *data, size_t indent) {
- size_t len = 0;
- for (size_t i = 0; i < strlen(data); i++) {
- if (len == 0) {
- repchar(wspace, indent);
- }
-
- if (data[i] == '\n') {
- putc('\n', stdout);
- len = 0;
- continue;
- }
-
- putc(data[i], stdout);
- len++;
- }
-}
-
-void driver_run(struct Driver *driver, char *input) {
- char *elem = driver->box_elements;
- box_top_left = elem[0];
- box_top = elem[1];
- box_top_right = elem[2];
- box_side = elem[3];
- box_bottom_left = elem[4];
- box_bottom = elem[5];
- box_bottom_right = elem[6];
- START_Y_BOX = driver->box_indent;
- START_Y_CARET = driver->caret_indent;
- START_Y_DATA = driver->data_indent;
-
- if (!driver->caret_pos) {
- boxprintf("%s", input);
- caret_draw(driver->caret, START_Y_CARET, driver->caret_attached);
- }
-
- if (driver->data) {
- data_draw(driver->data, START_Y_DATA);
- }
-
- if (driver->caret_pos) {
- caret_draw(driver->caret, START_Y_CARET, driver->caret_attached);
- boxprintf("%s", input);
- }
-}
-
-struct Driver *driver_lookup(char *name) {
- for (size_t i = 0; drivers[i] != NULL; i++) {
- if (!strcmp(drivers[i]->name, name)) {
- return drivers[i];
- }
- }
- return NULL;
-}
-
int main(int argc, char *argv[]) {
char driver_name[255] = {0};
char input[INPUT_BUFSIZ] = {0};
@@ -414,12 +113,10 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "option requires value\n");
usage(argv[0]);
exit(1);
- break;
case '?':
fprintf(stderr, "unknown option: %c\n", optopt);
usage(argv[0]);
exit(1);
- break;
default:
usage(argv[0]);
exit(1);