Merge branch 'rs/hex2chr' into maint
authorJunio C Hamano <gitster@pobox.com>
Mon, 19 Sep 2016 20:51:43 +0000 (13:51 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 19 Sep 2016 20:51:43 +0000 (13:51 -0700)
Code cleanup.

* rs/hex2chr:
introduce hex2chr() for converting two hexadecimal digits to a character

1  2 
cache.h
hex.c
pretty.c
diff --combined cache.h
index b780a91a567143ca2cd1283dd441dcc0e00673d4,81af2c2a6b04ae294b772fc9f2cdc84582776f6c..b0dae4bac1a1c22035b175a43c9fe436e789f5d7
+++ b/cache.h
@@@ -632,7 -632,6 +632,7 @@@ extern void fill_stat_cache_info(struc
  #define REFRESH_IGNORE_SUBMODULES     0x0010  /* ignore submodules */
  #define REFRESH_IN_PORCELAIN  0x0020  /* user friendly output, not "needs update" */
  extern int refresh_index(struct index_state *, unsigned int flags, const struct pathspec *pathspec, char *seen, const char *header_msg);
 +extern struct cache_entry *refresh_cache_entry(struct cache_entry *, unsigned int);
  
  extern void update_index_if_able(struct index_state *, struct lock_file *);
  
@@@ -1004,11 -1003,6 +1004,11 @@@ int adjust_shared_perm(const char *path
   * directory while we were working.  To be robust against this kind of
   * race, callers might want to try invoking the function again when it
   * returns SCLD_VANISHED.
 + *
 + * safe_create_leading_directories() temporarily changes path while it
 + * is working but restores it before returning.
 + * safe_create_leading_directories_const() doesn't modify path, even
 + * temporarily.
   */
  enum scld_error {
        SCLD_OK = 0,
@@@ -1139,6 -1133,16 +1139,16 @@@ static inline unsigned int hexval(unsig
        return hexval_table[c];
  }
  
+ /*
+  * Convert two consecutive hexadecimal digits into a char.  Return a
+  * negative value on error.  Don't run over the end of short strings.
+  */
+ static inline int hex2chr(const char *s)
+ {
+       int val = hexval(s[0]);
+       return (val < 0) ? val : (val << 4) | hexval(s[1]);
+ }
  /* Convert to/from hex/sha1 representation */
  #define MINIMUM_ABBREV minimum_abbrev
  #define DEFAULT_ABBREV default_abbrev
@@@ -1199,7 -1203,6 +1209,7 @@@ extern int get_oid_hex(const char *hex
   *   printf("%s -> %s", sha1_to_hex(one), sha1_to_hex(two));
   */
  extern char *sha1_to_hex_r(char *out, const unsigned char *sha1);
 +extern char *oid_to_hex_r(char *out, const struct object_id *oid);
  extern char *sha1_to_hex(const unsigned char *sha1);  /* static buffer result! */
  extern char *oid_to_hex(const struct object_id *oid); /* same static buffer as sha1_to_hex */
  
@@@ -1230,8 -1233,7 +1240,8 @@@ struct date_mode 
                DATE_ISO8601_STRICT,
                DATE_RFC2822,
                DATE_STRFTIME,
 -              DATE_RAW
 +              DATE_RAW,
 +              DATE_UNIX
        } type;
        const char *strftime_fmt;
        int local;
@@@ -1379,13 -1381,6 +1389,13 @@@ extern struct packed_git 
        char pack_name[FLEX_ARRAY]; /* more */
  } *packed_git;
  
 +/*
 + * A most-recently-used ordered version of the packed_git list, which can
 + * be iterated instead of packed_git (and marked via mru_mark).
 + */
 +struct mru;
 +extern struct mru *packed_git_mru;
 +
  struct pack_entry {
        off_t offset;
        unsigned char sha1[20];
@@@ -1425,6 -1420,7 +1435,6 @@@ extern unsigned char *use_pack(struct p
  extern void close_pack_windows(struct packed_git *);
  extern void close_all_packs(void);
  extern void unuse_pack(struct pack_window **);
 -extern void free_pack_by_name(const char *);
  extern void clear_delta_base_cache(void);
  extern struct packed_git *add_packed_git(const char *path, size_t path_len, int local);
  
@@@ -1574,18 -1570,10 +1584,18 @@@ struct git_config_source 
        const char *blob;
  };
  
 +enum config_origin_type {
 +      CONFIG_ORIGIN_BLOB,
 +      CONFIG_ORIGIN_FILE,
 +      CONFIG_ORIGIN_STDIN,
 +      CONFIG_ORIGIN_SUBMODULE_BLOB,
 +      CONFIG_ORIGIN_CMDLINE
 +};
 +
  typedef int (*config_fn_t)(const char *, const char *, void *);
  extern int git_default_config(const char *, const char *, void *);
  extern int git_config_from_file(config_fn_t fn, const char *, void *);
 -extern int git_config_from_mem(config_fn_t fn, const char *origin_type,
 +extern int git_config_from_mem(config_fn_t fn, const enum config_origin_type,
                                        const char *name, const char *buf, size_t len, void *data);
  extern void git_config_push_parameter(const char *text);
  extern int git_config_from_parameters(config_fn_t fn, void *data);
@@@ -1627,16 -1615,6 +1637,16 @@@ extern const char *get_log_output_encod
  extern const char *get_commit_output_encoding(void);
  
  extern int git_config_parse_parameter(const char *, config_fn_t fn, void *data);
 +
 +enum config_scope {
 +      CONFIG_SCOPE_UNKNOWN = 0,
 +      CONFIG_SCOPE_SYSTEM,
 +      CONFIG_SCOPE_GLOBAL,
 +      CONFIG_SCOPE_REPO,
 +      CONFIG_SCOPE_CMDLINE,
 +};
 +
 +extern enum config_scope current_config_scope(void);
  extern const char *current_config_origin_type(void);
  extern const char *current_config_name(void);
  
@@@ -1729,8 -1707,6 +1739,8 @@@ extern int ignore_untracked_cache_confi
  struct key_value_info {
        const char *filename;
        int linenr;
 +      enum config_origin_type origin_type;
 +      enum config_scope scope;
  };
  
  extern NORETURN void git_die_config(const char *key, const char *err, ...) __attribute__((format(printf, 2, 3)));
@@@ -1756,6 -1732,7 +1766,6 @@@ extern int copy_file(const char *dst, c
  extern int copy_file_with_time(const char *dst, const char *src, int mode);
  
  extern void write_or_die(int fd, const void *buf, size_t count);
 -extern int write_or_whine_pipe(int fd, const void *buf, size_t count, const char *msg);
  extern void fsync_or_die(int fd, const char *);
  
  extern ssize_t read_in_full(int fd, void *buf, size_t count);
@@@ -1767,21 -1744,8 +1777,21 @@@ static inline ssize_t write_str_in_full
        return write_in_full(fd, str, strlen(str));
  }
  
 -extern int write_file(const char *path, const char *fmt, ...);
 -extern int write_file_gently(const char *path, const char *fmt, ...);
 +/**
 + * Open (and truncate) the file at path, write the contents of buf to it,
 + * and close it. Dies if any errors are encountered.
 + */
 +extern void write_file_buf(const char *path, const char *buf, size_t len);
 +
 +/**
 + * Like write_file_buf(), but format the contents into a buffer first.
 + * Additionally, write_file() will append a newline if one is not already
 + * present, making it convenient to write text files:
 + *
 + *   write_file(path, "counter: %d", ctr);
 + */
 +__attribute__((format (printf, 2, 3)))
 +extern void write_file(const char *path, const char *fmt, ...);
  
  /* pager.c */
  extern void setup_pager(void);
diff --combined hex.c
index 9619b67af0b79c4ebae4c5e6a5f5748405bd4dea,60541c9d4b5e8e33e3e952ee638fad9e4230799d..ab2610e498615b197787a8c22cd00f979e488fc8
--- 1/hex.c
--- 2/hex.c
+++ b/hex.c
@@@ -39,16 -39,8 +39,8 @@@ int get_sha1_hex(const char *hex, unsig
  {
        int i;
        for (i = 0; i < GIT_SHA1_RAWSZ; i++) {
-               unsigned int val;
-               /*
-                * hex[1]=='\0' is caught when val is checked below,
-                * but if hex[0] is NUL we have to avoid reading
-                * past the end of the string:
-                */
-               if (!hex[0])
-                       return -1;
-               val = (hexval(hex[0]) << 4) | hexval(hex[1]);
-               if (val & ~0xff)
+               int val = hex2chr(hex);
+               if (val < 0)
                        return -1;
                *sha1++ = val;
                hex += 2;
@@@ -77,11 -69,6 +69,11 @@@ char *sha1_to_hex_r(char *buffer, cons
        return buffer;
  }
  
 +char *oid_to_hex_r(char *buffer, const struct object_id *oid)
 +{
 +      return sha1_to_hex_r(buffer, oid->hash);
 +}
 +
  char *sha1_to_hex(const unsigned char *sha1)
  {
        static int bufno;
diff --combined pretty.c
index 9609afb510e2486ae857501a160a9234be87661f,37e74cbb83b8ffeac6f062e73037fbb58430594f..9788bd8f3f0ece03a6b87778a2d43bfaf3c14a9d
+++ b/pretty.c
@@@ -92,7 -92,6 +92,7 @@@ static void setup_commit_formats(void
                { "medium",     CMIT_FMT_MEDIUM,        0,      8 },
                { "short",      CMIT_FMT_SHORT,         0,      0 },
                { "email",      CMIT_FMT_EMAIL,         0,      0 },
 +              { "mboxrd",     CMIT_FMT_MBOXRD,        0,      0 },
                { "fuller",     CMIT_FMT_FULLER,        0,      8 },
                { "full",       CMIT_FMT_FULL,          0,      8 },
                { "oneline",    CMIT_FMT_ONELINE,       1,      0 }
@@@ -445,7 -444,7 +445,7 @@@ void pp_user_info(struct pretty_print_c
        if (pp->mailmap)
                map_user(pp->mailmap, &mailbuf, &maillen, &namebuf, &namelen);
  
 -      if (pp->fmt == CMIT_FMT_EMAIL) {
 +      if (cmit_fmt_is_mail(pp->fmt)) {
                if (pp->from_ident && ident_cmp(pp->from_ident, &ident)) {
                        struct strbuf buf = STRBUF_INIT;
  
                            show_ident_date(&ident, &pp->date_mode));
                break;
        case CMIT_FMT_EMAIL:
 +      case CMIT_FMT_MBOXRD:
                strbuf_addf(sb, "Date: %s\n",
                            show_ident_date(&ident, DATE_MODE(RFC2822)));
                break;
@@@ -537,7 -535,7 +537,7 @@@ static void add_merge_info(const struc
  {
        struct commit_list *parent = commit->parents;
  
 -      if ((pp->fmt == CMIT_FMT_ONELINE) || (pp->fmt == CMIT_FMT_EMAIL) ||
 +      if ((pp->fmt == CMIT_FMT_ONELINE) || (cmit_fmt_is_mail(pp->fmt)) ||
            !parent || !parent->next)
                return;
  
@@@ -1065,7 -1063,7 +1065,7 @@@ static size_t format_commit_one(struct 
        const struct commit *commit = c->commit;
        const char *msg = c->message;
        struct commit_list *p;
-       int h1, h2;
+       int ch;
  
        /* these are independent of the commit */
        switch (placeholder[0]) {
                return 1;
        case 'x':
                /* %x00 == NUL, %x0a == LF, etc. */
-               if (0 <= (h1 = hexval_table[0xff & placeholder[1]]) &&
-                   h1 <= 16 &&
-                   0 <= (h2 = hexval_table[0xff & placeholder[2]]) &&
-                   h2 <= 16) {
-                       strbuf_addch(sb, (h1<<4)|h2);
-                       return 3;
-               } else
+               ch = hex2chr(placeholder + 1);
+               if (ch < 0)
                        return 0;
+               strbuf_addch(sb, ch);
+               return 3;
        case 'w':
                if (placeholder[1] == '(') {
                        unsigned long width = 0, indent1 = 0, indent2 = 0;
                        strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET));
                        return 1;
                }
 -              strbuf_addstr(sb, find_unique_abbrev(commit->object.oid.hash,
 -                                                   c->pretty_ctx->abbrev));
 +              strbuf_add_unique_abbrev(sb, commit->object.oid.hash,
 +                                       c->pretty_ctx->abbrev);
                strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET));
                c->abbrev_commit_hash.len = sb->len - c->abbrev_commit_hash.off;
                return 1;
        case 't':               /* abbreviated tree hash */
                if (add_again(sb, &c->abbrev_tree_hash))
                        return 1;
 -              strbuf_addstr(sb, find_unique_abbrev(commit->tree->object.oid.hash,
 -                                                   c->pretty_ctx->abbrev));
 +              strbuf_add_unique_abbrev(sb, commit->tree->object.oid.hash,
 +                                       c->pretty_ctx->abbrev);
                c->abbrev_tree_hash.len = sb->len - c->abbrev_tree_hash.off;
                return 1;
        case 'P':               /* parent hashes */
                for (p = commit->parents; p; p = p->next) {
                        if (p != commit->parents)
                                strbuf_addch(sb, ' ');
 -                      strbuf_addstr(sb, find_unique_abbrev(
 -                                      p->item->object.oid.hash,
 -                                      c->pretty_ctx->abbrev));
 +                      strbuf_add_unique_abbrev(sb, p->item->object.oid.hash,
 +                                               c->pretty_ctx->abbrev);
                }
                c->abbrev_parent_hashes.len = sb->len -
                                              c->abbrev_parent_hashes.off;
@@@ -1622,7 -1618,7 +1619,7 @@@ void pp_title_line(struct pretty_print_
        if (pp->after_subject) {
                strbuf_addstr(sb, pp->after_subject);
        }
 -      if (pp->fmt == CMIT_FMT_EMAIL) {
 +      if (cmit_fmt_is_mail(pp->fmt)) {
                strbuf_addch(sb, '\n');
        }
  
@@@ -1705,16 -1701,6 +1702,16 @@@ static void pp_handle_indent(struct pre
                strbuf_add(sb, line, linelen);
  }
  
 +static int is_mboxrd_from(const char *line, int len)
 +{
 +      /*
 +       * a line matching /^From $/ here would only have len == 4
 +       * at this point because is_empty_line would've trimmed all
 +       * trailing space
 +       */
 +      return len > 4 && starts_with(line + strspn(line, ">"), "From ");
 +}
 +
  void pp_remainder(struct pretty_print_context *pp,
                  const char **msg_p,
                  struct strbuf *sb,
                else if (pp->expand_tabs_in_log)
                        strbuf_add_tabexpand(sb, pp->expand_tabs_in_log,
                                             line, linelen);
 -              else
 +              else {
 +                      if (pp->fmt == CMIT_FMT_MBOXRD &&
 +                                      is_mboxrd_from(line, linelen))
 +                              strbuf_addch(sb, '>');
 +
                        strbuf_add(sb, line, linelen);
 +              }
                strbuf_addch(sb, '\n');
        }
  }
@@@ -1773,14 -1754,14 +1770,14 @@@ void pretty_print_commit(struct pretty_
        encoding = get_log_output_encoding();
        msg = reencoded = logmsg_reencode(commit, NULL, encoding);
  
 -      if (pp->fmt == CMIT_FMT_ONELINE || pp->fmt == CMIT_FMT_EMAIL)
 +      if (pp->fmt == CMIT_FMT_ONELINE || cmit_fmt_is_mail(pp->fmt))
                indent = 0;
  
        /*
         * We need to check and emit Content-type: to mark it
         * as 8-bit if we haven't done so.
         */
 -      if (pp->fmt == CMIT_FMT_EMAIL && need_8bit_cte == 0) {
 +      if (cmit_fmt_is_mail(pp->fmt) && need_8bit_cte == 0) {
                int i, ch, in_body;
  
                for (in_body = i = 0; (ch = msg[i]); i++) {
        msg = skip_blank_lines(msg);
  
        /* These formats treat the title line specially. */
 -      if (pp->fmt == CMIT_FMT_ONELINE || pp->fmt == CMIT_FMT_EMAIL)
 +      if (pp->fmt == CMIT_FMT_ONELINE || cmit_fmt_is_mail(pp->fmt))
                pp_title_line(pp, &msg, sb, encoding, need_8bit_cte);
  
        beginning_of_body = sb->len;
         * format.  Make sure we did not strip the blank line
         * between the header and the body.
         */
 -      if (pp->fmt == CMIT_FMT_EMAIL && sb->len <= beginning_of_body)
 +      if (cmit_fmt_is_mail(pp->fmt) && sb->len <= beginning_of_body)
                strbuf_addch(sb, '\n');
  
        unuse_commit_buffer(commit, reencoded);