ws.con commit Merge branch 'jc/shortlog-e' (cd1bea9)
   1/*
   2 * Whitespace rules
   3 *
   4 * Copyright (c) 2007 Junio C Hamano
   5 */
   6
   7#include "cache.h"
   8#include "attr.h"
   9
  10static struct whitespace_rule {
  11        const char *rule_name;
  12        unsigned rule_bits;
  13} whitespace_rule_names[] = {
  14        { "trailing-space", WS_TRAILING_SPACE },
  15        { "space-before-tab", WS_SPACE_BEFORE_TAB },
  16        { "indent-with-non-tab", WS_INDENT_WITH_NON_TAB },
  17};
  18
  19unsigned parse_whitespace_rule(const char *string)
  20{
  21        unsigned rule = WS_DEFAULT_RULE;
  22
  23        while (string) {
  24                int i;
  25                size_t len;
  26                const char *ep;
  27                int negated = 0;
  28
  29                string = string + strspn(string, ", \t\n\r");
  30                ep = strchr(string, ',');
  31                if (!ep)
  32                        len = strlen(string);
  33                else
  34                        len = ep - string;
  35
  36                if (*string == '-') {
  37                        negated = 1;
  38                        string++;
  39                        len--;
  40                }
  41                if (!len)
  42                        break;
  43                for (i = 0; i < ARRAY_SIZE(whitespace_rule_names); i++) {
  44                        if (strncmp(whitespace_rule_names[i].rule_name,
  45                                    string, len))
  46                                continue;
  47                        if (negated)
  48                                rule &= ~whitespace_rule_names[i].rule_bits;
  49                        else
  50                                rule |= whitespace_rule_names[i].rule_bits;
  51                        break;
  52                }
  53                string = ep;
  54        }
  55        return rule;
  56}
  57
  58static void setup_whitespace_attr_check(struct git_attr_check *check)
  59{
  60        static struct git_attr *attr_whitespace;
  61
  62        if (!attr_whitespace)
  63                attr_whitespace = git_attr("whitespace", 10);
  64        check[0].attr = attr_whitespace;
  65}
  66
  67unsigned whitespace_rule(const char *pathname)
  68{
  69        struct git_attr_check attr_whitespace_rule;
  70
  71        setup_whitespace_attr_check(&attr_whitespace_rule);
  72        if (!git_checkattr(pathname, 1, &attr_whitespace_rule)) {
  73                const char *value;
  74
  75                value = attr_whitespace_rule.value;
  76                if (ATTR_TRUE(value)) {
  77                        /* true (whitespace) */
  78                        unsigned all_rule = 0;
  79                        int i;
  80                        for (i = 0; i < ARRAY_SIZE(whitespace_rule_names); i++)
  81                                all_rule |= whitespace_rule_names[i].rule_bits;
  82                        return all_rule;
  83                } else if (ATTR_FALSE(value)) {
  84                        /* false (-whitespace) */
  85                        return 0;
  86                } else if (ATTR_UNSET(value)) {
  87                        /* reset to default (!whitespace) */
  88                        return whitespace_rule_cfg;
  89                } else {
  90                        /* string */
  91                        return parse_whitespace_rule(value);
  92                }
  93        } else {
  94                return whitespace_rule_cfg;
  95        }
  96}