shithub: neatmkfn

Download patch

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);