ref: 1b33609921166b3d25da56bea2c02fbb6f72f45c
parent: 6b8e528622a9b2b92d00ef7d10444b5be585abdd
author: Ali Gholami Rudi <ali@rudi.ir>
date: Mon Aug 14 18:04:12 EDT 2017
sbuf: import from neatvi
--- a/sbuf.c
+++ b/sbuf.c
@@ -1,3 +1,4 @@
+/* variable length string buffer */
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -5,80 +6,92 @@
#include "sbuf.h"
#define MAX(a, b) ((a) < (b) ? (b) : (a))
-#define SBUF_SZ 512
+#define ALIGN(n, a) (((n) + (a) - 1) & ~((a) - 1))
+#define NEXTSZ(o, r) ALIGN(MAX((o) * 2, (o) + (r)), SBUFSZ)
-static void sbuf_extend(struct sbuf *sbuf, int amount)
+#define SBUFSZ 128
+
+struct sbuf {
+ char *s; /* allocated buffer */
+ int s_n; /* length of the string stored in s[] */
+ int s_sz; /* size of memory allocated for s[] */
+};
+
+static void sbuf_extend(struct sbuf *sbuf, int newsz)
{
char *s = sbuf->s;
- sbuf->sz = (MAX(1, amount) + SBUF_SZ - 1) & ~(SBUF_SZ - 1);
- sbuf->s = malloc(sbuf->sz);
- if (sbuf->n)
- memcpy(sbuf->s, s, sbuf->n);
+ sbuf->s_sz = newsz;
+ sbuf->s = malloc(sbuf->s_sz);
+ if (sbuf->s_n)
+ memcpy(sbuf->s, s, sbuf->s_n);
free(s);
}
-void sbuf_init(struct sbuf *sbuf)
+struct sbuf *sbuf_make(void)
{
- memset(sbuf, 0, sizeof(*sbuf));
- sbuf_extend(sbuf, SBUF_SZ);
+ struct sbuf *sb = malloc(sizeof(*sb));
+ memset(sb, 0, sizeof(*sb));
+ return sb;
}
-void sbuf_add(struct sbuf *sbuf, int c)
+char *sbuf_buf(struct sbuf *sb)
{
- if (sbuf->n + 2 >= sbuf->sz)
- sbuf_extend(sbuf, sbuf->sz * 2);
- sbuf->s[sbuf->n++] = c;
+ if (!sb->s)
+ sbuf_extend(sb, 1);
+ sb->s[sb->s_n] = '\0';
+ return sb->s;
}
-void sbuf_append(struct sbuf *sbuf, char *s)
+char *sbuf_done(struct sbuf *sb)
{
- int len = strlen(s);
- if (sbuf->n + len + 1 >= sbuf->sz)
- sbuf_extend(sbuf, sbuf->n + len + 1);
- memcpy(sbuf->s + sbuf->n, s, len);
- sbuf->n += len;
+ char *s = sbuf_buf(sb);
+ free(sb);
+ return s;
}
-void sbuf_printf(struct sbuf *sbuf, char *s, ...)
+void sbuf_free(struct sbuf *sb)
{
- char buf[1024];
- va_list ap;
- va_start(ap, s);
- vsprintf(buf, s, ap);
- va_end(ap);
- sbuf_append(sbuf, buf);
+ free(sb->s);
+ free(sb);
}
-void sbuf_putnl(struct sbuf *sbuf)
+void sbuf_chr(struct sbuf *sbuf, int c)
{
- if (sbuf->n && sbuf->s[sbuf->n - 1] != '\n')
- sbuf_add(sbuf, '\n');
+ if (sbuf->s_n + 2 >= sbuf->s_sz)
+ sbuf_extend(sbuf, NEXTSZ(sbuf->s_sz, 1));
+ sbuf->s[sbuf->s_n++] = c;
}
-int sbuf_empty(struct sbuf *sbuf)
+void sbuf_mem(struct sbuf *sbuf, char *s, int len)
{
- return !sbuf->n;
+ if (sbuf->s_n + len + 1 >= sbuf->s_sz)
+ sbuf_extend(sbuf, NEXTSZ(sbuf->s_sz, len + 1));
+ memcpy(sbuf->s + sbuf->s_n, s, len);
+ sbuf->s_n += len;
}
-char *sbuf_buf(struct sbuf *sbuf)
+void sbuf_str(struct sbuf *sbuf, char *s)
{
- sbuf->s[sbuf->n] = '\0';
- return sbuf->s;
+ sbuf_mem(sbuf, s, strlen(s));
}
int sbuf_len(struct sbuf *sbuf)
{
- return sbuf->n;
+ return sbuf->s_n;
}
-/* shorten the sbuf */
-void sbuf_cut(struct sbuf *sbuf, int n)
+void sbuf_cut(struct sbuf *sb, int len)
{
- if (sbuf->n > n)
- sbuf->n = n;
+ if (sb->s_n > len)
+ sb->s_n = len;
}
-void sbuf_done(struct sbuf *sbuf)
+void sbuf_printf(struct sbuf *sbuf, char *s, ...)
{
- free(sbuf->s);
+ char buf[256];
+ va_list ap;
+ va_start(ap, s);
+ vsnprintf(buf, sizeof(buf), s, ap);
+ va_end(ap);
+ sbuf_str(sbuf, buf);
}
--- a/sbuf.h
+++ b/sbuf.h
@@ -1,12 +1,8 @@
/* variable length string buffer */
-struct sbuf {
- char *s; /* allocated buffer */
- int sz; /* buffer size */
- int n; /* length of the string stored in s */
-};
-
-void sbuf_init(struct sbuf *sbuf);
-void sbuf_done(struct sbuf *sbuf);
-char *sbuf_buf(struct sbuf *sbuf);
+struct sbuf *sbuf_make(void);
+void sbuf_free(struct sbuf *sb);
+char *sbuf_done(struct sbuf *sb);
+void sbuf_str(struct sbuf *sbuf, char *s);
+void sbuf_mem(struct sbuf *sbuf, char *s, int len);
+char *sbuf_buf(struct sbuf *sb);
void sbuf_printf(struct sbuf *sbuf, char *s, ...);
-int sbuf_empty(struct sbuf *sbuf);
--- a/trfn.c
+++ b/trfn.c
@@ -15,8 +15,8 @@
#define GNLEN 64 /* glyph name length */
#define AGLLEN 8192 /* adobe glyphlist length */
-static struct sbuf sbuf_char; /* characters */
-static struct sbuf sbuf_kern; /* kerning pairs */
+static struct sbuf *sbuf_char; /* characters */
+static struct sbuf *sbuf_kern; /* kerning pairs */
static int trfn_div; /* divisor of widths */
static int trfn_swid; /* space width */
static int trfn_special; /* special flag */
@@ -288,20 +288,20 @@
return;
if (strcmp("---", uc))
trfn_lig(uc);
- sbuf_printf(&sbuf_char, "char %s\t%d", uc, WX(wid));
+ sbuf_printf(sbuf_char, "char %s\t%d", uc, WX(wid));
if (trfn_bbox && (llx || lly || urx || ury))
- sbuf_printf(&sbuf_char, ",%d,%d,%d,%d",
+ sbuf_printf(sbuf_char, ",%d,%d,%d,%d",
WX(llx), WX(lly), WX(urx), WX(ury));
- sbuf_printf(&sbuf_char, "\t%d\t%s\t%s\n", typ, psname, pos);
+ sbuf_printf(sbuf_char, "\t%d\t%s\t%s\n", typ, psname, pos);
a_tr = tab_get(tab_alts, uc);
while (a_tr && *a_tr)
- sbuf_printf(&sbuf_char, "char %s\t\"\n", *a_tr++);
+ sbuf_printf(sbuf_char, "char %s\t\"\n", *a_tr++);
}
void trfn_kern(char *c1, char *c2, int x)
{
if (WX(x) && abs(WX(x)) >= trfn_kmin)
- sbuf_printf(&sbuf_kern, "kern %s\t%s\t%d\n", c1, c2, WX(x));
+ sbuf_printf(sbuf_kern, "kern %s\t%s\t%d\n", c1, c2, WX(x));
}
void trfn_trfont(char *name)
@@ -327,8 +327,8 @@
printf("ligatures %s%s0\n", trfn_ligs, trfn_ligs2);
if (trfn_special)
printf("special\n");
- printf("%s", sbuf_buf(&sbuf_char));
- printf("%s", sbuf_buf(&sbuf_kern));
+ fputs(sbuf_buf(sbuf_char), stdout);
+ fputs(sbuf_buf(sbuf_kern), stdout);
}
void trfn_init(int res, int spc, int kmin, int bbox, int ligs, int pos)
@@ -340,8 +340,8 @@
trfn_bbox = bbox;
trfn_noligs = !ligs;
trfn_pos = pos;
- sbuf_init(&sbuf_char);
- sbuf_init(&sbuf_kern);
+ sbuf_char = sbuf_make();
+ sbuf_kern = sbuf_make();
tab_agl = tab_alloc(LEN(agl));
for (i = 0; i < LEN(agl); i++)
tab_put(tab_agl, agl[i][0], agl[i][1]);
@@ -352,8 +352,8 @@
void trfn_done(void)
{
- sbuf_done(&sbuf_char);
- sbuf_done(&sbuf_kern);
+ sbuf_free(sbuf_char);
+ sbuf_free(sbuf_kern);
tab_free(tab_alts);
if (tab_agl)
tab_free(tab_agl);