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*/