Skip to content

Commit fef847a

Browse files
authored
Merge pull request libgit2#5110 from pks-t/pks/wildmatch
Replace fnmatch with wildmatch
2 parents 2b6594d + 13ded47 commit fef847a

File tree

20 files changed

+744
-409
lines changed

20 files changed

+744
-409
lines changed

COPYING

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -991,3 +991,31 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
991991
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
992992
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
993993
SOFTWARE.
994+
995+
----------------------------------------------------------------------
996+
997+
The bundled wildmatch code is licensed under the BSD license:
998+
999+
Copyright Rich Salz.
1000+
All rights reserved.
1001+
1002+
Redistribution and use in any form are permitted provided that the
1003+
following restrictions are are met:
1004+
1005+
1. Source distributions must retain this entire copyright notice
1006+
and comment.
1007+
2. Binary distributions must include the acknowledgement ``This
1008+
product includes software developed by Rich Salz'' in the
1009+
documentation or other materials provided with the
1010+
distribution. This must not be represented as an endorsement
1011+
or promotion without specific prior written permission.
1012+
3. The origin of this software must not be misrepresented, either
1013+
by explicit claim or by omission. Credits must appear in the
1014+
source and documentation.
1015+
4. Altered versions must be plainly marked as such in the source
1016+
and documentation and must not be misrepresented as being the
1017+
original software.
1018+
1019+
THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1020+
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1021+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

src/attr_file.c

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "git2/tree.h"
1616
#include "blob.h"
1717
#include "index.h"
18+
#include "wildmatch.h"
1819
#include <ctype.h>
1920

2021
static void attr_file_free(git_attr_file *file)
@@ -401,18 +402,13 @@ bool git_attr_fnmatch__match(
401402
}
402403

403404
if (match->flags & GIT_ATTR_FNMATCH_ICASE)
404-
flags |= FNM_CASEFOLD;
405-
if (match->flags & GIT_ATTR_FNMATCH_LEADINGDIR)
406-
flags |= FNM_LEADING_DIR;
405+
flags |= WM_CASEFOLD;
407406

408407
if (match->flags & GIT_ATTR_FNMATCH_FULLPATH) {
409408
filename = relpath;
410-
flags |= FNM_PATHNAME;
409+
flags |= WM_PATHNAME;
411410
} else {
412411
filename = path->basename;
413-
414-
if (path->is_dir)
415-
flags |= FNM_LEADING_DIR;
416412
}
417413

418414
if ((match->flags & GIT_ATTR_FNMATCH_DIRECTORY) && !path->is_dir) {
@@ -427,8 +423,6 @@ bool git_attr_fnmatch__match(
427423
path->basename == relpath)
428424
return false;
429425

430-
flags |= FNM_LEADING_DIR;
431-
432426
/* fail match if this is a file with same name as ignored folder */
433427
samename = (match->flags & GIT_ATTR_FNMATCH_ICASE) ?
434428
!strcasecmp(match->pattern, relpath) :
@@ -437,10 +431,10 @@ bool git_attr_fnmatch__match(
437431
if (samename)
438432
return false;
439433

440-
return (p_fnmatch(match->pattern, relpath, flags) != FNM_NOMATCH);
434+
return (wildmatch(match->pattern, relpath, flags) == WM_MATCH);
441435
}
442436

443-
return (p_fnmatch(match->pattern, filename, flags) != FNM_NOMATCH);
437+
return (wildmatch(match->pattern, filename, flags) == WM_MATCH);
444438
}
445439

