#endif
-/* log(2) is pretty close to 0.30103, just in case anyone is grepping for it */
-#define BIT_DIGITS(N) (((N)*146)/485 + 1) /* log2(10) =~ 146/485 */
+/* log(2) (i.e., log base 10 of 2) is pretty close to 0.30103, just in case
+ * anyone is grepping for it */
+#define BIT_DIGITS(N) (((N)*146)/485 + 1) /* log10(2) =~ 146/485 */
#define TYPE_DIGITS(T) BIT_DIGITS(sizeof(T) * 8)
#define TYPE_CHARS(T) (TYPE_DIGITS(T) + 2) /* sign, NUL */
/*
=head1 SV-Body Allocation
-=for apidoc Ama|SV*|newSVpvs|const char* s
-Like C<newSVpvn>, but takes a C<NUL>-terminated literal string instead of a
+=for apidoc Ama|SV*|newSVpvs|"literal string" s
+Like C<newSVpvn>, but takes a 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 C<NUL>-terminated literal string instead of
+=for apidoc Ama|SV*|newSVpvs_flags|"literal string" s|U32 flags
+Like C<newSVpvn_flags>, but takes a literal string instead of
a string/length pair.
-=for apidoc Ama|SV*|newSVpvs_share|const char* s
-Like C<newSVpvn_share>, but takes a C<NUL>-terminated literal string instead of
+=for apidoc Ama|SV*|newSVpvs_share|"literal string" s
+Like C<newSVpvn_share>, but takes a 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 C<NUL>-terminated literal string instead
+=for apidoc Am|void|sv_catpvs_flags|SV* sv|"literal string" s|I32 flags
+Like C<sv_catpvn_flags>, but takes a 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 C<NUL>-terminated literal string instead of
+=for apidoc Am|void|sv_catpvs_nomg|SV* sv|"literal string" s
+Like C<sv_catpvn_nomg>, but takes a 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 C<NUL>-terminated literal string instead of a
+=for apidoc Am|void|sv_catpvs|SV* sv|"literal string" s
+Like C<sv_catpvn>, but takes a 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 C<NUL>-terminated literal string instead of a
+=for apidoc Am|void|sv_catpvs_mg|SV* sv|"literal string" s
+Like C<sv_catpvn_mg>, but takes a 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 C<NUL>-terminated literal string instead of a
+=for apidoc Am|void|sv_setpvs|SV* sv|"literal string" s
+Like C<sv_setpvn>, but takes a 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 C<NUL>-terminated literal string instead of a
+=for apidoc Am|void|sv_setpvs_mg|SV* sv|"literal string" s
+Like C<sv_setpvn_mg>, but takes a 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 C<NUL>-terminated literal string instead of
+=for apidoc Am|SV *|sv_setref_pvs|"literal string" s
+Like C<sv_setref_pvn>, but takes a 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 C<NUL>-terminated literal string instead of a
+=for apidoc Ama|char*|savepvs|"literal string" s
+Like C<savepvn>, but takes a literal string instead of a
string/length pair.
-=for apidoc Ama|char*|savesharedpvs|const char* s
+=for apidoc Ama|char*|savesharedpvs|"literal string" s
A version of C<savepvs()> which allocates the duplicate string in memory
which is shared between threads.
=head1 GV Functions
-=for apidoc Am|HV*|gv_stashpvs|const char* name|I32 create
-Like C<gv_stashpvn>, but takes a C<NUL>-terminated literal string instead of a
+=for apidoc Am|HV*|gv_stashpvs|"literal string" name|I32 create
+Like C<gv_stashpvn>, but takes a 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 C<NUL>-terminated literal string instead of a
+=for apidoc Am|SV**|hv_fetchs|HV* tb|"literal string" key|I32 lval
+Like C<hv_fetch>, but takes a 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 C<NUL>-terminated literal string instead of a
+=for apidoc Am|SV**|hv_stores|HV* tb|"literal string" key|NULLOK SV* val
+Like C<hv_store>, but takes a 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
+=for apidoc Amx|void|lex_stuff_pvs|"literal string" pv|U32 flags
-Like L</lex_stuff_pvn>, but takes a C<NUL>-terminated literal string instead of
+Like L</lex_stuff_pvn>, but takes a literal string instead of
a string/length pair.
=cut
Returns zero if non-equal, or non-zero if equal.
=cut
+
+New macros should use the following conventions for their names (which are
+based on the underlying C library functions):
+
+ (mem | str n? ) (EQ | NE | LT | GT | GE | (( BEGIN | END ) P? )) l? s?
+
+ Each has two main parameters, string-like operands that are compared
+ against each other, as specified by the macro name. Some macros may
+ additionally have one or potentially even two length parameters. If a length
+ parameter applies to both string parameters, it will be positioned third;
+ otherwise any length parameter immediately follows the string parameter it
+ applies to.
+
+ If the prefix to the name is 'str', the string parameter is a pointer to a C
+ language string. Such a string does not contain embedded NUL bytes; its
+ length may be unknown, but can be calculated by C<strlen()>, since it is
+ terminated by a NUL, which isn't included in its length.
+
+ The optional 'n' following 'str' means that that there is a third parameter,
+ giving the maximum number of bytes to look at in each string. Even if both
+ strings are longer than the length parameter, those extra bytes will be
+ unexamined.
+
+ The 's' suffix means that the 2nd byte string parameter is a literal C
+ double-quoted string. Its length will automatically be calculated by the
+ macro, so no length parameter will ever be needed for it.
+
+ If the prefix is 'mem', the string parameters don't have to be C strings;
+ they may contain embedded NUL bytes, do not necessarily have a terminating
+ NUL, and their lengths can be known only through other means, which in
+ practice are additional parameter(s) passed to the function. All 'mem'
+ functions have at least one length parameter. Barring any 'l' or 's' suffix,
+ there is a single length parameter, in position 3, which applies to both
+ string parameters. The 's' suffix means, as described above, that the 2nd
+ string is a literal double-quoted C string (hence its length is calculated by
+ the macro, and the length parameter to the function applies just to the first
+ string parameter, and hence is positioned just after it). An 'l' suffix
+ means that the 2nd string parameter has its own length parameter, and the
+ signature will look like memFOOl(s1, l1, s2, l2).
+
+ BEGIN (and END) are for testing if the 2nd string is an initial (or final)
+ substring of the 1st string. 'P' if present indicates that the substring
+ must be a "proper" one in tha mathematical sense that the first one must be
+ strictly larger than the 2nd.
+
*/
#define NEWSV(x,len) newSV(len)
#endif
-#define MEM_SIZE_MAX ((MEM_SIZE)~0)
+#define MEM_SIZE_MAX ((MEM_SIZE)-1)
+#define _PERL_STRLEN_ROUNDUP_UNCHECKED(n) (((n) - 1 + PERL_STRLEN_ROUNDUP_QUANTUM) & ~((MEM_SIZE)PERL_STRLEN_ROUNDUP_QUANTUM - 1))
#ifdef PERL_MALLOC_WRAP
*/
# define _MEM_WRAP_NEEDS_RUNTIME_CHECK(n,t) \
- (8 * sizeof(n) + sizeof(t) > sizeof(MEM_SIZE))
+ ( 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
#define MEM_WRAP_CHECK_(n,t) MEM_WRAP_CHECK(n,t),
-#define PERL_STRLEN_ROUNDUP(n) ((void)(((n) > MEM_SIZE_MAX - 2 * PERL_STRLEN_ROUNDUP_QUANTUM) ? (croak_memory_wrap(),0):0),((n-1+PERL_STRLEN_ROUNDUP_QUANTUM)&~((MEM_SIZE)PERL_STRLEN_ROUNDUP_QUANTUM-1)))
+#define PERL_STRLEN_ROUNDUP(n) ((void)(((n) > MEM_SIZE_MAX - 2 * PERL_STRLEN_ROUNDUP_QUANTUM) ? (croak_memory_wrap(),0) : 0), _PERL_STRLEN_ROUNDUP_UNCHECKED(n))
#else
#define MEM_WRAP_CHECK(n,t)
#define MEM_WRAP_CHECK_2(n,t,a,b)
#define MEM_WRAP_CHECK_(n,t)
-#define PERL_STRLEN_ROUNDUP(n) (((n-1+PERL_STRLEN_ROUNDUP_QUANTUM)&~((MEM_SIZE)PERL_STRLEN_ROUNDUP_QUANTUM-1)))
+#define PERL_STRLEN_ROUNDUP(n) _PERL_STRLEN_ROUNDUP_UNCHECKED(n)
#endif
#define Safefree(d) safefree(MEM_LOG_FREE((Malloc_t)(d)))
#endif
+/* assert that a valid ptr has been supplied - use this instead of assert(ptr) *
+ * as it handles cases like constant string arguments without throwing warnings *
+ * the cast is required, as is the inequality check, to avoid warnings */
#define perl_assert_ptr(p) assert( ((void*)(p)) != 0 )