/* * Copyright (C) the libgit2 contributors. All rights reserved. * * This file is part of libgit2, distributed under the GNU GPL v2 with * a Linking Exception. For full terms see the included COPYING file. */ #ifndef INCLUDE_attr_file_h__ #define INCLUDE_attr_file_h__ #include "git2/oid.h" #include "git2/attr.h" #include "vector.h" #include "pool.h" #include "buffer.h" #include "fileops.h" #define GIT_ATTR_FILE ".gitattributes" #define GIT_ATTR_FILE_INREPO "attributes" #define GIT_ATTR_FILE_SYSTEM "gitattributes" #define GIT_ATTR_FILE_XDG "attributes" #define GIT_ATTR_FNMATCH_NEGATIVE (1U << 0) #define GIT_ATTR_FNMATCH_DIRECTORY (1U << 1) #define GIT_ATTR_FNMATCH_FULLPATH (1U << 2) #define GIT_ATTR_FNMATCH_MACRO (1U << 3) #define GIT_ATTR_FNMATCH_IGNORE (1U << 4) #define GIT_ATTR_FNMATCH_HASWILD (1U << 5) #define GIT_ATTR_FNMATCH_ALLOWSPACE (1U << 6) #define GIT_ATTR_FNMATCH_ICASE (1U << 7) #define GIT_ATTR_FNMATCH_MATCH_ALL (1U << 8) #define GIT_ATTR_FNMATCH_ALLOWNEG (1U << 9) #define GIT_ATTR_FNMATCH_ALLOWMACRO (1U << 10) #define GIT_ATTR_FNMATCH_LEADINGDIR (1U << 11) #define GIT_ATTR_FNMATCH_NOLEADINGDIR (1U << 12) #define GIT_ATTR_FNMATCH__INCOMING \ (GIT_ATTR_FNMATCH_ALLOWSPACE | GIT_ATTR_FNMATCH_ALLOWNEG | \ GIT_ATTR_FNMATCH_ALLOWMACRO | GIT_ATTR_FNMATCH_NOLEADINGDIR) typedef enum { GIT_ATTR_FILE__IN_MEMORY = 0, GIT_ATTR_FILE__FROM_FILE = 1, GIT_ATTR_FILE__FROM_INDEX = 2, GIT_ATTR_FILE_NUM_SOURCES = 3 } git_attr_file_source; extern const char *git_attr__true; extern const char *git_attr__false; extern const char *git_attr__unset; typedef struct { char *pattern; size_t length; char *containing_dir; size_t containing_dir_length; unsigned int flags; } git_attr_fnmatch; typedef struct { git_attr_fnmatch match; git_vector assigns; /* vector of */ } git_attr_rule; typedef struct { git_refcount unused; const char *name; uint32_t name_hash; } git_attr_name; typedef struct { git_refcount rc; /* for macros */ char *name; uint32_t name_hash; const char *value; } git_attr_assignment; typedef struct git_attr_file_entry git_attr_file_entry; typedef struct { git_refcount rc; git_mutex lock; git_attr_file_entry *entry; git_attr_file_source source; git_vector rules; /* vector of or */ git_pool pool; unsigned int nonexistent:1; int session_key; union { git_oid oid; git_futils_filestamp stamp; } cache_data; } git_attr_file; struct git_attr_file_entry { git_attr_file *file[GIT_ATTR_FILE_NUM_SOURCES]; const char *path; /* points into fullpath */ char fullpath[GIT_FLEX_ARRAY]; }; typedef struct { git_buf full; char *path; char *basename; int is_dir; } git_attr_path; /* A git_attr_session can provide an "instance" of reading, to prevent cache * invalidation during a single operation instance (like checkout). */ typedef struct { int key; unsigned int init_setup:1, init_sysdir:1; git_buf sysdir; git_buf tmp; } git_attr_session; extern int git_attr_session__init(git_attr_session *attr_session, git_repository *repo); extern void git_attr_session__free(git_attr_session *session); extern int git_attr_get_many_with_session( const char **values_out, git_repository *repo, git_attr_session *attr_session, uint32_t flags, const char *path, size_t num_attr, const char **names); typedef int (*git_attr_file_parser)( git_repository *repo, git_attr_file *file, const char *data); /* * git_attr_file API */ int git_attr_file__new( git_attr_file **out, git_attr_file_entry *entry, git_attr_file_source source); void git_attr_file__free(git_attr_file *file); int git_attr_file__load( git_attr_file **out, git_repository *repo, git_attr_session *attr_session, git_attr_file_entry *ce, git_attr_file_source source, git_attr_file_parser parser); int git_attr_file__load_standalone( git_attr_file **out, const char *path); int git_attr_file__out_of_date( git_repository *repo, git_attr_session *session, git_attr_file *file); int git_attr_file__parse_buffer( git_repository *repo, git_attr_file *attrs, const char *data); int git_attr_file__clear_rules( git_attr_file *file, bool need_lock); int git_attr_file__lookup_one( git_attr_file *file, git_attr_path *path, const char *attr, const char **value); /* loop over rules in file from bottom to top */ #define git_attr_file__foreach_matching_rule(file, path, iter, rule) \ git_vector_rforeach(&(file)->rules, (iter), (rule)) \ if (git_attr_rule__match((rule), (path))) uint32_t git_attr_file__name_hash(const char *name); /* * other utilities */ extern int git_attr_fnmatch__parse( git_attr_fnmatch *spec, git_pool *pool, const char *source, const char **base); extern bool git_attr_fnmatch__match( git_attr_fnmatch *rule, git_attr_path *path); extern void git_attr_rule__free(git_attr_rule *rule); extern bool git_attr_rule__match( git_attr_rule *rule, git_attr_path *path); extern git_attr_assignment *git_attr_rule__lookup_assignment( git_attr_rule *rule, const char *name); typedef enum { GIT_DIR_FLAG_TRUE = 1, GIT_DIR_FLAG_FALSE = 0, GIT_DIR_FLAG_UNKNOWN = -1 } git_dir_flag; extern int git_attr_path__init( git_attr_path *info, const char *path, const char *base, git_dir_flag is_dir); extern void git_attr_path__free(git_attr_path *info); extern int git_attr_assignment__parse( git_repository *repo, /* needed to expand macros */ git_pool *pool, git_vector *assigns, const char **scan); #endif