void zrex_test (bool verbose) { printf (" * zrex: "); // @selftest // This shows the pattern of matching many lines to a single pattern zrex_t *rex = zrex_new ("\\d+-\\d+-\\d+"); assert (rex); assert (zrex_valid (rex)); bool matches = zrex_matches (rex, "123-456-789"); assert (matches); assert (zrex_hits (rex) == 1); assert (streq (zrex_hit (rex, 0), "123-456-789")); assert (zrex_hit (rex, 1) == NULL); zrex_destroy (&rex); // Here we pick out hits using capture groups rex = zrex_new ("(\\d+)-(\\d+)-(\\d+)"); assert (rex); assert (zrex_valid (rex)); matches = zrex_matches (rex, "123-456-ABC"); assert (!matches); matches = zrex_matches (rex, "123-456-789"); assert (matches); assert (zrex_hits (rex) == 4); assert (streq (zrex_hit (rex, 0), "123-456-789")); assert (streq (zrex_hit (rex, 1), "123")); assert (streq (zrex_hit (rex, 2), "456")); assert (streq (zrex_hit (rex, 3), "789")); zrex_destroy (&rex); // This shows the pattern of matching one line against many // patterns and then handling the case when it hits rex = zrex_new (NULL); // No initial pattern assert (rex); char *input = "Mechanism: CURVE"; matches = zrex_eq (rex, input, "Version: (.+)"); assert (!matches); assert (zrex_hits (rex) == 0); matches = zrex_eq (rex, input, "Mechanism: (.+)"); assert (matches); assert (zrex_hits (rex) == 2); const char *mechanism; zrex_fetch (rex, &mechanism, NULL); assert (streq (zrex_hit (rex, 1), "CURVE")); assert (streq (mechanism, "CURVE")); zrex_destroy (&rex); #if defined (__WINDOWS__) zsys_shutdown(); #endif // @end printf ("OK\n"); }
void s_service_dispatch (service_t *self) { // for each message, check regexp and dispatch if possible if (zlistx_size (self->offers)) { mlm_msg_t *message = (mlm_msg_t *) zlistx_first (self->queue); while (message) { offer_t *offer = (offer_t *) zlistx_first (self->offers); while (offer) { if (zrex_matches (offer->rex, mlm_msg_subject (message))) { client_t *target = offer->client; assert (target); assert (!target->msg); target->msg = (mlm_msg_t *) zlistx_detach ( self->queue, zlistx_cursor (self->queue)); engine_send_event (target, service_message_event); zlistx_move_end (self->offers, zlistx_cursor (self->offers)); break; } offer = (offer_t *) zlistx_next (self->offers); } message = (mlm_msg_t *) zlistx_next (self->queue); } } }
static void s_load_certs_from_disk (zcertstore_t *self) { zhashx_purge (self->certs); zdir_t *dir = zdir_new (self->location, NULL); if (dir) { // Load all certificates including those in subdirectories zfile_t **filelist = zdir_flatten (dir); assert (filelist); zrex_t *rex = zrex_new ("_secret$"); assert (rex); uint index; for (index = 0;; index++) { zfile_t *file = filelist [index]; if (!file) break; // End of list if (zfile_is_regular (file) && !zrex_matches (rex, zfile_filename (file, NULL))) { zcert_t *cert = zcert_load (zfile_filename (file, NULL)); if (cert) zcertstore_insert (self, &cert); } } zdir_flatten_free (&filelist); self->modified = zdir_modified (dir); self->count = zdir_count (dir); self->cursize = zdir_cursize (dir); zrex_destroy (&rex); zdir_destroy (&dir); } }
static bool s_service_dispatch_message (service_t *self, mlm_msg_t *message) { offer_t *offer = (offer_t *) zlistx_first (self->offers); while (offer) { if (zrex_matches (offer->rex, mlm_msg_subject (message))) { client_t *target = offer->client; assert (target); assert (!target->msg); target->msg = message; engine_send_event (target, service_message_event); zlistx_move_end (self->offers, zlistx_cursor (self->offers)); return true; } offer = (offer_t *) zlistx_next (self->offers); } return false; }
bool zrex_eq (zrex_t *self, const char *text, const char *expression) { assert (self); assert (text); assert (expression); // Compile the new expression self->valid = (slre_compile (&self->slre, expression) == 1); if (!self->valid) self->strerror = self->slre.err_str; assert (self->slre.num_caps < MAX_HITS); // zrex_matches takes care of the rest for us if (self->valid) return zrex_matches (self, text); else return false; }
static ztrie_node_t * s_ztrie_matches_token (ztrie_node_t *parent, char *token, int len) { char firstbyte = *token; ztrie_node_t *child = (ztrie_node_t *) zlistx_first (parent->children); while (child) { if (child->token_type == NODE_TYPE_STRING) { if (firstbyte == *child->token // This achieves a small performance boost && child->token_len == len && strncmp (child->token, token, MIN_LEN (child->token_len, len)) == 0) return child; } else if (child->token_type == NODE_TYPE_ASTERISK) { child->asterisk_match = strdup (token); return child; } else { // Need to copy token as zrex_matches expects '\0' terminated string char *token_term = s_strndup (token, len); if (zrex_matches (child->regex, token_term)) { if (child->token_type == NODE_TYPE_PARAM) { // One hit means no capturing group was defined // More than one hit indicates that at least on capturing group. // In this case only the values of the capturing groups are considered. if (zrex_hits (child->regex) == 1) s_ztrie_node_update_param (child, 1, zrex_hit (child->regex, 0)); else if (zrex_hits (child->regex) > 1) { int index; for (index = 1; index < zrex_hits (child->regex); index++) s_ztrie_node_update_param (child, index, zrex_hit (child->regex, index)); } } free (token_term); return child; } free (token_term); } child = (ztrie_node_t *) zlistx_next (parent->children); } return NULL; }
static int s_stream_engine_handle_message (stream_engine_t *self) { void *sender; mlm_msg_t *msg; zsock_brecv (self->msgpipe, "pp", &sender, &msg); selector_t *selector = (selector_t *) zlistx_first (self->selectors); while (selector) { if (zrex_matches (selector->rex, mlm_msg_subject (msg))) { void *client = zlistx_first (selector->clients); while (client) { if (client != sender) zsock_bsend (self->msgpipe, "pp", client, mlm_msg_link (msg)); client = zlistx_next (selector->clients); } } selector = (selector_t *) zlistx_next (self->selectors); } mlm_msg_unlink (&msg); return 0; }