diff --git a/src/daemon/jack.conf.in b/src/daemon/jack.conf.in index bc5180651..84a9643c2 100644 --- a/src/daemon/jack.conf.in +++ b/src/daemon/jack.conf.in @@ -95,7 +95,7 @@ jack.properties = { jack.rules = [ { matches = [ { - # all keys must match the value. ~ starts regex. + # all keys must match the value. ! negates. ~ starts regex. #client.name = "Carla" #application.process.binary = "jack_simple_client" #application.name = "~jack_simple_client.*" diff --git a/src/daemon/pipewire-pulse.conf.in b/src/daemon/pipewire-pulse.conf.in index fe1210c9f..3db9ee86b 100644 --- a/src/daemon/pipewire-pulse.conf.in +++ b/src/daemon/pipewire-pulse.conf.in @@ -116,7 +116,7 @@ pulse.rules = [ { matches = [ { - # all keys must match the value. ~ starts regex. + # all keys must match the value. ! negates. ~ starts regex. #client.name = "Firefox" #application.process.binary = "teams" #application.name = "~speech-dispatcher.*" diff --git a/src/modules/module-combine-stream.c b/src/modules/module-combine-stream.c index f7dae7d58..d06b2aa88 100644 --- a/src/modules/module-combine-stream.c +++ b/src/modules/module-combine-stream.c @@ -93,7 +93,7 @@ * # any of the items in matches needs to match, if one does, * # actions are emited. * { - * # all keys must match the value. ~ in value starts regex. + * # all keys must match the value. ! negates. ~ starts regex. * #node.name = "~alsa_input.*" * media.class = "Audio/Sink" * } diff --git a/src/modules/module-rtp-sap.c b/src/modules/module-rtp-sap.c index 7988de60d..f692509b4 100644 --- a/src/modules/module-rtp-sap.c +++ b/src/modules/module-rtp-sap.c @@ -75,7 +75,7 @@ * { matches = [ * # any of the items in matches needs to match, if one does, * # actions are emited. - * { # all keys must match the value. ~ in value starts regex. + * { # all keys must match the value. ! negates. ~ starts regex. * #rtp.origin = "wim 3883629975 0 IN IP4 0.0.0.0" * #rtp.payload = "127" * #rtp.fmt = "L16/48000/2" @@ -91,7 +91,7 @@ * } * } * { matches = [ - * { # all keys must match the value. ~ in value starts regex. + * { # all keys must match the value. ! negates. ~ starts regex. * #rtp.origin = "wim 3883629975 0 IN IP4 0.0.0.0" * #rtp.payload = "127" * #rtp.fmt = "L16/48000/2" diff --git a/src/pipewire/conf.c b/src/pipewire/conf.c index 91ef7c049..a253ecb98 100644 --- a/src/pipewire/conf.c +++ b/src/pipewire/conf.c @@ -586,6 +586,7 @@ static int load_module(struct pw_context *context, const char *key, const char * /* * { * # all keys must match the value. ~ in value starts regex. + * # ! as the first char of the value negates the match * = * ... * } @@ -598,7 +599,7 @@ static bool find_match(struct spa_json *arr, const struct spa_dict *props) char key[256], val[1024]; const char *str, *value; int match = 0, fail = 0; - int len; + int len, skip = 0; while (spa_json_get_string(&it[0], key, sizeof(key)) > 0) { bool success = false; @@ -615,23 +616,28 @@ static bool find_match(struct spa_json *arr, const struct spa_dict *props) continue; value = val; len = strlen(val); + if (len > 0 && value[0] == '!') { + success = !success; + skip++; + } } if (str != NULL) { - if (value[0] == '~') { + if (value[skip] == '~') { regex_t preg; int res; - if ((res = regcomp(&preg, value+1, REG_EXTENDED | REG_NOSUB)) != 0) { + skip++; + if ((res = regcomp(&preg, value+skip, REG_EXTENDED | REG_NOSUB)) != 0) { char errbuf[1024]; regerror(res, &preg, errbuf, sizeof(errbuf)); - pw_log_warn("invalid regex %s: %s", value+1, errbuf); + pw_log_warn("invalid regex %s: %s", value+skip, errbuf); } else { if (regexec(&preg, str, 0, NULL, 0) == 0) - success = true; + success = !success; regfree(&preg); } - } else if (strncmp(str, value, len) == 0 && - strlen(str) == (size_t)len) { - success = true; + } else if (strncmp(str, value+skip, len-skip) == 0 && + strlen(str) == (size_t)(len-skip)) { + success = !success; } } if (success) { @@ -639,6 +645,7 @@ static bool find_match(struct spa_json *arr, const struct spa_dict *props) pw_log_debug("'%s' match '%s' < > '%.*s'", key, str, len, value); } else { + pw_log_debug("'%s' fail '%s' < > '%.*s'", key, str, len, value); fail++; break; } @@ -1080,7 +1087,7 @@ int pw_conf_load_conf_for_context(struct pw_properties *props, struct pw_propert * # any of the items in matches needs to match, if one does, * # actions are emited. * { - * # all keys must match the value. ~ in value starts regex. + * # all keys must match the value. ! negates. ~ starts regex. * = * ... * }