Merge branch 'ak/git-strip-extension-from-dashed-command' into maint
authorJunio C Hamano <gitster@pobox.com>
Thu, 10 Mar 2016 19:13:48 +0000 (11:13 -0800)
committerJunio C Hamano <gitster@pobox.com>
Thu, 10 Mar 2016 19:13:48 +0000 (11:13 -0800)
Code simplification.

* ak/git-strip-extension-from-dashed-command:
git.c: simplify stripping extension of a file in handle_builtin()

1  2 
git-compat-util.h
git.c
diff --combined git-compat-util.h
index 1459f9b87e9d939af3460d3461ad4ec805e1ef29,b7fcbd4b86664854a71128864ae41ae55a7d633d..c07e0c177890639cf016eac9766d04f235dbfbcf
  #define unsigned_add_overflows(a, b) \
      ((b) > maximum_unsigned_value_of_type(a) - (a))
  
 +/*
 + * Returns true if the multiplication of "a" and "b" will
 + * overflow. The types of "a" and "b" must match and must be unsigned.
 + * Note that this macro evaluates "a" twice!
 + */
 +#define unsigned_mult_overflows(a, b) \
 +    ((a) && (b) > maximum_unsigned_value_of_type(a) / (a))
 +
  #ifdef __GNUC__
  #define TYPEOF(x) (__typeof__(x))
  #else
@@@ -237,7 -229,7 +237,7 @@@ typedef unsigned long uintptr_t
  #else
  #define precompose_str(in,i_nfd2nfc)
  #define precompose_argv(c,v)
 -#define probe_utf8_pathname_composition(a,b)
 +#define probe_utf8_pathname_composition()
  #endif
  
  #ifdef MKDIR_WO_TRAILING_SLASH
@@@ -261,8 -253,6 +261,8 @@@ struct itimerval 
  #else
  #define basename gitbasename
  extern char *gitbasename(char *);
 +#define dirname gitdirname
 +extern char *gitdirname(char *);
  #endif
  
  #ifndef NO_ICONV
  #define PRIuMAX "llu"
  #endif
  
 +#ifndef SCNuMAX
 +#define SCNuMAX PRIuMAX
 +#endif
 +
  #ifndef PRIu32
  #define PRIu32 "u"
  #endif
  #define _PATH_DEFPATH "/usr/local/bin:/usr/bin:/bin"
  #endif
  
