URI: 
       txtbuf.c - ledit - Text editor (WIP)
  HTML git clone git://lumidify.org/ledit.git (fast, but not encrypted)
  HTML git clone https://lumidify.org/ledit.git (encrypted, but very slow)
  HTML git clone git://4kcetb7mo7hj6grozzybxtotsub5bempzo4lirzc3437amof2c2impyd.onion/ledit.git (over tor)
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR 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 }