config.con commit Set the parallel HTTP request limit via an environment variable (3807923)
   1#include <ctype.h>
   2
   3#include "cache.h"
   4
   5#define MAXNAME (256)
   6
   7static FILE *config_file;
   8static int config_linenr;
   9static int get_next_char(void)
  10{
  11        int c;
  12        FILE *f;
  13
  14        c = '\n';
  15        if ((f = config_file) != NULL) {
  16                c = fgetc(f);
  17                if (c == '\n')
  18                        config_linenr++;
  19                if (c == EOF) {
  20                        config_file = NULL;
  21                        c = '\n';
  22                }
  23        }
  24        return c;
  25}
  26
  27static char *parse_value(void)
  28{
  29        static char value[1024];
  30        int quote = 0, comment = 0, len = 0, space = 0;
  31
  32        for (;;) {
  33                int c = get_next_char();
  34                if (len >= sizeof(value))
  35                        return NULL;
  36                if (c == '\n') {
  37                        if (quote)
  38                                return NULL;
  39                        value[len] = 0;
  40                        return value;
  41                }
  42                if (comment)
  43                        continue;
  44                if (isspace(c) && !quote) {
  45                        space = 1;
  46                        continue;
  47                }
  48                if (space) {
  49                        if (len)
  50                                value[len++] = ' ';
  51                        space = 0;
  52                }
  53                if (c == '\\') {
  54                        c = get_next_char();
  55                        switch (c) {
  56                        case '\n':
  57                                continue;
  58                        case 't':
  59                                c = '\t';
  60                                break;
  61                        case 'b':
  62                                c = '\b';
  63                                break;
  64                        case 'n':
  65                                c = '\n';
  66                                break;
  67                        return NULL;
  68                        }
  69                        value[len++] = c;
  70                        continue;
  71                }
  72                if (c == '"') {
  73                        quote = 1-quote;
  74                        continue;
  75                }
  76                if (!quote) {
  77                        if (c == ';' || c == '#') {
  78                                comment = 1;
  79                                continue;
  80                        }
  81                }
  82                value[len++] = c;
  83        }
  84}
  85
  86static int get_value(config_fn_t fn, char *name, unsigned int len)
  87{
  88        int c;
  89        char *value;
  90
  91        /* Get the full name */
  92        for (;;) {
  93                c = get_next_char();
  94                if (c == EOF)
  95                        break;
  96                if (!isalnum(c))
  97                        break;
  98                name[len++] = tolower(c);
  99                if (len >= MAXNAME)
 100                        return -1;
 101        }
 102        name[len] = 0;
 103        while (c == ' ' || c == '\t')
 104                c = get_next_char();
 105
 106        value = NULL;
 107        if (c != '\n') {
 108                if (c != '=')
 109                        return -1;
 110                value = parse_value();
 111                if (!value)
 112                        return -1;
 113        }
 114        return fn(name, value);
 115}
 116
 117static int get_base_var(char *name)
 118{
 119        int baselen = 0;
 120
 121        for (;;) {
 122                int c = get_next_char();
 123                if (c == EOF)
 124                        return -1;
 125                if (c == ']')
 126                        return baselen;
 127                if (!isalnum(c))
 128                        return -1;
 129                if (baselen > MAXNAME / 2)
 130                        return -1;
 131                name[baselen++] = tolower(c);
 132        }
 133}
 134
 135static int git_parse_file(config_fn_t fn)
 136{
 137        int comment = 0;
 138        int baselen = 0;
 139        static char var[MAXNAME];
 140
 141        for (;;) {
 142                int c = get_next_char();
 143                if (c == '\n') {
 144                        /* EOF? */
 145                        if (!config_file)
 146                                return 0;
 147                        comment = 0;
 148                        continue;
 149                }
 150                if (comment || isspace(c))
 151                        continue;
 152                if (c == '#' || c == ';') {
 153                        comment = 1;
 154                        continue;
 155                }
 156                if (c == '[') {
 157                        baselen = get_base_var(var);
 158                        if (baselen <= 0)
 159                                break;
 160                        var[baselen++] = '.';
 161                        var[baselen] = 0;
 162                        continue;
 163                }
 164                if (!isalpha(c))
 165                        break;
 166                var[baselen] = c;
 167                if (get_value(fn, var, baselen+1) < 0)
 168                        break;
 169        }
 170        die("bad config file line %d", config_linenr);
 171}
 172
 173int git_config_int(const char *name, const char *value)
 174{
 175        if (value && *value) {
 176                char *end;
 177                int val = strtol(value, &end, 0);
 178                if (!*end)
 179                        return val;
 180        }
 181        die("bad config value for '%s'", name);
 182}
 183
 184int git_config_bool(const char *name, const char *value)
 185{
 186        if (!value)
 187                return 1;
 188        if (!*value)
 189                return 0;
 190        if (!strcasecmp(value, "true"))
 191                return 1;
 192        if (!strcasecmp(value, "false"))
 193                return 0;
 194        return git_config_int(name, value) != 0;
 195}
 196
 197int git_default_config(const char *var, const char *value)
 198{
 199        /* This needs a better name */
 200        if (!strcmp(var, "core.filemode")) {
 201                trust_executable_bit = git_config_bool(var, value);
 202                return 0;
 203        }
 204
 205        /* Add other config variables here.. */
 206        return 0;
 207}
 208
 209int git_config(config_fn_t fn)
 210{
 211        int ret;
 212        FILE *f = fopen(git_path("config"), "r");
 213
 214        ret = -1;
 215        if (f) {
 216                config_file = f;
 217                config_linenr = 1;
 218                ret = git_parse_file(fn);
 219                fclose(f);
 220        }
 221        return ret;
 222}