1    | /*	SCCS Id: @(#)alloc.c	3.3	95/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 *
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   | # ifdef MICRO
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 *
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
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 *
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
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*/