/* This is a helper macro to avoid preprocessor issues, replaced by nothing
* unless under DEBUGGING, where it expands to an assert of its argument,
* followed by a comma (hence the comma operator). If we just used a straight
- * assert(), we would get a comma with nothing before it when not DEBUGGING */
-#ifdef DEBUGGING
+ * assert(), we would get a comma with nothing before it when not DEBUGGING.
+ *
+ * We also use empty definition under Coverity since the __ASSERT__
+ * checks often check for things that Really Cannot Happen, and Coverity
+ * detects that and gets all excited. */
+
+#if defined(DEBUGGING) && !defined(__COVERITY__)
# define __ASSERT_(statement) assert(statement),
#else
# define __ASSERT_(statement)
=head1 SV-Body Allocation
=for apidoc Ama|SV*|newSVpvs|const char* s
-Like C<newSVpvn>, but takes a literal C<NUL>-terminated string instead of a
+Like C<newSVpvn>, but takes a C<NUL>-terminated literal string instead of a
string/length pair.
=for apidoc Ama|SV*|newSVpvs_flags|const char* s|U32 flags
-Like C<newSVpvn_flags>, but takes a literal C<NUL>-terminated string instead of
+Like C<newSVpvn_flags>, but takes a C<NUL>-terminated literal string instead of
a string/length pair.
=for apidoc Ama|SV*|newSVpvs_share|const char* s
-Like C<newSVpvn_share>, but takes a literal C<NUL>-terminated string instead of
+Like C<newSVpvn_share>, but takes a C<NUL>-terminated literal string instead of
a string/length pair and omits the hash parameter.
=for apidoc Am|void|sv_catpvs_flags|SV* sv|const char* s|I32 flags
-Like C<sv_catpvn_flags>, but takes a literal C<NUL>-terminated string instead
+Like C<sv_catpvn_flags>, but takes a C<NUL>-terminated literal string instead
of a string/length pair.
=for apidoc Am|void|sv_catpvs_nomg|SV* sv|const char* s
-Like C<sv_catpvn_nomg>, but takes a literal string instead of a
-string/length pair.
+Like C<sv_catpvn_nomg>, but takes a C<NUL>-terminated literal string instead of
+a string/length pair.
=for apidoc Am|void|sv_catpvs|SV* sv|const char* s
-Like C<sv_catpvn>, but takes a literal string instead of a string/length pair.
+Like C<sv_catpvn>, but takes a C<NUL>-terminated literal string instead of a
+string/length pair.
=for apidoc Am|void|sv_catpvs_mg|SV* sv|const char* s
-Like C<sv_catpvn_mg>, but takes a literal string instead of a
+Like C<sv_catpvn_mg>, but takes a C<NUL>-terminated literal string instead of a
string/length pair.
=for apidoc Am|void|sv_setpvs|SV* sv|const char* s
-Like C<sv_setpvn>, but takes a literal string instead of a string/length pair.
+Like C<sv_setpvn>, but takes a C<NUL>-terminated literal string instead of a
+string/length pair.
=for apidoc Am|void|sv_setpvs_mg|SV* sv|const char* s
-Like C<sv_setpvn_mg>, but takes a literal string instead of a
+Like C<sv_setpvn_mg>, but takes a C<NUL>-terminated literal string instead of a
string/length pair.
=for apidoc Am|SV *|sv_setref_pvs|const char* s
-Like C<sv_setref_pvn>, but takes a literal string instead of a
-string/length pair.
+Like C<sv_setref_pvn>, but takes a C<NUL>-terminated literal string instead of
+a string/length pair.
=head1 Memory Management
=for apidoc Ama|char*|savepvs|const char* s
-Like C<savepvn>, but takes a literal C<NUL>-terminated string instead of a
+Like C<savepvn>, but takes a C<NUL>-terminated literal string instead of a
string/length pair.
=for apidoc Ama|char*|savesharedpvs|const char* s
=head1 GV Functions
=for apidoc Am|HV*|gv_stashpvs|const char* name|I32 create
-Like C<gv_stashpvn>, but takes a literal string instead of a string/length pair.
+Like C<gv_stashpvn>, but takes a C<NUL>-terminated literal string instead of a
+string/length pair.
=head1 Hash Manipulation Functions
=for apidoc Am|SV**|hv_fetchs|HV* tb|const char* key|I32 lval
-Like C<hv_fetch>, but takes a literal string instead of a string/length pair.
+Like C<hv_fetch>, but takes a C<NUL>-terminated literal string instead of a
+string/length pair.
=for apidoc Am|SV**|hv_stores|HV* tb|const char* key|NULLOK SV* val
-Like C<hv_store>, but takes a literal string instead of a string/length pair
+Like C<hv_store>, but takes a C<NUL>-terminated literal string instead of a
+string/length pair
and omits the hash parameter.
=head1 Lexer interface
=for apidoc Amx|void|lex_stuff_pvs|const char *pv|U32 flags
-Like L</lex_stuff_pvn>, but takes a literal string instead of a
-string/length pair.
+Like L</lex_stuff_pvn>, but takes a C<NUL>-terminated literal string instead of
+a string/length pair.
=cut
*/
=head1 Miscellaneous Functions
=for apidoc Am|bool|strNE|char* s1|char* s2
-Test two strings to see if they are different. Returns true or
-false.
+Test two C<NUL>-terminated strings to see if they are different. Returns true
+or false.
=for apidoc Am|bool|strEQ|char* s1|char* s2
-Test two strings to see if they are equal. Returns true or false.
+Test two C<NUL>-terminated strings to see if they are equal. Returns true or
+false.
=for apidoc Am|bool|strLT|char* s1|char* s2
-Test two strings to see if the first, C<s1>, is less than the second,
-C<s2>. Returns true or false.
+Test two C<NUL>-terminated strings to see if the first, C<s1>, is less than the
+second, C<s2>. Returns true or false.
=for apidoc Am|bool|strLE|char* s1|char* s2
-Test two strings to see if the first, C<s1>, is less than or equal to the
-second, C<s2>. Returns true or false.
+Test two C<NUL>-terminated strings to see if the first, C<s1>, is less than or
+equal to the second, C<s2>. Returns true or false.
=for apidoc Am|bool|strGT|char* s1|char* s2
-Test two strings to see if the first, C<s1>, is greater than the second,
-C<s2>. Returns true or false.
+Test two C<NUL>-terminated strings to see if the first, C<s1>, is greater than
+the second, C<s2>. Returns true or false.
=for apidoc Am|bool|strGE|char* s1|char* s2
-Test two strings to see if the first, C<s1>, is greater than or equal to
-the second, C<s2>. Returns true or false.
+Test two C<NUL>-terminated strings to see if the first, C<s1>, is greater than
+or equal to the second, C<s2>. Returns true or false.
=for apidoc Am|bool|strnNE|char* s1|char* s2|STRLEN len
-Test two strings to see if they are different. The C<len> parameter
-indicates the number of bytes to compare. Returns true or false. (A
+Test two C<NUL>-terminated strings to see if they are different. The C<len>
+parameter indicates the number of bytes to compare. Returns true or false. (A
wrapper for C<strncmp>).
=for apidoc Am|bool|strnEQ|char* s1|char* s2|STRLEN len
-Test two strings to see if they are equal. The C<len> parameter indicates
-the number of bytes to compare. Returns true or false. (A wrapper for
-C<strncmp>).
+Test two C<NUL>-terminated strings to see if they are equal. The C<len>
+parameter indicates the number of bytes to compare. Returns true or false. (A
+wrapper for C<strncmp>).
=for apidoc Am|bool|memEQ|char* s1|char* s2|STRLEN len
Test two buffers (which may contain embedded C<NUL> characters, to see if they
WITH MACRON in Unicode, and is a word character.
Variant C<isFOO_utf8> is like C<isFOO_uni>, but the input is a pointer to a
-(known to be well-formed) UTF-8 encoded string (C<U8*> or C<char*>). The
-classification of just the first (possibly multi-byte) character in the string
-is tested.
+(known to be well-formed) UTF-8 encoded string (C<U8*> or C<char*>, and
+possibly containing embedded C<NUL> characters). The classification of just
+the first (possibly multi-byte) character in the string is tested.
Variant C<isFOO_LC> is like the C<isFOO_A> and C<isFOO_L1> variants, but the
result is based on the current locale, which is what C<LC> in the name stands
returns the hard-coded, not-affected-by-locale, Unicode results for larger ones.
Variant C<isFOO_LC_utf8> is like C<isFOO_LC_uvchr>, but the input is a pointer
-to a (known to be well-formed) UTF-8 encoded string (C<U8*> or C<char*>). The
-classification of just the first (possibly multi-byte) character in the string
-is tested.
+to a (known to be well-formed) UTF-8 encoded string (C<U8*> or C<char*>, and
+possibly containing embedded C<NUL> characters). The classification of just
+the first (possibly multi-byte) character in the string is tested.
=for apidoc Am|bool|isALPHA|char ch
Returns a boolean indicating whether the specified character is an
* compiler to optimize it out if possible. This is because Configure makes
* sure that the machine has an 8-bit byte, so if c is stored in a byte, the
* sizeof() guarantees that this evaluates to a constant true at compile time.
+ *
+ * For Coverity, be always true, because otherwise Coverity thinks
+ * it finds several expressions that are always true, independent
+ * of operands. Well, they are, but that is kind of the point.
*/
+#ifndef __COVERITY__
#define FITS_IN_8_BITS(c) ((sizeof(c) == 1) || !(((WIDEST_UTYPE)(c)) & ~0xFF))
+#else
+#define FITS_IN_8_BITS(c) (1)
+#endif
#ifdef EBCDIC
# ifndef _ALL_SOURCE
#else
/* There is a simple definition of ASCII for ASCII platforms. But the
* EBCDIC one isn't so simple, so is defined using table look-up like the
- * other macros below */
-# define isASCII(c) ((WIDEST_UTYPE)(c) < 128)
+ * other macros below.
+ * The '| 0' part ensures that c is an integer (and not e.g. a pointer) */
+# define isASCII(c) ((WIDEST_UTYPE)((c) | 0) < 128)
#endif
/* The lower 3 bits in both the ASCII and EBCDIC representations of '0' are 0,
/* This next group is only used on EBCDIC platforms, so theoretically could be
* shared with something entirely different that's only on ASCII platforms */
-# define _CC_UTF8_IS_START 29
-# define _CC_UTF8_IS_DOWNGRADEABLE_START 30
-# define _CC_UTF8_IS_CONTINUATION 31
-/* Unused: 24-28
+# define _CC_UTF8_START_BYTE_IS_FOR_AT_LEAST_SURROGATE 28
+# define _CC_UTF8_IS_START 29
+# define _CC_UTF8_IS_DOWNGRADEABLE_START 30
+# define _CC_UTF8_IS_CONTINUATION 31
+/* Unused: 24-27
* If more bits are needed, one could add a second word for non-64bit
* QUAD_IS_INT systems, using some #ifdefs to distinguish between having a 2nd
* word or not. The IS_IN_SOME_FOLD bit is the most easily expendable, as it
* As well as avoiding the need for a run-time check in some cases, it's
* designed to avoid compiler warnings like:
* comparison is always false due to limited range of data type
+ * It's mathematically equivalent to
+ * max(n) * sizeof(t) > MEM_SIZE_MAX
*/
# define _MEM_WRAP_NEEDS_RUNTIME_CHECK(n,t) \
- (sizeof(t) > ((MEM_SIZE)1 << 8*(sizeof(MEM_SIZE) - sizeof(n))))
+ ( sizeof(MEM_SIZE) < sizeof(n) \
+ || sizeof(t) > ((MEM_SIZE)1 << 8*(sizeof(MEM_SIZE) - sizeof(n))))
/* This is written in a slightly odd way to avoid various spurious
* compiler warnings. We *want* to write the expression as