summaryrefslogtreecommitdiff
path: root/t/helper
diff options
context:
space:
mode:
Diffstat (limited to 't/helper')
-rw-r--r--t/helper/.gitignore42
-rw-r--r--t/helper/test-chmtime.c59
-rw-r--r--t/helper/test-config.c6
-rw-r--r--t/helper/test-ctype.c3
-rw-r--r--t/helper/test-date.c27
-rw-r--r--t/helper/test-delta.c7
-rw-r--r--t/helper/test-drop-caches.c157
-rw-r--r--t/helper/test-dump-cache-tree.c3
-rw-r--r--t/helper/test-dump-fsmonitor.c21
-rw-r--r--t/helper/test-dump-split-index.c7
-rw-r--r--t/helper/test-dump-untracked-cache.c6
-rw-r--r--t/helper/test-example-decorate.c75
-rw-r--r--t/helper/test-genrandom.c3
-rw-r--r--t/helper/test-hashmap.c90
-rw-r--r--t/helper/test-index-version.c3
-rw-r--r--t/helper/test-json-writer.c565
-rw-r--r--t/helper/test-lazy-init-name-hash.c15
-rw-r--r--t/helper/test-line-buffer.c32
-rw-r--r--t/helper/test-match-trees.c3
-rw-r--r--t/helper/test-mergesort.c3
-rw-r--r--t/helper/test-mktemp.c3
-rw-r--r--t/helper/test-online-cpus.c3
-rw-r--r--t/helper/test-parse-options.c2
-rw-r--r--t/helper/test-path-utils.c41
-rw-r--r--t/helper/test-pkt-line.c97
-rw-r--r--t/helper/test-prio-queue.c3
-rw-r--r--t/helper/test-read-cache.c3
-rw-r--r--t/helper/test-ref-store.c35
-rw-r--r--t/helper/test-regex.c7
-rw-r--r--t/helper/test-repository.c82
-rw-r--r--t/helper/test-revision-walking.c3
-rw-r--r--t/helper/test-run-command.c12
-rw-r--r--t/helper/test-scrap-cache-tree.c7
-rw-r--r--t/helper/test-sha1-array.c3
-rw-r--r--t/helper/test-sha1.c3
-rwxr-xr-xt/helper/test-sha1.sh4
-rw-r--r--t/helper/test-sigchain.c3
-rw-r--r--t/helper/test-strcmp-offset.c5
-rw-r--r--t/helper/test-string-list.c5
-rw-r--r--t/helper/test-submodule-config.c25
-rw-r--r--t/helper/test-subprocess.c3
-rw-r--r--t/helper/test-tool.c65
-rw-r--r--t/helper/test-tool.h42
-rw-r--r--t/helper/test-urlmatch-normalization.c5
-rw-r--r--t/helper/test-wildmatch.c11
-rw-r--r--t/helper/test-write-cache.c20
46 files changed, 1412 insertions, 207 deletions
diff --git a/t/helper/.gitignore b/t/helper/.gitignore
index 721650256e..2bad28af92 100644
--- a/t/helper/.gitignore
+++ b/t/helper/.gitignore
@@ -1,37 +1,5 @@
-/test-chmtime
-/test-ctype
-/test-config
-/test-date
-/test-delta
-/test-dump-cache-tree
-/test-dump-split-index
-/test-dump-untracked-cache
-/test-fake-ssh
-/test-scrap-cache-tree
-/test-genrandom
-/test-hashmap
-/test-index-version
-/test-lazy-init-name-hash
-/test-line-buffer
-/test-match-trees
-/test-mergesort
-/test-mktemp
-/test-online-cpus
-/test-parse-options
-/test-path-utils
-/test-prio-queue
-/test-read-cache
-/test-ref-store
-/test-regex
-/test-revision-walking
-/test-run-command
-/test-sha1
-/test-sha1-array
-/test-sigchain
-/test-strcmp-offset
-/test-string-list
-/test-submodule-config
-/test-subprocess
-/test-svn-fe
-/test-urlmatch-normalization
-/test-wildmatch
+*
+!*.sh
+!*.[ch]
+!*.gitignore
+
diff --git a/t/helper/test-chmtime.c b/t/helper/test-chmtime.c
index e760256406..aa22af48c2 100644
--- a/t/helper/test-chmtime.c
+++ b/t/helper/test-chmtime.c
@@ -5,32 +5,43 @@
*
* The mtime can be changed to an absolute value:
*
- * test-chmtime =<seconds> file...
+ * test-tool chmtime =<seconds> file...
*
* Relative to the current time as returned by time(3):
*
- * test-chmtime =+<seconds> (or =-<seconds>) file...
+ * test-tool chmtime =+<seconds> (or =-<seconds>) file...
*
* Or relative to the current mtime of the file:
*
- * test-chmtime <seconds> file...
- * test-chmtime +<seconds> (or -<seconds>) file...
+ * test-tool chmtime <seconds> file...
+ * test-tool chmtime +<seconds> (or -<seconds>) file...
*
* Examples:
*
- * To just print the mtime use --verbose and set the file mtime offset to 0:
+ * To print the mtime and the file name use --verbose and set
+ * the file mtime offset to 0:
*
- * test-chmtime -v +0 file
+ * 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-chmtime =+0 file
+ * 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 (+|=|=+|=-|-)<seconds> <file>...";
+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)
{
@@ -46,7 +57,6 @@ static int timespec_arg(const char *arg, long int *set_time, int *set_eq)
}
*set_time = strtol(timespec, &test, 10);
if (*test) {
- fprintf(stderr, "Not a base-10 integer: %s\n", arg + 1);
return 0;
}
if ((*set_eq && *set_time < 0) || *set_eq == 2) {
@@ -56,9 +66,10 @@ static int timespec_arg(const char *arg, long int *set_time, int *set_eq)
return 1;
}
-int cmd_main(int argc, const char **argv)
+int cmd__chmtime(int argc, const char **argv)
{
static int verbose;
+ static int get;
int i = 1;
/* no mtime change by default */
@@ -68,18 +79,34 @@ int cmd_main(int argc, const char **argv)
if (argc < 3)
goto usage;
- if (strcmp(argv[i], "--verbose") == 0 || strcmp(argv[i], "-v") == 0) {
+ 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 (timespec_arg(argv[i], &set_time, &set_eq))
+
+ if (i == argc) {
+ goto usage;
+ }
+
+ if (timespec_arg(argv[i], &set_time, &set_eq)) {
++i;
- else
+ } 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",
@@ -99,8 +126,10 @@ int cmd_main(int argc, const char **argv)
utb.actime = sb.st_atime;
utb.modtime = set_eq ? set_time : sb.st_mtime + set_time;
- if (verbose) {
- uintmax_t mtime = utb.modtime < 0 ? 0: utb.modtime;
+ mtime = utb.modtime < 0 ? 0: utb.modtime;
+ if (get) {
+ printf("%"PRIuMAX"\n", mtime);
+ } else if (verbose) {
printf("%"PRIuMAX"\t%s\n", mtime, argv[i]);
}
diff --git a/t/helper/test-config.c b/t/helper/test-config.c
index 8e3ed6a76c..214003d5b2 100644
--- a/t/helper/test-config.c
+++ b/t/helper/test-config.c
@@ -1,4 +1,6 @@
+#include "test-tool.h"
#include "cache.h"
+#include "config.h"
#include "string-list.h"
/*
@@ -31,7 +33,7 @@
* Examples:
*
* To print the value with highest priority for key "foo.bAr Baz.rock":
- * test-config get_value "foo.bAr Baz.rock"
+ * test-tool config get_value "foo.bAr Baz.rock"
*
*/
@@ -76,7 +78,7 @@ static int early_config_cb(const char *var, const char *value, void *vdata)
return 0;
}
-int cmd_main(int argc, const char **argv)
+int cmd__config(int argc, const char **argv)
{
int i, val;
const char *v;
diff --git a/t/helper/test-ctype.c b/t/helper/test-ctype.c
index bb72c47df5..92c4c2313e 100644
--- a/t/helper/test-ctype.c
+++ b/t/helper/test-ctype.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
#include "cache.h"
static int rc;
@@ -28,7 +29,7 @@ static int is_in(const char *s, int ch)
#define LOWER "abcdefghijklmnopqrstuvwxyz"
#define UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-int cmd_main(int argc, const char **argv)
+int cmd__ctype(int argc, const char **argv)
{
TEST_CLASS(isdigit, DIGIT);
TEST_CLASS(isspace, " \n\r\t");
diff --git a/t/helper/test-date.c b/t/helper/test-date.c
index f414a3ac67..a0837371ab 100644
--- a/t/helper/test-date.c
+++ b/t/helper/test-date.c
@@ -1,12 +1,14 @@
+#include "test-tool.h"
#include "cache.h"
static const char *usage_msg = "\n"
-" test-date relative [time_t]...\n"
-" test-date show:<format> [time_t]...\n"
-" test-date parse [date]...\n"
-" test-date approxidate [date]...\n"
-" test-date is64bit\n"
-" test-date time_t-is64bit\n";
+" test-tool date relative [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 is64bit\n"
+" test-tool date time_t-is64bit\n";
static void show_relative_dates(const char **argv, struct timeval *now)
{
@@ -71,7 +73,16 @@ static void parse_approxidate(const char **argv, struct timeval *now)
}
}
-int cmd_main(int argc, const char **argv)
+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);
+ }
+}
+
+int cmd__date(int argc, const char **argv)
{
struct timeval now;
const char *x;
@@ -95,6 +106,8 @@ int cmd_main(int argc, const char **argv)
parse_dates(argv+1, &now);
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, "is64bit"))
return sizeof(timestamp_t) == 8 ? 0 : 1;
else if (!strcmp(*argv, "time_t-is64bit"))
diff --git a/t/helper/test-delta.c b/t/helper/test-delta.c
index 59937dc1be..34c7259248 100644
--- a/t/helper/test-delta.c
+++ b/t/helper/test-delta.c
@@ -8,14 +8,15 @@
* 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-delta (-d|-p) <from_file> <data_file> <out_file>";
+ "test-tool delta (-d|-p) <from_file> <data_file> <out_file>";
-int cmd_main(int argc, const char **argv)
+int cmd__delta(int argc, const char **argv)
{
int fd;
struct stat st;
@@ -69,7 +70,7 @@ int cmd_main(int argc, const char **argv)
}
fd = open (argv[4], O_WRONLY|O_CREAT|O_TRUNC, 0666);
- if (fd < 0 || write_in_full(fd, out_buf, out_size) != out_size) {
+ if (fd < 0 || write_in_full(fd, out_buf, out_size) < 0) {
perror(argv[4]);
return 1;
}
diff --git a/t/helper/test-drop-caches.c b/t/helper/test-drop-caches.c
new file mode 100644
index 0000000000..f65e301f9d
--- /dev/null
+++ b/t/helper/test-drop-caches.c
@@ -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();
+}
diff --git a/t/helper/test-dump-cache-tree.c b/t/helper/test-dump-cache-tree.c
index ebf3aab22d..98a4891f1d 100644
--- a/t/helper/test-dump-cache-tree.c
+++ b/t/helper/test-dump-cache-tree.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
#include "cache.h"
#include "tree.h"
#include "cache-tree.h"
@@ -54,7 +55,7 @@ static int dump_cache_tree(struct cache_tree *it,
return errs;
}
-int cmd_main(int ac, const char **av)
+int cmd__dump_cache_tree(int ac, const char **av)
{
struct index_state istate;
struct cache_tree *another = cache_tree();
diff --git a/t/helper/test-dump-fsmonitor.c b/t/helper/test-dump-fsmonitor.c
new file mode 100644
index 0000000000..ad452707e8
--- /dev/null
+++ b/t/helper/test-dump-fsmonitor.c
@@ -0,0 +1,21 @@
+#include "cache.h"
+
+int cmd_main(int ac, const char **av)
+{
+ struct index_state *istate = &the_index;
+ int i;
+
+ setup_git_directory();
+ if (do_read_index(istate, get_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;
+}
diff --git a/t/helper/test-dump-split-index.c b/t/helper/test-dump-split-index.c
index e44430b699..63c689d6ee 100644
--- a/t/helper/test-dump-split-index.c
+++ b/t/helper/test-dump-split-index.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
#include "cache.h"
#include "split-index.h"
#include "ewah/ewok.h"
@@ -7,19 +8,19 @@ static void show_bit(size_t pos, void *data)
printf(" %d", (int)pos);
}
-int cmd_main(int ac, const char **av)
+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", sha1_to_hex(the_index.sha1));
+ 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", sha1_to_hex(si->base_sha1));
+ 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,
diff --git a/t/helper/test-dump-untracked-cache.c b/t/helper/test-dump-untracked-cache.c
index f752532ffb..bd92fb305a 100644
--- a/t/helper/test-dump-untracked-cache.c
+++ b/t/helper/test-dump-untracked-cache.c
@@ -23,7 +23,7 @@ static void dump(struct untracked_cache_dir *ucd, struct strbuf *base)
len = base->len;
strbuf_addf(base, "%s/", ucd->name);
printf("%s %s", base->buf,
- sha1_to_hex(ucd->exclude_sha1));
+ oid_to_hex(&ucd->exclude_oid));
if (ucd->recurse)
fputs(" recurse", stdout);
if (ucd->check_only)
@@ -54,8 +54,8 @@ int cmd_main(int ac, const char **av)
printf("no untracked cache\n");
return 0;
}
- printf("info/exclude %s\n", sha1_to_hex(uc->ss_info_exclude.sha1));
- printf("core.excludesfile %s\n", sha1_to_hex(uc->ss_excludes_file.sha1));
+ 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)
diff --git a/t/helper/test-example-decorate.c b/t/helper/test-example-decorate.c
new file mode 100644
index 0000000000..a20a6161e4
--- /dev/null
+++ b/t/helper/test-example-decorate.c
@@ -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.hash);
+ two = lookup_unknown_object(two_oid.hash);
+ 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.hash);
+ 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;
+}
diff --git a/t/helper/test-genrandom.c b/t/helper/test-genrandom.c
index 8d11d22d98..99b8dc1e2d 100644
--- a/t/helper/test-genrandom.c
+++ b/t/helper/test-genrandom.c
@@ -4,9 +4,10 @@
* Copyright (C) 2007 by Nicolas Pitre, licensed under the GPL version 2.
*/
+#include "test-tool.h"
#include "git-compat-util.h"
-int cmd_main(int argc, const char **argv)
+int cmd__genrandom(int argc, const char **argv)
{
unsigned long count, next = 0;
unsigned char *c;
diff --git a/t/helper/test-hashmap.c b/t/helper/test-hashmap.c
index 7aa9440e27..23d2b172fe 100644
--- a/t/helper/test-hashmap.c
+++ b/t/helper/test-hashmap.c
@@ -1,5 +1,7 @@
+#include "test-tool.h"
#include "git-compat-util.h"
#include "hashmap.h"
+#include "strbuf.h"
struct test_entry
{
@@ -13,23 +15,28 @@ static const char *get_value(const struct test_entry *e)
return e->key + strlen(e->key) + 1;
}
-static int test_entry_cmp(const struct test_entry *e1,
- const struct test_entry *e2, const char* key)
+static int test_entry_cmp(const void *cmp_data,
+ const void *entry,
+ const void *entry_or_key,
+ const void *keydata)
{
- return strcmp(e1->key, key ? key : e2->key);
+ 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 int test_entry_cmp_icase(const struct test_entry *e1,
- const struct test_entry *e2, const char* key)
+static struct test_entry *alloc_test_entry(unsigned int hash,
+ char *key, char *value)
{
- return strcasecmp(e1->key, key ? key : e2->key);
-}
-
-static struct test_entry *alloc_test_entry(int hash, char *key, int klen,
- char *value, int vlen)
-{
- struct test_entry *entry = malloc(sizeof(struct test_entry) + klen
- + vlen + 2);
+ 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);
@@ -71,7 +78,7 @@ static unsigned int hash(unsigned int method, unsigned int i, const char *key)
/*
* Test performance of hashmap.[ch]
- * Usage: time echo "perfhashmap method rounds" | test-hashmap
+ * Usage: time echo "perfhashmap method rounds" | test-tool hashmap
*/
static void perf_hashmap(unsigned int method, unsigned int rounds)
{
@@ -81,18 +88,18 @@ static void perf_hashmap(unsigned int method, unsigned int rounds)
unsigned int *hashes;
unsigned int i, j;
- entries = malloc(TEST_SIZE * sizeof(struct test_entry *));
- hashes = malloc(TEST_SIZE * sizeof(int));
+ ALLOC_ARRAY(entries, TEST_SIZE);
+ ALLOC_ARRAY(hashes, TEST_SIZE);
for (i = 0; i < TEST_SIZE; i++) {
- snprintf(buf, sizeof(buf), "%i", i);
- entries[i] = alloc_test_entry(0, buf, strlen(buf), "", 0);
+ 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, (hashmap_cmp_fn) test_entry_cmp, 0);
+ hashmap_init(&map, test_entry_cmp, NULL, 0);
/* add entries */
for (i = 0; i < TEST_SIZE; i++) {
@@ -104,7 +111,7 @@ static void perf_hashmap(unsigned int method, unsigned int rounds)
}
} else {
/* test map lookups */
- hashmap_init(&map, (hashmap_cmp_fn) test_entry_cmp, 0);
+ hashmap_init(&map, test_entry_cmp, NULL, 0);
/* fill the map (sparsely if specified) */
j = (method & TEST_SPARSE) ? TEST_SIZE / 10 : TEST_SIZE;
@@ -138,56 +145,53 @@ static void perf_hashmap(unsigned int method, unsigned int rounds)
*
* perfhashmap method rounds -> test hashmap.[ch] performance
*/
-int cmd_main(int argc, const char **argv)
+int cmd__hashmap(int argc, const char **argv)
{
- char line[1024];
+ struct strbuf line = STRBUF_INIT;
struct hashmap map;
int icase;
/* init hash map */
icase = argc > 1 && !strcmp("ignorecase", argv[1]);
- hashmap_init(&map, (hashmap_cmp_fn) (icase ? test_entry_cmp_icase
- : test_entry_cmp), 0);
+ hashmap_init(&map, test_entry_cmp, &icase, 0);
/* process commands from stdin */
- while (fgets(line, sizeof(line), stdin)) {
+ while (strbuf_getline(&line, stdin) != EOF) {
char *cmd, *p1 = NULL, *p2 = NULL;
- int l1 = 0, l2 = 0, hash = 0;
+ unsigned int hash = 0;
struct test_entry *entry;
/* break line into command and up to two parameters */
- cmd = strtok(line, DELIM);
+ cmd = strtok(line.buf, DELIM);
/* ignore empty lines */
if (!cmd || *cmd == '#')
continue;
p1 = strtok(NULL, DELIM);
if (p1) {
- l1 = strlen(p1);
hash = icase ? strihash(p1) : strhash(p1);
p2 = strtok(NULL, DELIM);
- if (p2)
- l2 = strlen(p2);
}
- if (!strcmp("hash", cmd) && l1) {
+ if (!strcmp("hash", cmd) && p1) {
/* print results of different hash functions */
- printf("%u %u %u %u\n", strhash(p1), memhash(p1, l1),
- strihash(p1), memihash(p1, l1));
+ printf("%u %u %u %u\n",
+ strhash(p1), memhash(p1, strlen(p1)),
+ strihash(p1), memihash(p1, strlen(p1)));
- } else if (!strcmp("add", cmd) && l1 && l2) {
+ } else if (!strcmp("add", cmd) && p1 && p2) {
/* create entry with key = p1, value = p2 */
- entry = alloc_test_entry(hash, p1, l1, p2, l2);
+ entry = alloc_test_entry(hash, p1, p2);
/* add to hashmap */
hashmap_add(&map, entry);
- } else if (!strcmp("put", cmd) && l1 && l2) {
+ } else if (!strcmp("put", cmd) && p1 && p2) {
/* create entry with key = p1, value = p2 */
- entry = alloc_test_entry(hash, p1, l1, p2, l2);
+ entry = alloc_test_entry(hash, p1, p2);
/* add / replace entry */
entry = hashmap_put(&map, entry);
@@ -196,7 +200,7 @@ int cmd_main(int argc, const char **argv)
puts(entry ? get_value(entry) : "NULL");
free(entry);
- } else if (!strcmp("get", cmd) && l1) {
+ } else if (!strcmp("get", cmd) && p1) {
/* lookup entry in hashmap */
entry = hashmap_get_from_hash(&map, hash, p1);
@@ -209,7 +213,7 @@ int cmd_main(int argc, const char **argv)
entry = hashmap_get_next(&map, entry);
}
- } else if (!strcmp("remove", cmd) && l1) {
+ } else if (!strcmp("remove", cmd) && p1) {
/* setup static key */
struct hashmap_entry key;
@@ -232,9 +236,10 @@ int cmd_main(int argc, const char **argv)
} else if (!strcmp("size", cmd)) {
/* print table sizes */
- printf("%u %u\n", map.tablesize, map.size);
+ printf("%u %u\n", map.tablesize,
+ hashmap_get_size(&map));
- } else if (!strcmp("intern", cmd) && l1) {
+ } else if (!strcmp("intern", cmd) && p1) {
/* test that strintern works */
const char *i1 = strintern(p1);
@@ -248,7 +253,7 @@ int cmd_main(int argc, const char **argv)
else
printf("%s\n", i1);
- } else if (!strcmp("perfhashmap", cmd) && l1 && l2) {
+ } else if (!strcmp("perfhashmap", cmd) && p1 && p2) {
perf_hashmap(atoi(p1), atoi(p2));
@@ -259,6 +264,7 @@ int cmd_main(int argc, const char **argv)
}
}
+ strbuf_release(&line);
hashmap_free(&map, 1);
return 0;
}
diff --git a/t/helper/test-index-version.c b/t/helper/test-index-version.c
index f569f6b7ef..fcd10968cc 100644
--- a/t/helper/test-index-version.c
+++ b/t/helper/test-index-version.c
@@ -1,6 +1,7 @@
+#include "test-tool.h"
#include "cache.h"
-int cmd_main(int argc, const char **argv)
+int cmd__index_version(int argc, const char **argv)
{
struct cache_header hdr;
int version;
diff --git a/t/helper/test-json-writer.c b/t/helper/test-json-writer.c
new file mode 100644
index 0000000000..37c452535f
--- /dev/null
+++ b/t/helper/test-json-writer.c
@@ -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();
+}
diff --git a/t/helper/test-lazy-init-name-hash.c b/t/helper/test-lazy-init-name-hash.c
index 6368a89345..b99a37080d 100644
--- a/t/helper/test-lazy-init-name-hash.c
+++ b/t/helper/test-lazy-init-name-hash.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
#include "cache.h"
#include "parse-options.h"
@@ -112,7 +113,7 @@ static void analyze_run(void)
{
uint64_t t1s, t1m, t2s, t2m;
int cache_nr_limit;
- int nr_threads_used;
+ int nr_threads_used = 0;
int i;
int nr;
@@ -184,14 +185,14 @@ static void analyze_run(void)
}
}
-int cmd_main(int argc, const char **argv)
+int cmd__lazy_init_name_hash(int argc, const char **argv)
{
const char *usage[] = {
- "test-lazy-init-name-hash -d (-s | -m)",
- "test-lazy-init-name-hash -p [-c c]",
- "test-lazy-init-name-hash -a a [--step s] [-c c]",
- "test-lazy-init-name-hash (-s | -m) [-c c]",
- "test-lazy-init-name-hash -s -m [-c c]",
+ "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[] = {
diff --git a/t/helper/test-line-buffer.c b/t/helper/test-line-buffer.c
index 81575fe2ab..078dd7e29d 100644
--- a/t/helper/test-line-buffer.c
+++ b/t/helper/test-line-buffer.c
@@ -17,27 +17,17 @@ static uint32_t strtouint32(const char *s)
static void handle_command(const char *command, const char *arg, struct line_buffer *buf)
{
- switch (*command) {
- case 'b':
- 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);
- return;
- }
- case 'c':
- if (starts_with(command, "copy ")) {
- buffer_copy_bytes(buf, strtouint32(arg));
- return;
- }
- case 's':
- if (starts_with(command, "skip ")) {
- buffer_skip_bytes(buf, strtouint32(arg));
- return;
- }
- default:
+ 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);
}
}
diff --git a/t/helper/test-match-trees.c b/t/helper/test-match-trees.c
index 356d8edef1..96857f26ac 100644
--- a/t/helper/test-match-trees.c
+++ b/t/helper/test-match-trees.c
@@ -1,7 +1,8 @@
+#include "test-tool.h"
#include "cache.h"
#include "tree.h"
-int cmd_main(int ac, const char **av)
+int cmd__match_trees(int ac, const char **av)
{
struct object_id hash1, hash2, shifted;
struct tree *one, *two;
diff --git a/t/helper/test-mergesort.c b/t/helper/test-mergesort.c
index 335cf6b626..c5cffaa4b7 100644
--- a/t/helper/test-mergesort.c
+++ b/t/helper/test-mergesort.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
#include "cache.h"
#include "mergesort.h"
@@ -22,7 +23,7 @@ static int compare_strings(const void *a, const void *b)
return strcmp(x->text, y->text);
}
-int cmd_main(int argc, const char **argv)
+int cmd__mergesort(int argc, const char **argv)
{
struct line *line, *p = NULL, *lines = NULL;
struct strbuf sb = STRBUF_INIT;
diff --git a/t/helper/test-mktemp.c b/t/helper/test-mktemp.c
index 89d9b2f7be..2290688940 100644
--- a/t/helper/test-mktemp.c
+++ b/t/helper/test-mktemp.c
@@ -1,9 +1,10 @@
/*
* test-mktemp.c: code to exercise the creation of temporary files
*/
+#include "test-tool.h"
#include "git-compat-util.h"
-int cmd_main(int argc, const char **argv)
+int cmd__mktemp(int argc, const char **argv)
{
if (argc != 2)
usage("Expected 1 parameter defining the temporary file template");
diff --git a/t/helper/test-online-cpus.c b/t/helper/test-online-cpus.c
index 06c09c6b88..8cb0d53840 100644
--- a/t/helper/test-online-cpus.c
+++ b/t/helper/test-online-cpus.c
@@ -1,7 +1,8 @@
+#include "test-tool.h"
#include "git-compat-util.h"
#include "thread-utils.h"
-int cmd_main(int argc, const char **argv)
+int cmd__online_cpus(int argc, const char **argv)
{
printf("%d\n", online_cpus());
return 0;
diff --git a/t/helper/test-parse-options.c b/t/helper/test-parse-options.c
index 75fe883aac..630c76d127 100644
--- a/t/helper/test-parse-options.c
+++ b/t/helper/test-parse-options.c
@@ -99,6 +99,8 @@ int cmd_main(int argc, const char **argv)
const char *prefix = "prefix/";
const char *usage[] = {
"test-parse-options <options>",
+ "",
+ "A helper function for the parse-options API.",
NULL
};
struct string_list expect = STRING_LIST_INIT_NODUP;
diff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c
index 1ebe0f750c..ae091d9b3e 100644
--- a/t/helper/test-path-utils.c
+++ b/t/helper/test-path-utils.c
@@ -1,5 +1,7 @@
+#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
@@ -38,6 +40,20 @@ struct test_data {
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)
{
@@ -156,7 +172,12 @@ static struct test_data dirname_data[] = {
{ NULL, NULL }
};
-int cmd_main(int argc, const char **argv)
+static int is_dotgitmodules(const char *path)
+{
+ return is_hfs_dotgitmodules(path) || is_ntfs_dotgitmodules(path);
+}
+
+int cmd__path_utils(int argc, const char **argv)
{
if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) {
char *buf = xmallocz(strlen(argv[2]));
@@ -251,10 +272,24 @@ int cmd_main(int argc, const char **argv)
}
if (argc == 2 && !strcmp(argv[1], "basename"))
- return test_function(basename_data, basename, argv[1]);
+ return test_function(basename_data, posix_basename, argv[1]);
if (argc == 2 && !strcmp(argv[1], "dirname"))
- return test_function(dirname_data, dirname, argv[1]);
+ 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;
+ }
fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
argv[1] ? argv[1] : "(there was none)");
diff --git a/t/helper/test-pkt-line.c b/t/helper/test-pkt-line.c
new file mode 100644
index 0000000000..30775f986f
--- /dev/null
+++ b/t/helper/test-pkt-line.c
@@ -0,0 +1,97 @@
+#include "cache.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_main(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;
+}
diff --git a/t/helper/test-prio-queue.c b/t/helper/test-prio-queue.c
index ae58fff359..9807b649b1 100644
--- a/t/helper/test-prio-queue.c
+++ b/t/helper/test-prio-queue.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
#include "cache.h"
#include "prio-queue.h"
@@ -16,7 +17,7 @@ static void show(int *v)
free(v);
}
-int cmd_main(int argc, const char **argv)
+int cmd__prio_queue(int argc, const char **argv)
{
struct prio_queue pq = { intcmp };
diff --git a/t/helper/test-read-cache.c b/t/helper/test-read-cache.c
index 48255eef31..d674c88ba0 100644
--- a/t/helper/test-read-cache.c
+++ b/t/helper/test-read-cache.c
@@ -1,6 +1,7 @@
+#include "test-tool.h"
#include "cache.h"
-int cmd_main(int argc, const char **argv)
+int cmd__read_cache(int argc, const char **argv)
{
int i, cnt = 1;
if (argc == 2)
diff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c
index 05d8c4d8af..e9e0541276 100644
--- a/t/helper/test-ref-store.c
+++ b/t/helper/test-ref-store.c
@@ -1,6 +1,9 @@
+#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)
{
@@ -21,7 +24,7 @@ static const char **get_store(const char **argv, struct ref_store **refs)
if (!argv[0]) {
die("ref store required");
} else if (!strcmp(argv[0], "main")) {
- *refs = get_main_ref_store();
+ *refs = get_main_ref_store(the_repository);
} else if (skip_prefix(argv[0], "submodule:", &gitdir)) {
struct strbuf sb = STRBUF_INIT;
int ret;
@@ -72,12 +75,12 @@ static int cmd_pack_refs(struct ref_store *refs, const char **argv)
static int cmd_peel_ref(struct ref_store *refs, const char **argv)
{
const char *refname = notnull(*argv++, "refname");
- unsigned char sha1[20];
+ struct object_id oid;
int ret;
- ret = refs_peel_ref(refs, refname, sha1);
+ ret = refs_peel_ref(refs, refname, &oid);
if (!ret)
- puts(sha1_to_hex(sha1));
+ puts(oid_to_hex(&oid));
return ret;
}
@@ -127,15 +130,15 @@ static int cmd_for_each_ref(struct ref_store *refs, const char **argv)
static int cmd_resolve_ref(struct ref_store *refs, const char **argv)
{
- unsigned char sha1[20];
+ 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,
- sha1, &flags);
- printf("%s %s 0x%x\n", sha1_to_hex(sha1), ref, flags);
+ &oid, &flags);
+ printf("%s %s 0x%x\n", oid_to_hex(&oid), ref ? ref : "(null)", flags);
return ref ? 0 : 1;
}
@@ -218,12 +221,12 @@ static int cmd_delete_ref(struct ref_store *refs, const char **argv)
const char *refname = notnull(*argv++, "refname");
const char *sha1_buf = notnull(*argv++, "old-sha1");
unsigned int flags = arg_flags(*argv++, "flags");
- unsigned char old_sha1[20];
+ struct object_id old_oid;
- if (get_sha1_hex(sha1_buf, old_sha1))
+ if (get_oid_hex(sha1_buf, &old_oid))
die("not sha-1");
- return refs_delete_ref(refs, msg, refname, old_sha1, flags);
+ return refs_delete_ref(refs, msg, refname, &old_oid, flags);
}
static int cmd_update_ref(struct ref_store *refs, const char **argv)
@@ -233,15 +236,15 @@ static int cmd_update_ref(struct ref_store *refs, const char **argv)
const char *new_sha1_buf = notnull(*argv++, "old-sha1");
const char *old_sha1_buf = notnull(*argv++, "old-sha1");
unsigned int flags = arg_flags(*argv++, "flags");
- unsigned char old_sha1[20];
- unsigned char new_sha1[20];
+ struct object_id old_oid;
+ struct object_id new_oid;
- if (get_sha1_hex(old_sha1_buf, old_sha1) ||
- get_sha1_hex(new_sha1_buf, new_sha1))
+ 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_sha1, old_sha1,
+ &new_oid, &old_oid,
flags, UPDATE_REFS_DIE_ON_ERR);
}
@@ -274,7 +277,7 @@ static struct command commands[] = {
{ NULL, NULL }
};
-int cmd_main(int argc, const char **argv)
+int cmd__ref_store(int argc, const char **argv)
{
struct ref_store *refs;
const char *func;
diff --git a/t/helper/test-regex.c b/t/helper/test-regex.c
index b5ea8a97c5..10284cc56f 100644
--- a/t/helper/test-regex.c
+++ b/t/helper/test-regex.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
#include "git-compat-util.h"
#include "gettext.h"
@@ -36,7 +37,7 @@ static int test_regex_bug(void)
return 0;
}
-int cmd_main(int argc, const char **argv)
+int cmd__regex(int argc, const char **argv)
{
const char *pat;
const char *str;
@@ -47,8 +48,8 @@ int cmd_main(int argc, const char **argv)
if (argc == 2 && !strcmp(argv[1], "--bug"))
return test_regex_bug();
else if (argc < 3)
- usage("test-regex --bug\n"
- "test-regex <pattern> <string> [<options>]");
+ usage("test-tool regex --bug\n"
+ "test-tool regex <pattern> <string> [<options>]");
argv++;
pat = *argv++;
diff --git a/t/helper/test-repository.c b/t/helper/test-repository.c
new file mode 100644
index 0000000000..2762ca6562
--- /dev/null
+++ b/t/helper/test-repository.c
@@ -0,0 +1,82 @@
+#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;
+
+ repo_init(&r, gitdir, worktree);
+
+ 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;
+
+ repo_init(&r, gitdir, worktree);
+
+ 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;
+}
diff --git a/t/helper/test-revision-walking.c b/t/helper/test-revision-walking.c
index b8e6fe1d00..4f8bc75821 100644
--- a/t/helper/test-revision-walking.c
+++ b/t/helper/test-revision-walking.c
@@ -8,6 +8,7 @@
* published by the Free Software Foundation.
*/
+#include "test-tool.h"
#include "cache.h"
#include "commit.h"
#include "diff.h"
@@ -45,7 +46,7 @@ static int run_revision_walk(void)
return got_revision;
}
-int cmd_main(int argc, const char **argv)
+int cmd__revision_walking(int argc, const char **argv)
{
if (argc < 2)
return 1;
diff --git a/t/helper/test-run-command.c b/t/helper/test-run-command.c
index d24d157379..2cc93bb69c 100644
--- a/t/helper/test-run-command.c
+++ b/t/helper/test-run-command.c
@@ -8,6 +8,7 @@
* published by the Free Software Foundation.
*/
+#include "test-tool.h"
#include "git-compat-util.h"
#include "run-command.h"
#include "argv-array.h"
@@ -49,13 +50,22 @@ static int task_finished(int result,
return 1;
}
-int cmd_main(int argc, const char **argv)
+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")) {
diff --git a/t/helper/test-scrap-cache-tree.c b/t/helper/test-scrap-cache-tree.c
index d2a63bea43..393f1604ff 100644
--- a/t/helper/test-scrap-cache-tree.c
+++ b/t/helper/test-scrap-cache-tree.c
@@ -1,12 +1,13 @@
+#include "test-tool.h"
#include "cache.h"
#include "lockfile.h"
#include "tree.h"
#include "cache-tree.h"
-static struct lock_file index_lock;
-
-int cmd_main(int ac, const char **av)
+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)
diff --git a/t/helper/test-sha1-array.c b/t/helper/test-sha1-array.c
index edfd52d82a..ad5e69f9d3 100644
--- a/t/helper/test-sha1-array.c
+++ b/t/helper/test-sha1-array.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
#include "cache.h"
#include "sha1-array.h"
@@ -7,7 +8,7 @@ static int print_oid(const struct object_id *oid, void *data)
return 0;
}
-int cmd_main(int argc, const char **argv)
+int cmd__sha1_array(int argc, const char **argv)
{
struct oid_array array = OID_ARRAY_INIT;
struct strbuf line = STRBUF_INIT;
diff --git a/t/helper/test-sha1.c b/t/helper/test-sha1.c
index a1c13f54ec..1ba0675c75 100644
--- a/t/helper/test-sha1.c
+++ b/t/helper/test-sha1.c
@@ -1,6 +1,7 @@
+#include "test-tool.h"
#include "cache.h"
-int cmd_main(int ac, const char **av)
+int cmd__sha1(int ac, const char **av)
{
git_SHA_CTX ctx;
unsigned char sha1[20];
diff --git a/t/helper/test-sha1.sh b/t/helper/test-sha1.sh
index 750b95a0a1..84594885c7 100755
--- a/t/helper/test-sha1.sh
+++ b/t/helper/test-sha1.sh
@@ -1,7 +1,7 @@
#!/bin/sh
dd if=/dev/zero bs=1048576 count=100 2>/dev/null |
-/usr/bin/time t/helper/test-sha1 >/dev/null
+/usr/bin/time t/helper/test-tool sha1 >/dev/null
while read expect cnt pfx
do
@@ -11,7 +11,7 @@ do
test -z "$pfx" || echo "$pfx"
dd if=/dev/zero bs=1048576 count=$cnt 2>/dev/null |
perl -pe 'y/\000/g/'
- } | ./t/helper/test-sha1 $cnt
+ } | ./t/helper/test-tool sha1 $cnt
)
if test "$expect" = "$actual"
then
diff --git a/t/helper/test-sigchain.c b/t/helper/test-sigchain.c
index b71edbd442..77ac5bc33f 100644
--- a/t/helper/test-sigchain.c
+++ b/t/helper/test-sigchain.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
#include "cache.h"
#include "sigchain.h"
@@ -13,7 +14,7 @@ X(two)
X(three)
#undef X
-int cmd_main(int argc, const char **argv) {
+int cmd__sigchain(int argc, const char **argv) {
sigchain_push(SIGTERM, one);
sigchain_push(SIGTERM, two);
sigchain_push(SIGTERM, three);
diff --git a/t/helper/test-strcmp-offset.c b/t/helper/test-strcmp-offset.c
index 4a45a54e92..44e4a6d143 100644
--- a/t/helper/test-strcmp-offset.c
+++ b/t/helper/test-strcmp-offset.c
@@ -1,6 +1,7 @@
+#include "test-tool.h"
#include "cache.h"
-int cmd_main(int argc, const char **argv)
+int cmd__strcmp_offset(int argc, const char **argv)
{
int result;
size_t offset;
@@ -11,7 +12,7 @@ int cmd_main(int argc, const char **argv)
result = strcmp_offset(argv[1], argv[2], &offset);
/*
- * Because differnt CRTs behave differently, only rely on signs
+ * Because different CRTs behave differently, only rely on signs
* of the result values.
*/
result = (result < 0 ? -1 :
diff --git a/t/helper/test-string-list.c b/t/helper/test-string-list.c
index c502fa16d3..2123dda85b 100644
--- a/t/helper/test-string-list.c
+++ b/t/helper/test-string-list.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
#include "cache.h"
#include "string-list.h"
@@ -41,7 +42,7 @@ static int prefix_cb(struct string_list_item *item, void *cb_data)
return starts_with(item->string, prefix);
}
-int cmd_main(int argc, const char **argv)
+int cmd__string_list(int argc, const char **argv)
{
if (argc == 5 && !strcmp(argv[1], "split")) {
struct string_list list = STRING_LIST_INIT_DUP;
@@ -108,7 +109,7 @@ int cmd_main(int argc, const char **argv)
* Split by newline, but don't create a string_list item
* for the empty string after the last separator.
*/
- if (sb.buf[sb.len - 1] == '\n')
+ 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);
diff --git a/t/helper/test-submodule-config.c b/t/helper/test-submodule-config.c
index 2f144d539a..e2692746df 100644
--- a/t/helper/test-submodule-config.c
+++ b/t/helper/test-submodule-config.c
@@ -1,4 +1,6 @@
+#include "test-tool.h"
#include "cache.h"
+#include "config.h"
#include "submodule-config.h"
#include "submodule.h"
@@ -9,12 +11,7 @@ static void die_usage(int argc, const char **argv, const char *msg)
exit(1);
}
-static int git_test_config(const char *var, const char *value, void *cb)
-{
- return parse_submodule_config_option(var, value);
-}
-
-int cmd_main(int argc, const char **argv)
+int cmd__submodule_config(int argc, const char **argv)
{
const char **arg = argv;
int my_argc = argc;
@@ -36,11 +33,9 @@ int cmd_main(int argc, const char **argv)
die_usage(argc, argv, "Wrong number of arguments.");
setup_git_directory();
- gitmodules_config();
- git_config(git_test_config, NULL);
while (*arg) {
- unsigned char commit_sha1[20];
+ struct object_id commit_oid;
const struct submodule *submodule;
const char *commit;
const char *path_or_name;
@@ -49,14 +44,16 @@ int cmd_main(int argc, const char **argv)
path_or_name = arg[1];
if (commit[0] == '\0')
- hashclr(commit_sha1);
- else if (get_sha1(commit, commit_sha1) < 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(commit_sha1, path_or_name);
+ submodule = submodule_from_name(the_repository,
+ &commit_oid, path_or_name);
} else
- submodule = submodule_from_path(commit_sha1, path_or_name);
+ submodule = submodule_from_path(the_repository,
+ &commit_oid, path_or_name);
if (!submodule)
die_usage(argc, argv, "Submodule not found.");
@@ -70,7 +67,7 @@ int cmd_main(int argc, const char **argv)
arg += 2;
}
- submodule_free();
+ submodule_free(the_repository);
return 0;
}
diff --git a/t/helper/test-subprocess.c b/t/helper/test-subprocess.c
index 30c5765bfc..92b69de635 100644
--- a/t/helper/test-subprocess.c
+++ b/t/helper/test-subprocess.c
@@ -1,7 +1,8 @@
+#include "test-tool.h"
#include "cache.h"
#include "run-command.h"
-int cmd_main(int argc, const char **argv)
+int cmd__subprocess(int argc, const char **argv)
{
struct child_process cp = CHILD_PROCESS_INIT;
int nogit = 0;
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
new file mode 100644
index 0000000000..0edafcfd65
--- /dev/null
+++ b/t/helper/test-tool.c
@@ -0,0 +1,65 @@
+#include "git-compat-util.h"
+#include "test-tool.h"
+
+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 },
+ { "drop-caches", cmd__drop_caches },
+ { "dump-cache-tree", cmd__dump_cache_tree },
+ { "dump-split-index", cmd__dump_split_index },
+ { "example-decorate", cmd__example_decorate },
+ { "genrandom", cmd__genrandom },
+ { "hashmap", cmd__hashmap },
+ { "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 },
+ { "online-cpus", cmd__online_cpus },
+ { "path-utils", cmd__path_utils },
+ { "prio-queue", cmd__prio_queue },
+ { "read-cache", cmd__read_cache },
+ { "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 },
+ { "sha1-array", cmd__sha1_array },
+ { "sha1", cmd__sha1 },
+ { "sigchain", cmd__sigchain },
+ { "strcmp-offset", cmd__strcmp_offset },
+ { "string-list", cmd__string_list },
+ { "submodule-config", cmd__submodule_config },
+ { "subprocess", cmd__subprocess },
+ { "urlmatch-normalization", cmd__urlmatch_normalization },
+ { "wildmatch", cmd__wildmatch },
+ { "write-cache", cmd__write_cache },
+};
+
+int cmd_main(int argc, const char **argv)
+{
+ int i;
+
+ BUG_exit_code = 99;
+ if (argc < 2)
+ die("I need a test name!");
+
+ for (i = 0; i < ARRAY_SIZE(cmds); i++) {
+ if (!strcmp(cmds[i].name, argv[1])) {
+ argv++;
+ argc--;
+ return cmds[i].fn(argc, argv);
+ }
+ }
+ die("There is no test named '%s'", argv[1]);
+}
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
new file mode 100644
index 0000000000..e926c416ea
--- /dev/null
+++ b/t/helper/test-tool.h
@@ -0,0 +1,42 @@
+#ifndef __TEST_TOOL_H__
+#define __TEST_TOOL_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__drop_caches(int argc, const char **argv);
+int cmd__dump_cache_tree(int argc, const char **argv);
+int cmd__dump_split_index(int argc, const char **argv);
+int cmd__example_decorate(int argc, const char **argv);
+int cmd__genrandom(int argc, const char **argv);
+int cmd__hashmap(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__online_cpus(int argc, const char **argv);
+int cmd__path_utils(int argc, const char **argv);
+int cmd__prio_queue(int argc, const char **argv);
+int cmd__read_cache(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__sha1_array(int argc, const char **argv);
+int cmd__sha1(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__subprocess(int argc, const char **argv);
+int cmd__urlmatch_normalization(int argc, const char **argv);
+int cmd__wildmatch(int argc, const char **argv);
+int cmd__write_cache(int argc, const char **argv);
+
+#endif
diff --git a/t/helper/test-urlmatch-normalization.c b/t/helper/test-urlmatch-normalization.c
index 49b6e836be..8f4d67e646 100644
--- a/t/helper/test-urlmatch-normalization.c
+++ b/t/helper/test-urlmatch-normalization.c
@@ -1,9 +1,10 @@
+#include "test-tool.h"
#include "git-compat-util.h"
#include "urlmatch.h"
-int cmd_main(int argc, const char **argv)
+int cmd__urlmatch_normalization(int argc, const char **argv)
{
- const char usage[] = "test-urlmatch-normalization [-p | -l] <url1> | <url1> <url2>";
+ const char usage[] = "test-tool urlmatch-normalization [-p | -l] <url1> | <url1> <url2>";
char *url1, *url2;
int opt_p = 0, opt_l = 0;
diff --git a/t/helper/test-wildmatch.c b/t/helper/test-wildmatch.c
index 52be876fed..2c103d1824 100644
--- a/t/helper/test-wildmatch.c
+++ b/t/helper/test-wildmatch.c
@@ -1,6 +1,7 @@
+#include "test-tool.h"
#include "cache.h"
-int cmd_main(int argc, const char **argv)
+int cmd__wildmatch(int argc, const char **argv)
{
int i;
for (i = 2; i < argc; i++) {
@@ -11,11 +12,13 @@ int cmd_main(int argc, const char **argv)
argv[i] += 3;
}
if (!strcmp(argv[1], "wildmatch"))
- return !!wildmatch(argv[3], argv[2], WM_PATHNAME, NULL);
+ return !!wildmatch(argv[3], argv[2], WM_PATHNAME);
else if (!strcmp(argv[1], "iwildmatch"))
- return !!wildmatch(argv[3], argv[2], WM_PATHNAME | WM_CASEFOLD, NULL);
+ return !!wildmatch(argv[3], argv[2], WM_PATHNAME | WM_CASEFOLD);
else if (!strcmp(argv[1], "pathmatch"))
- return !!wildmatch(argv[3], argv[2], 0, NULL);
+ return !!wildmatch(argv[3], argv[2], 0);
+ else if (!strcmp(argv[1], "ipathmatch"))
+ return !!wildmatch(argv[3], argv[2], WM_CASEFOLD);
else
return 1;
}
diff --git a/t/helper/test-write-cache.c b/t/helper/test-write-cache.c
new file mode 100644
index 0000000000..8837717d36
--- /dev/null
+++ b/t/helper/test-write-cache.c
@@ -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;
+}