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)
14 char *FDECL(fmt_ptr, (const genericptr,char *));
15 #endif
16 
17 #ifdef MONITOR_HEAP
18 #undef alloc
19 #undef free
20 extern void FDECL(free,(genericptr_t));
21 static void NDECL(heapmon_init);
22 
23 static FILE *heaplog = 0;
24 static boolean tried_heaplog = FALSE;
25 #endif
26 
27 long *FDECL(alloc,(unsigned int));
28 extern void VDECL(panic, (const char *,...)) PRINTF_F(1,2);
29 
30 
31 long *
alloc(lth)32 alloc(lth)
33 register 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 */
79 char *
fmt_ptr(ptr,buf)80 fmt_ptr(ptr, buf)
81 const genericptr ptr;
82 char *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. */
94 static void
heapmon_init()95 heapmon_init()
96 {
97 	char *logname = getenv("NH_HEAPLOG");
98 
99 	if (logname && *logname)
100 		heaplog = fopen(logname, "w");
101 	tried_heaplog = TRUE;
102 }
103 
104 long *
nhalloc(lth,file,line)105 nhalloc(lth, file, line)
106 unsigned int lth;
107 const char *file;
108 int 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 
125 void
nhfree(ptr,file,line)126 nhfree(ptr, file, line)
127 genericptr_t ptr;
128 const char *file;
129 int 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