Git fork
at reftables-rust 716 lines 22 kB view raw
1#ifndef DIR_H 2#define DIR_H 3 4#include "hash.h" 5#include "hashmap.h" 6#include "pathspec.h" 7#include "statinfo.h" 8#include "strbuf.h" 9 10struct repository; 11 12/** 13 * The directory listing API is used to enumerate paths in the work tree, 14 * optionally taking `.git/info/exclude` and `.gitignore` files per directory 15 * into account. 16 */ 17 18/** 19 * Calling sequence 20 * ---------------- 21 * 22 * Note: The index may be checked for .gitignore files that are 23 * CE_SKIP_WORKTREE marked. If you want to exclude files, make sure you have 24 * loaded the index first. 25 * 26 * - Prepare `struct dir_struct dir` using `dir_init()` function. 27 * 28 * - To add single exclude pattern, call `add_pattern_list()` and then 29 * `add_pattern()`. 30 * 31 * - To add patterns from a file (e.g. `.git/info/exclude`), call 32 * `add_patterns_from_file()` , and/or set `dir.exclude_per_dir`. 33 * 34 * - A short-hand function `setup_standard_excludes()` can be used to set 35 * up the standard set of exclude settings, instead of manually calling 36 * the add_pattern*() family of functions. 37 * 38 * - Call `fill_directory()`. 39 * 40 * - Use `dir.entries[]` and `dir.ignored[]`. 41 * 42 * - Call `dir_clear()` when the contained elements are no longer in use. 43 * 44 */ 45 46 47struct dir_entry { 48 unsigned int len; 49 char name[FLEX_ARRAY]; /* more */ 50}; 51 52#define PATTERN_FLAG_NODIR 1 53#define PATTERN_FLAG_ENDSWITH 4 54#define PATTERN_FLAG_MUSTBEDIR 8 55#define PATTERN_FLAG_NEGATIVE 16 56 57struct path_pattern { 58 /* 59 * This allows callers of last_matching_pattern() etc. 60 * to determine the origin of the matching pattern. 61 */ 62 struct pattern_list *pl; 63 64 int patternlen; 65 int nowildcardlen; 66 const char *base; 67 int baselen; 68 unsigned flags; /* PATTERN_FLAG_* */ 69 70 /* 71 * Counting starts from 1 for line numbers in ignore files, 72 * and from -1 decrementing for patterns from CLI args. 73 */ 74 int srcpos; 75 76 char pattern[FLEX_ARRAY]; 77}; 78 79/* used for hashmaps for cone patterns */ 80struct pattern_entry { 81 struct hashmap_entry ent; 82 char *pattern; 83 size_t patternlen; 84}; 85 86/* 87 * Each excludes file will be parsed into a fresh exclude_list which 88 * is appended to the relevant exclude_list_group (either EXC_DIRS or 89 * EXC_FILE). An exclude_list within the EXC_CMDL exclude_list_group 90 * can also be used to represent the list of --exclude values passed 91 * via CLI args. 92 */ 93struct pattern_list { 94 int nr; 95 int alloc; 96 97 /* origin of list, e.g. path to filename, or descriptive string */ 98 const char *src; 99 100 struct path_pattern **patterns; 101 102 /* 103 * While scanning the excludes, we attempt to match the patterns 104 * with a more restricted set that allows us to use hashsets for 105 * matching logic, which is faster than the linear lookup in the 106 * excludes array above. If non-zero, that check succeeded. 107 */ 108 unsigned use_cone_patterns; 109 unsigned full_cone; 110 111 /* 112 * Stores paths where everything starting with those paths 113 * is included. 114 */ 115 struct hashmap recursive_hashmap; 116 117 /* 118 * Used to check single-level parents of blobs. 119 */ 120 struct hashmap parent_hashmap; 121}; 122 123/* 124 * The contents of the per-directory exclude files are lazily read on 125 * demand and then cached in memory, one per exclude_stack struct, in 126 * order to avoid opening and parsing each one every time that 127 * directory is traversed. 128 */ 129struct exclude_stack { 130 struct exclude_stack *prev; /* the struct exclude_stack for the parent directory */ 131 int baselen; 132 int exclude_ix; /* index of exclude_list within EXC_DIRS exclude_list_group */ 133 struct untracked_cache_dir *ucd; 134}; 135 136struct exclude_list_group { 137 int nr, alloc; 138 struct pattern_list *pl; 139}; 140 141struct oid_stat { 142 struct stat_data stat; 143 struct object_id oid; 144 int valid; 145}; 146 147/* 148 * Untracked cache 149 * 150 * The following inputs are sufficient to determine what files in a 151 * directory are excluded: 152 * 153 * - The list of files and directories of the directory in question 154 * - The $GIT_DIR/index 155 * - dir_struct flags 156 * - The content of $GIT_DIR/info/exclude 157 * - The content of core.excludesfile 158 * - The content (or the lack) of .gitignore of all parent directories 159 * from $GIT_WORK_TREE 160 * - The check_only flag in read_directory_recursive (for 161 * DIR_HIDE_EMPTY_DIRECTORIES) 162 * 163 * The first input can be checked using directory mtime. In many 164 * filesystems, directory mtime (stat_data field) is updated when its 165 * files or direct subdirs are added or removed. 166 * 167 * The second one can be hooked from cache_tree_invalidate_path(). 168 * Whenever a file (or a submodule) is added or removed from a 169 * directory, we invalidate that directory. 170 * 171 * The remaining inputs are easy, their SHA-1 could be used to verify 172 * their contents (exclude_sha1[], info_exclude_sha1[] and 173 * excludes_file_sha1[]) 174 */ 175struct untracked_cache_dir { 176 struct untracked_cache_dir **dirs; 177 char **untracked; 178 struct stat_data stat_data; 179 unsigned int untracked_alloc, dirs_nr, dirs_alloc; 180 unsigned int untracked_nr; 181 unsigned int check_only : 1; 182 /* all data except 'dirs' in this struct are good */ 183 unsigned int valid : 1; 184 unsigned int recurse : 1; 185 /* null object ID means this directory does not have .gitignore */ 186 struct object_id exclude_oid; 187 char name[FLEX_ARRAY]; 188}; 189 190struct untracked_cache { 191 struct oid_stat ss_info_exclude; 192 struct oid_stat ss_excludes_file; 193 const char *exclude_per_dir; 194 char *exclude_per_dir_to_free; 195 struct strbuf ident; 196 /* 197 * dir_struct#flags must match dir_flags or the untracked 198 * cache is ignored. 199 */ 200 unsigned dir_flags; 201 struct untracked_cache_dir *root; 202 /* Statistics */ 203 int dir_created; 204 int gitignore_invalidated; 205 int dir_invalidated; 206 int dir_opened; 207 /* fsmonitor invalidation data */ 208 unsigned int use_fsmonitor : 1; 209}; 210 211/** 212 * structure is used to pass directory traversal options to the library and to 213 * record the paths discovered. A single `struct dir_struct` is used regardless 214 * of whether or not the traversal recursively descends into subdirectories. 215 */ 216struct dir_struct { 217 218 /* bit-field of options */ 219 enum { 220 221 /** 222 * Return just ignored files in `entries[]`, not untracked files. 223 * This flag is mutually exclusive with `DIR_SHOW_IGNORED_TOO`. 224 */ 225 DIR_SHOW_IGNORED = 1<<0, 226 227 /* Include a directory that is not tracked. */ 228 DIR_SHOW_OTHER_DIRECTORIES = 1<<1, 229 230 /* Do not include a directory that is not tracked and is empty. */ 231 DIR_HIDE_EMPTY_DIRECTORIES = 1<<2, 232 233 /** 234 * If set, recurse into a directory that looks like a Git directory. 235 * Otherwise it is shown as a directory. 236 */ 237 DIR_NO_GITLINKS = 1<<3, 238 239 /** 240 * Special mode for git-add. Return ignored files in `ignored[]` and 241 * untracked files in `entries[]`. Only returns ignored files that match 242 * pathspec exactly (no wildcards). Does not recurse into ignored 243 * directories. 244 */ 245 DIR_COLLECT_IGNORED = 1<<4, 246 247 /** 248 * Similar to `DIR_SHOW_IGNORED`, but return ignored files in 249 * `ignored[]` in addition to untracked files in `entries[]`. 250 * This flag is mutually exclusive with `DIR_SHOW_IGNORED`. 251 */ 252 DIR_SHOW_IGNORED_TOO = 1<<5, 253 254 DIR_COLLECT_KILLED_ONLY = 1<<6, 255 256 /** 257 * Only has meaning if `DIR_SHOW_IGNORED_TOO` is also set; if this is 258 * set, the untracked contents of untracked directories are also 259 * returned in `entries[]`. 260 */ 261 DIR_KEEP_UNTRACKED_CONTENTS = 1<<7, 262 263 /** 264 * Only has meaning if `DIR_SHOW_IGNORED_TOO` is also set; if this is 265 * set, returns ignored files and directories that match an exclude 266 * pattern. If a directory matches an exclude pattern, then the 267 * directory is returned and the contained paths are not. A directory 268 * that does not match an exclude pattern will not be returned even if 269 * all of its contents are ignored. In this case, the contents are 270 * returned as individual entries. 271 * 272 * If this is set, files and directories that explicitly match an ignore 273 * pattern are reported. Implicitly ignored directories (directories that 274 * do not match an ignore pattern, but whose contents are all ignored) 275 * are not reported, instead all of the contents are reported. 276 */ 277 DIR_SHOW_IGNORED_TOO_MODE_MATCHING = 1<<8, 278 279 DIR_SKIP_NESTED_GIT = 1<<9 280 } flags; 281 282 /* The number of members in `entries[]` array. */ 283 int nr; /* output only */ 284 285 /* The number of members in `ignored[]` array. */ 286 int ignored_nr; /* output only */ 287 288 /* An array of `struct dir_entry`, each element of which describes a path. */ 289 struct dir_entry **entries; /* output only */ 290 291 /** 292 * used for ignored paths with the `DIR_SHOW_IGNORED_TOO` and 293 * `DIR_COLLECT_IGNORED` flags. 294 */ 295 struct dir_entry **ignored; /* output only */ 296 297 /* Enable/update untracked file cache if set */ 298 struct untracked_cache *untracked; 299 300 /** 301 * Deprecated: ls-files is the only allowed caller; all other callers 302 * should leave this as NULL; it pre-dated the 303 * setup_standard_excludes() mechanism that replaces this. 304 * 305 * This field tracks the name of the file to be read in each directory 306 * for excluded files (typically `.gitignore`). 307 */ 308 const char *exclude_per_dir; 309 310 struct dir_struct_internal { 311 /* Keeps track of allocation of `entries[]` array.*/ 312 int alloc; 313 314 /* Keeps track of allocation of `ignored[]` array. */ 315 int ignored_alloc; 316 317 /* 318 * We maintain three groups of exclude pattern lists: 319 * 320 * EXC_CMDL lists patterns explicitly given on the command line. 321 * EXC_DIRS lists patterns obtained from per-directory ignore 322 * files. 323 * EXC_FILE lists patterns from fallback ignore files, e.g. 324 * - .git/info/exclude 325 * - core.excludesfile 326 * 327 * Each group contains multiple exclude lists, a single list 328 * per source. 329 */ 330#define EXC_CMDL 0 331#define EXC_DIRS 1 332#define EXC_FILE 2 333 struct exclude_list_group exclude_list_group[3]; 334 335 /* 336 * Temporary variables which are used during loading of the 337 * per-directory exclude lists. 338 * 339 * exclude_stack points to the top of the exclude_stack, and 340 * basebuf contains the full path to the current 341 * (sub)directory in the traversal. Exclude points to the 342 * matching exclude struct if the directory is excluded. 343 */ 344 struct exclude_stack *exclude_stack; 345 struct path_pattern *pattern; 346 struct strbuf basebuf; 347 348 /* Additional metadata related to 'untracked' */ 349 struct oid_stat ss_info_exclude; 350 struct oid_stat ss_excludes_file; 351 unsigned unmanaged_exclude_files; 352 353 /* Stats about the traversal */ 354 unsigned visited_paths; 355 unsigned visited_directories; 356 } internal; 357}; 358 359#define DIR_INIT { 0 } 360 361struct dirent *readdir_skip_dot_and_dotdot(DIR *dirp); 362 363/* 364 * Get the d_type of a dirent. If the d_type is unknown, derive it from 365 * stat.st_mode using the path to the dirent's containing directory (path) and 366 * the name of the dirent itself. 367 * 368 * If 'follow_symlink' is 1, this function will attempt to follow DT_LNK types 369 * using 'stat'. Links are *not* followed recursively, so a symlink pointing 370 * to another symlink will still resolve to 'DT_LNK'. 371 * 372 * Note that 'path' is assumed to have a trailing slash. It is also modified 373 * in-place during the execution of the function, but is then reverted to its 374 * original value before returning. 375 */ 376unsigned char get_dtype(struct dirent *e, struct strbuf *path, 377 int follow_symlink); 378 379/*Count the number of slashes for string s*/ 380int count_slashes(const char *s); 381 382/* 383 * The ordering of these constants is significant, with 384 * higher-numbered match types signifying "closer" (i.e. more 385 * specific) matches which will override lower-numbered match types 386 * when populating the seen[] array. 387 */ 388#define MATCHED_RECURSIVELY 1 389#define MATCHED_RECURSIVELY_LEADING_PATHSPEC 2 390#define MATCHED_FNMATCH 3 391#define MATCHED_EXACTLY 4 392int simple_length(const char *match); 393int no_wildcard(const char *string); 394char *common_prefix(const struct pathspec *pathspec); 395int report_path_error(const char *ps_matched, const struct pathspec *pathspec); 396int within_depth(const char *name, int namelen, int depth, int max_depth); 397 398int fill_directory(struct dir_struct *dir, 399 struct index_state *istate, 400 const struct pathspec *pathspec); 401int read_directory(struct dir_struct *, struct index_state *istate, 402 const char *path, int len, 403 const struct pathspec *pathspec); 404 405enum pattern_match_result { 406 UNDECIDED = -1, 407 NOT_MATCHED = 0, 408 MATCHED = 1, 409 MATCHED_RECURSIVE = 2, 410}; 411 412/* 413 * Scan the list of patterns to determine if the ordered list 414 * of patterns matches on 'pathname'. 415 * 416 * Return 1 for a match, 0 for not matched and -1 for undecided. 417 */ 418enum pattern_match_result path_matches_pattern_list(const char *pathname, 419 int pathlen, 420 const char *basename, int *dtype, 421 struct pattern_list *pl, 422 struct index_state *istate); 423 424int init_sparse_checkout_patterns(struct index_state *state); 425 426int path_in_sparse_checkout(const char *path, 427 struct index_state *istate); 428int path_in_cone_mode_sparse_checkout(const char *path, 429 struct index_state *istate); 430 431struct dir_entry *dir_add_ignored(struct dir_struct *dir, 432 struct index_state *istate, 433 const char *pathname, int len); 434 435/* 436 * these implement the matching logic for dir.c:excluded_from_list and 437 * attr.c:path_matches() 438 */ 439int match_basename(const char *, int, 440 const char *, int, int, unsigned); 441int match_pathname(const char *, int, 442 const char *, int, 443 const char *, int, int); 444 445struct path_pattern *last_matching_pattern(struct dir_struct *dir, 446 struct index_state *istate, 447 const char *name, int *dtype); 448 449int is_excluded(struct dir_struct *dir, 450 struct index_state *istate, 451 const char *name, int *dtype); 452 453int pl_hashmap_cmp(const void *unused_cmp_data, 454 const struct hashmap_entry *a, 455 const struct hashmap_entry *b, 456 const void *key); 457int hashmap_contains_parent(struct hashmap *map, 458 const char *path, 459 struct strbuf *buffer); 460struct pattern_list *add_pattern_list(struct dir_struct *dir, 461 int group_type, const char *src); 462int add_patterns_from_file_to_list(const char *fname, const char *base, int baselen, 463 struct pattern_list *pl, struct index_state *istate, 464 unsigned flags); 465void add_patterns_from_file(struct dir_struct *, const char *fname); 466int add_patterns_from_blob_to_list(struct object_id *oid, 467 const char *base, int baselen, 468 struct pattern_list *pl); 469int add_patterns_from_buffer(char *buf, size_t size, 470 const char *base, int baselen, 471 struct pattern_list *pl); 472void parse_path_pattern(const char **string, int *patternlen, unsigned *flags, int *nowildcardlen); 473void add_pattern(const char *string, const char *base, 474 int baselen, struct pattern_list *pl, int srcpos); 475void clear_pattern_list(struct pattern_list *pl); 476void dir_clear(struct dir_struct *dir); 477 478int repo_file_exists(struct repository *repo, const char *path); 479int file_exists(const char *); 480 481int is_inside_dir(const char *dir); 482int dir_inside_of(const char *subdir, const char *dir); 483 484static inline int is_dot_or_dotdot(const char *name) 485{ 486 return (name[0] == '.' && 487 (name[1] == '\0' || 488 (name[1] == '.' && name[2] == '\0'))); 489} 490 491int is_empty_dir(const char *dir); 492 493/* 494 * Retrieve the "humanish" basename of the given Git URL. 495 * 496 * For example: 497 * /path/to/repo.git => "repo" 498 * host.xz:foo/.git => "foo" 499 * http://example.com/user/bar.baz => "bar.baz" 500 */ 501char *git_url_basename(const char *repo, int is_bundle, int is_bare); 502void strip_dir_trailing_slashes(char *dir); 503 504void setup_standard_excludes(struct dir_struct *dir); 505 506char *get_sparse_checkout_filename(void); 507int get_sparse_checkout_patterns(struct pattern_list *pl); 508 509/* Constants for remove_dir_recursively: */ 510 511/* 512 * If a non-directory is found within path, stop and return an error. 513 * (In this case some empty directories might already have been 514 * removed.) 515 */ 516#define REMOVE_DIR_EMPTY_ONLY 01 517 518/* 519 * If any Git work trees are found within path, skip them without 520 * considering it an error. 521 */ 522#define REMOVE_DIR_KEEP_NESTED_GIT 02 523 524/* Remove the contents of path, but leave path itself. */ 525#define REMOVE_DIR_KEEP_TOPLEVEL 04 526 527/* Remove the_original_cwd too */ 528#define REMOVE_DIR_PURGE_ORIGINAL_CWD 0x08 529 530/* 531 * Remove path and its contents, recursively. flags is a combination 532 * of the above REMOVE_DIR_* constants. Return 0 on success. 533 * 534 * This function uses path as temporary scratch space, but restores it 535 * before returning. 536 */ 537int remove_dir_recursively(struct strbuf *path, int flag); 538 539/* 540 * This function pointer type is called on each file discovered in 541 * for_each_file_in_dir. The iteration stops if this method returns 542 * non-zero. 543 */ 544typedef int (*file_iterator)(const char *path, const void *data); 545 546struct strbuf; 547/* 548 * Given a directory path, recursively visit each file within, including 549 * within subdirectories. 550 */ 551int for_each_file_in_dir(struct strbuf *path, file_iterator fn, const void *data); 552 553/* 554 * Tries to remove the path, along with leading empty directories so long as 555 * those empty directories are not startup_info->original_cwd. Ignores 556 * ENOENT. 557 */ 558int remove_path(const char *path); 559 560int git_fspathcmp(const char *a, const char *b); 561int fspatheq(const char *a, const char *b); 562int git_fspathncmp(const char *a, const char *b, size_t count); 563unsigned int fspathhash(const char *str); 564 565/* 566 * Reports whether paths collide. This may be because the paths differ only in 567 * case on a case-sensitive filesystem, or that one path refers to a symlink 568 * that collides with one of the parent directories of the other. 569 */ 570int paths_collide(const char *a, const char *b); 571 572/* 573 * The prefix part of pattern must not contains wildcards. 574 */ 575struct pathspec_item; 576int git_fnmatch(const struct pathspec_item *item, 577 const char *pattern, const char *string, 578 int prefix); 579 580int submodule_path_match(struct index_state *istate, 581 const struct pathspec *ps, 582 const char *submodule_name, 583 char *seen); 584 585static inline int dir_path_match(struct index_state *istate, 586 const struct dir_entry *ent, 587 const struct pathspec *pathspec, 588 int prefix, char *seen) 589{ 590 int has_trailing_dir = ent->len && ent->name[ent->len - 1] == '/'; 591 int len = has_trailing_dir ? ent->len - 1 : ent->len; 592 return match_pathspec(istate, pathspec, ent->name, len, prefix, seen, 593 has_trailing_dir); 594} 595 596int cmp_dir_entry(const void *p1, const void *p2); 597int check_dir_entry_contains(const struct dir_entry *out, const struct dir_entry *in); 598 599void untracked_cache_invalidate_path(struct index_state *, const char *, int safe_path); 600/* 601 * Invalidate the untracked-cache for this path, but first strip 602 * off a trailing slash, if present. 603 */ 604void untracked_cache_invalidate_trimmed_path(struct index_state *, 605 const char *path, 606 int safe_path); 607void untracked_cache_remove_from_index(struct index_state *, const char *); 608void untracked_cache_add_to_index(struct index_state *, const char *); 609 610void free_untracked_cache(struct untracked_cache *); 611struct untracked_cache *read_untracked_extension(const void *data, unsigned long sz); 612void write_untracked_extension(struct strbuf *out, struct untracked_cache *untracked); 613void add_untracked_cache(struct index_state *istate); 614void remove_untracked_cache(struct index_state *istate); 615 616/* 617 * Connect a worktree to a git directory by creating (or overwriting) a 618 * '.git' file containing the location of the git directory. In the git 619 * directory set the core.worktree setting to indicate where the worktree is. 620 * When `recurse_into_nested` is set, recurse into any nested submodules, 621 * connecting them as well. 622 */ 623void connect_work_tree_and_git_dir(const char *work_tree, 624 const char *git_dir, 625 int recurse_into_nested); 626void relocate_gitdir(const char *path, 627 const char *old_git_dir, 628 const char *new_git_dir); 629 630/** 631 * The "enum path_matches_kind" determines how path_match_flags() will 632 * behave. The flags come in sets, and one (and only one) must be 633 * provided out of each "set": 634 * 635 * PATH_MATCH_NATIVE: 636 * Path separator is is_dir_sep() 637 * PATH_MATCH_XPLATFORM: 638 * Path separator is is_xplatform_dir_sep() 639 * 640 * Do we use is_dir_sep() to check for a directory separator 641 * (*_NATIVE), or do we always check for '/' or '\' (*_XPLATFORM). The 642 * "*_NATIVE" version on Windows is the same as "*_XPLATFORM", 643 * everywhere else "*_NATIVE" means "only /". 644 * 645 * PATH_MATCH_STARTS_WITH_DOT_SLASH: 646 * Match a path starting with "./" 647 * PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH: 648 * Match a path starting with "../" 649 * 650 * The "/" in the above is adjusted based on the "*_NATIVE" and 651 * "*_XPLATFORM" flags. 652 */ 653enum path_match_flags { 654 PATH_MATCH_NATIVE = 1 << 0, 655 PATH_MATCH_XPLATFORM = 1 << 1, 656 PATH_MATCH_STARTS_WITH_DOT_SLASH = 1 << 2, 657 PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH = 1 << 3, 658}; 659#define PATH_MATCH_KINDS_MASK (PATH_MATCH_STARTS_WITH_DOT_SLASH | \ 660 PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH) 661#define PATH_MATCH_PLATFORM_MASK (PATH_MATCH_NATIVE | PATH_MATCH_XPLATFORM) 662 663/** 664 * path_match_flags() checks if a given "path" matches a given "enum 665 * path_match_flags" criteria. 666 */ 667int path_match_flags(const char *const path, const enum path_match_flags f); 668 669/** 670 * starts_with_dot_slash_native(): convenience wrapper for 671 * path_match_flags() with PATH_MATCH_STARTS_WITH_DOT_SLASH and 672 * PATH_MATCH_NATIVE. 673 */ 674static inline int starts_with_dot_slash_native(const char *const path) 675{ 676 const enum path_match_flags what = PATH_MATCH_STARTS_WITH_DOT_SLASH; 677 678 return path_match_flags(path, what | PATH_MATCH_NATIVE); 679} 680 681/** 682 * starts_with_dot_slash_native(): convenience wrapper for 683 * path_match_flags() with PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH and 684 * PATH_MATCH_NATIVE. 685 */ 686static inline int starts_with_dot_dot_slash_native(const char *const path) 687{ 688 const enum path_match_flags what = PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH; 689 690 return path_match_flags(path, what | PATH_MATCH_NATIVE); 691} 692 693/** 694 * starts_with_dot_slash: convenience wrapper for 695 * patch_match_flags() with PATH_MATCH_STARTS_WITH_DOT_SLASH and 696 * PATH_MATCH_XPLATFORM. 697 */ 698static inline int starts_with_dot_slash(const char *const path) 699{ 700 const enum path_match_flags what = PATH_MATCH_STARTS_WITH_DOT_SLASH; 701 702 return path_match_flags(path, what | PATH_MATCH_XPLATFORM); 703} 704 705/** 706 * starts_with_dot_dot_slash: convenience wrapper for 707 * patch_match_flags() with PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH and 708 * PATH_MATCH_XPLATFORM. 709 */ 710static inline int starts_with_dot_dot_slash(const char *const path) 711{ 712 const enum path_match_flags what = PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH; 713 714 return path_match_flags(path, what | PATH_MATCH_XPLATFORM); 715} 716#endif