aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Fandrich <dan@coneharvesters.com>2010-10-20 18:15:14 -0700
committerDan Fandrich <dan@coneharvesters.com>2010-10-20 18:27:56 -0700
commit59f07ddf28245da62c24c4913b4f285c94393aa4 (patch)
treee7e057504846b2ba6332b5a2e68e523723175710
parente214cd4a7323e0326bb9a731c4effdbb4082c85f (diff)
Lightened the stack in wc_statemach to permit deeper recursion
Also, added a few hints to help compilers to perform tail call recursion optimization.
-rw-r--r--lib/ftp.c28
1 files changed, 14 insertions, 14 deletions
diff --git a/lib/ftp.c b/lib/ftp.c
index 60d951722..b5a4fd5be 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -3562,14 +3562,12 @@ static CURLcode init_wc_data(struct connectdata *conn)
return CURLE_OK;
}
+/* This is called recursively */
static CURLcode wc_statemach(struct connectdata *conn)
{
- struct ftp_conn *ftpc = &conn->proto.ftpc;
- struct WildcardData *wildcard = &(conn->data->wildcard);
- struct ftp_wc_tmpdata *ftp_tmp = wildcard->tmp;
- char *tmp_path;
+ struct WildcardData * const wildcard = &(conn->data->wildcard);
CURLcode ret = CURLE_OK;
- long userresponse = 0;
+
switch (wildcard->state) {
case CURLWC_INIT:
ret = init_wc_data(conn);
@@ -3580,10 +3578,10 @@ static CURLcode wc_statemach(struct connectdata *conn)
wildcard->state = ret ? CURLWC_ERROR : CURLWC_MATCHING;
break;
- case CURLWC_MATCHING:
+ case CURLWC_MATCHING: {
/* In this state is LIST response successfully parsed, so lets restore
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.out = ftp_tmp->backup.file_descriptor;
wildcard->state = CURLWC_DOWNLOADING;
@@ -3598,13 +3596,14 @@ static CURLcode wc_statemach(struct connectdata *conn)
wildcard->state = CURLWC_CLEAN;
return CURLE_REMOTE_FILE_NOT_FOUND;
}
- ret = wc_statemach(conn);
- break;
+ return wc_statemach(conn);
+ } break;
case CURLWC_DOWNLOADING: {
/* 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;
- tmp_path = malloc(strlen(conn->data->state.path) +
+ char *tmp_path = malloc(strlen(conn->data->state.path) +
strlen(finfo->filename) + 1);
if(!tmp_path) {
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);
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);
switch(userresponse) {
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);
wildcard->state = (wildcard->filelist->size == 0) ?
CURLWC_CLEAN : CURLWC_DOWNLOADING;
- ret = wc_statemach(conn);
+ return wc_statemach(conn);
} break;
- case CURLWC_CLEAN:
+ case CURLWC_CLEAN: {
+ struct ftp_wc_tmpdata *ftp_tmp = wildcard->tmp;
ret = CURLE_OK;
if(ftp_tmp) {
ret = Curl_ftp_parselist_geterror(ftp_tmp->parser);
}
wildcard->state = ret ? CURLWC_ERROR : CURLWC_DONE;
- break;
+ } break;
case CURLWC_DONE:
case CURLWC_ERROR: