"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?"
"|[-+*/<>%&^|=!]="
"|--|\\+\\+|<<=?|>>>?=?|&&|\\|\\|"),
+PATTERNS("matlab",
+ "^[[:space:]]*((classdef|function)[[:space:]].*)$|^%%[[:space:]].*$",
+ "[a-zA-Z_][a-zA-Z0-9_]*|[-+0-9.e]+|[=~<>]=|\\.[*/\\^']|\\|\\||&&"),
PATTERNS("objc",
/* Negate C statements that can look like functions */
"!^[ \t]*(do|for|if|else|return|switch|while)\n"
"|[-+0-9.e]+|0[xXbB]?[0-9a-fA-F]+"
"|<>|<=|>=|:=|\\.\\."),
PATTERNS("perl",
- "^[ \t]*package .*;\n"
- "^[ \t]*sub .* \\{\n"
- "^[A-Z]+ \\{\n" /* BEGIN, END, ... */
- "^=head[0-9] ", /* POD */
+ "^package .*\n"
+ "^sub [[:alnum:]_':]+[ \t]*"
+ "(\\([^)]*\\)[ \t]*)?" /* prototype */
+ /*
+ * Attributes. A regex can't count nested parentheses,
+ * so just slurp up whatever we see, taking care not
+ * to accept lines like "sub foo; # defined elsewhere".
+ *
+ * An attribute could contain a semicolon, but at that
+ * point it seems reasonable enough to give up.
+ */
+ "(:[^;#]*)?"
+ "(\\{[ \t]*)?" /* brace can come here or on the next line */
+ "(#.*)?$\n" /* comment */
+ "^(BEGIN|END|INIT|CHECK|UNITCHECK|AUTOLOAD|DESTROY)[ \t]*"
+ "(\\{[ \t]*)?" /* brace can come here or on the next line */
+ "(#.*)?$\n"
+ "^=head[0-9] .*", /* POD */
/* -- */
"[[:alpha:]_'][[:alnum:]_']*"
"|0[xb]?[0-9a-fA-F_]*"
/* Jump targets or access declarations */
"!^[ \t]*[A-Za-z_][A-Za-z_0-9]*:.*$\n"
/* C/++ functions/methods at top level */
- "^([A-Za-z_][A-Za-z_0-9]*([ \t]+[A-Za-z_][A-Za-z_0-9]*([ \t]*::[ \t]*[^[:space:]]+)?){1,}[ \t]*\\([^;]*)$\n"
+ "^([A-Za-z_][A-Za-z_0-9]*([ \t*]+[A-Za-z_][A-Za-z_0-9]*([ \t]*::[ \t]*[^[:space:]]+)?){1,}[ \t]*\\([^;]*)$\n"
/* compound type at top level */
"^((struct|class|enum)[^;]*)$",
/* -- */
if (git_config_string(&f->pattern, k, v) < 0)
return -1;
f->cflags = cflags;
- return 1;
-}
-
-static int parse_string(const char **d, const char *k, const char *v)
-{
- if (git_config_string(d, k, v) < 0)
- return -1;
- return 1;
+ return 0;
}
static int parse_tristate(int *b, const char *k, const char *v)
*b = -1;
else
*b = git_config_bool(k, v);
- return 1;
+ return 0;
}
static int parse_bool(int *b, const char *k, const char *v)
{
*b = git_config_bool(k, v);
- return 1;
+ return 0;
}
int userdiff_config(const char *k, const char *v)
if ((drv = parse_driver(k, v, "binary")))
return parse_tristate(&drv->binary, k, v);
if ((drv = parse_driver(k, v, "command")))
- return parse_string(&drv->external, k, v);
+ return git_config_string(&drv->external, k, v);
if ((drv = parse_driver(k, v, "textconv")))
- return parse_string(&drv->textconv, k, v);
+ return git_config_string(&drv->textconv, k, v);
if ((drv = parse_driver(k, v, "cachetextconv")))
return parse_bool(&drv->textconv_want_cache, k, v);
if ((drv = parse_driver(k, v, "wordregex")))
- return parse_string(&drv->word_regex, k, v);
+ return git_config_string(&drv->word_regex, k, v);
return 0;
}
if (!path)
return NULL;
- if (git_checkattr(path, 1, &check))
+ if (git_check_attr(path, 1, &check))
return NULL;
if (ATTR_TRUE(check.value))
return NULL;
return userdiff_find_by_name(check.value);
}
+
+struct userdiff_driver *userdiff_get_textconv(struct userdiff_driver *driver)
+{
+ if (!driver->textconv)
+ return NULL;
+
+ if (driver->textconv_want_cache && !driver->textconv_cache) {
+ struct notes_cache *c = xmalloc(sizeof(*c));
+ struct strbuf name = STRBUF_INIT;
+
+ strbuf_addf(&name, "textconv/%s", driver->name);
+ notes_cache_init(c, name.buf, driver->textconv);
+ driver->textconv_cache = c;
+ }
+
+ return driver;
+}