mirror of
https://codeberg.org/dnkl/yambar.git
synced 2025-04-20 11:35:42 +02:00
string like operation
This commit is contained in:
parent
0f47cbb889
commit
4826a52306
6 changed files with 88 additions and 7 deletions
|
@ -24,10 +24,13 @@
|
||||||
([#392][392]).
|
([#392][392]).
|
||||||
* i3/sway: `output` tag, reflecting the output (monitor) a workspace
|
* i3/sway: `output` tag, reflecting the output (monitor) a workspace
|
||||||
is on.
|
is on.
|
||||||
|
* Added "string like" `~~` operator to Map particle. Allows
|
||||||
|
glob-style matching on strings using `*` and `?` characters. ([#400][400])
|
||||||
|
|
||||||
[96]: https://codeberg.org/dnkl/yambar/issues/96
|
[96]: https://codeberg.org/dnkl/yambar/issues/96
|
||||||
[380]: https://codeberg.org/dnkl/yambar/issues/380
|
[380]: https://codeberg.org/dnkl/yambar/issues/380
|
||||||
[392]: https://codeberg.org/dnkl/yambar/issues/392
|
[392]: https://codeberg.org/dnkl/yambar/issues/392
|
||||||
|
[400]: https://codeberg.org/dnkl/yambar/pulls/400
|
||||||
|
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
|
@ -265,6 +265,26 @@ To match for empty strings, use ' "" ':
|
||||||
<tag> == ""
|
<tag> == ""
|
||||||
```
|
```
|
||||||
|
|
||||||
|
String glob matching
|
||||||
|
|
||||||
|
To perform string matching using globbing with "\*" & "?" characters:
|
||||||
|
\* Match any zero or more characters.
|
||||||
|
? Match exactly any one character.
|
||||||
|
|
||||||
|
```
|
||||||
|
<tag> ~~ "hello*"
|
||||||
|
```
|
||||||
|
|
||||||
|
Will match any string starting with "hello", including "hello",
|
||||||
|
"hello1", "hello123", etc.
|
||||||
|
|
||||||
|
```
|
||||||
|
<tag> ~~ "hello?"
|
||||||
|
```
|
||||||
|
|
||||||
|
Will match any string starting with "hello" followed by any single
|
||||||
|
character, including "hello1", "hello-", but not "hello".
|
||||||
|
|
||||||
Furthermore, you may use the boolean operators:
|
Furthermore, you may use the boolean operators:
|
||||||
|
|
||||||
[- &&
|
[- &&
|
||||||
|
|
|
@ -13,6 +13,59 @@
|
||||||
|
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
|
||||||
|
// String globbing match.
|
||||||
|
// Note: Uses "non-greedy" implementation for "*" wildcard matching
|
||||||
|
static bool
|
||||||
|
string_like(const char* name, const char* pattern)
|
||||||
|
{
|
||||||
|
LOG_DBG("pattern:%s name:%s", pattern, name);
|
||||||
|
int px = 0, nx = 0;
|
||||||
|
int nextpx = 0, nextnx = 0;
|
||||||
|
while(px < strlen(pattern) || nx < strlen(name))
|
||||||
|
{
|
||||||
|
if(px < strlen(pattern))
|
||||||
|
{
|
||||||
|
char c = pattern[px];
|
||||||
|
switch (c) {
|
||||||
|
case '?': {
|
||||||
|
// single character
|
||||||
|
px++;
|
||||||
|
nx++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
case '*': {
|
||||||
|
// zero or more glob
|
||||||
|
nextpx=px;
|
||||||
|
nextnx=nx+1;
|
||||||
|
px++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
// normal character
|
||||||
|
if (nx < strlen(name) && name[nx] == c)
|
||||||
|
{
|
||||||
|
px++;
|
||||||
|
nx++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// mismatch
|
||||||
|
if (0 < nextnx && nextnx <= strlen(name)) {
|
||||||
|
px = nextpx;
|
||||||
|
nx = nextnx;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
LOG_DBG("map: name %s matched all the pattern %s", name, pattern);
|
||||||
|
// Matched all of pattern to all of name. Success.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
int_condition(const long tag_value, const long cond_value, enum map_op op)
|
int_condition(const long tag_value, const long cond_value, enum map_op op)
|
||||||
{
|
{
|
||||||
|
@ -75,6 +128,8 @@ str_condition(const char *tag_value, const char *cond_value, enum map_op op)
|
||||||
return strcmp(tag_value, cond_value) >= 0;
|
return strcmp(tag_value, cond_value) >= 0;
|
||||||
case MAP_OP_GT:
|
case MAP_OP_GT:
|
||||||
return strcmp(tag_value, cond_value) > 0;
|
return strcmp(tag_value, cond_value) > 0;
|
||||||
|
case MAP_OP_LIKE:
|
||||||
|
return string_like(tag_value, cond_value) != 0;
|
||||||
case MAP_OP_SELF:
|
case MAP_OP_SELF:
|
||||||
LOG_WARN("using String tag as bool");
|
LOG_WARN("using String tag as bool");
|
||||||
default:
|
default:
|
||||||
|
@ -166,6 +221,7 @@ free_map_condition(struct map_condition *c)
|
||||||
case MAP_OP_LE:
|
case MAP_OP_LE:
|
||||||
case MAP_OP_LT:
|
case MAP_OP_LT:
|
||||||
case MAP_OP_GE:
|
case MAP_OP_GE:
|
||||||
|
case MAP_OP_LIKE:
|
||||||
case MAP_OP_GT:
|
case MAP_OP_GT:
|
||||||
free(c->value);
|
free(c->value);
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
|
@ -9,6 +9,7 @@ enum map_op {
|
||||||
MAP_OP_GT,
|
MAP_OP_GT,
|
||||||
MAP_OP_SELF,
|
MAP_OP_SELF,
|
||||||
MAP_OP_NOT,
|
MAP_OP_NOT,
|
||||||
|
MAP_OP_LIKE,
|
||||||
|
|
||||||
MAP_OP_AND,
|
MAP_OP_AND,
|
||||||
MAP_OP_OR,
|
MAP_OP_OR,
|
||||||
|
|
|
@ -69,6 +69,7 @@ void yyerror(const char *s);
|
||||||
\< yylval.op = MAP_OP_LT; return CMP_OP;
|
\< yylval.op = MAP_OP_LT; return CMP_OP;
|
||||||
>= yylval.op = MAP_OP_GE; return CMP_OP;
|
>= yylval.op = MAP_OP_GE; return CMP_OP;
|
||||||
> yylval.op = MAP_OP_GT; return CMP_OP;
|
> yylval.op = MAP_OP_GT; return CMP_OP;
|
||||||
|
~~ yylval.op = MAP_OP_LIKE; return CMP_OP;
|
||||||
&& yylval.op = MAP_OP_AND; return BOOL_OP;
|
&& yylval.op = MAP_OP_AND; return BOOL_OP;
|
||||||
\|\| yylval.op = MAP_OP_OR; return BOOL_OP;
|
\|\| yylval.op = MAP_OP_OR; return BOOL_OP;
|
||||||
~ return NOT;
|
~ return NOT;
|
||||||
|
|
|
@ -79,7 +79,7 @@ static char const*
|
||||||
token_to_str(yysymbol_kind_t tkn)
|
token_to_str(yysymbol_kind_t tkn)
|
||||||
{
|
{
|
||||||
switch (tkn) {
|
switch (tkn) {
|
||||||
case YYSYMBOL_CMP_OP: return "==, !=, <=, <, >=, >";
|
case YYSYMBOL_CMP_OP: return "==, !=, <=, <, >=, >, ~~";
|
||||||
case YYSYMBOL_BOOL_OP: return "||, &&";
|
case YYSYMBOL_BOOL_OP: return "||, &&";
|
||||||
case YYSYMBOL_L_PAR: return "(";
|
case YYSYMBOL_L_PAR: return "(";
|
||||||
case YYSYMBOL_R_PAR: return ")";
|
case YYSYMBOL_R_PAR: return ")";
|
||||||
|
|
Loading…
Add table
Reference in a new issue