Commit 0c9eacf3 by Vicent Marti

attr: Do not export variables externally

Fixes #824

Exporting variables in a dynamic library is a PITA. Let's keep
these values internally and wrap them through a helper method.

This doesn't break the external API. @arrbee, aren't you glad I turned
the `GIT_ATTR_` macros into function macros? 
parent cf81ded6
...@@ -30,7 +30,7 @@ GIT_BEGIN_DECL ...@@ -30,7 +30,7 @@ GIT_BEGIN_DECL
* Then for file `xyz.c` looking up attribute "foo" gives a value for * Then for file `xyz.c` looking up attribute "foo" gives a value for
* which `GIT_ATTR_TRUE(value)` is true. * which `GIT_ATTR_TRUE(value)` is true.
*/ */
#define GIT_ATTR_TRUE(attr) ((attr) == git_l_attr__true) #define GIT_ATTR_TRUE(attr) (git_attr_value(attr) == GIT_ATTR_TRUE_T)
/** /**
* GIT_ATTR_FALSE checks if an attribute is set off. In core git * GIT_ATTR_FALSE checks if an attribute is set off. In core git
...@@ -44,7 +44,7 @@ GIT_BEGIN_DECL ...@@ -44,7 +44,7 @@ GIT_BEGIN_DECL
* Then for file `zyx.h` looking up attribute "foo" gives a value for * Then for file `zyx.h` looking up attribute "foo" gives a value for
* which `GIT_ATTR_FALSE(value)` is true. * which `GIT_ATTR_FALSE(value)` is true.
*/ */
#define GIT_ATTR_FALSE(attr) ((attr) == git_l_attr__false) #define GIT_ATTR_FALSE(attr) (git_attr_value(attr) == GIT_ATTR_FALSE_T)
/** /**
* GIT_ATTR_UNSPECIFIED checks if an attribute is unspecified. This * GIT_ATTR_UNSPECIFIED checks if an attribute is unspecified. This
...@@ -62,7 +62,7 @@ GIT_BEGIN_DECL ...@@ -62,7 +62,7 @@ GIT_BEGIN_DECL
* file `onefile.rb` or looking up "bar" on any file will all give * file `onefile.rb` or looking up "bar" on any file will all give
* `GIT_ATTR_UNSPECIFIED(value)` of true. * `GIT_ATTR_UNSPECIFIED(value)` of true.
*/ */
#define GIT_ATTR_UNSPECIFIED(attr) (!(attr) || (attr) == git_l_attr__unset) #define GIT_ATTR_UNSPECIFIED(attr) (git_attr_value(attr) == GIT_ATTR_UNSPECIFIED_T)
/** /**
* GIT_ATTR_HAS_VALUE checks if an attribute is set to a value (as * GIT_ATTR_HAS_VALUE checks if an attribute is set to a value (as
...@@ -74,13 +74,29 @@ GIT_BEGIN_DECL ...@@ -74,13 +74,29 @@ GIT_BEGIN_DECL
* Given this, looking up "eol" for `onefile.txt` will give back the * Given this, looking up "eol" for `onefile.txt` will give back the
* string "lf" and `GIT_ATTR_SET_TO_VALUE(attr)` will return true. * string "lf" and `GIT_ATTR_SET_TO_VALUE(attr)` will return true.
*/ */
#define GIT_ATTR_HAS_VALUE(attr) \ #define GIT_ATTR_HAS_VALUE(attr) (git_attr_value(attr) == GIT_ATTR_VALUE_T)
((attr) && (attr) != git_l_attr__unset && \
(attr) != git_l_attr__true && (attr) != git_attr__false)
GIT_EXTERN(const char *) git_l_attr__true; typedef enum {
GIT_EXTERN(const char *) git_l_attr__false; GIT_ATTR_UNSPECIFIED_T = 0,
GIT_EXTERN(const char *) git_l_attr__unset; GIT_ATTR_TRUE_T,
GIT_ATTR_FALSE_T,
GIT_ATTR_VALUE_T,
} git_attr_t;
/*
* Return the value type for a given attribute.
*
* This can be either `TRUE`, `FALSE`, `UNSPECIFIED` (if the attribute
* was not set at all), or `VALUE`, if the attribute was set to
* an actual string.
*
* If the attribute has a `VALUE` string, it can be accessed normally
* as a NULL-terminated C string.
*
* @param attr The attribute
* @return the value type for the attribute
*/
git_attr_t git_attr_value(const char *attr);
/** /**
* Check attribute flags: Reading values from index and working directory. * Check attribute flags: Reading values from index and working directory.
......
...@@ -5,6 +5,25 @@ ...@@ -5,6 +5,25 @@
GIT__USE_STRMAP; GIT__USE_STRMAP;
const char *git_attr__true = "[internal]__TRUE__";
const char *git_attr__false = "[internal]__FALSE__";
const char *git_attr__unset = "[internal]__UNSET__";
git_attr_t git_attr_value(const char *attr)
{
if (attr == NULL || attr == git_attr__unset)
return GIT_ATTR_UNSPECIFIED_T;
if (attr == git_attr__true)
return GIT_ATTR_TRUE_T;
if (attr == git_attr__false)
return GIT_ATTR_FALSE_T;
return GIT_ATTR_VALUE_T;
}
static int collect_attr_files( static int collect_attr_files(
git_repository *repo, git_repository *repo,
uint32_t flags, uint32_t flags,
......
...@@ -5,10 +5,6 @@ ...@@ -5,10 +5,6 @@
#include "git2/tree.h" #include "git2/tree.h"
#include <ctype.h> #include <ctype.h>
const char *git_l_attr__true = "[internal]__TRUE__";
const char *git_l_attr__false = "[internal]__FALSE__";
const char *git_l_attr__unset = "[internal]__UNSET__";
static int sort_by_hash_and_name(const void *a_raw, const void *b_raw); static int sort_by_hash_and_name(const void *a_raw, const void *b_raw);
static void git_attr_rule__clear(git_attr_rule *rule); static void git_attr_rule__clear(git_attr_rule *rule);
...@@ -493,14 +489,14 @@ int git_attr_assignment__parse( ...@@ -493,14 +489,14 @@ int git_attr_assignment__parse(
} }
assign->name_hash = 5381; assign->name_hash = 5381;
assign->value = git_l_attr__true; assign->value = git_attr__true;
/* look for magic name prefixes */ /* look for magic name prefixes */
if (*scan == '-') { if (*scan == '-') {
assign->value = git_l_attr__false; assign->value = git_attr__false;
scan++; scan++;
} else if (*scan == '!') { } else if (*scan == '!') {
assign->value = git_l_attr__unset; /* explicit unspecified state */ assign->value = git_attr__unset; /* explicit unspecified state */
scan++; scan++;
} else if (*scan == '#') /* comment rest of line */ } else if (*scan == '#') /* comment rest of line */
break; break;
...@@ -536,7 +532,7 @@ int git_attr_assignment__parse( ...@@ -536,7 +532,7 @@ int git_attr_assignment__parse(
} }
/* expand macros (if given a repo with a macro cache) */ /* expand macros (if given a repo with a macro cache) */
if (repo != NULL && assign->value == git_l_attr__true) { if (repo != NULL && assign->value == git_attr__true) {
git_attr_rule *macro = git_attr_rule *macro =
git_attr_cache__lookup_macro(repo, assign->name); git_attr_cache__lookup_macro(repo, assign->name);
......
...@@ -24,6 +24,10 @@ ...@@ -24,6 +24,10 @@
#define GIT_ATTR_FNMATCH_HASWILD (1U << 5) #define GIT_ATTR_FNMATCH_HASWILD (1U << 5)
#define GIT_ATTR_FNMATCH_ALLOWSPACE (1U << 6) #define GIT_ATTR_FNMATCH_ALLOWSPACE (1U << 6)
extern const char *git_attr__true;
extern const char *git_attr__false;
extern const char *git_attr__unset;
typedef struct { typedef struct {
char *pattern; char *pattern;
size_t length; size_t length;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment