summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/mfluadir/otfcc/lib/bk/bkblock.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/mfluadir/otfcc/lib/bk/bkblock.c')
-rw-r--r--Build/source/texk/web2c/mfluadir/otfcc/lib/bk/bkblock.c132
1 files changed, 132 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/mfluadir/otfcc/lib/bk/bkblock.c b/Build/source/texk/web2c/mfluadir/otfcc/lib/bk/bkblock.c
new file mode 100644
index 00000000000..577048a4293
--- /dev/null
+++ b/Build/source/texk/web2c/mfluadir/otfcc/lib/bk/bkblock.c
@@ -0,0 +1,132 @@
+#include "bkblock.h"
+
+static void bkblock_acells(bk_Block *b, uint32_t len) {
+ if (len <= b->length + b->free) {
+ // We have enough space
+ b->free -= len - b->length;
+ b->length = len;
+ } else {
+ // allocate space
+ b->length = len;
+ b->free = (len >> 1) & 0xFFFFFF;
+ RESIZE(b->cells, b->length + b->free);
+ }
+}
+bool bk_cellIsPointer(bk_Cell *cell) {
+ return cell->t >= p16;
+}
+
+static bk_Cell *bkblock_grow(bk_Block *b, uint32_t len) {
+ uint32_t olen = b->length;
+ bkblock_acells(b, olen + len);
+ return &(b->cells[olen]);
+}
+
+bk_Block *_bkblock_init() {
+ bk_Block *b;
+ NEW(b);
+ bkblock_acells(b, 0);
+ return b;
+}
+
+static void bkblock_pushint(bk_Block *b, bk_CellType type, uint32_t x) {
+ bk_Cell *cell = bkblock_grow(b, 1);
+ cell->t = type;
+ cell->z = x;
+}
+static void bkblock_pushptr(bk_Block *b, bk_CellType type, bk_Block *p) {
+ bk_Cell *cell = bkblock_grow(b, 1);
+ cell->t = type;
+ cell->p = p;
+}
+
+static void vbkpushitems(bk_Block *b, bk_CellType type0, va_list ap) {
+ bk_CellType curtype = type0;
+ while (curtype) {
+ if (curtype == bkcopy || curtype == bkembed) {
+ bk_Block *par = va_arg(ap, bk_Block *);
+ if (par && par->cells) {
+ for (uint32_t j = 0; j < par->length; j++) {
+ if (bk_cellIsPointer(par->cells + j)) {
+ bkblock_pushptr(b, par->cells[j].t, par->cells[j].p);
+ } else {
+ bkblock_pushint(b, par->cells[j].t, par->cells[j].z);
+ }
+ }
+ }
+ if (curtype == bkembed && par) {
+ FREE(par->cells);
+ FREE(par);
+ }
+ } else if (curtype < p16) {
+ uint32_t par = va_arg(ap, int);
+ bkblock_pushint(b, curtype, par);
+ } else {
+ bk_Block *par = va_arg(ap, bk_Block *);
+ bkblock_pushptr(b, curtype, par);
+ }
+ curtype = va_arg(ap, int);
+ }
+}
+
+bk_Block *bk_new_Block(int type0, ...) {
+ va_list ap;
+ va_start(ap, type0);
+ bk_Block *b = _bkblock_init();
+ vbkpushitems(b, type0, ap);
+ va_end(ap);
+ return b;
+}
+
+bk_Block *bk_push(bk_Block *b, int type0, ...) {
+ va_list ap;
+ va_start(ap, type0);
+ vbkpushitems(b, type0, ap);
+ va_end(ap);
+ return b;
+}
+
+bk_Block *bk_newBlockFromStringLen(size_t len, const char *str) {
+ if (!str) return NULL;
+ bk_Block *b = bk_new_Block(bkover);
+ for (size_t j = 0; j < len; j++) {
+ bkblock_pushint(b, b8, str[j]);
+ }
+ return b;
+}
+
+bk_Block *bk_newBlockFromBuffer(MOVE caryll_Buffer *buf) {
+ if (!buf) return NULL;
+ bk_Block *b = bk_new_Block(bkover);
+ for (size_t j = 0; j < buf->size; j++) {
+ bkblock_pushint(b, b8, buf->data[j]);
+ }
+ buffree(buf);
+ return b;
+}
+bk_Block *bk_newBlockFromBufferCopy(OBSERVE caryll_Buffer *buf) {
+ if (!buf) return NULL;
+ bk_Block *b = bk_new_Block(bkover);
+ for (size_t j = 0; j < buf->size; j++) {
+ bkblock_pushint(b, b8, buf->data[j]);
+ }
+ return b;
+}
+
+void bk_printBlock(bk_Block *b) {
+ fprintf(stderr, "Block size %08x\n", (uint32_t)b->length);
+ fprintf(stderr, "------------------\n");
+ for (uint32_t j = 0; j < b->length; j++) {
+ if (bk_cellIsPointer(b->cells + j)) {
+ if (b->cells[j].p) {
+ fprintf(stderr, " %3d %p[%d]\n", b->cells[j].t, b->cells[j].p,
+ b->cells[j].p->_index);
+ } else {
+ fprintf(stderr, " %3d [NULL]\n", b->cells[j].t);
+ }
+ } else {
+ fprintf(stderr, " %3d %d\n", b->cells[j].t, b->cells[j].z);
+ }
+ }
+ fprintf(stderr, "------------------\n");
+}