commit b0c1cae18066d0103a440894b5256939852021eb
Author:     Mattias Andrée <[email protected]>
AuthorDate: Tue Mar 1 18:37:05 2016 +0100
Commit:     Mattias Andrée <[email protected]>
CommitDate: Tue Mar 1 18:37:05 2016 +0100

    Add zsetup, zunsetup, zinit, zfree, zswap, zsave, zload, zbits, and zlsb
    
    Signed-off-by: Mattias Andrée <[email protected]>

diff --git a/TODO b/TODO
new file mode 100644
index 0000000..94dc424
--- /dev/null
+++ b/TODO
@@ -0,0 +1 @@
+Allocations shall be cached.
diff --git a/src/internals.h b/src/internals.h
new file mode 100644
index 0000000..ac74bd5
--- /dev/null
+++ b/src/internals.h
@@ -0,0 +1,30 @@
+/* See LICENSE file for copyright and license details. */
+#include "../zahl.h"
+
+#define BITS_PER_CHAR                32
+#define FLOOR_BITS_TO_CHARS(bits)    ((bits) >> 5)
+#define CEILING_BITS_TO_CHARS(bits)  (((bits) + (BITS_PER_CHAR - 1)) >> 5)
+#define BITS_IN_LAST_CHAR(bits)      ((bits) & (BITS_PER_CHAR - 1))
+
+#define LIST_TEMPS\
+       X(libzahl_tmp_a)\
+       X(libzahl_tmp_b)\
+       X(libzahl_tmp_c)\
+       X(libzahl_tmp_d)\
+       X(libzahl_tmp_e)\
+       X(libzahl_tmp_f)\
+       X(libzahl_tmp_g)\
+       X(libzahl_tmp_i)\
+       X(libzahl_tmp_j)\
+       X(libzahl_tmp_k)\
+       X(libzahl_tmp_l)\
+       X(libzahl_tmp_m)
+
+#define X(x)  extern z_t x;
+LIST_TEMPS
+#undef X
+
+extern jmp_buf libzahl_jmp_buf;
+extern int libzahl_set_up;
+
+#define FAILURE_JUMP()  (longjmp(libzahl_jmp_buf, 1))
diff --git a/src/zbits.c b/src/zbits.c
new file mode 100644
index 0000000..07c1591
--- /dev/null
+++ b/src/zbits.c
@@ -0,0 +1,21 @@
+/* See LICENSE file for copyright and license details. */
+#include "internals"
+
+
+size_t
+zbits(z_t a)
+{
+        size_t i;
+        uint32_t x;
+       if (zzero(a)) {
+               return 1;
+       }
+       for (i = a->used - 1;; i--) {
+               x = a->chars[i];
+               if (x) {
+                       a->used = i + 1;
+                       for (i *= BITS_PER_CHAR; x; x >>= 1, i++);
+                       return i;
+               }
+       }
+}
diff --git a/src/zfree.c b/src/zfree.c
new file mode 100644
index 0000000..f75bb38
--- /dev/null
+++ b/src/zfree.c
@@ -0,0 +1,13 @@
+/* See LICENSE file for copyright and license details. */
+#include "internals"
+
+#include <stdlib.h>
+
+
+void
+zfree(z_t a)
+{
+       free(a->chars);
+       a->alloced = 0;
+       a->chars = 0;
+}
diff --git a/src/zinit.c b/src/zinit.c
new file mode 100644
index 0000000..144534e
--- /dev/null
+++ b/src/zinit.c
@@ -0,0 +1,10 @@
+/* See LICENSE file for copyright and license details. */
+#include "internals"
+
+
+void
+zinit(z_t a)
+{
+       a->alloced = 0;
+       a->chars = 0;
+}
diff --git a/src/zload.c b/src/zload.c
new file mode 100644
index 0000000..53fae12
--- /dev/null
+++ b/src/zload.c
@@ -0,0 +1,24 @@
+/* See LICENSE file for copyright and license details. */
+#include "internals"
+
+#include <stdlib.h>
+#include <string.h>
+
+
+size_t
+zload(z_t a, const void *buffer)
+{
+        const char *buf = buffer;
+        a->sign    = *((int *)buf),    buf += sizeof(int);
+       a->used    = *((size_t *)buf), buf += sizeof(size_t);
+        a->alloced = *((size_t *)buf), buf += sizeof(size_t);
+       if (a->alloced) {
+               a->chars = realloc(a->chars, a->alloced * sizeof(*(a->chars)));
+       } else {
+               a->chars = 0;
+       }
+       if (a->sign) {
+                memcpy(a->chars, buf, a->used * sizeof(*(a->chars)));
+       }
+       return sizeof(z_t) - sizeof(a->chars) + (a->sign ? a->used * 
sizeof(*(a->chars)) : 0);
+}
diff --git a/src/zlsb.c b/src/zlsb.c
new file mode 100644
index 0000000..610b32f
--- /dev/null
+++ b/src/zlsb.c
@@ -0,0 +1,21 @@
+/* See LICENSE file for copyright and license details. */
+#include "internals"
+
+
+size_t
+zlsb(z_t a)
+{
+        size_t i = 0;
+        uint32_t x;
+       if (zzero(a)) {
+               return SIZE_MAX;
+       }
+       for (;; i++) {
+               x = a->chars[i];
+               if (x) {
+                       x = ~x;
+                       for (i *= BITS_PER_CHAR; x & 1; x >>= 1, i++);
+                       return i;
+               }
+       }
+}
diff --git a/src/zsave.c b/src/zsave.c
new file mode 100644
index 0000000..b312307
--- /dev/null
+++ b/src/zsave.c
@@ -0,0 +1,20 @@
+/* See LICENSE file for copyright and license details. */
+#include "internals"
+
+#include <string.h>
+
+
+size_t
+zsave(z_t a, void *buffer)
+{
+       if (buffer) {
+               char *buf = buffer;
+                *((int *)buf)    = a->sign,    buf += sizeof(int);
+                *((size_t *)buf) = a->used,    buf += sizeof(size_t);
+                *((size_t *)buf) = a->alloced, buf += sizeof(size_t);
+               if (a->sign) {
+                       memcpy(buf, a->chars, a->used * sizeof(*(a->chars)));
+               }
+       }
+       return sizeof(z_t) - sizeof(a->chars) + (a->sign ? a->used * 
sizeof(*(a->chars)) : 0);
+}
diff --git a/src/zsetup.c b/src/zsetup.c
new file mode 100644
index 0000000..626d6f6
--- /dev/null
+++ b/src/zsetup.c
@@ -0,0 +1,23 @@
+/* See LICENSE file for copyright and license details. */
+#include "internals"
+
+#define X(x)  z_t x;
+LIST_TEMPS
+#undef X
+
+jmp_buf libzahl_jmp_buf;
+int libzahl_set_up = 0;
+
+
+void
+zsetup(jmp_buf env)
+{
+        libzahl_jmp_buf = jmp_buf;
+
+       if (!libzahl_set_up) {
+               libzahl_set_up = 1;
+#define X(x)  zinit(zahl_tmp_##x);
+               LIST_TEMPS;
+#undef X
+       }
+}
diff --git a/src/zswap.c b/src/zswap.c
new file mode 100644
index 0000000..b9a1325
--- /dev/null
+++ b/src/zswap.c
@@ -0,0 +1,12 @@
+/* See LICENSE file for copyright and license details. */
+#include "internals"
+
+
+void
+zswap(z_t a, z_t b)
+{
+       z_t t;
+       *t = *a;
+       *a = *b;
+       *b = t;
+}
diff --git a/src/zunsetup.c b/src/zunsetup.c
new file mode 100644
index 0000000..0f766e1
--- /dev/null
+++ b/src/zunsetup.c
@@ -0,0 +1,14 @@
+/* See LICENSE file for copyright and license details. */
+#include "internals"
+
+
+void
+zunsetup(jmp_buf env)
+{
+       if (libzahl_set_up) {
+               libzahl_set_up = 0;
+#define X(x)  zfree(zahl_tmp_##x);
+               LIST_TEMPS;
+#undef X
+       }
+}

Reply via email to