1 /* 2 * Copyright (C) the libgit2 contributors. All rights reserved. 3 * 4 * This file is part of libgit2, distributed under the GNU GPL v2 with 5 * a Linking Exception. For full terms see the included COPYING file. 6 */ 7 #ifndef INCLUDE_attr_file_h__ 8 #define INCLUDE_attr_file_h__ 9 10 #include "common.h" 11 12 #include "git2/oid.h" 13 #include "git2/attr.h" 14 #include "vector.h" 15 #include "pool.h" 16 #include "buffer.h" 17 #include "futils.h" 18 19 #define GIT_ATTR_FILE ".gitattributes" 20 #define GIT_ATTR_FILE_INREPO "attributes" 21 #define GIT_ATTR_FILE_SYSTEM "gitattributes" 22 #define GIT_ATTR_FILE_XDG "attributes" 23 24 #define GIT_ATTR_FNMATCH_NEGATIVE (1U << 0) 25 #define GIT_ATTR_FNMATCH_DIRECTORY (1U << 1) 26 #define GIT_ATTR_FNMATCH_FULLPATH (1U << 2) 27 #define GIT_ATTR_FNMATCH_MACRO (1U << 3) 28 #define GIT_ATTR_FNMATCH_IGNORE (1U << 4) 29 #define GIT_ATTR_FNMATCH_HASWILD (1U << 5) 30 #define GIT_ATTR_FNMATCH_ALLOWSPACE (1U << 6) 31 #define GIT_ATTR_FNMATCH_ICASE (1U << 7) 32 #define GIT_ATTR_FNMATCH_MATCH_ALL (1U << 8) 33 #define GIT_ATTR_FNMATCH_ALLOWNEG (1U << 9) 34 #define GIT_ATTR_FNMATCH_ALLOWMACRO (1U << 10) 35 36 #define GIT_ATTR_FNMATCH__INCOMING \ 37 (GIT_ATTR_FNMATCH_ALLOWSPACE | GIT_ATTR_FNMATCH_ALLOWNEG | GIT_ATTR_FNMATCH_ALLOWMACRO) 38 39 typedef enum { 40 GIT_ATTR_FILE__IN_MEMORY = 0, 41 GIT_ATTR_FILE__FROM_FILE = 1, 42 GIT_ATTR_FILE__FROM_INDEX = 2, 43 GIT_ATTR_FILE__FROM_HEAD = 3, 44 45 GIT_ATTR_FILE_NUM_SOURCES = 4 46 } git_attr_file_source; 47 48 extern const char *git_attr__true; 49 extern const char *git_attr__false; 50 extern const char *git_attr__unset; 51 52 typedef struct { 53 char *pattern; 54 size_t length; 55 char *containing_dir; 56 size_t containing_dir_length; 57 unsigned int flags; 58 } git_attr_fnmatch; 59 60 typedef struct { 61 git_attr_fnmatch match; 62 git_vector assigns; /* vector of <git_attr_assignment*> */ 63 } git_attr_rule; 64 65 typedef struct { 66 git_refcount unused; 67 const char *name; 68 uint32_t name_hash; 69 } git_attr_name; 70 71 typedef struct { 72 git_refcount rc; /* for macros */ 73 char *name; 74 uint32_t name_hash; 75 const char *value; 76 } git_attr_assignment; 77 78 typedef struct git_attr_file_entry git_attr_file_entry; 79 80 typedef struct { 81 git_refcount rc; 82 git_mutex lock; 83 git_attr_file_entry *entry; 84 git_attr_file_source source; 85 git_vector rules; /* vector of <rule*> or <fnmatch*> */ 86 git_pool pool; 87 unsigned int nonexistent:1; 88 int session_key; 89 union { 90 git_oid oid; 91 git_futils_filestamp stamp; 92 } cache_data; 93 } git_attr_file; 94 95 struct git_attr_file_entry { 96 git_attr_file *file[GIT_ATTR_FILE_NUM_SOURCES]; 97 const char *path; /* points into fullpath */ 98 char fullpath[GIT_FLEX_ARRAY]; 99 }; 100 101 typedef struct { 102 git_buf full; 103 char *path; 104 char *basename; 105 int is_dir; 106 } git_attr_path; 107 108 /* A git_attr_session can provide an "instance" of reading, to prevent cache 109 * invalidation during a single operation instance (like checkout). 110 */ 111 112 typedef struct { 113 int key; 114 unsigned int init_setup:1, 115 init_sysdir:1; 116 git_buf sysdir; 117 git_buf tmp; 118 } git_attr_session; 119 120 extern int git_attr_session__init(git_attr_session *attr_session, git_repository *repo); 121 extern void git_attr_session__free(git_attr_session *session); 122 123 extern int git_attr_get_many_with_session( 124 const char **values_out, 125 git_repository *repo, 126 git_attr_session *attr_session, 127 uint32_t flags, 128 const char *path, 129 size_t num_attr, 130 const char **names); 131 132 typedef int (*git_attr_file_parser)( 133 git_repository *repo, 134 git_attr_file *file, 135 const char *data, 136 bool allow_macros); 137 138 /* 139 * git_attr_file API 140 */ 141 142 int git_attr_file__new( 143 git_attr_file **out, 144 git_attr_file_entry *entry, 145 git_attr_file_source source); 146 147 void git_attr_file__free(git_attr_file *file); 148 149 int git_attr_file__load( 150 git_attr_file **out, 151 git_repository *repo, 152 git_attr_session *attr_session, 153 git_attr_file_entry *ce, 154 git_attr_file_source source, 155 git_attr_file_parser parser, 156 bool allow_macros); 157 158 int git_attr_file__load_standalone( 159 git_attr_file **out, const char *path); 160 161 int git_attr_file__out_of_date( 162 git_repository *repo, git_attr_session *session, git_attr_file *file); 163 164 int git_attr_file__parse_buffer( 165 git_repository *repo, git_attr_file *attrs, const char *data, bool allow_macros); 166 167 int git_attr_file__clear_rules( 168 git_attr_file *file, bool need_lock); 169 170 int git_attr_file__lookup_one( 171 git_attr_file *file, 172 git_attr_path *path, 173 const char *attr, 174 const char **value); 175 176 /* loop over rules in file from bottom to top */ 177 #define git_attr_file__foreach_matching_rule(file, path, iter, rule) \ 178 git_vector_rforeach(&(file)->rules, (iter), (rule)) \ 179 if (git_attr_rule__match((rule), (path))) 180 181 uint32_t git_attr_file__name_hash(const char *name); 182 183 184 /* 185 * other utilities 186 */ 187 188 extern int git_attr_fnmatch__parse( 189 git_attr_fnmatch *spec, 190 git_pool *pool, 191 const char *source, 192 const char **base); 193 194 extern bool git_attr_fnmatch__match( 195 git_attr_fnmatch *rule, 196 git_attr_path *path); 197 198 extern void git_attr_rule__free(git_attr_rule *rule); 199 200 extern bool git_attr_rule__match( 201 git_attr_rule *rule, 202 git_attr_path *path); 203 204 extern git_attr_assignment *git_attr_rule__lookup_assignment( 205 git_attr_rule *rule, const char *name); 206 207 typedef enum { GIT_DIR_FLAG_TRUE = 1, GIT_DIR_FLAG_FALSE = 0, GIT_DIR_FLAG_UNKNOWN = -1 } git_dir_flag; 208 209 extern int git_attr_path__init( 210 git_attr_path *info, const char *path, const char *base, git_dir_flag is_dir); 211 212 extern void git_attr_path__free(git_attr_path *info); 213 214 extern int git_attr_assignment__parse( 215 git_repository *repo, /* needed to expand macros */ 216 git_pool *pool, 217 git_vector *assigns, 218 const char **scan); 219 220 #endif 221