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 | |
40 | struct slist_wc *easysrc_decl = NULL; /* Variable declarations */ |
41 | struct slist_wc *easysrc_data = NULL; /* Build slists, forms etc. */ |
42 | struct slist_wc *easysrc_code = NULL; /* Setopt calls */ |
43 | struct slist_wc *easysrc_toohard = NULL; /* Unconvertible setopt */ |
44 | struct slist_wc *easysrc_clean = NULL; /* Clean up allocated data */ |
45 | int easysrc_mime_count = 0; |
46 | int easysrc_slist_count = 0; |
47 | |
48 | static 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 */ |
64 | static 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 | }; |
71 | static 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 */ |
80 | static 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 */ |
95 | CURLcode 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 | |
108 | CURLcode 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 | |
128 | CURLcode easysrc_init(void) |
129 | { |
130 | CHKRET(easysrc_add(&easysrc_code, |
131 | "hnd = curl_easy_init();" )); |
132 | return CURLE_OK; |
133 | } |
134 | |
135 | CURLcode 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 | |
165 | CURLcode 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 | |
173 | void 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 | |