help: move list_config_help to builtin/help

Starting in 3ac68a93fd, help.o began to depend on builtin/branch.o,
builtin/clean.o, and builtin/config.o. This meant that help.o was
unusable outside of the context of the main Git executable.

To make help.o usable by other commands again, move list_config_help()
into builtin/help.c (where it makes sense to assume other builtin libraries
are present).

When command-list.h is included but a member is not used, we start to
hear a compiler warning. Since the config list is generated in a fairly
different way than the command list, and since commands and config
options are semantically different, move the config list into its own
header and move the generator into its own script and build rule.

For reasons explained in 976aaedc (msvc: add a Makefile target to
pre-generate the Visual Studio solution, 2019-07-29), some build
artifacts we consider non-source files cannot be generated in the
Visual Studio environment, and we already have some Makefile tweaks
to help Visual Studio to use generated command-list.h header file.
Do the same to a new generated file, config-list.h, introduced by
this change.

Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
This commit is contained in:
Emily Shaffer 2020-04-16 14:18:03 -07:00 committed by Junio C Hamano
parent 145d59f482
commit 709df95b78
9 changed files with 123 additions and 113 deletions

1
.gitignore vendored
View File

@ -189,6 +189,7 @@
/gitweb/gitweb.cgi /gitweb/gitweb.cgi
/gitweb/static/gitweb.js /gitweb/static/gitweb.js
/gitweb/static/gitweb.min.* /gitweb/static/gitweb.min.*
/config-list.h
/command-list.h /command-list.h
*.tar.gz *.tar.gz
*.dsc *.dsc

View File

