#include #include "git2.h" #include "egit.h" #include "egit-util.h" #include "interface.h" #include "egit-pathspec.h" EGIT_DOC(pathspec_new, "PATHSPECS", "Compile a pathspec object from a PATHSPECS list of strings."); emacs_value egit_pathspec_new(emacs_env *env, emacs_value _pathspecs) { git_strarray pathspecs; if (!egit_strarray_from_list(&pathspecs, env, _pathspecs)) { return esym_nil; } git_pathspec* spec = NULL; int retval = git_pathspec_new(&spec, &pathspecs); egit_strarray_dispose(&pathspecs); EGIT_CHECK_ERROR(retval); return egit_wrap(env, EGIT_PATHSPEC, spec, NULL); } static emacs_value extract_flags(int32_t *out, emacs_env* env, emacs_value _flags) { { EM_DOLIST(_flag, _flags, flags_label); git_pathspec_flag_t flag = 0; em_findsym_pathspec_flag(&flag, env, _flag, true); *out |= flag; EM_DOLIST_END(flags_label); } return esym_t; } EGIT_DOC(pathspec_matches_path, "PATHSPEC FLAGS PATH", "Try to match a PATH against a PATHSPEC.\n" "\n" "FLAGS should be nil or a list with the following symbols:\n" " - ignore-case: forces match to ignore case\n" " - use-case: forces case sensitive match\n" " - no-glob: disables glob patterns and just uses simple string " "comparison for matching\n" "\n" "Unlike most of the other pathspec matching functions, this will not " "fall back on the native case-sensitivity for your platform. " "You must explicitly pass flags to control case sensitivity or else " "this will fall back on being case sensitive."); emacs_value egit_pathspec_matches_path(emacs_env *env, emacs_value _pathspec, emacs_value _flags, emacs_value _path) { EGIT_ASSERT_PATHSPEC(_pathspec); EM_ASSERT_STRING(_path); git_pathspec *pathspec = EGIT_EXTRACT(_pathspec); int32_t flags = 0; extract_flags(&flags, env, _flags); char *path = EM_EXTRACT_STRING(_path); bool retval = git_pathspec_matches_path(pathspec, flags, path); free(path); return retval ? esym_t : esym_nil; } EGIT_DOC(pathspec_match_list_entrycount, "PATHSPEC-MATCH-LIST", "Get the number of items in a match list."); emacs_value egit_pathspec_match_list_entrycount(emacs_env *env, emacs_value _match_list) { EGIT_ASSERT_PATHSPEC_MATCH_LIST(_match_list); git_pathspec_match_list *match_list = EGIT_EXTRACT(_match_list); return EM_INTEGER(git_pathspec_match_list_entrycount(match_list)); } EGIT_DOC(pathspec_match_list_entry, "PATHSPEC-MATCH-LIST POSITION", "Get a matching filename by position.\n" "\n" "This routine cannot be used if the match list was generated by " "`libgit-pathspec-match-diff'. If so, it will always return nil."); emacs_value egit_pathspec_match_list_entry(emacs_env *env, emacs_value _match_list, emacs_value _pos) { EGIT_ASSERT_PATHSPEC_MATCH_LIST(_match_list); EM_ASSERT_INTEGER(_pos); git_pathspec_match_list *match_list = EGIT_EXTRACT(_match_list); size_t pos = EM_EXTRACT_INTEGER(_pos); const char *filename = git_pathspec_match_list_entry(match_list, pos); if (!filename) { return esym_nil; } return EM_STRING(filename); } EGIT_DOC(pathspec_match_list_diff_entry, "PATHSPEC-MATCH-LIST POSITION", "Get a matching diff delta by position.\n" "\n" "This routine can only be used if the match list was generated by " "`libgit-pathspec-match-diff'. Otherwise it will always return nil."); emacs_value egit_pathspec_match_list_diff_entry(emacs_env *env, emacs_value _match_list, emacs_value _pos) { EGIT_ASSERT_PATHSPEC_MATCH_LIST(_match_list); EM_ASSERT_INTEGER(_pos); git_pathspec_match_list *match_list = EGIT_EXTRACT(_match_list); size_t pos = EM_EXTRACT_INTEGER(_pos); const git_diff_delta *delta = git_pathspec_match_list_diff_entry(match_list, pos); if (!delta) { return esym_nil; } return egit_wrap(env, EGIT_DIFF_DELTA, delta, NULL); } EGIT_DOC(pathspec_match_list_failed_entrycount, "PATHSPEC-MATCH-LIST", "Get the number of pathspec items that did not match.\n" "\n" "This will be zero unless you passed `find-failures' when " "generating the pathspec match list."); emacs_value egit_pathspec_match_list_failed_entrycount(emacs_env *env, emacs_value _match_list) { EGIT_ASSERT_PATHSPEC_MATCH_LIST(_match_list); git_pathspec_match_list *match_list = EGIT_EXTRACT(_match_list); return EM_INTEGER(git_pathspec_match_list_failed_entrycount(match_list)); } EGIT_DOC(pathspec_match_list_failed_entry, "PATHSPEC-MATCH-LIST POSITION", "Get an original pathspec string that had no matches.\n" "\n" "This will be return nil for positions out of range."); emacs_value egit_pathspec_match_list_failed_entry(emacs_env *env, emacs_value _match_list, emacs_value _pos) { EGIT_ASSERT_PATHSPEC_MATCH_LIST(_match_list); EM_ASSERT_INTEGER(_pos); git_pathspec_match_list *match_list = EGIT_EXTRACT(_match_list); size_t pos = EM_EXTRACT_INTEGER(_pos); const char *filename = git_pathspec_match_list_failed_entry(match_list, pos); if (!filename) { return esym_nil; } return EM_STRING(filename); } EGIT_DOC(pathspec_match_workdir, "REPO FLAGS PATHSPEC", "Match a PATHSPEC against the working directory of a REPO repository.\n" "\n" "This matches the pathspec against the current files in the working " "directory of the repository. It is an error to invoke this on a bare" "repo. This handles git ignores (i.e. ignored files will not be" "considered to match the PATHSPEC unless the file is tracked in the " "index).\n" "\n" "FLAGS should be nil or a list with the following symbols:\n" " - ignore-case: forces match to ignore case\n" " - use-case: forces case sensitive match\n" " - no-glob: disables glob patterns and just uses simple string " "comparison for matching\n" " - no-match-error: signal an error if no matches are found; " "otherwise no matches is still success, but " "`libgit-pathspec-match-list-entrycount' will indicate 0 matches.\n" " - find-failures: means that the `libgit-pathspec-match-list' object " "should track which patterns matched which files so that at the end of " "the match we can identify patterns that did not match any files.\n" " - failures-only: means that the `libgit-pathspec-match-list' object " "does not need to keep the actual matching filenames. Use this to " "just test if there were any matches at all or in combination with " "`find-failures' to validate a pathspec."); emacs_value egit_pathspec_match_workdir(emacs_env *env, emacs_value _repo, emacs_value _flags, emacs_value _pathspec) { EGIT_ASSERT_REPOSITORY(_repo); EGIT_ASSERT_PATHSPEC(_pathspec); git_repository *repo = EGIT_EXTRACT(_repo); git_pathspec *pathspec = EGIT_EXTRACT(_pathspec); int32_t flags = 0; extract_flags(&flags, env, _flags); git_pathspec_match_list *match_list; int retval = git_pathspec_match_workdir(&match_list, repo, flags, pathspec); EGIT_CHECK_ERROR(retval); return egit_wrap(env, EGIT_PATHSPEC_MATCH_LIST, match_list, NULL); } EGIT_DOC(pathspec_match_index, "INDEX FLAGS PATHSPEC", "Match a PATHSPEC against an INDEX.\n" "\n" "FLAGS should be nil or a list with the following symbols:\n" " - ignore-case: forces match to ignore case\n" " - use-case: forces case sensitive match\n" " - no-glob: disables glob patterns and just uses simple string " "comparison for matching\n" " - no-match-error: signal an error if no matches are found; " "otherwise no matches is still success, but " "`libgit-pathspec-match-list-entrycount' will indicate 0 matches.\n" " - find-failures: means that the `libgit-pathspec-match-list' object " "should track which patterns matched which files so that at the end of " "the match we can identify patterns that did not match any files.\n" " - failures-only: means that the `libgit-pathspec-match-list' object " "does not need to keep the actual matching filenames. Use this to " "just test if there were any matches at all or in combination with " "`find-failures' to validate a pathspec."); emacs_value egit_pathspec_match_index(emacs_env *env, emacs_value _index, emacs_value _flags, emacs_value _pathspec) { EGIT_ASSERT_INDEX(_index); EGIT_ASSERT_PATHSPEC(_pathspec); git_index *index = EGIT_EXTRACT(_index); git_pathspec *pathspec = EGIT_EXTRACT(_pathspec); int32_t flags = 0; extract_flags(&flags, env, _flags); git_pathspec_match_list *match_list; int retval = git_pathspec_match_index(&match_list, index, flags, pathspec); EGIT_CHECK_ERROR(retval); return egit_wrap(env, EGIT_PATHSPEC_MATCH_LIST, match_list, NULL); } EGIT_DOC(pathspec_match_tree, "TREE FLAGS PATHSPEC", "Match a PATHSPEC against a TREE.\n" "\n" "FLAGS should be nil or a list with the following symbols:\n" " - ignore-case: forces match to ignore case\n" " - use-case: forces case sensitive match\n" " - no-glob: disables glob patterns and just uses simple string " "comparison for matching\n" " - no-match-error: signal an error if no matches are found; " "otherwise no matches is still success, but " "`libgit-pathspec-match-list-entrycount' will indicate 0 matches.\n" " - find-failures: means that the `libgit-pathspec-match-list' object " "should track which patterns matched which files so that at the end of " "the match we can identify patterns that did not match any files.\n" " - failures-only: means that the `libgit-pathspec-match-list' object " "does not need to keep the actual matching filenames. Use this to " "just test if there were any matches at all or in combination with " "`find-failures' to validate a pathspec."); emacs_value egit_pathspec_match_tree(emacs_env *env, emacs_value _tree, emacs_value _flags, emacs_value _pathspec) { EGIT_ASSERT_TREE(_tree); EGIT_ASSERT_PATHSPEC(_pathspec); git_tree *tree = EGIT_EXTRACT(_tree); git_pathspec *pathspec = EGIT_EXTRACT(_pathspec); int32_t flags = 0; extract_flags(&flags, env, _flags); git_pathspec_match_list *match_list; int retval = git_pathspec_match_tree(&match_list, tree, flags, pathspec); EGIT_CHECK_ERROR(retval); return egit_wrap(env, EGIT_PATHSPEC_MATCH_LIST, match_list, NULL); } EGIT_DOC(pathspec_match_diff, "DIFF FLAGS PATHSPEC", "Match a PATHSPEC against a DIFF.\n" "\n" "FLAGS should be nil or a list with the following symbols:\n" " - ignore-case: forces match to ignore case\n" " - use-case: forces case sensitive match\n" " - no-glob: disables glob patterns and just uses simple string " "comparison for matching\n" " - no-match-error: signal an error if no matches are found; " "otherwise no matches is still success, but " "`libgit-pathspec-match-list-entrycount' will indicate 0 matches.\n" " - find-failures: means that the `libgit-pathspec-match-list' object " "should track which patterns matched which files so that at the end of " "the match we can identify patterns that did not match any files.\n" " - failures-only: means that the `libgit-pathspec-match-list' object " "does not need to keep the actual matching filenames. Use this to " "just test if there were any matches at all or in combination with " "`find-failures' to validate a pathspec."); emacs_value egit_pathspec_match_diff(emacs_env *env, emacs_value _diff, emacs_value _flags, emacs_value _pathspec) { EGIT_ASSERT_DIFF(_diff); EGIT_ASSERT_PATHSPEC(_pathspec); git_diff *diff = EGIT_EXTRACT(_diff); git_pathspec *pathspec = EGIT_EXTRACT(_pathspec); int32_t flags = 0; extract_flags(&flags, env, _flags); git_pathspec_match_list *match_list; int retval = git_pathspec_match_diff(&match_list, diff, flags, pathspec); EGIT_CHECK_ERROR(retval); return egit_wrap(env, EGIT_PATHSPEC_MATCH_LIST, match_list, NULL); }