Home | History | Annotate | Download | only in src
      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel (at) 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 */
     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 */
     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 
    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 
    127 CURLcode easysrc_init(void)
    128 {
    129   CHKRET(easysrc_add(&easysrc_code,
    130                      "hnd = curl_easy_init();"));
    131   return CURLE_OK;
    132 }
    133 
    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 
    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 
    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