@@ -34,56 +34,63 @@ int fnmatch_icase(const char *pattern, const char *string, int flags)
3434 return fnmatch (pattern , string , flags | (ignore_case ? FNM_CASEFOLD : 0 ));
3535}
3636
37- static int common_prefix (const char * * pathspec )
37+ static size_t common_prefix_len (const char * * pathspec )
3838{
39- const char * path , * slash , * next ;
40- int prefix ;
39+ const char * n , * first ;
40+ size_t max = 0 ;
4141
4242 if (!pathspec )
43- return 0 ;
43+ return max ;
44+
45+ first = * pathspec ;
46+ while ((n = * pathspec ++ )) {
47+ size_t i , len = 0 ;
48+ for (i = 0 ; first == n || i < max ; i ++ ) {
49+ char c = n [i ];
50+ if (!c || c != first [i ] || is_glob_special (c ))
51+ break ;
52+ if (c == '/' )
53+ len = i + 1 ;
54+ }
55+ if (first == n || len < max ) {
56+ max = len ;
57+ if (!max )
58+ break ;
59+ }
60+ }
61+ return max ;
62+ }
4463
45- path = * pathspec ;
46- slash = strrchr (path , '/' );
47- if (!slash )
48- return 0 ;
64+ /*
65+ * Returns a copy of the longest leading path common among all
66+ * pathspecs.
67+ */
68+ char * common_prefix (const char * * pathspec )
69+ {
70+ unsigned long len = common_prefix_len (pathspec );
4971
50- /*
51- * The first 'prefix' characters of 'path' are common leading
52- * path components among the pathspecs we have seen so far,
53- * including the trailing slash.
54- */
55- prefix = slash - path + 1 ;
56- while ((next = * ++ pathspec ) != NULL ) {
57- int len , last_matching_slash = -1 ;
58- for (len = 0 ; len < prefix && next [len ] == path [len ]; len ++ )
59- if (next [len ] == '/' )
60- last_matching_slash = len ;
61- if (len == prefix )
62- continue ;
63- if (last_matching_slash < 0 )
64- return 0 ;
65- prefix = last_matching_slash + 1 ;
66- }
67- return prefix ;
72+ return len ? xmemdupz (* pathspec , len ) : NULL ;
6873}
6974
7075int fill_directory (struct dir_struct * dir , const char * * pathspec )
7176{
7277 const char * path ;
73- int len ;
78+ size_t len ;
7479
7580 /*
7681 * Calculate common prefix for the pathspec, and
7782 * use that to optimize the directory walk
7883 */
79- len = common_prefix (pathspec );
84+ len = common_prefix_len (pathspec );
8085 path = "" ;
8186
8287 if (len )
8388 path = xmemdupz (* pathspec , len );
8489
8590 /* Read the directory and prune it */
8691 read_directory (dir , path , len , pathspec );
92+ if (* path )
93+ free ((char * )path );
8794 return len ;
8895}
8996
0 commit comments