aboutsummaryrefslogtreecommitdiff
path: root/sb.c
diff options
context:
space:
mode:
authorHolden Rohrer <hr@hrhr.dev>2020-05-12 17:26:54 -0400
committerHolden Rohrer <hr@hrhr.dev>2020-05-12 17:26:54 -0400
commit2719d59866e96a3ae697a417a35540572af6ddfc (patch)
tree259a69e1cdb4e9de51f89c5301c22b43be2ed8bc /sb.c
parent60e6394056de9d7d1cd3c93abb1cd4cd2f5cb192 (diff)
Added .LS
Did a lot of code cleanup on the way because I was trying to find a bug in the new code, but it was actually in the handling of multiline inputs to wordset (now fixed). sb.* added for correct memory allocation in lineset, which, did I mention, now works. Makefile has been updated, and phrase-circuit.src can now handle line widths of about 50.
Diffstat (limited to 'sb.c')
-rw-r--r--sb.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/sb.c b/sb.c
new file mode 100644
index 0000000..06ee8d9
--- /dev/null
+++ b/sb.c
@@ -0,0 +1,88 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include "sb.h"
+
+struct sb {
+ sbnode* head;
+ sbnode* tail;
+ size_t loc;
+ size_t sz;
+};
+
+struct sbnode {
+ char* str;
+ sbnode* next;
+};
+
+sbnode* newsbnode(sbnode* prev, size_t sz){
+ sbnode* node = malloc(sizeof(sbnode)); // Allocate
+ node->str = malloc(sizeof(char)*(sz+1)); node->str[sz] = 0;
+ node->next = NULL; // Init
+ if (prev) prev->next = node; // Link
+ return node;
+}
+
+sb* newsb(size_t sz){
+ sb* out = malloc(sizeof(sb));
+ out->head = out->tail = newsbnode(NULL, sz);
+ out->sz = sz;
+ out->loc = 0;
+ return out;
+}
+
+void extendsb(sb* buf){
+ buf->sz *= 2;
+ buf->loc = 0;
+ buf->tail = newsbnode(buf->tail, buf->sz);
+}
+
+void insstr(sb* buf, char* str){
+ size_t rem = strlen(str); // remaining chars to push
+ while (rem > (buf->sz - buf->loc)){ // while buffer has less room
+ // than needed, fill the buffer with str
+ memcpy(buf->tail->str+buf->loc, str, buf->sz - buf->loc);
+ // move the string pointer by that amount
+ str += buf->sz - buf->loc;
+ // reduce the number of remaining characters by that amount
+ rem -= buf->sz - buf->loc;
+ // and add a new node, resetting buf->loc
+ extendsb(buf);
+ }
+ // copy the rest into the buffer
+ memcpy(buf->tail->str+buf->loc, str, rem);
+ // and advance buf->loc
+ buf->loc += rem;
+}
+
+sbnode* freenodenext(sbnode* node){
+ sbnode* out = node->next;
+ free(node->str);
+ free(node);
+ return out;
+}
+
+char* decompose(sb* buf){
+ // Make the last node a proper string
+ buf->tail->str[buf->loc] = 0;
+ // Start with the length of the last node
+ size_t len = 0;
+ // For every non-tail node (cur->next == NULL for it),
+ for (sbnode* cur = buf->head; cur != NULL; cur = cur->next){
+ // add the length of its string
+ len += strlen(cur->str);
+ }
+ // make a string to fit it all
+ char* str = malloc(sizeof(char)*(len+1)); str[len] = 0;
+ // and its iterator
+ char* pos = str;
+ // for every node,
+ for (sbnode* cur = buf->head; cur != NULL; cur = freenodenext(cur)){
+ size_t slen = strlen(cur->str);
+ memcpy(pos, cur->str, slen); // copy
+ pos += slen;
+ }
+ free(buf);
+ return str;
+}
+