Merge branch 'js/commit-slab-decl-fix'
authorJunio C Hamano <gitster@pobox.com>
Wed, 10 Aug 2016 19:33:20 +0000 (12:33 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 10 Aug 2016 19:33:20 +0000 (12:33 -0700)
* js/commit-slab-decl-fix:
commit-slab.h: avoid duplicated global static variables
config.c: avoid duplicated global static variables

1  2 
builtin/config.c
commit-slab.h
diff --combined builtin/config.c
index a991a53418506f18f439212f8cfe1f6f994ea571,e4d96313d79d8ca8dede8f89becaa2b94f909d24..6cbf73369b2f6cf41430d78e0a5e8ffa18de6d15
@@@ -3,7 -3,6 +3,7 @@@
  #include "color.h"
  #include "parse-options.h"
  #include "urlmatch.h"
 +#include "quote.h"
  
  static const char *const builtin_config_usage[] = {
        N_("git config [<options>]"),
@@@ -14,7 -13,6 +14,7 @@@ static char *key
  static regex_t *key_regexp;
  static regex_t *regexp;
  static int show_keys;
 +static int omit_values;
  static int use_key_regexp;
  static int do_all;
  static int do_not_match;
@@@ -25,10 -23,8 +25,9 @@@ static char term = '\n'
  static int use_global_config, use_system_config, use_local_config;
  static struct git_config_source given_config_source;
  static int actions, types;
- static const char *get_color_slot, *get_colorbool_slot;
  static int end_null;
  static int respect_includes = -1;
 +static int show_origin;
  
  #define ACTION_GET (1<<0)
  #define ACTION_GET_ALL (1<<1)
@@@ -81,9 -77,7 +80,9 @@@ static struct option builtin_config_opt
        OPT_BIT(0, "path", &types, N_("value is a path (file or directory name)"), TYPE_PATH),
        OPT_GROUP(N_("Other")),
        OPT_BOOL('z', "null", &end_null, N_("terminate values with NUL byte")),
 +      OPT_BOOL(0, "name-only", &omit_values, N_("show variable names only")),
        OPT_BOOL(0, "includes", &respect_includes, N_("respect include directives on lookup")),
 +      OPT_BOOL(0, "show-origin", &show_origin, N_("show origin of config (file, standard input, blob, command line)")),
        OPT_END(),
  };
  
@@@ -94,29 -88,9 +93,29 @@@ static void check_argc(int argc, int mi
        usage_with_options(builtin_config_usage, builtin_config_options);
  }
  
 +static void show_config_origin(struct strbuf *buf)
 +{
 +      const char term = end_null ? '\0' : '\t';
 +
 +      strbuf_addstr(buf, current_config_origin_type());
 +      strbuf_addch(buf, ':');
 +      if (end_null)
 +              strbuf_addstr(buf, current_config_name());
 +      else
 +              quote_c_style(current_config_name(), buf, NULL, 0);
 +      strbuf_addch(buf, term);
 +}
 +
  static int show_all_config(const char *key_, const char *value_, void *cb)
  {
 -      if (value_)
 +      if (show_origin) {
 +              struct strbuf buf = STRBUF_INIT;
 +              show_config_origin(&buf);
 +              /* Use fwrite as "buf" can contain \0's if "end_null" is set. */
 +              fwrite(buf.buf, 1, buf.len, stdout);
 +              strbuf_release(&buf);
 +      }
 +      if (!omit_values && value_)
                printf("%s%c%s%c", key_, delim, value_, term);
        else
                printf("%s%c", key_, term);
@@@ -131,42 -105,48 +130,42 @@@ struct strbuf_list 
  
  static int format_config(struct strbuf *buf, const char *key_, const char *value_)
  {
 -      int must_free_vptr = 0;
 -      int must_print_delim = 0;
 -      char value[256];
 -      const char *vptr = value;
 -
 -      strbuf_init(buf, 0);
 -
 -      if (show_keys) {
 +      if (show_origin)
 +              show_config_origin(buf);
 +      if (show_keys)
                strbuf_addstr(buf, key_);
 -              must_print_delim = 1;
 -      }
 -      if (types == TYPE_INT)
 -              sprintf(value, "%"PRId64,
 -                      git_config_int64(key_, value_ ? value_ : ""));
 -      else if (types == TYPE_BOOL)
 -              vptr = git_config_bool(key_, value_) ? "true" : "false";
 -      else if (types == TYPE_BOOL_OR_INT) {
 -              int is_bool, v;
 -              v = git_config_bool_or_int(key_, value_, &is_bool);
 -              if (is_bool)
 -                      vptr = v ? "true" : "false";
 -              else
 -                      sprintf(value, "%d", v);
 -      } else if (types == TYPE_PATH) {
 -              if (git_config_pathname(&vptr, key_, value_) < 0)
 -                      return -1;
 -              must_free_vptr = 1;
 -      } else if (value_) {
 -              vptr = value_;
 -      } else {
 -              /* Just show the key name */
 -              vptr = "";
 -              must_print_delim = 0;
 -      }
 +      if (!omit_values) {
 +              if (show_keys)
 +                      strbuf_addch(buf, key_delim);
  
 -      if (must_print_delim)
 -              strbuf_addch(buf, key_delim);
 -      strbuf_addstr(buf, vptr);
 +              if (types == TYPE_INT)
 +                      strbuf_addf(buf, "%"PRId64,
 +                                  git_config_int64(key_, value_ ? value_ : ""));
 +              else if (types == TYPE_BOOL)
 +                      strbuf_addstr(buf, git_config_bool(key_, value_) ?
 +                                    "true" : "false");
 +              else if (types == TYPE_BOOL_OR_INT) {
 +                      int is_bool, v;
 +                      v = git_config_bool_or_int(key_, value_, &is_bool);
 +                      if (is_bool)
 +                              strbuf_addstr(buf, v ? "true" : "false");
 +                      else
 +                              strbuf_addf(buf, "%d", v);
 +              } else if (types == TYPE_PATH) {
 +                      const char *v;
 +                      if (git_config_pathname(&v, key_, value_) < 0)
 +                              return -1;
 +                      strbuf_addstr(buf, v);
 +                      free((char *)v);
 +              } else if (value_) {
 +                      strbuf_addstr(buf, value_);
 +              } else {
 +                      /* Just show the key name; back out delimiter */
 +                      if (show_keys)
 +                              strbuf_setlen(buf, buf->len - 1);
 +              }
 +      }
        strbuf_addch(buf, term);
 -
 -      if (must_free_vptr)
 -              free((char *)vptr);
        return 0;
  }
  
@@@ -183,7 -163,6 +182,7 @@@ static int collect_config(const char *k
                return 0;
  
        ALLOC_GROW(values->items, values->nr + 1, values->alloc);
 +      strbuf_init(&values->items[values->nr], 0);
  
        return format_config(&values->items[values->nr++], key_, value_);
  }
@@@ -213,7 -192,7 +212,7 @@@ static int get_value(const char *key_, 
  
                key_regexp = (regex_t*)xmalloc(sizeof(regex_t));
                if (regcomp(key_regexp, key, REG_EXTENDED)) {
 -                      fprintf(stderr, "Invalid key pattern: %s\n", key_);
 +                      error("invalid key pattern: %s", key_);
                        free(key_regexp);
                        key_regexp = NULL;
                        ret = CONFIG_INVALID_PATTERN;
  
                regexp = (regex_t*)xmalloc(sizeof(regex_t));
                if (regcomp(regexp, regex_, REG_EXTENDED)) {
 -                      fprintf(stderr, "Invalid pattern: %s\n", regex_);
 +                      error("invalid pattern: %s", regex_);
                        free(regexp);
                        regexp = NULL;
                        ret = CONFIG_INVALID_PATTERN;
@@@ -271,6 -250,8 +270,6 @@@ free_strings
  
  static char *normalize_value(const char *key, const char *value)
  {
 -      char *normalized;
 -
        if (!value)
                return NULL;
  
                 * "~/foobar/" in the config file, and to expand the ~
                 * when retrieving the value.
                 */
 -              normalized = xstrdup(value);
 -      else {
 -              normalized = xmalloc(64);
 -              if (types == TYPE_INT) {
 -                      int64_t v = git_config_int64(key, value);
 -                      sprintf(normalized, "%"PRId64, v);
 -              }
 -              else if (types == TYPE_BOOL)
 -                      sprintf(normalized, "%s",
 -                              git_config_bool(key, value) ? "true" : "false");
 -              else if (types == TYPE_BOOL_OR_INT) {
 -                      int is_bool, v;
 -                      v = git_config_bool_or_int(key, value, &is_bool);
 -                      if (!is_bool)
 -                              sprintf(normalized, "%d", v);
 -                      else
 -                              sprintf(normalized, "%s", v ? "true" : "false");
 -              }
 +              return xstrdup(value);
 +      if (types == TYPE_INT)
 +              return xstrfmt("%"PRId64, git_config_int64(key, value));
 +      if (types == TYPE_BOOL)
 +              return xstrdup(git_config_bool(key, value) ?  "true" : "false");
 +      if (types == TYPE_BOOL_OR_INT) {
 +              int is_bool, v;
 +              v = git_config_bool_or_int(key, value, &is_bool);
 +              if (!is_bool)
 +                      return xstrfmt("%d", v);
 +              else
 +                      return xstrdup(v ? "true" : "false");
        }
  
 -      return normalized;
 +      die("BUG: cannot normalize type %d", types);
  }
  
  static int get_color_found;
@@@ -377,9 -364,6 +376,9 @@@ static int get_colorbool(const char *va
  
  static void check_write(void)
  {
 +      if (!given_config_source.file && !startup_info->have_repository)
 +              die("not in a git directory");
 +
        if (given_config_source.use_stdin)
                die("writing to stdin is not supported");
  
@@@ -417,7 -401,6 +416,7 @@@ static int urlmatch_collect_fn(const ch
  
  static int get_urlmatch(const char *var, const char *url)
  {
 +      int ret;
        char *section_tail;
        struct string_list_item *item;
        struct urlmatch_config config = { STRING_LIST_INIT_DUP };
        git_config_with_options(urlmatch_config_entry, &config,
                                &given_config_source, respect_includes);
  
 +      ret = !values.nr;
 +
        for_each_string_list_item(item, &values) {
                struct urlmatch_current_candidate_value *matched = item->util;
 -              struct strbuf key = STRBUF_INIT;
                struct strbuf buf = STRBUF_INIT;
  
 -              strbuf_addstr(&key, item->string);
 -              format_config(&buf, key.buf,
 +              format_config(&buf, item->string,
                              matched->value_is_null ? NULL : matched->value.buf);
                fwrite(buf.buf, 1, buf.len, stdout);
 -              strbuf_release(&key);
                strbuf_release(&buf);
  
                strbuf_release(&matched->value);
        free(config.url.url);
  
        free((void *)config.section);
 -      return 0;
 +      return ret;
  }
  
  static char *default_user_config(void)
@@@ -564,18 -548,6 +563,18 @@@ int cmd_config(int argc, const char **a
                default:
                        usage_with_options(builtin_config_usage, builtin_config_options);
                }
 +      if (omit_values &&
 +          !(actions == ACTION_LIST || actions == ACTION_GET_REGEXP)) {
 +              error("--name-only is only applicable to --list or --get-regexp");
 +              usage_with_options(builtin_config_usage, builtin_config_options);
 +      }
 +
 +      if (show_origin && !(actions &
 +              (ACTION_GET|ACTION_GET_ALL|ACTION_GET_REGEXP|ACTION_LIST))) {
 +              error("--show-origin is only applicable to --get, --get-all, "
 +                        "--get-regexp, and --list.");
 +              usage_with_options(builtin_config_usage, builtin_config_options);
 +      }
  
        if (actions == ACTION_LIST) {
                check_argc(argc, 0, 0);
                                      given_config_source.file : git_path("config"));
                if (use_global_config) {
                        int fd = open(config_file, O_CREAT | O_EXCL | O_WRONLY, 0666);
 -                      if (fd) {
 +                      if (fd >= 0) {
                                char *content = default_user_config();
                                write_str_in_full(fd, content);
                                free(content);
                check_write();
                check_argc(argc, 2, 2);
                value = normalize_value(argv[0], argv[1]);
 -              ret = git_config_set_in_file(given_config_source.file, argv[0], value);
 +              ret = git_config_set_in_file_gently(given_config_source.file, argv[0], value);
                if (ret == CONFIG_NOTHING_SET)
                        error("cannot overwrite multiple values with a single value\n"
                        "       Use a regexp, --add or --replace-all to change %s.", argv[0]);
                check_write();
                check_argc(argc, 2, 3);
                value = normalize_value(argv[0], argv[1]);
 -              return git_config_set_multivar_in_file(given_config_source.file,
 -                                                     argv[0], value, argv[2], 0);
 +              return git_config_set_multivar_in_file_gently(given_config_source.file,
 +                                                            argv[0], value, argv[2], 0);
        }
        else if (actions == ACTION_ADD) {
                check_write();
                check_argc(argc, 2, 2);
                value = normalize_value(argv[0], argv[1]);
 -              return git_config_set_multivar_in_file(given_config_source.file,
 -                                                     argv[0], value,
 -                                                     CONFIG_REGEX_NONE, 0);
 +              return git_config_set_multivar_in_file_gently(given_config_source.file,
 +                                                            argv[0], value,
 +                                                            CONFIG_REGEX_NONE, 0);
        }
        else if (actions == ACTION_REPLACE_ALL) {
                check_write();
                check_argc(argc, 2, 3);
                value = normalize_value(argv[0], argv[1]);
 -              return git_config_set_multivar_in_file(given_config_source.file,
 -                                                     argv[0], value, argv[2], 1);
 +              return git_config_set_multivar_in_file_gently(given_config_source.file,
 +                                                            argv[0], value, argv[2], 1);
        }
        else if (actions == ACTION_GET) {
                check_argc(argc, 1, 2);
                check_write();
                check_argc(argc, 1, 2);
                if (argc == 2)
 -                      return git_config_set_multivar_in_file(given_config_source.file,
 -                                                             argv[0], NULL, argv[1], 0);
 +                      return git_config_set_multivar_in_file_gently(given_config_source.file,
 +                                                                    argv[0], NULL, argv[1], 0);
                else
 -                      return git_config_set_in_file(given_config_source.file,
 -                                                    argv[0], NULL);
 +                      return git_config_set_in_file_gently(given_config_source.file,
 +                                                           argv[0], NULL);
        }
        else if (actions == ACTION_UNSET_ALL) {
                check_write();
                check_argc(argc, 1, 2);
 -              return git_config_set_multivar_in_file(given_config_source.file,
 -                                                     argv[0], NULL, argv[1], 1);
 +              return git_config_set_multivar_in_file_gently(given_config_source.file,
 +                                                            argv[0], NULL, argv[1], 1);
        }
        else if (actions == ACTION_RENAME_SECTION) {
                int ret;
diff --combined commit-slab.h
index f84b449413d434b8145426503a98bcd4f9ad995f,c10b2539fa7d378fc2f0cac85fc58c0f1662771d..006a50b5481b552278931f5aec33883d79891a80
   * - int *indegree_at(struct indegree *, struct commit *);
   *
   *   This function locates the data associated with the given commit in
 - *   the indegree slab, and returns the pointer to it.
 + *   the indegree slab, and returns the pointer to it.  The location to
 + *   store the data is allocated as necessary.
 + *
 + * - int *indegree_peek(struct indegree *, struct commit *);
 + *
 + *   This function is similar to indegree_at(), but it will return NULL
 + *   until a call to indegree_at() was made for the commit.
   *
   * - void init_indegree(struct indegree *);
   *   void init_indegree_with_stride(struct indegree *, int);
@@@ -86,9 -80,8 +86,9 @@@ static MAYBE_UNUSED void clear_ ##slabn
        s->slab = NULL;                                                 \
  }                                                                     \
                                                                        \
 -static MAYBE_UNUSED elemtype *slabname## _at(struct slabname *s,      \
 -                                     const struct commit *c)          \
 +static MAYBE_UNUSED elemtype *slabname## _at_peek(struct slabname *s, \
 +                                                const struct commit *c, \
 +                                                int add_if_missing)   \
  {                                                                     \
        int nth_slab, nth_slot;                                         \
                                                                        \
                                                                        \
        if (s->slab_count <= nth_slab) {                                \
                int i;                                                  \
 +              if (!add_if_missing)                                    \
 +                      return NULL;                                    \
                REALLOC_ARRAY(s->slab, nth_slab + 1);                   \
                stat_ ##slabname## realloc++;                           \
                for (i = s->slab_count; i <= nth_slab; i++)             \
                        s->slab[i] = NULL;                              \
                s->slab_count = nth_slab + 1;                           \
        }                                                               \
 -      if (!s->slab[nth_slab])                                         \
 +      if (!s->slab[nth_slab]) {                                       \
 +              if (!add_if_missing)                                    \
 +                      return NULL;                                    \
                s->slab[nth_slab] = xcalloc(s->slab_size,               \
                                            sizeof(**s->slab) * s->stride);             \
 -      return &s->slab[nth_slab][nth_slot * s->stride];                                \
 +      }                                                               \
 +      return &s->slab[nth_slab][nth_slot * s->stride];                \
 +}                                                                     \
 +                                                                      \
 +static MAYBE_UNUSED elemtype *slabname## _at(struct slabname *s,      \
 +                                           const struct commit *c)    \
 +{                                                                     \
 +      return slabname##_at_peek(s, c, 1);                             \
 +}                                                                     \
 +                                                                      \
 +static MAYBE_UNUSED elemtype *slabname## _peek(struct slabname *s,    \
 +                                           const struct commit *c)    \
 +{                                                                     \
 +      return slabname##_at_peek(s, c, 0);                             \
  }                                                                     \
                                                                        \
- static int stat_ ##slabname## realloc
+ struct slabname
  
  /*
-  * Note that this seemingly redundant second declaration is required
+  * Note that this redundant forward declaration is required
   * to allow a terminating semicolon, which makes instantiations look
   * like function declarations.  I.e., the expansion of
   *
   *    define_commit_slab(indegree, int);
   *
-  * ends in 'static int stat_indegreerealloc;'.  This would otherwise
+  * ends in 'struct indegree;'.  This would otherwise
   * be a syntax error according (at least) to ISO C.  It's hard to
   * catch because GCC silently parses it by default.
   */