1/*	SCCS Id: @(#)alloc.c	3.4	1995/10/04	*/
2/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3/* NetHack may be freely redistributed.  See license for details. */
4
5/* to get the malloc() prototype from system.h */
6#define ALLOC_C		/* comment line for pre-compiled headers */
7/* since this file is also used in auxiliary programs, don't include all the
8 * function declarations for all of nethack
9 */
10#define EXTERN_H	/* comment line for pre-compiled headers */
11#include "config.h"
12
13#if defined(MONITOR_HEAP) || defined(WIZARD)
14char *FDECL(fmt_ptr, (const genericptr,char *));
15#endif
16
17#ifdef MONITOR_HEAP
18#undef alloc
19#undef free
20extern void FDECL(free,(genericptr_t));
21static void NDECL(heapmon_init);
22
23static FILE *heaplog = 0;
24static boolean tried_heaplog = FALSE;
25#endif
26
27long *FDECL(alloc,(unsigned int));
28extern void VDECL(panic, (const char *,...)) PRINTF_F(1,2);
29
30
31long *
32alloc(lth)
33register unsigned int lth;
34{
35#ifdef LINT
36/*
37 * a ridiculous definition, suppressing
38 *	"possible pointer alignment problem" for (long *) malloc()
39 * from lint
40 */
41	long dummy = ftell(stderr);
42
43	if(lth) dummy = 0;	/* make sure arg is used */
44	return(&dummy);
45#else
46	register genericptr_t ptr;
47
48	ptr = malloc(lth);
49#ifndef MONITOR_HEAP
50	if (!ptr) panic("Memory allocation failure; cannot get %u bytes", lth);
51#endif
52	return((long *) ptr);
53#endif
54}
55
56
57#if defined(MONITOR_HEAP) || defined(WIZARD)
58
59# if defined(MICRO) || defined(WIN32)
60/* we actually want to know which systems have an ANSI run-time library
61 * to know which support the new %p format for printing pointers.
62 * due to the presence of things like gcc, NHSTDC is not a good test.
63 * so we assume microcomputers have all converted to ANSI and bigger
64 * computers which may have older libraries give reasonable results with
65 * the cast.
66 */
67#  define MONITOR_PTR_FMT
68# endif
69
70# ifdef MONITOR_PTR_FMT
71#  define PTR_FMT "%p"
72#  define PTR_TYP genericptr_t
73# else
74#  define PTR_FMT "%06lx"
75#  define PTR_TYP unsigned long
76# endif
77
78/* format a pointer for display purposes; caller supplies the result buffer */
79char *
80fmt_ptr(ptr, buf)
81const genericptr ptr;
82char *buf;
83{
84	Sprintf(buf, PTR_FMT, (PTR_TYP)ptr);
85	return buf;
86}
87
88#endif
89
90#ifdef MONITOR_HEAP
91
92/* If ${NH_HEAPLOG} is defined and we can create a file by that name,
93   then we'll log the allocation and release information to that file. */
94static void
95heapmon_init()
96{
97	char *logname = getenv("NH_HEAPLOG");
98
99	if (logname && *logname)
100		heaplog = fopen(logname, "w");
101	tried_heaplog = TRUE;
102}
103
104long *
105nhalloc(lth, file, line)
106unsigned int lth;
107const char *file;
108int line;
109{
110	long *ptr = alloc(lth);
111	char ptr_address[20];
112
113	if (!tried_heaplog) heapmon_init();
114	if (heaplog)
115		(void) fprintf(heaplog, "+%5u %s %4d %s\n", lth,
116				fmt_ptr((genericptr_t)ptr, ptr_address),
117				line, file);
118	/* potential panic in alloc() was deferred til here */
119	if (!ptr) panic("Cannot get %u bytes, line %d of %s",
120			lth, line, file);
121
122	return ptr;
123}
124
125void
126nhfree(ptr, file, line)
127genericptr_t ptr;
128const char *file;
129int line;
130{
131	char ptr_address[20];
132
133	if (!tried_heaplog) heapmon_init();
134	if (heaplog)
135		(void) fprintf(heaplog, "-      %s %4d %s\n",
136				fmt_ptr((genericptr_t)ptr, ptr_address),
137				line, file);
138
139	free(ptr);
140}
141
142#endif /* MONITOR_HEAP */
143
144/*alloc.c*/
145