struct regexp * regexp_minus(struct info *info, struct regexp *r1, struct regexp *r2) { const char *p1 = r1->pattern->str; const char *p2 = r2->pattern->str; struct regexp *result = NULL; struct fa *fa = NULL, *fa1 = NULL, *fa2 = NULL; int r; char *s = NULL; size_t s_len; r = fa_compile(p1, strlen(p1), &fa1); if (r != REG_NOERROR) goto error; r = fa_compile(p2, strlen(p2), &fa2); if (r != REG_NOERROR) goto error; fa = fa_minus(fa1, fa2); if (fa == NULL) goto error; r = fa_as_regexp(fa, &s, &s_len); if (r < 0) goto error; if (s == NULL) { /* FA is the empty set, which we can't represent as a regexp */ goto error; } result = make_regexp(info, s); s = NULL; done: fa_free(fa); fa_free(fa1); fa_free(fa2); free(s); return result; error: unref(result, regexp); goto done; }
struct regexp * regexp_minus(struct info *info, struct regexp *r1, struct regexp *r2) { struct regexp *result = NULL; struct fa *fa = NULL, *fa1 = NULL, *fa2 = NULL; int r; char *s = NULL; size_t s_len; fa1 = regexp_to_fa(r1); ERR_BAIL(r1->info); fa2 = regexp_to_fa(r2); ERR_BAIL(r2->info); fa = fa_minus(fa1, fa2); if (fa == NULL) goto error; r = fa_as_regexp(fa, &s, &s_len); if (r < 0) goto error; if (s == NULL) { /* FA is the empty set, which we can't represent as a regexp */ goto error; } if (regexp_c_locale(&s, NULL) < 0) goto error; result = make_regexp(info, s, fa_is_nocase(fa)); s = NULL; done: fa_free(fa); fa_free(fa1); fa_free(fa2); free(s); return result; error: unref(result, regexp); goto done; }