diff options
author | Karl Williamson <public@khwilliamson.com> | 2012-08-23 10:36:13 -0600 |
---|---|---|
committer | Karl Williamson <public@khwilliamson.com> | 2012-08-25 23:21:28 -0600 |
commit | 9e7f4f43739b2597e193f775558f39082b8a213f (patch) | |
tree | 3b9886d4f1e2997ed91984312c3992395ea7569f /inline_invlist.c | |
parent | 29f51c6b1e5614efba92db8b7bc3957bbb9b7942 (diff) | |
download | perl-9e7f4f43739b2597e193f775558f39082b8a213f.tar.gz |
regcomp.c: Move functions to inline_invlist.c
This populates inline_invlist.c with some static inline functions and
macro defines. These are the ones that are anticipated to be needed in
the near term outside regcomp.c
Diffstat (limited to 'inline_invlist.c')
-rw-r--r-- | inline_invlist.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/inline_invlist.c b/inline_invlist.c index de6738ff43..80a6898e42 100644 --- a/inline_invlist.c +++ b/inline_invlist.c @@ -13,4 +13,68 @@ #if defined(PERL_IN_UTF8_C) || defined(PERL_IN_REGCOMP_C) || defined(PERL_IN_REGEXEC_C) +#define INVLIST_LEN_OFFSET 0 /* Number of elements in the inversion list */ +#define INVLIST_ITER_OFFSET 1 /* Current iteration position */ + +/* This is a combination of a version and data structure type, so that one + * being passed in can be validated to be an inversion list of the correct + * vintage. When the structure of the header is changed, a new random number + * in the range 2**31-1 should be generated and the new() method changed to + * insert that at this location. Then, if an auxiliary program doesn't change + * correspondingly, it will be discovered immediately */ +#define INVLIST_VERSION_ID_OFFSET 2 +#define INVLIST_VERSION_ID 1064334010 + +/* For safety, when adding new elements, remember to #undef them at the end of + * the inversion list code section */ + +#define INVLIST_ZERO_OFFSET 3 /* 0 or 1; must be last element in header */ +/* The UV at position ZERO contains either 0 or 1. If 0, the inversion list + * contains the code point U+00000, and begins here. If 1, the inversion list + * doesn't contain U+0000, and it begins at the next UV in the array. + * Inverting an inversion list consists of adding or removing the 0 at the + * beginning of it. By reserving a space for that 0, inversion can be made + * very fast */ + +#define HEADER_LENGTH (INVLIST_ZERO_OFFSET + 1) + +/* An element is in an inversion list iff its index is even numbered: 0, 2, 4, + * etc */ +#define ELEMENT_RANGE_MATCHES_INVLIST(i) (! ((i) & 1)) +#define PREV_RANGE_MATCHES_INVLIST(i) (! ELEMENT_RANGE_MATCHES_INVLIST(i)) + +PERL_STATIC_INLINE UV* +S__get_invlist_len_addr(pTHX_ SV* invlist) +{ + /* Return the address of the UV that contains the current number + * of used elements in the inversion list */ + + PERL_ARGS_ASSERT__GET_INVLIST_LEN_ADDR; + + return (UV *) (SvPVX(invlist) + (INVLIST_LEN_OFFSET * sizeof (UV))); +} + +PERL_STATIC_INLINE UV +S__invlist_len(pTHX_ SV* const invlist) +{ + /* Returns the current number of elements stored in the inversion list's + * array */ + + PERL_ARGS_ASSERT__INVLIST_LEN; + + return *_get_invlist_len_addr(invlist); +} + +PERL_STATIC_INLINE bool +S__invlist_contains_cp(pTHX_ SV* const invlist, const UV cp) +{ + /* Does <invlist> contain code point <cp> as part of the set? */ + + IV index = _invlist_search(invlist, cp); + + PERL_ARGS_ASSERT__INVLIST_CONTAINS_CP; + + return index >= 0 && ELEMENT_RANGE_MATCHES_INVLIST(index); +} + #endif |