merge(third_party/git): Merge squashed git subtree at v2.23.0
Merge commit '1b593e1ea4' as 'third_party/git'
This commit is contained in:
commit
7ef0d62730
3629 changed files with 1139935 additions and 0 deletions
5
third_party/git/t/helper/.gitignore
vendored
Normal file
5
third_party/git/t/helper/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
*
|
||||
!*.sh
|
||||
!*.[ch]
|
||||
!*.gitignore
|
||||
|
||||
148
third_party/git/t/helper/test-chmtime.c
vendored
Normal file
148
third_party/git/t/helper/test-chmtime.c
vendored
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* This program can either change modification time of the given
|
||||
* file(s) or just print it. The program does not change atime or
|
||||
* ctime (their values are explicitly preserved).
|
||||
*
|
||||
* The mtime can be changed to an absolute value:
|
||||
*
|
||||
* test-tool chmtime =<seconds> file...
|
||||
*
|
||||
* Relative to the current time as returned by time(3):
|
||||
*
|
||||
* test-tool chmtime =+<seconds> (or =-<seconds>) file...
|
||||
*
|
||||
* Or relative to the current mtime of the file:
|
||||
*
|
||||
* test-tool chmtime <seconds> file...
|
||||
* test-tool chmtime +<seconds> (or -<seconds>) file...
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* To print the mtime and the file name use --verbose and set
|
||||
* the file mtime offset to 0:
|
||||
*
|
||||
* test-tool chmtime -v +0 file
|
||||
*
|
||||
* To print only the mtime use --get:
|
||||
*
|
||||
* test-tool chmtime --get file
|
||||
*
|
||||
* To set the mtime to current time:
|
||||
*
|
||||
* test-tool chmtime =+0 file
|
||||
*
|
||||
* To set the file mtime offset to +1 and print the new value:
|
||||
*
|
||||
* test-tool chmtime --get +1 file
|
||||
*
|
||||
*/
|
||||
#include "test-tool.h"
|
||||
#include "git-compat-util.h"
|
||||
#include <utime.h>
|
||||
|
||||
static const char usage_str[] =
|
||||
"(-v|--verbose|-g|--get) (+|=|=+|=-|-)<seconds> <file>...";
|
||||
|
||||
static int timespec_arg(const char *arg, long int *set_time, int *set_eq)
|
||||
{
|
||||
char *test;
|
||||
const char *timespec = arg;
|
||||
*set_eq = (*timespec == '=') ? 1 : 0;
|
||||
if (*set_eq) {
|
||||
timespec++;
|
||||
if (*timespec == '+') {
|
||||
*set_eq = 2; /* relative "in the future" */
|
||||
timespec++;
|
||||
}
|
||||
}
|
||||
*set_time = strtol(timespec, &test, 10);
|
||||
if (*test) {
|
||||
return 0;
|
||||
}
|
||||
if ((*set_eq && *set_time < 0) || *set_eq == 2) {
|
||||
time_t now = time(NULL);
|
||||
*set_time += now;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cmd__chmtime(int argc, const char **argv)
|
||||
{
|
||||
static int verbose;
|
||||
static int get;
|
||||
|
||||
int i = 1;
|
||||
/* no mtime change by default */
|
||||
int set_eq = 0;
|
||||
long int set_time = 0;
|
||||
|
||||
if (argc < 3)
|
||||
goto usage;
|
||||
|
||||
if (strcmp(argv[i], "--get") == 0 || strcmp(argv[i], "-g") == 0) {
|
||||
get = 1;
|
||||
++i;
|
||||
} else if (strcmp(argv[i], "--verbose") == 0 || strcmp(argv[i], "-v") == 0) {
|
||||
verbose = 1;
|
||||
++i;
|
||||
}
|
||||
|
||||
if (i == argc) {
|
||||
goto usage;
|
||||
}
|
||||
|
||||
if (timespec_arg(argv[i], &set_time, &set_eq)) {
|
||||
++i;
|
||||
} else {
|
||||
if (get == 0) {
|
||||
fprintf(stderr, "Not a base-10 integer: %s\n", argv[i] + 1);
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == argc)
|
||||
goto usage;
|
||||
|
||||
for (; i < argc; i++) {
|
||||
struct stat sb;
|
||||
struct utimbuf utb;
|
||||
uintmax_t mtime;
|
||||
|
||||
if (stat(argv[i], &sb) < 0) {
|
||||
fprintf(stderr, "Failed to stat %s: %s\n",
|
||||
argv[i], strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef GIT_WINDOWS_NATIVE
|
||||
if (!(sb.st_mode & S_IWUSR) &&
|
||||
chmod(argv[i], sb.st_mode | S_IWUSR)) {
|
||||
fprintf(stderr, "Could not make user-writable %s: %s",
|
||||
argv[i], strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
utb.actime = sb.st_atime;
|
||||
utb.modtime = set_eq ? set_time : sb.st_mtime + set_time;
|
||||
|
||||
mtime = utb.modtime < 0 ? 0: utb.modtime;
|
||||
if (get) {
|
||||
printf("%"PRIuMAX"\n", mtime);
|
||||
} else if (verbose) {
|
||||
printf("%"PRIuMAX"\t%s\n", mtime, argv[i]);
|
||||
}
|
||||
|
||||
if (utb.modtime != sb.st_mtime && utime(argv[i], &utb) < 0) {
|
||||
fprintf(stderr, "Failed to modify time on %s: %s\n",
|
||||
argv[i], strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf(stderr, "usage: %s %s\n", argv[0], usage_str);
|
||||
return 1;
|
||||
}
|
||||
208
third_party/git/t/helper/test-config.c
vendored
Normal file
208
third_party/git/t/helper/test-config.c
vendored
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "config.h"
|
||||
#include "string-list.h"
|
||||
|
||||
/*
|
||||
* This program exposes the C API of the configuration mechanism
|
||||
* as a set of simple commands in order to facilitate testing.
|
||||
*
|
||||
* Reads stdin and prints result of command to stdout:
|
||||
*
|
||||
* get_value -> prints the value with highest priority for the entered key
|
||||
*
|
||||
* get_value_multi -> prints all values for the entered key in increasing order
|
||||
* of priority
|
||||
*
|
||||
* get_int -> print integer value for the entered key or die
|
||||
*
|
||||
* get_bool -> print bool value for the entered key or die
|
||||
*
|
||||
* get_string -> print string value for the entered key or die
|
||||
*
|
||||
* configset_get_value -> returns value with the highest priority for the entered key
|
||||
* from a config_set constructed from files entered as arguments.
|
||||
*
|
||||
* configset_get_value_multi -> returns value_list for the entered key sorted in
|
||||
* ascending order of priority from a config_set
|
||||
* constructed from files entered as arguments.
|
||||
*
|
||||
* iterate -> iterate over all values using git_config(), and print some
|
||||
* data for each
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* To print the value with highest priority for key "foo.bAr Baz.rock":
|
||||
* test-tool config get_value "foo.bAr Baz.rock"
|
||||
*
|
||||
*/
|
||||
|
||||
static const char *scope_name(enum config_scope scope)
|
||||
{
|
||||
switch (scope) {
|
||||
case CONFIG_SCOPE_SYSTEM:
|
||||
return "system";
|
||||
case CONFIG_SCOPE_GLOBAL:
|
||||
return "global";
|
||||
case CONFIG_SCOPE_REPO:
|
||||
return "repo";
|
||||
case CONFIG_SCOPE_CMDLINE:
|
||||
return "cmdline";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
static int iterate_cb(const char *var, const char *value, void *data)
|
||||
{
|
||||
static int nr;
|
||||
|
||||
if (nr++)
|
||||
putchar('\n');
|
||||
|
||||
printf("key=%s\n", var);
|
||||
printf("value=%s\n", value ? value : "(null)");
|
||||
printf("origin=%s\n", current_config_origin_type());
|
||||
printf("name=%s\n", current_config_name());
|
||||
printf("scope=%s\n", scope_name(current_config_scope()));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int early_config_cb(const char *var, const char *value, void *vdata)
|
||||
{
|
||||
const char *key = vdata;
|
||||
|
||||
if (!strcmp(key, var))
|
||||
printf("%s\n", value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cmd__config(int argc, const char **argv)
|
||||
{
|
||||
int i, val;
|
||||
const char *v;
|
||||
const struct string_list *strptr;
|
||||
struct config_set cs;
|
||||
|
||||
if (argc == 3 && !strcmp(argv[1], "read_early_config")) {
|
||||
read_early_config(early_config_cb, (void *)argv[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
setup_git_directory();
|
||||
|
||||
git_configset_init(&cs);
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Please, provide a command name on the command-line\n");
|
||||
goto exit1;
|
||||
} else if (argc == 3 && !strcmp(argv[1], "get_value")) {
|
||||
if (!git_config_get_value(argv[2], &v)) {
|
||||
if (!v)
|
||||
printf("(NULL)\n");
|
||||
else
|
||||
printf("%s\n", v);
|
||||
goto exit0;
|
||||
} else {
|
||||
printf("Value not found for \"%s\"\n", argv[2]);
|
||||
goto exit1;
|
||||
}
|
||||
} else if (argc == 3 && !strcmp(argv[1], "get_value_multi")) {
|
||||
strptr = git_config_get_value_multi(argv[2]);
|
||||
if (strptr) {
|
||||
for (i = 0; i < strptr->nr; i++) {
|
||||
v = strptr->items[i].string;
|
||||
if (!v)
|
||||
printf("(NULL)\n");
|
||||
else
|
||||
printf("%s\n", v);
|
||||
}
|
||||
goto exit0;
|
||||
} else {
|
||||
printf("Value not found for \"%s\"\n", argv[2]);
|
||||
goto exit1;
|
||||
}
|
||||
} else if (argc == 3 && !strcmp(argv[1], "get_int")) {
|
||||
if (!git_config_get_int(argv[2], &val)) {
|
||||
printf("%d\n", val);
|
||||
goto exit0;
|
||||
} else {
|
||||
printf("Value not found for \"%s\"\n", argv[2]);
|
||||
goto exit1;
|
||||
}
|
||||
} else if (argc == 3 && !strcmp(argv[1], "get_bool")) {
|
||||
if (!git_config_get_bool(argv[2], &val)) {
|
||||
printf("%d\n", val);
|
||||
goto exit0;
|
||||
} else {
|
||||
printf("Value not found for \"%s\"\n", argv[2]);
|
||||
goto exit1;
|
||||
}
|
||||
} else if (argc == 3 && !strcmp(argv[1], "get_string")) {
|
||||
if (!git_config_get_string_const(argv[2], &v)) {
|
||||
printf("%s\n", v);
|
||||
goto exit0;
|
||||
} else {
|
||||
printf("Value not found for \"%s\"\n", argv[2]);
|
||||
goto exit1;
|
||||
}
|
||||
} else if (!strcmp(argv[1], "configset_get_value")) {
|
||||
for (i = 3; i < argc; i++) {
|
||||
int err;
|
||||
if ((err = git_configset_add_file(&cs, argv[i]))) {
|
||||
fprintf(stderr, "Error (%d) reading configuration file %s.\n", err, argv[i]);
|
||||
goto exit2;
|
||||
}
|
||||
}
|
||||
if (!git_configset_get_value(&cs, argv[2], &v)) {
|
||||
if (!v)
|
||||
printf("(NULL)\n");
|
||||
else
|
||||
printf("%s\n", v);
|
||||
goto exit0;
|
||||
} else {
|
||||
printf("Value not found for \"%s\"\n", argv[2]);
|
||||
goto exit1;
|
||||
}
|
||||
} else if (!strcmp(argv[1], "configset_get_value_multi")) {
|
||||
for (i = 3; i < argc; i++) {
|
||||
int err;
|
||||
if ((err = git_configset_add_file(&cs, argv[i]))) {
|
||||
fprintf(stderr, "Error (%d) reading configuration file %s.\n", err, argv[i]);
|
||||
goto exit2;
|
||||
}
|
||||
}
|
||||
strptr = git_configset_get_value_multi(&cs, argv[2]);
|
||||
if (strptr) {
|
||||
for (i = 0; i < strptr->nr; i++) {
|
||||
v = strptr->items[i].string;
|
||||
if (!v)
|
||||
printf("(NULL)\n");
|
||||
else
|
||||
printf("%s\n", v);
|
||||
}
|
||||
goto exit0;
|
||||
} else {
|
||||
printf("Value not found for \"%s\"\n", argv[2]);
|
||||
goto exit1;
|
||||
}
|
||||
} else if (!strcmp(argv[1], "iterate")) {
|
||||
git_config(iterate_cb, NULL);
|
||||
goto exit0;
|
||||
}
|
||||
|
||||
die("%s: Please check the syntax and the function name", argv[0]);
|
||||
|
||||
exit0:
|
||||
git_configset_clear(&cs);
|
||||
return 0;
|
||||
|
||||
exit1:
|
||||
git_configset_clear(&cs);
|
||||
return 1;
|
||||
|
||||
exit2:
|
||||
git_configset_clear(&cs);
|
||||
return 2;
|
||||
}
|
||||
43
third_party/git/t/helper/test-ctype.c
vendored
Normal file
43
third_party/git/t/helper/test-ctype.c
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
|
||||
static int rc;
|
||||
|
||||
static void report_error(const char *class, int ch)
|
||||
{
|
||||
printf("%s classifies char %d (0x%02x) wrongly\n", class, ch, ch);
|
||||
rc = 1;
|
||||
}
|
||||
|
||||
static int is_in(const char *s, int ch)
|
||||
{
|
||||
/* We can't find NUL using strchr. It's classless anyway. */
|
||||
if (ch == '\0')
|
||||
return 0;
|
||||
return !!strchr(s, ch);
|
||||
}
|
||||
|
||||
#define TEST_CLASS(t,s) { \
|
||||
int i; \
|
||||
for (i = 0; i < 256; i++) { \
|
||||
if (is_in(s, i) != t(i)) \
|
||||
report_error(#t, i); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define DIGIT "0123456789"
|
||||
#define LOWER "abcdefghijklmnopqrstuvwxyz"
|
||||
#define UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
|
||||
int cmd__ctype(int argc, const char **argv)
|
||||
{
|
||||
TEST_CLASS(isdigit, DIGIT);
|
||||
TEST_CLASS(isspace, " \n\r\t");
|
||||
TEST_CLASS(isalpha, LOWER UPPER);
|
||||
TEST_CLASS(isalnum, LOWER UPPER DIGIT);
|
||||
TEST_CLASS(is_glob_special, "*?[\\");
|
||||
TEST_CLASS(is_regex_special, "$()*+.?[\\^{|");
|
||||
TEST_CLASS(is_pathspec_magic, "!\"#%&',-/:;<=>@_`~");
|
||||
|
||||
return rc;
|
||||
}
|
||||
141
third_party/git/t/helper/test-date.c
vendored
Normal file
141
third_party/git/t/helper/test-date.c
vendored
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
|
||||
static const char *usage_msg = "\n"
|
||||
" test-tool date relative [time_t]...\n"
|
||||
" test-tool date human [time_t]...\n"
|
||||
" test-tool date show:<format> [time_t]...\n"
|
||||
" test-tool date parse [date]...\n"
|
||||
" test-tool date approxidate [date]...\n"
|
||||
" test-tool date timestamp [date]...\n"
|
||||
" test-tool date getnanos [start-nanos]\n"
|
||||
" test-tool date is64bit\n"
|
||||
" test-tool date time_t-is64bit\n";
|
||||
|
||||
static void show_relative_dates(const char **argv, struct timeval *now)
|
||||
{
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
|
||||
for (; *argv; argv++) {
|
||||
time_t t = atoi(*argv);
|
||||
show_date_relative(t, now, &buf);
|
||||
printf("%s -> %s\n", *argv, buf.buf);
|
||||
}
|
||||
strbuf_release(&buf);
|
||||
}
|
||||
|
||||
static void show_human_dates(const char **argv)
|
||||
{
|
||||
for (; *argv; argv++) {
|
||||
time_t t = atoi(*argv);
|
||||
printf("%s -> %s\n", *argv, show_date(t, 0, DATE_MODE(HUMAN)));
|
||||
}
|
||||
}
|
||||
|
||||
static void show_dates(const char **argv, const char *format)
|
||||
{
|
||||
struct date_mode mode;
|
||||
|
||||
parse_date_format(format, &mode);
|
||||
for (; *argv; argv++) {
|
||||
char *arg;
|
||||
timestamp_t t;
|
||||
int tz;
|
||||
|
||||
/*
|
||||
* Do not use our normal timestamp parsing here, as the point
|
||||
* is to test the formatting code in isolation.
|
||||
*/
|
||||
t = parse_timestamp(*argv, &arg, 10);
|
||||
while (*arg == ' ')
|
||||
arg++;
|
||||
tz = atoi(arg);
|
||||
|
||||
printf("%s -> %s\n", *argv, show_date(t, tz, &mode));
|
||||
}
|
||||
}
|
||||
|
||||
static void parse_dates(const char **argv)
|
||||
{
|
||||
struct strbuf result = STRBUF_INIT;
|
||||
|
||||
for (; *argv; argv++) {
|
||||
timestamp_t t;
|
||||
int tz;
|
||||
|
||||
strbuf_reset(&result);
|
||||
parse_date(*argv, &result);
|
||||
if (sscanf(result.buf, "%"PRItime" %d", &t, &tz) == 2)
|
||||
printf("%s -> %s\n",
|
||||
*argv, show_date(t, tz, DATE_MODE(ISO8601)));
|
||||
else
|
||||
printf("%s -> bad\n", *argv);
|
||||
}
|
||||
strbuf_release(&result);
|
||||
}
|
||||
|
||||
static void parse_approxidate(const char **argv, struct timeval *now)
|
||||
{
|
||||
for (; *argv; argv++) {
|
||||
timestamp_t t;
|
||||
t = approxidate_relative(*argv, now);
|
||||
printf("%s -> %s\n", *argv, show_date(t, 0, DATE_MODE(ISO8601)));
|
||||
}
|
||||
}
|
||||
|
||||
static void parse_approx_timestamp(const char **argv, struct timeval *now)
|
||||
{
|
||||
for (; *argv; argv++) {
|
||||
timestamp_t t;
|
||||
t = approxidate_relative(*argv, now);
|
||||
printf("%s -> %"PRItime"\n", *argv, t);
|
||||
}
|
||||
}
|
||||
|
||||
static void getnanos(const char **argv)
|
||||
{
|
||||
double seconds = getnanotime() / 1.0e9;
|
||||
|
||||
if (*argv)
|
||||
seconds -= strtod(*argv, NULL);
|
||||
printf("%lf\n", seconds);
|
||||
}
|
||||
|
||||
int cmd__date(int argc, const char **argv)
|
||||
{
|
||||
struct timeval now;
|
||||
const char *x;
|
||||
|
||||
x = getenv("GIT_TEST_DATE_NOW");
|
||||
if (x) {
|
||||
now.tv_sec = atoi(x);
|
||||
now.tv_usec = 0;
|
||||
}
|
||||
else
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
argv++;
|
||||
if (!*argv)
|
||||
usage(usage_msg);
|
||||
if (!strcmp(*argv, "relative"))
|
||||
show_relative_dates(argv+1, &now);
|
||||
else if (!strcmp(*argv, "human"))
|
||||
show_human_dates(argv+1);
|
||||
else if (skip_prefix(*argv, "show:", &x))
|
||||
show_dates(argv+1, x);
|
||||
else if (!strcmp(*argv, "parse"))
|
||||
parse_dates(argv+1);
|
||||
else if (!strcmp(*argv, "approxidate"))
|
||||
parse_approxidate(argv+1, &now);
|
||||
else if (!strcmp(*argv, "timestamp"))
|
||||
parse_approx_timestamp(argv+1, &now);
|
||||
else if (!strcmp(*argv, "getnanos"))
|
||||
getnanos(argv+1);
|
||||
else if (!strcmp(*argv, "is64bit"))
|
||||
return sizeof(timestamp_t) == 8 ? 0 : 1;
|
||||
else if (!strcmp(*argv, "time_t-is64bit"))
|
||||
return sizeof(time_t) == 8 ? 0 : 1;
|
||||
else
|
||||
usage(usage_msg);
|
||||
return 0;
|
||||
}
|
||||
79
third_party/git/t/helper/test-delta.c
vendored
Normal file
79
third_party/git/t/helper/test-delta.c
vendored
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* test-delta.c: test code to exercise diff-delta.c and patch-delta.c
|
||||
*
|
||||
* (C) 2005 Nicolas Pitre <nico@fluxnic.net>
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include "test-tool.h"
|
||||
#include "git-compat-util.h"
|
||||
#include "delta.h"
|
||||
#include "cache.h"
|
||||
|
||||
static const char usage_str[] =
|
||||
"test-tool delta (-d|-p) <from_file> <data_file> <out_file>";
|
||||
|
||||
int cmd__delta(int argc, const char **argv)
|
||||
{
|
||||
int fd;
|
||||
struct stat st;
|
||||
void *from_buf, *data_buf, *out_buf;
|
||||
unsigned long from_size, data_size, out_size;
|
||||
|
||||
if (argc != 5 || (strcmp(argv[1], "-d") && strcmp(argv[1], "-p"))) {
|
||||
fprintf(stderr, "usage: %s\n", usage_str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fd = open(argv[2], O_RDONLY);
|
||||
if (fd < 0 || fstat(fd, &st)) {
|
||||
perror(argv[2]);
|
||||
return 1;
|
||||
}
|
||||
from_size = st.st_size;
|
||||
from_buf = xmalloc(from_size);
|
||||
if (read_in_full(fd, from_buf, from_size) < 0) {
|
||||
perror(argv[2]);
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
fd = open(argv[3], O_RDONLY);
|
||||
if (fd < 0 || fstat(fd, &st)) {
|
||||
perror(argv[3]);
|
||||
return 1;
|
||||
}
|
||||
data_size = st.st_size;
|
||||
data_buf = xmalloc(data_size);
|
||||
if (read_in_full(fd, data_buf, data_size) < 0) {
|
||||
perror(argv[3]);
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
if (argv[1][1] == 'd')
|
||||
out_buf = diff_delta(from_buf, from_size,
|
||||
data_buf, data_size,
|
||||
&out_size, 0);
|
||||
else
|
||||
out_buf = patch_delta(from_buf, from_size,
|
||||
data_buf, data_size,
|
||||
&out_size);
|
||||
if (!out_buf) {
|
||||
fprintf(stderr, "delta operation failed (returned NULL)\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
fd = open (argv[4], O_WRONLY|O_CREAT|O_TRUNC, 0666);
|
||||
if (fd < 0 || write_in_full(fd, out_buf, out_size) < 0) {
|
||||
perror(argv[4]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
65
third_party/git/t/helper/test-dir-iterator.c
vendored
Normal file
65
third_party/git/t/helper/test-dir-iterator.c
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
#include "test-tool.h"
|
||||
#include "git-compat-util.h"
|
||||
#include "strbuf.h"
|
||||
#include "iterator.h"
|
||||
#include "dir-iterator.h"
|
||||
|
||||
static const char *error_name(int error_number)
|
||||
{
|
||||
switch (error_number) {
|
||||
case ENOENT: return "ENOENT";
|
||||
case ENOTDIR: return "ENOTDIR";
|
||||
default: return "ESOMETHINGELSE";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* usage:
|
||||
* tool-test dir-iterator [--follow-symlinks] [--pedantic] directory_path
|
||||
*/
|
||||
int cmd__dir_iterator(int argc, const char **argv)
|
||||
{
|
||||
struct dir_iterator *diter;
|
||||
unsigned int flags = 0;
|
||||
int iter_status;
|
||||
|
||||
for (++argv, --argc; *argv && starts_with(*argv, "--"); ++argv, --argc) {
|
||||
if (strcmp(*argv, "--follow-symlinks") == 0)
|
||||
flags |= DIR_ITERATOR_FOLLOW_SYMLINKS;
|
||||
else if (strcmp(*argv, "--pedantic") == 0)
|
||||
flags |= DIR_ITERATOR_PEDANTIC;
|
||||
else
|
||||
die("invalid option '%s'", *argv);
|
||||
}
|
||||
|
||||
if (!*argv || argc != 1)
|
||||
die("dir-iterator needs exactly one non-option argument");
|
||||
|
||||
diter = dir_iterator_begin(*argv, flags);
|
||||
|
||||
if (!diter) {
|
||||
printf("dir_iterator_begin failure: %s\n", error_name(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
while ((iter_status = dir_iterator_advance(diter)) == ITER_OK) {
|
||||
if (S_ISDIR(diter->st.st_mode))
|
||||
printf("[d] ");
|
||||
else if (S_ISREG(diter->st.st_mode))
|
||||
printf("[f] ");
|
||||
else if (S_ISLNK(diter->st.st_mode))
|
||||
printf("[s] ");
|
||||
else
|
||||
printf("[?] ");
|
||||
|
||||
printf("(%s) [%s] %s\n", diter->relative_path, diter->basename,
|
||||
diter->path.buf);
|
||||
}
|
||||
|
||||
if (iter_status != ITER_DONE) {
|
||||
printf("dir_iterator_advance failure\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
157
third_party/git/t/helper/test-drop-caches.c
vendored
Normal file
157
third_party/git/t/helper/test-drop-caches.c
vendored
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
#include "test-tool.h"
|
||||
#include "git-compat-util.h"
|
||||
|
||||
#if defined(GIT_WINDOWS_NATIVE)
|
||||
#include "lazyload.h"
|
||||
|
||||
static int cmd_sync(void)
|
||||
{
|
||||
char Buffer[MAX_PATH];
|
||||
DWORD dwRet;
|
||||
char szVolumeAccessPath[] = "\\\\.\\X:";
|
||||
HANDLE hVolWrite;
|
||||
int success = 0;
|
||||
|
||||
dwRet = GetCurrentDirectory(MAX_PATH, Buffer);
|
||||
if ((0 == dwRet) || (dwRet > MAX_PATH))
|
||||
return error("Error getting current directory");
|
||||
|
||||
if (!has_dos_drive_prefix(Buffer))
|
||||
return error("'%s': invalid drive letter", Buffer);
|
||||
|
||||
szVolumeAccessPath[4] = Buffer[0];
|
||||
hVolWrite = CreateFile(szVolumeAccessPath, GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (INVALID_HANDLE_VALUE == hVolWrite)
|
||||
return error("Unable to open volume for writing, need admin access");
|
||||
|
||||
success = FlushFileBuffers(hVolWrite);
|
||||
if (!success)
|
||||
error("Unable to flush volume");
|
||||
|
||||
CloseHandle(hVolWrite);
|
||||
|
||||
return !success;
|
||||
}
|
||||
|
||||
#define STATUS_SUCCESS (0x00000000L)
|
||||
#define STATUS_PRIVILEGE_NOT_HELD (0xC0000061L)
|
||||
|
||||
typedef enum _SYSTEM_INFORMATION_CLASS {
|
||||
SystemMemoryListInformation = 80,
|
||||
} SYSTEM_INFORMATION_CLASS;
|
||||
|
||||
typedef enum _SYSTEM_MEMORY_LIST_COMMAND {
|
||||
MemoryCaptureAccessedBits,
|
||||
MemoryCaptureAndResetAccessedBits,
|
||||
MemoryEmptyWorkingSets,
|
||||
MemoryFlushModifiedList,
|
||||
MemoryPurgeStandbyList,
|
||||
MemoryPurgeLowPriorityStandbyList,
|
||||
MemoryCommandMax
|
||||
} SYSTEM_MEMORY_LIST_COMMAND;
|
||||
|
||||
static BOOL GetPrivilege(HANDLE TokenHandle, LPCSTR lpName, int flags)
|
||||
{
|
||||
BOOL bResult;
|
||||
DWORD dwBufferLength;
|
||||
LUID luid;
|
||||
TOKEN_PRIVILEGES tpPreviousState;
|
||||
TOKEN_PRIVILEGES tpNewState;
|
||||
|
||||
dwBufferLength = 16;
|
||||
bResult = LookupPrivilegeValueA(0, lpName, &luid);
|
||||
if (bResult) {
|
||||
tpNewState.PrivilegeCount = 1;
|
||||
tpNewState.Privileges[0].Luid = luid;
|
||||
tpNewState.Privileges[0].Attributes = 0;
|
||||
bResult = AdjustTokenPrivileges(TokenHandle, 0, &tpNewState,
|
||||
(DWORD)((LPBYTE)&(tpNewState.Privileges[1]) - (LPBYTE)&tpNewState),
|
||||
&tpPreviousState, &dwBufferLength);
|
||||
if (bResult) {
|
||||
tpPreviousState.PrivilegeCount = 1;
|
||||
tpPreviousState.Privileges[0].Luid = luid;
|
||||
tpPreviousState.Privileges[0].Attributes = flags != 0 ? 2 : 0;
|
||||
bResult = AdjustTokenPrivileges(TokenHandle, 0, &tpPreviousState,
|
||||
dwBufferLength, 0, 0);
|
||||
}
|
||||
}
|
||||
return bResult;
|
||||
}
|
||||
|
||||
static int cmd_dropcaches(void)
|
||||
{
|
||||
HANDLE hProcess = GetCurrentProcess();
|
||||
HANDLE hToken;
|
||||
DECLARE_PROC_ADDR(ntdll.dll, DWORD, NtSetSystemInformation, INT, PVOID, ULONG);
|
||||
SYSTEM_MEMORY_LIST_COMMAND command;
|
||||
int status;
|
||||
|
||||
if (!OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
|
||||
return error("Can't open current process token");
|
||||
|
||||
if (!GetPrivilege(hToken, "SeProfileSingleProcessPrivilege", 1))
|
||||
return error("Can't get SeProfileSingleProcessPrivilege");
|
||||
|
||||
CloseHandle(hToken);
|
||||
|
||||
if (!INIT_PROC_ADDR(NtSetSystemInformation))
|
||||
return error("Could not find NtSetSystemInformation() function");
|
||||
|
||||
command = MemoryPurgeStandbyList;
|
||||
status = NtSetSystemInformation(
|
||||
SystemMemoryListInformation,
|
||||
&command,
|
||||
sizeof(SYSTEM_MEMORY_LIST_COMMAND)
|
||||
);
|
||||
if (status == STATUS_PRIVILEGE_NOT_HELD)
|
||||
error("Insufficient privileges to purge the standby list, need admin access");
|
||||
else if (status != STATUS_SUCCESS)
|
||||
error("Unable to execute the memory list command %d", status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#elif defined(__linux__)
|
||||
|
||||
static int cmd_sync(void)
|
||||
{
|
||||
return system("sync");
|
||||
}
|
||||
|
||||
static int cmd_dropcaches(void)
|
||||
{
|
||||
return system("echo 3 | sudo tee /proc/sys/vm/drop_caches");
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
static int cmd_sync(void)
|
||||
{
|
||||
return system("sync");
|
||||
}
|
||||
|
||||
static int cmd_dropcaches(void)
|
||||
{
|
||||
return system("sudo purge");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int cmd_sync(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_dropcaches(void)
|
||||
{
|
||||
return error("drop caches not implemented on this platform");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int cmd__drop_caches(int argc, const char **argv)
|
||||
{
|
||||
cmd_sync();
|
||||
return cmd_dropcaches();
|
||||
}
|
||||
69
third_party/git/t/helper/test-dump-cache-tree.c
vendored
Normal file
69
third_party/git/t/helper/test-dump-cache-tree.c
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "tree.h"
|
||||
#include "cache-tree.h"
|
||||
|
||||
|
||||
static void dump_one(struct cache_tree *it, const char *pfx, const char *x)
|
||||
{
|
||||
if (it->entry_count < 0)
|
||||
printf("%-40s %s%s (%d subtrees)\n",
|
||||
"invalid", x, pfx, it->subtree_nr);
|
||||
else
|
||||
printf("%s %s%s (%d entries, %d subtrees)\n",
|
||||
oid_to_hex(&it->oid), x, pfx,
|
||||
it->entry_count, it->subtree_nr);
|
||||
}
|
||||
|
||||
static int dump_cache_tree(struct cache_tree *it,
|
||||
struct cache_tree *ref,
|
||||
const char *pfx)
|
||||
{
|
||||
int i;
|
||||
int errs = 0;
|
||||
|
||||
if (!it || !ref)
|
||||
/* missing in either */
|
||||
return 0;
|
||||
|
||||
if (it->entry_count < 0) {
|
||||
/* invalid */
|
||||
dump_one(it, pfx, "");
|
||||
dump_one(ref, pfx, "#(ref) ");
|
||||
}
|
||||
else {
|
||||
dump_one(it, pfx, "");
|
||||
if (!oideq(&it->oid, &ref->oid) ||
|
||||
ref->entry_count != it->entry_count ||
|
||||
ref->subtree_nr != it->subtree_nr) {
|
||||
/* claims to be valid but is lying */
|
||||
dump_one(ref, pfx, "#(ref) ");
|
||||
errs = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < it->subtree_nr; i++) {
|
||||
char path[PATH_MAX];
|
||||
struct cache_tree_sub *down = it->down[i];
|
||||
struct cache_tree_sub *rdwn;
|
||||
|
||||
rdwn = cache_tree_sub(ref, down->name);
|
||||
xsnprintf(path, sizeof(path), "%s%.*s/", pfx, down->namelen, down->name);
|
||||
if (dump_cache_tree(down->cache_tree, rdwn->cache_tree, path))
|
||||
errs = 1;
|
||||
}
|
||||
return errs;
|
||||
}
|
||||
|
||||
int cmd__dump_cache_tree(int ac, const char **av)
|
||||
{
|
||||
struct index_state istate;
|
||||
struct cache_tree *another = cache_tree();
|
||||
setup_git_directory();
|
||||
if (read_cache() < 0)
|
||||
die("unable to read index file");
|
||||
istate = the_index;
|
||||
istate.cache_tree = another;
|
||||
cache_tree_update(&istate, WRITE_TREE_DRY_RUN);
|
||||
return dump_cache_tree(active_cache_tree, another, "");
|
||||
}
|
||||
22
third_party/git/t/helper/test-dump-fsmonitor.c
vendored
Normal file
22
third_party/git/t/helper/test-dump-fsmonitor.c
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
|
||||
int cmd__dump_fsmonitor(int ac, const char **av)
|
||||
{
|
||||
struct index_state *istate = the_repository->index;
|
||||
int i;
|
||||
|
||||
setup_git_directory();
|
||||
if (do_read_index(istate, the_repository->index_file, 0) < 0)
|
||||
die("unable to read index file");
|
||||
if (!istate->fsmonitor_last_update) {
|
||||
printf("no fsmonitor\n");
|
||||
return 0;
|
||||
}
|
||||
printf("fsmonitor last update %"PRIuMAX"\n", (uintmax_t)istate->fsmonitor_last_update);
|
||||
|
||||
for (i = 0; i < istate->cache_nr; i++)
|
||||
printf((istate->cache[i]->ce_flags & CE_FSMONITOR_VALID) ? "+" : "-");
|
||||
|
||||
return 0;
|
||||
}
|
||||
37
third_party/git/t/helper/test-dump-split-index.c
vendored
Normal file
37
third_party/git/t/helper/test-dump-split-index.c
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "split-index.h"
|
||||
#include "ewah/ewok.h"
|
||||
|
||||
static void show_bit(size_t pos, void *data)
|
||||
{
|
||||
printf(" %d", (int)pos);
|
||||
}
|
||||
|
||||
int cmd__dump_split_index(int ac, const char **av)
|
||||
{
|
||||
struct split_index *si;
|
||||
int i;
|
||||
|
||||
do_read_index(&the_index, av[1], 1);
|
||||
printf("own %s\n", oid_to_hex(&the_index.oid));
|
||||
si = the_index.split_index;
|
||||
if (!si) {
|
||||
printf("not a split index\n");
|
||||
return 0;
|
||||
}
|
||||
printf("base %s\n", oid_to_hex(&si->base_oid));
|
||||
for (i = 0; i < the_index.cache_nr; i++) {
|
||||
struct cache_entry *ce = the_index.cache[i];
|
||||
printf("%06o %s %d\t%s\n", ce->ce_mode,
|
||||
oid_to_hex(&ce->oid), ce_stage(ce), ce->name);
|
||||
}
|
||||
printf("replacements:");
|
||||
if (si->replace_bitmap)
|
||||
ewah_each_bit(si->replace_bitmap, show_bit, NULL);
|
||||
printf("\ndeletions:");
|
||||
if (si->delete_bitmap)
|
||||
ewah_each_bit(si->delete_bitmap, show_bit, NULL);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
66
third_party/git/t/helper/test-dump-untracked-cache.c
vendored
Normal file
66
third_party/git/t/helper/test-dump-untracked-cache.c
vendored
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#define USE_THE_INDEX_COMPATIBILITY_MACROS
|
||||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "dir.h"
|
||||
|
||||
static int compare_untracked(const void *a_, const void *b_)
|
||||
{
|
||||
const char *const *a = a_;
|
||||
const char *const *b = b_;
|
||||
return strcmp(*a, *b);
|
||||
}
|
||||
|
||||
static int compare_dir(const void *a_, const void *b_)
|
||||
{
|
||||
const struct untracked_cache_dir *const *a = a_;
|
||||
const struct untracked_cache_dir *const *b = b_;
|
||||
return strcmp((*a)->name, (*b)->name);
|
||||
}
|
||||
|
||||
static void dump(struct untracked_cache_dir *ucd, struct strbuf *base)
|
||||
{
|
||||
int i, len;
|
||||
QSORT(ucd->untracked, ucd->untracked_nr, compare_untracked);
|
||||
QSORT(ucd->dirs, ucd->dirs_nr, compare_dir);
|
||||
len = base->len;
|
||||
strbuf_addf(base, "%s/", ucd->name);
|
||||
printf("%s %s", base->buf,
|
||||
oid_to_hex(&ucd->exclude_oid));
|
||||
if (ucd->recurse)
|
||||
fputs(" recurse", stdout);
|
||||
if (ucd->check_only)
|
||||
fputs(" check_only", stdout);
|
||||
if (ucd->valid)
|
||||
fputs(" valid", stdout);
|
||||
printf("\n");
|
||||
for (i = 0; i < ucd->untracked_nr; i++)
|
||||
printf("%s\n", ucd->untracked[i]);
|
||||
for (i = 0; i < ucd->dirs_nr; i++)
|
||||
dump(ucd->dirs[i], base);
|
||||
strbuf_setlen(base, len);
|
||||
}
|
||||
|
||||
int cmd__dump_untracked_cache(int ac, const char **av)
|
||||
{
|
||||
struct untracked_cache *uc;
|
||||
struct strbuf base = STRBUF_INIT;
|
||||
|
||||
/* Hack to avoid modifying the untracked cache when we read it */
|
||||
ignore_untracked_cache_config = 1;
|
||||
|
||||
setup_git_directory();
|
||||
if (read_cache() < 0)
|
||||
die("unable to read index file");
|
||||
uc = the_index.untracked;
|
||||
if (!uc) {
|
||||
printf("no untracked cache\n");
|
||||
return 0;
|
||||
}
|
||||
printf("info/exclude %s\n", oid_to_hex(&uc->ss_info_exclude.oid));
|
||||
printf("core.excludesfile %s\n", oid_to_hex(&uc->ss_excludes_file.oid));
|
||||
printf("exclude_per_dir %s\n", uc->exclude_per_dir);
|
||||
printf("flags %08x\n", uc->dir_flags);
|
||||
if (uc->root)
|
||||
dump(uc->root, &base);
|
||||
return 0;
|
||||
}
|
||||
75
third_party/git/t/helper/test-example-decorate.c
vendored
Normal file
75
third_party/git/t/helper/test-example-decorate.c
vendored
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "object.h"
|
||||
#include "decorate.h"
|
||||
|
||||
int cmd__example_decorate(int argc, const char **argv)
|
||||
{
|
||||
struct decoration n;
|
||||
struct object_id one_oid = { {1} };
|
||||
struct object_id two_oid = { {2} };
|
||||
struct object_id three_oid = { {3} };
|
||||
struct object *one, *two, *three;
|
||||
|
||||
int decoration_a, decoration_b;
|
||||
|
||||
void *ret;
|
||||
|
||||
int i, objects_noticed = 0;
|
||||
|
||||
/*
|
||||
* The struct must be zero-initialized.
|
||||
*/
|
||||
memset(&n, 0, sizeof(n));
|
||||
|
||||
/*
|
||||
* Add 2 objects, one with a non-NULL decoration and one with a NULL
|
||||
* decoration.
|
||||
*/
|
||||
one = lookup_unknown_object(&one_oid);
|
||||
two = lookup_unknown_object(&two_oid);
|
||||
ret = add_decoration(&n, one, &decoration_a);
|
||||
if (ret)
|
||||
BUG("when adding a brand-new object, NULL should be returned");
|
||||
ret = add_decoration(&n, two, NULL);
|
||||
if (ret)
|
||||
BUG("when adding a brand-new object, NULL should be returned");
|
||||
|
||||
/*
|
||||
* When re-adding an already existing object, the old decoration is
|
||||
* returned.
|
||||
*/
|
||||
ret = add_decoration(&n, one, NULL);
|
||||
if (ret != &decoration_a)
|
||||
BUG("when readding an already existing object, existing decoration should be returned");
|
||||
ret = add_decoration(&n, two, &decoration_b);
|
||||
if (ret)
|
||||
BUG("when readding an already existing object, existing decoration should be returned");
|
||||
|
||||
/*
|
||||
* Lookup returns the added declarations, or NULL if the object was
|
||||
* never added.
|
||||
*/
|
||||
ret = lookup_decoration(&n, one);
|
||||
if (ret)
|
||||
BUG("lookup should return added declaration");
|
||||
ret = lookup_decoration(&n, two);
|
||||
if (ret != &decoration_b)
|
||||
BUG("lookup should return added declaration");
|
||||
three = lookup_unknown_object(&three_oid);
|
||||
ret = lookup_decoration(&n, three);
|
||||
if (ret)
|
||||
BUG("lookup for unknown object should return NULL");
|
||||
|
||||
/*
|
||||
* The user can also loop through all entries.
|
||||
*/
|
||||
for (i = 0; i < n.size; i++) {
|
||||
if (n.entries[i].base)
|
||||
objects_noticed++;
|
||||
}
|
||||
if (objects_noticed != 2)
|
||||
BUG("should have 2 objects");
|
||||
|
||||
return 0;
|
||||
}
|
||||
30
third_party/git/t/helper/test-fake-ssh.c
vendored
Normal file
30
third_party/git/t/helper/test-fake-ssh.c
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#include "git-compat-util.h"
|
||||
#include "run-command.h"
|
||||
#include "strbuf.h"
|
||||
|
||||
int cmd_main(int argc, const char **argv)
|
||||
{
|
||||
const char *trash_directory = getenv("TRASH_DIRECTORY");
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
FILE *f;
|
||||
int i;
|
||||
const char *child_argv[] = { NULL, NULL };
|
||||
|
||||
/* First, print all parameters into $TRASH_DIRECTORY/ssh-output */
|
||||
if (!trash_directory)
|
||||
die("Need a TRASH_DIRECTORY!");
|
||||
strbuf_addf(&buf, "%s/ssh-output", trash_directory);
|
||||
f = fopen(buf.buf, "w");
|
||||
if (!f)
|
||||
die("Could not write to %s", buf.buf);
|
||||
for (i = 0; i < argc; i++)
|
||||
fprintf(f, "%s%s", i > 0 ? " " : "", i > 0 ? argv[i] : "ssh:");
|
||||
fprintf(f, "\n");
|
||||
fclose(f);
|
||||
|
||||
/* Now, evaluate the *last* parameter */
|
||||
if (argc < 2)
|
||||
return 0;
|
||||
child_argv[0] = argv[argc - 1];
|
||||
return run_command_v_opt(child_argv, RUN_USING_SHELL);
|
||||
}
|
||||
34
third_party/git/t/helper/test-genrandom.c
vendored
Normal file
34
third_party/git/t/helper/test-genrandom.c
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Simple random data generator used to create reproducible test files.
|
||||
* This is inspired from POSIX.1-2001 implementation example for rand().
|
||||
* Copyright (C) 2007 by Nicolas Pitre, licensed under the GPL version 2.
|
||||
*/
|
||||
|
||||
#include "test-tool.h"
|
||||
#include "git-compat-util.h"
|
||||
|
||||
int cmd__genrandom(int argc, const char **argv)
|
||||
{
|
||||
unsigned long count, next = 0;
|
||||
unsigned char *c;
|
||||
|
||||
if (argc < 2 || argc > 3) {
|
||||
fprintf(stderr, "usage: %s <seed_string> [<size>]\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
c = (unsigned char *) argv[1];
|
||||
do {
|
||||
next = next * 11 + *c;
|
||||
} while (*c++);
|
||||
|
||||
count = (argc == 3) ? strtoul(argv[2], NULL, 0) : -1L;
|
||||
|
||||
while (count--) {
|
||||
next = next * 1103515245 + 12345;
|
||||
if (putchar((next >> 16) & 0xff) == EOF)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
21
third_party/git/t/helper/test-genzeros.c
vendored
Normal file
21
third_party/git/t/helper/test-genzeros.c
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#include "test-tool.h"
|
||||
#include "git-compat-util.h"
|
||||
|
||||
int cmd__genzeros(int argc, const char **argv)
|
||||
{
|
||||
long count;
|
||||
|
||||
if (argc > 2) {
|
||||
fprintf(stderr, "usage: %s [<count>]\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
count = argc > 1 ? strtol(argv[1], NULL, 0) : -1L;
|
||||
|
||||
while (count < 0 || count--) {
|
||||
if (putchar(0) == EOF)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
61
third_party/git/t/helper/test-hash-speed.c
vendored
Normal file
61
third_party/git/t/helper/test-hash-speed.c
vendored
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
|
||||
#define NUM_SECONDS 3
|
||||
|
||||
static inline void compute_hash(const struct git_hash_algo *algo, git_hash_ctx *ctx, uint8_t *final, const void *p, size_t len)
|
||||
{
|
||||
algo->init_fn(ctx);
|
||||
algo->update_fn(ctx, p, len);
|
||||
algo->final_fn(final, ctx);
|
||||
}
|
||||
|
||||
int cmd__hash_speed(int ac, const char **av)
|
||||
{
|
||||
git_hash_ctx ctx;
|
||||
unsigned char hash[GIT_MAX_RAWSZ];
|
||||
clock_t initial, start, end;
|
||||
unsigned bufsizes[] = { 64, 256, 1024, 8192, 16384 };
|
||||
int i;
|
||||
void *p;
|
||||
const struct git_hash_algo *algo = NULL;
|
||||
|
||||
if (ac == 2) {
|
||||
for (i = 1; i < GIT_HASH_NALGOS; i++) {
|
||||
if (!strcmp(av[1], hash_algos[i].name)) {
|
||||
algo = &hash_algos[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!algo)
|
||||
die("usage: test-tool hash-speed algo_name");
|
||||
|
||||
/* Use this as an offset to make overflow less likely. */
|
||||
initial = clock();
|
||||
|
||||
printf("algo: %s\n", algo->name);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(bufsizes); i++) {
|
||||
unsigned long j, kb;
|
||||
double kb_per_sec;
|
||||
p = xcalloc(1, bufsizes[i]);
|
||||
start = end = clock() - initial;
|
||||
for (j = 0; ((end - start) / CLOCKS_PER_SEC) < NUM_SECONDS; j++) {
|
||||
compute_hash(algo, &ctx, hash, p, bufsizes[i]);
|
||||
|
||||
/*
|
||||
* Only check elapsed time every 128 iterations to avoid
|
||||
* dominating the runtime with system calls.
|
||||
*/
|
||||
if (!(j & 127))
|
||||
end = clock() - initial;
|
||||
}
|
||||
kb = j * bufsizes[i];
|
||||
kb_per_sec = kb / (1024 * ((double)end - start) / CLOCKS_PER_SEC);
|
||||
printf("size %u: %lu iters; %lu KiB; %0.2f KiB/s\n", bufsizes[i], j, kb, kb_per_sec);
|
||||
free(p);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
58
third_party/git/t/helper/test-hash.c
vendored
Normal file
58
third_party/git/t/helper/test-hash.c
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
|
||||
int cmd_hash_impl(int ac, const char **av, int algo)
|
||||
{
|
||||
git_hash_ctx ctx;
|
||||
unsigned char hash[GIT_MAX_HEXSZ];
|
||||
unsigned bufsz = 8192;
|
||||
int binary = 0;
|
||||
char *buffer;
|
||||
const struct git_hash_algo *algop = &hash_algos[algo];
|
||||
|
||||
if (ac == 2) {
|
||||
if (!strcmp(av[1], "-b"))
|
||||
binary = 1;
|
||||
else
|
||||
bufsz = strtoul(av[1], NULL, 10) * 1024 * 1024;
|
||||
}
|
||||
|
||||
if (!bufsz)
|
||||
bufsz = 8192;
|
||||
|
||||
while ((buffer = malloc(bufsz)) == NULL) {
|
||||
fprintf(stderr, "bufsz %u is too big, halving...\n", bufsz);
|
||||
bufsz /= 2;
|
||||
if (bufsz < 1024)
|
||||
die("OOPS");
|
||||
}
|
||||
|
||||
algop->init_fn(&ctx);
|
||||
|
||||
while (1) {
|
||||
ssize_t sz, this_sz;
|
||||
char *cp = buffer;
|
||||
unsigned room = bufsz;
|
||||
this_sz = 0;
|
||||
while (room) {
|
||||
sz = xread(0, cp, room);
|
||||
if (sz == 0)
|
||||
break;
|
||||
if (sz < 0)
|
||||
die_errno("test-hash");
|
||||
this_sz += sz;
|
||||
cp += sz;
|
||||
room -= sz;
|
||||
}
|
||||
if (this_sz == 0)
|
||||
break;
|
||||
algop->update_fn(&ctx, buffer, this_sz);
|
||||
}
|
||||
algop->final_fn(hash, &ctx);
|
||||
|
||||
if (binary)
|
||||
fwrite(hash, 1, algop->rawsz, stdout);
|
||||
else
|
||||
puts(hash_to_hex_algop(hash, algop));
|
||||
exit(0);
|
||||
}
|
||||
263
third_party/git/t/helper/test-hashmap.c
vendored
Normal file
263
third_party/git/t/helper/test-hashmap.c
vendored
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
#include "test-tool.h"
|
||||
#include "git-compat-util.h"
|
||||
#include "hashmap.h"
|
||||
#include "strbuf.h"
|
||||
|
||||
struct test_entry
|
||||
{
|
||||
struct hashmap_entry ent;
|
||||
/* key and value as two \0-terminated strings */
|
||||
char key[FLEX_ARRAY];
|
||||
};
|
||||
|
||||
static const char *get_value(const struct test_entry *e)
|
||||
{
|
||||
return e->key + strlen(e->key) + 1;
|
||||
}
|
||||
|
||||
static int test_entry_cmp(const void *cmp_data,
|
||||
const void *entry,
|
||||
const void *entry_or_key,
|
||||
const void *keydata)
|
||||
{
|
||||
const int ignore_case = cmp_data ? *((int *)cmp_data) : 0;
|
||||
const struct test_entry *e1 = entry;
|
||||
const struct test_entry *e2 = entry_or_key;
|
||||
const char *key = keydata;
|
||||
|
||||
if (ignore_case)
|
||||
return strcasecmp(e1->key, key ? key : e2->key);
|
||||
else
|
||||
return strcmp(e1->key, key ? key : e2->key);
|
||||
}
|
||||
|
||||
static struct test_entry *alloc_test_entry(unsigned int hash,
|
||||
char *key, char *value)
|
||||
{
|
||||
size_t klen = strlen(key);
|
||||
size_t vlen = strlen(value);
|
||||
struct test_entry *entry = xmalloc(st_add4(sizeof(*entry), klen, vlen, 2));
|
||||
hashmap_entry_init(entry, hash);
|
||||
memcpy(entry->key, key, klen + 1);
|
||||
memcpy(entry->key + klen + 1, value, vlen + 1);
|
||||
return entry;
|
||||
}
|
||||
|
||||
#define HASH_METHOD_FNV 0
|
||||
#define HASH_METHOD_I 1
|
||||
#define HASH_METHOD_IDIV10 2
|
||||
#define HASH_METHOD_0 3
|
||||
#define HASH_METHOD_X2 4
|
||||
#define TEST_SPARSE 8
|
||||
#define TEST_ADD 16
|
||||
#define TEST_SIZE 100000
|
||||
|
||||
static unsigned int hash(unsigned int method, unsigned int i, const char *key)
|
||||
{
|
||||
unsigned int hash = 0;
|
||||
switch (method & 3)
|
||||
{
|
||||
case HASH_METHOD_FNV:
|
||||
hash = strhash(key);
|
||||
break;
|
||||
case HASH_METHOD_I:
|
||||
hash = i;
|
||||
break;
|
||||
case HASH_METHOD_IDIV10:
|
||||
hash = i / 10;
|
||||
break;
|
||||
case HASH_METHOD_0:
|
||||
hash = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (method & HASH_METHOD_X2)
|
||||
hash = 2 * hash;
|
||||
return hash;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test performance of hashmap.[ch]
|
||||
* Usage: time echo "perfhashmap method rounds" | test-tool hashmap
|
||||
*/
|
||||
static void perf_hashmap(unsigned int method, unsigned int rounds)
|
||||
{
|
||||
struct hashmap map;
|
||||
char buf[16];
|
||||
struct test_entry **entries;
|
||||
unsigned int *hashes;
|
||||
unsigned int i, j;
|
||||
|
||||
ALLOC_ARRAY(entries, TEST_SIZE);
|
||||
ALLOC_ARRAY(hashes, TEST_SIZE);
|
||||
for (i = 0; i < TEST_SIZE; i++) {
|
||||
xsnprintf(buf, sizeof(buf), "%i", i);
|
||||
entries[i] = alloc_test_entry(0, buf, "");
|
||||
hashes[i] = hash(method, i, entries[i]->key);
|
||||
}
|
||||
|
||||
if (method & TEST_ADD) {
|
||||
/* test adding to the map */
|
||||
for (j = 0; j < rounds; j++) {
|
||||
hashmap_init(&map, test_entry_cmp, NULL, 0);
|
||||
|
||||
/* add entries */
|
||||
for (i = 0; i < TEST_SIZE; i++) {
|
||||
hashmap_entry_init(entries[i], hashes[i]);
|
||||
hashmap_add(&map, entries[i]);
|
||||
}
|
||||
|
||||
hashmap_free(&map, 0);
|
||||
}
|
||||
} else {
|
||||
/* test map lookups */
|
||||
hashmap_init(&map, test_entry_cmp, NULL, 0);
|
||||
|
||||
/* fill the map (sparsely if specified) */
|
||||
j = (method & TEST_SPARSE) ? TEST_SIZE / 10 : TEST_SIZE;
|
||||
for (i = 0; i < j; i++) {
|
||||
hashmap_entry_init(entries[i], hashes[i]);
|
||||
hashmap_add(&map, entries[i]);
|
||||
}
|
||||
|
||||
for (j = 0; j < rounds; j++) {
|
||||
for (i = 0; i < TEST_SIZE; i++) {
|
||||
hashmap_get_from_hash(&map, hashes[i],
|
||||
entries[i]->key);
|
||||
}
|
||||
}
|
||||
|
||||
hashmap_free(&map, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#define DELIM " \t\r\n"
|
||||
|
||||
/*
|
||||
* Read stdin line by line and print result of commands to stdout:
|
||||
*
|
||||
* hash key -> strhash(key) memhash(key) strihash(key) memihash(key)
|
||||
* put key value -> NULL / old value
|
||||
* get key -> NULL / value
|
||||
* remove key -> NULL / old value
|
||||
* iterate -> key1 value1\nkey2 value2\n...
|
||||
* size -> tablesize numentries
|
||||
*
|
||||
* perfhashmap method rounds -> test hashmap.[ch] performance
|
||||
*/
|
||||
int cmd__hashmap(int argc, const char **argv)
|
||||
{
|
||||
struct strbuf line = STRBUF_INIT;
|
||||
struct hashmap map;
|
||||
int icase;
|
||||
|
||||
/* init hash map */
|
||||
icase = argc > 1 && !strcmp("ignorecase", argv[1]);
|
||||
hashmap_init(&map, test_entry_cmp, &icase, 0);
|
||||
|
||||
/* process commands from stdin */
|
||||
while (strbuf_getline(&line, stdin) != EOF) {
|
||||
char *cmd, *p1 = NULL, *p2 = NULL;
|
||||
unsigned int hash = 0;
|
||||
struct test_entry *entry;
|
||||
|
||||
/* break line into command and up to two parameters */
|
||||
cmd = strtok(line.buf, DELIM);
|
||||
/* ignore empty lines */
|
||||
if (!cmd || *cmd == '#')
|
||||
continue;
|
||||
|
||||
p1 = strtok(NULL, DELIM);
|
||||
if (p1) {
|
||||
hash = icase ? strihash(p1) : strhash(p1);
|
||||
p2 = strtok(NULL, DELIM);
|
||||
}
|
||||
|
||||
if (!strcmp("add", cmd) && p1 && p2) {
|
||||
|
||||
/* create entry with key = p1, value = p2 */
|
||||
entry = alloc_test_entry(hash, p1, p2);
|
||||
|
||||
/* add to hashmap */
|
||||
hashmap_add(&map, entry);
|
||||
|
||||
} else if (!strcmp("put", cmd) && p1 && p2) {
|
||||
|
||||
/* create entry with key = p1, value = p2 */
|
||||
entry = alloc_test_entry(hash, p1, p2);
|
||||
|
||||
/* add / replace entry */
|
||||
entry = hashmap_put(&map, entry);
|
||||
|
||||
/* print and free replaced entry, if any */
|
||||
puts(entry ? get_value(entry) : "NULL");
|
||||
free(entry);
|
||||
|
||||
} else if (!strcmp("get", cmd) && p1) {
|
||||
|
||||
/* lookup entry in hashmap */
|
||||
entry = hashmap_get_from_hash(&map, hash, p1);
|
||||
|
||||
/* print result */
|
||||
if (!entry)
|
||||
puts("NULL");
|
||||
while (entry) {
|
||||
puts(get_value(entry));
|
||||
entry = hashmap_get_next(&map, entry);
|
||||
}
|
||||
|
||||
} else if (!strcmp("remove", cmd) && p1) {
|
||||
|
||||
/* setup static key */
|
||||
struct hashmap_entry key;
|
||||
hashmap_entry_init(&key, hash);
|
||||
|
||||
/* remove entry from hashmap */
|
||||
entry = hashmap_remove(&map, &key, p1);
|
||||
|
||||
/* print result and free entry*/
|
||||
puts(entry ? get_value(entry) : "NULL");
|
||||
free(entry);
|
||||
|
||||
} else if (!strcmp("iterate", cmd)) {
|
||||
|
||||
struct hashmap_iter iter;
|
||||
hashmap_iter_init(&map, &iter);
|
||||
while ((entry = hashmap_iter_next(&iter)))
|
||||
printf("%s %s\n", entry->key, get_value(entry));
|
||||
|
||||
} else if (!strcmp("size", cmd)) {
|
||||
|
||||
/* print table sizes */
|
||||
printf("%u %u\n", map.tablesize,
|
||||
hashmap_get_size(&map));
|
||||
|
||||
} else if (!strcmp("intern", cmd) && p1) {
|
||||
|
||||
/* test that strintern works */
|
||||
const char *i1 = strintern(p1);
|
||||
const char *i2 = strintern(p1);
|
||||
if (strcmp(i1, p1))
|
||||
printf("strintern(%s) returns %s\n", p1, i1);
|
||||
else if (i1 == p1)
|
||||
printf("strintern(%s) returns input pointer\n", p1);
|
||||
else if (i1 != i2)
|
||||
printf("strintern(%s) != strintern(%s)", i1, i2);
|
||||
else
|
||||
printf("%s\n", i1);
|
||||
|
||||
} else if (!strcmp("perfhashmap", cmd) && p1 && p2) {
|
||||
|
||||
perf_hashmap(atoi(p1), atoi(p2));
|
||||
|
||||
} else {
|
||||
|
||||
printf("Unknown command %s\n", cmd);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
strbuf_release(&line);
|
||||
hashmap_free(&map, 1);
|
||||
return 0;
|
||||
}
|
||||
15
third_party/git/t/helper/test-index-version.c
vendored
Normal file
15
third_party/git/t/helper/test-index-version.c
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
|
||||
int cmd__index_version(int argc, const char **argv)
|
||||
{
|
||||
struct cache_header hdr;
|
||||
int version;
|
||||
|
||||
memset(&hdr,0,sizeof(hdr));
|
||||
if (read(0, &hdr, sizeof(hdr)) != sizeof(hdr))
|
||||
return 0;
|
||||
version = ntohl(hdr.hdr_version);
|
||||
printf("%d\n", version);
|
||||
return 0;
|
||||
}
|
||||
565
third_party/git/t/helper/test-json-writer.c
vendored
Normal file
565
third_party/git/t/helper/test-json-writer.c
vendored
Normal file
|
|
@ -0,0 +1,565 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "json-writer.h"
|
||||
|
||||
static const char *expect_obj1 = "{\"a\":\"abc\",\"b\":42,\"c\":true}";
|
||||
static const char *expect_obj2 = "{\"a\":-1,\"b\":2147483647,\"c\":0}";
|
||||
static const char *expect_obj3 = "{\"a\":0,\"b\":4294967295,\"c\":9223372036854775807}";
|
||||
static const char *expect_obj4 = "{\"t\":true,\"f\":false,\"n\":null}";
|
||||
static const char *expect_obj5 = "{\"abc\\tdef\":\"abc\\\\def\"}";
|
||||
static const char *expect_obj6 = "{\"a\":3.14}";
|
||||
|
||||
static const char *pretty_obj1 = ("{\n"
|
||||
" \"a\": \"abc\",\n"
|
||||
" \"b\": 42,\n"
|
||||
" \"c\": true\n"
|
||||
"}");
|
||||
static const char *pretty_obj2 = ("{\n"
|
||||
" \"a\": -1,\n"
|
||||
" \"b\": 2147483647,\n"
|
||||
" \"c\": 0\n"
|
||||
"}");
|
||||
static const char *pretty_obj3 = ("{\n"
|
||||
" \"a\": 0,\n"
|
||||
" \"b\": 4294967295,\n"
|
||||
" \"c\": 9223372036854775807\n"
|
||||
"}");
|
||||
static const char *pretty_obj4 = ("{\n"
|
||||
" \"t\": true,\n"
|
||||
" \"f\": false,\n"
|
||||
" \"n\": null\n"
|
||||
"}");
|
||||
|
||||
static struct json_writer obj1 = JSON_WRITER_INIT;
|
||||
static struct json_writer obj2 = JSON_WRITER_INIT;
|
||||
static struct json_writer obj3 = JSON_WRITER_INIT;
|
||||
static struct json_writer obj4 = JSON_WRITER_INIT;
|
||||
static struct json_writer obj5 = JSON_WRITER_INIT;
|
||||
static struct json_writer obj6 = JSON_WRITER_INIT;
|
||||
|
||||
static void make_obj1(int pretty)
|
||||
{
|
||||
jw_object_begin(&obj1, pretty);
|
||||
{
|
||||
jw_object_string(&obj1, "a", "abc");
|
||||
jw_object_intmax(&obj1, "b", 42);
|
||||
jw_object_true(&obj1, "c");
|
||||
}
|
||||
jw_end(&obj1);
|
||||
}
|
||||
|
||||
static void make_obj2(int pretty)
|
||||
{
|
||||
jw_object_begin(&obj2, pretty);
|
||||
{
|
||||
jw_object_intmax(&obj2, "a", -1);
|
||||
jw_object_intmax(&obj2, "b", 0x7fffffff);
|
||||
jw_object_intmax(&obj2, "c", 0);
|
||||
}
|
||||
jw_end(&obj2);
|
||||
}
|
||||
|
||||
static void make_obj3(int pretty)
|
||||
{
|
||||
jw_object_begin(&obj3, pretty);
|
||||
{
|
||||
jw_object_intmax(&obj3, "a", 0);
|
||||
jw_object_intmax(&obj3, "b", 0xffffffff);
|
||||
jw_object_intmax(&obj3, "c", 0x7fffffffffffffffULL);
|
||||
}
|
||||
jw_end(&obj3);
|
||||
}
|
||||
|
||||
static void make_obj4(int pretty)
|
||||
{
|
||||
jw_object_begin(&obj4, pretty);
|
||||
{
|
||||
jw_object_true(&obj4, "t");
|
||||
jw_object_false(&obj4, "f");
|
||||
jw_object_null(&obj4, "n");
|
||||
}
|
||||
jw_end(&obj4);
|
||||
}
|
||||
|
||||
static void make_obj5(int pretty)
|
||||
{
|
||||
jw_object_begin(&obj5, pretty);
|
||||
{
|
||||
jw_object_string(&obj5, "abc" "\x09" "def", "abc" "\\" "def");
|
||||
}
|
||||
jw_end(&obj5);
|
||||
}
|
||||
|
||||
static void make_obj6(int pretty)
|
||||
{
|
||||
jw_object_begin(&obj6, pretty);
|
||||
{
|
||||
jw_object_double(&obj6, "a", 2, 3.14159);
|
||||
}
|
||||
jw_end(&obj6);
|
||||
}
|
||||
|
||||
static const char *expect_arr1 = "[\"abc\",42,true]";
|
||||
static const char *expect_arr2 = "[-1,2147483647,0]";
|
||||
static const char *expect_arr3 = "[0,4294967295,9223372036854775807]";
|
||||
static const char *expect_arr4 = "[true,false,null]";
|
||||
|
||||
static const char *pretty_arr1 = ("[\n"
|
||||
" \"abc\",\n"
|
||||
" 42,\n"
|
||||
" true\n"
|
||||
"]");
|
||||
static const char *pretty_arr2 = ("[\n"
|
||||
" -1,\n"
|
||||
" 2147483647,\n"
|
||||
" 0\n"
|
||||
"]");
|
||||
static const char *pretty_arr3 = ("[\n"
|
||||
" 0,\n"
|
||||
" 4294967295,\n"
|
||||
" 9223372036854775807\n"
|
||||
"]");
|
||||
static const char *pretty_arr4 = ("[\n"
|
||||
" true,\n"
|
||||
" false,\n"
|
||||
" null\n"
|
||||
"]");
|
||||
|
||||
static struct json_writer arr1 = JSON_WRITER_INIT;
|
||||
static struct json_writer arr2 = JSON_WRITER_INIT;
|
||||
static struct json_writer arr3 = JSON_WRITER_INIT;
|
||||
static struct json_writer arr4 = JSON_WRITER_INIT;
|
||||
|
||||
static void make_arr1(int pretty)
|
||||
{
|
||||
jw_array_begin(&arr1, pretty);
|
||||
{
|
||||
jw_array_string(&arr1, "abc");
|
||||
jw_array_intmax(&arr1, 42);
|
||||
jw_array_true(&arr1);
|
||||
}
|
||||
jw_end(&arr1);
|
||||
}
|
||||
|
||||
static void make_arr2(int pretty)
|
||||
{
|
||||
jw_array_begin(&arr2, pretty);
|
||||
{
|
||||
jw_array_intmax(&arr2, -1);
|
||||
jw_array_intmax(&arr2, 0x7fffffff);
|
||||
jw_array_intmax(&arr2, 0);
|
||||
}
|
||||
jw_end(&arr2);
|
||||
}
|
||||
|
||||
static void make_arr3(int pretty)
|
||||
{
|
||||
jw_array_begin(&arr3, pretty);
|
||||
{
|
||||
jw_array_intmax(&arr3, 0);
|
||||
jw_array_intmax(&arr3, 0xffffffff);
|
||||
jw_array_intmax(&arr3, 0x7fffffffffffffffULL);
|
||||
}
|
||||
jw_end(&arr3);
|
||||
}
|
||||
|
||||
static void make_arr4(int pretty)
|
||||
{
|
||||
jw_array_begin(&arr4, pretty);
|
||||
{
|
||||
jw_array_true(&arr4);
|
||||
jw_array_false(&arr4);
|
||||
jw_array_null(&arr4);
|
||||
}
|
||||
jw_end(&arr4);
|
||||
}
|
||||
|
||||
static char *expect_nest1 =
|
||||
"{\"obj1\":{\"a\":\"abc\",\"b\":42,\"c\":true},\"arr1\":[\"abc\",42,true]}";
|
||||
|
||||
static struct json_writer nest1 = JSON_WRITER_INIT;
|
||||
|
||||
static void make_nest1(int pretty)
|
||||
{
|
||||
jw_object_begin(&nest1, pretty);
|
||||
{
|
||||
jw_object_sub_jw(&nest1, "obj1", &obj1);
|
||||
jw_object_sub_jw(&nest1, "arr1", &arr1);
|
||||
}
|
||||
jw_end(&nest1);
|
||||
}
|
||||
|
||||
static char *expect_inline1 =
|
||||
"{\"obj1\":{\"a\":\"abc\",\"b\":42,\"c\":true},\"arr1\":[\"abc\",42,true]}";
|
||||
|
||||
static char *pretty_inline1 =
|
||||
("{\n"
|
||||
" \"obj1\": {\n"
|
||||
" \"a\": \"abc\",\n"
|
||||
" \"b\": 42,\n"
|
||||
" \"c\": true\n"
|
||||
" },\n"
|
||||
" \"arr1\": [\n"
|
||||
" \"abc\",\n"
|
||||
" 42,\n"
|
||||
" true\n"
|
||||
" ]\n"
|
||||
"}");
|
||||
|
||||
static struct json_writer inline1 = JSON_WRITER_INIT;
|
||||
|
||||
static void make_inline1(int pretty)
|
||||
{
|
||||
jw_object_begin(&inline1, pretty);
|
||||
{
|
||||
jw_object_inline_begin_object(&inline1, "obj1");
|
||||
{
|
||||
jw_object_string(&inline1, "a", "abc");
|
||||
jw_object_intmax(&inline1, "b", 42);
|
||||
jw_object_true(&inline1, "c");
|
||||
}
|
||||
jw_end(&inline1);
|
||||
jw_object_inline_begin_array(&inline1, "arr1");
|
||||
{
|
||||
jw_array_string(&inline1, "abc");
|
||||
jw_array_intmax(&inline1, 42);
|
||||
jw_array_true(&inline1);
|
||||
}
|
||||
jw_end(&inline1);
|
||||
}
|
||||
jw_end(&inline1);
|
||||
}
|
||||
|
||||
static char *expect_inline2 =
|
||||
"[[1,2],[3,4],{\"a\":\"abc\"}]";
|
||||
|
||||
static char *pretty_inline2 =
|
||||
("[\n"
|
||||
" [\n"
|
||||
" 1,\n"
|
||||
" 2\n"
|
||||
" ],\n"
|
||||
" [\n"
|
||||
" 3,\n"
|
||||
" 4\n"
|
||||
" ],\n"
|
||||
" {\n"
|
||||
" \"a\": \"abc\"\n"
|
||||
" }\n"
|
||||
"]");
|
||||
|
||||
static struct json_writer inline2 = JSON_WRITER_INIT;
|
||||
|
||||
static void make_inline2(int pretty)
|
||||
{
|
||||
jw_array_begin(&inline2, pretty);
|
||||
{
|
||||
jw_array_inline_begin_array(&inline2);
|
||||
{
|
||||
jw_array_intmax(&inline2, 1);
|
||||
jw_array_intmax(&inline2, 2);
|
||||
}
|
||||
jw_end(&inline2);
|
||||
jw_array_inline_begin_array(&inline2);
|
||||
{
|
||||
jw_array_intmax(&inline2, 3);
|
||||
jw_array_intmax(&inline2, 4);
|
||||
}
|
||||
jw_end(&inline2);
|
||||
jw_array_inline_begin_object(&inline2);
|
||||
{
|
||||
jw_object_string(&inline2, "a", "abc");
|
||||
}
|
||||
jw_end(&inline2);
|
||||
}
|
||||
jw_end(&inline2);
|
||||
}
|
||||
|
||||
/*
|
||||
* When super is compact, we expect subs to be compacted (even if originally
|
||||
* pretty).
|
||||
*/
|
||||
static const char *expect_mixed1 =
|
||||
("{\"obj1\":{\"a\":\"abc\",\"b\":42,\"c\":true},"
|
||||
"\"arr1\":[\"abc\",42,true]}");
|
||||
|
||||
/*
|
||||
* When super is pretty, a compact sub (obj1) is kept compact and a pretty
|
||||
* sub (arr1) is re-indented.
|
||||
*/
|
||||
static const char *pretty_mixed1 =
|
||||
("{\n"
|
||||
" \"obj1\": {\"a\":\"abc\",\"b\":42,\"c\":true},\n"
|
||||
" \"arr1\": [\n"
|
||||
" \"abc\",\n"
|
||||
" 42,\n"
|
||||
" true\n"
|
||||
" ]\n"
|
||||
"}");
|
||||
|
||||
static struct json_writer mixed1 = JSON_WRITER_INIT;
|
||||
|
||||
static void make_mixed1(int pretty)
|
||||
{
|
||||
jw_init(&obj1);
|
||||
jw_init(&arr1);
|
||||
|
||||
make_obj1(0); /* obj1 is compact */
|
||||
make_arr1(1); /* arr1 is pretty */
|
||||
|
||||
jw_object_begin(&mixed1, pretty);
|
||||
{
|
||||
jw_object_sub_jw(&mixed1, "obj1", &obj1);
|
||||
jw_object_sub_jw(&mixed1, "arr1", &arr1);
|
||||
}
|
||||
jw_end(&mixed1);
|
||||
}
|
||||
|
||||
static void cmp(const char *test, const struct json_writer *jw, const char *exp)
|
||||
{
|
||||
if (!strcmp(jw->json.buf, exp))
|
||||
return;
|
||||
|
||||
printf("error[%s]: observed '%s' expected '%s'\n",
|
||||
test, jw->json.buf, exp);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#define t(v) do { make_##v(0); cmp(#v, &v, expect_##v); } while (0)
|
||||
#define p(v) do { make_##v(1); cmp(#v, &v, pretty_##v); } while (0)
|
||||
|
||||
/*
|
||||
* Run some basic regression tests with some known patterns.
|
||||
* These tests also demonstrate how to use the jw_ API.
|
||||
*/
|
||||
static int unit_tests(void)
|
||||
{
|
||||
/* comptact (canonical) forms */
|
||||
t(obj1);
|
||||
t(obj2);
|
||||
t(obj3);
|
||||
t(obj4);
|
||||
t(obj5);
|
||||
t(obj6);
|
||||
|
||||
t(arr1);
|
||||
t(arr2);
|
||||
t(arr3);
|
||||
t(arr4);
|
||||
|
||||
t(nest1);
|
||||
|
||||
t(inline1);
|
||||
t(inline2);
|
||||
|
||||
jw_init(&obj1);
|
||||
jw_init(&obj2);
|
||||
jw_init(&obj3);
|
||||
jw_init(&obj4);
|
||||
|
||||
jw_init(&arr1);
|
||||
jw_init(&arr2);
|
||||
jw_init(&arr3);
|
||||
jw_init(&arr4);
|
||||
|
||||
jw_init(&inline1);
|
||||
jw_init(&inline2);
|
||||
|
||||
/* pretty forms */
|
||||
p(obj1);
|
||||
p(obj2);
|
||||
p(obj3);
|
||||
p(obj4);
|
||||
|
||||
p(arr1);
|
||||
p(arr2);
|
||||
p(arr3);
|
||||
p(arr4);
|
||||
|
||||
p(inline1);
|
||||
p(inline2);
|
||||
|
||||
/* mixed forms */
|
||||
t(mixed1);
|
||||
jw_init(&mixed1);
|
||||
p(mixed1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void get_s(int line_nr, char **s_in)
|
||||
{
|
||||
*s_in = strtok(NULL, " ");
|
||||
if (!*s_in)
|
||||
die("line[%d]: expected: <s>", line_nr);
|
||||
}
|
||||
|
||||
static void get_i(int line_nr, intmax_t *s_in)
|
||||
{
|
||||
char *s;
|
||||
char *endptr;
|
||||
|
||||
get_s(line_nr, &s);
|
||||
|
||||
*s_in = strtol(s, &endptr, 10);
|
||||
if (*endptr || errno == ERANGE)
|
||||
die("line[%d]: invalid integer value", line_nr);
|
||||
}
|
||||
|
||||
static void get_d(int line_nr, double *s_in)
|
||||
{
|
||||
char *s;
|
||||
char *endptr;
|
||||
|
||||
get_s(line_nr, &s);
|
||||
|
||||
*s_in = strtod(s, &endptr);
|
||||
if (*endptr || errno == ERANGE)
|
||||
die("line[%d]: invalid float value", line_nr);
|
||||
}
|
||||
|
||||
static int pretty;
|
||||
|
||||
#define MAX_LINE_LENGTH (64 * 1024)
|
||||
|
||||
static char *get_trimmed_line(char *buf, int buf_size)
|
||||
{
|
||||
int len;
|
||||
|
||||
if (!fgets(buf, buf_size, stdin))
|
||||
return NULL;
|
||||
|
||||
len = strlen(buf);
|
||||
while (len > 0) {
|
||||
char c = buf[len - 1];
|
||||
if (c == '\n' || c == '\r' || c == ' ' || c == '\t')
|
||||
buf[--len] = 0;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
while (*buf == ' ' || *buf == '\t')
|
||||
buf++;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int scripted(void)
|
||||
{
|
||||
struct json_writer jw = JSON_WRITER_INIT;
|
||||
char buf[MAX_LINE_LENGTH];
|
||||
char *line;
|
||||
int line_nr = 0;
|
||||
|
||||
line = get_trimmed_line(buf, MAX_LINE_LENGTH);
|
||||
if (!line)
|
||||
return 0;
|
||||
|
||||
if (!strcmp(line, "object"))
|
||||
jw_object_begin(&jw, pretty);
|
||||
else if (!strcmp(line, "array"))
|
||||
jw_array_begin(&jw, pretty);
|
||||
else
|
||||
die("expected first line to be 'object' or 'array'");
|
||||
|
||||
while ((line = get_trimmed_line(buf, MAX_LINE_LENGTH)) != NULL) {
|
||||
char *verb;
|
||||
char *key;
|
||||
char *s_value;
|
||||
intmax_t i_value;
|
||||
double d_value;
|
||||
|
||||
line_nr++;
|
||||
|
||||
verb = strtok(line, " ");
|
||||
|
||||
if (!strcmp(verb, "end")) {
|
||||
jw_end(&jw);
|
||||
}
|
||||
else if (!strcmp(verb, "object-string")) {
|
||||
get_s(line_nr, &key);
|
||||
get_s(line_nr, &s_value);
|
||||
jw_object_string(&jw, key, s_value);
|
||||
}
|
||||
else if (!strcmp(verb, "object-int")) {
|
||||
get_s(line_nr, &key);
|
||||
get_i(line_nr, &i_value);
|
||||
jw_object_intmax(&jw, key, i_value);
|
||||
}
|
||||
else if (!strcmp(verb, "object-double")) {
|
||||
get_s(line_nr, &key);
|
||||
get_i(line_nr, &i_value);
|
||||
get_d(line_nr, &d_value);
|
||||
jw_object_double(&jw, key, i_value, d_value);
|
||||
}
|
||||
else if (!strcmp(verb, "object-true")) {
|
||||
get_s(line_nr, &key);
|
||||
jw_object_true(&jw, key);
|
||||
}
|
||||
else if (!strcmp(verb, "object-false")) {
|
||||
get_s(line_nr, &key);
|
||||
jw_object_false(&jw, key);
|
||||
}
|
||||
else if (!strcmp(verb, "object-null")) {
|
||||
get_s(line_nr, &key);
|
||||
jw_object_null(&jw, key);
|
||||
}
|
||||
else if (!strcmp(verb, "object-object")) {
|
||||
get_s(line_nr, &key);
|
||||
jw_object_inline_begin_object(&jw, key);
|
||||
}
|
||||
else if (!strcmp(verb, "object-array")) {
|
||||
get_s(line_nr, &key);
|
||||
jw_object_inline_begin_array(&jw, key);
|
||||
}
|
||||
else if (!strcmp(verb, "array-string")) {
|
||||
get_s(line_nr, &s_value);
|
||||
jw_array_string(&jw, s_value);
|
||||
}
|
||||
else if (!strcmp(verb, "array-int")) {
|
||||
get_i(line_nr, &i_value);
|
||||
jw_array_intmax(&jw, i_value);
|
||||
}
|
||||
else if (!strcmp(verb, "array-double")) {
|
||||
get_i(line_nr, &i_value);
|
||||
get_d(line_nr, &d_value);
|
||||
jw_array_double(&jw, i_value, d_value);
|
||||
}
|
||||
else if (!strcmp(verb, "array-true"))
|
||||
jw_array_true(&jw);
|
||||
else if (!strcmp(verb, "array-false"))
|
||||
jw_array_false(&jw);
|
||||
else if (!strcmp(verb, "array-null"))
|
||||
jw_array_null(&jw);
|
||||
else if (!strcmp(verb, "array-object"))
|
||||
jw_array_inline_begin_object(&jw);
|
||||
else if (!strcmp(verb, "array-array"))
|
||||
jw_array_inline_begin_array(&jw);
|
||||
else
|
||||
die("unrecognized token: '%s'", verb);
|
||||
}
|
||||
|
||||
if (!jw_is_terminated(&jw))
|
||||
die("json not terminated: '%s'", jw.json.buf);
|
||||
|
||||
printf("%s\n", jw.json.buf);
|
||||
|
||||
strbuf_release(&jw.json);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cmd__json_writer(int argc, const char **argv)
|
||||
{
|
||||
argc--; /* skip over "json-writer" arg */
|
||||
argv++;
|
||||
|
||||
if (argc > 0 && argv[0][0] == '-') {
|
||||
if (!strcmp(argv[0], "-u") || !strcmp(argv[0], "--unit"))
|
||||
return unit_tests();
|
||||
|
||||
if (!strcmp(argv[0], "-p") || !strcmp(argv[0], "--pretty"))
|
||||
pretty = 1;
|
||||
}
|
||||
|
||||
return scripted();
|
||||
}
|
||||
265
third_party/git/t/helper/test-lazy-init-name-hash.c
vendored
Normal file
265
third_party/git/t/helper/test-lazy-init-name-hash.c
vendored
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "parse-options.h"
|
||||
|
||||
static int single;
|
||||
static int multi;
|
||||
static int count = 1;
|
||||
static int dump;
|
||||
static int perf;
|
||||
static int analyze;
|
||||
static int analyze_step;
|
||||
|
||||
/*
|
||||
* Dump the contents of the "dir" and "name" hash tables to stdout.
|
||||
* If you sort the result, you can compare it with the other type
|
||||
* mode and verify that both single and multi produce the same set.
|
||||
*/
|
||||
static void dump_run(void)
|
||||
{
|
||||
struct hashmap_iter iter_dir;
|
||||
struct hashmap_iter iter_cache;
|
||||
|
||||
/* Stolen from name-hash.c */
|
||||
struct dir_entry {
|
||||
struct hashmap_entry ent;
|
||||
struct dir_entry *parent;
|
||||
int nr;
|
||||
unsigned int namelen;
|
||||
char name[FLEX_ARRAY];
|
||||
};
|
||||
|
||||
struct dir_entry *dir;
|
||||
struct cache_entry *ce;
|
||||
|
||||
read_cache();
|
||||
if (single) {
|
||||
test_lazy_init_name_hash(&the_index, 0);
|
||||
} else {
|
||||
int nr_threads_used = test_lazy_init_name_hash(&the_index, 1);
|
||||
if (!nr_threads_used)
|
||||
die("non-threaded code path used");
|
||||
}
|
||||
|
||||
dir = hashmap_iter_first(&the_index.dir_hash, &iter_dir);
|
||||
while (dir) {
|
||||
printf("dir %08x %7d %s\n", dir->ent.hash, dir->nr, dir->name);
|
||||
dir = hashmap_iter_next(&iter_dir);
|
||||
}
|
||||
|
||||
ce = hashmap_iter_first(&the_index.name_hash, &iter_cache);
|
||||
while (ce) {
|
||||
printf("name %08x %s\n", ce->ent.hash, ce->name);
|
||||
ce = hashmap_iter_next(&iter_cache);
|
||||
}
|
||||
|
||||
discard_cache();
|
||||
}
|
||||
|
||||
/*
|
||||
* Run the single or multi threaded version "count" times and
|
||||
* report on the time taken.
|
||||
*/
|
||||
static uint64_t time_runs(int try_threaded)
|
||||
{
|
||||
uint64_t t0, t1, t2;
|
||||
uint64_t sum = 0;
|
||||
uint64_t avg;
|
||||
int nr_threads_used;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
t0 = getnanotime();
|
||||
read_cache();
|
||||
t1 = getnanotime();
|
||||
nr_threads_used = test_lazy_init_name_hash(&the_index, try_threaded);
|
||||
t2 = getnanotime();
|
||||
|
||||
sum += (t2 - t1);
|
||||
|
||||
if (try_threaded && !nr_threads_used)
|
||||
die("non-threaded code path used");
|
||||
|
||||
if (nr_threads_used)
|
||||
printf("%f %f %d multi %d\n",
|
||||
((double)(t1 - t0))/1000000000,
|
||||
((double)(t2 - t1))/1000000000,
|
||||
the_index.cache_nr,
|
||||
nr_threads_used);
|
||||
else
|
||||
printf("%f %f %d single\n",
|
||||
((double)(t1 - t0))/1000000000,
|
||||
((double)(t2 - t1))/1000000000,
|
||||
the_index.cache_nr);
|
||||
fflush(stdout);
|
||||
|
||||
discard_cache();
|
||||
}
|
||||
|
||||
avg = sum / count;
|
||||
if (count > 1)
|
||||
printf("avg %f %s\n",
|
||||
(double)avg/1000000000,
|
||||
(try_threaded) ? "multi" : "single");
|
||||
|
||||
return avg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try a series of runs varying the "istate->cache_nr" and
|
||||
* try to find a good value for the multi-threaded criteria.
|
||||
*/
|
||||
static void analyze_run(void)
|
||||
{
|
||||
uint64_t t1s, t1m, t2s, t2m;
|
||||
int cache_nr_limit;
|
||||
int nr_threads_used = 0;
|
||||
int i;
|
||||
int nr;
|
||||
|
||||
read_cache();
|
||||
cache_nr_limit = the_index.cache_nr;
|
||||
discard_cache();
|
||||
|
||||
nr = analyze;
|
||||
while (1) {
|
||||
uint64_t sum_single = 0;
|
||||
uint64_t sum_multi = 0;
|
||||
uint64_t avg_single;
|
||||
uint64_t avg_multi;
|
||||
|
||||
if (nr > cache_nr_limit)
|
||||
nr = cache_nr_limit;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
read_cache();
|
||||
the_index.cache_nr = nr; /* cheap truncate of index */
|
||||
t1s = getnanotime();
|
||||
test_lazy_init_name_hash(&the_index, 0);
|
||||
t2s = getnanotime();
|
||||
sum_single += (t2s - t1s);
|
||||
the_index.cache_nr = cache_nr_limit;
|
||||
discard_cache();
|
||||
|
||||
read_cache();
|
||||
the_index.cache_nr = nr; /* cheap truncate of index */
|
||||
t1m = getnanotime();
|
||||
nr_threads_used = test_lazy_init_name_hash(&the_index, 1);
|
||||
t2m = getnanotime();
|
||||
sum_multi += (t2m - t1m);
|
||||
the_index.cache_nr = cache_nr_limit;
|
||||
discard_cache();
|
||||
|
||||
if (!nr_threads_used)
|
||||
printf(" [size %8d] [single %f] non-threaded code path used\n",
|
||||
nr, ((double)(t2s - t1s))/1000000000);
|
||||
else
|
||||
printf(" [size %8d] [single %f] %c [multi %f %d]\n",
|
||||
nr,
|
||||
((double)(t2s - t1s))/1000000000,
|
||||
(((t2s - t1s) < (t2m - t1m)) ? '<' : '>'),
|
||||
((double)(t2m - t1m))/1000000000,
|
||||
nr_threads_used);
|
||||
fflush(stdout);
|
||||
}
|
||||
if (count > 1) {
|
||||
avg_single = sum_single / count;
|
||||
avg_multi = sum_multi / count;
|
||||
if (!nr_threads_used)
|
||||
printf("avg [size %8d] [single %f]\n",
|
||||
nr,
|
||||
(double)avg_single/1000000000);
|
||||
else
|
||||
printf("avg [size %8d] [single %f] %c [multi %f %d]\n",
|
||||
nr,
|
||||
(double)avg_single/1000000000,
|
||||
(avg_single < avg_multi ? '<' : '>'),
|
||||
(double)avg_multi/1000000000,
|
||||
nr_threads_used);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
if (nr >= cache_nr_limit)
|
||||
return;
|
||||
nr += analyze_step;
|
||||
}
|
||||
}
|
||||
|
||||
int cmd__lazy_init_name_hash(int argc, const char **argv)
|
||||
{
|
||||
const char *usage[] = {
|
||||
"test-tool lazy-init-name-hash -d (-s | -m)",
|
||||
"test-tool lazy-init-name-hash -p [-c c]",
|
||||
"test-tool lazy-init-name-hash -a a [--step s] [-c c]",
|
||||
"test-tool lazy-init-name-hash (-s | -m) [-c c]",
|
||||
"test-tool lazy-init-name-hash -s -m [-c c]",
|
||||
NULL
|
||||
};
|
||||
struct option options[] = {
|
||||
OPT_BOOL('s', "single", &single, "run single-threaded code"),
|
||||
OPT_BOOL('m', "multi", &multi, "run multi-threaded code"),
|
||||
OPT_INTEGER('c', "count", &count, "number of passes"),
|
||||
OPT_BOOL('d', "dump", &dump, "dump hash tables"),
|
||||
OPT_BOOL('p', "perf", &perf, "compare single vs multi"),
|
||||
OPT_INTEGER('a', "analyze", &analyze, "analyze different multi sizes"),
|
||||
OPT_INTEGER(0, "step", &analyze_step, "analyze step factor"),
|
||||
OPT_END(),
|
||||
};
|
||||
const char *prefix;
|
||||
uint64_t avg_single, avg_multi;
|
||||
|
||||
prefix = setup_git_directory();
|
||||
|
||||
argc = parse_options(argc, argv, prefix, options, usage, 0);
|
||||
|
||||
/*
|
||||
* istate->dir_hash is only created when ignore_case is set.
|
||||
*/
|
||||
ignore_case = 1;
|
||||
|
||||
if (dump) {
|
||||
if (perf || analyze > 0)
|
||||
die("cannot combine dump, perf, or analyze");
|
||||
if (count > 1)
|
||||
die("count not valid with dump");
|
||||
if (single && multi)
|
||||
die("cannot use both single and multi with dump");
|
||||
if (!single && !multi)
|
||||
die("dump requires either single or multi");
|
||||
dump_run();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (perf) {
|
||||
if (analyze > 0)
|
||||
die("cannot combine dump, perf, or analyze");
|
||||
if (single || multi)
|
||||
die("cannot use single or multi with perf");
|
||||
avg_single = time_runs(0);
|
||||
avg_multi = time_runs(1);
|
||||
if (avg_multi > avg_single)
|
||||
die("multi is slower");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (analyze) {
|
||||
if (analyze < 500)
|
||||
die("analyze must be at least 500");
|
||||
if (!analyze_step)
|
||||
analyze_step = analyze;
|
||||
if (single || multi)
|
||||
die("cannot use single or multi with analyze");
|
||||
analyze_run();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!single && !multi)
|
||||
die("require either -s or -m or both");
|
||||
|
||||
if (single)
|
||||
time_runs(0);
|
||||
if (multi)
|
||||
time_runs(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
81
third_party/git/t/helper/test-line-buffer.c
vendored
Normal file
81
third_party/git/t/helper/test-line-buffer.c
vendored
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* test-line-buffer.c: code to exercise the svn importer's input helper
|
||||
*/
|
||||
|
||||
#include "git-compat-util.h"
|
||||
#include "strbuf.h"
|
||||
#include "vcs-svn/line_buffer.h"
|
||||
|
||||
static uint32_t strtouint32(const char *s)
|
||||
{
|
||||
char *end;
|
||||
uintmax_t n = strtoumax(s, &end, 10);
|
||||
if (*s == '\0' || *end != '\0')
|
||||
die("invalid count: %s", s);
|
||||
return (uint32_t) n;
|
||||
}
|
||||
|
||||
static void handle_command(const char *command, const char *arg, struct line_buffer *buf)
|
||||
{
|
||||
if (starts_with(command, "binary ")) {
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
strbuf_addch(&sb, '>');
|
||||
buffer_read_binary(buf, &sb, strtouint32(arg));
|
||||
fwrite(sb.buf, 1, sb.len, stdout);
|
||||
strbuf_release(&sb);
|
||||
} else if (starts_with(command, "copy ")) {
|
||||
buffer_copy_bytes(buf, strtouint32(arg));
|
||||
} else if (starts_with(command, "skip ")) {
|
||||
buffer_skip_bytes(buf, strtouint32(arg));
|
||||
} else {
|
||||
die("unrecognized command: %s", command);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_line(const char *line, struct line_buffer *stdin_buf)
|
||||
{
|
||||
const char *arg = strchr(line, ' ');
|
||||
if (!arg)
|
||||
die("no argument in line: %s", line);
|
||||
handle_command(line, arg + 1, stdin_buf);
|
||||
}
|
||||
|
||||
int cmd_main(int argc, const char **argv)
|
||||
{
|
||||
struct line_buffer stdin_buf = LINE_BUFFER_INIT;
|
||||
struct line_buffer file_buf = LINE_BUFFER_INIT;
|
||||
struct line_buffer *input = &stdin_buf;
|
||||
const char *filename;
|
||||
char *s;
|
||||
|
||||
if (argc == 1)
|
||||
filename = NULL;
|
||||
else if (argc == 2)
|
||||
filename = argv[1];
|
||||
else
|
||||
usage("test-line-buffer [file | &fd] < script");
|
||||
|
||||
if (buffer_init(&stdin_buf, NULL))
|
||||
die_errno("open error");
|
||||
if (filename) {
|
||||
if (*filename == '&') {
|
||||
if (buffer_fdinit(&file_buf, strtouint32(filename + 1)))
|
||||
die_errno("error opening fd %s", filename + 1);
|
||||
} else {
|
||||
if (buffer_init(&file_buf, filename))
|
||||
die_errno("error opening %s", filename);
|
||||
}
|
||||
input = &file_buf;
|
||||
}
|
||||
|
||||
while ((s = buffer_read_line(&stdin_buf)))
|
||||
handle_line(s, input);
|
||||
|
||||
if (filename && buffer_deinit(&file_buf))
|
||||
die("error reading from %s", filename);
|
||||
if (buffer_deinit(&stdin_buf))
|
||||
die("input error");
|
||||
if (ferror(stdout))
|
||||
die("output error");
|
||||
return 0;
|
||||
}
|
||||
27
third_party/git/t/helper/test-match-trees.c
vendored
Normal file
27
third_party/git/t/helper/test-match-trees.c
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "tree.h"
|
||||
|
||||
int cmd__match_trees(int ac, const char **av)
|
||||
{
|
||||
struct object_id hash1, hash2, shifted;
|
||||
struct tree *one, *two;
|
||||
|
||||
setup_git_directory();
|
||||
|
||||
if (get_oid(av[1], &hash1))
|
||||
die("cannot parse %s as an object name", av[1]);
|
||||
if (get_oid(av[2], &hash2))
|
||||
die("cannot parse %s as an object name", av[2]);
|
||||
one = parse_tree_indirect(&hash1);
|
||||
if (!one)
|
||||
die("not a tree-ish %s", av[1]);
|
||||
two = parse_tree_indirect(&hash2);
|
||||
if (!two)
|
||||
die("not a tree-ish %s", av[2]);
|
||||
|
||||
shift_tree(the_repository, &one->object.oid, &two->object.oid, &shifted, -1);
|
||||
printf("shifted: %s\n", oid_to_hex(&shifted));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
53
third_party/git/t/helper/test-mergesort.c
vendored
Normal file
53
third_party/git/t/helper/test-mergesort.c
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "mergesort.h"
|
||||
|
||||
struct line {
|
||||
char *text;
|
||||
struct line *next;
|
||||
};
|
||||
|
||||
static void *get_next(const void *a)
|
||||
{
|
||||
return ((const struct line *)a)->next;
|
||||
}
|
||||
|
||||
static void set_next(void *a, void *b)
|
||||
{
|
||||
((struct line *)a)->next = b;
|
||||
}
|
||||
|
||||
static int compare_strings(const void *a, const void *b)
|
||||
{
|
||||
const struct line *x = a, *y = b;
|
||||
return strcmp(x->text, y->text);
|
||||
}
|
||||
|
||||
int cmd__mergesort(int argc, const char **argv)
|
||||
{
|
||||
struct line *line, *p = NULL, *lines = NULL;
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
|
||||
for (;;) {
|
||||
if (strbuf_getwholeline(&sb, stdin, '\n'))
|
||||
break;
|
||||
line = xmalloc(sizeof(struct line));
|
||||
line->text = strbuf_detach(&sb, NULL);
|
||||
if (p) {
|
||||
line->next = p->next;
|
||||
p->next = line;
|
||||
} else {
|
||||
line->next = NULL;
|
||||
lines = line;
|
||||
}
|
||||
p = line;
|
||||
}
|
||||
|
||||
lines = llist_mergesort(lines, get_next, set_next, compare_strings);
|
||||
|
||||
while (lines) {
|
||||
printf("%s", lines->text);
|
||||
lines = lines->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
15
third_party/git/t/helper/test-mktemp.c
vendored
Normal file
15
third_party/git/t/helper/test-mktemp.c
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* test-mktemp.c: code to exercise the creation of temporary files
|
||||
*/
|
||||
#include "test-tool.h"
|
||||
#include "git-compat-util.h"
|
||||
|
||||
int cmd__mktemp(int argc, const char **argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
usage("Expected 1 parameter defining the temporary file template");
|
||||
|
||||
xmkstemp(xstrdup(argv[1]));
|
||||
|
||||
return 0;
|
||||
}
|
||||
112
third_party/git/t/helper/test-oidmap.c
vendored
Normal file
112
third_party/git/t/helper/test-oidmap.c
vendored
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "oidmap.h"
|
||||
#include "strbuf.h"
|
||||
|
||||
/* key is an oid and value is a name (could be a refname for example) */
|
||||
struct test_entry {
|
||||
struct oidmap_entry entry;
|
||||
char name[FLEX_ARRAY];
|
||||
};
|
||||
|
||||
#define DELIM " \t\r\n"
|
||||
|
||||
/*
|
||||
* Read stdin line by line and print result of commands to stdout:
|
||||
*
|
||||
* hash oidkey -> sha1hash(oidkey)
|
||||
* put oidkey namevalue -> NULL / old namevalue
|
||||
* get oidkey -> NULL / namevalue
|
||||
* remove oidkey -> NULL / old namevalue
|
||||
* iterate -> oidkey1 namevalue1\noidkey2 namevalue2\n...
|
||||
*
|
||||
*/
|
||||
int cmd__oidmap(int argc, const char **argv)
|
||||
{
|
||||
struct strbuf line = STRBUF_INIT;
|
||||
struct oidmap map = OIDMAP_INIT;
|
||||
|
||||
setup_git_directory();
|
||||
|
||||
/* init oidmap */
|
||||
oidmap_init(&map, 0);
|
||||
|
||||
/* process commands from stdin */
|
||||
while (strbuf_getline(&line, stdin) != EOF) {
|
||||
char *cmd, *p1 = NULL, *p2 = NULL;
|
||||
struct test_entry *entry;
|
||||
struct object_id oid;
|
||||
|
||||
/* break line into command and up to two parameters */
|
||||
cmd = strtok(line.buf, DELIM);
|
||||
/* ignore empty lines */
|
||||
if (!cmd || *cmd == '#')
|
||||
continue;
|
||||
|
||||
p1 = strtok(NULL, DELIM);
|
||||
if (p1)
|
||||
p2 = strtok(NULL, DELIM);
|
||||
|
||||
if (!strcmp("put", cmd) && p1 && p2) {
|
||||
|
||||
if (get_oid(p1, &oid)) {
|
||||
printf("Unknown oid: %s\n", p1);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* create entry with oid_key = p1, name_value = p2 */
|
||||
FLEX_ALLOC_STR(entry, name, p2);
|
||||
oidcpy(&entry->entry.oid, &oid);
|
||||
|
||||
/* add / replace entry */
|
||||
entry = oidmap_put(&map, entry);
|
||||
|
||||
/* print and free replaced entry, if any */
|
||||
puts(entry ? entry->name : "NULL");
|
||||
free(entry);
|
||||
|
||||
} else if (!strcmp("get", cmd) && p1) {
|
||||
|
||||
if (get_oid(p1, &oid)) {
|
||||
printf("Unknown oid: %s\n", p1);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* lookup entry in oidmap */
|
||||
entry = oidmap_get(&map, &oid);
|
||||
|
||||
/* print result */
|
||||
puts(entry ? entry->name : "NULL");
|
||||
|
||||
} else if (!strcmp("remove", cmd) && p1) {
|
||||
|
||||
if (get_oid(p1, &oid)) {
|
||||
printf("Unknown oid: %s\n", p1);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* remove entry from oidmap */
|
||||
entry = oidmap_remove(&map, &oid);
|
||||
|
||||
/* print result and free entry*/
|
||||
puts(entry ? entry->name : "NULL");
|
||||
free(entry);
|
||||
|
||||
} else if (!strcmp("iterate", cmd)) {
|
||||
|
||||
struct oidmap_iter iter;
|
||||
oidmap_iter_init(&map, &iter);
|
||||
while ((entry = oidmap_iter_next(&iter)))
|
||||
printf("%s %s\n", oid_to_hex(&entry->entry.oid), entry->name);
|
||||
|
||||
} else {
|
||||
|
||||
printf("Unknown command %s\n", cmd);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
strbuf_release(&line);
|
||||
oidmap_free(&map, 1);
|
||||
return 0;
|
||||
}
|
||||
9
third_party/git/t/helper/test-online-cpus.c
vendored
Normal file
9
third_party/git/t/helper/test-online-cpus.c
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#include "test-tool.h"
|
||||
#include "git-compat-util.h"
|
||||
#include "thread-utils.h"
|
||||
|
||||
int cmd__online_cpus(int argc, const char **argv)
|
||||
{
|
||||
printf("%d\n", online_cpus());
|
||||
return 0;
|
||||
}
|
||||
188
third_party/git/t/helper/test-parse-options.c
vendored
Normal file
188
third_party/git/t/helper/test-parse-options.c
vendored
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "parse-options.h"
|
||||
#include "string-list.h"
|
||||
#include "trace2.h"
|
||||
|
||||
static int boolean = 0;
|
||||
static int integer = 0;
|
||||
static unsigned long magnitude = 0;
|
||||
static timestamp_t timestamp;
|
||||
static int abbrev = 7;
|
||||
static int verbose = -1; /* unspecified */
|
||||
static int dry_run = 0, quiet = 0;
|
||||
static char *string = NULL;
|
||||
static char *file = NULL;
|
||||
static int ambiguous;
|
||||
static struct string_list list = STRING_LIST_INIT_NODUP;
|
||||
|
||||
static struct {
|
||||
int called;
|
||||
const char *arg;
|
||||
int unset;
|
||||
} length_cb;
|
||||
|
||||
static int length_callback(const struct option *opt, const char *arg, int unset)
|
||||
{
|
||||
length_cb.called = 1;
|
||||
length_cb.arg = arg;
|
||||
length_cb.unset = unset;
|
||||
|
||||
if (unset)
|
||||
return 1; /* do not support unset */
|
||||
|
||||
*(int *)opt->value = strlen(arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int number_callback(const struct option *opt, const char *arg, int unset)
|
||||
{
|
||||
BUG_ON_OPT_NEG(unset);
|
||||
*(int *)opt->value = strtol(arg, NULL, 10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int collect_expect(const struct option *opt, const char *arg, int unset)
|
||||
{
|
||||
struct string_list *expect;
|
||||
struct string_list_item *item;
|
||||
struct strbuf label = STRBUF_INIT;
|
||||
const char *colon;
|
||||
|
||||
if (!arg || unset)
|
||||
die("malformed --expect option");
|
||||
|
||||
expect = (struct string_list *)opt->value;
|
||||
colon = strchr(arg, ':');
|
||||
if (!colon)
|
||||
die("malformed --expect option, lacking a colon");
|
||||
strbuf_add(&label, arg, colon - arg);
|
||||
item = string_list_insert(expect, strbuf_detach(&label, NULL));
|
||||
if (item->util)
|
||||
die("malformed --expect option, duplicate %s", label.buf);
|
||||
item->util = (void *)arg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
__attribute__((format (printf,3,4)))
|
||||
static void show(struct string_list *expect, int *status, const char *fmt, ...)
|
||||
{
|
||||
struct string_list_item *item;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
strbuf_vaddf(&buf, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
if (!expect->nr)
|
||||
printf("%s\n", buf.buf);
|
||||
else {
|
||||
char *colon = strchr(buf.buf, ':');
|
||||
if (!colon)
|
||||
die("malformed output format, output lacking colon: %s", fmt);
|
||||
*colon = '\0';
|
||||
item = string_list_lookup(expect, buf.buf);
|
||||
*colon = ':';
|
||||
if (!item)
|
||||
; /* not among entries being checked */
|
||||
else {
|
||||
if (strcmp((const char *)item->util, buf.buf)) {
|
||||
printf("-%s\n", (char *)item->util);
|
||||
printf("+%s\n", buf.buf);
|
||||
*status = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
strbuf_release(&buf);
|
||||
}
|
||||
|
||||
int cmd__parse_options(int argc, const char **argv)
|
||||
{
|
||||
const char *prefix = "prefix/";
|
||||
const char *usage[] = {
|
||||
"test-tool parse-options <options>",
|
||||
"",
|
||||
"A helper function for the parse-options API.",
|
||||
NULL
|
||||
};
|
||||
struct string_list expect = STRING_LIST_INIT_NODUP;
|
||||
struct option options[] = {
|
||||
OPT_BOOL(0, "yes", &boolean, "get a boolean"),
|
||||
OPT_BOOL('D', "no-doubt", &boolean, "begins with 'no-'"),
|
||||
{ OPTION_SET_INT, 'B', "no-fear", &boolean, NULL,
|
||||
"be brave", PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1 },
|
||||
OPT_COUNTUP('b', "boolean", &boolean, "increment by one"),
|
||||
OPT_BIT('4', "or4", &boolean,
|
||||
"bitwise-or boolean with ...0100", 4),
|
||||
OPT_NEGBIT(0, "neg-or4", &boolean, "same as --no-or4", 4),
|
||||
OPT_GROUP(""),
|
||||
OPT_INTEGER('i', "integer", &integer, "get a integer"),
|
||||
OPT_INTEGER('j', NULL, &integer, "get a integer, too"),
|
||||
OPT_MAGNITUDE('m', "magnitude", &magnitude, "get a magnitude"),
|
||||
OPT_SET_INT(0, "set23", &integer, "set integer to 23", 23),
|
||||
OPT_CALLBACK('L', "length", &integer, "str",
|
||||
"get length of <str>", length_callback),
|
||||
OPT_FILENAME('F', "file", &file, "set file to <file>"),
|
||||
OPT_GROUP("String options"),
|
||||
OPT_STRING('s', "string", &string, "string", "get a string"),
|
||||
OPT_STRING(0, "string2", &string, "str", "get another string"),
|
||||
OPT_STRING(0, "st", &string, "st", "get another string (pervert ordering)"),
|
||||
OPT_STRING('o', NULL, &string, "str", "get another string"),
|
||||
OPT_NOOP_NOARG(0, "obsolete"),
|
||||
OPT_STRING_LIST(0, "list", &list, "str", "add str to list"),
|
||||
OPT_GROUP("Magic arguments"),
|
||||
OPT_ARGUMENT("quux", NULL, "means --quux"),
|
||||
OPT_NUMBER_CALLBACK(&integer, "set integer to NUM",
|
||||
number_callback),
|
||||
{ OPTION_COUNTUP, '+', NULL, &boolean, NULL, "same as -b",
|
||||
PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH },
|
||||
{ OPTION_COUNTUP, 0, "ambiguous", &ambiguous, NULL,
|
||||
"positive ambiguity", PARSE_OPT_NOARG | PARSE_OPT_NONEG },
|
||||
{ OPTION_COUNTUP, 0, "no-ambiguous", &ambiguous, NULL,
|
||||
"negative ambiguity", PARSE_OPT_NOARG | PARSE_OPT_NONEG },
|
||||
OPT_GROUP("Standard options"),
|
||||
OPT__ABBREV(&abbrev),
|
||||
OPT__VERBOSE(&verbose, "be verbose"),
|
||||
OPT__DRY_RUN(&dry_run, "dry run"),
|
||||
OPT__QUIET(&quiet, "be quiet"),
|
||||
OPT_CALLBACK(0, "expect", &expect, "string",
|
||||
"expected output in the variable dump",
|
||||
collect_expect),
|
||||
OPT_GROUP("Alias"),
|
||||
OPT_STRING('A', "alias-source", &string, "string", "get a string"),
|
||||
OPT_ALIAS('Z', "alias-target", "alias-source"),
|
||||
OPT_END(),
|
||||
};
|
||||
int i;
|
||||
int ret = 0;
|
||||
|
||||
trace2_cmd_name("_parse_");
|
||||
|
||||
argc = parse_options(argc, (const char **)argv, prefix, options, usage, 0);
|
||||
|
||||
if (length_cb.called) {
|
||||
const char *arg = length_cb.arg;
|
||||
int unset = length_cb.unset;
|
||||
show(&expect, &ret, "Callback: \"%s\", %d",
|
||||
(arg ? arg : "not set"), unset);
|
||||
}
|
||||
show(&expect, &ret, "boolean: %d", boolean);
|
||||
show(&expect, &ret, "integer: %d", integer);
|
||||
show(&expect, &ret, "magnitude: %lu", magnitude);
|
||||
show(&expect, &ret, "timestamp: %"PRItime, timestamp);
|
||||
show(&expect, &ret, "string: %s", string ? string : "(not set)");
|
||||
show(&expect, &ret, "abbrev: %d", abbrev);
|
||||
show(&expect, &ret, "verbose: %d", verbose);
|
||||
show(&expect, &ret, "quiet: %d", quiet);
|
||||
show(&expect, &ret, "dry run: %s", dry_run ? "yes" : "no");
|
||||
show(&expect, &ret, "file: %s", file ? file : "(not set)");
|
||||
|
||||
for (i = 0; i < list.nr; i++)
|
||||
show(&expect, &ret, "list: %s", list.items[i].string);
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
show(&expect, &ret, "arg %02d: %s", i, argv[i]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
361
third_party/git/t/helper/test-path-utils.c
vendored
Normal file
361
third_party/git/t/helper/test-path-utils.c
vendored
Normal file
|
|
@ -0,0 +1,361 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "string-list.h"
|
||||
#include "utf8.h"
|
||||
|
||||
/*
|
||||
* A "string_list_each_func_t" function that normalizes an entry from
|
||||
* GIT_CEILING_DIRECTORIES. If the path is unusable for some reason,
|
||||
* die with an explanation.
|
||||
*/
|
||||
static int normalize_ceiling_entry(struct string_list_item *item, void *unused)
|
||||
{
|
||||
char *ceil = item->string;
|
||||
|
||||
if (!*ceil)
|
||||
die("Empty path is not supported");
|
||||
if (!is_absolute_path(ceil))
|
||||
die("Path \"%s\" is not absolute", ceil);
|
||||
if (normalize_path_copy(ceil, ceil) < 0)
|
||||
die("Path \"%s\" could not be normalized", ceil);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void normalize_argv_string(const char **var, const char *input)
|
||||
{
|
||||
if (!strcmp(input, "<null>"))
|
||||
*var = NULL;
|
||||
else if (!strcmp(input, "<empty>"))
|
||||
*var = "";
|
||||
else
|
||||
*var = input;
|
||||
|
||||
if (*var && (**var == '<' || **var == '('))
|
||||
die("Bad value: %s\n", input);
|
||||
}
|
||||
|
||||
struct test_data {
|
||||
const char *from; /* input: transform from this ... */
|
||||
const char *to; /* output: ... to this. */
|
||||
const char *alternative; /* output: ... or this. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Compatibility wrappers for OpenBSD, whose basename(3) and dirname(3)
|
||||
* have const parameters.
|
||||
*/
|
||||
static char *posix_basename(char *path)
|
||||
{
|
||||
return basename(path);
|
||||
}
|
||||
|
||||
static char *posix_dirname(char *path)
|
||||
{
|
||||
return dirname(path);
|
||||
}
|
||||
|
||||
static int test_function(struct test_data *data, char *(*func)(char *input),
|
||||
const char *funcname)
|
||||
{
|
||||
int failed = 0, i;
|
||||
char buffer[1024];
|
||||
char *to;
|
||||
|
||||
for (i = 0; data[i].to; i++) {
|
||||
if (!data[i].from)
|
||||
to = func(NULL);
|
||||
else {
|
||||
xsnprintf(buffer, sizeof(buffer), "%s", data[i].from);
|
||||
to = func(buffer);
|
||||
}
|
||||
if (!strcmp(to, data[i].to))
|
||||
continue;
|
||||
if (!data[i].alternative)
|
||||
error("FAIL: %s(%s) => '%s' != '%s'\n",
|
||||
funcname, data[i].from, to, data[i].to);
|
||||
else if (!strcmp(to, data[i].alternative))
|
||||
continue;
|
||||
else
|
||||
error("FAIL: %s(%s) => '%s' != '%s', '%s'\n",
|
||||
funcname, data[i].from, to, data[i].to,
|
||||
data[i].alternative);
|
||||
failed = 1;
|
||||
}
|
||||
return failed;
|
||||
}
|
||||
|
||||
static struct test_data basename_data[] = {
|
||||
/* --- POSIX type paths --- */
|
||||
{ NULL, "." },
|
||||
{ "", "." },
|
||||
{ ".", "." },
|
||||
{ "..", ".." },
|
||||
{ "/", "/" },
|
||||
{ "//", "/", "//" },
|
||||
{ "///", "/", "//" },
|
||||
{ "////", "/", "//" },
|
||||
{ "usr", "usr" },
|
||||
{ "/usr", "usr" },
|
||||
{ "/usr/", "usr" },
|
||||
{ "/usr//", "usr" },
|
||||
{ "/usr/lib", "lib" },
|
||||
{ "usr/lib", "lib" },
|
||||
{ "usr/lib///", "lib" },
|
||||
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
/* --- win32 type paths --- */
|
||||
{ "\\usr", "usr" },
|
||||
{ "\\usr\\", "usr" },
|
||||
{ "\\usr\\\\", "usr" },
|
||||
{ "\\usr\\lib", "lib" },
|
||||
{ "usr\\lib", "lib" },
|
||||
{ "usr\\lib\\\\\\", "lib" },
|
||||
{ "C:/usr", "usr" },
|
||||
{ "C:/usr", "usr" },
|
||||
{ "C:/usr/", "usr" },
|
||||
{ "C:/usr//", "usr" },
|
||||
{ "C:/usr/lib", "lib" },
|
||||
{ "C:usr/lib", "lib" },
|
||||
{ "C:usr/lib///", "lib" },
|
||||
{ "C:", "." },
|
||||
{ "C:a", "a" },
|
||||
{ "C:/", "/" },
|
||||
{ "C:///", "/" },
|
||||
{ "\\", "\\", "/" },
|
||||
{ "\\\\", "\\", "/" },
|
||||
{ "\\\\\\", "\\", "/" },
|
||||
#endif
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static struct test_data dirname_data[] = {
|
||||
/* --- POSIX type paths --- */
|
||||
{ NULL, "." },
|
||||
{ "", "." },
|
||||
{ ".", "." },
|
||||
{ "..", "." },
|
||||
{ "/", "/" },
|
||||
{ "//", "/", "//" },
|
||||
{ "///", "/", "//" },
|
||||
{ "////", "/", "//" },
|
||||
{ "usr", "." },
|
||||
{ "/usr", "/" },
|
||||
{ "/usr/", "/" },
|
||||
{ "/usr//", "/" },
|
||||
{ "/usr/lib", "/usr" },
|
||||
{ "usr/lib", "usr" },
|
||||
{ "usr/lib///", "usr" },
|
||||
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
/* --- win32 type paths --- */
|
||||
{ "\\", "\\" },
|
||||
{ "\\\\", "\\\\" },
|
||||
{ "\\usr", "\\" },
|
||||
{ "\\usr\\", "\\" },
|
||||
{ "\\usr\\\\", "\\" },
|
||||
{ "\\usr\\lib", "\\usr" },
|
||||
{ "usr\\lib", "usr" },
|
||||
{ "usr\\lib\\\\\\", "usr" },
|
||||
{ "C:a", "C:." },
|
||||
{ "C:/", "C:/" },
|
||||
{ "C:///", "C:/" },
|
||||
{ "C:/usr", "C:/" },
|
||||
{ "C:/usr/", "C:/" },
|
||||
{ "C:/usr//", "C:/" },
|
||||
{ "C:/usr/lib", "C:/usr" },
|
||||
{ "C:usr/lib", "C:usr" },
|
||||
{ "C:usr/lib///", "C:usr" },
|
||||
{ "\\\\\\", "\\" },
|
||||
{ "\\\\\\\\", "\\" },
|
||||
{ "C:", "C:.", "." },
|
||||
#endif
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static int is_dotgitmodules(const char *path)
|
||||
{
|
||||
return is_hfs_dotgitmodules(path) || is_ntfs_dotgitmodules(path);
|
||||
}
|
||||
|
||||
static int cmp_by_st_size(const void *a, const void *b)
|
||||
{
|
||||
intptr_t x = (intptr_t)((struct string_list_item *)a)->util;
|
||||
intptr_t y = (intptr_t)((struct string_list_item *)b)->util;
|
||||
|
||||
return x > y ? -1 : (x < y ? +1 : 0);
|
||||
}
|
||||
|
||||
int cmd__path_utils(int argc, const char **argv)
|
||||
{
|
||||
if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) {
|
||||
char *buf = xmallocz(strlen(argv[2]));
|
||||
int rv = normalize_path_copy(buf, argv[2]);
|
||||
if (rv)
|
||||
buf = "++failed++";
|
||||
puts(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc >= 2 && !strcmp(argv[1], "real_path")) {
|
||||
while (argc > 2) {
|
||||
puts(real_path(argv[2]));
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc >= 2 && !strcmp(argv[1], "absolute_path")) {
|
||||
while (argc > 2) {
|
||||
puts(absolute_path(argv[2]));
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc == 4 && !strcmp(argv[1], "longest_ancestor_length")) {
|
||||
int len;
|
||||
struct string_list ceiling_dirs = STRING_LIST_INIT_DUP;
|
||||
char *path = xstrdup(argv[2]);
|
||||
|
||||
/*
|
||||
* We have to normalize the arguments because under
|
||||
* Windows, bash mangles arguments that look like
|
||||
* absolute POSIX paths or colon-separate lists of
|
||||
* absolute POSIX paths into DOS paths (e.g.,
|
||||
* "/foo:/foo/bar" might be converted to
|
||||
* "D:\Src\msysgit\foo;D:\Src\msysgit\foo\bar"),
|
||||
* whereas longest_ancestor_length() requires paths
|
||||
* that use forward slashes.
|
||||
*/
|
||||
if (normalize_path_copy(path, path))
|
||||
die("Path \"%s\" could not be normalized", argv[2]);
|
||||
string_list_split(&ceiling_dirs, argv[3], PATH_SEP, -1);
|
||||
filter_string_list(&ceiling_dirs, 0,
|
||||
normalize_ceiling_entry, NULL);
|
||||
len = longest_ancestor_length(path, &ceiling_dirs);
|
||||
string_list_clear(&ceiling_dirs, 0);
|
||||
free(path);
|
||||
printf("%d\n", len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc >= 4 && !strcmp(argv[1], "prefix_path")) {
|
||||
const char *prefix = argv[2];
|
||||
int prefix_len = strlen(prefix);
|
||||
int nongit_ok;
|
||||
setup_git_directory_gently(&nongit_ok);
|
||||
while (argc > 3) {
|
||||
puts(prefix_path(prefix, prefix_len, argv[3]));
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc == 4 && !strcmp(argv[1], "strip_path_suffix")) {
|
||||
char *prefix = strip_path_suffix(argv[2], argv[3]);
|
||||
printf("%s\n", prefix ? prefix : "(null)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc == 3 && !strcmp(argv[1], "print_path")) {
|
||||
puts(argv[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc == 4 && !strcmp(argv[1], "relative_path")) {
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
const char *in, *prefix, *rel;
|
||||
normalize_argv_string(&in, argv[2]);
|
||||
normalize_argv_string(&prefix, argv[3]);
|
||||
rel = relative_path(in, prefix, &sb);
|
||||
if (!rel)
|
||||
puts("(null)");
|
||||
else
|
||||
puts(strlen(rel) > 0 ? rel : "(empty)");
|
||||
strbuf_release(&sb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc == 2 && !strcmp(argv[1], "basename"))
|
||||
return test_function(basename_data, posix_basename, argv[1]);
|
||||
|
||||
if (argc == 2 && !strcmp(argv[1], "dirname"))
|
||||
return test_function(dirname_data, posix_dirname, argv[1]);
|
||||
|
||||
if (argc > 2 && !strcmp(argv[1], "is_dotgitmodules")) {
|
||||
int res = 0, expect = 1, i;
|
||||
for (i = 2; i < argc; i++)
|
||||
if (!strcmp("--not", argv[i]))
|
||||
expect = !expect;
|
||||
else if (expect != is_dotgitmodules(argv[i]))
|
||||
res = error("'%s' is %s.gitmodules", argv[i],
|
||||
expect ? "not " : "");
|
||||
else
|
||||
fprintf(stderr, "ok: '%s' is %s.gitmodules\n",
|
||||
argv[i], expect ? "" : "not ");
|
||||
return !!res;
|
||||
}
|
||||
|
||||
if (argc > 2 && !strcmp(argv[1], "file-size")) {
|
||||
int res = 0, i;
|
||||
struct stat st;
|
||||
|
||||
for (i = 2; i < argc; i++)
|
||||
if (stat(argv[i], &st))
|
||||
res = error_errno("Cannot stat '%s'", argv[i]);
|
||||
else
|
||||
printf("%"PRIuMAX"\n", (uintmax_t)st.st_size);
|
||||
return !!res;
|
||||
}
|
||||
|
||||
if (argc == 4 && !strcmp(argv[1], "skip-n-bytes")) {
|
||||
int fd = open(argv[2], O_RDONLY), offset = atoi(argv[3]);
|
||||
char buffer[65536];
|
||||
|
||||
if (fd < 0)
|
||||
die_errno("could not open '%s'", argv[2]);
|
||||
if (lseek(fd, offset, SEEK_SET) < 0)
|
||||
die_errno("could not skip %d bytes", offset);
|
||||
for (;;) {
|
||||
ssize_t count = read(fd, buffer, sizeof(buffer));
|
||||
if (count < 0)
|
||||
die_errno("could not read '%s'", argv[2]);
|
||||
if (!count)
|
||||
break;
|
||||
if (write(1, buffer, count) < 0)
|
||||
die_errno("could not write to stdout");
|
||||
}
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc > 5 && !strcmp(argv[1], "slice-tests")) {
|
||||
int res = 0;
|
||||
long offset, stride, i;
|
||||
struct string_list list = STRING_LIST_INIT_NODUP;
|
||||
struct stat st;
|
||||
|
||||
offset = strtol(argv[2], NULL, 10);
|
||||
stride = strtol(argv[3], NULL, 10);
|
||||
if (stride < 1)
|
||||
stride = 1;
|
||||
for (i = 4; i < argc; i++)
|
||||
if (stat(argv[i], &st))
|
||||
res = error_errno("Cannot stat '%s'", argv[i]);
|
||||
else
|
||||
string_list_append(&list, argv[i])->util =
|
||||
(void *)(intptr_t)st.st_size;
|
||||
QSORT(list.items, list.nr, cmp_by_st_size);
|
||||
for (i = offset; i < list.nr; i+= stride)
|
||||
printf("%s\n", list.items[i].string);
|
||||
|
||||
return !!res;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
|
||||
argv[1] ? argv[1] : "(there was none)");
|
||||
return 1;
|
||||
}
|
||||
98
third_party/git/t/helper/test-pkt-line.c
vendored
Normal file
98
third_party/git/t/helper/test-pkt-line.c
vendored
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
#include "cache.h"
|
||||
#include "test-tool.h"
|
||||
#include "pkt-line.h"
|
||||
|
||||
static void pack_line(const char *line)
|
||||
{
|
||||
if (!strcmp(line, "0000") || !strcmp(line, "0000\n"))
|
||||
packet_flush(1);
|
||||
else if (!strcmp(line, "0001") || !strcmp(line, "0001\n"))
|
||||
packet_delim(1);
|
||||
else
|
||||
packet_write_fmt(1, "%s", line);
|
||||
}
|
||||
|
||||
static void pack(int argc, const char **argv)
|
||||
{
|
||||
if (argc) { /* read from argv */
|
||||
int i;
|
||||
for (i = 0; i < argc; i++)
|
||||
pack_line(argv[i]);
|
||||
} else { /* read from stdin */
|
||||
char line[LARGE_PACKET_MAX];
|
||||
while (fgets(line, sizeof(line), stdin)) {
|
||||
pack_line(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void unpack(void)
|
||||
{
|
||||
struct packet_reader reader;
|
||||
packet_reader_init(&reader, 0, NULL, 0,
|
||||
PACKET_READ_GENTLE_ON_EOF |
|
||||
PACKET_READ_CHOMP_NEWLINE);
|
||||
|
||||
while (packet_reader_read(&reader) != PACKET_READ_EOF) {
|
||||
switch (reader.status) {
|
||||
case PACKET_READ_EOF:
|
||||
break;
|
||||
case PACKET_READ_NORMAL:
|
||||
printf("%s\n", reader.line);
|
||||
break;
|
||||
case PACKET_READ_FLUSH:
|
||||
printf("0000\n");
|
||||
break;
|
||||
case PACKET_READ_DELIM:
|
||||
printf("0001\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void unpack_sideband(void)
|
||||
{
|
||||
struct packet_reader reader;
|
||||
packet_reader_init(&reader, 0, NULL, 0,
|
||||
PACKET_READ_GENTLE_ON_EOF |
|
||||
PACKET_READ_CHOMP_NEWLINE);
|
||||
|
||||
while (packet_reader_read(&reader) != PACKET_READ_EOF) {
|
||||
int band;
|
||||
int fd;
|
||||
|
||||
switch (reader.status) {
|
||||
case PACKET_READ_EOF:
|
||||
break;
|
||||
case PACKET_READ_NORMAL:
|
||||
band = reader.line[0] & 0xff;
|
||||
if (band < 1 || band > 2)
|
||||
die("unexpected side band %d", band);
|
||||
fd = band;
|
||||
|
||||
write_or_die(fd, reader.line + 1, reader.pktlen - 1);
|
||||
break;
|
||||
case PACKET_READ_FLUSH:
|
||||
return;
|
||||
case PACKET_READ_DELIM:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int cmd__pkt_line(int argc, const char **argv)
|
||||
{
|
||||
if (argc < 2)
|
||||
die("too few arguments");
|
||||
|
||||
if (!strcmp(argv[1], "pack"))
|
||||
pack(argc - 2, argv + 2);
|
||||
else if (!strcmp(argv[1], "unpack"))
|
||||
unpack();
|
||||
else if (!strcmp(argv[1], "unpack-sideband"))
|
||||
unpack_sideband();
|
||||
else
|
||||
die("invalid argument '%s'", argv[1]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
50
third_party/git/t/helper/test-prio-queue.c
vendored
Normal file
50
third_party/git/t/helper/test-prio-queue.c
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "prio-queue.h"
|
||||
|
||||
static int intcmp(const void *va, const void *vb, void *data)
|
||||
{
|
||||
const int *a = va, *b = vb;
|
||||
return *a - *b;
|
||||
}
|
||||
|
||||
static void show(int *v)
|
||||
{
|
||||
if (!v)
|
||||
printf("NULL\n");
|
||||
else
|
||||
printf("%d\n", *v);
|
||||
free(v);
|
||||
}
|
||||
|
||||
int cmd__prio_queue(int argc, const char **argv)
|
||||
{
|
||||
struct prio_queue pq = { intcmp };
|
||||
|
||||
while (*++argv) {
|
||||
if (!strcmp(*argv, "get")) {
|
||||
void *peek = prio_queue_peek(&pq);
|
||||
void *get = prio_queue_get(&pq);
|
||||
if (peek != get)
|
||||
BUG("peek and get results do not match");
|
||||
show(get);
|
||||
} else if (!strcmp(*argv, "dump")) {
|
||||
void *peek;
|
||||
void *get;
|
||||
while ((peek = prio_queue_peek(&pq))) {
|
||||
get = prio_queue_get(&pq);
|
||||
if (peek != get)
|
||||
BUG("peek and get results do not match");
|
||||
show(get);
|
||||
}
|
||||
} else if (!strcmp(*argv, "stack")) {
|
||||
pq.compare = NULL;
|
||||
} else {
|
||||
int *v = xmalloc(sizeof(*v));
|
||||
*v = atoi(*argv);
|
||||
prio_queue_put(&pq, v);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
168
third_party/git/t/helper/test-reach.c
vendored
Normal file
168
third_party/git/t/helper/test-reach.c
vendored
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "commit.h"
|
||||
#include "commit-reach.h"
|
||||
#include "config.h"
|
||||
#include "parse-options.h"
|
||||
#include "ref-filter.h"
|
||||
#include "string-list.h"
|
||||
#include "tag.h"
|
||||
|
||||
static void print_sorted_commit_ids(struct commit_list *list)
|
||||
{
|
||||
int i;
|
||||
struct string_list s = STRING_LIST_INIT_DUP;
|
||||
|
||||
while (list) {
|
||||
string_list_append(&s, oid_to_hex(&list->item->object.oid));
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
string_list_sort(&s);
|
||||
|
||||
for (i = 0; i < s.nr; i++)
|
||||
printf("%s\n", s.items[i].string);
|
||||
|
||||
string_list_clear(&s, 0);
|
||||
}
|
||||
|
||||
int cmd__reach(int ac, const char **av)
|
||||
{
|
||||
struct object_id oid_A, oid_B;
|
||||
struct commit *A, *B;
|
||||
struct commit_list *X, *Y;
|
||||
struct object_array X_obj = OBJECT_ARRAY_INIT;
|
||||
struct commit **X_array, **Y_array;
|
||||
int X_nr, X_alloc, Y_nr, Y_alloc;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
struct repository *r = the_repository;
|
||||
|
||||
setup_git_directory();
|
||||
|
||||
if (ac < 2)
|
||||
exit(1);
|
||||
|
||||
A = B = NULL;
|
||||
X = Y = NULL;
|
||||
X_nr = Y_nr = 0;
|
||||
X_alloc = Y_alloc = 16;
|
||||
ALLOC_ARRAY(X_array, X_alloc);
|
||||
ALLOC_ARRAY(Y_array, Y_alloc);
|
||||
|
||||
while (strbuf_getline(&buf, stdin) != EOF) {
|
||||
struct object_id oid;
|
||||
struct object *orig;
|
||||
struct object *peeled;
|
||||
struct commit *c;
|
||||
if (buf.len < 3)
|
||||
continue;
|
||||
|
||||
if (get_oid_committish(buf.buf + 2, &oid))
|
||||
die("failed to resolve %s", buf.buf + 2);
|
||||
|
||||
orig = parse_object(r, &oid);
|
||||
peeled = deref_tag_noverify(orig);
|
||||
|
||||
if (!peeled)
|
||||
die("failed to load commit for input %s resulting in oid %s\n",
|
||||
buf.buf, oid_to_hex(&oid));
|
||||
|
||||
c = object_as_type(r, peeled, OBJ_COMMIT, 0);
|
||||
|
||||
if (!c)
|
||||
die("failed to load commit for input %s resulting in oid %s\n",
|
||||
buf.buf, oid_to_hex(&oid));
|
||||
|
||||
switch (buf.buf[0]) {
|
||||
case 'A':
|
||||
oidcpy(&oid_A, &oid);
|
||||
A = c;
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
oidcpy(&oid_B, &oid);
|
||||
B = c;
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
commit_list_insert(c, &X);
|
||||
ALLOC_GROW(X_array, X_nr + 1, X_alloc);
|
||||
X_array[X_nr++] = c;
|
||||
add_object_array(orig, NULL, &X_obj);
|
||||
break;
|
||||
|
||||
case 'Y':
|
||||
commit_list_insert(c, &Y);
|
||||
ALLOC_GROW(Y_array, Y_nr + 1, Y_alloc);
|
||||
Y_array[Y_nr++] = c;
|
||||
break;
|
||||
|
||||
default:
|
||||
die("unexpected start of line: %c", buf.buf[0]);
|
||||
}
|
||||
}
|
||||
strbuf_release(&buf);
|
||||
|
||||
if (!strcmp(av[1], "ref_newer"))
|
||||
printf("%s(A,B):%d\n", av[1], ref_newer(&oid_A, &oid_B));
|
||||
else if (!strcmp(av[1], "in_merge_bases"))
|
||||
printf("%s(A,B):%d\n", av[1], in_merge_bases(A, B));
|
||||
else if (!strcmp(av[1], "is_descendant_of"))
|
||||
printf("%s(A,X):%d\n", av[1], is_descendant_of(A, X));
|
||||
else if (!strcmp(av[1], "get_merge_bases_many")) {
|
||||
struct commit_list *list = get_merge_bases_many(A, X_nr, X_array);
|
||||
printf("%s(A,X):\n", av[1]);
|
||||
print_sorted_commit_ids(list);
|
||||
} else if (!strcmp(av[1], "reduce_heads")) {
|
||||
struct commit_list *list = reduce_heads(X);
|
||||
printf("%s(X):\n", av[1]);
|
||||
print_sorted_commit_ids(list);
|
||||
} else if (!strcmp(av[1], "can_all_from_reach")) {
|
||||
printf("%s(X,Y):%d\n", av[1], can_all_from_reach(X, Y, 1));
|
||||
} else if (!strcmp(av[1], "can_all_from_reach_with_flag")) {
|
||||
struct commit_list *iter = Y;
|
||||
|
||||
while (iter) {
|
||||
iter->item->object.flags |= 2;
|
||||
iter = iter->next;
|
||||
}
|
||||
|
||||
printf("%s(X,_,_,0,0):%d\n", av[1], can_all_from_reach_with_flag(&X_obj, 2, 4, 0, 0));
|
||||
} else if (!strcmp(av[1], "commit_contains")) {
|
||||
struct ref_filter filter;
|
||||
struct contains_cache cache;
|
||||
init_contains_cache(&cache);
|
||||
|
||||
if (ac > 2 && !strcmp(av[2], "--tag"))
|
||||
filter.with_commit_tag_algo = 1;
|
||||
else
|
||||
filter.with_commit_tag_algo = 0;
|
||||
|
||||
printf("%s(_,A,X,_):%d\n", av[1], commit_contains(&filter, A, X, &cache));
|
||||
} else if (!strcmp(av[1], "get_reachable_subset")) {
|
||||
const int reachable_flag = 1;
|
||||
int i, count = 0;
|
||||
struct commit_list *current;
|
||||
struct commit_list *list = get_reachable_subset(X_array, X_nr,
|
||||
Y_array, Y_nr,
|
||||
reachable_flag);
|
||||
printf("get_reachable_subset(X,Y)\n");
|
||||
for (current = list; current; current = current->next) {
|
||||
if (!(list->item->object.flags & reachable_flag))
|
||||
die(_("commit %s is not marked reachable"),
|
||||
oid_to_hex(&list->item->object.oid));
|
||||
count++;
|
||||
}
|
||||
for (i = 0; i < Y_nr; i++) {
|
||||
if (Y_array[i]->object.flags & reachable_flag)
|
||||
count--;
|
||||
}
|
||||
|
||||
if (count < 0)
|
||||
die(_("too many commits marked reachable"));
|
||||
|
||||
print_sorted_commit_ids(list);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
37
third_party/git/t/helper/test-read-cache.c
vendored
Normal file
37
third_party/git/t/helper/test-read-cache.c
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "config.h"
|
||||
|
||||
int cmd__read_cache(int argc, const char **argv)
|
||||
{
|
||||
int i, cnt = 1, namelen;
|
||||
const char *name = NULL;
|
||||
|
||||
if (argc > 1 && skip_prefix(argv[1], "--print-and-refresh=", &name)) {
|
||||
namelen = strlen(name);
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (argc == 2)
|
||||
cnt = strtol(argv[1], NULL, 0);
|
||||
setup_git_directory();
|
||||
git_config(git_default_config, NULL);
|
||||
for (i = 0; i < cnt; i++) {
|
||||
read_cache();
|
||||
if (name) {
|
||||
int pos;
|
||||
|
||||
refresh_index(&the_index, REFRESH_QUIET,
|
||||
NULL, NULL, NULL);
|
||||
pos = index_name_pos(&the_index, name, namelen);
|
||||
if (pos < 0)
|
||||
die("%s not in index", name);
|
||||
printf("%s is%s up to date\n", name,
|
||||
ce_uptodate(the_index.cache[pos]) ? "" : " not");
|
||||
write_file(name, "%d\n", i);
|
||||
}
|
||||
discard_cache();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
51
third_party/git/t/helper/test-read-midx.c
vendored
Normal file
51
third_party/git/t/helper/test-read-midx.c
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "midx.h"
|
||||
#include "repository.h"
|
||||
#include "object-store.h"
|
||||
|
||||
static int read_midx_file(const char *object_dir)
|
||||
{
|
||||
uint32_t i;
|
||||
struct multi_pack_index *m = load_multi_pack_index(object_dir, 1);
|
||||
|
||||
if (!m)
|
||||
return 1;
|
||||
|
||||
printf("header: %08x %d %d %d\n",
|
||||
m->signature,
|
||||
m->version,
|
||||
m->num_chunks,
|
||||
m->num_packs);
|
||||
|
||||
printf("chunks:");
|
||||
|
||||
if (m->chunk_pack_names)
|
||||
printf(" pack-names");
|
||||
if (m->chunk_oid_fanout)
|
||||
printf(" oid-fanout");
|
||||
if (m->chunk_oid_lookup)
|
||||
printf(" oid-lookup");
|
||||
if (m->chunk_object_offsets)
|
||||
printf(" object-offsets");
|
||||
if (m->chunk_large_offsets)
|
||||
printf(" large-offsets");
|
||||
|
||||
printf("\nnum_objects: %d\n", m->num_objects);
|
||||
|
||||
printf("packs:\n");
|
||||
for (i = 0; i < m->num_packs; i++)
|
||||
printf("%s\n", m->pack_names[i]);
|
||||
|
||||
printf("object-dir: %s\n", m->object_dir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cmd__read_midx(int argc, const char **argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
usage("read-midx <object-dir>");
|
||||
|
||||
return read_midx_file(argv[1]);
|
||||
}
|
||||
299
third_party/git/t/helper/test-ref-store.c
vendored
Normal file
299
third_party/git/t/helper/test-ref-store.c
vendored
Normal file
|
|
@ -0,0 +1,299 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "refs.h"
|
||||
#include "worktree.h"
|
||||
#include "object-store.h"
|
||||
#include "repository.h"
|
||||
|
||||
static const char *notnull(const char *arg, const char *name)
|
||||
{
|
||||
if (!arg)
|
||||
die("%s required", name);
|
||||
return arg;
|
||||
}
|
||||
|
||||
static unsigned int arg_flags(const char *arg, const char *name)
|
||||
{
|
||||
return atoi(notnull(arg, name));
|
||||
}
|
||||
|
||||
static const char **get_store(const char **argv, struct ref_store **refs)
|
||||
{
|
||||
const char *gitdir;
|
||||
|
||||
if (!argv[0]) {
|
||||
die("ref store required");
|
||||
} else if (!strcmp(argv[0], "main")) {
|
||||
*refs = get_main_ref_store(the_repository);
|
||||
} else if (skip_prefix(argv[0], "submodule:", &gitdir)) {
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
int ret;
|
||||
|
||||
ret = strbuf_git_path_submodule(&sb, gitdir, "objects/");
|
||||
if (ret)
|
||||
die("strbuf_git_path_submodule failed: %d", ret);
|
||||
add_to_alternates_memory(sb.buf);
|
||||
strbuf_release(&sb);
|
||||
|
||||
*refs = get_submodule_ref_store(gitdir);
|
||||
} else if (skip_prefix(argv[0], "worktree:", &gitdir)) {
|
||||
struct worktree **p, **worktrees = get_worktrees(0);
|
||||
|
||||
for (p = worktrees; *p; p++) {
|
||||
struct worktree *wt = *p;
|
||||
|
||||
if (!wt->id) {
|
||||
/* special case for main worktree */
|
||||
if (!strcmp(gitdir, "main"))
|
||||
break;
|
||||
} else if (!strcmp(gitdir, wt->id))
|
||||
break;
|
||||
}
|
||||
if (!*p)
|
||||
die("no such worktree: %s", gitdir);
|
||||
|
||||
*refs = get_worktree_ref_store(*p);
|
||||
} else
|
||||
die("unknown backend %s", argv[0]);
|
||||
|
||||
if (!*refs)
|
||||
die("no ref store");
|
||||
|
||||
/* consume store-specific optional arguments if needed */
|
||||
|
||||
return argv + 1;
|
||||
}
|
||||
|
||||
|
||||
static int cmd_pack_refs(struct ref_store *refs, const char **argv)
|
||||
{
|
||||
unsigned int flags = arg_flags(*argv++, "flags");
|
||||
|
||||
return refs_pack_refs(refs, flags);
|
||||
}
|
||||
|
||||
static int cmd_peel_ref(struct ref_store *refs, const char **argv)
|
||||
{
|
||||
const char *refname = notnull(*argv++, "refname");
|
||||
struct object_id oid;
|
||||
int ret;
|
||||
|
||||
ret = refs_peel_ref(refs, refname, &oid);
|
||||
if (!ret)
|
||||
puts(oid_to_hex(&oid));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cmd_create_symref(struct ref_store *refs, const char **argv)
|
||||
{
|
||||
const char *refname = notnull(*argv++, "refname");
|
||||
const char *target = notnull(*argv++, "target");
|
||||
const char *logmsg = *argv++;
|
||||
|
||||
return refs_create_symref(refs, refname, target, logmsg);
|
||||
}
|
||||
|
||||
static int cmd_delete_refs(struct ref_store *refs, const char **argv)
|
||||
{
|
||||
unsigned int flags = arg_flags(*argv++, "flags");
|
||||
const char *msg = *argv++;
|
||||
struct string_list refnames = STRING_LIST_INIT_NODUP;
|
||||
|
||||
while (*argv)
|
||||
string_list_append(&refnames, *argv++);
|
||||
|
||||
return refs_delete_refs(refs, msg, &refnames, flags);
|
||||
}
|
||||
|
||||
static int cmd_rename_ref(struct ref_store *refs, const char **argv)
|
||||
{
|
||||
const char *oldref = notnull(*argv++, "oldref");
|
||||
const char *newref = notnull(*argv++, "newref");
|
||||
const char *logmsg = *argv++;
|
||||
|
||||
return refs_rename_ref(refs, oldref, newref, logmsg);
|
||||
}
|
||||
|
||||
static int each_ref(const char *refname, const struct object_id *oid,
|
||||
int flags, void *cb_data)
|
||||
{
|
||||
printf("%s %s 0x%x\n", oid_to_hex(oid), refname, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_for_each_ref(struct ref_store *refs, const char **argv)
|
||||
{
|
||||
const char *prefix = notnull(*argv++, "prefix");
|
||||
|
||||
return refs_for_each_ref_in(refs, prefix, each_ref, NULL);
|
||||
}
|
||||
|
||||
static int cmd_resolve_ref(struct ref_store *refs, const char **argv)
|
||||
{
|
||||
struct object_id oid;
|
||||
const char *refname = notnull(*argv++, "refname");
|
||||
int resolve_flags = arg_flags(*argv++, "resolve-flags");
|
||||
int flags;
|
||||
const char *ref;
|
||||
|
||||
ref = refs_resolve_ref_unsafe(refs, refname, resolve_flags,
|
||||
&oid, &flags);
|
||||
printf("%s %s 0x%x\n", oid_to_hex(&oid), ref ? ref : "(null)", flags);
|
||||
return ref ? 0 : 1;
|
||||
}
|
||||
|
||||
static int cmd_verify_ref(struct ref_store *refs, const char **argv)
|
||||
{
|
||||
const char *refname = notnull(*argv++, "refname");
|
||||
struct strbuf err = STRBUF_INIT;
|
||||
int ret;
|
||||
|
||||
ret = refs_verify_refname_available(refs, refname, NULL, NULL, &err);
|
||||
if (err.len)
|
||||
puts(err.buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cmd_for_each_reflog(struct ref_store *refs, const char **argv)
|
||||
{
|
||||
return refs_for_each_reflog(refs, each_ref, NULL);
|
||||
}
|
||||
|
||||
static int each_reflog(struct object_id *old_oid, struct object_id *new_oid,
|
||||
const char *committer, timestamp_t timestamp,
|
||||
int tz, const char *msg, void *cb_data)
|
||||
{
|
||||
printf("%s %s %s %"PRItime" %d %s\n",
|
||||
oid_to_hex(old_oid), oid_to_hex(new_oid),
|
||||
committer, timestamp, tz, msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_for_each_reflog_ent(struct ref_store *refs, const char **argv)
|
||||
{
|
||||
const char *refname = notnull(*argv++, "refname");
|
||||
|
||||
return refs_for_each_reflog_ent(refs, refname, each_reflog, refs);
|
||||
}
|
||||
|
||||
static int cmd_for_each_reflog_ent_reverse(struct ref_store *refs, const char **argv)
|
||||
{
|
||||
const char *refname = notnull(*argv++, "refname");
|
||||
|
||||
return refs_for_each_reflog_ent_reverse(refs, refname, each_reflog, refs);
|
||||
}
|
||||
|
||||
static int cmd_reflog_exists(struct ref_store *refs, const char **argv)
|
||||
{
|
||||
const char *refname = notnull(*argv++, "refname");
|
||||
|
||||
return !refs_reflog_exists(refs, refname);
|
||||
}
|
||||
|
||||
static int cmd_create_reflog(struct ref_store *refs, const char **argv)
|
||||
{
|
||||
const char *refname = notnull(*argv++, "refname");
|
||||
int force_create = arg_flags(*argv++, "force-create");
|
||||
struct strbuf err = STRBUF_INIT;
|
||||
int ret;
|
||||
|
||||
ret = refs_create_reflog(refs, refname, force_create, &err);
|
||||
if (err.len)
|
||||
puts(err.buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cmd_delete_reflog(struct ref_store *refs, const char **argv)
|
||||
{
|
||||
const char *refname = notnull(*argv++, "refname");
|
||||
|
||||
return refs_delete_reflog(refs, refname);
|
||||
}
|
||||
|
||||
static int cmd_reflog_expire(struct ref_store *refs, const char **argv)
|
||||
{
|
||||
die("not supported yet");
|
||||
}
|
||||
|
||||
static int cmd_delete_ref(struct ref_store *refs, const char **argv)
|
||||
{
|
||||
const char *msg = notnull(*argv++, "msg");
|
||||
const char *refname = notnull(*argv++, "refname");
|
||||
const char *sha1_buf = notnull(*argv++, "old-sha1");
|
||||
unsigned int flags = arg_flags(*argv++, "flags");
|
||||
struct object_id old_oid;
|
||||
|
||||
if (get_oid_hex(sha1_buf, &old_oid))
|
||||
die("not sha-1");
|
||||
|
||||
return refs_delete_ref(refs, msg, refname, &old_oid, flags);
|
||||
}
|
||||
|
||||
static int cmd_update_ref(struct ref_store *refs, const char **argv)
|
||||
{
|
||||
const char *msg = notnull(*argv++, "msg");
|
||||
const char *refname = notnull(*argv++, "refname");
|
||||
const char *new_sha1_buf = notnull(*argv++, "new-sha1");
|
||||
const char *old_sha1_buf = notnull(*argv++, "old-sha1");
|
||||
unsigned int flags = arg_flags(*argv++, "flags");
|
||||
struct object_id old_oid;
|
||||
struct object_id new_oid;
|
||||
|
||||
if (get_oid_hex(old_sha1_buf, &old_oid) ||
|
||||
get_oid_hex(new_sha1_buf, &new_oid))
|
||||
die("not sha-1");
|
||||
|
||||
return refs_update_ref(refs, msg, refname,
|
||||
&new_oid, &old_oid,
|
||||
flags, UPDATE_REFS_DIE_ON_ERR);
|
||||
}
|
||||
|
||||
struct command {
|
||||
const char *name;
|
||||
int (*func)(struct ref_store *refs, const char **argv);
|
||||
};
|
||||
|
||||
static struct command commands[] = {
|
||||
{ "pack-refs", cmd_pack_refs },
|
||||
{ "peel-ref", cmd_peel_ref },
|
||||
{ "create-symref", cmd_create_symref },
|
||||
{ "delete-refs", cmd_delete_refs },
|
||||
{ "rename-ref", cmd_rename_ref },
|
||||
{ "for-each-ref", cmd_for_each_ref },
|
||||
{ "resolve-ref", cmd_resolve_ref },
|
||||
{ "verify-ref", cmd_verify_ref },
|
||||
{ "for-each-reflog", cmd_for_each_reflog },
|
||||
{ "for-each-reflog-ent", cmd_for_each_reflog_ent },
|
||||
{ "for-each-reflog-ent-reverse", cmd_for_each_reflog_ent_reverse },
|
||||
{ "reflog-exists", cmd_reflog_exists },
|
||||
{ "create-reflog", cmd_create_reflog },
|
||||
{ "delete-reflog", cmd_delete_reflog },
|
||||
{ "reflog-expire", cmd_reflog_expire },
|
||||
/*
|
||||
* backend transaction functions can't be tested separately
|
||||
*/
|
||||
{ "delete-ref", cmd_delete_ref },
|
||||
{ "update-ref", cmd_update_ref },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
int cmd__ref_store(int argc, const char **argv)
|
||||
{
|
||||
struct ref_store *refs;
|
||||
const char *func;
|
||||
struct command *cmd;
|
||||
|
||||
setup_git_directory();
|
||||
|
||||
argv = get_store(argv + 1, &refs);
|
||||
|
||||
func = *argv++;
|
||||
if (!func)
|
||||
die("ref function required");
|
||||
for (cmd = commands; cmd->name; cmd++) {
|
||||
if (!strcmp(func, cmd->name))
|
||||
return cmd->func(refs, argv);
|
||||
}
|
||||
die("unknown function %s", func);
|
||||
return 0;
|
||||
}
|
||||
76
third_party/git/t/helper/test-regex.c
vendored
Normal file
76
third_party/git/t/helper/test-regex.c
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
#include "test-tool.h"
|
||||
#include "git-compat-util.h"
|
||||
#include "gettext.h"
|
||||
|
||||
struct reg_flag {
|
||||
const char *name;
|
||||
int flag;
|
||||
};
|
||||
|
||||
static struct reg_flag reg_flags[] = {
|
||||
{ "EXTENDED", REG_EXTENDED },
|
||||
{ "NEWLINE", REG_NEWLINE },
|
||||
{ "ICASE", REG_ICASE },
|
||||
{ "NOTBOL", REG_NOTBOL },
|
||||
#ifdef REG_STARTEND
|
||||
{ "STARTEND", REG_STARTEND },
|
||||
#endif
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static int test_regex_bug(void)
|
||||
{
|
||||
char *pat = "[^={} \t]+";
|
||||
char *str = "={}\nfred";
|
||||
regex_t r;
|
||||
regmatch_t m[1];
|
||||
|
||||
if (regcomp(&r, pat, REG_EXTENDED | REG_NEWLINE))
|
||||
die("failed regcomp() for pattern '%s'", pat);
|
||||
if (regexec(&r, str, 1, m, 0))
|
||||
die("no match of pattern '%s' to string '%s'", pat, str);
|
||||
|
||||
/* http://sourceware.org/bugzilla/show_bug.cgi?id=3957 */
|
||||
if (m[0].rm_so == 3) /* matches '\n' when it should not */
|
||||
die("regex bug confirmed: re-build git with NO_REGEX=1");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cmd__regex(int argc, const char **argv)
|
||||
{
|
||||
const char *pat;
|
||||
const char *str;
|
||||
int flags = 0;
|
||||
regex_t r;
|
||||
regmatch_t m[1];
|
||||
|
||||
if (argc == 2 && !strcmp(argv[1], "--bug"))
|
||||
return test_regex_bug();
|
||||
else if (argc < 3)
|
||||
usage("test-tool regex --bug\n"
|
||||
"test-tool regex <pattern> <string> [<options>]");
|
||||
|
||||
argv++;
|
||||
pat = *argv++;
|
||||
str = *argv++;
|
||||
while (*argv) {
|
||||
struct reg_flag *rf;
|
||||
for (rf = reg_flags; rf->name; rf++)
|
||||
if (!strcmp(*argv, rf->name)) {
|
||||
flags |= rf->flag;
|
||||
break;
|
||||
}
|
||||
if (!rf->name)
|
||||
die("do not recognize %s", *argv);
|
||||
argv++;
|
||||
}
|
||||
git_setup_gettext();
|
||||
|
||||
if (regcomp(&r, pat, flags))
|
||||
die("failed regcomp() for pattern '%s'", pat);
|
||||
if (regexec(&r, str, 1, m, 0))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
98
third_party/git/t/helper/test-repository.c
vendored
Normal file
98
third_party/git/t/helper/test-repository.c
vendored
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "commit-graph.h"
|
||||
#include "commit.h"
|
||||
#include "config.h"
|
||||
#include "object-store.h"
|
||||
#include "object.h"
|
||||
#include "repository.h"
|
||||
#include "tree.h"
|
||||
|
||||
static void test_parse_commit_in_graph(const char *gitdir, const char *worktree,
|
||||
const struct object_id *commit_oid)
|
||||
{
|
||||
struct repository r;
|
||||
struct commit *c;
|
||||
struct commit_list *parent;
|
||||
|
||||
setup_git_env(gitdir);
|
||||
|
||||
memset(the_repository, 0, sizeof(*the_repository));
|
||||
|
||||
/* TODO: Needed for temporary hack in hashcmp, see 183a638b7da. */
|
||||
repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
|
||||
|
||||
if (repo_init(&r, gitdir, worktree))
|
||||
die("Couldn't init repo");
|
||||
|
||||
c = lookup_commit(&r, commit_oid);
|
||||
|
||||
if (!parse_commit_in_graph(&r, c))
|
||||
die("Couldn't parse commit");
|
||||
|
||||
printf("%"PRItime, c->date);
|
||||
for (parent = c->parents; parent; parent = parent->next)
|
||||
printf(" %s", oid_to_hex(&parent->item->object.oid));
|
||||
printf("\n");
|
||||
|
||||
repo_clear(&r);
|
||||
}
|
||||
|
||||
static void test_get_commit_tree_in_graph(const char *gitdir,
|
||||
const char *worktree,
|
||||
const struct object_id *commit_oid)
|
||||
{
|
||||
struct repository r;
|
||||
struct commit *c;
|
||||
struct tree *tree;
|
||||
|
||||
setup_git_env(gitdir);
|
||||
|
||||
memset(the_repository, 0, sizeof(*the_repository));
|
||||
|
||||
/* TODO: Needed for temporary hack in hashcmp, see 183a638b7da. */
|
||||
repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
|
||||
|
||||
if (repo_init(&r, gitdir, worktree))
|
||||
die("Couldn't init repo");
|
||||
|
||||
c = lookup_commit(&r, commit_oid);
|
||||
|
||||
/*
|
||||
* get_commit_tree_in_graph does not automatically parse the commit, so
|
||||
* parse it first.
|
||||
*/
|
||||
if (!parse_commit_in_graph(&r, c))
|
||||
die("Couldn't parse commit");
|
||||
tree = get_commit_tree_in_graph(&r, c);
|
||||
if (!tree)
|
||||
die("Couldn't get commit tree");
|
||||
|
||||
printf("%s\n", oid_to_hex(&tree->object.oid));
|
||||
|
||||
repo_clear(&r);
|
||||
}
|
||||
|
||||
int cmd__repository(int argc, const char **argv)
|
||||
{
|
||||
if (argc < 2)
|
||||
die("must have at least 2 arguments");
|
||||
if (!strcmp(argv[1], "parse_commit_in_graph")) {
|
||||
struct object_id oid;
|
||||
if (argc < 5)
|
||||
die("not enough arguments");
|
||||
if (parse_oid_hex(argv[4], &oid, &argv[4]))
|
||||
die("cannot parse oid '%s'", argv[4]);
|
||||
test_parse_commit_in_graph(argv[2], argv[3], &oid);
|
||||
} else if (!strcmp(argv[1], "get_commit_tree_in_graph")) {
|
||||
struct object_id oid;
|
||||
if (argc < 5)
|
||||
die("not enough arguments");
|
||||
if (parse_oid_hex(argv[4], &oid, &argv[4]))
|
||||
die("cannot parse oid '%s'", argv[4]);
|
||||
test_get_commit_tree_in_graph(argv[2], argv[3], &oid);
|
||||
} else {
|
||||
die("unrecognized '%s'", argv[1]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
69
third_party/git/t/helper/test-revision-walking.c
vendored
Normal file
69
third_party/git/t/helper/test-revision-walking.c
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* test-revision-walking.c: test revision walking API.
|
||||
*
|
||||
* (C) 2012 Heiko Voigt <hvoigt@hvoigt.net>
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "commit.h"
|
||||
#include "diff.h"
|
||||
#include "revision.h"
|
||||
|
||||
static void print_commit(struct commit *commit)
|
||||
{
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
struct pretty_print_context ctx = {0};
|
||||
ctx.date_mode.type = DATE_NORMAL;
|
||||
format_commit_message(commit, " %m %s", &sb, &ctx);
|
||||
printf("%s\n", sb.buf);
|
||||
strbuf_release(&sb);
|
||||
}
|
||||
|
||||
static int run_revision_walk(void)
|
||||
{
|
||||
struct rev_info rev;
|
||||
struct commit *commit;
|
||||
const char *argv[] = {NULL, "--all", NULL};
|
||||
int argc = ARRAY_SIZE(argv) - 1;
|
||||
int got_revision = 0;
|
||||
|
||||
repo_init_revisions(the_repository, &rev, NULL);
|
||||
setup_revisions(argc, argv, &rev, NULL);
|
||||
if (prepare_revision_walk(&rev))
|
||||
die("revision walk setup failed");
|
||||
|
||||
while ((commit = get_revision(&rev)) != NULL) {
|
||||
print_commit(commit);
|
||||
got_revision = 1;
|
||||
}
|
||||
|
||||
reset_revision_walk();
|
||||
return got_revision;
|
||||
}
|
||||
|
||||
int cmd__revision_walking(int argc, const char **argv)
|
||||
{
|
||||
if (argc < 2)
|
||||
return 1;
|
||||
|
||||
setup_git_directory();
|
||||
|
||||
if (!strcmp(argv[1], "run-twice")) {
|
||||
printf("1st\n");
|
||||
if (!run_revision_walk())
|
||||
return 1;
|
||||
printf("2nd\n");
|
||||
if (!run_revision_walk())
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "check usage\n");
|
||||
return 1;
|
||||
}
|
||||
97
third_party/git/t/helper/test-run-command.c
vendored
Normal file
97
third_party/git/t/helper/test-run-command.c
vendored
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* test-run-command.c: test run command API.
|
||||
*
|
||||
* (C) 2009 Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include "test-tool.h"
|
||||
#include "git-compat-util.h"
|
||||
#include "run-command.h"
|
||||
#include "argv-array.h"
|
||||
#include "strbuf.h"
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
static int number_callbacks;
|
||||
static int parallel_next(struct child_process *cp,
|
||||
struct strbuf *err,
|
||||
void *cb,
|
||||
void **task_cb)
|
||||
{
|
||||
struct child_process *d = cb;
|
||||
if (number_callbacks >= 4)
|
||||
return 0;
|
||||
|
||||
argv_array_pushv(&cp->args, d->argv);
|
||||
strbuf_addstr(err, "preloaded output of a child\n");
|
||||
number_callbacks++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int no_job(struct child_process *cp,
|
||||
struct strbuf *err,
|
||||
void *cb,
|
||||
void **task_cb)
|
||||
{
|
||||
strbuf_addstr(err, "no further jobs available\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int task_finished(int result,
|
||||
struct strbuf *err,
|
||||
void *pp_cb,
|
||||
void *pp_task_cb)
|
||||
{
|
||||
strbuf_addstr(err, "asking for a quick stop\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cmd__run_command(int argc, const char **argv)
|
||||
{
|
||||
struct child_process proc = CHILD_PROCESS_INIT;
|
||||
int jobs;
|
||||
|
||||
if (argc < 3)
|
||||
return 1;
|
||||
while (!strcmp(argv[1], "env")) {
|
||||
if (!argv[2])
|
||||
die("env specifier without a value");
|
||||
argv_array_push(&proc.env_array, argv[2]);
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
}
|
||||
if (argc < 3)
|
||||
return 1;
|
||||
proc.argv = (const char **)argv + 2;
|
||||
|
||||
if (!strcmp(argv[1], "start-command-ENOENT")) {
|
||||
if (start_command(&proc) < 0 && errno == ENOENT)
|
||||
return 0;
|
||||
fprintf(stderr, "FAIL %s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
if (!strcmp(argv[1], "run-command"))
|
||||
exit(run_command(&proc));
|
||||
|
||||
jobs = atoi(argv[2]);
|
||||
proc.argv = (const char **)argv + 3;
|
||||
|
||||
if (!strcmp(argv[1], "run-command-parallel"))
|
||||
exit(run_processes_parallel(jobs, parallel_next,
|
||||
NULL, NULL, &proc));
|
||||
|
||||
if (!strcmp(argv[1], "run-command-abort"))
|
||||
exit(run_processes_parallel(jobs, parallel_next,
|
||||
NULL, task_finished, &proc));
|
||||
|
||||
if (!strcmp(argv[1], "run-command-no-jobs"))
|
||||
exit(run_processes_parallel(jobs, no_job,
|
||||
NULL, task_finished, &proc));
|
||||
|
||||
fprintf(stderr, "check usage\n");
|
||||
return 1;
|
||||
}
|
||||
19
third_party/git/t/helper/test-scrap-cache-tree.c
vendored
Normal file
19
third_party/git/t/helper/test-scrap-cache-tree.c
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "lockfile.h"
|
||||
#include "tree.h"
|
||||
#include "cache-tree.h"
|
||||
|
||||
int cmd__scrap_cache_tree(int ac, const char **av)
|
||||
{
|
||||
struct lock_file index_lock = LOCK_INIT;
|
||||
|
||||
setup_git_directory();
|
||||
hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR);
|
||||
if (read_cache() < 0)
|
||||
die("unable to read index file");
|
||||
active_cache_tree = NULL;
|
||||
if (write_locked_index(&the_index, &index_lock, COMMIT_LOCK))
|
||||
die("unable to write index file");
|
||||
return 0;
|
||||
}
|
||||
31
third_party/git/t/helper/test-serve-v2.c
vendored
Normal file
31
third_party/git/t/helper/test-serve-v2.c
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "parse-options.h"
|
||||
#include "serve.h"
|
||||
|
||||
static char const * const serve_usage[] = {
|
||||
N_("test-tool serve-v2 [<options>]"),
|
||||
NULL
|
||||
};
|
||||
|
||||
int cmd__serve_v2(int argc, const char **argv)
|
||||
{
|
||||
struct serve_options opts = SERVE_OPTIONS_INIT;
|
||||
|
||||
struct option options[] = {
|
||||
OPT_BOOL(0, "stateless-rpc", &opts.stateless_rpc,
|
||||
N_("quit after a single request/response exchange")),
|
||||
OPT_BOOL(0, "advertise-capabilities", &opts.advertise_capabilities,
|
||||
N_("exit immediately after advertising capabilities")),
|
||||
OPT_END()
|
||||
};
|
||||
const char *prefix = setup_git_directory();
|
||||
|
||||
/* ignore all unknown cmdline switches for now */
|
||||
argc = parse_options(argc, argv, prefix, options, serve_usage,
|
||||
PARSE_OPT_KEEP_DASHDASH |
|
||||
PARSE_OPT_KEEP_UNKNOWN);
|
||||
serve(&opts);
|
||||
|
||||
return 0;
|
||||
}
|
||||
36
third_party/git/t/helper/test-sha1-array.c
vendored
Normal file
36
third_party/git/t/helper/test-sha1-array.c
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "sha1-array.h"
|
||||
|
||||
static int print_oid(const struct object_id *oid, void *data)
|
||||
{
|
||||
puts(oid_to_hex(oid));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cmd__sha1_array(int argc, const char **argv)
|
||||
{
|
||||
struct oid_array array = OID_ARRAY_INIT;
|
||||
struct strbuf line = STRBUF_INIT;
|
||||
|
||||
while (strbuf_getline(&line, stdin) != EOF) {
|
||||
const char *arg;
|
||||
struct object_id oid;
|
||||
|
||||
if (skip_prefix(line.buf, "append ", &arg)) {
|
||||
if (get_oid_hex(arg, &oid))
|
||||
die("not a hexadecimal SHA1: %s", arg);
|
||||
oid_array_append(&array, &oid);
|
||||
} else if (skip_prefix(line.buf, "lookup ", &arg)) {
|
||||
if (get_oid_hex(arg, &oid))
|
||||
die("not a hexadecimal SHA1: %s", arg);
|
||||
printf("%d\n", oid_array_lookup(&array, &oid));
|
||||
} else if (!strcmp(line.buf, "clear"))
|
||||
oid_array_clear(&array);
|
||||
else if (!strcmp(line.buf, "for_each_unique"))
|
||||
oid_array_for_each_unique(&array, print_oid, NULL);
|
||||
else
|
||||
die("unknown command: %s", line.buf);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
7
third_party/git/t/helper/test-sha1.c
vendored
Normal file
7
third_party/git/t/helper/test-sha1.c
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
|
||||
int cmd__sha1(int ac, const char **av)
|
||||
{
|
||||
return cmd_hash_impl(ac, av, GIT_HASH_SHA1);
|
||||
}
|
||||
83
third_party/git/t/helper/test-sha1.sh
vendored
Executable file
83
third_party/git/t/helper/test-sha1.sh
vendored
Executable file
|
|
@ -0,0 +1,83 @@
|
|||
#!/bin/sh
|
||||
|
||||
dd if=/dev/zero bs=1048576 count=100 2>/dev/null |
|
||||
/usr/bin/time t/helper/test-tool sha1 >/dev/null
|
||||
|
||||
while read expect cnt pfx
|
||||
do
|
||||
case "$expect" in '#'*) continue ;; esac
|
||||
actual=$(
|
||||
{
|
||||
test -z "$pfx" || echo "$pfx"
|
||||
dd if=/dev/zero bs=1048576 count=$cnt 2>/dev/null |
|
||||
perl -pe 'y/\000/g/'
|
||||
} | ./t/helper/test-tool sha1 $cnt
|
||||
)
|
||||
if test "$expect" = "$actual"
|
||||
then
|
||||
echo "OK: $expect $cnt $pfx"
|
||||
else
|
||||
echo >&2 "OOPS: $cnt"
|
||||
echo >&2 "expect: $expect"
|
||||
echo >&2 "actual: $actual"
|
||||
exit 1
|
||||
fi
|
||||
done <<EOF
|
||||
da39a3ee5e6b4b0d3255bfef95601890afd80709 0
|
||||
3f786850e387550fdab836ed7e6dc881de23001b 0 a
|
||||
5277cbb45a15902137d332d97e89cf8136545485 0 ab
|
||||
03cfd743661f07975fa2f1220c5194cbaff48451 0 abc
|
||||
3330b4373640f9e4604991e73c7e86bfd8da2dc3 0 abcd
|
||||
ec11312386ad561674f724b8cca7cf1796e26d1d 0 abcde
|
||||
bdc37c074ec4ee6050d68bc133c6b912f36474df 0 abcdef
|
||||
69bca99b923859f2dc486b55b87f49689b7358c7 0 abcdefg
|
||||
e414af7161c9554089f4106d6f1797ef14a73666 0 abcdefgh
|
||||
0707f2970043f9f7c22029482db27733deaec029 0 abcdefghi
|
||||
a4dd8aa74a5636728fe52451636e2e17726033aa 1
|
||||
9986b45e2f4d7086372533bb6953a8652fa3644a 1 frotz
|
||||
23d8d4f788e8526b4877548a32577543cbaaf51f 10
|
||||
8cd23f822ab44c7f481b8c92d591f6d1fcad431c 10 frotz
|
||||
f3b5604a4e604899c1233edb3bf1cc0ede4d8c32 512
|
||||
b095bd837a371593048136e429e9ac4b476e1bb3 512 frotz
|
||||
08fa81d6190948de5ccca3966340cc48c10cceac 1200 xyzzy
|
||||
e33a291f42c30a159733dd98b8b3e4ff34158ca0 4090 4G
|
||||
#a3bf783bc20caa958f6cb24dd140a7b21984838d 9999 nitfol
|
||||
EOF
|
||||
|
||||
exit
|
||||
|
||||
# generating test vectors
|
||||
# inputs are number of megabytes followed by some random string to prefix.
|
||||
|
||||
while read cnt pfx
|
||||
do
|
||||
actual=$(
|
||||
{
|
||||
test -z "$pfx" || echo "$pfx"
|
||||
dd if=/dev/zero bs=1048576 count=$cnt 2>/dev/null |
|
||||
perl -pe 'y/\000/g/'
|
||||
} | sha1sum |
|
||||
sed -e 's/ .*//'
|
||||
)
|
||||
echo "$actual $cnt $pfx"
|
||||
done <<EOF
|
||||
0
|
||||
0 a
|
||||
0 ab
|
||||
0 abc
|
||||
0 abcd
|
||||
0 abcde
|
||||
0 abcdef
|
||||
0 abcdefg
|
||||
0 abcdefgh
|
||||
0 abcdefghi
|
||||
1
|
||||
1 frotz
|
||||
10
|
||||
10 frotz
|
||||
512
|
||||
512 frotz
|
||||
1200 xyzzy
|
||||
4090 4G
|
||||
9999 nitfol
|
||||
EOF
|
||||
7
third_party/git/t/helper/test-sha256.c
vendored
Normal file
7
third_party/git/t/helper/test-sha256.c
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
|
||||
int cmd__sha256(int ac, const char **av)
|
||||
{
|
||||
return cmd_hash_impl(ac, av, GIT_HASH_SHA256);
|
||||
}
|
||||
24
third_party/git/t/helper/test-sigchain.c
vendored
Normal file
24
third_party/git/t/helper/test-sigchain.c
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "sigchain.h"
|
||||
|
||||
#define X(f) \
|
||||
static void f(int sig) { \
|
||||
puts(#f); \
|
||||
fflush(stdout); \
|
||||
sigchain_pop(sig); \
|
||||
raise(sig); \
|
||||
}
|
||||
X(one)
|
||||
X(two)
|
||||
X(three)
|
||||
#undef X
|
||||
|
||||
int cmd__sigchain(int argc, const char **argv)
|
||||
{
|
||||
sigchain_push(SIGTERM, one);
|
||||
sigchain_push(SIGTERM, two);
|
||||
sigchain_push(SIGTERM, three);
|
||||
raise(SIGTERM);
|
||||
return 0;
|
||||
}
|
||||
23
third_party/git/t/helper/test-strcmp-offset.c
vendored
Normal file
23
third_party/git/t/helper/test-strcmp-offset.c
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
|
||||
int cmd__strcmp_offset(int argc, const char **argv)
|
||||
{
|
||||
int result;
|
||||
size_t offset;
|
||||
|
||||
if (!argv[1] || !argv[2])
|
||||
die("usage: %s <string1> <string2>", argv[0]);
|
||||
|
||||
result = strcmp_offset(argv[1], argv[2], &offset);
|
||||
|
||||
/*
|
||||
* Because different CRTs behave differently, only rely on signs
|
||||
* of the result values.
|
||||
*/
|
||||
result = (result < 0 ? -1 :
|
||||
result > 0 ? 1 :
|
||||
0);
|
||||
printf("%d %"PRIuMAX"\n", result, (uintmax_t)offset);
|
||||
return 0;
|
||||
}
|
||||
129
third_party/git/t/helper/test-string-list.c
vendored
Normal file
129
third_party/git/t/helper/test-string-list.c
vendored
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "string-list.h"
|
||||
|
||||
/*
|
||||
* Parse an argument into a string list. arg should either be a
|
||||
* ':'-separated list of strings, or "-" to indicate an empty string
|
||||
* list (as opposed to "", which indicates a string list containing a
|
||||
* single empty string). list->strdup_strings must be set.
|
||||
*/
|
||||
static void parse_string_list(struct string_list *list, const char *arg)
|
||||
{
|
||||
if (!strcmp(arg, "-"))
|
||||
return;
|
||||
|
||||
(void)string_list_split(list, arg, ':', -1);
|
||||
}
|
||||
|
||||
static void write_list(const struct string_list *list)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < list->nr; i++)
|
||||
printf("[%d]: \"%s\"\n", i, list->items[i].string);
|
||||
}
|
||||
|
||||
static void write_list_compact(const struct string_list *list)
|
||||
{
|
||||
int i;
|
||||
if (!list->nr)
|
||||
printf("-\n");
|
||||
else {
|
||||
printf("%s", list->items[0].string);
|
||||
for (i = 1; i < list->nr; i++)
|
||||
printf(":%s", list->items[i].string);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int prefix_cb(struct string_list_item *item, void *cb_data)
|
||||
{
|
||||
const char *prefix = (const char *)cb_data;
|
||||
return starts_with(item->string, prefix);
|
||||
}
|
||||
|
||||
int cmd__string_list(int argc, const char **argv)
|
||||
{
|
||||
if (argc == 5 && !strcmp(argv[1], "split")) {
|
||||
struct string_list list = STRING_LIST_INIT_DUP;
|
||||
int i;
|
||||
const char *s = argv[2];
|
||||
int delim = *argv[3];
|
||||
int maxsplit = atoi(argv[4]);
|
||||
|
||||
i = string_list_split(&list, s, delim, maxsplit);
|
||||
printf("%d\n", i);
|
||||
write_list(&list);
|
||||
string_list_clear(&list, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc == 5 && !strcmp(argv[1], "split_in_place")) {
|
||||
struct string_list list = STRING_LIST_INIT_NODUP;
|
||||
int i;
|
||||
char *s = xstrdup(argv[2]);
|
||||
int delim = *argv[3];
|
||||
int maxsplit = atoi(argv[4]);
|
||||
|
||||
i = string_list_split_in_place(&list, s, delim, maxsplit);
|
||||
printf("%d\n", i);
|
||||
write_list(&list);
|
||||
string_list_clear(&list, 0);
|
||||
free(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc == 4 && !strcmp(argv[1], "filter")) {
|
||||
/*
|
||||
* Retain only the items that have the specified prefix.
|
||||
* Arguments: list|- prefix
|
||||
*/
|
||||
struct string_list list = STRING_LIST_INIT_DUP;
|
||||
const char *prefix = argv[3];
|
||||
|
||||
parse_string_list(&list, argv[2]);
|
||||
filter_string_list(&list, 0, prefix_cb, (void *)prefix);
|
||||
write_list_compact(&list);
|
||||
string_list_clear(&list, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc == 3 && !strcmp(argv[1], "remove_duplicates")) {
|
||||
struct string_list list = STRING_LIST_INIT_DUP;
|
||||
|
||||
parse_string_list(&list, argv[2]);
|
||||
string_list_remove_duplicates(&list, 0);
|
||||
write_list_compact(&list);
|
||||
string_list_clear(&list, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc == 2 && !strcmp(argv[1], "sort")) {
|
||||
struct string_list list = STRING_LIST_INIT_NODUP;
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
struct string_list_item *item;
|
||||
|
||||
strbuf_read(&sb, 0, 0);
|
||||
|
||||
/*
|
||||
* Split by newline, but don't create a string_list item
|
||||
* for the empty string after the last separator.
|
||||
*/
|
||||
if (sb.len && sb.buf[sb.len - 1] == '\n')
|
||||
strbuf_setlen(&sb, sb.len - 1);
|
||||
string_list_split_in_place(&list, sb.buf, '\n', -1);
|
||||
|
||||
string_list_sort(&list);
|
||||
|
||||
for_each_string_list_item(item, &list)
|
||||
puts(item->string);
|
||||
|
||||
string_list_clear(&list, 0);
|
||||
strbuf_release(&sb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
|
||||
argv[1] ? argv[1] : "(there was none)");
|
||||
return 1;
|
||||
}
|
||||
73
third_party/git/t/helper/test-submodule-config.c
vendored
Normal file
73
third_party/git/t/helper/test-submodule-config.c
vendored
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "config.h"
|
||||
#include "submodule-config.h"
|
||||
#include "submodule.h"
|
||||
|
||||
static void die_usage(int argc, const char **argv, const char *msg)
|
||||
{
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
fprintf(stderr, "Usage: %s [<commit> <submodulepath>] ...\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int cmd__submodule_config(int argc, const char **argv)
|
||||
{
|
||||
const char **arg = argv;
|
||||
int my_argc = argc;
|
||||
int output_url = 0;
|
||||
int lookup_name = 0;
|
||||
|
||||
arg++;
|
||||
my_argc--;
|
||||
while (arg[0] && starts_with(arg[0], "--")) {
|
||||
if (!strcmp(arg[0], "--url"))
|
||||
output_url = 1;
|
||||
if (!strcmp(arg[0], "--name"))
|
||||
lookup_name = 1;
|
||||
arg++;
|
||||
my_argc--;
|
||||
}
|
||||
|
||||
if (my_argc % 2 != 0)
|
||||
die_usage(argc, argv, "Wrong number of arguments.");
|
||||
|
||||
setup_git_directory();
|
||||
|
||||
while (*arg) {
|
||||
struct object_id commit_oid;
|
||||
const struct submodule *submodule;
|
||||
const char *commit;
|
||||
const char *path_or_name;
|
||||
|
||||
commit = arg[0];
|
||||
path_or_name = arg[1];
|
||||
|
||||
if (commit[0] == '\0')
|
||||
oidclr(&commit_oid);
|
||||
else if (get_oid(commit, &commit_oid) < 0)
|
||||
die_usage(argc, argv, "Commit not found.");
|
||||
|
||||
if (lookup_name) {
|
||||
submodule = submodule_from_name(the_repository,
|
||||
&commit_oid, path_or_name);
|
||||
} else
|
||||
submodule = submodule_from_path(the_repository,
|
||||
&commit_oid, path_or_name);
|
||||
if (!submodule)
|
||||
die_usage(argc, argv, "Submodule not found.");
|
||||
|
||||
if (output_url)
|
||||
printf("Submodule url: '%s' for path '%s'\n",
|
||||
submodule->url, submodule->path);
|
||||
else
|
||||
printf("Submodule name: '%s' for path '%s'\n",
|
||||
submodule->name, submodule->path);
|
||||
|
||||
arg += 2;
|
||||
}
|
||||
|
||||
submodule_free(the_repository);
|
||||
|
||||
return 0;
|
||||
}
|
||||
32
third_party/git/t/helper/test-submodule-nested-repo-config.c
vendored
Normal file
32
third_party/git/t/helper/test-submodule-nested-repo-config.c
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#include "test-tool.h"
|
||||
#include "submodule-config.h"
|
||||
|
||||
static void die_usage(int argc, const char **argv, const char *msg)
|
||||
{
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
fprintf(stderr, "Usage: %s <submodulepath> <config name>\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int cmd__submodule_nested_repo_config(int argc, const char **argv)
|
||||
{
|
||||
struct repository subrepo;
|
||||
const struct submodule *sub;
|
||||
|
||||
if (argc < 3)
|
||||
die_usage(argc, argv, "Wrong number of arguments.");
|
||||
|
||||
setup_git_directory();
|
||||
|
||||
sub = submodule_from_path(the_repository, &null_oid, argv[1]);
|
||||
if (repo_submodule_init(&subrepo, the_repository, sub)) {
|
||||
die_usage(argc, argv, "Submodule not found.");
|
||||
}
|
||||
|
||||
/* Read the config of _child_ submodules. */
|
||||
print_config_from_gitmodules(&subrepo, argv[2]);
|
||||
|
||||
submodule_free(the_repository);
|
||||
|
||||
return 0;
|
||||
}
|
||||
20
third_party/git/t/helper/test-subprocess.c
vendored
Normal file
20
third_party/git/t/helper/test-subprocess.c
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "run-command.h"
|
||||
|
||||
int cmd__subprocess(int argc, const char **argv)
|
||||
{
|
||||
struct child_process cp = CHILD_PROCESS_INIT;
|
||||
int nogit = 0;
|
||||
|
||||
setup_git_directory_gently(&nogit);
|
||||
if (nogit)
|
||||
die("No git repo found");
|
||||
if (argc > 1 && !strcmp(argv[1], "--setup-work-tree")) {
|
||||
setup_work_tree();
|
||||
argv++;
|
||||
}
|
||||
cp.git_cmd = 1;
|
||||
cp.argv = (const char **)argv + 1;
|
||||
return run_command(&cp);
|
||||
}
|
||||
52
third_party/git/t/helper/test-svn-fe.c
vendored
Normal file
52
third_party/git/t/helper/test-svn-fe.c
vendored
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* test-svn-fe: Code to exercise the svn import lib
|
||||
*/
|
||||
|
||||
#include "git-compat-util.h"
|
||||
#include "vcs-svn/svndump.h"
|
||||
#include "vcs-svn/svndiff.h"
|
||||
#include "vcs-svn/sliding_window.h"
|
||||
#include "vcs-svn/line_buffer.h"
|
||||
|
||||
static const char test_svnfe_usage[] =
|
||||
"test-svn-fe (<dumpfile> | [-d] <preimage> <delta> <len>)";
|
||||
|
||||
static int apply_delta(int argc, const char **argv)
|
||||
{
|
||||
struct line_buffer preimage = LINE_BUFFER_INIT;
|
||||
struct line_buffer delta = LINE_BUFFER_INIT;
|
||||
struct sliding_view preimage_view = SLIDING_VIEW_INIT(&preimage, -1);
|
||||
|
||||
if (argc != 5)
|
||||
usage(test_svnfe_usage);
|
||||
|
||||
if (buffer_init(&preimage, argv[2]))
|
||||
die_errno("cannot open preimage");
|
||||
if (buffer_init(&delta, argv[3]))
|
||||
die_errno("cannot open delta");
|
||||
if (svndiff0_apply(&delta, (off_t) strtoumax(argv[4], NULL, 0),
|
||||
&preimage_view, stdout))
|
||||
return 1;
|
||||
if (buffer_deinit(&preimage))
|
||||
die_errno("cannot close preimage");
|
||||
if (buffer_deinit(&delta))
|
||||
die_errno("cannot close delta");
|
||||
strbuf_release(&preimage_view.buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cmd_main(int argc, const char **argv)
|
||||
{
|
||||
if (argc == 2) {
|
||||
if (svndump_init(argv[1]))
|
||||
return 1;
|
||||
svndump_read(NULL, "refs/heads/master", "refs/notes/svn/revs");
|
||||
svndump_deinit();
|
||||
svndump_reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc >= 2 && !strcmp(argv[1], "-d"))
|
||||
return apply_delta(argc, argv);
|
||||
usage(test_svnfe_usage);
|
||||
}
|
||||
116
third_party/git/t/helper/test-tool.c
vendored
Normal file
116
third_party/git/t/helper/test-tool.c
vendored
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
#include "git-compat-util.h"
|
||||
#include "test-tool.h"
|
||||
#include "trace2.h"
|
||||
#include "parse-options.h"
|
||||
|
||||
static const char * const test_tool_usage[] = {
|
||||
"test-tool [-C <directory>] <command [<arguments>...]]",
|
||||
NULL
|
||||
};
|
||||
|
||||
struct test_cmd {
|
||||
const char *name;
|
||||
int (*fn)(int argc, const char **argv);
|
||||
};
|
||||
|
||||
static struct test_cmd cmds[] = {
|
||||
{ "chmtime", cmd__chmtime },
|
||||
{ "config", cmd__config },
|
||||
{ "ctype", cmd__ctype },
|
||||
{ "date", cmd__date },
|
||||
{ "delta", cmd__delta },
|
||||
{ "dir-iterator", cmd__dir_iterator },
|
||||
{ "drop-caches", cmd__drop_caches },
|
||||
{ "dump-cache-tree", cmd__dump_cache_tree },
|
||||
{ "dump-fsmonitor", cmd__dump_fsmonitor },
|
||||
{ "dump-split-index", cmd__dump_split_index },
|
||||
{ "dump-untracked-cache", cmd__dump_untracked_cache },
|
||||
{ "example-decorate", cmd__example_decorate },
|
||||
{ "genrandom", cmd__genrandom },
|
||||
{ "genzeros", cmd__genzeros },
|
||||
{ "hashmap", cmd__hashmap },
|
||||
{ "hash-speed", cmd__hash_speed },
|
||||
{ "index-version", cmd__index_version },
|
||||
{ "json-writer", cmd__json_writer },
|
||||
{ "lazy-init-name-hash", cmd__lazy_init_name_hash },
|
||||
{ "match-trees", cmd__match_trees },
|
||||
{ "mergesort", cmd__mergesort },
|
||||
{ "mktemp", cmd__mktemp },
|
||||
{ "oidmap", cmd__oidmap },
|
||||
{ "online-cpus", cmd__online_cpus },
|
||||
{ "parse-options", cmd__parse_options },
|
||||
{ "path-utils", cmd__path_utils },
|
||||
{ "pkt-line", cmd__pkt_line },
|
||||
{ "prio-queue", cmd__prio_queue },
|
||||
{ "reach", cmd__reach },
|
||||
{ "read-cache", cmd__read_cache },
|
||||
{ "read-midx", cmd__read_midx },
|
||||
{ "ref-store", cmd__ref_store },
|
||||
{ "regex", cmd__regex },
|
||||
{ "repository", cmd__repository },
|
||||
{ "revision-walking", cmd__revision_walking },
|
||||
{ "run-command", cmd__run_command },
|
||||
{ "scrap-cache-tree", cmd__scrap_cache_tree },
|
||||
{ "serve-v2", cmd__serve_v2 },
|
||||
{ "sha1", cmd__sha1 },
|
||||
{ "sha1-array", cmd__sha1_array },
|
||||
{ "sha256", cmd__sha256 },
|
||||
{ "sigchain", cmd__sigchain },
|
||||
{ "strcmp-offset", cmd__strcmp_offset },
|
||||
{ "string-list", cmd__string_list },
|
||||
{ "submodule-config", cmd__submodule_config },
|
||||
{ "submodule-nested-repo-config", cmd__submodule_nested_repo_config },
|
||||
{ "subprocess", cmd__subprocess },
|
||||
{ "trace2", cmd__trace2 },
|
||||
{ "urlmatch-normalization", cmd__urlmatch_normalization },
|
||||
{ "xml-encode", cmd__xml_encode },
|
||||
{ "wildmatch", cmd__wildmatch },
|
||||
#ifdef GIT_WINDOWS_NATIVE
|
||||
{ "windows-named-pipe", cmd__windows_named_pipe },
|
||||
#endif
|
||||
{ "write-cache", cmd__write_cache },
|
||||
};
|
||||
|
||||
static NORETURN void die_usage(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
fprintf(stderr, "usage: test-tool <toolname> [args]\n");
|
||||
for (i = 0; i < ARRAY_SIZE(cmds); i++)
|
||||
fprintf(stderr, " %s\n", cmds[i].name);
|
||||
exit(128);
|
||||
}
|
||||
|
||||
int cmd_main(int argc, const char **argv)
|
||||
{
|
||||
int i;
|
||||
const char *working_directory = NULL;
|
||||
struct option options[] = {
|
||||
OPT_STRING('C', NULL, &working_directory, "directory",
|
||||
"change the working directory"),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
BUG_exit_code = 99;
|
||||
argc = parse_options(argc, argv, NULL, options, test_tool_usage,
|
||||
PARSE_OPT_STOP_AT_NON_OPTION |
|
||||
PARSE_OPT_KEEP_ARGV0);
|
||||
|
||||
if (argc < 2)
|
||||
die_usage();
|
||||
|
||||
if (working_directory && chdir(working_directory) < 0)
|
||||
die("Could not cd to '%s'", working_directory);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cmds); i++) {
|
||||
if (!strcmp(cmds[i].name, argv[1])) {
|
||||
argv++;
|
||||
argc--;
|
||||
trace2_cmd_name(cmds[i].name);
|
||||
trace2_cmd_list_config();
|
||||
return cmds[i].fn(argc, argv);
|
||||
}
|
||||
}
|
||||
error("there is no tool named '%s'", argv[1]);
|
||||
die_usage();
|
||||
}
|
||||
65
third_party/git/t/helper/test-tool.h
vendored
Normal file
65
third_party/git/t/helper/test-tool.h
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
#ifndef TEST_TOOL_H
|
||||
#define TEST_TOOL_H
|
||||
|
||||
#define USE_THE_INDEX_COMPATIBILITY_MACROS
|
||||
#include "git-compat-util.h"
|
||||
|
||||
int cmd__chmtime(int argc, const char **argv);
|
||||
int cmd__config(int argc, const char **argv);
|
||||
int cmd__ctype(int argc, const char **argv);
|
||||
int cmd__date(int argc, const char **argv);
|
||||
int cmd__delta(int argc, const char **argv);
|
||||
int cmd__dir_iterator(int argc, const char **argv);
|
||||
int cmd__drop_caches(int argc, const char **argv);
|
||||
int cmd__dump_cache_tree(int argc, const char **argv);
|
||||
int cmd__dump_fsmonitor(int argc, const char **argv);
|
||||
int cmd__dump_split_index(int argc, const char **argv);
|
||||
int cmd__dump_untracked_cache(int argc, const char **argv);
|
||||
int cmd__example_decorate(int argc, const char **argv);
|
||||
int cmd__genrandom(int argc, const char **argv);
|
||||
int cmd__genzeros(int argc, const char **argv);
|
||||
int cmd__hashmap(int argc, const char **argv);
|
||||
int cmd__hash_speed(int argc, const char **argv);
|
||||
int cmd__index_version(int argc, const char **argv);
|
||||
int cmd__json_writer(int argc, const char **argv);
|
||||
int cmd__lazy_init_name_hash(int argc, const char **argv);
|
||||
int cmd__match_trees(int argc, const char **argv);
|
||||
int cmd__mergesort(int argc, const char **argv);
|
||||
int cmd__mktemp(int argc, const char **argv);
|
||||
int cmd__oidmap(int argc, const char **argv);
|
||||
int cmd__online_cpus(int argc, const char **argv);
|
||||
int cmd__parse_options(int argc, const char **argv);
|
||||
int cmd__path_utils(int argc, const char **argv);
|
||||
int cmd__pkt_line(int argc, const char **argv);
|
||||
int cmd__prio_queue(int argc, const char **argv);
|
||||
int cmd__reach(int argc, const char **argv);
|
||||
int cmd__read_cache(int argc, const char **argv);
|
||||
int cmd__read_midx(int argc, const char **argv);
|
||||
int cmd__ref_store(int argc, const char **argv);
|
||||
int cmd__regex(int argc, const char **argv);
|
||||
int cmd__repository(int argc, const char **argv);
|
||||
int cmd__revision_walking(int argc, const char **argv);
|
||||
int cmd__run_command(int argc, const char **argv);
|
||||
int cmd__scrap_cache_tree(int argc, const char **argv);
|
||||
int cmd__serve_v2(int argc, const char **argv);
|
||||
int cmd__sha1(int argc, const char **argv);
|
||||
int cmd__sha1_array(int argc, const char **argv);
|
||||
int cmd__sha256(int argc, const char **argv);
|
||||
int cmd__sigchain(int argc, const char **argv);
|
||||
int cmd__strcmp_offset(int argc, const char **argv);
|
||||
int cmd__string_list(int argc, const char **argv);
|
||||
int cmd__submodule_config(int argc, const char **argv);
|
||||
int cmd__submodule_nested_repo_config(int argc, const char **argv);
|
||||
int cmd__subprocess(int argc, const char **argv);
|
||||
int cmd__trace2(int argc, const char **argv);
|
||||
int cmd__urlmatch_normalization(int argc, const char **argv);
|
||||
int cmd__xml_encode(int argc, const char **argv);
|
||||
int cmd__wildmatch(int argc, const char **argv);
|
||||
#ifdef GIT_WINDOWS_NATIVE
|
||||
int cmd__windows_named_pipe(int argc, const char **argv);
|
||||
#endif
|
||||
int cmd__write_cache(int argc, const char **argv);
|
||||
|
||||
int cmd_hash_impl(int ac, const char **av, int algo);
|
||||
|
||||
#endif
|
||||
273
third_party/git/t/helper/test-trace2.c
vendored
Normal file
273
third_party/git/t/helper/test-trace2.c
vendored
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "argv-array.h"
|
||||
#include "run-command.h"
|
||||
#include "exec-cmd.h"
|
||||
#include "config.h"
|
||||
|
||||
typedef int(fn_unit_test)(int argc, const char **argv);
|
||||
|
||||
struct unit_test {
|
||||
fn_unit_test *ut_fn;
|
||||
const char *ut_name;
|
||||
const char *ut_usage;
|
||||
};
|
||||
|
||||
#define MyOk 0
|
||||
#define MyError 1
|
||||
|
||||
static int get_i(int *p_value, const char *data)
|
||||
{
|
||||
char *endptr;
|
||||
|
||||
if (!data || !*data)
|
||||
return MyError;
|
||||
|
||||
*p_value = strtol(data, &endptr, 10);
|
||||
if (*endptr || errno == ERANGE)
|
||||
return MyError;
|
||||
|
||||
return MyOk;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cause process to exit with the requested value via "return".
|
||||
*
|
||||
* Rely on test-tool.c:cmd_main() to call trace2_cmd_exit()
|
||||
* with our result.
|
||||
*
|
||||
* Test harness can confirm:
|
||||
* [] the process-exit value.
|
||||
* [] the "code" field in the "exit" trace2 event.
|
||||
* [] the "code" field in the "atexit" trace2 event.
|
||||
* [] the "name" field in the "cmd_name" trace2 event.
|
||||
* [] "def_param" events for all of the "interesting" pre-defined
|
||||
* config settings.
|
||||
*/
|
||||
static int ut_001return(int argc, const char **argv)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (get_i(&rc, argv[0]))
|
||||
die("expect <exit_code>");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cause the process to exit with the requested value via "exit()".
|
||||
*
|
||||
* Test harness can confirm:
|
||||
* [] the "code" field in the "exit" trace2 event.
|
||||
* [] the "code" field in the "atexit" trace2 event.
|
||||
* [] the "name" field in the "cmd_name" trace2 event.
|
||||
* [] "def_param" events for all of the "interesting" pre-defined
|
||||
* config settings.
|
||||
*/
|
||||
static int ut_002exit(int argc, const char **argv)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (get_i(&rc, argv[0]))
|
||||
die("expect <exit_code>");
|
||||
|
||||
exit(rc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send an "error" event with each value in argv. Normally, git only issues
|
||||
* a single "error" event immediately before issuing an "exit" event (such
|
||||
* as in die() or BUG()), but multiple "error" events are allowed.
|
||||
*
|
||||
* Test harness can confirm:
|
||||
* [] a trace2 "error" event for each value in argv.
|
||||
* [] the "name" field in the "cmd_name" trace2 event.
|
||||
* [] (optional) the file:line in the "exit" event refers to this function.
|
||||
*/
|
||||
static int ut_003error(int argc, const char **argv)
|
||||
{
|
||||
int k;
|
||||
|
||||
if (!argv[0] || !*argv[0])
|
||||
die("expect <error_message>");
|
||||
|
||||
for (k = 0; k < argc; k++)
|
||||
error("%s", argv[k]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run a child process and wait for it to finish and exit with its return code.
|
||||
* test-tool trace2 004child [<child-command-line>]
|
||||
*
|
||||
* For example:
|
||||
* test-tool trace2 004child git version
|
||||
* test-tool trace2 004child test-tool trace2 001return 0
|
||||
* test-tool trace2 004child test-tool trace2 004child test-tool trace2 004child
|
||||
* test-tool trace2 004child git -c alias.xyz=version xyz
|
||||
*
|
||||
* Test harness can confirm:
|
||||
* [] the "name" field in the "cmd_name" trace2 event.
|
||||
* [] that the outer process has a single component SID (or depth "d0" in
|
||||
* the PERF stream).
|
||||
* [] that "child_start" and "child_exit" events are generated for the child.
|
||||
* [] if the child process is an instrumented executable:
|
||||
* [] that "version", "start", ..., "exit", and "atexit" events are
|
||||
* generated by the child process.
|
||||
* [] that the child process events have a multiple component SID (or
|
||||
* depth "dN+1" in the PERF stream).
|
||||
* [] that the child exit code is propagated to the parent process "exit"
|
||||
* and "atexit" events..
|
||||
* [] (optional) that the "t_abs" field in the child process "atexit" event
|
||||
* is less than the "t_rel" field in the "child_exit" event of the parent
|
||||
* process.
|
||||
* [] if the child process is like the alias example above,
|
||||
* [] (optional) the child process attempts to run "git-xyx" as a dashed
|
||||
* command.
|
||||
* [] the child process emits an "alias" event with "xyz" => "version"
|
||||
* [] the child process runs "git version" as a child process.
|
||||
* [] the child process has a 3 component SID (or depth "d2" in the PERF
|
||||
* stream).
|
||||
*/
|
||||
static int ut_004child(int argc, const char **argv)
|
||||
{
|
||||
int result;
|
||||
|
||||
/*
|
||||
* Allow empty <child_command_line> so we can do arbitrarily deep
|
||||
* command nesting and let the last one be null.
|
||||
*/
|
||||
if (!argc)
|
||||
return 0;
|
||||
|
||||
result = run_command_v_opt(argv, 0);
|
||||
exit(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Exec a git command. This may either create a child process (Windows)
|
||||
* or replace the existing process.
|
||||
* test-tool trace2 005exec <git_command_args>
|
||||
*
|
||||
* For example:
|
||||
* test-tool trace2 005exec version
|
||||
*
|
||||
* Test harness can confirm (on Windows):
|
||||
* [] the "name" field in the "cmd_name" trace2 event.
|
||||
* [] that the outer process has a single component SID (or depth "d0" in
|
||||
* the PERF stream).
|
||||
* [] that "exec" and "exec_result" events are generated for the child
|
||||
* process (since the Windows compatibility layer fakes an exec() with
|
||||
* a CreateProcess(), WaitForSingleObject(), and exit()).
|
||||
* [] that the child process has multiple component SID (or depth "dN+1"
|
||||
* in the PERF stream).
|
||||
*
|
||||
* Test harness can confirm (on platforms with a real exec() function):
|
||||
* [] TODO talk about process replacement and how it affects SID.
|
||||
*/
|
||||
static int ut_005exec(int argc, const char **argv)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (!argc)
|
||||
return 0;
|
||||
|
||||
result = execv_git_cmd(argv);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int ut_006data(int argc, const char **argv)
|
||||
{
|
||||
const char *usage_error =
|
||||
"expect <cat0> <k0> <v0> [<cat1> <k1> <v1> [...]]";
|
||||
|
||||
if (argc % 3 != 0)
|
||||
die("%s", usage_error);
|
||||
|
||||
while (argc) {
|
||||
if (!argv[0] || !*argv[0] || !argv[1] || !*argv[1] ||
|
||||
!argv[2] || !*argv[2])
|
||||
die("%s", usage_error);
|
||||
|
||||
trace2_data_string(argv[0], the_repository, argv[1], argv[2]);
|
||||
argv += 3;
|
||||
argc -= 3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Usage:
|
||||
* test-tool trace2 <ut_name_1> <ut_usage_1>
|
||||
* test-tool trace2 <ut_name_2> <ut_usage_2>
|
||||
* ...
|
||||
*/
|
||||
#define USAGE_PREFIX "test-tool trace2"
|
||||
|
||||
/* clang-format off */
|
||||
static struct unit_test ut_table[] = {
|
||||
{ ut_001return, "001return", "<exit_code>" },
|
||||
{ ut_002exit, "002exit", "<exit_code>" },
|
||||
{ ut_003error, "003error", "<error_message>+" },
|
||||
{ ut_004child, "004child", "[<child_command_line>]" },
|
||||
{ ut_005exec, "005exec", "<git_command_args>" },
|
||||
{ ut_006data, "006data", "[<category> <key> <value>]+" },
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
/* clang-format off */
|
||||
#define for_each_ut(k, ut_k) \
|
||||
for (k = 0, ut_k = &ut_table[k]; \
|
||||
k < ARRAY_SIZE(ut_table); \
|
||||
k++, ut_k = &ut_table[k])
|
||||
/* clang-format on */
|
||||
|
||||
static int print_usage(void)
|
||||
{
|
||||
int k;
|
||||
struct unit_test *ut_k;
|
||||
|
||||
fprintf(stderr, "usage:\n");
|
||||
for_each_ut (k, ut_k)
|
||||
fprintf(stderr, "\t%s %s %s\n", USAGE_PREFIX, ut_k->ut_name,
|
||||
ut_k->ut_usage);
|
||||
|
||||
return 129;
|
||||
}
|
||||
|
||||
/*
|
||||
* Issue various trace2 events for testing.
|
||||
*
|
||||
* We assume that these trace2 routines has already been called:
|
||||
* [] trace2_initialize() [common-main.c:main()]
|
||||
* [] trace2_cmd_start() [common-main.c:main()]
|
||||
* [] trace2_cmd_name() [test-tool.c:cmd_main()]
|
||||
* [] tracd2_cmd_list_config() [test-tool.c:cmd_main()]
|
||||
* So that:
|
||||
* [] the various trace2 streams are open.
|
||||
* [] the process SID has been created.
|
||||
* [] the "version" event has been generated.
|
||||
* [] the "start" event has been generated.
|
||||
* [] the "cmd_name" event has been generated.
|
||||
* [] this writes various "def_param" events for interesting config values.
|
||||
*
|
||||
* We further assume that if we return (rather than exit()), trace2_cmd_exit()
|
||||
* will be called by test-tool.c:cmd_main().
|
||||
*/
|
||||
int cmd__trace2(int argc, const char **argv)
|
||||
{
|
||||
int k;
|
||||
struct unit_test *ut_k;
|
||||
|
||||
argc--; /* skip over "trace2" arg */
|
||||
argv++;
|
||||
|
||||
if (argc)
|
||||
for_each_ut (k, ut_k)
|
||||
if (!strcmp(argv[0], ut_k->ut_name))
|
||||
return ut_k->ut_fn(argc - 1, argv + 1);
|
||||
|
||||
return print_usage();
|
||||
}
|
||||
51
third_party/git/t/helper/test-urlmatch-normalization.c
vendored
Normal file
51
third_party/git/t/helper/test-urlmatch-normalization.c
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#include "test-tool.h"
|
||||
#include "git-compat-util.h"
|
||||
#include "urlmatch.h"
|
||||
|
||||
int cmd__urlmatch_normalization(int argc, const char **argv)
|
||||
{
|
||||
const char usage[] = "test-tool urlmatch-normalization [-p | -l] <url1> | <url1> <url2>";
|
||||
char *url1, *url2;
|
||||
int opt_p = 0, opt_l = 0;
|
||||
|
||||
/*
|
||||
* For one url, succeed if url_normalize succeeds on it, fail otherwise.
|
||||
* For two urls, succeed only if url_normalize succeeds on both and
|
||||
* the results compare equal with strcmp. If -p is given (one url only)
|
||||
* and url_normalize succeeds, print the result followed by "\n". If
|
||||
* -l is given (one url only) and url_normalize succeeds, print the
|
||||
* returned length in decimal followed by "\n".
|
||||
*/
|
||||
|
||||
if (argc > 1 && !strcmp(argv[1], "-p")) {
|
||||
opt_p = 1;
|
||||
argc--;
|
||||
argv++;
|
||||
} else if (argc > 1 && !strcmp(argv[1], "-l")) {
|
||||
opt_l = 1;
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (argc < 2 || argc > 3)
|
||||
die("%s", usage);
|
||||
|
||||
if (argc == 2) {
|
||||
struct url_info info;
|
||||
url1 = url_normalize(argv[1], &info);
|
||||
if (!url1)
|
||||
return 1;
|
||||
if (opt_p)
|
||||
printf("%s\n", url1);
|
||||
if (opt_l)
|
||||
printf("%u\n", (unsigned)info.url_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (opt_p || opt_l)
|
||||
die("%s", usage);
|
||||
|
||||
url1 = url_normalize(argv[1], NULL);
|
||||
url2 = url_normalize(argv[2], NULL);
|
||||
return (url1 && url2 && !strcmp(url1, url2)) ? 0 : 1;
|
||||
}
|
||||
24
third_party/git/t/helper/test-wildmatch.c
vendored
Normal file
24
third_party/git/t/helper/test-wildmatch.c
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
|
||||
int cmd__wildmatch(int argc, const char **argv)
|
||||
{
|
||||
int i;
|
||||
for (i = 2; i < argc; i++) {
|
||||
if (argv[i][0] == '/')
|
||||
die("Forward slash is not allowed at the beginning of the\n"
|
||||
"pattern because Windows does not like it. Use `XXX/' instead.");
|
||||
else if (!strncmp(argv[i], "XXX/", 4))
|
||||
argv[i] += 3;
|
||||
}
|
||||
if (!strcmp(argv[1], "wildmatch"))
|
||||
return !!wildmatch(argv[3], argv[2], WM_PATHNAME);
|
||||
else if (!strcmp(argv[1], "iwildmatch"))
|
||||
return !!wildmatch(argv[3], argv[2], WM_PATHNAME | WM_CASEFOLD);
|
||||
else if (!strcmp(argv[1], "pathmatch"))
|
||||
return !!wildmatch(argv[3], argv[2], 0);
|
||||
else if (!strcmp(argv[1], "ipathmatch"))
|
||||
return !!wildmatch(argv[3], argv[2], WM_CASEFOLD);
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
72
third_party/git/t/helper/test-windows-named-pipe.c
vendored
Normal file
72
third_party/git/t/helper/test-windows-named-pipe.c
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
#include "test-tool.h"
|
||||
#include "git-compat-util.h"
|
||||
#include "strbuf.h"
|
||||
|
||||
#ifdef GIT_WINDOWS_NATIVE
|
||||
static const char *usage_string = "<pipe-filename>";
|
||||
|
||||
#define TEST_BUFSIZE (4096)
|
||||
|
||||
int cmd__windows_named_pipe(int argc, const char **argv)
|
||||
{
|
||||
const char *filename;
|
||||
struct strbuf pathname = STRBUF_INIT;
|
||||
int err;
|
||||
HANDLE h;
|
||||
BOOL connected;
|
||||
char buf[TEST_BUFSIZE + 1];
|
||||
|
||||
if (argc < 2)
|
||||
goto print_usage;
|
||||
filename = argv[1];
|
||||
if (strchr(filename, '/') || strchr(filename, '\\'))
|
||||
goto print_usage;
|
||||
strbuf_addf(&pathname, "//./pipe/%s", filename);
|
||||
|
||||
/*
|
||||
* Create a single instance of the server side of the named pipe.
|
||||
* This will allow exactly one client instance to connect to it.
|
||||
*/
|
||||
h = CreateNamedPipeA(
|
||||
pathname.buf,
|
||||
PIPE_ACCESS_INBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE,
|
||||
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
|
||||
PIPE_UNLIMITED_INSTANCES,
|
||||
TEST_BUFSIZE, TEST_BUFSIZE, 0, NULL);
|
||||
if (h == INVALID_HANDLE_VALUE) {
|
||||
err = err_win_to_posix(GetLastError());
|
||||
fprintf(stderr, "CreateNamedPipe failed: %s\n",
|
||||
strerror(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
connected = ConnectNamedPipe(h, NULL)
|
||||
? TRUE
|
||||
: (GetLastError() == ERROR_PIPE_CONNECTED);
|
||||
if (!connected) {
|
||||
err = err_win_to_posix(GetLastError());
|
||||
fprintf(stderr, "ConnectNamedPipe failed: %s\n",
|
||||
strerror(err));
|
||||
CloseHandle(h);
|
||||
return err;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
DWORD nbr;
|
||||
BOOL success = ReadFile(h, buf, TEST_BUFSIZE, &nbr, NULL);
|
||||
if (!success || nbr == 0)
|
||||
break;
|
||||
buf[nbr] = 0;
|
||||
|
||||
write(1, buf, nbr);
|
||||
}
|
||||
|
||||
DisconnectNamedPipe(h);
|
||||
CloseHandle(h);
|
||||
return 0;
|
||||
|
||||
print_usage:
|
||||
fprintf(stderr, "usage: %s %s\n", argv[0], usage_string);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
20
third_party/git/t/helper/test-write-cache.c
vendored
Normal file
20
third_party/git/t/helper/test-write-cache.c
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "lockfile.h"
|
||||
|
||||
int cmd__write_cache(int argc, const char **argv)
|
||||
{
|
||||
struct lock_file index_lock = LOCK_INIT;
|
||||
int i, cnt = 1;
|
||||
if (argc == 2)
|
||||
cnt = strtol(argv[1], NULL, 0);
|
||||
setup_git_directory();
|
||||
read_cache();
|
||||
for (i = 0; i < cnt; i++) {
|
||||
hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR);
|
||||
if (write_locked_index(&the_index, &index_lock, COMMIT_LOCK))
|
||||
die("unable to write index file");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
80
third_party/git/t/helper/test-xml-encode.c
vendored
Normal file
80
third_party/git/t/helper/test-xml-encode.c
vendored
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
#include "test-tool.h"
|
||||
|
||||
static const char *utf8_replace_character = "�";
|
||||
|
||||
/*
|
||||
* Encodes (possibly incorrect) UTF-8 on <stdin> to <stdout>, to be embedded
|
||||
* in an XML file.
|
||||
*/
|
||||
int cmd__xml_encode(int argc, const char **argv)
|
||||
{
|
||||
unsigned char buf[1024], tmp[4], *tmp2 = NULL;
|
||||
ssize_t cur = 0, len = 1, remaining = 0;
|
||||
unsigned char ch;
|
||||
|
||||
for (;;) {
|
||||
if (++cur == len) {
|
||||
len = xread(0, buf, sizeof(buf));
|
||||
if (!len)
|
||||
return 0;
|
||||
if (len < 0)
|
||||
die_errno("Could not read <stdin>");
|
||||
cur = 0;
|
||||
}
|
||||
ch = buf[cur];
|
||||
|
||||
if (tmp2) {
|
||||
if ((ch & 0xc0) != 0x80) {
|
||||
fputs(utf8_replace_character, stdout);
|
||||
tmp2 = NULL;
|
||||
cur--;
|
||||
continue;
|
||||
}
|
||||
*tmp2 = ch;
|
||||
tmp2++;
|
||||
if (--remaining == 0) {
|
||||
fwrite(tmp, tmp2 - tmp, 1, stdout);
|
||||
tmp2 = NULL;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(ch & 0x80)) {
|
||||
/* 0xxxxxxx */
|
||||
if (ch == '&')
|
||||
fputs("&", stdout);
|
||||
else if (ch == '\'')
|
||||
fputs("'", stdout);
|
||||
else if (ch == '"')
|
||||
fputs(""", stdout);
|
||||
else if (ch == '<')
|
||||
fputs("<", stdout);
|
||||
else if (ch == '>')
|
||||
fputs(">", stdout);
|
||||
else if (ch >= 0x20)
|
||||
fputc(ch, stdout);
|
||||
else if (ch == 0x09 || ch == 0x0a || ch == 0x0d)
|
||||
fprintf(stdout, "&#x%02x;", ch);
|
||||
else
|
||||
fputs(utf8_replace_character, stdout);
|
||||
} else if ((ch & 0xe0) == 0xc0) {
|
||||
/* 110XXXXx 10xxxxxx */
|
||||
tmp[0] = ch;
|
||||
remaining = 1;
|
||||
tmp2 = tmp + 1;
|
||||
} else if ((ch & 0xf0) == 0xe0) {
|
||||
/* 1110XXXX 10Xxxxxx 10xxxxxx */
|
||||
tmp[0] = ch;
|
||||
remaining = 2;
|
||||
tmp2 = tmp + 1;
|
||||
} else if ((ch & 0xf8) == 0xf0) {
|
||||
/* 11110XXX 10XXxxxx 10xxxxxx 10xxxxxx */
|
||||
tmp[0] = ch;
|
||||
remaining = 3;
|
||||
tmp2 = tmp + 1;
|
||||
} else
|
||||
fputs(utf8_replace_character, stdout);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue