home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1989, 1991 Aladdin Enterprises. All rights reserved.
- Distributed by Free Software Foundation, Inc.
-
- This file is part of Ghostscript.
-
- Ghostscript is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
- to anyone for the consequences of using it or for whether it serves any
- particular purpose or works at all, unless he says so in writing. Refer
- to the Ghostscript General Public License for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- Ghostscript, but only under the conditions described in the Ghostscript
- General Public License. A copy of this license is supposed to have been
- given to you along with Ghostscript so you can know your rights and
- responsibilities. It should be in a file named COPYING. Among other
- things, the copyright notice and this notice must be preserved on all
- copies. */
-
- /* gsmisc.c */
- /* Miscellaneous utilities for Ghostscript library */
- #include "gx.h"
- #include "malloc_.h"
-
- /* Ghostscript writes to gs_out instead of stdout, */
- /* and writes debugging output to gs_debug_out. */
- FILE *gs_out;
- #ifdef DEBUG
- char gs_debug[128];
- FILE *gs_debug_out;
- #endif
-
- /* Versions of malloc and free compatible with Ghostscript's */
- /* model of memory management. We keep track of all allocated */
- /* blocks so we can free them at cleanup time. */
- typedef struct malloc_block_s malloc_block;
- struct malloc_block_s {
- malloc_block *next;
- uint size;
- char *cname;
- };
- private malloc_block *malloc_list = 0;
- char *
- gs_malloc(uint num_elts, uint elt_size, char *client_name)
- { char *ptr;
- uint size;
- if ( num_elts > (max_uint - sizeof(malloc_block)) / elt_size )
- { /* Can't represent the size in a uint! */
- lprintf3("%s: malloc(%u,%u) too large for size_t\n",
- client_name, num_elts, elt_size);
- return 0;
- }
- size = num_elts * elt_size;
- ptr = malloc(size + sizeof(malloc_block));
- if ( ptr == 0 )
- {
- #ifdef DEBUG
- if ( gs_debug['e'] | gs_debug['E'] )
- lprintf3("%s: malloc(%u,%u) failed\n",
- client_name, num_elts, elt_size);
- #endif
- }
- else
- { malloc_block *bp = (malloc_block *)ptr;
- bp->next = malloc_list;
- bp->size = size;
- bp->cname = client_name;
- malloc_list = bp;
- ptr = (char *)(bp + 1);
- #ifdef DEBUG
- if ( gs_debug['A'] | gs_debug['a'] )
- dprintf3("[a+]%lx:%u (%s)\n",
- (ulong)ptr, bp->size, client_name);
- /* Clear the block in an attempt to track down */
- /* uninitialized data errors. */
- { uint i;
- for ( i = 0; i < size; i++ ) ptr[i] = 0xa1;
- }
- #endif
- }
- return ptr;
- }
- void
- gs_free(char *ptr, uint num_elts, uint elt_size, char *client_name)
- { malloc_block *bp = malloc_list;
- #ifdef DEBUG
- if ( gs_debug['A'] | gs_debug['a'] )
- dprintf2("[a-]%lx:%u\n", (ulong)ptr, num_elts * elt_size);
- #endif
- if ( ptr == (char *)(bp + 1) )
- {
- #ifdef DEBUG
- if ( bp->size != num_elts * elt_size )
- lprintf5("%s: free 0x%x(%u,%u) size ~= %u\n",
- client_name, (ulong)ptr, num_elts, elt_size,
- bp->size);
- #endif
- malloc_list = bp->next;
- free(bp);
- }
- else
- { malloc_block *np;
- for ( ; (np = bp->next) != 0; bp = np )
- { if ( ptr == (char *)(np + 1) )
- {
- #ifdef DEBUG
- if ( np->size != num_elts * elt_size )
- lprintf5("%s: free 0x%x(%u,%u) size ~= %u\n",
- client_name, (ulong)ptr, num_elts, elt_size,
- np->size);
- #endif
- bp->next = np->next;
- free(np);
- return;
- }
- }
- lprintf4("%s: free 0x%x(%u,%u) not found\n",
- client_name, (ulong)ptr, num_elts, elt_size);
- free((char *)((malloc_block *)ptr - 1));
- }
- }
- void
- gs_malloc_release()
- { malloc_block *bp = malloc_list;
- malloc_block *np;
- for ( ; bp != 0; bp = np )
- { np = bp->next;
- free(bp);
- }
- malloc_list = 0;
- }
-