1
0
Fork 0
mirror of https://github.com/yshui/picom.git synced 2024-11-11 13:51:02 -05:00

c2: c2_dump is now c2_condition_to_str

Instead of printing directly to stdout, put the result into a string.
It's more flexible this way.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2024-02-14 00:45:23 +00:00
parent e981a7604a
commit 2119386713
No known key found for this signature in database
GPG key ID: D3A4405BE6CC17F4

153
src/c2.c
View file

@ -341,8 +341,6 @@ static const char *c2h_dump_str_tgt(const c2_l_t *pleaf);
static const char *c2h_dump_str_type(const c2_l_t *pleaf); static const char *c2h_dump_str_type(const c2_l_t *pleaf);
static void attr_unused c2_dump(c2_ptr_t p);
static xcb_atom_t c2_get_atom_type(const c2_l_t *pleaf); static xcb_atom_t c2_get_atom_type(const c2_l_t *pleaf);
static bool c2_match_once(session_t *ps, const struct managed_win *w, const c2_ptr_t cond); static bool c2_match_once(session_t *ps, const struct managed_win *w, const c2_ptr_t cond);
@ -1228,105 +1226,146 @@ static const char *c2h_dump_str_type(const c2_l_t *pleaf) {
} }
/** /**
* Dump a condition tree. * Dump a condition tree to string. Return the number of characters that
* would have been written if the buffer had been large enough, excluding
* the null terminator.
* null terminator will not be written to the output.
*/ */
static void c2_dump(c2_ptr_t p) { static size_t c2_condition_to_str(c2_ptr_t p, char *output, size_t len) {
// For a branch #define push_char(c) \
if (offset < len) \
output[offset] = (c); \
offset++
#define push_str(str) \
do { \
if (offset < len) { \
size_t slen = strlen(str); \
if (offset + slen > len) \
slen = len - offset; \
memcpy(output + offset, str, slen); \
} \
offset += strlen(str); \
} while (false)
size_t offset = 0;
if (p.isbranch) { if (p.isbranch) {
// Branch, i.e. logical operators &&, ||, XOR
const c2_b_t *const pbranch = p.b; const c2_b_t *const pbranch = p.b;
if (!pbranch) { if (!pbranch) {
return; return 0;
} }
if (pbranch->neg) { if (pbranch->neg) {
putchar('!'); push_char('!');
} }
printf("("); push_char('(');
c2_dump(pbranch->opr1); if (len > offset) {
offset += c2_condition_to_str(pbranch->opr1, output + offset,
len - offset);
} else {
offset += c2_condition_to_str(pbranch->opr1, NULL, 0);
}
switch (pbranch->op) { switch (pbranch->op) {
case C2_B_OAND: printf(" && "); break; case C2_B_OAND: push_str(" && "); break;
case C2_B_OOR: printf(" || "); break; case C2_B_OOR: push_str(" || "); break;
case C2_B_OXOR: printf(" XOR "); break; case C2_B_OXOR: push_str(" XOR "); break;
default: assert(0); break; default: assert(0); break;
} }
c2_dump(pbranch->opr2); if (len > offset) {
printf(") "); offset += c2_condition_to_str(pbranch->opr2, output + offset,
len - offset);
} else {
offset += c2_condition_to_str(pbranch->opr2, NULL, 0);
} }
// For a leaf push_str(")");
else { } else {
// Leaf node
const c2_l_t *const pleaf = p.l; const c2_l_t *const pleaf = p.l;
char number[128];
if (!pleaf) { if (!pleaf) {
return; return 0;
} }
if (C2_L_OEXISTS == pleaf->op && pleaf->neg) { if (C2_L_OEXISTS == pleaf->op && pleaf->neg) {
putchar('!'); push_char('!');
} }
// Print target name, type, and format // Print target name, type, and format
{ const char *target_str = c2h_dump_str_tgt(pleaf);
printf("%s", c2h_dump_str_tgt(pleaf)); push_str(target_str);
if (pleaf->tgt_onframe) { if (pleaf->tgt_onframe) {
putchar('@'); push_char('@');
} }
if (pleaf->predef == C2_L_PUNDEFINED) { if (pleaf->predef == C2_L_PUNDEFINED) {
if (pleaf->index < 0) { if (pleaf->index < 0) {
printf("[*]"); push_str("[*]");
} else { } else {
printf("[%d]", pleaf->index); sprintf(number, "[%d]", pleaf->index);
push_str(number);
} }
} }
printf(":%d%s", pleaf->format, c2h_dump_str_type(pleaf));
const char *type_str = c2h_dump_str_type(pleaf);
push_char(':');
sprintf(number, "%d", pleaf->format);
push_str(number);
push_str(type_str);
if (C2_L_OEXISTS == pleaf->op) {
return offset;
} }
// Print operator // Print operator
putchar(' '); push_char(' ');
if (C2_L_OEXISTS != pleaf->op && pleaf->neg) { if (C2_L_OEXISTS != pleaf->op && pleaf->neg) {
putchar('!'); push_char('!');
} }
switch (pleaf->match) { switch (pleaf->match) {
case C2_L_MEXACT: break; case C2_L_MEXACT: break;
case C2_L_MCONTAINS: putchar('*'); break; case C2_L_MCONTAINS: push_char('*'); break;
case C2_L_MSTART: putchar('^'); break; case C2_L_MSTART: push_char('^'); break;
case C2_L_MPCRE: putchar('~'); break; case C2_L_MPCRE: push_char('~'); break;
case C2_L_MWILDCARD: putchar('%'); break; case C2_L_MWILDCARD: push_char('%'); break;
} }
if (pleaf->match_ignorecase) { if (pleaf->match_ignorecase) {
putchar('?'); push_char('?');
} }
switch (pleaf->op) { switch (pleaf->op) {
case C2_L_OEXISTS: break; case C2_L_OEXISTS: break;
case C2_L_OEQ: fputs("=", stdout); break; case C2_L_OEQ: push_str("="); break;
case C2_L_OGT: fputs(">", stdout); break; case C2_L_OGT: push_str(">"); break;
case C2_L_OGTEQ: fputs(">=", stdout); break; case C2_L_OGTEQ: push_str(">="); break;
case C2_L_OLT: fputs("<", stdout); break; case C2_L_OLT: push_str("<"); break;
case C2_L_OLTEQ: fputs("<=", stdout); break; case C2_L_OLTEQ: push_str("<="); break;
}
if (C2_L_OEXISTS == pleaf->op) {
return;
} }
// Print pattern // Print pattern
putchar(' '); push_char(' ');
switch (pleaf->ptntype) { switch (pleaf->ptntype) {
case C2_L_PTINT: printf("%ld", pleaf->ptnint); break; case C2_L_PTINT:
sprintf(number, "%ld", pleaf->ptnint);
push_str(number);
break;
case C2_L_PTSTRING: case C2_L_PTSTRING:
// TODO(yshui) Escape string before printing out? // TODO(yshui) Escape string before printing out?
printf("\"%s\"", pleaf->ptnstr); push_char('"');
push_str(pleaf->ptnstr);
push_char('"');
break; break;
default: assert(0); break; default: assert(0); break;
} }
} }
#undef push_char
#undef push_str
return offset;
} }
/** /**
@ -1622,6 +1661,7 @@ c2_match_once_leaf(session_t *ps, const struct managed_win *w, const c2_l_t *lea
*/ */
static bool c2_match_once(session_t *ps, const struct managed_win *w, const c2_ptr_t cond) { static bool c2_match_once(session_t *ps, const struct managed_win *w, const c2_ptr_t cond) {
bool result = false; bool result = false;
char condition_str[1024];
if (cond.isbranch) { if (cond.isbranch) {
// Handle a branch (and/or/xor operation) // Handle a branch (and/or/xor operation)
@ -1650,11 +1690,13 @@ static bool c2_match_once(session_t *ps, const struct managed_win *w, const c2_p
return false; return false;
} }
#ifdef DEBUG_WINMATCH if (unlikely(log_get_level_tls() <= LOG_LEVEL_TRACE)) {
log_trace("(%#010x): branch: result = %d, pattern = ", w->base.id, result); size_t len =
c2_dump(cond); c2_condition_to_str(cond, condition_str, sizeof(condition_str));
putchar('\n'); len = min2(len, sizeof(condition_str));
#endif log_debug("(%#010x): branch: result = %d, pattern = %.*s",
w->base.id, result, (int)len, condition_str);
}
} else { } else {
// A leaf // A leaf
const c2_l_t *pleaf = cond.l; const c2_l_t *pleaf = cond.l;
@ -1665,13 +1707,14 @@ static bool c2_match_once(session_t *ps, const struct managed_win *w, const c2_p
result = c2_match_once_leaf(ps, w, pleaf); result = c2_match_once_leaf(ps, w, pleaf);
#ifdef DEBUG_WINMATCH if (unlikely(log_get_level_tls() <= LOG_LEVEL_TRACE)) {
log_trace("(%#010x): leaf: result = %d, error = %d, " size_t len =
"client = %#010x, pattern = ", c2_condition_to_str(cond, condition_str, sizeof(condition_str));
w->base.id, result, error, w->client_win); len = min2(len, sizeof(condition_str));
c2_dump(cond); log_debug("(%#010x): leaf: result = %d, client = %#010x, "
putchar('\n'); "pattern = %.*s",
#endif w->base.id, result, w->client_win, (int)len, condition_str);
}
} }
// Postprocess the result // Postprocess the result