Skip to content

Commit

Permalink
Add 'ASSERT_IS_LITERAL' macro
Browse files Browse the repository at this point in the history
This is intended to make it obvious what this relatively obscure C
construct is doing.
  • Loading branch information
khwilliamson authored and demerphq committed Mar 3, 2022
1 parent 198c4f1 commit ca0572d
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 17 deletions.
22 changes: 12 additions & 10 deletions handy.h
Expand Up @@ -419,6 +419,8 @@ a string/length pair.
=cut
*/

#define ASSERT_IS_LITERAL(s) ("" s "")

/*
=for apidoc_section $string
Expand All @@ -433,7 +435,7 @@ Perl_xxx(aTHX_ ...) form for any API calls where it's used.
=cut
*/

#define STR_WITH_LEN(s) ("" s ""), (sizeof(s)-1)
#define STR_WITH_LEN(s) ASSERT_IS_LITERAL(s), (sizeof(s)-1)

/* STR_WITH_LEN() shortcuts */
#define newSVpvs(str) Perl_newSVpvn(aTHX_ STR_WITH_LEN(str))
Expand Down Expand Up @@ -694,34 +696,34 @@ based on the underlying C library functions):

/* memEQ and memNE where second comparand is a string constant */
#define memEQs(s1, l, s2) \
(((sizeof(s2)-1) == (l)) && memEQ((s1), ("" s2 ""), (sizeof(s2)-1)))
(((sizeof(s2)-1) == (l)) && memEQ((s1), ASSERT_IS_LITERAL(s2), (sizeof(s2)-1)))
#define memNEs(s1, l, s2) (! memEQs(s1, l, s2))

/* Keep these private until we decide it was a good idea */
#if defined(PERL_CORE) || defined(PERL_EXT) || defined(PERL_EXT_POSIX)

#define strBEGINs(s1,s2) (strncmp(s1,"" s2 "", sizeof(s2)-1) == 0)
#define strBEGINs(s1,s2) (strncmp(s1,ASSERT_IS_LITERAL(s2), sizeof(s2)-1) == 0)

#define memBEGINs(s1, l, s2) \
( (Ptrdiff_t) (l) >= (Ptrdiff_t) sizeof(s2) - 1 \
&& memEQ(s1, "" s2 "", sizeof(s2)-1))
&& memEQ(s1, ASSERT_IS_LITERAL(s2), sizeof(s2)-1))
#define memBEGINPs(s1, l, s2) \
( (Ptrdiff_t) (l) > (Ptrdiff_t) sizeof(s2) - 1 \
&& memEQ(s1, "" s2 "", sizeof(s2)-1))
&& memEQ(s1, ASSERT_IS_LITERAL(s2), sizeof(s2)-1))
#define memENDs(s1, l, s2) \
( (Ptrdiff_t) (l) >= (Ptrdiff_t) sizeof(s2) - 1 \
&& memEQ(s1 + (l) - (sizeof(s2) - 1), "" s2 "", sizeof(s2)-1))
&& memEQ(s1 + (l) - (sizeof(s2) - 1), ASSERT_IS_LITERAL(s2), sizeof(s2)-1))
#define memENDPs(s1, l, s2) \
( (Ptrdiff_t) (l) > (Ptrdiff_t) sizeof(s2) \
&& memEQ(s1 + (l) - (sizeof(s2) - 1), "" s2 "", sizeof(s2)-1))
&& memEQ(s1 + (l) - (sizeof(s2) - 1), ASSERT_IS_LITERAL(s2), sizeof(s2)-1))
#endif /* End of making macros private */

#define memLT(s1,s2,l) (memcmp(s1,s2,l) < 0)
#define memLE(s1,s2,l) (memcmp(s1,s2,l) <= 0)
#define memGT(s1,s2,l) (memcmp(s1,s2,l) > 0)
#define memGE(s1,s2,l) (memcmp(s1,s2,l) >= 0)

#define memCHRs(s1,c) ((const char *) memchr("" s1 "" , c, sizeof(s1)-1))
#define memCHRs(s1,c) ((const char *) memchr(ASSERT_IS_LITERAL(s1) , c, sizeof(s1)-1))

/*
* Character classes.
Expand Down Expand Up @@ -2667,8 +2669,8 @@ PoisonWith(0xEF) for catching access to freed memory.

/* "a" arg must be a string literal */
# define MEM_WRAP_CHECK_s(n,t,a) \
(void)(UNLIKELY(_MEM_WRAP_WILL_WRAP(n,t)) \
&& (Perl_croak_nocontext("" a ""),0))
( (void) (UNLIKELY(_MEM_WRAP_WILL_WRAP(n,t)) \
&& (Perl_croak_nocontext(ASSERT_IS_LITERAL(a)), 0)))

#define MEM_WRAP_CHECK_(n,t) MEM_WRAP_CHECK(n,t),

Expand Down
10 changes: 5 additions & 5 deletions hv.h
Expand Up @@ -498,19 +498,19 @@ See L</hv_fill>.
* chars). See STR_WITH_LEN in handy.h - because these are macros we cant use
* STR_WITH_LEN to do the work, we have to unroll it. */
#define hv_existss(hv, key) \
hv_exists((hv), ("" key ""), (sizeof(key)-1))
hv_exists((hv), ASSERT_IS_LITERAL(key), (sizeof(key)-1))

#define hv_fetchs(hv, key, lval) \
hv_fetch((hv), ("" key ""), (sizeof(key)-1), (lval))
hv_fetch((hv), ASSERT_IS_LITERAL(key), (sizeof(key)-1), (lval))

#define hv_deletes(hv, key, flags) \
hv_delete((hv), ("" key ""), (sizeof(key)-1), (flags))
hv_delete((hv), ASSERT_IS_LITERAL(key), (sizeof(key)-1), (flags))

#define hv_name_sets(hv, name, flags) \
hv_name_set((hv),("" name ""),(sizeof(name)-1), flags)
hv_name_set((hv),ASSERT_IS_LITERAL(name),(sizeof(name)-1), flags)

#define hv_stores(hv, key, val) \
hv_store((hv), ("" key ""), (sizeof(key)-1), (val), 0)
hv_store((hv), ASSERT_IS_LITERAL(key), (sizeof(key)-1), (val), 0)

#ifdef PERL_CORE
# define hv_storehek(hv, hek, val) \
Expand Down
4 changes: 2 additions & 2 deletions scope.h
Expand Up @@ -201,7 +201,7 @@ scope has the given name. C<name> must be a literal string.
STMT_START { \
push_scope(); \
if (PL_scopestack_name) \
PL_scopestack_name[PL_scopestack_ix-1] = name; \
PL_scopestack_name[PL_scopestack_ix-1] = ASSERT_IS_LITERAL(name);\
DEBUG_SCOPE("ENTER \"" name "\"") \
} STMT_END
#define LEAVE_with_name(name) \
Expand All @@ -210,7 +210,7 @@ scope has the given name. C<name> must be a literal string.
if (PL_scopestack_name) { \
CLANG_DIAG_IGNORE_STMT(-Wstring-compare); \
assert(((char*)PL_scopestack_name[PL_scopestack_ix-1] \
== (char*)name) \
== (char*)ASSERT_IS_LITERAL(name)) \
|| strEQ(PL_scopestack_name[PL_scopestack_ix-1], name)); \
CLANG_DIAG_RESTORE_STMT; \
} \
Expand Down

0 comments on commit ca0572d

Please sign in to comment.