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