- #ifndef STRIP_EXTENSION
- #define STRIP_EXTENSION ""
- #endif
  #ifndef has_dos_drive_prefix
  static inline int git_has_dos_drive_prefix(const char *path)
  {
  #define has_dos_drive_prefix git_has_dos_drive_prefix
  #endif
  
 +#ifndef skip_dos_drive_prefix
 +static inline int git_skip_dos_drive_prefix(char **path)
 +{
 +      return 0;
 +}
 +#define skip_dos_drive_prefix git_skip_dos_drive_prefix
 +#endif
 +
  #ifndef is_dir_sep
  static inline int git_is_dir_sep(int c)
  {
@@@ -590,7 -564,7 +586,7 @@@ extern int git_lstat(const char *, stru
  #endif
  
  #define DEFAULT_PACKED_GIT_LIMIT \
 -      ((1024L * 1024L) * (sizeof(void*) >= 8 ? 8192 : 256))
 +      ((1024L * 1024L) * (size_t)(sizeof(void*) >= 8 ? 8192 : 256))
  
  #ifdef NO_PREAD
  #define pread git_pread
@@@ -681,6 -655,7 +677,6 @@@ extern int git_vsnprintf(char *str, siz
  #ifdef __GLIBC_PREREQ
  #if __GLIBC_PREREQ(2, 1)
  #define HAVE_STRCHRNUL
 -#define HAVE_MEMPCPY
  #endif
  #endif
  
@@@ -694,6 -669,14 +690,6 @@@ static inline char *gitstrchrnul(const 
  }
  #endif
  
 -#ifndef HAVE_MEMPCPY
 -#define mempcpy gitmempcpy
 -static inline void *gitmempcpy(void *dest, const void *src, size_t n)
 -{
 -      return (char *)memcpy(dest, src, n) + n;
 -}
 -#endif
 -
  #ifdef NO_INET_PTON
  int inet_pton(int af, const char *src, void *dst);
  #endif
@@@ -712,32 -695,6 +708,32 @@@ extern void release_pack_memory(size_t)
  typedef void (*try_to_free_t)(size_t);
  extern try_to_free_t set_try_to_free_routine(try_to_free_t);
  
 +static inline size_t st_add(size_t a, size_t b)
 +{
 +      if (unsigned_add_overflows(a, b))
 +              die("size_t overflow: %"PRIuMAX" + %"PRIuMAX,
 +                  (uintmax_t)a, (uintmax_t)b);
 +      return a + b;
 +}
 +#define st_add3(a,b,c)   st_add((a),st_add((b),(c)))
 +#define st_add4(a,b,c,d) st_add((a),st_add3((b),(c),(d)))
 +
 +static inline size_t st_mult(size_t a, size_t b)
 +{
 +      if (unsigned_mult_overflows(a, b))
 +              die("size_t overflow: %"PRIuMAX" * %"PRIuMAX,
 +                  (uintmax_t)a, (uintmax_t)b);
 +      return a * b;
 +}
 +
 +static inline size_t st_sub(size_t a, size_t b)
 +{
 +      if (a < b)
 +              die("size_t underflow: %"PRIuMAX" - %"PRIuMAX,
 +                  (uintmax_t)a, (uintmax_t)b);
 +      return a - b;
 +}
 +
  #ifdef HAVE_ALLOCA_H
  # include <alloca.h>
  # define xalloca(size)      (alloca(size))
@@@ -768,72 -725,8 +764,72 @@@ extern int xmkstemp_mode(char *template
  extern int odb_mkstemp(char *template, size_t limit, const char *pattern);
  extern int odb_pack_keep(char *name, size_t namesz, const unsigned char *sha1);
  extern char *xgetcwd(void);
 +extern FILE *fopen_for_writing(const char *path);
  
 -#define REALLOC_ARRAY(x, alloc) (x) = xrealloc((x), (alloc) * sizeof(*(x)))
 +#define ALLOC_ARRAY(x, alloc) (x) = xmalloc(st_mult(sizeof(*(x)), (alloc)))
 +#define REALLOC_ARRAY(x, alloc) (x) = xrealloc((x), st_mult(sizeof(*(x)), (alloc)))
 +
 +/*
 + * These functions help you allocate structs with flex arrays, and copy
 + * the data directly into the array. For example, if you had:
 + *
 + *   struct foo {
 + *     int bar;
 + *     char name[FLEX_ARRAY];
 + *   };
 + *
 + * you can do:
 + *
 + *   struct foo *f;
 + *   FLEX_ALLOC_MEM(f, name, src, len);
 + *
 + * to allocate a "foo" with the contents of "src" in the "name" field.
 + * The resulting struct is automatically zero'd, and the flex-array field
 + * is NUL-terminated (whether the incoming src buffer was or not).
 + *
 + * The FLEXPTR_* variants operate on structs that don't use flex-arrays,
 + * but do want to store a pointer to some extra data in the same allocated
 + * block. For example, if you have:
 + *
 + *   struct foo {
 + *     char *name;
 + *     int bar;
 + *   };
 + *
 + * you can do:
 + *
 + *   struct foo *f;
 + *   FLEX_ALLOC_STR(f, name, src);
 + *
 + * and "name" will point to a block of memory after the struct, which will be
 + * freed along with the struct (but the pointer can be repointed anywhere).
 + *
 + * The *_STR variants accept a string parameter rather than a ptr/len
 + * combination.
 + *
 + * Note that these macros will evaluate the first parameter multiple
 + * times, and it must be assignable as an lvalue.
 + */
 +#define FLEX_ALLOC_MEM(x, flexname, buf, len) do { \
 +      (x) = NULL; /* silence -Wuninitialized for offset calculation */ \
 +      (x) = xalloc_flex(sizeof(*(x)), (char *)(&((x)->flexname)) - (char *)(x), (buf), (len)); \
 +} while (0)
 +#define FLEXPTR_ALLOC_MEM(x, ptrname, buf, len) do { \
 +      (x) = xalloc_flex(sizeof(*(x)), sizeof(*(x)), (buf), (len)); \
 +      (x)->ptrname = (void *)((x)+1); \
 +} while(0)
 +#define FLEX_ALLOC_STR(x, flexname, str) \
 +      FLEX_ALLOC_MEM((x), flexname, (str), strlen(str))
 +#define FLEXPTR_ALLOC_STR(x, ptrname, str) \
 +      FLEXPTR_ALLOC_MEM((x), ptrname, (str), strlen(str))
 +
 +static inline void *xalloc_flex(size_t base_len, size_t offset,
 +                              const void *src, size_t src_len)
 +{
 +      unsigned char *ret = xcalloc(1, st_add3(base_len, src_len, 1));
 +      memcpy(ret + offset, src, src_len);
 +      return ret;
 +}
  
  static inline char *xstrdup_or_null(const char *str)
  {
@@@ -847,9 -740,6 +843,9 @@@ static inline size_t xsize_t(off_t len
        return (size_t)len;
  }
  
 +__attribute__((format (printf, 3, 4)))
 +extern int xsnprintf(char *dst, size_t max, const char *fmt, ...);
 +
  /* in ctype.c, for kwset users */
  extern const unsigned char tolower_trans_tbl[256];
  
@@@ -920,9 -810,6 +916,9 @@@ static inline int strtoul_ui(char cons
        char *p;
  
        errno = 0;
 +      /* negative values would be accepted by strtoul */
 +      if (strchr(s, '-'))
 +              return -1;
        ul = strtoul(s, &p, base);
        if (errno || *p || p == s || (unsigned int) ul != ul)
                return -1;
@@@ -1028,6 -915,9 +1024,6 @@@ int access_or_die(const char *path, in
  /* Warn on an inaccessible file that ought to be accessible */
  void warn_on_inaccessible(const char *path);
  
 -/* Get the passwd entry for the UID of the current process. */
 -struct passwd *xgetpwuid_self(void);
 -
  #ifdef GMTIME_UNRELIABLE_ERRORS
  struct tm *git_gmtime(const time_t *);
  struct tm *git_gmtime_r(const time_t *, struct tm *);
diff --combined git.c
index e61a59c0145af8d24575e11d38ff91910b2cae8a,a9dc2e8b492589e1f41d2c91cf4149aefe25c872..c19d6bf47bdc2831c8d5c98e4921910ae1ff4db5
--- 1/git.c
--- 2/git.c
+++ b/git.c
@@@ -239,15 -239,19 +239,15 @@@ static int handle_alias(int *argcp, con
        alias_string = alias_lookup(alias_command);
        if (alias_string) {
                if (alias_string[0] == '!') {
 -                      const char **alias_argv;
 -                      int argc = *argcp, i;
 +                      struct child_process child = CHILD_PROCESS_INIT;
  
                        commit_pager_choice();
  
 -                      /* build alias_argv */
 -                      alias_argv = xmalloc(sizeof(*alias_argv) * (argc + 1));
 -                      alias_argv[0] = alias_string + 1;
 -                      for (i = 1; i < argc; ++i)
 -                              alias_argv[i] = (*argv)[i];
 -                      alias_argv[argc] = NULL;
 +                      child.use_shell = 1;
 +                      argv_array_push(&child.args, alias_string + 1);
 +                      argv_array_pushv(&child.args, (*argv) + 1);
  
 -                      ret = run_command_v_opt(alias_argv, RUN_USING_SHELL);
 +                      ret = run_command(&child);
                        if (ret >= 0)   /* normal exit */
                                exit(ret);
  
@@@ -413,7 -417,7 +413,7 @@@ static struct cmd_struct commands[] = 
        { "index-pack", cmd_index_pack, RUN_SETUP_GENTLY },
        { "init", cmd_init_db, NO_SETUP },
        { "init-db", cmd_init_db, NO_SETUP },
 -      { "interpret-trailers", cmd_interpret_trailers, RUN_SETUP },
 +      { "interpret-trailers", cmd_interpret_trailers, RUN_SETUP_GENTLY },
        { "log", cmd_log, RUN_SETUP },
        { "ls-files", cmd_ls_files, RUN_SETUP },
        { "ls-remote", cmd_ls_remote, RUN_SETUP_GENTLY },
        { "stage", cmd_add, RUN_SETUP | NEED_WORK_TREE },
        { "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
        { "stripspace", cmd_stripspace },
 +      { "submodule--helper", cmd_submodule__helper, RUN_SETUP },
        { "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
        { "tag", cmd_tag, RUN_SETUP },
        { "unpack-file", cmd_unpack_file, RUN_SETUP },
@@@ -502,21 -505,25 +502,25 @@@ int is_builtin(const char *s
        return !!get_builtin(s);
  }
  
+ #ifdef STRIP_EXTENSION
+ static void strip_extension(const char **argv)
+ {
+       size_t len;
+       if (strip_suffix(argv[0], STRIP_EXTENSION, &len))
+               argv[0] = xmemdupz(argv[0], len);
+ }
+ #else
+ #define strip_extension(cmd)
+ #endif
  static void handle_builtin(int argc, const char **argv)
  {
-       const char *cmd = argv[0];
-       int i;
-       static const char ext[] = STRIP_EXTENSION;
+       const char *cmd;
        struct cmd_struct *builtin;
  
-       if (sizeof(ext) > 1) {
-               i = strlen(argv[0]) - strlen(ext);
-               if (i > 0 && !strcmp(argv[0] + i, ext)) {
-                       char *argv0 = xstrdup(argv[0]);
-                       argv[0] = cmd = argv0;
-                       argv0[i] = '\0';
-               }
-       }
+       strip_extension(argv);
+       cmd = argv[0];
  
        /* Turn "git cmd --help" into "git help cmd" */
        if (argc > 1 && !strcmp(argv[1], "--help")) {