1 /*
2  *    (c) Copyright 2004  Uwe Steinmann.
3  *    All rights reserved.
4  *
5  *    This library is free software; you can redistribute it and/or
6  *    modify it under the terms of the GNU Lesser General Public
7  *    License as published by the Free Software Foundation; either
8  *    version 2 of the License, or (at your option) any later version.
9  *
10  *    This library is distributed in the hope that it will be useful,
11  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *    Lesser General Public License for more details.
14  *
15  *    You should have received a copy of the GNU Lesser General Public
16  *    License along with this library; if not, write to the
17  *    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  *    Boston, MA 02111-1307, USA.
19  */
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include "ps_intern.h"
28 #include "libps/pslib-mp.h"
29 #include "ps_error.h"
30 
31 #define MAXMEM 15000
32 
33 struct mem {
34 	void *ptr;
35 	int size;
36 	char *caller;
37 };
38 
39 static struct mem memlist[MAXMEM];
40 static int peakmem = 0;
41 static int summem = 0;
42 
43 PSLIB_API void PSLIB_CALL
PS_mp_init()44 PS_mp_init() {
45 	memset(memlist, 0, MAXMEM*sizeof(struct mem));
46 }
47 
48 PSLIB_API void * PSLIB_CALL
PS_mp_malloc(PSDoc * p,size_t size,const char * caller)49 PS_mp_malloc(PSDoc *p, size_t size, const char *caller) {
50 	void *a;
51 	int i;
52 	a = (void *) malloc(size);
53 	if(NULL == a)
54 		return NULL;
55 	i = 0;
56 	/* Find a free slot in the list of memory blocks */
57 	while((i < MAXMEM) && (memlist[i].ptr != NULL)) {
58 		i++;
59 	}
60 	if(i >= MAXMEM) {
61 		fprintf(stderr, _("Aiii, no more space for new memory block. Enlarge MAXMEM in %s."), __FILE__);
62 		fprintf(stderr, "\n");
63 	}
64 	memlist[i].ptr = a;
65 	memlist[i].size = size;
66 	summem += size;
67 	peakmem = (summem > peakmem) ? summem : peakmem;
68 	memlist[i].caller = strdup(caller);
69 	return(a);
70 }
71 
72 PSLIB_API void * PSLIB_CALL
PS_mp_realloc(PSDoc * p,void * mem,size_t size,const char * caller)73 PS_mp_realloc(PSDoc *p, void *mem, size_t size, const char *caller) {
74 	void *a;
75 	int i;
76 	a = realloc(mem, size);
77 	if(NULL == a)
78 		return NULL;
79 	i = 0;
80 	while((i < MAXMEM) && (memlist[i].ptr != mem)) {
81 		i++;
82 	}
83 	if(i >= MAXMEM) {
84 		fprintf(stderr, _("Aiii, did not find memory block at 0x%X to enlarge: %s"), (unsigned int) mem, caller);
85 		fprintf(stderr, "\n");
86 	}
87 	memlist[i].ptr = a;
88 	summem -= memlist[i].size;
89 	summem += size;
90 	memlist[i].size = size;
91 	free(memlist[i].caller);
92 	memlist[i].caller = strdup(caller);
93 
94 	return(a);
95 }
96 
97 PSLIB_API void PSLIB_CALL
PS_mp_free(PSDoc * p,void * mem)98 PS_mp_free(PSDoc *p, void *mem) {
99 	int i;
100 	if(NULL == mem) {
101 		fprintf(stderr, _("Aiii, you cannot free a NULL pointer."));
102 		fprintf(stderr, "\n");
103 		return;
104 	}
105 	i = 0;
106 	while((i < MAXMEM) && (memlist[i].ptr != mem)) {
107 		i++;
108 	}
109 	if(i >= MAXMEM) {
110 		fprintf(stderr, _("Aiii, did not find memory block at 0x%X to free."), (unsigned int) mem);
111 		fprintf(stderr, "\n");
112 	} else {
113 		memlist[i].ptr = NULL;
114 		summem -= memlist[i].size;
115 		memlist[i].size = 0;
116 		free(memlist[i].caller);
117 	}
118 	free(mem);
119 }
120 
121 PSLIB_API void PSLIB_CALL
PS_mp_list_unfreed()122 PS_mp_list_unfreed() {
123 	int i, j, l;
124 	const char *ptr;
125 	i = j = 0;
126 	while(i < MAXMEM) {
127 		if(memlist[i].ptr) {
128 			fprintf(stderr, _("%d. Memory at address 0x%X (%d) not freed: '%s'."), j, (unsigned int) memlist[i].ptr, memlist[i].size, memlist[i].caller);
129 			ptr = memlist[i].ptr;
130 			for(l=0; l<memlist[i].size; l++, ptr++) {
131 				fputc(*ptr, stderr);
132 			}
133 			fprintf(stderr, "\n");
134 			j++;
135 		}
136 		i++;
137 	}
138 	fprintf(stderr, _("Remaining unfreed memory: %d Bytes."), summem);
139 	fprintf(stderr, "\n");
140 	fprintf(stderr, _("Max. amount of memory used: %d Bytes."), peakmem);
141 	fprintf(stderr, "\n");
142 }
143 
144 /*
145  * Local variables:
146  * tab-width: 4
147  * c-basic-offset: 4
148  * End:
149  * vim600: sw=4 ts=4 fdm=marker
150  * vim<600: sw=4 ts=4
151  */
152