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