ledit

Text editor (WIP)
git clone git://lumidify.org/ledit.git (fast, but not encrypted)
git clone https://lumidify.org/ledit.git (encrypted, but very slow)
git clone git://4kcetb7mo7hj6grozzybxtotsub5bempzo4lirzc3437amof2c2impyd.onion/ledit.git (over tor)
Log | Files | Refs | README | LICENSE

txtbuf.c (3012B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 #include <stdarg.h>
      5 
      6 #include "util.h"
      7 #include "memory.h"
      8 #include "txtbuf.h"
      9 #include "assert.h"
     10 
     11 txtbuf *
     12 txtbuf_new(void) {
     13 	txtbuf *buf = ledit_malloc(sizeof(txtbuf));
     14 	buf->text = NULL;
     15 	buf->cap = buf->len = 0;
     16 	return buf;
     17 }
     18 
     19 txtbuf *
     20 txtbuf_new_from_char(char *str) {
     21 	txtbuf *buf = ledit_malloc(sizeof(txtbuf));
     22 	buf->text = ledit_strdup(str);
     23 	buf->len = strlen(str);
     24 	buf->cap = buf->len + 1;
     25 	return buf;
     26 }
     27 
     28 txtbuf *
     29 txtbuf_new_from_char_len(char *str, size_t len) {
     30 	txtbuf *buf = ledit_malloc(sizeof(txtbuf));
     31 	buf->text = ledit_strndup(str, len);
     32 	buf->len = len;
     33 	buf->cap = len + 1;
     34 	return buf;
     35 }
     36 
     37 void
     38 txtbuf_fmt(txtbuf *buf, char *fmt, ...) {
     39 	va_list args;
     40 	va_start(args, fmt);
     41 	int len = vsnprintf(buf->text, buf->cap, fmt, args);
     42 	/* FIXME: len can never be negative, right? */
     43 	/* FIXME: maybe also shrink here */
     44 	if ((size_t)len >= buf->cap) {
     45 		va_end(args);
     46 		va_start(args, fmt);
     47 		txtbuf_resize(buf, len);
     48 		vsnprintf(buf->text, buf->cap, fmt, args);
     49 	}
     50 	buf->len = len;
     51 	va_end(args);
     52 }
     53 
     54 void
     55 txtbuf_set_text(txtbuf *buf, char *text) {
     56 	txtbuf_set_textn(buf, text, strlen(text));
     57 }
     58 
     59 void
     60 txtbuf_set_textn(txtbuf *buf, char *text, size_t len) {
     61 	txtbuf_resize(buf, len);
     62 	buf->len = len;
     63 	memmove(buf->text, text, len);
     64 	buf->text[buf->len] = '\0';
     65 }
     66 
     67 void
     68 txtbuf_append(txtbuf *buf, char *text) {
     69 	txtbuf_appendn(buf, text, strlen(text));
     70 }
     71 
     72 /* FIXME: some sort of append that does not resize until there's not enough
     73    space so a buffer that will be filled up anyways doesn't have to be
     74    constantly resized */
     75 void
     76 txtbuf_appendn(txtbuf *buf, char *text, size_t len) {
     77 	txtbuf_resize(buf, add_sz(buf->len, len));
     78 	memmove(buf->text + buf->len, text, len);
     79 	buf->len += len;
     80 	buf->text[buf->len] = '\0';
     81 }
     82 
     83 void
     84 txtbuf_resize(txtbuf *buf, size_t sz) {
     85 	/* always leave room for extra \0 */
     86 	size_t cap = ideal_array_size(buf->cap, add_sz(sz, 1));
     87 	if (cap != buf->cap) {
     88 		buf->text = ledit_realloc(buf->text, cap);
     89 		buf->cap = cap;
     90 	}
     91 }
     92 
     93 void
     94 txtbuf_destroy(txtbuf *buf) {
     95 	if (!buf)
     96 		return;
     97 	free(buf->text);
     98 	free(buf);
     99 }
    100 
    101 void
    102 txtbuf_copy(txtbuf *dst, txtbuf *src) {
    103 	txtbuf_resize(dst, src->len);
    104 	if (src->text && dst->text) {
    105 		memcpy(dst->text, src->text, src->len);
    106 		dst->text[src->len] = '\0';
    107 	}
    108 	dst->len = src->len;
    109 }
    110 
    111 txtbuf *
    112 txtbuf_dup(txtbuf *src) {
    113 	txtbuf *dst = txtbuf_new();
    114 	txtbuf_copy(dst, src);
    115 	return dst;
    116 }
    117 
    118 int
    119 txtbuf_cmp(txtbuf *buf1, txtbuf *buf2) {
    120 	/* FIXME: I guess strcmp would be possible as well since it's nul-terminated now */
    121 	/* FIXME: Test this because I was tired while writing it */
    122 	int cmp = strncmp(buf1->text, buf2->text, LEDIT_MIN(buf1->len, buf2->len));
    123 	if (cmp == 0) {
    124 		if (buf1->len < buf2->len)
    125 			return -1;
    126 		else if (buf1->len > buf2->len)
    127 			return 1;
    128 	}
    129 	return cmp;
    130 }
    131 
    132 int
    133 txtbuf_eql(txtbuf *buf1, txtbuf *buf2) {
    134 	return txtbuf_cmp(buf1, buf2) == 0;
    135 }
    136 
    137 void
    138 txtbuf_clear(txtbuf *buf) {
    139 	if (buf->len > 0) {
    140 		buf->len = 0;
    141 		buf->text[0] = '\0';
    142 	}
    143 }