b9b03e14d3f6a6cedb6cf6363d55e4d564cc3d28
   1#include "builtin.h"
   2#include "cache.h"
   3#include "refs.h"
   4#include "object.h"
   5#include "tag.h"
   6#include "commit.h"
   7#include "tree.h"
   8#include "blob.h"
   9#include "quote.h"
  10#include "parse-options.h"
  11#include "remote.h"
  12
  13/* Quoting styles */
  14#define QUOTE_NONE 0
  15#define QUOTE_SHELL 1
  16#define QUOTE_PERL 2
  17#define QUOTE_PYTHON 4
  18#define QUOTE_TCL 8
  19
  20typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME } cmp_type;
  21
  22struct atom_value {
  23        const char *s;
  24        unsigned long ul; /* used for sorting when not FIELD_STR */
  25};
  26
  27struct ref_sort {
  28        struct ref_sort *next;
  29        int atom; /* index into used_atom array */
  30        unsigned reverse : 1;
  31};
  32
  33struct refinfo {
  34        char *refname;
  35        unsigned char objectname[20];
  36        int flag;
  37        const char *symref;
  38        struct atom_value *value;
  39};
  40
  41static struct {
  42        const char *name;
  43        cmp_type cmp_type;
  44} valid_atom[] = {
  45        { "refname" },
  46        { "objecttype" },
  47        { "objectsize", FIELD_ULONG },
  48        { "objectname" },
  49        { "tree" },
  50        { "parent" },
  51        { "numparent", FIELD_ULONG },
  52        { "object" },
  53        { "type" },
  54        { "tag" },
  55        { "author" },
  56        { "authorname" },
  57        { "authoremail" },
  58        { "authordate", FIELD_TIME },
  59        { "committer" },
  60        { "committername" },
  61        { "committeremail" },
  62        { "committerdate", FIELD_TIME },
  63        { "tagger" },
  64        { "taggername" },
  65        { "taggeremail" },
  66        { "taggerdate", FIELD_TIME },
  67        { "creator" },
  68        { "creatordate", FIELD_TIME },
  69        { "subject" },
  70        { "body" },
  71        { "contents" },
  72        { "upstream" },
  73        { "symref" },
  74};
  75
  76/*
  77 * An atom is a valid field atom listed above, possibly prefixed with
  78 * a "*" to denote deref_tag().
  79 *
  80 * We parse given format string and sort specifiers, and make a list
  81 * of properties that we need to extract out of objects.  refinfo
  82 * structure will hold an array of values extracted that can be
  83 * indexed with the "atom number", which is an index into this
  84 * array.
  85 */
  86static const char **used_atom;
  87static cmp_type *used_atom_type;
  88static int used_atom_cnt, sort_atom_limit, need_tagged, need_symref;
  89
  90/*
  91 * Used to parse format string and sort specifiers
  92 */
  93static int parse_atom(const char *atom, const char *ep)
  94{
  95        const char *sp;
  96        int i, at;
  97
  98        sp = atom;
  99        if (*sp == '*' && sp < ep)
 100                sp++; /* deref */
 101        if (ep <= sp)
 102                die("malformed field name: %.*s", (int)(ep-atom), atom);
 103
 104        /* Do we have the atom already used elsewhere? */
 105        for (i = 0; i < used_atom_cnt; i++) {
 106                int len = strlen(used_atom[i]);
 107                if (len == ep - atom && !memcmp(used_atom[i], atom, len))
 108                        return i;
 109        }
 110
 111        /* Is the atom a valid one? */
 112        for (i = 0; i < ARRAY_SIZE(valid_atom); i++) {
 113                int len = strlen(valid_atom[i].name);
 114                /*
 115                 * If the atom name has a colon, strip it and everything after
 116                 * it off - it specifies the format for this entry, and
 117                 * shouldn't be used for checking against the valid_atom
 118                 * table.
 119                 */
 120                const char *formatp = strchr(sp, ':');
 121                if (!formatp || ep < formatp)
 122                        formatp = ep;
 123                if (len == formatp - sp && !memcmp(valid_atom[i].name, sp, len))
 124                        break;
 125        }
 126
 127        if (ARRAY_SIZE(valid_atom) <= i)
 128                die("unknown field name: %.*s", (int)(ep-atom), atom);
 129
 130        /* Add it in, including the deref prefix */
 131        at = used_atom_cnt;
 132        used_atom_cnt++;
 133        used_atom = xrealloc(used_atom,
 134                             (sizeof *used_atom) * used_atom_cnt);
 135        used_atom_type = xrealloc(used_atom_type,
 136                                  (sizeof(*used_atom_type) * used_atom_cnt));
 137        used_atom[at] = xmemdupz(atom, ep - atom);
 138        used_atom_type[at] = valid_atom[i].cmp_type;
 139        if (*atom == '*')
 140                need_tagged = 1;
 141        if (!strcmp(used_atom[at], "symref"))
 142                need_symref = 1;
 143        return at;
 144}
 145
 146/*
 147 * In a format string, find the next occurrence of %(atom).
 148 */
 149static const char *find_next(const char *cp)
 150{
 151        while (*cp) {
 152                if (*cp == '%') {
 153                        /*
 154                         * %( is the start of an atom;
 155                         * %% is a quoted per-cent.
 156                         */
 157                        if (cp[1] == '(')
 158                                return cp;
 159                        else if (cp[1] == '%')
 160                                cp++; /* skip over two % */
 161                        /* otherwise this is a singleton, literal % */
 162                }
 163                cp++;
 164        }
 165        return NULL;
 166}
 167
 168/*
 169 * Make sure the format string is well formed, and parse out
 170 * the used atoms.
 171 */
 172static int verify_format(const char *format)
 173{
 174        const char *cp, *sp;
 175        for (cp = format; *cp && (sp = find_next(cp)); ) {
 176                const char *ep = strchr(sp, ')');
 177                if (!ep)
 178                        return error("malformed format string %s", sp);
 179                /* sp points at "%(" and ep points at the closing ")" */
 180                parse_atom(sp + 2, ep);
 181                cp = ep + 1;
 182        }
 183        return 0;
 184}
 185
 186/*
 187 * Given an object name, read the object data and size, and return a
 188 * "struct object".  If the object data we are returning is also borrowed
 189 * by the "struct object" representation, set *eaten as well---it is a
 190 * signal from parse_object_buffer to us not to free the buffer.
 191 */
 192static void *get_obj(const unsigned char *sha1, struct object **obj, unsigned long *sz, int *eaten)
 193{
 194        enum object_type type;
 195        void *buf = read_sha1_file(sha1, &type, sz);
 196
 197        if (buf)
 198                *obj = parse_object_buffer(sha1, type, *sz, buf, eaten);
 199        else
 200                *obj = NULL;
 201        return buf;
 202}
 203
 204/* See grab_values */
 205static void grab_common_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
 206{
 207        int i;
 208
 209        for (i = 0; i < used_atom_cnt; i++) {
 210                const char *name = used_atom[i];
 211                struct atom_value *v = &val[i];
 212                if (!!deref != (*name == '*'))
 213                        continue;
 214                if (deref)
 215                        name++;
 216                if (!strcmp(name, "objecttype"))
 217                        v->s = typename(obj->type);
 218                else if (!strcmp(name, "objectsize")) {
 219                        char *s = xmalloc(40);
 220                        sprintf(s, "%lu", sz);
 221                        v->ul = sz;
 222                        v->s = s;
 223                }
 224                else if (!strcmp(name, "objectname")) {
 225                        char *s = xmalloc(41);
 226                        strcpy(s, sha1_to_hex(obj->sha1));
 227                        v->s = s;
 228                }
 229        }
 230}
 231
 232/* See grab_values */
 233static void grab_tag_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
 234{
 235        int i;
 236        struct tag *tag = (struct tag *) obj;
 237
 238        for (i = 0; i < used_atom_cnt; i++) {
 239                const char *name = used_atom[i];
 240                struct atom_value *v = &val[i];
 241                if (!!deref != (*name == '*'))
 242                        continue;
 243                if (deref)
 244                        name++;
 245                if (!strcmp(name, "tag"))
 246                        v->s = tag->tag;
 247                else if (!strcmp(name, "type") && tag->tagged)
 248                        v->s = typename(tag->tagged->type);
 249                else if (!strcmp(name, "object") && tag->tagged) {
 250                        char *s = xmalloc(41);
 251                        strcpy(s, sha1_to_hex(tag->tagged->sha1));
 252                        v->s = s;
 253                }
 254        }
 255}
 256
 257static int num_parents(struct commit *commit)
 258{
 259        struct commit_list *parents;
 260        int i;
 261
 262        for (i = 0, parents = commit->parents;
 263             parents;
 264             parents = parents->next)
 265                i++;
 266        return i;
 267}
 268
 269/* See grab_values */
 270static void grab_commit_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
 271{
 272        int i;
 273        struct commit *commit = (struct commit *) obj;
 274
 275        for (i = 0; i < used_atom_cnt; i++) {
 276                const char *name = used_atom[i];
 277                struct atom_value *v = &val[i];
 278                if (!!deref != (*name == '*'))
 279                        continue;
 280                if (deref)
 281                        name++;
 282                if (!strcmp(name, "tree")) {
 283                        char *s = xmalloc(41);
 284                        strcpy(s, sha1_to_hex(commit->tree->object.sha1));
 285                        v->s = s;
 286                }
 287                if (!strcmp(name, "numparent")) {
 288                        char *s = xmalloc(40);
 289                        v->ul = num_parents(commit);
 290                        sprintf(s, "%lu", v->ul);
 291                        v->s = s;
 292                }
 293                else if (!strcmp(name, "parent")) {
 294                        int num = num_parents(commit);
 295                        int i;
 296                        struct commit_list *parents;
 297                        char *s = xmalloc(41 * num + 1);
 298                        v->s = s;
 299                        for (i = 0, parents = commit->parents;
 300                             parents;
 301                             parents = parents->next, i = i + 41) {
 302                                struct commit *parent = parents->item;
 303                                strcpy(s+i, sha1_to_hex(parent->object.sha1));
 304                                if (parents->next)
 305                                        s[i+40] = ' ';
 306                        }
 307                        if (!i)
 308                                *s = '\0';
 309                }
 310        }
 311}
 312
 313static const char *find_wholine(const char *who, int wholen, const char *buf, unsigned long sz)
 314{
 315        const char *eol;
 316        while (*buf) {
 317                if (!strncmp(buf, who, wholen) &&
 318                    buf[wholen] == ' ')
 319                        return buf + wholen + 1;
 320                eol = strchr(buf, '\n');
 321                if (!eol)
 322                        return "";
 323                eol++;
 324                if (*eol == '\n')
 325                        return ""; /* end of header */
 326                buf = eol;
 327        }
 328        return "";
 329}
 330
 331static const char *copy_line(const char *buf)
 332{
 333        const char *eol = strchrnul(buf, '\n');
 334        return xmemdupz(buf, eol - buf);
 335}
 336
 337static const char *copy_name(const char *buf)
 338{
 339        const char *cp;
 340        for (cp = buf; *cp && *cp != '\n'; cp++) {
 341                if (!strncmp(cp, " <", 2))
 342                        return xmemdupz(buf, cp - buf);
 343        }
 344        return "";
 345}
 346
 347static const char *copy_email(const char *buf)
 348{
 349        const char *email = strchr(buf, '<');
 350        const char *eoemail;
 351        if (!email)
 352                return "";
 353        eoemail = strchr(email, '>');
 354        if (!eoemail)
 355                return "";
 356        return xmemdupz(email, eoemail + 1 - email);
 357}
 358
 359static void grab_date(const char *buf, struct atom_value *v, const char *atomname)
 360{
 361        const char *eoemail = strstr(buf, "> ");
 362        char *zone;
 363        unsigned long timestamp;
 364        long tz;
 365        enum date_mode date_mode = DATE_NORMAL;
 366        const char *formatp;
 367
 368        /*
 369         * We got here because atomname ends in "date" or "date<something>";
 370         * it's not possible that <something> is not ":<format>" because
 371         * parse_atom() wouldn't have allowed it, so we can assume that no
 372         * ":" means no format is specified, and use the default.
 373         */
 374        formatp = strchr(atomname, ':');
 375        if (formatp != NULL) {
 376                formatp++;
 377                date_mode = parse_date_format(formatp);
 378        }
 379
 380        if (!eoemail)
 381                goto bad;
 382        timestamp = strtoul(eoemail + 2, &zone, 10);
 383        if (timestamp == ULONG_MAX)
 384                goto bad;
 385        tz = strtol(zone, NULL, 10);
 386        if ((tz == LONG_MIN || tz == LONG_MAX) && errno == ERANGE)
 387                goto bad;
 388        v->s = xstrdup(show_date(timestamp, tz, date_mode));
 389        v->ul = timestamp;
 390        return;
 391 bad:
 392        v->s = "";
 393        v->ul = 0;
 394}
 395
 396/* See grab_values */
 397static void grab_person(const char *who, struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
 398{
 399        int i;
 400        int wholen = strlen(who);
 401        const char *wholine = NULL;
 402
 403        for (i = 0; i < used_atom_cnt; i++) {
 404                const char *name = used_atom[i];
 405                struct atom_value *v = &val[i];
 406                if (!!deref != (*name == '*'))
 407                        continue;
 408                if (deref)
 409                        name++;
 410                if (strncmp(who, name, wholen))
 411                        continue;
 412                if (name[wholen] != 0 &&
 413                    strcmp(name + wholen, "name") &&
 414                    strcmp(name + wholen, "email") &&
 415                    prefixcmp(name + wholen, "date"))
 416                        continue;
 417                if (!wholine)
 418                        wholine = find_wholine(who, wholen, buf, sz);
 419                if (!wholine)
 420                        return; /* no point looking for it */
 421                if (name[wholen] == 0)
 422                        v->s = copy_line(wholine);
 423                else if (!strcmp(name + wholen, "name"))
 424                        v->s = copy_name(wholine);
 425                else if (!strcmp(name + wholen, "email"))
 426                        v->s = copy_email(wholine);
 427                else if (!prefixcmp(name + wholen, "date"))
 428                        grab_date(wholine, v, name);
 429        }
 430
 431        /*
 432         * For a tag or a commit object, if "creator" or "creatordate" is
 433         * requested, do something special.
 434         */
 435        if (strcmp(who, "tagger") && strcmp(who, "committer"))
 436                return; /* "author" for commit object is not wanted */
 437        if (!wholine)
 438                wholine = find_wholine(who, wholen, buf, sz);
 439        if (!wholine)
 440                return;
 441        for (i = 0; i < used_atom_cnt; i++) {
 442                const char *name = used_atom[i];
 443                struct atom_value *v = &val[i];
 444                if (!!deref != (*name == '*'))
 445                        continue;
 446                if (deref)
 447                        name++;
 448
 449                if (!prefixcmp(name, "creatordate"))
 450                        grab_date(wholine, v, name);
 451                else if (!strcmp(name, "creator"))
 452                        v->s = copy_line(wholine);
 453        }
 454}
 455
 456static void find_subpos(const char *buf, unsigned long sz, const char **sub, const char **body)
 457{
 458        while (*buf) {
 459                const char *eol = strchr(buf, '\n');
 460                if (!eol)
 461                        return;
 462                if (eol[1] == '\n') {
 463                        buf = eol + 1;
 464                        break; /* found end of header */
 465                }
 466                buf = eol + 1;
 467        }
 468        while (*buf == '\n')
 469                buf++;
 470        if (!*buf)
 471                return;
 472        *sub = buf; /* first non-empty line */
 473        buf = strchr(buf, '\n');
 474        if (!buf) {
 475                *body = "";
 476                return; /* no body */
 477        }
 478        while (*buf == '\n')
 479                buf++; /* skip blank between subject and body */
 480        *body = buf;
 481}
 482
 483/* See grab_values */
 484static void grab_sub_body_contents(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
 485{
 486        int i;
 487        const char *subpos = NULL, *bodypos = NULL;
 488
 489        for (i = 0; i < used_atom_cnt; i++) {
 490                const char *name = used_atom[i];
 491                struct atom_value *v = &val[i];
 492                if (!!deref != (*name == '*'))
 493                        continue;
 494                if (deref)
 495                        name++;
 496                if (strcmp(name, "subject") &&
 497                    strcmp(name, "body") &&
 498                    strcmp(name, "contents"))
 499                        continue;
 500                if (!subpos)
 501                        find_subpos(buf, sz, &subpos, &bodypos);
 502                if (!subpos)
 503                        return;
 504
 505                if (!strcmp(name, "subject"))
 506                        v->s = copy_line(subpos);
 507                else if (!strcmp(name, "body"))
 508                        v->s = xstrdup(bodypos);
 509                else if (!strcmp(name, "contents"))
 510                        v->s = xstrdup(subpos);
 511        }
 512}
 513
 514/*
 515 * We want to have empty print-string for field requests
 516 * that do not apply (e.g. "authordate" for a tag object)
 517 */
 518static void fill_missing_values(struct atom_value *val)
 519{
 520        int i;
 521        for (i = 0; i < used_atom_cnt; i++) {
 522                struct atom_value *v = &val[i];
 523                if (v->s == NULL)
 524                        v->s = "";
 525        }
 526}
 527
 528/*
 529 * val is a list of atom_value to hold returned values.  Extract
 530 * the values for atoms in used_atom array out of (obj, buf, sz).
 531 * when deref is false, (obj, buf, sz) is the object that is
 532 * pointed at by the ref itself; otherwise it is the object the
 533 * ref (which is a tag) refers to.
 534 */
 535static void grab_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
 536{
 537        grab_common_values(val, deref, obj, buf, sz);
 538        switch (obj->type) {
 539        case OBJ_TAG:
 540                grab_tag_values(val, deref, obj, buf, sz);
 541                grab_sub_body_contents(val, deref, obj, buf, sz);
 542                grab_person("tagger", val, deref, obj, buf, sz);
 543                break;
 544        case OBJ_COMMIT:
 545                grab_commit_values(val, deref, obj, buf, sz);
 546                grab_sub_body_contents(val, deref, obj, buf, sz);
 547                grab_person("author", val, deref, obj, buf, sz);
 548                grab_person("committer", val, deref, obj, buf, sz);
 549                break;
 550        case OBJ_TREE:
 551                // grab_tree_values(val, deref, obj, buf, sz);
 552                break;
 553        case OBJ_BLOB:
 554                // grab_blob_values(val, deref, obj, buf, sz);
 555                break;
 556        default:
 557                die("Eh?  Object of type %d?", obj->type);
 558        }
 559}
 560
 561/*
 562 * Parse the object referred by ref, and grab needed value.
 563 */
 564static void populate_value(struct refinfo *ref)
 565{
 566        void *buf;
 567        struct object *obj;
 568        int eaten, i;
 569        unsigned long size;
 570        const unsigned char *tagged;
 571
 572        ref->value = xcalloc(sizeof(struct atom_value), used_atom_cnt);
 573
 574        if (need_symref && (ref->flag & REF_ISSYMREF) && !ref->symref) {
 575                unsigned char unused1[20];
 576                const char *symref;
 577                symref = resolve_ref(ref->refname, unused1, 1, NULL);
 578                if (symref)
 579                        ref->symref = xstrdup(symref);
 580                else
 581                        ref->symref = "";
 582        }
 583
 584        /* Fill in specials first */
 585        for (i = 0; i < used_atom_cnt; i++) {
 586                const char *name = used_atom[i];
 587                struct atom_value *v = &ref->value[i];
 588                int deref = 0;
 589                const char *refname;
 590                const char *formatp;
 591
 592                if (*name == '*') {
 593                        deref = 1;
 594                        name++;
 595                }
 596
 597                if (!prefixcmp(name, "refname"))
 598                        refname = ref->refname;
 599                else if (!prefixcmp(name, "symref"))
 600                        refname = ref->symref ? ref->symref : "";
 601                else if (!prefixcmp(name, "upstream")) {
 602                        struct branch *branch;
 603                        /* only local branches may have an upstream */
 604                        if (prefixcmp(ref->refname, "refs/heads/"))
 605                                continue;
 606                        branch = branch_get(ref->refname + 11);
 607
 608                        if (!branch || !branch->merge || !branch->merge[0] ||
 609                            !branch->merge[0]->dst)
 610                                continue;
 611                        refname = branch->merge[0]->dst;
 612                }
 613                else
 614                        continue;
 615
 616                formatp = strchr(name, ':');
 617                /* look for "short" refname format */
 618                if (formatp) {
 619                        formatp++;
 620                        if (!strcmp(formatp, "short"))
 621                                refname = shorten_unambiguous_ref(refname,
 622                                                      warn_ambiguous_refs);
 623                        else
 624                                die("unknown %.*s format %s",
 625                                    (int)(formatp - name), name, formatp);
 626                }
 627
 628                if (!deref)
 629                        v->s = refname;
 630                else {
 631                        int len = strlen(refname);
 632                        char *s = xmalloc(len + 4);
 633                        sprintf(s, "%s^{}", refname);
 634                        v->s = s;
 635                }
 636        }
 637
 638        for (i = 0; i < used_atom_cnt; i++) {
 639                struct atom_value *v = &ref->value[i];
 640                if (v->s == NULL)
 641                        goto need_obj;
 642        }
 643        return;
 644
 645 need_obj:
 646        buf = get_obj(ref->objectname, &obj, &size, &eaten);
 647        if (!buf)
 648                die("missing object %s for %s",
 649                    sha1_to_hex(ref->objectname), ref->refname);
 650        if (!obj)
 651                die("parse_object_buffer failed on %s for %s",
 652                    sha1_to_hex(ref->objectname), ref->refname);
 653
 654        grab_values(ref->value, 0, obj, buf, size);
 655        if (!eaten)
 656                free(buf);
 657
 658        /*
 659         * If there is no atom that wants to know about tagged
 660         * object, we are done.
 661         */
 662        if (!need_tagged || (obj->type != OBJ_TAG))
 663                return;
 664
 665        /*
 666         * If it is a tag object, see if we use a value that derefs
 667         * the object, and if we do grab the object it refers to.
 668         */
 669        tagged = ((struct tag *)obj)->tagged->sha1;
 670
 671        /*
 672         * NEEDSWORK: This derefs tag only once, which
 673         * is good to deal with chains of trust, but
 674         * is not consistent with what deref_tag() does
 675         * which peels the onion to the core.
 676         */
 677        buf = get_obj(tagged, &obj, &size, &eaten);
 678        if (!buf)
 679                die("missing object %s for %s",
 680                    sha1_to_hex(tagged), ref->refname);
 681        if (!obj)
 682                die("parse_object_buffer failed on %s for %s",
 683                    sha1_to_hex(tagged), ref->refname);
 684        grab_values(ref->value, 1, obj, buf, size);
 685        if (!eaten)
 686                free(buf);
 687}
 688
 689/*
 690 * Given a ref, return the value for the atom.  This lazily gets value
 691 * out of the object by calling populate value.
 692 */
 693static void get_value(struct refinfo *ref, int atom, struct atom_value **v)
 694{
 695        if (!ref->value) {
 696                populate_value(ref);
 697                fill_missing_values(ref->value);
 698        }
 699        *v = &ref->value[atom];
 700}
 701
 702struct grab_ref_cbdata {
 703        struct refinfo **grab_array;
 704        const char **grab_pattern;
 705        int grab_cnt;
 706};
 707
 708/*
 709 * A call-back given to for_each_ref().  Filter refs and keep them for
 710 * later object processing.
 711 */
 712static int grab_single_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
 713{
 714        struct grab_ref_cbdata *cb = cb_data;
 715        struct refinfo *ref;
 716        int cnt;
 717
 718        if (*cb->grab_pattern) {
 719                const char **pattern;
 720                int namelen = strlen(refname);
 721                for (pattern = cb->grab_pattern; *pattern; pattern++) {
 722                        const char *p = *pattern;
 723                        int plen = strlen(p);
 724
 725                        if ((plen <= namelen) &&
 726                            !strncmp(refname, p, plen) &&
 727                            (refname[plen] == '\0' ||
 728                             refname[plen] == '/' ||
 729                             p[plen-1] == '/'))
 730                                break;
 731                        if (!fnmatch(p, refname, FNM_PATHNAME))
 732                                break;
 733                }
 734                if (!*pattern)
 735                        return 0;
 736        }
 737
 738        /*
 739         * We do not open the object yet; sort may only need refname
 740         * to do its job and the resulting list may yet to be pruned
 741         * by maxcount logic.
 742         */
 743        ref = xcalloc(1, sizeof(*ref));
 744        ref->refname = xstrdup(refname);
 745        hashcpy(ref->objectname, sha1);
 746        ref->flag = flag;
 747
 748        cnt = cb->grab_cnt;
 749        cb->grab_array = xrealloc(cb->grab_array,
 750                                  sizeof(*cb->grab_array) * (cnt + 1));
 751        cb->grab_array[cnt++] = ref;
 752        cb->grab_cnt = cnt;
 753        return 0;
 754}
 755
 756static int cmp_ref_sort(struct ref_sort *s, struct refinfo *a, struct refinfo *b)
 757{
 758        struct atom_value *va, *vb;
 759        int cmp;
 760        cmp_type cmp_type = used_atom_type[s->atom];
 761
 762        get_value(a, s->atom, &va);
 763        get_value(b, s->atom, &vb);
 764        switch (cmp_type) {
 765        case FIELD_STR:
 766                cmp = strcmp(va->s, vb->s);
 767                break;
 768        default:
 769                if (va->ul < vb->ul)
 770                        cmp = -1;
 771                else if (va->ul == vb->ul)
 772                        cmp = 0;
 773                else
 774                        cmp = 1;
 775                break;
 776        }
 777        return (s->reverse) ? -cmp : cmp;
 778}
 779
 780static struct ref_sort *ref_sort;
 781static int compare_refs(const void *a_, const void *b_)
 782{
 783        struct refinfo *a = *((struct refinfo **)a_);
 784        struct refinfo *b = *((struct refinfo **)b_);
 785        struct ref_sort *s;
 786
 787        for (s = ref_sort; s; s = s->next) {
 788                int cmp = cmp_ref_sort(s, a, b);
 789                if (cmp)
 790                        return cmp;
 791        }
 792        return 0;
 793}
 794
 795static void sort_refs(struct ref_sort *sort, struct refinfo **refs, int num_refs)
 796{
 797        ref_sort = sort;
 798        qsort(refs, num_refs, sizeof(struct refinfo *), compare_refs);
 799}
 800
 801static void print_value(struct refinfo *ref, int atom, int quote_style)
 802{
 803        struct atom_value *v;
 804        get_value(ref, atom, &v);
 805        switch (quote_style) {
 806        case QUOTE_NONE:
 807                fputs(v->s, stdout);
 808                break;
 809        case QUOTE_SHELL:
 810                sq_quote_print(stdout, v->s);
 811                break;
 812        case QUOTE_PERL:
 813                perl_quote_print(stdout, v->s);
 814                break;
 815        case QUOTE_PYTHON:
 816                python_quote_print(stdout, v->s);
 817                break;
 818        case QUOTE_TCL:
 819                tcl_quote_print(stdout, v->s);
 820                break;
 821        }
 822}
 823
 824static int hex1(char ch)
 825{
 826        if ('0' <= ch && ch <= '9')
 827                return ch - '0';
 828        else if ('a' <= ch && ch <= 'f')
 829                return ch - 'a' + 10;
 830        else if ('A' <= ch && ch <= 'F')
 831                return ch - 'A' + 10;
 832        return -1;
 833}
 834static int hex2(const char *cp)
 835{
 836        if (cp[0] && cp[1])
 837                return (hex1(cp[0]) << 4) | hex1(cp[1]);
 838        else
 839                return -1;
 840}
 841
 842static void emit(const char *cp, const char *ep)
 843{
 844        while (*cp && (!ep || cp < ep)) {
 845                if (*cp == '%') {
 846                        if (cp[1] == '%')
 847                                cp++;
 848                        else {
 849                                int ch = hex2(cp + 1);
 850                                if (0 <= ch) {
 851                                        putchar(ch);
 852                                        cp += 3;
 853                                        continue;
 854                                }
 855                        }
 856                }
 857                putchar(*cp);
 858                cp++;
 859        }
 860}
 861
 862static void show_ref(struct refinfo *info, const char *format, int quote_style)
 863{
 864        const char *cp, *sp, *ep;
 865
 866        for (cp = format; *cp && (sp = find_next(cp)); cp = ep + 1) {
 867                ep = strchr(sp, ')');
 868                if (cp < sp)
 869                        emit(cp, sp);
 870                print_value(info, parse_atom(sp + 2, ep), quote_style);
 871        }
 872        if (*cp) {
 873                sp = cp + strlen(cp);
 874                emit(cp, sp);
 875        }
 876        putchar('\n');
 877}
 878
 879static struct ref_sort *default_sort(void)
 880{
 881        static const char cstr_name[] = "refname";
 882
 883        struct ref_sort *sort = xcalloc(1, sizeof(*sort));
 884
 885        sort->next = NULL;
 886        sort->atom = parse_atom(cstr_name, cstr_name + strlen(cstr_name));
 887        return sort;
 888}
 889
 890static int opt_parse_sort(const struct option *opt, const char *arg, int unset)
 891{
 892        struct ref_sort **sort_tail = opt->value;
 893        struct ref_sort *s;
 894        int len;
 895
 896        if (!arg) /* should --no-sort void the list ? */
 897                return -1;
 898
 899        *sort_tail = s = xcalloc(1, sizeof(*s));
 900
 901        if (*arg == '-') {
 902                s->reverse = 1;
 903                arg++;
 904        }
 905        len = strlen(arg);
 906        s->atom = parse_atom(arg, arg+len);
 907        return 0;
 908}
 909
 910static char const * const for_each_ref_usage[] = {
 911        "git for-each-ref [options] [<pattern>]",
 912        NULL
 913};
 914
 915int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
 916{
 917        int i, num_refs;
 918        const char *format = "%(objectname) %(objecttype)\t%(refname)";
 919        struct ref_sort *sort = NULL, **sort_tail = &sort;
 920        int maxcount = 0, quote_style = 0;
 921        struct refinfo **refs;
 922        struct grab_ref_cbdata cbdata;
 923
 924        struct option opts[] = {
 925                OPT_BIT('s', "shell", &quote_style,
 926                        "quote placeholders suitably for shells", QUOTE_SHELL),
 927                OPT_BIT('p', "perl",  &quote_style,
 928                        "quote placeholders suitably for perl", QUOTE_PERL),
 929                OPT_BIT(0 , "python", &quote_style,
 930                        "quote placeholders suitably for python", QUOTE_PYTHON),
 931                OPT_BIT(0 , "tcl",  &quote_style,
 932                        "quote placeholders suitably for tcl", QUOTE_TCL),
 933
 934                OPT_GROUP(""),
 935                OPT_INTEGER( 0 , "count", &maxcount, "show only <n> matched refs"),
 936                OPT_STRING(  0 , "format", &format, "format", "format to use for the output"),
 937                OPT_CALLBACK(0 , "sort", sort_tail, "key",
 938                            "field name to sort on", &opt_parse_sort),
 939                OPT_END(),
 940        };
 941
 942        parse_options(argc, argv, prefix, opts, for_each_ref_usage, 0);
 943        if (maxcount < 0) {
 944                error("invalid --count argument: `%d'", maxcount);
 945                usage_with_options(for_each_ref_usage, opts);
 946        }
 947        if (HAS_MULTI_BITS(quote_style)) {
 948                error("more than one quoting style?");
 949                usage_with_options(for_each_ref_usage, opts);
 950        }
 951        if (verify_format(format))
 952                usage_with_options(for_each_ref_usage, opts);
 953
 954        if (!sort)
 955                sort = default_sort();
 956        sort_atom_limit = used_atom_cnt;
 957
 958        /* for warn_ambiguous_refs */
 959        git_config(git_default_config, NULL);
 960
 961        memset(&cbdata, 0, sizeof(cbdata));
 962        cbdata.grab_pattern = argv;
 963        for_each_rawref(grab_single_ref, &cbdata);
 964        refs = cbdata.grab_array;
 965        num_refs = cbdata.grab_cnt;
 966
 967        sort_refs(sort, refs, num_refs);
 968
 969        if (!maxcount || num_refs < maxcount)
 970                maxcount = num_refs;
 971        for (i = 0; i < maxcount; i++)
 972                show_ref(refs[i], format, quote_style);
 973        return 0;
 974}