scc

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

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

 1#include <errno.h>
 2#include <stdint.h>
 3#include <stdlib.h>
 4#include <string.h>
 5
 6#include "malloc.h"
 7#undef realloc
 8
 9void *
10realloc(void *ptr, size_t nbytes)
11{
12	Header *oh, *prev, *next, *new;
13	size_t nunits, avail, onbytes, n;
14
15	if (nbytes == 0) {
16		free(ptr);
17		ptr = NULL;
18	} else if (nbytes > SIZE_MAX - sizeof(Header)-1) {
19		errno = ENOMEM;
20		return NULL;
21	}
22
23	if (!ptr)
24		return malloc(nbytes);
25
26	nunits = (nbytes+sizeof(Header)-1)/sizeof(Header) + 1;
27	oh = (Header *) ptr - 1;
28
29	if (oh->h.size == nunits)
30		return ptr;
31
32	new = oh + nunits;
33
34	if (nunits < oh->h.size) {
35		new->h.size = oh->h.size - nunits;
36		oh->h.size = nunits;
37		free(new + 1);
38		return ptr;
39	}
40
41	prev = _prevchunk(oh);
42	next = prev->h.next;
43
44	if (oh + oh->h.size == next) {
45		/*
46		 * if there is free space adjacent
47		 * to the current memory
48		 */
49		avail = oh->h.size + next->h.size;
50
51		if (avail == nunits) {
52			oh->h.size = nunits;
53			prev->h.next = next->h.next;
54			_freep = prev;
55			return ptr;
56		}
57
58		if (nunits < avail) {
59			oh->h.size = nunits;
60			prev->h.next = new;
61			new->h.next = next->h.next;
62			new->h.size = avail - nunits;
63			_freep = new;
64			return ptr;
65		}
66	}
67
68	if ((new = malloc(nbytes)) == NULL)
69		return NULL;
70
71	n = (oh->h.size - 1) * sizeof(Header);
72	if (n > nbytes)
73		n = nbytes;
74	memcpy(new, ptr, n);
75	free(ptr);
76
77	return new;
78}