if ((error = git_path_diriter_init(&diriter, dirpath, flags)) < 0)
goto done;
- while ((error = git_path_diriter_next(&path, &path_len, &diriter)) == 0) {
+ while ((error = git_path_diriter_next(&diriter)) == 0) {
if ((error = git_path_diriter_fullpath(&path, &path_len, &diriter)) < 0)
goto done;
return 0;
}
-int git_path_diriter_next(
- const char **out,
- size_t *out_len,
- git_path_diriter *diriter)
+int git_path_diriter_next(git_path_diriter *diriter)
{
struct dirent *de;
const char *filename;
bool skip_dot = !(diriter->flags & GIT_PATH_DIR_INCLUDE_DOT_AND_DOTDOT);
int error = 0;
- assert(out && out_len && diriter);
-
- *out = NULL;
- *out_len = 0;
+ assert(diriter);
errno = 0;
if (git_buf_oom(&diriter->path))
return -1;
- *out = &diriter->path.ptr[diriter->parent_len+1];
- *out_len = filename_len;
-
return error;
}
+int git_path_diriter_filename(
+ const char **out,
+ size_t *out_len,
+ git_path_diriter *diriter)
+{
+ assert(out && out_len && diriter);
+
+ *out = &diriter->path.ptr[diriter->parent_len+1];
+ *out_len = diriter->path.size - diriter->parent_len - 1;
+ return 0;
+}
+
int git_path_diriter_fullpath(
const char **out,
size_t *out_len,
if ((error = git_path_diriter_init(&iter, path, flags)) < 0)
return error;
- while ((error = git_path_diriter_next(&name, &name_len, &iter)) == 0) {
+ while ((error = git_path_diriter_next(&iter)) == 0) {
if ((error = git_path_diriter_fullpath(&name, &name_len, &iter)) < 0)
break;
DIR *dir;
};
+/**
+ * Initialize a directory iterator.
+ *
+ * @param diriter Pointer to a diriter structure that will be setup.
+ * @param path The path that will be iterated over
+ * @param flags Directory reader flags
+ * @return 0 or an error code
+ */
extern int git_path_diriter_init(
git_path_diriter *diriter,
const char *path,
unsigned int flags);
-extern int git_path_diriter_next(
+/**
+ * Advance the directory iterator. Will return GIT_ITEROVER when
+ * the iteration has completed successfully.
+ *
+ * @param diriter The directory iterator
+ * @return 0, GIT_ITEROVER, or an error code
+ */
+extern int git_path_diriter_next(git_path_diriter *diriter);
+
+/**
+ * Returns the file name of the current item in the iterator.
+ *
+ * @param out Pointer to store the path in
+ * @param out_len Pointer to store the length of the path in
+ * @param diriter The directory iterator
+ * @return 0 or an error code
+ */
+extern int git_path_diriter_filename(
const char **out,
size_t *out_len,
git_path_diriter *diriter);
+/**
+ * Returns the full path of the current item in the iterator; that
+ * is the current filename plus the path of the directory that the
+ * iterator was constructed with.
+ *
+ * @param out Pointer to store the path in
+ * @param out_len Pointer to store the length of the path in
+ * @param diriter The directory iterator
+ * @return 0 or an error code
+ */
extern int git_path_diriter_fullpath(
const char **out,
size_t *out_len,
git_path_diriter *diriter);
+/**
+ * Performs an `lstat` on the current item in the iterator.
+ *
+ * @param out Pointer to store the stat data in
+ * @param diriter The directory iterator
+ * @return 0 or an error code
+ */
extern int git_path_diriter_stat(struct stat *out, git_path_diriter *diriter);
+/**
+ * Closes the directory iterator.
+ *
+ * @param diriter The directory iterator
+ */
extern void git_path_diriter_free(git_path_diriter *diriter);
/**
}
}
+static int update_count(name_data *data, const char *name)
+{
+ name_data *n;
+
+ for (n = data; n->name; n++) {
+ if (!strcmp(n->name, name)) {
+ n->count++;
+ return 0;
+ }
+ }
+
+ return GIT_ERROR;
+}
+
static int one_entry(void *state, git_buf *path)
{
walk_data *d = (walk_data *) state;
- name_data *n;
if (state != state_loc)
return GIT_ERROR;
if (path != &d->path)
return GIT_ERROR;
- for (n = d->names; n->name; n++) {
- if (!strcmp(n->name, path->ptr)) {
- n->count++;
- return 0;
- }
- }
-
- return GIT_ERROR;
+ return update_count(d->names, path->ptr);
}
cl_must_pass(p_rmdir("empty_dir"));
}
+
+static void handle_next(git_path_diriter *diriter, walk_data *walk)
+{
+ const char *fullpath, *filename;
+ size_t fullpath_len, filename_len;
+
+ cl_git_pass(git_path_diriter_fullpath(&fullpath, &fullpath_len, diriter));
+ cl_git_pass(git_path_diriter_filename(&filename, &filename_len, diriter));
+
+ cl_assert_equal_strn(fullpath, "sub/", 4);
+ cl_assert_equal_s(fullpath+4, filename);
+
+ update_count(walk->names, fullpath);
+}
+
+/* test directory iterator */
+void test_core_dirent__diriter_with_fullname(void)
+{
+ git_path_diriter diriter = GIT_PATH_DIRITER_INIT;
+ int error;
+
+ cl_set_cleanup(&dirent_cleanup__cb, &sub);
+ setup(&sub);
+
+ cl_git_pass(git_path_diriter_init(&diriter, sub.path.ptr, 0));
+
+ while ((error = git_path_diriter_next(&diriter)) == 0)
+ handle_next(&diriter, &sub);
+
+ cl_assert_equal_i(error, GIT_ITEROVER);
+
+ git_path_diriter_free(&diriter);
+
+ check_counts(&sub);
+}