@ -814,6 +814,7 @@ LIB_FILE = libgit.a
XDIFF_LIB = xdiff/lib.a XDIFF_LIB = xdiff/lib.a
VCSSVN_LIB = vcs-svn/lib.a VCSSVN_LIB = vcs-svn/lib.a
GENERATED_H += config-list.h
GENERATED_H += command-list.h GENERATED_H += command-list.h
LIB_H := $(sort $(patsubst ./%,%,$(shell git ls-files '*.h' ':!t/' ':!Documentation/' 2>/dev/null || \ LIB_H := $(sort $(patsubst ./%,%,$(shell git ls-files '*.h' ':!t/' ':!Documentation/' 2>/dev/null || \
@ -2128,7 +2129,7 @@ git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS)
help.sp help.s help.o: command-list.h help.sp help.s help.o: command-list.h
builtin/help.sp builtin/help.s builtin/help.o: command-list.h GIT-PREFIX builtin/help.sp builtin/help.s builtin/help.o: config-list.h GIT-PREFIX
builtin/help.sp builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \ builtin/help.sp builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \
'-DGIT_HTML_PATH="$(htmldir_relative_SQ)"' \ '-DGIT_HTML_PATH="$(htmldir_relative_SQ)"' \
'-DGIT_MAN_PATH="$(mandir_relative_SQ)"' \ '-DGIT_MAN_PATH="$(mandir_relative_SQ)"' \
@ -2148,6 +2149,12 @@ $(BUILT_INS): git$X
ln -s $< $@ 2>/dev/null || \ ln -s $< $@ 2>/dev/null || \
cp $< $@ cp $< $@
config-list.h: generate-configlist.sh
config-list.h:
$(QUIET_GEN)$(SHELL_PATH) ./generate-configlist.sh \
>$@+ && mv $@+ $@
command-list.h: generate-cmdlist.sh command-list.txt command-list.h: generate-cmdlist.sh command-list.txt
command-list.h: $(wildcard Documentation/git*.txt) Documentation/*config.txt Documentation/config/*.txt command-list.h: $(wildcard Documentation/git*.txt) Documentation/*config.txt Documentation/config/*.txt
@ -2781,7 +2788,7 @@ $(SP_OBJ): %.sp: %.c GIT-CFLAGS FORCE
.PHONY: sparse $(SP_OBJ) .PHONY: sparse $(SP_OBJ)
sparse: $(SP_OBJ) sparse: $(SP_OBJ)
EXCEPT_HDRS := command-list.h unicode-width.h compat/% xdiff/% EXCEPT_HDRS := command-list.h config-list.h unicode-width.h compat/% xdiff/%
ifndef GCRYPT_SHA256 ifndef GCRYPT_SHA256
EXCEPT_HDRS += sha256/gcrypt.h EXCEPT_HDRS += sha256/gcrypt.h
endif endif
@ -2803,7 +2810,7 @@ hdr-check: $(HCO)
style: style:
git clang-format --style file --diff --extensions c,h git clang-format --style file --diff --extensions c,h
check: command-list.h check: config-list.h command-list.h
@if sparse; \ @if sparse; \
then \ then \
echo >&2 "Use 'make sparse' instead"; \ echo >&2 "Use 'make sparse' instead"; \

View File

@ -8,6 +8,7 @@
#include "parse-options.h" #include "parse-options.h"
#include "run-command.h" #include "run-command.h"
#include "column.h" #include "column.h"
#include "config-list.h"
#include "help.h" #include "help.h"
#include "alias.h" #include "alias.h"
@ -62,6 +63,91 @@ static const char * const builtin_help_usage[] = {
NULL NULL
}; };
struct slot_expansion {
const char *prefix;
const char *placeholder;
void (*fn)(struct string_list *list, const char *prefix);
int found;
};
static void list_config_help(int for_human)
{
struct slot_expansion slot_expansions[] = {
{ "advice", "*", list_config_advices },
{ "color.branch", "<slot>", list_config_color_branch_slots },
{ "color.decorate", "<slot>", list_config_color_decorate_slots },
{ "color.diff", "<slot>", list_config_color_diff_slots },
{ "color.grep", "<slot>", list_config_color_grep_slots },
{ "color.interactive", "<slot>", list_config_color_interactive_slots },
{ "color.remote", "<slot>", list_config_color_sideband_slots },
{ "color.status", "<slot>", list_config_color_status_slots },
{ "fsck", "<msg-id>", list_config_fsck_msg_ids },
{ "receive.fsck", "<msg-id>", list_config_fsck_msg_ids },
{ NULL, NULL, NULL }
};
const char **p;
struct slot_expansion *e;
struct string_list keys = STRING_LIST_INIT_DUP;
int i;
for (p = config_name_list; *p; p++) {
const char *var = *p;
struct strbuf sb = STRBUF_INIT;
for (e = slot_expansions; e->prefix; e++) {
strbuf_reset(&sb);
strbuf_addf(&sb, "%s.%s", e->prefix, e->placeholder);
if (!strcasecmp(var, sb.buf)) {
e->fn(&keys, e->prefix);
e->found++;
break;
}
}
strbuf_release(&sb);
if (!e->prefix)
string_list_append(&keys, var);
}
for (e = slot_expansions; e->prefix; e++)
if (!e->found)
BUG("slot_expansion %s.%s is not used",
e->prefix, e->placeholder);
string_list_sort(&keys);
for (i = 0; i < keys.nr; i++) {
const char *var = keys.items[i].string;
const char *wildcard, *tag, *cut;
if (for_human) {
puts(var);
continue;
}
wildcard = strchr(var, '*');
tag = strchr(var, '<');
if (!wildcard && !tag) {
puts(var);
continue;
}
if (wildcard && !tag)
cut = wildcard;
else if (!wildcard && tag)
cut = tag;
else
cut = wildcard < tag ? wildcard : tag;
/*
* We may produce duplicates, but that's up to
* git-completion.bash to handle
*/
printf("%.*s\n", (int)(cut - var), var);
}
string_list_clear(&keys, 0);
}
static enum help_format parse_help_format(const char *format) static enum help_format parse_help_format(const char *format)
{ {
if (!strcmp(format, "man")) if (!strcmp(format, "man"))

View File

@ -92,8 +92,8 @@ The Steps of Build Git with VS2008
the git operations. the git operations.
3. Inside Git's directory run the command: 3. Inside Git's directory run the command:
make command-list.h make command-list.h config-list.h
to generate the command-list.h file needed to compile git. to generate the header file needed to compile git.
4. Then either build Git with the GNU Make Makefile in the Git projects 4. Then either build Git with the GNU Make Makefile in the Git projects
root root

View File

@ -721,9 +721,9 @@ vcxproj:
echo '</Project>') >git-remote-http/LinkOrCopyRemoteHttp.targets echo '</Project>') >git-remote-http/LinkOrCopyRemoteHttp.targets
git add -f git/LinkOrCopyBuiltins.targets git-remote-http/LinkOrCopyRemoteHttp.targets git add -f git/LinkOrCopyBuiltins.targets git-remote-http/LinkOrCopyRemoteHttp.targets
# Add command-list.h # Add command-list.h and config-list.h
$(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 command-list.h $(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 config-list.h command-list.h
git add -f command-list.h git add -f config-list.h command-list.h
# Add scripts # Add scripts
rm -f perl/perl.mak rm -f perl/perl.mak

View File

@ -76,23 +76,6 @@ print_command_list () {
echo "};" echo "};"
} }
print_config_list () {
cat <<EOF
static const char *config_name_list[] = {
EOF
grep -h '^[a-zA-Z].*\..*::$' Documentation/*config.txt Documentation/config/*.txt |
sed '/deprecated/d; s/::$//; s/, */\n/g' |
sort |
while read line
do
echo " \"$line\","
done
cat <<EOF
NULL,
};
EOF
}
exclude_programs= exclude_programs=
while test "--exclude-program" = "$1" while test "--exclude-program" = "$1"
do do
@ -113,5 +96,3 @@ echo
define_category_names "$1" define_category_names "$1"
echo echo
print_command_list "$1" print_command_list "$1"
echo
print_config_list

21
generate-configlist.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/sh
echo "/* Automatically generated by generate-configlist.sh */"
echo
print_config_list () {
cat <<EOF
static const char *config_name_list[] = {
EOF
grep -h '^[a-zA-Z].*\..*::$' Documentation/*config.txt Documentation/config/*.txt |
sed '/deprecated/d; s/::$//; s/, */\n/g' |
sort |
sed 's/^.*$/ "&",/'
cat <<EOF
NULL,
};
EOF
}
echo
print_config_list

85
help.c
View File

@ -407,91 +407,6 @@ void list_common_guides_help(void)
putchar('\n'); putchar('\n');
} }
struct slot_expansion {
const char *prefix;
const char *placeholder;
void (*fn)(struct string_list *list, const char *prefix);
int found;
};
void list_config_help(int for_human)
{
struct slot_expansion slot_expansions[] = {
{ "advice", "*", list_config_advices },
{ "color.branch", "<slot>", list_config_color_branch_slots },
{ "color.decorate", "<slot>", list_config_color_decorate_slots },
{ "color.diff", "<slot>", list_config_color_diff_slots },
{ "color.grep", "<slot>", list_config_color_grep_slots },
{ "color.interactive", "<slot>", list_config_color_interactive_slots },
{ "color.remote", "<slot>", list_config_color_sideband_slots },
{ "color.status", "<slot>", list_config_color_status_slots },
{ "fsck", "<msg-id>", list_config_fsck_msg_ids },
{ "receive.fsck", "<msg-id>", list_config_fsck_msg_ids },
{ NULL, NULL, NULL }
};
const char **p;
struct slot_expansion *e;
struct string_list keys = STRING_LIST_INIT_DUP;
int i;
for (p = config_name_list; *p; p++) {
const char *var = *p;
struct strbuf sb = STRBUF_INIT;
for (e = slot_expansions; e->prefix; e++) {
strbuf_reset(&sb);
strbuf_addf(&sb, "%s.%s", e->prefix, e->placeholder);
if (!strcasecmp(var, sb.buf)) {
e->fn(&keys, e->prefix);
e->found++;
break;
}
}
strbuf_release(&sb);
if (!e->prefix)
string_list_append(&keys, var);
}
for (e = slot_expansions; e->prefix; e++)
if (!e->found)
BUG("slot_expansion %s.%s is not used",
e->prefix, e->placeholder);
string_list_sort(&keys);
for (i = 0; i < keys.nr; i++) {
const char *var = keys.items[i].string;
const char *wildcard, *tag, *cut;
if (for_human) {
puts(var);
continue;
}
wildcard = strchr(var, '*');
tag = strchr(var, '<');
if (!wildcard && !tag) {
puts(var);
continue;
}
if (wildcard && !tag)
cut = wildcard;
else if (!wildcard && tag)
cut = tag;
else
cut = wildcard < tag ? wildcard : tag;
/*
* We may produce duplicates, but that's up to
* git-completion.bash to handle
*/
printf("%.*s\n", (int)(cut - var), var);
}
string_list_clear(&keys, 0);
}
static int get_alias(const char *var, const char *value, void *data) static int get_alias(const char *var, const char *value, void *data)
{ {
struct string_list *list = data; struct string_list *list = data;

1
help.h
View File

@ -22,7 +22,6 @@ static inline void mput_char(char c, unsigned int num)
void list_common_cmds_help(void); void list_common_cmds_help(void);
void list_all_cmds_help(void); void list_all_cmds_help(void);
void list_common_guides_help(void); void list_common_guides_help(void);
void list_config_help(int for_human);
void list_all_main_cmds(struct string_list *list); void list_all_main_cmds(struct string_list *list);
void list_all_other_cmds(struct string_list *list); void list_all_other_cmds(struct string_list *list);