restyle builtin modules to match project style

Now that the IWYU cleanup has been merged compile all, not just a couple, of
the builtin modules independent of builtin.cpp. That is, no longer `#include
builtin_NAME.cpp` in builtin.cpp. This is more consistent, more in line with
what developers expect, and is likely to reduce mistakes.

Reduces lint errors from 384 to 336 (-13%). Line count from 6307 to 4988 (-21%).

Another step in resolving issue #2902.
This commit is contained in:
Kurtis Rader 2016-04-19 19:49:15 -07:00
parent c2f9d60eb1
commit df10b53c0c
22 changed files with 2397 additions and 3589 deletions

View File

@ -95,29 +95,19 @@ HAVE_DOXYGEN=@HAVE_DOXYGEN@
# All objects that the system needs to build fish, except fish.o
#
FISH_OBJS := obj/function.o obj/builtin.o obj/complete.o obj/env.o obj/exec.o \
FISH_OBJS := obj/function.o obj/builtin.o obj/builtin_commandline.o obj/builtin_complete.o obj/builtin_jobs.o obj/builtin_printf.o obj/builtin_set.o obj/builtin_set_color.o obj/builtin_string.o obj/builtin_test.o obj/builtin_ulimit.o obj/complete.o obj/env.o obj/exec.o \
obj/expand.o obj/highlight.o obj/history.o obj/kill.o obj/parser.o \
obj/proc.o obj/reader.o obj/sanity.o obj/tokenizer.o obj/wildcard.o \
obj/wgetopt.o obj/wutil.o obj/input.o obj/output.o obj/intern.o \
obj/env_universal_common.o obj/input_common.o obj/event.o obj/signal.o \
obj/io.o obj/parse_util.o obj/common.o obj/screen.o obj/path.o \
obj/autoload.o obj/parser_keywords.o obj/iothread.o obj/color.o \
obj/postfork.o obj/builtin_string.o obj/builtin_test.o obj/parse_tree.o \
obj/postfork.o obj/parse_tree.o \
obj/parse_productions.o obj/parse_execution.o obj/pager.o obj/utf8.o \
obj/fish_version.o obj/wcstringutil.o
FISH_INDENT_OBJS := obj/fish_indent.o obj/print_help.o $(FISH_OBJS)
#
# Additional files used by builtin.o
#
BUILTIN_FILES := src/builtin_set.cpp src/builtin_commandline.cpp \
src/builtin_ulimit.cpp src/builtin_complete.cpp \
src/builtin_jobs.cpp src/builtin_set_color.cpp \
src/builtin_printf.cpp
#
# All objects that the system needs to build fish_tests
#
@ -504,8 +494,6 @@ messages.pot: src/*.cpp src/*.h share/completions/*.fish share/functions/*.fish
xgettext -k_ -kN_ src/*.cpp src/*.h -o messages.pot
xgettext -j -k_ -kN_ -k--description -LShell --from-code=UTF-8 share/completions/*.fish share/functions/*.fish -o messages.pot
builtin.o: $(BUILTIN_FILES)
ifdef EXTRA_PCRE2
src/builtin_string.cpp: $(PCRE2_H)
endif
@ -917,117 +905,151 @@ clean:
# DO NOT DELETE THIS LINE -- make depend depends on it.
obj/autoload.o: config.h src/autoload.h src/common.h src/fallback.h
obj/autoload.o: src/signal.h src/lru.h src/wutil.h src/env.h src/exec.h
obj/builtin.o: config.h src/signal.h src/fallback.h src/wutil.h src/common.h
obj/builtin.o: src/builtin.h src/io.h src/function.h src/event.h src/env.h
obj/builtin.o: src/complete.h src/proc.h src/parse_tree.h src/tokenizer.h
obj/builtin.o: src/parse_constants.h src/parser.h src/reader.h
obj/builtin.o: src/highlight.h src/color.h src/wgetopt.h src/input.h
obj/builtin.o: src/input_common.h src/intern.h src/exec.h src/parse_util.h
obj/builtin.o: src/parser_keywords.h src/expand.h src/path.h src/history.h
obj/builtin.o: src/wcstringutil.h src/builtin_set.cpp src/util.h
obj/builtin.o: src/builtin_commandline.cpp src/builtin_complete.cpp
obj/builtin.o: src/builtin_ulimit.cpp src/builtin_jobs.cpp
obj/builtin.o: src/builtin_set_color.cpp src/output.h src/builtin_printf.cpp
obj/builtin.o: src/builtin_string.cpp
obj/builtin_test.o: config.h src/common.h src/fallback.h src/signal.h
obj/builtin_test.o: src/builtin.h src/io.h src/wutil.h src/proc.h
obj/builtin_test.o: src/parse_tree.h src/tokenizer.h src/parse_constants.h
obj/autoload.o: src/autoload.h src/common.h config.h src/fallback.h
obj/autoload.o: src/signal.h src/lru.h src/env.h src/exec.h src/wutil.h
obj/builtin.o: src/builtin.h src/common.h config.h src/fallback.h
obj/builtin.o: src/signal.h src/builtin_commandline.h src/builtin_complete.h
obj/builtin.o: src/builtin_jobs.h src/builtin_printf.h src/builtin_set.h
obj/builtin.o: src/builtin_set_color.h src/builtin_string.h
obj/builtin.o: src/builtin_test.h src/builtin_ulimit.h src/complete.h
obj/builtin.o: src/env.h src/event.h src/exec.h src/expand.h
obj/builtin.o: src/parse_constants.h src/function.h src/highlight.h
obj/builtin.o: src/color.h src/history.h src/wutil.h src/input.h src/intern.h
obj/builtin.o: src/io.h src/parse_util.h src/tokenizer.h src/parser.h
obj/builtin.o: src/proc.h src/parse_tree.h src/parser_keywords.h src/path.h
obj/builtin.o: src/reader.h src/wcstringutil.h src/wgetopt.h
obj/builtin_commandline.o: src/builtin.h src/common.h config.h src/fallback.h
obj/builtin_commandline.o: src/signal.h src/input.h src/env.h src/io.h
obj/builtin_commandline.o: src/parse_util.h src/parse_constants.h
obj/builtin_commandline.o: src/tokenizer.h src/proc.h src/parse_tree.h
obj/builtin_commandline.o: src/reader.h src/complete.h src/highlight.h
obj/builtin_commandline.o: src/color.h src/util.h src/wgetopt.h src/wutil.h
obj/builtin_complete.o: src/builtin.h src/common.h config.h src/fallback.h
obj/builtin_complete.o: src/signal.h src/complete.h src/env.h src/io.h
obj/builtin_complete.o: src/parse_constants.h src/parse_util.h
obj/builtin_complete.o: src/tokenizer.h src/parser.h src/proc.h
obj/builtin_complete.o: src/parse_tree.h src/event.h src/expand.h
obj/builtin_complete.o: src/reader.h src/highlight.h src/color.h
obj/builtin_complete.o: src/wgetopt.h src/wutil.h
obj/builtin_jobs.o: config.h src/builtin.h src/common.h src/fallback.h
obj/builtin_jobs.o: src/signal.h src/io.h src/proc.h src/parse_tree.h
obj/builtin_jobs.o: src/tokenizer.h src/parse_constants.h src/wgetopt.h
obj/builtin_jobs.o: src/wutil.h
obj/builtin_printf.o: src/builtin.h src/common.h config.h src/fallback.h
obj/builtin_printf.o: src/signal.h src/io.h src/proc.h src/parse_tree.h
obj/builtin_printf.o: src/tokenizer.h src/parse_constants.h src/wutil.h
obj/builtin_set.o: src/builtin.h src/common.h config.h src/fallback.h
obj/builtin_set.o: src/signal.h src/env.h src/expand.h src/parse_constants.h
obj/builtin_set.o: src/io.h src/proc.h src/parse_tree.h src/tokenizer.h
obj/builtin_set.o: src/wgetopt.h src/wutil.h
obj/builtin_set_color.o: config.h src/builtin.h src/common.h src/fallback.h
obj/builtin_set_color.o: src/signal.h src/color.h src/io.h src/output.h
obj/builtin_set_color.o: src/proc.h src/parse_tree.h src/tokenizer.h
obj/builtin_set_color.o: src/parse_constants.h src/wgetopt.h src/wutil.h
obj/builtin_string.o: config.h src/builtin.h src/common.h src/fallback.h
obj/builtin_string.o: src/signal.h src/io.h src/parse_util.h
obj/builtin_string.o: src/parse_constants.h src/tokenizer.h src/wgetopt.h
obj/builtin_string.o: src/wildcard.h src/expand.h src/complete.h src/wutil.h
obj/builtin_test.o: src/builtin.h src/common.h config.h src/fallback.h
obj/builtin_test.o: src/signal.h src/io.h src/proc.h src/parse_tree.h
obj/builtin_test.o: src/tokenizer.h src/parse_constants.h src/wutil.h
obj/builtin_ulimit.o: src/builtin.h src/common.h config.h src/fallback.h
obj/builtin_ulimit.o: src/signal.h src/io.h src/util.h src/wgetopt.h
obj/builtin_ulimit.o: src/wutil.h
obj/color.o: src/color.h src/common.h config.h src/fallback.h src/signal.h
obj/common.o: config.h src/signal.h src/fallback.h src/wutil.h src/common.h
obj/common.o: src/expand.h src/parse_constants.h src/wildcard.h
obj/common.o: src/complete.h src/util.cpp src/util.h src/fallback.cpp
obj/complete.o: config.h src/fallback.h src/signal.h src/util.h
obj/complete.o: src/fallback.h config.h src/signal.h src/util.h
obj/complete.o: src/wildcard.h src/common.h src/expand.h
obj/complete.o: src/parse_constants.h src/complete.h src/proc.h src/io.h
obj/complete.o: src/parse_tree.h src/tokenizer.h src/parser.h src/event.h
obj/complete.o: src/function.h src/env.h src/builtin.h src/exec.h
obj/complete.o: src/parse_util.h src/wutil.h src/path.h src/iothread.h
obj/complete.o: src/autoload.h src/lru.h
obj/env.o: config.h src/fallback.h src/signal.h src/wutil.h src/common.h
obj/env.o: src/fallback.h config.h src/signal.h src/wutil.h src/common.h
obj/env.o: src/proc.h src/io.h src/parse_tree.h src/tokenizer.h
obj/env.o: src/parse_constants.h src/env.h src/sanity.h src/expand.h
obj/env.o: src/history.h src/reader.h src/complete.h src/highlight.h
obj/env.o: src/color.h src/env_universal_common.h src/input.h
obj/env.o: src/input_common.h src/event.h src/path.h src/fish_version.h
obj/env.o: src/color.h src/env_universal_common.h src/input.h src/event.h
obj/env.o: src/path.h src/fish_version.h src/input_common.h
obj/env_universal_common.o: config.h src/env_universal_common.h src/common.h
obj/env_universal_common.o: src/fallback.h src/signal.h src/wutil.h src/env.h
obj/env_universal_common.o: src/util.h src/utf8.h
obj/event.o: config.h src/signal.h src/fallback.h src/wutil.h src/common.h
obj/event.o: src/signal.h src/fallback.h config.h src/wutil.h src/common.h
obj/event.o: src/input_common.h src/proc.h src/io.h src/parse_tree.h
obj/event.o: src/tokenizer.h src/parse_constants.h src/parser.h src/event.h
obj/exec.o: config.h src/signal.h src/fallback.h src/postfork.h src/io.h
obj/exec.o: src/common.h src/wutil.h src/proc.h src/parse_tree.h
obj/exec.o: src/tokenizer.h src/parse_constants.h src/exec.h src/parser.h
obj/exec.o: src/event.h src/builtin.h src/function.h src/env.h
obj/exec.o: src/parse_util.h
obj/event.o: src/expand.h
obj/exec.o: config.h src/signal.h src/fallback.h src/postfork.h src/common.h
obj/exec.o: src/wutil.h src/proc.h src/io.h src/parse_tree.h src/tokenizer.h
obj/exec.o: src/parse_constants.h src/exec.h src/parser.h src/event.h
obj/exec.o: src/expand.h src/builtin.h src/function.h src/env.h src/reader.h
obj/exec.o: src/complete.h src/highlight.h src/color.h
obj/expand.o: config.h src/fallback.h src/signal.h src/util.h src/common.h
obj/expand.o: src/wutil.h src/env.h src/proc.h src/io.h src/parse_tree.h
obj/expand.o: src/tokenizer.h src/parse_constants.h src/parser.h src/event.h
obj/expand.o: src/expand.h src/wildcard.h src/complete.h src/exec.h
obj/expand.o: src/iothread.h src/parse_util.h
obj/expand.o: src/tokenizer.h src/parse_constants.h src/path.h src/expand.h
obj/expand.o: src/wildcard.h src/complete.h src/exec.h src/iothread.h
obj/expand.o: src/parse_util.h
obj/fish.o: config.h src/fallback.h src/signal.h src/common.h src/reader.h
obj/fish.o: src/io.h src/complete.h src/highlight.h src/env.h src/color.h
obj/fish.o: src/complete.h src/highlight.h src/env.h src/color.h
obj/fish.o: src/parse_constants.h src/builtin.h src/function.h src/event.h
obj/fish.o: src/wutil.h src/proc.h src/parse_tree.h src/tokenizer.h
obj/fish.o: src/parser.h src/expand.h src/intern.h src/history.h src/path.h
obj/fish.o: src/input.h src/input_common.h src/fish_version.h
obj/fish_indent.o: config.h src/color.h src/common.h src/fallback.h
obj/fish.o: src/wutil.h src/proc.h src/io.h src/parse_tree.h src/tokenizer.h
obj/fish.o: src/parser.h src/expand.h src/history.h src/path.h src/input.h
obj/fish.o: src/fish_version.h src/input_common.h src/wildcard.h
obj/fish_indent.o: src/color.h src/common.h config.h src/fallback.h
obj/fish_indent.o: src/signal.h src/highlight.h src/env.h
obj/fish_indent.o: src/parse_constants.h src/wutil.h src/output.h src/input.h
obj/fish_indent.o: src/input_common.h src/parse_tree.h src/tokenizer.h
obj/fish_indent.o: src/print_help.h src/fish_version.h
obj/fish_tests.o: config.h src/signal.h src/fallback.h src/util.h
obj/fish_indent.o: src/parse_tree.h src/tokenizer.h src/print_help.h
obj/fish_indent.o: src/fish_version.h
obj/fish_tests.o: src/signal.h src/fallback.h config.h src/util.h
obj/fish_tests.o: src/common.h src/proc.h src/io.h src/parse_tree.h
obj/fish_tests.o: src/tokenizer.h src/parse_constants.h src/reader.h
obj/fish_tests.o: src/complete.h src/highlight.h src/env.h src/color.h
obj/fish_tests.o: src/builtin.h src/function.h src/event.h src/autoload.h
obj/fish_tests.o: src/lru.h src/wutil.h src/expand.h src/parser.h
obj/fish_tests.o: src/output.h src/exec.h src/path.h src/history.h
obj/fish_tests.o: src/iothread.h src/postfork.h src/parse_util.h src/pager.h
obj/fish_tests.o: src/screen.h src/input.h src/input_common.h src/wildcard.h
obj/fish_tests.o: src/utf8.h src/env_universal_common.h src/wcstringutil.h
obj/fish_tests.o: src/builtin.h src/function.h src/event.h src/wutil.h
obj/fish_tests.o: src/expand.h src/parser.h src/path.h src/history.h
obj/fish_tests.o: src/iothread.h src/parse_util.h src/pager.h src/screen.h
obj/fish_tests.o: src/input.h src/wildcard.h src/utf8.h
obj/fish_tests.o: src/env_universal_common.h src/wcstringutil.h src/lru.h
obj/fish_tests.o: src/input_common.h
obj/fish_version.o: src/fish_version.h
obj/function.o: config.h src/wutil.h src/common.h src/fallback.h src/signal.h
obj/function.o: src/wutil.h src/common.h config.h src/fallback.h src/signal.h
obj/function.o: src/autoload.h src/lru.h src/function.h src/event.h src/env.h
obj/function.o: src/intern.h src/reader.h src/io.h src/complete.h
obj/function.o: src/highlight.h src/color.h src/parse_constants.h
obj/function.o: src/parser_keywords.h
obj/highlight.o: config.h src/fallback.h src/signal.h src/wutil.h
obj/function.o: src/intern.h src/reader.h src/complete.h src/highlight.h
obj/function.o: src/color.h src/parse_constants.h src/parser_keywords.h
obj/highlight.o: src/fallback.h config.h src/signal.h src/wutil.h
obj/highlight.o: src/common.h src/highlight.h src/env.h src/color.h
obj/highlight.o: src/tokenizer.h src/parse_util.h src/parse_constants.h
obj/highlight.o: src/builtin.h src/io.h src/function.h src/event.h
obj/highlight.o: src/expand.h src/output.h src/wildcard.h src/complete.h
obj/highlight.o: src/path.h src/history.h src/parse_tree.h
obj/history.o: config.h src/fallback.h src/signal.h src/sanity.h src/reader.h
obj/history.o: src/io.h src/common.h src/complete.h src/highlight.h src/env.h
obj/history.o: src/color.h src/parse_constants.h src/parse_tree.h
obj/history.o: src/tokenizer.h src/wutil.h src/history.h src/path.h
obj/history.o: src/iothread.h src/lru.h
obj/highlight.o: src/builtin.h src/function.h src/event.h src/expand.h
obj/highlight.o: src/output.h src/wildcard.h src/complete.h src/path.h
obj/highlight.o: src/history.h src/parse_tree.h
obj/history.o: src/common.h config.h src/fallback.h src/signal.h src/env.h
obj/history.o: src/history.h src/wutil.h src/iothread.h src/lru.h
obj/history.o: src/parse_constants.h src/parse_tree.h src/tokenizer.h
obj/history.o: src/path.h src/reader.h src/complete.h src/highlight.h
obj/history.o: src/color.h src/sanity.h
obj/input.o: config.h src/fallback.h src/signal.h src/wutil.h src/common.h
obj/input.o: src/reader.h src/complete.h src/highlight.h src/env.h
obj/input.o: src/color.h src/parse_constants.h src/proc.h src/io.h
obj/input.o: src/parse_tree.h src/tokenizer.h src/input_common.h src/input.h
obj/input.o: src/parser.h src/event.h src/expand.h src/output.h
obj/input_common.o: config.h src/fallback.h src/signal.h src/util.h
obj/input_common.o: src/common.h src/input_common.h
obj/input_common.o: src/env_universal_common.h src/wutil.h src/env.h
obj/input_common.o: src/iothread.h
obj/input.o: config.h src/fallback.h src/signal.h src/wutil.h src/common.h
obj/input.o: src/reader.h src/io.h src/complete.h src/highlight.h src/env.h
obj/input.o: src/color.h src/parse_constants.h src/proc.h src/parse_tree.h
obj/input.o: src/tokenizer.h src/input_common.h src/input.h src/parser.h
obj/input.o: src/event.h src/output.h
obj/intern.o: config.h src/fallback.h src/signal.h src/common.h src/intern.h
obj/io.o: config.h src/fallback.h src/signal.h src/wutil.h src/common.h
obj/intern.o: src/fallback.h config.h src/signal.h src/common.h src/intern.h
obj/io.o: src/fallback.h config.h src/signal.h src/wutil.h src/common.h
obj/io.o: src/exec.h src/io.h
obj/iothread.o: config.h src/iothread.h src/common.h src/fallback.h
obj/iothread.o: src/signal.h
obj/key_reader.o: config.h src/common.h src/fallback.h src/signal.h
obj/iothread.o: src/signal.h src/iothread.h src/common.h config.h
obj/iothread.o: src/fallback.h
obj/key_reader.o: src/common.h config.h src/fallback.h src/signal.h
obj/key_reader.o: src/input_common.h
obj/kill.o: config.h src/fallback.h src/signal.h src/kill.h src/common.h
obj/kill.o: src/fallback.h config.h src/signal.h src/kill.h src/common.h
obj/kill.o: src/env.h src/exec.h src/path.h
obj/output.o: config.h src/fallback.h src/signal.h src/wutil.h src/common.h
obj/output.o: src/output.h src/color.h
obj/pager.o: config.h src/util.h src/wutil.h src/common.h src/fallback.h
obj/pager.o: src/util.h src/wutil.h src/common.h config.h src/fallback.h
obj/pager.o: src/signal.h src/pager.h src/complete.h src/screen.h
obj/pager.o: src/highlight.h src/env.h src/color.h src/reader.h src/io.h
obj/pager.o: src/highlight.h src/env.h src/color.h src/reader.h
obj/pager.o: src/parse_constants.h
obj/parse_execution.o: src/parse_execution.h src/common.h config.h
obj/parse_execution.o: src/fallback.h src/signal.h src/io.h
@ -1037,26 +1059,26 @@ obj/parse_execution.o: src/parse_util.h src/complete.h src/wildcard.h
obj/parse_execution.o: src/expand.h src/parser.h src/reader.h src/highlight.h
obj/parse_execution.o: src/color.h src/wutil.h src/path.h src/function.h
obj/parse_execution.o: src/builtin.h src/exec.h
obj/parse_productions.o: src/parse_productions.h src/common.h config.h
obj/parse_productions.o: src/fallback.h src/signal.h src/parse_constants.h
obj/parse_productions.o: src/parse_tree.h src/tokenizer.h
obj/parser.o: config.h src/fallback.h src/signal.h src/common.h src/wutil.h
obj/parser.o: src/proc.h src/io.h src/parse_tree.h src/tokenizer.h
obj/parser.o: src/parse_constants.h src/parser.h src/event.h src/function.h
obj/parser.o: src/env.h src/expand.h src/reader.h src/complete.h
obj/parser.o: src/highlight.h src/color.h src/sanity.h src/intern.h
obj/parser.o: src/parse_util.h src/parse_execution.h
obj/parser_keywords.o: config.h src/fallback.h src/signal.h src/common.h
obj/parser_keywords.o: src/parser_keywords.h
obj/parse_productions.o: src/parse_tree.h src/common.h config.h
obj/parse_productions.o: src/fallback.h src/signal.h src/tokenizer.h
obj/parse_productions.o: src/parse_constants.h src/parse_productions.h
obj/parse_tree.o: src/common.h config.h src/fallback.h src/signal.h
obj/parse_tree.o: src/parse_constants.h src/parse_productions.h
obj/parse_tree.o: src/parse_tree.h src/tokenizer.h src/wutil.h src/proc.h
obj/parse_tree.o: src/io.h
obj/parse_util.o: config.h src/fallback.h src/signal.h src/util.h src/wutil.h
obj/parse_util.o: src/fallback.h config.h src/signal.h src/util.h src/wutil.h
obj/parse_util.o: src/common.h src/tokenizer.h src/parse_util.h
obj/parse_util.o: src/parse_constants.h src/expand.h src/env.h src/wildcard.h
obj/parse_util.o: src/complete.h src/parse_tree.h src/builtin.h src/io.h
obj/path.o: config.h src/fallback.h src/signal.h src/common.h src/env.h
obj/parse_util.o: src/parse_constants.h src/expand.h src/wildcard.h
obj/parse_util.o: src/complete.h src/parse_tree.h src/builtin.h
obj/parser.o: src/fallback.h config.h src/signal.h src/common.h src/wutil.h
obj/parser.o: src/proc.h src/io.h src/parse_tree.h src/tokenizer.h
obj/parser.o: src/parse_constants.h src/parser.h src/event.h src/expand.h
obj/parser.o: src/function.h src/env.h src/reader.h src/complete.h
obj/parser.o: src/highlight.h src/color.h src/sanity.h src/intern.h
obj/parser.o: src/parse_util.h src/parse_execution.h
obj/parser_keywords.o: src/fallback.h config.h src/signal.h src/common.h
obj/parser_keywords.o: src/parser_keywords.h
obj/path.o: src/fallback.h config.h src/signal.h src/common.h src/env.h
obj/path.o: src/wutil.h src/path.h src/expand.h src/parse_constants.h
obj/postfork.o: src/signal.h src/common.h config.h src/fallback.h src/proc.h
obj/postfork.o: src/io.h src/parse_tree.h src/tokenizer.h
@ -1067,36 +1089,35 @@ obj/proc.o: config.h src/signal.h src/fallback.h src/util.h src/wutil.h
obj/proc.o: src/common.h src/proc.h src/io.h src/parse_tree.h src/tokenizer.h
obj/proc.o: src/parse_constants.h src/reader.h src/complete.h src/highlight.h
obj/proc.o: src/env.h src/color.h src/sanity.h src/parser.h src/event.h
obj/proc.o: src/output.h
obj/proc.o: src/expand.h src/output.h
obj/reader.o: config.h src/signal.h src/fallback.h src/util.h src/wutil.h
obj/reader.o: src/common.h src/highlight.h src/env.h src/color.h src/reader.h
obj/reader.o: src/io.h src/complete.h src/parse_constants.h src/proc.h
obj/reader.o: src/complete.h src/parse_constants.h src/proc.h src/io.h
obj/reader.o: src/parse_tree.h src/tokenizer.h src/parser.h src/event.h
obj/reader.o: src/history.h src/sanity.h src/exec.h src/expand.h src/kill.h
obj/reader.o: src/expand.h src/history.h src/sanity.h src/exec.h src/kill.h
obj/reader.o: src/input_common.h src/input.h src/function.h src/output.h
obj/reader.o: src/screen.h src/iothread.h src/intern.h src/parse_util.h
obj/reader.o: src/pager.h
obj/sanity.o: config.h src/fallback.h src/signal.h src/common.h src/sanity.h
obj/sanity.o: src/fallback.h config.h src/signal.h src/common.h src/sanity.h
obj/sanity.o: src/proc.h src/io.h src/parse_tree.h src/tokenizer.h
obj/sanity.o: src/parse_constants.h src/history.h src/wutil.h src/reader.h
obj/sanity.o: src/complete.h src/highlight.h src/env.h src/color.h src/kill.h
obj/screen.o: config.h src/fallback.h src/signal.h src/common.h src/util.h
obj/screen.o: src/output.h src/color.h src/highlight.h src/env.h src/screen.h
obj/screen.o: src/pager.h src/complete.h src/reader.h src/io.h
obj/screen.o: src/parse_constants.h
obj/signal.o: config.h src/signal.h src/common.h src/fallback.h src/wutil.h
obj/signal.o: src/event.h src/reader.h src/io.h src/complete.h
obj/signal.o: src/highlight.h src/env.h src/color.h src/parse_constants.h
obj/signal.o: src/proc.h src/parse_tree.h src/tokenizer.h
obj/tokenizer.o: config.h src/fallback.h src/signal.h src/common.h
obj/screen.o: src/pager.h src/complete.h src/reader.h src/parse_constants.h
obj/signal.o: src/signal.h src/common.h config.h src/fallback.h src/wutil.h
obj/signal.o: src/event.h src/reader.h src/complete.h src/highlight.h
obj/signal.o: src/env.h src/color.h src/parse_constants.h src/proc.h src/io.h
obj/signal.o: src/parse_tree.h src/tokenizer.h
obj/tokenizer.o: src/fallback.h config.h src/signal.h src/common.h
obj/tokenizer.o: src/wutil.h src/tokenizer.h
obj/utf8.o: src/utf8.h
obj/wcstringutil.o: config.h src/wcstringutil.h src/common.h src/fallback.h
obj/wcstringutil.o: src/signal.h
obj/wcstringutil.o: src/common.h config.h src/fallback.h src/signal.h
obj/wcstringutil.o: src/wcstringutil.h
obj/wgetopt.o: config.h src/common.h src/fallback.h src/signal.h
obj/wgetopt.o: src/wgetopt.h src/wutil.h
obj/wildcard.o: config.h src/fallback.h src/signal.h src/wutil.h src/common.h
obj/wildcard.o: src/fallback.h config.h src/signal.h src/wutil.h src/common.h
obj/wildcard.o: src/wildcard.h src/expand.h src/parse_constants.h
obj/wildcard.o: src/complete.h src/reader.h src/io.h src/highlight.h
obj/wildcard.o: src/env.h src/color.h
obj/wutil.o: config.h src/fallback.h src/signal.h src/common.h src/wutil.h
obj/wildcard.o: src/complete.h src/reader.h src/highlight.h src/env.h
obj/wildcard.o: src/color.h
obj/wutil.o: config.h src/common.h src/fallback.h src/signal.h src/wutil.h

View File

@ -14,4 +14,6 @@
{ symbol: ["size_t", "private", "<stddef.h>", "public"] },
{ symbol: ["size_t", "private", "<stdlib.h>", "public"] },
{ symbol: ["uint64_t", "private", "<sys/types.h>", "public"] },
{ symbol: ["memset", "private", "<string.h>", "public"] },
{ symbol: ["strerror", "private", "<string.h>", "public"] },
]

View File

@ -39,7 +39,7 @@ else
set git_clang_format yes
else
# No pending changes so lint the files in the most recent commit.
set files (git show --name-only --pretty=oneline head | tail --lines=+2)
set files (git show --name-only --pretty=oneline | tail --lines=+2)
end
# Extract just the C/C++ files.

View File

@ -1,3 +1,4 @@
//
// Functions for executing builtin functions.
//
// How to add a new builtin function:
@ -19,6 +20,8 @@
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -29,24 +32,33 @@
#include <wctype.h>
#include <algorithm>
#include <map>
#include <memory> // IWYU pragma: keep
#include <string>
#include <utility>
#include <limits.h>
#include <memory> // IWYU pragma: keep
#include <stdbool.h>
#include "fallback.h" // IWYU pragma: keep
#include "builtin.h"
#include "builtin_commandline.h"
#include "builtin_complete.h"
#include "builtin_jobs.h"
#include "builtin_printf.h"
#include "builtin_set.h"
#include "builtin_set_color.h"
#include "builtin_string.h"
#include "builtin_test.h"
#include "builtin_ulimit.h"
#include "common.h"
#include "complete.h"
#include "env.h"
#include "event.h"
#include "exec.h"
#include "expand.h"
#include "fallback.h" // IWYU pragma: keep
#include "function.h"
#include "highlight.h"
#include "history.h"
#include "input.h"
#include "intern.h"
#include "io.h"
#include "parse_constants.h"
#include "parse_util.h"
#include "parser.h"
@ -58,9 +70,7 @@
#include "tokenizer.h"
#include "wcstringutil.h"
#include "wgetopt.h"
#include "wutil.h"
#include "common.h"
#include "io.h"
#include "wutil.h" // IWYU pragma: keep
// The default prompt for the read command.
#define DEFAULT_READ_PROMPT L"set_color green; echo -n read; set_color normal; echo -n \"> \""
@ -241,7 +251,7 @@ void builtin_missing_argument(parser_t &parser, io_streams_t &streams, const wch
builtin_print_help(parser, streams, cmd, streams.err);
}
// Here follows the definition of all builtin commands. The function names are all on the form
// Here follows the definition of all builtin commands. The function names are all of the form
// builtin_NAME where NAME is the name of the builtin. so the function name for the builtin 'fg' is
// 'builtin_fg'.
//
@ -253,21 +263,7 @@ void builtin_missing_argument(parser_t &parser, io_streams_t &streams, const wch
// implementation, namely 'builtin_break_continue.
//
// Several other builtins, including jobs, ulimit and set are so big that they have been given their
// own file. These files are all named 'builtin_NAME.c', where NAME is the name of the builtin.
// These files are included directly below.
#include "builtin_commandline.cpp"
#include "builtin_complete.cpp"
#include "builtin_jobs.cpp"
#include "builtin_printf.cpp"
#include "builtin_set.cpp"
#include "builtin_set_color.cpp"
#include "builtin_ulimit.cpp"
// builtin_test lives in builtin_test.cpp
int builtin_test(parser_t &parser, io_streams_t &streams, wchar_t **argv);
// builtin_string lives in builtin_string.cpp
int builtin_string(parser_t &parser, io_streams_t &streams, wchar_t **argv);
// own module. These files are all named 'builtin_NAME.cpp', where NAME is the name of the builtin.
/// List a single key binding.
/// Returns false if no binding with that sequence and mode exists.

View File

@ -1,110 +1,81 @@
/** \file builtin_commandline.c Functions defining the commandline builtin
Functions used for implementing the commandline builtin.
*/
// Functions used for implementing the commandline builtin.
#include <assert.h>
#include <errno.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdlib.h>
#include <wchar.h>
#include <assert.h>
#include <pthread.h>
#include <errno.h>
#include <cstring>
#include <stdbool.h>
#include "fallback.h" // IWYU pragma: keep
#include "util.h"
#include "builtin.h"
#include "common.h"
#include "wgetopt.h"
#include "reader.h"
#include "proc.h"
#include "tokenizer.h"
#include "fallback.h" // IWYU pragma: keep
#include "input.h"
#include "parse_util.h"
#include "io.h"
#include "parse_util.h"
#include "proc.h"
#include "reader.h"
#include "tokenizer.h"
#include "util.h"
#include "wgetopt.h"
#include "wutil.h" // IWYU pragma: keep
class parser_t;
/**
Which part of the comandbuffer are we operating on
*/
enum
{
STRING_MODE=1, /**< Operate on entire buffer */
JOB_MODE, /**< Operate on job under cursor */
PROCESS_MODE, /**< Operate on process under cursor */
TOKEN_MODE /**< Operate on token under cursor */
}
;
/// Which part of the comandbuffer are we operating on.
enum {
STRING_MODE = 1, // operate on entire buffer
JOB_MODE, // operate on job under cursor
PROCESS_MODE, // operate on process under cursor
TOKEN_MODE // operate on token under cursor
};
/**
For text insertion, how should it be done
*/
enum
{
REPLACE_MODE=1, /**< Replace current text */
INSERT_MODE, /**< Insert at cursor position */
APPEND_MODE /**< Insert at end of current token/command/buffer */
}
;
/// For text insertion, how should it be done.
enum {
REPLACE_MODE = 1, // replace current text
INSERT_MODE, // insert at cursor position
APPEND_MODE // insert at end of current token/command/buffer
};
/**
Pointer to what the commandline builtin considers to be the current
contents of the command line buffer.
*/
static const wchar_t *current_buffer=0;
/**
What the commandline builtin considers to be the current cursor
position.
*/
/// Pointer to what the commandline builtin considers to be the current contents of the command line
/// buffer.
static const wchar_t *current_buffer = 0;
// What the commandline builtin considers to be the current cursor position.
static size_t current_cursor_pos = (size_t)(-1);
/**
Returns the current commandline buffer.
*/
static const wchar_t *get_buffer()
{
return current_buffer;
}
/// Returns the current commandline buffer.
static const wchar_t *get_buffer() { return current_buffer; }
/**
Returns the position of the cursor
*/
static size_t get_cursor_pos()
{
return current_cursor_pos;
}
/// Returns the position of the cursor.
static size_t get_cursor_pos() { return current_cursor_pos; }
static pthread_mutex_t transient_commandline_lock = PTHREAD_MUTEX_INITIALIZER;
static wcstring_list_t *get_transient_stack()
{
static wcstring_list_t *get_transient_stack() {
ASSERT_IS_MAIN_THREAD();
ASSERT_IS_LOCKED(transient_commandline_lock);
// A pointer is a little more efficient than an object as a static because we can elide the thread-safe initialization
// A pointer is a little more efficient than an object as a static because we can elide the
// thread-safe initialization.
static wcstring_list_t *result = NULL;
if (! result)
{
if (!result) {
result = new wcstring_list_t();
}
return result;
}
static bool get_top_transient(wcstring *out_result)
{
static bool get_top_transient(wcstring *out_result) {
ASSERT_IS_MAIN_THREAD();
bool result = false;
scoped_lock locker(transient_commandline_lock);
const wcstring_list_t *stack = get_transient_stack();
if (! stack->empty())
{
if (!stack->empty()) {
out_result->assign(stack->back());
result = true;
}
return result;
}
builtin_commandline_scoped_transient_t::builtin_commandline_scoped_transient_t(const wcstring &cmd)
{
builtin_commandline_scoped_transient_t::builtin_commandline_scoped_transient_t(
const wcstring &cmd) {
ASSERT_IS_MAIN_THREAD();
scoped_lock locker(transient_commandline_lock);
wcstring_list_t *stack = get_transient_stack();
@ -112,8 +83,7 @@ builtin_commandline_scoped_transient_t::builtin_commandline_scoped_transient_t(c
this->token = stack->size();
}
builtin_commandline_scoped_transient_t::~builtin_commandline_scoped_transient_t()
{
builtin_commandline_scoped_transient_t::~builtin_commandline_scoped_transient_t() {
ASSERT_IS_MAIN_THREAD();
scoped_lock locker(transient_commandline_lock);
wcstring_list_t *stack = get_transient_stack();
@ -121,19 +91,15 @@ builtin_commandline_scoped_transient_t::~builtin_commandline_scoped_transient_t(
stack->pop_back();
}
/**
Replace/append/insert the selection with/at/after the specified string.
\param begin beginning of selection
\param end end of selection
\param insert the string to insert
\param append_mode can be one of REPLACE_MODE, INSERT_MODE or APPEND_MODE, affects the way the test update is performed
*/
static void replace_part(const wchar_t *begin,
const wchar_t *end,
const wchar_t *insert,
int append_mode)
{
/// Replace/append/insert the selection with/at/after the specified string.
///
/// \param begin beginning of selection
/// \param end end of selection
/// \param insert the string to insert
/// \param append_mode can be one of REPLACE_MODE, INSERT_MODE or APPEND_MODE, affects the way the
/// test update is performed
static void replace_part(const wchar_t *begin, const wchar_t *end, const wchar_t *insert,
int append_mode) {
const wchar_t *buff = get_buffer();
size_t out_pos = get_cursor_pos();
@ -141,29 +107,23 @@ static void replace_part(const wchar_t *begin,
out.append(buff, begin - buff);
switch (append_mode)
{
case REPLACE_MODE:
{
switch (append_mode) {
case REPLACE_MODE: {
out.append(insert);
out_pos = wcslen(insert) + (begin-buff);
out_pos = wcslen(insert) + (begin - buff);
break;
}
case APPEND_MODE:
{
out.append(begin, end-begin);
case APPEND_MODE: {
out.append(begin, end - begin);
out.append(insert);
break;
}
case INSERT_MODE:
{
long cursor = get_cursor_pos() -(begin-buff);
case INSERT_MODE: {
long cursor = get_cursor_pos() - (begin - buff);
out.append(begin, cursor);
out.append(insert);
out.append(begin+cursor, end-begin-cursor);
out_pos += wcslen(insert);
out.append(begin + cursor, end - begin - cursor);
out_pos += wcslen(insert);
break;
}
}
@ -171,84 +131,60 @@ static void replace_part(const wchar_t *begin,
reader_set_buffer(out, out_pos);
}
/**
Output the specified selection.
/// Output the specified selection.
///
/// \param begin start of selection
/// \param end end of selection
/// \param cut_at_cursor whether printing should stop at the surrent cursor position
/// \param tokenize whether the string should be tokenized, printing one string token on every line
/// and skipping non-string tokens
static void write_part(const wchar_t *begin, const wchar_t *end, int cut_at_cursor, int tokenize,
io_streams_t &streams) {
size_t pos = get_cursor_pos() - (begin - get_buffer());
\param begin start of selection
\param end end of selection
\param cut_at_cursor whether printing should stop at the surrent cursor position
\param tokenize whether the string should be tokenized, printing one string token on every line and skipping non-string tokens
*/
static void write_part(const wchar_t *begin,
const wchar_t *end,
int cut_at_cursor,
int tokenize,
io_streams_t &streams)
{
size_t pos = get_cursor_pos()-(begin-get_buffer());
if (tokenize)
{
wchar_t *buff = wcsndup(begin, end-begin);
// fwprintf( stderr, L"Subshell: %ls, end char %lc\n", buff, *end );
if (tokenize) {
wchar_t *buff = wcsndup(begin, end - begin);
// fwprintf( stderr, L"Subshell: %ls, end char %lc\n", buff, *end );
wcstring out;
tokenizer_t tok(buff, TOK_ACCEPT_UNFINISHED);
tok_t token;
while (tok.next(&token))
{
if ((cut_at_cursor) &&
(token.offset + token.text.size() >= pos))
break;
while (tok.next(&token)) {
if ((cut_at_cursor) && (token.offset + token.text.size() >= pos)) break;
switch (token.type)
{
case TOK_STRING:
{
switch (token.type) {
case TOK_STRING: {
wcstring tmp = token.text;
unescape_string_in_place(&tmp, UNESCAPE_INCOMPLETE);
out.append(tmp);
out.push_back(L'\n');
break;
}
default:
{
break;
}
default: { break; }
}
}
streams.out.append(out);
free(buff);
}
else
{
if (cut_at_cursor)
{
end = begin+pos;
} else {
if (cut_at_cursor) {
end = begin + pos;
}
// debug( 0, L"woot2 %ls -> %ls", buff, esc );
// debug( 0, L"woot2 %ls -> %ls", buff, esc );
streams.out.append(begin, end - begin);
streams.out.append(L"\n");
}
}
/**
The commandline builtin. It is used for specifying a new value for
the commandline.
*/
static int builtin_commandline(parser_t &parser, io_streams_t &streams, wchar_t **argv)
{
/// The commandline builtin. It is used for specifying a new value for the commandline.
int builtin_commandline(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
wgetopter_t w;
int buffer_part=0;
int cut_at_cursor=0;
int buffer_part = 0;
int cut_at_cursor = 0;
int argc = builtin_count_args(argv);
int append_mode=0;
int append_mode = 0;
int function_mode = 0;
int selection_mode = 0;
@ -260,31 +196,23 @@ static int builtin_commandline(parser_t &parser, io_streams_t &streams, wchar_t
int search_mode = 0;
int paging_mode = 0;
const wchar_t *begin = NULL, *end = NULL;
scoped_push<const wchar_t *> saved_current_buffer(&current_buffer);
scoped_push<size_t> saved_current_cursor_pos(&current_cursor_pos);
wcstring transient_commandline;
if (get_top_transient(&transient_commandline))
{
if (get_top_transient(&transient_commandline)) {
current_buffer = transient_commandline.c_str();
current_cursor_pos = transient_commandline.size();
}
else
{
} else {
current_buffer = reader_get_buffer();
current_cursor_pos = reader_get_cursor_pos();
}
if (!get_buffer())
{
if (is_interactive_session)
{
/*
Prompt change requested while we don't have
a prompt, most probably while reading the
init files. Just ignore it.
*/
if (!get_buffer()) {
if (is_interactive_session) {
// Prompt change requested while we don't have a prompt, most probably while reading the
// init files. Just ignore it.
return 1;
}
@ -294,173 +222,146 @@ static int builtin_commandline(parser_t &parser, io_streams_t &streams, wchar_t
return 1;
}
w.woptind=0;
w.woptind = 0;
while (1)
{
static const struct woption
long_options[] =
{
{ L"append", no_argument, 0, 'a' },
{ L"insert", no_argument, 0, 'i' },
{ L"replace", no_argument, 0, 'r' },
{ L"current-job", no_argument, 0, 'j' },
{ L"current-process", no_argument, 0, 'p' },
{ L"current-token", no_argument, 0, 't' },
{ L"current-buffer", no_argument, 0, 'b' },
{ L"cut-at-cursor", no_argument, 0, 'c' },
{ L"function", no_argument, 0, 'f' },
{ L"tokenize", no_argument, 0, 'o' },
{ L"help", no_argument, 0, 'h' },
{ L"input", required_argument, 0, 'I' },
{ L"cursor", no_argument, 0, 'C' },
{ L"line", no_argument, 0, 'L' },
{ L"search-mode", no_argument, 0, 'S' },
{ L"selection", no_argument, 0, 's' },
{ L"paging-mode", no_argument, 0, 'P' },
{ 0, 0, 0, 0 }
};
while (1) {
static const struct woption long_options[] = {{L"append", no_argument, 0, 'a'},
{L"insert", no_argument, 0, 'i'},
{L"replace", no_argument, 0, 'r'},
{L"current-job", no_argument, 0, 'j'},
{L"current-process", no_argument, 0, 'p'},
{L"current-token", no_argument, 0, 't'},
{L"current-buffer", no_argument, 0, 'b'},
{L"cut-at-cursor", no_argument, 0, 'c'},
{L"function", no_argument, 0, 'f'},
{L"tokenize", no_argument, 0, 'o'},
{L"help", no_argument, 0, 'h'},
{L"input", required_argument, 0, 'I'},
{L"cursor", no_argument, 0, 'C'},
{L"line", no_argument, 0, 'L'},
{L"search-mode", no_argument, 0, 'S'},
{L"selection", no_argument, 0, 's'},
{L"paging-mode", no_argument, 0, 'P'},
{0, 0, 0, 0}};
int opt_index = 0;
int opt = w.wgetopt_long(argc,
argv,
L"abijpctwforhI:CLSsP",
long_options,
&opt_index);
if (opt == -1)
break;
int opt = w.wgetopt_long(argc, argv, L"abijpctwforhI:CLSsP", long_options, &opt_index);
if (opt == -1) break;
switch (opt)
{
case 0:
if (long_options[opt_index].flag != 0)
break;
streams.err.append_format(BUILTIN_ERR_UNKNOWN,
argv[0],
long_options[opt_index].name);
switch (opt) {
case 0: {
if (long_options[opt_index].flag != 0) break;
streams.err.append_format(BUILTIN_ERR_UNKNOWN, argv[0],
long_options[opt_index].name);
builtin_print_help(parser, streams, argv[0], streams.err);
return 1;
case L'a':
}
case L'a': {
append_mode = APPEND_MODE;
break;
case L'b':
}
case L'b': {
buffer_part = STRING_MODE;
break;
case L'i':
}
case L'i': {
append_mode = INSERT_MODE;
break;
case L'r':
}
case L'r': {
append_mode = REPLACE_MODE;
break;
case 'c':
cut_at_cursor=1;
}
case 'c': {
cut_at_cursor = 1;
break;
case 't':
}
case 't': {
buffer_part = TOKEN_MODE;
break;
case 'j':
}
case 'j': {
buffer_part = JOB_MODE;
break;
case 'p':
}
case 'p': {
buffer_part = PROCESS_MODE;
break;
case 'f':
function_mode=1;
}
case 'f': {
function_mode = 1;
break;
case 'o':
tokenize=1;
}
case 'o': {
tokenize = 1;
break;
case 'I':
}
case 'I': {
current_buffer = w.woptarg;
current_cursor_pos = wcslen(w.woptarg);
break;
case 'C':
}
case 'C': {
cursor_mode = 1;
break;
case 'L':
}
case 'L': {
line_mode = 1;
break;
case 'S':
}
case 'S': {
search_mode = 1;
break;
case 's':
}
case 's': {
selection_mode = 1;
break;
case 'P':
}
case 'P': {
paging_mode = 1;
break;
case 'h':
}
case 'h': {
builtin_print_help(parser, streams, argv[0], streams.out);
return 0;
case L'?':
builtin_unknown_option(parser, streams, argv[0], argv[w.woptind-1]);
}
case L'?': {
builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return 1;
}
}
}
if (function_mode)
{
if (function_mode) {
int i;
/*
Check for invalid switch combinations
*/
if (buffer_part || cut_at_cursor || append_mode || tokenize || cursor_mode || line_mode || search_mode || paging_mode)
{
streams.err.append_format(BUILTIN_ERR_COMBO,
argv[0]);
// Check for invalid switch combinations.
if (buffer_part || cut_at_cursor || append_mode || tokenize || cursor_mode || line_mode ||
search_mode || paging_mode) {
streams.err.append_format(BUILTIN_ERR_COMBO, argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err);
return 1;
}
if (argc == w.woptind)
{
streams.err.append_format(BUILTIN_ERR_MISSING,
argv[0]);
if (argc == w.woptind) {
streams.err.append_format(BUILTIN_ERR_MISSING, argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err);
return 1;
}
for (i=w.woptind; i<argc; i++)
{
for (i = w.woptind; i < argc; i++) {
wchar_t c = input_function_get_code(argv[i]);
if (c != INPUT_CODE_NONE)
{
/*
input_unreadch inserts the specified keypress or
readline function at the back of the queue of unused
keypresses
*/
if (c != INPUT_CODE_NONE) {
// input_unreadch inserts the specified keypress or readline function at the back of
// the queue of unused keypresses.
input_queue_ch(c);
}
else
{
streams.err.append_format(_(L"%ls: Unknown input function '%ls'\n"),
argv[0],
argv[i]);
} else {
streams.err.append_format(_(L"%ls: Unknown input function '%ls'\n"), argv[0],
argv[i]);
builtin_print_help(parser, streams, argv[0], streams.err);
return 1;
}
@ -469,88 +370,66 @@ static int builtin_commandline(parser_t &parser, io_streams_t &streams, wchar_t
return 0;
}
if (selection_mode)
{
if (selection_mode) {
size_t start, len;
const wchar_t *buffer = reader_get_buffer();
if (reader_get_selection(&start, &len))
{
if (reader_get_selection(&start, &len)) {
streams.out.append(buffer + start, len);
}
return 0;
}
/*
Check for invalid switch combinations
*/
if ((search_mode || line_mode || cursor_mode || paging_mode) && (argc-w.woptind > 1))
{
streams.err.append_format(argv[0],
L": Too many arguments\n",
NULL);
// Check for invalid switch combinations.
if ((search_mode || line_mode || cursor_mode || paging_mode) && (argc - w.woptind > 1)) {
streams.err.append_format(argv[0], L": Too many arguments\n", NULL);
builtin_print_help(parser, streams, argv[0], streams.err);
return 1;
}
if ((buffer_part || tokenize || cut_at_cursor) && (cursor_mode || line_mode || search_mode || paging_mode))
{
streams.err.append_format(BUILTIN_ERR_COMBO,
argv[0]);
if ((buffer_part || tokenize || cut_at_cursor) &&
(cursor_mode || line_mode || search_mode || paging_mode)) {
streams.err.append_format(BUILTIN_ERR_COMBO, argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err);
return 1;
}
if ((tokenize || cut_at_cursor) && (argc-w.woptind))
{
streams.err.append_format(BUILTIN_ERR_COMBO2,
argv[0],
L"--cut-at-cursor and --tokenize can not be used when setting the commandline");
if ((tokenize || cut_at_cursor) && (argc - w.woptind)) {
streams.err.append_format(
BUILTIN_ERR_COMBO2, argv[0],
L"--cut-at-cursor and --tokenize can not be used when setting the commandline");
builtin_print_help(parser, streams, argv[0], streams.err);
return 1;
}
if (append_mode && !(argc-w.woptind))
{
streams.err.append_format(BUILTIN_ERR_COMBO2,
argv[0],
L"insertion mode switches can not be used when not in insertion mode");
if (append_mode && !(argc - w.woptind)) {
streams.err.append_format(
BUILTIN_ERR_COMBO2, argv[0],
L"insertion mode switches can not be used when not in insertion mode");
builtin_print_help(parser, streams, argv[0], streams.err);
return 1;
}
/*
Set default modes
*/
if (!append_mode)
{
// Set default modes.
if (!append_mode) {
append_mode = REPLACE_MODE;
}
if (!buffer_part)
{
if (!buffer_part) {
buffer_part = STRING_MODE;
}
if (cursor_mode)
{
if (argc-w.woptind)
{
if (cursor_mode) {
if (argc - w.woptind) {
wchar_t *endptr;
long new_pos;
errno = 0;
new_pos = wcstol(argv[w.woptind], &endptr, 10);
if (*endptr || errno)
{
streams.err.append_format(BUILTIN_ERR_NOT_NUMBER,
argv[0],
argv[w.woptind]);
if (*endptr || errno) {
streams.err.append_format(BUILTIN_ERR_NOT_NUMBER, argv[0], argv[w.woptind]);
builtin_print_help(parser, streams, argv[0], streams.err);
}
@ -558,101 +437,63 @@ static int builtin_commandline(parser_t &parser, io_streams_t &streams, wchar_t
new_pos = maxi(0L, mini(new_pos, (long)wcslen(current_buffer)));
reader_set_buffer(current_buffer, (size_t)new_pos);
return 0;
}
else
{
streams.out.append_format( L"%lu\n", (unsigned long)reader_get_cursor_pos());
} else {
streams.out.append_format(L"%lu\n", (unsigned long)reader_get_cursor_pos());
return 0;
}
}
if (line_mode)
{
if (line_mode) {
size_t pos = reader_get_cursor_pos();
const wchar_t *buff = reader_get_buffer();
streams.out.append_format( L"%lu\n", (unsigned long)parse_util_lineno(buff, pos));
streams.out.append_format(L"%lu\n", (unsigned long)parse_util_lineno(buff, pos));
return 0;
}
if (search_mode)
{
return ! reader_search_mode();
if (search_mode) {
return !reader_search_mode();
}
if (paging_mode)
{
return ! reader_has_pager_contents();
if (paging_mode) {
return !reader_has_pager_contents();
}
switch (buffer_part)
{
case STRING_MODE:
{
switch (buffer_part) {
case STRING_MODE: {
begin = get_buffer();
end = begin+wcslen(begin);
end = begin + wcslen(begin);
break;
}
case PROCESS_MODE:
{
parse_util_process_extent(get_buffer(),
get_cursor_pos(),
&begin,
&end);
case PROCESS_MODE: {
parse_util_process_extent(get_buffer(), get_cursor_pos(), &begin, &end);
break;
}
case JOB_MODE:
{
parse_util_job_extent(get_buffer(),
get_cursor_pos(),
&begin,
&end);
case JOB_MODE: {
parse_util_job_extent(get_buffer(), get_cursor_pos(), &begin, &end);
break;
}
case TOKEN_MODE:
{
parse_util_token_extent(get_buffer(),
get_cursor_pos(),
&begin,
&end,
0, 0);
case TOKEN_MODE: {
parse_util_token_extent(get_buffer(), get_cursor_pos(), &begin, &end, 0, 0);
break;
}
}
switch (argc-w.woptind)
{
case 0:
{
switch (argc - w.woptind) {
case 0: {
write_part(begin, end, cut_at_cursor, tokenize, streams);
break;
}
case 1:
{
case 1: {
replace_part(begin, end, argv[w.woptind], append_mode);
break;
}
default:
{
default: {
wcstring sb = argv[w.woptind];
int i;
for (i=w.woptind+1; i<argc; i++)
{
for (int i = w.woptind + 1; i < argc; i++) {
sb.push_back(L'\n');
sb.append(argv[i]);
}
replace_part(begin, end, sb.c_str(), append_mode);
break;
}
}

11
src/builtin_commandline.h Normal file
View File

@ -0,0 +1,11 @@
// Prototypes for functions for executing builtin_commandline functions.
#ifndef FISH_BUILTIN_COMMANDLINE_H
#define FISH_BUILTIN_COMMANDLINE_H
#include <wchar.h>
#include <cstring>
class parser_t;
int builtin_commandline(parser_t &parser, io_streams_t &streams, wchar_t **argv);
#endif

View File

@ -1,237 +1,136 @@
/** \file builtin_complete.c Functions defining the complete builtin
Functions used for implementing the complete builtin.
*/
// Functions used for implementing the complete builtin.
#include <stdbool.h>
#include <stdlib.h>
#include <wchar.h>
#include <memory> // IWYU pragma: keep
#include <string>
#include <vector>
#include <memory> // IWYU pragma: keep
#include <stdbool.h>
#include "fallback.h" // IWYU pragma: keep
#include "builtin.h"
#include "common.h"
#include "complete.h"
#include "wgetopt.h"
#include "parser.h"
#include "reader.h"
#include "env.h"
#include "fallback.h" // IWYU pragma: keep
#include "io.h"
#include "parse_constants.h"
#include "proc.h"
#include "parse_util.h"
#include "parser.h"
#include "proc.h"
#include "reader.h"
#include "wgetopt.h"
#include "wutil.h" // IWYU pragma: keep
/*
builtin_complete_* are a set of rather silly looping functions that
make sure that all the proper combinations of complete_add or
complete_remove get called. This is needed since complete allows you
to specify multiple switches on a single commandline, like 'complete
-s a -s b -s c', but the complete_add function only accepts one
short switch and one long switch.
*/
// builtin_complete_* are a set of rather silly looping functions that make sure that all the proper
// combinations of complete_add or complete_remove get called. This is needed since complete allows
// you to specify multiple switches on a single commandline, like 'complete -s a -s b -s c', but the
// complete_add function only accepts one short switch and one long switch.
/**
Silly function
*/
static void builtin_complete_add2(const wchar_t *cmd,
int cmd_type,
const wchar_t *short_opt,
const wcstring_list_t &gnu_opt,
const wcstring_list_t &old_opt,
int result_mode,
const wchar_t *condition,
const wchar_t *comp,
const wchar_t *desc,
int flags)
{
/// Silly function.
static void builtin_complete_add2(const wchar_t *cmd, int cmd_type, const wchar_t *short_opt,
const wcstring_list_t &gnu_opt, const wcstring_list_t &old_opt,
int result_mode, const wchar_t *condition, const wchar_t *comp,
const wchar_t *desc, int flags) {
size_t i;
const wchar_t *s;
for (s=short_opt; *s; s++)
{
complete_add(cmd,
cmd_type,
wcstring(1, *s),
option_type_short,
result_mode,
condition,
comp,
desc,
flags);
for (s = short_opt; *s; s++) {
complete_add(cmd, cmd_type, wcstring(1, *s), option_type_short, result_mode, condition,
comp, desc, flags);
}
for (i=0; i<gnu_opt.size(); i++)
{
complete_add(cmd,
cmd_type,
gnu_opt.at(i),
option_type_double_long,
result_mode,
condition,
comp,
desc,
flags);
for (i = 0; i < gnu_opt.size(); i++) {
complete_add(cmd, cmd_type, gnu_opt.at(i), option_type_double_long, result_mode, condition,
comp, desc, flags);
}
for (i=0; i<old_opt.size(); i++)
{
complete_add(cmd,
cmd_type,
old_opt.at(i),
option_type_single_long,
result_mode,
condition,
comp,
desc,
flags);
for (i = 0; i < old_opt.size(); i++) {
complete_add(cmd, cmd_type, old_opt.at(i), option_type_single_long, result_mode, condition,
comp, desc, flags);
}
if (old_opt.empty() && gnu_opt.empty() && wcslen(short_opt) == 0)
{
complete_add(cmd,
cmd_type,
wcstring(),
option_type_args_only,
result_mode,
condition,
comp,
desc,
flags);
if (old_opt.empty() && gnu_opt.empty() && wcslen(short_opt) == 0) {
complete_add(cmd, cmd_type, wcstring(), option_type_args_only, result_mode, condition, comp,
desc, flags);
}
}
/**
Silly function
*/
static void builtin_complete_add(const wcstring_list_t &cmd,
const wcstring_list_t &path,
const wchar_t *short_opt,
wcstring_list_t &gnu_opt,
wcstring_list_t &old_opt,
int result_mode,
int authoritative,
const wchar_t *condition,
const wchar_t *comp,
const wchar_t *desc,
int flags)
{
for (size_t i=0; i<cmd.size(); i++)
{
builtin_complete_add2(cmd.at(i).c_str(),
COMMAND,
short_opt,
gnu_opt,
old_opt,
result_mode,
condition,
comp,
desc,
flags);
/// Silly function.
static void builtin_complete_add(const wcstring_list_t &cmd, const wcstring_list_t &path,
const wchar_t *short_opt, wcstring_list_t &gnu_opt,
wcstring_list_t &old_opt, int result_mode, int authoritative,
const wchar_t *condition, const wchar_t *comp, const wchar_t *desc,
int flags) {
for (size_t i = 0; i < cmd.size(); i++) {
builtin_complete_add2(cmd.at(i).c_str(), COMMAND, short_opt, gnu_opt, old_opt, result_mode,
condition, comp, desc, flags);
if (authoritative != -1)
{
complete_set_authoritative(cmd.at(i).c_str(),
COMMAND,
authoritative);
if (authoritative != -1) {
complete_set_authoritative(cmd.at(i).c_str(), COMMAND, authoritative);
}
}
for (size_t i=0; i<path.size(); i++)
{
builtin_complete_add2(path.at(i).c_str(),
PATH,
short_opt,
gnu_opt,
old_opt,
result_mode,
condition,
comp,
desc,
flags);
for (size_t i = 0; i < path.size(); i++) {
builtin_complete_add2(path.at(i).c_str(), PATH, short_opt, gnu_opt, old_opt, result_mode,
condition, comp, desc, flags);
if (authoritative != -1)
{
complete_set_authoritative(path.at(i).c_str(),
PATH,
authoritative);
if (authoritative != -1) {
complete_set_authoritative(path.at(i).c_str(), PATH, authoritative);
}
}
}
static void builtin_complete_remove_cmd(const wcstring &cmd,
int cmd_type,
const wchar_t *short_opt,
static void builtin_complete_remove_cmd(const wcstring &cmd, int cmd_type, const wchar_t *short_opt,
const wcstring_list_t &gnu_opt,
const wcstring_list_t &old_opt)
{
const wcstring_list_t &old_opt) {
bool removed = false;
size_t i;
for (i=0; short_opt[i] != L'\0'; i++)
{
for (i = 0; short_opt[i] != L'\0'; i++) {
complete_remove(cmd, cmd_type, wcstring(1, short_opt[i]), option_type_short);
removed = true;
}
for (i=0; i < old_opt.size(); i++)
{
for (i = 0; i < old_opt.size(); i++) {
complete_remove(cmd, cmd_type, old_opt.at(i), option_type_single_long);
removed = true;
}
for (i=0; i < gnu_opt.size(); i++)
{
for (i = 0; i < gnu_opt.size(); i++) {
complete_remove(cmd, cmd_type, gnu_opt.at(i), option_type_double_long);
removed = true;
}
if (! removed)
{
// This means that all loops were empty
if (!removed) {
// This means that all loops were empty.
complete_remove_all(cmd, cmd_type);
}
}
static void builtin_complete_remove(const wcstring_list_t &cmd,
const wcstring_list_t &path,
const wchar_t *short_opt,
const wcstring_list_t &gnu_opt,
const wcstring_list_t &old_opt)
{
for (size_t i=0; i<cmd.size(); i++)
{
static void builtin_complete_remove(const wcstring_list_t &cmd, const wcstring_list_t &path,
const wchar_t *short_opt, const wcstring_list_t &gnu_opt,
const wcstring_list_t &old_opt) {
for (size_t i = 0; i < cmd.size(); i++) {
builtin_complete_remove_cmd(cmd.at(i), COMMAND, short_opt, gnu_opt, old_opt);
}
for (size_t i=0; i<path.size(); i++)
{
for (size_t i = 0; i < path.size(); i++) {
builtin_complete_remove_cmd(path.at(i), PATH, short_opt, gnu_opt, old_opt);
}
}
/**
The complete builtin. Used for specifying programmable
tab-completions. Calls the functions in complete.c for any heavy
lifting. Defined in builtin_complete.c
*/
static int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv)
{
/// The complete builtin. Used for specifying programmable tab-completions. Calls the functions in
// complete.cpp for any heavy lifting.
int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
ASSERT_IS_MAIN_THREAD();
wgetopter_t w;
bool res=false;
int argc=0;
int result_mode=SHARED;
bool res = false;
int argc = 0;
int result_mode = SHARED;
int remove = 0;
int authoritative = -1;
wcstring short_opt;
wcstring_list_t gnu_opt, old_opt;
const wchar_t *comp=L"", *desc=L"", *condition=L"";
const wchar_t *comp = L"", *desc = L"", *condition = L"";
bool do_complete = false;
wcstring do_complete_param;
@ -240,173 +139,145 @@ static int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **a
wcstring_list_t path;
wcstring_list_t wrap_targets;
static int recursion_level=0;
static int recursion_level = 0;
argc = builtin_count_args(argv);
w.woptind=0;
w.woptind = 0;
while (! res)
{
static const struct woption
long_options[] =
{
{ L"exclusive", no_argument, 0, 'x' },
{ L"no-files", no_argument, 0, 'f' },
{ L"require-parameter", no_argument, 0, 'r' },
{ L"path", required_argument, 0, 'p' },
{ L"command", required_argument, 0, 'c' },
{ L"short-option", required_argument, 0, 's' },
{ L"long-option", required_argument, 0, 'l' },
{ L"old-option", required_argument, 0, 'o' },
{ L"description", required_argument, 0, 'd' },
{ L"arguments", required_argument, 0, 'a' },
{ L"erase", no_argument, 0, 'e' },
{ L"unauthoritative", no_argument, 0, 'u' },
{ L"authoritative", no_argument, 0, 'A' },
{ L"condition", required_argument, 0, 'n' },
{ L"wraps", required_argument, 0, 'w' },
{ L"do-complete", optional_argument, 0, 'C' },
{ L"help", no_argument, 0, 'h' },
{ 0, 0, 0, 0 }
};
while (!res) {
static const struct woption long_options[] = {{L"exclusive", no_argument, 0, 'x'},
{L"no-files", no_argument, 0, 'f'},
{L"require-parameter", no_argument, 0, 'r'},
{L"path", required_argument, 0, 'p'},
{L"command", required_argument, 0, 'c'},
{L"short-option", required_argument, 0, 's'},
{L"long-option", required_argument, 0, 'l'},
{L"old-option", required_argument, 0, 'o'},
{L"description", required_argument, 0, 'd'},
{L"arguments", required_argument, 0, 'a'},
{L"erase", no_argument, 0, 'e'},
{L"unauthoritative", no_argument, 0, 'u'},
{L"authoritative", no_argument, 0, 'A'},
{L"condition", required_argument, 0, 'n'},
{L"wraps", required_argument, 0, 'w'},
{L"do-complete", optional_argument, 0, 'C'},
{L"help", no_argument, 0, 'h'},
{0, 0, 0, 0}};
int opt_index = 0;
int opt =
w.wgetopt_long(argc, argv, L"a:c:p:s:l:o:d:frxeuAn:C::w:h", long_options, &opt_index);
if (opt == -1) break;
int opt = w.wgetopt_long(argc,
argv,
L"a:c:p:s:l:o:d:frxeuAn:C::w:h",
long_options,
&opt_index);
if (opt == -1)
break;
switch (opt)
{
case 0:
if (long_options[opt_index].flag != 0)
break;
streams.err.append_format(BUILTIN_ERR_UNKNOWN,
argv[0],
long_options[opt_index].name);
switch (opt) {
case 0: {
if (long_options[opt_index].flag != 0) break;
streams.err.append_format(BUILTIN_ERR_UNKNOWN, argv[0],
long_options[opt_index].name);
builtin_print_help(parser, streams, argv[0], streams.err);
res = true;
break;
case 'x':
}
case 'x': {
result_mode |= EXCLUSIVE;
break;
case 'f':
}
case 'f': {
result_mode |= NO_FILES;
break;
case 'r':
}
case 'r': {
result_mode |= NO_COMMON;
break;
}
case 'p':
case 'c':
{
case 'c': {
wcstring tmp;
if (unescape_string(w.woptarg, &tmp, UNESCAPE_SPECIAL))
{
if (opt=='p')
if (unescape_string(w.woptarg, &tmp, UNESCAPE_SPECIAL)) {
if (opt == 'p')
path.push_back(tmp);
else
cmd.push_back(tmp);
}
else
{
} else {
streams.err.append_format(L"%ls: Invalid token '%ls'\n", argv[0], w.woptarg);
res = true;
}
break;
}
case 'd':
case 'd': {
desc = w.woptarg;
break;
case 'u':
authoritative=0;
}
case 'u': {
authoritative = 0;
break;
case 'A':
authoritative=1;
}
case 'A': {
authoritative = 1;
break;
case 's':
}
case 's': {
short_opt.append(w.woptarg);
break;
case 'l':
}
case 'l': {
gnu_opt.push_back(w.woptarg);
break;
case 'o':
}
case 'o': {
old_opt.push_back(w.woptarg);
break;
case 'a':
}
case 'a': {
comp = w.woptarg;
break;
case 'e':
}
case 'e': {
remove = 1;
break;
case 'n':
}
case 'n': {
condition = w.woptarg;
break;
case 'w':
}
case 'w': {
wrap_targets.push_back(w.woptarg);
break;
case 'C':
{
}
case 'C': {
do_complete = true;
const wchar_t *arg = w.woptarg ? w.woptarg : reader_get_buffer();
if (arg == NULL)
{
// This corresponds to using 'complete -C' in non-interactive mode
// See #2361
builtin_missing_argument(parser, streams, argv[0], argv[w.woptind-1]);
if (arg == NULL) {
// This corresponds to using 'complete -C' in non-interactive mode.
// See #2361.
builtin_missing_argument(parser, streams, argv[0], argv[w.woptind - 1]);
return STATUS_BUILTIN_ERROR;
}
do_complete_param = arg;
break;
}
case 'h':
case 'h': {
builtin_print_help(parser, streams, argv[0], streams.out);
return 0;
case '?':
builtin_unknown_option(parser, streams, argv[0], argv[w.woptind-1]);
}
case '?': {
builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
res = true;
break;
}
}
}
if (!res)
{
if (condition && wcslen(condition))
{
if (!res) {
if (condition && wcslen(condition)) {
const wcstring condition_string = condition;
parse_error_list_t errors;
if (parse_util_detect_errors(condition_string, &errors, false /* do not accept incomplete */))
{
streams.err.append_format(L"%ls: Condition '%ls' contained a syntax error",
argv[0],
condition);
for (size_t i=0; i < errors.size(); i++)
{
if (parse_util_detect_errors(condition_string, &errors,
false /* do not accept incomplete */)) {
streams.err.append_format(L"%ls: Condition '%ls' contained a syntax error", argv[0],
condition);
for (size_t i = 0; i < errors.size(); i++) {
streams.err.append_format(L"\n%s: ", argv[0]);
streams.err.append(errors.at(i).describe(condition_string));
}
@ -415,23 +286,18 @@ static int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **a
}
}
if (!res)
{
if (comp && wcslen(comp))
{
if (!res) {
if (comp && wcslen(comp)) {
wcstring prefix;
if (argv[0])
{
if (argv[0]) {
prefix.append(argv[0]);
prefix.append(L": ");
}
wcstring err_text;
if (parser.detect_errors_in_argument_list(comp, &err_text, prefix.c_str()))
{
if (parser.detect_errors_in_argument_list(comp, &err_text, prefix.c_str())) {
streams.err.append_format(L"%ls: Completion '%ls' contained a syntax error\n",
argv[0],
comp);
argv[0], comp);
streams.err.append(err_text);
streams.err.push_back(L'\n');
res = true;
@ -439,46 +305,51 @@ static int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **a
}
}
if (!res)
{
if (do_complete)
{
if (!res) {
if (do_complete) {
const wchar_t *token;
parse_util_token_extent(do_complete_param.c_str(), do_complete_param.size(), &token, 0, 0, 0);
/* Create a scoped transient command line, so that bulitin_commandline will see our argument, not the reader buffer */
parse_util_token_extent(do_complete_param.c_str(), do_complete_param.size(), &token, 0,
0, 0);
// Create a scoped transient command line, so that bulitin_commandline will see our
// argument, not the reader buffer.
builtin_commandline_scoped_transient_t temp_buffer(do_complete_param);
if (recursion_level < 1)
{
if (recursion_level < 1) {
recursion_level++;
std::vector<completion_t> comp;
complete(do_complete_param, &comp, COMPLETION_REQUEST_DEFAULT, env_vars_snapshot_t::current());
complete(do_complete_param, &comp, COMPLETION_REQUEST_DEFAULT,
env_vars_snapshot_t::current());
for (size_t i=0; i< comp.size() ; i++)
{
const completion_t &next = comp.at(i);
for (size_t i = 0; i < comp.size(); i++) {
const completion_t &next = comp.at(i);
/* Make a fake commandline, and then apply the completion to it. */
// Make a fake commandline, and then apply the completion to it.
const wcstring faux_cmdline = token;
size_t tmp_cursor = faux_cmdline.size();
wcstring faux_cmdline_with_completion = completion_apply_to_command_line(next.completion, next.flags, faux_cmdline, &tmp_cursor, false);
wcstring faux_cmdline_with_completion = completion_apply_to_command_line(
next.completion, next.flags, faux_cmdline, &tmp_cursor, false);
/* completion_apply_to_command_line will append a space unless COMPLETE_NO_SPACE is set. We don't want to set COMPLETE_NO_SPACE because that won't close quotes. What we want is to close the quote, but not append the space. So we just look for the space and clear it. */
if (!(next.flags & COMPLETE_NO_SPACE) && string_suffixes_string(L" ", faux_cmdline_with_completion))
{
faux_cmdline_with_completion.resize(faux_cmdline_with_completion.size() - 1);
// completion_apply_to_command_line will append a space unless COMPLETE_NO_SPACE
// is set. We don't want to set COMPLETE_NO_SPACE because that won't close
// quotes. What we want is to close the quote, but not append the space. So we
// just look for the space and clear it.
if (!(next.flags & COMPLETE_NO_SPACE) &&
string_suffixes_string(L" ", faux_cmdline_with_completion)) {
faux_cmdline_with_completion.resize(faux_cmdline_with_completion.size() -
1);
}
/* The input data is meant to be something like you would have on the command line, e.g. includes backslashes. The output should be raw, i.e. unescaped. So we need to unescape the command line. See #1127 */
// The input data is meant to be something like you would have on the command
// line, e.g. includes backslashes. The output should be raw, i.e. unescaped. So
// we need to unescape the command line. See #1127.
unescape_string_in_place(&faux_cmdline_with_completion, UNESCAPE_DEFAULT);
streams.out.append(faux_cmdline_with_completion);
/* Append any description */
if (! next.description.empty())
{
// Append any description.
if (!next.description.empty()) {
streams.out.push_back(L'\t');
streams.out.append(next.description);
}
@ -487,58 +358,32 @@ static int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **a
recursion_level--;
}
}
else if (w.woptind != argc)
{
streams.err.append_format(_(L"%ls: Too many arguments\n"),
argv[0]);
} else if (w.woptind != argc) {
streams.err.append_format(_(L"%ls: Too many arguments\n"), argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err);
res = true;
}
else if (cmd.empty() && path.empty())
{
/* No arguments specified, meaning we print the definitions of
* all specified completions to stdout.*/
} else if (cmd.empty() && path.empty()) {
// No arguments specified, meaning we print the definitions of all specified completions
// to stdout.
streams.out.append(complete_print());
}
else
{
} else {
int flags = COMPLETE_AUTO_SPACE;
if (remove)
{
builtin_complete_remove(cmd,
path,
short_opt.c_str(),
gnu_opt,
old_opt);
if (remove) {
builtin_complete_remove(cmd, path, short_opt.c_str(), gnu_opt, old_opt);
} else {
builtin_complete_add(cmd, path, short_opt.c_str(), gnu_opt, old_opt, result_mode,
authoritative, condition, comp, desc, flags);
}
else
{
builtin_complete_add(cmd,
path,
short_opt.c_str(),
gnu_opt,
old_opt,
result_mode,
authoritative,
condition,
comp,
desc,
flags);
}
// Handle wrap targets (probably empty)
// We only wrap commands, not paths
for (size_t w=0; w < wrap_targets.size(); w++)
{
// Handle wrap targets (probably empty). We only wrap commands, not paths.
for (size_t w = 0; w < wrap_targets.size(); w++) {
const wcstring &wrap_target = wrap_targets.at(w);
for (size_t i=0; i < cmd.size(); i++)
{
(remove ? complete_remove_wrapper : complete_add_wrapper)(cmd.at(i), wrap_target);
for (size_t i = 0; i < cmd.size(); i++) {
(remove ? complete_remove_wrapper : complete_add_wrapper)(cmd.at(i),
wrap_target);
}
}
}

11
src/builtin_complete.h Normal file
View File

@ -0,0 +1,11 @@
// Prototypes for functions for executing builtin_complete functions.
#ifndef FISH_BUILTIN_COMPLETE_H
#define FISH_BUILTIN_COMPLETE_H
#include <wchar.h>
#include <cstring>
class parser_t;
int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv);
#endif

View File

@ -1,6 +1,4 @@
/** \file builtin_jobs.c
Functions for executing the jobs builtin.
*/
// Functions for executing the jobs builtin.
#include "config.h" // IWYU pragma: keep
#include <errno.h>
@ -9,75 +7,53 @@
#include <sys/time.h>
#endif
#include "fallback.h" // IWYU pragma: keep
#include "wutil.h"
#include "builtin.h"
#include "proc.h"
#include "common.h"
#include "wgetopt.h"
#include "fallback.h" // IWYU pragma: keep
#include "io.h"
#include "proc.h"
#include "wgetopt.h"
#include "wutil.h" // IWYU pragma: keep
class parser_t;
/**
Print modes for the jobs builtin
*/
enum
{
JOBS_DEFAULT, /**< Print lots of general info */
JOBS_PRINT_PID, /**< Print pid of each process in job */
JOBS_PRINT_COMMAND, /**< Print command name of each process in job */
JOBS_PRINT_GROUP, /**< Print group id of job */
}
;
/// Print modes for the jobs builtin.
enum {
JOBS_DEFAULT, // print lots of general info
JOBS_PRINT_PID, // print pid of each process in job
JOBS_PRINT_COMMAND, // print command name of each process in job
JOBS_PRINT_GROUP, // print group id of job
};
#ifdef HAVE__PROC_SELF_STAT
/**
Calculates the cpu usage (in percent) of the specified job.
*/
static int cpu_use(const job_t *j)
{
double u=0;
/// Calculates the cpu usage (in percent) of the specified job.
static int cpu_use(const job_t *j) {
double u = 0;
process_t *p;
for (p=j->first_process; p; p=p->next)
{
for (p = j->first_process; p; p = p->next) {
struct timeval t;
int jiffies;
gettimeofday(&t, 0);
jiffies = proc_get_jiffies(p);
double t1 = 1000000.0*p->last_time.tv_sec+p->last_time.tv_usec;
double t2 = 1000000.0*t.tv_sec+t.tv_usec;
double t1 = 1000000.0 * p->last_time.tv_sec + p->last_time.tv_usec;
double t2 = 1000000.0 * t.tv_sec + t.tv_usec;
/* fwprintf( stderr, L"t1 %f t2 %f p1 %d p2 %d\n",
t1, t2, jiffies, p->last_jiffies );
*/
u += ((double)(jiffies-p->last_jiffies))/(t2-t1);
// fwprintf( stderr, L"t1 %f t2 %f p1 %d p2 %d\n", t1, t2, jiffies, p->last_jiffies );
u += ((double)(jiffies - p->last_jiffies)) / (t2 - t1);
}
return u*1000000;
return u * 1000000;
}
#endif
/**
Print information about the specified job
*/
static void builtin_jobs_print(const job_t *j, int mode, int header, io_streams_t &streams)
{
/// Print information about the specified job.
static void builtin_jobs_print(const job_t *j, int mode, int header, io_streams_t &streams) {
process_t *p;
switch (mode)
{
case JOBS_DEFAULT:
{
if (header)
{
/*
Print table header before first job
*/
switch (mode) {
case JOBS_DEFAULT: {
if (header) {
// Print table header before first job.
streams.out.append(_(L"Job\tGroup\t"));
#ifdef HAVE__PROC_SELF_STAT
streams.out.append(_(L"CPU\t"));
@ -85,234 +61,149 @@ static void builtin_jobs_print(const job_t *j, int mode, int header, io_streams_
streams.out.append(_(L"State\tCommand\n"));
}
streams.out.append_format( L"%d\t%d\t", j->job_id, j->pgid);
streams.out.append_format(L"%d\t%d\t", j->job_id, j->pgid);
#ifdef HAVE__PROC_SELF_STAT
streams.out.append_format( L"%d%%\t", cpu_use(j));
streams.out.append_format(L"%d%%\t", cpu_use(j));
#endif
streams.out.append(job_is_stopped(j)?_(L"stopped"):_(L"running"));
streams.out.append(job_is_stopped(j) ? _(L"stopped") : _(L"running"));
streams.out.append(L"\t");
streams.out.append(j->command_wcstr());
streams.out.append(L"\n");
break;
}
case JOBS_PRINT_GROUP:
{
if (header)
{
/*
Print table header before first job
*/
case JOBS_PRINT_GROUP: {
if (header) {
// Print table header before first job.
streams.out.append(_(L"Group\n"));
}
streams.out.append_format( L"%d\n", j->pgid);
streams.out.append_format(L"%d\n", j->pgid);
break;
}
case JOBS_PRINT_PID:
{
if (header)
{
/*
Print table header before first job
*/
case JOBS_PRINT_PID: {
if (header) {
// Print table header before first job.
streams.out.append(_(L"Process\n"));
}
for (p=j->first_process; p; p=p->next)
{
streams.out.append_format( L"%d\n", p->pid);
for (p = j->first_process; p; p = p->next) {
streams.out.append_format(L"%d\n", p->pid);
}
break;
}
case JOBS_PRINT_COMMAND:
{
if (header)
{
/*
Print table header before first job
*/
case JOBS_PRINT_COMMAND: {
if (header) {
// Print table header before first job.
streams.out.append(_(L"Command\n"));
}
for (p=j->first_process; p; p=p->next)
{
streams.out.append_format( L"%ls\n", p->argv0());
for (p = j->first_process; p; p = p->next) {
streams.out.append_format(L"%ls\n", p->argv0());
}
break;
}
}
}
/**
The jobs builtin. Used fopr printing running jobs. Defined in builtin_jobs.c.
*/
static int builtin_jobs(parser_t &parser, io_streams_t &streams, wchar_t **argv)
{
/// The jobs builtin. Used fopr printing running jobs. Defined in builtin_jobs.c.
int builtin_jobs(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
wgetopter_t w;
int argc=0;
int found=0;
int mode=JOBS_DEFAULT;
int argc = 0;
int found = 0;
int mode = JOBS_DEFAULT;
int print_last = 0;
argc = builtin_count_args(argv);
w.woptind=0;
w.woptind = 0;
while (1)
{
static const struct woption
long_options[] =
{
{
L"pid", no_argument, 0, 'p'
}
,
{
L"command", no_argument, 0, 'c'
}
,
{
L"group", no_argument, 0, 'g'
}
,
{
L"last", no_argument, 0, 'l'
}
,
{
L"help", no_argument, 0, 'h'
}
,
{
0, 0, 0, 0
}
}
;
while (1) {
static const struct woption long_options[] = {
{L"pid", no_argument, 0, 'p'}, {L"command", no_argument, 0, 'c'},
{L"group", no_argument, 0, 'g'}, {L"last", no_argument, 0, 'l'},
{L"help", no_argument, 0, 'h'}, {0, 0, 0, 0}};
int opt_index = 0;
int opt = w.wgetopt_long(argc,
argv,
L"pclgh",
long_options,
&opt_index);
if (opt == -1)
break;
int opt = w.wgetopt_long(argc, argv, L"pclgh", long_options, &opt_index);
if (opt == -1) break;
switch (opt)
{
case 0:
if (long_options[opt_index].flag != 0)
break;
streams.err.append_format(BUILTIN_ERR_UNKNOWN,
argv[0],
long_options[opt_index].name);
switch (opt) {
case 0: {
if (long_options[opt_index].flag != 0) break;
streams.err.append_format(BUILTIN_ERR_UNKNOWN, argv[0],
long_options[opt_index].name);
builtin_print_help(parser, streams, argv[0], streams.err);
return 1;
case 'p':
mode=JOBS_PRINT_PID;
}
case 'p': {
mode = JOBS_PRINT_PID;
break;
case 'c':
mode=JOBS_PRINT_COMMAND;
}
case 'c': {
mode = JOBS_PRINT_COMMAND;
break;
case 'g':
mode=JOBS_PRINT_GROUP;
}
case 'g': {
mode = JOBS_PRINT_GROUP;
break;
case 'l':
{
}
case 'l': {
print_last = 1;
break;
}
case 'h':
case 'h': {
builtin_print_help(parser, streams, argv[0], streams.out);
return 0;
case '?':
builtin_unknown_option(parser, streams, argv[0], argv[w.woptind-1]);
}
case '?': {
builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return 1;
}
}
}
if (print_last)
{
/*
Ignore unconstructed jobs, i.e. ourself.
*/
if (print_last) {
// Ignore unconstructed jobs, i.e. ourself.
job_iterator_t jobs;
const job_t *j;
while ((j = jobs.next()))
{
if ((j->flags & JOB_CONSTRUCTED) && !job_is_completed(j))
{
while ((j = jobs.next())) {
if ((j->flags & JOB_CONSTRUCTED) && !job_is_completed(j)) {
builtin_jobs_print(j, mode, !streams.out_is_redirected, streams);
return 0;
}
}
}
else
{
if (w.woptind < argc)
{
} else {
if (w.woptind < argc) {
int i;
for (i=w.woptind; i<argc; i++)
{
for (i = w.woptind; i < argc; i++) {
int pid;
wchar_t *end;
errno=0;
pid=fish_wcstoi(argv[i], &end, 10);
if (errno || *end)
{
streams.err.append_format(_(L"%ls: '%ls' is not a job\n"),
argv[0],
argv[i]);
errno = 0;
pid = fish_wcstoi(argv[i], &end, 10);
if (errno || *end) {
streams.err.append_format(_(L"%ls: '%ls' is not a job\n"), argv[0], argv[i]);
return 1;
}
const job_t *j = job_get_from_pid(pid);
if (j && !job_is_completed(j))
{
if (j && !job_is_completed(j)) {
builtin_jobs_print(j, mode, false, streams);
found = 1;
}
else
{
streams.err.append_format(_(L"%ls: No suitable job: %d\n"),
argv[0],
pid);
} else {
streams.err.append_format(_(L"%ls: No suitable job: %d\n"), argv[0], pid);
return 1;
}
}
}
else
{
} else {
job_iterator_t jobs;
const job_t *j;
while ((j = jobs.next()))
{
/*
Ignore unconstructed jobs, i.e. ourself.
*/
if ((j->flags & JOB_CONSTRUCTED) && !job_is_completed(j))
{
while ((j = jobs.next())) {
// Ignore unconstructed jobs, i.e. ourself.
if ((j->flags & JOB_CONSTRUCTED) && !job_is_completed(j)) {
builtin_jobs_print(j, mode, !streams.out_is_redirected, streams);
found = 1;
}
@ -320,20 +211,13 @@ static int builtin_jobs(parser_t &parser, io_streams_t &streams, wchar_t **argv)
}
}
if (!found)
{
/*
Do not babble if not interactive
*/
if (!streams.out_is_redirected)
{
streams.out.append_format(
_(L"%ls: There are no jobs\n"),
argv[0]);
if (!found) {
// Do not babble if not interactive.
if (!streams.out_is_redirected) {
streams.out.append_format(_(L"%ls: There are no jobs\n"), argv[0]);
}
return 1;
}
return 0;
}

11
src/builtin_jobs.h Normal file
View File

@ -0,0 +1,11 @@
// Prototypes for functions for executing builtin_jobs functions.
#ifndef FISH_BUILTIN_JOBS_H
#define FISH_BUILTIN_JOBS_H
#include <wchar.h>
#include <cstring>
class parser_t;
int builtin_jobs(parser_t &parser, io_streams_t &streams, wchar_t **argv);
#endif

File diff suppressed because it is too large Load Diff

11
src/builtin_printf.h Normal file
View File

@ -0,0 +1,11 @@
// Prototypes for functions for executing builtin_printf functions.
#ifndef FISH_BUILTIN_PRINTF_H
#define FISH_BUILTIN_PRINTF_H
#include <wchar.h>
#include <cstring>
class parser_t;
int builtin_printf(parser_t &parser, io_streams_t &streams, wchar_t **argv);
#endif

File diff suppressed because it is too large Load Diff

11
src/builtin_set.h Normal file
View File

@ -0,0 +1,11 @@
// Prototypes for functions for executing builtin_set functions.
#ifndef FISH_BUILTIN_SET_H
#define FISH_BUILTIN_SET_H
#include <wchar.h>
#include <cstring>
class parser_t;
int builtin_set(parser_t &parser, io_streams_t &streams, wchar_t **argv);
#endif

View File

@ -1,8 +1,4 @@
/** \file builtin_set_color.cpp Functions defining the set_color builtin
Functions used for implementing the set_color builtin.
*/
// Functions used for implementing the set_color builtin.
#include "config.h"
#if HAVE_NCURSES_H
@ -17,234 +13,197 @@ Functions used for implementing the set_color builtin.
#elif HAVE_NCURSES_TERM_H
#include <ncurses/term.h>
#endif
#include <unistd.h>
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
#include <memory>
#include <string>
#include <vector>
#include <memory>
#include <stdlib.h>
#include <stdbool.h>
#include "builtin.h"
#include "color.h"
#include "output.h"
#include "wgetopt.h"
#include "proc.h"
#include "io.h"
#include "common.h"
#include "io.h"
#include "output.h"
#include "proc.h"
#include "wgetopt.h"
#include "wutil.h" // IWYU pragma: keep
class parser_t;
/**
Error message for invalid path operations
*/
/// Error message for invalid path operations.
#define BUILTIN_SET_PATH_ERROR L"%ls: Warning: path component %ls may not be valid in %ls.\n"
/**
Hint for invalid path operation with a colon
*/
/// Hint for invalid path operation with a colon.
#define BUILTIN_SET_PATH_HINT L"%ls: Did you mean 'set %ls $%ls %ls'?\n"
/**
Error for mismatch between index count and elements
*/
#define BUILTIN_SET_ARG_COUNT L"%ls: The number of variable indexes does not match the number of values\n"
/// Error for mismatch between index count and elements.
#define BUILTIN_SET_ARG_COUNT \
L"%ls: The number of variable indexes does not match the number of values\n"
static void print_colors(io_streams_t &streams)
{
static void print_colors(io_streams_t &streams) {
const wcstring_list_t result = rgb_color_t::named_color_names();
size_t i;
for (i=0; i < result.size(); i++)
{
for (i = 0; i < result.size(); i++) {
streams.out.append(result.at(i));
streams.out.push_back(L'\n');
}
}
/* function we set as the output writer */
static std::string builtin_set_color_output;
static int set_color_builtin_outputter(char c)
{
/// Function we set as the output writer.
static int set_color_builtin_outputter(char c) {
ASSERT_IS_MAIN_THREAD();
builtin_set_color_output.push_back(c);
return 0;
}
/**
set_color builtin
*/
static int builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t **argv)
{
/// set_color builtin.
int builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
wgetopter_t w;
/** Variables used for parsing the argument list */
const struct woption long_options[] =
{
{ L"background", required_argument, 0, 'b'},
{ L"help", no_argument, 0, 'h' },
{ L"bold", no_argument, 0, 'o' },
{ L"underline", no_argument, 0, 'u' },
{ L"version", no_argument, 0, 'v' },
{ L"print-colors", no_argument, 0, 'c' },
{ 0, 0, 0, 0 }
};
// Variables used for parsing the argument list.
const struct woption long_options[] = {{L"background", required_argument, 0, 'b'},
{L"help", no_argument, 0, 'h'},
{L"bold", no_argument, 0, 'o'},
{L"underline", no_argument, 0, 'u'},
{L"version", no_argument, 0, 'v'},
{L"print-colors", no_argument, 0, 'c'},
{0, 0, 0, 0}};
const wchar_t *short_options = L"b:hvocu";
int argc = builtin_count_args(argv);
/* Some code passes variables to set_color that don't exist, like $fish_user_whatever. As a hack, quietly return failure. */
if (argc <= 1)
{
// Some code passes variables to set_color that don't exist, like $fish_user_whatever. As a
// hack, quietly return failure.
if (argc <= 1) {
return EXIT_FAILURE;
}
const wchar_t *bgcolor = NULL;
bool bold = false, underline=false;
bool bold = false, underline = false;
int errret;
/* Parse options to obtain the requested operation and the modifiers */
// Parse options to obtain the requested operation and the modifiers.
w.woptind = 0;
while (1)
{
while (1) {
int c = w.wgetopt_long(argc, argv, short_options, long_options, 0);
if (c == -1)
{
if (c == -1) {
break;
}
switch (c)
{
case 0:
switch (c) {
case 0: {
break;
case 'b':
}
case 'b': {
bgcolor = w.woptarg;
break;
case 'h':
}
case 'h': {
builtin_print_help(parser, streams, argv[0], streams.out);
return STATUS_BUILTIN_OK;
case 'o':
}
case 'o': {
bold = true;
break;
case 'u':
}
case 'u': {
underline = true;
break;
case 'c':
}
case 'c': {
print_colors(streams);
return STATUS_BUILTIN_OK;
case '?':
}
case '?': {
return STATUS_BUILTIN_ERROR;
}
}
}
/* Remaining arguments are foreground color */
// Remaining arguments are foreground color.
std::vector<rgb_color_t> fgcolors;
for (; w.woptind < argc; w.woptind++)
{
for (; w.woptind < argc; w.woptind++) {
rgb_color_t fg = rgb_color_t(argv[w.woptind]);
if (fg.is_none())
{
if (fg.is_none()) {
streams.err.append_format(_(L"%ls: Unknown color '%ls'\n"), argv[0], argv[w.woptind]);
return STATUS_BUILTIN_ERROR;
}
fgcolors.push_back(fg);
}
if (fgcolors.empty() && bgcolor == NULL && !bold && !underline)
{
streams.err.append_format(_(L"%ls: Expected an argument\n"),
argv[0]);
if (fgcolors.empty() && bgcolor == NULL && !bold && !underline) {
streams.err.append_format(_(L"%ls: Expected an argument\n"), argv[0]);
return STATUS_BUILTIN_ERROR;
}
// #1323: We may have multiple foreground colors. Choose the best one.
// If we had no foreground coor, we'll get none(); if we have at least one we expect not-none
// #1323: We may have multiple foreground colors. Choose the best one. If we had no foreground
// color, we'll get none(); if we have at least one we expect not-none.
const rgb_color_t fg = best_color(fgcolors, output_get_color_support());
assert(fgcolors.empty() || !fg.is_none());
const rgb_color_t bg = rgb_color_t(bgcolor ? bgcolor : L"");
if (bgcolor && bg.is_none())
{
if (bgcolor && bg.is_none()) {
streams.err.append_format(_(L"%ls: Unknown color '%ls'\n"), argv[0], bgcolor);
return STATUS_BUILTIN_ERROR;
}
/* Make sure that the term exists */
if (cur_term == NULL && setupterm(0, STDOUT_FILENO, &errret) == ERR)
{
// Make sure that the term exists.
if (cur_term == NULL && setupterm(0, STDOUT_FILENO, &errret) == ERR) {
streams.err.append_format(_(L"%ls: Could not set up terminal\n"), argv[0]);
return STATUS_BUILTIN_ERROR;
}
/*
Test if we have at least basic support for setting fonts, colors
and related bits - otherwise just give up...
*/
if (! exit_attribute_mode)
{
// Test if we have at least basic support for setting fonts, colors and related bits - otherwise
// just give up...
if (!exit_attribute_mode) {
return STATUS_BUILTIN_ERROR;
}
/* Save old output function so we can restore it */
int (* const saved_writer_func)(char) = output_get_writer();
// Save old output function so we can restore it.
int (*const saved_writer_func)(char) = output_get_writer();
/* Set our output function, which writes to a std::string */
// Set our output function, which writes to a std::string.
builtin_set_color_output.clear();
output_set_writer(set_color_builtin_outputter);
if (bold)
{
if (enter_bold_mode)
writembs(tparm(enter_bold_mode));
if (bold) {
if (enter_bold_mode) writembs(tparm(enter_bold_mode));
}
if (underline)
{
if (enter_underline_mode)
writembs(enter_underline_mode);
if (underline) {
if (enter_underline_mode) writembs(enter_underline_mode);
}
if (bgcolor != NULL)
{
if (bg.is_normal())
{
if (bgcolor != NULL) {
if (bg.is_normal()) {
write_color(rgb_color_t::black(), false /* not is_fg */);
writembs(tparm(exit_attribute_mode));
}
}
if (! fg.is_none())
{
if (fg.is_normal() || fg.is_reset())
{
if (!fg.is_none()) {
if (fg.is_normal() || fg.is_reset()) {
write_color(rgb_color_t::black(), true /* is_fg */);
writembs(tparm(exit_attribute_mode));
}
else
{
} else {
write_color(fg, true /* is_fg */);
}
}
if (bgcolor != NULL)
{
if (! bg.is_normal() && ! bg.is_reset())
{
if (bgcolor != NULL) {
if (!bg.is_normal() && !bg.is_reset()) {
write_color(bg, false /* not is_fg */);
}
}
/* Restore saved writer function */
// Restore saved writer function.
output_set_writer(saved_writer_func);
/* Output the collected string */
// Output the collected string.
streams.out.append(str2wcstring(builtin_set_color_output));
builtin_set_color_output.clear();

11
src/builtin_set_color.h Normal file
View File

@ -0,0 +1,11 @@
// Prototypes for functions for executing builtin_set_color functions.
#ifndef FISH_BUILTIN_SET_COLOR_H
#define FISH_BUILTIN_SET_COLOR_H
#include <wchar.h>
#include <cstring>
class parser_t;
int builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t **argv);
#endif

File diff suppressed because it is too large Load Diff

11
src/builtin_string.h Normal file
View File

@ -0,0 +1,11 @@
// Prototypes for functions for executing builtin_string functions.
#ifndef FISH_BUILTIN_STRING_H
#define FISH_BUILTIN_STRING_H
#include <wchar.h>
#include <cstring>
class parser_t;
int builtin_string(parser_t &parser, io_streams_t &streams, wchar_t **argv);
#endif

File diff suppressed because it is too large Load Diff

9
src/builtin_test.h Normal file
View File

@ -0,0 +1,9 @@
// Prototypes for functions for executing builtin_test functions.
#ifndef FISH_BUILTIN_TEST_H
#define FISH_BUILTIN_TEST_H
class parser_t;
struct io_streams_t;
int builtin_test(parser_t &parser, io_streams_t &streams, wchar_t **argv);
#endif

View File

@ -1,241 +1,146 @@
/** \file builtin_ulimit.c Functions defining the ulimit builtin
Functions used for implementing the ulimit builtin.
*/
#include <wchar.h>
#include <sys/resource.h>
// Functions used for implementing the ulimit builtin.
#include <errno.h>
#include <sys/resource.h>
#include <wchar.h>
#include "fallback.h" // IWYU pragma: keep
#include "util.h"
#include "builtin.h"
#include "common.h"
#include "wgetopt.h"
#include "fallback.h" // IWYU pragma: keep
#include "io.h"
#include "util.h"
#include "wgetopt.h"
#include "wutil.h" // IWYU pragma: keep
class parser_t;
/**
Struct describing a resource limit
*/
struct resource_t
{
/**
Resource id
*/
int resource;
/**
Description of resource
*/
const wchar_t *desc;
/**
Switch used on commandline to specify resource
*/
wchar_t switch_char;
/**
The implicit multiplier used when setting getting values
*/
int multiplier;
}
;
/// Struct describing a resource limit.
struct resource_t {
int resource; // resource ID
const wchar_t *desc; // description of resource
wchar_t switch_char; // switch used on commandline to specify resource
int multiplier; // the implicit multiplier used when setting getting values
};
/**
Array of resource_t structs, describing all known resource types.
*/
static const struct resource_t resource_arr[] =
{
{
RLIMIT_CORE, L"Maximum size of core files created", L'c', 1024
}
,
{
RLIMIT_DATA, L"Maximum size of a processs data segment", L'd', 1024
}
,
{
RLIMIT_FSIZE, L"Maximum size of files created by the shell", L'f', 1024
}
,
/// Array of resource_t structs, describing all known resource types.
static const struct resource_t resource_arr[] = {
{RLIMIT_CORE, L"Maximum size of core files created", L'c', 1024},
{RLIMIT_DATA, L"Maximum size of a processs data segment", L'd', 1024},
{RLIMIT_FSIZE, L"Maximum size of files created by the shell", L'f', 1024},
#ifdef RLIMIT_MEMLOCK
{
RLIMIT_MEMLOCK, L"Maximum size that may be locked into memory", L'l', 1024
}
,
{RLIMIT_MEMLOCK, L"Maximum size that may be locked into memory", L'l', 1024},
#endif
#ifdef RLIMIT_RSS
{
RLIMIT_RSS, L"Maximum resident set size", L'm', 1024
}
,
{RLIMIT_RSS, L"Maximum resident set size", L'm', 1024},
#endif
{
RLIMIT_NOFILE, L"Maximum number of open file descriptors", L'n', 1
}
,
{
RLIMIT_STACK, L"Maximum stack size", L's', 1024
}
,
{
RLIMIT_CPU, L"Maximum amount of cpu time in seconds", L't', 1
}
,
{RLIMIT_NOFILE, L"Maximum number of open file descriptors", L'n', 1},
{RLIMIT_STACK, L"Maximum stack size", L's', 1024},
{RLIMIT_CPU, L"Maximum amount of cpu time in seconds", L't', 1},
#ifdef RLIMIT_NPROC
{
RLIMIT_NPROC, L"Maximum number of processes available to a single user", L'u', 1
}
,
{RLIMIT_NPROC, L"Maximum number of processes available to a single user", L'u', 1},
#endif
#ifdef RLIMIT_AS
{
RLIMIT_AS, L"Maximum amount of virtual memory available to the shell", L'v', 1024
}
,
{RLIMIT_AS, L"Maximum amount of virtual memory available to the shell", L'v', 1024},
#endif
{
0, 0, 0, 0
}
}
;
{0, 0, 0, 0}};
/**
Get the implicit multiplication factor for the specified resource limit
*/
static int get_multiplier(int what)
{
int i;
for (i=0; resource_arr[i].desc; i++)
{
if (resource_arr[i].resource == what)
{
/// Get the implicit multiplication factor for the specified resource limit.
static int get_multiplier(int what) {
for (int i = 0; resource_arr[i].desc; i++) {
if (resource_arr[i].resource == what) {
return resource_arr[i].multiplier;
}
}
return -1;
}
/**
Return the value for the specified resource limit. This function
does _not_ multiply the limit value by the multiplier constant used
by the commandline ulimit.
*/
static rlim_t get(int resource, int hard)
{
/// Return the value for the specified resource limit. This function does _not_ multiply the limit
/// value by the multiplier constant used by the commandline ulimit.
static rlim_t get(int resource, int hard) {
struct rlimit ls;
getrlimit(resource, &ls);
return hard ? ls.rlim_max:ls.rlim_cur;
return hard ? ls.rlim_max : ls.rlim_cur;
}
/**
Print the value of the specified resource limit
*/
static void print(int resource, int hard, io_streams_t &streams)
{
/// Print the value of the specified resource limit.
static void print(int resource, int hard, io_streams_t &streams) {
rlim_t l = get(resource, hard);
if (l == RLIM_INFINITY)
streams.out.append(L"unlimited\n");
else
streams.out.append_format( L"%d\n", l / get_multiplier(resource));
streams.out.append_format(L"%d\n", l / get_multiplier(resource));
}
/**
Print values of all resource limits
*/
static void print_all(int hard, io_streams_t &streams)
{
/// Print values of all resource limits.
static void print_all(int hard, io_streams_t &streams) {
int i;
int w=0;
int w = 0;
for (i=0; resource_arr[i].desc; i++)
{
w=maxi(w, fish_wcswidth(resource_arr[i].desc));
for (i = 0; resource_arr[i].desc; i++) {
w = maxi(w, fish_wcswidth(resource_arr[i].desc));
}
for (i=0; resource_arr[i].desc; i++)
{
for (i = 0; resource_arr[i].desc; i++) {
struct rlimit ls;
rlim_t l;
getrlimit(resource_arr[i].resource, &ls);
l = hard ? ls.rlim_max:ls.rlim_cur;
l = hard ? ls.rlim_max : ls.rlim_cur;
const wchar_t *unit = ((resource_arr[i].resource==RLIMIT_CPU)?L"(seconds, ":(get_multiplier(resource_arr[i].resource)==1?L"(":L"(kB, "));
const wchar_t *unit =
((resource_arr[i].resource == RLIMIT_CPU)
? L"(seconds, "
: (get_multiplier(resource_arr[i].resource) == 1 ? L"(" : L"(kB, "));
streams.out.append_format(
L"%-*ls %10ls-%lc) ",
w,
resource_arr[i].desc,
unit,
resource_arr[i].switch_char);
streams.out.append_format(L"%-*ls %10ls-%lc) ", w, resource_arr[i].desc, unit,
resource_arr[i].switch_char);
if (l == RLIM_INFINITY)
{
if (l == RLIM_INFINITY) {
streams.out.append(L"unlimited\n");
}
else
{
streams.out.append_format( L"%d\n", l/get_multiplier(resource_arr[i].resource));
} else {
streams.out.append_format(L"%d\n", l / get_multiplier(resource_arr[i].resource));
}
}
}
/**
Returns the description for the specified resource limit
*/
static const wchar_t *get_desc(int what)
{
/// Returns the description for the specified resource limit.
static const wchar_t *get_desc(int what) {
int i;
for (i=0; resource_arr[i].desc; i++)
{
if (resource_arr[i].resource == what)
{
for (i = 0; resource_arr[i].desc; i++) {
if (resource_arr[i].resource == what) {
return resource_arr[i].desc;
}
}
return L"Not a resource";
}
/**
Set the new value of the specified resource limit. This function
does _not_ multiply the limit value by the multiplier constant used
by the commandline ulimit.
*/
static int set(int resource, int hard, int soft, rlim_t value, io_streams_t &streams)
{
/// Set the new value of the specified resource limit. This function does _not_ multiply the limit
// value by the multiplier constant used by the commandline ulimit.
static int set(int resource, int hard, int soft, rlim_t value, io_streams_t &streams) {
struct rlimit ls;
getrlimit(resource, &ls);
if (hard)
{
if (hard) {
ls.rlim_max = value;
}
if (soft)
{
if (soft) {
ls.rlim_cur = value;
/*
Do not attempt to set the soft limit higher than the hard limit
*/
// Do not attempt to set the soft limit higher than the hard limit.
if ((value == RLIM_INFINITY && ls.rlim_max != RLIM_INFINITY) ||
(value != RLIM_INFINITY && ls.rlim_max != RLIM_INFINITY && value > ls.rlim_max))
{
(value != RLIM_INFINITY && ls.rlim_max != RLIM_INFINITY && value > ls.rlim_max)) {
ls.rlim_cur = ls.rlim_max;
}
}
if (setrlimit(resource, &ls))
{
if (setrlimit(resource, &ls)) {
if (errno == EPERM)
streams.err.append_format(L"ulimit: Permission denied when changing resource of type '%ls'\n", get_desc(resource));
streams.err.append_format(
L"ulimit: Permission denied when changing resource of type '%ls'\n",
get_desc(resource));
else
builtin_wperror(L"ulimit", streams);
return 1;
@ -243,190 +148,125 @@ static int set(int resource, int hard, int soft, rlim_t value, io_streams_t &str
return 0;
}
/**
The ulimit builtin, used for setting resource limits. Defined in
builtin_ulimit.c.
*/
static int builtin_ulimit(parser_t &parser, io_streams_t &streams, wchar_t **argv)
{
/// The ulimit builtin, used for setting resource limits.
int builtin_ulimit(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
wgetopter_t w;
int hard=0;
int soft=0;
int hard = 0;
int soft = 0;
int what = RLIMIT_FSIZE;
int report_all = 0;
int argc = builtin_count_args(argv);
w.woptind=0;
while (1)
{
static const struct woption
long_options[] =
{
{
L"all", no_argument, 0, 'a'
}
,
{
L"hard", no_argument, 0, 'H'
}
,
{
L"soft", no_argument, 0, 'S'
}
,
{
L"core-size", no_argument, 0, 'c'
}
,
{
L"data-size", no_argument, 0, 'd'
}
,
{
L"file-size", no_argument, 0, 'f'
}
,
{
L"lock-size", no_argument, 0, 'l'
}
,
{
L"resident-set-size", no_argument, 0, 'm'
}
,
{
L"file-descriptor-count", no_argument, 0, 'n'
}
,
{
L"stack-size", no_argument, 0, 's'
}
,
{
L"cpu-time", no_argument, 0, 't'
}
,
{
L"process-count", no_argument, 0, 'u'
}
,
{
L"virtual-memory-size", no_argument, 0, 'v'
}
,
{
L"help", no_argument, 0, 'h'
}
,
{
0, 0, 0, 0
}
}
;
w.woptind = 0;
while (1) {
static const struct woption long_options[] = {
{L"all", no_argument, 0, 'a'},
{L"hard", no_argument, 0, 'H'},
{L"soft", no_argument, 0, 'S'},
{L"core-size", no_argument, 0, 'c'},
{L"data-size", no_argument, 0, 'd'},
{L"file-size", no_argument, 0, 'f'},
{L"lock-size", no_argument, 0, 'l'},
{L"resident-set-size", no_argument, 0, 'm'},
{L"file-descriptor-count", no_argument, 0, 'n'},
{L"stack-size", no_argument, 0, 's'},
{L"cpu-time", no_argument, 0, 't'},
{L"process-count", no_argument, 0, 'u'},
{L"virtual-memory-size", no_argument, 0, 'v'},
{L"help", no_argument, 0, 'h'},
{0, 0, 0, 0}};
int opt_index = 0;
int opt = w.wgetopt_long(argc,
argv,
L"aHScdflmnstuvh",
long_options,
&opt_index);
if (opt == -1)
break;
int opt = w.wgetopt_long(argc, argv, L"aHScdflmnstuvh", long_options, &opt_index);
if (opt == -1) break;
switch (opt)
{
case 0:
if (long_options[opt_index].flag != 0)
break;
streams.err.append_format(BUILTIN_ERR_UNKNOWN,
argv[0],
long_options[opt_index].name);
switch (opt) {
case 0: {
if (long_options[opt_index].flag != 0) break;
streams.err.append_format(BUILTIN_ERR_UNKNOWN, argv[0],
long_options[opt_index].name);
builtin_print_help(parser, streams, argv[0], streams.err);
return 1;
case L'a':
report_all=1;
}
case L'a': {
report_all = 1;
break;
case L'H':
hard=1;
}
case L'H': {
hard = 1;
break;
case L'S':
soft=1;
}
case L'S': {
soft = 1;
break;
case L'c':
what=RLIMIT_CORE;
}
case L'c': {
what = RLIMIT_CORE;
break;
case L'd':
what=RLIMIT_DATA;
}
case L'd': {
what = RLIMIT_DATA;
break;
case L'f':
what=RLIMIT_FSIZE;
}
case L'f': {
what = RLIMIT_FSIZE;
break;
}
#ifdef RLIMIT_MEMLOCK
case L'l':
what=RLIMIT_MEMLOCK;
case L'l': {
what = RLIMIT_MEMLOCK;
break;
}
#endif
#ifdef RLIMIT_RSS
case L'm':
what=RLIMIT_RSS;
case L'm': {
what = RLIMIT_RSS;
break;
}
#endif
case L'n':
what=RLIMIT_NOFILE;
case L'n': {
what = RLIMIT_NOFILE;
break;
case L's':
what=RLIMIT_STACK;
}
case L's': {
what = RLIMIT_STACK;
break;
case L't':
what=RLIMIT_CPU;
}
case L't': {
what = RLIMIT_CPU;
break;
}
#ifdef RLIMIT_NPROC
case L'u':
what=RLIMIT_NPROC;
case L'u': {
what = RLIMIT_NPROC;
break;
}
#endif
#ifdef RLIMIT_AS
case L'v':
what=RLIMIT_AS;
case L'v': {
what = RLIMIT_AS;
break;
}
#endif
case L'h':
case L'h': {
builtin_print_help(parser, streams, argv[0], streams.out);
return 0;
case L'?':
builtin_unknown_option(parser, streams, argv[0], argv[w.woptind-1]);
}
case L'?': {
builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return 1;
}
}
}
if (report_all)
{
if (argc - w.woptind == 0)
{
if (report_all) {
if (argc - w.woptind == 0) {
print_all(hard, streams);
}
else
{
} else {
streams.err.append(argv[0]);
streams.err.append(L": Too many arguments\n");
builtin_print_help(parser, streams, argv[0], streams.err);
@ -436,54 +276,32 @@ static int builtin_ulimit(parser_t &parser, io_streams_t &streams, wchar_t **arg
return 0;
}
switch (argc - w.woptind)
{
case 0:
{
/*
Show current limit value
*/
switch (argc - w.woptind) {
case 0: { // show current limit value
print(what, hard, streams);
break;
}
case 1:
{
/*
Change current limit value
*/
case 1: { // change current limit value
rlim_t new_limit;
wchar_t *end;
/*
Set both hard and soft limits if nothing else was specified
*/
if (!(hard+soft))
{
hard=soft=1;
// Set both hard and soft limits if nothing else was specified.
if (!(hard + soft)) {
hard = soft = 1;
}
if (wcscasecmp(argv[w.woptind], L"unlimited")==0)
{
if (wcscasecmp(argv[w.woptind], L"unlimited") == 0) {
new_limit = RLIM_INFINITY;
}
else if (wcscasecmp(argv[w.woptind], L"hard")==0)
{
} else if (wcscasecmp(argv[w.woptind], L"hard") == 0) {
new_limit = get(what, 1);
}
else if (wcscasecmp(argv[w.woptind], L"soft")==0)
{
} else if (wcscasecmp(argv[w.woptind], L"soft") == 0) {
new_limit = get(what, soft);
}
else
{
errno=0;
} else {
errno = 0;
new_limit = wcstol(argv[w.woptind], &end, 10);
if (errno || *end)
{
streams.err.append_format(L"%ls: Invalid limit '%ls'\n",
argv[0],
argv[w.woptind]);
if (errno || *end) {
streams.err.append_format(L"%ls: Invalid limit '%ls'\n", argv[0],
argv[w.woptind]);
builtin_print_help(parser, streams, argv[0], streams.err);
return 1;
}
@ -492,15 +310,12 @@ static int builtin_ulimit(parser_t &parser, io_streams_t &streams, wchar_t **arg
return set(what, hard, soft, new_limit, streams);
}
default:
{
default: {
streams.err.append(argv[0]);
streams.err.append(L": Too many arguments\n");
builtin_print_help(parser, streams, argv[0], streams.err);
return 1;
}
}
return 0;
}

11
src/builtin_ulimit.h Normal file
View File

@ -0,0 +1,11 @@
// Prototypes for functions for executing builtin_ulimit functions.
#ifndef FISH_BUILTIN_ULIMIT_H
#define FISH_BUILTIN_ULIMIT_H
#include <wchar.h>
#include <cstring>
class parser_t;
int builtin_ulimit(parser_t &parser, io_streams_t &streams, wchar_t **argv);
#endif