git-config-set: support selecting values by non-matching regex
[git.git] / config-set.c
1 #include "cache.h"
2 #include <regex.h>
3
4 static const char git_config_set_usage[] =
5 "git-config-set [--get | --get-all | --replace-all | --unset | --unset-all] name [value [value_regex]]";
6
7 static char* key = NULL;
8 static char* value = NULL;
9 static regex_t* regex = NULL;
10 static int do_all = 0;
11 static int do_not_match = 0;
12 static int seen = 0;
13
14 static int show_config(const char* key_, const char* value_)
15 {
16         if (!strcmp(key_, key) &&
17                         (regex == NULL ||
18                          (do_not_match ^
19                           !regexec(regex, value_, 0, NULL, 0)))) {
20                 if (do_all) {
21                         printf("%s\n", value_);
22                         return 0;
23                 }
24                 if (seen > 0) {
25                         fprintf(stderr, "More than one value: %s\n", value);
26                         free(value);
27                 }
28                 value = strdup(value_);
29                 seen++;
30         }
31         return 0;
32 }
33
34 static int get_value(const char* key_, const char* regex_)
35 {
36         int i;
37
38         key = malloc(strlen(key_)+1);
39         for (i = 0; key_[i]; i++)
40                 key[i] = tolower(key_[i]);
41
42         if (regex_) {
43                 if (regex_[0] == '!') {
44                         do_not_match = 1;
45                         regex_++;
46                 }
47
48                 regex = (regex_t*)malloc(sizeof(regex_t));
49                 if (regcomp(regex, regex_, REG_EXTENDED)) {
50                         fprintf(stderr, "Invalid pattern: %s\n", regex_);
51                         return -1;
52                 }
53         }
54
55         i = git_config(show_config);
56         if (value) {
57                 printf("%s\n", value);
58                 free(value);
59         }
60         free(key);
61         if (regex) {
62                 regfree(regex);
63                 free(regex);
64         }
65
66         if (do_all)
67                 return 0;
68
69         return seen == 1 ? 0 : 1;
70 }
71
72 int main(int argc, const char **argv)
73 {
74         setup_git_directory();
75         switch (argc) {
76         case 2:
77                 return get_value(argv[1], NULL);
78         case 3:
79                 if (!strcmp(argv[1], "--unset"))
80                         return git_config_set(argv[2], NULL);
81                 else if (!strcmp(argv[1], "--unset-all"))
82                         return git_config_set_multivar(argv[2], NULL, NULL, 1);
83                 else if (!strcmp(argv[1], "--get"))
84                         return get_value(argv[2], NULL);
85                 else if (!strcmp(argv[1], "--get-all")) {
86                         do_all = 1;
87                         return get_value(argv[2], NULL);
88                 } else
89
90                         return git_config_set(argv[1], argv[2]);
91         case 4:
92                 if (!strcmp(argv[1], "--unset"))
93                         return git_config_set_multivar(argv[2], NULL, argv[3], 0);
94                 else if (!strcmp(argv[1], "--unset-all"))
95                         return git_config_set_multivar(argv[2], NULL, argv[3], 1);
96                 else if (!strcmp(argv[1], "--get"))
97                         return get_value(argv[2], argv[3]);
98                 else if (!strcmp(argv[1], "--get-all")) {
99                         do_all = 1;
100                         return get_value(argv[2], argv[3]);
101                 } else if (!strcmp(argv[1], "--replace-all"))
102
103                         return git_config_set_multivar(argv[2], argv[3], NULL, 1);
104                 else
105
106                         return git_config_set_multivar(argv[1], argv[2], argv[3], 0);
107         case 5:
108                 if (!strcmp(argv[1], "--replace-all"))
109                         return git_config_set_multivar(argv[2], argv[3], argv[4], 1);
110         case 1:
111         default:
112                 usage(git_config_set_usage);
113         }
114         return 0;
115 }