From 59f07ddf28245da62c24c4913b4f285c94393aa4 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Wed, 20 Oct 2010 18:15:14 -0700 Subject: Lightened the stack in wc_statemach to permit deeper recursion Also, added a few hints to help compilers to perform tail call recursion optimization. --- lib/ftp.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'lib') 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: -- cgit v1.2.3