URI: 
       txtbuf.c - ltk - GUI toolkit for X11 (WIP)
  HTML git clone git://lumidify.org/ltk.git (fast, but not encrypted)
  HTML git clone https://lumidify.org/ltk.git (encrypted, but very slow)
  HTML git clone git://4kcetb7mo7hj6grozzybxtotsub5bempzo4lirzc3437amof2c2impyd.onion/ltk.git (over tor)
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       txtbuf.c (4171B)
       ---
            1 /*
            2  * Copyright (c) 2021-2024 lumidify <nobody@lumidify.org>
            3  *
            4  * Permission to use, copy, modify, and/or distribute this software for any
            5  * purpose with or without fee is hereby granted, provided that the above
            6  * copyright notice and this permission notice appear in all copies.
            7  *
            8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
            9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
           10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
           11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
           12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
           13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
           14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
           15  */
           16 
           17 #include <stdio.h>
           18 #include <stdlib.h>
           19 #include <string.h>
           20 #include <stdarg.h>
           21 
           22 #include "memory.h"
           23 #include "txtbuf.h"
           24 
           25 txtbuf *
           26 txtbuf_new(void) {
           27         txtbuf *buf = ltk_malloc(sizeof(txtbuf));
           28         buf->text = NULL;
           29         buf->cap = buf->len = 0;
           30         return buf;
           31 }
           32 
           33 txtbuf *
           34 txtbuf_new_from_char(const char *str) {
           35         txtbuf *buf = ltk_malloc(sizeof(txtbuf));
           36         buf->text = ltk_strdup(str);
           37         buf->len = strlen(str);
           38         buf->cap = buf->len + 1;
           39         return buf;
           40 }
           41 
           42 txtbuf *
           43 txtbuf_new_from_char_len(const char *str, size_t len) {
           44         txtbuf *buf = ltk_malloc(sizeof(txtbuf));
           45         buf->text = ltk_strndup(str, len);
           46         buf->len = len;
           47         buf->cap = len + 1;
           48         return buf;
           49 }
           50 
           51 void
           52 txtbuf_fmt(txtbuf *buf, const char *fmt, ...) {
           53         va_list args;
           54         va_start(args, fmt);
           55         int len = vsnprintf(buf->text, buf->cap, fmt, args);
           56         /* FIXME: len can never be negative, right? */
           57         /* FIXME: maybe also shrink here */
           58         if ((size_t)len >= buf->cap) {
           59                 va_end(args);
           60                 va_start(args, fmt);
           61                 txtbuf_resize(buf, len);
           62                 vsnprintf(buf->text, buf->cap, fmt, args);
           63         }
           64         buf->len = len;
           65         va_end(args);
           66 }
           67 
           68 void
           69 txtbuf_set_text(txtbuf *buf, const char *text) {
           70         txtbuf_set_textn(buf, text, strlen(text));
           71 }
           72 
           73 void
           74 txtbuf_set_textn(txtbuf *buf, const char *text, size_t len) {
           75         txtbuf_resize(buf, len);
           76         buf->len = len;
           77         memmove(buf->text, text, len);
           78         buf->text[buf->len] = '\0';
           79 }
           80 
           81 void
           82 txtbuf_append(txtbuf *buf, const char *text) {
           83         txtbuf_appendn(buf, text, strlen(text));
           84 }
           85 
           86 /* FIXME: some sort of append that does not resize until there's not enough
           87    space so a buffer that will be filled up anyways doesn't have to be
           88    constantly resized */
           89 void
           90 txtbuf_appendn(txtbuf *buf, const char *text, size_t len) {
           91         /* FIXME: overflow protection here and everywhere else */
           92         txtbuf_resize(buf, buf->len + len);
           93         memmove(buf->text + buf->len, text, len);
           94         buf->len += len;
           95         buf->text[buf->len] = '\0';
           96 }
           97 
           98 void
           99 txtbuf_resize(txtbuf *buf, size_t sz) {
          100         /* always leave room for extra \0 */
          101         size_t cap = ideal_array_size(buf->cap, sz + 1);
          102         if (cap != buf->cap) {
          103                 buf->text = ltk_realloc(buf->text, cap);
          104                 buf->cap = cap;
          105         }
          106 }
          107 
          108 void
          109 txtbuf_destroy(txtbuf *buf) {
          110         if (!buf)
          111                 return;
          112         free(buf->text);
          113         free(buf);
          114 }
          115 
          116 void
          117 txtbuf_copy(txtbuf *dst, txtbuf *src) {
          118         txtbuf_resize(dst, src->len);
          119         if (src->text && dst->text) {
          120                 memcpy(dst->text, src->text, src->len);
          121                 dst->text[src->len] = '\0';
          122         }
          123         dst->len = src->len;
          124 }
          125 
          126 txtbuf *
          127 txtbuf_dup(txtbuf *src) {
          128         txtbuf *dst = txtbuf_new();
          129         txtbuf_copy(dst, src);
          130         return dst;
          131 }
          132 
          133 char *
          134 txtbuf_get_textcopy(txtbuf *buf) {
          135         return buf->text ? ltk_strndup(buf->text, buf->len) : ltk_strdup("");
          136 }
          137 
          138 const char *
          139 txtbuf_get_text(txtbuf *buf) {
          140         return buf->text;
          141 }
          142 
          143 size_t
          144 txtbuf_len(txtbuf *buf) {
          145         return buf->len;
          146 }
          147 
          148 /* FIXME: proper "normalize" function to add nul-termination if needed */
          149 int
          150 txtbuf_cmp(txtbuf *buf1, txtbuf *buf2) {
          151         /* FIXME: I guess strcmp would be possible as well since it's nul-terminated now */
          152         /* FIXME: Test this because I was tired while writing it */
          153         int cmp = strncmp(buf1->text, buf2->text, buf1->len < buf2->len ? buf1->len : buf2->len);
          154         if (cmp == 0) {
          155                 if (buf1->len < buf2->len)
          156                         return -1;
          157                 else if (buf1->len > buf2->len)
          158                         return 1;
          159         }
          160         return cmp;
          161 }
          162 
          163 int
          164 txtbuf_eql(txtbuf *buf1, txtbuf *buf2) {
          165         return txtbuf_cmp(buf1, buf2) == 0;
          166 }
          167 
          168 void
          169 txtbuf_clear(txtbuf *buf) {
          170         if (buf->len > 0) {
          171                 buf->len = 0;
          172                 buf->text[0] = '\0';
          173         }
          174 }