attr: convert git_all_attrs() to use "struct attr_check"

This updates the other two ways the attribute check is done via an array of "struct attr_check_item" elements. These two niches appear only in "git check-attr". * The caller does not know offhand what attributes it wants to ask about and cannot use attr_check_initl() to prepare the attr_check structure. * The caller may not know what attributes it wants to ask at all, and instead wants to learn everything that the given path has. Such a caller can call attr_check_alloc() to allocate an empty attr_check, and then call attr_check_append() to add attribute names one by one. Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Jan 30, 2017 at 10:06 UTC 7f8641112de8724a565a47b0f0b2a9b826b6baa9
3 files changed +43 -56
attr.c
+10 -20
@@ -906,32 +906,22 @@ int git_check_attrs(const char *path, int num, struct attr_check_item *check)
906 return 0;
907 }
908
909 -int git_all_attrs(const char *path, int *num, struct attr_check_item **check)
909 +void git_all_attrs(const char *path, struct attr_check *check)
910 {
911 - int i, count, j;
911 + int i;
912
913 - collect_some_attrs(path, 0, NULL);
913 + attr_check_reset(check);
914 + collect_some_attrs(path, check->nr, check->items);
915
915 - /* Count the number of attributes that are set. */
916 - count = 0;
917 - for (i = 0; i < attr_nr; i++) {
918 - const char *value = check_all_attr[i].value;
919 - if (value != ATTR__UNSET && value != ATTR__UNKNOWN)
920 - ++count;
921 - }
922 - *num = count;
923 - ALLOC_ARRAY(*check, count);
924 - j = 0;
916 for (i = 0; i < attr_nr; i++) {
917 + const char *name = check_all_attr[i].attr->name;
918 const char *value = check_all_attr[i].value;
927 - if (value != ATTR__UNSET && value != ATTR__UNKNOWN) {
928 - (*check)[j].attr = check_all_attr[i].attr;
929 - (*check)[j].value = value;
930 - ++j;
931 - }
919 + struct attr_check_item *item;
920 + if (value == ATTR__UNSET || value == ATTR__UNKNOWN)
921 + continue;
922 + item = attr_check_append(check, git_attr(name));
923 + item->value = value;
924 }
933 -
934 - return 0;
925 }
926
927 int git_check_attr(const char *path, struct attr_check *check)
attr.h
+3 -6
@@ -56,13 +56,10 @@ int git_check_attrs(const char *path, int, struct attr_check_item *);
56 extern int git_check_attr(const char *path, struct attr_check *check);
57
58 /*
59 - * Retrieve all attributes that apply to the specified path. *num
60 - * will be set to the number of attributes on the path; **check will
61 - * be set to point at a newly-allocated array of git_attr_check
62 - * objects describing the attributes and their values. *check must be
63 - * free()ed by the caller.
59 + * Retrieve all attributes that apply to the specified path.
60 + * check holds the attributes and their values.
61 */
65 -int git_all_attrs(const char *path, int *num, struct attr_check_item **check);
62 +extern void git_all_attrs(const char *path, struct attr_check *check);
63
64 enum git_attr_direction {
65 GIT_ATTR_CHECKIN,
builtin/check-attr.c
+30 -30
@@ -24,12 +24,13 @@ static const struct option check_attr_options[] = {
24 OPT_END()
25 };
26
27 -static void output_attr(int cnt, struct attr_check_item *check,
28 - const char *file)
27 +static void output_attr(struct attr_check *check, const char *file)
28 {
29 int j;
30 + int cnt = check->nr;
31 +
32 for (j = 0; j < cnt; j++) {
32 - const char *value = check[j].value;
33 + const char *value = check->items[j].value;
34
35 if (ATTR_TRUE(value))
36 value = "set";
@@ -42,36 +43,38 @@ static void output_attr(int cnt, struct attr_check_item *check,
43 printf("%s%c" /* path */
44 "%s%c" /* attrname */
45 "%s%c" /* attrvalue */,
45 - file, 0, git_attr_name(check[j].attr), 0, value, 0);
46 + file, 0,
47 + git_attr_name(check->items[j].attr), 0, value, 0);
48 } else {
49 quote_c_style(file, NULL, stdout, 0);
48 - printf(": %s: %s\n", git_attr_name(check[j].attr), value);
50 + printf(": %s: %s\n",
51 + git_attr_name(check->items[j].attr), value);
52 }
50 -
53 }
54 }
55
56 static void check_attr(const char *prefix,
55 - int cnt, struct attr_check_item *check,
57 + struct attr_check *check,
58 + int collect_all,
59 const char *file)
60 {
61 char *full_path =
62 prefix_path(prefix, prefix ? strlen(prefix) : 0, file);
60 - if (check != NULL) {
61 - if (git_check_attrs(full_path, cnt, check))
62 - die("git_check_attrs died");
63 - output_attr(cnt, check, file);
63 +
64 + if (collect_all) {
65 + git_all_attrs(full_path, check);
66 } else {
65 - if (git_all_attrs(full_path, &cnt, &check))
66 - die("git_all_attrs died");
67 - output_attr(cnt, check, file);
68 - free(check);
67 + if (git_check_attr(full_path, check))
68 + die("git_check_attr died");
69 }
70 + output_attr(check, file);
71 +
72 free(full_path);
73 }
74
75 static void check_attr_stdin_paths(const char *prefix,
74 - int cnt, struct attr_check_item *check)
76 + struct attr_check *check,
77 + int collect_all)
78 {
79 struct strbuf buf = STRBUF_INIT;
80 struct strbuf unquoted = STRBUF_INIT;
@@ -85,7 +88,7 @@ static void check_attr_stdin_paths(const char *prefix,
88 die("line is badly quoted");
89 strbuf_swap(&buf, &unquoted);
90 }
88 - check_attr(prefix, cnt, check, buf.buf);
91 + check_attr(prefix, check, collect_all, buf.buf);
92 maybe_flush_or_die(stdout, "attribute to stdout");
93 }
94 strbuf_release(&buf);
@@ -100,7 +103,7 @@ static NORETURN void error_with_usage(const char *msg)
103
104 int cmd_check_attr(int argc, const char **argv, const char *prefix)
105 {
103 - struct attr_check_item *check;
106 + struct attr_check *check;
107 int cnt, i, doubledash, filei;
108
109 if (!is_bare_repository())
@@ -160,28 +163,25 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)
163 error_with_usage("No file specified");
164 }
165
163 - if (all_attrs) {
164 - check = NULL;
165 - } else {
166 - check = xcalloc(cnt, sizeof(*check));
166 + check = attr_check_alloc();
167 + if (!all_attrs) {
168 for (i = 0; i < cnt; i++) {
168 - const char *name;
169 - struct git_attr *a;
170 - name = argv[i];
171 - a = git_attr(name);
169 + struct git_attr *a = git_attr(argv[i]);
170 if (!a)
171 return error("%s: not a valid attribute name",
174 - name);
175 - check[i].attr = a;
172 + argv[i]);
173 + attr_check_append(check, a);
174 }
175 }
176
177 if (stdin_paths)
180 - check_attr_stdin_paths(prefix, cnt, check);
178 + check_attr_stdin_paths(prefix, check, all_attrs);
179 else {
180 for (i = filei; i < argc; i++)
183 - check_attr(prefix, cnt, check, argv[i]);
181 + check_attr(prefix, check, all_attrs, argv[i]);
182 maybe_flush_or_die(stdout, "attribute to stdout");
183 }
184 +
185 + attr_check_free(check);
186 return 0;
187 }