[BACK]Return to alloc.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot

Annotation of OpenXM_contrib/gnuplot/alloc.c, Revision 1.1

1.1     ! maekawa     1: #ifndef lint
        !             2: static char *RCSid = "$Id: alloc.c,v 1.12 1998/03/22 22:31:16 drd Exp $";
        !             3: #endif
        !             4:
        !             5: /* GNUPLOT - alloc.c */
        !             6:
        !             7: /*[
        !             8:  * Copyright 1986 - 1993, 1998   Thomas Williams, Colin Kelley
        !             9:  *
        !            10:  * Permission to use, copy, and distribute this software and its
        !            11:  * documentation for any purpose with or without fee is hereby granted,
        !            12:  * provided that the above copyright notice appear in all copies and
        !            13:  * that both that copyright notice and this permission notice appear
        !            14:  * in supporting documentation.
        !            15:  *
        !            16:  * Permission to modify the software is granted, but not the right to
        !            17:  * distribute the complete modified source code.  Modifications are to
        !            18:  * be distributed as patches to the released version.  Permission to
        !            19:  * distribute binaries produced by compiling modified sources is granted,
        !            20:  * provided you
        !            21:  *   1. distribute the corresponding source modifications from the
        !            22:  *    released version in the form of a patch file along with the binaries,
        !            23:  *   2. add special version identification to distinguish your version
        !            24:  *    in addition to the base release version number,
        !            25:  *   3. provide your name and address as the primary contact for the
        !            26:  *    support of your modified version, and
        !            27:  *   4. retain our contact information in regard to use of the base
        !            28:  *    software.
        !            29:  * Permission to distribute the released version of the source code along
        !            30:  * with corresponding source modifications in the form of a patch file is
        !            31:  * granted with same provisions 2 through 4 for binary distributions.
        !            32:  *
        !            33:  * This software is provided "as is" without express or implied warranty
        !            34:  * to the extent permitted by applicable law.
        !            35: ]*/
        !            36:
        !            37: /*
        !            38:  * AUTHORS
        !            39:  *
        !            40:  * Alexander Lehmann (collected functions from misc.c and binary.c)
        !            41:  *
        !            42:  */
        !            43:
        !            44: #include "plot.h" /* includes "alloc.h" */
        !            45:
        !            46: #if defined(MSDOS) && defined(__TURBOC__) && !defined(DOSX286)
        !            47: #include <alloc.h>             /* for farmalloc, farrealloc */
        !            48: #endif
        !            49:
        !            50: #if defined(_Windows) && !defined(WIN32)
        !            51: #include <windows.h>
        !            52: #include <windowsx.h>
        !            53: #define farmalloc(s) GlobalAllocPtr(GHND,s)
        !            54: #define farrealloc(p,s) GlobalReAllocPtr(p,s,GHND)
        !            55: #endif
        !            56:
        !            57: #ifndef NO_GIH
        !            58: #include "help.h"
        !            59: #endif
        !            60:
        !            61: #ifndef GP_FARMALLOC
        !            62: # ifdef FARALLOC
        !            63: #  define GP_FARMALLOC(size) farmalloc ((size))
        !            64: #  define GP_FARREALLOC(p,size) farrealloc ((p), (size))
        !            65: # else
        !            66: #  define GP_FARMALLOC(size) malloc ((size_t)(size))
        !            67: #  define GP_FARREALLOC(p,size) realloc ((p), (size_t)(size))
        !            68: # endif
        !            69: #endif
        !            70:
        !            71: /* uncomment if you want to trace all allocs */
        !            72: #define TRACE_ALLOC(x) /*printf x*/
        !            73:
        !            74:
        !            75: #ifdef CHECK_HEAP_USE
        !            76:
        !            77: /* This is in no way supported, and in particular it breaks the
        !            78:  * online help. But it is useful to leave it in in case any
        !            79:  * heap-corruption bugs turn up. Wont work with FARALLOC
        !            80:  */
        !            81:
        !            82: struct frame_struct {
        !            83:        char *use;
        !            84:        int requested_size;
        !            85:        int pad; /* preserve 8-byte alignment */
        !            86:        int checksum;
        !            87: };
        !            88:
        !            89: struct leak_struct {
        !            90:        char *file;
        !            91:        int line;
        !            92:        int allocated;
        !            93: };
        !            94:
        !            95: static struct leak_struct leak_stack[40];  /* up to 40 nested leak checks */
        !            96: static struct leak_struct *leak_frame = leak_stack;
        !            97:
        !            98: static long bytes_allocated = 0;
        !            99:
        !           100: #define RESERVED_SIZE sizeof(struct frame_struct)
        !           101: #define CHECKSUM_INT 0xcaac5e1f
        !           102: #define CHECKSUM_FREE 0xf3eed222
        !           103: #define CHECKSUM_CHAR 0xc5
        !           104:
        !           105: static void mark(p, size, usage)
        !           106: struct frame_struct *p;
        !           107: unsigned long size;
        !           108: char *usage;
        !           109: {
        !           110:        p->use = usage;
        !           111:        p->requested_size = size;
        !           112:        p->checksum = (CHECKSUM_INT ^ (int)(p->use) ^ size);
        !           113:        ((unsigned char *)(p+1))[size] = CHECKSUM_CHAR;
        !           114: }
        !           115:
        !           116: #define mark_free(p) ( ((struct frame_struct *)p)[-1].checksum = CHECKSUM_FREE)
        !           117:
        !           118: static void validate(x)
        !           119: void *x;
        !           120: {
        !           121:        struct frame_struct *p = (struct frame_struct *)x - 1;
        !           122:        if (p->checksum != (CHECKSUM_INT ^ (int)(p->use) ^ p->requested_size))
        !           123:        {
        !           124:                fprintf(stderr, "Heap corruption at start of block for %s\n", p->use);
        !           125:                if (p->checksum == CHECKSUM_FREE)
        !           126:                        fprintf(stderr, "Looks like it has already been freed ?\n");
        !           127:                abort();
        !           128:        }
        !           129:
        !           130:        if ( ((unsigned char *)(p+1))[p->requested_size] != CHECKSUM_CHAR)
        !           131:        {
        !           132:                fprintf(stderr, "Heap corruption at end of block for %-60s\n", p->use);
        !           133:                int_error("Argh !", NO_CARET);
        !           134:        }
        !           135: }
        !           136:
        !           137: /* used to confirm that a pointer is inside an allocated region via
        !           138:  * macro CHECK_POINTER. Nowhere near as good as using a bounds-checking
        !           139:  * compiler (such as gcc-with-bounds-checking), but when we do
        !           140:  * come across problems, we can add these guards to the code until
        !           141:  * we find the problem, and then leave the guards in (as CHECK_POINTER
        !           142:  * macros which expand to nothing, until we need to re-enable them)
        !           143:  */
        !           144:
        !           145: void check_pointer_in_block(void *block, void *p, int size, char *file, int line)
        !           146: {
        !           147:        struct frame_struct *f = (struct frame_struct *)block - 1;
        !           148:        validate(block);
        !           149:        if (p < block || p >= (block + f->requested_size))
        !           150:        {
        !           151:                fprintf(stderr, "argh - pointer %p outside block %p->%p for %s at %s:%d\n",
        !           152:                  p, block, (char *)block + f->requested_size, f->use, file, line);
        !           153:                int_error("argh - pointer misuse !", NO_CARET);
        !           154:        }
        !           155: }
        !           156:
        !           157: char *gp_alloc(size, usage)
        !           158: unsigned long size;
        !           159: char *usage;
        !           160: {
        !           161:        struct frame_struct *p;
        !           162:        unsigned long total_size = size + RESERVED_SIZE + 1;
        !           163:
        !           164:        TRACE_ALLOC(("gp_alloc %d for %s\n", (int) size, usage?usage:"<unknown>"));
        !           165:
        !           166:        p=malloc(total_size);
        !           167:        if (!p) int_error("Out of memory", NO_CARET);
        !           168:
        !           169:        bytes_allocated += size;
        !           170:
        !           171:        mark(p,size,usage);
        !           172:
        !           173:        return (char *)(p+1);
        !           174: }
        !           175:
        !           176: generic *gp_realloc(old, size, usage)
        !           177: generic *old;
        !           178: unsigned long size;
        !           179: char *usage;
        !           180: {
        !           181:        if (!old) return gp_alloc(size, usage);
        !           182:        validate(old);
        !           183:        mark_free(old); /* if block gets moved, old block is marked free */
        !           184:                        /* if not, we'll remark it later */
        !           185:
        !           186:
        !           187:        {
        !           188:                struct frame_struct *p = (struct frame_struct *)old - 1;
        !           189:                unsigned long total = size + RESERVED_SIZE + 1;
        !           190:
        !           191:                p = realloc(p, total);
        !           192:
        !           193:                if (!p) int_error("Out of memory", NO_CARET);
        !           194:
        !           195:                TRACE_ALLOC(("gp_realloc %d for %s (was %d)\n",
        !           196:                  (int)size, usage?usage:"<unknown>", p->requested_size));
        !           197:
        !           198:                bytes_allocated += size - p->requested_size;
        !           199:
        !           200:                mark(p,size,usage);
        !           201:
        !           202:                return (generic *)(p+1);
        !           203:        }
        !           204: }
        !           205:
        !           206: #undef free
        !           207:
        !           208: void checked_free(p)
        !           209: void *p;
        !           210: {
        !           211:        validate(p);
        !           212:        mark_free(p);  /* trap attempts to free twice */
        !           213:        TRACE_ALLOC(("free %d for %s\n",
        !           214:          ((struct frame_struct *)p - 1)->requested_size,
        !           215:          ((struct frame_struct *)p - 1)->use));
        !           216:        bytes_allocated -= ((struct frame_struct *)p - 1) -> requested_size;
        !           217:        free( (struct frame_struct *) p - 1);
        !           218: }
        !           219:
        !           220:
        !           221: /* this leak checking stuff will be broken by first int_error or interrupt */
        !           222:
        !           223: void start_leak_check(char *file, int line)
        !           224: {
        !           225:        if (leak_frame >= leak_stack+40)
        !           226:        {
        !           227:                fprintf(stderr, "too many nested memory-leak checks - %s:%d\n", file, line);
        !           228:                return;
        !           229:        }
        !           230:
        !           231:        leak_frame->file = file;
        !           232:        leak_frame->line = line;
        !           233:        leak_frame->allocated = bytes_allocated;
        !           234:
        !           235:        ++leak_frame;
        !           236: }
        !           237:
        !           238: void end_leak_check(char *file, int line)
        !           239: {
        !           240:        if (--leak_frame < leak_stack)
        !           241:        {
        !           242:                fprintf(stderr, "memory-leak stack underflow at %s:%d\n", file, line);
        !           243:                return;
        !           244:        }
        !           245:
        !           246:        if (leak_frame->allocated != bytes_allocated)
        !           247:        {
        !           248:                fprintf(stderr, "net change of %+d heap bytes between %s:%d and %s:%d\n",
        !           249:                        (int)(bytes_allocated - leak_frame->allocated),
        !           250:                        leak_frame->file, leak_frame->line, file, line);
        !           251:        }
        !           252: }
        !           253:
        !           254: #else  /* CHECK_HEAP_USE */
        !           255:
        !           256: /* gp_alloc:
        !           257:  * allocate memory
        !           258:  * This is a protected version of malloc. It causes an int_error
        !           259:  * if there is not enough memory, but first it tries FreeHelp()
        !           260:  * to make some room, and tries again. If message is NULL, we
        !           261:  * allow NULL return. Otherwise, we handle the error, using the
        !           262:  * message to create the int_error string. Note cp/sp_extend uses realloc,
        !           263:  * so it depends on this using malloc().
        !           264:  */
        !           265:
        !           266: char *
        !           267: gp_alloc(size, message)
        !           268:        unsigned long size;             /* # of bytes */
        !           269:        char *message;                  /* description of what is being allocated */
        !           270: {
        !           271:     char *p;                           /* the new allocation */
        !           272:     char errbuf[100];          /* error message string */
        !           273:
        !           274: #ifndef NO_GIH
        !           275:     p = GP_FARMALLOC(size);
        !           276:     if (p == (char *)NULL) {
        !           277:           FreeHelp();                  /* out of memory, try to make some room */
        !           278: #endif /* NO_GIH */
        !           279:           p = GP_FARMALLOC(size);      /* try again */
        !           280:           if (p == (char *)NULL) {
        !           281:                  /* really out of memory */
        !           282:                  if (message != NULL) {
        !           283:                         (void) sprintf(errbuf, "out of memory for %s", message);
        !           284:                         int_error(errbuf, NO_CARET);
        !           285:                         /* NOTREACHED */
        !           286:                  }
        !           287:                  /* else we return NULL */
        !           288:           }
        !           289: #ifndef NO_GIH
        !           290:     }
        !           291: #endif
        !           292:     return(p);
        !           293: }
        !           294:
        !           295: /*
        !           296:  * note gp_realloc assumes that failed realloc calls leave the original mem block
        !           297:  * allocated. If this is not the case with any C compiler, a substitue
        !           298:  * realloc function has to be used.
        !           299:  */
        !           300:
        !           301: generic *
        !           302: gp_realloc(p, size, message)
        !           303:        generic *p;                     /* old mem block */
        !           304:        unsigned long size;             /* # of bytes */
        !           305:        char *message;                  /* description of what is being allocated */
        !           306: {
        !           307:     char *res;                         /* the new allocation */
        !           308:     char errbuf[100];          /* error message string */
        !           309:
        !           310:     /* realloc(NULL,x) is meant to do malloc(x), but doesn't always */
        !           311:     if (!p)
        !           312:        return gp_alloc(size,message);
        !           313:
        !           314: #ifndef NO_GIH
        !           315:     res = GP_FARREALLOC(p,size);
        !           316:     if (res == (char *)NULL) {
        !           317:           FreeHelp();                  /* out of memory, try to make some room */
        !           318: #endif /* NO_GIH */
        !           319:           res = GP_FARREALLOC(p,size); /* try again */
        !           320:           if (res == (char *)NULL) {
        !           321:                  /* really out of memory */
        !           322:                  if (message != NULL) {
        !           323:                         (void) sprintf(errbuf, "out of memory for %s", message);
        !           324:                         int_error(errbuf, NO_CARET);
        !           325:                         /* NOTREACHED */
        !           326:                  }
        !           327:                  /* else we return NULL */
        !           328:           }
        !           329: #ifndef NO_GIH
        !           330:     }
        !           331: #endif
        !           332:     return(res);
        !           333: }
        !           334:
        !           335: #endif /* CHECK_HEAP_USE */
        !           336:
        !           337: #ifdef FARALLOC
        !           338: void gpfree(p)
        !           339: generic *p;
        !           340: {
        !           341: #ifdef _Windows
        !           342: HGLOBAL hGlobal = GlobalHandle(SELECTOROF(p));
        !           343:        GlobalUnlock(hGlobal);
        !           344:        GlobalFree(hGlobal);
        !           345: #else
        !           346:        farfree(p);
        !           347: #endif
        !           348: }
        !           349: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>