Update for 0.51.0
[wmaker-crm.git] / WINGs / memory.c
blobe694f9508c56698030cb6d1e4870e1fd4a7622d6
1 /*
2 * Window Maker miscelaneous function library
3 *
4 * Copyright (c) 1997 Alfredo K. Kojima
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "../src/config.h"
24 #include "WUtil.h"
26 #include <stdlib.h>
27 #include <sys/types.h>
28 #include <unistd.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <assert.h>
32 #include <signal.h>
34 #ifndef False
35 # define False 0
36 #endif
37 #ifndef True
38 # define True 1
39 #endif
42 static void
43 defaultHandler(int bla)
45 if (bla)
46 raise(SIGABRT);
47 else
48 exit(1);
52 static waborthandler *aborthandler = (waborthandler*)defaultHandler;
54 #define wAbort(a) (*aborthandler)(a)
57 waborthandler*
58 wsetabort(waborthandler *handler)
60 waborthandler *old = aborthandler;
62 aborthandler = handler;
64 return old;
69 static int Aborting=0; /* if we're in the middle of an emergency exit */
72 static WMHashTable *table = NULL;
75 void *wmalloc(size_t size)
77 void *tmp;
79 tmp = malloc(size);
80 if (tmp == NULL) {
81 wwarning("malloc() failed. Retrying after 2s.");
82 sleep(2);
83 tmp = malloc(size);
84 if (tmp == NULL) {
85 if (Aborting) {
86 puts("Real Bad Error: recursive malloc() failure.");
87 exit(-1);
88 } else {
89 wfatal("virtual memory exhausted");
90 Aborting=1;
91 wAbort(False);
95 return tmp;
99 void *wrealloc(void *ptr, size_t newsize)
101 void *nptr;
103 if (!ptr) {
104 nptr = malloc(newsize);
105 } else {
106 nptr=realloc(ptr, newsize);
108 if (nptr==NULL) {
109 printf("Could not do realloc");
110 return NULL;
112 return nptr;
116 void*
117 wretain(void *ptr)
119 int *refcount;
121 if (!table) {
122 table = WMCreateHashTable(WMIntHashCallbacks);
125 refcount = WMHashGet(table, ptr);
126 if (!refcount) {
127 refcount = wmalloc(sizeof(int));
128 *refcount = 1;
129 WMHashInsert(table, ptr, refcount);
130 #ifdef VERBOSE
131 printf("== %i (%p)\n", *refcount, ptr);
132 #endif
133 } else {
134 (*refcount)++;
135 #ifdef VERBOSE
136 printf("+ %i (%p)\n", *refcount, ptr);
137 #endif
140 return ptr;
144 void
145 wrelease(void *ptr)
147 int *refcount;
149 refcount = WMHashGet(table, ptr);
150 if (!refcount) {
151 wwarning("trying to release unexisting data %p", ptr);
152 } else {
153 (*refcount)--;
154 if (*refcount < 1) {
155 #ifdef VERBOSE
156 printf("RELEASING %p\n", ptr);
157 #endif
158 WMHashRemove(table, ptr);
159 free(refcount);
160 free(ptr);
162 #ifdef VERBOSE
163 else {
164 printf("- %i (%p)\n", *refcount, ptr);
166 #endif
171 char*
172 wstrdup(char *str)
174 assert(str!=NULL);
176 return strcpy(wmalloc(strlen(str)+1), str);
180 char*
181 wstrappend(char *dst, char *src)
183 char *str;
185 if (!dst)
186 return wstrdup(src);
187 else if (!src)
188 return wstrdup(dst);
190 str = wmalloc(strlen(dst)+strlen(src)+1);
191 strcpy(str, dst);
192 strcat(str, src);
194 return str;