Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 217 lines (197 sloc) 6.166 kb
be58e70 Jeff King diff: unify external diff and funcname parsing code
peff authored
1 #include "userdiff.h"
2 #include "cache.h"
3 #include "attr.h"
4
5 static struct userdiff_driver *drivers;
6 static int ndrivers;
7 static int drivers_alloc;
8
ae3b970 Boyd Stephen Smith Jr. Change the spelling of "wordregex".
stephen-smith authored
9 #define PATTERNS(name, pattern, word_regex) \
10 { name, NULL, -1, { pattern, REG_EXTENDED }, word_regex }
be58e70 Jeff King diff: unify external diff and funcname parsing code
peff authored
11 static struct userdiff_driver builtin_drivers[] = {
80c49c3 trast color-words: make regex configurable via attributes
trast authored
12 PATTERNS("html", "^[ \t]*(<[Hh][1-6][ \t].*>.*)$",
13 "[^<>= \t]+|[^[:space:]]|[\x80-\xff]+"),
14 PATTERNS("java",
be58e70 Jeff King diff: unify external diff and funcname parsing code
peff authored
15 "!^[ \t]*(catch|do|for|if|instanceof|new|return|switch|throw|while)\n"
959e2e6 Paolo Bonzini avoid exponential regex match for java and objc function names
bonzini authored
16 "^[ \t]*(([A-Za-z_][A-Za-z_0-9]*[ \t]+)+[A-Za-z_][A-Za-z_0-9]*[ \t]*\\([^;]*)$",
17 /* -- */
80c49c3 trast color-words: make regex configurable via attributes
trast authored
18 "[a-zA-Z_][a-zA-Z0-9_]*"
19 "|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?"
20 "|[-+*/<>%&^|=!]="
21 "|--|\\+\\+|<<=?|>>>?=?|&&|\\|\\|"
22 "|[^[:space:]]|[\x80-\xff]+"),
23 PATTERNS("objc",
be58e70 Jeff King diff: unify external diff and funcname parsing code
peff authored
24 /* Negate C statements that can look like functions */
25 "!^[ \t]*(do|for|if|else|return|switch|while)\n"
26 /* Objective-C methods */
27 "^[ \t]*([-+][ \t]*\\([ \t]*[A-Za-z_][A-Za-z_0-9* \t]*\\)[ \t]*[A-Za-z_].*)$\n"
28 /* C functions */
959e2e6 Paolo Bonzini avoid exponential regex match for java and objc function names
bonzini authored
29 "^[ \t]*(([A-Za-z_][A-Za-z_0-9]*[ \t]+)+[A-Za-z_][A-Za-z_0-9]*[ \t]*\\([^;]*)$\n"
be58e70 Jeff King diff: unify external diff and funcname parsing code
peff authored
30 /* Objective-C class/protocol definitions */
80c49c3 trast color-words: make regex configurable via attributes
trast authored
31 "^(@(implementation|interface|protocol)[ \t].*)$",
32 /* -- */
33 "[a-zA-Z_][a-zA-Z0-9_]*"
34 "|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?"
35 "|[-+*/<>%&^|=!]=|--|\\+\\+|<<=?|>>=?|&&|\\|\\||::|->"
36 "|[^[:space:]]|[\x80-\xff]+"),
37 PATTERNS("pascal",
be58e70 Jeff King diff: unify external diff and funcname parsing code
peff authored
38 "^((procedure|function|constructor|destructor|interface|"
39 "implementation|initialization|finalization)[ \t]*.*)$"
40 "\n"
80c49c3 trast color-words: make regex configurable via attributes
trast authored
41 "^(.*=[ \t]*(class|record).*)$",
42 /* -- */
43 "[a-zA-Z_][a-zA-Z0-9_]*"
44 "|[-+0-9.e]+|0[xXbB]?[0-9a-fA-F]+"
45 "|<>|<=|>=|:=|\\.\\."
46 "|[^[:space:]]|[\x80-\xff]+"),
47 PATTERNS("php", "^[\t ]*((function|class).*)",
48 /* -- */
49 "[a-zA-Z_][a-zA-Z0-9_]*"
50 "|[-+0-9.e]+|0[xXbB]?[0-9a-fA-F]+"
51 "|[-+*/<>%&^|=!.]=|--|\\+\\+|<<=?|>>=?|===|&&|\\|\\||::|->"
52 "|[^[:space:]]|[\x80-\xff]+"),
53 PATTERNS("python", "^[ \t]*((class|def)[ \t].*)$",
54 /* -- */
55 "[a-zA-Z_][a-zA-Z0-9_]*"
56 "|[-+0-9.e]+[jJlL]?|0[xX]?[0-9a-fA-F]+[lL]?"
57 "|[-+*/<>%&^|=!]=|//=?|<<=?|>>=?|\\*\\*=?"
58 "|[^[:space:]|[\x80-\xff]+"),
59 /* -- */
60 PATTERNS("ruby", "^[ \t]*((class|module|def)[ \t].*)$",
61 /* -- */
62 "(@|@@|\\$)?[a-zA-Z_][a-zA-Z0-9_]*"
63 "|[-+0-9.e]+|0[xXbB]?[0-9a-fA-F]+|\\?(\\\\C-)?(\\\\M-)?."
64 "|//=?|[-+*/<>%&^|=!]=|<<=?|>>=?|===|\\.{1,3}|::|[!=]~"
65 "|[^[:space:]|[\x80-\xff]+"),
66 PATTERNS("bibtex", "(@[a-zA-Z]{1,}[ \t]*\\{{0,1}[ \t]*[^ \t\"@',\\#}{~%]*).*$",
67 "[={}\"]|[^={}\" \t]+"),
68 PATTERNS("tex", "^(\\\\((sub)*section|chapter|part)\\*{0,1}\\{.*)$",
69 "\\\\[a-zA-Z@]+|\\\\.|[a-zA-Z0-9\x80-\xff]+|[^[:space:]]"),
70 PATTERNS("cpp",
71 /* Jump targets or access declarations */
72 "!^[ \t]*[A-Za-z_][A-Za-z_0-9]*:.*$\n"
73 /* C/++ functions/methods at top level */
74 "^([A-Za-z_][A-Za-z_0-9]*([ \t]+[A-Za-z_][A-Za-z_0-9]*([ \t]*::[ \t]*[^[:space:]]+)?){1,}[ \t]*\\([^;]*)$\n"
75 /* compound type at top level */
76 "^((struct|class|enum)[^;]*)$",
77 /* -- */
78 "[a-zA-Z_][a-zA-Z0-9_]*"
79 "|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?"
80 "|[-+*/<>%&^|=!]=|--|\\+\\+|<<=?|>>=?|&&|\\|\\||::|->"
81 "|[^[:space:]]|[\x80-\xff]+"),
122aa6f Jeff King diff: introduce diff.<driver>.binary
peff authored
82 { "default", NULL, -1, { NULL, 0 } },
be58e70 Jeff King diff: unify external diff and funcname parsing code
peff authored
83 };
80c49c3 trast color-words: make regex configurable via attributes
trast authored
84 #undef PATTERNS
be58e70 Jeff King diff: unify external diff and funcname parsing code
peff authored
85
86 static struct userdiff_driver driver_true = {
87 "diff=true",
88 NULL,
122aa6f Jeff King diff: introduce diff.<driver>.binary
peff authored
89 0,
be58e70 Jeff King diff: unify external diff and funcname parsing code
peff authored
90 { NULL, 0 }
91 };
92
93 static struct userdiff_driver driver_false = {
94 "!diff",
95 NULL,
122aa6f Jeff King diff: introduce diff.<driver>.binary
peff authored
96 1,
be58e70 Jeff King diff: unify external diff and funcname parsing code
peff authored
97 { NULL, 0 }
98 };
99
100 static struct userdiff_driver *userdiff_find_by_namelen(const char *k, int len)
101 {
102 int i;
103 for (i = 0; i < ndrivers; i++) {
104 struct userdiff_driver *drv = drivers + i;
105 if (!strncmp(drv->name, k, len) && !drv->name[len])
106 return drv;
107 }
108 for (i = 0; i < ARRAY_SIZE(builtin_drivers); i++) {
109 struct userdiff_driver *drv = builtin_drivers + i;
110 if (!strncmp(drv->name, k, len) && !drv->name[len])
111 return drv;
112 }
113 return NULL;
114 }
115
116 static struct userdiff_driver *parse_driver(const char *var,
117 const char *value, const char *type)
118 {
119 struct userdiff_driver *drv;
120 const char *dot;
121 const char *name;
122 int namelen;
123
124 if (prefixcmp(var, "diff."))
125 return NULL;
126 dot = strrchr(var, '.');
127 if (dot == var + 4)
128 return NULL;
129 if (strcmp(type, dot+1))
130 return NULL;
131
132 name = var + 5;
133 namelen = dot - name;
134 drv = userdiff_find_by_namelen(name, namelen);
135 if (!drv) {
136 ALLOC_GROW(drivers, ndrivers+1, drivers_alloc);
137 drv = &drivers[ndrivers++];
138 memset(drv, 0, sizeof(*drv));
139 drv->name = xmemdupz(name, namelen);
122aa6f Jeff King diff: introduce diff.<driver>.binary
peff authored
140 drv->binary = -1;
be58e70 Jeff King diff: unify external diff and funcname parsing code
peff authored
141 }
142 return drv;
143 }
144
145 static int parse_funcname(struct userdiff_funcname *f, const char *k,
146 const char *v, int cflags)
147 {
148 if (git_config_string(&f->pattern, k, v) < 0)
149 return -1;
150 f->cflags = cflags;
151 return 1;
152 }
153
154 static int parse_string(const char **d, const char *k, const char *v)
155 {
156 if (git_config_string(d, k, v) < 0)
157 return -1;
158 return 1;
159 }
160
122aa6f Jeff King diff: introduce diff.<driver>.binary
peff authored
161 static int parse_tristate(int *b, const char *k, const char *v)
162 {
163 if (v && !strcasecmp(v, "auto"))
164 *b = -1;
165 else
166 *b = git_config_bool(k, v);
167 return 1;
168 }
169
c7534ef Jeff King userdiff: require explicitly allowing textconv
peff authored
170 int userdiff_config(const char *k, const char *v)
be58e70 Jeff King diff: unify external diff and funcname parsing code
peff authored
171 {
172 struct userdiff_driver *drv;
173
174 if ((drv = parse_driver(k, v, "funcname")))
175 return parse_funcname(&drv->funcname, k, v, 0);
176 if ((drv = parse_driver(k, v, "xfuncname")))
177 return parse_funcname(&drv->funcname, k, v, REG_EXTENDED);
122aa6f Jeff King diff: introduce diff.<driver>.binary
peff authored
178 if ((drv = parse_driver(k, v, "binary")))
179 return parse_tristate(&drv->binary, k, v);
be58e70 Jeff King diff: unify external diff and funcname parsing code
peff authored
180 if ((drv = parse_driver(k, v, "command")))
181 return parse_string(&drv->external, k, v);
9cb92c3 Jeff King diff: add filter for converting binary to text
peff authored
182 if ((drv = parse_driver(k, v, "textconv")))
183 return parse_string(&drv->textconv, k, v);
80c49c3 trast color-words: make regex configurable via attributes
trast authored
184 if ((drv = parse_driver(k, v, "wordregex")))
185 return parse_string(&drv->word_regex, k, v);
be58e70 Jeff King diff: unify external diff and funcname parsing code
peff authored
186
187 return 0;
188 }
189
190 struct userdiff_driver *userdiff_find_by_name(const char *name) {
191 int len = strlen(name);
192 return userdiff_find_by_namelen(name, len);
193 }
194
195 struct userdiff_driver *userdiff_find_by_path(const char *path)
196 {
197 static struct git_attr *attr;
198 struct git_attr_check check;
199
200 if (!attr)
201 attr = git_attr("diff", 4);
202 check.attr = attr;
203
204 if (!path)
205 return NULL;
206 if (git_checkattr(path, 1, &check))
207 return NULL;
208
209 if (ATTR_TRUE(check.value))
210 return &driver_true;
211 if (ATTR_FALSE(check.value))
212 return &driver_false;
213 if (ATTR_UNSET(check.value))
214 return NULL;
215 return userdiff_find_by_name(check.value);
216 }
Something went wrong with that request. Please try again.