tool_easysrc.c 6.3 KB

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