t / helper / test-regex.con commit grep: recurse in-process using 'struct repository' (f9ee2fc)
   1#include "git-compat-util.h"
   2#include "gettext.h"
   3
   4struct reg_flag {
   5        const char *name;
   6        int flag;
   7};
   8
   9static struct reg_flag reg_flags[] = {
  10        { "EXTENDED",    REG_EXTENDED   },
  11        { "NEWLINE",     REG_NEWLINE    },
  12        { "ICASE",       REG_ICASE      },
  13        { "NOTBOL",      REG_NOTBOL     },
  14#ifdef REG_STARTEND
  15        { "STARTEND",    REG_STARTEND   },
  16#endif
  17        { NULL, 0 }
  18};
  19
  20static int test_regex_bug(void)
  21{
  22        char *pat = "[^={} \t]+";
  23        char *str = "={}\nfred";
  24        regex_t r;
  25        regmatch_t m[1];
  26
  27        if (regcomp(&r, pat, REG_EXTENDED | REG_NEWLINE))
  28                die("failed regcomp() for pattern '%s'", pat);
  29        if (regexec(&r, str, 1, m, 0))
  30                die("no match of pattern '%s' to string '%s'", pat, str);
  31
  32        /* http://sourceware.org/bugzilla/show_bug.cgi?id=3957  */
  33        if (m[0].rm_so == 3) /* matches '\n' when it should not */
  34                die("regex bug confirmed: re-build git with NO_REGEX=1");
  35
  36        return 0;
  37}
  38
  39int cmd_main(int argc, const char **argv)
  40{
  41        const char *pat;
  42        const char *str;
  43        int flags = 0;
  44        regex_t r;
  45        regmatch_t m[1];
  46
  47        if (argc == 2 && !strcmp(argv[1], "--bug"))
  48                return test_regex_bug();
  49        else if (argc < 3)
  50                usage("test-regex --bug\n"
  51                      "test-regex <pattern> <string> [<options>]");
  52
  53        argv++;
  54        pat = *argv++;
  55        str = *argv++;
  56        while (*argv) {
  57                struct reg_flag *rf;
  58                for (rf = reg_flags; rf->name; rf++)
  59                        if (!strcmp(*argv, rf->name)) {
  60                                flags |= rf->flag;
  61                                break;
  62                        }
  63                if (!rf->name)
  64                        die("do not recognize %s", *argv);
  65                argv++;
  66        }
  67        git_setup_gettext();
  68
  69        if (regcomp(&r, pat, flags))
  70                die("failed regcomp() for pattern '%s'", pat);
  71        if (regexec(&r, str, 1, m, 0))
  72                return 1;
  73
  74        return 0;
  75}