Imported Upstream version 7.40.0
[platform/upstream/curl.git] / src / tool_parsecfg.c
index 680688a..c5d390b 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
 #include "memdebug.h" /* keep this as LAST include */
 
 #define CURLRC DOT_CHAR "curlrc"
-#define ISSEP(x) (((x) == '=') || ((x) == ':'))
+
+/* only acknowledge colon or equals as separators if the option was not
+   specified with an initial dash! */
+#define ISSEP(x,dash) (!dash && (((x) == '=') || ((x) == ':')))
 
 static const char *unslashquote(const char *line, char *param);
 static char *my_get_line(FILE *fp);
 
 /* return 0 on everything-is-fine, and non-zero otherwise */
-int parseconfig(const char *filename,
-                struct Configurable *config)
+int parseconfig(const char *filename, struct GlobalConfig *global)
 {
   int res;
   FILE *file;
@@ -50,6 +52,7 @@ int parseconfig(const char *filename,
   bool usedarg;
   char *home;
   int rc = 0;
+  struct OperationConfig *operation = global->first;
 
   if(!filename || !*filename) {
     /* NULL or no file name attempts to load .curlrc from the homedir! */
@@ -123,6 +126,7 @@ int parseconfig(const char *filename,
     char *param;
     int lineno = 0;
     bool alloced_param;
+    bool dashed_option;
 
     while(NULL != (aline = my_get_line(file))) {
       lineno++;
@@ -146,7 +150,11 @@ int parseconfig(const char *filename,
 
       /* the option keywords starts here */
       option = line;
-      while(*line && !ISSPACE(*line) && !ISSEP(*line))
+
+      /* the option starts with a dash? */
+      dashed_option = option[0]=='-'?TRUE:FALSE;
+
+      while(*line && !ISSPACE(*line) && !ISSEP(*line, dashed_option))
         line++;
       /* ... and has ended here */
 
@@ -158,7 +166,7 @@ int parseconfig(const char *filename,
 #endif
 
       /* pass spaces and separator(s) */
-      while(*line && (ISSPACE(*line) || ISSEP(*line)))
+      while(*line && (ISSPACE(*line) || ISSEP(*line, dashed_option)))
         line++;
 
       /* the parameter starts here (unless quoted) */
@@ -180,9 +188,27 @@ int parseconfig(const char *filename,
         while(*line && !ISSPACE(*line))
           line++;
         *line = '\0'; /* zero terminate */
+
+        /* to detect mistakes better, see if there's data following */
+        line++;
+        /* pass all spaces */
+        while(*line && ISSPACE(*line))
+          line++;
+
+        switch(*line) {
+        case '\0':
+        case '\r':
+        case '\n':
+        case '#': /* comment */
+          break;
+        default:
+          warnf(operation, "%s:%d: warning: '%s' uses unquoted white space in"
+                " the line that may cause side-effects!\n",
+                filename, lineno, option);
+        }
       }
 
-      if(param && !*param) {
+      if(!*param) {
         /* do this so getparameter can check for required parameters.
            Otherwise it always thinks there's a parameter. */
         if(alloced_param)
@@ -193,20 +219,49 @@ int parseconfig(const char *filename,
 #ifdef DEBUG_CONFIG
       fprintf(stderr, "PARAM: \"%s\"\n",(param ? param : "(null)"));
 #endif
-      res = getparameter(option, param, &usedarg, config);
+      res = getparameter(option, param, &usedarg, global, operation);
 
       if(param && *param && !usedarg)
         /* we passed in a parameter that wasn't used! */
         res = PARAM_GOT_EXTRA_PARAMETER;
 
-      if(res != PARAM_OK) {
+      if(res == PARAM_NEXT_OPERATION) {
+        if(operation->url_list && operation->url_list->url) {
+          /* Allocate the next config */
+          operation->next = malloc(sizeof(struct OperationConfig));
+          if(operation->next) {
+            /* Initialise the newly created config */
+            config_init(operation->next);
+
+            /* Copy the easy handle */
+            operation->next->easy = global->easy;
+
+            /* Set the global config pointer */
+            operation->next->global = global;
+
+            /* Update the last operation pointer */
+            global->last = operation->next;
+
+            /* Move onto the new config */
+            operation->next->prev = operation;
+            operation = operation->next;
+          }
+          else
+            res = PARAM_NO_MEM;
+        }
+      }
+
+      if(res != PARAM_OK && res != PARAM_NEXT_OPERATION) {
         /* the help request isn't really an error */
         if(!strcmp(filename, "-")) {
           filename = (char *)"<stdin>";
         }
-        if(PARAM_HELP_REQUESTED != res) {
+        if(res != PARAM_HELP_REQUESTED &&
+           res != PARAM_MANUAL_REQUESTED &&
+           res != PARAM_VERSION_INFO_REQUESTED &&
+           res != PARAM_ENGINES_REQUESTED) {
           const char *reason = param2text(res);
-          warnf(config, "%s:%d: warning: '%s' %s\n",
+          warnf(operation, "%s:%d: warning: '%s' %s\n",
                 filename, lineno, option, reason);
         }
       }