OSDN Git Service

GCC says embedding a directive within macro arguments is not portable
[jnethack/source.git] / src / alloc.c
1 /* NetHack 3.6  alloc.c $NHDT-Date: 1454376505 2016/02/02 01:28:25 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.16 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2012. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 /* to get the malloc() prototype from system.h */
7 #define ALLOC_C /* comment line for pre-compiled headers */
8 /* since this file is also used in auxiliary programs, don't include all the
9    function declarations for all of nethack */
10 #define EXTERN_H /* comment line for pre-compiled headers */
11 #include "config.h"
12
13 char *FDECL(fmt_ptr, (const genericptr));
14
15 #ifdef MONITOR_HEAP
16 #undef alloc
17 #undef free
18 extern void FDECL(free, (genericptr_t));
19 static void NDECL(heapmon_init);
20
21 static FILE *heaplog = 0;
22 static boolean tried_heaplog = FALSE;
23 #endif
24
25 long *FDECL(alloc, (unsigned int));
26 extern void VDECL(panic, (const char *, ...)) PRINTF_F(1, 2);
27
28 long *
29 alloc(lth)
30 register unsigned int lth;
31 {
32 #ifdef LINT
33     /*
34      * a ridiculous definition, suppressing
35      *  "possible pointer alignment problem" for (long *) malloc()
36      * from lint
37      */
38     long dummy = ftell(stderr);
39
40     if (lth)
41         dummy = 0; /* make sure arg is used */
42     return &dummy;
43 #else
44     register genericptr_t ptr;
45
46     ptr = malloc(lth);
47 #ifndef MONITOR_HEAP
48     if (!ptr)
49         panic("Memory allocation failure; cannot get %u bytes", lth);
50 #endif
51     return (long *) ptr;
52 #endif
53 }
54
55 #ifdef HAS_PTR_FMT
56 #define PTR_FMT "%p"
57 #define PTR_TYP genericptr_t
58 #else
59 #define PTR_FMT "%06lx"
60 #define PTR_TYP unsigned long
61 #endif
62
63 /* A small pool of static formatting buffers.
64  * PTRBUFSIZ:  We assume that pointers will be formatted as integers in
65  * hexadecimal, requiring at least 16+1 characters for each buffer to handle
66  * 64-bit systems, but the standard doesn't mandate that encoding and an
67  * implementation could do something different for %p, so we make some
68  * extra room.
69  * PTRBUFCNT:  Number of formatted values which can be in use at the same
70  * time.  To have more, callers need to make copies of them as they go.
71  */
72 #define PTRBUFCNT 4
73 #define PTRBUFSIZ 32
74 static char ptrbuf[PTRBUFCNT][PTRBUFSIZ];
75 static int ptrbufidx = 0;
76
77 /* format a pointer for display purposes; returns a static buffer */
78 char *
79 fmt_ptr(ptr)
80 const genericptr ptr;
81 {
82     char *buf;
83
84     buf = ptrbuf[ptrbufidx];
85     if (++ptrbufidx >= PTRBUFCNT)
86         ptrbufidx = 0;
87
88     Sprintf(buf, PTR_FMT, (PTR_TYP) ptr);
89     return buf;
90 }
91
92 #ifdef MONITOR_HEAP
93
94 /* If ${NH_HEAPLOG} is defined and we can create a file by that name,
95    then we'll log the allocation and release information to that file. */
96 static void
97 heapmon_init()
98 {
99     char *logname = getenv("NH_HEAPLOG");
100
101     if (logname && *logname)
102         heaplog = fopen(logname, "w");
103     tried_heaplog = TRUE;
104 }
105
106 long *
107 nhalloc(lth, file, line)
108 unsigned int lth;
109 const char *file;
110 int line;
111 {
112     long *ptr = alloc(lth);
113
114     if (!tried_heaplog)
115         heapmon_init();
116     if (heaplog)
117         (void) fprintf(heaplog, "+%5u %s %4d %s\n", lth,
118                        fmt_ptr((genericptr_t) ptr), line, file);
119     /* potential panic in alloc() was deferred til here */
120     if (!ptr)
121         panic("Cannot get %u bytes, line %d of %s", lth, line, file);
122
123     return ptr;
124 }
125
126 void
127 nhfree(ptr, file, line)
128 genericptr_t ptr;
129 const char *file;
130 int line;
131 {
132     if (!tried_heaplog)
133         heapmon_init();
134     if (heaplog)
135         (void) fprintf(heaplog, "-      %s %4d %s\n",
136                        fmt_ptr((genericptr_t) ptr), line, file);
137
138     free(ptr);
139 }
140
141 /* strdup() which uses our alloc() rather than libc's malloc(),
142    with caller tracking */
143 char *
144 nhdupstr(string, file, line)
145 const char *string;
146 const char *file;
147 int line;
148 {
149     return strcpy((char *) nhalloc(strlen(string) + 1, file, line), string);
150 }
151 #undef dupstr
152
153 #endif /* MONITOR_HEAP */
154
155 /* strdup() which uses our alloc() rather than libc's malloc();
156    not used when MONITOR_HEAP is enabled, but included unconditionally
157    in case utility programs get built using a different setting for that */
158 char *
159 dupstr(string)
160 const char *string;
161 {
162     return strcpy((char *) alloc(strlen(string) + 1), string);
163 }
164
165 /*alloc.c*/