446440
bool git_attr_rule__match(
@@ -658,8 +652,6 @@ int git_attr_fnmatch__parse(
658652

659653
if (*pattern == '!' && (spec->flags & GIT_ATTR_FNMATCH_ALLOWNEG) != 0) {
660654
spec->flags = spec->flags | GIT_ATTR_FNMATCH_NEGATIVE;
661-
if ((spec->flags & GIT_ATTR_FNMATCH_NOLEADINGDIR) == 0)
662-
spec->flags |= GIT_ATTR_FNMATCH_LEADINGDIR;
663655
pattern++;
664656
}
665657

@@ -715,14 +707,6 @@ int git_attr_fnmatch__parse(
715707
if (--slash_count <= 0)
716708
spec->flags = spec->flags & ~GIT_ATTR_FNMATCH_FULLPATH;
717709
}
718-
if ((spec->flags & GIT_ATTR_FNMATCH_NOLEADINGDIR) == 0 &&
719-
spec->length >= 2 &&
720-
pattern[spec->length - 1] == '*' &&
721-
pattern[spec->length - 2] == '/') {
722-
spec->length -= 2;
723-
spec->flags = spec->flags | GIT_ATTR_FNMATCH_LEADINGDIR;
724-
/* leave FULLPATH match on, however */
725-
}
726710

727711
if (context) {
728712
char *slash = strrchr(context, '/');

src/attr_file.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,9 @@
3232
#define GIT_ATTR_FNMATCH_MATCH_ALL (1U << 8)
3333
#define GIT_ATTR_FNMATCH_ALLOWNEG (1U << 9)
3434
#define GIT_ATTR_FNMATCH_ALLOWMACRO (1U << 10)
35-
#define GIT_ATTR_FNMATCH_LEADINGDIR (1U << 11)
36-
#define GIT_ATTR_FNMATCH_NOLEADINGDIR (1U << 12)
3735

3836
#define GIT_ATTR_FNMATCH__INCOMING \
39-
(GIT_ATTR_FNMATCH_ALLOWSPACE | GIT_ATTR_FNMATCH_ALLOWNEG | \
40-
GIT_ATTR_FNMATCH_ALLOWMACRO | GIT_ATTR_FNMATCH_NOLEADINGDIR)
37+
(GIT_ATTR_FNMATCH_ALLOWSPACE | GIT_ATTR_FNMATCH_ALLOWNEG | GIT_ATTR_FNMATCH_ALLOWMACRO)
4138

4239
typedef enum {
4340
GIT_ATTR_FILE__IN_MEMORY = 0,

src/config_file.c

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "array.h"
1919
#include "config_parse.h"
2020
#include "config_entries.h"
21+
#include "wildmatch.h"
2122

2223
#include <ctype.h>
2324
#include <sys/types.h>
@@ -697,41 +698,41 @@ static int do_match_gitdir(
697698
int *matches,
698699
const git_repository *repo,
699700
const char *cfg_file,
700-
const char *value,
701+
const char *condition,
701702
bool case_insensitive)
702703
{
703-
git_buf path = GIT_BUF_INIT;
704-
int error, fnmatch_flags;
705-
706-
if (value[0] == '.' && git_path_is_dirsep(value[1])) {
707-
git_path_dirname_r(&path, cfg_file);
708-
git_buf_joinpath(&path, path.ptr, value + 2);
709-
} else if (value[0] == '~' && git_path_is_dirsep(value[1]))
710-
git_sysdir_expand_global_file(&path, value + 1);
711-
else if (!git_path_is_absolute(value))
712-
git_buf_joinpath(&path, "**", value);
704+
git_buf pattern = GIT_BUF_INIT, gitdir = GIT_BUF_INIT;
705+
int error;
706+
707+
if (condition[0] == '.' && git_path_is_dirsep(condition[1])) {
708+
git_path_dirname_r(&pattern, cfg_file);
709+
git_buf_joinpath(&pattern, pattern.ptr, condition + 2);
710+
} else if (condition[0] == '~' && git_path_is_dirsep(condition[1]))
711+
git_sysdir_expand_global_file(&pattern, condition + 1);
712+
else if (!git_path_is_absolute(condition))
713+
git_buf_joinpath(&pattern, "**", condition);
713714
else
714-
git_buf_sets(&path, value);
715+
git_buf_sets(&pattern, condition);
715716

716-
if (git_buf_oom(&path)) {
717+
if (git_path_is_dirsep(condition[strlen(condition) - 1]))
718+
git_buf_puts(&pattern, "**");
719+
720+
if (git_buf_oom(&pattern)) {
717721
error = -1;
718722
goto out;
719723
}
720724

721-
if (git_path_is_dirsep(value[strlen(value) - 1]))
722-
git_buf_puts(&path, "**");
723-
724-
fnmatch_flags = FNM_PATHNAME|FNM_LEADING_DIR;
725-
if (case_insensitive)
726-
fnmatch_flags |= FNM_IGNORECASE;
727-
728-
if ((error = p_fnmatch(path.ptr, git_repository_path(repo), fnmatch_flags)) < 0)
725+
if ((error = git_repository_item_path(&gitdir, repo, GIT_REPOSITORY_ITEM_GITDIR)) < 0)
729726
goto out;
730727

731-
*matches = (error == 0);
728+
if (git_path_is_dirsep(gitdir.ptr[gitdir.size - 1]))
729+
git_buf_truncate(&gitdir, gitdir.size - 1);
732730

731+
*matches = wildmatch(pattern.ptr, gitdir.ptr,
732+
WM_PATHNAME | (case_insensitive ? WM_CASEFOLD : 0)) == WM_MATCH;
733733
out:
734-
git_buf_dispose(&path);
734+
git_buf_dispose(&pattern);
735+
git_buf_dispose(&gitdir);
735736
return error;
736737
}
737738

src/describe.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@
1616
#include "commit_list.h"
1717
#include "oidmap.h"
1818
#include "refs.h"
19+
#include "repository.h"
1920
#include "revwalk.h"
2021
#include "tag.h"
2122
#include "vector.h"
22-
#include "repository.h"
23+
#include "wildmatch.h"
2324

2425
/* Ported from https://github.com/git/git/blob/89dde7882f71f846ccd0359756d27bebc31108de/builtin/describe.c */
2526

@@ -214,7 +215,7 @@ static int get_name(const char *refname, void *payload)
214215
return 0;
215216

216217
/* Accept only tags that match the pattern, if given */
217-
if (data->opts->pattern && (!is_tag || p_fnmatch(data->opts->pattern,
218+
if (data->opts->pattern && (!is_tag || wildmatch(data->opts->pattern,
218219
refname + strlen(GIT_REFS_TAGS_DIR), 0)))
219220
return 0;
220221

0 commit comments

Comments
 (0)