/* handy.h
*
- * Copyright (c) 1991-2002, Larry Wall
+ * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1999,
+ * 2000, 2001, 2002, 2004, 2005 by Larry Wall and others
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
=for apidoc AmU||Nullch
Null character pointer.
+
=for apidoc AmU||Nullsv
Null SV pointer.
# endif
#endif
+/* HMB H.Merijn Brand - a placeholder for preparing Configure patches */
+#if defined(LIBM_LIB_VERSION)
+/* Not (yet) used at top level, but mention them for metaconfig */
+#endif
+
/* Mention I8SIZE, U8SIZE, I16SIZE, U16SIZE, I32SIZE, U32SIZE,
I64SIZE, and U64SIZE here so that metaconfig pulls them in. */
#define I32_MAX INT32_MAX
#define I32_MIN INT32_MIN
-#define U32_MAX UINT32_MAX
+#ifndef UINT32_MAX_BROKEN /* e.g. HP-UX with gcc messes this up */
+# define U32_MAX UINT32_MAX
+#else
+# define U32_MAX 4294967295U
+#endif
#define U32_MIN UINT32_MIN
#else
# define isGRAPH(c) (isALNUM(c) || isPUNCT(c))
# define isPRINT(c) (((c) > 32 && (c) < 127) || (c) == ' ')
# define isPUNCT(c) (((c) >= 33 && (c) <= 47) || ((c) >= 58 && (c) <= 64) || ((c) >= 91 && (c) <= 96) || ((c) >= 123 && (c) <= 126))
-# define isXDIGIT(c) (isdigit(c) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
+# define isXDIGIT(c) (isDIGIT(c) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
# define toUPPER(c) (isLOWER(c) ? (c) - ('a' - 'A') : (c))
# define toLOWER(c) (isUPPER(c) ? (c) + ('a' - 'A') : (c))
#endif
#define isBLANK_LC_uni(c) isBLANK(c) /* could be wrong */
#define isALNUM_utf8(p) is_utf8_alnum(p)
-#define isIDFIRST_utf8(p) is_utf8_idfirst(p)
+/* The ID_Start of Unicode is quite limiting: it assumes a L-class
+ * character (meaning that you cannot have, say, a CJK character).
+ * Instead, let's allow ID_Continue but not digits. */
+#define isIDFIRST_utf8(p) (is_utf8_idcont(p) && !is_utf8_digit(p))
#define isALPHA_utf8(p) is_utf8_alpha(p)
#define isSPACE_utf8(p) is_utf8_space(p)
#define isDIGIT_utf8(p) is_utf8_digit(p)
#define isBLANK_LC_utf8(c) isBLANK(c) /* could be wrong */
#ifdef EBCDIC
-# define toCTRL(c) Perl_ebcdic_control(c)
+# ifdef PERL_IMPLICIT_CONTEXT
+# define toCTRL(c) Perl_ebcdic_control(aTHX_ c)
+# else
+# define toCTRL Perl_ebcdic_control
+# endif
#else
/* This conversion works both ways, strangely enough. */
# define toCTRL(c) (toUPPER(c) ^ 64)
#endif
-/* Line numbers are unsigned, 16 bits. */
-typedef U16 line_t;
-#ifdef lint
-#define NOLINE ((line_t)0)
-#else
-#define NOLINE ((line_t) 65535)
-#endif
+/* Line numbers are unsigned, 32 bits. */
+typedef U32 line_t;
+#define NOLINE ((line_t) 4294967295UL)
/*
- XXX LEAKTEST doesn't really work in perl5. There are direct calls to
- safemalloc() in the source, so LEAKTEST won't pick them up.
- (The main "offenders" are extensions.)
- Further, if you try LEAKTEST, you'll also end up calling
- Safefree, which might call safexfree() on some things that weren't
- malloced with safexmalloc. The correct "fix" to this, if anyone
- is interested, is to ensure that all calls go through the New and
- Renew macros.
- --Andy Dougherty August 1996
-*/
-
-/*
=head1 SV Manipulation Functions
=for apidoc Am|SV*|NEWSV|int id|STRLEN len
=head1 Memory Management
-=for apidoc Am|void|New|int id|void* ptr|int nitems|type
+=for apidoc Am|void|Newx|void* ptr|int nitems|type
The XSUB-writer's interface to the C C<malloc> function.
-=for apidoc Am|void|Newc|int id|void* ptr|int nitems|type|cast
+=for apidoc Am|void|Newxc|void* ptr|int nitems|type|cast
The XSUB-writer's interface to the C C<malloc> function, with
cast.
-=for apidoc Am|void|Newz|int id|void* ptr|int nitems|type
+=for apidoc Am|void|Newxz|void* ptr|int nitems|type
The XSUB-writer's interface to the C C<malloc> function. The allocated
memory is zeroed with C<memzero>.
+In 5.9.3, we removed the 1st parameter, a debug aid, from the api. It
+was used to uniquely identify each usage of these allocation
+functions, but was deemed unnecessary with the availability of better
+memory tracking tools, valgrind for example.
+
=for apidoc Am|void|Renew|void* ptr|int nitems|type
The XSUB-writer's interface to the C C<realloc> function.
source, C<dest> is the destination, C<nitems> is the number of items, and C<type> is
the type. Can do overlapping moves. See also C<Copy>.
+=for apidoc Am|void *|MoveD|void* src|void* dest|int nitems|type
+Like C<Move> but returns dest. Useful for encouraging compilers to tail-call
+optimise.
+
=for apidoc Am|void|Copy|void* src|void* dest|int nitems|type
The XSUB-writer's interface to the C C<memcpy> function. The C<src> is the
source, C<dest> is the destination, C<nitems> is the number of items, and C<type> is
the type. May fail on overlapping copies. See also C<Move>.
+=for apidoc Am|void *|CopyD|void* src|void* dest|int nitems|type
+
+Like C<Copy> but returns dest. Useful for encouraging compilers to tail-call
+optimise.
+
=for apidoc Am|void|Zero|void* dest|int nitems|type
The XSUB-writer's interface to the C C<memzero> function. The C<dest> is the
destination, C<nitems> is the number of items, and C<type> is the type.
+=for apidoc Am|void *|ZeroD|void* dest|int nitems|type
+
+Like C<Zero> but returns dest. Useful for encouraging compilers to tail-call
+optimise.
+
=for apidoc Am|void|StructCopy|type src|type dest|type
This is an architecture-independent macro to copy one structure to another.
-=cut
-*/
+=for apidoc Am|void|Poison|void* dest|int nitems|type
+
+Fill up memory with a pattern (byte 0xAB over and over again) that
+hopefully catches attempts to access uninitialized memory.
-#ifndef lint
+=cut */
#define NEWSV(x,len) newSV(len)
-#ifndef LEAKTEST
+#ifdef PERL_MALLOC_WRAP
+#define MEM_WRAP_CHECK(n,t) \
+ (void)((sizeof(t)>1?(n):1)>((MEM_SIZE)~0)/sizeof(t)?(Perl_croak_nocontext(PL_memory_wrap),0):0)
+#define MEM_WRAP_CHECK_1(n,t,a) \
+ (void)((sizeof(t)>1?(n):1)>((MEM_SIZE)~0)/sizeof(t)?(Perl_croak_nocontext(a),0):0)
+#define MEM_WRAP_CHECK_2(n,t,a,b) \
+ (void)((sizeof(t)>1?(n):1)>((MEM_SIZE)~0)/sizeof(t)?(Perl_croak_nocontext(a,b),0):0)
+#define MEM_WRAP_CHECK_(n,t) MEM_WRAP_CHECK(n,t),
-#define New(x,v,n,t) (v = (t*)safemalloc((MEM_SIZE)((n)*sizeof(t))))
-#define Newc(x,v,n,t,c) (v = (c*)safemalloc((MEM_SIZE)((n)*sizeof(t))))
-#define Newz(x,v,n,t) (v = (t*)safemalloc((MEM_SIZE)((n)*sizeof(t)))), \
- memzero((char*)(v), (n)*sizeof(t))
-#define Renew(v,n,t) \
- (v = (t*)saferealloc((Malloc_t)(v),(MEM_SIZE)((n)*sizeof(t))))
-#define Renewc(v,n,t,c) \
- (v = (c*)saferealloc((Malloc_t)(v),(MEM_SIZE)((n)*sizeof(t))))
-#define Safefree(d) safefree((Malloc_t)(d))
+#define PERL_STRLEN_ROUNDUP(n) ((void)(((n) > (MEM_SIZE)~0 - 2 * PERL_STRLEN_ROUNDUP_QUANTUM) ? (Perl_croak_nocontext(PL_memory_wrap),0):0),((n-1+PERL_STRLEN_ROUNDUP_QUANTUM)&~((MEM_SIZE)PERL_STRLEN_ROUNDUP_QUANTUM-1)))
+
+#else
-#else /* LEAKTEST */
+#define MEM_WRAP_CHECK(n,t)
+#define MEM_WRAP_CHECK_1(n,t,a)
+#define MEM_WRAP_CHECK_2(n,t,a,b)
+#define MEM_WRAP_CHECK_(n,t)
-#define New(x,v,n,t) (v = (t*)safexmalloc((x),(MEM_SIZE)((n)*sizeof(t))))
-#define Newc(x,v,n,t,c) (v = (c*)safexmalloc((x),(MEM_SIZE)((n)*sizeof(t))))
-#define Newz(x,v,n,t) (v = (t*)safexmalloc((x),(MEM_SIZE)((n)*sizeof(t)))), \
- memzero((char*)(v), (n)*sizeof(t))
-#define Renew(v,n,t) \
- (v = (t*)safexrealloc((Malloc_t)(v),(MEM_SIZE)((n)*sizeof(t))))
-#define Renewc(v,n,t,c) \
- (v = (c*)safexrealloc((Malloc_t)(v),(MEM_SIZE)((n)*sizeof(t))))
-#define Safefree(d) safexfree((Malloc_t)(d))
+#define PERL_STRLEN_ROUNDUP(n) (((n-1+PERL_STRLEN_ROUNDUP_QUANTUM)&~((MEM_SIZE)PERL_STRLEN_ROUNDUP_QUANTUM-1)))
+
+#endif
-#define MAXXCOUNT 1400
-#define MAXY_SIZE 80
-#define MAXYCOUNT 16 /* (MAXY_SIZE/4 + 1) */
-extern long xcount[MAXXCOUNT];
-extern long lastxcount[MAXXCOUNT];
-extern long xycount[MAXXCOUNT][MAXYCOUNT];
-extern long lastxycount[MAXXCOUNT][MAXYCOUNT];
+#define Newx(v,n,t) (v = (MEM_WRAP_CHECK_(n,t) (t*)safemalloc((MEM_SIZE)((n)*sizeof(t)))))
+#define Newxc(v,n,t,c) (v = (MEM_WRAP_CHECK_(n,t) (c*)safemalloc((MEM_SIZE)((n)*sizeof(t)))))
+#define Newxz(v,n,t) (v = (MEM_WRAP_CHECK_(n,t) (t*)safemalloc((MEM_SIZE)((n)*sizeof(t))))), \
+ memzero((char*)(v), (n)*sizeof(t))
+/* pre 5.9.x compatibility */
+#define New(x,v,n,t) Newx(v,n,t)
+#define Newc(x,v,n,t,c) Newxc(v,n,t,c)
+#define Newc(x,v,n,t,c) Newxc(v,n,t,c)
-#endif /* LEAKTEST */
+#define Renew(v,n,t) \
+ (v = (MEM_WRAP_CHECK_(n,t) (t*)saferealloc((Malloc_t)(v),(MEM_SIZE)((n)*sizeof(t)))))
+#define Renewc(v,n,t,c) \
+ (v = (MEM_WRAP_CHECK_(n,t) (c*)saferealloc((Malloc_t)(v),(MEM_SIZE)((n)*sizeof(t)))))
-#define Move(s,d,n,t) (void)memmove((char*)(d),(char*)(s), (n) * sizeof(t))
-#define Copy(s,d,n,t) (void)memcpy((char*)(d),(char*)(s), (n) * sizeof(t))
-#define Zero(d,n,t) (void)memzero((char*)(d), (n) * sizeof(t))
+#ifdef PERL_POISON
+#define Safefree(d) \
+ ((d) ? (void)(safefree((Malloc_t)(d)), Poison(&(d), 1, Malloc_t)) : (void) 0)
+#else
+#define Safefree(d) safefree((Malloc_t)(d))
+#endif
-#else /* lint */
+#define Move(s,d,n,t) (MEM_WRAP_CHECK_(n,t) (void)memmove((char*)(d),(const char*)(s), (n) * sizeof(t)))
+#define Copy(s,d,n,t) (MEM_WRAP_CHECK_(n,t) (void)memcpy((char*)(d),(const char*)(s), (n) * sizeof(t)))
+#define Zero(d,n,t) (MEM_WRAP_CHECK_(n,t) (void)memzero((char*)(d), (n) * sizeof(t)))
-#define New(x,v,n,s) (v = Null(s *))
-#define Newc(x,v,n,s,c) (v = Null(s *))
-#define Newz(x,v,n,s) (v = Null(s *))
-#define Renew(v,n,s) (v = Null(s *))
-#define Move(s,d,n,t)
-#define Copy(s,d,n,t)
-#define Zero(d,n,t)
-#define Safefree(d) (d) = (d)
+#define MoveD(s,d,n,t) (MEM_WRAP_CHECK_(n,t) memmove((char*)(d),(const char*)(s), (n) * sizeof(t)))
+#define CopyD(s,d,n,t) (MEM_WRAP_CHECK_(n,t) memcpy((char*)(d),(const char*)(s), (n) * sizeof(t)))
+#ifdef HAS_MEMSET
+#define ZeroD(d,n,t) (MEM_WRAP_CHECK_(n,t) memzero((char*)(d), (n) * sizeof(t)))
+#else
+/* Using bzero(), which returns void. */
+#define ZeroD(d,n,t) (MEM_WRAP_CHECK_(n,t) memzero((char*)(d), (n) * sizeof(t)),d)
+#endif
-#endif /* lint */
+#define Poison(d,n,t) (MEM_WRAP_CHECK_(n,t) (void)memset((char*)(d), 0xAB, (n) * sizeof(t)))
#ifdef USE_STRUCT_COPY
#define StructCopy(s,d,t) (*((t*)(d)) = *((t*)(s)))
#define StructCopy(s,d,t) Copy(s,d,1,t)
#endif
+#define C_ARRAY_LENGTH(a) (sizeof(a)/sizeof((a)[0]))
+
#ifdef NEED_VA_COPY
# ifdef va_copy
# define Perl_va_copy(s, d) va_copy(d, s)
# endif
#endif
+/* convenience debug macros */
+#ifdef USE_ITHREADS
+#define pTHX_FORMAT "Perl interpreter: 0x%p"
+#define pTHX__FORMAT ", Perl interpreter: 0x%p"
+#define pTHX_VALUE_ (void *)my_perl,
+#define pTHX_VALUE (void *)my_perl
+#define pTHX__VALUE_ ,(void *)my_perl,
+#define pTHX__VALUE ,(void *)my_perl
+#else
+#define pTHX_FORMAT
+#define pTHX__FORMAT
+#define pTHX_VALUE_
+#define pTHX_VALUE
+#define pTHX__VALUE_
+#define pTHX__VALUE
+#endif /* USE_ITHREADS */