libzahl

big integer library
git clone git://git.suckless.org/libzahl
Log | Files | Refs | README | LICENSE

commit b0c1cae18066d0103a440894b5256939852021eb
parent f18ad18729afc971ea77e73869f8fb99da30c701
Author: Mattias Andrée <maandree@kth.se>
Date:   Tue,  1 Mar 2016 18:37:05 +0100

Add zsetup, zunsetup, zinit, zfree, zswap, zsave, zload, zbits, and zlsb

Signed-off-by: Mattias Andrée <maandree@kth.se>

Diffstat:
ATODO | 1+
Asrc/internals.h | 30++++++++++++++++++++++++++++++
Asrc/zbits.c | 21+++++++++++++++++++++
Asrc/zfree.c | 13+++++++++++++
Asrc/zinit.c | 10++++++++++
Asrc/zload.c | 24++++++++++++++++++++++++
Asrc/zlsb.c | 21+++++++++++++++++++++
Asrc/zsave.c | 20++++++++++++++++++++
Asrc/zsetup.c | 23+++++++++++++++++++++++
Asrc/zswap.c | 12++++++++++++
Asrc/zunsetup.c | 14++++++++++++++
11 files changed, 189 insertions(+), 0 deletions(-)

diff --git a/TODO b/TODO @@ -0,0 +1 @@ +Allocations shall be cached. diff --git a/src/internals.h 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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 + } +}