EditDist limit1_edit_distance(const char * a, const char * b, const EditDistanceWeights & ws) { int min = LARGE_NUM; const char * a0; const char * b0; const char * amax = a; while(*a == *b) { if (*a == '\0') return EditDist(0, a); ++a; ++b; } if (*a == '\0') { ++b; if (*b == '\0') return EditDist(ws.del2, a); return EditDist(LARGE_NUM, a); } else if (*b == '\0') { ++a; if (*a == '\0') return EditDist(ws.del1, a); return EditDist(LARGE_NUM, a); } else { // delete a character from a check_rest(a+1,b,ws.del1); // delete a character from b check_rest(a,b+1,ws.del2); if (*a == *(b+1) && *b == *(a+1)) { // swap two characters check_rest(a+2,b+2,ws.swap); } else { // substitute one character for another which is the same // thing as deleting a character from both a & b check_rest(a+1,b+1,ws.sub); } } return EditDist(min, amax); }
int get_next_line(int const fd, char **line) { t_get *get; static char **rest = NULL; if (fd < 0 || fd >= FD_MAX || BUFF_SIZE <= 0 || !line) return (-1); if (!(get = (t_get *)malloc(sizeof(t_get)))) return (-1); get->fd = fd; if (rest == NULL) if (!(rest = (char **)malloc(sizeof(char *) * FD_MAX))) return (-1); *line = NEW(0); if (rest[fd] == NULL || !check_rest(get, &rest[fd], line)) ft_read(get, &rest[fd], line); if (get->ret == -1) return (-1); if (get->ret == 0 && rest[fd] == NULL && *line && LEN(*line) == 0) { REMOVE(line); /* peut poser probleme selon le cas */ ft_memdel((void *)&get); return (0); } ft_memdel((void *)&get); return (1); }
LOCAL HTTP_RESPONSE_STATUS ICACHE_FLASH_ATTR get_cb(const char *path, const char *key, HTTP_CONTENT *content_in, HTTP_ANSWER *answer) { HTTP_RESPONSE_STATUS res; if(check_rest(&res, path, key, content_in, answer)) { return res; } if(path[0]=='/') { if(path[1]==0) { answer->content.data = uploadable_page_get(&answer->content.len); if(answer->content.len == 0) { // default page answer->content.data = help_html; answer->content.len = sizeof(help_html) - 1; } return HRCS_ANSWERED_HTML; } int i; for(i = 0; i < sizeof(web_pages) / sizeof(WEBPAGE); i++) { if(os_strcmp(web_pages[i].path, &path[1]) == 0) { answer->content.data = web_pages[i].data; answer->content.len = web_pages[i].data_len; return HRCS_ANSWERED_HTML; } } } return HRCS_NOT_FOUND; }
LOCAL HTTP_RESPONSE_STATUS ICACHE_FLASH_ATTR post_cb(const char *path, const char *key, HTTP_CONTENT *content_in, HTTP_ANSWER *answer) { HTTP_RESPONSE_STATUS res; if(check_rest(&res, path, key, content_in, answer)) { return res; } return uploadable_api_handle(path, key, content_in, answer); }
void ft_read(t_get *get, char **rest, char **line) { char *buf; buf = NEW(BUFF_SIZE); if (buf == NULL) { get->ret = -1; return ; } while ((get->ret = read(get->fd, buf, BUFF_SIZE))) { buf[get->ret] = '\0'; *rest = JOIN(*rest, buf); if (*rest == NULL) *rest = SDUP(buf); if ((get->ret < 0) || check_rest(get, rest, line)) break ; } REMOVE(&buf); }
ERL_NIF_TERM reverse_tokens(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { decode_ctx ctx; yajl_parser_config conf = {0, 1}; // No comments, check utf8 yajl_handle handle = yajl_alloc(&decoder_callbacks, &conf, NULL, &ctx); yajl_status status; unsigned int used; ErlNifBinary bin; ERL_NIF_TERM ret; ctx.env = env; ctx.head = enif_make_list_from_array(env, NULL, 0); if(!enif_inspect_iolist_as_binary(env, argv[0], &bin)) { ret = enif_make_badarg(env); goto done; } status = yajl_parse(handle, bin.data, bin.size); used = handle->bytesConsumed; // Parsing something like "2.0" (without quotes) will // cause a spurious semi-error. We add the extra size // check so that "2008-20-10" doesn't pass. if(status == yajl_status_insufficient_data && used == bin.size) { status = yajl_parse_complete(handle); } if(status == yajl_status_ok && used != bin.size) { if(check_rest(bin.data, bin.size, used) == CANCEL) { ret = enif_make_tuple(env, 2, enif_make_atom(env, "error"), enif_make_atom(env, "garbage_after_value") ); goto done; } } switch(status) { case yajl_status_ok: ret = enif_make_tuple(env, 2, enif_make_atom(env, "ok"), ctx.head); goto done; case yajl_status_error: ret = make_error(handle, env); goto done; case yajl_status_insufficient_data: ret = enif_make_tuple(env, 2, enif_make_atom(env, "error"), enif_make_atom(env, "insufficient_data") ); goto done; case yajl_status_client_canceled: /* the only time we do this is when we can't allocate a binary. */ ret = enif_make_tuple(env, 2, enif_make_atom(env, "error"), enif_make_atom(env, "insufficient_memory") ); goto done; default: ret = enif_make_tuple(env, 2, enif_make_atom(env, "error"), enif_make_atom(env, "unknown") ); goto done; } done: if(handle != NULL) yajl_free(handle); return ret; }
int limit_edit_distance(const char * a, const char * b, int limit, const EditDistanceWeights & w) { limit = limit*w.max; static const int size = 10; struct Edit { const char * a; const char * b; int score; }; Edit begin[size]; Edit * i = begin; const char * a0; const char * b0; int score = 0; int min = LARGE_NUM; while (true) { while (*a == *b) { if (*a == '\0') { if (score < min) min = score; goto FINISH; } ++a; ++b; } if (*a == '\0') { do { score += w.del2; if (score >= min) goto FINISH; ++b; } while (*b != '\0'); min = score; } else if (*b == '\0') { do { score += w.del1; if (score >= min) goto FINISH; ++a; } while (*a != '\0'); min = score; } else { if (score + w.max <= limit) { if (limit*w.min <= w.max*(w.min+score)) { // if floor(score/max)=limit/max-1 then this edit is only good // if it makes the rest of the string match. So check if // the rest of the string matches to avoid the overhead of // pushing it on then off the stack // delete a character from a check_rest(a+1,b,score + w.del1); // delete a character from b check_rest(a,b+1,score + w.del2); if (*a == *(b+1) && *b == *(a+1)) { // swap two characters check_rest(a+2,b+2, score + w.swap); } else { // substitute one character for another which is the same // thing as deleting a character from both a & b check_rest(a+1,b+1, score + w.sub); } } else { // delete a character from a i->a = a + 1; i->b = b; i->score = score + w.del1; ++i; // delete a character from b i->a = a; i->b = b + 1; i->score = score + w.del2; ++i; // If two characters can be swapped and make a match // then the substitution is pointless. // Also, there is no need to push this on the stack as // it is going to be imminently removed. if (*a == *(b+1) && *b == *(a+1)) { // swap two characters a = a + 2; b = b + 2; score += w.swap; continue; } else { // substitute one character for another which is the same // thing as deleting a character from both a & b a = a + 1; b = b + 1; score += w.sub; continue; } } } } FINISH: if (i == begin) return min; --i; a = i->a; b = i->b; score = i->score; } }