]> granicus.if.org Git - graphviz/commitdiff
remove now extraneous parts of vmalloc
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Sat, 11 Jul 2020 23:10:27 +0000 (16:10 -0700)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Sat, 25 Jul 2020 18:54:37 +0000 (11:54 -0700)
lib/vmalloc/vmalloc.h
lib/vmalloc/vmhdr.h
lib/vmalloc/vmstrdup.c

index 8678a9f5de0e8b12615a7df69e57a5e0bde03ef6..315eba575430d6704ddc925e112a09e547493cb1 100644 (file)
@@ -23,86 +23,23 @@ extern "C" {
 **     Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
 */
 
-#define VMALLOC_VERSION        19990805L
-
-#include "config.h"
-
-#ifdef HAVE_SYS_TYPES_H
-#   include <sys/types.h>
-#endif // HAVE_SYS_TYPES_H
-
     typedef struct _vmalloc_s Vmalloc_t;
-    typedef struct _vmstat_s Vmstat_t;
-    typedef struct _vmdisc_s Vmdisc_t;
     typedef struct _vmethod_s Vmethod_t;
-    typedef void *(*Vmemory_f)
-       (Vmalloc_t *, void *, size_t, size_t, Vmdisc_t *);
-    typedef int (*Vmexcept_f)
-       (Vmalloc_t *, int, void *, Vmdisc_t *);
-
-    struct _vmstat_s {
-       int n_busy;             /* number of busy blocks        */
-       int n_free;             /* number of free blocks        */
-       size_t s_busy;          /* total amount of busy space   */
-       size_t s_free;          /* total amount of free space   */
-       size_t m_busy;          /* largest busy piece           */
-       size_t m_free;          /* largest free piece           */
-       int n_seg;              /* number of segments           */
-       size_t extent;          /* total size of region         */
-    };
-
-    struct _vmdisc_s {
-       Vmemory_f memoryf;      /* memory manipulator           */
-       Vmexcept_f exceptf;     /* exception handler            */
-       size_t round;           /* rounding requirement         */
-    };
 
     struct _vmethod_s {
        void *(*allocf) (Vmalloc_t *, size_t);
        void *(*resizef) (Vmalloc_t *, void *, size_t);
        int (*freef) (Vmalloc_t *, void *);
-       long (*addrf) (Vmalloc_t *, void *);
-       unsigned short meth;
     };
 
     struct _vmalloc_s {
        Vmethod_t meth;         /* method for allocation        */
-       char *file;             /* file name                    */
-       int line;               /* line number                  */
-#ifdef _VM_PRIVATE_
-        _VM_PRIVATE_
-#endif
 
        void **allocated;       /* pointers we have given out           */
        size_t size;    /* used entries in `allocated`          */
        size_t capacity;        /* available entries in `allocated`     */
     };
 
-#define VM_TRUST       0000001 /* forgo some security checks   */
-#define VM_TRACE       0000002 /* generate trace               */
-#define VM_DBCHECK     0000004 /* check for boundary overwrite */
-#define VM_DBABORT     0000010 /* abort on any warning         */
-#define VM_FLAGS       0000017 /* user-settable flags          */
-
-#define VM_MTBEST      0000100 /* Vmbest method                */
-#define VM_MTPOOL      0000200 /* Vmpool method                */
-#define VM_MTLAST      0000400 /* Vmlast method                */
-#define VM_MTDEBUG     0001000 /* Vmdebug method               */
-#define VM_MTPROFILE   0002000 /* Vmdebug method               */
-#define VM_METHODS     0003700 /* available allocation methods */
-
-#define VM_RSCOPY      0000001 /* copy old contents            */
-#define VM_RSMOVE      0000002 /* old contents is moveable     */
-#define VM_RSZERO      0000004 /* clear new space              */
-
-/* exception types */
-#define VM_OPEN                0       /* region being opened          */
-#define VM_CLOSE       1       /* region being closed          */
-#define VM_NOMEM       2       /* can't obtain memory          */
-#define VM_BADADDR     3       /* bad addr in vmfree/vmresize  */
-#define VM_DISC                4       /* discipline being changed     */
-
-
     extern Vmalloc_t *vmopen(void);
     extern int vmclose(Vmalloc_t *);
     extern int vmclear(Vmalloc_t *);
@@ -129,8 +66,6 @@ extern "C" {
 #ifndef vmfree
 #define vmfree(vm,d)           (*(_VM_(vm)->meth.freef))((vm),(void*)(d))
 #endif
-#define vmaddr(vm,addr)                (*(_VM_(vm)->meth.addrf))((vm),(void*)(addr))
-#define vmoldof(v,p,t,n,x)     (t*)vmresize((v), (p), sizeof(t)*(n)+(x))
 #define vmnewof(v,p,t,n,x)     (t*)vmresize((v), (p), sizeof(t)*(n)+(x))
 #endif                         /* _VMALLOC_H */
 #ifdef __cplusplus
index 9f8149a43c0ad2cd8f64c55c6a66c289f121f14d..ee3a98fb18bd0a775890c4fb414a6ae0991c86ed 100644 (file)
@@ -17,401 +17,15 @@ extern "C" {
 
 #ifndef _VMHDR_H
 #define _VMHDR_H       1
-#ifndef _BLD_vmalloc
-#define _BLD_vmalloc   1
-#endif
-#ifdef _WIN32
-#include <io.h>
-#endif
 
 /*     Common types, and macros for vmalloc functions.
 **
 **     Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
 */
 
-#include "config.h"
-
-#include <inttypes.h>
 #include <stdlib.h>
-
-#ifdef HAVE_SYS_TYPES_H
-#   include <sys/types.h>
-#endif // HAVE_SYS_TYPES_H
-
-#undef BITS
-
-    typedef unsigned char Vmuchar_t;
-    typedef uint64_t Vmulong_t;
-
-    typedef union _head_u Head_t;
-    typedef union _body_u Body_t;
-    typedef struct _block_s Block_t;
-    typedef struct _seg_s Seg_t;
-    typedef struct _pfobj_s Pfobj_t;
-
-#define NIL(t)         ((t)0)
-#define reg            register
-#define NOTUSED(x)     (void)(x)
-
-/* convert an address to an integral value */
-#define VLONG(addr)    ((Vmulong_t)((char*)(addr) - (char*)0) )
-
-/* Round x up to a multiple of y. ROUND2 does powers-of-2 and ROUNDX does others */
-#define ROUND2(x,y)    (((x) + ((y)-1)) & ~((y)-1))
-#define ROUNDX(x,y)    ((((x) + ((y)-1)) / (y)) * (y))
-#define ROUND(x,y)     (((y)&((y)-1)) ? ROUNDX((x),(y)) : ROUND2((x),(y)) )
-
-/* compute a value that is a common multiple of x and y */
-#define MULTIPLE(x,y)  ((x)%(y) == 0 ? (x) : (y)%(x) == 0 ? (y) : (y)*(x))
-
-#ifndef DEBUG
-#define ASSERT(p)
-#define COUNT(n)
-#else
-    extern int printf(const char *, ...);
-#if defined(__LINE__) && defined(__FILE__)
-#define PRFILELINE     printf("Assertion failed at %s:%d\n",__FILE__,__LINE__)
-#else
-#define PRFILELINE     0
-#endif
-#define ASSERT(p)      ((p) ? 0 : (PRFILELINE, abort(), 0) )
-#define COUNT(n)       ((n) += 1)
-#endif /*DEBUG*/
-#define VMPAGESIZE     8192
-#ifdef HAVE_GETPAGESIZE
-#define GETPAGESIZE(x) ((x) ? (x) : \
-                        (((x)=getpagesize()) < VMPAGESIZE ? ((x)=VMPAGESIZE) : (x)) )
-#else
-#define GETPAGESIZE(x) ((x) = VMPAGESIZE)
-#endif
-/* Blocks are allocated such that their sizes are 0%(BITS+1)
-** This frees up enough low order bits to store state information
-*/
-#define BUSY           (01)    /* block is busy                                */
-#define PFREE          (02)    /* preceding block is free                      */
-#define JUNK           (04)    /* marked as freed but not yet processed        */
-#define BITS           (07)    /* (BUSY|PFREE|JUNK)                            */
-#define ALIGNB         (8)     /* size must be a multiple of BITS+1            */
-#define ISBITS(w)      ((w) & BITS)
-#define CLRBITS(w)     ((w) &= ~BITS)
-#define CPYBITS(w,f)   ((w) |= ((f)&BITS) )
-#define ISBUSY(w)      ((w) & BUSY)
-#define SETBUSY(w)     ((w) |= BUSY)
-#define CLRBUSY(w)     ((w) &= ~BUSY)
-#define ISPFREE(w)     ((w) & PFREE)
-#define SETPFREE(w)    ((w) |= PFREE)
-#define CLRPFREE(w)    ((w) &= ~PFREE)
-#define ISJUNK(w)      ((w) & JUNK)
-#define SETJUNK(w)     ((w) |= JUNK)
-#define CLRJUNK(w)     ((w) &= ~JUNK)
-#define OFFSET(t,e)    ((size_t)(&(((t*)0)->e)) )
-/* these bits share the "mode" field with the public bits */
-#define VM_AGAIN       0010000 /* research the arena for space */
-#define VM_LOCK                0020000 /* region is locked             */
-#define VM_LOCAL       0040000 /* local call, bypass lock      */
-#define VM_UNUSED      0104060
-#define VMETHOD(vd)    ((vd)->mode&VM_METHODS)
-/* test/set/clear lock state */
-#define SETLOCAL(vd)   ((vd)->mode |= VM_LOCAL)
-#define GETLOCAL(vd,l) (((l) = (vd)->mode&VM_LOCAL), ((vd)->mode &= ~VM_LOCAL) )
-#define ISLOCK(vd,l)   ((l) ? 0 : ((vd)->mode &  VM_LOCK) )
-#define SETLOCK(vd,l)  ((l) ? 0 : ((vd)->mode |= VM_LOCK) )
-#define CLRLOCK(vd,l)  ((l) ? 0 : ((vd)->mode &= ~VM_LOCK) )
-/* local calls */
-#define KPVALLOC(vm,sz,func)           (SETLOCAL((vm)->data), func((vm),(sz)) )
-#define KPVALIGN(vm,sz,al,func)                (SETLOCAL((vm)->data), func((vm),(sz),(al)) )
-#define KPVFREE(vm,d,func)             (SETLOCAL((vm)->data), func((vm),(d)) )
-#define KPVRESIZE(vm,d,sz,mv,func)     (SETLOCAL((vm)->data), func((vm),(d),(sz),(mv)) )
-#define KPVADDR(vm,addr,func)          (SETLOCAL((vm)->data), func((vm),(addr)) )
-/* ALIGN is chosen so that a block can store all primitive types.
-** It should also be a multiple of ALIGNB==(BITS+1) so the size field
-** of Block_t will always be 0%(BITS+1) as noted above.
-** Of paramount importance is the ALIGNA macro below. If the local compile
-** environment is strange enough that the below method does not calculate
-** ALIGNA right, then the code below should be commented out and ALIGNA
-** redefined to the appropriate requirement.
-*/
-       union _align_u {
-       char c, *cp;
-       int i, *ip;
-       long l, *lp;
-       double d, *dp, ***dppp[8];
-       size_t s, *sp;
-       void (*fn) (void);
-       union _align_u *align;
-       Head_t *head;
-       Body_t *body;
-       Block_t *block;
-       Vmuchar_t a[ALIGNB];
-#if _long_double
-       long double ld, *ldp;
-#endif
-    };
-    struct _a_s {
-       char c;
-       union _align_u a;
-    };
-#define ALIGNA (sizeof(struct _a_s) - sizeof(union _align_u))
-    struct _align_s {
-       char data[MULTIPLE(ALIGNA, ALIGNB)];
-    };
-#define ALIGN  sizeof(struct _align_s)
-
-/* make sure that the head of a block is a multiple of ALIGN */
-    struct _head_s {
-       union {
-           Seg_t *seg;         /* the containing segment       */
-           Block_t *link;      /* possible link list usage     */
-           Pfobj_t *pf;        /* profile structure pointer    */
-           char *file;         /* for file name in Vmdebug     */
-       } seg;
-       union {
-           size_t size;        /* size of data area in bytes   */
-           Block_t *link;      /* possible link list usage     */
-           int line;           /* for line number in Vmdebug   */
-       } size;
-    };
-#define HEADSIZE       ROUND(sizeof(struct _head_s),ALIGN)
-    union _head_u {
-       Vmuchar_t data[HEADSIZE];       /* to standardize size          */
-       struct _head_s head;
-    };
-
-/* now make sure that the body of a block is a multiple of ALIGN */
-    struct _body_s {
-       Block_t *link;          /* next in link list            */
-       Block_t *left;          /* left child in free tree      */
-       Block_t *right;         /* right child in free tree     */
-       Block_t **self;         /* self pointer when free       */
-    };
-#define BODYSIZE       ROUND(sizeof(struct _body_s),ALIGN)
-    union _body_u {
-       Vmuchar_t data[BODYSIZE];       /* to standardize size          */
-       struct _body_s body;
-    };
-
-/* After all the songs and dances, we should now have:
-**     sizeof(Head_t)%ALIGN == 0
-**     sizeof(Body_t)%ALIGN == 0
-** and sizeof(Block_t) = sizeof(Head_t)+sizeof(Body_t)
-*/
-    struct _block_s {
-       Head_t head;
-       Body_t body;
-    };
-
-/* requirements for smallest block type */
-    struct _tiny_s {
-       Block_t *link;
-       Block_t *self;
-    };
-#define TINYSIZE       ROUND(sizeof(struct _tiny_s),ALIGN)
-#define S_TINY         7       /* # of tiny blocks     */
-#define MAXTINY                (S_TINY*ALIGN + TINYSIZE)
-#define TLEFT(b)       ((b)->head.head.seg.link)       /* instead of LEFT      */
-#define TINIEST(b)     (SIZE(b) == TINYSIZE)   /* this type uses TLEFT */
-
-#define DIV(x,y)       ((y) == 8 ? ((x)>>3) : (x)/(y) )
-#define INDEX(s)       DIV((s)-TINYSIZE,ALIGN)
-
-/* number of small block types that can be cached after free */
-#define S_CACHE                7
-#define MAXCACHE       (S_CACHE*ALIGN + TINYSIZE)
-#define C_INDEX(s)     (s < MAXCACHE ? INDEX(s) : S_CACHE)
-
-#define TINY(vd)       ((vd)->tiny)
-#define CACHE(vd)      ((vd)->cache)
-
-    typedef struct _vmdata_s {
-       int mode;               /* current mode for region              */
-       size_t incr;            /* allocate in multiple of this         */
-       size_t pool;            /* size of an elt in a Vmpool region    */
-       Seg_t *seg;             /* list of segments                     */
-       Block_t *free;          /* most recent free block               */
-       Block_t *wild;          /* wilderness block                     */
-       Block_t *root;          /* root of free tree                    */
-       Block_t *tiny[S_TINY];  /* small blocks                         */
-       Block_t *cache[S_CACHE + 1];    /* delayed free blocks                */
-    } Vmdata_t;
-
-/* private parts of Vmalloc_t */
-#define _VM_PRIVATE_ \
-       Vmdisc_t*       disc;           /* discipline to get space              */ \
-       Vmdata_t*       data;           /* the real region data                 */ \
-       Vmalloc_t*      next;   /* linked list of regions               */
-
 #include       "vmalloc.h"
 
-/* segment structure */
-    struct _seg_s {
-       Vmalloc_t *vm;          /* the region that holds this   */
-       Seg_t *next;            /* next segment                 */
-       void *addr;             /* starting segment address     */
-       size_t extent;          /* extent of segment            */
-       Vmuchar_t *baddr;       /* bottom of usable memory      */
-       size_t size;            /* allocable size               */
-       Block_t *free;          /* recent free blocks           */
-       Block_t *last;          /* Vmlast last-allocated block  */
-    };
-
-/* starting block of a segment */
-#define SEGBLOCK(s)    ((Block_t*)(((Vmuchar_t*)(s)) + ROUND(sizeof(Seg_t),ALIGN)))
-
-/* short-hands for block data */
-#define SEG(b)         ((b)->head.head.seg.seg)
-#define SEGLINK(b)     ((b)->head.head.seg.link)
-#define        SIZE(b)         ((b)->head.head.size.size)
-#define SIZELINK(b)    ((b)->head.head.size.link)
-#define LINK(b)                ((b)->body.body.link)
-#define LEFT(b)                ((b)->body.body.left)
-#define RIGHT(b)       ((b)->body.body.right)
-#define VM(b)          (SEG(b)->vm)
-
-#define DATA(b)                ((void*)((b)->body.data) )
-#define BLOCK(d)       ((Block_t*)((char*)(d) - sizeof(Head_t)) )
-#define SELF(b)                ((Block_t**)((b)->body.data + SIZE(b) - sizeof(Block_t*)) )
-#define LAST(b)                (*((Block_t**)(((char*)(b)) - sizeof(Block_t*)) ) )
-#define NEXT(b)                ((Block_t*)((b)->body.data + SIZE(b)) )
-
-/* functions to manipulate link lists of elts of the same size */
-#define SETLINK(b)     (RIGHT(b) =  (b) )
-#define ISLINK(b)      (RIGHT(b) == (b) )
-#define UNLINK(vd,b,i,t) \
-               ((((t) = LINK(b)) ? (LEFT(t) = LEFT(b)) : NIL(Block_t*) ), \
-                (((t) = LEFT(b)) ? (LINK(t) = LINK(b)) : (TINY(vd)[i] = LINK(b)) ) )
-
-/* delete a block from a link list or the free tree.
-** The test in the below macro is worth scratching your head a bit.
-** Even though tiny blocks (size < BODYSIZE) are kept in separate lists,
-** only the TINIEST ones require TLEFT(b) for the back link. Since this
-** destroys the SEG(b) pointer, it must be carefully restored in bestsearch().
-** Other tiny blocks have enough space to use the usual LEFT(b).
-** In this case, I have also carefully arranged so that RIGHT(b) and
-** SELF(b) can be overlapped and the test ISLINK() will go through.
-*/
-#define REMOVE(vd,b,i,t,func) \
-               ((!TINIEST(b) && ISLINK(b)) ? UNLINK((vd),(b),(i),(t)) : \
-                       func((vd),SIZE(b),(b)) )
-
-/* see if a block is the wilderness block */
-#define SEGWILD(b)     (((b)->body.data+SIZE(b)+sizeof(Head_t)) >= SEG(b)->baddr)
-#define VMWILD(vd,b)   (((b)->body.data+SIZE(b)+sizeof(Head_t)) >= vd->seg->baddr)
-
-#define VMFILELINE(vm,f,l)     ((f) = (vm)->file, (vm)->file = NIL(char*), \
-                                (l) = (vm)->line, (vm)->line = 0 )
-
-/* The lay-out of a Vmprofile block is this:
-**     seg_ size ----data---- _pf_ size
-**     _________ ____________ _________
-**     seg_, size: header required by Vmbest.
-**     data:   actual data block.
-**     _pf_:   pointer to the corresponding Pfobj_t struct
-**     size:   the true size of the block.
-** So each block requires an extra Head_t.
-*/
-#define PF_EXTRA   sizeof(Head_t)
-#define PFDATA(d)  ((Head_t*)((Vmuchar_t*)(d)+(SIZE(BLOCK(d))&~BITS)-sizeof(Head_t)) )
-#define PFOBJ(d)   (PFDATA(d)->head.seg.pf)
-#define PFSIZE(d)  (PFDATA(d)->head.size.size)
-
-/* The lay-out of a block allocated by Vmdebug is this:
-**     seg_ size file size seg_ magi ----data---- --magi-- magi line
-**     --------- --------- --------- ------------ -------- ---------
-**     seg_,size: header required by Vmbest management.
-**     file:   the file where it was created.
-**     size:   the true byte count of the block
-**     seg_:   should be the same as the previous seg_.
-**     magi:   magic bytes to detect overwrites.
-**     data:   the actual data block.
-**     magi:   more magic bytes.
-**     line:   the line number in the file where it was created.
-** So for each allocated block, we'll need 3 extra Head_t.
-*/
-
-/* convenient macros for accessing the above fields */
-#define DB_HEAD                (2*sizeof(Head_t))
-#define DB_TAIL                (2*sizeof(Head_t))
-#define DB_EXTRA       (DB_HEAD+DB_TAIL)
-#define DBBLOCK(d)     ((Block_t*)((Vmuchar_t*)(d) - 3*sizeof(Head_t)) )
-#define DBBSIZE(d)     (SIZE(DBBLOCK(d)) & ~BITS)
-#define DBSEG(d)       (((Head_t*)((Vmuchar_t*)(d) - sizeof(Head_t)))->head.seg.seg )
-#define DBSIZE(d)      (((Head_t*)((Vmuchar_t*)(d) - 2*sizeof(Head_t)))->head.size.size )
-#define DBFILE(d)      (((Head_t*)((Vmuchar_t*)(d) - 2*sizeof(Head_t)))->head.seg.file )
-#define DBLN(d)                (((Head_t*)((Vmuchar_t*)DBBLOCK(d)+DBBSIZE(d)))->head.size.line )
-#define DBLINE(d)      (DBLN(d) < 0 ? -DBLN(d) : DBLN(d))
-
-/* forward/backward translation for addresses between Vmbest and Vmdebug */
-#define DB2BEST(d)     ((Vmuchar_t*)(d) - 2*sizeof(Head_t))
-#define DB2DEBUG(b)    ((Vmuchar_t*)(b) + 2*sizeof(Head_t))
-
-/* set file and line number, note that DBLN > 0 so that DBISBAD will work  */
-#define DBSETFL(d,f,l) (DBFILE(d) = (f), DBLN(d) = (f) ? (l) : 1)
-
-/* set and test the state of known to be corrupted */
-#define DBSETBAD(d)    (DBLN(d) > 0 ? (DBLN(d) = -DBLN(d)) : -1)
-#define DBISBAD(d)     (DBLN(d) <= 0)
-
-#define DB_MAGIC       0255    /* 10101101     */
-
-/* compute the bounds of the magic areas */
-#define DBHEAD(d,begp,endp) \
-               (((begp) = (Vmuchar_t*)(&DBSEG(d)) + sizeof(Seg_t*)), ((endp) = (d)) )
-#define DBTAIL(d,begp,endp) \
-               (((begp) = (Vmuchar_t*)(d)+DBSIZE(d)), ((endp) = (Vmuchar_t*)(&DBLN(d))) )
-
-/* clear and copy functions */
-#define INTCOPY(to,fr,n) \
-       switch(n/sizeof(int)) \
-       { default: memcpy((void*)to,(void*)fr,n); break; \
-         case 7:       *to++ = *fr++; \
-         case 6:       *to++ = *fr++; \
-         case 5:       *to++ = *fr++; \
-         case 4:       *to++ = *fr++; \
-         case 3:       *to++ = *fr++; \
-         case 2:       *to++ = *fr++; \
-         case 1:       *to++ = *fr++; \
-       }
-#define INTZERO(d,n) \
-       switch(n/sizeof(int)) \
-       { default: memset((void*)d,0,n); break; \
-         case 7:       *d++ = 0; \
-         case 6:       *d++ = 0; \
-         case 5:       *d++ = 0; \
-         case 4:       *d++ = 0; \
-         case 3:       *d++ = 0; \
-         case 2:       *d++ = 0; \
-         case 1:       *d++ = 0; \
-       }
-
-/* external symbols for internal use by vmalloc */
-    typedef Block_t *(*Vmsearch_f) (Vmdata_t *, size_t, Block_t *);
-
-    extern size_t getpagesize(void);
-
-#ifndef _WIN32
-    extern void abort(void);
-    extern ssize_t write(int, const void *, size_t);
-#endif
-
-#ifndef cfree
-#define cfree ______cfree
-#endif
-#include       <stdlib.h>
-#undef cfree
-#include       <string.h>
-
-/* for vmexit.c */
-#ifndef _WIN32
-    extern int onexit(void(*)(void));
-    extern void _exit(int);
-#endif
-    extern void _cleanup(void);
-
-/* for vmdcsbrk.c */
-#if !defined(_WIN32)
-    extern Vmuchar_t *sbrk(ssize_t);
-#endif
-
 void *bestalloc(Vmalloc_t * vm, size_t size);
 int bestfree(Vmalloc_t * vm, void * data);
 void *bestresize(Vmalloc_t * vm, void * data, size_t size);
index 3482c9485aa871e01f012eaaa3c60dfc52635051..85260ca67f651f5cc1b756b0cfaeac408c0a707c 100644 (file)
@@ -12,6 +12,7 @@
  *************************************************************************/
 
 
+#include <string.h>
 #include       "vmhdr.h"
 /*
  * return a copy of s using vmalloc