/* * Typechecking of lenses */ static struct value *disjoint_check(struct info *info, const char *msg, struct regexp *r1, struct regexp *r2) { struct fa *fa1 = NULL; struct fa *fa2 = NULL; struct fa *fa = NULL; struct value *exn = NULL; exn = regexp_to_fa(r1, &fa1); if (exn != NULL) goto done; exn = regexp_to_fa(r2, &fa2); if (exn != NULL) goto done; fa = fa_intersect(fa1, fa2); if (! fa_is_basic(fa, FA_EMPTY)) { size_t xmpl_len; char *xmpl; fa_example(fa, &xmpl, &xmpl_len); exn = make_exn_value(ref(info), "overlapping lenses in %s", msg); exn_printf_line(exn, "Example matched by both: '%s'", xmpl); free(xmpl); } done: fa_free(fa); fa_free(fa1); fa_free(fa2); return exn; }
int fa_destroy_trans_udpsrv(fa_trans_t *trans) { if (trans->trans_name) fa_free(trans->trans_name); if (trans->priv_data) fa_free(trans->priv_data); trans->open = NULL; trans->send = NULL; trans->recv = NULL; trans->close = NULL; return 0; }
static int udpsrv_close(fa_trans_t *trans) { udpsrv_context_t *s = trans->priv_data; closesocket(s->fd); fa_free(s); return 0; }
static struct value *ambig_iter_check(struct info *info, const char *msg, struct regexp *r) { struct fa *fas = NULL, *fa = NULL; struct value *result = NULL; result = regexp_to_fa(r, &fa); if (result != NULL) goto done; fas = fa_iter(fa, 0, -1); result = ambig_check(info, fa, fas, msg); done: fa_free(fa); fa_free(fas); return result; }
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; }
static struct value *ambig_concat_check(struct info *info, const char *msg, struct regexp *r1, struct regexp *r2) { struct fa *fa1 = NULL; struct fa *fa2 = NULL; struct value *result = NULL; result = regexp_to_fa(r1, &fa1); if (result != NULL) goto done; result = regexp_to_fa(r2, &fa2); if (result != NULL) goto done; result = ambig_check(info, fa1, fa2, msg); done: fa_free(fa1); fa_free(fa2); return result; }
static struct fa *regexp_to_fa(struct regexp *r) { const char *p = r->pattern->str; int ret; struct fa *fa = NULL; ret = fa_compile(p, strlen(p), &fa); ERR_NOMEM(ret == REG_ESPACE, r->info); BUG_ON(ret != REG_NOERROR, r->info, NULL); if (r->nocase) { ret = fa_nocase(fa); ERR_NOMEM(ret < 0, r->info); } return fa; error: fa_free(fa); return NULL; }
/* * Lens primitives */ struct value *lns_make_prim(enum lens_tag tag, struct info *info, struct regexp *regexp, struct string *string) { struct lens *lens = NULL; struct value *exn = NULL; struct fa *fa_slash = NULL; struct fa *fa_key = NULL; struct fa *fa_isect = NULL; /* Typecheck */ if (tag == L_KEY) { exn = str_to_fa(info, "(.|\n)*/(.|\n)*", &fa_slash); if (exn != NULL) goto error; exn = regexp_to_fa(regexp, &fa_key); if (exn != NULL) goto error; fa_isect = fa_intersect(fa_slash, fa_key); if (! fa_is_basic(fa_isect, FA_EMPTY)) { exn = make_exn_value(info, "The key regexp /%s/ matches a '/'", regexp->pattern->str); goto error; } fa_free(fa_isect); fa_free(fa_key); fa_free(fa_slash); fa_isect = fa_key = fa_slash = NULL; } else if (tag == L_LABEL) { if (strchr(string->str, SEP) != NULL) { exn = make_exn_value(info, "The label string \"%s\" contains a '/'", string->str); goto error; } } else if (tag == L_DEL) { int cnt; const char *dflt = string->str; cnt = regexp_match(regexp, dflt, strlen(dflt), 0, NULL); if (cnt != strlen(dflt)) { char *s = escape(dflt, -1); char *r = escape(regexp->pattern->str, -1); exn = make_exn_value(info, "del: the default value '%s' does not match /%s/", s, r); FREE(s); FREE(r); goto error; } } /* Build the actual lens */ lens = make_lens(tag, info); lens->regexp = regexp; lens->string = string; lens->key = (tag == L_KEY || tag == L_LABEL || tag == L_SEQ); lens->value = (tag == L_STORE); lens->consumes_value = (tag == L_STORE); lens->atype = regexp_make_empty(info); if (tag == L_DEL || tag == L_STORE || tag == L_KEY) { lens->ctype = ref(regexp); } else if (tag == L_LABEL || tag == L_SEQ || tag == L_COUNTER) { lens->ctype = regexp_make_empty(info); } else { assert(0); } return make_lens_value(lens); error: fa_free(fa_isect); fa_free(fa_key); fa_free(fa_slash); return exn; }
static int udpsrv_open(fa_trans_t *trans, char *hostname, int port) { struct addrinfo hints, *cur_ai; udpsrv_context_t *s = NULL; int ret; char portstr[10]; int fd = -1; int tmp; if (port <= 0 || port >= 65536) { FA_PRINT("FAIL: %s , [err at: %s-%d]\n", FA_ERR_NETWORK_PORTNO, __FILE__, __LINE__); return -1; //port is not correct } s = fa_malloc(sizeof(udpsrv_context_t)); if (!s) { FA_PRINT("FAIL: %s , [err at: %s-%d]\n", FA_ERR_SYS_NOMEM, __FILE__, __LINE__); return -1; } memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; snprintf(portstr, sizeof(portstr), "%d", port); ret = getaddrinfo(hostname, portstr, &hints, &(s->ai)); //cvt the hostname to the address(support ipv6) if (ret) { FA_PRINT("FAIL: %s , [err at: %s-%d]\n", FA_ERR_SYS_IO, __FILE__, __LINE__); goto fail; } cur_ai = s->ai; fd = socket(cur_ai->ai_family, cur_ai->ai_socktype, cur_ai->ai_protocol); if (fd < 0) goto fail; tmp = 1; setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp)); if (bind (fd, cur_ai->ai_addr, cur_ai->ai_addrlen) < 0) { char bindmsg[32]; /*snprintf(bindmsg, sizeof(bindmsg), "bind(port %d)", ntohs(cur_ai->ai_addr->sin_port));*/ snprintf(bindmsg, sizeof(bindmsg), "bind fail"); // perror (bindmsg); FA_PRINT("FAIL: %s , [err at: %s-%d]\n", bindmsg, __FILE__, __LINE__); closesocket(fd); return -1; } #ifdef UDP_USE_BLOCK fa_socket_nonblock(fd, 0); #else fa_socket_nonblock(fd, 1); #endif s->fd = fd; trans->priv_data = s; return 0; fail: FA_PRINT("FAIL: %s , [err at: %s-%d]\n", FA_ERR_SYS_IO, __FILE__, __LINE__); if (fd >= 0) closesocket(fd); if (s) { if (s->ai) freeaddrinfo(s->ai); fa_free(s); } return -1; }
fa_ptr_t default_destroy(fa_ptr_t _, fa_ptr_t data) { fa_free(data); return NULL; }
fa_ptr_t default_destroy(fa_ptr_t b, fa_ptr_t _) { fa_free(b); return NULL; }
list_for_each(fl, fa_list) { fa_free(fl->fa); }