Lightened the stack in wc_statemach to permit deeper recursion
Also, added a few hints to help compilers to perform tail call recursion optimization.
This commit is contained in:
parent
e214cd4a73
commit
59f07ddf28
28
lib/ftp.c
28
lib/ftp.c
@ -3562,14 +3562,12 @@ static CURLcode init_wc_data(struct connectdata *conn)
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is called recursively */
|
||||||
static CURLcode wc_statemach(struct connectdata *conn)
|
static CURLcode wc_statemach(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
struct WildcardData * const wildcard = &(conn->data->wildcard);
|
||||||
struct WildcardData *wildcard = &(conn->data->wildcard);
|
|
||||||
struct ftp_wc_tmpdata *ftp_tmp = wildcard->tmp;
|
|
||||||
char *tmp_path;
|
|
||||||
CURLcode ret = CURLE_OK;
|
CURLcode ret = CURLE_OK;
|
||||||
long userresponse = 0;
|
|
||||||
switch (wildcard->state) {
|
switch (wildcard->state) {
|
||||||
case CURLWC_INIT:
|
case CURLWC_INIT:
|
||||||
ret = init_wc_data(conn);
|
ret = init_wc_data(conn);
|
||||||
@ -3580,10 +3578,10 @@ static CURLcode wc_statemach(struct connectdata *conn)
|
|||||||
wildcard->state = ret ? CURLWC_ERROR : CURLWC_MATCHING;
|
wildcard->state = ret ? CURLWC_ERROR : CURLWC_MATCHING;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURLWC_MATCHING:
|
case CURLWC_MATCHING: {
|
||||||
/* In this state is LIST response successfully parsed, so lets restore
|
/* In this state is LIST response successfully parsed, so lets restore
|
||||||
previous WRITEFUNCTION callback and WRITEDATA pointer */
|
previous WRITEFUNCTION callback and WRITEDATA pointer */
|
||||||
ftp_tmp = wildcard->tmp;
|
struct ftp_wc_tmpdata *ftp_tmp = wildcard->tmp;
|
||||||
conn->data->set.fwrite_func = ftp_tmp->backup.write_function;
|
conn->data->set.fwrite_func = ftp_tmp->backup.write_function;
|
||||||
conn->data->set.out = ftp_tmp->backup.file_descriptor;
|
conn->data->set.out = ftp_tmp->backup.file_descriptor;
|
||||||
wildcard->state = CURLWC_DOWNLOADING;
|
wildcard->state = CURLWC_DOWNLOADING;
|
||||||
@ -3598,13 +3596,14 @@ static CURLcode wc_statemach(struct connectdata *conn)
|
|||||||
wildcard->state = CURLWC_CLEAN;
|
wildcard->state = CURLWC_CLEAN;
|
||||||
return CURLE_REMOTE_FILE_NOT_FOUND;
|
return CURLE_REMOTE_FILE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
ret = wc_statemach(conn);
|
return wc_statemach(conn);
|
||||||
break;
|
} break;
|
||||||
|
|
||||||
case CURLWC_DOWNLOADING: {
|
case CURLWC_DOWNLOADING: {
|
||||||
/* filelist has at least one file, lets get first one */
|
/* filelist has at least one file, lets get first one */
|
||||||
|
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||||
struct curl_fileinfo *finfo = wildcard->filelist->head->ptr;
|
struct curl_fileinfo *finfo = wildcard->filelist->head->ptr;
|
||||||
tmp_path = malloc(strlen(conn->data->state.path) +
|
char *tmp_path = malloc(strlen(conn->data->state.path) +
|
||||||
strlen(finfo->filename) + 1);
|
strlen(finfo->filename) + 1);
|
||||||
if(!tmp_path) {
|
if(!tmp_path) {
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
@ -3623,7 +3622,7 @@ static CURLcode wc_statemach(struct connectdata *conn)
|
|||||||
|
|
||||||
infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename);
|
infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename);
|
||||||
if(conn->data->set.chunk_bgn) {
|
if(conn->data->set.chunk_bgn) {
|
||||||
userresponse = conn->data->set.chunk_bgn(
|
long userresponse = conn->data->set.chunk_bgn(
|
||||||
finfo, wildcard->customptr, (int)wildcard->filelist->size);
|
finfo, wildcard->customptr, (int)wildcard->filelist->size);
|
||||||
switch(userresponse) {
|
switch(userresponse) {
|
||||||
case CURL_CHUNK_BGN_FUNC_SKIP:
|
case CURL_CHUNK_BGN_FUNC_SKIP:
|
||||||
@ -3666,16 +3665,17 @@ static CURLcode wc_statemach(struct connectdata *conn)
|
|||||||
Curl_llist_remove(wildcard->filelist, wildcard->filelist->head, NULL);
|
Curl_llist_remove(wildcard->filelist, wildcard->filelist->head, NULL);
|
||||||
wildcard->state = (wildcard->filelist->size == 0) ?
|
wildcard->state = (wildcard->filelist->size == 0) ?
|
||||||
CURLWC_CLEAN : CURLWC_DOWNLOADING;
|
CURLWC_CLEAN : CURLWC_DOWNLOADING;
|
||||||
ret = wc_statemach(conn);
|
return wc_statemach(conn);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case CURLWC_CLEAN:
|
case CURLWC_CLEAN: {
|
||||||
|
struct ftp_wc_tmpdata *ftp_tmp = wildcard->tmp;
|
||||||
ret = CURLE_OK;
|
ret = CURLE_OK;
|
||||||
if(ftp_tmp) {
|
if(ftp_tmp) {
|
||||||
ret = Curl_ftp_parselist_geterror(ftp_tmp->parser);
|
ret = Curl_ftp_parselist_geterror(ftp_tmp->parser);
|
||||||
}
|
}
|
||||||
wildcard->state = ret ? CURLWC_ERROR : CURLWC_DONE;
|
wildcard->state = ret ? CURLWC_ERROR : CURLWC_DONE;
|
||||||
break;
|
} break;
|
||||||
|
|
||||||
case CURLWC_DONE:
|
case CURLWC_DONE:
|
||||||
case CURLWC_ERROR:
|
case CURLWC_ERROR:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user