1111#include "attr.h"
1212#include "run-command.h"
1313#include "utf8.h"
14+ #include "userdiff.h"
1415
1516#ifdef NO_FAST_WORKING_DIRECTORY
1617#define FAST_WORKING_DIRECTORY 0
@@ -56,80 +57,6 @@ static int parse_diff_color_slot(const char *var, int ofs)
5657 die ("bad config variable '%s'" , var );
5758}
5859
59- static struct ll_diff_driver {
60- const char * name ;
61- struct ll_diff_driver * next ;
62- const char * cmd ;
63- } * user_diff , * * user_diff_tail ;
64-
65- /*
66- * Currently there is only "diff.<drivername>.command" variable;
67- * because there are "diff.color.<slot>" variables, we are parsing
68- * this in a bit convoluted way to allow low level diff driver
69- * called "color".
70- */
71- static int parse_lldiff_command (const char * var , const char * ep , const char * value )
72- {
73- const char * name ;
74- int namelen ;
75- struct ll_diff_driver * drv ;
76-
77- name = var + 5 ;
78- namelen = ep - name ;
79- for (drv = user_diff ; drv ; drv = drv -> next )
80- if (!strncmp (drv -> name , name , namelen ) && !drv -> name [namelen ])
81- break ;
82- if (!drv ) {
83- drv = xcalloc (1 , sizeof (struct ll_diff_driver ));
84- drv -> name = xmemdupz (name , namelen );
85- if (!user_diff_tail )
86- user_diff_tail = & user_diff ;
87- * user_diff_tail = drv ;
88- user_diff_tail = & (drv -> next );
89- }
90-
91- return git_config_string (& (drv -> cmd ), var , value );
92- }
93-
94- /*
95- * 'diff.<what>.funcname' attribute can be specified in the configuration
96- * to define a customized regexp to find the beginning of a function to
97- * be used for hunk header lines of "diff -p" style output.
98- */
99- struct funcname_pattern_entry {
100- char * name ;
101- char * pattern ;
102- int cflags ;
103- };
104- static struct funcname_pattern_list {
105- struct funcname_pattern_list * next ;
106- struct funcname_pattern_entry e ;
107- } * funcname_pattern_list ;
108-
109- static int parse_funcname_pattern (const char * var , const char * ep , const char * value , int cflags )
110- {
111- const char * name ;
112- int namelen ;
113- struct funcname_pattern_list * pp ;
114-
115- name = var + 5 ; /* "diff." */
116- namelen = ep - name ;
117-
118- for (pp = funcname_pattern_list ; pp ; pp = pp -> next )
119- if (!strncmp (pp -> e .name , name , namelen ) && !pp -> e .name [namelen ])
120- break ;
121- if (!pp ) {
122- pp = xcalloc (1 , sizeof (* pp ));
123- pp -> e .name = xmemdupz (name , namelen );
124- pp -> next = funcname_pattern_list ;
125- funcname_pattern_list = pp ;
126- }
127- free (pp -> e .pattern );
128- pp -> e .pattern = xstrdup (value );
129- pp -> e .cflags = cflags ;
130- return 0 ;
131- }
132-
13360/*
13461 * These are to give UI layer defaults.
13562 * The core-level commands such as git-diff-files should
@@ -162,11 +89,11 @@ int git_diff_ui_config(const char *var, const char *value, void *cb)
16289 }
16390 if (!strcmp (var , "diff.external" ))
16491 return git_config_string (& external_diff_cmd_cfg , var , value );
165- if (!prefixcmp (var , "diff." )) {
166- const char * ep = strrchr (var , '.' );
16792
168- if (ep != var + 4 && !strcmp (ep , ".command" ))
169- return parse_lldiff_command (var , ep , value );
93+ switch (userdiff_config_porcelain (var , value )) {
94+ case 0 : break ;
95+ case -1 : return -1 ;
96+ default : return 0 ;
17097 }
17198
17299 return git_diff_basic_config (var , value , cb );
@@ -193,21 +120,10 @@ int git_diff_basic_config(const char *var, const char *value, void *cb)
193120 return 0 ;
194121 }
195122
196- if (!prefixcmp (var , "diff." )) {
197- const char * ep = strrchr (var , '.' );
198- if (ep != var + 4 ) {
199- if (!strcmp (ep , ".funcname" )) {
200- if (!value )
201- return config_error_nonbool (var );
202- return parse_funcname_pattern (var , ep , value ,
203- 0 );
204- } else if (!strcmp (ep , ".xfuncname" )) {
205- if (!value )
206- return config_error_nonbool (var );
207- return parse_funcname_pattern (var , ep , value ,
208- REG_EXTENDED );
209- }
210- }
123+ switch (userdiff_config_basic (var , value )) {
124+ case 0 : break ;
125+ case -1 : return -1 ;
126+ default : return 0 ;
211127 }
212128
213129 return git_color_default_config (var , value , cb );
@@ -1352,46 +1268,24 @@ static void emit_binary_diff(FILE *file, mmfile_t *one, mmfile_t *two)
13521268 emit_binary_diff_body (file , two , one );
13531269}
13541270
1355- static void setup_diff_attr_check (struct git_attr_check * check )
1356- {
1357- static struct git_attr * attr_diff ;
1358-
1359- if (!attr_diff ) {
1360- attr_diff = git_attr ("diff" , 4 );
1361- }
1362- check [0 ].attr = attr_diff ;
1363- }
1364-
13651271static void diff_filespec_check_attr (struct diff_filespec * one )
13661272{
1367- struct git_attr_check attr_diff_check ;
1273+ struct userdiff_driver * drv ;
13681274 int check_from_data = 0 ;
13691275
13701276 if (one -> checked_attr )
13711277 return ;
13721278
1373- setup_diff_attr_check ( & attr_diff_check );
1279+ drv = userdiff_find_by_path ( one -> path );
13741280 one -> is_binary = 0 ;
1375- one -> funcname_pattern_ident = NULL ;
13761281
1377- if (!git_checkattr (one -> path , 1 , & attr_diff_check )) {
1378- const char * value ;
1379-
1380- /* binaryness */
1381- value = attr_diff_check .value ;
1382- if (ATTR_TRUE (value ))
1383- ;
1384- else if (ATTR_FALSE (value ))
1385- one -> is_binary = 1 ;
1386- else
1387- check_from_data = 1 ;
1388-
1389- /* funcname pattern ident */
1390- if (ATTR_TRUE (value ) || ATTR_FALSE (value ) || ATTR_UNSET (value ))
1391- ;
1392- else
1393- one -> funcname_pattern_ident = value ;
1394- }
1282+ /* binaryness */
1283+ if (drv == USERDIFF_ATTR_TRUE )
1284+ ;
1285+ else if (drv == USERDIFF_ATTR_FALSE )
1286+ one -> is_binary = 1 ;
1287+ else
1288+ check_from_data = 1 ;
13951289
13961290 if (check_from_data ) {
13971291 if (!one -> data && DIFF_FILE_VALID (one ))
@@ -1408,80 +1302,12 @@ int diff_filespec_is_binary(struct diff_filespec *one)
14081302 return one -> is_binary ;
14091303}
14101304
1411- static const struct funcname_pattern_entry * funcname_pattern (const char * ident )
1412- {
1413- struct funcname_pattern_list * pp ;
1414-
1415- for (pp = funcname_pattern_list ; pp ; pp = pp -> next )
1416- if (!strcmp (ident , pp -> e .name ))
1417- return & pp -> e ;
1418- return NULL ;
1419- }
1420-
1421- static const struct funcname_pattern_entry builtin_funcname_pattern [] = {
1422- { "bibtex" , "(@[a-zA-Z]{1,}[ \t]*\\{{0,1}[ \t]*[^ \t\"@',\\#}{~%]*).*$" ,
1423- REG_EXTENDED },
1424- { "html" , "^[ \t]*(<[Hh][1-6][ \t].*>.*)$" , REG_EXTENDED },
1425- { "java" ,
1426- "!^[ \t]*(catch|do|for|if|instanceof|new|return|switch|throw|while)\n"
1427- "^[ \t]*(([ \t]*[A-Za-z_][A-Za-z_0-9]*){2,}[ \t]*\\([^;]*)$" ,
1428- REG_EXTENDED },
1429- { "objc" ,
1430- /* Negate C statements that can look like functions */
1431- "!^[ \t]*(do|for|if|else|return|switch|while)\n"
1432- /* Objective-C methods */
1433- "^[ \t]*([-+][ \t]*\\([ \t]*[A-Za-z_][A-Za-z_0-9* \t]*\\)[ \t]*[A-Za-z_].*)$\n"
1434- /* C functions */
1435- "^[ \t]*(([ \t]*[A-Za-z_][A-Za-z_0-9]*){2,}[ \t]*\\([^;]*)$\n"
1436- /* Objective-C class/protocol definitions */
1437- "^(@(implementation|interface|protocol)[ \t].*)$" ,
1438- REG_EXTENDED },
1439- { "pascal" ,
1440- "^((procedure|function|constructor|destructor|interface|"
1441- "implementation|initialization|finalization)[ \t]*.*)$"
1442- "\n"
1443- "^(.*=[ \t]*(class|record).*)$" ,
1444- REG_EXTENDED },
1445- { "php" , "^[\t ]*((function|class).*)" , REG_EXTENDED },
1446- { "python" , "^[ \t]*((class|def)[ \t].*)$" , REG_EXTENDED },
1447- { "ruby" , "^[ \t]*((class|module|def)[ \t].*)$" ,
1448- REG_EXTENDED },
1449- { "tex" ,
1450- "^(\\\\((sub)*section|chapter|part)\\*{0,1}\\{.*)$" ,
1451- REG_EXTENDED },
1452- };
1453-
1454- static const struct funcname_pattern_entry * diff_funcname_pattern (struct diff_filespec * one )
1305+ static const struct userdiff_funcname * diff_funcname_pattern (struct diff_filespec * one )
14551306{
1456- const char * ident ;
1457- const struct funcname_pattern_entry * pe ;
1458- int i ;
1459-
1460- diff_filespec_check_attr (one );
1461- ident = one -> funcname_pattern_ident ;
1462-
1463- if (!ident )
1464- /*
1465- * If the config file has "funcname.default" defined, that
1466- * regexp is used; otherwise NULL is returned and xemit uses
1467- * the built-in default.
1468- */
1469- return funcname_pattern ("default" );
1470-
1471- /* Look up custom "funcname.$ident" regexp from config. */
1472- pe = funcname_pattern (ident );
1473- if (pe )
1474- return pe ;
1475-
1476- /*
1477- * And define built-in fallback patterns here. Note that
1478- * these can be overridden by the user's config settings.
1479- */
1480- for (i = 0 ; i < ARRAY_SIZE (builtin_funcname_pattern ); i ++ )
1481- if (!strcmp (ident , builtin_funcname_pattern [i ].name ))
1482- return & builtin_funcname_pattern [i ];
1483-
1484- return NULL ;
1307+ struct userdiff_driver * drv = userdiff_find_by_path (one -> path );
1308+ if (!drv )
1309+ drv = userdiff_find_by_name ("default" );
1310+ return drv && drv -> funcname .pattern ? & drv -> funcname : NULL ;
14851311}
14861312
14871313void diff_set_mnemonic_prefix (struct diff_options * options , const char * a , const char * b )
@@ -1579,7 +1405,7 @@ static void builtin_diff(const char *name_a,
15791405 xdemitconf_t xecfg ;
15801406 xdemitcb_t ecb ;
15811407 struct emit_callback ecbdata ;
1582- const struct funcname_pattern_entry * pe ;
1408+ const struct userdiff_funcname * pe ;
15831409
15841410 pe = diff_funcname_pattern (one );
15851411 if (!pe )
@@ -2117,29 +1943,6 @@ static void run_external_diff(const char *pgm,
21171943 }
21181944}
21191945
2120- static const char * external_diff_attr (const char * name )
2121- {
2122- struct git_attr_check attr_diff_check ;
2123-
2124- if (!name )
2125- return NULL ;
2126-
2127- setup_diff_attr_check (& attr_diff_check );
2128- if (!git_checkattr (name , 1 , & attr_diff_check )) {
2129- const char * value = attr_diff_check .value ;
2130- if (!ATTR_TRUE (value ) &&
2131- !ATTR_FALSE (value ) &&
2132- !ATTR_UNSET (value )) {
2133- struct ll_diff_driver * drv ;
2134-
2135- for (drv = user_diff ; drv ; drv = drv -> next )
2136- if (!strcmp (drv -> name , value ))
2137- return drv -> cmd ;
2138- }
2139- }
2140- return NULL ;
2141- }
2142-
21431946static void run_diff_cmd (const char * pgm ,
21441947 const char * name ,
21451948 const char * other ,
@@ -2153,9 +1956,9 @@ static void run_diff_cmd(const char *pgm,
21531956 if (!DIFF_OPT_TST (o , ALLOW_EXTERNAL ))
21541957 pgm = NULL ;
21551958 else {
2156- const char * cmd = external_diff_attr (attr_path );
2157- if (cmd )
2158- pgm = cmd ;
1959+ struct userdiff_driver * drv = userdiff_find_by_path (attr_path );
1960+ if (drv && drv -> external )
1961+ pgm = drv -> external ;
21591962 }
21601963
21611964 if (pgm ) {
0 commit comments