+ return 0;
+}
+
+rx_t **rx_lookup(rx_t **l, const char *pat)
+{
+ if (m_strisempty(pat))
+ return NULL;
+
+ while (*l) {
+ if (!m_strcmp((*l)->pattern, pat))
+ return l;
+ l = &(*l)->next;
+ }
+
+ return l;
+}
+
+void rx_list_add(rx_t **l, rx_t *rxp)
+{
+ l = rx_lookup(l, rxp->pattern);
+ if (*l) {
+ rx_t *r = rx_list_pop(l);
+ rx_delete(&r);
+ }
+ rx_list_push(l, rxp);
+}
+
+void rx_list_add2(rx_t **l, rx_t **rxp)
+{
+ l = rx_lookup(l, (*rxp)->pattern);
+ if (*l) {
+ rx_t *r = rx_list_pop(l);
+ rx_delete(&r);
+ }
+ if (m_strisempty((*rxp)->tpl)) {
+ rx_delete(rxp);
+ } else {
+ rx_list_push(l, *rxp);
+ }
+}
+
+void rx_list_remove(rx_t **l, const rx_t *r)
+{
+ l = rx_lookup(l, r->pattern);
+ if (*l) {
+ rx_t *tmp = rx_list_pop(l);
+ rx_delete(&tmp);
+ }
+}
+
+int rx_sanitize_string(char *dst, ssize_t n, const char *src)
+{
+ while (*src) {
+ if (n <= 1)
+ break;
+
+ /* these characters must be escaped in regular expressions */
+ if (strchr("^.[$()|*+?{\\", *src)) {
+ if (n <= 2)
+ break;
+
+ *dst++ = '\\';
+ n--;
+ }
+
+ *dst++ = *src++;
+ n--;
+ }
+
+ *dst = '\0';
+
+ return *src ? -1 : 0;