/* * stack implemented computation for epsilon closure set from input */ struct set *epsilon_closure(struct set *input, struct accept **acp, int dup) { struct nfa *nfastack[MAXSTACKNFAS]; struct nfa *nfa; int top = -1, state; struct set *output; int i; /* init accpet */ if (acp) *acp = NULL; if (!input) return NULL; /* set return value (output set)*/ output = dup ? dupset(input) : input; /* push all states in the input set onto nfastack */ for_each_member(state, input) { nfastack[++top] = statenfa(state); if (top >= MAXSTACKNFAS) errexit("nfa stack overflows"); }
/* * recursion implemented computation for epsilon closure set from input * @dup if 1, output set realloced * otherwise, epsilon closure set is added into input * and return input * @accept accept state * @input start state for computing epsilon closure * * input only contains sstate */ struct set *epsilon_closure(struct set *input, struct accept **acp, int dup) { int start_state[MAXSTACKNFAS]; int state; struct set *output; /* * We cannot using e_closure(nfa, output), * because sstate is already in output. */ if (acp) *acp = NULL; if (!input) return NULL; /* set return value(epsilon closure set) */ output = dup ? dupset(input) : input; /* buffering start state int input */ for (startmember(input), state = 0; state < MAXSTACKNFAS; state++) { start_state[state] = nextmember(input); if (start_state[state] == -1) { state--; break; } } if (state >= MAXSTACKNFAS) errexit("state stack overflows"); /* computing epsilon closure of every start state in input set */ for (; state >= 0; state--) e_closure(statenfa(start_state[state]), output, acp); return output; }
/* * curl_easy_duphandle() is an external interface to allow duplication of a * given input easy handle. The returned handle will be a new working handle * with all options set exactly as the input source handle. */ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data) { struct Curl_easy *outcurl = calloc(1, sizeof(struct Curl_easy)); if(NULL == outcurl) goto fail; /* * We setup a few buffers we need. We should probably make them * get setup on-demand in the code, as that would probably decrease * the likeliness of us forgetting to init a buffer here in the future. */ outcurl->set.buffer_size = data->set.buffer_size; outcurl->state.buffer = malloc(outcurl->set.buffer_size + 1); if(!outcurl->state.buffer) goto fail; outcurl->state.headerbuff = malloc(HEADERSIZE); if(!outcurl->state.headerbuff) goto fail; outcurl->state.headersize = HEADERSIZE; /* copy all userdefined values */ if(dupset(outcurl, data)) goto fail; /* the connection cache is setup on demand */ outcurl->state.conn_cache = NULL; outcurl->state.lastconnect = NULL; outcurl->progress.flags = data->progress.flags; outcurl->progress.callback = data->progress.callback; if(data->cookies) { /* If cookies are enabled in the parent handle, we enable them in the clone as well! */ outcurl->cookies = Curl_cookie_init(data, data->cookies->filename, outcurl->cookies, data->set.cookiesession); if(!outcurl->cookies) goto fail; } /* duplicate all values in 'change' */ if(data->change.cookielist) { outcurl->change.cookielist = Curl_slist_duplicate(data->change.cookielist); if(!outcurl->change.cookielist) goto fail; } if(data->change.url) { outcurl->change.url = strdup(data->change.url); if(!outcurl->change.url) goto fail; outcurl->change.url_alloc = TRUE; } if(data->change.referer) { outcurl->change.referer = strdup(data->change.referer); if(!outcurl->change.referer) goto fail; outcurl->change.referer_alloc = TRUE; } /* Clone the resolver handle, if present, for the new handle */ if(Curl_resolver_duphandle(&outcurl->state.resolver, data->state.resolver)) goto fail; Curl_convert_setup(outcurl); Curl_initinfo(outcurl); outcurl->magic = CURLEASY_MAGIC_NUMBER; /* we reach this point and thus we are OK */ return outcurl; fail: if(outcurl) { curl_slist_free_all(outcurl->change.cookielist); outcurl->change.cookielist = NULL; Curl_safefree(outcurl->state.buffer); Curl_safefree(outcurl->state.headerbuff); Curl_safefree(outcurl->change.url); Curl_safefree(outcurl->change.referer); Curl_freeset(outcurl); free(outcurl); } return NULL; }