tsbuf.c - neatvi - [fork] simple vi-type editor with UTF-8 support
 (HTM) git clone git://src.adamsgaard.dk/neatvi
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
       ---
       tsbuf.c (1724B)
       ---
            1 /* variable length string buffer */
            2 #include <stdarg.h>
            3 #include <stdio.h>
            4 #include <stdlib.h>
            5 #include <string.h>
            6 #include "vi.h"
            7 
            8 #define SBUFSZ                128
            9 #define ALIGN(n, a)        (((n) + (a) - 1) & ~((a) - 1))
           10 #define NEXTSZ(o, r)        ALIGN(MAX((o) * 2, (o) + (r)), SBUFSZ)
           11 
           12 struct sbuf {
           13         char *s;                /* allocated buffer */
           14         int s_n;                /* length of the string stored in s[] */
           15         int s_sz;                /* size of memory allocated for s[] */
           16 };
           17 
           18 static void sbuf_extend(struct sbuf *sbuf, int newsz)
           19 {
           20         char *s = sbuf->s;
           21         sbuf->s_sz = newsz;
           22         sbuf->s = malloc(sbuf->s_sz);
           23         if (sbuf->s_n)
           24                 memcpy(sbuf->s, s, sbuf->s_n);
           25         free(s);
           26 }
           27 
           28 struct sbuf *sbuf_make(void)
           29 {
           30         struct sbuf *sb = malloc(sizeof(*sb));
           31         memset(sb, 0, sizeof(*sb));
           32         return sb;
           33 }
           34 
           35 char *sbuf_buf(struct sbuf *sb)
           36 {
           37         if (!sb->s)
           38                 sbuf_extend(sb, 1);
           39         sb->s[sb->s_n] = '\0';
           40         return sb->s;
           41 }
           42 
           43 char *sbuf_done(struct sbuf *sb)
           44 {
           45         char *s = sbuf_buf(sb);
           46         free(sb);
           47         return s;
           48 }
           49 
           50 void sbuf_free(struct sbuf *sb)
           51 {
           52         free(sb->s);
           53         free(sb);
           54 }
           55 
           56 void sbuf_chr(struct sbuf *sbuf, int c)
           57 {
           58         if (sbuf->s_n + 2 >= sbuf->s_sz)
           59                 sbuf_extend(sbuf, NEXTSZ(sbuf->s_sz, 1));
           60         sbuf->s[sbuf->s_n++] = c;
           61 }
           62 
           63 void sbuf_mem(struct sbuf *sbuf, char *s, int len)
           64 {
           65         if (sbuf->s_n + len + 1 >= sbuf->s_sz)
           66                 sbuf_extend(sbuf, NEXTSZ(sbuf->s_sz, len + 1));
           67         memcpy(sbuf->s + sbuf->s_n, s, len);
           68         sbuf->s_n += len;
           69 }
           70 
           71 void sbuf_str(struct sbuf *sbuf, char *s)
           72 {
           73         sbuf_mem(sbuf, s, strlen(s));
           74 }
           75 
           76 int sbuf_len(struct sbuf *sbuf)
           77 {
           78         return sbuf->s_n;
           79 }
           80 
           81 void sbuf_cut(struct sbuf *sb, int len)
           82 {
           83         if (sb->s_n > len)
           84                 sb->s_n = len;
           85 }
           86 
           87 void sbuf_printf(struct sbuf *sbuf, char *s, ...)
           88 {
           89         char buf[256];
           90         va_list ap;
           91         va_start(ap, s);
           92         vsnprintf(buf, sizeof(buf), s, ap);
           93         va_end(ap);
           94         sbuf_str(sbuf, buf);
           95 }