scc

A fork of https://git.simple-cc.org/scc/ for Qute

git clone https://git.8pit.net/scc.git

  1#include <stdlib.h>
  2#include <scc/scc.h>
  3
  4/*
  5 * This is the most pedantic piece of code that I have written
  6 * in my life. The next union is used to enforce the alignment
  7 * of the address returned by new(). A union has the alignment
  8 * of the field with the biggest alignment. This union has all
  9 * the types that we use in scc, and we round all the addresses
 10 * to the alignment of this struct, so we can be sure that any
 11 * pointer using that address will be safe. The field ap is
 12 * in the union to be sure that struct pointers are included
 13 * in the list, although they will have the same alignment or
 14 * smaller than void *, but I wanted to be pedantic.
 15 */
 16union hdr {
 17	union hdr *next;
 18	struct arena *ap;
 19	char c;
 20	unsigned char uc;
 21	int i;
 22	short s;
 23	long l;
 24	long long ll;
 25	float f;
 26	double d;
 27	long double ld;
 28	void *vp;
 29};
 30
 31struct arena {
 32	struct arena *next;
 33	union hdr *array;
 34};
 35
 36struct alloc {
 37	size_t size;
 38	size_t nmemb;
 39	size_t padding;
 40	struct arena *arena;
 41	union hdr *freep;
 42};
 43
 44static void
 45newarena(Alloc *allocp)
 46{
 47	struct arena *ap;
 48	union hdr *bp, *lim;
 49	size_t unit, n = allocp->nmemb;
 50
 51	unit = (allocp->size-1) / sizeof(union hdr) + 1;
 52	ap = xmalloc(sizeof(struct arena));
 53	ap->array = xmalloc(unit * sizeof(union hdr) * n);
 54
 55	bp = ap->array;
 56	for (lim = &bp[unit * (n-1)]; bp < lim; bp += unit)
 57		bp->next = bp + unit;
 58	bp->next = NULL;
 59
 60	ap->next = allocp->arena;
 61	allocp->arena = ap;
 62	allocp->freep = ap->array;
 63}
 64
 65Alloc *
 66alloc(size_t size, size_t nmemb)
 67{
 68	Alloc *allocp = xmalloc(sizeof(*allocp));
 69
 70	allocp->size = size;
 71	allocp->nmemb = nmemb;
 72	allocp->arena = NULL;
 73	allocp->freep = NULL;
 74
 75	return allocp;
 76}
 77
 78void
 79dealloc(Alloc *allocp)
 80{
 81	struct arena *ap, *next;
 82
 83	for (ap = allocp->arena; ap; ap = next) {
 84		next = ap->next;
 85		free(ap->array);
 86		free(ap);
 87	}
 88	free(allocp);
 89}
 90
 91void *
 92new(Alloc *allocp)
 93{
 94	union hdr *bp;
 95
 96	if (!allocp->freep)
 97		newarena(allocp);
 98	bp = allocp->freep;
 99	allocp->freep = bp->next;
100
101	return bp;
102}
103
104void
105delete(Alloc *allocp, void *p)
106{
107	union hdr *bp = p;
108
109	bp->next = allocp->freep;
110	allocp->freep = bp;
111}