/*
 * This source file is part of Vahunz,
 * a tool to make source code un-/more legible.
 *
 *--------------------------------------------------------------------------
 *
 * Vahunz and the Ugly library are Copyright (C) 1998 by
 * Thomas Aglassinger <agi@giga.or.at>
 *
 * All rights reserved.
 *
 * Refer to the manual for more information.
 *
 *--------------------------------------------------------------------------
 *
 * Ubiqx library is Copyright (C) 1991-1998 by
 * Christopher R. Hertel <crh@ubiqx.mn.org>
 *
 * Ubiqx library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "utypes.h"
#define e8U
#include "umemory.h"
#define a2C 16
#if defined(AMIGA)
#define d7J 8 
#else
#define d7J 8
#endif
#ifndef c4M
#define c4M(x,by) ((by)*(((x)+(by-1))/(by)))
#endif
static s4Q *x3B = NULL;
static UBYTE z7P[4] =
{0xDE, 0xAD, 0xBE, 0xEF}; 
static UBYTE m2Ep[4] =
{0xDE, 0xAD, 0xF0, 0x0D}; 
static UBYTE z1X = 0x81;
static ULONG g4A = 0; 
static ULONG m6W = 0; 
static ULONG f9Dw = 0; 
static ULONG d3T = 0; 
static ULONG a2Wl = 0; 
static ULONG e6O = 0; 
static ULONG t1L = 0; 
static ULONG u4U = 0; 
static ULONG w0S = 0; 
static ULONG v3V = 0; 
void *q4E(size_t u0Qh);
static BOOL p1L(s4Q * l1Pu);
BOOL(*k0Cr) (size_t u0Qh) = NULL;
VOID i0Y(char *msg, char *j5R, size_t q6U)
{
fprintf(stderr, "\n\n");
fprintf(stderr, "  I won't be a monkey in anyone's zoo\n");
fprintf(stderr, "  I won't get fazed whatever you do\n");
fprintf(stderr, "                   (Ride, \"Not Fazed\")\n\n");
fprintf(stderr, "** internal error: \"%s\" (%lu): %s\n", \
j5R, (unsigned long) q6U, msg);
exit(255);
}
static s4Q *r5T(void *mem)
{
s4Q *q8Gz = x3B;
s4Q *y0O = NULL;
while (q8Gz && (!y0O))
{
if (q8Gz->ptr == mem)
{
y0O = q8Gz;
}
q8Gz = q8Gz->z7X;
}
#if c6K==2
if (!y0O)
{
fprintf(stderr, "*memory* FIND_UMEM: couln't find %p\n", mem);
}
#endif
return (y0O);
}
static s4Q *h1Z(s4Q * l1Pu)
{
s4Q *prev = x3B;
s4Q *p9B = NULL;
BOOL y0O = FALSE;
while (prev && (!y0O))
{
y0O = (prev == l1Pu);
if (!y0O)
{
p9B = prev;
prev = prev->z7X;
}
}
return (p9B);
}
static void v9X(void *mem, size_t u0Qh, UBYTE value[4])
{
size_t i;
for (i = 0; i < u0Qh; i++)
{
(((UBYTE *) mem)[i]) = value[i % 4];
}
}
static void f1By(void *mem, size_t u0Qh, UBYTE value)
{
size_t i;
for (i = 0; i < u0Qh; i++)
{
(((UBYTE *) mem)[i]) = value;
}
}
static void r7X(s4Q * l1Pu)
{
s4Q *prev = h1Z(l1Pu);
if (prev)
{
prev->z7X = l1Pu->z7X;
}
else
{
x3B = l1Pu->z7X;
}
if (!p1L(l1Pu))
{
v9X(l1Pu->j7R, l1Pu->u0Qh + 2 * a2C, z7P);
free(l1Pu->j7R);
}
l1Pu->j7R = NULL;
l1Pu->m6S = NULL;
l1Pu->u0Qh = 0;
l1Pu->j5R = NULL;
l1Pu->q6U = 0;
free(l1Pu);
}
static s4Q *o8O(size_t p1Bk, STRPTR b1J, ULONG o6O)
{
s4Q *w6U = (s4Q *) malloc(sizeof(s4Q));
if (w6U)
{
w6U->j7R = (UBYTE *) q4E(p1Bk
+ 2 * a2C);
if (w6U->j7R)
{
w6U->ptr = (void *) (w6U->j7R + a2C);
w6U->m6S = (w6U->j7R + a2C + p1Bk);
w6U->z7X = x3B;
x3B = w6U;
w6U->u0Qh = p1Bk;
w6U->j5R = b1J;
w6U->q6U = o6O;
w6U->c2G = z1X;
v9X(w6U->ptr, p1Bk, m2Ep);
f1By(w6U->j7R, a2C, z1X);
f1By(w6U->m6S, a2C, z1X);
if (z1X == 0xff)
{
z1X = 0x81;
}
else
{
z1X++;
}
}
else
free(w6U);
}
return (w6U);
}
static void u4C(STRPTR msg)
{
fprintf(stderr, "%s\n", msg);
}
static void d1T(void *ptr, size_t u0Qh)
{
unsigned char *data = (unsigned char *) ptr;
if (u0Qh > 16)
{
u0Qh = 16;
}
fprintf(stderr, "  %p:", ptr);
if (data)
{
size_t i;
for (i = 0; i < u0Qh; i++)
{
if (!(i % 4))
{
fprintf(stderr, " ");
}
fprintf(stderr, "%02x", data[i]);
}
while (i < 16)
{
if (!(i % 4))
{
fprintf(stderr, " ");
}
fprintf(stderr, "  ");
i++;
}
fprintf(stderr, "  \"");
for (i = 0; i < u0Qh; i++)
{
if (data[i] < ' ' || ((data[i] > 128) && (data[i] < 160)))
{
fprintf(stderr, ".");
}
else
{
fprintf(stderr, "%c", data[i]);
}
}
fprintf(stderr, "\"\n");
}
else
fprintf(stderr, "NULL\n");
}
static void b3R(void *ptr, STRPTR j5R, ULONG q6U)
{
fprintf(stderr, "  %p: from \"%s\" (%lu)\n", ptr, j5R, q6U);
}
static void b7D(s4Q * l1Pu)
{
fprintf(stderr, "  %p: %lu (0x%lx) bytes from \"%s\" (%lu)\n",
l1Pu->ptr, (ULONG) l1Pu->u0Qh, (ULONG) l1Pu->u0Qh,
l1Pu->j5R, l1Pu->q6U);
}
static STRPTR a2M(UBYTE p5X)
{
static z5N j9Z[30];
UBYTE ch = p5X;
if (ch < 32)
ch = '.';
sprintf(j9Z, "(0x%02x/#%d/`%c')", p5X, p5X, ch);
return (j9Z);
}
static BOOL p1L(s4Q * l1Pu)
{
size_t i = 0;
BOOL t1Jq = FALSE;
while (!t1Jq && (i < a2C))
{
BOOL m4Q = (l1Pu->j7R[i] != l1Pu->c2G);
BOOL h3F = (l1Pu->m6S[i] != l1Pu->c2G);
t1Jq = m4Q || h3F;
if (t1Jq)
{
STRPTR c8M;
UBYTE value;
if (m4Q)
{
c8M = "LOWER";
value = l1Pu->j7R[i];
}
else
{
c8M = "UPPER";
value = l1Pu->m6S[i];
}
fprintf(stderr, "*** MEMORY WALL DAMAGED!!!\n");
fprintf(stderr, "*** %s wall, byte#%lu is %s instead of 0x%02x\n",
c8M, (ULONG) i, a2M(value), l1Pu->c2G);
b7D(l1Pu);
d1T(l1Pu->ptr, l1Pu->u0Qh);
fprintf(stderr, "  * lower wall:\n");
d1T(l1Pu->j7R, a2C);
fprintf(stderr, "  * upper wall:\n");
d1T(l1Pu->m6S, a2C);
}
else
{
i++;
}
}
return (t1Jq);
}
VOID b9D(STRPTR msg, STRPTR j5R, ULONG q6U)
{
s4Q *l1Pu = x3B;
if (l1Pu)
{
fprintf(stderr, "MEMORY WALL-CHECK (%s)", msg);
if (j5R)
fprintf(stderr, " from `%s' (%lu)", j5R, q6U);
fprintf(stderr, "\n");
while (l1Pu)
{
if (l1Pu->ptr)
{
p1L(l1Pu);
l1Pu = l1Pu->z7X;
}
else
{
l1Pu = NULL;
fprintf(stderr, "\n** PANIC: memory list trashed\n");
}
}
}
}
void l5Z(STRPTR msg, STRPTR j5R, ULONG q6U, STRPTR date, STRPTR time)
{
s4Q *l1Pu = x3B;
if (l1Pu)
{
fprintf(stderr, "MEMORY REPORT (%s)\n", msg);
if (j5R)
{
fprintf(stderr, "(\"%s\" (%lu), at %s, %s)\n",
j5R, q6U, date, time);
}
while (l1Pu)
{
if (l1Pu->ptr)
{
b7D(l1Pu);
d1T(l1Pu->ptr, l1Pu->u0Qh);
l1Pu = l1Pu->z7X;
}
else
{
l1Pu = NULL;
fprintf(stderr, "##\n## panic: memory list trashed\n##\n");
}
}
}
}
void q4M(STRPTR msg, STRPTR j5R, ULONG q6U, STRPTR date, STRPTR time)
{
fprintf(stderr, "MEMORY STATISTICS (%s)\n", msg);
if (j5R)
{
fprintf(stderr, "(\"%s\" (%lu), at %s, %s)\n",
j5R, q6U, date, time);
}
fprintf(stderr, "  bytes used: %lu max: %lu/%lu  ",
e6O, t1L,
a2Wl);
if (a2Wl)
{
fprintf(stderr, "slack: %lu%%\n",
(100 * (t1L - a2Wl))
/ a2Wl);
}
else
{
fprintf(stderr, "no slack\n");
}
fprintf(stderr, "  nodes used: %lu (max: %lu)\n",
v3V, w0S);
fprintf(stderr, "  calls to: umalloc(%lu)   ufree(%lu)\n",
g4A, m6W);
}
void d3V(void)
{
ULONG c0O = e6O;
l5Z("at exit:  MEMORY LEAK detected!",
NULL, 0, NULL, NULL);
q4M("[exit]", NULL, 0, NULL, NULL);
while (x3B)
{
r7X(x3B);
}
if (c0O)
{
fprintf(stderr, "\n%lu bytes of memory lost!\n", c0O);
}
}
void q8G(void)
{
}
void *q4E(size_t u0Qh)
{
void *mem;
BOOL m6Q;
do
{
mem = malloc(u0Qh);
if (!mem && k0Cr)
{
m6Q = (*k0Cr) (u0Qh);
if (!m6Q)
{
exit(EXIT_FAILURE); 
}
}
else
{
m6Q = FALSE;
}
}
while (m6Q);
return (mem);
}
void *n3V(size_t u0Qh, STRPTR j5R, ULONG q6U)
{
void *mem = NULL;
s4Q *l1Pu = NULL;
#if c6K==2
fprintf(stderr, "*memory* UMALLOC() from `%s' (%lu)\n", j5R, q6U);
#endif
if (u0Qh)
{
g4A++;
l1Pu = o8O(u0Qh, j5R, q6U);
if (l1Pu)
{
mem = l1Pu->ptr;
e6O += u0Qh;
u4U += c4M(u0Qh, d7J);
if (e6O > a2Wl)
a2Wl = e6O;
if (u4U > t1L)
t1L = u4U;
v3V++;
if (v3V > w0S)
w0S = v3V;
}
}
else
{
f9Dw++;
u4C("MALLOC: zero-sized allocation");
b3R(NULL, j5R, q6U);
}
return (mem);
}
void u6K(void *ptr, STRPTR j5R, ULONG q6U)
{
#if c6K==2
fprintf(stderr, "*memory* UFREE() from `%s' (%lu)\n", j5R, q6U);
#elif 0
fputc('.', stderr); 
fflush(stderr);
#endif
if (ptr)
{
s4Q *l1Pu = r5T(ptr);
if (l1Pu)
{
m6W++;
e6O -= l1Pu->u0Qh;
u4U -= c4M(l1Pu->u0Qh, d7J);
r7X(l1Pu);
v3V--;
}
else
{
d3T++;
u4C("*** FREE: memory never allocated "
" or released twice");
b3R(ptr, j5R, q6U);
}
}
}
void *g0Cd(void *ptr, size_t u0Qh, STRPTR j5R, ULONG q6U)
{
void *o2O = n3V(u0Qh, j5R, q6U);
s4Q *l1Pu = r5T(ptr);
if (o2O && l1Pu)
{
memcpy(o2O, l1Pu->ptr, l1Pu->u0Qh);
u6K(ptr, j5R, q6U);
}
return (o2O);
}
void *i4I(size_t count, size_t u0Qh, STRPTR j5R, ULONG q6U)
{
void *mem = n3V(count * u0Qh, j5R, q6U);
if (mem)
{
memset(mem, 0, u0Qh * count);
}
return (mem);
}
