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