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