1
0
Fork 0
mirror of https://github.com/yshui/picom.git synced 2024-12-09 14:18:57 -05:00

c2: replace pcre with pcre2

Because pcre has been deprecated.[1]

There are subtle changes from pcre to pcre2, so this could be a breaking
change.

Closes #895

[1]: https://www.pcre.org/original/changelog.txt

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2022-11-22 16:12:36 +00:00
parent 2d35f78dc3
commit e2b8c3fd1e
No known key found for this signature in database
GPG key ID: D3A4405BE6CC17F4
2 changed files with 79 additions and 81 deletions

155
src/c2.c
View file

@ -17,15 +17,8 @@
// libpcre // libpcre
#ifdef CONFIG_REGEX_PCRE #ifdef CONFIG_REGEX_PCRE
#include <pcre.h> #define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>
// For compatibility with <libpcre-8.20
#ifndef PCRE_STUDY_JIT_COMPILE
#define PCRE_STUDY_JIT_COMPILE 0
#define LPCRE_FREE_STUDY(extra) pcre_free(extra)
#else
#define LPCRE_FREE_STUDY(extra) pcre_free_study(extra)
#endif
#endif #endif
@ -89,49 +82,52 @@ struct _c2_b {
/// Structure for leaf element in a window condition /// Structure for leaf element in a window condition
struct _c2_l { struct _c2_l {
bool neg : 1; bool neg : 1;
enum { C2_L_OEXISTS, enum {
C2_L_OEQ, C2_L_OEXISTS,
C2_L_OGT, C2_L_OEQ,
C2_L_OGTEQ, C2_L_OGT,
C2_L_OLT, C2_L_OGTEQ,
C2_L_OLTEQ, C2_L_OLT,
C2_L_OLTEQ,
} op : 3; } op : 3;
enum { C2_L_MEXACT, enum {
C2_L_MSTART, C2_L_MEXACT,
C2_L_MCONTAINS, C2_L_MSTART,
C2_L_MWILDCARD, C2_L_MCONTAINS,
C2_L_MPCRE, C2_L_MWILDCARD,
C2_L_MPCRE,
} match : 3; } match : 3;
bool match_ignorecase : 1; bool match_ignorecase : 1;
char *tgt; char *tgt;
xcb_atom_t tgtatom; xcb_atom_t tgtatom;
bool tgt_onframe; bool tgt_onframe;
int index; int index;
enum { C2_L_PUNDEFINED = -1, enum {
C2_L_PID = 0, C2_L_PUNDEFINED = -1,
C2_L_PX, C2_L_PID = 0,
C2_L_PY, C2_L_PX,
C2_L_PX2, C2_L_PY,
C2_L_PY2, C2_L_PX2,
C2_L_PWIDTH, C2_L_PY2,
C2_L_PHEIGHT, C2_L_PWIDTH,
C2_L_PWIDTHB, C2_L_PHEIGHT,
C2_L_PHEIGHTB, C2_L_PWIDTHB,
C2_L_PBDW, C2_L_PHEIGHTB,
C2_L_PFULLSCREEN, C2_L_PBDW,
C2_L_POVREDIR, C2_L_PFULLSCREEN,
C2_L_PARGB, C2_L_POVREDIR,
C2_L_PFOCUSED, C2_L_PARGB,
C2_L_PWMWIN, C2_L_PFOCUSED,
C2_L_PBSHAPED, C2_L_PWMWIN,
C2_L_PROUNDED, C2_L_PBSHAPED,
C2_L_PCLIENT, C2_L_PROUNDED,
C2_L_PWINDOWTYPE, C2_L_PCLIENT,
C2_L_PLEADER, C2_L_PWINDOWTYPE,
C2_L_PNAME, C2_L_PLEADER,
C2_L_PCLASSG, C2_L_PNAME,
C2_L_PCLASSI, C2_L_PCLASSG,
C2_L_PROLE, C2_L_PCLASSI,
C2_L_PROLE,
} predef; } predef;
enum c2_l_type { enum c2_l_type {
C2_L_TUNDEFINED, C2_L_TUNDEFINED,
@ -142,15 +138,16 @@ struct _c2_l {
C2_L_TDRAWABLE, C2_L_TDRAWABLE,
} type; } type;
int format; int format;
enum { C2_L_PTUNDEFINED, enum {
C2_L_PTSTRING, C2_L_PTUNDEFINED,
C2_L_PTINT, C2_L_PTSTRING,
C2_L_PTINT,
} ptntype; } ptntype;
char *ptnstr; char *ptnstr;
long ptnint; long ptnint;
#ifdef CONFIG_REGEX_PCRE #ifdef CONFIG_REGEX_PCRE
pcre *regex_pcre; pcre2_code *regex_pcre;
pcre_extra *regex_pcre_extra; pcre2_match_data *regex_pcre_match;
#endif #endif
}; };
@ -1059,32 +1056,31 @@ static bool c2_l_postprocess(session_t *ps, c2_l_t *pleaf) {
// PCRE patterns // PCRE patterns
if (C2_L_PTSTRING == pleaf->ptntype && C2_L_MPCRE == pleaf->match) { if (C2_L_PTSTRING == pleaf->ptntype && C2_L_MPCRE == pleaf->match) {
#ifdef CONFIG_REGEX_PCRE #ifdef CONFIG_REGEX_PCRE
const char *error = NULL; int errorcode = 0;
int erroffset = 0; PCRE2_SIZE erroffset = 0;
int options = 0; unsigned int options = 0;
// Ignore case flag // Ignore case flag
if (pleaf->match_ignorecase) if (pleaf->match_ignorecase) {
options |= PCRE_CASELESS; options |= PCRE2_CASELESS;
}
// Compile PCRE expression // Compile PCRE expression
pleaf->regex_pcre = pleaf->regex_pcre =
pcre_compile(pleaf->ptnstr, options, &error, &erroffset, NULL); pcre2_compile((PCRE2_SPTR)pleaf->ptnstr, PCRE2_ZERO_TERMINATED,
if (!pleaf->regex_pcre) { options, &errorcode, &erroffset, NULL);
log_error("Pattern \"%s\": PCRE regular expression parsing " if (pleaf->regex_pcre == NULL) {
PCRE2_UCHAR buffer[256];
pcre2_get_error_message(errorcode, buffer, sizeof(buffer));
log_error("Pattern \"%s\": PCRE regular expression "
"parsing "
"failed on " "failed on "
"offset %d: %s", "offset %zu: %s",
pleaf->ptnstr, erroffset, error); pleaf->ptnstr, erroffset, buffer);
return false; return false;
} }
#ifdef CONFIG_REGEX_PCRE_JIT pleaf->regex_pcre_match =
pleaf->regex_pcre_extra = pcre2_match_data_create_from_pattern(pleaf->regex_pcre, NULL);
pcre_study(pleaf->regex_pcre, PCRE_STUDY_JIT_COMPILE, &error);
if (!pleaf->regex_pcre_extra) {
printf("Pattern \"%s\": PCRE regular expression study failed: %s",
pleaf->ptnstr, error);
}
#endif
// Free the target string // Free the target string
// free(pleaf->tgt); // free(pleaf->tgt);
@ -1102,16 +1098,18 @@ static bool c2_tree_postprocess(session_t *ps, c2_ptr_t node) {
if (!node.isbranch) { if (!node.isbranch) {
return c2_l_postprocess(ps, node.l); return c2_l_postprocess(ps, node.l);
} }
if (!c2_tree_postprocess(ps, node.b->opr1)) if (!c2_tree_postprocess(ps, node.b->opr1)) {
return false; return false;
}
return c2_tree_postprocess(ps, node.b->opr2); return c2_tree_postprocess(ps, node.b->opr2);
} }
bool c2_list_postprocess(session_t *ps, c2_lptr_t *list) { bool c2_list_postprocess(session_t *ps, c2_lptr_t *list) {
c2_lptr_t *head = list; c2_lptr_t *head = list;
while (head) { while (head) {
if (!c2_tree_postprocess(ps, head->ptr)) if (!c2_tree_postprocess(ps, head->ptr)) {
return false; return false;
}
head = head->next; head = head->next;
} }
return true; return true;
@ -1124,8 +1122,9 @@ static void c2_free(c2_ptr_t p) {
if (p.isbranch) { if (p.isbranch) {
c2_b_t *const pbranch = p.b; c2_b_t *const pbranch = p.b;
if (!pbranch) if (!pbranch) {
return; return;
}
c2_free(pbranch->opr1); c2_free(pbranch->opr1);
c2_free(pbranch->opr2); c2_free(pbranch->opr2);
@ -1135,14 +1134,15 @@ static void c2_free(c2_ptr_t p) {
else { else {
c2_l_t *const pleaf = p.l; c2_l_t *const pleaf = p.l;
if (!pleaf) if (!pleaf) {
return; return;
}
free(pleaf->tgt); free(pleaf->tgt);
free(pleaf->ptnstr); free(pleaf->ptnstr);
#ifdef CONFIG_REGEX_PCRE #ifdef CONFIG_REGEX_PCRE
pcre_free(pleaf->regex_pcre); pcre2_code_free(pleaf->regex_pcre);
LPCRE_FREE_STUDY(pleaf->regex_pcre_extra); pcre2_match_data_free(pleaf->regex_pcre_match);
#endif #endif
free(pleaf); free(pleaf);
} }
@ -1550,9 +1550,10 @@ static inline void c2_match_once_leaf(session_t *ps, const struct managed_win *w
case C2_L_MPCRE: case C2_L_MPCRE:
#ifdef CONFIG_REGEX_PCRE #ifdef CONFIG_REGEX_PCRE
assert(strlen(tgt) <= INT_MAX); assert(strlen(tgt) <= INT_MAX);
res = (pcre_exec(pleaf->regex_pcre, assert(pleaf->regex_pcre);
pleaf->regex_pcre_extra, tgt, res = (pcre2_match(pleaf->regex_pcre, (PCRE2_SPTR)tgt,
(int)strlen(tgt), 0, 0, NULL, 0) >= 0); strlen(tgt), 0, 0,
pleaf->regex_pcre_match, NULL) > 0);
#else #else
assert(0); assert(0);
#endif #endif

View file

@ -44,11 +44,8 @@ if get_option('config_file')
srcs += [ 'config_libconfig.c' ] srcs += [ 'config_libconfig.c' ]
endif endif
if get_option('regex') if get_option('regex')
pcre = dependency('libpcre', required: true) pcre = dependency('libpcre2-8', required: true)
cflags += ['-DCONFIG_REGEX_PCRE'] cflags += ['-DCONFIG_REGEX_PCRE']
if pcre.version().version_compare('>=8.20')
cflags += ['-DCONFIG_REGEX_PCRE_JIT']
endif
deps += [pcre] deps += [pcre]
endif endif