1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel (at) haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at http://curl.haxx.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 ***************************************************************************/ 22 #include "tool_setup.h" 23 24 #ifndef CURL_DISABLE_LIBCURL_OPTION 25 26 #define ENABLE_CURLX_PRINTF 27 /* use our own printf() functions */ 28 #include "curlx.h" 29 30 #include "tool_cfgable.h" 31 #include "tool_easysrc.h" 32 #include "tool_msgs.h" 33 34 #include "memdebug.h" /* keep this as LAST include */ 35 36 /* global variable definitions, for easy-interface source code generation */ 37 38 struct curl_slist *easysrc_decl = NULL; /* Variable declarations */ 39 struct curl_slist *easysrc_data = NULL; /* Build slists, forms etc. */ 40 struct curl_slist *easysrc_code = NULL; /* Setopt calls */ 41 struct curl_slist *easysrc_toohard = NULL; /* Unconvertible setopt */ 42 struct curl_slist *easysrc_clean = NULL; /* Clean up allocated data */ 43 int easysrc_form_count = 0; 44 int easysrc_slist_count = 0; 45 46 static const char *const srchead[]={ 47 "/********* Sample code generated by the curl command line tool **********", 48 " * All curl_easy_setopt() options are documented at:", 49 " * http://curl.haxx.se/libcurl/c/curl_easy_setopt.html", 50 " ************************************************************************/", 51 "#include <curl/curl.h>", 52 "", 53 "int main(int argc, char *argv[])", 54 "{", 55 " CURLcode ret;", 56 " CURL *hnd;", 57 NULL 58 }; 59 /* easysrc_decl declarations come here */ 60 /* easysrc_data initialisations come here */ 61 /* easysrc_code statements come here */ 62 static const char *const srchard[]={ 63 "/* Here is a list of options the curl code used that cannot get generated", 64 " as source easily. You may select to either not use them or implement", 65 " them yourself.", 66 "", 67 NULL 68 }; 69 static const char *const srcend[]={ 70 "", 71 " return (int)ret;", 72 "}", 73 "/**** End of sample code ****/", 74 NULL 75 }; 76 77 /* Clean up all source code if we run out of memory */ 78 static void easysrc_free(void) 79 { 80 curl_slist_free_all(easysrc_decl); 81 easysrc_decl = NULL; 82 curl_slist_free_all(easysrc_data); 83 easysrc_data = NULL; 84 curl_slist_free_all(easysrc_code); 85 easysrc_code = NULL; 86 curl_slist_free_all(easysrc_toohard); 87 easysrc_toohard = NULL; 88 curl_slist_free_all(easysrc_clean); 89 easysrc_clean = NULL; 90 } 91 92 /* Add a source line to the main code or remarks */ 93 CURLcode easysrc_add(struct curl_slist **plist, const char *line) 94 { 95 CURLcode ret = CURLE_OK; 96 struct curl_slist *list = 97 curl_slist_append(*plist, line); 98 if(!list) { 99 easysrc_free(); 100 ret = CURLE_OUT_OF_MEMORY; 101 } 102 else 103 *plist = list; 104 return ret; 105 } 106 107 CURLcode easysrc_addf(struct curl_slist **plist, const char *fmt, ...) 108 { 109 CURLcode ret; 110 char *bufp; 111 va_list ap; 112 va_start(ap, fmt); 113 bufp = curlx_mvaprintf(fmt, ap); 114 va_end(ap); 115 if(! bufp) { 116 ret = CURLE_OUT_OF_MEMORY; 117 } 118 else { 119 ret = easysrc_add(plist, bufp); 120 curl_free(bufp); 121 } 122 return ret; 123 } 124 125 #define CHKRET(v) do {CURLcode ret = (v); if(ret) return ret;} WHILE_FALSE 126 127 CURLcode easysrc_init(void) 128 { 129 CHKRET(easysrc_add(&easysrc_code, 130 "hnd = curl_easy_init();")); 131 return CURLE_OK; 132 } 133 134 CURLcode easysrc_perform(void) 135 { 136 /* Note any setopt calls which we could not convert */ 137 if(easysrc_toohard) { 138 int i; 139 struct curl_slist *ptr; 140 const char *c; 141 CHKRET(easysrc_add(&easysrc_code, "")); 142 /* Preamble comment */ 143 for(i=0; ((c = srchard[i]) != NULL); i++) 144 CHKRET(easysrc_add(&easysrc_code, c)); 145 /* Each unconverted option */ 146 for(ptr=easysrc_toohard; ptr; ptr = ptr->next) 147 CHKRET(easysrc_add(&easysrc_code, ptr->data)); 148 CHKRET(easysrc_add(&easysrc_code, "")); 149 CHKRET(easysrc_add(&easysrc_code, "*/")); 150 151 curl_slist_free_all(easysrc_toohard); 152 easysrc_toohard = NULL; 153 } 154 155 CHKRET(easysrc_add(&easysrc_code, "")); 156 CHKRET(easysrc_add(&easysrc_code, "ret = curl_easy_perform(hnd);")); 157 CHKRET(easysrc_add(&easysrc_code, "")); 158 159 return CURLE_OK; 160 } 161 162 CURLcode easysrc_cleanup(void) 163 { 164 CHKRET(easysrc_add(&easysrc_code, "curl_easy_cleanup(hnd);")); 165 CHKRET(easysrc_add(&easysrc_code, "hnd = NULL;")); 166 167 return CURLE_OK; 168 } 169 170 void dumpeasysrc(struct GlobalConfig *config) 171 { 172 struct curl_slist *ptr; 173 char *o = config->libcurl; 174 175 if(o) { 176 FILE *out; 177 bool fopened = FALSE; 178 if(strcmp(o, "-")) { 179 out = fopen(o, FOPEN_WRITETEXT); 180 fopened = TRUE; 181 } 182 else 183 out = stdout; 184 if(!out) 185 warnf(config, "Failed to open %s to write libcurl code!\n", o); 186 else { 187 int i; 188 const char *c; 189 190 for(i=0; ((c = srchead[i]) != NULL); i++) 191 fprintf(out, "%s\n", c); 192 193 /* Declare variables used for complex setopt values */ 194 for(ptr=easysrc_decl; ptr; ptr = ptr->next) 195 fprintf(out, " %s\n", ptr->data); 196 197 /* Set up complex values for setopt calls */ 198 if(easysrc_data) { 199 fprintf(out, "\n"); 200 201 for(ptr=easysrc_data; ptr; ptr = ptr->next) 202 fprintf(out, " %s\n", ptr->data); 203 } 204 205 fprintf(out, "\n"); 206 for(ptr=easysrc_code; ptr; ptr = ptr->next) { 207 if(ptr->data[0]) { 208 fprintf(out, " %s\n", ptr->data); 209 } 210 else { 211 fprintf(out, "\n"); 212 } 213 } 214 215 for(ptr=easysrc_clean; ptr; ptr = ptr->next) 216 fprintf(out, " %s\n", ptr->data); 217 218 for(i=0; ((c = srcend[i]) != NULL); i++) 219 fprintf(out, "%s\n", c); 220 221 if(fopened) 222 fclose(out); 223 } 224 } 225 226 easysrc_free(); 227 } 228 229 #endif /* CURL_DISABLE_LIBCURL_OPTION */ 230