/* sv.h
*
- * Copyright (c) 1991-1999, Larry Wall
+ * Copyright (c) 1991-2001, Larry Wall
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
/* Using C's structural equivalence to help emulate C++ inheritance here... */
-struct sv {
+struct STRUCT_SV {
void* sv_any; /* pointer to something */
U32 sv_refcnt; /* how many references to us */
U32 sv_flags; /* what we are */
#ifdef USE_THREADS
-# ifdef EMULATE_ATOMIC_REFCOUNTS
-# define ATOMIC_INC(count) STMT_START { \
- MUTEX_LOCK(&PL_svref_mutex); \
- ++count; \
- MUTEX_UNLOCK(&PL_svref_mutex); \
- } STMT_END
-# define ATOMIC_DEC_AND_TEST(res,count) STMT_START { \
- MUTEX_LOCK(&PL_svref_mutex); \
- res = (--count == 0); \
- MUTEX_UNLOCK(&PL_svref_mutex); \
- } STMT_END
-# else
-# define ATOMIC_INC(count) atomic_inc(&count)
-# define ATOMIC_DEC_AND_TEST(res,count) (res = atomic_dec_and_test(&count))
-# endif /* EMULATE_ATOMIC_REFCOUNTS */
+# if defined(VMS)
+# define ATOMIC_INC(count) __ATOMIC_INCREMENT_LONG(&count)
+# define ATOMIC_DEC_AND_TEST(res,count) res=(1==__ATOMIC_DECREMENT_LONG(&count))
+ # else
+# ifdef EMULATE_ATOMIC_REFCOUNTS
+ # define ATOMIC_INC(count) STMT_START { \
+ MUTEX_LOCK(&PL_svref_mutex); \
+ ++count; \
+ MUTEX_UNLOCK(&PL_svref_mutex); \
+ } STMT_END
+# define ATOMIC_DEC_AND_TEST(res,count) STMT_START { \
+ MUTEX_LOCK(&PL_svref_mutex); \
+ res = (--count == 0); \
+ MUTEX_UNLOCK(&PL_svref_mutex); \
+ } STMT_END
+# else
+# define ATOMIC_INC(count) atomic_inc(&count)
+# define ATOMIC_DEC_AND_TEST(res,count) (res = atomic_dec_and_test(&count))
+# endif /* EMULATE_ATOMIC_REFCOUNTS */
+# endif /* VMS */
#else
# define ATOMIC_INC(count) (++count)
# define ATOMIC_DEC_AND_TEST(res, count) (res = (--count == 0))
})
#else
# if defined(CRIPPLED_CC) || defined(USE_THREADS)
-# define SvREFCNT_inc(sv) sv_newref((SV*)sv)
+# if defined(VMS) && defined(__ALPHA)
+# define SvREFCNT_inc(sv) \
+ (PL_Sv=(SV*)(sv), (PL_Sv && __ATOMIC_INCREMENT_LONG(&(SvREFCNT(PL_Sv)))), (SV *)PL_Sv)
+# else
+# define SvREFCNT_inc(sv) sv_newref((SV*)sv)
+# endif
# else
# define SvREFCNT_inc(sv) \
((PL_Sv=(SV*)(sv)), (PL_Sv && ATOMIC_INC(SvREFCNT(PL_Sv))), (SV*)PL_Sv)
PerlIO * xio_ifp; /* ifp and ofp are normally the same */
PerlIO * xio_ofp; /* but sockets need separate streams */
- DIR * xio_dirp; /* for opendir, readdir, etc */
+ /* Cray addresses everything by word boundaries (64 bits) and
+ * code and data pointers cannot be mixed (which is exactly what
+ * Perl_filter_add() tries to do with the dirp), hence the following
+ * union trick (as suggested by Gurusamy Sarathy).
+ * For further information see Geir Johansen's problem report titled
+ [ID 20000612.002] Perl problem on Cray system
+ * The any pointer (known as IoANY()) will also be a good place
+ * to hang any IO disciplines to.
+ */
+ union {
+ DIR * xiou_dirp; /* for opendir, readdir, etc */
+ void * xiou_any; /* for alignment */
+ } xio_dirpu;
long xio_lines; /* $. */
long xio_page; /* $% */
long xio_page_len; /* $= */
char xio_type;
char xio_flags;
};
+#define xio_dirp xio_dirpu.xiou_dirp
+#define xio_any xio_dirpu.xiou_any
#define IOf_ARGV 1 /* this fp iterates over ARGV */
#define IOf_START 2 /* check for null ARGV and substitute '-' */
=for apidoc Am|void|SvIOK_only|SV* sv
Tells an SV that it is an integer and disables all other OK bits.
+=for apidoc Am|void|SvIOK_only_UV|SV* sv
+Tells and SV that it is an unsigned integer and disables all other OK bits.
+
+=for apidoc Am|void|SvIOK_UV|SV* sv
+Returns a boolean indicating whether the SV contains an unsigned integer.
+
+=for apidoc Am|void|SvUOK|SV* sv
+Returns a boolean indicating whether the SV contains an unsigned integer.
+
+=for apidoc Am|void|SvIOK_notUV|SV* sv
+Returns a boolean indicating whether the SV contains an signed integer.
+
=for apidoc Am|bool|SvNOK|SV* sv
Returns a boolean indicating whether the SV contains a double.
Returns the length of the string which is in the SV. See C<SvLEN>.
=for apidoc Am|STRLEN|SvLEN|SV* sv
-Returns the size of the string buffer in the SV. See C<SvCUR>.
+Returns the size of the string buffer in the SV, not including any part
+attributable to C<SvOOK>. See C<SvCUR>.
=for apidoc Am|char*|SvEND|SV* sv
Returns a pointer to the last character in the string which is in the SV.
#define SvOK(sv) (SvFLAGS(sv) & SVf_OK)
#define SvOK_off(sv) (SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \
- SVf_IVisUV), \
+ SVf_IVisUV|SVf_UTF8), \
SvOOK_off(sv))
-#define SvOK_off_exc_UV(sv) (SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC), \
+#define SvOK_off_exc_UV(sv) (SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \
+ SVf_UTF8), \
SvOOK_off(sv))
#define SvOKp(sv) (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK))
#define SvIOKp(sv) (SvFLAGS(sv) & SVp_IOK)
-#define SvIOKp_on(sv) (SvOOK_off(sv), SvFLAGS(sv) |= SVp_IOK)
+#define SvIOKp_on(sv) ((void)SvOOK_off(sv), SvFLAGS(sv) |= SVp_IOK)
#define SvNOKp(sv) (SvFLAGS(sv) & SVp_NOK)
#define SvNOKp_on(sv) (SvFLAGS(sv) |= SVp_NOK)
#define SvPOKp(sv) (SvFLAGS(sv) & SVp_POK)
#define SvPOKp_on(sv) (SvFLAGS(sv) |= SVp_POK)
#define SvIOK(sv) (SvFLAGS(sv) & SVf_IOK)
-#define SvIOK_on(sv) (SvOOK_off(sv), \
+#define SvIOK_on(sv) ((void)SvOOK_off(sv), \
SvFLAGS(sv) |= (SVf_IOK|SVp_IOK))
#define SvIOK_off(sv) (SvFLAGS(sv) &= ~(SVf_IOK|SVp_IOK|SVf_IVisUV))
-#define SvIOK_only(sv) (SvOK_off(sv), \
+#define SvIOK_only(sv) ((void)SvOK_off(sv), \
SvFLAGS(sv) |= (SVf_IOK|SVp_IOK))
-#define SvIOK_only_UV(sv) (SvOK_off_exc_UV(sv), \
+#define SvIOK_only_UV(sv) ((void)SvOK_off_exc_UV(sv), \
SvFLAGS(sv) |= (SVf_IOK|SVp_IOK))
#define SvIOK_UV(sv) ((SvFLAGS(sv) & (SVf_IOK|SVf_IVisUV)) \
== (SVf_IOK|SVf_IVisUV))
+#define SvUOK(sv) SvIOK_UV(sv)
#define SvIOK_notUV(sv) ((SvFLAGS(sv) & (SVf_IOK|SVf_IVisUV)) \
== SVf_IOK)
#define SvNOK(sv) (SvFLAGS(sv) & SVf_NOK)
#define SvNOK_on(sv) (SvFLAGS(sv) |= (SVf_NOK|SVp_NOK))
#define SvNOK_off(sv) (SvFLAGS(sv) &= ~(SVf_NOK|SVp_NOK))
-#define SvNOK_only(sv) (SvOK_off(sv), \
+#define SvNOK_only(sv) ((void)SvOK_off(sv), \
SvFLAGS(sv) |= (SVf_NOK|SVp_NOK))
+/*
+=for apidoc Am|void|SvUTF8|SV* sv
+Returns a boolean indicating whether the SV contains UTF-8 encoded data.
+
+=for apidoc Am|void|SvUTF8_on|SV *sv
+Tells an SV that it is a string and encoded in UTF8. Do not use frivolously.
+
+=for apidoc Am|void|SvUTF8_off|SV *sv
+Unsets the UTF8 status of an SV.
+
+=for apidoc Am|void|SvPOK_only_UTF8|SV* sv
+Tells an SV that it is a UTF8 string (do not use frivolously)
+and disables all other OK bits.
+
+=cut
+ */
+
#define SvUTF8(sv) (SvFLAGS(sv) & SVf_UTF8)
#define SvUTF8_on(sv) (SvFLAGS(sv) |= (SVf_UTF8))
#define SvUTF8_off(sv) (SvFLAGS(sv) &= ~(SVf_UTF8))
#define SvPOK(sv) (SvFLAGS(sv) & SVf_POK)
#define SvPOK_on(sv) (SvFLAGS(sv) |= (SVf_POK|SVp_POK))
#define SvPOK_off(sv) (SvFLAGS(sv) &= ~(SVf_POK|SVp_POK))
-#define SvPOK_only(sv) (SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC|SVf_IVisUV), \
+#define SvPOK_only(sv) (SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \
+ SVf_IVisUV|SVf_UTF8), \
+ SvFLAGS(sv) |= (SVf_POK|SVp_POK))
+#define SvPOK_only_UTF8(sv) (SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \
+ SVf_IVisUV), \
SvFLAGS(sv) |= (SVf_POK|SVp_POK))
#define SvOOK(sv) (SvFLAGS(sv) & SVf_OOK)
-#define SvOOK_on(sv) (SvIOK_off(sv), SvFLAGS(sv) |= SVf_OOK)
+#define SvOOK_on(sv) ((void)SvIOK_off(sv), SvFLAGS(sv) |= SVf_OOK)
#define SvOOK_off(sv) (SvOOK(sv) && sv_backoff(sv))
#define SvFAKE(sv) (SvFLAGS(sv) & SVf_FAKE)
#define SvAMAGIC_on(sv) (SvFLAGS(sv) |= SVf_AMAGIC)
#define SvAMAGIC_off(sv) (SvFLAGS(sv) &= ~SVf_AMAGIC)
+#define SvGAMAGIC(sv) (SvFLAGS(sv) & (SVs_GMG|SVf_AMAGIC))
+
/*
#define Gv_AMG(stash) \
(HV_AMAGICmb(stash) && \
#define SvMAGIC(sv) ((XPVMG*) SvANY(sv))->xmg_magic
#define SvSTASH(sv) ((XPVMG*) SvANY(sv))->xmg_stash
+/* Ask a scalar nicely to try to become an IV, if possible.
+ Not guaranteed to stay returning void */
+/* Macro won't actually call sv_2iv if already IOK */
+#define SvIV_please(sv) \
+ STMT_START {if (!SvIOKp(sv) && (SvNOK(sv) || SvPOK(sv))) \
+ (void) SvIV(sv); } STMT_END
#define SvIV_set(sv, val) \
STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \
(((XPVIV*) SvANY(sv))->xiv_iv = val); } STMT_END
#define IoIFP(sv) ((XPVIO*) SvANY(sv))->xio_ifp
#define IoOFP(sv) ((XPVIO*) SvANY(sv))->xio_ofp
#define IoDIRP(sv) ((XPVIO*) SvANY(sv))->xio_dirp
+#define IoANY(sv) ((XPVIO*) SvANY(sv))->xio_any
#define IoLINES(sv) ((XPVIO*) SvANY(sv))->xio_lines
#define IoPAGE(sv) ((XPVIO*) SvANY(sv))->xio_page
#define IoPAGE_LEN(sv) ((XPVIO*) SvANY(sv))->xio_page_len
#define IoTYPE(sv) ((XPVIO*) SvANY(sv))->xio_type
#define IoFLAGS(sv) ((XPVIO*) SvANY(sv))->xio_flags
+/* IoTYPE(sv) is a single character telling the type of I/O connection. */
+#define IoTYPE_RDONLY '<'
+#define IoTYPE_WRONLY '>'
+#define IoTYPE_RDWR '+'
+#define IoTYPE_APPEND 'a'
+#define IoTYPE_PIPE '|'
+#define IoTYPE_STD '-' /* stdin or stdout */
+#define IoTYPE_SOCKET 's'
+#define IoTYPE_CLOSED ' '
+
/*
=for apidoc Am|bool|SvTAINTED|SV* sv
Checks to see if an SV is tainted. Returns TRUE if it is, FALSE if
#define SvTAINT(sv) \
STMT_START { \
if (PL_tainting) { \
- dTHR; \
if (PL_tainted) \
SvTAINTED_on(sv); \
} \
#define SvGROW(sv,len) (SvLEN(sv) < (len) ? sv_grow(sv,len) : SvPVX(sv))
#define Sv_Grow sv_grow
+
+#define SV_IMMEDIATE_UNREF 1