summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/fileops.h1
-rw-r--r--tests/t0020-dirent.c241
2 files changed, 217 insertions, 25 deletions
diff --git a/src/fileops.h b/src/fileops.h
index f2a98a88c..dca7499de 100644
--- a/src/fileops.h
+++ b/src/fileops.h
@@ -44,6 +44,7 @@ extern void gitfo_free_buf(gitfo_buf *obj);
#define gitfo_unlink(p) unlink(p)
#define gitfo_rmdir(p) rmdir(p)
+#define gitfo_chdir(p) chdir(p)
#ifdef GIT_WIN32
#define gitfo_mkdir(p,m) mkdir(p)
diff --git a/tests/t0020-dirent.c b/tests/t0020-dirent.c
index 4c6545319..966f3c578 100644
--- a/tests/t0020-dirent.c
+++ b/tests/t0020-dirent.c
@@ -1,48 +1,239 @@
+#include <stdarg.h>
#include "test_lib.h"
#include "fileops.h"
+
+typedef struct name_data {
+ int count; /* return count */
+ char *name; /* filename */
+} name_data;
+
+typedef struct walk_data {
+ char *sub; /* sub-directory name */
+ name_data *names; /* name state data */
+} walk_data;
+
+
static char path_buffer[GIT_PATH_MAX];
-static int state_loc;
-static const char* names[] = {
- "./a",
- "./asdf",
- "./pack-foo.pack",
- NULL
-};
+static char *top_dir = "dir-walk";
+static walk_data *state_loc;
+
+
+static int error(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+ return -1;
+}
+
+static int setup(walk_data *d)
+{
+ name_data *n;
+
+ if (gitfo_mkdir(top_dir, 0755) < 0)
+ return error("can't mkdir(\"%s\")", top_dir);
+
+ if (gitfo_chdir(top_dir) < 0)
+ return error("can't chdir(\"%s\")", top_dir);
+
+ if (strcmp(d->sub, ".") != 0)
+ if (gitfo_mkdir(d->sub, 0755) < 0)
+ return error("can't mkdir(\"%s\")", d->sub);
+
+ strcpy(path_buffer, d->sub);
+ state_loc = d;
+
+ for (n = d->names; n->name; n++) {
+ git_file fd = gitfo_creat(n->name, 0600);
+ must_be_true(fd >= 0);
+ gitfo_close(fd);
+ n->count = 0;
+ }
+
+ return 0;
+}
+
+static int knockdown(walk_data *d)
+{
+ name_data *n;
+
+ for (n = d->names; n->name; n++) {
+ if (gitfo_unlink(n->name) < 0)
+ return error("can't unlink(\"%s\")", n->name);
+ }
+
+ if (strcmp(d->sub, ".") != 0)
+ if (gitfo_rmdir(d->sub) < 0)
+ return error("can't rmdir(\"%s\")", d->sub);
+
+ if (gitfo_chdir("..") < 0)
+ return error("can't chdir(\"..\")");
+
+ if (gitfo_rmdir(top_dir) < 0)
+ return error("can't rmdir(\"%s\")", top_dir);
+
+ return 0;
+}
+
+static int check_counts(walk_data *d)
+{
+ int ret = 0;
+ name_data *n;
+
+ for (n = d->names; n->name; n++) {
+ if (n->count != 1)
+ ret = error("count (%d, %s)", n->count, n->name);
+ }
+ return ret;
+}
static int one_entry(void *state, char *path)
{
- const char **c;
+ walk_data *d = (walk_data *) state;
+ name_data *n;
- must_be_true(state == &state_loc);
+ must_be_true(state == state_loc);
must_be_true(path == path_buffer);
- for (c = names; *c; c++) {
- if (!strcmp(*c, path)) {
- *c = "";
+ for (n = d->names; n->name; n++) {
+ if (!strcmp(n->name, path)) {
+ n->count++;
return 0;
}
}
test_die("unexpected path \"%s\"", path);
}
-BEGIN_TEST(setup)
- const char **c;
- for (c = names; *c; c++) {
- git_file fd = gitfo_creat(*c, 0600);
- must_be_true(fd >= 0);
- gitfo_close(fd);
- }
+
+static name_data dot_names[] = {
+ { 0, "./a" },
+ { 0, "./asdf" },
+ { 0, "./pack-foo.pack" },
+ { 0, NULL }
+};
+static walk_data dot = {
+ ".",
+ dot_names
+};
+
+BEGIN_TEST(dot)
+
+ must_pass(setup(&dot));
+
+ must_pass(gitfo_dirent(path_buffer,
+ sizeof(path_buffer),
+ one_entry,
+ &dot));
+
+ must_pass(check_counts(&dot));
+
+ must_pass(knockdown(&dot));
+END_TEST
+
+static name_data sub_names[] = {
+ { 0, "sub/a" },
+ { 0, "sub/asdf" },
+ { 0, "sub/pack-foo.pack" },
+ { 0, NULL }
+};
+static walk_data sub = {
+ "sub",
+ sub_names
+};
+
+BEGIN_TEST(sub)
+
+ must_pass(setup(&sub));
+
+ must_pass(gitfo_dirent(path_buffer,
+ sizeof(path_buffer),
+ one_entry,
+ &sub));
+
+ must_pass(check_counts(&sub));
+
+ must_pass(knockdown(&sub));
+END_TEST
+
+static walk_data sub_slash = {
+ "sub/",
+ sub_names
+};
+
+BEGIN_TEST(sub_slash)
+
+ must_pass(setup(&sub_slash));
+
+ must_pass(gitfo_dirent(path_buffer,
+ sizeof(path_buffer),
+ one_entry,
+ &sub_slash));
+
+ must_pass(check_counts(&sub_slash));
+
+ must_pass(knockdown(&sub_slash));
END_TEST
-BEGIN_TEST(direent_walk)
- const char **c;
+static name_data empty_names[] = {
+ { 0, NULL }
+};
+static walk_data empty = {
+ "empty",
+ empty_names
+};
+
+static int dont_call_me(void *state, char *path)
+{
+ test_die("dont_call_me: unexpected callback!");
+}
+
+BEGIN_TEST(empty)
+
+ must_pass(setup(&empty));
+
+ must_pass(gitfo_dirent(path_buffer,
+ sizeof(path_buffer),
+ one_entry,
+ &empty));
+
+ must_pass(check_counts(&empty));
+
+ /* make sure callback not called */
+ must_pass(gitfo_dirent(path_buffer,
+ sizeof(path_buffer),
+ dont_call_me,
+ &empty));
+
+ must_pass(knockdown(&empty));
+END_TEST
+
+static name_data odd_names[] = {
+ { 0, "odd/.a" },
+ { 0, "odd/..c" },
+ /* the following don't work on cygwin/win32 */
+ /* { 0, "odd/.b." }, */
+ /* { 0, "odd/..d.." }, */
+ { 0, NULL }
+};
+static walk_data odd = {
+ "odd",
+ odd_names
+};
+
+BEGIN_TEST(odd)
+
+ must_pass(setup(&odd));
- strcpy(path_buffer, ".");
must_pass(gitfo_dirent(path_buffer,
sizeof(path_buffer),
one_entry,
- &state_loc));
+ &odd));
+
+ must_pass(check_counts(&odd));
- for (c = names; *c; c++)
- must_pass(strcmp("", *c));
+ must_pass(knockdown(&odd));
END_TEST
+