c2.h cleanup
Move most of the static functions into c2.c itself, and only keep the public functions in c2.h
This commit is contained in:
parent
e875f7566f
commit
4940a93f03
343
src/c2.c
343
src/c2.c
|
@ -8,8 +8,351 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <fnmatch.h>
|
||||
#include <ctype.h>
|
||||
|
||||
// libpcre
|
||||
#ifdef CONFIG_REGEX_PCRE
|
||||
#include <pcre.h>
|
||||
|
||||
// For compatiblity 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
|
||||
|
||||
#include "common.h"
|
||||
#include "c2.h"
|
||||
|
||||
#define C2_MAX_LEVELS 10
|
||||
|
||||
typedef struct _c2_b c2_b_t;
|
||||
typedef struct _c2_l c2_l_t;
|
||||
|
||||
/// Pointer to a condition tree.
|
||||
typedef struct {
|
||||
bool isbranch : 1;
|
||||
union {
|
||||
c2_b_t *b;
|
||||
c2_l_t *l;
|
||||
};
|
||||
} c2_ptr_t;
|
||||
|
||||
/// Initializer for c2_ptr_t.
|
||||
#define C2_PTR_INIT { \
|
||||
.isbranch = false, \
|
||||
.l = NULL, \
|
||||
}
|
||||
|
||||
const static c2_ptr_t C2_PTR_NULL = C2_PTR_INIT;
|
||||
|
||||
/// Operator of a branch element.
|
||||
typedef enum {
|
||||
C2_B_OUNDEFINED,
|
||||
C2_B_OAND,
|
||||
C2_B_OOR,
|
||||
C2_B_OXOR,
|
||||
} c2_b_op_t;
|
||||
|
||||
/// Structure for branch element in a window condition
|
||||
struct _c2_b {
|
||||
bool neg : 1;
|
||||
c2_b_op_t op;
|
||||
c2_ptr_t opr1;
|
||||
c2_ptr_t opr2;
|
||||
};
|
||||
|
||||
/// Initializer for c2_b_t.
|
||||
#define C2_B_INIT { \
|
||||
.neg = false, \
|
||||
.op = C2_B_OUNDEFINED, \
|
||||
.opr1 = C2_PTR_INIT, \
|
||||
.opr2 = C2_PTR_INIT, \
|
||||
}
|
||||
|
||||
/// Structure for leaf element in a window condition
|
||||
struct _c2_l {
|
||||
bool neg : 1;
|
||||
enum {
|
||||
C2_L_OEXISTS,
|
||||
C2_L_OEQ,
|
||||
C2_L_OGT,
|
||||
C2_L_OGTEQ,
|
||||
C2_L_OLT,
|
||||
C2_L_OLTEQ,
|
||||
} op : 3;
|
||||
enum {
|
||||
C2_L_MEXACT,
|
||||
C2_L_MSTART,
|
||||
C2_L_MCONTAINS,
|
||||
C2_L_MWILDCARD,
|
||||
C2_L_MPCRE,
|
||||
} match : 3;
|
||||
bool match_ignorecase : 1;
|
||||
char *tgt;
|
||||
Atom tgtatom;
|
||||
bool tgt_onframe;
|
||||
int index;
|
||||
enum {
|
||||
C2_L_PUNDEFINED,
|
||||
C2_L_PID,
|
||||
C2_L_PX,
|
||||
C2_L_PY,
|
||||
C2_L_PX2,
|
||||
C2_L_PY2,
|
||||
C2_L_PWIDTH,
|
||||
C2_L_PHEIGHT,
|
||||
C2_L_PWIDTHB,
|
||||
C2_L_PHEIGHTB,
|
||||
C2_L_PBDW,
|
||||
C2_L_PFULLSCREEN,
|
||||
C2_L_POVREDIR,
|
||||
C2_L_PARGB,
|
||||
C2_L_PFOCUSED,
|
||||
C2_L_PWMWIN,
|
||||
C2_L_PBSHAPED,
|
||||
C2_L_PROUNDED,
|
||||
C2_L_PCLIENT,
|
||||
C2_L_PWINDOWTYPE,
|
||||
C2_L_PLEADER,
|
||||
C2_L_PNAME,
|
||||
C2_L_PCLASSG,
|
||||
C2_L_PCLASSI,
|
||||
C2_L_PROLE,
|
||||
} predef;
|
||||
enum c2_l_type {
|
||||
C2_L_TUNDEFINED,
|
||||
C2_L_TSTRING,
|
||||
C2_L_TCARDINAL,
|
||||
C2_L_TWINDOW,
|
||||
C2_L_TATOM,
|
||||
C2_L_TDRAWABLE,
|
||||
} type;
|
||||
int format;
|
||||
enum {
|
||||
C2_L_PTUNDEFINED,
|
||||
C2_L_PTSTRING,
|
||||
C2_L_PTINT,
|
||||
} ptntype;
|
||||
char *ptnstr;
|
||||
long ptnint;
|
||||
#ifdef CONFIG_REGEX_PCRE
|
||||
pcre *regex_pcre;
|
||||
pcre_extra *regex_pcre_extra;
|
||||
#endif
|
||||
};
|
||||
|
||||
/// Initializer for c2_l_t.
|
||||
#define C2_L_INIT { \
|
||||
.neg = false, \
|
||||
.op = C2_L_OEXISTS, \
|
||||
.match = C2_L_MEXACT, \
|
||||
.match_ignorecase = false, \
|
||||
.tgt = NULL, \
|
||||
.tgtatom = 0, \
|
||||
.tgt_onframe = false, \
|
||||
.predef = C2_L_PUNDEFINED, \
|
||||
.index = -1, \
|
||||
.type = C2_L_TUNDEFINED, \
|
||||
.format = 0, \
|
||||
.ptntype = C2_L_PTUNDEFINED, \
|
||||
.ptnstr = NULL, \
|
||||
.ptnint = 0, \
|
||||
}
|
||||
|
||||
const static c2_l_t leaf_def = C2_L_INIT;
|
||||
|
||||
/// Linked list type of conditions.
|
||||
struct _c2_lptr {
|
||||
c2_ptr_t ptr;
|
||||
void *data;
|
||||
struct _c2_lptr *next;
|
||||
};
|
||||
|
||||
/// Initializer for c2_lptr_t.
|
||||
#define C2_LPTR_INIT { \
|
||||
.ptr = C2_PTR_INIT, \
|
||||
.data = NULL, \
|
||||
.next = NULL, \
|
||||
}
|
||||
|
||||
/// Structure representing a predefined target.
|
||||
typedef struct {
|
||||
const char *name;
|
||||
enum c2_l_type type;
|
||||
int format;
|
||||
} c2_predef_t;
|
||||
|
||||
// Predefined targets.
|
||||
const static c2_predef_t C2_PREDEFS[] = {
|
||||
[C2_L_PID ] = { "id" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PX ] = { "x" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PY ] = { "y" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PX2 ] = { "x2" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PY2 ] = { "y2" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PWIDTH ] = { "width" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PHEIGHT ] = { "height" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PWIDTHB ] = { "widthb" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PHEIGHTB ] = { "heightb" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PBDW ] = { "border_width" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PFULLSCREEN ] = { "fullscreen" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_POVREDIR ] = { "override_redirect" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PARGB ] = { "argb" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PFOCUSED ] = { "focused" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PWMWIN ] = { "wmwin" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PBSHAPED ] = { "bounding_shaped" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PROUNDED ] = { "rounded_corners" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PCLIENT ] = { "client" , C2_L_TWINDOW , 0 },
|
||||
[C2_L_PWINDOWTYPE ] = { "window_type" , C2_L_TSTRING , 0 },
|
||||
[C2_L_PLEADER ] = { "leader" , C2_L_TWINDOW , 0 },
|
||||
[C2_L_PNAME ] = { "name" , C2_L_TSTRING , 0 },
|
||||
[C2_L_PCLASSG ] = { "class_g" , C2_L_TSTRING , 0 },
|
||||
[C2_L_PCLASSI ] = { "class_i" , C2_L_TSTRING , 0 },
|
||||
[C2_L_PROLE ] = { "role" , C2_L_TSTRING , 0 },
|
||||
};
|
||||
|
||||
#define mstrncmp(s1, s2) strncmp((s1), (s2), strlen(s1))
|
||||
|
||||
/**
|
||||
* Compare next word in a string with another string.
|
||||
*/
|
||||
static inline int
|
||||
strcmp_wd(const char *needle, const char *src) {
|
||||
int ret = mstrncmp(needle, src);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
char c = src[strlen(needle)];
|
||||
if (isalnum(c) || '_' == c)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether a c2_ptr_t is empty.
|
||||
*/
|
||||
static inline bool
|
||||
c2_ptr_isempty(const c2_ptr_t p) {
|
||||
return !(p.isbranch ? (bool) p.b: (bool) p.l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset a c2_ptr_t.
|
||||
*/
|
||||
static inline void
|
||||
c2_ptr_reset(c2_ptr_t *pp) {
|
||||
if (pp)
|
||||
memcpy(pp, &C2_PTR_NULL, sizeof(c2_ptr_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine two condition trees.
|
||||
*/
|
||||
static inline c2_ptr_t
|
||||
c2h_comb_tree(c2_b_op_t op, c2_ptr_t p1, c2_ptr_t p2) {
|
||||
c2_ptr_t p = {
|
||||
.isbranch = true,
|
||||
.b = malloc(sizeof(c2_b_t))
|
||||
};
|
||||
|
||||
p.b->opr1 = p1;
|
||||
p.b->opr2 = p2;
|
||||
p.b->op = op;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the precedence value of a condition branch operator.
|
||||
*/
|
||||
static inline int
|
||||
c2h_b_opp(c2_b_op_t op) {
|
||||
switch (op) {
|
||||
case C2_B_OAND: return 2;
|
||||
case C2_B_OOR: return 1;
|
||||
case C2_B_OXOR: return 1;
|
||||
default: break;
|
||||
}
|
||||
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare precedence of two condition branch operators.
|
||||
*
|
||||
* Associativity is left-to-right, forever.
|
||||
*
|
||||
* @return positive number if op1 > op2, 0 if op1 == op2 in precedence,
|
||||
* negative number otherwise
|
||||
*/
|
||||
static inline int
|
||||
c2h_b_opcmp(c2_b_op_t op1, c2_b_op_t op2) {
|
||||
return c2h_b_opp(op1) - c2h_b_opp(op2);
|
||||
}
|
||||
|
||||
static int
|
||||
c2_parse_grp(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult, int level);
|
||||
|
||||
static int
|
||||
c2_parse_target(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult);
|
||||
|
||||
static int
|
||||
c2_parse_op(const char *pattern, int offset, c2_ptr_t *presult);
|
||||
|
||||
static int
|
||||
c2_parse_pattern(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult);
|
||||
|
||||
static int
|
||||
c2_parse_legacy(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult);
|
||||
|
||||
static bool
|
||||
c2_l_postprocess(session_t *ps, c2_l_t *pleaf);
|
||||
|
||||
static void
|
||||
c2_free(c2_ptr_t p);
|
||||
|
||||
/**
|
||||
* Wrapper of c2_free().
|
||||
*/
|
||||
static inline void
|
||||
c2_freep(c2_ptr_t *pp) {
|
||||
if (pp) {
|
||||
c2_free(*pp);
|
||||
c2_ptr_reset(pp);
|
||||
}
|
||||
}
|
||||
|
||||
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 void
|
||||
c2_dump_raw(c2_ptr_t p);
|
||||
|
||||
/**
|
||||
* Wrapper of c2_dump_raw().
|
||||
*/
|
||||
static inline void __attribute__((unused))
|
||||
c2_dump(c2_ptr_t p) {
|
||||
c2_dump_raw(p);
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
static Atom
|
||||
c2_get_atom_type(const c2_l_t *pleaf);
|
||||
|
||||
static bool
|
||||
c2_match_once(session_t *ps, win *w, const c2_ptr_t cond);
|
||||
|
||||
/**
|
||||
* Parse a condition string.
|
||||
*/
|
||||
|
|
353
src/c2.h
353
src/c2.h
|
@ -8,347 +8,26 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#pragma once
|
||||
|
||||
#include <fnmatch.h>
|
||||
#include <ctype.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// libpcre
|
||||
#ifdef CONFIG_REGEX_PCRE
|
||||
#include <pcre.h>
|
||||
typedef struct _c2_lptr c2_lptr_t;
|
||||
typedef struct session session_t;
|
||||
typedef struct win win;
|
||||
|
||||
// For compatiblity 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
|
||||
c2_lptr_t *
|
||||
c2_parsed(session_t *ps, c2_lptr_t **pcondlst, const char *pattern,
|
||||
void *data);
|
||||
|
||||
#endif
|
||||
#define c2_parse(ps, pcondlst, pattern) c2_parsed((ps), (pcondlst), (pattern), NULL)
|
||||
|
||||
#define C2_MAX_LEVELS 10
|
||||
c2_lptr_t *
|
||||
c2_free_lptr(c2_lptr_t *lp);
|
||||
|
||||
typedef struct _c2_b c2_b_t;
|
||||
typedef struct _c2_l c2_l_t;
|
||||
|
||||
/// Pointer to a condition tree.
|
||||
typedef struct {
|
||||
bool isbranch : 1;
|
||||
union {
|
||||
c2_b_t *b;
|
||||
c2_l_t *l;
|
||||
};
|
||||
} c2_ptr_t;
|
||||
|
||||
/// Initializer for c2_ptr_t.
|
||||
#define C2_PTR_INIT { \
|
||||
.isbranch = false, \
|
||||
.l = NULL, \
|
||||
}
|
||||
|
||||
const static c2_ptr_t C2_PTR_NULL = C2_PTR_INIT;
|
||||
|
||||
/// Operator of a branch element.
|
||||
typedef enum {
|
||||
C2_B_OUNDEFINED,
|
||||
C2_B_OAND,
|
||||
C2_B_OOR,
|
||||
C2_B_OXOR,
|
||||
} c2_b_op_t;
|
||||
|
||||
/// Structure for branch element in a window condition
|
||||
struct _c2_b {
|
||||
bool neg : 1;
|
||||
c2_b_op_t op;
|
||||
c2_ptr_t opr1;
|
||||
c2_ptr_t opr2;
|
||||
};
|
||||
|
||||
/// Initializer for c2_b_t.
|
||||
#define C2_B_INIT { \
|
||||
.neg = false, \
|
||||
.op = C2_B_OUNDEFINED, \
|
||||
.opr1 = C2_PTR_INIT, \
|
||||
.opr2 = C2_PTR_INIT, \
|
||||
}
|
||||
|
||||
/// Structure for leaf element in a window condition
|
||||
struct _c2_l {
|
||||
bool neg : 1;
|
||||
enum {
|
||||
C2_L_OEXISTS,
|
||||
C2_L_OEQ,
|
||||
C2_L_OGT,
|
||||
C2_L_OGTEQ,
|
||||
C2_L_OLT,
|
||||
C2_L_OLTEQ,
|
||||
} op : 3;
|
||||
enum {
|
||||
C2_L_MEXACT,
|
||||
C2_L_MSTART,
|
||||
C2_L_MCONTAINS,
|
||||
C2_L_MWILDCARD,
|
||||
C2_L_MPCRE,
|
||||
} match : 3;
|
||||
bool match_ignorecase : 1;
|
||||
char *tgt;
|
||||
Atom tgtatom;
|
||||
bool tgt_onframe;
|
||||
int index;
|
||||
enum {
|
||||
C2_L_PUNDEFINED,
|
||||
C2_L_PID,
|
||||
C2_L_PX,
|
||||
C2_L_PY,
|
||||
C2_L_PX2,
|
||||
C2_L_PY2,
|
||||
C2_L_PWIDTH,
|
||||
C2_L_PHEIGHT,
|
||||
C2_L_PWIDTHB,
|
||||
C2_L_PHEIGHTB,
|
||||
C2_L_PBDW,
|
||||
C2_L_PFULLSCREEN,
|
||||
C2_L_POVREDIR,
|
||||
C2_L_PARGB,
|
||||
C2_L_PFOCUSED,
|
||||
C2_L_PWMWIN,
|
||||
C2_L_PBSHAPED,
|
||||
C2_L_PROUNDED,
|
||||
C2_L_PCLIENT,
|
||||
C2_L_PWINDOWTYPE,
|
||||
C2_L_PLEADER,
|
||||
C2_L_PNAME,
|
||||
C2_L_PCLASSG,
|
||||
C2_L_PCLASSI,
|
||||
C2_L_PROLE,
|
||||
} predef;
|
||||
enum c2_l_type {
|
||||
C2_L_TUNDEFINED,
|
||||
C2_L_TSTRING,
|
||||
C2_L_TCARDINAL,
|
||||
C2_L_TWINDOW,
|
||||
C2_L_TATOM,
|
||||
C2_L_TDRAWABLE,
|
||||
} type;
|
||||
int format;
|
||||
enum {
|
||||
C2_L_PTUNDEFINED,
|
||||
C2_L_PTSTRING,
|
||||
C2_L_PTINT,
|
||||
} ptntype;
|
||||
char *ptnstr;
|
||||
long ptnint;
|
||||
#ifdef CONFIG_REGEX_PCRE
|
||||
pcre *regex_pcre;
|
||||
pcre_extra *regex_pcre_extra;
|
||||
#endif
|
||||
};
|
||||
|
||||
/// Initializer for c2_l_t.
|
||||
#define C2_L_INIT { \
|
||||
.neg = false, \
|
||||
.op = C2_L_OEXISTS, \
|
||||
.match = C2_L_MEXACT, \
|
||||
.match_ignorecase = false, \
|
||||
.tgt = NULL, \
|
||||
.tgtatom = 0, \
|
||||
.tgt_onframe = false, \
|
||||
.predef = C2_L_PUNDEFINED, \
|
||||
.index = -1, \
|
||||
.type = C2_L_TUNDEFINED, \
|
||||
.format = 0, \
|
||||
.ptntype = C2_L_PTUNDEFINED, \
|
||||
.ptnstr = NULL, \
|
||||
.ptnint = 0, \
|
||||
}
|
||||
|
||||
const static c2_l_t leaf_def = C2_L_INIT;
|
||||
|
||||
/// Linked list type of conditions.
|
||||
struct _c2_lptr {
|
||||
c2_ptr_t ptr;
|
||||
void *data;
|
||||
struct _c2_lptr *next;
|
||||
};
|
||||
|
||||
/// Initializer for c2_lptr_t.
|
||||
#define C2_LPTR_INIT { \
|
||||
.ptr = C2_PTR_INIT, \
|
||||
.data = NULL, \
|
||||
.next = NULL, \
|
||||
}
|
||||
|
||||
/// Structure representing a predefined target.
|
||||
typedef struct {
|
||||
const char *name;
|
||||
enum c2_l_type type;
|
||||
int format;
|
||||
} c2_predef_t;
|
||||
|
||||
// Predefined targets.
|
||||
const static c2_predef_t C2_PREDEFS[] = {
|
||||
[C2_L_PID ] = { "id" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PX ] = { "x" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PY ] = { "y" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PX2 ] = { "x2" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PY2 ] = { "y2" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PWIDTH ] = { "width" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PHEIGHT ] = { "height" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PWIDTHB ] = { "widthb" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PHEIGHTB ] = { "heightb" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PBDW ] = { "border_width" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PFULLSCREEN ] = { "fullscreen" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_POVREDIR ] = { "override_redirect" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PARGB ] = { "argb" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PFOCUSED ] = { "focused" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PWMWIN ] = { "wmwin" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PBSHAPED ] = { "bounding_shaped" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PROUNDED ] = { "rounded_corners" , C2_L_TCARDINAL , 0 },
|
||||
[C2_L_PCLIENT ] = { "client" , C2_L_TWINDOW , 0 },
|
||||
[C2_L_PWINDOWTYPE ] = { "window_type" , C2_L_TSTRING , 0 },
|
||||
[C2_L_PLEADER ] = { "leader" , C2_L_TWINDOW , 0 },
|
||||
[C2_L_PNAME ] = { "name" , C2_L_TSTRING , 0 },
|
||||
[C2_L_PCLASSG ] = { "class_g" , C2_L_TSTRING , 0 },
|
||||
[C2_L_PCLASSI ] = { "class_i" , C2_L_TSTRING , 0 },
|
||||
[C2_L_PROLE ] = { "role" , C2_L_TSTRING , 0 },
|
||||
};
|
||||
|
||||
#define mstrncmp(s1, s2) strncmp((s1), (s2), strlen(s1))
|
||||
|
||||
/**
|
||||
* Compare next word in a string with another string.
|
||||
*/
|
||||
static inline int
|
||||
strcmp_wd(const char *needle, const char *src) {
|
||||
int ret = mstrncmp(needle, src);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
char c = src[strlen(needle)];
|
||||
if (isalnum(c) || '_' == c)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether a c2_ptr_t is empty.
|
||||
*/
|
||||
static inline bool
|
||||
c2_ptr_isempty(const c2_ptr_t p) {
|
||||
return !(p.isbranch ? (bool) p.b: (bool) p.l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset a c2_ptr_t.
|
||||
*/
|
||||
static inline void
|
||||
c2_ptr_reset(c2_ptr_t *pp) {
|
||||
if (pp)
|
||||
memcpy(pp, &C2_PTR_NULL, sizeof(c2_ptr_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine two condition trees.
|
||||
*/
|
||||
static inline c2_ptr_t
|
||||
c2h_comb_tree(c2_b_op_t op, c2_ptr_t p1, c2_ptr_t p2) {
|
||||
c2_ptr_t p = {
|
||||
.isbranch = true,
|
||||
.b = malloc(sizeof(c2_b_t))
|
||||
};
|
||||
|
||||
p.b->opr1 = p1;
|
||||
p.b->opr2 = p2;
|
||||
p.b->op = op;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the precedence value of a condition branch operator.
|
||||
*/
|
||||
static inline int
|
||||
c2h_b_opp(c2_b_op_t op) {
|
||||
switch (op) {
|
||||
case C2_B_OAND: return 2;
|
||||
case C2_B_OOR: return 1;
|
||||
case C2_B_OXOR: return 1;
|
||||
default: break;
|
||||
}
|
||||
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare precedence of two condition branch operators.
|
||||
*
|
||||
* Associativity is left-to-right, forever.
|
||||
*
|
||||
* @return positive number if op1 > op2, 0 if op1 == op2 in precedence,
|
||||
* negative number otherwise
|
||||
*/
|
||||
static inline int
|
||||
c2h_b_opcmp(c2_b_op_t op1, c2_b_op_t op2) {
|
||||
return c2h_b_opp(op1) - c2h_b_opp(op2);
|
||||
}
|
||||
|
||||
static int
|
||||
c2_parse_grp(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult, int level);
|
||||
|
||||
static int
|
||||
c2_parse_target(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult);
|
||||
|
||||
static int
|
||||
c2_parse_op(const char *pattern, int offset, c2_ptr_t *presult);
|
||||
|
||||
static int
|
||||
c2_parse_pattern(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult);
|
||||
|
||||
static int
|
||||
c2_parse_legacy(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult);
|
||||
|
||||
static bool
|
||||
c2_l_postprocess(session_t *ps, c2_l_t *pleaf);
|
||||
|
||||
static void
|
||||
c2_free(c2_ptr_t p);
|
||||
|
||||
/**
|
||||
* Wrapper of c2_free().
|
||||
*/
|
||||
static inline void
|
||||
c2_freep(c2_ptr_t *pp) {
|
||||
if (pp) {
|
||||
c2_free(*pp);
|
||||
c2_ptr_reset(pp);
|
||||
}
|
||||
}
|
||||
|
||||
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 void
|
||||
c2_dump_raw(c2_ptr_t p);
|
||||
|
||||
/**
|
||||
* Wrapper of c2_dump_raw().
|
||||
*/
|
||||
static inline void
|
||||
c2_dump(c2_ptr_t p) {
|
||||
c2_dump_raw(p);
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
static Atom
|
||||
c2_get_atom_type(const c2_l_t *pleaf);
|
||||
|
||||
static bool
|
||||
c2_match_once(session_t *ps, win *w, const c2_ptr_t cond);
|
||||
bool
|
||||
c2_matchd(session_t *ps, win *w, const c2_lptr_t *condlst,
|
||||
const c2_lptr_t **cache, void **pdata);
|
||||
|
||||
#define c2_match(ps, w, condlst, cache) c2_matchd((ps), (w), (condlst), \
|
||||
(cache), NULL)
|
||||
|
|
47
src/common.h
47
src/common.h
|
@ -227,6 +227,7 @@
|
|||
|
||||
typedef uint32_t opacity_t;
|
||||
typedef long time_ms_t;
|
||||
typedef struct _c2_lptr c2_lptr_t;
|
||||
|
||||
typedef enum {
|
||||
WINTYPE_UNKNOWN,
|
||||
|
@ -519,9 +520,7 @@ typedef struct {
|
|||
|
||||
struct _timeout_t;
|
||||
|
||||
struct _win;
|
||||
|
||||
typedef struct _c2_lptr c2_lptr_t;
|
||||
typedef struct win win;
|
||||
|
||||
/// Structure representing all options.
|
||||
typedef struct _options_t {
|
||||
|
@ -787,7 +786,7 @@ typedef struct {
|
|||
#endif
|
||||
|
||||
/// Structure containing all necessary data for a compton session.
|
||||
typedef struct _session_t {
|
||||
typedef struct session {
|
||||
// === Display related ===
|
||||
/// Display in use.
|
||||
Display *dpy;
|
||||
|
@ -888,13 +887,13 @@ typedef struct _session_t {
|
|||
|
||||
// === Window related ===
|
||||
/// Linked list of all windows.
|
||||
struct _win *list;
|
||||
win *list;
|
||||
/// Pointer to <code>win</code> of current active window. Used by
|
||||
/// EWMH <code>_NET_ACTIVE_WINDOW</code> focus detection. In theory,
|
||||
/// it's more reliable to store the window ID directly here, just in
|
||||
/// case the WM does something extraordinary, but caching the pointer
|
||||
/// means another layer of complexity.
|
||||
struct _win *active_win;
|
||||
win *active_win;
|
||||
/// Window ID of leader window of currently active window. Used for
|
||||
/// subsidiary window detection.
|
||||
Window active_leader;
|
||||
|
@ -1038,11 +1037,11 @@ typedef struct _session_t {
|
|||
} session_t;
|
||||
|
||||
/// Structure representing a top-level window compton manages.
|
||||
typedef struct _win {
|
||||
struct win {
|
||||
/// Pointer to the next structure in the linked list.
|
||||
struct _win *next;
|
||||
win *next;
|
||||
/// Pointer to the next higher window to paint.
|
||||
struct _win *prev_trans;
|
||||
win *prev_trans;
|
||||
|
||||
// Core members
|
||||
/// ID of the top-level frame window.
|
||||
|
@ -1164,7 +1163,7 @@ typedef struct _win {
|
|||
/// Override value of window fade state. Set by D-Bus method calls.
|
||||
switch_t fade_force;
|
||||
/// Callback to be called after fading completed.
|
||||
void (*fade_callback) (session_t *ps, struct _win *w);
|
||||
void (*fade_callback) (session_t *ps, win *w);
|
||||
|
||||
// Frame-opacity-related members
|
||||
/// Current window frame opacity. Affected by window opacity.
|
||||
|
@ -1216,7 +1215,7 @@ typedef struct _win {
|
|||
/// Textures and FBO background blur use.
|
||||
glx_blur_cache_t glx_blur_cache;
|
||||
#endif
|
||||
} win;
|
||||
};
|
||||
|
||||
/// Temporary structure used for communication between
|
||||
/// <code>get_cfg()</code> and <code>parse_config()</code>.
|
||||
|
@ -1879,7 +1878,7 @@ find_win(session_t *ps, Window id) {
|
|||
* Find out the WM frame of a client window using existing data.
|
||||
*
|
||||
* @param id window ID
|
||||
* @return struct _win object of the found window, NULL if not found
|
||||
* @return struct win object of the found window, NULL if not found
|
||||
*/
|
||||
static inline win *
|
||||
find_toplevel(session_t *ps, Window id) {
|
||||
|
@ -1936,7 +1935,7 @@ win_is_focused_real(session_t *ps, const win *w) {
|
|||
/**
|
||||
* Find out the currently focused window.
|
||||
*
|
||||
* @return struct _win object of the found window, NULL if not found
|
||||
* @return struct win object of the found window, NULL if not found
|
||||
*/
|
||||
static inline win *
|
||||
find_focused(session_t *ps) {
|
||||
|
@ -2466,28 +2465,6 @@ opts_set_no_fading_openclose(session_t *ps, bool newval);
|
|||
//!@}
|
||||
#endif
|
||||
|
||||
/** @name c2
|
||||
*/
|
||||
///@{
|
||||
|
||||
c2_lptr_t *
|
||||
c2_parsed(session_t *ps, c2_lptr_t **pcondlst, const char *pattern,
|
||||
void *data);
|
||||
|
||||
#define c2_parse(ps, pcondlst, pattern) c2_parsed((ps), (pcondlst), (pattern), NULL)
|
||||
|
||||
c2_lptr_t *
|
||||
c2_free_lptr(c2_lptr_t *lp);
|
||||
|
||||
bool
|
||||
c2_matchd(session_t *ps, win *w, const c2_lptr_t *condlst,
|
||||
const c2_lptr_t **cache, void **pdata);
|
||||
|
||||
#define c2_match(ps, w, condlst, cache) c2_matchd((ps), (w), (condlst), \
|
||||
(cache), NULL)
|
||||
|
||||
///@}
|
||||
|
||||
/**
|
||||
* @brief Dump the given data to a file.
|
||||
*/
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
|
||||
// === Includes ===
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <sys/select.h>
|
||||
#include <limits.h>
|
||||
|
@ -27,6 +25,9 @@
|
|||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include "c2.h"
|
||||
|
||||
// == Functions ==
|
||||
|
||||
// inline functions must be made static to compile correctly under clang:
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "common.h"
|
||||
#include "config.h"
|
||||
#include "c2.h"
|
||||
|
||||
/**
|
||||
* Parse a long number.
|
||||
|
|
Loading…
Reference in New Issue