1 /***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 1998 - 2015, 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 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 */
easysrc_free(void)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 */
easysrc_add(struct curl_slist ** plist,const char * line)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
easysrc_addf(struct curl_slist ** plist,const char * fmt,...)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
easysrc_init(void)127 CURLcode easysrc_init(void)
128 {
129 CHKRET(easysrc_add(&easysrc_code,
130 "hnd = curl_easy_init();"));
131 return CURLE_OK;
132 }
133
easysrc_perform(void)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
easysrc_cleanup(void)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
dumpeasysrc(struct GlobalConfig * config)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