xref: /third_party/curl/src/tool_easysrc.c (revision 13498266)
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