vendor/libgit2/src/path.h in rugged-0.19.0 vs vendor/libgit2/src/path.h in rugged-0.21.0

- old
+ new

@@ -117,10 +117,18 @@ } #else # define git_path_mkposix(p) /* blank */ #endif +/** + * Check if string is a relative path (i.e. starts with "./" or "../") + */ +GIT_INLINE(int) git_path_is_relative(const char *p) +{ + return (p[0] == '.' && (p[1] == '/' || (p[1] == '.' && p[2] == '/'))); +} + extern int git__percent_decode(git_buf *decoded_out, const char *input); /** * Extract path from file:// URL. */ @@ -173,21 +181,19 @@ /** * Check if the given path contains the given subdirectory. * * @param parent Directory path that might contain subdir * @param subdir Subdirectory name to look for in parent - * @param append_if_exists If true, then subdir will be appended to the parent path if it does exist * @return true if subdirectory exists, false otherwise. */ extern bool git_path_contains_dir(git_buf *parent, const char *subdir); /** * Check if the given path contains the given file. * * @param dir Directory path that might contain file * @param file File name to look for in parent - * @param append_if_exists If true, then file will be appended to the path if it does exist * @return true if file exists, false otherwise. */ extern bool git_path_contains_file(git_buf *dir, const char *file); /** @@ -242,25 +248,33 @@ * slash, "." will be eaten with no change, and ".." will remove a * segment from the base path. */ extern int git_path_apply_relative(git_buf *target, const char *relpath); +enum { + GIT_PATH_DIR_IGNORE_CASE = (1u << 0), + GIT_PATH_DIR_PRECOMPOSE_UNICODE = (1u << 1), +}; + /** * Walk each directory entry, except '.' and '..', calling fn(state). * - * @param pathbuf buffer the function reads the initial directory + * @param pathbuf Buffer the function reads the initial directory * path from, and updates with each successive entry's name. - * @param fn function to invoke with each entry. The first arg is - * the input state and the second arg is pathbuf. The function - * may modify the pathbuf, but only by appending new text. - * @param state to pass to fn as the first arg. - * @return 0 on success, GIT_EUSER on non-zero callback, or error code + * @param flags Combination of GIT_PATH_DIR flags. + * @param callback Callback for each entry. Passed the `payload` and each + * successive path inside the directory as a full path. This may + * safely append text to the pathbuf if needed. Return non-zero to + * cancel iteration (and return value will be propagated back). + * @param payload Passed to callback as first argument. + * @return 0 on success or error code from OS error or from callback */ extern int git_path_direach( git_buf *pathbuf, - int (*fn)(void *, git_buf *), - void *state); + uint32_t flags, + int (*callback)(void *payload, git_buf *path), + void *payload); /** * Sort function to order two paths */ extern int git_path_cmp( @@ -276,23 +290,23 @@ * will stop the iteration and propogate the error to the caller. * * @param pathbuf Buffer the function reads the directory from and * and updates with each successive name. * @param ceiling Prefix of path at which to stop walking up. If NULL, - * this will walk all the way up to the root. If not a prefix of - * pathbuf, the callback will be invoked a single time on the - * original input path. - * @param fn Function to invoke on each path. The first arg is the - * input satte and the second arg is the pathbuf. The function - * should not modify the pathbuf. + * this will walk all the way up to the root. If not a prefix of + * pathbuf, the callback will be invoked a single time on the + * original input path. + * @param callback Function to invoke on each path. Passed the `payload` + * and the buffer containing the current path. The path should not + * be modified in any way. Return non-zero to stop iteration. * @param state Passed to fn as the first ath. */ extern int git_path_walk_up( git_buf *pathbuf, const char *ceiling, - int (*fn)(void *state, git_buf *), - void *state); + int (*callback)(void *payload, git_buf *path), + void *payload); /** * Load all directory entries (except '.' and '..') into a vector. * * For cases where `git_path_direach()` is not appropriate, this @@ -304,16 +318,18 @@ * @param prefix_len When inserting entries, the trailing part of path * will be prefixed after this length. I.e. given path "/a/b" and * prefix_len 3, the entries will look like "b/e1", "b/e2", etc. * @param alloc_extra Extra bytes to add to each string allocation in * case you want to append anything funny. + * @param flags Combination of GIT_PATH_DIR flags. * @param contents Vector to fill with directory entry names. */ extern int git_path_dirload( const char *path, size_t prefix_len, size_t alloc_extra, + uint32_t flags, git_vector *contents); typedef struct { struct stat st; @@ -336,19 +352,93 @@ * 4. Optionally, you can be a start and end prefix and only elements * after the start and before the end (inclusively) will be stat'ed. * * @param path The directory to read from * @param prefix_len The trailing part of path to prefix to entry paths - * @param ignore_case How to sort and compare paths with start/end limits + * @param flags GIT_PATH_DIR flags from above * @param start_stat As optimization, only stat values after this prefix * @param end_stat As optimization, only stat values before this prefix * @param contents Vector to fill with git_path_with_stat structures */ extern int git_path_dirload_with_stat( const char *path, size_t prefix_len, - bool ignore_case, + uint32_t flags, const char *start_stat, const char *end_stat, git_vector *contents); + +enum { GIT_PATH_NOTEQUAL = 0, GIT_PATH_EQUAL = 1, GIT_PATH_PREFIX = 2 }; + +/* + * Determines if a path is equal to or potentially a child of another. + * @param parent The possible parent + * @param child The possible child + */ +GIT_INLINE(int) git_path_equal_or_prefixed( + const char *parent, + const char *child) +{ + const char *p = parent, *c = child; + + while (*p && *c) { + if (*p++ != *c++) + return GIT_PATH_NOTEQUAL; + } + + if (*p != '\0') + return GIT_PATH_NOTEQUAL; + if (*c == '\0') + return GIT_PATH_EQUAL; + if (*c == '/') + return GIT_PATH_PREFIX; + + return GIT_PATH_NOTEQUAL; +} + +/* translate errno to libgit2 error code and set error message */ +extern int git_path_set_error( + int errno_value, const char *path, const char *action); + +/* check if non-ascii characters are present in filename */ +extern bool git_path_has_non_ascii(const char *path, size_t pathlen); + +#define GIT_PATH_REPO_ENCODING "UTF-8" + +#ifdef __APPLE__ +#define GIT_PATH_NATIVE_ENCODING "UTF-8-MAC" +#else +#define GIT_PATH_NATIVE_ENCODING "UTF-8" +#endif + +#ifdef GIT_USE_ICONV + +#include <iconv.h> + +typedef struct { + iconv_t map; + git_buf buf; +} git_path_iconv_t; + +#define GIT_PATH_ICONV_INIT { (iconv_t)-1, GIT_BUF_INIT } + +/* Init iconv data for converting decomposed UTF-8 to precomposed */ +extern int git_path_iconv_init_precompose(git_path_iconv_t *ic); + +/* Clear allocated iconv data */ +extern void git_path_iconv_clear(git_path_iconv_t *ic); + +/* + * Rewrite `in` buffer using iconv map if necessary, replacing `in` + * pointer internal iconv buffer if rewrite happened. The `in` pointer + * will be left unchanged if no rewrite was needed. + */ +extern int git_path_iconv(git_path_iconv_t *ic, char **in, size_t *inlen); + +#endif /* GIT_USE_ICONV */ + +extern bool git_path_does_fs_decompose_unicode(const char *root); + +/* Used for paths to repositories on the filesystem */ +extern int git_path_from_url_or_path(git_buf *local_path_out, const char *url_or_path); #endif