aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Kurtis Rader <krader@skepticism.us>2016-04-19 19:49:15 -0700
committerGravatar Kurtis Rader <krader@skepticism.us>2016-04-26 21:58:59 -0700
commitdf10b53c0caecd43a02b7f24515a9ff9edea7056 (patch)
treec4330d36de296ee75a608a6665091134be780167
parentc2f9d60eb1f04a3aa0b01d785c1e133cac8ecf1d (diff)
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.
-rw-r--r--Makefile.in253
-rw-r--r--build_tools/iwyu.linux.imp2
-rwxr-xr-xbuild_tools/style.fish2
-rw-r--r--src/builtin.cpp42
-rw-r--r--src/builtin_commandline.cpp613
-rw-r--r--src/builtin_commandline.h11
-rw-r--r--src/builtin_complete.cpp563
-rw-r--r--src/builtin_complete.h11
-rw-r--r--src/builtin_jobs.cpp316
-rw-r--r--src/builtin_jobs.h11
-rw-r--r--src/builtin_printf.cpp730
-rw-r--r--src/builtin_printf.h11
-rw-r--r--src/builtin_set.cpp693
-rw-r--r--src/builtin_set.h11
-rw-r--r--src/builtin_set_color.cpp199
-rw-r--r--src/builtin_set_color.h11
-rw-r--r--src/builtin_string.cpp1050
-rw-r--r--src/builtin_string.h11
-rw-r--r--src/builtin_test.cpp947
-rw-r--r--src/builtin_test.h9
-rw-r--r--src/builtin_ulimit.cpp509
-rw-r--r--src/builtin_ulimit.h11
22 files changed, 2412 insertions, 3604 deletions
diff --git a/Makefile.in b/Makefile.in
index b73e75d1..6af1d21c 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -95,30 +95,20 @@ 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
#
FISH_TESTS_OBJS := $(FISH_OBJS) obj/fish_tests.o
@@ -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
diff --git a/build_tools/iwyu.linux.imp b/build_tools/iwyu.linux.imp
index 6fc614ae..27700b67 100644
--- a/build_tools/iwyu.linux.imp
+++ b/build_tools/iwyu.linux.imp
@@ -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"] },
]
diff --git a/build_tools/style.fish b/build_tools/style.fish
index 62d8d5c7..fc9a96e3 100755
--- a/build_tools/style.fish
+++ b/build_tools/style.fish
@@ -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.
diff --git a/src/builtin.cpp b/src/builtin.cpp
index b7a84c69..b0356543 100644
--- a/src/builtin.cpp
+++ b/src/builtin.cpp
@@ -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.
diff --git a/src/builtin_commandline.cpp b/src/builtin_commandline.cpp
index e84bcb07..0ccea616 100644
--- a/src/builtin_commandline.cpp
+++ b/src/builtin_commandline.cpp
@@ -1,110 +1,81 @@
-/** \file builtin_commandline.c Functions defining the commandline builtin
-
-Functions used for implementing the commandline builtin.
-*/
-#include <stdlib.h>
-#include <wchar.h>
+// Functions used for implementing the commandline builtin.
#include <assert.h>
-#include <pthread.h>
#include <errno.h>
-#include <cstring>
+#include <pthread.h>
#include <stdbool.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <cstring>
-#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 */
-}
-;
-
-/**
- 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.
- */
+/// 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
+};
+
+/// 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.
-
- \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 );
+/// 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());
+
+ 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;
-
- 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 }
- };
+ 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}};
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;
}
}
diff --git a/src/builtin_commandline.h b/src/builtin_commandline.h
new file mode 100644
index 00000000..a8cbd956
--- /dev/null
+++ b/src/builtin_commandline.h
@@ -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
diff --git a/src/builtin_complete.cpp b/src/builtin_complete.cpp
index bd117a8f..90fc4714 100644
--- a/src/builtin_complete.cpp
+++ b/src/builtin_complete.cpp
@@ -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.
-*/
-
-/**
- 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)
-{
+// 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) {
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);
-
- if (authoritative != -1)
- {
- complete_set_authoritative(cmd.at(i).c_str(),
- COMMAND,
- authoritative);
+/// 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);
}
-
}
- 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);
- }
+ 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);
+ }
}
}
-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;
-
- 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 }
- };
+ 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}};
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;
-
- 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);
+ 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);
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);
-
- /* 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);
+ 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);
}
- /* 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);
-
- }
- else
- {
- builtin_complete_add(cmd,
- path,
- short_opt.c_str(),
- gnu_opt,
- old_opt,
- result_mode,
- authoritative,
- condition,
- comp,
- desc,
- flags);
+
+ 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);
}
-
- // 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);
}
}
}
diff --git a/src/builtin_complete.h b/src/builtin_complete.h
new file mode 100644
index 00000000..3ef45a32
--- /dev/null
+++ b/src/builtin_complete.h
@@ -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
diff --git a/src/builtin_jobs.cpp b/src/builtin_jobs.cpp
index 41982769..406795aa 100644
--- a/src/builtin_jobs.cpp
+++ b/src/builtin_jobs.cpp
@@ -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;
}
-
diff --git a/src/builtin_jobs.h b/src/builtin_jobs.h
new file mode 100644
index 00000000..caf059f8
--- /dev/null
+++ b/src/builtin_jobs.h
@@ -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
diff --git a/src/builtin_printf.cpp b/src/builtin_printf.cpp
index 97427948..a3df00d3 100644
--- a/src/builtin_printf.cpp
+++ b/src/builtin_printf.cpp
@@ -1,94 +1,91 @@
-/* printf - format and print data
- Copyright (C) 1990-2007 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* Usage: printf format [argument...]
-
- A front end to the printf function that lets it be used from the shell.
-
- Backslash escapes:
-
- \" = double quote
- \\ = backslash
- \a = alert (bell)
- \b = backspace
- \c = produce no further output
- \e = escape
- \f = form feed
- \n = new line
- \r = carriage return
- \t = horizontal tab
- \v = vertical tab
- \ooo = octal number (ooo is 1 to 3 digits)
- \xhh = hexadecimal number (hhh is 1 to 2 digits)
- \uhhhh = 16-bit Unicode character (hhhh is 4 digits)
- \Uhhhhhhhh = 32-bit Unicode character (hhhhhhhh is 8 digits)
-
- Additional directive:
-
- %b = print an argument string, interpreting backslash escapes,
- except that octal escapes are of the form \0 or \0ooo.
-
- The `format' argument is re-used as many times as necessary
- to convert all of the given arguments.
-
- David MacKenzie <djm@gnu.ai.mit.edu> */
-
-/* This file has been imported from source code of printf command in GNU Coreutils version 6.9 */
+// printf - format and print data
+// Copyright (C) 1990-2007 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+// Usage: printf format [argument...]
+//
+// A front end to the printf function that lets it be used from the shell.
+//
+// Backslash escapes:
+//
+// \" = double quote
+// \\ = backslash
+// \a = alert (bell)
+// \b = backspace
+// \c = produce no further output
+// \e = escape
+// \f = form feed
+// \n = new line
+// \r = carriage return
+// \t = horizontal tab
+// \v = vertical tab
+// \ooo = octal number (ooo is 1 to 3 digits)
+// \xhh = hexadecimal number (hhh is 1 to 2 digits)
+// \uhhhh = 16-bit Unicode character (hhhh is 4 digits)
+// \Uhhhhhhhh = 32-bit Unicode character (hhhhhhhh is 8 digits)
+//
+// Additional directive:
+//
+// %b = print an argument string, interpreting backslash escapes,
+// except that octal escapes are of the form \0 or \0ooo.
+//
+// The `format' argument is re-used as many times as necessary
+// to convert all of the given arguments.
+//
+// David MacKenzie <djm@gnu.ai.mit.edu>
+
+// This file has been imported from source code of printf command in GNU Coreutils version 6.9.
#include <errno.h>
#include <limits.h>
#include <locale.h>
-#include <wchar.h>
-#include <wctype.h>
-#include <stdio.h>
-#include <sys/types.h>
#include <stdarg.h>
-#include <string.h>
#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <wchar.h>
+#include <wctype.h>
+#include "builtin.h"
#include "common.h"
#include "io.h"
-#include "wutil.h" // IWYU pragma: keep
#include "proc.h"
-#include "builtin.h"
+#include "wutil.h" // IWYU pragma: keep
class parser_t;
-struct builtin_printf_state_t
-{
- /* Out and err streams. Note this is a captured reference! */
+struct builtin_printf_state_t {
+ // Out and err streams. Note this is a captured reference!
io_streams_t &streams;
-
- /* The status of the operation */
+
+ // The status of the operation.
int exit_code;
- /* Whether we should stop outputting. This gets set in the case of an error, and also with the \c escape. */
+ // Whether we should stop outputting. This gets set in the case of an error, and also with the
+ // \c escape.
bool early_exit;
- explicit builtin_printf_state_t(io_streams_t &s) : streams(s), exit_code(0), early_exit(false)
- {
- }
+ explicit builtin_printf_state_t(io_streams_t &s)
+ : streams(s), exit_code(0), early_exit(false) {}
void verify_numeric(const wchar_t *s, const wchar_t *end, int errcode);
- void print_direc(const wchar_t *start, size_t length, wchar_t conversion,
- bool have_field_width, int field_width,
- bool have_precision, int precision,
- wchar_t const *argument);
+ void print_direc(const wchar_t *start, size_t length, wchar_t conversion, bool have_field_width,
+ int field_width, bool have_precision, int precision, wchar_t const *argument);
int print_formatted(const wchar_t *format, int argc, wchar_t **argv);
@@ -103,155 +100,152 @@ struct builtin_printf_state_t
void append_format_output(const wchar_t *fmt, ...);
};
-static bool is_octal_digit(wchar_t c)
-{
- return c != L'\0' && wcschr(L"01234567", c) != NULL;
-}
+static bool is_octal_digit(wchar_t c) { return c != L'\0' && wcschr(L"01234567", c) != NULL; }
-static bool is_hex_digit(wchar_t c)
-{
+static bool is_hex_digit(wchar_t c) {
return c != L'\0' && wcschr(L"0123456789ABCDEFabcdef", c) != NULL;
}
-static int hex_to_bin(const wchar_t &c)
-{
- switch (c)
- {
- case L'0':
+static int hex_to_bin(const wchar_t &c) {
+ switch (c) {
+ case L'0': {
return 0;
- case L'1':
+ }
+ case L'1': {
return 1;
- case L'2':
+ }
+ case L'2': {
return 2;
- case L'3':
+ }
+ case L'3': {
return 3;
- case L'4':
+ }
+ case L'4': {
return 4;
- case L'5':
+ }
+ case L'5': {
return 5;
- case L'6':
+ }
+ case L'6': {
return 6;
- case L'7':
+ }
+ case L'7': {
return 7;
- case L'8':
+ }
+ case L'8': {
return 8;
- case L'9':
+ }
+ case L'9': {
return 9;
+ }
case L'a':
- case L'A':
+ case L'A': {
return 10;
+ }
case L'b':
- case L'B':
+ case L'B': {
return 11;
+ }
case L'c':
- case L'C':
+ case L'C': {
return 12;
+ }
case L'd':
- case L'D':
+ case L'D': {
return 13;
+ }
case L'e':
- case L'E':
+ case L'E': {
return 14;
+ }
case L'f':
- case L'F':
+ case L'F': {
return 15;
- default:
- return -1;
+ }
+ default: { return -1; }
}
}
-static int octal_to_bin(wchar_t c)
-{
- switch (c)
- {
- case L'0':
+static int octal_to_bin(wchar_t c) {
+ switch (c) {
+ case L'0': {
return 0;
- case L'1':
+ }
+ case L'1': {
return 1;
- case L'2':
+ }
+ case L'2': {
return 2;
- case L'3':
+ }
+ case L'3': {
return 3;
- case L'4':
+ }
+ case L'4': {
return 4;
- case L'5':
+ }
+ case L'5': {
return 5;
- case L'6':
+ }
+ case L'6': {
return 6;
- case L'7':
+ }
+ case L'7': {
return 7;
- default:
- return -1;
+ }
+ default: { return -1; }
}
}
-/* This message appears in N_() here rather than just in _() below because
- the sole use would have been in a #define. */
-static wchar_t const *const cfcc_msg =
- N_(L"warning: %ls: character(s) following character constant have been ignored");
-
-double C_STRTOD(wchar_t const *nptr, wchar_t **endptr)
-{
+double C_STRTOD(wchar_t const *nptr, wchar_t **endptr) {
double r;
const wcstring saved_locale = wsetlocale(LC_NUMERIC, NULL);
- if (!saved_locale.empty())
- {
+ if (!saved_locale.empty()) {
wsetlocale(LC_NUMERIC, L"C");
}
r = wcstod(nptr, endptr);
- if (!saved_locale.empty())
- {
+ if (!saved_locale.empty()) {
wsetlocale(LC_NUMERIC, saved_locale.c_str());
}
return r;
}
-void builtin_printf_state_t::fatal_error(const wchar_t *fmt, ...)
-{
- // Don't error twice
- if (early_exit)
- return;
+void builtin_printf_state_t::fatal_error(const wchar_t *fmt, ...) {
+ // Don't error twice.
+ if (early_exit) return;
va_list va;
va_start(va, fmt);
wcstring errstr = vformat_string(fmt, va);
va_end(va);
streams.err.append(errstr);
- if (! string_suffixes_string(L"\n", errstr))
- streams.err.push_back(L'\n');
+ if (!string_suffixes_string(L"\n", errstr)) streams.err.push_back(L'\n');
this->exit_code = STATUS_BUILTIN_ERROR;
this->early_exit = true;
}
-void builtin_printf_state_t::append_output(wchar_t c)
-{
- // Don't output if we're done
- if (early_exit)
- return;
+void builtin_printf_state_t::append_output(wchar_t c) {
+ // Don't output if we're done.
+ if (early_exit) return;
streams.out.push_back(c);
}
-void builtin_printf_state_t::append_output(const wchar_t *c)
-{
- // Don't output if we're done
- if (early_exit)
- return;
+void builtin_printf_state_t::append_output(const wchar_t *c) {
+ // Don't output if we're done.
+ if (early_exit) return;
streams.out.append(c);
}
-void builtin_printf_state_t::append_format_output(const wchar_t *fmt, ...)
-{
- // Don't output if we're done
- if (early_exit)
- return;
+void builtin_printf_state_t::append_format_output(const wchar_t *fmt, ...) {
+ // Don't output if we're done.
+ if (early_exit) return;
va_list va;
va_start(va, fmt);
@@ -260,15 +254,10 @@ void builtin_printf_state_t::append_format_output(const wchar_t *fmt, ...)
streams.out.append(tmp);
}
-
-void builtin_printf_state_t::verify_numeric(const wchar_t *s, const wchar_t *end, int errcode)
-{
- if (errcode != 0)
- {
+void builtin_printf_state_t::verify_numeric(const wchar_t *s, const wchar_t *end, int errcode) {
+ if (errcode != 0) {
this->fatal_error(L"%ls: %s", s, strerror(errcode));
- }
- else if (*end)
- {
+ } else if (*end) {
if (s == end)
this->fatal_error(_(L"%ls: expected a numeric value"), s);
else
@@ -276,39 +265,33 @@ void builtin_printf_state_t::verify_numeric(const wchar_t *s, const wchar_t *end
}
}
-template<typename T>
-static T raw_string_to_scalar_type(const wchar_t *s, wchar_t ** end);
+template <typename T>
+static T raw_string_to_scalar_type(const wchar_t *s, wchar_t **end);
-// we use wcstoll instead of wcstoimax because FreeBSD 8 has busted wcstoumax and wcstoimax - see #626
-template<>
-intmax_t raw_string_to_scalar_type(const wchar_t *s, wchar_t ** end)
-{
+// we use wcstoll instead of wcstoimax because FreeBSD 8 has busted wcstoumax and wcstoimax - see
+// #626
+template <>
+intmax_t raw_string_to_scalar_type(const wchar_t *s, wchar_t **end) {
return wcstoll(s, end, 0);
}
-template<>
-uintmax_t raw_string_to_scalar_type(const wchar_t *s, wchar_t ** end)
-{
+template <>
+uintmax_t raw_string_to_scalar_type(const wchar_t *s, wchar_t **end) {
return wcstoull(s, end, 0);
}
-template<>
-long double raw_string_to_scalar_type(const wchar_t *s, wchar_t ** end)
-{
+template <>
+long double raw_string_to_scalar_type(const wchar_t *s, wchar_t **end) {
return C_STRTOD(s, end);
}
-template<typename T>
-static T string_to_scalar_type(const wchar_t *s, builtin_printf_state_t *state)
-{
+template <typename T>
+static T string_to_scalar_type(const wchar_t *s, builtin_printf_state_t *state) {
T val;
- if (*s == L'\"' || *s == L'\'')
- {
+ if (*s == L'\"' || *s == L'\'') {
wchar_t ch = *++s;
val = ch;
- }
- else
- {
+ } else {
wchar_t *end = NULL;
errno = 0;
val = raw_string_to_scalar_type<T>(s, &end);
@@ -317,91 +300,85 @@ static T string_to_scalar_type(const wchar_t *s, builtin_printf_state_t *state)
return val;
}
-/* Output a single-character \ escape. */
-
-void builtin_printf_state_t::print_esc_char(wchar_t c)
-{
- switch (c)
- {
- case L'a': /* Alert. */
+/// Output a single-character \ escape.
+void builtin_printf_state_t::print_esc_char(wchar_t c) {
+ switch (c) {
+ case L'a': { // alert
this->append_output(L'\a');
break;
- case L'b': /* Backspace. */
+ }
+ case L'b': { // backspace
this->append_output(L'\b');
break;
- case L'c': /* Cancel the rest of the output. */
+ }
+ case L'c': { // cancel the rest of the output
this->early_exit = true;
break;
- case L'e': /* Escape */
+ }
+ case L'e': { // escape
this->append_output(L'\x1B');
break;
- case L'f': /* Form feed. */
+ }
+ case L'f': { // form feed
this->append_output(L'\f');
break;
- case L'n': /* New line. */
+ }
+ case L'n': { // new line
this->append_output(L'\n');
break;
- case L'r': /* Carriage return. */
+ }
+ case L'r': { // carriage return
this->append_output(L'\r');
break;
- case L't': /* Horizontal tab. */
+ }
+ case L't': { // horizontal tab
this->append_output(L'\t');
break;
- case L'v': /* Vertical tab. */
+ }
+ case L'v': { // vertical tab
this->append_output(L'\v');
break;
- default:
+ }
+ default: {
this->append_output(c);
break;
+ }
}
}
-/* Print a \ escape sequence starting at ESCSTART.
- Return the number of characters in the escape sequence
- besides the backslash.
- If OCTAL_0 is nonzero, octal escapes are of the form \0ooo, where o
- is an octal digit; otherwise they are of the form \ooo. */
-long builtin_printf_state_t::print_esc(const wchar_t *escstart, bool octal_0)
-{
+/// Print a \ escape sequence starting at ESCSTART.
+/// Return the number of characters in the escape sequence besides the backslash..
+/// If OCTAL_0 is nonzero, octal escapes are of the form \0ooo, where o
+/// is an octal digit; otherwise they are of the form \ooo.
+long builtin_printf_state_t::print_esc(const wchar_t *escstart, bool octal_0) {
const wchar_t *p = escstart + 1;
- int esc_value = 0; /* Value of \nnn escape. */
- int esc_length; /* Length of \nnn escape. */
+ int esc_value = 0; /* Value of \nnn escape. */
+ int esc_length; /* Length of \nnn escape. */
- if (*p == L'x')
- {
- /* A hexadecimal \xhh escape sequence must have 1 or 2 hex. digits. */
+ if (*p == L'x') {
+ // A hexadecimal \xhh escape sequence must have 1 or 2 hex. digits.
for (esc_length = 0, ++p; esc_length < 2 && is_hex_digit(*p); ++esc_length, ++p)
esc_value = esc_value * 16 + hex_to_bin(*p);
- if (esc_length == 0)
- this->fatal_error(_(L"missing hexadecimal number in escape"));
+ if (esc_length == 0) this->fatal_error(_(L"missing hexadecimal number in escape"));
this->append_output(ENCODE_DIRECT_BASE + esc_value % 256);
- }
- else if (is_octal_digit(*p))
- {
- /* Parse \0ooo (if octal_0 && *p == L'0') or \ooo (otherwise).
- Allow \ooo if octal_0 && *p != L'0'; this is an undocumented
- extension to POSIX that is compatible with Bash 2.05b. */
- /* Wrap mod 256, which matches historic behavior */
- for (esc_length = 0, p += octal_0 && *p == L'0'; esc_length < 3 && is_octal_digit(*p); ++esc_length, ++p)
+ } else if (is_octal_digit(*p)) {
+ // Parse \0ooo (if octal_0 && *p == L'0') or \ooo (otherwise). Allow \ooo if octal_0 && *p
+ // != L'0'; this is an undocumented extension to POSIX that is compatible with Bash 2.05b.
+ // Wrap mod 256, which matches historic behavior.
+ for (esc_length = 0, p += octal_0 && *p == L'0'; esc_length < 3 && is_octal_digit(*p);
+ ++esc_length, ++p)
esc_value = esc_value * 8 + octal_to_bin(*p);
this->append_output(ENCODE_DIRECT_BASE + esc_value % 256);
- }
- else if (*p && wcschr(L"\"\\abcefnrtv", *p))
- {
+ } else if (*p && wcschr(L"\"\\abcefnrtv", *p)) {
print_esc_char(*p++);
- }
- else if (*p == L'u' || *p == L'U')
- {
+ } else if (*p == L'u' || *p == L'U') {
wchar_t esc_char = *p;
p++;
uint32_t uni_value = 0;
- for (size_t esc_length = 0; esc_length < (esc_char == L'u' ? 4 : 8); esc_length++)
- {
- if (! is_hex_digit(*p))
- {
- /* Escape sequence must be done. Complain if we didn't get anything */
- if (esc_length == 0)
- {
+ for (size_t esc_length = 0; esc_length < (esc_char == L'u' ? 4 : 8); esc_length++) {
+ if (!is_hex_digit(*p)) {
+ // Escape sequence must be done. Complain if we didn't get anything.
+ if (esc_length == 0) {
this->fatal_error(_(L"Missing hexadecimal number in Unicode escape"));
}
break;
@@ -410,28 +387,27 @@ long builtin_printf_state_t::print_esc(const wchar_t *escstart, bool octal_0)
p++;
}
- /* PCA GNU printf respects the limitations described in ISO N717, about which universal characters "shall not" be specified. I believe this limitation is for the benefit of compilers; I see no reason to impose it in builtin_printf.
-
- If __STDC_ISO_10646__ is defined, then it means wchar_t can and does hold Unicode code points, so just use that. If not defined, use the %lc printf conversion; this probably won't do anything good if your wide character set is not Unicode, but such platforms are exceedingly rare.
- */
- if (uni_value > 0x10FFFF)
- {
- this->fatal_error(_(L"Unicode character out of range: \\%c%0*x"), esc_char, (esc_char == L'u' ? 4 : 8), uni_value);
- }
- else
- {
+ // PCA GNU printf respects the limitations described in ISO N717, about which universal
+ // characters "shall not" be specified. I believe this limitation is for the benefit of
+ // compilers; I see no reason to impose it in builtin_printf.
+ //
+ // If __STDC_ISO_10646__ is defined, then it means wchar_t can and does hold Unicode code
+ // points, so just use that. If not defined, use the %lc printf conversion; this probably
+ // won't do anything good if your wide character set is not Unicode, but such platforms are
+ // exceedingly rare.
+ if (uni_value > 0x10FFFF) {
+ this->fatal_error(_(L"Unicode character out of range: \\%c%0*x"), esc_char,
+ (esc_char == L'u' ? 4 : 8), uni_value);
+ } else {
#if defined(__STDC_ISO_10646__)
this->append_output(uni_value);
#else
this->append_format_output(L"%lc", uni_value);
#endif
}
- }
- else
- {
+ } else {
this->append_output(L'\\');
- if (*p)
- {
+ if (*p) {
this->append_output(*p);
p++;
}
@@ -439,10 +415,8 @@ long builtin_printf_state_t::print_esc(const wchar_t *escstart, bool octal_0)
return p - escstart - 1;
}
-/* Print string STR, evaluating \ escapes. */
-
-void builtin_printf_state_t::print_esc_string(const wchar_t *str)
-{
+/// Print string STR, evaluating \ escapes.
+void builtin_printf_state_t::print_esc_string(const wchar_t *str) {
for (; *str; str++)
if (*str == L'\\')
str += print_esc(str, true);
@@ -450,30 +424,27 @@ void builtin_printf_state_t::print_esc_string(const wchar_t *str)
this->append_output(*str);
}
-/* Evaluate a printf conversion specification. START is the start of
- the directive, LENGTH is its length, and CONVERSION specifies the
- type of conversion. LENGTH does not include any length modifier or
- the conversion specifier itself. FIELD_WIDTH and PRECISION are the
- field width and precision for '*' values, if HAVE_FIELD_WIDTH and
- HAVE_PRECISION are true, respectively. ARGUMENT is the argument to
- be formatted. */
-
+/// Evaluate a printf conversion specification. START is the start of the directive, LENGTH is its
+/// length, and CONVERSION specifies the type of conversion. LENGTH does not include any length
+/// modifier or the conversion specifier itself. FIELD_WIDTH and PRECISION are the field width and
+/// precision for '*' values, if HAVE_FIELD_WIDTH and HAVE_PRECISION are true, respectively.
+/// ARGUMENT is the argument to be formatted.
void builtin_printf_state_t::print_direc(const wchar_t *start, size_t length, wchar_t conversion,
- bool have_field_width, int field_width,
- bool have_precision, int precision,
- wchar_t const *argument)
-{
- // Start with everything except the conversion specifier
+ bool have_field_width, int field_width,
+ bool have_precision, int precision,
+ wchar_t const *argument) {
+ // Start with everything except the conversion specifier.
wcstring fmt(start, length);
- /* Create a copy of the % directive, with an intmax_t-wide width modifier substituted for any existing integer length modifier. */
- switch (conversion)
- {
+ // Create a copy of the % directive, with an intmax_t-wide width modifier substituted for any
+ // existing integer length modifier.
+ switch (conversion) {
case L'd':
case L'i':
- case L'u':
+ case L'u': {
fmt.append(L"ll");
break;
+ }
case L'a':
case L'e':
case L'f':
@@ -481,66 +452,56 @@ void builtin_printf_state_t::print_direc(const wchar_t *start, size_t length, wc
case L'A':
case L'E':
case L'F':
- case L'G':
+ case L'G': {
fmt.append(L"L");
break;
+ }
case L's':
- case L'c':
+ case L'c': {
fmt.append(L"l");
break;
- default:
- break;
+ }
+ default: { break; }
}
- // Append the conversion itself
+ // Append the conversion itself.
fmt.push_back(conversion);
- switch (conversion)
- {
+ switch (conversion) {
case L'd':
- case L'i':
- {
+ case L'i': {
intmax_t arg = string_to_scalar_type<intmax_t>(argument, this);
- if (! have_field_width)
- {
- if (! have_precision)
+ if (!have_field_width) {
+ if (!have_precision)
this->append_format_output(fmt.c_str(), arg);
else
this->append_format_output(fmt.c_str(), precision, arg);
- }
- else
- {
- if (! have_precision)
+ } else {
+ if (!have_precision)
this->append_format_output(fmt.c_str(), field_width, arg);
else
this->append_format_output(fmt.c_str(), field_width, precision, arg);
}
+ break;
}
- break;
-
case L'o':
case L'u':
case L'x':
- case L'X':
- {
+ case L'X': {
uintmax_t arg = string_to_scalar_type<uintmax_t>(argument, this);
- if (!have_field_width)
- {
+ if (!have_field_width) {
if (!have_precision)
this->append_format_output(fmt.c_str(), arg);
else
this->append_format_output(fmt.c_str(), precision, arg);
- }
- else
- {
+ } else {
if (!have_precision)
this->append_format_output(fmt.c_str(), field_width, arg);
else
this->append_format_output(fmt.c_str(), field_width, precision, arg);
}
+ break;
}
- break;
-
case L'a':
case L'A':
case L'e':
@@ -548,98 +509,81 @@ void builtin_printf_state_t::print_direc(const wchar_t *start, size_t length, wc
case L'f':
case L'F':
case L'g':
- case L'G':
- {
+ case L'G': {
long double arg = string_to_scalar_type<long double>(argument, this);
- if (!have_field_width)
- {
+ if (!have_field_width) {
if (!have_precision)
this->append_format_output(fmt.c_str(), arg);
else
this->append_format_output(fmt.c_str(), precision, arg);
- }
- else
- {
+ } else {
if (!have_precision)
this->append_format_output(fmt.c_str(), field_width, arg);
else
this->append_format_output(fmt.c_str(), field_width, precision, arg);
}
+ break;
}
- break;
-
- case L'c':
+ case L'c': {
if (!have_field_width)
this->append_format_output(fmt.c_str(), *argument);
else
this->append_format_output(fmt.c_str(), field_width, *argument);
break;
- case L's':
- if (!have_field_width)
- {
- if (!have_precision)
- {
+ }
+ case L's': {
+ if (!have_field_width) {
+ if (!have_precision) {
this->append_format_output(fmt.c_str(), argument);
- }
- else
+ } else
this->append_format_output(fmt.c_str(), precision, argument);
- }
- else
- {
+ } else {
if (!have_precision)
this->append_format_output(fmt.c_str(), field_width, argument);
else
this->append_format_output(fmt.c_str(), field_width, precision, argument);
}
break;
+ }
}
}
-/* For each character in str, set the corresponding boolean in the array to the given flag */
-static inline void modify_allowed_format_specifiers(bool ok[UCHAR_MAX + 1], const char *str, bool flag)
-{
- for (const char *c = str; *c != '\0'; c++)
- {
+/// For each character in str, set the corresponding boolean in the array to the given flag.
+static inline void modify_allowed_format_specifiers(bool ok[UCHAR_MAX + 1], const char *str,
+ bool flag) {
+ for (const char *c = str; *c != '\0'; c++) {
unsigned char idx = static_cast<unsigned char>(*c);
ok[idx] = flag;
}
}
-/* Print the text in FORMAT, using ARGV (with ARGC elements) for
- arguments to any `%' directives.
- Return the number of elements of ARGV used. */
-
-int builtin_printf_state_t::print_formatted(const wchar_t *format, int argc, wchar_t **argv)
-{
- int save_argc = argc; /* Preserve original value. */
- const wchar_t *f; /* Pointer into `format'. */
- const wchar_t *direc_start; /* Start of % directive. */
- size_t direc_length; /* Length of % directive. */
- bool have_field_width; /* True if FIELD_WIDTH is valid. */
- int field_width = 0; /* Arg to first '*'. */
- bool have_precision; /* True if PRECISION is valid. */
- int precision = 0; /* Arg to second '*'. */
- bool ok[UCHAR_MAX + 1] = { }; /* ok['x'] is true if %x is allowed. */
-
- for (f = format; *f != L'\0'; ++f)
- {
- switch (*f)
- {
- case L'%':
+/// Print the text in FORMAT, using ARGV (with ARGC elements) for arguments to any `%' directives.
+/// Return the number of elements of ARGV used.
+int builtin_printf_state_t::print_formatted(const wchar_t *format, int argc, wchar_t **argv) {
+ int save_argc = argc; /* Preserve original value. */
+ const wchar_t *f; /* Pointer into `format'. */
+ const wchar_t *direc_start; /* Start of % directive. */
+ size_t direc_length; /* Length of % directive. */
+ bool have_field_width; /* True if FIELD_WIDTH is valid. */
+ int field_width = 0; /* Arg to first '*'. */
+ bool have_precision; /* True if PRECISION is valid. */
+ int precision = 0; /* Arg to second '*'. */
+ bool ok[UCHAR_MAX + 1] = {}; /* ok['x'] is true if %x is allowed. */
+
+ for (f = format; *f != L'\0'; ++f) {
+ switch (*f) {
+ case L'%': {
direc_start = f++;
direc_length = 1;
have_field_width = have_precision = false;
- if (*f == L'%')
- {
+ if (*f == L'%') {
this->append_output(L'%');
break;
}
- if (*f == L'b')
- {
- /* FIXME: Field width and precision are not supported
- for %b, even though POSIX requires it. */
- if (argc > 0)
- {
+ if (*f == L'b') {
+ // FIXME: Field width and precision are not supported for %b, even though POSIX
+ // requires it.
+ if (argc > 0) {
print_esc_string(*argv);
++argv;
--argc;
@@ -649,10 +593,8 @@ int builtin_printf_state_t::print_formatted(const wchar_t *format, int argc, wch
modify_allowed_format_specifiers(ok, "aAcdeEfFgGiosuxX", true);
- for (;; f++, direc_length++)
- {
- switch (*f)
- {
+ for (;; f++, direc_length++) {
+ switch (*f) {
case L'I':
case L'\'':
modify_allowed_format_specifiers(ok, "aAceEosxX", false);
@@ -671,15 +613,12 @@ int builtin_printf_state_t::print_formatted(const wchar_t *format, int argc, wch
goto no_more_flag_characters;
}
}
-no_more_flag_characters:
- ;
+ no_more_flag_characters:;
- if (*f == L'*')
- {
+ if (*f == L'*') {
++f;
++direc_length;
- if (argc > 0)
- {
+ if (argc > 0) {
intmax_t width = string_to_scalar_type<intmax_t>(*argv, this);
if (INT_MIN <= width && width <= INT_MAX)
field_width = static_cast<int>(width);
@@ -687,104 +626,83 @@ no_more_flag_characters:
this->fatal_error(_(L"invalid field width: %ls"), *argv);
++argv;
--argc;
- }
- else
- {
+ } else {
field_width = 0;
}
have_field_width = true;
- }
- else
- {
- while (iswdigit(*f))
- {
+ } else {
+ while (iswdigit(*f)) {
++f;
++direc_length;
}
}
- if (*f == L'.')
- {
+ if (*f == L'.') {
++f;
++direc_length;
modify_allowed_format_specifiers(ok, "c", false);
- if (*f == L'*')
- {
+ if (*f == L'*') {
++f;
++direc_length;
- if (argc > 0)
- {
+ if (argc > 0) {
intmax_t prec = string_to_scalar_type<intmax_t>(*argv, this);
- if (prec < 0)
- {
- /* A negative precision is taken as if the
- precision were omitted, so -1 is safe
- here even if prec < INT_MIN. */
+ if (prec < 0) {
+ // A negative precision is taken as if the precision were omitted,
+ // so -1 is safe here even if prec < INT_MIN.
precision = -1;
- }
- else if (INT_MAX < prec)
+ } else if (INT_MAX < prec)
this->fatal_error(_(L"invalid precision: %ls"), *argv);
- else
- {
+ else {
precision = static_cast<int>(prec);
}
++argv;
--argc;
- }
- else
- {
+ } else {
precision = 0;
}
have_precision = true;
- }
- else
- {
- while (iswdigit(*f))
- {
+ } else {
+ while (iswdigit(*f)) {
++f;
++direc_length;
}
}
}
- while (*f == L'l' || *f == L'L' || *f == L'h' || *f == L'j' || *f == L't' || *f == L'z')
+ while (*f == L'l' || *f == L'L' || *f == L'h' || *f == L'j' || *f == L't' ||
+ *f == L'z') {
++f;
+ }
- {
- wchar_t conversion = *f;
- if (conversion > 0xFF || ! ok[conversion])
- {
- this->fatal_error(_(L"%.*ls: invalid conversion specification"), (int)(f + 1 - direc_start), direc_start);
- return 0;
- }
+ wchar_t conversion = *f;
+ if (conversion > 0xFF || !ok[conversion]) {
+ this->fatal_error(_(L"%.*ls: invalid conversion specification"),
+ (int)(f + 1 - direc_start), direc_start);
+ return 0;
}
- print_direc(direc_start, direc_length, *f,
- have_field_width, field_width,
- have_precision, precision,
- (argc <= 0 ? L"" : (argc--, *argv++)));
+ print_direc(direc_start, direc_length, *f, have_field_width, field_width,
+ have_precision, precision, (argc <= 0 ? L"" : (argc--, *argv++)));
break;
-
- case L'\\':
+ }
+ case L'\\': {
f += print_esc(f, false);
break;
-
- default:
- this->append_output(*f);
+ }
+ default: { this->append_output(*f); }
}
}
return save_argc - argc;
}
-static int builtin_printf(parser_t &parser, io_streams_t &streams, wchar_t **argv)
-{
+/// The printf builtin.
+int builtin_printf(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
builtin_printf_state_t state(streams);
wchar_t *format;
int args_used;
int argc = builtin_count_args(argv);
- if (argc <= 1)
- {
+ if (argc <= 1) {
state.fatal_error(_(L"printf: not enough arguments"));
return STATUS_BUILTIN_ERROR;
}
@@ -793,12 +711,10 @@ static int builtin_printf(parser_t &parser, io_streams_t &streams, wchar_t **arg
argc -= 2;
argv += 2;
- do
- {
+ do {
args_used = state.print_formatted(format, argc, argv);
argc -= args_used;
argv += args_used;
- }
- while (args_used > 0 && argc > 0 && ! state.early_exit);
+ } while (args_used > 0 && argc > 0 && !state.early_exit);
return state.exit_code;
}
diff --git a/src/builtin_printf.h b/src/builtin_printf.h
new file mode 100644
index 00000000..f99a864f
--- /dev/null
+++ b/src/builtin_printf.h
@@ -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
diff --git a/src/builtin_set.cpp b/src/builtin_set.cpp
index 823bdebc..2bc60d8b 100644
--- a/src/builtin_set.cpp
+++ b/src/builtin_set.cpp
@@ -1,88 +1,72 @@
-/** \file builtin_set.c Functions defining the set builtin
-
-Functions used for implementing the set builtin.
-
-*/
+// Functions used for implementing the set builtin.
+#include <errno.h>
+#include <stdbool.h>
#include <stdlib.h>
+#include <sys/stat.h>
#include <wchar.h>
#include <wctype.h>
-#include <vector>
#include <algorithm>
-#include <sys/stat.h>
-#include <string>
+#include <iterator>
#include <memory>
-#include <errno.h>
#include <set>
-#include <iterator>
-#include <stdbool.h>
+#include <string>
+#include <vector>
-#include "fallback.h" // IWYU pragma: keep
-#include "wutil.h" // IWYU pragma: keep
#include "builtin.h"
+#include "common.h"
#include "env.h"
#include "expand.h"
-#include "common.h"
-#include "wgetopt.h"
-#include "proc.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;
-/**
- 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"
-
-/**
- Test if the specified variable should be subject to path validation
-*/
-static int is_path_variable(const wchar_t *env)
-{
- return contains(env, L"PATH", L"CDPATH");
-}
+// 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"
+
+// Test if the specified variable should be subject to path validation.
+static int is_path_variable(const wchar_t *env) { return contains(env, L"PATH", L"CDPATH"); }
-/**
- Call env_set. If this is a path variable, e.g. PATH, validate the
- elements. On error, print a description of the problem to stderr.
-*/
-static int my_env_set(const wchar_t *key, const wcstring_list_t &val, int scope, io_streams_t &streams)
-{
+/// Call env_set. If this is a path variable, e.g. PATH, validate the elements. On error, print a
+/// description of the problem to stderr.
+static int my_env_set(const wchar_t *key, const wcstring_list_t &val, int scope,
+ io_streams_t &streams) {
size_t i;
int retcode = 0;
- const wchar_t *val_str=NULL;
+ const wchar_t *val_str = NULL;
- if (is_path_variable(key))
- {
- /* Fix for https://github.com/fish-shell/fish-shell/issues/199 . Return success if any path setting succeeds. */
+ if (is_path_variable(key)) {
+ // Fix for https://github.com/fish-shell/fish-shell/issues/199 . Return success if any path
+ // setting succeeds.
bool any_success = false;
- /* Don't bother validating (or complaining about) values that are already present.
- When determining already-present values, use ENV_DEFAULT instead of the passed-in scope because in:
- set -l PATH stuff $PATH
- where we are temporarily shadowing a variable, we want to compare against the shadowed value, not the
- (missing) local value.
- Also don't bother to complain about relative paths, which don't start with /.
- */
+ // Don't bother validating (or complaining about) values that are already present. When
+ // determining already-present values, use ENV_DEFAULT instead of the passed-in scope
+ // because in:
+ //
+ // set -l PATH stuff $PATH
+ //
+ // where we are temporarily shadowing a variable, we want to compare against the shadowed
+ // value, not the (missing) local value. Also don't bother to complain about relative paths,
+ // which don't start with /.
wcstring_list_t existing_values;
const env_var_t existing_variable = env_get_string(key, ENV_DEFAULT);
- if (! existing_variable.missing_or_empty())
+ if (!existing_variable.missing_or_empty())
tokenize_variable_array(existing_variable, existing_values);
- for (i=0; i< val.size() ; i++)
- {
+ for (i = 0; i < val.size(); i++) {
const wcstring &dir = val.at(i);
- if (!string_prefixes_string(L"/", dir) || list_contains_string(existing_values, dir))
- {
+ if (!string_prefixes_string(L"/", dir) || list_contains_string(existing_values, dir)) {
any_success = true;
continue;
}
@@ -92,87 +76,73 @@ static int my_env_set(const wchar_t *key, const wcstring_list_t &val, int scope,
bool error = false;
struct stat buff;
- if (wstat(dir, &buff))
- {
+ if (wstat(dir, &buff)) {
error = true;
show_perror = true;
}
- if (!(S_ISDIR(buff.st_mode)))
- {
+ if (!(S_ISDIR(buff.st_mode))) {
error = true;
}
- if (!error)
- {
+ if (!error) {
any_success = true;
- }
- else
- {
+ } else {
streams.err.append_format(_(BUILTIN_SET_PATH_ERROR), L"set", dir.c_str(), key);
const wchar_t *colon = wcschr(dir.c_str(), L':');
- if (colon && *(colon+1))
- {
+ if (colon && *(colon + 1)) {
show_hint = 1;
}
-
}
- if (show_perror)
- {
+ if (show_perror) {
builtin_wperror(L"set", streams);
}
- if (show_hint)
- {
- streams.err.append_format(_(BUILTIN_SET_PATH_HINT), L"set", key, key, wcschr(dir.c_str(), L':')+1);
+ if (show_hint) {
+ streams.err.append_format(_(BUILTIN_SET_PATH_HINT), L"set", key, key,
+ wcschr(dir.c_str(), L':') + 1);
}
-
}
- /* Fail at setting the path if we tried to set it to something non-empty, but it wound up empty. */
- if (! val.empty() && ! any_success)
- {
+ // Fail at setting the path if we tried to set it to something non-empty, but it wound up
+ // empty.
+ if (!val.empty() && !any_success) {
return 1;
}
-
}
wcstring sb;
- if (! val.empty())
- {
- for (i=0; i< val.size() ; i++)
- {
+ if (!val.empty()) {
+ for (i = 0; i < val.size(); i++) {
sb.append(val[i]);
- if (i<val.size() - 1)
- {
+ if (i < val.size() - 1) {
sb.append(ARRAY_SEP_STR);
}
}
val_str = sb.c_str();
}
- switch (env_set(key, val_str, scope | ENV_USER))
- {
- case ENV_PERM:
- {
- streams.err.append_format(_(L"%ls: Tried to change the read-only variable '%ls'\n"), L"set", key);
- retcode=1;
+ switch (env_set(key, val_str, scope | ENV_USER)) {
+ case ENV_PERM: {
+ streams.err.append_format(_(L"%ls: Tried to change the read-only variable '%ls'\n"),
+ L"set", key);
+ retcode = 1;
break;
}
-
- case ENV_SCOPE:
- {
- streams.err.append_format(_(L"%ls: Tried to set the special variable '%ls' with the wrong scope\n"), L"set", key);
- retcode=1;
+ case ENV_SCOPE: {
+ streams.err.append_format(
+ _(L"%ls: Tried to set the special variable '%ls' with the wrong scope\n"), L"set",
+ key);
+ retcode = 1;
break;
}
-
- case ENV_INVALID:
- {
- streams.err.append_format(_(L"%ls: Tried to set the special variable '%ls' to an invalid value\n"), L"set", key);
- retcode=1;
+ case ENV_INVALID: {
+ streams.err.append_format(
+ _(L"%ls: Tried to set the special variable '%ls' to an invalid value\n"), L"set",
+ key);
+ retcode = 1;
break;
}
}
@@ -180,66 +150,50 @@ static int my_env_set(const wchar_t *key, const wcstring_list_t &val, int scope,
return retcode;
}
-
-
-/**
- Extract indexes from a destination argument of the form name[index1 index2...]
-
- \param indexes the list to insert the new indexes into
- \param src the source string to parse
- \param name the name of the element. Return null if the name in \c src does not match this name
- \param var_count the number of elements in the array to parse.
-
- \return the total number of indexes parsed, or -1 on error
-*/
-static int parse_index(std::vector<long> &indexes,
- const wchar_t *src,
- const wchar_t *name,
- size_t var_count,
- io_streams_t &streams)
-{
+/// Extract indexes from a destination argument of the form name[index1 index2...]
+///
+/// \param indexes the list to insert the new indexes into
+/// \param src the source string to parse
+/// \param name the name of the element. Return null if the name in \c src does not match this name
+/// \param var_count the number of elements in the array to parse.
+///
+/// \return the total number of indexes parsed, or -1 on error
+static int parse_index(std::vector<long> &indexes, const wchar_t *src, const wchar_t *name,
+ size_t var_count, io_streams_t &streams) {
size_t len;
int count = 0;
const wchar_t *src_orig = src;
- if (src == 0)
- {
+ if (src == 0) {
return 0;
}
- while (*src != L'\0' && (iswalnum(*src) || *src == L'_'))
- {
+ while (*src != L'\0' && (iswalnum(*src) || *src == L'_')) {
src++;
}
- if (*src != L'[')
- {
+ if (*src != L'[') {
streams.err.append_format(_(BUILTIN_SET_ARG_COUNT), L"set");
return 0;
}
- len = src-src_orig;
+ len = src - src_orig;
- if ((wcsncmp(src_orig, name, len)!=0) || (wcslen(name) != (len)))
- {
- streams.err.append_format(_(L"%ls: Multiple variable names specified in single call (%ls and %.*ls)\n"),
- L"set",
- name,
- len,
- src_orig);
+ if ((wcsncmp(src_orig, name, len) != 0) || (wcslen(name) != (len))) {
+ streams.err.append_format(
+ _(L"%ls: Multiple variable names specified in single call (%ls and %.*ls)\n"), L"set",
+ name, len, src_orig);
return 0;
}
src++;
- while (iswspace(*src))
- {
+ while (iswspace(*src)) {
src++;
}
- while (*src != L']')
- {
+ while (*src != L']') {
wchar_t *end;
long l_ind;
@@ -248,42 +202,34 @@ static int parse_index(std::vector<long> &indexes,
l_ind = wcstol(src, &end, 10);
- if (end==src || errno)
- {
+ if (end == src || errno) {
streams.err.append_format(_(L"%ls: Invalid index starting at '%ls'\n"), L"set", src);
return 0;
}
- if (l_ind < 0)
- {
- l_ind = var_count+l_ind+1;
+ if (l_ind < 0) {
+ l_ind = var_count + l_ind + 1;
}
src = end;
- if (*src==L'.' && *(src+1)==L'.')
- {
- src+=2;
+ if (*src == L'.' && *(src + 1) == L'.') {
+ src += 2;
long l_ind2 = wcstol(src, &end, 10);
- if (end==src || errno)
- {
+ if (end == src || errno) {
return 1;
}
src = end;
- if (l_ind2 < 0)
- {
- l_ind2 = var_count+l_ind2+1;
+ if (l_ind2 < 0) {
+ l_ind2 = var_count + l_ind2 + 1;
}
- int direction = l_ind2<l_ind ? -1 : 1 ;
- for (long jjj = l_ind; jjj*direction <= l_ind2*direction; jjj+=direction)
- {
+ int direction = l_ind2 < l_ind ? -1 : 1;
+ for (long jjj = l_ind; jjj * direction <= l_ind2 * direction; jjj += direction) {
// debug(0, L"Expand range [set]: %i\n", jjj);
indexes.push_back(jjj);
count++;
}
- }
- else
- {
+ } else {
indexes.push_back(l_ind);
count++;
}
@@ -293,85 +239,67 @@ static int parse_index(std::vector<long> &indexes,
return count;
}
-static int update_values(wcstring_list_t &list,
- std::vector<long> &indexes,
- wcstring_list_t &values)
-{
+static int update_values(wcstring_list_t &list, std::vector<long> &indexes,
+ wcstring_list_t &values) {
size_t i;
- /* Replace values where needed */
- for (i = 0; i < indexes.size(); i++)
- {
- /*
- The '- 1' below is because the indices in fish are
- one-based, but the vector uses zero-based indices
- */
+ // Replace values where needed.
+ for (i = 0; i < indexes.size(); i++) {
+ // The '- 1' below is because the indices in fish are one-based, but the vector uses
+ // zero-based indices.
long ind = indexes[i] - 1;
- const wcstring newv = values[ i ];
- if (ind < 0)
- {
+ const wcstring newv = values[i];
+ if (ind < 0) {
return 1;
}
- if ((size_t)ind >= list.size())
- {
- list.resize(ind+1);
+ if ((size_t)ind >= list.size()) {
+ list.resize(ind + 1);
}
-// free((void *) al_get(list, ind));
- list[ ind ] = newv;
+ // free((void *) al_get(list, ind));
+ list[ind] = newv;
}
return 0;
}
-/**
- Erase from a list of wcstring values at specified indexes
-*/
-static void erase_values(wcstring_list_t &list, const std::vector<long> &indexes)
-{
+/// Erase from a list of wcstring values at specified indexes.
+static void erase_values(wcstring_list_t &list, const std::vector<long> &indexes) {
// Make a set of indexes.
// This both sorts them into ascending order and removes duplicates.
const std::set<long> indexes_set(indexes.begin(), indexes.end());
- // Now walk the set backwards, so we encounter larger indexes first, and remove elements at the given (1-based) indexes.
+ // Now walk the set backwards, so we encounter larger indexes first, and remove elements at the
+ // given (1-based) indexes.
std::set<long>::const_reverse_iterator iter;
- for (iter = indexes_set.rbegin(); iter != indexes_set.rend(); ++iter)
- {
+ for (iter = indexes_set.rbegin(); iter != indexes_set.rend(); ++iter) {
long val = *iter;
- if (val > 0 && (size_t)val <= list.size())
- {
+ if (val > 0 && (size_t)val <= list.size()) {
// One-based indexing!
list.erase(list.begin() + val - 1);
}
}
}
-
-/**
- Print the names of all environment variables in the scope, with or without shortening,
- with or without values, with or without escaping
-*/
-static void print_variables(int include_values, int esc, bool shorten_ok, int scope, io_streams_t &streams)
-{
+/// Print the names of all environment variables in the scope, with or without shortening, with or
+/// without values, with or without escaping
+static void print_variables(int include_values, int esc, bool shorten_ok, int scope,
+ io_streams_t &streams) {
wcstring_list_t names = env_get_names(scope);
sort(names.begin(), names.end());
- for (size_t i = 0; i < names.size(); i++)
- {
+ for (size_t i = 0; i < names.size(); i++) {
const wcstring key = names.at(i);
const wcstring e_key = escape_string(key, 0);
streams.out.append(e_key);
- if (include_values)
- {
+ if (include_values) {
env_var_t value = env_get_string(key, scope);
- if (!value.missing())
- {
+ if (!value.missing()) {
int shorten = 0;
- if (shorten_ok && value.length() > 64)
- {
+ if (shorten_ok && value.length() > 64) {
shorten = 1;
value.resize(60);
}
@@ -381,11 +309,9 @@ static void print_variables(int include_values, int esc, bool shorten_ok, int sc
streams.out.append(L" ");
streams.out.append(e_value);
- if (shorten)
- {
+ if (shorten) {
streams.out.push_back(ellipsis_char);
}
-
}
}
@@ -393,117 +319,101 @@ static void print_variables(int include_values, int esc, bool shorten_ok, int sc
}
}
-
-
-/**
- The set builtin. Creates, updates and erases environment variables
- and environemnt variable arrays.
-*/
-static int builtin_set(parser_t &parser, io_streams_t &streams, wchar_t **argv)
-{
+/// The set builtin. Creates, updates and erases environment variables and environemnt variable
+/// arrays.
+int builtin_set(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"export", no_argument, 0, 'x' },
- { L"global", no_argument, 0, 'g' },
- { L"local", no_argument, 0, 'l' },
- { L"erase", no_argument, 0, 'e' },
- { L"names", no_argument, 0, 'n' },
- { L"unexport", no_argument, 0, 'u' },
- { L"universal", no_argument, 0, 'U' },
- { L"long", no_argument, 0, 'L' },
- { L"query", no_argument, 0, 'q' },
- { L"help", no_argument, 0, 'h' },
- { 0, 0, 0, 0 }
- } ;
+ // Variables used for parsing the argument list.
+ const struct woption long_options[] = {{L"export", no_argument, 0, 'x'},
+ {L"global", no_argument, 0, 'g'},
+ {L"local", no_argument, 0, 'l'},
+ {L"erase", no_argument, 0, 'e'},
+ {L"names", no_argument, 0, 'n'},
+ {L"unexport", no_argument, 0, 'u'},
+ {L"universal", no_argument, 0, 'U'},
+ {L"long", no_argument, 0, 'L'},
+ {L"query", no_argument, 0, 'q'},
+ {L"help", no_argument, 0, 'h'},
+ {0, 0, 0, 0}};
const wchar_t *short_options = L"+xglenuULqh";
int argc = builtin_count_args(argv);
- /*
- Flags to set the work mode
- */
+ // Flags to set the work mode.
int local = 0, global = 0, exportv = 0;
- int erase = 0, list = 0, unexport=0;
- int universal = 0, query=0;
+ int erase = 0, list = 0, unexport = 0;
+ int universal = 0, query = 0;
bool shorten_ok = true;
bool preserve_incoming_failure_exit_status = true;
const int incoming_exit_status = proc_get_last_status();
- /*
- Variables used for performing the actual work
- */
+ // Variables used for performing the actual work.
wchar_t *dest = 0;
- int retcode=0;
+ int retcode = 0;
int scope;
- int slice=0;
+ int slice = 0;
const wchar_t *bad_char = NULL;
-
- /* 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 'e':
+ }
+ case 'e': {
erase = 1;
preserve_incoming_failure_exit_status = false;
break;
-
- case 'n':
+ }
+ case 'n': {
list = 1;
preserve_incoming_failure_exit_status = false;
break;
-
- case 'x':
+ }
+ case 'x': {
exportv = 1;
break;
-
- case 'l':
+ }
+ case 'l': {
local = 1;
break;
-
- case 'g':
+ }
+ case 'g': {
global = 1;
break;
-
- case 'u':
+ }
+ case 'u': {
unexport = 1;
break;
-
- case 'U':
+ }
+ case 'U': {
universal = 1;
break;
-
- case 'L':
+ }
+ case 'L': {
shorten_ok = false;
break;
-
- case 'q':
+ }
+ case 'q': {
query = 1;
preserve_incoming_failure_exit_status = false;
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]);
+ builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return 1;
default:
@@ -511,229 +421,164 @@ static int builtin_set(parser_t &parser, io_streams_t &streams, wchar_t **argv)
}
}
- /*
- Ok, all arguments have been parsed, let's validate them
- */
-
- /*
- If we are checking the existance of a variable (-q) we can not
- also specify scope
- */
-
- if (query && (erase || list))
- {
- streams.err.append_format(BUILTIN_ERR_COMBO,
- argv[0]);
+ // Ok, all arguments have been parsed, let's validate them. If we are checking the existance of
+ // a variable (-q) we can not also specify scope.
+ if (query && (erase || list)) {
+ streams.err.append_format(BUILTIN_ERR_COMBO, argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err);
return 1;
}
-
- /* We can't both list and erase variables */
- if (erase && list)
- {
- streams.err.append_format(BUILTIN_ERR_COMBO,
- argv[0]);
+ // We can't both list and erase variables.
+ if (erase && list) {
+ streams.err.append_format(BUILTIN_ERR_COMBO, argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err);
return 1;
}
- /*
- Variables can only have one scope
- */
- if (local + global + universal > 1)
- {
- streams.err.append_format(BUILTIN_ERR_GLOCAL,
- argv[0]);
+ // Variables can only have one scope.
+ if (local + global + universal > 1) {
+ streams.err.append_format(BUILTIN_ERR_GLOCAL, argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err);
return 1;
}
- /*
- Variables can only have one export status
- */
- if (exportv && unexport)
- {
- streams.err.append_format(BUILTIN_ERR_EXPUNEXP,
- argv[0]);
+ // Variables can only have one export status.
+ if (exportv && unexport) {
+ streams.err.append_format(BUILTIN_ERR_EXPUNEXP, argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err);
return 1;
}
- /*
- Calculate the scope value for variable assignement
- */
- scope = (local ? ENV_LOCAL : 0) | (global ? ENV_GLOBAL : 0) | (exportv ? ENV_EXPORT : 0) | (unexport ? ENV_UNEXPORT : 0) | (universal ? ENV_UNIVERSAL:0) | ENV_USER;
-
- if (query)
- {
- /*
- Query mode. Return the number of variables that do not exist
- out of the specified variables.
- */
+ // Calculate the scope value for variable assignement.
+ scope = (local ? ENV_LOCAL : 0) | (global ? ENV_GLOBAL : 0) | (exportv ? ENV_EXPORT : 0) |
+ (unexport ? ENV_UNEXPORT : 0) | (universal ? ENV_UNIVERSAL : 0) | ENV_USER;
+
+ if (query) {
+ // Query mode. Return the number of variables that do not exist out of the specified
+ // variables.
int i;
- for (i=w.woptind; i<argc; i++)
- {
+ for (i = w.woptind; i < argc; i++) {
wchar_t *arg = argv[i];
- int slice=0;
+ int slice = 0;
- if (!(dest = wcsdup(arg)))
- {
+ if (!(dest = wcsdup(arg))) {
DIE_MEM();
}
- if (wcschr(dest, L'['))
- {
+ if (wcschr(dest, L'[')) {
slice = 1;
- *wcschr(dest, L'[')=0;
+ *wcschr(dest, L'[') = 0;
}
- if (slice)
- {
+ if (slice) {
std::vector<long> indexes;
wcstring_list_t result;
size_t j;
env_var_t dest_str = env_get_string(dest, scope);
- if (! dest_str.missing())
- tokenize_variable_array(dest_str, result);
+ if (!dest_str.missing()) tokenize_variable_array(dest_str, result);
- if (!parse_index(indexes, arg, dest, result.size(), streams))
- {
+ if (!parse_index(indexes, arg, dest, result.size(), streams)) {
builtin_print_help(parser, streams, argv[0], streams.err);
retcode = 1;
break;
}
- for (j=0; j < indexes.size() ; j++)
- {
+ for (j = 0; j < indexes.size(); j++) {
long idx = indexes[j];
- if (idx < 1 || (size_t)idx > result.size())
- {
+ if (idx < 1 || (size_t)idx > result.size()) {
retcode++;
}
}
- }
- else
- {
- if (!env_exist(arg, scope))
- {
+ } else {
+ if (!env_exist(arg, scope)) {
retcode++;
}
}
free(dest);
-
}
return retcode;
}
- if (list)
- {
- /* Maybe we should issue an error if there are any other arguments? */
+ if (list) {
+ // Maybe we should issue an error if there are any other arguments?
print_variables(0, 0, shorten_ok, scope, streams);
return 0;
}
- if (w.woptind == argc)
- {
- /*
- Print values of variables
- */
-
- if (erase)
- {
- streams.err.append_format(_(L"%ls: Erase needs a variable name\n"),
- argv[0]);
+ if (w.woptind == argc) {
+ // Print values of variables.
+ if (erase) {
+ streams.err.append_format(_(L"%ls: Erase needs a variable name\n"), argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err);
retcode = 1;
- }
- else
- {
+ } else {
print_variables(1, 1, shorten_ok, scope, streams);
}
return retcode;
}
- if (!(dest = wcsdup(argv[w.woptind])))
- {
+ if (!(dest = wcsdup(argv[w.woptind]))) {
DIE_MEM();
}
- if (wcschr(dest, L'['))
- {
+ if (wcschr(dest, L'[')) {
slice = 1;
- *wcschr(dest, L'[')=0;
+ *wcschr(dest, L'[') = 0;
}
- if (!wcslen(dest))
- {
+ if (!wcslen(dest)) {
free(dest);
streams.err.append_format(BUILTIN_ERR_VARNAME_ZERO, argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err);
return 1;
}
- if ((bad_char = wcsvarname(dest)))
- {
+ if ((bad_char = wcsvarname(dest))) {
streams.err.append_format(BUILTIN_ERR_VARCHAR, argv[0], *bad_char);
builtin_print_help(parser, streams, argv[0], streams.err);
free(dest);
return 1;
}
- /*
- set assignment can work in two modes, either using slices or
- using the whole array. We detect which mode is used here.
- */
-
- if (slice)
- {
-
- /*
- Slice mode
- */
+ // Set assignment can work in two modes, either using slices or using the whole array. We detect
+ // which mode is used here.
+ if (slice) {
+ // Slice mode.
std::vector<long> indexes;
wcstring_list_t result;
const env_var_t dest_str = env_get_string(dest, scope);
- if (! dest_str.missing())
- {
+ if (!dest_str.missing()) {
tokenize_variable_array(dest_str, result);
- }
- else if (erase)
- {
+ } else if (erase) {
retcode = 1;
}
- if (!retcode)
- {
- for (; w.woptind<argc; w.woptind++)
- {
- if (!parse_index(indexes, argv[w.woptind], dest, result.size(), streams))
- {
+ if (!retcode) {
+ for (; w.woptind < argc; w.woptind++) {
+ if (!parse_index(indexes, argv[w.woptind], dest, result.size(), streams)) {
builtin_print_help(parser, streams, argv[0], streams.err);
retcode = 1;
break;
}
size_t idx_count = indexes.size();
- size_t val_count = argc-w.woptind-1;
+ size_t val_count = argc - w.woptind - 1;
- if (!erase)
- {
- if (val_count < idx_count)
- {
+ if (!erase) {
+ if (val_count < idx_count) {
streams.err.append_format(_(BUILTIN_SET_ARG_COUNT), argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err);
- retcode=1;
+ retcode = 1;
break;
}
- if (val_count == idx_count)
- {
+ if (val_count == idx_count) {
w.woptind++;
break;
}
@@ -741,79 +586,53 @@ static int builtin_set(parser_t &parser, io_streams_t &streams, wchar_t **argv)
}
}
- if (!retcode)
- {
- /*
- Slice indexes have been calculated, do the actual work
- */
-
- if (erase)
- {
+ if (!retcode) {
+ // Slice indexes have been calculated, do the actual work.
+ if (erase) {
erase_values(result, indexes);
my_env_set(dest, result, scope, streams);
- }
- else
- {
+ } else {
wcstring_list_t value;
- while (w.woptind < argc)
- {
+ while (w.woptind < argc) {
value.push_back(argv[w.woptind++]);
}
- if (update_values(result,
- indexes,
- value))
- {
+ if (update_values(result, indexes, value)) {
streams.err.append_format(L"%ls: ", argv[0]);
streams.err.append_format(ARRAY_BOUNDS_ERR);
streams.err.push_back(L'\n');
}
my_env_set(dest, result, scope, streams);
-
-
}
}
- }
- else
- {
+ } else {
w.woptind++;
-
- /*
- No slicing
- */
- if (erase)
- {
- if (w.woptind != argc)
- {
+ // No slicing.
+ if (erase) {
+ if (w.woptind != argc) {
streams.err.append_format(_(L"%ls: Values cannot be specfied with erase\n"),
- argv[0]);
+ argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err);
- retcode=1;
- }
- else
- {
+ retcode = 1;
+ } else {
retcode = env_remove(dest, scope);
}
- }
- else
- {
+ } else {
wcstring_list_t val;
- for (int i=w.woptind; i<argc; i++)
- val.push_back(argv[i]);
+ for (int i = w.woptind; i < argc; i++) val.push_back(argv[i]);
retcode = my_env_set(dest, val, scope, streams);
}
}
- /* Check if we are setting variables above the effective scope.
- See https://github.com/fish-shell/fish-shell/issues/806
- */
-
+ // Check if we are setting variables above the effective scope. See
+ // https://github.com/fish-shell/fish-shell/issues/806
env_var_t global_dest = env_get_string(dest, ENV_GLOBAL);
- if (universal && ! global_dest.missing())
- {
- streams.err.append_format(_(L"%ls: Warning: universal scope selected, but a global variable '%ls' exists.\n"), L"set", dest);
+ if (universal && !global_dest.missing()) {
+ streams.err.append_format(
+ _(L"%ls: Warning: universal scope selected, but a global variable '%ls' exists.\n"),
+ L"set", dest);
}
free(dest);
@@ -821,6 +640,4 @@ static int builtin_set(parser_t &parser, io_streams_t &streams, wchar_t **argv)
if (retcode == STATUS_BUILTIN_OK && preserve_incoming_failure_exit_status)
retcode = incoming_exit_status;
return retcode;
-
}
-
diff --git a/src/builtin_set.h b/src/builtin_set.h
new file mode 100644
index 00000000..76585733
--- /dev/null
+++ b/src/builtin_set.h
@@ -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
diff --git a/src/builtin_set_color.cpp b/src/builtin_set_color.cpp
index d3b744cd..2cd1d876 100644
--- a/src/builtin_set_color.cpp
+++ b/src/builtin_set_color.cpp
@@ -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 "common.h"
+#include "io.h"
#include "output.h"
-#include "wgetopt.h"
#include "proc.h"
-#include "io.h"
-#include "common.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();
diff --git a/src/builtin_set_color.h b/src/builtin_set_color.h
new file mode 100644
index 00000000..7e41cd58
--- /dev/null
+++ b/src/builtin_set_color.h
@@ -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
diff --git a/src/builtin_string.cpp b/src/builtin_string.cpp
index 51c824ca..9e6c11a4 100644
--- a/src/builtin_string.cpp
+++ b/src/builtin_string.cpp
@@ -1,54 +1,41 @@
-/** \file builtin_string.cpp
- Implementation of the string builtin.
-*/
+// Implementation of the string builtin.
#include "config.h"
#define PCRE2_CODE_UNIT_WIDTH WCHAR_T_BITS
#ifdef _WIN32
#define PCRE2_STATIC
#endif
-#include <iterator>
-#include <algorithm>
#include <assert.h>
+#include <errno.h>
#include <limits.h>
#include <stdarg.h>
+#include <stdbool.h>
#include <stdlib.h>
-#include <errno.h>
+#include <sys/types.h>
#include <wchar.h>
#include <wctype.h>
+#include <algorithm>
+#include <iterator>
#include <string>
#include <vector>
-#include <sys/types.h>
-#include <stdbool.h>
-#include "pcre2.h"
#include "builtin.h"
#include "common.h"
+#include "fallback.h" // IWYU pragma: keep
+#include "io.h"
#include "parse_util.h"
+#include "pcre2.h"
#include "wgetopt.h"
#include "wildcard.h"
-#include "fallback.h" // IWYU pragma: keep
-#include "io.h"
#include "wutil.h" // IWYU pragma: keep
class parser_t;
-#define STRING_ERR_MISSING _(L"%ls: Expected argument\n")
-
-/* externs from builtin.cpp */
-extern int builtin_count_args(const wchar_t * const * argv);
-void builtin_print_help(parser_t &parser, io_streams_t &streams, const wchar_t *cmd, output_stream_t &b);
+#define STRING_ERR_MISSING _(L"%ls: Expected argument\n")
+enum { BUILTIN_STRING_OK = 0, BUILTIN_STRING_NONE = 1, BUILTIN_STRING_ERROR = 2 };
-enum
-{
- BUILTIN_STRING_OK = 0,
- BUILTIN_STRING_NONE = 1,
- BUILTIN_STRING_ERROR = 2
-};
-
-static void string_error(io_streams_t &streams, const wchar_t *fmt, ...)
-{
+static void string_error(io_streams_t &streams, const wchar_t *fmt, ...) {
streams.err.append(L"string ");
va_list va;
va_start(va, fmt);
@@ -56,111 +43,88 @@ static void string_error(io_streams_t &streams, const wchar_t *fmt, ...)
va_end(va);
}
-static void string_unknown_option(parser_t &parser, io_streams_t &streams, const wchar_t *subcmd, const wchar_t *opt)
-{
+static void string_unknown_option(parser_t &parser, io_streams_t &streams, const wchar_t *subcmd,
+ const wchar_t *opt) {
string_error(streams, BUILTIN_ERR_UNKNOWN, subcmd, opt);
builtin_print_help(parser, streams, L"string", streams.err);
}
-/* We read from stdin if we are the second or later process in a pipeline. */
-static bool string_args_from_stdin(const io_streams_t &streams)
-{
+// We read from stdin if we are the second or later process in a pipeline.
+static bool string_args_from_stdin(const io_streams_t &streams) {
return streams.stdin_is_directly_redirected;
}
-static const wchar_t *string_get_arg_stdin(wcstring *storage, const io_streams_t &streams)
-{
+static const wchar_t *string_get_arg_stdin(wcstring *storage, const io_streams_t &streams) {
std::string arg;
- for (;;)
- {
+ for (;;) {
char ch = '\0';
long rc = read_blocked(streams.stdin_fd, &ch, 1);
- if (rc < 0)
- {
- // failure
+ if (rc < 0) { // failure
return 0;
}
- if (rc == 0)
- {
- // eof
- if (arg.empty())
- {
+ if (rc == 0) { // EOF
+ if (arg.empty()) {
return 0;
- }
- else
- {
+ } else {
break;
}
}
- if (ch == '\n')
- {
+ if (ch == '\n') {
break;
}
arg += ch;
}
-
+
*storage = str2wcstring(arg);
return storage->c_str();
}
-static const wchar_t *string_get_arg_argv(int *argidx, wchar_t **argv)
-{
+static const wchar_t *string_get_arg_argv(int *argidx, wchar_t **argv) {
return (argv && argv[*argidx]) ? argv[(*argidx)++] : 0;
}
-static const wchar_t *string_get_arg(int *argidx, wchar_t **argv, wcstring *storage, const io_streams_t &streams)
-{
- if (string_args_from_stdin(streams))
- {
+static const wchar_t *string_get_arg(int *argidx, wchar_t **argv, wcstring *storage,
+ const io_streams_t &streams) {
+ if (string_args_from_stdin(streams)) {
return string_get_arg_stdin(storage, streams);
- }
- else
- {
+ } else {
return string_get_arg_argv(argidx, argv);
}
}
-static int string_escape(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv)
-{
+static int string_escape(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
const wchar_t *short_options = L"n";
- const struct woption long_options[] =
- {
- { L"no-quoted", no_argument, 0, 'n' },
- { 0, 0, 0, 0 }
- };
+ const struct woption long_options[] = {{L"no-quoted", no_argument, 0, 'n'}, {0, 0, 0, 0}};
escape_flags_t flags = ESCAPE_ALL;
wgetopter_t w;
- for (;;)
- {
+ for (;;) {
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 'n':
+ }
+ case 'n': {
flags |= ESCAPE_NO_QUOTED;
break;
-
- case '?':
+ }
+ case '?': {
string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return BUILTIN_STRING_ERROR;
+ }
}
}
int i = w.woptind;
- if (string_args_from_stdin(streams) && argc > i)
- {
+ if (string_args_from_stdin(streams) && argc > i) {
string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
return BUILTIN_STRING_ERROR;
}
@@ -168,8 +132,7 @@ static int string_escape(parser_t &parser, io_streams_t &streams, int argc, wcha
int nesc = 0;
wcstring storage;
const wchar_t *arg;
- while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0)
- {
+ while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0) {
streams.out.append(escape(arg, flags));
streams.out.append(L'\n');
nesc++;
@@ -178,50 +141,40 @@ static int string_escape(parser_t &parser, io_streams_t &streams, int argc, wcha
return (nesc > 0) ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
}
-static int string_join(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv)
-{
+static int string_join(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
const wchar_t *short_options = L"q";
- const struct woption long_options[] =
- {
- { L"quiet", no_argument, 0, 'q'},
- { 0, 0, 0, 0 }
- };
+ const struct woption long_options[] = {{L"quiet", no_argument, 0, 'q'}, {0, 0, 0, 0}};
bool quiet = false;
wgetopter_t w;
- for (;;)
- {
+ for (;;) {
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 'q':
+ }
+ case 'q': {
quiet = true;
break;
-
- case '?':
+ }
+ case '?': {
string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return BUILTIN_STRING_ERROR;
+ }
}
}
int i = w.woptind;
const wchar_t *sep;
- if ((sep = string_get_arg_argv(&i, argv)) == 0)
- {
+ if ((sep = string_get_arg_argv(&i, argv)) == 0) {
string_error(streams, STRING_ERR_MISSING, argv[0]);
return BUILTIN_STRING_ERROR;
}
- if (string_args_from_stdin(streams) && argc > i)
- {
+ if (string_args_from_stdin(streams) && argc > i) {
string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
return BUILTIN_STRING_ERROR;
}
@@ -229,63 +182,51 @@ static int string_join(parser_t &parser, io_streams_t &streams, int argc, wchar_
int nargs = 0;
const wchar_t *arg;
wcstring storage;
- while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0)
- {
- if (!quiet)
- {
- if (nargs > 0)
- {
+ while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0) {
+ if (!quiet) {
+ if (nargs > 0) {
streams.out.append(sep);
}
streams.out.append(arg);
}
nargs++;
}
- if (nargs > 0 && !quiet)
- {
+ if (nargs > 0 && !quiet) {
streams.out.push_back(L'\n');
}
return (nargs > 1) ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
}
-static int string_length(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv)
-{
+static int string_length(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
const wchar_t *short_options = L"q";
- const struct woption long_options[] =
- {
- { L"quiet", no_argument, 0, 'q'},
- { 0, 0, 0, 0 }
- };
+ const struct woption long_options[] = {{L"quiet", no_argument, 0, 'q'}, {0, 0, 0, 0}};
bool quiet = false;
wgetopter_t w;
- for (;;)
- {
+ for (;;) {
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 'q':
+ }
+ case 'q': {
quiet = true;
break;
-
- case '?':
+ }
+ case '?': {
string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return BUILTIN_STRING_ERROR;
+ }
}
}
int i = w.woptind;
- if (string_args_from_stdin(streams) && argc > i)
- {
+ if (string_args_from_stdin(streams) && argc > i) {
string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
return BUILTIN_STRING_ERROR;
}
@@ -293,15 +234,12 @@ static int string_length(parser_t &parser, io_streams_t &streams, int argc, wcha
const wchar_t *arg;
int nnonempty = 0;
wcstring storage;
- while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0)
- {
+ while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0) {
size_t n = wcslen(arg);
- if (n > 0)
- {
+ if (n > 0) {
nnonempty++;
}
- if (!quiet)
- {
+ if (!quiet) {
streams.out.append(to_string(n));
streams.out.append(L'\n');
}
@@ -310,84 +248,70 @@ static int string_length(parser_t &parser, io_streams_t &streams, int argc, wcha
return (nnonempty > 0) ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
}
-struct match_options_t
-{
+struct match_options_t {
bool all;
bool ignore_case;
bool index;
bool invert_match;
bool quiet;
- match_options_t(): all(false), ignore_case(false), index(false), invert_match(false), quiet(false) { }
+ match_options_t()
+ : all(false), ignore_case(false), index(false), invert_match(false), quiet(false) {}
};
-class string_matcher_t
-{
-protected:
+class string_matcher_t {
+ protected:
match_options_t opts;
io_streams_t &streams;
int total_matched;
-public:
+ public:
string_matcher_t(const match_options_t &opts_, io_streams_t &streams_)
- : opts(opts_), streams(streams_), total_matched(0)
- { }
+ : opts(opts_), streams(streams_), total_matched(0) {}
- virtual ~string_matcher_t() { }
+ virtual ~string_matcher_t() {}
virtual bool report_matches(const wchar_t *arg) = 0;
int match_count() { return total_matched; }
};
-class wildcard_matcher_t: public string_matcher_t
-{
-private:
+class wildcard_matcher_t : public string_matcher_t {
+ private:
wcstring wcpattern;
-public:
- wildcard_matcher_t(const wchar_t * /*argv0*/, const wchar_t *pattern, const match_options_t &opts, io_streams_t &streams)
- : string_matcher_t(opts, streams), wcpattern(parse_util_unescape_wildcards(pattern))
- {
- if (opts.ignore_case)
- {
- for (size_t i = 0; i < wcpattern.length(); i++)
- {
+
+ public:
+ wildcard_matcher_t(const wchar_t * /*argv0*/, const wchar_t *pattern,
+ const match_options_t &opts, io_streams_t &streams)
+ : string_matcher_t(opts, streams), wcpattern(parse_util_unescape_wildcards(pattern)) {
+ if (opts.ignore_case) {
+ for (size_t i = 0; i < wcpattern.length(); i++) {
wcpattern[i] = towlower(wcpattern[i]);
}
}
}
- virtual ~wildcard_matcher_t() { }
+ virtual ~wildcard_matcher_t() {}
- bool report_matches(const wchar_t *arg)
- {
- // Note: --all is a no-op for glob matching since the pattern is always
- // matched against the entire argument
+ bool report_matches(const wchar_t *arg) {
+ // Note: --all is a no-op for glob matching since the pattern is always matched against the
+ // entire argument.
bool match;
- if (opts.ignore_case)
- {
+ if (opts.ignore_case) {
wcstring s = arg;
- for (size_t i = 0; i < s.length(); i++)
- {
+ for (size_t i = 0; i < s.length(); i++) {
s[i] = towlower(s[i]);
}
match = wildcard_match(s, wcpattern, false);
- }
- else
- {
+ } else {
match = wildcard_match(arg, wcpattern, false);
}
- if (match ^ opts.invert_match)
- {
+ if (match ^ opts.invert_match) {
total_matched++;
- if (!opts.quiet)
- {
- if (opts.index)
- {
+ if (!opts.quiet) {
+ if (opts.index) {
streams.out.append_format(L"1 %lu\n", wcslen(arg));
- }
- else
- {
+ } else {
streams.out.append(arg);
streams.out.append(L'\n');
}
@@ -397,22 +321,20 @@ public:
}
};
-static wcstring pcre2_strerror(int err_code)
-{
+static wcstring pcre2_strerror(int err_code) {
wchar_t buf[128];
pcre2_get_error_message(err_code, (PCRE2_UCHAR *)buf, sizeof(buf) / sizeof(wchar_t));
return buf;
}
-struct compiled_regex_t
-{
+struct compiled_regex_t {
pcre2_code *code;
pcre2_match_data *match;
- compiled_regex_t(const wchar_t *argv0, const wchar_t *pattern, bool ignore_case, io_streams_t &streams)
- : code(0), match(0)
- {
- // Disable some sequences that can lead to security problems
+ compiled_regex_t(const wchar_t *argv0, const wchar_t *pattern, bool ignore_case,
+ io_streams_t &streams)
+ : code(0), match(0) {
+ // Disable some sequences that can lead to security problems.
uint32_t options = PCRE2_NEVER_UTF;
#if PCRE2_CODE_UNIT_WIDTH < 32
options |= PCRE2_NEVER_BACKSLASH_C;
@@ -421,68 +343,51 @@ struct compiled_regex_t
int err_code = 0;
PCRE2_SIZE err_offset = 0;
- code = pcre2_compile(
- PCRE2_SPTR(pattern),
- PCRE2_ZERO_TERMINATED,
- options | (ignore_case ? PCRE2_CASELESS : 0),
- &err_code,
- &err_offset,
- 0);
- if (code == 0)
- {
- string_error(streams, _(L"%ls: Regular expression compile error: %ls\n"),
- argv0, pcre2_strerror(err_code).c_str());
+ code =
+ pcre2_compile(PCRE2_SPTR(pattern), PCRE2_ZERO_TERMINATED,
+ options | (ignore_case ? PCRE2_CASELESS : 0), &err_code, &err_offset, 0);
+ if (code == 0) {
+ string_error(streams, _(L"%ls: Regular expression compile error: %ls\n"), argv0,
+ pcre2_strerror(err_code).c_str());
string_error(streams, L"%ls: %ls\n", argv0, pattern);
string_error(streams, L"%ls: %*ls\n", argv0, err_offset, L"^");
return;
}
match = pcre2_match_data_create_from_pattern(code, 0);
- if (match == 0)
- {
+ if (match == 0) {
DIE_MEM();
}
}
- ~compiled_regex_t()
- {
- if (match != 0)
- {
+ ~compiled_regex_t() {
+ if (match != 0) {
pcre2_match_data_free(match);
}
- if (code != 0)
- {
+ if (code != 0) {
pcre2_code_free(code);
}
}
};
-class pcre2_matcher_t: public string_matcher_t
-{
+class pcre2_matcher_t : public string_matcher_t {
const wchar_t *argv0;
compiled_regex_t regex;
- int report_match(const wchar_t *arg, int pcre2_rc)
- {
- // Return values: -1 = error, 0 = no match, 1 = match
- if (pcre2_rc == PCRE2_ERROR_NOMATCH)
- {
- if (opts.invert_match && !opts.quiet)
- {
+ int report_match(const wchar_t *arg, int pcre2_rc) {
+ // Return values: -1 = error, 0 = no match, 1 = match.
+ if (pcre2_rc == PCRE2_ERROR_NOMATCH) {
+ if (opts.invert_match && !opts.quiet) {
streams.out.append(arg);
streams.out.push_back(L'\n');
}
return opts.invert_match ? 1 : 0;
- }
- else if (pcre2_rc < 0)
- {
- string_error(streams, _(L"%ls: Regular expression match error: %ls\n"),
- argv0, pcre2_strerror(pcre2_rc).c_str());
+ } else if (pcre2_rc < 0) {
+ string_error(streams, _(L"%ls: Regular expression match error: %ls\n"), argv0,
+ pcre2_strerror(pcre2_rc).c_str());
return -1;
- }
- else if (pcre2_rc == 0)
- {
+ } else if (pcre2_rc == 0) {
// The output vector wasn't big enough. Should not happen.
string_error(streams, _(L"%ls: Regular expression internal error\n"), argv0);
return -1;
@@ -493,18 +398,15 @@ class pcre2_matcher_t: public string_matcher_t
PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(regex.match);
- for (int j = 0; j < pcre2_rc; j++)
- {
- PCRE2_SIZE begin = ovector[2*j];
- PCRE2_SIZE end = ovector[2*j + 1];
+ for (int j = 0; j < pcre2_rc; j++) {
+ PCRE2_SIZE begin = ovector[2 * j];
+ PCRE2_SIZE end = ovector[2 * j + 1];
- if (begin != PCRE2_UNSET && end != PCRE2_UNSET && !opts.quiet)
- {
- if (opts.index)
- {
- streams.out.append_format(L"%lu %lu", (unsigned long)(begin + 1), (unsigned long)(end - begin));
- }
- else if (end > begin) // may have end < begin if \K is used
+ if (begin != PCRE2_UNSET && end != PCRE2_UNSET && !opts.quiet) {
+ if (opts.index) {
+ streams.out.append_format(L"%lu %lu", (unsigned long)(begin + 1),
+ (unsigned long)(end - begin));
+ } else if (end > begin) // may have end < begin if \K is used
{
streams.out.append(wcstring(&arg[begin], end - begin));
}
@@ -513,77 +415,63 @@ class pcre2_matcher_t: public string_matcher_t
}
return opts.invert_match ? 0 : 1;
-
}
-public:
- pcre2_matcher_t(const wchar_t *argv0_, const wchar_t *pattern, const match_options_t &opts, io_streams_t &streams)
+ public:
+ pcre2_matcher_t(const wchar_t *argv0_, const wchar_t *pattern, const match_options_t &opts,
+ io_streams_t &streams)
: string_matcher_t(opts, streams),
argv0(argv0_),
- regex(argv0_, pattern, opts.ignore_case, streams)
- { }
+ regex(argv0_, pattern, opts.ignore_case, streams) {}
- virtual ~pcre2_matcher_t() { }
+ virtual ~pcre2_matcher_t() {}
- bool report_matches(const wchar_t *arg)
- {
- // A return value of true means all is well (even if no matches were
- // found), false indicates an unrecoverable error.
- if (regex.code == 0)
- {
- // pcre2_compile() failed
+ bool report_matches(const wchar_t *arg) {
+ // A return value of true means all is well (even if no matches were found), false indicates
+ // an unrecoverable error.
+ if (regex.code == 0) {
+ // pcre2_compile() failed.
return false;
}
int matched = 0;
- // See pcre2demo.c for an explanation of this logic
+ // See pcre2demo.c for an explanation of this logic.
PCRE2_SIZE arglen = wcslen(arg);
- int rc = report_match(arg, pcre2_match(regex.code, PCRE2_SPTR(arg), arglen, 0, 0, regex.match, 0));
- if (rc < 0)
- {
- // pcre2 match error
+ int rc = report_match(
+ arg, pcre2_match(regex.code, PCRE2_SPTR(arg), arglen, 0, 0, regex.match, 0));
+ if (rc < 0) { // pcre2 match error.
return false;
- }
- else if (rc == 0)
- {
- // no match
+ } else if (rc == 0) { // no match
return true;
}
matched++;
total_matched++;
- if (opts.invert_match)
- {
+ if (opts.invert_match) {
return true;
}
- // Report any additional matches
+ // Report any additional matches.
PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(regex.match);
- while (opts.all || matched == 0)
- {
+ while (opts.all || matched == 0) {
uint32_t options = 0;
- PCRE2_SIZE offset = ovector[1]; // Start at end of previous match
+ PCRE2_SIZE offset = ovector[1]; // start at end of previous match
- if (ovector[0] == ovector[1])
- {
- if (ovector[0] == arglen)
- {
+ if (ovector[0] == ovector[1]) {
+ if (ovector[0] == arglen) {
break;
}
options = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;
}
- rc = report_match(arg, pcre2_match(regex.code, PCRE2_SPTR(arg), arglen, offset, options, regex.match, 0));
- if (rc < 0)
- {
+ rc = report_match(arg, pcre2_match(regex.code, PCRE2_SPTR(arg), arglen, offset, options,
+ regex.match, 0));
+ if (rc < 0) {
return false;
}
- if (rc == 0)
- {
- if (options == 0)
- {
- // All matches found
+ if (rc == 0) {
+ if (options == 0) { // all matches found
break;
}
ovector[1] = offset + 1;
@@ -596,96 +484,83 @@ public:
}
};
-static int string_match(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv)
-{
+static int string_match(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
const wchar_t *short_options = L"ainvqr";
- const struct woption long_options[] =
- {
- { L"all", no_argument, 0, 'a'},
- { L"ignore-case", no_argument, 0, 'i'},
- { L"index", no_argument, 0, 'n'},
- { L"invert", no_argument, 0, 'v'},
- { L"quiet", no_argument, 0, 'q'},
- { L"regex", no_argument, 0, 'r'},
- { 0, 0, 0, 0 }
- };
+ const struct woption long_options[] = {{L"all", no_argument, 0, 'a'},
+ {L"ignore-case", no_argument, 0, 'i'},
+ {L"index", no_argument, 0, 'n'},
+ {L"invert", no_argument, 0, 'v'},
+ {L"quiet", no_argument, 0, 'q'},
+ {L"regex", no_argument, 0, 'r'},
+ {0, 0, 0, 0}};
match_options_t opts;
bool regex = false;
wgetopter_t w;
- for (;;)
- {
+ for (;;) {
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 'a':
+ }
+ case 'a': {
opts.all = true;
break;
-
- case 'i':
+ }
+ case 'i': {
opts.ignore_case = true;
break;
-
- case 'n':
+ }
+ case 'n': {
opts.index = true;
break;
-
- case 'v':
+ }
+ case 'v': {
opts.invert_match = true;
break;
-
- case 'q':
+ }
+ case 'q': {
opts.quiet = true;
break;
-
- case 'r':
+ }
+ case 'r': {
regex = true;
break;
-
- case '?':
+ }
+ case '?': {
string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return BUILTIN_STRING_ERROR;
+ }
}
}
int i = w.woptind;
const wchar_t *pattern;
- if ((pattern = string_get_arg_argv(&i, argv)) == 0)
- {
+ if ((pattern = string_get_arg_argv(&i, argv)) == 0) {
string_error(streams, STRING_ERR_MISSING, argv[0]);
return BUILTIN_STRING_ERROR;
}
- if (string_args_from_stdin(streams) && argc > i)
- {
+ if (string_args_from_stdin(streams) && argc > i) {
string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
return BUILTIN_STRING_ERROR;
}
string_matcher_t *matcher;
- if (regex)
- {
+ if (regex) {
matcher = new pcre2_matcher_t(argv[0], pattern, opts, streams);
- }
- else
- {
+ } else {
matcher = new wildcard_matcher_t(argv[0], pattern, opts, streams);
}
const wchar_t *arg;
wcstring storage;
- while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0)
- {
- if (!matcher->report_matches(arg))
- {
+ while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0) {
+ if (!matcher->report_matches(arg)) {
delete matcher;
return BUILTIN_STRING_ERROR;
}
@@ -696,78 +571,67 @@ static int string_match(parser_t &parser, io_streams_t &streams, int argc, wchar
return rc;
}
-struct replace_options_t
-{
+struct replace_options_t {
bool all;
bool ignore_case;
bool quiet;
- replace_options_t(): all(false), ignore_case(false), quiet(false) { }
+ replace_options_t() : all(false), ignore_case(false), quiet(false) {}
};
-class string_replacer_t
-{
-protected:
+class string_replacer_t {
+ protected:
const wchar_t *argv0;
replace_options_t opts;
int total_replaced;
io_streams_t &streams;
-public:
+ public:
string_replacer_t(const wchar_t *argv0_, const replace_options_t &opts_, io_streams_t &streams_)
- : argv0(argv0_), opts(opts_), total_replaced(0), streams(streams_)
- { }
+ : argv0(argv0_), opts(opts_), total_replaced(0), streams(streams_) {}
virtual ~string_replacer_t() {}
virtual bool replace_matches(const wchar_t *arg) = 0;
int replace_count() { return total_replaced; }
};
-class literal_replacer_t: public string_replacer_t
-{
+class literal_replacer_t : public string_replacer_t {
const wchar_t *pattern;
const wchar_t *replacement;
size_t patlen;
-public:
+ public:
literal_replacer_t(const wchar_t *argv0, const wchar_t *pattern_, const wchar_t *replacement_,
- const replace_options_t &opts, io_streams_t &streams)
+ const replace_options_t &opts, io_streams_t &streams)
: string_replacer_t(argv0, opts, streams),
- pattern(pattern_), replacement(replacement_), patlen(wcslen(pattern))
- { }
+ pattern(pattern_),
+ replacement(replacement_),
+ patlen(wcslen(pattern)) {}
- virtual ~literal_replacer_t() { }
+ virtual ~literal_replacer_t() {}
- bool replace_matches(const wchar_t *arg)
- {
+ bool replace_matches(const wchar_t *arg) {
wcstring result;
- if (patlen == 0)
- {
+ if (patlen == 0) {
result = arg;
- }
- else
- {
+ } else {
int replaced = 0;
const wchar_t *cur = arg;
- while (*cur != L'\0')
- {
+ while (*cur != L'\0') {
if ((opts.all || replaced == 0) &&
- (opts.ignore_case ? wcsncasecmp(cur, pattern, patlen) : wcsncmp(cur, pattern, patlen)) == 0)
- {
+ (opts.ignore_case ? wcsncasecmp(cur, pattern, patlen)
+ : wcsncmp(cur, pattern, patlen)) == 0) {
result += replacement;
cur += patlen;
replaced++;
total_replaced++;
- }
- else
- {
+ } else {
result += *cur;
cur++;
}
}
}
- if (!opts.quiet)
- {
+ if (!opts.quiet) {
streams.out.append(result);
streams.out.append(L'\n');
}
@@ -775,23 +639,17 @@ public:
}
};
-class regex_replacer_t: public string_replacer_t
-{
+class regex_replacer_t : public string_replacer_t {
compiled_regex_t regex;
wcstring replacement;
- static wcstring interpret_escapes(const wchar_t *orig)
- {
+ static wcstring interpret_escapes(const wchar_t *orig) {
wcstring result;
- while (*orig != L'\0')
- {
- if (*orig == L'\\')
- {
+ while (*orig != L'\0') {
+ if (*orig == L'\\') {
orig += read_unquoted_escape(orig, &result, true, false);
- }
- else
- {
+ } else {
result += *orig;
orig++;
}
@@ -800,22 +658,17 @@ class regex_replacer_t: public string_replacer_t
return result;
}
-public:
+ public:
regex_replacer_t(const wchar_t *argv0, const wchar_t *pattern, const wchar_t *replacement_,
- const replace_options_t &opts, io_streams_t &streams)
+ const replace_options_t &opts, io_streams_t &streams)
: string_replacer_t(argv0, opts, streams),
regex(argv0, pattern, opts.ignore_case, streams),
- replacement(interpret_escapes(replacement_))
- { }
-
- virtual ~regex_replacer_t() { }
+ replacement(interpret_escapes(replacement_)) {}
- bool replace_matches(const wchar_t *arg)
- {
- // A return value of true means all is well (even if no replacements
- // were performed), false indicates an unrecoverable error.
- if (regex.code == 0)
- {
+ bool replace_matches(const wchar_t *arg) {
+ // A return value of true means all is well (even if no replacements were performed), false
+ // indicates an unrecoverable error.
+ if (regex.code == 0) {
// pcre2_compile() failed
return false;
}
@@ -826,28 +679,19 @@ public:
PCRE2_SIZE bufsize = (arglen == 0) ? 16 : 2 * arglen;
wchar_t *output = (wchar_t *)malloc(sizeof(wchar_t) * bufsize);
int pcre2_rc = 0;
- for (;;)
- {
- if (output == NULL)
- {
+ for (;;) {
+ if (output == NULL) {
DIE_MEM();
}
PCRE2_SIZE outlen = bufsize;
- pcre2_rc = pcre2_substitute(
- regex.code,
- PCRE2_SPTR(arg),
- arglen,
- 0, // start offset
- options,
- regex.match,
- 0, // match context
- PCRE2_SPTR(replacement.c_str()),
- PCRE2_ZERO_TERMINATED,
- (PCRE2_UCHAR *)output,
- &outlen);
-
- if (pcre2_rc == PCRE2_ERROR_NOMEMORY && bufsize < outlen)
- {
+ pcre2_rc = pcre2_substitute(regex.code, PCRE2_SPTR(arg), arglen,
+ 0, // start offset
+ options, regex.match,
+ 0, // match context
+ PCRE2_SPTR(replacement.c_str()), PCRE2_ZERO_TERMINATED,
+ (PCRE2_UCHAR *)output, &outlen);
+
+ if (pcre2_rc == PCRE2_ERROR_NOMEMORY && bufsize < outlen) {
bufsize = outlen;
// cppcheck-suppress memleakOnRealloc
output = (wchar_t *)realloc(output, sizeof(wchar_t) * bufsize);
@@ -857,16 +701,12 @@ public:
}
bool rc = true;
- if (pcre2_rc < 0)
- {
- string_error(streams, _(L"%ls: Regular expression substitute error: %ls\n"),
- argv0, pcre2_strerror(pcre2_rc).c_str());
+ if (pcre2_rc < 0) {
+ string_error(streams, _(L"%ls: Regular expression substitute error: %ls\n"), argv0,
+ pcre2_strerror(pcre2_rc).c_str());
rc = false;
- }
- else
- {
- if (!opts.quiet)
- {
+ } else {
+ if (!opts.quiet) {
streams.out.append(output);
streams.out.append(L'\n');
}
@@ -878,91 +718,77 @@ public:
}
};
-static int string_replace(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv)
-{
+static int string_replace(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
const wchar_t *short_options = L"aiqr";
- const struct woption long_options[] =
- {
- { L"all", no_argument, 0, 'a'},
- { L"ignore-case", no_argument, 0, 'i'},
- { L"quiet", no_argument, 0, 'q'},
- { L"regex", no_argument, 0, 'r'},
- { 0, 0, 0, 0 }
- };
+ const struct woption long_options[] = {{L"all", no_argument, 0, 'a'},
+ {L"ignore-case", no_argument, 0, 'i'},
+ {L"quiet", no_argument, 0, 'q'},
+ {L"regex", no_argument, 0, 'r'},
+ {0, 0, 0, 0}};
replace_options_t opts;
bool regex = false;
wgetopter_t w;
- for (;;)
- {
+ for (;;) {
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 'a':
+ }
+ case 'a': {
opts.all = true;
break;
-
- case 'i':
+ }
+ case 'i': {
opts.ignore_case = true;
break;
-
- case 'q':
+ }
+ case 'q': {
opts.quiet = true;
break;
-
- case 'r':
+ }
+ case 'r': {
regex = true;
break;
-
- case '?':
+ }
+ case '?': {
string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return BUILTIN_STRING_ERROR;
+ }
}
}
int i = w.woptind;
const wchar_t *pattern, *replacement;
- if ((pattern = string_get_arg_argv(&i, argv)) == 0)
- {
+ if ((pattern = string_get_arg_argv(&i, argv)) == 0) {
string_error(streams, STRING_ERR_MISSING, argv[0]);
return BUILTIN_STRING_ERROR;
}
- if ((replacement = string_get_arg_argv(&i, argv)) == 0)
- {
+ if ((replacement = string_get_arg_argv(&i, argv)) == 0) {
string_error(streams, STRING_ERR_MISSING, argv[0]);
return BUILTIN_STRING_ERROR;
}
- if (string_args_from_stdin(streams) && argc > i)
- {
+ if (string_args_from_stdin(streams) && argc > i) {
string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
return BUILTIN_STRING_ERROR;
}
string_replacer_t *replacer;
- if (regex)
- {
+ if (regex) {
replacer = new regex_replacer_t(argv[0], pattern, replacement, opts, streams);
- }
- else
- {
+ } else {
replacer = new literal_replacer_t(argv[0], pattern, replacement, opts, streams);
}
const wchar_t *arg;
wcstring storage;
- while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0)
- {
- if (!replacer->replace_matches(arg))
- {
+ while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0) {
+ if (!replacer->replace_matches(arg)) {
delete replacer;
return BUILTIN_STRING_ERROR;
}
@@ -973,115 +799,94 @@ static int string_replace(parser_t &parser, io_streams_t &streams, int argc, wch
return rc;
}
-// Given iterators into a string (forward or reverse), splits the haystack iterators
-// about the needle sequence, up to max times. Inserts splits into the output array
-// If the iterators are forward, this does the normal thing.
-// If the iterators are backward, this returns reversed strings, in reversed order!
-// If the needle is empty, split on individual elements (characters)
-template<typename ITER>
-void split_about(ITER haystack_start, ITER haystack_end,
- ITER needle_start, ITER needle_end,
- wcstring_list_t *output, long max)
-{
+/// Given iterators into a string (forward or reverse), splits the haystack iterators
+/// about the needle sequence, up to max times. Inserts splits into the output array.
+/// If the iterators are forward, this does the normal thing.
+/// If the iterators are backward, this returns reversed strings, in reversed order!
+/// If the needle is empty, split on individual elements (characters).
+template <typename ITER>
+void split_about(ITER haystack_start, ITER haystack_end, ITER needle_start, ITER needle_end,
+ wcstring_list_t *output, long max) {
long remaining = max;
ITER haystack_cursor = haystack_start;
- while (remaining > 0 && haystack_cursor != haystack_end)
- {
+ while (remaining > 0 && haystack_cursor != haystack_end) {
ITER split_point;
- if (needle_start == needle_end)
- {
- // empty needle, we split on individual elements
+ if (needle_start == needle_end) { // empty needle, we split on individual elements
split_point = haystack_cursor + 1;
- }
- else
- {
+ } else {
split_point = std::search(haystack_cursor, haystack_end, needle_start, needle_end);
}
- if (split_point == haystack_end)
- {
- // not found
+ if (split_point == haystack_end) { // not found
break;
}
output->push_back(wcstring(haystack_cursor, split_point));
remaining--;
- // need to skip over the needle for the next search
- // note that the needle may be empty
+ // Need to skip over the needle for the next search note that the needle may be empty.
haystack_cursor = split_point + std::distance(needle_start, needle_end);
}
- // trailing component, possibly empty
+ // Trailing component, possibly empty.
output->push_back(wcstring(haystack_cursor, haystack_end));
}
-static int string_split(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv)
-{
+static int string_split(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
const wchar_t *short_options = L":m:qr";
- const struct woption long_options[] =
- {
- { L"max", required_argument, 0, 'm'},
- { L"quiet", no_argument, 0, 'q'},
- { L"right", no_argument, 0, 'r'},
- { 0, 0, 0, 0 }
- };
+ const struct woption long_options[] = {{L"max", required_argument, 0, 'm'},
+ {L"quiet", no_argument, 0, 'q'},
+ {L"right", no_argument, 0, 'r'},
+ {0, 0, 0, 0}};
long max = LONG_MAX;
bool quiet = false;
bool right = false;
wgetopter_t w;
- for (;;)
- {
+ for (;;) {
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 'm':
- {
+ }
+ case 'm': {
errno = 0;
wchar_t *endptr = 0;
max = wcstol(w.woptarg, &endptr, 10);
- if (*endptr != L'\0' || errno != 0)
- {
+ if (*endptr != L'\0' || errno != 0) {
string_error(streams, BUILTIN_ERR_NOT_NUMBER, argv[0], w.woptarg);
return BUILTIN_STRING_ERROR;
}
break;
}
-
- case 'q':
+ case 'q': {
quiet = true;
break;
-
- case 'r':
+ }
+ case 'r': {
right = true;
break;
-
- case ':':
+ }
+ case ':': {
string_error(streams, STRING_ERR_MISSING, argv[0]);
return BUILTIN_STRING_ERROR;
-
- case '?':
+ }
+ case '?': {
string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return BUILTIN_STRING_ERROR;
+ }
}
}
int i = w.woptind;
const wchar_t *sep;
- if ((sep = string_get_arg_argv(&i, argv)) == NULL)
- {
+ if ((sep = string_get_arg_argv(&i, argv)) == NULL) {
string_error(streams, STRING_ERR_MISSING, argv[0]);
return BUILTIN_STRING_ERROR;
}
const wchar_t *sep_end = sep + wcslen(sep);
- if (string_args_from_stdin(streams) && argc > i)
- {
+ if (string_args_from_stdin(streams) && argc > i) {
string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
return BUILTIN_STRING_ERROR;
}
@@ -1090,124 +895,104 @@ static int string_split(parser_t &parser, io_streams_t &streams, int argc, wchar
size_t arg_count = 0;
wcstring storage;
const wchar_t *arg;
- while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0)
- {
+ while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0) {
const wchar_t *arg_end = arg + wcslen(arg);
- if (right)
- {
+ if (right) {
typedef std::reverse_iterator<const wchar_t *> reverser;
- split_about(reverser(arg_end), reverser(arg),
- reverser(sep_end), reverser(sep),
- &splits, max);
- }
- else
- {
- split_about(arg, arg_end,
- sep, sep_end,
- &splits, max);
+ split_about(reverser(arg_end), reverser(arg), reverser(sep_end), reverser(sep), &splits,
+ max);
+ } else {
+ split_about(arg, arg_end, sep, sep_end, &splits, max);
}
arg_count++;
}
-
+
// If we are from the right, split_about gave us reversed strings, in reversed order!
- if (right)
- {
- for (size_t j = 0; j < splits.size(); j++)
- {
+ if (right) {
+ for (size_t j = 0; j < splits.size(); j++) {
std::reverse(splits[j].begin(), splits[j].end());
}
std::reverse(splits.begin(), splits.end());
}
-
- if (!quiet)
- {
- for (wcstring_list_t::const_iterator si = splits.begin(); si != splits.end(); ++si)
- {
+
+ if (!quiet) {
+ for (wcstring_list_t::const_iterator si = splits.begin(); si != splits.end(); ++si) {
streams.out.append(*si);
streams.out.append(L'\n');
}
}
- // we split something if we have more split values than args
+ // We split something if we have more split values than args.
return (splits.size() > arg_count) ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
}
-static int string_sub(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv)
-{
+static int string_sub(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
const wchar_t *short_options = L":l:qs:";
- const struct woption long_options[] =
- {
- { L"length", required_argument, 0, 'l'},
- { L"quiet", no_argument, 0, 'q'},
- { L"start", required_argument, 0, 's'},
- { 0, 0, 0, 0 }
- };
+ const struct woption long_options[] = {{L"length", required_argument, 0, 'l'},
+ {L"quiet", no_argument, 0, 'q'},
+ {L"start", required_argument, 0, 's'},
+ {0, 0, 0, 0}};
long start = 0;
long length = -1;
bool quiet = false;
wgetopter_t w;
wchar_t *endptr = NULL;
- for (;;)
- {
+ for (;;) {
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 'l':
+ }
+ case 'l': {
errno = 0;
length = wcstol(w.woptarg, &endptr, 10);
- if (*endptr != L'\0' || (errno != 0 && errno != ERANGE))
- {
+ if (*endptr != L'\0' || (errno != 0 && errno != ERANGE)) {
string_error(streams, BUILTIN_ERR_NOT_NUMBER, argv[0], w.woptarg);
return BUILTIN_STRING_ERROR;
}
- if (length < 0 || errno == ERANGE)
- {
- string_error(streams, _(L"%ls: Invalid length value '%ls'\n"), argv[0], w.woptarg);
+ if (length < 0 || errno == ERANGE) {
+ string_error(streams, _(L"%ls: Invalid length value '%ls'\n"), argv[0],
+ w.woptarg);
return BUILTIN_STRING_ERROR;
}
break;
-
- case 'q':
+ }
+ case 'q': {
quiet = true;
break;
-
- case 's':
+ }
+ case 's': {
errno = 0;
start = wcstol(w.woptarg, &endptr, 10);
- if (*endptr != L'\0' || (errno != 0 && errno != ERANGE))
- {
+ if (*endptr != L'\0' || (errno != 0 && errno != ERANGE)) {
string_error(streams, BUILTIN_ERR_NOT_NUMBER, argv[0], w.woptarg);
return BUILTIN_STRING_ERROR;
}
- if (start == 0 || start == LONG_MIN || errno == ERANGE)
- {
- string_error(streams, _(L"%ls: Invalid start value '%ls'\n"), argv[0], w.woptarg);
+ if (start == 0 || start == LONG_MIN || errno == ERANGE) {
+ string_error(streams, _(L"%ls: Invalid start value '%ls'\n"), argv[0],
+ w.woptarg);
return BUILTIN_STRING_ERROR;
}
break;
-
- case ':':
+ }
+ case ':': {
string_error(streams, STRING_ERR_MISSING, argv[0]);
return BUILTIN_STRING_ERROR;
-
- case '?':
+ }
+ case '?': {
string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return BUILTIN_STRING_ERROR;
+ }
}
}
int i = w.woptind;
- if (string_args_from_stdin(streams) && argc > i)
- {
+ if (string_args_from_stdin(streams) && argc > i) {
string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
return BUILTIN_STRING_ERROR;
}
@@ -1215,35 +1000,28 @@ static int string_sub(parser_t &parser, io_streams_t &streams, int argc, wchar_t
int nsub = 0;
const wchar_t *arg;
wcstring storage;
- while ((arg = string_get_arg(&i, argv, &storage, streams)) != NULL)
- {
+ while ((arg = string_get_arg(&i, argv, &storage, streams)) != NULL) {
typedef wcstring::size_type size_type;
size_type pos = 0;
size_type count = wcstring::npos;
wcstring s(arg);
- if (start > 0)
- {
+ if (start > 0) {
pos = static_cast<size_type>(start - 1);
- }
- else if (start < 0)
- {
- assert(start != LONG_MIN); // checked above
+ } else if (start < 0) {
+ assert(start != LONG_MIN); // checked above
size_type n = static_cast<size_type>(-start);
pos = n > s.length() ? 0 : s.length() - n;
}
- if (pos > s.length())
- {
+ if (pos > s.length()) {
pos = s.length();
}
- if (length >= 0)
- {
+ if (length >= 0) {
count = static_cast<size_type>(length);
}
- // note that std::string permits count to extend past end of string
- if (!quiet)
- {
+ // Note that std::string permits count to extend past end of string.
+ if (!quiet) {
streams.out.append(s.substr(pos, count));
streams.out.append(L'\n');
}
@@ -1253,100 +1031,88 @@ static int string_sub(parser_t &parser, io_streams_t &streams, int argc, wchar_t
return (nsub > 0) ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
}
-static int string_trim(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv)
-{
+static int string_trim(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
const wchar_t *short_options = L":c:lqr";
- const struct woption long_options[] =
- {
- { L"chars", required_argument, 0, 'c'},
- { L"left", no_argument, 0, 'l'},
- { L"quiet", no_argument, 0, 'q'},
- { L"right", no_argument, 0, 'r'},
- { 0, 0, 0, 0 }
- };
+ const struct woption long_options[] = {{L"chars", required_argument, 0, 'c'},
+ {L"left", no_argument, 0, 'l'},
+ {L"quiet", no_argument, 0, 'q'},
+ {L"right", no_argument, 0, 'r'},
+ {0, 0, 0, 0}};
bool do_left = 0, do_right = 0;
bool quiet = false;
wcstring chars_to_trim = L" \f\n\r\t";
wgetopter_t w;
- for (;;)
- {
+ for (;;) {
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 'c':
+ }
+ case 'c': {
chars_to_trim = w.woptarg;
break;
-
- case 'l':
+ }
+ case 'l': {
do_left = true;
break;
-
- case 'q':
+ }
+ case 'q': {
quiet = true;
break;
-
- case 'r':
+ }
+ case 'r': {
do_right = true;
break;
-
- case ':':
+ }
+ case ':': {
string_error(streams, STRING_ERR_MISSING, argv[0]);
return BUILTIN_STRING_ERROR;
-
- case '?':
+ }
+ case '?': {
string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return BUILTIN_STRING_ERROR;
+ }
}
}
int i = w.woptind;
- if (string_args_from_stdin(streams) && argc > i)
- {
+ if (string_args_from_stdin(streams) && argc > i) {
string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
return BUILTIN_STRING_ERROR;
}
- /* if neither left or right is specified, we do both */
- if (! do_left && ! do_right)
- {
+ // If neither left or right is specified, we do both.
+ if (!do_left && !do_right) {
do_left = true;
do_right = true;
}
const wchar_t *arg;
size_t ntrim = 0;
-
+
wcstring argstr;
wcstring storage;
- while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0)
- {
+ while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0) {
argstr = arg;
- // begin and end are respectively the first character to keep on the left,
- // and first character to trim on the right. The length is thus end - start.
+ // Begin and end are respectively the first character to keep on the left, and first
+ // character to trim on the right. The length is thus end - start.
size_t begin = 0, end = argstr.size();
- if (do_right)
- {
+ if (do_right) {
size_t last_to_keep = argstr.find_last_not_of(chars_to_trim);
end = (last_to_keep == wcstring::npos) ? 0 : last_to_keep + 1;
}
- if (do_left)
- {
+ if (do_left) {
size_t first_to_keep = argstr.find_first_not_of(chars_to_trim);
begin = (first_to_keep == wcstring::npos ? end : first_to_keep);
}
assert(begin <= end && end <= argstr.size());
ntrim += argstr.size() - (end - begin);
- if (!quiet)
- {
+ if (!quiet) {
streams.out.append(wcstring(argstr, begin, end - begin));
streams.out.append(L'\n');
}
@@ -1355,51 +1121,35 @@ static int string_trim(parser_t &parser, io_streams_t &streams, int argc, wchar_
return (ntrim > 0) ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
}
-static const struct string_subcommand
-{
+static const struct string_subcommand {
const wchar_t *name;
int (*handler)(parser_t &, io_streams_t &, int argc, wchar_t **argv);
}
-string_subcommands[] =
-{
- { L"escape", &string_escape },
- { L"join", &string_join },
- { L"length", &string_length },
- { L"match", &string_match },
- { L"replace", &string_replace },
- { L"split", &string_split },
- { L"sub", &string_sub },
- { L"trim", &string_trim },
- { 0, 0 }
-};
+string_subcommands[] = {
+ {L"escape", &string_escape}, {L"join", &string_join}, {L"length", &string_length},
+ {L"match", &string_match}, {L"replace", &string_replace}, {L"split", &string_split},
+ {L"sub", &string_sub}, {L"trim", &string_trim}, {0, 0}};
-/**
- The string builtin, for manipulating strings.
-*/
-int builtin_string(parser_t &parser, io_streams_t &streams, wchar_t **argv)
-{
+/// The string builtin, for manipulating strings.
+int builtin_string(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
int argc = builtin_count_args(argv);
- if (argc <= 1)
- {
+ if (argc <= 1) {
streams.err.append_format(_(L"string: Expected subcommand\n"));
builtin_print_help(parser, streams, L"string", streams.err);
return BUILTIN_STRING_ERROR;
}
- if (wcscmp(argv[1], L"-h") == 0 || wcscmp(argv[1], L"--help") == 0)
- {
+ if (wcscmp(argv[1], L"-h") == 0 || wcscmp(argv[1], L"--help") == 0) {
builtin_print_help(parser, streams, L"string", streams.err);
return BUILTIN_STRING_OK;
}
const string_subcommand *subcmd = &string_subcommands[0];
- while (subcmd->name != 0 && wcscmp(subcmd->name, argv[1]) != 0)
- {
+ while (subcmd->name != 0 && wcscmp(subcmd->name, argv[1]) != 0) {
subcmd++;
}
- if (subcmd->handler == 0)
- {
+ if (subcmd->handler == 0) {
streams.err.append_format(_(L"string: Unknown subcommand '%ls'\n"), argv[1]);
builtin_print_help(parser, streams, L"string", streams.err);
return BUILTIN_STRING_ERROR;
diff --git a/src/builtin_string.h b/src/builtin_string.h
new file mode 100644
index 00000000..49247d9c
--- /dev/null
+++ b/src/builtin_string.h
@@ -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
diff --git a/src/builtin_test.cpp b/src/builtin_test.cpp
index 9c66238d..16d0209a 100644
--- a/src/builtin_test.cpp
+++ b/src/builtin_test.cpp
@@ -1,70 +1,60 @@
-/** \file builtin_test.cpp Functions defining the test builtin
-
-Functions used for implementing the test builtin.
-Implemented from scratch (yes, really) by way of IEEE 1003.1 as reference.
-
-*/
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <memory>
+// Functions used for implementing the test builtin.
+//
+// Implemented from scratch (yes, really) by way of IEEE 1003.1 as reference.
#include <assert.h>
#include <stdarg.h>
+#include <stdbool.h>
#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
#include <wchar.h>
+#include <memory>
#include <string>
-#include <stdbool.h>
-#include "common.h"
#include "builtin.h"
-#include "wutil.h" // IWYU pragma: keep
-#include "proc.h"
+#include "common.h"
#include "io.h"
+#include "proc.h"
+#include "wutil.h" // IWYU pragma: keep
-enum
-{
- BUILTIN_TEST_SUCCESS = STATUS_BUILTIN_OK,
- BUILTIN_TEST_FAIL = STATUS_BUILTIN_ERROR
-};
-
+enum { BUILTIN_TEST_SUCCESS = STATUS_BUILTIN_OK, BUILTIN_TEST_FAIL = STATUS_BUILTIN_ERROR };
int builtin_test(parser_t &parser, io_streams_t &streams, wchar_t **argv);
-namespace test_expressions
-{
+namespace test_expressions {
-enum token_t
-{
- test_unknown, // arbitrary string
+enum token_t {
+ test_unknown, // arbitrary string
- test_bang, // "!", inverts sense
+ test_bang, // "!", inverts sense
- test_filetype_b, // "-b", for block special files
- test_filetype_c, // "-c", for character special files
- test_filetype_d, // "-d", for directories
- test_filetype_e, // "-e", for files that exist
- test_filetype_f, // "-f", for for regular files
- test_filetype_G, // "-G", for check effective group id
- test_filetype_g, // "-g", for set-group-id
- test_filetype_h, // "-h", for symbolic links
- test_filetype_L, // "-L", same as -h
- test_filetype_O, // "-O", for check effective user id
- test_filetype_p, // "-p", for FIFO
- test_filetype_S, // "-S", socket
+ test_filetype_b, // "-b", for block special files
+ test_filetype_c, // "-c", for character special files
+ test_filetype_d, // "-d", for directories
+ test_filetype_e, // "-e", for files that exist
+ test_filetype_f, // "-f", for for regular files
+ test_filetype_G, // "-G", for check effective group id
+ test_filetype_g, // "-g", for set-group-id
+ test_filetype_h, // "-h", for symbolic links
+ test_filetype_L, // "-L", same as -h
+ test_filetype_O, // "-O", for check effective user id
+ test_filetype_p, // "-p", for FIFO
+ test_filetype_S, // "-S", socket
- test_filesize_s, // "-s", size greater than zero
+ test_filesize_s, // "-s", size greater than zero
- test_filedesc_t, // "-t", whether the fd is associated with a terminal
+ test_filedesc_t, // "-t", whether the fd is associated with a terminal
- test_fileperm_r, // "-r", read permission
- test_fileperm_u, // "-u", whether file is setuid
- test_fileperm_w, // "-w", whether file write permission is allowed
- test_fileperm_x, // "-x", whether file execute/search is allowed
+ test_fileperm_r, // "-r", read permission
+ test_fileperm_u, // "-u", whether file is setuid
+ test_fileperm_w, // "-w", whether file write permission is allowed
+ test_fileperm_x, // "-x", whether file execute/search is allowed
- test_string_n, // "-n", non-empty string
- test_string_z, // "-z", true if length of string is 0
- test_string_equal, // "=", true if strings are identical
- test_string_not_equal, // "!=", true if strings are not identical
+ test_string_n, // "-n", non-empty string
+ test_string_z, // "-z", true if length of string is 0
+ test_string_equal, // "=", true if strings are identical
+ test_string_not_equal, // "!=", true if strings are not identical
test_number_equal, // "-eq", true if numbers are equal
test_number_not_equal, // "-ne", true if numbers are not equal
@@ -73,113 +63,95 @@ enum token_t
test_number_lesser, // "-lt", true if first number is smaller than second
test_number_lesser_equal, // "-le", true if first number is at most second
- test_combine_and, // "-a", true if left and right are both true
- test_combine_or, // "-o", true if either left or right is true
+ test_combine_and, // "-a", true if left and right are both true
+ test_combine_or, // "-o", true if either left or right is true
- test_paren_open, // "(", open paren
- test_paren_close, // ")", close paren
+ test_paren_open, // "(", open paren
+ test_paren_close, // ")", close paren
};
-static bool binary_primary_evaluate(test_expressions::token_t token, const wcstring &left, const wcstring &right, wcstring_list_t &errors);
-static bool unary_primary_evaluate(test_expressions::token_t token, const wcstring &arg, wcstring_list_t &errors);
-
+static bool binary_primary_evaluate(test_expressions::token_t token, const wcstring &left,
+ const wcstring &right, wcstring_list_t &errors);
+static bool unary_primary_evaluate(test_expressions::token_t token, const wcstring &arg,
+ wcstring_list_t &errors);
-enum
-{
- UNARY_PRIMARY = 1 << 0,
- BINARY_PRIMARY = 1 << 1
-};
+enum { UNARY_PRIMARY = 1 << 0, BINARY_PRIMARY = 1 << 1 };
-static const struct token_info_t
-{
+static const struct token_info_t {
token_t tok;
const wchar_t *string;
unsigned int flags;
-} token_infos[] =
-{
- {test_unknown, L"", 0},
- {test_bang, L"!", 0},
- {test_filetype_b, L"-b", UNARY_PRIMARY},
- {test_filetype_c, L"-c", UNARY_PRIMARY},
- {test_filetype_d, L"-d", UNARY_PRIMARY},
- {test_filetype_e, L"-e", UNARY_PRIMARY},
- {test_filetype_f, L"-f", UNARY_PRIMARY},
- {test_filetype_G, L"-G", UNARY_PRIMARY},
- {test_filetype_g, L"-g", UNARY_PRIMARY},
- {test_filetype_h, L"-h", UNARY_PRIMARY},
- {test_filetype_L, L"-L", UNARY_PRIMARY},
- {test_filetype_O, L"-O", UNARY_PRIMARY},
- {test_filetype_p, L"-p", UNARY_PRIMARY},
- {test_filetype_S, L"-S", UNARY_PRIMARY},
- {test_filesize_s, L"-s", UNARY_PRIMARY},
- {test_filedesc_t, L"-t", UNARY_PRIMARY},
- {test_fileperm_r, L"-r", UNARY_PRIMARY},
- {test_fileperm_u, L"-u", UNARY_PRIMARY},
- {test_fileperm_w, L"-w", UNARY_PRIMARY},
- {test_fileperm_x, L"-x", UNARY_PRIMARY},
- {test_string_n, L"-n", UNARY_PRIMARY},
- {test_string_z, L"-z", UNARY_PRIMARY},
- {test_string_equal, L"=", BINARY_PRIMARY},
- {test_string_not_equal, L"!=", BINARY_PRIMARY},
- {test_number_equal, L"-eq", BINARY_PRIMARY},
- {test_number_not_equal, L"-ne", BINARY_PRIMARY},
- {test_number_greater, L"-gt", BINARY_PRIMARY},
- {test_number_greater_equal, L"-ge", BINARY_PRIMARY},
- {test_number_lesser, L"-lt", BINARY_PRIMARY},
- {test_number_lesser_equal, L"-le", BINARY_PRIMARY},
- {test_combine_and, L"-a", 0},
- {test_combine_or, L"-o", 0},
- {test_paren_open, L"(", 0},
- {test_paren_close, L")", 0}
-};
-
-const token_info_t *token_for_string(const wcstring &str)
-{
- for (size_t i=0; i < sizeof token_infos / sizeof *token_infos; i++)
- {
- if (str == token_infos[i].string)
- {
+} token_infos[] = {{test_unknown, L"", 0},
+ {test_bang, L"!", 0},
+ {test_filetype_b, L"-b", UNARY_PRIMARY},
+ {test_filetype_c, L"-c", UNARY_PRIMARY},
+ {test_filetype_d, L"-d", UNARY_PRIMARY},
+ {test_filetype_e, L"-e", UNARY_PRIMARY},
+ {test_filetype_f, L"-f", UNARY_PRIMARY},
+ {test_filetype_G, L"-G", UNARY_PRIMARY},
+ {test_filetype_g, L"-g", UNARY_PRIMARY},
+ {test_filetype_h, L"-h", UNARY_PRIMARY},
+ {test_filetype_L, L"-L", UNARY_PRIMARY},
+ {test_filetype_O, L"-O", UNARY_PRIMARY},
+ {test_filetype_p, L"-p", UNARY_PRIMARY},
+ {test_filetype_S, L"-S", UNARY_PRIMARY},
+ {test_filesize_s, L"-s", UNARY_PRIMARY},
+ {test_filedesc_t, L"-t", UNARY_PRIMARY},
+ {test_fileperm_r, L"-r", UNARY_PRIMARY},
+ {test_fileperm_u, L"-u", UNARY_PRIMARY},
+ {test_fileperm_w, L"-w", UNARY_PRIMARY},
+ {test_fileperm_x, L"-x", UNARY_PRIMARY},
+ {test_string_n, L"-n", UNARY_PRIMARY},
+ {test_string_z, L"-z", UNARY_PRIMARY},
+ {test_string_equal, L"=", BINARY_PRIMARY},
+ {test_string_not_equal, L"!=", BINARY_PRIMARY},
+ {test_number_equal, L"-eq", BINARY_PRIMARY},
+ {test_number_not_equal, L"-ne", BINARY_PRIMARY},
+ {test_number_greater, L"-gt", BINARY_PRIMARY},
+ {test_number_greater_equal, L"-ge", BINARY_PRIMARY},
+ {test_number_lesser, L"-lt", BINARY_PRIMARY},
+ {test_number_lesser_equal, L"-le", BINARY_PRIMARY},
+ {test_combine_and, L"-a", 0},
+ {test_combine_or, L"-o", 0},
+ {test_paren_open, L"(", 0},
+ {test_paren_close, L")", 0}};
+
+const token_info_t *token_for_string(const wcstring &str) {
+ for (size_t i = 0; i < sizeof token_infos / sizeof *token_infos; i++) {
+ if (str == token_infos[i].string) {
return &token_infos[i];
}
}
- return &token_infos[0]; //unknown
+ return &token_infos[0]; // unknown
}
-
-/* Grammar.
-
- <expr> = <combining_expr>
-
- <combining_expr> = <unary_expr> and/or <combining_expr> |
- <unary_expr>
-
- <unary_expr> = bang <unary_expr> |
- <primary>
-
- <primary> = <unary_primary> arg |
- arg <binary_primary> arg |
- '(' <expr> ')'
-
-*/
+// Grammar.
+//
+// <expr> = <combining_expr>
+//
+// <combining_expr> = <unary_expr> and/or <combining_expr> |
+// <unary_expr>
+//
+// <unary_expr> = bang <unary_expr> |
+// <primary>
+//
+// <primary> = <unary_primary> arg |
+// arg <binary_primary> arg |
+// '(' <expr> ')'
class expression;
-class test_parser
-{
-private:
+class test_parser {
+ private:
wcstring_list_t strings;
wcstring_list_t errors;
expression *error(const wchar_t *fmt, ...);
void add_error(const wchar_t *fmt, ...);
- const wcstring &arg(unsigned int idx)
- {
- return strings.at(idx);
- }
+ const wcstring &arg(unsigned int idx) { return strings.at(idx); }
-public:
- explicit test_parser(const wcstring_list_t &val) : strings(val)
- { }
+ public:
+ explicit test_parser(const wcstring_list_t &val) : strings(val) {}
expression *parse_expression(unsigned int start, unsigned int end);
expression *parse_3_arg_expression(unsigned int start, unsigned int end);
@@ -196,81 +168,76 @@ public:
static expression *parse_args(const wcstring_list_t &args, wcstring &err);
};
-struct range_t
-{
+struct range_t {
unsigned int start;
unsigned int end;
- range_t(unsigned s, unsigned e) : start(s), end(e) { }
+ range_t(unsigned s, unsigned e) : start(s), end(e) {}
};
+/// Base class for expressions.
+class expression {
+ protected:
+ expression(token_t what, range_t where) : token(what), range(where) {}
-/* Base class for expressions */
-class expression
-{
-protected:
- expression(token_t what, range_t where) : token(what), range(where) { }
-
-public:
+ public:
const token_t token;
range_t range;
- virtual ~expression() { }
+ virtual ~expression() {}
- // evaluate returns true if the expression is true (i.e. BUILTIN_TEST_SUCCESS)
+ /// Evaluate returns true if the expression is true (i.e. BUILTIN_TEST_SUCCESS).
virtual bool evaluate(wcstring_list_t &errors) = 0;
};
typedef std::auto_ptr<expression> expr_ref_t;
-/* Single argument like -n foo or "just a string" */
-class unary_primary : public expression
-{
-public:
+/// Single argument like -n foo or "just a string".
+class unary_primary : public expression {
+ public:
wcstring arg;
- unary_primary(token_t tok, range_t where, const wcstring &what) : expression(tok, where), arg(what) { }
+ unary_primary(token_t tok, range_t where, const wcstring &what)
+ : expression(tok, where), arg(what) {}
bool evaluate(wcstring_list_t &errors);
};
-/* Two argument primary like foo != bar */
-class binary_primary : public expression
-{
-public:
+/// Two argument primary like foo != bar.
+class binary_primary : public expression {
+ public:
wcstring arg_left;
wcstring arg_right;
- binary_primary(token_t tok, range_t where, const wcstring &left, const wcstring &right) : expression(tok, where), arg_left(left), arg_right(right)
- { }
+ binary_primary(token_t tok, range_t where, const wcstring &left, const wcstring &right)
+ : expression(tok, where), arg_left(left), arg_right(right) {}
bool evaluate(wcstring_list_t &errors);
};
-/* Unary operator like bang */
-class unary_operator : public expression
-{
-public:
+/// Unary operator like bang.
+class unary_operator : public expression {
+ public:
expr_ref_t subject;
- unary_operator(token_t tok, range_t where, expr_ref_t &exp) : expression(tok, where), subject(exp) { }
+ unary_operator(token_t tok, range_t where, expr_ref_t &exp)
+ : expression(tok, where), subject(exp) {}
bool evaluate(wcstring_list_t &errors);
};
-/* Combining expression. Contains a list of AND or OR expressions. It takes more than two so that we don't have to worry about precedence in the parser. */
-class combining_expression : public expression
-{
-public:
+/// Combining expression. Contains a list of AND or OR expressions. It takes more than two so that
+/// we don't have to worry about precedence in the parser.
+class combining_expression : public expression {
+ public:
const std::vector<expression *> subjects;
const std::vector<token_t> combiners;
- combining_expression(token_t tok, range_t where, const std::vector<expression *> &exprs, const std::vector<token_t> &combs) : expression(tok, where), subjects(exprs), combiners(combs)
- {
- /* We should have one more subject than combiner */
+ combining_expression(token_t tok, range_t where, const std::vector<expression *> &exprs,
+ const std::vector<token_t> &combs)
+ : expression(tok, where), subjects(exprs), combiners(combs) {
+ // We should have one more subject than combiner.
assert(subjects.size() == combiners.size() + 1);
}
- /* We are responsible for destroying our expressions */
- virtual ~combining_expression()
- {
- for (size_t i=0; i < subjects.size(); i++)
- {
+ // We are responsible for destroying our expressions.
+ virtual ~combining_expression() {
+ for (size_t i = 0; i < subjects.size(); i++) {
delete subjects[i];
}
}
@@ -278,18 +245,17 @@ public:
bool evaluate(wcstring_list_t &errors);
};
-/* Parenthetical expression */
-class parenthetical_expression : public expression
-{
-public:
+/// Parenthetical expression.
+class parenthetical_expression : public expression {
+ public:
expr_ref_t contents;
- parenthetical_expression(token_t tok, range_t where, expr_ref_t &expr) : expression(tok, where), contents(expr) { }
+ parenthetical_expression(token_t tok, range_t where, expr_ref_t &expr)
+ : expression(tok, where), contents(expr) {}
virtual bool evaluate(wcstring_list_t &errors);
};
-void test_parser::add_error(const wchar_t *fmt, ...)
-{
+void test_parser::add_error(const wchar_t *fmt, ...) {
assert(fmt != NULL);
va_list va;
va_start(va, fmt);
@@ -297,8 +263,7 @@ void test_parser::add_error(const wchar_t *fmt, ...)
va_end(va);
}
-expression *test_parser::error(const wchar_t *fmt, ...)
-{
+expression *test_parser::error(const wchar_t *fmt, ...) {
assert(fmt != NULL);
va_list va;
va_start(va, fmt);
@@ -307,170 +272,140 @@ expression *test_parser::error(const wchar_t *fmt, ...)
return NULL;
}
-expression *test_parser::parse_unary_expression(unsigned int start, unsigned int end)
-{
- if (start >= end)
- {
+expression *test_parser::parse_unary_expression(unsigned int start, unsigned int end) {
+ if (start >= end) {
return error(L"Missing argument at index %u", start);
}
token_t tok = token_for_string(arg(start))->tok;
- if (tok == test_bang)
- {
+ if (tok == test_bang) {
expr_ref_t subject(parse_unary_expression(start + 1, end));
- if (subject.get())
- {
+ if (subject.get()) {
return new unary_operator(tok, range_t(start, subject->range.end), subject);
- }
- else
- {
+ } else {
return NULL;
}
- }
- else
- {
+ } else {
return parse_primary(start, end);
}
}
-/* Parse a combining expression (AND, OR) */
-expression *test_parser::parse_combining_expression(unsigned int start, unsigned int end)
-{
- if (start >= end)
- return NULL;
+/// Parse a combining expression (AND, OR).
+expression *test_parser::parse_combining_expression(unsigned int start, unsigned int end) {
+ if (start >= end) return NULL;
std::vector<expression *> subjects;
std::vector<token_t> combiners;
unsigned int idx = start;
bool first = true;
- while (idx < end)
- {
-
- if (! first)
- {
- /* This is not the first expression, so we expect a combiner. */
+ while (idx < end) {
+ if (!first) {
+ // This is not the first expression, so we expect a combiner.
token_t combiner = token_for_string(arg(idx))->tok;
- if (combiner != test_combine_and && combiner != test_combine_or)
- {
+ if (combiner != test_combine_and && combiner != test_combine_or) {
/* Not a combiner, we're done */
- this->errors.insert(this->errors.begin(), format_string(L"Expected a combining operator like '-a' at index %u", idx));
+ this->errors.insert(
+ this->errors.begin(),
+ format_string(L"Expected a combining operator like '-a' at index %u", idx));
break;
}
combiners.push_back(combiner);
idx++;
}
- /* Parse another expression */
+ // Parse another expression.
expression *expr = parse_unary_expression(idx, end);
- if (! expr)
- {
+ if (!expr) {
add_error(L"Missing argument at index %u", idx);
- if (! first)
- {
- /* Clean up the dangling combiner, since it never got its right hand expression */
+ if (!first) {
+ // Clean up the dangling combiner, since it never got its right hand expression.
combiners.pop_back();
}
break;
}
- /* Go to the end of this expression */
+ // Go to the end of this expression.
idx = expr->range.end;
subjects.push_back(expr);
first = false;
}
- if (! subjects.empty())
- {
- /* Our new expression takes ownership of all expressions we created. The token we pass is irrelevant. */
+ if (!subjects.empty()) {
+ // Our new expression takes ownership of all expressions we created. The token we pass is
+ // irrelevant.
return new combining_expression(test_combine_and, range_t(start, idx), subjects, combiners);
- }
- else
- {
- /* No subjects */
+ } else {
+ // No subjects.
return NULL;
}
}
-expression *test_parser::parse_unary_primary(unsigned int start, unsigned int end)
-{
- /* We need two arguments */
- if (start >= end)
- {
+expression *test_parser::parse_unary_primary(unsigned int start, unsigned int end) {
+ // We need two arguments.
+ if (start >= end) {
return error(L"Missing argument at index %u", start);
}
- if (start + 1 >= end)
- {
+ if (start + 1 >= end) {
return error(L"Missing argument at index %u", start + 1);
}
- /* All our unary primaries are prefix, so the operator is at start. */
+ // All our unary primaries are prefix, so the operator is at start.
const token_info_t *info = token_for_string(arg(start));
- if (!(info->flags & UNARY_PRIMARY))
- return NULL;
+ if (!(info->flags & UNARY_PRIMARY)) return NULL;
return new unary_primary(info->tok, range_t(start, start + 2), arg(start + 1));
}
-expression *test_parser::parse_just_a_string(unsigned int start, unsigned int end)
-{
- /* Handle a string as a unary primary that is not a token of any other type.
- e.g. 'test foo -a bar' should evaluate to true
- We handle this with a unary primary of test_string_n
- */
-
- /* We need one arguments */
- if (start >= end)
- {
+expression *test_parser::parse_just_a_string(unsigned int start, unsigned int end) {
+ // Handle a string as a unary primary that is not a token of any other type. e.g. 'test foo -a
+ // bar' should evaluate to true We handle this with a unary primary of test_string_n.
+
+ // We need one argument.
+ if (start >= end) {
return error(L"Missing argument at index %u", start);
}
const token_info_t *info = token_for_string(arg(start));
- if (info->tok != test_unknown)
- {
+ if (info->tok != test_unknown) {
return error(L"Unexpected argument type at index %u", start);
}
- /* This is hackish; a nicer way to implement this would be with a "just a string" expression type */
+ // This is hackish; a nicer way to implement this would be with a "just a string" expression
+ // type.
return new unary_primary(test_string_n, range_t(start, start + 1), arg(start));
}
#if 0
expression *test_parser::parse_unary_primary(unsigned int start, unsigned int end)
{
- /* We need either one or two arguments */
- if (start >= end)
- {
+ // We need either one or two arguments.
+ if (start >= end) {
return error(L"Missing argument at index %u", start);
}
- /* The index of the argument to the unary primary */
+ // The index of the argument to the unary primary.
unsigned int arg_idx;
- /* All our unary primaries are prefix, so any operator is at start. But it also may just be a string, with no operator. */
+ // All our unary primaries are prefix, so any operator is at start. But it also may just be a
+ // string, with no operator.
const token_info_t *info = token_for_string(arg(start));
- if (info->flags & UNARY_PRIMARY)
- {
+ if (info->flags & UNARY_PRIMARY) {
/* We have an operator. Skip the operator argument */
arg_idx = start + 1;
- /* We have some freedom here...do we allow other tokens for the argument to operate on?
- For example, should 'test -n =' work? I say yes. So no typechecking on the next token. */
-
- }
- else if (info->tok == test_unknown)
- {
- /* "Just a string. */
+ // We have some freedom here...do we allow other tokens for the argument to operate on? For
+ // example, should 'test -n =' work? I say yes. So no typechecking on the next token.
+ } else if (info->tok == test_unknown) {
+ // "Just a string.
arg_idx = start;
- }
- else
- {
- /* Here we don't allow arbitrary tokens as "just a string." I.e. 'test = -a =' should have a parse error. We could relax this at some point. */
+ } else {
+ // Here we don't allow arbitrary tokens as "just a string." I.e. 'test = -a =' should have a
+ // parse error. We could relax this at some point.
return error(L"Parse error at argument index %u", start);
}
- /* Verify we have the argument we want, i.e. test -n should fail to parse */
- if (arg_idx >= end)
- {
+ // Verify we have the argument we want, i.e. test -n should fail to parse.
+ if (arg_idx >= end) {
return error(L"Missing argument at index %u", arg_idx);
}
@@ -478,199 +413,157 @@ expression *test_parser::parse_unary_primary(unsigned int start, unsigned int en
}
#endif
-expression *test_parser::parse_binary_primary(unsigned int start, unsigned int end)
-{
- /* We need three arguments */
- for (unsigned int idx = start; idx < start + 3; idx++)
- {
- if (idx >= end)
- {
+expression *test_parser::parse_binary_primary(unsigned int start, unsigned int end) {
+ // We need three arguments.
+ for (unsigned int idx = start; idx < start + 3; idx++) {
+ if (idx >= end) {
return error(L"Missing argument at index %u", idx);
}
}
- /* All our binary primaries are infix, so the operator is at start + 1. */
+ // All our binary primaries are infix, so the operator is at start + 1.
const token_info_t *info = token_for_string(arg(start + 1));
- if (!(info->flags & BINARY_PRIMARY))
- return NULL;
+ if (!(info->flags & BINARY_PRIMARY)) return NULL;
return new binary_primary(info->tok, range_t(start, start + 3), arg(start), arg(start + 2));
}
-expression *test_parser::parse_parenthentical(unsigned int start, unsigned int end)
-{
- /* We need at least three arguments: open paren, argument, close paren */
- if (start + 3 >= end)
- return NULL;
+expression *test_parser::parse_parenthentical(unsigned int start, unsigned int end) {
+ // We need at least three arguments: open paren, argument, close paren.
+ if (start + 3 >= end) return NULL;
- /* Must start with an open expression */
+ // Must start with an open expression.
const token_info_t *open_paren = token_for_string(arg(start));
- if (open_paren->tok != test_paren_open)
- return NULL;
+ if (open_paren->tok != test_paren_open) return NULL;
- /* Parse a subexpression */
+ // Parse a subexpression.
expression *subexr_ptr = parse_expression(start + 1, end);
- if (! subexr_ptr)
- return NULL;
+ if (!subexr_ptr) return NULL;
expr_ref_t subexpr(subexr_ptr);
- /* Parse a close paren */
+ // Parse a close paren.
unsigned close_index = subexpr->range.end;
assert(close_index <= end);
- if (close_index == end)
- {
+ if (close_index == end) {
return error(L"Missing close paren at index %u", close_index);
}
const token_info_t *close_paren = token_for_string(arg(close_index));
- if (close_paren->tok != test_paren_close)
- {
+ if (close_paren->tok != test_paren_close) {
return error(L"Expected close paren at index %u", close_index);
}
- /* Success */
- return new parenthetical_expression(test_paren_open, range_t(start, close_index+1), subexpr);
+ // Success.
+ return new parenthetical_expression(test_paren_open, range_t(start, close_index + 1), subexpr);
}
-expression *test_parser::parse_primary(unsigned int start, unsigned int end)
-{
- if (start >= end)
- {
+expression *test_parser::parse_primary(unsigned int start, unsigned int end) {
+ if (start >= end) {
return error(L"Missing argument at index %u", start);
}
expression *expr = NULL;
- if (! expr) expr = parse_parenthentical(start, end);
- if (! expr) expr = parse_unary_primary(start, end);
- if (! expr) expr = parse_binary_primary(start, end);
- if (! expr) expr = parse_just_a_string(start, end);
+ if (!expr) expr = parse_parenthentical(start, end);
+ if (!expr) expr = parse_unary_primary(start, end);
+ if (!expr) expr = parse_binary_primary(start, end);
+ if (!expr) expr = parse_just_a_string(start, end);
return expr;
}
-// See IEEE 1003.1 breakdown of the behavior for different parameter counts
-expression *test_parser::parse_3_arg_expression(unsigned int start, unsigned int end)
-{
+// See IEEE 1003.1 breakdown of the behavior for different parameter counts.
+expression *test_parser::parse_3_arg_expression(unsigned int start, unsigned int end) {
assert(end - start == 3);
expression *result = NULL;
const token_info_t *center_token = token_for_string(arg(start + 1));
- if (center_token->flags & BINARY_PRIMARY)
- {
+ if (center_token->flags & BINARY_PRIMARY) {
result = parse_binary_primary(start, end);
- }
- else if (center_token->tok == test_combine_and || center_token->tok == test_combine_or)
- {
+ } else if (center_token->tok == test_combine_and || center_token->tok == test_combine_or) {
expr_ref_t left(parse_unary_expression(start, start + 1));
expr_ref_t right(parse_unary_expression(start + 2, start + 3));
- if (left.get() && right.get())
- {
- // Transfer ownership to the vector of subjects
+ if (left.get() && right.get()) {
+ // Transfer ownership to the vector of subjects.
std::vector<token_t> combiners(1, center_token->tok);
std::vector<expression *> subjects;
subjects.push_back(left.release());
subjects.push_back(right.release());
- result = new combining_expression(center_token->tok, range_t(start, end), subjects, combiners);
+ result = new combining_expression(center_token->tok, range_t(start, end), subjects,
+ combiners);
}
- }
- else
- {
+ } else {
result = parse_unary_expression(start, end);
}
return result;
}
-expression *test_parser::parse_4_arg_expression(unsigned int start, unsigned int end)
-{
+expression *test_parser::parse_4_arg_expression(unsigned int start, unsigned int end) {
assert(end - start == 4);
expression *result = NULL;
token_t first_token = token_for_string(arg(start))->tok;
- if (first_token == test_bang)
- {
+ if (first_token == test_bang) {
expr_ref_t subject(parse_3_arg_expression(start + 1, end));
- if (subject.get())
- {
+ if (subject.get()) {
result = new unary_operator(first_token, range_t(start, subject->range.end), subject);
}
- }
- else if (first_token == test_paren_open)
- {
+ } else if (first_token == test_paren_open) {
result = parse_parenthentical(start, end);
- }
- else
- {
+ } else {
result = parse_combining_expression(start, end);
}
return result;
}
-
-expression *test_parser::parse_expression(unsigned int start, unsigned int end)
-{
- if (start >= end)
- {
+expression *test_parser::parse_expression(unsigned int start, unsigned int end) {
+ if (start >= end) {
return error(L"Missing argument at index %u", start);
}
unsigned int argc = end - start;
- switch (argc)
- {
- case 0:
- assert(0); //should have been caught by the above test
+ switch (argc) {
+ case 0: {
+ assert(0); // should have been caught by the above test
return NULL;
-
- case 1:
- {
+ }
+ case 1: {
return error(L"Missing argument at index %u", start + 1);
}
- case 2:
- {
+ case 2: {
return parse_unary_expression(start, end);
}
-
- case 3:
- {
+ case 3: {
return parse_3_arg_expression(start, end);
}
-
- case 4:
- {
+ case 4: {
return parse_4_arg_expression(start, end);
}
-
- default:
- {
- return parse_combining_expression(start, end);
- }
+ default: { return parse_combining_expression(start, end); }
}
}
-expression *test_parser::parse_args(const wcstring_list_t &args, wcstring &err)
-{
- /* Empty list and one-arg list should be handled by caller */
+expression *test_parser::parse_args(const wcstring_list_t &args, wcstring &err) {
+ // Empty list and one-arg list should be handled by caller.
assert(args.size() > 1);
test_parser parser(args);
expression *result = parser.parse_expression(0, (unsigned int)args.size());
- /* Handle errors */
- for (size_t i = 0; i < parser.errors.size(); i++)
- {
+ // Handle errors.
+ for (size_t i = 0; i < parser.errors.size(); i++) {
err.append(L"test: ");
err.append(parser.errors.at(i));
err.push_back(L'\n');
- // For now we only show the first error
+ // For now we only show the first error.
break;
}
- if (result)
- {
- /* It's also an error if there are any unused arguments. This is not detected by parse_expression() */
+ if (result) {
+ // It's also an error if there are any unused arguments. This is not detected by
+ // parse_expression().
assert(result->range.end <= args.size());
- if (result->range.end < args.size())
- {
- if (err.empty())
- {
- append_format(err, L"test: unexpected argument at index %lu: '%ls'\n", (unsigned long)result->range.end, args.at(result->range.end).c_str());
+ if (result->range.end < args.size()) {
+ if (err.empty()) {
+ append_format(err, L"test: unexpected argument at index %lu: '%ls'\n",
+ (unsigned long)result->range.end, args.at(result->range.end).c_str());
}
delete result;
@@ -681,290 +574,262 @@ expression *test_parser::parse_args(const wcstring_list_t &args, wcstring &err)
return result;
}
-bool unary_primary::evaluate(wcstring_list_t &errors)
-{
+bool unary_primary::evaluate(wcstring_list_t &errors) {
return unary_primary_evaluate(token, arg, errors);
}
-bool binary_primary::evaluate(wcstring_list_t &errors)
-{
+bool binary_primary::evaluate(wcstring_list_t &errors) {
return binary_primary_evaluate(token, arg_left, arg_right, errors);
}
-bool unary_operator::evaluate(wcstring_list_t &errors)
-{
- switch (token)
- {
- case test_bang:
+bool unary_operator::evaluate(wcstring_list_t &errors) {
+ switch (token) {
+ case test_bang: {
assert(subject.get());
- return ! subject->evaluate(errors);
- default:
+ return !subject->evaluate(errors);
+ }
+ default: {
errors.push_back(format_string(L"Unknown token type in %s", __func__));
return false;
-
+ }
}
}
-bool combining_expression::evaluate(wcstring_list_t &errors)
-{
- switch (token)
- {
+bool combining_expression::evaluate(wcstring_list_t &errors) {
+ switch (token) {
case test_combine_and:
- case test_combine_or:
- {
- /* One-element case */
- if (subjects.size() == 1)
- return subjects.at(0)->evaluate(errors);
+ case test_combine_or: {
+ // One-element case.
+ if (subjects.size() == 1) return subjects.at(0)->evaluate(errors);
- /* Evaluate our lists, remembering that AND has higher precedence than OR. We can visualize this as a sequence of OR expressions of AND expressions. */
+ // Evaluate our lists, remembering that AND has higher precedence than OR. We can
+ // visualize this as a sequence of OR expressions of AND expressions.
assert(combiners.size() + 1 == subjects.size());
- assert(! subjects.empty());
+ assert(!subjects.empty());
size_t idx = 0, max = subjects.size();
bool or_result = false;
- while (idx < max)
- {
- if (or_result)
- {
- /* Short circuit */
+ while (idx < max) {
+ if (or_result) { // short circuit
break;
}
- /* Evaluate a stream of AND starting at given subject index. It may only have one element. */
+ // Evaluate a stream of AND starting at given subject index. It may only have one
+ // element.
bool and_result = true;
- for (; idx < max; idx++)
- {
- /* Evaluate it, short-circuiting */
+ for (; idx < max; idx++) {
+ // Evaluate it, short-circuiting.
and_result = and_result && subjects.at(idx)->evaluate(errors);
- /* If the combiner at this index (which corresponding to how we combine with the next subject) is not AND, then exit the loop */
- if (idx + 1 < max && combiners.at(idx) != test_combine_and)
- {
+ // If the combiner at this index (which corresponding to how we combine with the
+ // next subject) is not AND, then exit the loop.
+ if (idx + 1 < max && combiners.at(idx) != test_combine_and) {
idx++;
break;
}
}
- /* OR it in */
+ // OR it in.
or_result = or_result || and_result;
}
return or_result;
}
-
- default:
+ default: {
errors.push_back(format_string(L"Unknown token type in %s", __func__));
return BUILTIN_TEST_FAIL;
-
+ }
}
}
-bool parenthetical_expression::evaluate(wcstring_list_t &errors)
-{
+bool parenthetical_expression::evaluate(wcstring_list_t &errors) {
return contents->evaluate(errors);
}
-/* IEEE 1003.1 says nothing about what it means for two strings to be "algebraically equal". For example, should we interpret 0x10 as 0, 10, or 16? Here we use only base 10 and use wcstoll, which allows for leading + and -, and leading whitespace. This matches bash. */
-static bool parse_number(const wcstring &arg, long long *out)
-{
+// IEEE 1003.1 says nothing about what it means for two strings to be "algebraically equal". For
+// example, should we interpret 0x10 as 0, 10, or 16? Here we use only base 10 and use wcstoll,
+// which allows for leading + and -, and leading whitespace. This matches bash.
+static bool parse_number(const wcstring &arg, long long *out) {
const wchar_t *str = arg.c_str();
wchar_t *endptr = NULL;
*out = wcstoll(str, &endptr, 10);
return endptr && *endptr == L'\0';
}
-static bool binary_primary_evaluate(test_expressions::token_t token, const wcstring &left, const wcstring &right, wcstring_list_t &errors)
-{
+static bool binary_primary_evaluate(test_expressions::token_t token, const wcstring &left,
+ const wcstring &right, wcstring_list_t &errors) {
using namespace test_expressions;
long long left_num, right_num;
- switch (token)
- {
- case test_string_equal:
+ switch (token) {
+ case test_string_equal: {
return left == right;
-
- case test_string_not_equal:
+ }
+ case test_string_not_equal: {
return left != right;
-
- case test_number_equal:
- return parse_number(left, &left_num) && parse_number(right, &right_num) && left_num == right_num;
-
- case test_number_not_equal:
- return parse_number(left, &left_num) && parse_number(right, &right_num) && left_num != right_num;
-
- case test_number_greater:
- return parse_number(left, &left_num) && parse_number(right, &right_num) && left_num > right_num;
-
- case test_number_greater_equal:
- return parse_number(left, &left_num) && parse_number(right, &right_num) && left_num >= right_num;
-
- case test_number_lesser:
- return parse_number(left, &left_num) && parse_number(right, &right_num) && left_num < right_num;
-
- case test_number_lesser_equal:
- return parse_number(left, &left_num) && parse_number(right, &right_num) && left_num <= right_num;
-
- default:
+ }
+ case test_number_equal: {
+ return parse_number(left, &left_num) && parse_number(right, &right_num) &&
+ left_num == right_num;
+ }
+ case test_number_not_equal: {
+ return parse_number(left, &left_num) && parse_number(right, &right_num) &&
+ left_num != right_num;
+ }
+ case test_number_greater: {
+ return parse_number(left, &left_num) && parse_number(right, &right_num) &&
+ left_num > right_num;
+ }
+ case test_number_greater_equal: {
+ return parse_number(left, &left_num) && parse_number(right, &right_num) &&
+ left_num >= right_num;
+ }
+ case test_number_lesser: {
+ return parse_number(left, &left_num) && parse_number(right, &right_num) &&
+ left_num < right_num;
+ }
+ case test_number_lesser_equal: {
+ return parse_number(left, &left_num) && parse_number(right, &right_num) &&
+ left_num <= right_num;
+ }
+ default: {
errors.push_back(format_string(L"Unknown token type in %s", __func__));
return false;
+ }
}
}
-
-static bool unary_primary_evaluate(test_expressions::token_t token, const wcstring &arg, wcstring_list_t &errors)
-{
+static bool unary_primary_evaluate(test_expressions::token_t token, const wcstring &arg,
+ wcstring_list_t &errors) {
using namespace test_expressions;
struct stat buf;
long long num;
- switch (token)
- {
- case test_filetype_b: // "-b", for block special files
+ switch (token) {
+ case test_filetype_b: { // "-b", for block special files
return !wstat(arg, &buf) && S_ISBLK(buf.st_mode);
-
- case test_filetype_c: // "-c", for character special files
+ }
+ case test_filetype_c: { // "-c", for character special files
return !wstat(arg, &buf) && S_ISCHR(buf.st_mode);
-
- case test_filetype_d: // "-d", for directories
+ }
+ case test_filetype_d: { // "-d", for directories
return !wstat(arg, &buf) && S_ISDIR(buf.st_mode);
-
- case test_filetype_e: // "-e", for files that exist
+ }
+ case test_filetype_e: { // "-e", for files that exist
return !wstat(arg, &buf);
-
- case test_filetype_f: // "-f", for for regular files
+ }
+ case test_filetype_f: { // "-f", for for regular files
return !wstat(arg, &buf) && S_ISREG(buf.st_mode);
-
- case test_filetype_G: // "-G", for check effective group id
+ }
+ case test_filetype_G: { // "-G", for check effective group id
return !wstat(arg, &buf) && getegid() == buf.st_gid;
-
- case test_filetype_g: // "-g", for set-group-id
+ }
+ case test_filetype_g: { // "-g", for set-group-id
return !wstat(arg, &buf) && (S_ISGID & buf.st_mode);
-
- case test_filetype_h: // "-h", for symbolic links
- case test_filetype_L: // "-L", same as -h
+ }
+ case test_filetype_h: // "-h", for symbolic links
+ case test_filetype_L: { // "-L", same as -h
return !lwstat(arg, &buf) && S_ISLNK(buf.st_mode);
-
- case test_filetype_O: // "-O", for check effective user id
+ }
+ case test_filetype_O: { // "-O", for check effective user id
return !wstat(arg, &buf) && geteuid() == buf.st_uid;
-
- case test_filetype_p: // "-p", for FIFO
+ }
+ case test_filetype_p: { // "-p", for FIFO
return !wstat(arg, &buf) && S_ISFIFO(buf.st_mode);
-
- case test_filetype_S: // "-S", socket
+ }
+ case test_filetype_S: { // "-S", socket
return !wstat(arg, &buf) && S_ISSOCK(buf.st_mode);
-
- case test_filesize_s: // "-s", size greater than zero
+ }
+ case test_filesize_s: { // "-s", size greater than zero
return !wstat(arg, &buf) && buf.st_size > 0;
-
- case test_filedesc_t: // "-t", whether the fd is associated with a terminal
+ }
+ case test_filedesc_t: { // "-t", whether the fd is associated with a terminal
return parse_number(arg, &num) && num == (int)num && isatty((int)num);
-
- case test_fileperm_r: // "-r", read permission
+ }
+ case test_fileperm_r: { // "-r", read permission
return !waccess(arg, R_OK);
-
- case test_fileperm_u: // "-u", whether file is setuid
+ }
+ case test_fileperm_u: { // "-u", whether file is setuid
return !wstat(arg, &buf) && (S_ISUID & buf.st_mode);
-
- case test_fileperm_w: // "-w", whether file write permission is allowed
+ }
+ case test_fileperm_w: { // "-w", whether file write permission is allowed
return !waccess(arg, W_OK);
-
- case test_fileperm_x: // "-x", whether file execute/search is allowed
+ }
+ case test_fileperm_x: { // "-x", whether file execute/search is allowed
return !waccess(arg, X_OK);
-
- case test_string_n: // "-n", non-empty string
- return ! arg.empty();
-
- case test_string_z: // "-z", true if length of string is 0
+ }
+ case test_string_n: { // "-n", non-empty string
+ return !arg.empty();
+ }
+ case test_string_z: { // "-z", true if length of string is 0
return arg.empty();
-
- default:
+ }
+ default: {
errors.push_back(format_string(L"Unknown token type in %s", __func__));
return false;
+ }
}
}
-
};
-/*
- * Evaluate a conditional expression given the arguments.
- * If fromtest is set, the caller is the test or [ builtin;
- * with the pointer giving the name of the command.
- * for POSIX conformance this supports a more limited range
- * of functionality.
- *
- * Return status is the final shell status, i.e. 0 for true,
- * 1 for false and 2 for error.
- */
-int builtin_test(parser_t &parser, io_streams_t &streams, wchar_t **argv)
-{
+/// Evaluate a conditional expression given the arguments. If fromtest is set, the caller is the
+/// test or [ builtin; with the pointer giving the name of the command. for POSIX conformance this
+/// supports a more limited range of functionality.
+///
+/// Return status is the final shell status, i.e. 0 for true, 1 for false and 2 for error.
+int builtin_test(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
using namespace test_expressions;
- /* The first argument should be the name of the command ('test') */
- if (! argv[0])
- return BUILTIN_TEST_FAIL;
+ // The first argument should be the name of the command ('test').
+ if (!argv[0]) return BUILTIN_TEST_FAIL;
- /* Whether we are invoked with bracket '[' or not */
- const bool is_bracket = ! wcscmp(argv[0], L"[");
+ // Whether we are invoked with bracket '[' or not.
+ const bool is_bracket = !wcscmp(argv[0], L"[");
size_t argc = 0;
- while (argv[argc + 1])
- argc++;
-
- /* If we're bracket, the last argument ought to be ]; we ignore it. Note that argc is the number of arguments after the command name; thus argv[argc] is the last argument. */
- if (is_bracket)
- {
- if (! wcscmp(argv[argc], L"]"))
- {
- /* Ignore the closing bracketp */
+ while (argv[argc + 1]) argc++;
+
+ // If we're bracket, the last argument ought to be ]; we ignore it. Note that argc is the number
+ // of arguments after the command name; thus argv[argc] is the last argument.
+ if (is_bracket) {
+ if (!wcscmp(argv[argc], L"]")) {
+ // Ignore the closing bracketp.
argc--;
- }
- else
- {
+ } else {
streams.err.append(L"[: the last argument must be ']'\n");
return BUILTIN_TEST_FAIL;
}
-
}
- /* Collect the arguments into a list */
+ // Collect the arguments into a list.
const wcstring_list_t args(argv + 1, argv + 1 + argc);
- switch (argc)
- {
- case 0:
- {
- // Per 1003.1, exit false
+ switch (argc) {
+ case 0: {
+ // Per 1003.1, exit false.
return BUILTIN_TEST_FAIL;
}
- case 1:
- {
- // Per 1003.1, exit true if the arg is non-empty
+ case 1: {
+ // Per 1003.1, exit true if the arg is non-empty.
return args.at(0).empty() ? BUILTIN_TEST_FAIL : BUILTIN_TEST_SUCCESS;
}
- default:
- {
+ default: {
// Try parsing. If expr is not nil, we are responsible for deleting it.
wcstring err;
expression *expr = test_parser::parse_args(args, err);
- if (! expr)
- {
+ if (!expr) {
#if 0
printf("Oops! test was given args:\n");
- for (size_t i=0; i < argc; i++)
- {
+ for (size_t i=0; i < argc; i++) {
printf("\t%ls\n", args.at(i).c_str());
}
printf("and returned parse error: %ls\n", err.c_str());
#endif
streams.err.append(err);
return BUILTIN_TEST_FAIL;
- }
- else
- {
+ } else {
wcstring_list_t eval_errors;
bool result = expr->evaluate(eval_errors);
- if (! eval_errors.empty())
- {
+ if (!eval_errors.empty()) {
printf("test returned eval errors:\n");
- for (size_t i=0; i < eval_errors.size(); i++)
- {
+ for (size_t i = 0; i < eval_errors.size(); i++) {
printf("\t%ls\n", eval_errors.at(i).c_str());
}
}
diff --git a/src/builtin_test.h b/src/builtin_test.h
new file mode 100644
index 00000000..b350cc63
--- /dev/null
+++ b/src/builtin_test.h
@@ -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
diff --git a/src/builtin_ulimit.cpp b/src/builtin_ulimit.cpp
index 27036023..f873c385 100644
--- a/src/builtin_ulimit.cpp
+++ b/src/builtin_ulimit.cpp
@@ -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;
-}
-;
-
-/**
- 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 process’s data segment", L'd', 1024
- }
- ,
- {
- RLIMIT_FSIZE, L"Maximum size of files created by the shell", L'f', 1024
- }
- ,
+/// 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 process’s 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
- }
-}
-;
-
-/**
- Get the implicit multiplication factor for the specified resource limit
-*/
-static int get_multiplier(int what)
-{
- int i;
+ {0, 0, 0, 0}};
- 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;
}
diff --git a/src/builtin_ulimit.h b/src/builtin_ulimit.h
new file mode 100644
index 00000000..1e694e07
--- /dev/null
+++ b/src/builtin_ulimit.h
@@ -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