From 995424298052fa02ac82a584ee4247939503f24a Mon Sep 17 00:00:00 2001 From: Colin Hogben Date: Thu, 23 Feb 2012 09:43:37 +0000 Subject: Generate lists and use symbols in --libcurl code output. This patch improves the output of curl's --libcurl option by generating code which builds curl_httppost and curl_slist lists, and uses symbolic names for enum and flag values. Variants of the my_setopt macro in tool_setopt.h are added in order to pass extra type information to the code-generation step in tool_setopt.c. If curl is configured with --disable-libcurl-option then the macros call curl_easy_setopt directly. --- src/tool_easysrc.c | 162 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 138 insertions(+), 24 deletions(-) (limited to 'src/tool_easysrc.c') diff --git a/src/tool_easysrc.c b/src/tool_easysrc.c index ba1e78e0d..f672386a1 100644 --- a/src/tool_easysrc.c +++ b/src/tool_easysrc.c @@ -37,8 +37,13 @@ /* global variable definitions, for easy-interface source code generation */ -struct curl_slist *easysrc = NULL; -struct curl_slist *easysrc_remarks = NULL; +struct curl_slist *easysrc_decl = NULL; /* Variable declarations */ +struct curl_slist *easysrc_data = NULL; /* Build slists, forms etc. */ +struct curl_slist *easysrc_code = NULL; /* Setopt calls */ +struct curl_slist *easysrc_toohard = NULL; /* Unconvertible setopt */ +struct curl_slist *easysrc_clean = NULL; /* Clean up allocated data */ +int easysrc_form_count = 0; +int easysrc_slist_count = 0; static const char *const srchead[]={ "/********* Sample code generated by the curl command line tool **********", @@ -50,8 +55,117 @@ static const char *const srchead[]={ "int main(int argc, char *argv[])", "{", " CURLcode ret;", + " CURL *hnd;", NULL }; +/* easysrc_decl declarations come here */ +/* easysrc_data initialisations come here */ +/* easysrc_code statements come here */ +static const char *const srchard[]={ + "/* Here is a list of options the curl code used that cannot get generated", + " as source easily. You may select to either not use them or implement", + " them yourself.", + "", + NULL +}; +static const char *const srcend[]={ + "", + " return (int)ret;", + "}", + "/**** End of sample code ****/", + NULL +}; + +/* Clean up all source code if we run out of memory */ +static void easysrc_free(void) +{ + curl_slist_free_all(easysrc_decl); + easysrc_decl = NULL; + curl_slist_free_all(easysrc_data); + easysrc_data = NULL; + curl_slist_free_all(easysrc_code); + easysrc_code = NULL; + curl_slist_free_all(easysrc_toohard); + easysrc_toohard = NULL; + curl_slist_free_all(easysrc_clean); + easysrc_clean = NULL; +} + +/* Add a source line to the main code or remarks */ +CURLcode easysrc_add(struct curl_slist **plist, const char *line) +{ + CURLcode ret = CURLE_OK; + struct curl_slist *list = + curl_slist_append(*plist, line); + if(!list) { + easysrc_free(); + ret = CURLE_OUT_OF_MEMORY; + } + else + *plist = list; + return ret; +} + +CURLcode easysrc_addf(struct curl_slist **plist, const char *fmt, ...) +{ + CURLcode ret; + char *bufp; + va_list ap; + va_start(ap, fmt); + bufp = curlx_mvaprintf(fmt, ap); + va_end(ap); + if(! bufp) { + ret = CURLE_OUT_OF_MEMORY; + } + else { + ret = easysrc_add(plist, bufp); + curl_free(bufp); + } + return ret; +} + +#define CHKRET(v) do {CURLcode ret = (v); if(ret) return ret;} while(0) + +CURLcode easysrc_init(void) +{ + CHKRET(easysrc_add(&easysrc_code, + "hnd = curl_easy_init();")); + return CURLE_OK; +} + +CURLcode easysrc_perform(void) +{ + /* Note any setopt calls which we could not convert */ + if(easysrc_toohard) { + int i; + struct curl_slist *ptr; + const char *c; + CHKRET(easysrc_add(&easysrc_code, "")); + /* Preamble comment */ + for(i=0; ((c = srchard[i]) != '\0'); i++) + CHKRET(easysrc_add(&easysrc_code, c)); + /* Each unconverted option */ + for(ptr=easysrc_toohard; ptr; ptr = ptr->next) + CHKRET(easysrc_add(&easysrc_code, ptr->data)); + CHKRET(easysrc_add(&easysrc_code, "")); + CHKRET(easysrc_add(&easysrc_code, "*/")); + + curl_slist_free_all(easysrc_toohard); + easysrc_toohard = NULL; + } + + CHKRET(easysrc_add(&easysrc_code, "")); + CHKRET(easysrc_add(&easysrc_code, "ret = curl_easy_perform(hnd);")); + return CURLE_OK; +} + +CURLcode easysrc_cleanup(void) +{ + CHKRET(easysrc_add(&easysrc_code, "")); + CHKRET(easysrc_add(&easysrc_code, "curl_easy_cleanup(hnd);")); + CHKRET(easysrc_add(&easysrc_code, "hnd = NULL;")); + return CURLE_OK; +} void dumpeasysrc(struct Configurable *config) { @@ -76,40 +190,40 @@ void dumpeasysrc(struct Configurable *config) for(i=0; ((c = srchead[i]) != '\0'); i++) fprintf(out, "%s\n", c); - ptr = easysrc; - while(ptr) { + /* Declare variables used for complex setopt values */ + for(ptr=easysrc_decl; ptr; ptr = ptr->next) fprintf(out, " %s\n", ptr->data); - ptr = ptr->next; + + /* Set up complex values for setopt calls */ + if(easysrc_data) { + fprintf(out, "\n"); + + for(ptr=easysrc_data; ptr; ptr = ptr->next) + fprintf(out, " %s\n", ptr->data); } - ptr = easysrc_remarks; - if(ptr) { - fprintf(out, - "\n /* Here is a list of options the curl code" - " used that cannot get generated\n" - " as source easily. You may select to either" - " not use them or implement\n them yourself.\n" - "\n"); - while(ptr) { + fprintf(out, "\n"); + for(ptr=easysrc_code; ptr; ptr = ptr->next) { + if(ptr->data[0]) { fprintf(out, " %s\n", ptr->data); - ptr = ptr->next; } - fprintf(out, "\n */\n"); + else { + fprintf(out, "\n"); + } } - fprintf(out, - " return (int)ret;\n" - "}\n" - "/**** End of sample code ****/\n"); + for(ptr=easysrc_clean; ptr; ptr = ptr->next) + fprintf(out, " %s\n", ptr->data); + + for(i=0; ((c = srcend[i]) != '\0'); i++) + fprintf(out, "%s\n", c); + if(fopened) fclose(out); } } - curl_slist_free_all(easysrc_remarks); - curl_slist_free_all(easysrc); - easysrc_remarks = NULL; - easysrc = NULL; + easysrc_free(); } #endif /* CURL_DISABLE_LIBCURL_OPTION */ -- cgit v1.2.3